[PATCH 3/5] dwrite: Evaluate IsMonospacedFont() flag at font level.

Nikolay Sivov nsivov at codeweavers.com
Thu Jan 23 03:24:13 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  3 +--
 dlls/dwrite/font.c           | 21 ++++-----------------
 dlls/dwrite/freetype.c       | 18 ------------------
 dlls/dwrite/opentype.c       | 19 ++++++++++++++++++-
 dlls/dwrite/tests/font.c     |  2 --
 5 files changed, 23 insertions(+), 40 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 76cf40cd1f..0705d43b1f 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -186,7 +186,7 @@ struct fontfacecached
 enum font_flags
 {
     FONT_IS_SYMBOL                 = 1 << 0,
-    FONTFACE_IS_MONOSPACED         = 1 << 1,
+    FONT_IS_MONOSPACED             = 1 << 1,
     FONTFACE_HAS_KERNING_PAIRS     = 1 << 2,
     FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3
 };
@@ -391,7 +391,6 @@ extern void release_freetype(void) DECLSPEC_HIDDEN;
 extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
         DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
 extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
-extern BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
 extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emsize, UINT16 const *glyphs,
         float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl,
         IDWriteGeometrySink *sink) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index f2b8655003..c1c9ce20fa 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -955,7 +955,7 @@ static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace5 *iface)
 
     TRACE("%p.\n", iface);
 
-    return !!(fontface->flags & FONTFACE_IS_MONOSPACED);
+    return !!(fontface->flags & FONT_IS_MONOSPACED);
 }
 
 static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode,
@@ -1765,19 +1765,10 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m
 static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface)
 {
     struct dwrite_font *font = impl_from_IDWriteFont3(iface);
-    IDWriteFontFace5 *fontface;
-    HRESULT hr;
-    BOOL ret;
 
     TRACE("%p.\n", iface);
 
-    hr = get_fontface_from_font(font, &fontface);
-    if (FAILED(hr))
-        return FALSE;
-
-    ret = IDWriteFontFace5_IsMonospacedFont(fontface);
-    IDWriteFontFace5_Release(fontface);
-    return ret;
+    return !!(font->data->flags & FONT_IS_MONOSPACED);
 }
 
 static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface)
@@ -4690,8 +4681,6 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
     fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace5_iface);
     if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface))
         fontface->flags |= FONTFACE_HAS_KERNING_PAIRS;
-    if (freetype_is_monospaced(&fontface->IDWriteFontFace5_iface))
-        fontface->flags |= FONTFACE_IS_MONOSPACED;
     if (opentype_has_vertical_variants(&fontface->IDWriteFontFace5_iface))
         fontface->flags |= FONTFACE_HAS_VERTICAL_VARIANTS;
     fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace5_iface);
@@ -4709,8 +4698,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
         fontface->panose = desc->font_data->panose;
         fontface->fontsig = desc->font_data->fontsig;
         fontface->lf = desc->font_data->lf;
-        if (desc->font_data->flags & FONT_IS_SYMBOL)
-            fontface->flags |= FONT_IS_SYMBOL;
+        fontface->flags |= desc->font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED);
     }
     else
     {
@@ -4730,8 +4718,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
         fontface->panose = data->panose;
         fontface->fontsig = data->fontsig;
         fontface->lf = data->lf;
-        if (data->flags & FONT_IS_SYMBOL)
-            fontface->flags |= FONT_IS_SYMBOL;
+        fontface->flags |= data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED);
 
         IDWriteLocalizedStrings_Release(names);
         release_font_data(data);
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 3c54da27f9..86c8315e6a 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -303,19 +303,6 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
     return S_OK;
 }
 
-BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface)
-{
-    BOOL is_monospaced = FALSE;
-    FT_Face face;
-
-    EnterCriticalSection(&freetype_cs);
-    if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0)
-        is_monospaced = !!FT_IS_FIXED_WIDTH(face);
-    LeaveCriticalSection(&freetype_cs);
-
-    return is_monospaced;
-}
-
 struct decompose_context {
     IDWriteGeometrySink *sink;
     D2D1_POINT_2F offset;
@@ -925,11 +912,6 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
     return E_NOTIMPL;
 }
 
-BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface)
-{
-    return FALSE;
-}
-
 HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs,
         float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl,
         IDWriteGeometrySink *sink)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 02a71b3528..5f41a5764b 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -1716,9 +1716,9 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT
 void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct dwrite_font_props *props)
 {
     struct dwrite_fonttable os2, head;
+    BOOL is_symbol, is_monospaced;
     const TT_OS2_V2 *tt_os2;
     const TT_HEAD *tt_head;
-    BOOL is_symbol;
 
     opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2);
     opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head);
@@ -1733,6 +1733,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
     memset(&props->panose, 0, sizeof(props->panose));
     memset(&props->fontsig, 0, sizeof(props->fontsig));
     memset(&props->lf, 0, sizeof(props->lf));
+    props->flags = 0;
 
     /* DWRITE_FONT_STRETCH enumeration values directly match font data values */
     if (tt_os2)
@@ -1823,6 +1824,22 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
     if (is_symbol)
         props->flags |= FONT_IS_SYMBOL;
 
+    if (!(is_monospaced = props->panose.text.proportion == DWRITE_PANOSE_PROPORTION_MONOSPACED))
+    {
+        struct dwrite_fonttable post;
+
+        opentype_get_font_table(stream_desc, MS_POST_TAG, &post);
+
+        if (post.data)
+        {
+            is_monospaced = !!table_read_dword(&post, FIELD_OFFSET(TT_POST, fixed_pitch));
+
+            IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post.context);
+        }
+    }
+    if (is_monospaced)
+        props->flags |= FONT_IS_MONOSPACED;
+
     TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
 
     if (os2.data)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 33603f6571..ac70a4c137 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -4990,9 +4990,7 @@ static void test_IsMonospacedFont(void)
 
             IDWriteFont1_GetPanose(font1, &panose);
 
-            /* FIXME: failures disabled on Wine for now */
             is_monospaced_expected = get_expected_is_monospaced(fontface1, &panose);
-        todo_wine_if(is_monospaced_expected != is_monospaced_face)
             ok(is_monospaced_expected == is_monospaced_face, "Unexpected is_monospaced flag %d for %s, font %d.\n",
                     is_monospaced_face, wine_dbgstr_w(nameW), j);
 
-- 
2.24.1




More information about the wine-devel mailing list