1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2006 Apple Computer, Inc. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #ifndef RenderView_h 23 #define RenderView_h 24 25 #include "core/frame/FrameView.h" 26 #include "core/rendering/LayoutState.h" 27 #include "core/rendering/RenderBlockFlow.h" 28 #include "platform/PODFreeListArena.h" 29 #include "platform/scroll/ScrollableArea.h" 30 #include "wtf/OwnPtr.h" 31 32 namespace WebCore { 33 34 class FlowThreadController; 35 class RenderLayerCompositor; 36 class RenderQuote; 37 38 // The root of the render tree, corresponding to the CSS initial containing block. 39 // It's dimensions match that of the logical viewport (which may be different from 40 // the visible viewport in fixed-layout mode), and it is always at position (0,0) 41 // relative to the document (and so isn't necessarily in view). 42 class RenderView FINAL : public RenderBlockFlow { 43 public: 44 explicit RenderView(Document*); 45 virtual ~RenderView(); 46 47 bool hitTest(const HitTestRequest&, HitTestResult&); 48 bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&); 49 renderName()50 virtual const char* renderName() const OVERRIDE { return "RenderView"; } 51 isRenderView()52 virtual bool isRenderView() const OVERRIDE { return true; } 53 layerTypeRequired()54 virtual LayerType layerTypeRequired() const OVERRIDE { return NormalLayer; } 55 56 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE; 57 58 virtual void layout() OVERRIDE; 59 virtual void updateLogicalWidth() OVERRIDE; 60 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE; 61 62 virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const OVERRIDE; 63 64 // The same as the FrameView's layoutHeight/layoutWidth but with null check guards. 65 int viewHeight(IncludeScrollbarsInRect = ExcludeScrollbars) const; 66 int viewWidth(IncludeScrollbarsInRect = ExcludeScrollbars) const; viewLogicalWidth()67 int viewLogicalWidth() const 68 { 69 return style()->isHorizontalWritingMode() ? viewWidth(ExcludeScrollbars) : viewHeight(ExcludeScrollbars); 70 } 71 int viewLogicalHeight() const; 72 LayoutUnit viewLogicalHeightForPercentages() const; 73 74 float zoomFactor() const; 75 frameView()76 FrameView* frameView() const { return m_frameView; } 77 78 virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE; 79 void repaintViewRectangle(const LayoutRect&) const; 80 81 void repaintViewAndCompositedLayers(); 82 83 virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE; 84 virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE; 85 86 enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing }; 87 void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld); 88 void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const; 89 void clearSelection(); selectionStart()90 RenderObject* selectionStart() const { return m_selectionStart; } selectionEnd()91 RenderObject* selectionEnd() const { return m_selectionEnd; } 92 IntRect selectionBounds(bool clipToVisibleContent = true) const; 93 void selectionStartEnd(int& startPos, int& endPos) const; 94 void repaintSelection() const; 95 96 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE; 97 virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE; 98 99 virtual LayoutRect viewRect() const OVERRIDE; 100 101 // layoutDelta is used transiently during layout to store how far an object has moved from its 102 // last layout location, in order to repaint correctly. 103 // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter. layoutDelta()104 LayoutSize layoutDelta() const 105 { 106 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); 107 return m_layoutState ? m_layoutState->layoutDelta() : LayoutSize(); 108 } addLayoutDelta(const LayoutSize & delta)109 void addLayoutDelta(const LayoutSize& delta) 110 { 111 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); 112 if (m_layoutState) 113 m_layoutState->addLayoutDelta(delta); 114 } 115 116 #if ASSERT_ENABLED layoutDeltaMatches(const LayoutSize & delta)117 bool layoutDeltaMatches(const LayoutSize& delta) 118 { 119 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); 120 if (!m_layoutState) 121 return false; 122 return (delta.width() == m_layoutState->layoutDelta().width() || m_layoutState->layoutDeltaXSaturated()) && (delta.height() == m_layoutState->layoutDelta().height() || m_layoutState->layoutDeltaYSaturated()); 123 } 124 #endif 125 126 bool shouldDoFullRepaintForNextLayout() const; doingFullRepaint()127 bool doingFullRepaint() const { return m_frameView->needsFullPaintInvalidation(); } 128 129 // Returns true if layoutState should be used for its cached offset and clip. layoutStateCachedOffsetsEnabled()130 bool layoutStateCachedOffsetsEnabled() const { return m_layoutState && m_layoutState->cachedOffsetsEnabled(); } layoutState()131 LayoutState* layoutState() const { return m_layoutState; } 132 canMapUsingLayoutStateForContainer(const RenderObject * repaintContainer)133 bool canMapUsingLayoutStateForContainer(const RenderObject* repaintContainer) const 134 { 135 // FIXME: LayoutState should be enabled for other repaint containers than the RenderView. crbug.com/363834 136 return layoutStateCachedOffsetsEnabled() && (repaintContainer == this); 137 } 138 139 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRIDE; 140 pageLogicalHeight()141 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } setPageLogicalHeight(LayoutUnit height)142 void setPageLogicalHeight(LayoutUnit height) 143 { 144 if (m_pageLogicalHeight != height) { 145 m_pageLogicalHeight = height; 146 m_pageLogicalHeightChanged = true; 147 } 148 } pageLogicalHeightChanged()149 bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; } 150 151 // Notification that this view moved into or out of a native window. 152 void setIsInWindow(bool); 153 154 RenderLayerCompositor* compositor(); 155 bool usesCompositing() const; 156 157 IntRect unscaledDocumentRect() const; 158 LayoutRect backgroundRect(RenderBox* backgroundRenderer) const; 159 160 IntRect documentRect() const; 161 162 // Renderer that paints the root background has background-images which all have background-attachment: fixed. 163 bool rootBackgroundIsEntirelyFixed() const; 164 165 FlowThreadController* flowThreadController(); 166 167 IntervalArena* intervalArena(); 168 setRenderQuoteHead(RenderQuote * head)169 void setRenderQuoteHead(RenderQuote* head) { m_renderQuoteHead = head; } renderQuoteHead()170 RenderQuote* renderQuoteHead() const { return m_renderQuoteHead; } 171 172 // FIXME: This is a work around because the current implementation of counters 173 // requires walking the entire tree repeatedly and most pages don't actually use either 174 // feature so we shouldn't take the performance hit when not needed. Long term we should 175 // rewrite the counter and quotes code. addRenderCounter()176 void addRenderCounter() { m_renderCounterCount++; } removeRenderCounter()177 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCounterCount--; } hasRenderCounters()178 bool hasRenderCounters() { return m_renderCounterCount; } 179 180 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE; 181 182 double layoutViewportWidth() const; 183 double layoutViewportHeight() const; 184 185 void pushLayoutState(LayoutState&); 186 void popLayoutState(); 187 private: 188 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE; 189 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; 190 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE; 191 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE; 192 193 virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer) OVERRIDE FINAL; 194 195 bool shouldRepaint(const LayoutRect&) const; 196 197 bool rootFillsViewportBackground(RenderBox* rootBox) const; 198 199 void layoutContent(); 200 #ifndef NDEBUG 201 void checkLayoutState(); 202 #endif 203 204 void positionDialog(RenderBox*); 205 void positionDialogs(); 206 207 friend class ForceHorriblySlowRectMapping; 208 209 bool shouldUsePrintingLayout() const; 210 211 RenderObject* backgroundRenderer() const; 212 213 FrameView* m_frameView; 214 215 RenderObject* m_selectionStart; 216 RenderObject* m_selectionEnd; 217 218 int m_selectionStartPos; 219 int m_selectionEndPos; 220 221 LayoutUnit m_pageLogicalHeight; 222 bool m_pageLogicalHeightChanged; 223 LayoutState* m_layoutState; 224 OwnPtr<RenderLayerCompositor> m_compositor; 225 OwnPtr<FlowThreadController> m_flowThreadController; 226 RefPtr<IntervalArena> m_intervalArena; 227 228 RenderQuote* m_renderQuoteHead; 229 unsigned m_renderCounterCount; 230 }; 231 232 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); 233 234 // Suspends the LayoutState cached offset and clipRect optimization. Used under transforms 235 // that cannot be represented by LayoutState (common in SVG) and when manipulating the render 236 // tree during layout in ways that can trigger repaint of a non-child (e.g. when a list item 237 // moves its list marker around). Note that even when disabled, LayoutState is still used to 238 // store layoutDelta. 239 class ForceHorriblySlowRectMapping { 240 WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping); 241 public: ForceHorriblySlowRectMapping(const RenderObject & root)242 ForceHorriblySlowRectMapping(const RenderObject& root) 243 : m_view(*root.view()) 244 , m_didDisable(m_view.layoutState() && m_view.layoutState()->cachedOffsetsEnabled()) 245 { 246 if (m_view.layoutState()) 247 m_view.layoutState()->m_cachedOffsetsEnabled = false; 248 #if ASSERT_ENABLED 249 m_layoutState = m_view.layoutState(); 250 #endif 251 } 252 ~ForceHorriblySlowRectMapping()253 ~ForceHorriblySlowRectMapping() 254 { 255 ASSERT(m_view.layoutState() == m_layoutState); 256 if (m_didDisable) 257 m_view.layoutState()->m_cachedOffsetsEnabled = true; 258 } 259 private: 260 RenderView& m_view; 261 bool m_didDisable; 262 #if ASSERT_ENABLED 263 LayoutState* m_layoutState; 264 #endif 265 }; 266 267 } // namespace WebCore 268 269 #endif // RenderView_h 270