Commit d933afc4 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite/layout: Improve overhangs metrics computation.

parent 27aef423
...@@ -252,13 +252,14 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLS ...@@ -252,13 +252,14 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLS
extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN; extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN;
/* FreeType integration */ /* FreeType integration */
struct dwrite_glyphbitmap { struct dwrite_glyphbitmap
{
IDWriteFontFace4 *fontface; IDWriteFontFace4 *fontface;
DWORD simulations; DWORD simulations;
FLOAT emsize; float emsize;
BOOL nohint; BOOL nohint;
BOOL aliased; BOOL aliased;
UINT16 index; UINT16 glyph;
INT pitch; INT pitch;
RECT bbox; RECT bbox;
BYTE *buf; BYTE *buf;
...@@ -276,7 +277,7 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN; ...@@ -276,7 +277,7 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN; extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN;
extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN; extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN;
extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN; extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN; extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN;
......
...@@ -5060,7 +5060,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a ...@@ -5060,7 +5060,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
RECT *bbox = &glyph_bitmap.bbox; RECT *bbox = &glyph_bitmap.bbox;
UINT32 bitmap_size; UINT32 bitmap_size;
glyph_bitmap.index = analysis->run.glyphIndices[i]; glyph_bitmap.glyph = analysis->run.glyphIndices[i];
freetype_get_glyph_bbox(&glyph_bitmap); freetype_get_glyph_bbox(&glyph_bitmap);
bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) * bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) *
...@@ -5161,7 +5161,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) ...@@ -5161,7 +5161,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
int x, y, width, height; int x, y, width, height;
BOOL is_1bpp; BOOL is_1bpp;
glyph_bitmap.index = analysis->run.glyphIndices[i]; glyph_bitmap.glyph = analysis->run.glyphIndices[i];
freetype_get_glyph_bbox(&glyph_bitmap); freetype_get_glyph_bbox(&glyph_bitmap);
if (IsRectEmpty(bbox)) if (IsRectEmpty(bbox))
......
...@@ -686,7 +686,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) ...@@ -686,7 +686,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
imagetype.height = bitmap->emsize; imagetype.height = bitmap->emsize;
imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) { if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) {
if (needs_transform) { if (needs_transform) {
FT_Glyph glyph_copy; FT_Glyph glyph_copy;
...@@ -844,7 +844,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) ...@@ -844,7 +844,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
imagetype.height = bitmap->emsize; imagetype.height = bitmap->emsize;
imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) { if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) {
FT_Glyph glyph_copy; FT_Glyph glyph_copy;
if (needs_transform) { if (needs_transform) {
......
...@@ -3604,16 +3604,6 @@ static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWR ...@@ -3604,16 +3604,6 @@ static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWR
return hr; return hr;
} }
static void scale_glyph_bbox(RECT *bbox, FLOAT emSize, UINT16 units_per_em, D2D1_RECT_F *ret)
{
#define SCALE(x) ((FLOAT)x * emSize / (FLOAT)units_per_em)
ret->left = SCALE(bbox->left);
ret->right = SCALE(bbox->right);
ret->top = SCALE(bbox->top);
ret->bottom = SCALE(bbox->bottom);
#undef SCALE
}
static void d2d_rect_offset(D2D1_RECT_F *rect, FLOAT x, FLOAT y) static void d2d_rect_offset(D2D1_RECT_F *rect, FLOAT x, FLOAT y)
{ {
rect->left += x; rect->left += x;
...@@ -3652,26 +3642,45 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout ...@@ -3652,26 +3642,45 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout
const struct regular_layout_run *regular = &run->run->u.regular; const struct regular_layout_run *regular = &run->run->u.regular;
UINT32 start_glyph = regular->clustermap[run->start]; UINT32 start_glyph = regular->clustermap[run->start];
const DWRITE_GLYPH_RUN *glyph_run = &regular->run; const DWRITE_GLYPH_RUN *glyph_run = &regular->run;
DWRITE_FONT_METRICS font_metrics;
D2D1_POINT_2F origin = { 0 }; D2D1_POINT_2F origin = { 0 };
float rtl_factor;
UINT32 i; UINT32 i;
if (run->bbox.top == run->bbox.bottom) { if (run->bbox.top == run->bbox.bottom)
IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics); {
struct dwrite_glyphbitmap glyph_bitmap;
RECT *bbox;
memset(&glyph_bitmap, 0, sizeof(glyph_bitmap));
glyph_bitmap.fontface = (IDWriteFontFace4 *)glyph_run->fontFace;
glyph_bitmap.simulations = IDWriteFontFace_GetSimulations(glyph_run->fontFace);
glyph_bitmap.emsize = glyph_run->fontEmSize;
glyph_bitmap.nohint = layout->measuringmode == DWRITE_MEASURING_MODE_NATURAL;
bbox = &glyph_bitmap.bbox;
rtl_factor = glyph_run->bidiLevel & 1 ? -1.0f : 1.0f;
for (i = 0; i < run->glyphcount; i++) { for (i = 0; i < run->glyphcount; i++) {
D2D1_RECT_F glyph_bbox; D2D1_RECT_F glyph_bbox;
RECT design_bbox;
freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm, /* FIXME: take care of vertical/rtl */
glyph_run->glyphIndices[i + start_glyph], &design_bbox); if (glyph_run->bidiLevel & 1)
origin.x -= glyph_run->glyphAdvances[i + start_glyph];
glyph_bitmap.glyph = glyph_run->glyphIndices[i + start_glyph];
freetype_get_glyph_bbox(&glyph_bitmap);
glyph_bbox.left = bbox->left;
glyph_bbox.top = bbox->top;
glyph_bbox.right = bbox->right;
glyph_bbox.bottom = bbox->bottom;
d2d_rect_offset(&glyph_bbox, origin.x + rtl_factor * glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
origin.y - glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
scale_glyph_bbox(&design_bbox, glyph_run->fontEmSize, font_metrics.designUnitsPerEm, &glyph_bbox);
d2d_rect_offset(&glyph_bbox, origin.x + glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
origin.y + glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
d2d_rect_union(&run->bbox, &glyph_bbox); d2d_rect_union(&run->bbox, &glyph_bbox);
/* FIXME: take care of vertical/rtl */ if (!(glyph_run->bidiLevel & 1))
origin.x += glyph_run->glyphAdvances[i + start_glyph]; origin.x += glyph_run->glyphAdvances[i + start_glyph];
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment