| 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 toLayoutInline(obj)->createAndAppendInlineFlowBox(); | 66 return toLayoutInline(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 toLayoutInline(o)->dirtyLineBoxes(fullLayout); | 90 toLayoutInline(o)->dirtyLineBoxes(fullLayout); |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 | 93 |
| 94 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) | 94 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) |
| 95 { | 95 { |
| 96 do { | 96 do { |
| 97 if (parentBox->isConstructed() || parentBox->nextOnLine()) | 97 if (parentBox->isConstructed() || parentBox->nextOnLine()) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 | 176 |
| 177 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) | 177 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) |
| 178 { | 178 { |
| 179 BidiRun* run = bidiRuns.logicallyLastRun(); | 179 BidiRun* run = bidiRuns.logicallyLastRun(); |
| 180 if (!run) | 180 if (!run) |
| 181 return true; | 181 return true; |
| 182 unsigned pos = run->stop(); | 182 unsigned pos = run->stop(); |
| 183 LayoutObject* r = run->m_object; | 183 LayoutObject* r = run->m_object; |
| 184 if (!r->isText() || r->isBR()) | 184 if (!r->isText() || r->isBR()) |
| 185 return false; | 185 return false; |
| 186 RenderText* renderText = toRenderText(r); | 186 LayoutText* renderText = toLayoutText(r); |
| 187 unsigned length = renderText->textLength(); | 187 unsigned length = renderText->textLength(); |
| 188 if (pos >= length) | 188 if (pos >= length) |
| 189 return true; | 189 return true; |
| 190 | 190 |
| 191 if (renderText->is8Bit()) | 191 if (renderText->is8Bit()) |
| 192 return endsWithASCIISpaces(renderText->characters8(), pos, length); | 192 return endsWithASCIISpaces(renderText->characters8(), pos, length); |
| 193 return endsWithASCIISpaces(renderText->characters16(), pos, length); | 193 return endsWithASCIISpaces(renderText->characters16(), pos, length); |
| 194 } | 194 } |
| 195 | 195 |
| 196 RootInlineBox* LayoutBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
nst LineInfo& lineInfo) | 196 RootInlineBox* LayoutBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
nst LineInfo& lineInfo) |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { | 360 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { |
| 361 nextObject = runWithNextObject->m_object; | 361 nextObject = runWithNextObject->m_object; |
| 362 break; | 362 break; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); | 365 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); |
| 366 setMarginStartForChild(*renderer, -startOverhang); | 366 setMarginStartForChild(*renderer, -startOverhang); |
| 367 setMarginEndForChild(*renderer, -endOverhang); | 367 setMarginEndForChild(*renderer, -endOverhang); |
| 368 } | 368 } |
| 369 | 369 |
| 370 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, RenderText* renderer, float xPos, const LineInfo& lineInfo, | 370 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, LayoutText* renderer, float xPos, const LineInfo& lineInfo, |
| 371 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) | 371 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) |
| 372 { | 372 { |
| 373 HashSet<const SimpleFontData*> fallbackFonts; | 373 HashSet<const SimpleFontData*> fallbackFonts; |
| 374 GlyphOverflow glyphOverflow; | 374 GlyphOverflow glyphOverflow; |
| 375 | 375 |
| 376 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 376 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); |
| 377 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". | 377 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". |
| 378 if (lineBox->fitsToGlyphs()) { | 378 if (lineBox->fitsToGlyphs()) { |
| 379 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization | 379 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization |
| 380 // will keep us from computing glyph bounds in nearly all cases. | 380 // will keep us from computing glyph bounds in nearly all cases. |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 TextJustify textJustify = style()->textJustify(); | 590 TextJustify textJustify = style()->textJustify(); |
| 591 | 591 |
| 592 BidiRun* r = firstRun; | 592 BidiRun* r = firstRun; |
| 593 for (; r; r = r->next()) { | 593 for (; r; r = r->next()) { |
| 594 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) { | 594 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) { |
| 595 continue; // Positioned objects are only participating to figure out
their | 595 continue; // Positioned objects are only participating to figure out
their |
| 596 // correct static x position. They have no effect on the width. | 596 // correct static x position. They have no effect on the width. |
| 597 // Similarly, line break boxes have no effect on the width. | 597 // Similarly, line break boxes have no effect on the width. |
| 598 } | 598 } |
| 599 if (r->m_object->isText()) { | 599 if (r->m_object->isText()) { |
| 600 RenderText* rt = toRenderText(r->m_object); | 600 LayoutText* rt = toLayoutText(r->m_object); |
| 601 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { | 601 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { |
| 602 if (!isAfterExpansion) | 602 if (!isAfterExpansion) |
| 603 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); | 603 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); |
| 604 unsigned opportunitiesInRun; | 604 unsigned opportunitiesInRun; |
| 605 if (rt->is8Bit()) | 605 if (rt->is8Bit()) |
| 606 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion, textJustify); | 606 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion, textJustify); |
| 607 else | 607 else |
| 608 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion, textJustify); | 608 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion, textJustify); |
| 609 expansionOpportunities.append(opportunitiesInRun); | 609 expansionOpportunities.append(opportunitiesInRun); |
| 610 expansionOpportunityCount += opportunitiesInRun; | 610 expansionOpportunityCount += opportunitiesInRun; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 continue; // Skip runs with no line boxes. | 657 continue; // Skip runs with no line boxes. |
| 658 | 658 |
| 659 // Align positioned boxes with the top of the line box. This is | 659 // Align positioned boxes with the top of the line box. This is |
| 660 // a reasonable approximation of an appropriate y position. | 660 // a reasonable approximation of an appropriate y position. |
| 661 if (r->m_object->isOutOfFlowPositioned()) | 661 if (r->m_object->isOutOfFlowPositioned()) |
| 662 r->m_box->setLogicalTop(logicalHeight().toFloat()); | 662 r->m_box->setLogicalTop(logicalHeight().toFloat()); |
| 663 | 663 |
| 664 // Position is used to properly position both replaced elements and | 664 // Position is used to properly position both replaced elements and |
| 665 // to update the static normal flow x/y of positioned elements. | 665 // to update the static normal flow x/y of positioned elements. |
| 666 if (r->m_object->isText()) | 666 if (r->m_object->isText()) |
| 667 toRenderText(r->m_object)->positionLineBox(r->m_box); | 667 toLayoutText(r->m_object)->positionLineBox(r->m_box); |
| 668 else if (r->m_object->isBox()) | 668 else if (r->m_object->isBox()) |
| 669 toLayoutBox(r->m_object)->positionLineBox(r->m_box); | 669 toLayoutBox(r->m_object)->positionLineBox(r->m_box); |
| 670 } | 670 } |
| 671 } | 671 } |
| 672 | 672 |
| 673 void LayoutBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObj
ect) | 673 void LayoutBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObj
ect) |
| 674 { | 674 { |
| 675 ASSERT(!floatingObject->originatingLine()); | 675 ASSERT(!floatingObject->originatingLine()); |
| 676 floatingObject->setOriginatingLine(lastRootBox()); | 676 floatingObject->setOriginatingLine(lastRootBox()); |
| 677 lastRootBox()->appendFloat(floatingObject->renderer()); | 677 lastRootBox()->appendFloat(floatingObject->renderer()); |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 } | 1169 } |
| 1170 | 1170 |
| 1171 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, | 1171 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, |
| 1172 LayoutObject* trailingSpaceChild) | 1172 LayoutObject* trailingSpaceChild) |
| 1173 { | 1173 { |
| 1174 if (trailingSpaceChild && trailingSpaceChild->isText()) { | 1174 if (trailingSpaceChild && trailingSpaceChild->isText()) { |
| 1175 // Collapse away the trailing space at the end of a block by finding | 1175 // Collapse away the trailing space at the end of a block by finding |
| 1176 // the first white-space character and subtracting its width. Subsequent | 1176 // the first white-space character and subtracting its width. Subsequent |
| 1177 // white-space characters have been collapsed into the first one (which | 1177 // white-space characters have been collapsed into the first one (which |
| 1178 // can be either a space or a tab character). | 1178 // can be either a space or a tab character). |
| 1179 RenderText* text = toRenderText(trailingSpaceChild); | 1179 LayoutText* text = toLayoutText(trailingSpaceChild); |
| 1180 UChar trailingWhitespaceChar = ' '; | 1180 UChar trailingWhitespaceChar = ' '; |
| 1181 for (unsigned i = text->textLength(); i > 0; i--) { | 1181 for (unsigned i = text->textLength(); i > 0; i--) { |
| 1182 UChar c = text->characterAt(i - 1); | 1182 UChar c = text->characterAt(i - 1); |
| 1183 if (!Character::treatAsSpace(c)) | 1183 if (!Character::treatAsSpace(c)) |
| 1184 break; | 1184 break; |
| 1185 trailingWhitespaceChar = c; | 1185 trailingWhitespaceChar = c; |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 // FIXME: This ignores first-line. | 1188 // FIXME: This ignores first-line. |
| 1189 const Font& font = text->style()->font(); | 1189 const Font& font = text->style()->font(); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 } | 1386 } |
| 1387 | 1387 |
| 1388 // We are no longer stripping whitespace at the start of | 1388 // We are no longer stripping whitespace at the start of |
| 1389 // a line. | 1389 // a line. |
| 1390 if (!child->isFloating()) { | 1390 if (!child->isFloating()) { |
| 1391 stripFrontSpaces = false; | 1391 stripFrontSpaces = false; |
| 1392 trailingSpaceChild = 0; | 1392 trailingSpaceChild = 0; |
| 1393 } | 1393 } |
| 1394 } else if (child->isText()) { | 1394 } else if (child->isText()) { |
| 1395 // Case (3). Text. | 1395 // Case (3). Text. |
| 1396 RenderText* t = toRenderText(child); | 1396 LayoutText* t = toLayoutText(child); |
| 1397 | 1397 |
| 1398 if (t->isWordBreak()) { | 1398 if (t->isWordBreak()) { |
| 1399 minLogicalWidth = std::max(minLogicalWidth, inlineMin.toLayo
utUnit()); | 1399 minLogicalWidth = std::max(minLogicalWidth, inlineMin.toLayo
utUnit()); |
| 1400 inlineMin = FloatWillBeLayoutUnit(); | 1400 inlineMin = FloatWillBeLayoutUnit(); |
| 1401 continue; | 1401 continue; |
| 1402 } | 1402 } |
| 1403 | 1403 |
| 1404 // Determine if we have a breakable character. Pass in | 1404 // Determine if we have a breakable character. Pass in |
| 1405 // whether or not we should ignore any spaces at the front | 1405 // whether or not we should ignore any spaces at the front |
| 1406 // of the string. If those are going to be stripped out, | 1406 // of the string. If those are going to be stripped out, |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1708 RootInlineBox* next = curr->nextRootBox(); | 1708 RootInlineBox* next = curr->nextRootBox(); |
| 1709 curr->deleteLine(); | 1709 curr->deleteLine(); |
| 1710 curr = next; | 1710 curr = next; |
| 1711 } | 1711 } |
| 1712 ASSERT(!firstLineBox() && !lastLineBox()); | 1712 ASSERT(!firstLineBox() && !lastLineBox()); |
| 1713 } else { | 1713 } else { |
| 1714 if (curr) { | 1714 if (curr) { |
| 1715 // We have a dirty line. | 1715 // We have a dirty line. |
| 1716 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { | 1716 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { |
| 1717 // We have a previous line. | 1717 // We have a previous line. |
| 1718 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo
otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->
lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))) { | 1718 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo
otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->
lineBreakPos() >= toLayoutText(prevRootBox->lineBreakObj())->textLength()))) { |
| 1719 // The previous line didn't break cleanly or broke at a newl
ine | 1719 // The previous line didn't break cleanly or broke at a newl
ine |
| 1720 // that has been deleted, so treat it as dirty too. | 1720 // that has been deleted, so treat it as dirty too. |
| 1721 curr = prevRootBox; | 1721 curr = prevRootBox; |
| 1722 } | 1722 } |
| 1723 } | 1723 } |
| 1724 } else { | 1724 } else { |
| 1725 // No dirty lines were found. | 1725 // No dirty lines were found. |
| 1726 // If the last line didn't break cleanly, treat it as dirty. | 1726 // If the last line didn't break cleanly, treat it as dirty. |
| 1727 if (lastRootBox() && !lastRootBox()->endsWithBreak()) | 1727 if (lastRootBox() && !lastRootBox()->endsWithBreak()) |
| 1728 curr = lastRootBox(); | 1728 curr = lastRootBox(); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2053 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2053 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
| 2054 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2054 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
| 2055 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2055 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
| 2056 | 2056 |
| 2057 if (!style()->isLeftToRightDirection()) | 2057 if (!style()->isLeftToRightDirection()) |
| 2058 return logicalWidth() - logicalLeft; | 2058 return logicalWidth() - logicalLeft; |
| 2059 return logicalLeft; | 2059 return logicalLeft; |
| 2060 } | 2060 } |
| 2061 | 2061 |
| 2062 } | 2062 } |
| OLD | NEW |