2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "ActivateFonts.h"
29 #import <AppKit/AppKit.h>
30 #import <CoreFoundation/CoreFoundation.h>
31 #import <objc/objc-runtime.h>
32 #import <wtf/RetainPtr.h>
34 @interface WKTRFontActivatorDummyClass : NSObject
37 @implementation WKTRFontActivatorDummyClass
43 static NSSet *allowedFontFamilySet()
45 static NSSet *fontFamiliySet = [[NSSet setWithObjects:
48 @"American Typewriter",
62 @"Arial Rounded MT Bold",
102 @"Hiragino Kaku Gothic Pro",
103 @"Hiragino Kaku Gothic ProN",
104 @"Hiragino Kaku Gothic Std",
105 @"Hiragino Kaku Gothic StdN",
106 @"Hiragino Maru Gothic Pro",
107 @"Hiragino Maru Gothic ProN",
108 @"Hiragino Mincho Pro",
109 @"Hiragino Mincho ProN",
124 @"Microsoft Sans Serif",
134 @"Plantagenet Cherokee",
151 @"WebKit WeightWatcher",
159 return fontFamiliySet;
162 static IMP appKitAvailableFontFamiliesIMP;
163 static IMP appKitAvailableFontsIMP;
165 static NSArray *wtr_NSFontManager_availableFontFamilies(id self, SEL _cmd)
167 static NSArray *availableFontFamilies;
168 if (availableFontFamilies)
169 return availableFontFamilies;
171 NSArray *availableFamilies = appKitAvailableFontFamiliesIMP(self, _cmd);
173 NSMutableSet *prunedFamiliesSet = [NSMutableSet setWithArray:availableFamilies];
174 [prunedFamiliesSet intersectSet:allowedFontFamilySet()];
176 availableFontFamilies = [[prunedFamiliesSet allObjects] retain];
177 return availableFontFamilies;
180 static NSArray *wtr_NSFontManager_availableFonts(id self, SEL _cmd)
182 static NSArray *availableFonts;
184 return availableFonts;
186 NSSet *allowedFamilies = allowedFontFamilySet();
187 NSMutableArray *availableFontList = [[NSMutableArray alloc] initWithCapacity:[allowedFamilies count] * 2];
188 for (NSString *fontFamily in allowedFontFamilySet()) {
189 NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
190 for (NSArray* fontInfo in fontsForFamily) {
191 // Font name is the first entry in the array.
192 [availableFontList addObject:[fontInfo objectAtIndex:0]];
196 availableFonts = availableFontList;
197 return availableFonts;
200 static void swizzleNSFontManagerMethods()
202 Method availableFontFamiliesMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFontFamilies));
203 ASSERT(availableFontFamiliesMethod);
204 if (!availableFontFamiliesMethod) {
205 NSLog(@"Failed to swizzle the \"availableFontFamilies\" method on NSFontManager");
209 appKitAvailableFontFamiliesIMP = method_setImplementation(availableFontFamiliesMethod, (IMP)wtr_NSFontManager_availableFontFamilies);
211 Method availableFontsMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFonts));
212 ASSERT(availableFontsMethod);
213 if (!availableFontsMethod) {
214 NSLog(@"Failed to swizzle the \"availableFonts\" method on NSFontManager");
218 appKitAvailableFontsIMP = method_setImplementation(availableFontsMethod, (IMP)wtr_NSFontManager_availableFonts);
223 // Work around <rdar://problem/6698023> by activating fonts from disk
225 static const char* fontFileNames[] = {
227 "WebKitWeightWatcher100.ttf",
228 "WebKitWeightWatcher200.ttf",
229 "WebKitWeightWatcher300.ttf",
230 "WebKitWeightWatcher400.ttf",
231 "WebKitWeightWatcher500.ttf",
232 "WebKitWeightWatcher600.ttf",
233 "WebKitWeightWatcher700.ttf",
234 "WebKitWeightWatcher800.ttf",
235 "WebKitWeightWatcher900.ttf",
239 NSMutableArray *fontURLs = [NSMutableArray array];
240 NSURL *resourcesDirectory = [[NSBundle bundleForClass:[WKTRFontActivatorDummyClass class]] resourceURL];
241 for (unsigned i = 0; fontFileNames[i]; ++i) {
242 NSURL *fontURL = [resourcesDirectory URLByAppendingPathComponent:[NSString stringWithUTF8String:fontFileNames[i]]];
243 [fontURLs addObject:[fontURL absoluteURL]];
246 CFArrayRef errors = 0;
247 if (!CTFontManagerRegisterFontsForURLs((CFArrayRef)fontURLs, kCTFontManagerScopeProcess, &errors)) {
248 NSLog(@"Failed to activate fonts: %@", errors);
253 swizzleNSFontManagerMethods();