Nikolay Sivov : dwrite: Support font replacement registry settings.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Feb 12 09:47:44 CST 2016


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Feb 12 01:51:58 2016 +0300

dwrite: Support font replacement registry settings.

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

---

 dlls/dwrite/font.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index fd64d8b..9bd5404 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -2986,6 +2986,88 @@ static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data
     }
 }
 
+static BOOL fontcollection_add_replacement(struct dwrite_fontcollection *collection, const WCHAR *target_name,
+    const WCHAR *replacement_name)
+{
+    UINT32 i = collection_find_family(collection, replacement_name);
+    struct dwrite_fontfamily_data *target;
+    IDWriteLocalizedStrings *strings;
+    HRESULT hr;
+
+    /* replacement does not exist */
+    if (i == ~0u)
+        return FALSE;
+
+    hr = create_localizedstrings(&strings);
+    if (FAILED(hr))
+        return FALSE;
+
+    /* add a new family with target name, reuse font data from replacement */
+    add_localizedstring(strings, enusW, target_name);
+    hr = init_fontfamily_data(strings, &target);
+    if (hr == S_OK) {
+        struct dwrite_fontfamily_data *replacement = collection->family_data[i];
+        WCHAR nameW[255];
+
+        for (i = 0; i < replacement->font_count; i++)
+            fontfamily_add_font(target, replacement->fonts[i]);
+
+        fontcollection_add_family(collection, target);
+        fontstrings_get_en_string(replacement->familyname, nameW, sizeof(nameW)/sizeof(WCHAR));
+        TRACE("replacement %s -> %s\n", debugstr_w(target_name), debugstr_w(nameW));
+    }
+    IDWriteLocalizedStrings_Release(strings);
+    return TRUE;
+}
+
+/* Add family mappings from HKCU\Software\Wine\Fonts\Replacements. This only affects
+   system font collections. */
+static void fontcollection_add_replacements(struct dwrite_fontcollection *collection)
+{
+    DWORD max_namelen, max_datalen, i = 0, type, datalen, namelen;
+    WCHAR *name;
+    void *data;
+    HKEY hkey;
+
+    if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts\\Replacements", &hkey))
+        return;
+
+    if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &max_namelen, &max_datalen, NULL, NULL)) {
+        RegCloseKey(hkey);
+        return;
+    }
+
+    max_namelen++; /* returned value doesn't include room for '\0' */
+    name = heap_alloc(max_namelen * sizeof(WCHAR));
+    data = heap_alloc(max_datalen);
+
+    datalen = max_datalen;
+    namelen = max_namelen;
+    while (RegEnumValueW(hkey, i++, name, &namelen, NULL, &type, data, &datalen) == ERROR_SUCCESS) {
+        if (collection_find_family(collection, name) == ~0u) {
+            if (type == REG_MULTI_SZ) {
+                WCHAR *replacement = data;
+                while (*replacement) {
+                    if (fontcollection_add_replacement(collection, name, replacement))
+                        break;
+                    replacement += strlenW(replacement) + 1;
+                }
+            }
+            else if (type == REG_SZ)
+                fontcollection_add_replacement(collection, name, data);
+        }
+        else
+	    TRACE("%s is available, won't be replaced.\n", debugstr_w(name));
+
+        datalen = max_datalen;
+        namelen = max_namelen;
+    }
+
+    heap_free(data);
+    heap_free(name);
+    RegCloseKey(hkey);
+}
+
 HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, IDWriteFontCollection **ret)
 {
     struct fontfile_enum {
@@ -3106,6 +3188,9 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
         fontfamily_add_oblique_simulated_face(collection->family_data[i]);
     }
 
+    if (is_system)
+        fontcollection_add_replacements(collection);
+
     return hr;
 }
 




More information about the wine-cvs mailing list