1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) 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 "FrameView.h" 26 #include "LayoutState.h" 27 #include "RenderBlock.h" 28 #include <wtf/OwnPtr.h> 29 30 namespace WebCore { 31 32 class RenderWidget; 33 34 #if USE(ACCELERATED_COMPOSITING) 35 class RenderLayerCompositor; 36 #endif 37 38 class RenderView : public RenderBlock { 39 public: 40 RenderView(Node*, FrameView*); 41 virtual ~RenderView(); 42 43 virtual const char* renderName() const { return "RenderView"; } 44 45 virtual bool isRenderView() const { return true; } 46 47 virtual bool requiresLayer() const { return true; } 48 49 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const; 50 51 virtual void layout(); 52 virtual void computeLogicalWidth(); 53 virtual void computeLogicalHeight(); 54 virtual void computePreferredLogicalWidths(); 55 56 // The same as the FrameView's layoutHeight/layoutWidth but with null check guards. 57 int viewHeight() const; 58 int viewWidth() const; 59 int viewLogicalWidth() const { return style()->isHorizontalWritingMode() ? viewWidth() : viewHeight(); } 60 int viewLogicalHeight() const { return style()->isHorizontalWritingMode() ? viewHeight() : viewWidth(); } 61 62 float zoomFactor() const; 63 64 FrameView* frameView() const { return m_frameView; } 65 66 virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false); 67 virtual void repaintViewRectangle(const IntRect&, bool immediate = false); 68 // Repaint the view, and all composited layers that intersect the given absolute rectangle. 69 // FIXME: ideally we'd never have to do this, if all repaints are container-relative. 70 virtual void repaintRectangleInViewAndCompositedLayers(const IntRect&, bool immediate = false); 71 72 virtual void paint(PaintInfo&, int tx, int ty); 73 virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); 74 75 enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld }; 76 void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld); 77 void clearSelection(); 78 RenderObject* selectionStart() const { return m_selectionStart; } 79 RenderObject* selectionEnd() const { return m_selectionEnd; } 80 IntRect selectionBounds(bool clipToVisibleContent = true) const; 81 void selectionStartEnd(int& startPos, int& endPos) const; 82 83 bool printing() const; 84 85 virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); 86 virtual void absoluteQuads(Vector<FloatQuad>&); 87 88 #if USE(ACCELERATED_COMPOSITING) 89 void setMaximalOutlineSize(int o); 90 #else 91 void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; } 92 #endif 93 int maximalOutlineSize() const { return m_maximalOutlineSize; } 94 95 virtual IntRect viewRect() const; 96 97 void updateWidgetPositions(); 98 void addWidget(RenderWidget*); 99 void removeWidget(RenderWidget*); 100 101 void notifyWidgets(WidgetNotification); 102 #ifdef ANDROID_PLUGINS 103 const HashSet<RenderWidget*>& widgets() const { return m_widgets; } 104 #endif 105 106 // layoutDelta is used transiently during layout to store how far an object has moved from its 107 // last layout location, in order to repaint correctly. 108 // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter. 109 IntSize layoutDelta() const 110 { 111 return m_layoutState ? m_layoutState->m_layoutDelta : IntSize(); 112 } 113 void addLayoutDelta(const IntSize& delta) 114 { 115 if (m_layoutState) 116 m_layoutState->m_layoutDelta += delta; 117 } 118 119 bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); } 120 121 // Subtree push/pop 122 void pushLayoutState(RenderObject*); 123 void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical. 124 125 bool shouldDisableLayoutStateForSubtree(RenderObject*) const; 126 127 // Returns true if layoutState should be used for its cached offset and clip. 128 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; } 129 LayoutState* layoutState() const { return m_layoutState; } 130 131 // Suspends the LayoutState optimization. Used under transforms that cannot be represented by 132 // LayoutState (common in SVG) and when manipulating the render tree during layout in ways 133 // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around). 134 // Note that even when disabled, LayoutState is still used to store layoutDelta. 135 void disableLayoutState() { m_layoutStateDisableCount++; } 136 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; } 137 138 virtual void updateHitTestResult(HitTestResult&, const IntPoint&); 139 140 unsigned pageLogicalHeight() const { return m_pageLogicalHeight; } 141 void setPageLogicalHeight(unsigned height) 142 { 143 if (m_pageLogicalHeight != height) { 144 m_pageLogicalHeight = height; 145 m_pageLogicalHeightChanged = true; 146 } 147 } 148 149 // FIXME: These functions are deprecated. No code should be added that uses these. 150 int bestTruncatedAt() const { return m_legacyPrinting.m_bestTruncatedAt; } 151 void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false); 152 int truncatedAt() const { return m_legacyPrinting.m_truncatedAt; } 153 void setTruncatedAt(int y) 154 { 155 m_legacyPrinting.m_truncatedAt = y; 156 m_legacyPrinting.m_bestTruncatedAt = 0; 157 m_legacyPrinting.m_truncatorWidth = 0; 158 m_legacyPrinting.m_forcedPageBreak = false; 159 } 160 const IntRect& printRect() const { return m_legacyPrinting.m_printRect; } 161 void setPrintRect(const IntRect& r) { m_legacyPrinting.m_printRect = r; } 162 // End deprecated functions. 163 164 // Notifications that this view became visible in a window, or will be 165 // removed from the window. 166 void didMoveOnscreen(); 167 void willMoveOffscreen(); 168 169 #if USE(ACCELERATED_COMPOSITING) 170 RenderLayerCompositor* compositor(); 171 bool usesCompositing() const; 172 #endif 173 174 int docTop() const; 175 int docBottom() const; 176 int docHeight() const { return docBottom() - docTop(); } 177 int docLeft() const; 178 int docRight() const; 179 int docWidth() const { return docRight() - docLeft(); } 180 IntRect documentRect() const { return IntRect(docLeft(), docTop(), docWidth(), docHeight()); } 181 182 protected: 183 virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const; 184 virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; 185 186 private: 187 bool shouldRepaint(const IntRect& r) const; 188 189 // These functions may only be accessed by LayoutStateMaintainer. 190 bool pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 191 { 192 // We push LayoutState even if layoutState is disabled because it stores layoutDelta too. 193 if (!doingFullRepaint() || renderer->hasColumns() || m_layoutState->isPaginated()) { 194 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo); 195 return true; 196 } 197 return false; 198 } 199 200 void popLayoutState() 201 { 202 LayoutState* state = m_layoutState; 203 m_layoutState = state->m_next; 204 state->destroy(renderArena()); 205 } 206 207 size_t getRetainedWidgets(Vector<RenderWidget*>&); 208 void releaseWidgets(Vector<RenderWidget*>&); 209 210 friend class LayoutStateMaintainer; 211 212 protected: 213 FrameView* m_frameView; 214 215 RenderObject* m_selectionStart; 216 RenderObject* m_selectionEnd; 217 int m_selectionStartPos; 218 int m_selectionEndPos; 219 220 // FIXME: Only used by embedded WebViews inside AppKit NSViews. Find a way to remove. 221 struct LegacyPrinting { 222 LegacyPrinting() 223 : m_bestTruncatedAt(0) 224 , m_truncatedAt(0) 225 , m_truncatorWidth(0) 226 , m_forcedPageBreak(false) 227 { } 228 229 int m_bestTruncatedAt; 230 int m_truncatedAt; 231 int m_truncatorWidth; 232 IntRect m_printRect; 233 bool m_forcedPageBreak; 234 }; 235 LegacyPrinting m_legacyPrinting; 236 // End deprecated members. 237 238 int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables. 239 240 typedef HashSet<RenderWidget*> RenderWidgetSet; 241 RenderWidgetSet m_widgets; 242 243 private: 244 unsigned m_pageLogicalHeight; 245 bool m_pageLogicalHeightChanged; 246 LayoutState* m_layoutState; 247 unsigned m_layoutStateDisableCount; 248 #if USE(ACCELERATED_COMPOSITING) 249 OwnPtr<RenderLayerCompositor> m_compositor; 250 #endif 251 }; 252 253 inline RenderView* toRenderView(RenderObject* object) 254 { 255 ASSERT(!object || object->isRenderView()); 256 return static_cast<RenderView*>(object); 257 } 258 259 inline const RenderView* toRenderView(const RenderObject* object) 260 { 261 ASSERT(!object || object->isRenderView()); 262 return static_cast<const RenderView*>(object); 263 } 264 265 // This will catch anyone doing an unnecessary cast. 266 void toRenderView(const RenderView*); 267 268 269 // Stack-based class to assist with LayoutState push/pop 270 class LayoutStateMaintainer { 271 WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer); 272 public: 273 // ctor to push now 274 LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 275 : m_view(view) 276 , m_disabled(disableState) 277 , m_didStart(false) 278 , m_didEnd(false) 279 , m_didCreateLayoutState(false) 280 { 281 push(root, offset, pageHeight, pageHeightChanged, colInfo); 282 } 283 284 // ctor to maybe push later 285 LayoutStateMaintainer(RenderView* view) 286 : m_view(view) 287 , m_disabled(false) 288 , m_didStart(false) 289 , m_didEnd(false) 290 , m_didCreateLayoutState(false) 291 { 292 } 293 294 ~LayoutStateMaintainer() 295 { 296 ASSERT(m_didStart == m_didEnd); // if this fires, it means that someone did a push(), but forgot to pop(). 297 } 298 299 void push(RenderBox* root, IntSize offset, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 300 { 301 ASSERT(!m_didStart); 302 // We push state even if disabled, because we still need to store layoutDelta 303 m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo); 304 if (m_disabled && m_didCreateLayoutState) 305 m_view->disableLayoutState(); 306 m_didStart = true; 307 } 308 309 void pop() 310 { 311 if (m_didStart) { 312 ASSERT(!m_didEnd); 313 if (m_didCreateLayoutState) { 314 m_view->popLayoutState(); 315 if (m_disabled) 316 m_view->enableLayoutState(); 317 } 318 319 m_didEnd = true; 320 } 321 } 322 323 bool didPush() const { return m_didStart; } 324 325 private: 326 RenderView* m_view; 327 bool m_disabled : 1; // true if the offset and clip part of layoutState is disabled 328 bool m_didStart : 1; // true if we did a push or disable 329 bool m_didEnd : 1; // true if we popped or re-enabled 330 bool m_didCreateLayoutState : 1; // true if we actually made a layout state. 331 }; 332 333 } // namespace WebCore 334 335 #endif // RenderView_h 336