OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/paint/FramePainter.h" | |
7 | |
8 #include "core/dom/DocumentMarkerController.h" | |
9 #include "core/frame/FrameView.h" | |
10 #include "core/inspector/InspectorInstrumentation.h" | |
11 #include "core/inspector/InspectorTraceEvents.h" | |
12 #include "core/page/Chrome.h" | |
13 #include "core/page/ChromeClient.h" | |
14 #include "core/page/Page.h" | |
15 #include "core/paint/LayerPainter.h" | |
16 #include "core/paint/ScrollbarPainter.h" | |
17 #include "core/rendering/RenderLayer.h" | |
18 #include "core/rendering/RenderView.h" | |
19 #include "platform/fonts/FontCache.h" | |
20 #include "platform/graphics/GraphicsContext.h" | |
21 #include "platform/graphics/GraphicsContextStateSaver.h" | |
22 #include "platform/scroll/ScrollbarTheme.h" | |
23 | |
24 namespace blink { | |
25 | |
26 bool FramePainter::s_inPaintContents = false; | |
27 | |
28 void FramePainter::paint(GraphicsContext* context, const IntRect& rect) | |
29 { | |
30 m_frameView.notifyPageThatContentAreaWillPaint(); | |
31 | |
32 IntRect documentDirtyRect = rect; | |
33 IntRect visibleAreaWithoutScrollbars(m_frameView.location(), m_frameView.vis ibleContentRect().size()); | |
34 documentDirtyRect.intersect(visibleAreaWithoutScrollbars); | |
35 | |
36 if (!documentDirtyRect.isEmpty()) { | |
37 GraphicsContextStateSaver stateSaver(*context); | |
38 | |
39 context->translate(m_frameView.x() - m_frameView.scrollX(), m_frameView. y() - m_frameView.scrollY()); | |
40 context->clip(m_frameView.visibleContentRect()); | |
41 | |
42 documentDirtyRect.moveBy(-m_frameView.location() + m_frameView.scrollPos ition()); | |
43 paintContents(context, documentDirtyRect); | |
44 } | |
45 | |
46 calculateAndPaintOverhangAreas(context, rect); | |
47 | |
48 // Now paint the scrollbars. | |
49 if (!m_frameView.scrollbarsSuppressed() && (m_frameView.horizontalScrollbar( ) || m_frameView.verticalScrollbar())) { | |
50 GraphicsContextStateSaver stateSaver(*context); | |
51 IntRect scrollViewDirtyRect = rect; | |
52 IntRect visibleAreaWithScrollbars(m_frameView.location(), m_frameView.vi sibleContentRect(IncludeScrollbars).size()); | |
53 scrollViewDirtyRect.intersect(visibleAreaWithScrollbars); | |
54 context->translate(m_frameView.x(), m_frameView.y()); | |
55 scrollViewDirtyRect.moveBy(-m_frameView.location()); | |
56 context->clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size())); | |
57 | |
58 paintScrollbars(context, scrollViewDirtyRect); | |
59 } | |
60 | |
61 // Paint the panScroll Icon | |
62 if (m_frameView.drawPanScrollIcon()) | |
63 m_frameView.paintPanScrollIcon(context); | |
64 } | |
65 | |
66 void FramePainter::paintContents(GraphicsContext* p, const IntRect& rect) | |
67 { | |
68 Document* document = m_frameView.frame().document(); | |
69 | |
70 #ifndef NDEBUG | |
71 bool fillWithRed; | |
72 if (document->printing()) | |
73 fillWithRed = false; // Printing, don't fill with red (can't remember wh y). | |
74 else if (m_frameView.frame().owner()) | |
75 fillWithRed = false; // Subframe, don't fill with red. | |
76 else if (m_frameView.isTransparent()) | |
77 fillWithRed = false; // Transparent, don't fill with red. | |
78 else if (m_frameView.paintBehavior() & PaintBehaviorSelectionOnly) | |
79 fillWithRed = false; // Selections are transparent, don't fill with red. | |
80 else if (m_frameView.nodeToDraw()) | |
81 fillWithRed = false; // Element images are transparent, don't fill with red. | |
82 else | |
83 fillWithRed = true; | |
84 | |
85 if (fillWithRed) | |
86 p->fillRect(rect, Color(0xFF, 0, 0)); | |
87 #endif | |
88 | |
89 RenderView* renderView = m_frameView.renderView(); | |
90 if (!renderView) { | |
91 WTF_LOG_ERROR("called FramePainter::paint with nil renderer"); | |
92 return; | |
93 } | |
94 | |
95 RELEASE_ASSERT(!m_frameView.needsLayout()); | |
96 ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean) ; | |
97 | |
98 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data" , InspectorPaintEvent::data(renderView, rect, 0)); | |
99 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", "stack", InspectorCallStackEvent::currentCallStack()); | |
100 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli ne migrates to tracing. | |
101 InspectorInstrumentation::willPaint(renderView, 0); | |
102 | |
103 bool isTopLevelPainter = !s_inPaintContents; | |
104 s_inPaintContents = true; | |
105 | |
106 FontCachePurgePreventer fontCachePurgePreventer; | |
107 | |
108 PaintBehavior oldPaintBehavior = m_frameView.paintBehavior(); | |
109 | |
110 if (FrameView* parentView = m_frameView.parentFrameView()) { | |
111 if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers) | |
112 m_frameView.setPaintBehavior(m_frameView.paintBehavior() | PaintBeha viorFlattenCompositingLayers); | |
113 } | |
114 | |
115 if (m_frameView.paintBehavior() == PaintBehaviorNormal) | |
116 document->markers().invalidateRenderedRectsForMarkersInRect(rect); | |
117 | |
118 if (document->printing()) | |
119 m_frameView.setPaintBehavior(m_frameView.paintBehavior() | PaintBehavior FlattenCompositingLayers); | |
120 | |
121 ASSERT(!m_frameView.isPainting()); | |
122 m_frameView.setIsPainting(true); | |
123 | |
124 // m_nodeToDraw is used to draw only one element (and its descendants) | |
leviw_travelin_and_unemployed
2014/10/14 22:06:11
s/m_nodeToDraw()/nodeToDraw/?
chrishtr
2014/10/14 22:11:43
Done.
| |
125 RenderObject* renderer = m_frameView.nodeToDraw() ? m_frameView.nodeToDraw() ->renderer() : 0; | |
126 RenderLayer* rootLayer = renderView->layer(); | |
127 | |
128 #if ENABLE(ASSERT) | |
129 renderView->assertSubtreeIsLaidOut(); | |
130 RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer- >renderer()); | |
131 #endif | |
132 | |
133 LayerPainter layerPainter(*rootLayer); | |
134 | |
135 layerPainter.paint(p, rect, m_frameView.paintBehavior(), renderer); | |
136 | |
137 if (rootLayer->containsDirtyOverlayScrollbars()) | |
138 layerPainter.paintOverlayScrollbars(p, rect, m_frameView.paintBehavior() , renderer); | |
139 | |
140 m_frameView.setIsPainting(false); | |
141 | |
142 m_frameView.setPaintBehavior(oldPaintBehavior); | |
143 m_frameView.setLastPaintTime(currentTime()); | |
144 | |
145 // Regions may have changed as a result of the visibility/z-index of element changing. | |
146 if (document->annotatedRegionsDirty()) | |
147 m_frameView.updateAnnotatedRegions(); | |
148 | |
149 if (isTopLevelPainter) { | |
150 // Everything that happens after paintContents completions is considered | |
151 // to be part of the next frame. | |
152 m_frameView.setCurrentFrameTimeStamp(currentTime()); | |
leviw_travelin_and_unemployed
2014/10/14 22:06:11
This is kinda funky, but alright.
chrishtr
2014/10/14 22:11:43
Yeah.
| |
153 s_inPaintContents = false; | |
154 } | |
155 | |
156 InspectorInstrumentation::didPaint(renderView, 0, p, rect); | |
157 } | |
158 | |
159 void FramePainter::paintScrollbars(GraphicsContext* context, const IntRect& rect ) | |
160 { | |
161 if (m_frameView.horizontalScrollbar() && !m_frameView.layerForHorizontalScro llbar()) | |
162 paintScrollbar(context, m_frameView.horizontalScrollbar(), rect); | |
163 if (m_frameView.verticalScrollbar() && !m_frameView.layerForVerticalScrollba r()) | |
164 paintScrollbar(context, m_frameView.verticalScrollbar(), rect); | |
165 | |
166 if (m_frameView.layerForScrollCorner()) | |
167 return; | |
168 paintScrollCorner(context, m_frameView.scrollCornerRect()); | |
169 } | |
170 | |
171 void FramePainter::paintScrollCorner(GraphicsContext* context, const IntRect& co rnerRect) | |
172 { | |
173 if (m_frameView.scrollCorner()) { | |
174 bool needsBackground = m_frameView.frame().isMainFrame(); | |
175 if (needsBackground) | |
176 context->fillRect(cornerRect, m_frameView.baseBackgroundColor()); | |
177 ScrollbarPainter::paintIntoRect(m_frameView.scrollCorner(), context, cor nerRect.location(), cornerRect); | |
178 return; | |
179 } | |
180 | |
181 ScrollbarTheme::theme()->paintScrollCorner(context, cornerRect); | |
182 } | |
183 | |
184 void FramePainter::paintScrollbar(GraphicsContext* context, Scrollbar* bar, cons t IntRect& rect) | |
185 { | |
186 bool needsBackground = bar->isCustomScrollbar() && m_frameView.frame().isMai nFrame(); | |
187 if (needsBackground) { | |
188 IntRect toFill = bar->frameRect(); | |
189 toFill.intersect(rect); | |
190 context->fillRect(toFill, m_frameView.baseBackgroundColor()); | |
191 } | |
192 | |
193 bar->paint(context, rect); | |
194 } | |
195 | |
196 void FramePainter::paintOverhangAreas(GraphicsContext* context, const IntRect& h orizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirty Rect) | |
197 { | |
198 if (m_frameView.frame().document()->printing()) | |
199 return; | |
200 | |
201 if (m_frameView.frame().isMainFrame()) { | |
202 if (m_frameView.frame().page()->chrome().client().paintCustomOverhangAre a(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect)) | |
203 return; | |
204 } | |
205 | |
206 paintOverhangAreasInternal(context, horizontalOverhangArea, verticalOverhang Area, dirtyRect); | |
207 } | |
208 | |
209 void FramePainter::paintOverhangAreasInternal(GraphicsContext* context, const In tRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRec t& dirtyRect) | |
210 { | |
211 ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOverhang Rect, verticalOverhangRect, dirtyRect); | |
212 ScrollbarTheme::theme()->paintOverhangShadows(context, m_frameView.scrollOff set(), horizontalOverhangRect, verticalOverhangRect, dirtyRect); | |
213 } | |
214 | |
215 void FramePainter::calculateAndPaintOverhangAreas(GraphicsContext* context, cons t IntRect& dirtyRect) | |
216 { | |
217 IntRect horizontalOverhangRect; | |
218 IntRect verticalOverhangRect; | |
219 m_frameView.calculateOverhangAreasForPainting(horizontalOverhangRect, vertic alOverhangRect); | |
220 | |
221 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver ticalOverhangRect)) | |
222 paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect , dirtyRect); | |
223 } | |
224 | |
225 } // namespace blink | |
OLD | NEW |