gdiplus: Add support for extra transformation in GdipMeasureDriverString and GdipDrawDriverString.

Dmitry Timoshkov dmitry at baikal.ru
Wed Oct 31 00:34:15 CDT 2012


---
 dlls/gdiplus/graphics.c | 77 +++++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 35 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index c428b6b..e4f6bfa 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -309,7 +309,7 @@ static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace d
  * gdi to draw, and these functions would irreparably mess with line widths.
  */
 static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
-    GpPointF *ptf, INT count)
+    GpPointF *ptf, INT count, GDIPCONST GpMatrix *extra)
 {
     REAL scale_x, scale_y;
     GpMatrix *matrix;
@@ -327,6 +327,11 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
 
     GdipCloneMatrix(graphics->worldtrans, &matrix);
     GdipScaleMatrix(matrix, scale_x, scale_y, MatrixOrderAppend);
+    if (extra)
+    {
+        GpMatrix xform = *extra;
+        GdipMultiplyMatrix(matrix, &xform, MatrixOrderAppend);
+    }
     GdipTransformMatrixPoints(matrix, ptf, count);
     GdipDeleteMatrix(matrix);
 
@@ -1436,7 +1441,7 @@ static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
     deg2xy(startAngle+sweepAngle, x + width / 2.0, y + width / 2.0, &ptf[2].X, &ptf[2].Y);
     deg2xy(startAngle, x + width / 2.0, y + width / 2.0, &ptf[3].X, &ptf[3].Y);
 
-    transform_and_round_points(graphics, pti, ptf, 4);
+    transform_and_round_points(graphics, pti, ptf, 4, NULL);
 
     Pie(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y, pti[2].x,
         pti[2].y, pti[3].x, pti[3].y);
@@ -1506,7 +1511,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             ptf[3].X = x2 - dbig;
             ptf[2].X = x2 + dsmall;
 
-            transform_and_round_points(graphics, pt, ptf, 4);
+            transform_and_round_points(graphics, pt, ptf, 4, NULL);
             Polygon(graphics->hdc, pt, 4);
 
             break;
@@ -1528,7 +1533,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             ptf[2].X = x2;
             ptf[2].Y = y2;
 
-            transform_and_round_points(graphics, pt, ptf, 3);
+            transform_and_round_points(graphics, pt, ptf, 3, NULL);
             Polygon(graphics->hdc, pt, 3);
 
             break;
@@ -1540,7 +1545,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             ptf[1].X = x2 + dx;
             ptf[1].Y = y2 + dy;
 
-            transform_and_round_points(graphics, pt, ptf, 2);
+            transform_and_round_points(graphics, pt, ptf, 2, NULL);
             Ellipse(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
 
             break;
@@ -1560,7 +1565,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             ptf[2].X = x2 + dx;
             ptf[2].Y = y2 + dy;
 
-            transform_and_round_points(graphics, pt, ptf, 3);
+            transform_and_round_points(graphics, pt, ptf, 3, NULL);
             Polygon(graphics->hdc, pt, 3);
 
             break;
@@ -1580,7 +1585,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             ptf[3].X = x2 + dx;
             ptf[3].Y = y2 + dy;
 
-            transform_and_round_points(graphics, pt, ptf, 4);
+            transform_and_round_points(graphics, pt, ptf, 4, NULL);
             Pie(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y, pt[2].x,
                 pt[2].y, pt[3].x, pt[3].y);
 
@@ -1605,7 +1610,7 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
             GdipTranslateMatrix(matrix, x2, y2, MatrixOrderAppend);
             GdipTransformMatrixPoints(matrix, custptf, count);
 
-            transform_and_round_points(graphics, custpt, custptf, count);
+            transform_and_round_points(graphics, custpt, custptf, count, NULL);
 
             for(i = 0; i < count; i++)
                 tp[i] = convert_path_point_type(custom->pathdata.Types[i]);
@@ -1723,7 +1728,7 @@ static GpStatus draw_polyline(GpGraphics *graphics, GpPen *pen,
                          pt[1].X, pt[1].Y, pt[0].X, pt[0].Y);
     }
 
-    transform_and_round_points(graphics, pti, ptcopy, count);
+    transform_and_round_points(graphics, pti, ptcopy, count, NULL);
 
     if(Polyline(graphics->hdc, pti, count))
         status = Ok;
@@ -1825,7 +1830,7 @@ static GpStatus draw_polybezier(GpGraphics *graphics, GpPen *pen,
             pt[0].Y - (ptcopy[0].Y - ptcopy[1].Y), pt[0].X, pt[0].Y);
     }
 
-    transform_and_round_points(graphics, pti, ptcopy, count);
+    transform_and_round_points(graphics, pti, ptcopy, count, NULL);
 
     PolyBezier(graphics->hdc, pti, count);
 
@@ -1946,7 +1951,7 @@ static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *
         }
     }
 
-    transform_and_round_points(graphics, pti, ptcopy, count);
+    transform_and_round_points(graphics, pti, ptcopy, count, NULL);
 
     for(i = 0; i < count; i++){
         tp[i] = convert_path_point_type(types[i]);
@@ -2166,7 +2171,8 @@ 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 GpStringFormat *format, HFONT *hfont,
+                           GDIPCONST GpMatrix *matrix)
 {
     HDC hdc = CreateCompatibleDC(0);
     GpPointF pt[3];
@@ -2195,6 +2201,11 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font,
     pt[2].Y = 1.0;
     if (graphics)
         GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
+    if (matrix)
+    {
+        GpMatrix xform = *matrix;
+        GdipTransformMatrixPoints(&xform, pt, 3);
+    }
     angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
     rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
                      (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
@@ -2974,7 +2985,7 @@ GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x,
     save_state = prepare_dc(graphics, pen);
     SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
 
-    transform_and_round_points(graphics, pti, ptf, 2);
+    transform_and_round_points(graphics, pti, ptf, 2, NULL);
 
     Ellipse(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y);
 
@@ -3112,7 +3123,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
     ptf[3].Y = ptf[2].Y + ptf[1].Y - ptf[0].Y;
     if (!srcwidth || !srcheight || ptf[3].X == ptf[0].X || ptf[3].Y == ptf[0].Y)
         return Ok;
-    transform_and_round_points(graphics, pti, ptf, 4);
+    transform_and_round_points(graphics, pti, ptf, 4, NULL);
 
     TRACE("%s %s %s %s\n", wine_dbgstr_point(&pti[0]), wine_dbgstr_point(&pti[1]),
         wine_dbgstr_point(&pti[2]), wine_dbgstr_point(&pti[3]));
@@ -3728,7 +3739,7 @@ GpStatus WINGDIPAPI GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x,
     save_state = prepare_dc(graphics, pen);
     SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
 
-    transform_and_round_points(graphics, pti, ptf, 4);
+    transform_and_round_points(graphics, pti, ptf, 4, NULL);
     Polygon(graphics->hdc, pti, 4);
 
     restore_dc(graphics, save_state);
@@ -3784,7 +3795,7 @@ GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen,
     save_state = prepare_dc(graphics, pen);
     SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
 
-    transform_and_round_points(graphics, pti, ptf, 4 * count);
+    transform_and_round_points(graphics, pti, ptf, 4 * count, NULL);
 
     for(i = 0; i < count; i++)
         Polygon(graphics->hdc, &pti[4 * i], 4);
@@ -5047,7 +5058,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
         if (scaled_rect.Width < 0.5) return Ok; /* doesn't fit */
     }
 
-    get_font_hfont(graphics, font, stringFormat, &gdifont);
+    get_font_hfont(graphics, font, stringFormat, &gdifont, NULL);
     oldfont = SelectObject(hdc, gdifont);
 
     for (i=0; i<stringFormat->range_count; i++)
@@ -5177,7 +5188,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
     if (scaled_rect.Width >= 1 << 23 || scaled_rect.Width < 0.5) scaled_rect.Width = 1 << 23;
     if (scaled_rect.Height >= 1 << 23 || scaled_rect.Height < 0.5) scaled_rect.Height = 1 << 23;
 
-    get_font_hfont(graphics, font, format, &gdifont);
+    get_font_hfont(graphics, font, format, &gdifont, NULL);
     oldfont = SelectObject(hdc, gdifont);
 
     bounds->X = rect->X;
@@ -5332,7 +5343,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
     rectcpy[1].Y = rectcpy[0].Y = rect->Y;
     rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
     rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
-    transform_and_round_points(graphics, corners, rectcpy, 4);
+    transform_and_round_points(graphics, corners, rectcpy, 4, NULL);
 
     margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0;
     margin_x *= units_scale(font->unit, graphics->unit, graphics->xres);
@@ -5364,7 +5375,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
         SelectClipRgn(hdc, rgn);
     }
 
-    get_font_hfont(graphics, font, format, &gdifont);
+    get_font_hfont(graphics, font, format, &gdifont, NULL);
     SelectObject(hdc, gdifont);
 
     args.graphics = graphics;
@@ -5884,7 +5895,7 @@ GpStatus WINGDIPAPI GdipDrawPolygon(GpGraphics *graphics,GpPen *pen,GDIPCONST Gp
     save_state = prepare_dc(graphics, pen);
     SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
 
-    transform_and_round_points(graphics, pti, (GpPointF*)points, count);
+    transform_and_round_points(graphics, pti, (GpPointF*)points, count, NULL);
     Polygon(graphics->hdc, pti, count);
 
     restore_dc(graphics, save_state);
@@ -6320,10 +6331,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
     if (flags & unsupported_flags)
         FIXME("Ignoring flags %x\n", flags & unsupported_flags);
 
-    if (matrix)
-        FIXME("Ignoring matrix\n");
-
-    get_font_hfont(graphics, font, NULL, &hfont);
+    get_font_hfont(graphics, font, NULL, &hfont, matrix);
 
     hdc = CreateCompatibleDC(0);
     SelectObject(hdc, hfont);
@@ -6337,6 +6345,11 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
     pt[2].X = 0.0;
     pt[2].Y = 1.0;
     GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
+    if (matrix)
+    {
+        GpMatrix xform = *matrix;
+        GdipTransformMatrixPoints(&xform, pt, 3);
+    }
     rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
                      (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
     rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
@@ -6412,9 +6425,6 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
     if (flags & unsupported_flags)
         FIXME("Ignoring flags %x\n", flags & unsupported_flags);
 
-    if (matrix)
-        FIXME("Ignoring matrix\n");
-
     if (!(flags & DriverStringOptionsCmapLookup))
         eto_flags |= ETO_GLYPH_INDEX;
 
@@ -6425,7 +6435,7 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
     pt = positions[0];
     GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1);
 
-    get_font_hfont(graphics, font, format, &hfont);
+    get_font_hfont(graphics, font, format, &hfont, matrix);
     SelectObject(graphics->hdc, hfont);
 
     SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT);
@@ -6471,9 +6481,6 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
     if (flags & unsupported_flags)
         FIXME("Ignoring flags %x\n", flags & unsupported_flags);
 
-    if (matrix)
-        FIXME("Ignoring matrix\n");
-
     pti = GdipAlloc(sizeof(POINT) * length);
     if (!pti)
         return OutOfMemory;
@@ -6482,7 +6489,7 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
     {
         real_position = positions[0];
 
-        transform_and_round_points(graphics, pti, &real_position, 1);
+        transform_and_round_points(graphics, pti, &real_position, 1, matrix);
     }
     else
     {
@@ -6495,12 +6502,12 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
 
         memcpy(real_positions, positions, sizeof(PointF) * length);
 
-        transform_and_round_points(graphics, pti, real_positions, length);
+        transform_and_round_points(graphics, pti, real_positions, length, matrix);
 
         GdipFree(real_positions);
     }
 
-    get_font_hfont(graphics, font, format, &hfont);
+    get_font_hfont(graphics, font, format, &hfont, matrix);
 
     hdc = CreateCompatibleDC(0);
     SelectObject(hdc, hfont);
-- 
1.7.12.4




More information about the wine-patches mailing list