[2/2] gdiplus: Add support for generic typographic string format.
Dmitry Timoshkov
dmitry at baikal.ru
Mon Sep 3 03:57:17 CDT 2012
Application in the bug 31601 depends on this.
---
dlls/gdiplus/gdiplus_private.h | 1 +
dlls/gdiplus/graphics.c | 89 ++++++++++++++++++++++++------------------
dlls/gdiplus/stringformat.c | 4 ++
3 files changed, 56 insertions(+), 38 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 9c0e722..d44c969 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 96e2533..e986c94 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; i<stringFormat->range_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,6 +6585,28 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
return stat;
}
+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;
+
+ if (length == -1)
+ length = strlenW(text);
+
+ if (graphics->hdc &&
+ ((flags & DriverStringOptionsRealizedAdvance) || length <= 1) &&
+ brush->bt == BrushTypeSolidColor &&
+ (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000)
+ stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format,
+ brush, positions, flags, matrix);
+ if (stat == NotImplemented)
+ stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, format,
+ brush, positions, flags, matrix);
+ return stat;
+}
+
/*****************************************************************************
* GdipDrawDriverString [GDIPLUS.@]
*/
@@ -6587,28 +6615,13 @@ GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16
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;
- if (length == -1)
- length = strlenW(text);
-
- if (graphics->hdc &&
- ((flags & DriverStringOptionsRealizedAdvance) || length <= 1) &&
- brush->bt == BrushTypeSolidColor &&
- (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000)
- stat = GDI32_GdipDrawDriverString(graphics, text, length, font, brush,
- positions, flags, matrix);
-
- if (stat == NotImplemented)
- stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, brush,
- positions, flags, matrix);
-
- return stat;
+ 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,
diff --git a/dlls/gdiplus/stringformat.c b/dlls/gdiplus/stringformat.c
index cf6ea1f..7d6bcb0 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;
}
--
1.7.11.5
More information about the wine-patches
mailing list