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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "platform/text/BidiResolver.h" | 45 #include "platform/text/BidiResolver.h" |
46 #include "wtf/RefCountedLeakCounter.h" | 46 #include "wtf/RefCountedLeakCounter.h" |
47 #include "wtf/StdLibExtras.h" | 47 #include "wtf/StdLibExtras.h" |
48 #include "wtf/Vector.h" | 48 #include "wtf/Vector.h" |
49 #include "wtf/text/CharacterNames.h" | 49 #include "wtf/text/CharacterNames.h" |
50 | 50 |
51 namespace blink { | 51 namespace blink { |
52 | 52 |
53 using namespace WTF::Unicode; | 53 using namespace WTF::Unicode; |
54 | 54 |
| 55 typedef WTF::HashMap<LayoutBlockFlow*, HashSet<LayoutInline*>> InlinesWithOutlin
eAndContinuationMap; |
| 56 static InlinesWithOutlineAndContinuationMap* gInlinesWithOutlineAndContinuationM
ap = nullptr; |
| 57 |
55 static inline InlineBox* createInlineBoxForLayoutObject(LayoutObject* obj, bool
isRootLineBox, bool isOnlyRun = false) | 58 static inline InlineBox* createInlineBoxForLayoutObject(LayoutObject* obj, bool
isRootLineBox, bool isOnlyRun = false) |
56 { | 59 { |
57 // Callers should handle text themselves. | 60 // Callers should handle text themselves. |
58 ASSERT(!obj->isText()); | 61 ASSERT(!obj->isText()); |
59 | 62 |
60 if (isRootLineBox) | 63 if (isRootLineBox) |
61 return toLayoutBlockFlow(obj)->createAndAppendRootInlineBox(); | 64 return toLayoutBlockFlow(obj)->createAndAppendRootInlineBox(); |
62 | 65 |
63 if (obj->isBox()) | 66 if (obj->isBox()) |
64 return toLayoutBox(obj)->createInlineBox(); | 67 return toLayoutBox(obj)->createInlineBox(); |
(...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1482 oldAutoWrap = autoWrap; | 1485 oldAutoWrap = autoWrap; |
1483 } | 1486 } |
1484 | 1487 |
1485 if (styleToUse.collapseWhiteSpace()) | 1488 if (styleToUse.collapseWhiteSpace()) |
1486 stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild); | 1489 stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild); |
1487 | 1490 |
1488 minLogicalWidth = std::max(minLogicalWidth, inlineMin); | 1491 minLogicalWidth = std::max(minLogicalWidth, inlineMin); |
1489 maxLogicalWidth = std::max(maxLogicalWidth, inlineMax); | 1492 maxLogicalWidth = std::max(maxLogicalWidth, inlineMax); |
1490 } | 1493 } |
1491 | 1494 |
| 1495 void LayoutBlockFlow::removeInlinesWithOutlineAndContinuation() |
| 1496 { |
| 1497 if (gInlinesWithOutlineAndContinuationMap) |
| 1498 gInlinesWithOutlineAndContinuationMap->remove(this); |
| 1499 } |
| 1500 |
| 1501 void LayoutBlockFlow::addInlineWithOutlineAndContinuation(LayoutInline* layoutIn
line) |
| 1502 { |
| 1503 if (!gInlinesWithOutlineAndContinuationMap) |
| 1504 gInlinesWithOutlineAndContinuationMap = new InlinesWithOutlineAndContinu
ationMap; |
| 1505 gInlinesWithOutlineAndContinuationMap->add(this, HashSet<LayoutInline*>()).s
toredValue->value.add(layoutInline); |
| 1506 } |
| 1507 |
1492 void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& pa
intInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUni
t afterEdge) | 1508 void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& pa
intInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUni
t afterEdge) |
1493 { | 1509 { |
1494 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 1510 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
1495 bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->
hasColumnSets(); | 1511 bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->
hasColumnSets(); |
1496 | 1512 |
1497 // Figure out if we should clear out our line boxes. | 1513 // Figure out if we should clear out our line boxes. |
1498 // FIXME: Handle resize eventually! | 1514 // FIXME: Handle resize eventually! |
1499 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren
|| clearLinesForPagination; | 1515 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren
|| clearLinesForPagination; |
1500 LineLayoutState layoutState(isFullLayout, paintInvalidationLogicalTop, paint
InvalidationLogicalBottom, flowThread); | 1516 LineLayoutState layoutState(isFullLayout, paintInvalidationLogicalTop, paint
InvalidationLogicalBottom, flowThread); |
1501 | 1517 |
(...skipping 13 matching lines...) Expand all Loading... |
1515 // difficult to figure out in general (especially in the middle of doing lay
out), so we only handle the | 1531 // difficult to figure out in general (especially in the middle of doing lay
out), so we only handle the |
1516 // simple case of an anonymous block truncating when it's parent is clipped. | 1532 // simple case of an anonymous block truncating when it's parent is clipped. |
1517 bool hasTextOverflow = (style()->textOverflow() && hasOverflowClip()) | 1533 bool hasTextOverflow = (style()->textOverflow() && hasOverflowClip()) |
1518 || (isAnonymousBlock() && parent() && parent()->isLayoutBlock() && toLay
outBlock(parent())->canCollapseAnonymousBlockChild() | 1534 || (isAnonymousBlock() && parent() && parent()->isLayoutBlock() && toLay
outBlock(parent())->canCollapseAnonymousBlockChild() |
1519 && parent()->style()->textOverflow() && parent()->hasOverflowClip())
; | 1535 && parent()->style()->textOverflow() && parent()->hasOverflowClip())
; |
1520 | 1536 |
1521 // Walk all the lines and delete our ellipsis line boxes if they exist. | 1537 // Walk all the lines and delete our ellipsis line boxes if they exist. |
1522 if (hasTextOverflow) | 1538 if (hasTextOverflow) |
1523 deleteEllipsisLineBoxes(); | 1539 deleteEllipsisLineBoxes(); |
1524 | 1540 |
| 1541 removeInlinesWithOutlineAndContinuation(); |
| 1542 |
1525 if (firstChild()) { | 1543 if (firstChild()) { |
1526 // In full layout mode, clear the line boxes of children upfront. Otherw
ise, | 1544 // In full layout mode, clear the line boxes of children upfront. Otherw
ise, |
1527 // siblings can run into stale root lineboxes during layout. Then layout | 1545 // siblings can run into stale root lineboxes during layout. Then layout |
1528 // the replaced elements later. In partial layout mode, line boxes are n
ot | 1546 // the replaced elements later. In partial layout mode, line boxes are n
ot |
1529 // deleted and only dirtied. In that case, we can layout the replaced | 1547 // deleted and only dirtied. In that case, we can layout the replaced |
1530 // elements at the same time. | 1548 // elements at the same time. |
1531 Vector<LayoutBox*> replacedChildren; | 1549 Vector<LayoutBox*> replacedChildren; |
1532 LayoutObject* lastChild = nullptr; | 1550 LayoutObject* lastChild = nullptr; |
1533 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { | 1551 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { |
1534 LayoutObject* o = walker.current(); | 1552 LayoutObject* o = walker.current(); |
(...skipping 24 matching lines...) Expand all Loading... |
1559 } | 1577 } |
1560 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { | 1578 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { |
1561 if (!o->isText()) | 1579 if (!o->isText()) |
1562 toLayoutInline(o)->updateAlwaysCreateLineBoxes(layoutState.i
sFullLayout()); | 1580 toLayoutInline(o)->updateAlwaysCreateLineBoxes(layoutState.i
sFullLayout()); |
1563 if (layoutState.isFullLayout() || o->selfNeedsLayout()) | 1581 if (layoutState.isFullLayout() || o->selfNeedsLayout()) |
1564 dirtyLineBoxesForObject(o, layoutState.isFullLayout()); | 1582 dirtyLineBoxesForObject(o, layoutState.isFullLayout()); |
1565 o->clearNeedsLayout(); | 1583 o->clearNeedsLayout(); |
1566 } | 1584 } |
1567 if (!o->isText() || !toLayoutText(o)->isAllCollapsibleWhitespace()) | 1585 if (!o->isText() || !toLayoutText(o)->isAllCollapsibleWhitespace()) |
1568 lastChild = o; | 1586 lastChild = o; |
| 1587 |
| 1588 if (o->isLayoutInline() && o->styleRef().hasOutline() && !o->isEleme
ntContinuation() && toLayoutInline(o)->continuation()) |
| 1589 addInlineWithOutlineAndContinuation(toLayoutInline(o)); |
1569 } | 1590 } |
1570 // If there is a trailing float on the line that will possibly occur aft
er a natural line break | 1591 // If there is a trailing float on the line that will possibly occur aft
er a natural line break |
1571 // then dirty its adjacent lineboxes to ensure it gets placed. | 1592 // then dirty its adjacent lineboxes to ensure it gets placed. |
1572 if (lastChild && lastChild->isFloating()) | 1593 if (lastChild && lastChild->isFloating()) |
1573 dirtyLinesFromChangedChild(lastChild); | 1594 dirtyLinesFromChangedChild(lastChild); |
1574 | 1595 |
1575 for (size_t i = 0; i < replacedChildren.size(); i++) | 1596 for (size_t i = 0; i < replacedChildren.size(); i++) |
1576 replacedChildren[i]->layoutIfNeeded(); | 1597 replacedChildren[i]->layoutIfNeeded(); |
1577 | 1598 |
1578 layoutRunsAndFloats(layoutState); | 1599 layoutRunsAndFloats(layoutState); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 { | 1877 { |
1857 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); | 1878 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); |
1858 // FIXME: Need to find another way to do this, since scrollbars could show w
hen we don't want them to. | 1879 // FIXME: Need to find another way to do this, since scrollbars could show w
hen we don't want them to. |
1859 if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElem
ent() && style()->isLeftToRightDirection()) | 1880 if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElem
ent() && style()->isLeftToRightDirection()) |
1860 endPadding = 1; | 1881 endPadding = 1; |
1861 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ | 1882 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ |
1862 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); | 1883 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); |
1863 LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), cu
rr->lineBottom()); | 1884 LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), cu
rr->lineBottom()); |
1864 addContentsVisualOverflow(visualOverflow); | 1885 addContentsVisualOverflow(visualOverflow); |
1865 } | 1886 } |
| 1887 |
| 1888 if (!gInlinesWithOutlineAndContinuationMap) |
| 1889 return; |
| 1890 InlinesWithOutlineAndContinuationMap::const_iterator it = gInlinesWithOutlin
eAndContinuationMap->find(this); |
| 1891 if (it == gInlinesWithOutlineAndContinuationMap->end() || it->value.isEmpty(
)) |
| 1892 return; |
| 1893 |
| 1894 // Add outline rects of continuations of descendant inlines into visual over
flow of this block. |
| 1895 LayoutRect outlineBoundsOfAllContinuations; |
| 1896 for (LayoutInline* flow : it->value) { |
| 1897 Vector<LayoutRect> outlineRects; |
| 1898 flow->addOutlineRectsForContinuations(outlineRects, LayoutPoint()); |
| 1899 LayoutRect outlineBounds = unionRect(outlineRects); |
| 1900 outlineBounds.inflate(flow->styleRef().outlineOutsetExtent()); |
| 1901 outlineBoundsOfAllContinuations.unite(outlineBounds); |
| 1902 } |
| 1903 addContentsVisualOverflow(outlineBoundsOfAllContinuations); |
1866 } | 1904 } |
1867 | 1905 |
1868 void LayoutBlockFlow::deleteEllipsisLineBoxes() | 1906 void LayoutBlockFlow::deleteEllipsisLineBoxes() |
1869 { | 1907 { |
1870 ETextAlign textAlign = style()->textAlign(); | 1908 ETextAlign textAlign = style()->textAlign(); |
1871 bool firstLine = true; | 1909 bool firstLine = true; |
1872 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ | 1910 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ |
1873 if (curr->hasEllipsisBox()) { | 1911 if (curr->hasEllipsisBox()) { |
1874 curr->clearTruncation(); | 1912 curr->clearTruncation(); |
1875 | 1913 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2022 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false); | 2060 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false); |
2023 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, false) - logicalLeft; | 2061 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, false) - logicalLeft; |
2024 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2062 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
2025 | 2063 |
2026 if (!style()->isLeftToRightDirection()) | 2064 if (!style()->isLeftToRightDirection()) |
2027 return logicalWidth() - logicalLeft; | 2065 return logicalWidth() - logicalLeft; |
2028 return logicalLeft; | 2066 return logicalLeft; |
2029 } | 2067 } |
2030 | 2068 |
2031 } | 2069 } |
OLD | NEW |