refactor private sizing method to sizeWithFont:

This commit is contained in:
daboe01
2015-05-10 15:12:31 +02:00
parent c4310c554e
commit 4d1fc994c0
2 changed files with 36 additions and 54 deletions
+35 -6
View File
@@ -26,7 +26,11 @@
@import "CPPlatformString.j"
var CPStringSizeWithFontInWidthCache = {};
var CPStringSizeWithFontInWidthCache = {},
CPStringSizeWithFontHeightCache = {},
CPStringSizeMeasuringContext,
CPStringSizeIsCanvasSizingInvalid,
CPStringSizeDidTestCanvasSizingValid;
CPStringSizeCachingEnabled = YES;
@@ -53,20 +57,45 @@ CPStringSizeCachingEnabled = YES;
return [self sizeWithFont:aFont inWidth:NULL];
}
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
{
if (!CPStringSizeCachingEnabled)
return [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
var cacheKey = self + [aFont cssString] + aWidth,
size = CPStringSizeWithFontInWidthCache[cacheKey];
var cssString = [aFont cssString],
cacheKey = self + cssString + aWidth,
size = CPStringSizeWithFontInWidthCache[cacheKey],
fontHeight = CPStringSizeWithFontHeightCache[cssString];
if (size === undefined)
if (size !== undefined)
return CGSizeMakeCopy(size);
if (fontHeight === undefined)
fontHeight = CPStringSizeWithFontHeightCache[cssString] = [aFont defaultLineHeightForFont];
if (!CPStringSizeMeasuringContext)
CPStringSizeMeasuringContext = CGBitmapGraphicsContextCreate();
if (!CPStringSizeDidTestCanvasSizingValid && CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
size = [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
CPStringSizeWithFontInWidthCache[cacheKey] = size;
var teststring = "0123456879abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-()";
CPStringSizeDidTestCanvasSizingValid = YES;
CPStringSizeMeasuringContext.font = cssString;
CPStringSizeIsCanvasSizingInvalid = ABS([teststring sizeWithFont:aFont].width - CPStringSizeMeasuringContext.measureText(teststring).width) > 2;
}
if (!CPFeatureIsCompatible(CPHTMLCanvasFeature) || CPStringSizeIsCanvasSizingInvalid)
size = [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
else
{
if (CPStringSizeMeasuringContext.font !== aFont)
CPStringSizeMeasuringContext.font = cssString;
size = CGSizeMake(CPStringSizeMeasuringContext.measureText(self), fontHeight);
}
CPStringSizeWithFontInWidthCache[cacheKey] = size;
return CGSizeMakeCopy(size);
}
+1 -48
View File
@@ -48,49 +48,7 @@ CPTypesetterLineBreakAction = 1 << 3;
CPTypesetterParagraphBreakAction = 1 << 4;
CPTypesetterContainerBreakAction = 1 << 5;
var _measuringContext,
_measuringContextFont,
_isCanvasSizingInvalid,
_didTestCanvasSizingValid,
_sharedSimpleTypesetter,
_sizingCache;
function _widthOfStringForFont(aString, aFont)
{
var peek,
cssString = [aFont cssString];
if (!_measuringContext)
_measuringContext = CGBitmapGraphicsContextCreate();
if (!_didTestCanvasSizingValid && CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
var teststring = "0123456879abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-()";
_didTestCanvasSizingValid = YES;
_measuringContext.font = cssString;
_isCanvasSizingInvalid = ABS([teststring sizeWithFont:aFont].width -_measuringContext.measureText(teststring).width) > 2;
}
if (!_sizingCache)
_sizingCache = [];
if (_sizingCache[cssString] !== undefined && (peek = _sizingCache[cssString][aString]) !== undefined)
return peek;
if (_sizingCache[cssString] === undefined)
_sizingCache[cssString] = [];
if (!CPFeatureIsCompatible(CPHTMLCanvasFeature) || _isCanvasSizingInvalid) // measuring with canvas is _much_ faster on chrome
return _sizingCache[cssString][aString] = [aString sizeWithFont:aFont];
if (_measuringContextFont !== aFont)
{
_measuringContextFont = aFont;
_measuringContext.font = cssString;
}
return _sizingCache[cssString][aString] = _measuringContext.measureText(aString);
}
var _sharedSimpleTypesetter;
var CPSystemTypesetterFactory;
@@ -348,12 +306,7 @@ var CPSystemTypesetterFactory;
var currentChar = theString[glyphIndex];
#if PLATFORM(DOM)
// use pure javascript methods for performance reasons -> why don't we use sizeWithFont ?
var rangeWidth = _widthOfStringForFont(theString.substr(measuringRange.location, measuringRange.length), _currentFont).width + currentAnchor;
#else
var rangeWidth = [theString.substr(measuringRange.location, measuringRange.length) sizeWithFont:_currentFont].width + currentAnchor;
#endif
switch (currentChar) // faster than sending actionForControlCharacterAtIndex: called for each char.
{