1 /* 2 * This file is part of the HTML widget for KDE. 3 * 4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 * Copyright (C) 2006 Apple Computer, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 * 22 */ 23 24 #ifndef RenderView_h 25 #define RenderView_h 26 27 #include "FrameView.h" 28 #include "Frame.h" 29 #include "LayoutState.h" 30 #include "RenderBlock.h" 31 32 namespace WebCore { 33 34 class RenderView : public RenderBlock { 35 public: 36 RenderView(Node*, FrameView*); 37 virtual ~RenderView(); 38 renderName()39 virtual const char* renderName() const { return "RenderView"; } 40 isRenderView()41 virtual bool isRenderView() const { return true; } 42 43 virtual void layout(); 44 virtual void calcWidth(); 45 virtual void calcHeight(); 46 virtual void calcPrefWidths(); 47 virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const; 48 virtual FloatPoint absoluteToLocal(FloatPoint containerPoint, bool fixed = false, bool useTransforms = false) const; 49 50 int docHeight() const; 51 int docWidth() const; 52 53 // The same as the FrameView's layoutHeight/layoutWidth but with null check guards. 54 int viewHeight() const; 55 int viewWidth() const; 56 zoomFactor()57 float zoomFactor() const { return m_frameView->frame() && m_frameView->frame()->shouldApplyPageZoom() ? m_frameView->frame()->zoomFactor() : 1.0f; } 58 frameView()59 FrameView* frameView() const { return m_frameView; } 60 hasOverhangingFloats()61 virtual bool hasOverhangingFloats() { return false; } 62 63 virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false); 64 virtual void repaintViewRectangle(const IntRect&, bool immediate = false); 65 66 virtual void paint(PaintInfo&, int tx, int ty); 67 virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); 68 69 void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos); 70 void clearSelection(); selectionStart()71 virtual RenderObject* selectionStart() const { return m_selectionStart; } selectionEnd()72 virtual RenderObject* selectionEnd() const { return m_selectionEnd; } 73 74 bool printing() const; setPrintImages(bool enable)75 void setPrintImages(bool enable) { m_printImages = enable; } printImages()76 bool printImages() const { return m_printImages; } setTruncatedAt(int y)77 void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; } 78 void setBestTruncatedAt(int y, RenderBox* forRenderer, bool forcedBreak = false); bestTruncatedAt()79 int bestTruncatedAt() const { return m_bestTruncatedAt; } 80 truncatedAt()81 int truncatedAt() const { return m_truncatedAt; } 82 83 virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true); 84 virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true); 85 86 IntRect selectionBounds(bool clipToVisibleContent = true) const; 87 setMaximalOutlineSize(int o)88 void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; } maximalOutlineSize()89 int maximalOutlineSize() const { return m_maximalOutlineSize; } 90 91 virtual IntRect viewRect() const; 92 93 virtual void selectionStartEnd(int& startPos, int& endPos) const; 94 printRect()95 IntRect printRect() const { return m_printRect; } setPrintRect(const IntRect & r)96 void setPrintRect(const IntRect& r) { m_printRect = r; } 97 98 void updateWidgetPositions(); 99 void addWidget(RenderObject*); 100 void removeWidget(RenderObject*); 101 102 // layoutDelta is used transiently during layout to store how far an object has moved from its 103 // last layout location, in order to repaint correctly. 104 // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter. layoutDelta()105 IntSize layoutDelta() const 106 { 107 return m_layoutState ? m_layoutState->m_layoutDelta : IntSize(); 108 } addLayoutDelta(const IntSize & delta)109 void addLayoutDelta(const IntSize& delta) 110 { 111 if (m_layoutState) 112 m_layoutState->m_layoutDelta += delta; 113 } 114 doingFullRepaint()115 bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); } 116 pushLayoutState(RenderBox * renderer,const IntSize & offset)117 void pushLayoutState(RenderBox* renderer, const IntSize& offset) 118 { 119 if (doingFullRepaint()) 120 return; 121 // We push LayoutState even if layoutState is disabled because it stores layoutDelta too. 122 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset); 123 } 124 125 void pushLayoutState(RenderObject*); 126 popLayoutState()127 void popLayoutState() 128 { 129 if (doingFullRepaint()) 130 return; 131 LayoutState* state = m_layoutState; 132 m_layoutState = state->m_next; 133 state->destroy(renderArena()); 134 } 135 136 // Returns true if layoutState should be used for its cached offset and clip. layoutStateEnabled()137 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; } layoutState()138 LayoutState* layoutState() const { return m_layoutState; } 139 140 // Suspends the LayoutState optimization. Used under transforms that cannot be represented by 141 // LayoutState (common in SVG) and when manipulating the render tree during layout in ways 142 // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around). 143 // Note that even when disabled, LayoutState is still used to store layoutDelta. disableLayoutState()144 void disableLayoutState() { m_layoutStateDisableCount++; } enableLayoutState()145 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; } 146 147 protected: 148 virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const; 149 150 private: 151 // selectionRect should never be called on a RenderView 152 virtual IntRect selectionRect(bool); 153 154 protected: 155 FrameView* m_frameView; 156 157 RenderObject* m_selectionStart; 158 RenderObject* m_selectionEnd; 159 int m_selectionStartPos; 160 int m_selectionEndPos; 161 162 // used to ignore viewport width when printing to the printer 163 bool m_printImages; 164 int m_truncatedAt; 165 166 int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables. 167 IntRect m_printRect; // Used when printing. 168 169 typedef HashSet<RenderObject*> RenderObjectSet; 170 171 RenderObjectSet m_widgets; 172 173 private: 174 int m_bestTruncatedAt; 175 int m_truncatorWidth; 176 bool m_forcedPageBreak; 177 LayoutState* m_layoutState; 178 unsigned m_layoutStateDisableCount; 179 }; 180 181 // Stack-based class to assist with LayoutState push/pop 182 class LayoutStateMaintainer : Noncopyable { 183 public: 184 // ctor to push now 185 LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false) m_view(view)186 : m_view(view) 187 , m_disabled(disableState) 188 , m_didStart(false) 189 , m_didEnd(false) 190 { 191 push(root, offset); 192 } 193 194 // ctor to maybe push later LayoutStateMaintainer(RenderView * view)195 LayoutStateMaintainer(RenderView* view) 196 : m_view(view) 197 , m_disabled(false) 198 , m_didStart(false) 199 , m_didEnd(false) 200 { 201 } 202 ~LayoutStateMaintainer()203 ~LayoutStateMaintainer() 204 { 205 ASSERT(m_didStart == m_didEnd); // if this fires, it means that someone did a push(), but forgot to pop(). 206 } 207 push(RenderBox * root,IntSize offset)208 void push(RenderBox* root, IntSize offset) 209 { 210 ASSERT(!m_didStart); 211 // We push state even if disabled, because we still need to store layoutDelta 212 m_view->pushLayoutState(root, offset); 213 if (m_disabled) 214 m_view->disableLayoutState(); 215 m_didStart = true; 216 } 217 pop()218 void pop() 219 { 220 if (m_didStart) { 221 ASSERT(!m_didEnd); 222 m_view->popLayoutState(); 223 if (m_disabled) 224 m_view->enableLayoutState(); 225 m_didEnd = true; 226 } 227 } 228 didPush()229 bool didPush() const { return m_didStart; } 230 231 private: 232 RenderView* m_view; 233 bool m_disabled : 1; // true if the offset and clip part of layoutState is disabled 234 bool m_didStart : 1; // true if we did a push or disable 235 bool m_didEnd : 1; // true if we popped or re-enabled 236 }; 237 238 } // namespace WebCore 239 240 #endif // RenderView_h 241