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_frameView.nodeToDraw() is used to draw only one element (and its descen
dants) |
| 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()); |
| 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 |