Changeset 130851 in webkit
- Timestamp:
- Oct 9, 2012, 10:48:51 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r130850 r130851 1 2012-10-09 Enrica Casucci <enrica@apple.com> 2 3 Only measure text once instead of twice when performing line layout. 4 https://bugs.webkit.org/show_bug.cgi?id=98317 5 <rdar://problem/12080821> 6 7 Reviewed by Dan Bernstein. 8 9 Since we are measuring each word to find out where the line break should occur, 10 we should cache that information to avoid measuring the run again when 11 creating the line box. The bulk of the change is in nextLineBreak, where 12 the measurements are collected and placed in a vector so that they can 13 be consumed in setLogicalWidthForTextRun where we used to measure the 14 text one more time. 15 Each entry in the vector is a WordMeasurement object that contains information 16 about the start and end offset in the run, the renderer, the measured width 17 and, possibly, a list of fallback fonts. 18 When we need to compute the width of the run to create the line box, we add 19 all the measurements for the given renderer in the run to get the total width. 20 This optiomization is currently disabled for platforms using HarfBuzz. 21 22 * platform/graphics/Font.cpp: 23 (WebCore::Font::width): Added fallback fonts parameter. 24 * platform/graphics/Font.h: 25 (Font): Added fallback fonts parameter to the width static member function. 26 This method is called when we compute the width using TextLayout. 27 * platform/graphics/mac/ComplexTextController.cpp: 28 (WebCore::TextLayout::width): Added fallback fonts parameter. 29 (WebCore::Font::width): 30 (WebCore::ComplexTextController::advance): 31 * platform/graphics/mac/ComplexTextController.h: 32 (ComplexTextController): Added fallback fonts parameter to advance method. 33 * rendering/RenderBlock.h: Added WordMeasures parameter to few methods. 34 * rendering/RenderBlockLineLayout.cpp: 35 (WordMeasurement): Added new class to hold measurement information. 36 (WebCore::setLogicalWidthForTextRun): This is where we compute the run width using the 37 cached information. 38 (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Added wordMeasures parameter. 39 (WebCore::RenderBlock::createLineBoxesFromBidiRuns): Added wordMeasures parameter. 40 (WebCore::RenderBlock::layoutRunsAndFloatsInRange): Added declaration of the WordMeasures 41 vector and its use. 42 (WebCore::textWidth): Added fallbackFonts parameter, since now we only measure once. 43 (WebCore::RenderBlock::LineBreaker::nextLineBreak): This method has been modified to collect 44 the measurements of the individual words and add them to the vector. 45 1 46 2012-10-09 Andreas Kling <kling@webkit.org> 2 47 -
trunk/Source/WebCore/platform/graphics/Font.cpp
r130820 r130851 221 221 } 222 222 223 float Font::width(TextLayout&, unsigned, unsigned )223 float Font::width(TextLayout&, unsigned, unsigned, HashSet<const SimpleFontData*>*) 224 224 { 225 225 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/platform/graphics/Font.h
r130820 r130851 106 106 PassOwnPtr<TextLayout> createLayout(RenderText*, float xPos, bool collapseWhiteSpace) const; 107 107 static void deleteLayout(TextLayout*); 108 static float width(TextLayout&, unsigned from, unsigned len );108 static float width(TextLayout&, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts = 0); 109 109 110 110 int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const; -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
r130820 r130851 55 55 } 56 56 57 float width(unsigned from, unsigned len )57 float width(unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts) 58 58 { 59 m_controller->advance(from, 0, ByWholeGlyphs );59 m_controller->advance(from, 0, ByWholeGlyphs, fallbackFonts); 60 60 float beforeWidth = m_controller->runWidthSoFar(); 61 61 if (m_font.wordSpacing() && from && Font::treatAsSpace(m_run[from])) 62 62 beforeWidth += m_font.wordSpacing(); 63 m_controller->advance(from + len, 0, ByWholeGlyphs );63 m_controller->advance(from + len, 0, ByWholeGlyphs, fallbackFonts); 64 64 float afterWidth = m_controller->runWidthSoFar(); 65 65 return afterWidth - beforeWidth; … … 95 95 } 96 96 97 float Font::width(TextLayout& layout, unsigned from, unsigned len )98 { 99 return layout.width(from, len );97 float Font::width(TextLayout& layout, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts) 98 { 99 return layout.width(from, len, fallbackFonts); 100 100 } 101 101 … … 461 461 } 462 462 463 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle )463 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle, HashSet<const SimpleFontData*>* fallbackFonts) 464 464 { 465 465 if (static_cast<int>(offset) > m_end) … … 486 486 unsigned g = ltr ? m_glyphInCurrentRun : glyphCount - 1 - m_glyphInCurrentRun; 487 487 unsigned k = leftmostGlyph + g; 488 if (fallbackFonts && complexTextRun.fontData() != m_font.primaryFont()) 489 fallbackFonts->add(complexTextRun.fontData()); 488 490 489 491 while (m_glyphInCurrentRun < glyphCount) { -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h
r130820 r130851 55 55 56 56 // Advance and emit glyphs up to the specified character. 57 void advance(unsigned to, GlyphBuffer* = 0, GlyphIterationStyle = IncludePartialGlyphs );57 void advance(unsigned to, GlyphBuffer* = 0, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const SimpleFontData*>* fallbackFonts = 0); 58 58 59 59 // Compute the character offset for a given x coordinate. -
trunk/Source/WebCore/rendering/RenderBlock.h
r130820 r130851 54 54 class RenderRubyRun; 55 55 class TextLayout; 56 class WordMeasurement; 56 57 57 58 template <class Iterator, class Run> class BidiResolver; … … 63 64 typedef WTF::HashMap<const RenderBlock*, TrackedRendererListHashSet*> TrackedDescendantsMap; 64 65 typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> TrackedContainerMap; 66 typedef Vector<WordMeasurement, 64> WordMeasurements; 65 67 66 68 enum CaretType { CursorCaret, DragCaret }; … … 730 732 } 731 733 732 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines );734 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&); 733 735 734 736 bool lineWasHyphenated() { return m_hyphenated; } … … 758 760 void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&); 759 761 760 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache& );762 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&); 761 763 void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); 762 764 void deleteEllipsisLineBoxes(); … … 964 966 965 967 // Helper function for layoutInlineChildren() 966 RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun );968 RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&); 967 969 void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild); 968 970 void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines); -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r130820 r130851 693 693 } 694 694 695 class WordMeasurement { 696 public: 697 WordMeasurement() 698 : renderer(0) 699 , width(0) 700 , startOffset(0) 701 , endOffset(0) 702 { 703 } 704 705 RenderText* renderer; 706 float width; 707 int startOffset; 708 int endOffset; 709 HashSet<const SimpleFontData*> fallbackFonts; 710 }; 711 695 712 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo, 696 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) 697 { 713 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements) 714 { 715 #if USE(HARFBUZZ_NG) 716 UNUSED_PARAM(wordMeasurements); 717 #endif 698 718 HashSet<const SimpleFontData*> fallbackFonts; 699 719 GlyphOverflow glyphOverflow; 700 720 721 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); 701 722 // Always compute glyph overflow if the block's line-box-contain value is "glyphs". 702 723 if (lineBox->fitsToGlyphs()) { … … 705 726 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); 706 727 int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache); 707 int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0;708 int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0;709 int boxAscent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift;710 int boxDescent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift;728 int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; 729 int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; 730 int boxAscent = font.fontMetrics().ascent() - baselineShift; 731 int boxDescent = font.fontMetrics().descent() + baselineShift; 711 732 if (boxAscent > rootDescent || boxDescent > rootAscent) 712 733 glyphOverflow.computeBounds = true; … … 718 739 hyphenWidth = measureHyphenWidth(renderer, font); 719 740 } 720 run->m_box->setLogicalWidth(renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth); 741 float measuredWidth = 0; 742 743 #if !USE(HARFBUZZ_NG) 744 bool kerningIsEnabled = font.typesettingFeatures() & Kerning; 745 746 // Since we don't cache glyph overflows, we need to re-measure the run if 747 // the style is linebox-contain: glyph. 748 749 if (!lineBox->fitsToGlyphs() && renderer->canUseSimpleFontCodePath()) { 750 int lastEndOffset = run->m_start; 751 for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) { 752 const WordMeasurement& wordMeasurement = wordMeasurements[i]; 753 if (wordMeasurement.width <=0 || wordMeasurement.startOffset == wordMeasurement.endOffset) 754 continue; 755 if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop) 756 continue; 757 758 lastEndOffset = wordMeasurement.endOffset; 759 if (kerningIsEnabled && lastEndOffset == run->m_stop) { 760 measuredWidth += renderer->width(wordMeasurement.startOffset, lastEndOffset - wordMeasurement.startOffset, xPos, lineInfo.isFirstLine()); 761 if (i > 0) 762 measuredWidth += renderer->style()->wordSpacing(); 763 } else 764 measuredWidth += wordMeasurement.width; 765 if (!wordMeasurement.fallbackFonts.isEmpty()) { 766 HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end(); 767 for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it) 768 fallbackFonts.add(*it); 769 } 770 } 771 if (measuredWidth && lastEndOffset != run->m_stop) { 772 // If we don't have enough cached data, we'll measure the run again. 773 measuredWidth = 0; 774 fallbackFonts.clear(); 775 } 776 } 777 #endif 778 779 if (!measuredWidth) 780 measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow); 781 782 run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); 721 783 if (!fallbackFonts.isEmpty()) { 722 784 ASSERT(run->m_box->isText()); … … 808 870 809 871 void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, 810 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache )872 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements) 811 873 { 812 874 ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak()); … … 855 917 } 856 918 857 setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache );919 setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements); 858 920 } else { 859 921 isAfterExpansion = false; … … 1082 1144 1083 1145 // This function constructs line boxes for all of the text runs in the resolver and computes their position. 1084 RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun )1146 RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements) 1085 1147 { 1086 1148 if (!bidiRuns.runCount()) … … 1106 1168 // Now we position all of our text runs horizontally. 1107 1169 if (!isSVGRootInlineBox) 1108 computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache );1170 computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements); 1109 1171 1110 1172 // Now position our text runs vertically. … … 1352 1414 } 1353 1415 #endif 1354 end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines); 1416 WordMeasurements wordMeasurements; 1417 end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); 1355 1418 if (resolver.position().atEnd()) { 1356 1419 // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with! … … 1394 1457 1395 1458 LayoutUnit oldLogicalHeight = logicalHeight(); 1396 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun );1459 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements); 1397 1460 1398 1461 bidiRuns.deleteRuns(); … … 2052 2115 } 2053 2116 2054 static inline float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, TextLayout* layout = 0) 2055 { 2117 static ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0, TextLayout* layout = 0) 2118 { 2119 GlyphOverflow glyphOverflow; 2056 2120 if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine()) 2057 return text->width(from, len, font, xPos );2121 return text->width(from, len, font, xPos, fallbackFonts, &glyphOverflow); 2058 2122 2059 2123 if (layout) 2060 return Font::width(*layout, from, len );2124 return Font::width(*layout, from, len, fallbackFonts); 2061 2125 2062 2126 TextRun run = RenderBlock::constructTextRun(text, font, text->characters() + from, len, text->style()); … … 2067 2131 run.setTabSize(!collapseWhiteSpace, text->style()->tabSize()); 2068 2132 run.setXPos(xPos); 2069 return font.width(run );2133 return font.width(run, fallbackFonts, &glyphOverflow); 2070 2134 } 2071 2135 … … 2221 2285 } 2222 2286 2223 InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines )2287 InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) 2224 2288 { 2225 2289 reset(); … … 2439 2503 float wordSpacing = currentStyle->wordSpacing(); 2440 2504 float lastSpaceWordSpacing = 0; 2505 float wordSpacingForWordMeasurement = 0; 2441 2506 2442 2507 float wrapW = width.uncommittedWidth() + inlineLogicalWidth(current.m_obj, !appliedStartWidth, true); … … 2494 2559 wrapW += charWidth; 2495 2560 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && current.m_pos + 1 < t->textLength() && U16_IS_TRAIL(t->characters()[current.m_pos + 1]); 2496 charWidth = textWidth(t, current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace, textLayout);2561 charWidth = textWidth(t, current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace, 0, textLayout); 2497 2562 midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth(); 2498 2563 } … … 2509 2574 ignoringSpaces = false; 2510 2575 lastSpaceWordSpacing = 0; 2576 wordSpacingForWordMeasurement = 0; 2511 2577 lastSpace = current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces. 2512 2578 addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos)); … … 2518 2584 } 2519 2585 2586 wordMeasurements.grow(wordMeasurements.size() + 1); 2587 WordMeasurement& wordMeasurement = wordMeasurements.last(); 2588 2589 wordMeasurement.renderer = t; 2590 wordMeasurement.endOffset = current.m_pos; 2591 wordMeasurement.startOffset = lastSpace; 2592 2520 2593 float additionalTmpW; 2521 2594 if (wordTrailingSpaceWidth && currentCharacterIsSpace) 2522 additionalTmpW = textWidth(t, lastSpace, current.m_pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) - wordTrailingSpaceWidth + lastSpaceWordSpacing;2595 additionalTmpW = textWidth(t, lastSpace, current.m_pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; 2523 2596 else 2524 additionalTmpW = textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + lastSpaceWordSpacing; 2597 additionalTmpW = textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); 2598 2599 wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasurement; 2600 additionalTmpW += lastSpaceWordSpacing; 2525 2601 width.addUncommittedWidth(additionalTmpW); 2526 2602 if (!appliedStartWidth) { … … 2529 2605 } 2530 2606 2531 applyWordSpacing = 2607 applyWordSpacing = wordSpacing && currentCharacterIsSpace; 2532 2608 2533 2609 if (!width.committedWidth() && autoWrap && !width.fitsOnLine()) … … 2539 2615 bool lineWasTooWide = false; 2540 2616 if (width.fitsOnLine() && currentCharacterIsWS && currentStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { 2541 float charWidth = textWidth(t, current.m_pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + (applyWordSpacing ? wordSpacing : 0);2617 float charWidth = textWidth(t, current.m_pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); 2542 2618 // Check if line is too big even without the extra space 2543 2619 // at the end of the line. If it is not, do nothing. … … 2565 2641 lBreak.increment(); 2566 2642 lineInfo.setPreviousLineBrokeCleanly(true); 2643 wordMeasurement.endOffset = lBreak.m_pos; 2567 2644 } 2568 2645 if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characters()[lBreak.m_pos - 1] == softHyphen && style->hyphens() != HyphensNone) 2569 2646 m_hyphenated = true; 2647 if (lBreak.m_pos && lBreak.m_pos != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) { 2648 if (charWidth) { 2649 wordMeasurement.endOffset = lBreak.m_pos; 2650 wordMeasurement.width = charWidth; 2651 } 2652 } 2570 2653 goto end; // Didn't fit. Jump to the end. 2571 2654 } else { … … 2610 2693 if (betweenWords) { 2611 2694 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 2695 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement.width) ? wordSpacing : 0; 2612 2696 lastSpace = current.m_pos; 2613 2697 } … … 2632 2716 ignoringSpaces = false; 2633 2717 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 2718 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurements.last().width) ? wordSpacing : 0; 2634 2719 lastSpace = current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces. 2635 2720 addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos)); … … 2664 2749 } 2665 2750 2751 wordMeasurements.grow(wordMeasurements.size() + 1); 2752 WordMeasurement& wordMeasurement = wordMeasurements.last(); 2753 wordMeasurement.renderer = t; 2754 2666 2755 // IMPORTANT: current.m_pos is > length here! 2667 float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + lastSpaceWordSpacing; 2756 float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); 2757 wordMeasurement.startOffset = lastSpace; 2758 wordMeasurement.endOffset = current.m_pos; 2759 wordMeasurement.width = ignoringSpaces ? 0 : additionalTmpW + wordSpacingForWordMeasurement; 2760 additionalTmpW += lastSpaceWordSpacing; 2668 2761 width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(current.m_obj, !appliedStartWidth, includeEndWidth)); 2669 2762 includeEndWidth = false;
Note:
See TracChangeset
for help on using the changeset viewer.