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; | |
Xianzhu
2015/08/06 18:12:45
Note: This map will replace the continuationOutlin
| |
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 |