diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index b8fb25026fe..6ee59cfd024 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -252,13 +252,14 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLS extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN; /* FreeType integration */ -struct dwrite_glyphbitmap { +struct dwrite_glyphbitmap +{ IDWriteFontFace4 *fontface; DWORD simulations; - FLOAT emsize; + float emsize; BOOL nohint; BOOL aliased; - UINT16 index; + UINT16 glyph; INT pitch; RECT bbox; BYTE *buf; @@ -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 BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) 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 INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN; extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c657eeb2055..b10096de203 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5060,7 +5060,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a RECT *bbox = &glyph_bitmap.bbox; UINT32 bitmap_size; - glyph_bitmap.index = analysis->run.glyphIndices[i]; + glyph_bitmap.glyph = analysis->run.glyphIndices[i]; freetype_get_glyph_bbox(&glyph_bitmap); 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) int x, y, width, height; BOOL is_1bpp; - glyph_bitmap.index = analysis->run.glyphIndices[i]; + glyph_bitmap.glyph = analysis->run.glyphIndices[i]; freetype_get_glyph_bbox(&glyph_bitmap); if (IsRectEmpty(bbox)) diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index ffdd8a8f1e8..d3036537f0d 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -686,7 +686,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) imagetype.height = bitmap->emsize; 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) { FT_Glyph glyph_copy; @@ -844,7 +844,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) imagetype.height = bitmap->emsize; 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; if (needs_transform) { diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index a5629270e13..f27fe9fbecc 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -3604,16 +3604,6 @@ static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWR 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) { rect->left += x; @@ -3652,27 +3642,46 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout const struct regular_layout_run *regular = &run->run->u.regular; UINT32 start_glyph = regular->clustermap[run->start]; const DWRITE_GLYPH_RUN *glyph_run = ®ular->run; - DWRITE_FONT_METRICS font_metrics; D2D1_POINT_2F origin = { 0 }; + float rtl_factor; UINT32 i; - if (run->bbox.top == run->bbox.bottom) { - IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics); + if (run->bbox.top == run->bbox.bottom) + { + 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++) { D2D1_RECT_F glyph_bbox; - RECT design_bbox; - - freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm, - glyph_run->glyphIndices[i + start_glyph], &design_bbox); - - 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); /* FIXME: take care of vertical/rtl */ - origin.x += glyph_run->glyphAdvances[i + start_glyph]; + 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); + + d2d_rect_union(&run->bbox, &glyph_bbox); + + if (!(glyph_run->bidiLevel & 1)) + origin.x += glyph_run->glyphAdvances[i + start_glyph]; } }