Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 816 lines (631 sloc) 18.886 kb
1ab25c2 @Cocoanetics Added new files
authored
1 //
2 // DTCoreTextFontDescriptor.m
3 // CoreTextExtensions
4 //
5 // Created by Oliver Drobnik on 1/26/11.
6 // Copyright 2011 Drobnik.com. All rights reserved.
7 //
8
9 #import "DTCoreTextFontDescriptor.h"
d140d94 @Cocoanetics Moved DTZipArchive, DTHTMLParser and DTDownloadCache into their own l…
authored
10 #import "DTVersion.h"
1ab25c2 @Cocoanetics Added new files
authored
11
696397a @Cocoanetics Removed DTCache, no longer necessary because we only support >= 4.3
authored
12 static NSCache *_fontCache = nil;
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
13 static NSMutableDictionary *_fontOverrides = nil;
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
14 static dispatch_queue_t _fontQueue;
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
15
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
16 // adds "STHeitiSC-Light" font for cascading fix on iOS 5
17 static BOOL _needsChineseFontCascadeFix = NO;
18
dce97b9 @dhoerl Lock for font actions
dhoerl authored
19 @implementation DTCoreTextFontDescriptor
06980a2 @dhoerl18 Debug a retain cycle; moved ivars to implementation; cleared all warn…
dhoerl18 authored
20 {
21 NSString *fontFamily;
22 NSString *fontName;
23
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
24 CGFloat _pointSize;
25
26 CTFontSymbolicTraits _stylisticTraits;
27 CTFontStylisticClass _stylisticClass;
06980a2 @dhoerl18 Debug a retain cycle; moved ivars to implementation; cleared all warn…
dhoerl18 authored
28
29 BOOL smallCapsFeature;
30 }
dce97b9 @dhoerl Lock for font actions
dhoerl authored
31
32 + (void)initialize
33 {
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
34 // only this class (and not subclasses) do this
35 if (self == [DTCoreTextFontDescriptor class])
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
36 {
696397a @Cocoanetics Removed DTCache, no longer necessary because we only support >= 4.3
authored
37 _fontCache = [[NSCache alloc] init];
75c4b1f @Cocoanetics reindented
authored
38
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
39 _fontQueue = dispatch_queue_create("DTCoreTextFontDescriptor", 0);
40
2c06877 @Cocoanetics cleanup
authored
41 // init/load of overrides
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
42 _fontOverrides = [[NSMutableDictionary alloc] init];
43
44 NSString *path = [[NSBundle mainBundle] pathForResource:@"DTCoreTextFontOverrides" ofType:@"plist"];
45 NSArray *fileArray = [NSArray arrayWithContentsOfFile:path];
46
47 for (NSDictionary *oneOverride in fileArray)
48 {
49 NSString *fontFamily = [oneOverride objectForKey:@"FontFamily"];
50 NSString *overrideFontName = [oneOverride objectForKey:@"OverrideFontName"];
51 BOOL bold = [[oneOverride objectForKey:@"Bold"] boolValue];
52 BOOL italic = [[oneOverride objectForKey:@"Italic"] boolValue];
53 BOOL smallcaps = [[oneOverride objectForKey:@"SmallCaps"] boolValue];
54
55 if (smallcaps)
56 {
57 [DTCoreTextFontDescriptor setSmallCapsFontName:overrideFontName forFontFamily:fontFamily bold:bold italic:italic];
58 }
59 else
60 {
61 [DTCoreTextFontDescriptor setOverrideFontName:overrideFontName forFontFamily:fontFamily bold:bold italic:italic];
62 }
63 }
64 }
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
65
957532d @Cocoanetics Fixed unit tests
authored
66 #if TARGET_OS_IPHONE
184ef08 @Cocoanetics activated chinese font cascade bug workaround for iOS 5.x
authored
67 // workaround for iOS 5.x bug: global font cascade table has incorrect bold font for Chinese characters in Chinese locale
d140d94 @Cocoanetics Moved DTZipArchive, DTHTMLParser and DTDownloadCache into their own l…
authored
68
69
70 DTVersion *version = [DTVersion osVersion];
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
71
aaf5992 @Cocoanetics Added test cases for known CoreText issues
authored
72 // seems to be fixed in iOS 6
c70a9b5 @Cocoanetics switched workaround DTVersion usage to new property names
authored
73 if (version.major<6)
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
74 {
75 _needsChineseFontCascadeFix = YES;
76 }
957532d @Cocoanetics Fixed unit tests
authored
77 #endif
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
78 }
79
80 + (void)setSmallCapsFontName:(NSString *)fontName forFontFamily:(NSString *)fontFamily bold:(BOOL)bold italic:(BOOL)italic
81 {
75c4b1f @Cocoanetics reindented
authored
82 NSString *key = [NSString stringWithFormat:@"%@-%d-%d-smallcaps", fontFamily, bold, italic];
83 [_fontOverrides setObject:fontName forKey:key];
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
84 }
85
86 + (NSString *)smallCapsFontNameforFontFamily:(NSString *)fontFamily bold:(BOOL)bold italic:(BOOL)italic
87 {
75c4b1f @Cocoanetics reindented
authored
88 NSString *key = [NSString stringWithFormat:@"%@-%d-%d-smallcaps", fontFamily, bold, italic];
89 return [_fontOverrides objectForKey:key];
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
90 }
91
92 + (void)setOverrideFontName:(NSString *)fontName forFontFamily:(NSString *)fontFamily bold:(BOOL)bold italic:(BOOL)italic
93 {
75c4b1f @Cocoanetics reindented
authored
94 NSString *key = [NSString stringWithFormat:@"%@-%d-%d-override", fontFamily, bold, italic];
95 [_fontOverrides setObject:fontName forKey:key];
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
96 }
97
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
98 + (NSString *)overrideFontNameforFontFamily:(NSString *)fontFamily bold:(BOOL)bold italic:(BOOL)italic
99 {
75c4b1f @Cocoanetics reindented
authored
100 NSString *key = [NSString stringWithFormat:@"%@-%d-%d-override", fontFamily, bold, italic];
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
101 return [_fontOverrides objectForKey:key];
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
102 }
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
103
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
104 #pragma mark Initializing
105
1ab25c2 @Cocoanetics Added new files
authored
106 + (DTCoreTextFontDescriptor *)fontDescriptorWithFontAttributes:(NSDictionary *)attributes
107 {
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
108 return [[DTCoreTextFontDescriptor alloc] initWithFontAttributes:attributes];
1ab25c2 @Cocoanetics Added new files
authored
109 }
110
feb1899 @Cocoanetics method to create CTFont from descriptor
authored
111 + (DTCoreTextFontDescriptor *)fontDescriptorForCTFont:(CTFontRef)ctFont
112 {
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
113 return [[DTCoreTextFontDescriptor alloc] initWithCTFont:ctFont];
feb1899 @Cocoanetics method to create CTFont from descriptor
authored
114 }
115
1ab25c2 @Cocoanetics Added new files
authored
116 - (id)initWithFontAttributes:(NSDictionary *)attributes
117 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
118 self = [super init];
feb1899 @Cocoanetics method to create CTFont from descriptor
authored
119 if (self)
1ab25c2 @Cocoanetics Added new files
authored
120 {
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
121 [self setFontAttributes:attributes];
1ab25c2 @Cocoanetics Added new files
authored
122 }
123
124 return self;
125 }
126
78f44ea @Cocoanetics added description and additional init
authored
127 - (id)initWithCTFontDescriptor:(CTFontDescriptorRef)ctFontDescriptor
128 {
129 self = [super init];
130 if (self)
131 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
132 CFDictionaryRef dict = CTFontDescriptorCopyAttributes(ctFontDescriptor);
133
134 CFDictionaryRef traitsDict = CTFontDescriptorCopyAttribute(ctFontDescriptor, kCTFontTraitsAttribute);
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
135 CTFontSymbolicTraits traitsValue = [[(__bridge NSDictionary *)traitsDict objectForKey:(id)kCTFontSymbolicTrait] unsignedIntValue];
136 CFRelease(traitsDict);
78f44ea @Cocoanetics added description and additional init
authored
137
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
138 self.symbolicTraits = traitsValue;
139
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
140 [self setFontAttributes:CFBridgingRelease(dict)];
78f44ea @Cocoanetics added description and additional init
authored
141
142 // also get family name
143
144 CFStringRef familyName = CTFontDescriptorCopyAttribute(ctFontDescriptor, kCTFontFamilyNameAttribute);
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
145 self.fontFamily = CFBridgingRelease(familyName);
78f44ea @Cocoanetics added description and additional init
authored
146 }
147
148 return self;
149 }
150
feb1899 @Cocoanetics method to create CTFont from descriptor
authored
151 - (id)initWithCTFont:(CTFontRef)ctFont
152 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
153 self = [super init];
154 if (self)
155 {
156 CTFontDescriptorRef fd = CTFontCopyFontDescriptor(ctFont);
157 CFDictionaryRef dict = CTFontDescriptorCopyAttributes(fd);
158
159 CFDictionaryRef traitsDict = CTFontDescriptorCopyAttribute(fd, kCTFontTraitsAttribute);
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
160 CTFontSymbolicTraits traitsValue = [[(__bridge NSDictionary *)traitsDict objectForKey:(id)kCTFontSymbolicTrait] unsignedIntValue];
161 CFRelease(traitsDict);
162 CFRelease(fd);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
163
164 self.symbolicTraits = traitsValue;
165
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
166 [self setFontAttributes:CFBridgingRelease(dict)];
167 //CFRelease(dict);
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
168
169 // also get the family while we're at it
170 CFStringRef cfStr = CTFontCopyFamilyName(ctFont);
171
172 if (cfStr)
173 {
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
174 self.fontFamily = CFBridgingRelease(cfStr);
175 //CFRelease(cfStr);
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
176 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
177 }
178
179 return self;
feb1899 @Cocoanetics method to create CTFont from descriptor
authored
180 }
181
182
1ab25c2 @Cocoanetics Added new files
authored
183
78f44ea @Cocoanetics added description and additional init
authored
184 - (NSString *)description
185 {
186 NSMutableString *string = [NSMutableString string];
187
188 [string appendFormat:@"<%@ ", [self class]];
189
190
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
191 if (self.fontName)
78f44ea @Cocoanetics added description and additional init
authored
192 {
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
193 [string appendFormat:@"name:\'%@\' ", self.fontName];
78f44ea @Cocoanetics added description and additional init
authored
194 }
195
196 if (fontFamily)
197 {
198 [string appendFormat:@"family:\'%@\' ", fontFamily];
199 }
200
201 NSMutableArray *tmpTraits = [NSMutableArray array];
202
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
203 if (_stylisticTraits & kCTFontBoldTrait)
78f44ea @Cocoanetics added description and additional init
authored
204 {
205 [tmpTraits addObject:@"bold"];
206 }
207
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
208 if (_stylisticTraits & kCTFontItalicTrait)
78f44ea @Cocoanetics added description and additional init
authored
209 {
210 [tmpTraits addObject:@"italic"];
211 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
212
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
213 if (_stylisticTraits & kCTFontMonoSpaceTrait)
78f44ea @Cocoanetics added description and additional init
authored
214 {
215 [tmpTraits addObject:@"monospace"];
216 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
217
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
218 if (_stylisticTraits & kCTFontCondensedTrait)
78f44ea @Cocoanetics added description and additional init
authored
219 {
220 [tmpTraits addObject:@"condensed"];
221 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
222
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
223 if (_stylisticTraits & kCTFontExpandedTrait)
78f44ea @Cocoanetics added description and additional init
authored
224 {
225 [tmpTraits addObject:@"expanded"];
226 }
227
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
228 if (_stylisticTraits & kCTFontVerticalTrait)
78f44ea @Cocoanetics added description and additional init
authored
229 {
230 [tmpTraits addObject:@"vertical"];
231 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
232
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
233 if (_stylisticTraits & kCTFontUIOptimizedTrait)
78f44ea @Cocoanetics added description and additional init
authored
234 {
235 [tmpTraits addObject:@"UI optimized"];
236 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
237
238
78f44ea @Cocoanetics added description and additional init
authored
239 if ([tmpTraits count])
240 {
241 [string appendString:@"attributes:"];
242 [string appendString:[tmpTraits componentsJoinedByString:@", "]];
243 }
244
245 [string appendString:@">"];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
246
78f44ea @Cocoanetics added description and additional init
authored
247 return string;
248 }
249
1ab25c2 @Cocoanetics Added new files
authored
250 - (CTFontSymbolicTraits)symbolicTraits
251 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
252 CTFontSymbolicTraits retValue = _stylisticTraits;
1ab25c2 @Cocoanetics Added new files
authored
253
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
254 // bundle in class
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
255 retValue |= _stylisticClass;
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
256
1ab25c2 @Cocoanetics Added new files
authored
257 return retValue;
258 }
259
260 - (NSDictionary *)fontAttributes
261 {
262 NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary];
263
264 NSMutableDictionary *traitsDict = [NSMutableDictionary dictionary];
265
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
266 CTFontSymbolicTraits theSymbolicTraits = _stylisticTraits | _stylisticClass;
1ab25c2 @Cocoanetics Added new files
authored
267
7851ca9 @BrianDoig Fixed compiler warnings when compiling with -Wshadow enabled
BrianDoig authored
268 if (theSymbolicTraits)
1ab25c2 @Cocoanetics Added new files
authored
269 {
7851ca9 @BrianDoig Fixed compiler warnings when compiling with -Wshadow enabled
BrianDoig authored
270 [traitsDict setObject:[NSNumber numberWithUnsignedInt:theSymbolicTraits] forKey:(id)kCTFontSymbolicTrait];
1ab25c2 @Cocoanetics Added new files
authored
271 }
272
273 if ([traitsDict count])
274 {
275 [tmpDict setObject:traitsDict forKey:(id)kCTFontTraitsAttribute];
276 }
277
278 if (fontFamily)
279 {
280 [tmpDict setObject:fontFamily forKey:(id)kCTFontFamilyNameAttribute];
281 }
282
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
283 if (fontName)
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
284 {
cf7a578 @Cocoanetics Extended the overriding possibility in DTCoreTextFontDescriptor so th…
authored
285 [tmpDict setObject:fontName forKey:(id)kCTFontNameAttribute];
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
286 }
287
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
288 // we need size because that's what makes a font unique, for searching it's ignored anyway
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
289 [tmpDict setObject:[NSNumber numberWithFloat:_pointSize] forKey:(id)kCTFontSizeAttribute];
1ab25c2 @Cocoanetics Added new files
authored
290
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
291
292 if (smallCapsFeature)
293 {
294 NSNumber *typeNum = [NSNumber numberWithInteger:3];
295 NSNumber *selNum = [NSNumber numberWithInteger:3];
296
297 NSDictionary *setting = [NSDictionary dictionaryWithObjectsAndKeys:selNum, (id)kCTFontFeatureSelectorIdentifierKey,
75c4b1f @Cocoanetics reindented
authored
298 typeNum, (id)kCTFontFeatureTypeIdentifierKey, nil];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
299
300 NSArray *featureSettings = [NSArray arrayWithObject:setting];
301
302 [tmpDict setObject:featureSettings forKey:(id)kCTFontFeatureSettingsAttribute];
303 }
304
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
305 if (!self.boldTrait && _needsChineseFontCascadeFix)
306 {
307 CTFontDescriptorRef desc = CTFontDescriptorCreateWithNameAndSize(CFSTR("STHeitiSC-Light"), self.pointSize);
308
309 [tmpDict setObject:[NSArray arrayWithObject:(__bridge_transfer id) desc] forKey:(id)kCTFontCascadeListAttribute];
310 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
311
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
312 //return [NSDictionary dictionaryWithDictionary:tmpDict];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
313 // converting to non-mutable costs 42% of entire method
314 return tmpDict;
1ab25c2 @Cocoanetics Added new files
authored
315 }
316
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
317 - (NSDictionary *)fontAttributesWithOverrideFontName:(NSString *)overrideFontName
318 {
319 NSMutableDictionary *tmpAttributes = [[self fontAttributes] mutableCopy];
320
321 // remove family
322 [tmpAttributes removeObjectForKey:(id)kCTFontFamilyNameAttribute];
323
324 // replace font name
325 [tmpAttributes setObject:overrideFontName forKey:(id)kCTFontNameAttribute];
326
327 return tmpAttributes;
328 }
329
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
330 - (BOOL)supportsNativeSmallCaps
331 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
332 if ([DTCoreTextFontDescriptor smallCapsFontNameforFontFamily:fontFamily bold:self.boldTrait italic:self.italicTrait])
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
333 {
334 return YES;
335 }
336
337 CTFontRef tmpFont = [self newMatchingFont];
338
339 BOOL smallCapsSupported = NO;
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
340
341 // check if this font supports small caps
342 CFArrayRef fontFeatures = CTFontCopyFeatures(tmpFont);
343
344 if (fontFeatures)
345 {
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
346 for (NSDictionary *oneFeature in (__bridge NSArray *)fontFeatures)
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
347 {
348 NSInteger featureTypeIdentifier = [[oneFeature objectForKey:(id)kCTFontFeatureTypeIdentifierKey] integerValue];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
349
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
350 if (featureTypeIdentifier == 3) // Letter Case
351 {
352 NSArray *featureSelectors = [oneFeature objectForKey:(id)kCTFontFeatureTypeSelectorsKey];
353
354 for (NSDictionary *oneFeatureSelector in featureSelectors)
355 {
356 NSInteger featureSelectorIdentifier = [[oneFeatureSelector objectForKey:(id)kCTFontFeatureSelectorIdentifierKey] integerValue];
357
358 if (featureSelectorIdentifier == 3) // Small Caps
359 {
360 // hooray, small caps supported!
361 smallCapsSupported = YES;
362
363 break;
364 }
365 }
366
367 break;
368 }
369 }
370
371 CFRelease(fontFeatures);
372 }
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
373
374 CFRelease(tmpFont);
375
376 return smallCapsSupported;
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
377 }
378
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
379 #pragma mark Finding Font
380
9ddfe56 @Cocoanetics made checking if font needs synthesized obliqueness more robust
authored
381 - (BOOL)_fontIsOblique:(CTFontRef)font
382 {
383 NSDictionary *traits = (__bridge_transfer NSDictionary *)CTFontCopyTraits(font);
384
385 CGFloat slant = [[traits objectForKey:(id)kCTFontSlantTrait] floatValue];
386 BOOL hasItalicTrait = ([[traits objectForKey:(id)kCTFontSymbolicTrait] unsignedIntValue] & kCTFontItalicTrait) ==kCTFontItalicTrait;
387
d0e8c80 @Cocoanetics reverted supposed fix for #178 because it breaks normal font handling.
authored
388 if (!hasItalicTrait || slant<0.01)
9ddfe56 @Cocoanetics made checking if font needs synthesized obliqueness more robust
authored
389 {
e68b0ae @Cocoanetics Adjusted detection of font obliqueness
authored
390 return NO;
9ddfe56 @Cocoanetics made checking if font needs synthesized obliqueness more robust
authored
391 }
392
e68b0ae @Cocoanetics Adjusted detection of font obliqueness
authored
393 // font HAS italic trait AND sufficient slant angle
394 return YES;
9ddfe56 @Cocoanetics made checking if font needs synthesized obliqueness more robust
authored
395
396 }
397
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
398 - (CTFontRef)_findOrMakeMatchingFont
ecfe1c2 @Cocoanetics Removed unnecessary font searching, not needed if a font descriptor h…
authored
399 {
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
400 NSNumber *cacheKey = [NSNumber numberWithUnsignedInteger:[self hash]];
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
401
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
402 CTFontRef cachedFont = (__bridge_retained CTFontRef)[_fontCache objectForKey:cacheKey];
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
403
404 if (cachedFont)
405 {
753e6ce @dhoerl used a dispatch semaphore to protect newMatchingFont
dhoerl authored
406 return cachedFont;
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
407 }
408
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
409 CTFontDescriptorRef fontDesc = NULL;
410
411 CTFontRef matchingFont;
412
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
413 NSString *overrideName = nil;
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
414
415 // override fontName if a small caps or regular override is registered
416 if (fontFamily)
417 {
418 if (smallCapsFeature)
419 {
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
420 overrideName = [DTCoreTextFontDescriptor smallCapsFontNameforFontFamily:fontFamily bold:self.boldTrait italic:self.italicTrait];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
421 }
422 else
423 {
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
424 overrideName = [DTCoreTextFontDescriptor overrideFontNameforFontFamily:fontFamily bold:self.boldTrait italic:self.italicTrait];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
425 }
426 }
427
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
428 // if we use the chinese font cascade fix we cannot use fast method as it does not allow specifying the custom cascade list
429 BOOL useFastFontCreation = !(_needsChineseFontCascadeFix && !self.boldTrait);
430
431 if (useFastFontCreation && (fontName || overrideName))
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
432 {
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
433 NSString *usedName = overrideName?overrideName:fontName;
434
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
435 matchingFont = CTFontCreateWithName((__bridge CFStringRef)usedName, _pointSize, NULL);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
436 }
437 else
438 {
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
439 NSDictionary *attributes;
440
441 if (overrideName)
442 {
443 attributes = [self fontAttributesWithOverrideFontName:overrideName];
444 }
445 else
446 {
447 attributes = [self fontAttributes];
448 }
449
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
450 fontDesc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attributes);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
451
de2de5c @Cocoanetics Workaround for iOS 5.0 bug: incorrect entry in global font cascade ta…
authored
452 // we need font family, font name or an overridden font name for fast font creation
453 if (fontFamily||fontName||overrideName)
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
454 {
455 // fast font creation
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
456 matchingFont = CTFontCreateWithFontDescriptor(fontDesc, _pointSize, NULL);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
457 }
458 else
459 {
460 // without font name or family we need to do expensive search
461 // otherwise we always get Helvetica
462
463 NSMutableSet *set = [NSMutableSet setWithObject:(id)kCTFontTraitsAttribute];
464
465 if (fontFamily)
466 {
467 [set addObject:(id)kCTFontFamilyNameAttribute];
468 }
469
470 if (smallCapsFeature)
471 {
472 [set addObject:(id)kCTFontFeaturesAttribute];
473 }
474
05aa188 @dhoerl Looking real good now - no leaks
dhoerl authored
475 CTFontDescriptorRef matchingDesc = CTFontDescriptorCreateMatchingFontDescriptor(fontDesc, (__bridge CFSetRef)set);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
476
477 if (matchingDesc)
478 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
479 matchingFont = CTFontCreateWithFontDescriptor(matchingDesc, _pointSize, NULL);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
480 CFRelease(matchingDesc);
481 }
482 else
483 {
484 matchingFont = nil;
485 }
486 }
487
13285cb @Cocoanetics Added synthesizing obliqueness for fonts that don't have an oblique f…
authored
488 // check if we indeed got an oblique font if we wanted one
489
490 if (matchingFont)
491 {
492 if (self.italicTrait)
493 {
9ddfe56 @Cocoanetics made checking if font needs synthesized obliqueness more robust
authored
494 if (![self _fontIsOblique:matchingFont])
13285cb @Cocoanetics Added synthesizing obliqueness for fonts that don't have an oblique f…
authored
495 {
496 // need to synthesize slant
497 CGAffineTransform slantMatrix = { 1, 0, 0.25, 1, 0, 0 };
498
499 CFRelease(matchingFont);
500 matchingFont = CTFontCreateWithFontDescriptor(fontDesc, _pointSize, &slantMatrix);
501 }
502 }
503 }
504
505 CFRelease(fontDesc);
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
506 }
507
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
508 if (matchingFont)
509 {
510 // cache it
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
511 [_fontCache setObject:(__bridge id)(matchingFont) forKey:cacheKey];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
512 }
02fb2f3 @Cocoanetics replaced GCD semaphore with queue, moved init of cache and override t…
authored
513
514 return matchingFont; // returns a +1 reference
515 }
516
517 - (CTFontRef)newMatchingFont
518 {
519 __block CTFontRef retFont;
520
521 // all calls get queued
522 dispatch_sync(_fontQueue, ^{
523 retFont = [self _findOrMakeMatchingFont];
524 });
525
526 return retFont;
ecfe1c2 @Cocoanetics Removed unnecessary font searching, not needed if a font descriptor h…
authored
527 }
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
528
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
529 // two font descriptors are equal if their attributes has identical hash codes
cb61b5d @Cocoanetics Added experimental font caching
authored
530 - (NSUInteger)hash
531 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
532 NSUInteger calcHash = 7;
533
534 calcHash = calcHash*31 + _pointSize;
535 calcHash = calcHash*31 + (_stylisticClass | _stylisticTraits);
536 calcHash = calcHash*31 + [fontName hash];
537 calcHash = calcHash*31 + [fontFamily hash];
538
539 return calcHash;
cb61b5d @Cocoanetics Added experimental font caching
authored
540 }
541
542 - (BOOL)isEqual:(id)object
543 {
a961041 @Cocoanetics Applied John's Magic
authored
544 return (([object isKindOfClass:[DTCoreTextFontDescriptor class]]) && ([self hash] == [object hash]));
cb61b5d @Cocoanetics Added experimental font caching
authored
545 }
546
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
547
548 #pragma mark NSCoding
549
550 - (void)encodeWithCoder:(NSCoder *)encoder
551 {
552 [encoder encodeObject:self.fontName forKey:@"FontName"];
553 [encoder encodeObject:self.fontFamily forKey:@"FontFamily"];
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
554 [encoder encodeBool:self.boldTrait forKey:@"BoldTrait"];
555 [encoder encodeBool:self.italicTrait forKey:@"ItalicTrait"];
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
556 }
557
558 - (id)initWithCoder:(NSCoder *)decoder
559 {
560 self = [super init];
561
562 if (self)
563 {
564 self.fontName = [decoder decodeObjectForKey:@"FontName"];
565 self.fontFamily = [decoder decodeObjectForKey:@"FontFamily"];
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
566 self.boldTrait = [decoder decodeBoolForKey:@"BoldTrait"];
567 self.italicTrait = [decoder decodeBoolForKey:@"ItalicTrait"];
9dcfd0f @Cocoanetics added global font matching cache to speed up font creation
authored
568 }
569
570 return self;
571 }
572
573
1ab25c2 @Cocoanetics Added new files
authored
574 #pragma mark Copying
575
576 - (id)copyWithZone:(NSZone *)zone
577 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
578 DTCoreTextFontDescriptor *newDesc = [[DTCoreTextFontDescriptor allocWithZone:zone] initWithFontAttributes:[self fontAttributes]];
579 newDesc.pointSize = self.pointSize;
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
580 if (_stylisticClass)
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
581 {
582 newDesc.stylisticClass = self.stylisticClass;
583 }
584
585 return newDesc;
1ab25c2 @Cocoanetics Added new files
authored
586 }
587
588
589 #pragma mark Properties
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
590 - (void)setStylisticClass:(CTFontStylisticClass)newClass
591 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
592 self.fontFamily = nil;
593
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
594 _stylisticClass = newClass;
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
595 }
596
597
598 - (void)setFontAttributes:(NSDictionary *)attributes
599 {
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
600 if (!attributes)
601 {
602 self.fontFamily = nil;
0a5cbf6 @dhoerl18 When nilling attributes, nil the name and symbolicTraits too.
dhoerl18 authored
603 self.fontName = nil;
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
604 self.pointSize = 12;
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
605
606 _stylisticTraits = 0;
607 _stylisticClass = 0;
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
608 }
609
610 NSDictionary *traitsDict = [attributes objectForKey:(id)kCTFontTraitsAttribute];
611
612 if (traitsDict)
613 {
614 CTFontSymbolicTraits traitsValue = [[traitsDict objectForKey:(id)kCTFontSymbolicTrait ] unsignedIntValue];
615 self.symbolicTraits = traitsValue;
616 }
617
618 NSNumber *pointNum = [attributes objectForKey:(id)kCTFontSizeAttribute];
619 if (pointNum)
620 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
621 _pointSize = [pointNum floatValue];
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
622 }
623
624 NSString *family = [attributes objectForKey:(id)kCTFontFamilyNameAttribute];
625
626 if (family)
627 {
628 self.fontFamily = family;
629 }
630
631 NSString *name = [attributes objectForKey:(id)kCTFontNameAttribute];
632
633 if (name)
634 {
635 self.fontName = name;
636 }
f4b290c @Cocoanetics Add method to copy stylistic traits between font descriptors, option …
authored
637 }
638
7851ca9 @BrianDoig Fixed compiler warnings when compiling with -Wshadow enabled
BrianDoig authored
639 - (void)setSymbolicTraits:(CTFontSymbolicTraits)theSymbolicTraits
f4b290c @Cocoanetics Add method to copy stylistic traits between font descriptors, option …
authored
640 {
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
641 _stylisticTraits = theSymbolicTraits;
7528d11 @jonsterling Normalized indentation (tabs)
jonsterling authored
642
643 // stylistic class is bundled in the traits
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
644 _stylisticClass = theSymbolicTraits & kCTFontClassMaskTrait;
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
645 }
646
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
647
648 // a representation of this font in CSS style
649 - (NSString *)cssStyleRepresentation
650 {
651 NSMutableString *retString = [NSMutableString string];
652
653 if (fontFamily)
654 {
655 [retString appendFormat:@"font-family:'%@';", fontFamily];
656 }
657
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
658 [retString appendFormat:@"font-size:%.0fpx;", _pointSize];
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
659
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
660 if (self.italicTrait)
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
661 {
662 [retString appendString:@"font-style:italic;"];
663 }
664
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
665 if (self.boldTrait)
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
666 {
667 [retString appendString:@"font-weight:bold;"];
668 }
75c4b1f @Cocoanetics reindented
authored
669
fa18eb7 @Cocoanetics Beginnings of generating HTML from NSAttributedStrings.
authored
670 // return nil if no content
671 if ([retString length])
672 {
673 return retString;
674 }
675 else
676 {
677 return nil;
678 }
679 }
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
680
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
681 - (void)setBoldTrait:(BOOL)boldTrait
682 {
683 if (boldTrait)
684 {
685 _stylisticTraits |= kCTFontBoldTrait;
686 }
687 else
688 {
689 _stylisticTraits &= ~kCTFontBoldTrait;
690 }
691 }
692
693 - (BOOL)boldTrait
694 {
695 return (_stylisticTraits & kCTFontBoldTrait)!=0;
696 }
697
698 - (void)setItalicTrait:(BOOL)italicTrait
699 {
700 if (italicTrait)
701 {
702 _stylisticTraits |= kCTFontItalicTrait;
703 }
704 else
705 {
706 _stylisticTraits &= ~kCTFontItalicTrait;
707 }
708 }
709
710 - (BOOL)italicTrait
711 {
712 return (_stylisticTraits & kCTFontItalicTrait)!=0;
713 }
714
715 - (void)setExpandedTrait:(BOOL)expandedTrait
716 {
717 if (expandedTrait)
718 {
719 _stylisticTraits |= kCTFontExpandedTrait;
720 }
721 else
722 {
723 _stylisticTraits &= ~kCTFontExpandedTrait;
724 }
725 }
726
727 - (BOOL)expandedTrait
728 {
729 return (_stylisticTraits & kCTFontExpandedTrait)!=0;
730 }
731
732 - (void)setCondensedTrait:(BOOL)condensedTrait
733 {
734 if (condensedTrait)
735 {
736 _stylisticTraits |= kCTFontCondensedTrait;
737 }
738 else
739 {
740 _stylisticTraits &= ~kCTFontCondensedTrait;
741 }
742 }
743
744 - (BOOL)condensedTrait
745 {
746 return (_stylisticTraits & kCTFontCondensedTrait)!=0;
747 }
748
749 - (void)setMonospaceTrait:(BOOL)monospaceTrait
750 {
751 if (monospaceTrait)
752 {
753 _stylisticTraits |= kCTFontMonoSpaceTrait;
754 }
755 else
756 {
757 _stylisticTraits &= ~kCTFontMonoSpaceTrait;
758 }
759 }
760
761 - (BOOL)monospaceTrait
762 {
763 return (_stylisticTraits & kCTFontMonoSpaceTrait)!=0;
764 }
765
766 - (void)setVerticalTrait:(BOOL)verticalTrait
767 {
768 if (verticalTrait)
769 {
770 _stylisticTraits |= kCTFontVerticalTrait;
771 }
772 else
773 {
774 _stylisticTraits &= ~kCTFontVerticalTrait;
775 }
776 }
777
778 - (BOOL)verticalTrait
779 {
780 return (_stylisticTraits & kCTFontVerticalTrait)!=0;
781 }
782
783 - (void)setUIoptimizedTrait:(BOOL)UIoptimizedTrait
784 {
785 if (UIoptimizedTrait)
786 {
787 _stylisticTraits |= kCTFontUIOptimizedTrait;
788 }
789 else
790 {
791 _stylisticTraits &= ~kCTFontUIOptimizedTrait;
792 }
793 }
794
795 - (BOOL)UIoptimizedTrait
796 {
797 return (_stylisticTraits & kCTFontUIOptimizedTrait)!=0;
798 }
799
800 - (void)setPointSize:(CGFloat)pointSize
801 {
802 _pointSize = roundf(pointSize);
803 }
804
1ab25c2 @Cocoanetics Added new files
authored
805 @synthesize fontFamily;
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
806 @synthesize fontName;
394620a @Cocoanetics performance improvements on DTCoreTextFontDescriptor. Moved the styli…
authored
807 @synthesize pointSize = _pointSize;
1ab25c2 @Cocoanetics Added new files
authored
808
f4b290c @Cocoanetics Add method to copy stylistic traits between font descriptors, option …
authored
809 @synthesize symbolicTraits;
810
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
811 @synthesize stylisticClass;
fd640f1 @Cocoanetics cleaned up native small caps support. A new class method allows speci…
authored
812 @synthesize smallCapsFeature;
e5220b0 @Cocoanetics Added font searching to DTCoreTextFontDescriptor
authored
813
1ab25c2 @Cocoanetics Added new files
authored
814 @end
815
Something went wrong with that request. Please try again.