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;
|
REAL *tabs;
|
||||||
CharacterRange *character_ranges;
|
CharacterRange *character_ranges;
|
||||||
INT range_count;
|
INT range_count;
|
||||||
|
BOOL generic_typographic;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpFontCollection{
|
struct GpFontCollection{
|
||||||
|
|
|
@ -46,6 +46,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
|
||||||
#define ANCHOR_WIDTH (2.0)
|
#define ANCHOR_WIDTH (2.0)
|
||||||
#define MAX_ITERS (50)
|
#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 */
|
/* Converts angle (in degrees) to x/y coordinates */
|
||||||
static void deg2xy(REAL angle, REAL x_0, REAL y_0, REAL *x, REAL *y)
|
static void deg2xy(REAL angle, REAL x_0, REAL y_0, REAL *x, REAL *y)
|
||||||
{
|
{
|
||||||
|
@ -2110,7 +2115,8 @@ end:
|
||||||
return stat;
|
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);
|
HDC hdc = CreateCompatibleDC(0);
|
||||||
GpPointF pt[3];
|
GpPointF pt[3];
|
||||||
|
@ -2119,7 +2125,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *
|
||||||
HFONT unscaled_font;
|
HFONT unscaled_font;
|
||||||
TEXTMETRICW textmet;
|
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)
|
if (font->unit == UnitPixel)
|
||||||
font_height = font->emSize * font_to_pixel_scale;
|
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)+
|
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));
|
(pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
|
||||||
|
|
||||||
/* FIXME: GenericTypographic format prevents extra margins */
|
margin_x = stringFormat->generic_typographic ? 0.0 : font->emSize / 6.0;
|
||||||
margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * 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.X = (layoutRect->X + margin_x) * args.rel_width;
|
||||||
scaled_rect.Y = layoutRect->Y * args.rel_height;
|
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 */
|
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);
|
oldfont = SelectObject(hdc, gdifont);
|
||||||
|
|
||||||
for (i=0; i<stringFormat->range_count; i++)
|
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)+
|
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));
|
(pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
|
||||||
|
|
||||||
/* FIXME: GenericTypographic format prevents extra margins */
|
margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0;
|
||||||
margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * 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.X = (rect->X + margin_x) * args.rel_width;
|
||||||
scaled_rect.Y = rect->Y * args.rel_height;
|
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.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);
|
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);
|
oldfont = SelectObject(hdc, gdifont);
|
||||||
|
|
||||||
bounds->X = rect->X;
|
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.X = args->x + bounds->X / args->rel_width;
|
||||||
position.Y = args->y + bounds->Y / args->rel_height + args->ascent;
|
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,
|
args->brush, &position,
|
||||||
DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL);
|
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;
|
rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
|
||||||
transform_and_round_points(graphics, corners, rectcpy, 4);
|
transform_and_round_points(graphics, corners, rectcpy, 4);
|
||||||
|
|
||||||
/* FIXME: GenericTypographic format prevents extra margins */
|
margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0;
|
||||||
margin_x = units_scale(font->unit, graphics->unit, graphics->xres) * font->emSize / 6.0;
|
margin_x *= units_scale(font->unit, graphics->unit, graphics->xres);
|
||||||
|
|
||||||
scaled_rect.X = margin_x * rel_width;
|
scaled_rect.X = margin_x * rel_width;
|
||||||
scaled_rect.Y = 0.0;
|
scaled_rect.Y = 0.0;
|
||||||
|
@ -5310,7 +5316,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
||||||
SelectClipRgn(hdc, rgn);
|
SelectClipRgn(hdc, rgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_font_hfont(graphics, font, &gdifont);
|
get_font_hfont(graphics, font, format, &gdifont);
|
||||||
SelectObject(hdc, gdifont);
|
SelectObject(hdc, gdifont);
|
||||||
|
|
||||||
args.graphics = graphics;
|
args.graphics = graphics;
|
||||||
|
@ -6269,7 +6275,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
|
||||||
if (matrix)
|
if (matrix)
|
||||||
FIXME("Ignoring matrix\n");
|
FIXME("Ignoring matrix\n");
|
||||||
|
|
||||||
get_font_hfont(graphics, font, &hfont);
|
get_font_hfont(graphics, font, NULL, &hfont);
|
||||||
|
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
SelectObject(hdc, hfont);
|
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,
|
static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
|
||||||
GDIPCONST GpFont *font, GDIPCONST GpBrush *brush,
|
GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format,
|
||||||
GDIPCONST PointF *positions, INT flags,
|
GDIPCONST GpBrush *brush, GDIPCONST PointF *positions,
|
||||||
GDIPCONST GpMatrix *matrix )
|
INT flags, GDIPCONST GpMatrix *matrix)
|
||||||
{
|
{
|
||||||
static const INT unsupported_flags = ~(DriverStringOptionsRealizedAdvance|DriverStringOptionsCmapLookup);
|
static const INT unsupported_flags = ~(DriverStringOptionsRealizedAdvance|DriverStringOptionsCmapLookup);
|
||||||
INT save_state;
|
INT save_state;
|
||||||
|
@ -6371,7 +6377,7 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
|
||||||
pt = positions[0];
|
pt = positions[0];
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1);
|
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1);
|
||||||
|
|
||||||
get_font_hfont(graphics, font, &hfont);
|
get_font_hfont(graphics, font, format, &hfont);
|
||||||
SelectObject(graphics->hdc, hfont);
|
SelectObject(graphics->hdc, hfont);
|
||||||
|
|
||||||
SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT);
|
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,
|
static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
|
||||||
GDIPCONST GpFont *font, GDIPCONST GpBrush *brush,
|
GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format,
|
||||||
GDIPCONST PointF *positions, INT flags,
|
GDIPCONST GpBrush *brush, GDIPCONST PointF *positions,
|
||||||
GDIPCONST GpMatrix *matrix )
|
INT flags, GDIPCONST GpMatrix *matrix)
|
||||||
{
|
{
|
||||||
static const INT unsupported_flags = ~(DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance);
|
static const INT unsupported_flags = ~(DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance);
|
||||||
GpStatus stat;
|
GpStatus stat;
|
||||||
|
@ -6446,7 +6452,7 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
||||||
GdipFree(real_positions);
|
GdipFree(real_positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_font_hfont(graphics, font, &hfont);
|
get_font_hfont(graphics, font, format, &hfont);
|
||||||
|
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
SelectObject(hdc, hfont);
|
SelectObject(hdc, hfont);
|
||||||
|
@ -6579,21 +6585,13 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
|
||||||
* GdipDrawDriverString [GDIPLUS.@]
|
GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format,
|
||||||
*/
|
GDIPCONST GpBrush *brush, GDIPCONST PointF *positions,
|
||||||
GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
|
INT flags, GDIPCONST GpMatrix *matrix)
|
||||||
GDIPCONST GpFont *font, GDIPCONST GpBrush *brush,
|
|
||||||
GDIPCONST PointF *positions, INT flags,
|
|
||||||
GDIPCONST GpMatrix *matrix )
|
|
||||||
{
|
{
|
||||||
GpStatus stat = NotImplemented;
|
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)
|
if (length == -1)
|
||||||
length = strlenW(text);
|
length = strlenW(text);
|
||||||
|
|
||||||
|
@ -6601,16 +6599,31 @@ GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16
|
||||||
((flags & DriverStringOptionsRealizedAdvance) || length <= 1) &&
|
((flags & DriverStringOptionsRealizedAdvance) || length <= 1) &&
|
||||||
brush->bt == BrushTypeSolidColor &&
|
brush->bt == BrushTypeSolidColor &&
|
||||||
(((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000)
|
(((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000)
|
||||||
stat = GDI32_GdipDrawDriverString(graphics, text, length, font, brush,
|
stat = GDI32_GdipDrawDriverString(graphics, text, length, font, format,
|
||||||
positions, flags, matrix);
|
brush, positions, flags, matrix);
|
||||||
|
|
||||||
if (stat == NotImplemented)
|
if (stat == NotImplemented)
|
||||||
stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, brush,
|
stat = SOFTWARE_GdipDrawDriverString(graphics, text, length, font, format,
|
||||||
positions, flags, matrix);
|
brush, positions, flags, matrix);
|
||||||
|
|
||||||
return stat;
|
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,
|
GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRect *frameRect,
|
||||||
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
|
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
|
||||||
(*format)->digitsub = StringDigitSubstituteUser;
|
(*format)->digitsub = StringDigitSubstituteUser;
|
||||||
(*format)->character_ranges = NULL;
|
(*format)->character_ranges = NULL;
|
||||||
(*format)->range_count = 0;
|
(*format)->range_count = 0;
|
||||||
|
(*format)->generic_typographic = FALSE;
|
||||||
/* tabstops */
|
/* tabstops */
|
||||||
(*format)->tabcount = 0;
|
(*format)->tabcount = 0;
|
||||||
(*format)->firsttab = 0.0;
|
(*format)->firsttab = 0.0;
|
||||||
|
@ -386,6 +387,9 @@ GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **forma
|
||||||
(*format)->hkprefix = HotkeyPrefixNone;
|
(*format)->hkprefix = HotkeyPrefixNone;
|
||||||
(*format)->align = StringAlignmentNear;
|
(*format)->align = StringAlignmentNear;
|
||||||
(*format)->vertalign = StringAlignmentNear;
|
(*format)->vertalign = StringAlignmentNear;
|
||||||
|
(*format)->generic_typographic = TRUE;
|
||||||
|
|
||||||
|
TRACE("%p => %p\n", format, *format);
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue