Nikolay Sivov : dwrite/fallback: Make sure all consecutively mapped characters belong to the same mapping.

Alexandre Julliard julliard at winehq.org
Mon Aug 8 15:17:52 CDT 2022


Module: wine
Branch: master
Commit: 1bff5e58590d54cf0ef40be26c9e6310ca07c910
URL:    https://gitlab.winehq.org/wine/wine/-/commit/1bff5e58590d54cf0ef40be26c9e6310ca07c910

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Aug  5 23:14:59 2022 +0300

dwrite/fallback: Make sure all consecutively mapped characters belong to the same mapping.

Picked fallback font often has wider character support than the ranges it's configured for.
Desired behavior is to stop at the first character that doesn't belong to current mapping.
For example, in texts like "abc<some CJK sequence>abc" we'd want the same for both "abc" sequences,
as opposed to using fallback CJK font for trailing Latin range.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>

---

 dlls/dwrite/analyzer.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 3f23c72dab4..f93d06a84d9 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -465,11 +465,24 @@ static void release_fallback_data(struct fallback_data *data)
     fallback_locale_list_destroy(&data->locales);
 }
 
+static BOOL fallback_mapping_contains_character(const struct fallback_mapping *mapping, UINT32 ch)
+{
+    size_t i;
+
+    for (i = 0; i < mapping->ranges_count; ++i)
+    {
+        const DWRITE_UNICODE_RANGE *range = &mapping->ranges[i];
+        if (range->first <= ch && range->last >= ch) return TRUE;
+    }
+
+    return FALSE;
+}
+
 static const struct fallback_mapping * find_fallback_mapping(const struct fallback_data *fallback,
         const struct fallback_locale *locale, UINT32 ch)
 {
     const struct fallback_mapping *mapping;
-    size_t i, j, r;
+    size_t i, j;
 
     for (i = 0; i < locale->ranges.count; i += 2)
     {
@@ -477,11 +490,7 @@ static const struct fallback_mapping * find_fallback_mapping(const struct fallba
         for (j = start; j <= end; ++j)
         {
             mapping = &fallback->mappings[j];
-            for (r = 0; r < mapping->ranges_count; ++r)
-            {
-                const DWRITE_UNICODE_RANGE *range = &mapping->ranges[r];
-                if (range->first <= ch && range->last >= ch) return mapping;
-            }
+            if (fallback_mapping_contains_character(mapping, ch)) return mapping;
         }
     }
 
@@ -2255,8 +2264,8 @@ static ULONG WINAPI fontfallback_Release(IDWriteFontFallback1 *iface)
     return IDWriteFactory7_Release(fallback->factory);
 }
 
-static UINT32 fallback_font_get_supported_length(IDWriteFont3 *font, IDWriteTextAnalysisSource *source, UINT32 position,
-        UINT32 length)
+static UINT32 fallback_font_get_supported_length(IDWriteFont3 *font, const struct fallback_mapping *mapping,
+        IDWriteTextAnalysisSource *source, UINT32 position, UINT32 length)
 {
     struct text_source_context context;
     UINT32 mapped = 0;
@@ -2264,6 +2273,7 @@ static UINT32 fallback_font_get_supported_length(IDWriteFont3 *font, IDWriteText
     text_source_context_init(&context, source, position, length);
     while (!text_source_get_next_u32_char(&context))
     {
+        if (mapping && !fallback_mapping_contains_character(mapping, context.ch)) break;
         if (!IDWriteFont3_HasCharacter(font, context.ch)) break;
         mapped += context.ch > 0xffff ? 2 : 1;
     }
@@ -2321,7 +2331,7 @@ static HRESULT fallback_map_characters(const struct dwrite_fontfallback *fallbac
         if (SUCCEEDED(create_matching_font(mapping->collection ? mapping->collection : fallback->systemcollection,
                 mapping->families[i], weight, style, stretch, &IID_IDWriteFont3, (void **)&font)))
         {
-            if (!(mapped = fallback_font_get_supported_length(font, source, position, length)))
+            if (!(mapped = fallback_font_get_supported_length(font, mapping, source, position, length)))
             {
                 IDWriteFont3_Release(font);
                 continue;
@@ -2405,7 +2415,7 @@ static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback1 *iface, ID
         if (SUCCEEDED(create_matching_font(basecollection, basefamily, weight, style, stretch,
                 &IID_IDWriteFont, (void **)&font)))
         {
-            if ((*mapped_length = fallback_font_get_supported_length(font, source, position, length)))
+            if ((*mapped_length = fallback_font_get_supported_length(font, NULL, source, position, length)))
             {
                 *ret_font = (IDWriteFont *)font;
                 *scale = 1.0f;




More information about the wine-cvs mailing list