| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 157 |
| 158 if (!child->layoutObject().isOutOfFlowPositioned()) { | 158 if (!child->layoutObject().isOutOfFlowPositioned()) { |
| 159 if (child->isText()) { | 159 if (child->isText()) { |
| 160 const ComputedStyle& childStyle = child->layoutObject().styleRef(isF
irstLineStyle()); | 160 const ComputedStyle& childStyle = child->layoutObject().styleRef(isF
irstLineStyle()); |
| 161 if (childStyle.letterSpacing() < 0 || childStyle.textShadow() || chi
ldStyle.textEmphasisMark() != TextEmphasisMarkNone || childStyle.textStrokeWidth
()) | 161 if (childStyle.letterSpacing() < 0 || childStyle.textShadow() || chi
ldStyle.textEmphasisMark() != TextEmphasisMarkNone || childStyle.textStrokeWidth
()) |
| 162 child->clearKnownToHaveNoOverflow(); | 162 child->clearKnownToHaveNoOverflow(); |
| 163 } else if (child->layoutObject().isReplaced()) { | 163 } else if (child->layoutObject().isReplaced()) { |
| 164 LayoutBox& box = toLayoutBox(child->layoutObject()); | 164 LayoutBox& box = toLayoutBox(child->layoutObject()); |
| 165 if (box.hasOverflowModel() || box.hasSelfPaintingLayer()) | 165 if (box.hasOverflowModel() || box.hasSelfPaintingLayer()) |
| 166 child->clearKnownToHaveNoOverflow(); | 166 child->clearKnownToHaveNoOverflow(); |
| 167 } else if (!child->layoutObject().isBR() && (child->layoutObject().style
(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLay
er() | 167 } else if (!child->layoutObject().isBR() && (child->layoutObject().style
(isFirstLineStyle())->boxShadow() || child->boxModelObject().hasSelfPaintingLaye
r() |
| 168 || (child->layoutObject().isListMarker() && !toLayoutListMarker(chil
d->layoutObject()).isInside()) | 168 || (child->layoutObject().isListMarker() && !toLayoutListMarker(chil
d->layoutObject()).isInside()) |
| 169 || child->layoutObject().style(isFirstLineStyle())->hasBorderImageOu
tsets() | 169 || child->layoutObject().style(isFirstLineStyle())->hasBorderImageOu
tsets() |
| 170 || child->layoutObject().style(isFirstLineStyle())->hasOutline())) { | 170 || child->layoutObject().style(isFirstLineStyle())->hasOutline())) { |
| 171 child->clearKnownToHaveNoOverflow(); | 171 child->clearKnownToHaveNoOverflow(); |
| 172 } | 172 } |
| 173 | 173 |
| 174 if (knownToHaveNoOverflow() && child->isInlineFlowBox() && !toInlineFlow
Box(child)->knownToHaveNoOverflow()) | 174 if (knownToHaveNoOverflow() && child->isInlineFlowBox() && !toInlineFlow
Box(child)->knownToHaveNoOverflow()) |
| 175 clearKnownToHaveNoOverflow(); | 175 clearKnownToHaveNoOverflow(); |
| 176 } | 176 } |
| 177 | 177 |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 logicalLeft += flow->marginLogicalLeft(); | 422 logicalLeft += flow->marginLogicalLeft(); |
| 423 if (knownToHaveNoOverflow()) | 423 if (knownToHaveNoOverflow()) |
| 424 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); | 424 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); |
| 425 logicalLeft = flow->placeBoxesInInlineDirection(logicalLeft, nee
dsWordSpacing); | 425 logicalLeft = flow->placeBoxesInInlineDirection(logicalLeft, nee
dsWordSpacing); |
| 426 if (knownToHaveNoOverflow()) | 426 if (knownToHaveNoOverflow()) |
| 427 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); | 427 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); |
| 428 logicalLeft += flow->marginLogicalRight(); | 428 logicalLeft += flow->marginLogicalRight(); |
| 429 } else if (!curr->layoutObject().isListMarker() || toLayoutListMarke
r(curr->layoutObject()).isInside()) { | 429 } else if (!curr->layoutObject().isListMarker() || toLayoutListMarke
r(curr->layoutObject()).isInside()) { |
| 430 // The box can have a different writing-mode than the overall li
ne, so this is a bit complicated. | 430 // The box can have a different writing-mode than the overall li
ne, so this is a bit complicated. |
| 431 // Just get all the physical margin and overflow values by hand
based off |isHorizontal|. | 431 // Just get all the physical margin and overflow values by hand
based off |isHorizontal|. |
| 432 LayoutUnit logicalLeftMargin = isHorizontal() ? curr->boxModelOb
ject()->marginLeft() : curr->boxModelObject()->marginTop(); | 432 LayoutUnit logicalLeftMargin = isHorizontal() ? curr->boxModelOb
ject().marginLeft() : curr->boxModelObject().marginTop(); |
| 433 LayoutUnit logicalRightMargin = isHorizontal() ? curr->boxModelO
bject()->marginRight() : curr->boxModelObject()->marginBottom(); | 433 LayoutUnit logicalRightMargin = isHorizontal() ? curr->boxModelO
bject().marginRight() : curr->boxModelObject().marginBottom(); |
| 434 | 434 |
| 435 logicalLeft += logicalLeftMargin; | 435 logicalLeft += logicalLeftMargin; |
| 436 curr->setLogicalLeft(logicalLeft); | 436 curr->setLogicalLeft(logicalLeft); |
| 437 if (knownToHaveNoOverflow()) | 437 if (knownToHaveNoOverflow()) |
| 438 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); | 438 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); |
| 439 logicalLeft += curr->logicalWidth(); | 439 logicalLeft += curr->logicalWidth(); |
| 440 if (knownToHaveNoOverflow()) | 440 if (knownToHaveNoOverflow()) |
| 441 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); | 441 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); |
| 442 logicalLeft += logicalRightMargin; | 442 logicalLeft += logicalRightMargin; |
| 443 // If we encounter any space after this inline block then ensure
it is treated as the space between two words. | 443 // If we encounter any space after this inline block then ensure
it is treated as the space between two words. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 int descent = 0; | 542 int descent = 0; |
| 543 rootBox->ascentAndDescentForBox(curr, textBoxDataMap, ascent, descent, a
ffectsAscent, affectsDescent); | 543 rootBox->ascentAndDescentForBox(curr, textBoxDataMap, ascent, descent, a
ffectsAscent, affectsDescent); |
| 544 | 544 |
| 545 LayoutUnit boxHeight = ascent + descent; | 545 LayoutUnit boxHeight = ascent + descent; |
| 546 if (curr->verticalAlign() == TOP) { | 546 if (curr->verticalAlign() == TOP) { |
| 547 if (maxPositionTop < boxHeight) | 547 if (maxPositionTop < boxHeight) |
| 548 maxPositionTop = boxHeight; | 548 maxPositionTop = boxHeight; |
| 549 } else if (curr->verticalAlign() == BOTTOM) { | 549 } else if (curr->verticalAlign() == BOTTOM) { |
| 550 if (maxPositionBottom < boxHeight) | 550 if (maxPositionBottom < boxHeight) |
| 551 maxPositionBottom = boxHeight; | 551 maxPositionBottom = boxHeight; |
| 552 } else if (!inlineFlowBox || strictMode || inlineFlowBox->hasTextChildre
n() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowB
ox->hasTextDescendants()) || inlineFlowBox->boxModelObject()->hasInlineDirection
BordersOrPadding()) { | 552 } else if (!inlineFlowBox || strictMode || inlineFlowBox->hasTextChildre
n() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowB
ox->hasTextDescendants()) || inlineFlowBox->boxModelObject().hasInlineDirectionB
ordersOrPadding()) { |
| 553 // Note that these values can be negative. Even though we only affe
ct the maxAscent and maxDescent values | 553 // Note that these values can be negative. Even though we only affe
ct the maxAscent and maxDescent values |
| 554 // if our box (excluding line-height) was above (for ascent) or belo
w (for descent) the root baseline, once you factor in line-height | 554 // if our box (excluding line-height) was above (for ascent) or belo
w (for descent) the root baseline, once you factor in line-height |
| 555 // the final box can end up being fully above or fully below the roo
t box's baseline! This is ok, but what it | 555 // the final box can end up being fully above or fully below the roo
t box's baseline! This is ok, but what it |
| 556 // means is that ascent and descent (including leading), can end up
being negative. The setMaxAscent and | 556 // means is that ascent and descent (including leading), can end up
being negative. The setMaxAscent and |
| 557 // setMaxDescent booleans are used to ensure that we're willing to i
nitially set maxAscent/Descent to negative | 557 // setMaxDescent booleans are used to ensure that we're willing to i
nitially set maxAscent/Descent to negative |
| 558 // values. | 558 // values. |
| 559 ascent -= curr->logicalTop().round(); | 559 ascent -= curr->logicalTop().round(); |
| 560 descent += curr->logicalTop().round(); | 560 descent += curr->logicalTop().round(); |
| 561 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { | 561 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { |
| 562 maxAscent = ascent; | 562 maxAscent = ascent; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 581 const FontMetrics& fontMetrics = layoutObject().style(isFirstLineStyle()
)->fontMetrics(); | 581 const FontMetrics& fontMetrics = layoutObject().style(isFirstLineStyle()
)->fontMetrics(); |
| 582 // RootInlineBoxes are always placed at pixel boundaries in their logica
l y direction. Not doing | 582 // RootInlineBoxes are always placed at pixel boundaries in their logica
l y direction. Not doing |
| 583 // so results in incorrect layout of text decorations, most notably unde
rlines. | 583 // so results in incorrect layout of text decorations, most notably unde
rlines. |
| 584 setLogicalTop(roundToInt(top + maxAscent - fontMetrics.ascent(baselineTy
pe))); | 584 setLogicalTop(roundToInt(top + maxAscent - fontMetrics.ascent(baselineTy
pe))); |
| 585 } | 585 } |
| 586 | 586 |
| 587 LayoutUnit adjustmentForChildrenWithSameLineHeightAndBaseline = 0; | 587 LayoutUnit adjustmentForChildrenWithSameLineHeightAndBaseline = 0; |
| 588 if (descendantsHaveSameLineHeightAndBaseline()) { | 588 if (descendantsHaveSameLineHeightAndBaseline()) { |
| 589 adjustmentForChildrenWithSameLineHeightAndBaseline = logicalTop(); | 589 adjustmentForChildrenWithSameLineHeightAndBaseline = logicalTop(); |
| 590 if (parent()) | 590 if (parent()) |
| 591 adjustmentForChildrenWithSameLineHeightAndBaseline += (boxModelObjec
t()->borderBefore() + boxModelObject()->paddingBefore()); | 591 adjustmentForChildrenWithSameLineHeightAndBaseline += (boxModelObjec
t().borderBefore() + boxModelObject().paddingBefore()); |
| 592 } | 592 } |
| 593 | 593 |
| 594 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 594 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 595 if (curr->layoutObject().isOutOfFlowPositioned()) | 595 if (curr->layoutObject().isOutOfFlowPositioned()) |
| 596 continue; // Positioned placeholders don't affect calculations. | 596 continue; // Positioned placeholders don't affect calculations. |
| 597 | 597 |
| 598 if (descendantsHaveSameLineHeightAndBaseline()) { | 598 if (descendantsHaveSameLineHeightAndBaseline()) { |
| 599 curr->moveInBlockDirection(adjustmentForChildrenWithSameLineHeightAn
dBaseline); | 599 curr->moveInBlockDirection(adjustmentForChildrenWithSameLineHeightAn
dBaseline); |
| 600 continue; | 600 continue; |
| 601 } | 601 } |
| 602 | 602 |
| 603 InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox
(curr) : nullptr; | 603 InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox
(curr) : nullptr; |
| 604 bool childAffectsTopBottomPos = true; | 604 bool childAffectsTopBottomPos = true; |
| 605 if (curr->verticalAlign() == TOP) { | 605 if (curr->verticalAlign() == TOP) { |
| 606 curr->setLogicalTop(top); | 606 curr->setLogicalTop(top); |
| 607 } else if (curr->verticalAlign() == BOTTOM) { | 607 } else if (curr->verticalAlign() == BOTTOM) { |
| 608 curr->setLogicalTop((top + maxHeight - curr->lineHeight())); | 608 curr->setLogicalTop((top + maxHeight - curr->lineHeight())); |
| 609 } else { | 609 } else { |
| 610 if (!strictMode && inlineFlowBox && !inlineFlowBox->hasTextChildren(
) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() | 610 if (!strictMode && inlineFlowBox && !inlineFlowBox->hasTextChildren(
) && !curr->boxModelObject().hasInlineDirectionBordersOrPadding() |
| 611 && !(inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() &
& inlineFlowBox->hasTextDescendants())) | 611 && !(inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() &
& inlineFlowBox->hasTextDescendants())) |
| 612 childAffectsTopBottomPos = false; | 612 childAffectsTopBottomPos = false; |
| 613 LayoutUnit posAdjust = maxAscent - curr->baselinePosition(baselineTy
pe); | 613 LayoutUnit posAdjust = maxAscent - curr->baselinePosition(baselineTy
pe); |
| 614 curr->setLogicalTop(curr->logicalTop() + top + posAdjust); | 614 curr->setLogicalTop(curr->logicalTop() + top + posAdjust); |
| 615 } | 615 } |
| 616 | 616 |
| 617 LayoutUnit newLogicalTop = curr->logicalTop(); | 617 LayoutUnit newLogicalTop = curr->logicalTop(); |
| 618 LayoutUnit newLogicalTopIncludingMargins = newLogicalTop; | 618 LayoutUnit newLogicalTopIncludingMargins = newLogicalTop; |
| 619 LayoutUnit boxHeight = curr->logicalHeight(); | 619 LayoutUnit boxHeight = curr->logicalHeight(); |
| 620 LayoutUnit boxHeightIncludingMargins = boxHeight; | 620 LayoutUnit boxHeightIncludingMargins = boxHeight; |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 InlineTextBox* text = toInlineTextBox(curr); | 915 InlineTextBox* text = toInlineTextBox(curr); |
| 916 LayoutText& rt = text->layoutObject(); | 916 LayoutText& rt = text->layoutObject(); |
| 917 if (rt.isBR()) | 917 if (rt.isBR()) |
| 918 continue; | 918 continue; |
| 919 LayoutRect textBoxOverflow(text->logicalFrameRect()); | 919 LayoutRect textBoxOverflow(text->logicalFrameRect()); |
| 920 addTextBoxVisualOverflow(text, textBoxDataMap, textBoxOverflow); | 920 addTextBoxVisualOverflow(text, textBoxDataMap, textBoxOverflow); |
| 921 logicalVisualOverflow.unite(textBoxOverflow); | 921 logicalVisualOverflow.unite(textBoxOverflow); |
| 922 } else if (curr->layoutObject().isLayoutInline()) { | 922 } else if (curr->layoutObject().isLayoutInline()) { |
| 923 InlineFlowBox* flow = toInlineFlowBox(curr); | 923 InlineFlowBox* flow = toInlineFlowBox(curr); |
| 924 flow->computeOverflow(lineTop, lineBottom, textBoxDataMap); | 924 flow->computeOverflow(lineTop, lineBottom, textBoxDataMap); |
| 925 if (!flow->boxModelObject()->hasSelfPaintingLayer()) | 925 if (!flow->boxModelObject().hasSelfPaintingLayer()) |
| 926 logicalVisualOverflow.unite(flow->logicalVisualOverflowRect(line
Top, lineBottom)); | 926 logicalVisualOverflow.unite(flow->logicalVisualOverflowRect(line
Top, lineBottom)); |
| 927 LayoutRect childLayoutOverflow = flow->logicalLayoutOverflowRect(lin
eTop, lineBottom); | 927 LayoutRect childLayoutOverflow = flow->logicalLayoutOverflowRect(lin
eTop, lineBottom); |
| 928 childLayoutOverflow.move(flow->boxModelObject()->relativePositionLog
icalOffset()); | 928 childLayoutOverflow.move(flow->boxModelObject().relativePositionLogi
calOffset()); |
| 929 logicalLayoutOverflow.unite(childLayoutOverflow); | 929 logicalLayoutOverflow.unite(childLayoutOverflow); |
| 930 } else { | 930 } else { |
| 931 addReplacedChildOverflow(curr, logicalLayoutOverflow, logicalVisualO
verflow); | 931 addReplacedChildOverflow(curr, logicalLayoutOverflow, logicalVisualO
verflow); |
| 932 } | 932 } |
| 933 } | 933 } |
| 934 | 934 |
| 935 setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, li
neTop, lineBottom); | 935 setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, li
neTop, lineBottom); |
| 936 } | 936 } |
| 937 | 937 |
| 938 void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, const LayoutRect&
frameBox) | 938 void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, const LayoutRect&
frameBox) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 // We need to hit test both our inline children (InlineBoxes) and culled inl
ines | 979 // We need to hit test both our inline children (InlineBoxes) and culled inl
ines |
| 980 // (LayoutObjects). We check our inlines in the same order as line layout bu
t | 980 // (LayoutObjects). We check our inlines in the same order as line layout bu
t |
| 981 // for each inline we additionally need to hit test its culled inline parent
s. | 981 // for each inline we additionally need to hit test its culled inline parent
s. |
| 982 // While hit testing culled inline parents, we can stop once we reach | 982 // While hit testing culled inline parents, we can stop once we reach |
| 983 // a non-inline parent or a culled inline associated with a different inline
box. | 983 // a non-inline parent or a culled inline associated with a different inline
box. |
| 984 InlineBox* prev; | 984 InlineBox* prev; |
| 985 for (InlineBox* curr = lastChild(); curr; curr = prev) { | 985 for (InlineBox* curr = lastChild(); curr; curr = prev) { |
| 986 prev = curr->prevOnLine(); | 986 prev = curr->prevOnLine(); |
| 987 | 987 |
| 988 // Layers will handle hit testing themselves. | 988 // Layers will handle hit testing themselves. |
| 989 if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLay
er()) | 989 if (curr->boxModelObject() && curr->boxModelObject().hasSelfPaintingLaye
r()) |
| 990 continue; | 990 continue; |
| 991 | 991 |
| 992 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, li
neTop, lineBottom)) { | 992 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, li
neTop, lineBottom)) { |
| 993 layoutObject().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); | 993 layoutObject().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); |
| 994 return true; | 994 return true; |
| 995 } | 995 } |
| 996 | 996 |
| 997 // If the current inlinebox's layout object and the previous inlinebox's
layout object are same, | 997 // If the current inlinebox's layout object and the previous inlinebox's
layout object are same, |
| 998 // we should yield the hit-test to the previous inlinebox. | 998 // we should yield the hit-test to the previous inlinebox. |
| 999 if (prev && curr->layoutObject() == prev->layoutObject()) | 999 if (prev && curr->layoutObject() == prev->layoutObject()) |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 ASSERT(child->prevOnLine() == prev); | 1308 ASSERT(child->prevOnLine() == prev); |
| 1309 prev = child; | 1309 prev = child; |
| 1310 } | 1310 } |
| 1311 ASSERT(prev == m_lastChild); | 1311 ASSERT(prev == m_lastChild); |
| 1312 #endif | 1312 #endif |
| 1313 } | 1313 } |
| 1314 | 1314 |
| 1315 #endif | 1315 #endif |
| 1316 | 1316 |
| 1317 } // namespace blink | 1317 } // namespace blink |
| OLD | NEW |