| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; | 77 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; |
| 78 static int gDelayUpdateScrollInfo = 0; | 78 static int gDelayUpdateScrollInfo = 0; |
| 79 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; | 79 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; |
| 80 | 80 |
| 81 RenderBlock::RenderBlock(ContainerNode* node) | 81 RenderBlock::RenderBlock(ContainerNode* node) |
| 82 : RenderBox(node) | 82 : RenderBox(node) |
| 83 , m_hasMarginBeforeQuirk(false) | 83 , m_hasMarginBeforeQuirk(false) |
| 84 , m_hasMarginAfterQuirk(false) | 84 , m_hasMarginAfterQuirk(false) |
| 85 , m_beingDestroyed(false) | 85 , m_beingDestroyed(false) |
| 86 , m_hasMarkupTruncation(false) | |
| 87 , m_hasBorderOrPaddingLogicalWidthChanged(false) | 86 , m_hasBorderOrPaddingLogicalWidthChanged(false) |
| 88 { | 87 { |
| 89 } | 88 } |
| 90 | 89 |
| 91 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, Tracke
dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) | 90 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, Tracke
dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) |
| 92 { | 91 { |
| 93 if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(b
lock)) { | 92 if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(b
lock)) { |
| 94 TrackedRendererListHashSet::iterator end = descendantSet->end(); | 93 TrackedRendererListHashSet::iterator end = descendantSet->end(); |
| 95 for (TrackedRendererListHashSet::iterator descendant = descendantSet->be
gin(); descendant != end; ++descendant) { | 94 for (TrackedRendererListHashSet::iterator descendant = descendantSet->be
gin(); descendant != end; ++descendant) { |
| 96 TrackedContainerMap::iterator it = containerMap->find(*descendant); | 95 TrackedContainerMap::iterator it = containerMap->find(*descendant); |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 | 877 |
| 879 if (hasTransform()) { | 878 if (hasTransform()) { |
| 880 // FIXME: We should learn how to gap fill multiple columns and transform
s eventually. | 879 // FIXME: We should learn how to gap fill multiple columns and transform
s eventually. |
| 881 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) +
logicalHeight(); | 880 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) +
logicalHeight(); |
| 882 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight())
; | 881 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight())
; |
| 883 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(
)); | 882 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(
)); |
| 884 return result; | 883 return result; |
| 885 } | 884 } |
| 886 | 885 |
| 887 if (isRenderParagraph()) | 886 if (isRenderParagraph()) |
| 888 result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlo
ckPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLo
gicalRight, paintInfo); | 887 result = toRenderParagraph(this)->inlineSelectionGaps(rootBlock, rootBlo
ckPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLo
gicalRight, paintInfo); |
| 889 else | 888 else |
| 890 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offset
FromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); | 889 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offset
FromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); |
| 891 | 890 |
| 892 // Go ahead and fill the vertical gap all the way to the bottom of our block
if the selection extends past our block. | 891 // Go ahead and fill the vertical gap all the way to the bottom of our block
if the selection extends past our block. |
| 893 if (rootBlock == this && (selectionState() != SelectionBoth && selectionStat
e() != SelectionEnd)) | 892 if (rootBlock == this && (selectionState() != SelectionBoth && selectionStat
e() != SelectionEnd)) |
| 894 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPositio
n, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, | 893 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPositio
n, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, |
| 895 logicalHeight(), paintInfo)); | 894 logicalHeight(), paintInfo)); |
| 896 return result; | 895 return result; |
| 897 } | 896 } |
| 898 | 897 |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, Layou
tUnit replacedHeight) const | 1709 LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, Layou
tUnit replacedHeight) const |
| 1711 { | 1710 { |
| 1712 if (!(style(isFirstLine)->lineBoxContain() & LineBoxContainBlock)) | 1711 if (!(style(isFirstLine)->lineBoxContain() & LineBoxContainBlock)) |
| 1713 return 0; | 1712 return 0; |
| 1714 | 1713 |
| 1715 return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, Horizont
alLine, PositionOfInteriorLineBoxes)); | 1714 return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, Horizont
alLine, PositionOfInteriorLineBoxes)); |
| 1716 } | 1715 } |
| 1717 | 1716 |
| 1718 int RenderBlock::firstLineBoxBaseline() const | 1717 int RenderBlock::firstLineBoxBaseline() const |
| 1719 { | 1718 { |
| 1720 if (isRenderParagraph()) { | 1719 for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox())
{ |
| 1721 if (firstLineBox()) | 1720 if (!curr->isFloatingOrOutOfFlowPositioned()) { |
| 1722 return firstLineBox()->logicalTop() + style(true)->fontMetrics().asc
ent(firstRootBox()->baselineType()); | 1721 int result = curr->firstLineBoxBaseline(); |
| 1723 else | 1722 if (result != -1) |
| 1724 return -1; | 1723 return curr->logicalTop() + result; // Translate to our coordina
te space. |
| 1725 } | |
| 1726 else { | |
| 1727 for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBo
x()) { | |
| 1728 if (!curr->isFloatingOrOutOfFlowPositioned()) { | |
| 1729 int result = curr->firstLineBoxBaseline(); | |
| 1730 if (result != -1) | |
| 1731 return curr->logicalTop() + result; // Translate to our coor
dinate space. | |
| 1732 } | |
| 1733 } | 1724 } |
| 1734 } | 1725 } |
| 1735 | 1726 |
| 1736 return -1; | 1727 return -1; |
| 1737 } | 1728 } |
| 1738 | 1729 |
| 1739 int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const | 1730 int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const |
| 1740 { | 1731 { |
| 1741 if (!style()->isOverflowVisible()) { | 1732 if (!style()->isOverflowVisible()) { |
| 1742 // We are not calling RenderBox::baselinePosition here because the calle
r should add the margin-top/margin-right, not us. | 1733 // We are not calling RenderBox::baselinePosition here because the calle
r should add the margin-top/margin-right, not us. |
| 1743 return direction == HorizontalLine ? height() + m_marginBox.bottom() : w
idth() + m_marginBox.left(); | 1734 return direction == HorizontalLine ? height() + m_marginBox.bottom() : w
idth() + m_marginBox.left(); |
| 1744 } | 1735 } |
| 1745 | 1736 |
| 1746 return lastLineBoxBaseline(direction); | 1737 return lastLineBoxBaseline(direction); |
| 1747 } | 1738 } |
| 1748 | 1739 |
| 1749 int RenderBlock::lastLineBoxBaseline(LineDirectionMode lineDirection) const | 1740 int RenderBlock::lastLineBoxBaseline(LineDirectionMode lineDirection) const |
| 1750 { | 1741 { |
| 1751 if (isRenderParagraph()) { | 1742 bool haveNormalFlowChild = false; |
| 1752 if (!firstLineBox() && hasLineIfEmpty()) { | 1743 for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox
()) { |
| 1753 const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); | 1744 if (!curr->isFloatingOrOutOfFlowPositioned()) { |
| 1754 return fontMetrics.ascent() | 1745 haveNormalFlowChild = true; |
| 1755 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes)
- fontMetrics.height()) / 2 | 1746 int result = curr->inlineBlockBaseline(lineDirection); |
| 1756 + (lineDirection == HorizontalLine ? borderTop() + paddingTop()
: borderRight() + paddingRight()); | 1747 if (result != -1) |
| 1748 return curr->logicalTop() + result; // Translate to our coordina
te space. |
| 1757 } | 1749 } |
| 1758 if (lastLineBox()) | 1750 } |
| 1759 return lastLineBox()->logicalTop() + style(lastLineBox() == firstLin
eBox())->fontMetrics().ascent(lastRootBox()->baselineType()); | 1751 if (!haveNormalFlowChild && hasLineIfEmpty()) { |
| 1760 return -1; | 1752 const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); |
| 1761 } else { | 1753 return fontMetrics.ascent() |
| 1762 bool haveNormalFlowChild = false; | 1754 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f
ontMetrics.height()) / 2 |
| 1763 for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblin
gBox()) { | 1755 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : b
orderRight() + paddingRight()); |
| 1764 if (!curr->isFloatingOrOutOfFlowPositioned()) { | |
| 1765 haveNormalFlowChild = true; | |
| 1766 int result = curr->inlineBlockBaseline(lineDirection); | |
| 1767 if (result != -1) | |
| 1768 return curr->logicalTop() + result; // Translate to our coor
dinate space. | |
| 1769 } | |
| 1770 } | |
| 1771 if (!haveNormalFlowChild && hasLineIfEmpty()) { | |
| 1772 const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); | |
| 1773 return fontMetrics.ascent() | |
| 1774 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes)
- fontMetrics.height()) / 2 | |
| 1775 + (lineDirection == HorizontalLine ? borderTop() + paddingTop()
: borderRight() + paddingRight()); | |
| 1776 } | |
| 1777 } | 1756 } |
| 1778 | 1757 |
| 1779 return -1; | 1758 return -1; |
| 1780 } | 1759 } |
| 1781 | 1760 |
| 1782 RenderBlock* RenderBlock::firstLineBlock() const | 1761 RenderBlock* RenderBlock::firstLineBlock() const |
| 1783 { | 1762 { |
| 1784 RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this); | 1763 RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this); |
| 1785 bool hasPseudo = false; | 1764 bool hasPseudo = false; |
| 1786 while (true) { | 1765 while (true) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1808 // Helper methods for obtaining the last line, computing line counts and heights
for line counts | 1787 // Helper methods for obtaining the last line, computing line counts and heights
for line counts |
| 1809 // (crawling into blocks). | 1788 // (crawling into blocks). |
| 1810 static bool shouldCheckLines(RenderObject* obj) | 1789 static bool shouldCheckLines(RenderObject* obj) |
| 1811 { | 1790 { |
| 1812 return !obj->isFloatingOrOutOfFlowPositioned() | 1791 return !obj->isFloatingOrOutOfFlowPositioned() |
| 1813 && obj->isRenderBlock() && obj->style()->height().isAuto(); | 1792 && obj->isRenderBlock() && obj->style()->height().isAuto(); |
| 1814 } | 1793 } |
| 1815 | 1794 |
| 1816 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
int& count) | 1795 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
int& count) |
| 1817 { | 1796 { |
| 1818 if (block->isRenderParagraph()) { | 1797 RenderBox* normalFlowChildWithoutLines = 0; |
| 1819 for (RootInlineBox* box = toRenderBlockFlow(block)->firstRootBox(); box;
box = box->nextRootBox()) { | 1798 for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox
()) { |
| 1820 if (++count == l) | 1799 if (shouldCheckLines(obj)) { |
| 1821 return box->lineBottom() + (includeBottom ? (block->borderBottom
() + block->paddingBottom()) : LayoutUnit()); | 1800 int result = getHeightForLineCount(toRenderBlock(obj), l, false, cou
nt); |
| 1801 if (result != -1) |
| 1802 return result + obj->y() + (includeBottom ? (block->borderBottom
() + block->paddingBottom()) : LayoutUnit()); |
| 1803 } else if (!obj->isFloatingOrOutOfFlowPositioned()) { |
| 1804 normalFlowChildWithoutLines = obj; |
| 1822 } | 1805 } |
| 1823 } else { | |
| 1824 RenderBox* normalFlowChildWithoutLines = 0; | |
| 1825 for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblin
gBox()) { | |
| 1826 if (shouldCheckLines(obj)) { | |
| 1827 int result = getHeightForLineCount(toRenderBlock(obj), l, false,
count); | |
| 1828 if (result != -1) | |
| 1829 return result + obj->y() + (includeBottom ? (block->borderBo
ttom() + block->paddingBottom()) : LayoutUnit()); | |
| 1830 } else if (!obj->isFloatingOrOutOfFlowPositioned()) { | |
| 1831 normalFlowChildWithoutLines = obj; | |
| 1832 } | |
| 1833 } | |
| 1834 if (normalFlowChildWithoutLines && l == 0) | |
| 1835 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLine
s->height(); | |
| 1836 } | 1806 } |
| 1807 if (normalFlowChildWithoutLines && l == 0) |
| 1808 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->h
eight(); |
| 1837 | 1809 |
| 1838 return -1; | 1810 return -1; |
| 1839 } | 1811 } |
| 1840 | 1812 |
| 1841 RootInlineBox* RenderBlock::lineAtIndex(int i) const | 1813 RootInlineBox* RenderBlock::lineAtIndex(int i) const |
| 1842 { | 1814 { |
| 1843 ASSERT(i >= 0); | 1815 ASSERT(i >= 0); |
| 1844 | 1816 |
| 1845 if (isRenderParagraph()) { | 1817 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 1846 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) | 1818 if (!shouldCheckLines(child)) |
| 1847 if (!i--) | 1819 continue; |
| 1848 return box; | 1820 if (RootInlineBox* box = toRenderBlock(child)->lineAtIndex(i)) |
| 1849 } else { | 1821 return box; |
| 1850 for (RenderObject* child = firstChild(); child; child = child->nextSibli
ng()) { | |
| 1851 if (!shouldCheckLines(child)) | |
| 1852 continue; | |
| 1853 if (RootInlineBox* box = toRenderBlock(child)->lineAtIndex(i)) | |
| 1854 return box; | |
| 1855 } | |
| 1856 } | 1822 } |
| 1857 | 1823 |
| 1858 return 0; | 1824 return 0; |
| 1859 } | 1825 } |
| 1860 | 1826 |
| 1861 int RenderBlock::lineCount(const RootInlineBox* stopRootInlineBox, bool* found)
const | 1827 int RenderBlock::lineCount(const RootInlineBox* stopRootInlineBox, bool* found)
const |
| 1862 { | 1828 { |
| 1863 int count = 0; | 1829 int count = 0; |
| 1864 if (isRenderParagraph()) { | 1830 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) { |
| 1865 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
{ | 1831 if (shouldCheckLines(obj)) { |
| 1866 count++; | 1832 bool recursiveFound = false; |
| 1867 if (box == stopRootInlineBox) { | 1833 count += toRenderBlock(obj)->lineCount(stopRootInlineBox, &recursive
Found); |
| 1834 if (recursiveFound) { |
| 1868 if (found) | 1835 if (found) |
| 1869 *found = true; | 1836 *found = true; |
| 1870 break; | 1837 break; |
| 1871 } | 1838 } |
| 1872 } | 1839 } |
| 1873 } else { | |
| 1874 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) | |
| 1875 if (shouldCheckLines(obj)) { | |
| 1876 bool recursiveFound = false; | |
| 1877 count += toRenderBlock(obj)->lineCount(stopRootInlineBox, &recur
siveFound); | |
| 1878 if (recursiveFound) { | |
| 1879 if (found) | |
| 1880 *found = true; | |
| 1881 break; | |
| 1882 } | |
| 1883 } | |
| 1884 } | 1840 } |
| 1841 |
| 1885 return count; | 1842 return count; |
| 1886 } | 1843 } |
| 1887 | 1844 |
| 1888 int RenderBlock::heightForLineCount(int l) | |
| 1889 { | |
| 1890 int count = 0; | |
| 1891 return getHeightForLineCount(this, l, true, count); | |
| 1892 } | |
| 1893 | |
| 1894 void RenderBlock::clearTruncation() | 1845 void RenderBlock::clearTruncation() |
| 1895 { | 1846 { |
| 1896 if (isRenderParagraph() && hasMarkupTruncation()) { | 1847 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) { |
| 1897 setHasMarkupTruncation(false); | 1848 if (shouldCheckLines(obj)) |
| 1898 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) | 1849 toRenderBlock(obj)->clearTruncation(); |
| 1899 box->clearTruncation(); | |
| 1900 } else { | |
| 1901 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) { | |
| 1902 if (shouldCheckLines(obj)) | |
| 1903 toRenderBlock(obj)->clearTruncation(); | |
| 1904 } | |
| 1905 } | 1850 } |
| 1906 } | 1851 } |
| 1907 | 1852 |
| 1908 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const | 1853 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const |
| 1909 { | 1854 { |
| 1910 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); | 1855 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); |
| 1911 } | 1856 } |
| 1912 | 1857 |
| 1913 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const | 1858 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const |
| 1914 { | 1859 { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2112 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 2057 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
| 2113 { | 2058 { |
| 2114 showRenderObject(); | 2059 showRenderObject(); |
| 2115 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 2060 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
| 2116 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 2061 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
| 2117 } | 2062 } |
| 2118 | 2063 |
| 2119 #endif | 2064 #endif |
| 2120 | 2065 |
| 2121 } // namespace blink | 2066 } // namespace blink |
| OLD | NEW |