Vincent Povirk : gdiplus: Use DrawDriverString to draw the text in DrawString.
Alexandre Julliard
julliard at winehq.org
Tue Jun 28 17:25:19 CDT 2011
Module: wine
Branch: master
Commit: d59c3d45e34817e08e68305d3e5f632e3c8523a3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d59c3d45e34817e08e68305d3e5f632e3c8523a3
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Jun 27 14:40:59 2011 -0500
gdiplus: Use DrawDriverString to draw the text in DrawString.
---
dlls/gdiplus/graphics.c | 77 +++++++++++++++++++---------------------------
1 files changed, 32 insertions(+), 45 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index d756c0b..be25653 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -4608,9 +4608,9 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
}
struct draw_string_args {
- POINT drawbase;
- UINT drawflags;
- REAL ang_cos, ang_sin;
+ GpGraphics *graphics;
+ GDIPCONST GpBrush *brush;
+ REAL x, y, rel_width, rel_height, ascent;
};
static GpStatus draw_string_callback(HDC hdc,
@@ -4619,14 +4619,14 @@ static GpStatus draw_string_callback(HDC hdc,
INT lineno, const RectF *bounds, void *user_data)
{
struct draw_string_args *args = user_data;
- RECT drawcoord;
+ PointF position;
- drawcoord.left = drawcoord.right = args->drawbase.x + roundr(args->ang_sin * bounds->Y);
- drawcoord.top = drawcoord.bottom = args->drawbase.y + roundr(args->ang_cos * bounds->Y);
+ position.X = args->x + bounds->X / args->rel_width;
+ position.Y = args->y + bounds->Y / args->rel_height + args->ascent;
- DrawTextW(hdc, string + index, length, &drawcoord, args->drawflags);
-
- return Ok;
+ return GdipDrawDriverString(args->graphics, &string[index], length, font,
+ args->brush, &position,
+ DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL);
}
GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string,
@@ -4637,10 +4637,12 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
HFONT gdifont;
GpPointF pt[3], rectcpy[4];
POINT corners[4];
- REAL angle, rel_width, rel_height;
+ REAL rel_width, rel_height;
INT offsety = 0, save_state;
struct draw_string_args args;
RectF scaled_rect;
+ HDC hdc, temp_hdc=NULL;
+ TEXTMETRICW textmetric;
TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length),
length, font, debugstr_rectf(rect), format, brush);
@@ -4648,15 +4650,13 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
if(!graphics || !string || !font || !brush || !rect)
return InvalidParameter;
- if((brush->bt != BrushTypeSolidColor)){
- FIXME("not implemented for given parameters\n");
- return NotImplemented;
+ if(graphics->hdc)
+ {
+ hdc = graphics->hdc;
}
-
- if(!graphics->hdc)
+ else
{
- FIXME("graphics object has no HDC\n");
- return Ok;
+ hdc = temp_hdc = CreateCompatibleDC(0);
}
if(format){
@@ -4675,9 +4675,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
}
}
- save_state = SaveDC(graphics->hdc);
- SetBkMode(graphics->hdc, TRANSPARENT);
- SetTextColor(graphics->hdc, brush->lb.lbColor);
+ save_state = SaveDC(hdc);
pt[0].X = 0.0;
pt[0].Y = 0.0;
@@ -4686,9 +4684,6 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
pt[2].X = 0.0;
pt[2].Y = 1.0;
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
- angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
- args.ang_cos = cos(angle);
- args.ang_sin = sin(angle);
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)+
@@ -4709,38 +4704,30 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
{
/* FIXME: If only the width or only the height is 0, we should probably still clip */
rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
- SelectClipRgn(graphics->hdc, rgn);
+ SelectClipRgn(hdc, rgn);
}
get_font_hfont(graphics, font, &gdifont);
- SelectObject(graphics->hdc, gdifont);
+ SelectObject(hdc, gdifont);
- if (!format || format->align == StringAlignmentNear)
- {
- args.drawbase.x = corners[0].x;
- args.drawbase.y = corners[0].y;
- args.drawflags = DT_NOCLIP | DT_EXPANDTABS;
- }
- else if (format->align == StringAlignmentCenter)
- {
- args.drawbase.x = (corners[0].x + corners[1].x)/2;
- args.drawbase.y = (corners[0].y + corners[1].y)/2;
- args.drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_CENTER;
- }
- else /* (format->align == StringAlignmentFar) */
- {
- args.drawbase.x = corners[1].x;
- args.drawbase.y = corners[1].y;
- args.drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_RIGHT;
- }
+ args.graphics = graphics;
+ args.brush = brush;
- gdip_format_string(graphics->hdc, string, length, font, &scaled_rect, format,
+ args.rel_width = rel_width;
+ args.rel_height = rel_height;
+
+ GetTextMetricsW(hdc, &textmetric);
+ args.ascent = textmetric.tmAscent / rel_height;
+
+ gdip_format_string(hdc, string, length, font, &scaled_rect, format,
draw_string_callback, &args);
DeleteObject(rgn);
DeleteObject(gdifont);
- RestoreDC(graphics->hdc, save_state);
+ RestoreDC(hdc, save_state);
+
+ DeleteDC(temp_hdc);
return Ok;
}
More information about the wine-cvs
mailing list