| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
| 4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 | 62 |
| 63 if (obj->isBox()) | 63 if (obj->isBox()) |
| 64 return toLayoutBox(obj)->createInlineBox(); | 64 return toLayoutBox(obj)->createInlineBox(); |
| 65 | 65 |
| 66 return toRenderInline(obj)->createAndAppendInlineFlowBox(); | 66 return toRenderInline(obj)->createAndAppendInlineFlowBox(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) | 69 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) |
| 70 { | 70 { |
| 71 ASSERT(run.m_object->isText()); | 71 ASSERT(run.m_object->isText()); |
| 72 RenderText* text = toRenderText(run.m_object); | 72 LayoutText* text = toLayoutText(run.m_object); |
| 73 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); | 73 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); |
| 74 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode | 74 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode |
| 75 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) | 75 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) |
| 76 if (text->isBR()) | 76 if (text->isBR()) |
| 77 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); | 77 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); |
| 78 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); | 78 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); |
| 79 if (run.m_hasHyphen) | 79 if (run.m_hasHyphen) |
| 80 textBox->setHasHyphen(true); | 80 textBox->setHasHyphen(true); |
| 81 return textBox; | 81 return textBox; |
| 82 } | 82 } |
| 83 | 83 |
| 84 static inline void dirtyLineBoxesForRenderer(LayoutObject* o, bool fullLayout) | 84 static inline void dirtyLineBoxesForRenderer(LayoutObject* o, bool fullLayout) |
| 85 { | 85 { |
| 86 if (o->isText()) { | 86 if (o->isText()) { |
| 87 RenderText* renderText = toRenderText(o); | 87 LayoutText* renderText = toLayoutText(o); |
| 88 renderText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); | 88 renderText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); |
| 89 } else | 89 } else |
| 90 toRenderInline(o)->dirtyLineBoxes(fullLayout); | 90 toRenderInline(o)->dirtyLineBoxes(fullLayout); |
| 91 } | 91 } |
| 92 | 92 |
| 93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) | 93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) |
| 94 { | 94 { |
| 95 do { | 95 do { |
| 96 if (parentBox->isConstructed() || parentBox->nextOnLine()) | 96 if (parentBox->isConstructed() || parentBox->nextOnLine()) |
| 97 return true; | 97 return true; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 | 175 |
| 176 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) | 176 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) |
| 177 { | 177 { |
| 178 BidiRun* run = bidiRuns.logicallyLastRun(); | 178 BidiRun* run = bidiRuns.logicallyLastRun(); |
| 179 if (!run) | 179 if (!run) |
| 180 return true; | 180 return true; |
| 181 unsigned pos = run->stop(); | 181 unsigned pos = run->stop(); |
| 182 LayoutObject* r = run->m_object; | 182 LayoutObject* r = run->m_object; |
| 183 if (!r->isText() || r->isBR()) | 183 if (!r->isText() || r->isBR()) |
| 184 return false; | 184 return false; |
| 185 RenderText* renderText = toRenderText(r); | 185 LayoutText* renderText = toLayoutText(r); |
| 186 unsigned length = renderText->textLength(); | 186 unsigned length = renderText->textLength(); |
| 187 if (pos >= length) | 187 if (pos >= length) |
| 188 return true; | 188 return true; |
| 189 | 189 |
| 190 if (renderText->is8Bit()) | 190 if (renderText->is8Bit()) |
| 191 return endsWithASCIISpaces(renderText->characters8(), pos, length); | 191 return endsWithASCIISpaces(renderText->characters8(), pos, length); |
| 192 return endsWithASCIISpaces(renderText->characters16(), pos, length); | 192 return endsWithASCIISpaces(renderText->characters16(), pos, length); |
| 193 } | 193 } |
| 194 | 194 |
| 195 RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
nst LineInfo& lineInfo) | 195 RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
nst LineInfo& lineInfo) |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { | 358 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { |
| 359 nextObject = runWithNextObject->m_object; | 359 nextObject = runWithNextObject->m_object; |
| 360 break; | 360 break; |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); | 363 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); |
| 364 setMarginStartForChild(*renderer, -startOverhang); | 364 setMarginStartForChild(*renderer, -startOverhang); |
| 365 setMarginEndForChild(*renderer, -endOverhang); | 365 setMarginEndForChild(*renderer, -endOverhang); |
| 366 } | 366 } |
| 367 | 367 |
| 368 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, RenderText* renderer, float xPos, const LineInfo& lineInfo, | 368 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, LayoutText* renderer, float xPos, const LineInfo& lineInfo, |
| 369 GlyphOverflowAndFallbackFontsMap& t
extBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& w
ordMeasurements) | 369 GlyphOverflowAndFallbackFontsMap& t
extBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& w
ordMeasurements) |
| 370 { | 370 { |
| 371 HashSet<const SimpleFontData*> fallbackFonts; | 371 HashSet<const SimpleFontData*> fallbackFonts; |
| 372 GlyphOverflow glyphOverflow; | 372 GlyphOverflow glyphOverflow; |
| 373 | 373 |
| 374 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 374 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); |
| 375 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". | 375 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". |
| 376 if (lineBox->fitsToGlyphs()) { | 376 if (lineBox->fitsToGlyphs()) { |
| 377 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization | 377 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization |
| 378 // will keep us from computing glyph bounds in nearly all cases. | 378 // will keep us from computing glyph bounds in nearly all cases. |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 LayoutObject* previousObject = 0; | 586 LayoutObject* previousObject = 0; |
| 587 TextJustify textJustify = style()->textJustify(); | 587 TextJustify textJustify = style()->textJustify(); |
| 588 | 588 |
| 589 BidiRun* r = firstRun; | 589 BidiRun* r = firstRun; |
| 590 for (; r; r = r->next()) { | 590 for (; r; r = r->next()) { |
| 591 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) | 591 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) |
| 592 continue; // Positioned objects are only participating to figure out
their | 592 continue; // Positioned objects are only participating to figure out
their |
| 593 // correct static x position. They have no effect on the
width. | 593 // correct static x position. They have no effect on the
width. |
| 594 // Similarly, line break boxes have no effect on the width
. | 594 // Similarly, line break boxes have no effect on the width
. |
| 595 if (r->m_object->isText()) { | 595 if (r->m_object->isText()) { |
| 596 RenderText* rt = toRenderText(r->m_object); | 596 LayoutText* rt = toLayoutText(r->m_object); |
| 597 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { | 597 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { |
| 598 if (!isAfterExpansion) | 598 if (!isAfterExpansion) |
| 599 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); | 599 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); |
| 600 unsigned opportunitiesInRun; | 600 unsigned opportunitiesInRun; |
| 601 if (rt->is8Bit()) | 601 if (rt->is8Bit()) |
| 602 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion, textJustify); | 602 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion, textJustify); |
| 603 else | 603 else |
| 604 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion, textJustify); | 604 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion, textJustify); |
| 605 expansionOpportunities.append(opportunitiesInRun); | 605 expansionOpportunities.append(opportunitiesInRun); |
| 606 expansionOpportunityCount += opportunitiesInRun; | 606 expansionOpportunityCount += opportunitiesInRun; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 continue; // Skip runs with no line boxes. | 653 continue; // Skip runs with no line boxes. |
| 654 | 654 |
| 655 // Align positioned boxes with the top of the line box. This is | 655 // Align positioned boxes with the top of the line box. This is |
| 656 // a reasonable approximation of an appropriate y position. | 656 // a reasonable approximation of an appropriate y position. |
| 657 if (r->m_object->isOutOfFlowPositioned()) | 657 if (r->m_object->isOutOfFlowPositioned()) |
| 658 r->m_box->setLogicalTop(logicalHeight().toFloat()); | 658 r->m_box->setLogicalTop(logicalHeight().toFloat()); |
| 659 | 659 |
| 660 // Position is used to properly position both replaced elements and | 660 // Position is used to properly position both replaced elements and |
| 661 // to update the static normal flow x/y of positioned elements. | 661 // to update the static normal flow x/y of positioned elements. |
| 662 if (r->m_object->isText()) | 662 if (r->m_object->isText()) |
| 663 toRenderText(r->m_object)->positionLineBox(r->m_box); | 663 toLayoutText(r->m_object)->positionLineBox(r->m_box); |
| 664 else if (r->m_object->isBox()) | 664 else if (r->m_object->isBox()) |
| 665 toLayoutBox(r->m_object)->positionLineBox(r->m_box); | 665 toLayoutBox(r->m_object)->positionLineBox(r->m_box); |
| 666 } | 666 } |
| 667 } | 667 } |
| 668 | 668 |
| 669 void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObj
ect) | 669 void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObj
ect) |
| 670 { | 670 { |
| 671 ASSERT(!floatingObject->originatingLine()); | 671 ASSERT(!floatingObject->originatingLine()); |
| 672 floatingObject->setOriginatingLine(lastRootBox()); | 672 floatingObject->setOriginatingLine(lastRootBox()); |
| 673 lastRootBox()->appendFloat(floatingObject->renderer()); | 673 lastRootBox()->appendFloat(floatingObject->renderer()); |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, | 1167 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, |
| 1168 LayoutObject* trailingSpaceChild) | 1168 LayoutObject* trailingSpaceChild) |
| 1169 { | 1169 { |
| 1170 if (trailingSpaceChild && trailingSpaceChild->isText()) { | 1170 if (trailingSpaceChild && trailingSpaceChild->isText()) { |
| 1171 // Collapse away the trailing space at the end of a block by finding | 1171 // Collapse away the trailing space at the end of a block by finding |
| 1172 // the first white-space character and subtracting its width. Subsequent | 1172 // the first white-space character and subtracting its width. Subsequent |
| 1173 // white-space characters have been collapsed into the first one (which | 1173 // white-space characters have been collapsed into the first one (which |
| 1174 // can be either a space or a tab character). | 1174 // can be either a space or a tab character). |
| 1175 RenderText* text = toRenderText(trailingSpaceChild); | 1175 LayoutText* text = toLayoutText(trailingSpaceChild); |
| 1176 UChar trailingWhitespaceChar = ' '; | 1176 UChar trailingWhitespaceChar = ' '; |
| 1177 for (unsigned i = text->textLength(); i > 0; i--) { | 1177 for (unsigned i = text->textLength(); i > 0; i--) { |
| 1178 UChar c = text->characterAt(i - 1); | 1178 UChar c = text->characterAt(i - 1); |
| 1179 if (!Character::treatAsSpace(c)) | 1179 if (!Character::treatAsSpace(c)) |
| 1180 break; | 1180 break; |
| 1181 trailingWhitespaceChar = c; | 1181 trailingWhitespaceChar = c; |
| 1182 } | 1182 } |
| 1183 | 1183 |
| 1184 // FIXME: This ignores first-line. | 1184 // FIXME: This ignores first-line. |
| 1185 const Font& font = text->style()->font(); | 1185 const Font& font = text->style()->font(); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 } | 1382 } |
| 1383 | 1383 |
| 1384 // We are no longer stripping whitespace at the start of | 1384 // We are no longer stripping whitespace at the start of |
| 1385 // a line. | 1385 // a line. |
| 1386 if (!child->isFloating()) { | 1386 if (!child->isFloating()) { |
| 1387 stripFrontSpaces = false; | 1387 stripFrontSpaces = false; |
| 1388 trailingSpaceChild = 0; | 1388 trailingSpaceChild = 0; |
| 1389 } | 1389 } |
| 1390 } else if (child->isText()) { | 1390 } else if (child->isText()) { |
| 1391 // Case (3). Text. | 1391 // Case (3). Text. |
| 1392 RenderText* t = toRenderText(child); | 1392 LayoutText* t = toLayoutText(child); |
| 1393 | 1393 |
| 1394 if (t->isWordBreak()) { | 1394 if (t->isWordBreak()) { |
| 1395 minLogicalWidth = std::max(minLogicalWidth, inlineMin.toLayo
utUnit()); | 1395 minLogicalWidth = std::max(minLogicalWidth, inlineMin.toLayo
utUnit()); |
| 1396 inlineMin = FloatWillBeLayoutUnit(); | 1396 inlineMin = FloatWillBeLayoutUnit(); |
| 1397 continue; | 1397 continue; |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 // Determine if we have a breakable character. Pass in | 1400 // Determine if we have a breakable character. Pass in |
| 1401 // whether or not we should ignore any spaces at the front | 1401 // whether or not we should ignore any spaces at the front |
| 1402 // of the string. If those are going to be stripped out, | 1402 // of the string. If those are going to be stripped out, |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 RootInlineBox* next = curr->nextRootBox(); | 1704 RootInlineBox* next = curr->nextRootBox(); |
| 1705 curr->deleteLine(); | 1705 curr->deleteLine(); |
| 1706 curr = next; | 1706 curr = next; |
| 1707 } | 1707 } |
| 1708 ASSERT(!firstLineBox() && !lastLineBox()); | 1708 ASSERT(!firstLineBox() && !lastLineBox()); |
| 1709 } else { | 1709 } else { |
| 1710 if (curr) { | 1710 if (curr) { |
| 1711 // We have a dirty line. | 1711 // We have a dirty line. |
| 1712 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { | 1712 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { |
| 1713 // We have a previous line. | 1713 // We have a previous line. |
| 1714 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo
otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->
lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))) | 1714 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo
otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->
lineBreakPos() >= toLayoutText(prevRootBox->lineBreakObj())->textLength()))) |
| 1715 // The previous line didn't break cleanly or broke at a newl
ine | 1715 // The previous line didn't break cleanly or broke at a newl
ine |
| 1716 // that has been deleted, so treat it as dirty too. | 1716 // that has been deleted, so treat it as dirty too. |
| 1717 curr = prevRootBox; | 1717 curr = prevRootBox; |
| 1718 } | 1718 } |
| 1719 } else { | 1719 } else { |
| 1720 // No dirty lines were found. | 1720 // No dirty lines were found. |
| 1721 // If the last line didn't break cleanly, treat it as dirty. | 1721 // If the last line didn't break cleanly, treat it as dirty. |
| 1722 if (lastRootBox() && !lastRootBox()->endsWithBreak()) | 1722 if (lastRootBox() && !lastRootBox()->endsWithBreak()) |
| 1723 curr = lastRootBox(); | 1723 curr = lastRootBox(); |
| 1724 } | 1724 } |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2048 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
| 2049 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2049 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
| 2050 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2050 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
| 2051 | 2051 |
| 2052 if (!style()->isLeftToRightDirection()) | 2052 if (!style()->isLeftToRightDirection()) |
| 2053 return logicalWidth() - logicalLeft; | 2053 return logicalWidth() - logicalLeft; |
| 2054 return logicalLeft; | 2054 return logicalLeft; |
| 2055 } | 2055 } |
| 2056 | 2056 |
| 2057 } | 2057 } |
| OLD | NEW |