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

This commit is contained in:
Vincent Povirk 2012-06-21 15:31:27 -05:00 committed by Alexandre Julliard
parent a8643ccc85
commit cae52d078a
1 changed files with 31 additions and 15 deletions

View File

@ -840,7 +840,8 @@ static float fromfixedpoint(const FIXED v)
struct format_string_args struct format_string_args
{ {
GpPath *path; GpPath *path;
UINT maxY; float maxY;
float scale;
}; };
static GpStatus format_string_callback(HDC dc, static GpStatus format_string_callback(HDC dc,
@ -853,8 +854,8 @@ static GpStatus format_string_callback(HDC dc,
struct format_string_args *args = priv; struct format_string_args *args = priv;
GpPath *path = args->path; GpPath *path = args->path;
GpStatus status = Ok; GpStatus status = Ok;
float x = bounds->X; float x = rect->X + (bounds->X - rect->X) * args->scale;
float y = bounds->Y; float y = rect->Y + (bounds->Y - rect->Y) * args->scale;
int i; int i;
if (underlined_index_count) if (underlined_index_count)
@ -866,7 +867,7 @@ static GpStatus format_string_callback(HDC dc,
TTPOLYGONHEADER *ph = NULL; TTPOLYGONHEADER *ph = NULL;
char *start; char *start;
DWORD len, ofs = 0; DWORD len, ofs = 0;
UINT bb_end; float bb_end;
len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity); len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
if (len == GDI_ERROR) if (len == GDI_ERROR)
{ {
@ -881,7 +882,7 @@ static GpStatus format_string_callback(HDC dc,
break; break;
} }
GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, len, start, &identity); 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) if (bb_end + y > args->maxY)
args->maxY = bb_end + y; args->maxY = bb_end + y;
@ -891,8 +892,8 @@ static GpStatus format_string_callback(HDC dc,
DWORD ofs_start = ofs; DWORD ofs_start = ofs;
ph = (TTPOLYGONHEADER*)&start[ofs]; ph = (TTPOLYGONHEADER*)&start[ofs];
path->pathdata.Types[path->pathdata.Count] = PathPointTypeStart; 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].X = x + fromfixedpoint(ph->pfxStart.x) * args->scale;
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(ph->pfxStart.y); 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); TRACE("Starting at count %i with pos %f, %f)\n", path->pathdata.Count, x, y);
ofs += sizeof(*ph); ofs += sizeof(*ph);
while (ofs - ofs_start < ph->cb) while (ofs - ofs_start < ph->cb)
@ -907,16 +908,16 @@ static GpStatus format_string_callback(HDC dc,
for (j = 0; j < curve->cpfx; ++j) for (j = 0; j < curve->cpfx; ++j)
{ {
path->pathdata.Types[path->pathdata.Count] = PathPointTypeLine; 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].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y); path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y) * args->scale;
} }
break; break;
case TT_PRIM_CSPLINE: case TT_PRIM_CSPLINE:
for (j = 0; j < curve->cpfx; ++j) for (j = 0; j < curve->cpfx; ++j)
{ {
path->pathdata.Types[path->pathdata.Count] = PathPointTypeBezier; 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].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y); path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y) * args->scale;
} }
break; break;
default: default:
@ -927,8 +928,8 @@ static GpStatus format_string_callback(HDC dc,
path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath; path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
} }
path->newfigure = TRUE; path->newfigure = TRUE;
x += gm.gmCellIncX; x += gm.gmCellIncX * args->scale;
y += gm.gmCellIncY; y += gm.gmCellIncY * args->scale;
GdipFree(ph); GdipFree(ph);
if (status != Ok) if (status != Ok)
@ -948,12 +949,24 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
GpPath *backup; GpPath *backup;
struct format_string_args args; struct format_string_args args;
int i; 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); 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) if (!path || !string || !family || !emSize || !layoutRect || !format)
return InvalidParameter; 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) if (status != Ok)
return status; return status;
@ -974,9 +987,12 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
dc = CreateCompatibleDC(0); dc = CreateCompatibleDC(0);
SelectObject(dc, hfont); SelectObject(dc, hfont);
GetTextMetricsW(dc, &textmetric);
args.path = path; args.path = path;
args.maxY = 0; 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); DeleteDC(dc);
DeleteObject(hfont); DeleteObject(hfont);