From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/graphics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 83fca7a9bfa..4dd33e5616b 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -7806,7 +7806,7 @@ static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, return METAFILE_DrawDriverString((GpMetafile*)graphics->image, text, length, font, format, brush, positions, flags, matrix);
- if (graphics->hdc && !graphics->alpha_hdc && + if (has_gdi_dc(graphics) && !graphics->alpha_hdc && brush->bt == BrushTypeSolidColor && (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000) stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format,
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/region.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 063ccc96d90..ebab5c0a8a8 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -990,7 +990,7 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) { - HDC new_hdc=NULL; + HDC new_hdc=NULL, hdc; GpGraphics *new_graphics=NULL; GpStatus stat; INT save_state; @@ -1003,7 +1003,7 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
if (!graphics) { - new_hdc = CreateCompatibleDC(0); + hdc = new_hdc = CreateCompatibleDC(0); if (!new_hdc) return OutOfMemory;
@@ -1015,31 +1015,36 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) return stat; } } - else if (!graphics->hdc) + else if (has_gdi_dc(graphics)) { - graphics->hdc = new_hdc = CreateCompatibleDC(0); + stat = gdi_dc_acquire(graphics, &hdc); + if (stat != Ok) + return stat; + } + else + { + graphics->hdc = hdc = new_hdc = CreateCompatibleDC(0); if (!new_hdc) return OutOfMemory; }
- save_state = SaveDC(graphics->hdc); - EndPath(graphics->hdc); + save_state = SaveDC(hdc); + EndPath(hdc);
- SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE - : WINDING)); + SetPolyFillMode(hdc, (path->fill == FillModeAlternate ? ALTERNATE : WINDING));
gdi_transform_acquire(graphics);
stat = trace_path(graphics, path); if (stat == Ok) { - *hrgn = PathToRegion(graphics->hdc); + *hrgn = PathToRegion(hdc); stat = *hrgn ? Ok : OutOfMemory; }
gdi_transform_release(graphics);
- RestoreDC(graphics->hdc, save_state); + RestoreDC(hdc, save_state); if (new_hdc) { DeleteDC(new_hdc); @@ -1048,6 +1053,8 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) else graphics->hdc = NULL; } + else + gdi_dc_release(graphics, hdc);
return stat; }
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/graphics.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 4dd33e5616b..d50379e5943 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -7154,14 +7154,21 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
GpStatus gdi_transform_acquire(GpGraphics *graphics) { - if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc) + if (graphics->gdi_transform_acquire_count == 0 && has_gdi_dc(graphics)) { - graphics->gdi_transform_save = SaveDC(graphics->hdc); - ModifyWorldTransform(graphics->hdc, NULL, MWT_IDENTITY); - SetGraphicsMode(graphics->hdc, GM_COMPATIBLE); - SetMapMode(graphics->hdc, MM_TEXT); - SetWindowOrgEx(graphics->hdc, 0, 0, NULL); - SetViewportOrgEx(graphics->hdc, 0, 0, NULL); + HDC hdc; + GpStatus stat; + + stat = gdi_dc_acquire(graphics, &hdc); + if (stat != Ok) + return stat; + + graphics->gdi_transform_save = SaveDC(hdc); + ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); + SetGraphicsMode(hdc, GM_COMPATIBLE); + SetMapMode(hdc, MM_TEXT); + SetWindowOrgEx(hdc, 0, 0, NULL); + SetViewportOrgEx(hdc, 0, 0, NULL); } graphics->gdi_transform_acquire_count++; return Ok; @@ -7177,6 +7184,7 @@ GpStatus gdi_transform_release(GpGraphics *graphics) if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc) { RestoreDC(graphics->hdc, graphics->gdi_transform_save); + gdi_dc_release(graphics, graphics->hdc); } graphics->gdi_transform_acquire_count--; return Ok;
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/gdiplus_private.h | 2 +- dlls/gdiplus/graphics.c | 38 ++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index e25f60de78e..d247b973b3b 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -665,7 +665,7 @@ static inline void image_unlock(GpImage *image)
static inline BOOL has_gdi_dc(GpGraphics *graphics) { - return graphics->hdc != NULL; + return graphics->hdc != NULL || graphics->owndc; }
static inline void set_rect(GpRectF *rect, REAL x, REAL y, REAL width, REAL height) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index d50379e5943..58fa129b504 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -55,6 +55,14 @@ GpStatus gdi_dc_acquire(GpGraphics *graphics, HDC *hdc) graphics->hdc_refs++; return Ok; } + else if (graphics->owndc) + { + *hdc = graphics->hdc = GetDC(graphics->hwnd); + if (!graphics->hdc) + return OutOfMemory; + graphics->hdc_refs++; + return Ok; + }
*hdc = NULL; return InvalidParameter; @@ -64,6 +72,13 @@ void gdi_dc_release(GpGraphics *graphics, HDC hdc) { assert(graphics->hdc_refs > 0); graphics->hdc_refs--; + + if (graphics->owndc && !graphics->hdc_refs) + { + assert(graphics->hdc == hdc); + graphics->hdc = NULL; + ReleaseDC(graphics->hwnd, hdc); + } }
static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, @@ -2556,6 +2571,9 @@ GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics) (*graphics)->hwnd = hwnd; (*graphics)->owndc = TRUE;
+ ReleaseDC(hwnd, hdc); + (*graphics)->hdc = NULL; + return Ok; }
@@ -2610,13 +2628,13 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
if (graphics->temp_hdc) { - DeleteDC(graphics->temp_hdc); + if (graphics->owndc) + ReleaseDC(graphics->hwnd, graphics->temp_hdc); + else + DeleteDC(graphics->temp_hdc); graphics->temp_hdc = NULL; }
- if(graphics->owndc) - ReleaseDC(graphics->hwnd, graphics->hdc); - LIST_FOR_EACH_ENTRY_SAFE(cont, next, &graphics->containers, GraphicsContainerItem, entry){ list_remove(&cont->entry); delete_container(cont); @@ -7002,6 +7020,13 @@ GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc) { stat = METAFILE_GetDC((GpMetafile*)graphics->image, hdc); } + else if (graphics->owndc) + { + graphics->temp_hdc = GetDC(graphics->hwnd); + if (!graphics->temp_hdc) + return OutOfMemory; + *hdc = graphics->temp_hdc; + } else if (!graphics->hdc || (graphics->image && graphics->image->type == ImageTypeBitmap)) { @@ -7083,6 +7108,11 @@ GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc) { stat = METAFILE_ReleaseDC((GpMetafile*)graphics->image, hdc); } + else if (graphics->owndc) + { + ReleaseDC(graphics->hwnd, graphics->temp_hdc); + graphics->temp_hdc = NULL; + } else if (graphics->temp_hdc == hdc) { DWORD* pos;
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/graphics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 58fa129b504..14e09e7cc47 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -519,7 +519,8 @@ static GpStatus alpha_blend_hdc_pixels(GpGraphics *graphics, INT dst_x, INT dst_ if(!hbitmap || !temp_bits) goto done;
- if ((GetDeviceCaps(graphics->hdc, TECHNOLOGY) == DT_RASPRINTER && + if ((graphics->hdc && + GetDeviceCaps(graphics->hdc, TECHNOLOGY) == DT_RASPRINTER && GetDeviceCaps(graphics->hdc, SHADEBLENDCAPS) == SB_NONE) || fmt & PixelFormatPAlpha) memcpy(temp_bits, src, src_width * src_height * 4);