Vincent Povirk : gdiplus: Scale all points in GdipAddPathString instead of the font.

Alexandre Julliard julliard at winehq.org
Fri Jun 22 10:52:04 CDT 2012


Module: wine
Branch: master
Commit: cae52d078a871f184653da7ff171b337b2848e21
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cae52d078a871f184653da7ff171b337b2848e21

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Jun 21 15:31:27 2012 -0500

gdiplus: Scale all points in GdipAddPathString instead of the font.

---

 dlls/gdiplus/graphicspath.c |   46 +++++++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index f61d588..3095c08 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -840,7 +840,8 @@ static float fromfixedpoint(const FIXED v)
 struct format_string_args
 {
     GpPath *path;
-    UINT maxY;
+    float maxY;
+    float scale;
 };
 
 static GpStatus format_string_callback(HDC dc,
@@ -853,8 +854,8 @@ static GpStatus format_string_callback(HDC dc,
     struct format_string_args *args = priv;
     GpPath *path = args->path;
     GpStatus status = Ok;
-    float x = bounds->X;
-    float y = bounds->Y;
+    float x = rect->X + (bounds->X - rect->X) * args->scale;
+    float y = rect->Y + (bounds->Y - rect->Y) * args->scale;
     int i;
 
     if (underlined_index_count)
@@ -866,7 +867,7 @@ static GpStatus format_string_callback(HDC dc,
         TTPOLYGONHEADER *ph = NULL;
         char *start;
         DWORD len, ofs = 0;
-        UINT bb_end;
+        float bb_end;
         len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
         if (len == GDI_ERROR)
         {
@@ -881,7 +882,7 @@ static GpStatus format_string_callback(HDC dc,
             break;
         }
         GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, len, start, &identity);
-        bb_end = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
+        bb_end = (gm.gmBlackBoxY + gm.gmptGlyphOrigin.y) * args->scale;
         if (bb_end + y > args->maxY)
             args->maxY = bb_end + y;
 
@@ -891,8 +892,8 @@ static GpStatus format_string_callback(HDC dc,
             DWORD ofs_start = ofs;
             ph = (TTPOLYGONHEADER*)&start[ofs];
             path->pathdata.Types[path->pathdata.Count] = PathPointTypeStart;
-            path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x);
-            path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(ph->pfxStart.y);
+            path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x) * args->scale;
+            path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(ph->pfxStart.y) * args->scale;
             TRACE("Starting at count %i with pos %f, %f)\n", path->pathdata.Count, x, y);
             ofs += sizeof(*ph);
             while (ofs - ofs_start < ph->cb)
@@ -907,16 +908,16 @@ static GpStatus format_string_callback(HDC dc,
                     for (j = 0; j < curve->cpfx; ++j)
                     {
                         path->pathdata.Types[path->pathdata.Count] = PathPointTypeLine;
-                        path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
-                        path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
+                        path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
+                        path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y) * args->scale;
                     }
                     break;
                 case TT_PRIM_CSPLINE:
                     for (j = 0; j < curve->cpfx; ++j)
                     {
                         path->pathdata.Types[path->pathdata.Count] = PathPointTypeBezier;
-                        path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
-                        path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
+                        path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
+                        path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y) * args->scale;
                     }
                     break;
                 default:
@@ -927,8 +928,8 @@ static GpStatus format_string_callback(HDC dc,
             path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
         }
         path->newfigure = TRUE;
-        x += gm.gmCellIncX;
-        y += gm.gmCellIncY;
+        x += gm.gmCellIncX * args->scale;
+        y += gm.gmCellIncY * args->scale;
 
         GdipFree(ph);
         if (status != Ok)
@@ -948,12 +949,24 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
     GpPath *backup;
     struct format_string_args args;
     int i;
+    UINT16 native_height;
+    RectF scaled_layout_rect;
+    TEXTMETRICW textmetric;
 
     FIXME("(%p, %s, %d, %p, %d, %f, %p, %p): stub\n", path, debugstr_w(string), length, family, style, emSize, layoutRect, format);
     if (!path || !string || !family || !emSize || !layoutRect || !format)
         return InvalidParameter;
 
-    status = GdipCreateFont(family, emSize, style, UnitPixel, &font);
+    status = GdipGetEmHeight(family, style, &native_height);
+    if (status != Ok)
+        return status;
+
+    scaled_layout_rect.X = layoutRect->X;
+    scaled_layout_rect.Y = layoutRect->Y;
+    scaled_layout_rect.Width = layoutRect->Width * native_height / emSize;
+    scaled_layout_rect.Height = layoutRect->Height * native_height / emSize;
+
+    status = GdipCreateFont(family, native_height, style, UnitPixel, &font);
     if (status != Ok)
         return status;
 
@@ -974,9 +987,12 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
     dc = CreateCompatibleDC(0);
     SelectObject(dc, hfont);
 
+    GetTextMetricsW(dc, &textmetric);
+
     args.path = path;
     args.maxY = 0;
-    status = gdip_format_string(dc, string, length, NULL, layoutRect, format, format_string_callback, &args);
+    args.scale = emSize / native_height;
+    status = gdip_format_string(dc, string, length, NULL, &scaled_layout_rect, format, format_string_callback, &args);
 
     DeleteDC(dc);
     DeleteObject(hfont);




More information about the wine-cvs mailing list