Changeset 85685 in webkit
- Timestamp:
- May 3, 2011 4:28:11 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r85684 r85685 1 2011-05-03 Levi Weintraub <leviw@chromium.org> 2 3 Reviewed by Eric Seidel. 4 5 Refactor computeInlineDirectionPositionsForLine into smaller functions 6 https://bugs.webkit.org/show_bug.cgi?id=60072 7 8 Split three functions off from computeInlineDirectionPositionsForLine 9 to improve its readability. 10 11 No new tests since this is just moving code around. 12 13 * rendering/RenderBlock.h: 14 * rendering/RenderBlockLineLayout.cpp: 15 (WebCore::RenderBlock::setMarginsForRubyRun): 16 (WebCore::setLogicalWidthForTextRun): 17 (WebCore::computeExpansionForJustifiedText): 18 (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): 19 1 20 2011-05-03 David Kilzer <ddkilzer@apple.com> 2 21 -
trunk/Source/WebCore/rendering/RenderBlock.h
r85668 r85685 45 45 struct PaintInfo; 46 46 class LineInfo; 47 class RenderRubyRun; 47 48 48 49 template <class Iterator, class Run> class BidiResolver; … … 507 508 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox); 508 509 510 void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&); 511 509 512 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); 510 513 void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r85668 r85685 444 444 } 445 445 446 void RenderBlock::setMarginsForRubyRun(BidiRun* run, RenderRubyRun* renderer, RenderObject* previousObject, const LineInfo& lineInfo) 447 { 448 int startOverhang; 449 int endOverhang; 450 RenderObject* nextObject = 0; 451 for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) { 452 if (!runWithNextObject->m_object->isPositioned() && !runWithNextObject->m_box->isLineBreak()) { 453 nextObject = runWithNextObject->m_object; 454 break; 455 } 456 } 457 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRightDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang); 458 setMarginStartForChild(renderer, -startOverhang); 459 setMarginEndForChild(renderer, -endOverhang); 460 } 461 462 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo, 463 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) 464 { 465 HashSet<const SimpleFontData*> fallbackFonts; 466 GlyphOverflow glyphOverflow; 467 468 // Always compute glyph overflow if the block's line-box-contain value is "glyphs". 469 if (lineBox->fitsToGlyphs()) { 470 // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization 471 // will keep us from computing glyph bounds in nearly all cases. 472 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); 473 int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache); 474 int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0; 475 int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0; 476 int boxAscent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift; 477 int boxDescent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift; 478 if (boxAscent > rootDescent || boxDescent > rootAscent) 479 glyphOverflow.computeBounds = true; 480 } 481 482 int hyphenWidth = 0; 483 if (static_cast<InlineTextBox*>(run->m_box)->hasHyphen()) { 484 const AtomicString& hyphenString = renderer->style()->hyphenString(); 485 hyphenWidth = renderer->style(lineInfo.isFirstLine())->font().width(TextRun(hyphenString.characters(), hyphenString.length())); 486 } 487 run->m_box->setLogicalWidth(renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth); 488 if (!fallbackFonts.isEmpty()) { 489 ASSERT(run->m_box->isText()); 490 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 491 ASSERT(it->second.first.isEmpty()); 492 copyToVector(fallbackFonts, it->second.first); 493 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); 494 } 495 if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) { 496 ASSERT(run->m_box->isText()); 497 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 498 it->second.second = glyphOverflow; 499 run->m_box->clearKnownToHaveNoOverflow(); 500 } 501 } 502 503 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth) 504 { 505 if (expansionOpportunityCount && availableLogicalWidth > totalLogicalWidth) { 506 size_t i = 0; 507 for (BidiRun* r = firstRun; r; r = r->next()) { 508 if (!r->m_box || r == trailingSpaceRun) 509 continue; 510 511 if (r->m_object->isText()) { 512 unsigned opportunitiesInRun = expansionOpportunities[i++]; 513 514 ASSERT(opportunitiesInRun <= expansionOpportunityCount); 515 516 // Only justify text if whitespace is collapsed. 517 if (r->m_object->style()->collapseWhiteSpace()) { 518 InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box); 519 float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount; 520 textBox->setExpansion(expansion); 521 totalLogicalWidth += expansion; 522 } 523 expansionOpportunityCount -= opportunitiesInRun; 524 if (!expansionOpportunityCount) 525 break; 526 } 527 } 528 } 529 } 530 446 531 void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, 447 532 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) … … 465 550 if (r->m_object->isText()) { 466 551 RenderText* rt = toRenderText(r->m_object); 467 468 552 if (textAlign == JUSTIFY && r != trailingSpaceRun) { 469 553 if (!isAfterExpansion) … … 479 563 needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length; 480 564 } 481 HashSet<const SimpleFontData*> fallbackFonts; 482 GlyphOverflow glyphOverflow; 483 484 // Always compute glyph overflow if the block's line-box-contain value is "glyphs". 485 if (lineBox->fitsToGlyphs()) { 486 // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization 487 // will keep us from computing glyph bounds in nearly all cases. 488 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); 489 int baselineShift = lineBox->verticalPositionForBox(r->m_box, verticalPositionCache); 490 int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0; 491 int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0; 492 int boxAscent = rt->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift; 493 int boxDescent = rt->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift; 494 if (boxAscent > rootDescent || boxDescent > rootAscent) 495 glyphOverflow.computeBounds = true; 496 } 497 498 int hyphenWidth = 0; 499 if (static_cast<InlineTextBox*>(r->m_box)->hasHyphen()) { 500 const AtomicString& hyphenString = rt->style()->hyphenString(); 501 hyphenWidth = rt->style(lineInfo.isFirstLine())->font().width(TextRun(hyphenString.characters(), hyphenString.length())); 502 } 503 r->m_box->setLogicalWidth(rt->width(r->m_start, r->m_stop - r->m_start, totalLogicalWidth, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth); 504 if (!fallbackFonts.isEmpty()) { 505 ASSERT(r->m_box->isText()); 506 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 507 ASSERT(it->second.first.isEmpty()); 508 copyToVector(fallbackFonts, it->second.first); 509 r->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); 510 } 511 if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) { 512 ASSERT(r->m_box->isText()); 513 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 514 it->second.second = glyphOverflow; 515 r->m_box->clearKnownToHaveNoOverflow(); 516 } 565 566 setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache); 517 567 } else { 518 568 isAfterExpansion = false; 519 569 if (!r->m_object->isRenderInline()) { 520 570 RenderBox* renderBox = toRenderBox(r->m_object); 521 if (renderBox->isRubyRun()) { 522 int startOverhang; 523 int endOverhang; 524 RenderObject* nextObject = 0; 525 for (BidiRun* runWithNextObject = r->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) { 526 if (!runWithNextObject->m_object->isPositioned() && !runWithNextObject->m_box->isLineBreak()) { 527 nextObject = runWithNextObject->m_object; 528 break; 529 } 530 } 531 toRenderRubyRun(renderBox)->getOverhang(lineInfo.isFirstLine(), renderBox->style()->isLeftToRightDirection() ? previousObject : nextObject, renderBox->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang); 532 setMarginStartForChild(renderBox, -startOverhang); 533 setMarginEndForChild(renderBox, -endOverhang); 534 } 571 if (renderBox->isRubyRun()) 572 setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo); 535 573 r->m_box->setLogicalWidth(logicalWidthForChild(renderBox)); 536 574 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox); … … 595 633 } 596 634 597 if (expansionOpportunityCount && availableLogicalWidth > totalLogicalWidth) { 598 size_t i = 0; 599 for (BidiRun* r = firstRun; r; r = r->next()) { 600 if (!r->m_box || r == trailingSpaceRun) 601 continue; 602 603 if (r->m_object->isText()) { 604 unsigned opportunitiesInRun = expansionOpportunities[i++]; 605 606 ASSERT(opportunitiesInRun <= expansionOpportunityCount); 607 608 // Only justify text if whitespace is collapsed. 609 if (r->m_object->style()->collapseWhiteSpace()) { 610 InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box); 611 float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount; 612 textBox->setExpansion(expansion); 613 totalLogicalWidth += expansion; 614 } 615 expansionOpportunityCount -= opportunitiesInRun; 616 if (!expansionOpportunityCount) 617 break; 618 } 619 } 620 } 635 computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth); 621 636 622 637 // The widths of all runs are now known. We can now place every inline box (and
Note: See TracChangeset
for help on using the changeset viewer.