[PATCH 1/4] dwrite: Properly pass measuring mode to renderer

Nikolay Sivov nsivov at codeweavers.com
Thu Jul 16 05:10:54 CDT 2015


---

-------------- next part --------------
From cd599f311803bbbad972d3676e40c142fda7aac7 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed, 15 Jul 2015 22:15:20 +0300
Subject: [PATCH 1/4] dwrite: Properly pass measuring mode to renderer

---
 dlls/dwrite/layout.c       | 32 ++++++++++++---------
 dlls/dwrite/tests/layout.c | 71 +++++++++++++++++++++++++++++++++++++---------
 2 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 99ec7b4..8e96762 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -252,10 +252,10 @@ struct dwrite_textlayout {
 
     DWRITE_TEXT_METRICS1 metrics;
 
+    DWRITE_MEASURING_MODE measuringmode;
+
     /* gdi-compatible layout specifics */
-    BOOL   gdicompatible;
     FLOAT  pixels_per_dip;
-    BOOL   use_gdi_natural;
     DWRITE_MATRIX transform;
 };
 
@@ -333,6 +333,11 @@ static inline const char *debugstr_run(const struct regular_layout_run *run)
         run->descr.stringLength);
 }
 
+static inline BOOL is_layout_gdi_compatible(struct dwrite_textlayout *layout)
+{
+    return layout->measuringmode != DWRITE_MEASURING_MODE_NATURAL;
+}
+
 static inline HRESULT format_set_textalignment(struct dwrite_textformat_data *format, DWRITE_TEXT_ALIGNMENT alignment,
     BOOL *changed)
 {
@@ -808,12 +813,12 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
             goto memerr;
 
         /* now set advances and offsets */
-        if (layout->gdicompatible)
+        if (is_layout_gdi_compatible(layout))
             hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, run->descr.string, run->descr.clusterMap,
                 text_props, run->descr.stringLength, run->run.glyphIndices, glyph_props, run->glyphcount,
-                run->run.fontFace, run->run.fontEmSize, layout->pixels_per_dip, &layout->transform, layout->use_gdi_natural,
-                run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName, NULL, NULL, 0,
-                run->advances, run->offsets);
+                run->run.fontFace, run->run.fontEmSize, layout->pixels_per_dip, &layout->transform,
+                layout->measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL, run->run.isSideways,
+                run->run.bidiLevel & 1, &run->sa, run->descr.localeName, NULL, NULL, 0, run->advances, run->offsets);
         else
             hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, run->descr.string, run->descr.clusterMap, text_props,
                 run->descr.stringLength, run->run.glyphIndices, glyph_props, run->glyphcount, run->run.fontFace,
@@ -837,7 +842,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
             run->run.glyphCount = run->glyphcount;
 
         /* baseline derived from font metrics */
-        if (layout->gdicompatible) {
+        if (is_layout_gdi_compatible(layout)) {
             hr = IDWriteFontFace_GetGdiCompatibleMetrics(run->run.fontFace,
                 run->run.fontEmSize,
                 layout->pixels_per_dip,
@@ -1054,7 +1059,7 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
         if (!s)
             return E_OUTOFMEMORY;
 
-        if (layout->gdicompatible) {
+        if (is_layout_gdi_compatible(layout)) {
             HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics(
                 r->u.regular.run.fontFace,
                 r->u.regular.run.fontEmSize,
@@ -1073,7 +1078,7 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
         s->s.readingDirection = layout->format.readingdir;
         s->s.flowDirection = layout->format.flow;
         s->s.localeName = r->u.regular.descr.localeName;
-        s->s.measuringMode = DWRITE_MEASURING_MODE_NATURAL; /* FIXME */
+        s->s.measuringMode = layout->measuringmode;
         s->run = run;
 
         list_add_tail(&layout->strikethrough, &s->entry);
@@ -2830,7 +2835,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
             context,
             run->origin_x + run->align_dx + origin_x,
             disabled ? run->origin_y + origin_y : SNAP_COORD(run->origin_y + origin_y),
-            DWRITE_MEASURING_MODE_NATURAL,
+            This->measuringmode,
             &glyph_run,
             &descr,
             NULL);
@@ -3894,10 +3899,9 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
     memset(&layout->metrics, 0, sizeof(layout->metrics));
     layout->metrics.layoutWidth = maxwidth;
     layout->metrics.layoutHeight = maxheight;
+    layout->measuringmode = DWRITE_MEASURING_MODE_NATURAL;
 
-    layout->gdicompatible = FALSE;
     layout->pixels_per_dip = 0.0;
-    layout->use_gdi_natural = FALSE;
     memset(&layout->transform, 0, sizeof(layout->transform));
 
     layout->str = heap_strdupnW(str, len);
@@ -3964,10 +3968,10 @@ HRESULT create_gdicompat_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFor
 
     hr = init_textlayout(str, len, format, maxwidth, maxheight, layout);
     if (hr == S_OK) {
+        layout->measuringmode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
+
         /* set gdi-specific properties */
-        layout->gdicompatible = TRUE;
         layout->pixels_per_dip = pixels_per_dip;
-        layout->use_gdi_natural = use_gdi_natural;
         layout->transform = transform ? *transform : identity;
 
         *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout2_iface;
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 950b021..a2a5d39 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -420,6 +420,8 @@ static ULONG WINAPI testrenderer_Release(IDWriteTextRenderer *iface)
 }
 
 struct renderer_context {
+    BOOL gdicompat;
+    BOOL use_gdi_natural;
     BOOL snapping_disabled;
     DWRITE_MATRIX m;
     FLOAT ppdip;
@@ -455,6 +457,19 @@ static HRESULT WINAPI testrenderer_GetPixelsPerDip(IDWriteTextRenderer *iface,
     return S_OK;
 }
 
+#define TEST_MEASURING_MODE(ctxt, mode) test_measuring_mode(ctxt, mode, __LINE__)
+static void test_measuring_mode(const struct renderer_context *ctxt, DWRITE_MEASURING_MODE mode, int line)
+{
+    if (ctxt->gdicompat) {
+        if (ctxt->use_gdi_natural)
+            ok_(__FILE__, line)(mode == DWRITE_MEASURING_MODE_GDI_NATURAL, "got %d\n", mode);
+        else
+            ok_(__FILE__, line)(mode == DWRITE_MEASURING_MODE_GDI_CLASSIC, "got %d\n", mode);
+    }
+    else
+        ok_(__FILE__, line)(mode == DWRITE_MEASURING_MODE_NATURAL, "got %d\n", mode);
+}
+
 static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
     void *context,
     FLOAT baselineOriginX,
@@ -469,6 +484,7 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
     DWRITE_SCRIPT_ANALYSIS sa;
 
     if (ctxt) {
+        TEST_MEASURING_MODE(ctxt, mode);
         ctxt->originX = baselineOriginX;
         ctxt->originY = baselineOriginY;
     }
@@ -503,13 +519,18 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
 }
 
 static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface,
-    void *client_drawingcontext,
+    void *context,
     FLOAT baselineOriginX,
     FLOAT baselineOriginY,
     DWRITE_UNDERLINE const* underline,
     IUnknown *effect)
 {
+    struct renderer_context *ctxt = (struct renderer_context*)context;
     struct drawcall_entry entry;
+
+    if (ctxt)
+        TEST_MEASURING_MODE(ctxt, underline->measuringMode);
+
     entry.kind = DRAW_UNDERLINE;
     if (effect)
         entry.kind |= DRAW_EFFECT;
@@ -518,13 +539,18 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface,
 }
 
 static HRESULT WINAPI testrenderer_DrawStrikethrough(IDWriteTextRenderer *iface,
-    void *client_drawingcontext,
+    void *context,
     FLOAT baselineOriginX,
     FLOAT baselineOriginY,
     DWRITE_STRIKETHROUGH const* strikethrough,
     IUnknown *effect)
 {
+    struct renderer_context *ctxt = (struct renderer_context*)context;
     struct drawcall_entry entry;
+
+    if (ctxt)
+        TEST_MEASURING_MODE(ctxt, strikethrough->measuringMode);
+
     entry.kind = DRAW_STRIKETHROUGH;
     if (effect)
         entry.kind |= DRAW_EFFECT;
@@ -533,7 +559,7 @@ static HRESULT WINAPI testrenderer_DrawStrikethrough(IDWriteTextRenderer *iface,
 }
 
 static HRESULT WINAPI testrenderer_DrawInlineObject(IDWriteTextRenderer *iface,
-    void *client_drawingcontext,
+    void *context,
     FLOAT originX,
     FLOAT originY,
     IDWriteInlineObject *object,
@@ -1342,6 +1368,7 @@ static void test_Draw(void)
     static const WCHAR str2W[] = {0x202a,0x202c,'a','b',0};
     static const WCHAR ruW[] = {'r','u',0};
     IDWriteInlineObject *inlineobj;
+    struct renderer_context ctxt;
     IDWriteTextFormat *format;
     IDWriteTextLayout *layout;
     DWRITE_TEXT_RANGE range;
@@ -1351,6 +1378,10 @@ static void test_Draw(void)
 
     factory = create_factory();
 
+    ctxt.gdicompat = FALSE;
+    ctxt.use_gdi_natural = FALSE;
+    ctxt.snapping_disabled = TRUE;
+
     hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_BOLD, DWRITE_FONT_STYLE_NORMAL,
         DWRITE_FONT_STRETCH_NORMAL, 10.0, ruW, &format);
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -1382,7 +1413,7 @@ static void test_Draw(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_seq, "draw test", TRUE);
     IDWriteTextLayout_Release(layout);
@@ -1391,7 +1422,7 @@ static void test_Draw(void)
     hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, format, 5.0, 100.0, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_seq2, "draw test 2", TRUE);
     IDWriteTextLayout_Release(layout);
@@ -1400,7 +1431,7 @@ static void test_Draw(void)
     hr = IDWriteFactory_CreateTextLayout(factory, str2W, 4, format, 500.0, 100.0, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_seq3, "draw test 3", TRUE);
     IDWriteTextLayout_Release(layout);
@@ -1416,7 +1447,7 @@ static void test_Draw(void)
     hr = IDWriteTextLayout_SetStrikethrough(layout, TRUE, range);
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_seq4, "draw test 4", FALSE);
     IDWriteTextLayout_Release(layout);
@@ -1431,7 +1462,7 @@ static void test_Draw(void)
     hr = IDWriteTextLayout_SetStrikethrough(layout, TRUE, range);
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_seq5, "draw test 5", FALSE);
     IDWriteTextLayout_Release(layout);
@@ -1441,44 +1472,56 @@ static void test_Draw(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, empty_seq, "draw test 6", FALSE);
     IDWriteTextLayout_Release(layout);
 
+    ctxt.gdicompat = TRUE;
+    ctxt.use_gdi_natural = TRUE;
+
     /* different parameter combinations with gdi-compatible layout */
     hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, format, 100.0, 100.0, 1.0, NULL, TRUE, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_single_run_seq, "draw test 7", FALSE);
     IDWriteTextLayout_Release(layout);
 
+    ctxt.gdicompat = TRUE;
+    ctxt.use_gdi_natural = FALSE;
+
     hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, format, 100.0, 100.0, 1.0, NULL, FALSE, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_single_run_seq, "draw test 8", FALSE);
     IDWriteTextLayout_Release(layout);
 
+    ctxt.gdicompat = TRUE;
+    ctxt.use_gdi_natural = TRUE;
+
     m.m11 = m.m22 = 2.0;
     m.m12 = m.m21 = m.dx = m.dy = 0.0;
     hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, format, 100.0, 100.0, 1.0, &m, TRUE, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_single_run_seq, "draw test 9", FALSE);
     IDWriteTextLayout_Release(layout);
 
+    ctxt.gdicompat = TRUE;
+    ctxt.use_gdi_natural = FALSE;
+
     m.m11 = m.m22 = 2.0;
     m.m12 = m.m21 = m.dx = m.dy = 0.0;
     hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, format, 100.0, 100.0, 1.0, &m, FALSE, &layout);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     flush_sequence(sequences, RENDERER_ID);
-    hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);
+    hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok_sequence(sequences, RENDERER_ID, draw_single_run_seq, "draw test 10", FALSE);
     IDWriteTextLayout_Release(layout);
@@ -3373,6 +3416,8 @@ static void test_pixelsnapping(void)
 
     /* disabled snapping */
     ctxt.snapping_disabled = TRUE;
+    ctxt.gdicompat = FALSE;
+    ctxt.use_gdi_natural = FALSE;
     ctxt.ppdip = 1.0f;
     memset(&ctxt.m, 0, sizeof(ctxt.m));
     ctxt.m.m11 = ctxt.m.m22 = 1.0;
-- 
2.1.4



More information about the wine-patches mailing list