[2/3] gdiplus: Add support for extra transformation in GdipMeasureDriverString and GdipDrawDriverString. Resend.
Dmitry Timoshkov
dmitry at baikal.ru
Fri Nov 2 05:17:41 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 b3eaa86d..23edda8 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));
@@ -2960,7 +2971,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);
@@ -3105,7 +3116,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]));
@@ -3733,7 +3744,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);
@@ -3789,7 +3800,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);
@@ -5052,7 +5063,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++)
@@ -5182,7 +5193,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;
@@ -5337,7 +5348,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);
@@ -5369,7 +5380,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;
@@ -5889,7 +5900,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);
@@ -6325,10 +6336,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);
@@ -6342,6 +6350,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)+
@@ -6417,9 +6430,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;
@@ -6430,7 +6440,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);
@@ -6476,9 +6486,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;
@@ -6487,7 +6494,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
{
@@ -6500,12 +6507,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