OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2006 Apple Computer, Inc. | 3 * Copyright (C) 2006 Apple Computer, Inc. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 { | 132 { |
133 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); | 133 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); |
134 if (!m_layoutState) | 134 if (!m_layoutState) |
135 return false; | 135 return false; |
136 return (delta.width() == m_layoutState->m_layoutDelta.width() || m_layou
tState->m_layoutDeltaXSaturated) && (delta.height() == m_layoutState->m_layoutDe
lta.height() || m_layoutState->m_layoutDeltaYSaturated); | 136 return (delta.width() == m_layoutState->m_layoutDelta.width() || m_layou
tState->m_layoutDeltaXSaturated) && (delta.height() == m_layoutState->m_layoutDe
lta.height() || m_layoutState->m_layoutDeltaYSaturated); |
137 } | 137 } |
138 #endif | 138 #endif |
139 | 139 |
140 bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); } | 140 bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); } |
141 | 141 |
142 // Subtree push/pop | 142 // Subtree push |
143 void pushLayoutState(RenderObject*); | 143 void pushLayoutState(RenderObject&); |
144 void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doin
g this to keep popLayoutState() private and to make the subtree calls symmetrica
l. | |
145 | 144 |
146 bool shouldDisableLayoutStateForSubtree(RenderObject*) const; | 145 void popLayoutState() |
| 146 { |
| 147 LayoutState* state = m_layoutState; |
| 148 m_layoutState = state->m_next; |
| 149 delete state; |
| 150 popLayoutStateForCurrentFlowThread(); |
| 151 } |
| 152 |
| 153 bool shouldDisableLayoutStateForSubtree(RenderObject&) const; |
147 | 154 |
148 // Returns true if layoutState should be used for its cached offset and clip
. | 155 // Returns true if layoutState should be used for its cached offset and clip
. |
149 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m
_layoutState; } | 156 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m
_layoutState; } |
150 LayoutState* layoutState() const { return m_layoutState; } | 157 LayoutState* layoutState() const { return m_layoutState; } |
151 | 158 |
152 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID
E; | 159 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID
E; |
153 | 160 |
154 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } | 161 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } |
155 void setPageLogicalHeight(LayoutUnit height) | 162 void setPageLogicalHeight(LayoutUnit height) |
156 { | 163 { |
(...skipping 30 matching lines...) Expand all Loading... |
187 // rewrite the counter and quotes code. | 194 // rewrite the counter and quotes code. |
188 void addRenderCounter() { m_renderCounterCount++; } | 195 void addRenderCounter() { m_renderCounterCount++; } |
189 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount
erCount--; } | 196 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount
erCount--; } |
190 bool hasRenderCounters() { return m_renderCounterCount; } | 197 bool hasRenderCounters() { return m_renderCounterCount; } |
191 | 198 |
192 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const OVERRIDE; | 199 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const OVERRIDE; |
193 | 200 |
194 double layoutViewportWidth() const; | 201 double layoutViewportWidth() const; |
195 double layoutViewportHeight() const; | 202 double layoutViewportHeight() const; |
196 | 203 |
| 204 // Suspends the LayoutState optimization. Used under transforms that cannot
be represented by |
| 205 // LayoutState (common in SVG) and when manipulating the render tree during
layout in ways |
| 206 // that can trigger repaint of a non-child (e.g. when a list item moves its
list marker around). |
| 207 // Note that even when disabled, LayoutState is still used to store layoutDe
lta. |
| 208 // These functions may only be accessed by LayoutStateMaintainer or LayoutSt
ateDisabler. |
| 209 void disableLayoutState() { m_layoutStateDisableCount++; } |
| 210 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutSt
ateDisableCount--; } |
| 211 |
197 private: | 212 private: |
198 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContai
ner, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed =
0) const OVERRIDE; | 213 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContai
ner, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed =
0) const OVERRIDE; |
199 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObj
ect* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; | 214 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObj
ect* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; |
200 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c
onst OVERRIDE; | 215 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c
onst OVERRIDE; |
201 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint&
layerOffset) const OVERRIDE; | 216 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint&
layerOffset) const OVERRIDE; |
202 | 217 |
203 void initializeLayoutState(LayoutState&); | 218 void initializeLayoutState(LayoutState&); |
204 | 219 |
205 bool shouldRepaint(const LayoutRect&) const; | 220 bool shouldRepaint(const LayoutRect&) const; |
206 | 221 |
207 bool rootFillsViewportBackground(RenderBox* rootBox) const; | 222 bool rootFillsViewportBackground(RenderBox* rootBox) const; |
208 | 223 |
209 // These functions may only be accessed by LayoutStateMaintainer. | 224 // These functions may only be accessed by LayoutStateMaintainer. |
210 bool pushLayoutState(RenderBox* renderer, const LayoutSize& offset, LayoutUn
it pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) | 225 bool pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn
it pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) |
211 { | 226 { |
212 // We push LayoutState even if layoutState is disabled because it stores
layoutDelta too. | 227 // We push LayoutState even if layoutState is disabled because it stores
layoutDelta too. |
213 if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->has
Columns() || renderer->flowThreadContainingBlock() | 228 if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer.hasC
olumns() || renderer.flowThreadContainingBlock() |
214 || (renderer->isRenderBlock() && toRenderBlock(renderer)->shapeInsid
eInfo()) | 229 || (renderer.isRenderBlock() && toRenderBlock(renderer).shapeInsideI
nfo()) |
215 || (m_layoutState->shapeInsideInfo() && renderer->isRenderBlock() &&
!toRenderBlock(renderer)->allowsShapeInsideInfoSharing(m_layoutState->shapeInsi
deInfo()->owner())) | 230 || (m_layoutState->shapeInsideInfo() && renderer.isRenderBlock() &&
!toRenderBlock(renderer).allowsShapeInsideInfoSharing(m_layoutState->shapeInside
Info()->owner())) |
216 ) { | 231 ) { |
217 pushLayoutStateForCurrentFlowThread(renderer); | 232 pushLayoutStateForCurrentFlowThread(renderer); |
218 m_layoutState = new LayoutState(m_layoutState, renderer, offset, pag
eHeight, pageHeightChanged, colInfo); | 233 m_layoutState = new LayoutState(m_layoutState, renderer, offset, pag
eHeight, pageHeightChanged, colInfo); |
219 return true; | 234 return true; |
220 } | 235 } |
221 return false; | 236 return false; |
222 } | 237 } |
223 | 238 |
224 void popLayoutState() | |
225 { | |
226 LayoutState* state = m_layoutState; | |
227 m_layoutState = state->m_next; | |
228 delete state; | |
229 popLayoutStateForCurrentFlowThread(); | |
230 } | |
231 | |
232 // Suspends the LayoutState optimization. Used under transforms that cannot
be represented by | |
233 // LayoutState (common in SVG) and when manipulating the render tree during
layout in ways | |
234 // that can trigger repaint of a non-child (e.g. when a list item moves its
list marker around). | |
235 // Note that even when disabled, LayoutState is still used to store layoutDe
lta. | |
236 // These functions may only be accessed by LayoutStateMaintainer or LayoutSt
ateDisabler. | |
237 void disableLayoutState() { m_layoutStateDisableCount++; } | |
238 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutSt
ateDisableCount--; } | |
239 | |
240 void layoutContent(const LayoutState&); | 239 void layoutContent(const LayoutState&); |
241 #ifndef NDEBUG | 240 #ifndef NDEBUG |
242 void checkLayoutState(const LayoutState&); | 241 void checkLayoutState(const LayoutState&); |
243 #endif | 242 #endif |
244 | 243 |
245 void positionDialog(RenderBox*); | 244 void positionDialog(RenderBox*); |
246 void positionDialogs(); | 245 void positionDialogs(); |
247 | 246 |
248 void pushLayoutStateForCurrentFlowThread(const RenderObject*); | 247 void pushLayoutStateForCurrentFlowThread(const RenderObject&); |
249 void popLayoutStateForCurrentFlowThread(); | 248 void popLayoutStateForCurrentFlowThread(); |
250 | 249 |
251 friend class LayoutStateMaintainer; | 250 friend class LayoutStateMaintainer; |
252 friend class LayoutStateDisabler; | 251 friend class LayoutStateDisabler; |
253 | 252 |
254 bool shouldUsePrintingLayout() const; | 253 bool shouldUsePrintingLayout() const; |
255 | 254 |
256 FrameView* m_frameView; | 255 FrameView* m_frameView; |
257 | 256 |
258 RenderObject* m_selectionStart; | 257 RenderObject* m_selectionStart; |
(...skipping 17 matching lines...) Expand all Loading... |
276 unsigned m_renderCounterCount; | 275 unsigned m_renderCounterCount; |
277 }; | 276 }; |
278 | 277 |
279 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); | 278 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); |
280 | 279 |
281 // Stack-based class to assist with LayoutState push/pop | 280 // Stack-based class to assist with LayoutState push/pop |
282 class LayoutStateMaintainer { | 281 class LayoutStateMaintainer { |
283 WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer); | 282 WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer); |
284 public: | 283 public: |
285 // ctor to push now | 284 // ctor to push now |
286 LayoutStateMaintainer(RenderBox* root, LayoutSize offset, LayoutUnit pageHei
ght = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) | 285 explicit LayoutStateMaintainer(RenderBox& root, const LayoutSize& offset, La
youtUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0
) |
287 : m_view(root->view()) | 286 : m_view(*root.view()) |
288 , m_disabled(root->shouldDisableLayoutState()) | 287 , m_disabled(root.shouldDisableLayoutState()) |
289 , m_didStart(false) | 288 , m_didStart(false) |
290 , m_didEnd(false) | 289 , m_didEnd(false) |
291 , m_didCreateLayoutState(false) | 290 , m_didCreateLayoutState(false) |
292 { | 291 { |
293 push(root, offset, pageHeight, pageHeightChanged, colInfo); | 292 push(root, offset, pageHeight, pageHeightChanged, colInfo); |
294 } | 293 } |
295 | 294 |
296 // ctor to maybe push later | 295 // ctor to maybe push later |
297 LayoutStateMaintainer(RenderBox* root) | 296 explicit LayoutStateMaintainer(RenderBox& root) |
298 : m_view(root->view()) | 297 : m_view(*root.view()) |
299 , m_disabled(false) | 298 , m_disabled(false) |
300 , m_didStart(false) | 299 , m_didStart(false) |
301 , m_didEnd(false) | 300 , m_didEnd(false) |
302 , m_didCreateLayoutState(false) | 301 , m_didCreateLayoutState(false) |
303 { | 302 { |
304 } | 303 } |
305 | 304 |
306 ~LayoutStateMaintainer() | 305 ~LayoutStateMaintainer() |
307 { | 306 { |
308 ASSERT(m_didStart == m_didEnd); // if this fires, it means that someon
e did a push(), but forgot to pop(). | 307 ASSERT(m_didStart == m_didEnd); // if this fires, it means that someon
e did a push(), but forgot to pop(). |
309 } | 308 } |
310 | 309 |
311 void push(RenderBox* root, LayoutSize offset, LayoutUnit pageHeight = 0, boo
l pageHeightChanged = false, ColumnInfo* colInfo = 0) | 310 void push(RenderBox& root, const LayoutSize& offset, LayoutUnit pageHeight =
0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) |
312 { | 311 { |
313 ASSERT(!m_didStart); | 312 ASSERT(!m_didStart); |
314 // We push state even if disabled, because we still need to store layout
Delta | 313 // We push state even if disabled, because we still need to store layout
Delta |
315 m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeigh
t, pageHeightChanged, colInfo); | 314 m_didCreateLayoutState = m_view.pushLayoutState(root, offset, pageHeight
, pageHeightChanged, colInfo); |
316 if (m_disabled && m_didCreateLayoutState) | 315 if (m_disabled && m_didCreateLayoutState) |
317 m_view->disableLayoutState(); | 316 m_view.disableLayoutState(); |
318 m_didStart = true; | 317 m_didStart = true; |
319 } | 318 } |
320 | 319 |
321 void pop() | 320 void pop() |
322 { | 321 { |
323 if (m_didStart) { | 322 if (m_didStart) { |
324 ASSERT(!m_didEnd); | 323 ASSERT(!m_didEnd); |
325 if (m_didCreateLayoutState) { | 324 if (m_didCreateLayoutState) { |
326 m_view->popLayoutState(); | 325 m_view.popLayoutState(); |
327 if (m_disabled) | 326 if (m_disabled) |
328 m_view->enableLayoutState(); | 327 m_view.enableLayoutState(); |
329 } | 328 } |
330 | 329 |
331 m_didEnd = true; | 330 m_didEnd = true; |
332 } | 331 } |
333 } | 332 } |
334 | 333 |
335 bool didPush() const { return m_didStart; } | 334 bool didPush() const { return m_didStart; } |
336 | 335 |
337 private: | 336 private: |
338 RenderView* m_view; | 337 RenderView& m_view; |
339 bool m_disabled : 1; // true if the offset and clip part of layoutSta
te is disabled | 338 bool m_disabled : 1; // true if the offset and clip part of layoutSta
te is disabled |
340 bool m_didStart : 1; // true if we did a push or disable | 339 bool m_didStart : 1; // true if we did a push or disable |
341 bool m_didEnd : 1; // true if we popped or re-enabled | 340 bool m_didEnd : 1; // true if we popped or re-enabled |
342 bool m_didCreateLayoutState : 1; // true if we actually made a layout state. | 341 bool m_didCreateLayoutState : 1; // true if we actually made a layout state. |
343 }; | 342 }; |
344 | 343 |
345 class LayoutStateDisabler { | 344 class LayoutStateDisabler { |
346 WTF_MAKE_NONCOPYABLE(LayoutStateDisabler); | 345 WTF_MAKE_NONCOPYABLE(LayoutStateDisabler); |
347 public: | 346 public: |
348 LayoutStateDisabler(RenderView* view) | 347 LayoutStateDisabler(const RenderBox& root) |
349 : m_view(view) | 348 : m_view(*root.view()) |
350 { | 349 { |
351 if (m_view) | 350 m_view.disableLayoutState(); |
352 m_view->disableLayoutState(); | |
353 } | 351 } |
354 | 352 |
355 ~LayoutStateDisabler() | 353 ~LayoutStateDisabler() |
356 { | 354 { |
357 if (m_view) | 355 m_view.enableLayoutState(); |
358 m_view->enableLayoutState(); | |
359 } | 356 } |
360 private: | 357 private: |
361 RenderView* m_view; | 358 RenderView& m_view; |
362 }; | 359 }; |
363 | 360 |
364 } // namespace WebCore | 361 } // namespace WebCore |
365 | 362 |
366 #endif // RenderView_h | 363 #endif // RenderView_h |
OLD | NEW |