35 _CPFontSystemFacePlaceholder =
"_CPFontSystemFacePlaceholder";
37 var _CPFontCache = {},
38 _CPSystemFontCache = {},
40 _CPFontSystemFontSize = 12,
42 _CPFontStripRegExp =
new RegExp(
"(^\\s*[\"']?|[\"']?\\s*$)",
"g");
45 #define _CPRealFontSize(aSize) (aSize <= 0 ? _CPFontSystemFontSize : aSize)
46 #define _CPFontNormalizedNames(aName) _CPFontNormalizedNameArray(aName).join(", ")
47 #define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFontCache[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
48 #define _CPUserFont(aName, aSize, isBold, isItalic) _CPCachedFont(aName, aSize, isBold, isItalic) || [[CPFont alloc] _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO]
50 #define _CPSystemFontCacheKey(aSize, isBold) (String(aSize) + (isBold ? "b" : ""))
51 #define _CPCachedSystemFont(aSize, isBold) _CPSystemFontCache[_CPSystemFontCacheKey(aSize, isBold)]
52 #define _CPSystemFont(aSize, isBold) (_CPCachedSystemFont(aSize, isBold) || [[CPFont alloc] _initWithName:_CPFontSystemFacePlaceholder size:aSize bold:isBold italic:NO system:YES])
124 if (
self !== [
CPFont class])
133 _CPFontSystemFontFace = _CPFontNormalizedNames(systemFontFace);
141 _CPFontSystemFontSize = systemFontSize;
149 return _CPFontSystemFontFace;
157 var normalizedFaces = _CPFontNormalizedNames(aFace);
159 if (normalizedFaces === _CPFontSystemFontFace)
162 [
self _invalidateSystemFontCache]
163 _CPFontSystemFontFace = aFace;
169 + (float)systemFontSize
171 return _CPFontSystemFontSize;
174 + (float)systemFontSizeForControlSize:(CPControlSize)aSize
180 return _CPFontSystemFontSize - 1;
183 return _CPFontSystemFontSize - 2;
187 return _CPFontSystemFontSize;
194 + (float)setSystemFontSize:(
float)size
196 if (size > 0 && size !== _CPFontSystemFontSize)
198 [
self _invalidateSystemFontCache];
199 _CPFontSystemFontSize = size;
203 + (void)_invalidateSystemFontCache
205 var systemSize = String(_CPFontSystemFontSize),
208 for (var key in _CPSystemFontCache)
210 if (_CPSystemFontCache.hasOwnProperty(key) &&
211 (key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
213 delete _CPSystemFontCache[key];
227 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, NO);
240 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, italic);
252 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, NO);
265 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, italic);
271 + (
CPFont)_fontWithName:(
CPString)aName size:(
float)aSize bold:(BOOL)bold italic:(BOOL)italic
273 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, bold, italic);
285 return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
295 + (
CPFont)boldSystemFontOfSize:(CGSize)aSize
297 return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
300 - (id)_initWithName:(
CPString)aName size:(
float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic system:(BOOL)isSystem
311 _isItalic = isItalic;
312 _isSystem = isSystem;
317 _cssString = _CPFontCreateCSSString(_CPFontSystemFontFace, _size, _isBold, _isItalic);
318 _CPSystemFontCache[_CPSystemFontCacheKey(_size, _isBold)] =
self;
322 _name = _CPFontNormalizedNames(aName);
323 _cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
324 _CPFontCache[_cssString] =
self;
336 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
341 return font._ascender;
350 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
352 if (!font._descender)
355 return font._descender;
363 - (float)defaultLineHeightForFont
365 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
367 if (!font._lineHeight)
370 return font._lineHeight;
378 return _CPRealFontSize(_size);
386 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
388 return font._cssString;
397 return _CPFontSystemFontFace;
409 return [anObject isKindOfClass:[
CPFont class]] && [anObject cssString] === _cssString;
414 return [
CPString stringWithFormat:@"%@ %@", [
super description], [
self cssString]];
419 return [[
CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic system:_isSystem];
424 var metrics = [
CPString metricsOfFont:self];
426 _ascender = [metrics objectForKey:@"ascender"];
427 _descender = [metrics objectForKey:@"descender"];
428 _lineHeight = [metrics objectForKey:@"lineHeight"];
448 var fontName = [aCoder decodeObjectForKey:CPFontNameKey],
449 size = [aCoder decodeFloatForKey:CPFontSizeKey],
450 isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey],
451 isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey],
452 isSystem = [aCoder decodeBoolForKey:CPFontIsSystemKey];
454 return [
self _initWithName:fontName size:size bold:isBold italic:isItalic system:isSystem];
463 [aCoder encodeObject:_name forKey:CPFontNameKey];
464 [aCoder encodeFloat:_size forKey:CPFontSizeKey];
465 [aCoder encodeBool:_isBold forKey:CPFontIsBoldKey];
466 [aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey];
467 [aCoder encodeBool:_isSystem forKey:CPFontIsSystemKey];
474 var _CPFontCreateCSSString =
function(aName, aSize, isBold, isItalic)
476 var properties = (isItalic ?
"italic " :
"") + (isBold ?
"bold " :
"") + _CPRealFontSize(aSize) + "px ";
478 return properties + _CPFontConcatNameWithFallback(aName);
481 var _CPFontConcatNameWithFallback =
function(aName)
483 var names = _CPFontNormalizedNameArray(aName),
484 fallbackFaces = _CPFontFallbackFaces.slice(0);
487 for (var i = 0; i < names.length; ++i)
489 for (var j = 0; j < fallbackFaces.length; ++j)
491 if (names[i].toLowerCase() === fallbackFaces[j].toLowerCase())
493 fallbackFaces.splice(j, 1);
498 if (names[i].indexOf(
" ") > 0)
499 names[i] =
'"' + names[i] + '"';
502 return names.concat(fallbackFaces).join(
", ");
505 var _CPFontNormalizedNameArray =
function(aName)
507 var names = aName.split(
",");
509 for (var i = 0; i < names.length; ++i)
510 names[i] = names[i].replace(_CPFontStripRegExp, "");