42 _sharedSimpleTypesetter;
50 #pragma mark Class methods 57 + (id)sharedSystemTypesetter
59 return [CPSystemTypesetterFactory sharedInstance];
62 + (void)_setSystemTypesetterFactory:(Class)aClass
67 - (CPTypesetterControlCharacterAction)actionForControlCharacterAtIndex:(
unsigned)charIndex
82 - (CPArray)textContainers
88 startingAtGlyphIndex:(
unsigned)startGlyphIndex
89 maxNumberOfLineFragments:(
unsigned)maxNumLines
90 nextGlyphIndex:(UIntegerReference)nextGlyph
92 _CPRaiseInvalidAbstractInvocation(
self, _cmd);
103 CPRange _attributesRange;
111 unsigned _indexOfCurrentContainer;
113 CPArray _lineFragments;
118 #pragma mark Class methods 122 if (!_sharedSimpleTypesetter)
125 return _sharedSimpleTypesetter;
128 - (CPArray)textContainers
130 return [_layoutManager textContainers];
133 - (
CPTextTab)textTabForWidth:(
double)aWidth writingDirection:(CPWritingDirection)direction
135 var tabStops = [_currentParagraph tabStops];
140 var l = tabStops.length;
142 if (aWidth > tabStops[l - 1]._location)
145 for (var i = l - 1; i >= 0; i--)
147 if (aWidth > tabStops[i]._location)
150 return tabStops[i + 1];
160 - (BOOL)_flushRange:(CPRange)lineRange
161 lineOrigin:(CGPoint)lineOrigin
163 advancements:(CPArray)advancements
164 lineCount:(
unsigned)lineCount
165 sameLine:(BOOL)sameLine
168 rect = CGRectMake(lineOrigin.x, lineOrigin.y, _lineWidth, _lineHeight),
169 containerSize = aContainer._size;
171 [_layoutManager _appendNewLineFragmentInTextContainer:_currentTextContainer forGlyphRange:lineRange];
173 var fragment = [_layoutManager._lineFragments lastObject];
174 fragment._isLast = !sameLine;
175 _lineFragments.push(fragment);
177 [_layoutManager setLineFragmentRect:rect forGlyphRange:lineRange usedRect:rect];
179 switch ([_currentParagraph alignment])
186 myX = (containerSize.width - _lineWidth) / 2;
190 myX = containerSize.width - _lineWidth;
194 [_layoutManager setLocation:CGPointMake(myX, _lineBase) forStartOfGlyphRange:lineRange];
195 [_layoutManager _setAdvancements:advancements forGlyphRange:lineRange];
199 var l = _lineFragments.length;
201 for (var i = 0 ; i < l ; i++)
202 [_lineFragments[i] _adjustForHeight:_lineHeight];
208 if (aContainer._inResizing)
211 return ([_layoutManager _rescuingInvalidFragmentsWasPossibleForGlyphRange:lineRange]);
215 startingAtGlyphIndex:(
unsigned)glyphIndex
216 maxNumberOfLineFragments:(
unsigned)maxNumLines
217 nextGlyphIndex:(UIntegerReference)nextGlyph
219 var textContainers = [layoutManager textContainers],
220 textContainersCount = [textContainers count];
222 _layoutManager = layoutManager;
223 _textStorage = [_layoutManager textStorage];
224 _indexOfCurrentContainer = MAX(0, [textContainers
225 indexOfObject:[_layoutManager textContainerForGlyphAtIndex:glyphIndex effectiveRange:nil withoutAdditionalLayout:YES]
228 _currentTextContainer = textContainers[_indexOfCurrentContainer];
235 var containerSize = [_currentTextContainer containerSize],
236 containerSizeWidth = containerSize.width,
237 containerSizeHeight = containerSize.height,
244 numberOfGlyphs= [_textStorage length],
247 theString = [_textStorage string],
256 currentFontLineHeight,
258 currentParagraphMinimumLineHeight,
259 currentParagraphMaximumLineHeight,
260 currentParagraphLineSpacing;
263 lineOrigin = CGPointCreateCopy([_layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:nil].origin);
264 else if ([_layoutManager extraLineFragmentTextContainer])
265 lineOrigin = CGPointMake(0, [_layoutManager extraLineFragmentUsedRect].origin.y);
267 lineOrigin = CGPointMake(0, 0);
269 [_layoutManager _removeInvalidLineFragments];
271 if (![_textStorage length])
276 for (; numLines != maxNumLines && glyphIndex < numberOfGlyphs; glyphIndex++)
281 _currentAttributes = [_textStorage attributesAtIndex:glyphIndex effectiveRange:_attributesRange];
282 currentFont = [_currentAttributes objectForKey:CPFontAttributeName];
284 currentParagraphMinimumLineHeight = [_currentParagraph minimumLineHeight];
285 currentParagraphMaximumLineHeight = [_currentParagraph maximumLineHeight];
286 currentParagraphLineSpacing = [_currentParagraph lineSpacing];
291 ascent = [currentFont ascender];
292 descent = [currentFont descender];
293 leading = (ascent - descent) * 0.2;
295 currentFontLineHeight = ascent - descent + leading;
297 if (previousFont !== currentFont)
300 currentAnchor = prevRangeWidth;
301 previousFont = currentFont;
306 if (currentFontLineHeight > _lineHeight)
307 _lineHeight = currentFontLineHeight;
309 if (ascent > _lineBase)
313 measuringRange.length++;
315 var currentCharCode = theString.charCodeAt(glyphIndex),
316 rangeWidth = [theString.substr(measuringRange.location, measuringRange.length) _sizeWithFont:currentFont inWidth:NULL].width + currentAnchor;
318 switch (currentCharCode)
327 rangeWidth = nextTab._location - lineOrigin.x;
333 wrapWidth = rangeWidth;
334 wrapRange._height = _lineHeight;
335 wrapRange._base = _lineBase;
343 advancements.push({
width: rangeWidth - prevRangeWidth, height: ascent, descent: descent});
345 prevRangeWidth = _lineWidth = rangeWidth;
347 if (lineOrigin.x + rangeWidth > containerSizeWidth)
351 lineRange = wrapRange;
352 _lineWidth = wrapWidth;
353 _lineHeight = wrapRange._height;
354 _lineBase = wrapRange._base;
362 if (isNewline || isTabStop)
364 if ([
self _flushRange:lineRange lineOrigin:lineOrigin currentContainer:_currentTextContainer advancements:advancements lineCount:numLines sameLine:!isNewline])
369 lineOrigin.x += rangeWidth;
375 if (currentParagraphMinimumLineHeight && currentParagraphMinimumLineHeight > _lineHeight)
376 _lineHeight = currentParagraphMinimumLineHeight;
378 if (currentParagraphMaximumLineHeight && currentParagraphMaximumLineHeight < _lineHeight)
379 _lineHeight = currentParagraphMaximumLineHeight;
381 lineOrigin.y += _lineHeight;
383 if (currentParagraphLineSpacing)
384 lineOrigin.y += currentParagraphLineSpacing;
386 if (lineOrigin.y > containerSizeHeight && _indexOfCurrentContainer < textContainersCount - 1)
388 _currentTextContainer = textContainers[++_indexOfCurrentContainer];
389 containerSize = [_currentTextContainer containerSize];
390 containerSizeWidth = containerSize.width;
391 containerSizeHeight = containerSize.height;
415 if (lineRange.length)
417 [
self _flushRange:lineRange lineOrigin:lineOrigin currentContainer:_currentTextContainer advancements:advancements lineCount:numLines sameLine:NO];
420 var rect = CGRectMake(0, lineOrigin.y, containerSizeWidth, [_layoutManager._lineFragments lastObject]._usedRect.size.height - descent);
421 [_layoutManager setExtraLineFragmentRect:rect usedRect:rect textContainer:_currentTextContainer];
433 return _layoutManager;
441 _layoutManager = aValue;
449 return _currentTextContainer;
457 _currentTextContainer = aValue;
CPFont systemFontOfSize:(CGSize aSize)
CPTypesetterLineBreakAction
CPTypesetterZeroAdvancementAction
A mutable key-value pair collection.
var CPSystemTypesetterFactory
CPSTypesetterHorizontalTabAction
function CPMaxRange(aRange)
CPParagraphStyle defaultParagraphStyle()
CPTypesetterWhitespaceAction
function CPMakeRangeCopy(aRange)
function CPLocationInRange(aLocation, aRange)
CPTextAlignment CPLeftTextAlignment
CPTypesetterParagraphBreakAction
CPRange function CPMakeRange(location, length)
CPTypesetterContainerBreakAction
CPTextTab textTabForWidth:writingDirection:(double aWidth, [writingDirection] CPWritingDirection direction)