@@ -320,10 +320,16 @@ gdip_is_region_empty (const GpRegion *region, BOOL allowNegative)
320320static BOOL
321321gdip_is_rect_infinite (const GpRectF * rect )
322322{
323- return (rect && (rect -> X == REGION_INFINITE_POSITION ) &&
324- (rect -> Y == REGION_INFINITE_POSITION ) &&
325- (rect -> Width == REGION_INFINITE_LENGTH ) &&
326- (rect -> Height == REGION_INFINITE_LENGTH ));
323+ if (!rect )
324+ return FALSE;
325+
326+ if (gdip_is_rectF_empty (rect , /* allowNegative */ TRUE))
327+ return FALSE;
328+
329+ if (rect -> Width >= REGION_INFINITE_LENGTH || rect -> Height >= REGION_INFINITE_LENGTH )
330+ return TRUE;
331+
332+ return FALSE;
327333}
328334
329335BOOL
@@ -2039,18 +2045,17 @@ GdipGetRegionScans (GpRegion *region, GpRectF* rects, INT* count, GpMatrix* matr
20392045
20402046if (gdip_is_region_empty (work , /* allowNegative */ TRUE)) {
20412047* count = 0 ;
2048+ } else if (gdip_is_InfiniteRegion (work )) {
2049+ if (rects ) {
2050+ rects -> X = REGION_INFINITE_POSITION ;
2051+ rects -> Y = REGION_INFINITE_POSITION ;
2052+ rects -> Width = REGION_INFINITE_LENGTH ;
2053+ rects -> Height = REGION_INFINITE_LENGTH ;
2054+ }
2055+
2056+ * count = 1 ;
20422057} else {
20432058switch (region -> type ) {
2044- case RegionTypeInfinite :
2045- if (rects ) {
2046- rects -> X = REGION_INFINITE_POSITION ;
2047- rects -> Y = REGION_INFINITE_POSITION ;
2048- rects -> Width = REGION_INFINITE_LENGTH ;
2049- rects -> Height = REGION_INFINITE_LENGTH ;
2050- }
2051-
2052- * count = 1 ;
2053- break ;
20542059case RegionTypeRect :
20552060if (rects ) {
20562061for (int i = 0 ; i < work -> cnt ; i ++ ) {
@@ -2208,10 +2213,8 @@ GdipTranslateRegion (GpRegion *region, float dx, float dy)
22082213if (!region )
22092214return InvalidParameter ;
22102215
2211- /* can't transforman infinite region to anything else than an infinite region
2212- * (even if you scale it by half it's still infinite ;-) see unit tests
2213- */
2214- if (gdip_is_InfiniteRegion (region ))
2216+ // Infinite regions cannot be transformed.
2217+ if (region -> type == RegionTypeInfinite )
22152218return Ok ;
22162219
22172220switch (region -> type ) {
@@ -2251,18 +2254,14 @@ GdipTranslateRegionI (GpRegion *region, int dx, int dy)
22512254static GpStatus
22522255ScaleRegion (GpRegion * region , float sx , float sy )
22532256{
2254- if (! region )
2255- return InvalidParameter ;
2257+ g_assert ( region );
2258+ g_assert ( region -> type == RegionTypeRect && region -> rects ) ;
22562259
2257- if ((region -> type == RegionTypeRect ) && region -> rects ) {
2258- int i ;
2259- GpRectF * rect ;
2260- for (i = 0 , rect = region -> rects ; i < region -> cnt ; i ++ , rect ++ ) {
2261- rect -> X *= sx ;
2262- rect -> Y *= sy ;
2263- rect -> Width *= sx ;
2264- rect -> Height *= sy ;
2265- }
2260+ for (int i = 0 ; i < region -> cnt ; i ++ ) {
2261+ region -> rects [i ].X *= sx ;
2262+ region -> rects [i ].Y *= sy ;
2263+ region -> rects [i ].Width *= sx ;
2264+ region -> rects [i ].Height *= sy ;
22662265}
22672266
22682267return Ok ;
@@ -2276,43 +2275,36 @@ GdipTransformRegion (GpRegion *region, GpMatrix *matrix)
22762275if (!region || !matrix )
22772276return InvalidParameter ;
22782277
2279- /* no transformation to do on an empty region */
2280- if (( region -> cnt == 0 ) && (region -> type == RegionTypeRect ))
2278+ // Infinite and empty regions cannot be transformed.
2279+ if (region -> type == RegionTypeInfinite || (( region -> cnt == 0 ) && (region -> type == RegionTypeRect ) ))
22812280return Ok ;
22822281
2283- /* don't (possibly) convert to a bitmap if the matrix is empty (a no-op) */
2282+ // Nothing to do.
22842283if (gdip_is_matrix_empty (matrix ))
22852284return Ok ;
22862285
2287- /* can't transforman infinite region to anything else than an infinite region
2288- * (even if you scale it by half it's still infinite ;-) see unit tests
2289- */
2290- if (gdip_is_InfiniteRegion (region ))
2291- return Ok ;
2286+ BOOL isSimpleMatrix = (matrix -> xy == 0 ) && (matrix -> yx == 0 );
2287+ BOOL matrixHasTranslate = (matrix -> x0 != 0 ) || (matrix -> y0 != 0 );
2288+ BOOL matrixHasScale = (matrix -> xx != 1 ) || (matrix -> yy != 1 );
22922289
22932290/* try to avoid heavy stuff (e.g. conversion to path, invalidating
22942291 * bitmap...) if the transform is:
22952292 * - a translation + scale operations (for rectangle ebased region)
22962293 * - only to do a scale operation (for a rectangle based region)
22972294 * - only to do a simple translation (for both rectangular and bitmap based regions)
22982295 */
2299- if ((matrix -> xy == 0.0f ) && (matrix -> yx == 0.0f )) {
2300- BOOL s = (((matrix -> xx != 1.0f ) || (matrix -> yy != 1.0f )) && (region -> type == RegionTypeRect ));
2301- BOOL t = ((matrix -> x0 != 0.0f ) || (matrix -> yx != 0.0f ));
2302- if (s ) {
2303- status = ScaleRegion (region ,
2304- gdip_matrix_get_x_scale (matrix ),
2305- gdip_matrix_get_y_scale (matrix ));
2306- }
2307- if (t && (status == Ok )) {
2308- status = GdipTranslateRegion (region ,
2309- gdip_matrix_get_x_translation (matrix ),
2310- gdip_matrix_get_y_translation (matrix ));
2311- }
2296+ if (region -> type == RegionTypeRect ) {
2297+ if (isSimpleMatrix ) {
2298+ if (matrixHasScale )
2299+ ScaleRegion (region , matrix -> xx , matrix -> yy );
2300+ if (matrixHasTranslate )
2301+ GdipTranslateRegion (region , matrix -> x0 , matrix -> y0 );
23122302
2313- /* return now if we could optimize the transform (to avoid bitmaps) */
2314- if (t || s )
2315- return status ;
2303+ return Ok ;
2304+ }
2305+ } else if (isSimpleMatrix && !matrixHasScale ) {
2306+ GdipTranslateRegion (region , matrix -> x0 , matrix -> y0 );
2307+ return Ok ;
23162308}
23172309
23182310/* most matrix operations would change the rectangles into path so we always preempt this */
0 commit comments