Nikolay Sivov : dwrite: Update overhangs rectangle on alignment changes.

Alexandre Julliard julliard at winehq.org
Tue Apr 25 16:22:34 CDT 2017


Module: wine
Branch: master
Commit: ace830625d09dbb384cff19ff9723265357990a8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ace830625d09dbb384cff19ff9723265357990a8

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Apr 25 08:54:43 2017 +0300

dwrite: Update overhangs rectangle on alignment changes.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/layout.c | 51 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index c988c75..ab68ecf 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -188,6 +188,7 @@ struct layout_effective_run {
     UINT16 *clustermap;     /* effective clustermap, allocated separately, is not reused from nominal map */
     UINT32 line;            /* 0-based line index in line metrics array */
     BOOL underlined;        /* set if this run is underlined */
+    D2D1_RECT_F bbox;       /* ink run box, top == bottom means it wasn't estimated yet */
 };
 
 struct layout_effective_inline {
@@ -1249,6 +1250,7 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
     run->start = start = layout->clusters[first_cluster].position;
     run->length = length;
     run->width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count);
+    memset(&run->bbox, 0, sizeof(run->bbox));
 
     /* Check if run direction matches paragraph direction, if it doesn't adjust by
        run width */
@@ -3581,25 +3583,28 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout
     D2D1_POINT_2F origin = { 0 };
     UINT32 i;
 
-    IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);
+    if (run->bbox.top == run->bbox.bottom) {
+        IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);
 
-    origin.x = run->origin.x + run->align_dx;
-    origin.y = run->origin.y;
-    for (i = 0; i < run->glyphcount; i++) {
-        D2D1_RECT_F glyph_bbox;
-        RECT design_bbox;
+        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);
+            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(bbox, &glyph_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];
+            /* FIXME: take care of vertical/rtl */
+            origin.x += glyph_run->glyphAdvances[i + start_glyph];
+       }
     }
+
+    *bbox = run->bbox;
+    d2d_rect_offset(bbox, run->origin.x + run->align_dx, run->origin.y);
 }
 
 static HRESULT WINAPI dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout3 *iface,
@@ -4091,9 +4096,12 @@ static HRESULT WINAPI dwritetextformat_layout_SetTextAlignment(IDWriteTextFormat
     if (FAILED(hr))
         return hr;
 
-    /* if layout is not ready there's nothing to align */
-    if (changed && !(This->recompute & RECOMPUTE_LINES))
-        layout_apply_text_alignment(This);
+    if (changed) {
+        /* if layout is not ready there's nothing to align */
+        if (!(This->recompute & RECOMPUTE_LINES))
+            layout_apply_text_alignment(This);
+        This->recompute |= RECOMPUTE_OVERHANGS;
+    }
 
     return S_OK;
 }
@@ -4110,9 +4118,12 @@ static HRESULT WINAPI dwritetextformat_layout_SetParagraphAlignment(IDWriteTextF
     if (FAILED(hr))
         return hr;
 
-    /* if layout is not ready there's nothing to align */
-    if (changed && !(This->recompute & RECOMPUTE_LINES))
-        layout_apply_par_alignment(This);
+    if (changed) {
+        /* if layout is not ready there's nothing to align */
+        if (!(This->recompute & RECOMPUTE_LINES))
+            layout_apply_par_alignment(This);
+        This->recompute |= RECOMPUTE_OVERHANGS;
+    }
 
     return S_OK;
 }




More information about the wine-cvs mailing list