Vincent Povirk : gdiplus: Support character offsets in GDI32_GdipDrawDriverString.

Alexandre Julliard julliard at winehq.org
Fri May 8 15:20:31 CDT 2020


Module: wine
Branch: master
Commit: 3250a17e208852fc0fbcac897a69d56010796c1f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3250a17e208852fc0fbcac897a69d56010796c1f

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu May  7 21:08:46 2020 -0500

gdiplus: Support character offsets in GDI32_GdipDrawDriverString.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdiplus/graphics.c | 66 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 52 insertions(+), 14 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 04c5501deb..72075e02fb 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2242,7 +2242,7 @@ void get_log_fontW(const GpFont *font, GpGraphics *graphics, LOGFONTW *lf)
 
 static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font,
                            GDIPCONST GpStringFormat *format, HFONT *hfont,
-                           GDIPCONST GpMatrix *matrix)
+                           LOGFONTW *lfw_return, GDIPCONST GpMatrix *matrix)
 {
     HDC hdc = CreateCompatibleDC(0);
     GpPointF pt[3];
@@ -2300,6 +2300,9 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font,
 
     *hfont = CreateFontIndirectW(&lfw);
 
+    if (lfw_return)
+        *lfw_return = lfw;
+
     DeleteDC(hdc);
     DeleteObject(unscaled_font);
 }
@@ -5371,7 +5374,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
     if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23;
     if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23;
 
-    get_font_hfont(graphics, font, stringFormat, &gdifont, NULL);
+    get_font_hfont(graphics, font, stringFormat, &gdifont, NULL, NULL);
     oldfont = SelectObject(hdc, gdifont);
 
     for (i=0; i<stringFormat->range_count; i++)
@@ -5505,7 +5508,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
     if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23;
     if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23;
 
-    get_font_hfont(graphics, font, format, &gdifont, NULL);
+    get_font_hfont(graphics, font, format, &gdifont, NULL, NULL);
     oldfont = SelectObject(hdc, gdifont);
 
     bounds->X = rect->X;
@@ -5692,7 +5695,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
         SelectClipRgn(hdc, rgn);
     }
 
-    get_font_hfont(graphics, font, format, &gdifont, NULL);
+    get_font_hfont(graphics, font, format, &gdifont, NULL, NULL);
     SelectObject(hdc, gdifont);
 
     args.graphics = graphics;
@@ -6990,7 +6993,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
     if (flags & unsupported_flags)
         FIXME("Ignoring flags %x\n", flags & unsupported_flags);
 
-    get_font_hfont(graphics, font, NULL, &hfont, matrix);
+    get_font_hfont(graphics, font, NULL, &hfont, NULL, matrix);
 
     hdc = CreateCompatibleDC(0);
     SelectObject(hdc, hfont);
@@ -7075,20 +7078,30 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
                                            GDIPCONST GpBrush *brush, GDIPCONST PointF *positions,
                                            INT flags, GDIPCONST GpMatrix *matrix)
 {
-    static const INT unsupported_flags = ~(DriverStringOptionsRealizedAdvance|DriverStringOptionsCmapLookup);
     INT save_state;
-    GpPointF pt;
+    GpPointF pt, *real_positions=NULL;
+    INT *eto_positions=NULL;
     HFONT hfont;
+    LOGFONTW lfw;
     UINT eto_flags=0;
     GpStatus status;
     HRGN hrgn;
 
-    if (flags & unsupported_flags)
-        FIXME("Ignoring flags %x\n", flags & unsupported_flags);
-
     if (!(flags & DriverStringOptionsCmapLookup))
         eto_flags |= ETO_GLYPH_INDEX;
 
+    if (!(flags & DriverStringOptionsRealizedAdvance) && length > 1)
+    {
+        real_positions = heap_alloc(sizeof(*real_positions) * length);
+        eto_positions = heap_alloc(sizeof(*eto_positions) * 2 * (length - 1));
+        if (!real_positions || !eto_positions)
+        {
+            heap_free(real_positions);
+            heap_free(eto_positions);
+            return OutOfMemory;
+        }
+    }
+
     save_state = SaveDC(graphics->hdc);
     SetBkMode(graphics->hdc, TRANSPARENT);
     SetTextColor(graphics->hdc, get_gdi_brush_color(brush));
@@ -7104,14 +7117,37 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
     pt = positions[0];
     gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &pt, 1);
 
-    get_font_hfont(graphics, font, format, &hfont, matrix);
+    get_font_hfont(graphics, font, format, &hfont, &lfw, matrix);
+
+    if (!(flags & DriverStringOptionsRealizedAdvance) && length > 1)
+    {
+        GpMatrix rotation;
+        INT i;
+
+        eto_flags |= ETO_PDY;
+
+        memcpy(real_positions, positions, sizeof(PointF) * length);
+
+        gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, real_positions, length);
+
+        GdipSetMatrixElements(&rotation, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+        GdipRotateMatrix(&rotation, lfw.lfEscapement / 10.0, MatrixOrderAppend);
+        GdipTransformMatrixPoints(&rotation, real_positions, length);
+
+        for (i = 0; i < (length - 1); i++)
+        {
+            eto_positions[i*2] = gdip_round(real_positions[i+1].X) - gdip_round(real_positions[i].X);
+            eto_positions[i*2+1] = gdip_round(real_positions[i].Y) - gdip_round(real_positions[i+1].Y);
+        }
+    }
+
     SelectObject(graphics->hdc, hfont);
 
     SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT);
 
     gdi_transform_acquire(graphics);
 
-    ExtTextOutW(graphics->hdc, gdip_round(pt.X), gdip_round(pt.Y), eto_flags, NULL, text, length, NULL);
+    ExtTextOutW(graphics->hdc, gdip_round(pt.X), gdip_round(pt.Y), eto_flags, NULL, text, length, eto_positions);
 
     gdi_transform_release(graphics);
 
@@ -7119,6 +7155,9 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
 
     DeleteObject(hfont);
 
+    heap_free(real_positions);
+    heap_free(eto_positions);
+
     return Ok;
 }
 
@@ -7182,7 +7221,7 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
         heap_free(real_positions);
     }
 
-    get_font_hfont(graphics, font, format, &hfont, matrix);
+    get_font_hfont(graphics, font, format, &hfont, NULL, matrix);
 
     hdc = CreateCompatibleDC(0);
     SelectObject(hdc, hfont);
@@ -7346,7 +7385,6 @@ static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text,
         length = lstrlenW(text);
 
     if (graphics->hdc && !graphics->alpha_hdc &&
-        ((flags & DriverStringOptionsRealizedAdvance) || length <= 1) &&
         brush->bt == BrushTypeSolidColor &&
         (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000)
         stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format,




More information about the wine-cvs mailing list