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 |