/***************************************************************************** * GdipCombineRegionRect [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode) { GpRegion *rect_region; region_element *left, *right = NULL; GpStatus stat; TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode); if (!(region && rect)) return InvalidParameter; stat = GdipCreateRegionRect(rect, &rect_region); if (stat != Ok) return stat; /* simply replace region data */ if(mode == CombineModeReplace){ delete_element(®ion->node); memcpy(region, rect_region, sizeof(GpRegion)); heap_free(rect_region); return Ok; } left = heap_alloc_zero(sizeof(region_element)); if (left) { memcpy(left, ®ion->node, sizeof(region_element)); stat = clone_element(&rect_region->node, &right); if (stat == Ok) { fuse_region(region, left, right, mode); GdipDeleteRegion(rect_region); return Ok; } } else stat = OutOfMemory; heap_free(left); GdipDeleteRegion(rect_region); return stat; }
/***************************************************************************** * GdipGetRegionBounds [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect) { HRGN hrgn; RECT r; GpStatus status; TRACE("(%p, %p, %p)\n", region, graphics, rect); if(!region || !graphics || !rect) return InvalidParameter; /* Contrary to MSDN, native ignores the graphics transform. */ status = GdipGetRegionHRgn(region, NULL, &hrgn); if(status != Ok) return status; /* infinite */ if(!hrgn){ rect->X = rect->Y = -(REAL)(1 << 22); rect->Width = rect->Height = (REAL)(1 << 23); TRACE("%p => infinite\n", region); return Ok; } if(GetRgnBox(hrgn, &r)){ rect->X = r.left; rect->Y = r.top; rect->Width = r.right - r.left; rect->Height = r.bottom - r.top; TRACE("%p => %s\n", region, debugstr_rectf(rect)); } else status = GenericError; DeleteObject(hrgn); return status; }
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics, GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *destPoints, INT count, GDIPCONST GpRectF *srcRect, Unit srcUnit, EnumerateMetafileProc callback, VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes) { struct enum_metafile_data data; GpStatus stat; GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */ GraphicsContainer state; GpPath *dst_path; TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile, destPoints, count, srcRect, srcUnit, callback, callbackData, imageAttributes); if (!graphics || !metafile || !destPoints || count != 3 || !srcRect) return InvalidParameter; if (!metafile->hemf) return InvalidParameter; if (metafile->playback_graphics) return ObjectBusy; TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit, debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]), debugstr_pointf(&destPoints[2])); data.callback = callback; data.callback_data = callbackData; data.metafile = real_metafile; real_metafile->playback_graphics = graphics; real_metafile->playback_dc = NULL; real_metafile->src_rect = *srcRect; memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3); stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3); if (stat == Ok) stat = GdipBeginContainer2(graphics, &state); if (stat == Ok) { stat = GdipSetPageScale(graphics, 1.0); if (stat == Ok) stat = GdipSetPageUnit(graphics, UnitPixel); if (stat == Ok) stat = GdipResetWorldTransform(graphics); if (stat == Ok) stat = GdipCreateRegion(&real_metafile->base_clip); if (stat == Ok) stat = GdipGetClip(graphics, real_metafile->base_clip); if (stat == Ok) stat = GdipCreatePath(FillModeAlternate, &dst_path); if (stat == Ok) { GpPointF clip_points[4]; clip_points[0] = real_metafile->playback_points[0]; clip_points[1] = real_metafile->playback_points[1]; clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X - real_metafile->playback_points[0].X; clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y - real_metafile->playback_points[0].Y; clip_points[3] = real_metafile->playback_points[2]; stat = GdipAddPathPolygon(dst_path, clip_points, 4); if (stat == Ok) stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect); GdipDeletePath(dst_path); } if (stat == Ok) stat = GdipCreateMatrix(&real_metafile->world_transform); if (stat == Ok) { real_metafile->page_unit = UnitDisplay; real_metafile->page_scale = 1.0; stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile); } if (stat == Ok) { stat = METAFILE_PlaybackUpdateClip(real_metafile); } if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf || metafile->metafile_type == MetafileTypeWmfPlaceable || metafile->metafile_type == MetafileTypeWmf)) stat = METAFILE_PlaybackGetDC(real_metafile); if (stat == Ok) EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL); METAFILE_PlaybackReleaseDC(real_metafile); GdipDeleteMatrix(real_metafile->world_transform); real_metafile->world_transform = NULL; GdipDeleteRegion(real_metafile->base_clip); real_metafile->base_clip = NULL; GdipEndContainer(graphics, state); } real_metafile->playback_graphics = NULL; return stat; }