[PATCH 4/5] dwrite/layout: Improve overhangs metrics computation.

Nikolay Sivov nsivov at codeweavers.com
Fri Jan 25 05:56:40 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  9 ++++---
 dlls/dwrite/font.c           |  4 +--
 dlls/dwrite/freetype.c       |  4 +--
 dlls/dwrite/layout.c         | 51 +++++++++++++++++++++---------------
 4 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index b8fb25026f..6ee59cfd02 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 c657eeb205..b10096de20 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 ffdd8a8f1e..d3036537f0 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 a5629270e1..f27fe9fbec 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 = &regular->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);
+            /* FIXME: take care of vertical/rtl */
+            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);
 
-            /* 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];
        }
     }
 
-- 
2.20.1




More information about the wine-devel mailing list