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 |