WebCore: WebCore part of
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Sep 2009 23:07:21 +0000 (23:07 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Sep 2009 23:07:21 +0000 (23:07 +0000)
<rdar://problem/7211635> 2 byte characters are displayed as garbaged
<rdar://problem/7212626> garbled/gibberish text (off-by-one)

Reviewed by Jon Honeycutt.

When the Windows Fonts directory contains more than one font file for a
given font name, which of the fonts gets assigned to the name in the
Core Graphics font database was determined arbitrarily and did not
always match the font GDI used for the same font name. The mismatch
caused character-to-glyph mapping to use one font and glyph rendering to
use another.

The fix is to update the Core Graphics font database from the registry
entries (that reflect the name-to-font mapping that GDI uses) after
populating it with the result of scanning the Fonts directory. As a
consequence, the directory needs to be scanned at startup every time the
registry key changes, so the last value of the registry key is kept
in the property list on disk so that it could be compared to the current
value on startup.

* platform/graphics/win/FontDatabase.cpp:
(WebCore::populateFontDatabaseFromPlist): Now takes a property list as
a parameter and avoids round-tripping through XML by calling
wkAddFontsFromPlist() instead of wkAddFontsFromPlistRepresentation().
(WebCore::fontFilenamesFromRegistryKey):
(WebCore::cgFontDBKey):
(WebCore::writeFontDatabaseToPlist): Now takes the CG font DB property
list and a property list with the font filenames from the registry and
writes a dictionary with those property lists as values.
(WebCore::fontFilenamesFromRegistry): Added. Returns an array with the
values in the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
registry key.
(WebCore::populateFontDatabase): Changed to read the contents of the
Fonts registry key and compare it with the last-saved value from the
property list, and to call wkAddFontsFromRegistry() after populating the
CG font DB from the file system. Uses wkCreateFontsPlist() instead of
wkCreateFontsPlistRepresentation() to avoid round-tripping through XML.

WebKitLibraries: WebKitSystemInterface changes for
<rdar://problem/7211635> 2 byte characters are displayed as garbaged
<rdar://problem/7212626> garbled/gibberish text (off-by-one)

Reviewed by Adam Roben.

* win/include/WebKitSystemInterface/WebKitSystemInterface.h: Added
wkAddFontsFromPlistRepresentation() and replaced
wkCreateFontsPlistRepresentation() with wkCreateFontsPlist() and
wkAddFontsFromPlistRepresentation() with wkAddFontsFromPlist().
* win/lib/WebKitSystemInterface.lib:
* win/lib/WebKitSystemInterface_debug.lib:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@48775 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/win/FontDatabase.cpp
WebKitLibraries/ChangeLog
WebKitLibraries/win/include/WebKitSystemInterface/WebKitSystemInterface.h
WebKitLibraries/win/lib/WebKitSystemInterface.lib
WebKitLibraries/win/lib/WebKitSystemInterface_debug.lib

index 7ee0d424cee8ceb199e6740ddd3e6585182cee9b..3de0c226fedbbd3690dd72dcb23cb0990e68e3b7 100644 (file)
@@ -1,3 +1,44 @@
+2009-09-25  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Jon Honeycutt.
+
+        WebCore part of
+        <rdar://problem/7211635> 2 byte characters are displayed as garbaged
+        <rdar://problem/7212626> garbled/gibberish text (off-by-one)
+
+        When the Windows Fonts directory contains more than one font file for a
+        given font name, which of the fonts gets assigned to the name in the
+        Core Graphics font database was determined arbitrarily and did not
+        always match the font GDI used for the same font name. The mismatch
+        caused character-to-glyph mapping to use one font and glyph rendering to
+        use another.
+
+        The fix is to update the Core Graphics font database from the registry
+        entries (that reflect the name-to-font mapping that GDI uses) after
+        populating it with the result of scanning the Fonts directory. As a
+        consequence, the directory needs to be scanned at startup every time the
+        registry key changes, so the last value of the registry key is kept
+        in the property list on disk so that it could be compared to the current
+        value on startup.
+
+        * platform/graphics/win/FontDatabase.cpp:
+        (WebCore::populateFontDatabaseFromPlist): Now takes a property list as
+        a parameter and avoids round-tripping through XML by calling
+        wkAddFontsFromPlist() instead of wkAddFontsFromPlistRepresentation().
+        (WebCore::fontFilenamesFromRegistryKey):
+        (WebCore::cgFontDBKey):
+        (WebCore::writeFontDatabaseToPlist): Now takes the CG font DB property
+        list and a property list with the font filenames from the registry and
+        writes a dictionary with those property lists as values.
+        (WebCore::fontFilenamesFromRegistry): Added. Returns an array with the
+        values in the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
+        registry key.
+        (WebCore::populateFontDatabase): Changed to read the contents of the
+        Fonts registry key and compare it with the last-saved value from the
+        property list, and to call wkAddFontsFromRegistry() after populating the
+        CG font DB from the file system. Uses wkCreateFontsPlist() instead of
+        wkCreateFontsPlistRepresentation() to avoid round-tripping through XML.
+
 2009-09-25  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Darin Adler.
index 1308ff0c0d3d3673784ddb582aa083cee229d3e6..e7871063a9420461431a62d482c36d1a98cf8b41 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -99,17 +99,12 @@ static RetainPtr<CFPropertyListRef> readFontPlist()
     return plist;
 }
 
-static bool populateFontDatabaseFromPlist()
+static bool populateFontDatabaseFromPlist(CFPropertyListRef plist)
 {
-    RetainPtr<CFPropertyListRef> plist = readFontPlist();
     if (!plist)
         return false;
 
-    RetainPtr<CFDataRef> data(AdoptCF, CFPropertyListCreateXMLData(0, plist.get()));
-    if (!data)
-        return false;
-
-    wkAddFontsFromPlistRepresentation(data.get());
+    wkAddFontsFromPlist(plist);
     return true;
 }
 
@@ -123,15 +118,70 @@ static bool populateFontDatabaseFromFileSystem()
     return true;
 }
 
-static void writeFontDatabaseToPlist()
+static CFStringRef fontFilenamesFromRegistryKey()
+{
+    static CFStringRef key = CFSTR("WebKitFontFilenamesFromRegistry");
+    return key;
+}
+
+static CFStringRef cgFontDBKey()
 {
-    RetainPtr<CFDataRef> data(AdoptCF, wkCreateFontsPlistRepresentation());
+    static CFStringRef key = CFSTR("WebKitCGFontDB");
+    return key;
+}
+
+static void writeFontDatabaseToPlist(CFPropertyListRef cgFontDBPropertyList, CFPropertyListRef filenamesFromRegistry)
+{
+    RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF, CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+    if (cgFontDBPropertyList)
+        CFDictionarySetValue(dictionary.get(), cgFontDBKey(), cgFontDBPropertyList);
+    if (filenamesFromRegistry)
+        CFDictionarySetValue(dictionary.get(), fontFilenamesFromRegistryKey(), filenamesFromRegistry);
+
+    RetainPtr<CFDataRef> data(AdoptCF, CFPropertyListCreateXMLData(kCFAllocatorDefault, dictionary.get()));
     if (!data)
         return;
 
     safeCreateFile(fontsPlistPath(), data.get());
 }
 
+static RetainPtr<CFArrayRef> fontFilenamesFromRegistry()
+{
+    RetainPtr<CFMutableArrayRef> filenames(AdoptCF, CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
+
+    HKEY key;
+    if (FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), 0, KEY_READ, &key)))
+        return filenames;
+
+    DWORD valueCount;
+    DWORD maxNameLength;
+    DWORD maxValueLength;
+    if (FAILED(RegQueryInfoKey(key, 0, 0, 0, 0, 0, 0, &valueCount, &maxNameLength, &maxValueLength, 0, 0))) {
+        RegCloseKey(key);
+        return filenames;
+    }
+
+    Vector<TCHAR> name(maxNameLength + 1);
+    Vector<BYTE> value(maxValueLength + 1);
+
+    for (size_t i = 0; i < valueCount; ++i) {
+        DWORD nameLength = name.size();
+        DWORD valueLength = value.size();
+        DWORD type;
+        if (FAILED(RegEnumValue(key, i, name.data(), &nameLength, 0, &type, value.data(), &valueLength)))
+            continue;
+        if (type != REG_SZ)
+            continue;
+
+        RetainPtr<CFDataRef> filename(AdoptCF, CFDataCreate(kCFAllocatorDefault, value.data(), valueLength));
+        CFArrayAppendValue(filenames.get(), filename.get());
+    }
+
+    RegCloseKey(key);
+    return filenames;
+}
+
 void populateFontDatabase()
 {
     static bool initialized;
@@ -139,12 +189,38 @@ void populateFontDatabase()
         return;
     initialized = true;
 
-    if (!systemHasFontsNewerThanFontsPlist())
-        if (populateFontDatabaseFromPlist())
+    RetainPtr<CFPropertyListRef> propertyList = readFontPlist();
+    RetainPtr<CFArrayRef> lastFilenamesFromRegistry;
+    if (propertyList && CFGetTypeID(propertyList.get()) == CFDictionaryGetTypeID()) {
+        CFDictionaryRef dictionary = static_cast<CFDictionaryRef>(propertyList.get());
+        CFArrayRef array = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, fontFilenamesFromRegistryKey()));
+        if (array && CFGetTypeID(array) == CFArrayGetTypeID())
+            lastFilenamesFromRegistry = array;
+    }
+    RetainPtr<CFArrayRef> currentFilenamesFromRegistry = fontFilenamesFromRegistry();
+    bool registryChanged = !lastFilenamesFromRegistry || !CFEqual(lastFilenamesFromRegistry.get(), currentFilenamesFromRegistry.get());
+
+    if (!registryChanged && !systemHasFontsNewerThanFontsPlist()) {
+        RetainPtr<CFPropertyListRef> cgFontDBPropertyList;
+        if (propertyList) {
+            if (CFGetTypeID(propertyList.get()) == CFDictionaryGetTypeID()) {
+                CFDictionaryRef dictionary = static_cast<CFDictionaryRef>(propertyList.get());
+                cgFontDBPropertyList = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, cgFontDBKey()));
+            }
+            // Older versions of WebKit stored the CG font DB property list at the root of the property list.
+            if (!cgFontDBPropertyList)
+                cgFontDBPropertyList = propertyList;
+        }
+
+        if (populateFontDatabaseFromPlist(cgFontDBPropertyList.get()))
             return;
+    }
 
-    if (populateFontDatabaseFromFileSystem())
-        writeFontDatabaseToPlist();
+    if (populateFontDatabaseFromFileSystem()) {
+        wkAddFontsFromRegistry();
+        RetainPtr<CFPropertyListRef> cgFontDBPropertyList(AdoptCF, wkCreateFontsPlist());
+        writeFontDatabaseToPlist(cgFontDBPropertyList.get(), currentFilenamesFromRegistry.get());
+    }
 }
 
 } // namespace WebCore
index 99afe7ae38ed0843e81e217c36b6fe0cda362a5d..6a3394344005db03631fdac867f9409009eae5d5 100644 (file)
@@ -1,3 +1,18 @@
+2009-09-25  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Adam Roben.
+
+        WebKitSystemInterface changes for
+        <rdar://problem/7211635> 2 byte characters are displayed as garbaged
+        <rdar://problem/7212626> garbled/gibberish text (off-by-one)
+
+        * win/include/WebKitSystemInterface/WebKitSystemInterface.h: Added
+        wkAddFontsFromPlistRepresentation() and replaced
+        wkCreateFontsPlistRepresentation() with wkCreateFontsPlist() and
+        wkAddFontsFromPlistRepresentation() with wkAddFontsFromPlist().
+        * win/lib/WebKitSystemInterface.lib:
+        * win/lib/WebKitSystemInterface_debug.lib:
+
 2009-09-23  Marshall Culpepper  <mculpepper@appcelerator.com>
 
         Reviewed by Eric Seidel.
index d2183d4a60048e5fe7a2c093eb5132dde7f6dd67..b5ce0977b5932fbef9e41d0436d11e131849248c 100644 (file)
@@ -56,8 +56,9 @@ void wkSetFontPlatformInfo(CGFontRef, LOGFONT*, void(*)(void*));
 void wkSetUpFontCache(size_t s);
 void wkAddFontsInDirectory(CFStringRef);
 void wkAddFontsAtPath(CFStringRef);
-void wkAddFontsFromPlistRepresentation(CFDataRef);
-CFDataRef wkCreateFontsPlistRepresentation();
+void wkAddFontsFromRegistry();
+void wkAddFontsFromPlist(CFPropertyListRef);
+CFPropertyListRef wkCreateFontsPlist();
 
 void wkSetPatternBaseCTM(CGContextRef, CGAffineTransform);
 void wkSetPatternPhaseInUserSpace(CGContextRef, CGPoint phasePoint);
index 718f791838d5176c236c158f6c4d314a70116a37..d4f9dd9b0b437cdeeedac9ef8bb165a7c4635d34 100644 (file)
Binary files a/WebKitLibraries/win/lib/WebKitSystemInterface.lib and b/WebKitLibraries/win/lib/WebKitSystemInterface.lib differ
index 02b431a802382ec90a570360aeaf2b1371662e8e..6d1858808b08c05b7a6ea5a65157276262b75ad9 100644 (file)
Binary files a/WebKitLibraries/win/lib/WebKitSystemInterface_debug.lib and b/WebKitLibraries/win/lib/WebKitSystemInterface_debug.lib differ