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;
182 return _CPFontSystemFontSize - 2;
185 return _CPFontSystemFontSize;
192 + (float)setSystemFontSize:(
float)size
194 if (size > 0 && size !== _CPFontSystemFontSize)
196 [
self _invalidateSystemFontCache];
197 _CPFontSystemFontSize = size;
201 + (void)_invalidateSystemFontCache
203 var systemSize = String(_CPFontSystemFontSize),
206 for (key in _CPSystemFontCache)
208 if (_CPSystemFontCache.hasOwnProperty(key) &&
209 (key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
211 delete _CPSystemFontCache[key];
225 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, NO);
238 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, italic);
250 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, NO);
263 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, italic);
269 + (
CPFont)_fontWithName:(
CPString)aName size:(
float)aSize bold:(BOOL)bold italic:(BOOL)italic
271 return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, bold, italic);
283 return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
293 + (
CPFont)boldSystemFontOfSize:(CPSize)aSize
295 return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
298 - (id)_initWithName:(
CPString)aName size:(
float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic system:(BOOL)isSystem
309 _isItalic = isItalic;
310 _isSystem = isSystem;
315 _cssString = _CPFontCreateCSSString(_CPFontSystemFontFace, _size, _isBold, _isItalic);
316 _CPSystemFontCache[_CPSystemFontCacheKey(_size, _isBold)] =
self;
320 _name = _CPFontNormalizedNames(aName);
321 _cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
322 _CPFontCache[_cssString] =
self;
334 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
339 return font._ascender;
348 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
350 if (!font._descender)
353 return font._descender;
361 - (float)defaultLineHeightForFont
363 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
365 if (!font._lineHeight)
368 return font._lineHeight;
376 return _CPRealFontSize(_size);
384 var font = _isSystem ? _CPSystemFont(_size, _isBold) :
self;
386 return font._cssString;
395 return _CPFontSystemFontFace;
407 return [anObject isKindOfClass:[
CPFont class]] && [anObject cssString] === _cssString;
417 return [[
CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic system:_isSystem];
424 _ascender = [metrics objectForKey:@"ascender"];
425 _descender = [metrics objectForKey:@"descender"];
426 _lineHeight = [metrics objectForKey:@"lineHeight"];
446 var fontName = [aCoder decodeObjectForKey:CPFontNameKey],
447 size = [aCoder decodeFloatForKey:CPFontSizeKey],
448 isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey],
449 isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey],
450 isSystem = [aCoder decodeBoolForKey:CPFontIsSystemKey];
452 return [
self _initWithName:fontName size:size bold:isBold italic:isItalic system:isSystem];
461 [aCoder encodeObject:_name forKey:CPFontNameKey];
462 [aCoder encodeFloat:_size forKey:CPFontSizeKey];
463 [aCoder encodeBool:_isBold forKey:CPFontIsBoldKey];
464 [aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey];
465 [aCoder encodeBool:_isSystem forKey:CPFontIsSystemKey];
472 var _CPFontCreateCSSString =
function(aName, aSize, isBold, isItalic)
474 var properties = (isItalic ?
"italic " :
"") + (isBold ?
"bold " :
"") + _CPRealFontSize(aSize) + "px ";
476 return properties + _CPFontConcatNameWithFallback(aName);
479 var _CPFontConcatNameWithFallback =
function(aName)
481 var names = _CPFontNormalizedNameArray(aName),
482 fallbackFaces = _CPFontFallbackFaces.slice(0);
485 for (var i = 0; i < names.length; ++i)
487 for (var j = 0; j < fallbackFaces.length; ++j)
489 if (names[i].toLowerCase() === fallbackFaces[j].toLowerCase())
491 fallbackFaces.splice(j, 1);
496 if (names[i].indexOf(
" ") > 0)
497 names[i] =
'"' + names[i] + '"';
500 return names.concat(fallbackFaces).join(
", ");
503 var _CPFontNormalizedNameArray =
function(aName)
505 var names = aName.split(
",");
507 for (var i = 0; i < names.length; ++i)
508 names[i] = names[i].replace(_CPFontStripRegExp, "");