Title: [96434] trunk/Tools
Revision
96434
Author
simon.fra...@apple.com
Date
2011-09-30 15:53:53 -0700 (Fri, 30 Sep 2011)

Log Message

fast/forms/text-control-intrinsic-widths.html fails on Mac if Word/Office fonts are installed
https://bugs.webkit.org/show_bug.cgi?id=35273

Reviewed by Dan Bernstein.

There are two types of font issue that can cause layout test failure.
First, the user may have non-standard fonts installed that affect the layout
of some tests. For example, some tests use the MS Gothic font if installed.

Secondly, the user may have duplicate fonts installed in ~/Library/Fonts,
which override the system fonts (e.g. a copy of Arial from MS Office). For
some tests, this can affect font metrics or fallback behavior.

This change addresses the first problem only. It limits the set of fonts
available through NSFontManager, by swizzling some methods to return
a list of fonts or font families which only include fonts from a hardcoded
whitelist.

* DumpRenderTree/mac/DumpRenderTree.mm:
(allowedFontFamilySet):
(drt_NSFontManager_availableFontFamilies):
(drt_NSFontManager_availableFonts):
(swizzleNSFontManagerMethods):
(activateTestingFonts):
(adjustFonts):
(createWebViewAndOffscreenWindow):
(prepareConsistentTestingEnvironment):
* WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
(WTR::allowedFontFamilySet):
(WTR::drt_NSFontManager_availableFontFamilies):
(WTR::drt_NSFontManager_availableFonts):
(WTR::swizzleNSFontManagerMethods):
(WTR::InjectedBundle::platformInitialize):

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (96433 => 96434)


--- trunk/Tools/ChangeLog	2011-09-30 22:31:01 UTC (rev 96433)
+++ trunk/Tools/ChangeLog	2011-09-30 22:53:53 UTC (rev 96434)
@@ -1,3 +1,39 @@
+2011-09-30  Simon Fraser  <simon.fra...@apple.com>
+
+        fast/forms/text-control-intrinsic-widths.html fails on Mac if Word/Office fonts are installed
+        https://bugs.webkit.org/show_bug.cgi?id=35273
+
+        Reviewed by Dan Bernstein.
+        
+        There are two types of font issue that can cause layout test failure.
+        First, the user may have non-standard fonts installed that affect the layout
+        of some tests. For example, some tests use the MS Gothic font if installed.
+        
+        Secondly, the user may have duplicate fonts installed in ~/Library/Fonts,
+        which override the system fonts (e.g. a copy of Arial from MS Office). For
+        some tests, this can affect font metrics or fallback behavior.
+        
+        This change addresses the first problem only. It limits the set of fonts
+        available through NSFontManager, by swizzling some methods to return
+        a list of fonts or font families which only include fonts from a hardcoded
+        whitelist.
+        
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (allowedFontFamilySet):
+        (drt_NSFontManager_availableFontFamilies):
+        (drt_NSFontManager_availableFonts):
+        (swizzleNSFontManagerMethods):
+        (activateTestingFonts):
+        (adjustFonts):
+        (createWebViewAndOffscreenWindow):
+        (prepareConsistentTestingEnvironment):
+        * WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
+        (WTR::allowedFontFamilySet):
+        (WTR::drt_NSFontManager_availableFontFamilies):
+        (WTR::drt_NSFontManager_availableFonts):
+        (WTR::swizzleNSFontManagerMethods):
+        (WTR::InjectedBundle::platformInitialize):
+
 2011-09-30  David Levin  <le...@chromium.org>
 
         Need to skip webkitpy.common.checkout.baselineoptimizer_unittest.BaselineOptimizerTest on Windows..

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (96433 => 96434)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2011-09-30 22:31:01 UTC (rev 96433)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2011-09-30 22:53:53 UTC (rev 96434)
@@ -221,41 +221,187 @@
     return false;
 }
 
-static void activateFonts()
+static NSSet *allowedFontFamilySet()
 {
-#ifdef BUILDING_ON_LEOPARD
-    static const char* fontSectionNames[] = {
-        "Ahem",
-        "WeightWatcher100",
-        "WeightWatcher200",
-        "WeightWatcher300",
-        "WeightWatcher400",
-        "WeightWatcher500",
-        "WeightWatcher600",
-        "WeightWatcher700",
-        "WeightWatcher800",
-        "WeightWatcher900",
-        0
-    };
+    static NSSet *fontFamiliySet = [[NSSet setWithObjects:
+        @"Ahem",
+        @"Al Bayan",
+        @"American Typewriter",
+        @"Andale Mono",
+        @"Apple Braille",
+        @"Apple Color Emoji",
+        @"Apple Chancery",
+        @"Apple Garamond BT",
+        @"Apple LiGothic",
+        @"Apple LiSung",
+        @"Apple Symbols",
+        @"AppleGothic",
+        @"AppleMyungjo",
+        @"Arial Black",
+        @"Arial Hebrew",
+        @"Arial Narrow",
+        @"Arial Rounded MT Bold",
+        @"Arial Unicode MS",
+        @"Arial",
+        @"Ayuthaya",
+        @"Baghdad",
+        @"Baskerville",
+        @"BiauKai",
+        @"Big Caslon",
+        @"Brush Script MT",
+        @"Chalkboard",
+        @"Chalkduster",
+        @"Charcoal CY",
+        @"Cochin",
+        @"ColorBits",
+        @"Comic Sans MS",
+        @"Copperplate",
+        @"Corsiva Hebrew",
+        @"Courier New",
+        @"Courier",
+        @"DecoType Naskh",
+        @"Devanagari MT",
+        @"Didot",
+        @"Euphemia UCAS",
+        @"Futura",
+        @"GB18030 Bitmap",
+        @"Geeza Pro",
+        @"Geneva CY",
+        @"Geneva",
+        @"Georgia",
+        @"Gill Sans",
+        @"Gujarati MT",
+        @"GungSeo",
+        @"Gurmukhi MT",
+        @"HeadLineA",
+        @"Hei",
+        @"Heiti SC",
+        @"Heiti TC",
+        @"Helvetica CY",
+        @"Helvetica Neue",
+        @"Helvetica",
+        @"Herculanum",
+        @"Hiragino Kaku Gothic Pro",
+        @"Hiragino Kaku Gothic ProN",
+        @"Hiragino Kaku Gothic Std",
+        @"Hiragino Kaku Gothic StdN",
+        @"Hiragino Maru Gothic Pro",
+        @"Hiragino Maru Gothic ProN",
+        @"Hiragino Mincho Pro",
+        @"Hiragino Mincho ProN",
+        @"Hiragino Sans GB",
+        @"Hoefler Text",
+        @"Impact",
+        @"InaiMathi",
+        @"Kai",
+        @"Kailasa",
+        @"Kokonor",
+        @"Krungthep",
+        @"KufiStandardGK",
+        @"LiHei Pro",
+        @"LiSong Pro",
+        @"Lucida Grande",
+        @"Marker Felt",
+        @"Menlo",
+        @"Microsoft Sans Serif",
+        @"Monaco",
+        @"Mshtakan",
+        @"Nadeem",
+        @"New Peninim MT",
+        @"Optima",
+        @"Osaka",
+        @"Papyrus",
+        @"PCMyungjo",
+        @"PilGi",
+        @"Plantagenet Cherokee",
+        @"Raanana",
+        @"Sathu",
+        @"Silom",
+        @"Skia",
+        @"STFangsong",
+        @"STHeiti",
+        @"STKaiti",
+        @"STSong",
+        @"Symbol",
+        @"Tahoma",
+        @"Thonburi",
+        @"Times New Roman",
+        @"Times",
+        @"Trebuchet MS",
+        @"Verdana",
+        @"Webdings",
+        @"WebKit WeightWatcher",
+        @"Wingdings 2",
+        @"Wingdings 3",
+        @"Wingdings",
+        @"Zapf Dingbats",
+        @"Zapfino",
+        nil] retain];
+    
+    return fontFamiliySet;
+}
 
-    for (unsigned i = 0; fontSectionNames[i]; ++i) {
-        unsigned long fontDataLength;
-        char* fontData = getsectdata("__DATA", fontSectionNames[i], &fontDataLength);
-        if (!fontData) {
-            fprintf(stderr, "Failed to locate the %s font.\n", fontSectionNames[i]);
-            exit(1);
-        }
+static IMP appKitAvailableFontFamiliesIMP;
+static IMP appKitAvailableFontsIMP;
 
-        ATSFontContainerRef fontContainer;
-        OSStatus status = ATSFontActivateFromMemory(fontData, fontDataLength, kATSFontContextLocal, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &fontContainer);
+static NSArray *drt_NSFontManager_availableFontFamilies(id self, SEL _cmd)
+{
+    static NSArray *availableFontFamilies;
+    if (availableFontFamilies)
+        return availableFontFamilies;
+    
+    NSArray *availableFamilies = appKitAvailableFontFamiliesIMP(self, _cmd);
 
-        if (status != noErr) {
-            fprintf(stderr, "Failed to activate the %s font.\n", fontSectionNames[i]);
-            exit(1);
+    NSMutableSet *prunedFamiliesSet = [NSMutableSet setWithArray:availableFamilies];
+    [prunedFamiliesSet intersectSet:allowedFontFamilySet()];
+
+    availableFontFamilies = [[prunedFamiliesSet allObjects] retain];
+    return availableFontFamilies;
+}
+
+static NSArray *drt_NSFontManager_availableFonts(id self, SEL _cmd)
+{
+    static NSArray *availableFonts;
+    if (availableFonts)
+        return availableFonts;
+    
+    NSSet *allowedFamilies = allowedFontFamilySet();
+    NSMutableArray *availableFontList = [[NSMutableArray alloc] initWithCapacity:[allowedFamilies count] * 2];
+    for (NSString *fontFamily in allowedFontFamilySet()) {
+        NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
+        for (NSArray* fontInfo in fontsForFamily) {
+            // Font name is the first entry in the array.
+            [availableFontList addObject:[fontInfo objectAtIndex:0]];
         }
     }
-#else
+    
+    availableFonts = availableFontList;
+    return availableFonts;
+}
 
+static void swizzleNSFontManagerMethods()
+{
+    Method availableFontFamiliesMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFontFamilies));
+    ASSERT(availableFontFamiliesMethod);
+    if (!availableFontFamiliesMethod) {
+        NSLog(@"Failed to swizzle the \"availableFontFamilies\" method on NSFontManager");
+        return;
+    }
+    
+    appKitAvailableFontFamiliesIMP = method_setImplementation(availableFontFamiliesMethod, (IMP)drt_NSFontManager_availableFontFamilies);
+
+    Method availableFontsMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFonts));
+    ASSERT(availableFontsMethod);
+    if (!availableFontsMethod) {
+        NSLog(@"Failed to swizzle the \"availableFonts\" method on NSFontManager");
+        return;
+    }
+    
+    appKitAvailableFontsIMP = method_setImplementation(availableFontsMethod, (IMP)drt_NSFontManager_availableFonts);
+}
+
+static void activateTestingFonts()
+{
     // Work around <rdar://problem/6698023> by activating fonts from disk
     // FIXME: This code can be removed once <rdar://problem/6698023> is addressed.
 
@@ -287,9 +433,14 @@
         CFRelease(errors);
         exit(1);
     }
-#endif
 }
 
+static void adjustFonts()
+{
+    swizzleNSFontManagerMethods();
+    activateTestingFonts();
+}
+
 WebView *createWebViewAndOffscreenWindow()
 {
     NSRect rect = NSMakeRect(0, 0, LayoutTestController::maxViewWidth, LayoutTestController::maxViewHeight);
@@ -317,10 +468,7 @@
     NSRect windowRect = NSOffsetRect(rect, -10000, [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - rect.size.height + 10000);
     DumpRenderTreeWindow *window = [[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
 
-#ifndef BUILDING_ON_LEOPARD
     [window setColorSpace:[[NSScreen mainScreen] colorSpace]];
-#endif
-
     [[window contentView] addSubview:webView];
     [window orderBack:nil];
     [window setAutodisplay:NO];
@@ -601,7 +749,7 @@
     poseAsClass("DumpRenderTreeEvent", "NSEvent");
 
     setDefaultsToConsistentValuesForTesting();
-    activateFonts();
+    adjustFonts();
     
     if (dumpPixels)
         setupMainDisplayColorProfile();

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm (96433 => 96434)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm	2011-09-30 22:31:01 UTC (rev 96433)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm	2011-09-30 22:53:53 UTC (rev 96434)
@@ -25,10 +25,191 @@
 
 #import "InjectedBundle.h"
 
+#import <AppKit/AppKit.h>
 #import <Foundation/Foundation.h>
+#import <objc/objc-runtime.h>
 
 namespace WTR {
 
+static NSSet *allowedFontFamilySet()
+{
+    static NSSet *fontFamiliySet = [[NSSet setWithObjects:
+        @"Ahem",
+        @"Al Bayan",
+        @"American Typewriter",
+        @"Andale Mono",
+        @"Apple Braille",
+        @"Apple Color Emoji",
+        @"Apple Chancery",
+        @"Apple Garamond BT",
+        @"Apple LiGothic",
+        @"Apple LiSung",
+        @"Apple Symbols",
+        @"AppleGothic",
+        @"AppleMyungjo",
+        @"Arial Black",
+        @"Arial Hebrew",
+        @"Arial Narrow",
+        @"Arial Rounded MT Bold",
+        @"Arial Unicode MS",
+        @"Arial",
+        @"Ayuthaya",
+        @"Baghdad",
+        @"Baskerville",
+        @"BiauKai",
+        @"Big Caslon",
+        @"Brush Script MT",
+        @"Chalkboard",
+        @"Chalkduster",
+        @"Charcoal CY",
+        @"Cochin",
+        @"ColorBits",
+        @"Comic Sans MS",
+        @"Copperplate",
+        @"Corsiva Hebrew",
+        @"Courier New",
+        @"Courier",
+        @"DecoType Naskh",
+        @"Devanagari MT",
+        @"Didot",
+        @"Euphemia UCAS",
+        @"Futura",
+        @"GB18030 Bitmap",
+        @"Geeza Pro",
+        @"Geneva CY",
+        @"Geneva",
+        @"Georgia",
+        @"Gill Sans",
+        @"Gujarati MT",
+        @"GungSeo",
+        @"Gurmukhi MT",
+        @"HeadLineA",
+        @"Hei",
+        @"Heiti SC",
+        @"Heiti TC",
+        @"Helvetica CY",
+        @"Helvetica Neue",
+        @"Helvetica",
+        @"Herculanum",
+        @"Hiragino Kaku Gothic Pro",
+        @"Hiragino Kaku Gothic ProN",
+        @"Hiragino Kaku Gothic Std",
+        @"Hiragino Kaku Gothic StdN",
+        @"Hiragino Maru Gothic Pro",
+        @"Hiragino Maru Gothic ProN",
+        @"Hiragino Mincho Pro",
+        @"Hiragino Mincho ProN",
+        @"Hiragino Sans GB",
+        @"Hoefler Text",
+        @"Impact",
+        @"InaiMathi",
+        @"Kai",
+        @"Kailasa",
+        @"Kokonor",
+        @"Krungthep",
+        @"KufiStandardGK",
+        @"LiHei Pro",
+        @"LiSong Pro",
+        @"Lucida Grande",
+        @"Marker Felt",
+        @"Menlo",
+        @"Microsoft Sans Serif",
+        @"Monaco",
+        @"Mshtakan",
+        @"Nadeem",
+        @"New Peninim MT",
+        @"Optima",
+        @"Osaka",
+        @"Papyrus",
+        @"PCMyungjo",
+        @"PilGi",
+        @"Plantagenet Cherokee",
+        @"Raanana",
+        @"Sathu",
+        @"Silom",
+        @"Skia",
+        @"STFangsong",
+        @"STHeiti",
+        @"STKaiti",
+        @"STSong",
+        @"Symbol",
+        @"Tahoma",
+        @"Thonburi",
+        @"Times New Roman",
+        @"Times",
+        @"Trebuchet MS",
+        @"Verdana",
+        @"Webdings",
+        @"WebKit WeightWatcher",
+        @"Wingdings 2",
+        @"Wingdings 3",
+        @"Wingdings",
+        @"Zapf Dingbats",
+        @"Zapfino",
+        nil] retain];
+    
+    return fontFamiliySet;
+}
+
+static IMP appKitAvailableFontFamiliesIMP;
+static IMP appKitAvailableFontsIMP;
+
+static NSArray *drt_NSFontManager_availableFontFamilies(id self, SEL _cmd)
+{
+    static NSArray *availableFontFamilies;
+    if (availableFontFamilies)
+        return availableFontFamilies;
+    
+    NSArray *availableFamilies = appKitAvailableFontFamiliesIMP(self, _cmd);
+
+    NSMutableSet *prunedFamiliesSet = [NSMutableSet setWithArray:availableFamilies];
+    [prunedFamiliesSet intersectSet:allowedFontFamilySet()];
+
+    availableFontFamilies = [[prunedFamiliesSet allObjects] retain];
+    return availableFontFamilies;
+}
+
+static NSArray *drt_NSFontManager_availableFonts(id self, SEL _cmd)
+{
+    static NSArray *availableFonts;
+    if (availableFonts)
+        return availableFonts;
+    
+    NSSet *allowedFamilies = allowedFontFamilySet();
+    NSMutableArray *availableFontList = [[NSMutableArray alloc] initWithCapacity:[allowedFamilies count] * 2];
+    for (NSString *fontFamily in allowedFontFamilySet()) {
+        NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
+        for (NSArray* fontInfo in fontsForFamily) {
+            // Font name is the first entry in the array.
+            [availableFontList addObject:[fontInfo objectAtIndex:0]];
+        }
+    }
+    
+    availableFonts = availableFontList;
+    return availableFonts;
+}
+
+static void swizzleNSFontManagerMethods()
+{
+    Method availableFontFamiliesMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFontFamilies));
+    ASSERT(availableFontFamiliesMethod);
+    if (!availableFontFamiliesMethod) {
+        NSLog(@"Failed to swizzle the \"availableFontFamilies\" method on NSFontManager");
+        return;
+    }
+    
+    appKitAvailableFontFamiliesIMP = method_setImplementation(availableFontFamiliesMethod, (IMP)drt_NSFontManager_availableFontFamilies);
+
+    Method availableFontsMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFonts));
+    ASSERT(availableFontsMethod);
+    if (!availableFontsMethod) {
+        NSLog(@"Failed to swizzle the \"availableFonts\" method on NSFontManager");
+        return;
+    }
+    
+    appKitAvailableFontsIMP = method_setImplementation(availableFontsMethod, (IMP)drt_NSFontManager_availableFonts);
+}
+
 void InjectedBundle::platformInitialize(WKTypeRef)
 {
     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@@ -40,6 +221,8 @@
         nil];
 
     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
+    
+    swizzleNSFontManagerMethods();
 }
 
 } // namespace WTR
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to