Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: Source/core/rendering/RenderBlock.cpp

Issue 569683004: Factor painting code from RenderBlock into BlockPainter. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 20 matching lines...) Expand all
31 #include "core/dom/StyleEngine.h" 31 #include "core/dom/StyleEngine.h"
32 #include "core/dom/shadow/ShadowRoot.h" 32 #include "core/dom/shadow/ShadowRoot.h"
33 #include "core/editing/Editor.h" 33 #include "core/editing/Editor.h"
34 #include "core/editing/FrameSelection.h" 34 #include "core/editing/FrameSelection.h"
35 #include "core/events/OverflowEvent.h" 35 #include "core/events/OverflowEvent.h"
36 #include "core/fetch/ResourceLoadPriorityOptimizer.h" 36 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
37 #include "core/frame/FrameView.h" 37 #include "core/frame/FrameView.h"
38 #include "core/frame/LocalFrame.h" 38 #include "core/frame/LocalFrame.h"
39 #include "core/frame/Settings.h" 39 #include "core/frame/Settings.h"
40 #include "core/page/Page.h" 40 #include "core/page/Page.h"
41 #include "core/paint/BlockPainter.h"
41 #include "core/paint/BoxPainter.h" 42 #include "core/paint/BoxPainter.h"
42 #include "core/rendering/GraphicsContextAnnotator.h" 43 #include "core/rendering/GraphicsContextAnnotator.h"
43 #include "core/rendering/HitTestLocation.h" 44 #include "core/rendering/HitTestLocation.h"
44 #include "core/rendering/HitTestResult.h" 45 #include "core/rendering/HitTestResult.h"
45 #include "core/rendering/InlineIterator.h" 46 #include "core/rendering/InlineIterator.h"
46 #include "core/rendering/InlineTextBox.h" 47 #include "core/rendering/InlineTextBox.h"
47 #include "core/rendering/PaintInfo.h" 48 #include "core/rendering/PaintInfo.h"
48 #include "core/rendering/RenderCombineText.h" 49 #include "core/rendering/RenderCombineText.h"
49 #include "core/rendering/RenderDeprecatedFlexibleBox.h" 50 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
50 #include "core/rendering/RenderFlexibleBox.h" 51 #include "core/rendering/RenderFlexibleBox.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 90
90 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap; 91 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
91 static ColumnInfoMap* gColumnInfoMap = 0; 92 static ColumnInfoMap* gColumnInfoMap = 0;
92 93
93 static TrackedDescendantsMap* gPositionedDescendantsMap = 0; 94 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
94 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0; 95 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
95 96
96 static TrackedContainerMap* gPositionedContainerMap = 0; 97 static TrackedContainerMap* gPositionedContainerMap = 0;
97 static TrackedContainerMap* gPercentHeightContainerMap = 0; 98 static TrackedContainerMap* gPercentHeightContainerMap = 0;
98 99
99 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > Continu ationOutlineTableMap;
100
101 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; 100 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
102 static int gDelayUpdateScrollInfo = 0; 101 static int gDelayUpdateScrollInfo = 0;
103 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; 102 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
104 103
105 static bool gColumnFlowSplitEnabled = true; 104 static bool gColumnFlowSplitEnabled = true;
106 105
107 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code 106 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
108 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes. 107 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes.
109 class OverflowEventDispatcher { 108 class OverflowEventDispatcher {
110 WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher); 109 WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 ASSERT(!needsLayout()); 1750 ASSERT(!needsLayout());
1752 if (needsLayout()) 1751 if (needsLayout())
1753 return; 1752 return;
1754 1753
1755 if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutStat e()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logi calTop()) != pageLogicalOffset())) 1754 if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutStat e()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logi calTop()) != pageLogicalOffset()))
1756 layoutScope.setChildNeedsLayout(this); 1755 layoutScope.setChildNeedsLayout(this);
1757 } 1756 }
1758 1757
1759 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 1758 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1760 { 1759 {
1761 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this); 1760 BlockPainter(*this).paint(paintInfo, paintOffset);
1762
1763 LayoutPoint adjustedPaintOffset = paintOffset + location();
1764
1765 PaintPhase phase = paintInfo.phase;
1766
1767 LayoutRect overflowBox;
1768 // Check if we need to do anything at all.
1769 // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
1770 // paints the root's background.
1771 if (!isDocumentElement()) {
1772 overflowBox = overflowRectForPaintRejection();
1773 flipForWritingMode(overflowBox);
1774 overflowBox.moveBy(adjustedPaintOffset);
1775 if (!overflowBox.intersects(paintInfo.rect))
1776 return;
1777 }
1778
1779 // There are some cases where not all clipped visual overflow is accounted f or.
1780 // FIXME: reduce the number of such cases.
1781 ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
1782 if (hasOverflowClip() && !hasControlClip() && !(shouldPaintSelectionGaps() & & phase == PaintPhaseForeground) && !hasCaret())
1783 contentsClipBehavior = SkipContentsClipIfPossible;
1784
1785 bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsC lipBehavior);
1786 {
1787 GraphicsContextCullSaver cullSaver(*paintInfo.context);
1788 // Cull if we have more than one child and we didn't already clip.
1789 bool shouldCull = document().settings()->containerCullingEnabled() && !p ushedClip && !isDocumentElement()
1790 && firstChild() && lastChild() && firstChild() != lastChild();
1791 if (shouldCull)
1792 cullSaver.cull(overflowBox);
1793
1794 paintObject(paintInfo, adjustedPaintOffset);
1795 }
1796 if (pushedClip)
1797 popContentsClip(paintInfo, phase, adjustedPaintOffset);
1798
1799 // Our scrollbar widgets paint exactly when we tell them to, so that they wo rk properly with
1800 // z-index. We paint after we painted the background/border, so that the sc rollbars will
1801 // sit above the background/border.
1802 if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == Paint PhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.sh ouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
1803 layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roun dedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayContro ls */);
1804 }
1805
1806 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain tOffset)
1807 {
1808 const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
1809 bool ruleTransparent = style()->columnRuleIsTransparent();
1810 EBorderStyle ruleStyle = style()->columnRuleStyle();
1811 LayoutUnit ruleThickness = style()->columnRuleWidth();
1812 LayoutUnit colGap = columnGap();
1813 bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
1814 if (!renderRule)
1815 return;
1816
1817 ColumnInfo* colInfo = columnInfo();
1818 unsigned colCount = columnCount(colInfo);
1819
1820 bool antialias = BoxPainter::shouldAntialiasLines(paintInfo.context);
1821
1822 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
1823 bool leftToRight = style()->isLeftToRightDirection();
1824 LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentL ogicalWidth();
1825 LayoutUnit ruleAdd = logicalLeftOffsetForContent();
1826 LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogical Width();
1827 LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
1828 BoxSide boxSide = isHorizontalWritingMode()
1829 ? leftToRight ? BSLeft : BSRight
1830 : leftToRight ? BSTop : BSBottom;
1831
1832 for (unsigned i = 0; i < colCount; i++) {
1833 // Move to the next position.
1834 if (leftToRight) {
1835 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
1836 currLogicalLeftOffset += inlineDirectionSize + colGap;
1837 } else {
1838 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
1839 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
1840 }
1841
1842 // Now paint the column rule.
1843 if (i < colCount - 1) {
1844 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x( ) + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft () + paddingLeft();
1845 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ru leThickness : ruleLeft + contentWidth();
1846 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThicknes s / 2 + ruleAdd;
1847 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + co ntentHeight() : ruleTop + ruleThickness;
1848 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(rule Left, ruleTop, ruleRight, ruleBottom);
1849 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY (), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
1850 }
1851
1852 ruleLogicalLeft = currLogicalLeftOffset;
1853 }
1854 } else {
1855 bool topToBottom = !style()->isFlippedBlocksWritingMode();
1856 LayoutUnit ruleLeft = isHorizontalWritingMode()
1857 ? borderLeft() + paddingLeft()
1858 : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + padding Before();
1859 LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : rule Thickness;
1860 LayoutUnit ruleTop = isHorizontalWritingMode()
1861 ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + padding Before()
1862 : borderStart() + paddingStart();
1863 LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : cont entHeight();
1864 LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
1865
1866 if (!topToBottom) {
1867 if (isHorizontalWritingMode())
1868 ruleRect.setY(height() - ruleRect.maxY());
1869 else
1870 ruleRect.setX(width() - ruleRect.maxX());
1871 }
1872
1873 ruleRect.moveBy(paintOffset);
1874
1875 BoxSide boxSide = isHorizontalWritingMode()
1876 ? topToBottom ? BSTop : BSBottom
1877 : topToBottom ? BSLeft : BSRight;
1878
1879 LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(co lInfo->columnHeight() + colGap));
1880 if (!isHorizontalWritingMode())
1881 step = step.transposedSize();
1882
1883 for (unsigned i = 1; i < colCount; i++) {
1884 ruleRect.move(step);
1885 IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
1886 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixe lSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
1887 }
1888 }
1889 }
1890
1891 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p aintOffset, bool paintingFloats)
1892 {
1893 // We need to do multiple passes, breaking up our child painting into strips .
1894 GraphicsContext* context = paintInfo.context;
1895 ColumnInfo* colInfo = columnInfo();
1896 unsigned colCount = columnCount(colInfo);
1897 if (!colCount)
1898 return;
1899 LayoutUnit currLogicalTopOffset = 0;
1900 LayoutUnit colGap = columnGap();
1901 for (unsigned i = 0; i < colCount; i++) {
1902 // For each rect, we clip to the rect, and then we adjust our coords.
1903 LayoutRect colRect = columnRectAt(colInfo, i);
1904 flipForWritingMode(colRect);
1905 LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
1906 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOf fset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset );
1907 if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
1908 if (isHorizontalWritingMode())
1909 offset.expand(0, colRect.y() - borderTop() - paddingTop());
1910 else
1911 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
1912 }
1913 colRect.moveBy(paintOffset);
1914 PaintInfo info(paintInfo);
1915 info.rect.intersect(enclosingIntRect(colRect));
1916
1917 if (!info.rect.isEmpty()) {
1918 GraphicsContextStateSaver stateSaver(*context);
1919 LayoutRect clipRect(colRect);
1920
1921 if (i < colCount - 1) {
1922 if (isHorizontalWritingMode())
1923 clipRect.expand(colGap / 2, 0);
1924 else
1925 clipRect.expand(0, colGap / 2);
1926 }
1927 // Each strip pushes a clip, since column boxes are specified as bei ng
1928 // like overflow:hidden.
1929 // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
1930 // are clipped according to the 'overflow' property.
1931 context->clip(enclosingIntRect(clipRect));
1932
1933 // Adjust our x and y when painting.
1934 LayoutPoint adjustedPaintOffset = paintOffset + offset;
1935 if (paintingFloats)
1936 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintP haseSelection || paintInfo.phase == PaintPhaseTextClip);
1937 else
1938 paintContents(info, adjustedPaintOffset);
1939 }
1940
1941 LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
1942 if (style()->isFlippedBlocksWritingMode())
1943 currLogicalTopOffset += blockDelta;
1944 else
1945 currLogicalTopOffset -= blockDelta;
1946 }
1947 }
1948
1949 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
1950 {
1951 // Avoid painting descendants of the root element when stylesheets haven't l oaded. This eliminates FOUC.
1952 // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
1953 // will do a full paint invalidation.
1954 if (document().didLayoutWithPendingStylesheets() && !isRenderView())
1955 return;
1956
1957 if (childrenInline())
1958 m_lineBoxes.paint(this, paintInfo, paintOffset);
1959 else {
1960 PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? Pai ntPhaseOutline : paintInfo.phase;
1961 newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChi ldBlockBackground : newPhase;
1962
1963 // We don't paint our own background, but we do let the kids paint their backgrounds.
1964 PaintInfo paintInfoForChild(paintInfo);
1965 paintInfoForChild.phase = newPhase;
1966 paintInfoForChild.updatePaintingRootForChildren(this);
1967 paintChildren(paintInfoForChild, paintOffset);
1968 }
1969 } 1761 }
1970 1762
1971 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOf fset) 1763 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
1972 { 1764 {
1973 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) 1765 BlockPainter(*this).paintChildren(paintInfo, paintOffset);
1974 paintChild(child, paintInfo, paintOffset);
1975 }
1976
1977 void RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const Layou tPoint& paintOffset)
1978 {
1979 LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
1980 if (!child->hasSelfPaintingLayer() && !child->isFloating())
1981 child->paint(paintInfo, childPoint);
1982 }
1983
1984 void RenderBlock::paintChildAsInlineBlock(RenderBox* child, PaintInfo& paintInfo , const LayoutPoint& paintOffset)
1985 {
1986 LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
1987 if (!child->hasSelfPaintingLayer() && !child->isFloating())
1988 paintAsInlineBlock(child, paintInfo, childPoint);
1989 }
1990
1991 void RenderBlock::paintAsInlineBlock(RenderObject* renderer, PaintInfo& paintInf o, const LayoutPoint& childPoint)
1992 {
1993 if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhase Selection)
1994 return;
1995
1996 // Paint all phases atomically, as though the element established its own
1997 // stacking context. (See Appendix E.2, section 7.2.1.4 on
1998 // inline block/table/replaced elements in the CSS2.1 specification.)
1999 // This is also used by other elements (e.g. flex items and grid items).
2000 bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.pha se == PaintPhaseTextClip;
2001 PaintInfo info(paintInfo);
2002 info.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2003 renderer->paint(info, childPoint);
2004 if (!preservePhase) {
2005 info.phase = PaintPhaseChildBlockBackgrounds;
2006 renderer->paint(info, childPoint);
2007 info.phase = PaintPhaseFloat;
2008 renderer->paint(info, childPoint);
2009 info.phase = PaintPhaseForeground;
2010 renderer->paint(info, childPoint);
2011 info.phase = PaintPhaseOutline;
2012 renderer->paint(info, childPoint);
2013 }
2014 }
2015
2016 static inline bool caretBrowsingEnabled(const Frame* frame)
2017 {
2018 Settings* settings = frame->settings();
2019 return settings && settings->caretBrowsingEnabled();
2020 }
2021
2022 static inline bool hasCursorCaret(const FrameSelection& selection, const RenderB lock* block, bool caretBrowsing)
2023 {
2024 return selection.caretRenderer() == block && (selection.hasEditableStyle() | | caretBrowsing);
2025 }
2026
2027 static inline bool hasDragCaret(const DragCaretController& dragCaretController, const RenderBlock* block, bool caretBrowsing)
2028 {
2029 return dragCaretController.caretRenderer() == block && (dragCaretController. isContentEditable() || caretBrowsing);
2030 }
2031
2032 bool RenderBlock::hasCaret() const
2033 {
2034 bool caretBrowsing = caretBrowsingEnabled(frame());
2035 return hasCursorCaret(frame()->selection(), this, caretBrowsing)
2036 || hasDragCaret(frame()->page()->dragCaretController(), this, caretBrows ing);
2037 }
2038
2039 void RenderBlock::paintCarets(PaintInfo& paintInfo, const LayoutPoint& paintOffs et)
2040 {
2041 bool caretBrowsing = caretBrowsingEnabled(frame());
2042
2043 FrameSelection& selection = frame()->selection();
2044 if (hasCursorCaret(selection, this, caretBrowsing)) {
2045 selection.paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
2046 }
2047
2048 DragCaretController& dragCaretController = frame()->page()->dragCaretControl ler();
2049 if (hasDragCaret(dragCaretController, this, caretBrowsing)) {
2050 dragCaretController.paintDragCaret(frame(), paintInfo.context, paintOffs et, paintInfo.rect);
2051 }
2052 } 1766 }
2053 1767
2054 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs et) 1768 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs et)
2055 { 1769 {
2056 PaintPhase paintPhase = paintInfo.phase; 1770 BlockPainter(*this).paintObject(paintInfo, paintOffset);
2057
2058 // Adjust our painting position if we're inside a scrolled layer (e.g., an o verflow:auto div).
2059 LayoutPoint scrolledOffset = paintOffset;
2060 if (hasOverflowClip())
2061 scrolledOffset.move(-scrolledContentOffset());
2062
2063 // 1. paint background, borders etc
2064 if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChil dBlockBackground) && style()->visibility() == VISIBLE) {
2065 if (hasBoxDecorationBackground())
2066 paintBoxDecorationBackground(paintInfo, paintOffset);
2067 if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
2068 paintColumnRules(paintInfo, scrolledOffset);
2069 }
2070
2071 if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2072 paintMask(paintInfo, paintOffset);
2073 return;
2074 }
2075
2076 if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE ) {
2077 paintClippingMask(paintInfo, paintOffset);
2078 return;
2079 }
2080
2081 // We're done. We don't bother painting any children.
2082 if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackground Only())
2083 return;
2084
2085 // 2. paint contents
2086 if (paintPhase != PaintPhaseSelfOutline) {
2087 if (hasColumns())
2088 paintColumnContents(paintInfo, scrolledOffset);
2089 else
2090 paintContents(paintInfo, scrolledOffset);
2091 }
2092
2093 // 3. paint selection
2094 // FIXME: Make this work with multi column layouts. For now don't fill gaps .
2095 bool isPrinting = document().printing();
2096 if (!isPrinting && !hasColumns())
2097 paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2098
2099 // 4. paint floats.
2100 if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || pa intPhase == PaintPhaseTextClip) {
2101 if (hasColumns())
2102 paintColumnContents(paintInfo, scrolledOffset, true);
2103 else
2104 paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelec tion || paintPhase == PaintPhaseTextClip);
2105 }
2106
2107 // 5. paint outline.
2108 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && style()->hasOutline() && style()->visibility() == VISIBLE) {
2109 // Don't paint focus ring for anonymous block continuation because the
2110 // inline element having outline-style:auto paints the whole focus ring.
2111 if (!style()->outlineStyleIsAuto() || !isAnonymousBlockContinuation())
2112 paintOutline(paintInfo, LayoutRect(paintOffset, size()));
2113 }
2114
2115 // 6. paint continuation outlines.
2116 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutline s))
2117 paintContinuationOutlines(paintInfo, paintOffset);
2118
2119 // 7. paint caret.
2120 // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2121 // then paint the caret.
2122 if (paintPhase == PaintPhaseForeground)
2123 paintCarets(paintInfo, paintOffset);
2124 } 1771 }
2125 1772
2126 RenderInline* RenderBlock::inlineElementContinuation() const 1773 RenderInline* RenderBlock::inlineElementContinuation() const
2127 { 1774 {
2128 RenderBoxModelObject* continuation = this->continuation(); 1775 RenderBoxModelObject* continuation = this->continuation();
2129 return continuation && continuation->isInline() ? toRenderInline(continuatio n) : 0; 1776 return continuation && continuation->isInline() ? toRenderInline(continuatio n) : 0;
2130 } 1777 }
2131 1778
2132 RenderBlock* RenderBlock::blockElementContinuation() const 1779 RenderBlock* RenderBlock::blockElementContinuation() const
2133 { 1780 {
2134 RenderBoxModelObject* currentContinuation = continuation(); 1781 RenderBoxModelObject* currentContinuation = continuation();
2135 if (!currentContinuation || currentContinuation->isInline()) 1782 if (!currentContinuation || currentContinuation->isInline())
2136 return 0; 1783 return 0;
2137 RenderBlock* nextContinuation = toRenderBlock(currentContinuation); 1784 RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2138 if (nextContinuation->isAnonymousBlock()) 1785 if (nextContinuation->isAnonymousBlock())
2139 return nextContinuation->blockElementContinuation(); 1786 return nextContinuation->blockElementContinuation();
2140 return nextContinuation; 1787 return nextContinuation;
2141 } 1788 }
2142 1789
2143 static ContinuationOutlineTableMap* continuationOutlineTable() 1790 ContinuationOutlineTableMap* continuationOutlineTable()
2144 { 1791 {
2145 DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ()); 1792 DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2146 return &table; 1793 return &table;
2147 } 1794 }
2148 1795
2149 void RenderBlock::addContinuationWithOutline(RenderInline* flow) 1796 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2150 { 1797 {
2151 // We can't make this work if the inline is in a layer. We'll just rely on the broken 1798 // We can't make this work if the inline is in a layer. We'll just rely on the broken
2152 // way of painting. 1799 // way of painting.
2153 ASSERT(!flow->layer() && !flow->isInlineElementContinuation()); 1800 ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2154 1801
2155 ContinuationOutlineTableMap* table = continuationOutlineTable(); 1802 ContinuationOutlineTableMap* table = continuationOutlineTable();
2156 ListHashSet<RenderInline*>* continuations = table->get(this); 1803 ListHashSet<RenderInline*>* continuations = table->get(this);
2157 if (!continuations) { 1804 if (!continuations) {
2158 continuations = new ListHashSet<RenderInline*>; 1805 continuations = new ListHashSet<RenderInline*>;
2159 table->set(this, adoptPtr(continuations)); 1806 table->set(this, adoptPtr(continuations));
2160 } 1807 }
2161 1808
2162 continuations->add(flow); 1809 continuations->add(flow);
2163 } 1810 }
2164 1811
2165 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2166 {
2167 ContinuationOutlineTableMap* table = continuationOutlineTable();
2168 if (table->isEmpty())
2169 return false;
2170
2171 ListHashSet<RenderInline*>* continuations = table->get(this);
2172 if (!continuations)
2173 return false;
2174
2175 return continuations->contains(flow);
2176 }
2177
2178 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
2179 {
2180 RenderInline* inlineCont = inlineElementContinuation();
2181 if (inlineCont && inlineCont->style()->hasOutline() && inlineCont->style()-> visibility() == VISIBLE) {
2182 RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->render er());
2183 RenderBlock* cb = containingBlock();
2184
2185 bool inlineEnclosedInSelfPaintingLayer = false;
2186 for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->p arent()->enclosingBoxModelObject()) {
2187 if (box->hasSelfPaintingLayer()) {
2188 inlineEnclosedInSelfPaintingLayer = true;
2189 break;
2190 }
2191 }
2192
2193 // Do not add continuations for outline painting by our containing block if we are a relative positioned
2194 // anonymous block (i.e. have our own layer), paint them straightaway in stead. This is because a block depends on renderers in its continuation table be ing
2195 // in the same layer.
2196 if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
2197 cb->addContinuationWithOutline(inlineRenderer);
2198 else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPainti ngLayer && hasLayer()))
2199 inlineRenderer->paintOutline(info, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
2200 }
2201
2202 ContinuationOutlineTableMap* table = continuationOutlineTable();
2203 if (table->isEmpty())
2204 return;
2205
2206 OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
2207 if (!continuations)
2208 return;
2209
2210 LayoutPoint accumulatedPaintOffset = paintOffset;
2211 // Paint each continuation outline.
2212 ListHashSet<RenderInline*>::iterator end = continuations->end();
2213 for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2214 // Need to add in the coordinates of the intervening blocks.
2215 RenderInline* flow = *it;
2216 RenderBlock* block = flow->containingBlock();
2217 for ( ; block && block != this; block = block->containingBlock())
2218 accumulatedPaintOffset.moveBy(block->location());
2219 ASSERT(block);
2220 flow->paintOutline(info, accumulatedPaintOffset);
2221 }
2222 }
2223
2224 bool RenderBlock::shouldPaintSelectionGaps() const 1812 bool RenderBlock::shouldPaintSelectionGaps() const
2225 { 1813 {
2226 return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot(); 1814 return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2227 } 1815 }
2228 1816
2229 bool RenderBlock::isSelectionRoot() const 1817 bool RenderBlock::isSelectionRoot() const
2230 { 1818 {
2231 if (isPseudoElement()) 1819 if (isPseudoElement())
2232 return false; 1820 return false;
2233 ASSERT(node() || isAnonymous()); 1821 ASSERT(node() || isAnonymous());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 if (hasOverflowClip()) 1854 if (hasOverflowClip())
2267 offsetFromPaintInvalidationContainer -= scrolledContentOffset(); 1855 offsetFromPaintInvalidationContainer -= scrolledContentOffset();
2268 1856
2269 LayoutUnit lastTop = 0; 1857 LayoutUnit lastTop = 0;
2270 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop); 1858 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2271 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop); 1859 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2272 1860
2273 return selectionGaps(this, offsetFromPaintInvalidationContainer, IntSize(), lastTop, lastLeft, lastRight); 1861 return selectionGaps(this, offsetFromPaintInvalidationContainer, IntSize(), lastTop, lastLeft, lastRight);
2274 } 1862 }
2275 1863
2276 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintO ffset)
2277 {
2278 if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2279 LayoutUnit lastTop = 0;
2280 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2281 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2282 GraphicsContextStateSaver stateSaver(*paintInfo.context);
2283
2284 LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize( ), lastTop, lastLeft, lastRight, &paintInfo);
2285 if (!gapRectsBounds.isEmpty()) {
2286 RenderLayer* layer = enclosingLayer();
2287 gapRectsBounds.moveBy(-paintOffset);
2288 if (!hasLayer()) {
2289 LayoutRect localBounds(gapRectsBounds);
2290 flipForWritingMode(localBounds);
2291 gapRectsBounds = localToContainerQuad(FloatRect(localBounds), la yer->renderer()).enclosingBoundingBox();
2292 if (layer->renderer()->hasOverflowClip())
2293 gapRectsBounds.move(layer->renderBox()->scrolledContentOffse t());
2294 }
2295 layer->addBlockSelectionGapsBounds(gapRectsBounds);
2296 }
2297 }
2298 }
2299
2300 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoi nt& offset, TrackedRendererListHashSet* positionedObjects) 1864 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoi nt& offset, TrackedRendererListHashSet* positionedObjects)
2301 { 1865 {
2302 if (!positionedObjects) 1866 if (!positionedObjects)
2303 return; 1867 return;
2304 1868
2305 TrackedRendererListHashSet::const_iterator end = positionedObjects->end(); 1869 TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
2306 for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begi n(); it != end; ++it) { 1870 for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begi n(); it != end; ++it) {
2307 RenderBox* r = *it; 1871 RenderBox* r = *it;
2308 paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r- >y(), r->width(), r->height())); 1872 paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r- >y(), r->width(), r->height()));
2309 } 1873 }
(...skipping 2486 matching lines...) Expand 10 before | Expand all | Expand 10 after
4796 4360
4797 if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects( )) { 4361 if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects( )) {
4798 TrackedRendererListHashSet::const_iterator end = positionedDescendantSet ->end(); 4362 TrackedRendererListHashSet::const_iterator end = positionedDescendantSet ->end();
4799 for (TrackedRendererListHashSet::const_iterator it = positionedDescendan tSet->begin(); it != end; ++it) { 4363 for (TrackedRendererListHashSet::const_iterator it = positionedDescendan tSet->begin(); it != end; ++it) {
4800 RenderBox* currBox = *it; 4364 RenderBox* currBox = *it;
4801 ASSERT(!currBox->needsLayout()); 4365 ASSERT(!currBox->needsLayout());
4802 } 4366 }
4803 } 4367 }
4804 } 4368 }
4805 4369
4370 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
4371 {
4372 ContinuationOutlineTableMap* table = continuationOutlineTable();
4373 if (table->isEmpty())
4374 return false;
4375
4376 ListHashSet<RenderInline*>* continuations = table->get(this);
4377 if (!continuations)
4378 return false;
4379
4380 return continuations->contains(flow);
4381 }
4382
4806 #endif 4383 #endif
4807 4384
4808 #ifndef NDEBUG 4385 #ifndef NDEBUG
4809 4386
4810 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const 4387 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const
4811 { 4388 {
4812 showRenderObject(); 4389 showRenderObject();
4813 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 4390 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
4814 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 4391 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
4815 } 4392 }
4816 4393
4817 #endif 4394 #endif
4818 4395
4819 } // namespace blink 4396 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698