From b8f42522905272b11328f79457447d6b3185a3b1 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Mon, 3 Sep 2012 17:57:17 +0900 Subject: [PATCH] gdiplus: Add support for generic typographic string format. --- dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/graphics.c | 93 +++++++++++++++++++--------------- dlls/gdiplus/stringformat.c | 4 ++ 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 9c0e722ff55..d44c9699288 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -368,6 +368,7 @@ struct GpStringFormat{ REAL *tabs; CharacterRange *character_ranges; INT range_count; + BOOL generic_typographic; }; struct GpFontCollection{ diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 96e25338bef..e986c9420f0 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -46,6 +46,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); #define ANCHOR_WIDTH (2.0) #define MAX_ITERS (50) +static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, + GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, + INT flags, GDIPCONST GpMatrix *matrix); + /* Converts angle (in degrees) to x/y coordinates */ static void deg2xy(REAL angle, REAL x_0, REAL y_0, REAL *x, REAL *y) { @@ -2110,7 +2115,8 @@ end: return stat; } -static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *hfont) +static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, + GDIPCONST GpStringFormat *format, HFONT *hfont) { HDC hdc = CreateCompatibleDC(0); GpPointF pt[3]; @@ -2119,7 +2125,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT * HFONT unscaled_font; TEXTMETRICW textmet; - font_to_pixel_scale = units_scale(UnitPoint, UnitPixel, font->family->dpi); + font_to_pixel_scale = (format && format->generic_typographic) ? 1.0 : units_scale(UnitPoint, UnitPixel, font->family->dpi); if (font->unit == UnitPixel) font_height = font->emSize * font_to_pixel_scale; @@ -4972,8 +4978,8 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X)); - /* FIXME: GenericTypographic format prevents extra margins */ - margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * font->emSize / 6.0; + margin_x = stringFormat->generic_typographic ? 0.0 : font->emSize / 6.0; + margin_x *= units_scale(font->unit, graphics->unit, graphics->xres); scaled_rect.X = (layoutRect->X + margin_x) * args.rel_width; scaled_rect.Y = layoutRect->Y * args.rel_height; @@ -4993,7 +4999,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, if (scaled_rect.Width < 0.5) return Ok; /* doesn't fit */ } - get_font_hfont(graphics, font, &gdifont); + get_font_hfont(graphics, font, stringFormat, &gdifont); oldfont = SelectObject(hdc, gdifont); for (i=0; irange_count; i++) @@ -5101,8 +5107,8 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X)); - /* FIXME: GenericTypographic format prevents extra margins */ - margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * font->emSize / 6.0; + margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0; + margin_x *= units_scale(font->unit, graphics->unit, graphics->xres); scaled_rect.X = (rect->X + margin_x) * args.rel_width; scaled_rect.Y = rect->Y * args.rel_height; @@ -5123,7 +5129,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, if (scaled_rect.Width >= INT_MAX || scaled_rect.Width < 0.5) scaled_rect.Width = (REAL)(1 << 23); if (scaled_rect.Height >= INT_MAX || scaled_rect.Height < 0.5) scaled_rect.Height = (REAL)(1 << 23); - get_font_hfont(graphics, font, &gdifont); + get_font_hfont(graphics, font, format, &gdifont); oldfont = SelectObject(hdc, gdifont); bounds->X = rect->X; @@ -5173,7 +5179,7 @@ static GpStatus draw_string_callback(HDC hdc, position.X = args->x + bounds->X / args->rel_width; position.Y = args->y + bounds->Y / args->rel_height + args->ascent; - stat = GdipDrawDriverString(args->graphics, &string[index], length, font, + stat = draw_driver_string(args->graphics, &string[index], length, font, format, args->brush, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL); @@ -5280,8 +5286,8 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height; transform_and_round_points(graphics, corners, rectcpy, 4); - /* FIXME: GenericTypographic format prevents extra margins */ - margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * font->emSize / 6.0; + margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0; + margin_x *= units_scale(font->unit, graphics->unit, graphics->xres); scaled_rect.X = margin_x * rel_width; scaled_rect.Y = 0.0; @@ -5310,7 +5316,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string SelectClipRgn(hdc, rgn); } - get_font_hfont(graphics, font, &gdifont); + get_font_hfont(graphics, font, format, &gdifont); SelectObject(hdc, gdifont); args.graphics = graphics; @@ -6269,7 +6275,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT if (matrix) FIXME("Ignoring matrix\n"); - get_font_hfont(graphics, font, &hfont); + get_font_hfont(graphics, font, NULL, &hfont); hdc = CreateCompatibleDC(0); SelectObject(hdc, hfont); @@ -6345,9 +6351,9 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT } static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, - GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, - GDIPCONST PointF *positions, INT flags, - GDIPCONST GpMatrix *matrix ) + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, + GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, + INT flags, GDIPCONST GpMatrix *matrix) { static const INT unsupported_flags = ~(DriverStringOptionsRealizedAdvance|DriverStringOptionsCmapLookup); INT save_state; @@ -6371,7 +6377,7 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1 pt = positions[0]; GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1); - get_font_hfont(graphics, font, &hfont); + get_font_hfont(graphics, font, format, &hfont); SelectObject(graphics->hdc, hfont); SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT); @@ -6386,9 +6392,9 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1 } static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, - GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, - GDIPCONST PointF *positions, INT flags, - GDIPCONST GpMatrix *matrix ) + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, + GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, + INT flags, GDIPCONST GpMatrix *matrix) { static const INT unsupported_flags = ~(DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance); GpStatus stat; @@ -6446,7 +6452,7 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI GdipFree(real_positions); } - get_font_hfont(graphics, font, &hfont); + get_font_hfont(graphics, font, format, &hfont); hdc = CreateCompatibleDC(0); SelectObject(hdc, hfont); @@ -6579,20 +6585,12 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI return stat; } -/***************************************************************************** - * GdipDrawDriverString [GDIPLUS.@] - */ -GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, - GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, - GDIPCONST PointF *positions, INT flags, - GDIPCONST GpMatrix *matrix ) +static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, + GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, + GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, + INT flags, GDIPCONST GpMatrix *matrix) { - GpStatus stat=NotImplemented; - - TRACE("(%p %s %p %p %p %d %p)\n", graphics, debugstr_wn(text, length), font, brush, positions, flags, matrix); - - if (!graphics || !text || !font || !brush || !positions) - return InvalidParameter; + GpStatus stat = NotImplemented; if (length == -1) length = strlenW(text); @@ -6601,16 +6599,31 @@ GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 ((flags & DriverStringOptionsRealizedAdvance) || length <= 1) && brush->bt == BrushTypeSolidColor && (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000) - stat = GDI32_GdipDrawDriverString(graphics, text, length, font, brush, - positions, flags, matrix); - + stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format, + brush, positions, flags, matrix); if (stat == NotImplemented) - stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, brush, - positions, flags, matrix); - + stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, format, + brush, positions, flags, matrix); return stat; } +/***************************************************************************** + * GdipDrawDriverString [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, + GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, + GDIPCONST PointF *positions, INT flags, + GDIPCONST GpMatrix *matrix ) +{ + TRACE("(%p %s %p %p %p %d %p)\n", graphics, debugstr_wn(text, length), font, brush, positions, flags, matrix); + + if (!graphics || !text || !font || !brush || !positions) + return InvalidParameter; + + return draw_driver_string(graphics, text, length, font, NULL, + brush, positions, flags, matrix); +} + GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRect *frameRect, MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile) { diff --git a/dlls/gdiplus/stringformat.c b/dlls/gdiplus/stringformat.c index cf6ea1f392a..7d6bcb0e3fb 100644 --- a/dlls/gdiplus/stringformat.c +++ b/dlls/gdiplus/stringformat.c @@ -50,6 +50,7 @@ GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang, (*format)->digitsub = StringDigitSubstituteUser; (*format)->character_ranges = NULL; (*format)->range_count = 0; + (*format)->generic_typographic = FALSE; /* tabstops */ (*format)->tabcount = 0; (*format)->firsttab = 0.0; @@ -386,6 +387,9 @@ GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **forma (*format)->hkprefix = HotkeyPrefixNone; (*format)->align = StringAlignmentNear; (*format)->vertalign = StringAlignmentNear; + (*format)->generic_typographic = TRUE; + + TRACE("%p => %p\n", format, *format); return Ok; }