gdiplus: Add support for generic typographic string format.
This commit is contained in:
parent
bfa35f37a7
commit
b8f4252290
|
@ -368,6 +368,7 @@ struct GpStringFormat{
|
|||
REAL *tabs;
|
||||
CharacterRange *character_ranges;
|
||||
INT range_count;
|
||||
BOOL generic_typographic;
|
||||
};
|
||||
|
||||
struct GpFontCollection{
|
||||
|
|
|
@ -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,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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue