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 |