| 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) 2004, 2006, 2007, 2008 Apple Inc. All right reserved. | 3 * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All right reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 // these midpoints, so we just keep an array around and never clear it. We trac
k | 82 // these midpoints, so we just keep an array around and never clear it. We trac
k |
| 83 // the number of items and position using the two other variables. | 83 // the number of items and position using the two other variables. |
| 84 static Vector<InlineIterator>* smidpoints; | 84 static Vector<InlineIterator>* smidpoints; |
| 85 static unsigned sNumMidpoints; | 85 static unsigned sNumMidpoints; |
| 86 static unsigned sCurrMidpoint; | 86 static unsigned sCurrMidpoint; |
| 87 static bool betweenMidpoints; | 87 static bool betweenMidpoints; |
| 88 | 88 |
| 89 static bool isLineEmpty = true; | 89 static bool isLineEmpty = true; |
| 90 static bool previousLineBrokeCleanly = true; | 90 static bool previousLineBrokeCleanly = true; |
| 91 | 91 |
| 92 static int getBorderPaddingMargin(RenderBox* child, bool endOfInline) | 92 static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline) |
| 93 { | 93 { |
| 94 bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfI
nline; | 94 bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfI
nline; |
| 95 if (leftSide) | 95 if (leftSide) |
| 96 return child->marginLeft() + child->paddingLeft() + child->borderLeft(); | 96 return child->marginLeft() + child->paddingLeft() + child->borderLeft(); |
| 97 return child->marginRight() + child->paddingRight() + child->borderRight(); | 97 return child->marginRight() + child->paddingRight() + child->borderRight(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 static int inlineWidth(RenderObject* child, bool start = true, bool end = true) | 100 static int inlineWidth(RenderObject* child, bool start = true, bool end = true) |
| 101 { | 101 { |
| 102 unsigned lineDepth = 1; | 102 unsigned lineDepth = 1; |
| 103 int extraWidth = 0; | 103 int extraWidth = 0; |
| 104 RenderObject* parent = child->parent(); | 104 RenderObject* parent = child->parent(); |
| 105 while (parent->isBox() && parent->isInline() && !parent->isInlineBlockOrInli
neTable() && lineDepth++ < cMaxLineDepth) { | 105 while (parent->isInline() && !parent->isInlineBlockOrInlineTable() && lineDe
pth++ < cMaxLineDepth) { |
| 106 if (start && !child->previousSibling()) | 106 if (start && !child->previousSibling()) |
| 107 extraWidth += getBorderPaddingMargin(toRenderBox(parent), false); | 107 extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent),
false); |
| 108 if (end && !child->nextSibling()) | 108 if (end && !child->nextSibling()) |
| 109 extraWidth += getBorderPaddingMargin(toRenderBox(parent), true); | 109 extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent),
true); |
| 110 child = parent; | 110 child = parent; |
| 111 parent = child->parent(); | 111 parent = child->parent(); |
| 112 } | 112 } |
| 113 return extraWidth; | 113 return extraWidth; |
| 114 } | 114 } |
| 115 | 115 |
| 116 #ifndef NDEBUG | 116 #ifndef NDEBUG |
| 117 static WTF::RefCountedLeakCounter bidiRunCounter("BidiRun"); | 117 static WTF::RefCountedLeakCounter bidiRunCounter("BidiRun"); |
| 118 | 118 |
| 119 static bool inBidiRunDestroy; | 119 static bool inBidiRunDestroy; |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 | 789 |
| 790 // Walk all the lines and delete our ellipsis line boxes if they exist. | 790 // Walk all the lines and delete our ellipsis line boxes if they exist. |
| 791 if (hasTextOverflow) | 791 if (hasTextOverflow) |
| 792 deleteEllipsisLineBoxes(); | 792 deleteEllipsisLineBoxes(); |
| 793 | 793 |
| 794 if (firstChild()) { | 794 if (firstChild()) { |
| 795 // layout replaced elements | 795 // layout replaced elements |
| 796 bool endOfInline = false; | 796 bool endOfInline = false; |
| 797 RenderObject* o = bidiFirst(this, 0, false); | 797 RenderObject* o = bidiFirst(this, 0, false); |
| 798 Vector<FloatWithRect> floats; | 798 Vector<FloatWithRect> floats; |
| 799 int containerWidth = max(0, containingBlockWidth()); | |
| 800 while (o) { | 799 while (o) { |
| 801 o->invalidateVerticalPosition(); | 800 o->invalidateVerticalPosition(); |
| 802 if (o->isReplaced() || o->isFloating() || o->isPositioned()) { | 801 if (o->isReplaced() || o->isFloating() || o->isPositioned()) { |
| 803 RenderBox* box = toRenderBox(o); | 802 RenderBox* box = toRenderBox(o); |
| 804 | 803 |
| 805 if (relayoutChildren || o->style()->width().isPercent() || o->st
yle()->height().isPercent()) | 804 if (relayoutChildren || o->style()->width().isPercent() || o->st
yle()->height().isPercent()) |
| 806 o->setChildNeedsLayout(true, false); | 805 o->setChildNeedsLayout(true, false); |
| 807 | 806 |
| 808 // If relayoutChildren is set and we have percentage padding, we
also need to invalidate the child's pref widths. | 807 // If relayoutChildren is set and we have percentage padding, we
also need to invalidate the child's pref widths. |
| 809 if (relayoutChildren && (o->style()->paddingLeft().isPercent() |
| o->style()->paddingRight().isPercent())) | 808 if (relayoutChildren && (o->style()->paddingLeft().isPercent() |
| o->style()->paddingRight().isPercent())) |
| 810 o->setPrefWidthsDirty(true, false); | 809 o->setPrefWidthsDirty(true, false); |
| 811 | 810 |
| 812 if (o->isPositioned()) | 811 if (o->isPositioned()) |
| 813 o->containingBlock()->insertPositionedObject(box); | 812 o->containingBlock()->insertPositionedObject(box); |
| 814 else { | 813 else { |
| 815 if (o->isFloating()) | 814 if (o->isFloating()) |
| 816 floats.append(FloatWithRect(box)); | 815 floats.append(FloatWithRect(box)); |
| 817 else if (fullLayout || o->needsLayout()) // Replaced element
s | 816 else if (fullLayout || o->needsLayout()) // Replaced element
s |
| 818 o->dirtyLineBoxes(fullLayout); | 817 o->dirtyLineBoxes(fullLayout); |
| 819 | 818 |
| 820 o->layoutIfNeeded(); | 819 o->layoutIfNeeded(); |
| 821 } | 820 } |
| 822 } else if (o->isText() || (o->isRenderInline() && !endOfInline)) { | 821 } else if (o->isText() || (o->isRenderInline() && !endOfInline)) { |
| 823 if (fullLayout || o->selfNeedsLayout()) | 822 if (fullLayout || o->selfNeedsLayout()) |
| 824 o->dirtyLineBoxes(fullLayout); | 823 o->dirtyLineBoxes(fullLayout); |
| 825 | |
| 826 // Calculate margins of inline flows so that they can be used la
ter by line layout. | |
| 827 if (o->isRenderInline()) | |
| 828 toRenderInline(o)->calcMargins(containerWidth); | |
| 829 o->setNeedsLayout(false); | 824 o->setNeedsLayout(false); |
| 830 } | 825 } |
| 831 o = bidiNext(this, o, 0, false, &endOfInline); | 826 o = bidiNext(this, o, 0, false, &endOfInline); |
| 832 } | 827 } |
| 833 | 828 |
| 834 // We want to skip ahead to the first dirty line | 829 // We want to skip ahead to the first dirty line |
| 835 InlineBidiResolver resolver; | 830 InlineBidiResolver resolver; |
| 836 unsigned floatIndex; | 831 unsigned floatIndex; |
| 837 bool firstLine = true; | 832 bool firstLine = true; |
| 838 RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout,
resolver, floats, floatIndex); | 833 RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout,
resolver, floats, floatIndex); |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 static inline bool shouldPreserveNewline(RenderObject* object) | 1372 static inline bool shouldPreserveNewline(RenderObject* object) |
| 1378 { | 1373 { |
| 1379 #if ENABLE(SVG) | 1374 #if ENABLE(SVG) |
| 1380 if (object->isSVGText()) | 1375 if (object->isSVGText()) |
| 1381 return false; | 1376 return false; |
| 1382 #endif | 1377 #endif |
| 1383 | 1378 |
| 1384 return object->style()->preserveNewline(); | 1379 return object->style()->preserveNewline(); |
| 1385 } | 1380 } |
| 1386 | 1381 |
| 1387 static bool inlineFlowRequiresLineBox(RenderBox* flow) | 1382 static bool inlineFlowRequiresLineBox(RenderInline* flow) |
| 1388 { | 1383 { |
| 1389 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. | 1384 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. |
| 1390 // We need to fix this, though, because at the very least, inlines containin
g only | 1385 // We need to fix this, though, because at the very least, inlines containin
g only |
| 1391 // ignorable whitespace should should also have line boxes. | 1386 // ignorable whitespace should should also have line boxes. |
| 1392 return flow->isRenderInline() && !flow->firstChild() && flow->hasHorizontalB
ordersPaddingOrMargin(); | 1387 return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin(); |
| 1393 } | 1388 } |
| 1394 | 1389 |
| 1395 static inline bool requiresLineBox(const InlineIterator& it) | 1390 static inline bool requiresLineBox(const InlineIterator& it) |
| 1396 { | 1391 { |
| 1397 if (it.obj->isFloatingOrPositioned()) | 1392 if (it.obj->isFloatingOrPositioned()) |
| 1398 return false; | 1393 return false; |
| 1399 | 1394 |
| 1400 if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderBox(it.ob
j))) | 1395 if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it
.obj))) |
| 1401 return false; | 1396 return false; |
| 1402 | 1397 |
| 1403 if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR()) | 1398 if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR()) |
| 1404 return true; | 1399 return true; |
| 1405 | 1400 |
| 1406 UChar current = it.current(); | 1401 UChar current = it.current(); |
| 1407 return current != ' ' && current != '\t' && current != softHyphen && (curren
t != '\n' || shouldPreserveNewline(it.obj)) && !skipNonBreakingSpace(it); | 1402 return current != ' ' && current != '\t' && current != softHyphen && (curren
t != '\n' || shouldPreserveNewline(it.obj)) && !skipNonBreakingSpace(it); |
| 1408 } | 1403 } |
| 1409 | 1404 |
| 1410 bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj) | 1405 bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 if (c->isRenderInline()) { | 1468 if (c->isRenderInline()) { |
| 1474 // A relative positioned inline encloses us. In this case, we a
lso have to determine our | 1469 // A relative positioned inline encloses us. In this case, we a
lso have to determine our |
| 1475 // position as though we were an inline. Set |staticX| and |sta
ticY| on the relative positioned | 1470 // position as though we were an inline. Set |staticX| and |sta
ticY| on the relative positioned |
| 1476 // inline so that we can obtain the value later. | 1471 // inline so that we can obtain the value later. |
| 1477 toRenderInline(c)->layer()->setStaticX(style()->direction() == L
TR ? leftOffset(height(), firstLine) : rightOffset(height(), firstLine)); | 1472 toRenderInline(c)->layer()->setStaticX(style()->direction() == L
TR ? leftOffset(height(), firstLine) : rightOffset(height(), firstLine)); |
| 1478 toRenderInline(c)->layer()->setStaticY(height()); | 1473 toRenderInline(c)->layer()->setStaticY(height()); |
| 1479 } | 1474 } |
| 1480 | 1475 |
| 1481 RenderBox* box = toRenderBox(object); | 1476 RenderBox* box = toRenderBox(object); |
| 1482 if (box->style()->hasStaticX()) { | 1477 if (box->style()->hasStaticX()) { |
| 1483 if (object->style()->isOriginalDisplayInlineType()) | 1478 if (box->style()->isOriginalDisplayInlineType()) |
| 1484 box->layer()->setStaticX(style()->direction() == LTR ? leftO
ffset(height(), firstLine) : width() - rightOffset(height(), firstLine)); | 1479 box->layer()->setStaticX(style()->direction() == LTR ? leftO
ffset(height(), firstLine) : width() - rightOffset(height(), firstLine)); |
| 1485 else | 1480 else |
| 1486 box->layer()->setStaticX(style()->direction() == LTR ? borde
rLeft() + paddingLeft() : borderRight() + paddingRight()); | 1481 box->layer()->setStaticX(style()->direction() == LTR ? borde
rLeft() + paddingLeft() : borderRight() + paddingRight()); |
| 1487 } | 1482 } |
| 1488 | 1483 |
| 1489 if (box->style()->hasStaticY()) | 1484 if (box->style()->hasStaticY()) |
| 1490 box->layer()->setStaticY(height()); | 1485 box->layer()->setStaticY(height()); |
| 1491 } | 1486 } |
| 1492 resolver.increment(); | 1487 resolver.increment(); |
| 1493 } | 1488 } |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 addMidpoint(ignoreStart); // Stop ignoring spaces. | 1672 addMidpoint(ignoreStart); // Stop ignoring spaces. |
| 1678 addMidpoint(ignoreStart); // Start ignoring again. | 1673 addMidpoint(ignoreStart); // Start ignoring again. |
| 1679 } | 1674 } |
| 1680 | 1675 |
| 1681 } | 1676 } |
| 1682 } | 1677 } |
| 1683 } else if (o->isRenderInline()) { | 1678 } else if (o->isRenderInline()) { |
| 1684 // Right now, we should only encounter empty inlines here. | 1679 // Right now, we should only encounter empty inlines here. |
| 1685 ASSERT(!o->firstChild()); | 1680 ASSERT(!o->firstChild()); |
| 1686 | 1681 |
| 1687 RenderBox* flowBox = toRenderBox(o); | 1682 RenderInline* flowBox = toRenderInline(o); |
| 1688 | 1683 |
| 1689 // Now that some inline flows have line boxes, if we are already ign
oring spaces, we need | 1684 // Now that some inline flows have line boxes, if we are already ign
oring spaces, we need |
| 1690 // to make sure that we stop to include this object and then start i
gnoring spaces again. | 1685 // to make sure that we stop to include this object and then start i
gnoring spaces again. |
| 1691 // If this object is at the start of the line, we need to behave lik
e list markers and | 1686 // If this object is at the start of the line, we need to behave lik
e list markers and |
| 1692 // start ignoring spaces. | 1687 // start ignoring spaces. |
| 1693 if (inlineFlowRequiresLineBox(flowBox)) { | 1688 if (inlineFlowRequiresLineBox(flowBox)) { |
| 1694 isLineEmpty = false; | 1689 isLineEmpty = false; |
| 1695 if (ignoringSpaces) { | 1690 if (ignoringSpaces) { |
| 1696 trailingSpaceObject = 0; | 1691 trailingSpaceObject = 0; |
| 1697 addMidpoint(InlineIterator(0, o, 0)); // Stop ignoring space
s. | 1692 addMidpoint(InlineIterator(0, o, 0)); // Stop ignoring space
s. |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2199 // space. | 2194 // space. |
| 2200 int width = curr == firstRootBox() ? firstLineEllipsisWidth : ellips
isWidth; | 2195 int width = curr == firstRootBox() ? firstLineEllipsisWidth : ellips
isWidth; |
| 2201 if (curr->canAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)
) | 2196 if (curr->canAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)
) |
| 2202 curr->placeEllipsis(ellipsisStr, ltr, blockEdge, width); | 2197 curr->placeEllipsis(ellipsisStr, ltr, blockEdge, width); |
| 2203 } | 2198 } |
| 2204 } | 2199 } |
| 2205 } | 2200 } |
| 2206 | 2201 |
| 2207 } | 2202 } |
| 2208 | 2203 |
| OLD | NEW |