ActivateFonts.mm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  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.
  12. *
  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.
  24. */
  25. #include "config.h"
  26. #include "ActivateFonts.h"
  27. #import <AppKit/AppKit.h>
  28. #import <CoreFoundation/CoreFoundation.h>
  29. #import <wtf/ObjcRuntimeExtras.h>
  30. #import <wtf/RetainPtr.h>
  31. @interface WKTRFontActivatorDummyClass : NSObject
  32. @end
  33. @implementation WKTRFontActivatorDummyClass
  34. @end
  35. namespace WTR {
  36. static NSSet *allowedFontFamilySet()
  37. {
  38. static NSSet *fontFamilySet = [[NSSet setWithObjects:
  39. @"Ahem",
  40. @"Al Bayan",
  41. @"American Typewriter",
  42. @"Andale Mono",
  43. @"Apple Braille",
  44. @"Apple Color Emoji",
  45. @"Apple Chancery",
  46. @"Apple Garamond BT",
  47. @"Apple LiGothic",
  48. @"Apple LiSung",
  49. @"Apple Symbols",
  50. @"AppleGothic",
  51. @"AppleMyungjo",
  52. @"Arial Black",
  53. @"Arial Hebrew",
  54. @"Arial Narrow",
  55. @"Arial Rounded MT Bold",
  56. @"Arial Unicode MS",
  57. @"Arial",
  58. @"Ayuthaya",
  59. @"Baghdad",
  60. @"Baskerville",
  61. @"BiauKai",
  62. @"Big Caslon",
  63. @"Brush Script MT",
  64. @"Chalkboard",
  65. @"Chalkduster",
  66. @"Charcoal CY",
  67. @"Cochin",
  68. @"Comic Sans MS",
  69. @"Copperplate",
  70. @"Corsiva Hebrew",
  71. @"Courier New",
  72. @"Courier",
  73. @"DecoType Naskh",
  74. @"Devanagari MT",
  75. @"Didot",
  76. @"Euphemia UCAS",
  77. @"Futura",
  78. @"GB18030 Bitmap",
  79. @"Geeza Pro",
  80. @"Geneva CY",
  81. @"Geneva",
  82. @"Georgia",
  83. @"Gill Sans",
  84. @"Gujarati MT",
  85. @"GungSeo",
  86. @"Gurmukhi MT",
  87. @"HeadLineA",
  88. @"Hei",
  89. @"Heiti SC",
  90. @"Heiti TC",
  91. @"Helvetica CY",
  92. @"Helvetica Neue",
  93. @"Helvetica",
  94. @"Herculanum",
  95. @"Hiragino Kaku Gothic Pro",
  96. @"Hiragino Kaku Gothic ProN",
  97. @"Hiragino Kaku Gothic Std",
  98. @"Hiragino Kaku Gothic StdN",
  99. @"Hiragino Maru Gothic Monospaced",
  100. @"Hiragino Maru Gothic Pro",
  101. @"Hiragino Maru Gothic ProN",
  102. @"Hiragino Mincho Pro",
  103. @"Hiragino Mincho ProN",
  104. @"Hiragino Sans GB",
  105. @"Hoefler Text",
  106. @"Impact",
  107. @"InaiMathi",
  108. @"Kai",
  109. @"Kailasa",
  110. @"Kokonor",
  111. @"Krungthep",
  112. @"KufiStandardGK",
  113. @"LiHei Pro",
  114. @"LiSong Pro",
  115. @"Lucida Grande",
  116. @"Marker Felt",
  117. @"Menlo",
  118. @"Microsoft Sans Serif",
  119. @"Monaco",
  120. @"Mshtakan",
  121. @"Nadeem",
  122. @"New Peninim MT",
  123. @"Optima",
  124. @"Osaka",
  125. @"Papyrus",
  126. @"PCMyungjo",
  127. @"PilGi",
  128. @"Plantagenet Cherokee",
  129. @"Raanana",
  130. @"Sathu",
  131. @"Silom",
  132. @"Skia",
  133. @"Songti SC",
  134. @"Songti TC",
  135. @"STFangsong",
  136. @"STHeiti",
  137. @"STIXGeneral",
  138. @"STIXSizeOneSym",
  139. @"STKaiti",
  140. @"STSong",
  141. @"Symbol",
  142. @"Tahoma",
  143. @"Thonburi",
  144. @"Times New Roman",
  145. @"Times",
  146. @"Trebuchet MS",
  147. @"Verdana",
  148. @"Webdings",
  149. @"WebKit WeightWatcher",
  150. @"Wingdings 2",
  151. @"Wingdings 3",
  152. @"Wingdings",
  153. @"Zapf Dingbats",
  154. @"Zapfino",
  155. nil] retain];
  156. return fontFamilySet;
  157. }
  158. static NSSet *systemHiddenFontFamilySet()
  159. {
  160. static NSSet *fontFamilySet = [[NSSet setWithObjects:
  161. @".LucidaGrandeUI",
  162. nil] retain];
  163. return fontFamilySet;
  164. }
  165. static IMP appKitAvailableFontFamiliesIMP;
  166. static IMP appKitAvailableFontsIMP;
  167. static NSArray *wtr_NSFontManager_availableFontFamilies(id self, SEL _cmd)
  168. {
  169. static NSArray *availableFontFamilies;
  170. if (availableFontFamilies)
  171. return availableFontFamilies;
  172. NSArray *availableFamilies = wtfCallIMP<id>(appKitAvailableFontFamiliesIMP, self, _cmd);
  173. NSMutableSet *prunedFamiliesSet = [NSMutableSet setWithArray:availableFamilies];
  174. [prunedFamiliesSet intersectSet:allowedFontFamilySet()];
  175. availableFontFamilies = [[prunedFamiliesSet allObjects] retain];
  176. return availableFontFamilies;
  177. }
  178. static NSArray *wtr_NSFontManager_availableFonts(id self, SEL _cmd)
  179. {
  180. static NSArray *availableFonts;
  181. if (availableFonts)
  182. return availableFonts;
  183. NSSet *allowedFamilies = allowedFontFamilySet();
  184. NSMutableArray *availableFontList = [[NSMutableArray alloc] initWithCapacity:[allowedFamilies count] * 2];
  185. for (NSString *fontFamily in allowedFontFamilySet()) {
  186. NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
  187. for (NSArray* fontInfo in fontsForFamily) {
  188. // Font name is the first entry in the array.
  189. [availableFontList addObject:[fontInfo objectAtIndex:0]];
  190. }
  191. }
  192. for (NSString *hiddenFontFamily in systemHiddenFontFamilySet()) {
  193. [availableFontList addObject:hiddenFontFamily];
  194. }
  195. availableFonts = availableFontList;
  196. return availableFonts;
  197. }
  198. static void swizzleNSFontManagerMethods()
  199. {
  200. Method availableFontFamiliesMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFontFamilies));
  201. ASSERT(availableFontFamiliesMethod);
  202. if (!availableFontFamiliesMethod) {
  203. NSLog(@"Failed to swizzle the \"availableFontFamilies\" method on NSFontManager");
  204. return;
  205. }
  206. appKitAvailableFontFamiliesIMP = method_setImplementation(availableFontFamiliesMethod, (IMP)wtr_NSFontManager_availableFontFamilies);
  207. Method availableFontsMethod = class_getInstanceMethod(objc_getClass("NSFontManager"), @selector(availableFonts));
  208. ASSERT(availableFontsMethod);
  209. if (!availableFontsMethod) {
  210. NSLog(@"Failed to swizzle the \"availableFonts\" method on NSFontManager");
  211. return;
  212. }
  213. appKitAvailableFontsIMP = method_setImplementation(availableFontsMethod, (IMP)wtr_NSFontManager_availableFonts);
  214. }
  215. void activateFonts()
  216. {
  217. static const char* fontFileNames[] = {
  218. "AHEM____.TTF",
  219. "WebKitWeightWatcher100.ttf",
  220. "WebKitWeightWatcher200.ttf",
  221. "WebKitWeightWatcher300.ttf",
  222. "WebKitWeightWatcher400.ttf",
  223. "WebKitWeightWatcher500.ttf",
  224. "WebKitWeightWatcher600.ttf",
  225. "WebKitWeightWatcher700.ttf",
  226. "WebKitWeightWatcher800.ttf",
  227. "WebKitWeightWatcher900.ttf",
  228. #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
  229. "SampleFont.sfont",
  230. #endif
  231. 0
  232. };
  233. NSMutableArray *fontURLs = [NSMutableArray array];
  234. NSURL *resourcesDirectory = [[NSBundle bundleForClass:[WKTRFontActivatorDummyClass class]] resourceURL];
  235. for (unsigned i = 0; fontFileNames[i]; ++i) {
  236. NSURL *fontURL = [resourcesDirectory URLByAppendingPathComponent:[NSString stringWithUTF8String:fontFileNames[i]]];
  237. [fontURLs addObject:[fontURL absoluteURL]];
  238. }
  239. CFArrayRef errors = 0;
  240. if (!CTFontManagerRegisterFontsForURLs((CFArrayRef)fontURLs, kCTFontManagerScopeProcess, &errors)) {
  241. NSLog(@"Failed to activate fonts: %@", errors);
  242. CFRelease(errors);
  243. exit(1);
  244. }
  245. swizzleNSFontManagerMethods();
  246. }
  247. }