Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: Source/core/rendering/RenderRegion.cpp

Issue 153233002: *** DO NOT LAND *** Remove regions support, keeping a bare minimum to support "region-based"... (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/rendering/RenderRegion.h ('k') | Source/core/rendering/RenderRegionSet.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. 2 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above 8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following 9 * copyright notice, this list of conditions and the following
10 * disclaimer. 10 * disclaimer.
(...skipping 16 matching lines...) Expand all
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30 #include "config.h" 30 #include "config.h"
31 #include "core/rendering/RenderRegion.h" 31 #include "core/rendering/RenderRegion.h"
32 32
33 #include "core/css/resolver/StyleResolver.h" 33 #include "core/css/resolver/StyleResolver.h"
34 #include "core/rendering/FlowThreadController.h" 34 #include "core/rendering/FlowThreadController.h"
35 #include "core/rendering/HitTestLocation.h" 35 #include "core/rendering/HitTestLocation.h"
36 #include "core/rendering/PaintInfo.h" 36 #include "core/rendering/PaintInfo.h"
37 #include "core/rendering/RenderBoxRegionInfo.h" 37 #include "core/rendering/RenderFlowThread.h"
38 #include "core/rendering/RenderNamedFlowThread.h"
39 #include "core/rendering/RenderView.h" 38 #include "core/rendering/RenderView.h"
40 39
41 using namespace std; 40 using namespace std;
42 41
43 namespace WebCore { 42 namespace WebCore {
44 43
45 RenderRegion::RenderRegion(Element* element, RenderFlowThread* flowThread) 44 RenderRegion::RenderRegion(Element* element, RenderFlowThread* flowThread)
46 : RenderBlockFlow(element) 45 : RenderBlockFlow(element)
47 , m_flowThread(flowThread) 46 , m_flowThread(flowThread)
48 , m_parentNamedFlowThread(0)
49 , m_computedAutoHeight(-1)
50 , m_isValid(false) 47 , m_isValid(false)
51 , m_hasCustomRegionStyle(false)
52 , m_hasAutoLogicalHeight(false)
53 { 48 {
54 } 49 }
55 50
56 LayoutUnit RenderRegion::pageLogicalWidth() const 51 LayoutUnit RenderRegion::pageLogicalWidth() const
57 { 52 {
58 ASSERT(m_flowThread); 53 ASSERT(m_flowThread);
59 return m_flowThread->isHorizontalWritingMode() ? contentWidth() : contentHei ght(); 54 return m_flowThread->isHorizontalWritingMode() ? contentWidth() : contentHei ght();
60 } 55 }
61 56
62 LayoutUnit RenderRegion::pageLogicalHeight() const 57 LayoutUnit RenderRegion::pageLogicalHeight() const
63 { 58 {
64 ASSERT(m_flowThread); 59 ASSERT(m_flowThread);
65 if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
66 ASSERT(hasAutoLogicalHeight());
67 return computedAutoHeight();
68 }
69 return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWi dth(); 60 return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWi dth();
70 } 61 }
71 62
72 // This method returns the maximum page size of a region with auto-height. This is the initial
73 // height value for auto-height regions in the first layout phase of the parent named flow.
74 LayoutUnit RenderRegion::maxPageLogicalHeight() const
75 {
76 ASSERT(m_flowThread);
77 ASSERT(hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase());
78 return style()->logicalMaxHeight().isUndefined() ? RenderFlowThread::maxLogi calHeight() : computeReplacedLogicalHeightUsing(style()->logicalMaxHeight());
79 }
80
81 LayoutUnit RenderRegion::logicalHeightOfAllFlowThreadContent() const 63 LayoutUnit RenderRegion::logicalHeightOfAllFlowThreadContent() const
82 { 64 {
83 ASSERT(m_flowThread); 65 ASSERT(m_flowThread);
84 if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
85 ASSERT(hasAutoLogicalHeight());
86 return computedAutoHeight();
87 }
88 return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWi dth(); 66 return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWi dth();
89 } 67 }
90 68
91 LayoutRect RenderRegion::flowThreadPortionOverflowRect() const 69 LayoutRect RenderRegion::flowThreadPortionOverflowRect() const
92 { 70 {
93 return overflowRectForFlowThreadPortion(flowThreadPortionRect(), isFirstRegi on(), isLastRegion()); 71 return overflowRectForFlowThreadPortion(flowThreadPortionRect(), isFirstRegi on(), isLastRegion());
94 } 72 }
95 73
96 LayoutRect RenderRegion::overflowRectForFlowThreadPortion(const LayoutRect& flow ThreadPortionRect, bool isFirstPortion, bool isLastPortion) const 74 LayoutRect RenderRegion::overflowRectForFlowThreadPortion(const LayoutRect& flow ThreadPortionRect, bool isFirstPortion, bool isLastPortion) const
97 { 75 {
98 ASSERT(isValid()); 76 ASSERT(isValid());
99 77
100 bool isLastRegionWithRegionFragmentBreak = (isLastPortion && (style()->regio nFragment() == BreakRegionFragment)); 78 if (hasOverflowClip())
101 if (hasOverflowClip() || isLastRegionWithRegionFragmentBreak)
102 return flowThreadPortionRect; 79 return flowThreadPortionRect;
103 80
104 LayoutRect flowThreadOverflow = m_flowThread->visualOverflowRect(); 81 LayoutRect flowThreadOverflow = m_flowThread->visualOverflowRect();
105 82
106 // Only clip along the flow thread axis. 83 // Only clip along the flow thread axis.
107 LayoutUnit outlineSize = maximalOutlineSize(PaintPhaseOutline); 84 LayoutUnit outlineSize = maximalOutlineSize(PaintPhaseOutline);
108 LayoutRect clipRect; 85 LayoutRect clipRect;
109 bool shouldApplyClip = !style()->isOverflowVisible(); 86 bool shouldApplyClip = !style()->isOverflowVisible();
110 if (m_flowThread->isHorizontalWritingMode()) { 87 if (m_flowThread->isHorizontalWritingMode()) {
111 LayoutUnit minY = isFirstPortion ? (flowThreadOverflow.y() - outlineSize ) : flowThreadPortionRect.y(); 88 LayoutUnit minY = isFirstPortion ? (flowThreadOverflow.y() - outlineSize ) : flowThreadPortionRect.y();
112 LayoutUnit maxY = isLastPortion ? max(flowThreadPortionRect.maxY(), flow ThreadOverflow.maxY()) + outlineSize : flowThreadPortionRect.maxY(); 89 LayoutUnit maxY = isLastPortion ? max(flowThreadPortionRect.maxY(), flow ThreadOverflow.maxY()) + outlineSize : flowThreadPortionRect.maxY();
113 LayoutUnit minX = shouldApplyClip ? flowThreadPortionRect.x() : min(flow ThreadPortionRect.x(), flowThreadOverflow.x() - outlineSize); 90 LayoutUnit minX = shouldApplyClip ? flowThreadPortionRect.x() : min(flow ThreadPortionRect.x(), flowThreadOverflow.x() - outlineSize);
114 LayoutUnit maxX = shouldApplyClip ? flowThreadPortionRect.maxX() : max(f lowThreadPortionRect.maxX(), (flowThreadOverflow.maxX() + outlineSize)); 91 LayoutUnit maxX = shouldApplyClip ? flowThreadPortionRect.maxX() : max(f lowThreadPortionRect.maxX(), (flowThreadOverflow.maxX() + outlineSize));
115 clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY); 92 clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY);
116 } else { 93 } else {
117 LayoutUnit minX = isFirstPortion ? (flowThreadOverflow.x() - outlineSize ) : flowThreadPortionRect.x(); 94 LayoutUnit minX = isFirstPortion ? (flowThreadOverflow.x() - outlineSize ) : flowThreadPortionRect.x();
118 LayoutUnit maxX = isLastPortion ? max(flowThreadPortionRect.maxX(), flow ThreadOverflow.maxX()) + outlineSize : flowThreadPortionRect.maxX(); 95 LayoutUnit maxX = isLastPortion ? max(flowThreadPortionRect.maxX(), flow ThreadOverflow.maxX()) + outlineSize : flowThreadPortionRect.maxX();
119 LayoutUnit minY = shouldApplyClip ? flowThreadPortionRect.y() : min(flow ThreadPortionRect.y(), (flowThreadOverflow.y() - outlineSize)); 96 LayoutUnit minY = shouldApplyClip ? flowThreadPortionRect.y() : min(flow ThreadPortionRect.y(), (flowThreadOverflow.y() - outlineSize));
120 LayoutUnit maxY = shouldApplyClip ? flowThreadPortionRect.maxY() : max(f lowThreadPortionRect.y(), (flowThreadOverflow.maxY() + outlineSize)); 97 LayoutUnit maxY = shouldApplyClip ? flowThreadPortionRect.maxY() : max(f lowThreadPortionRect.y(), (flowThreadOverflow.maxY() + outlineSize));
121 clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY); 98 clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY);
122 } 99 }
123 100
124 return clipRect; 101 return clipRect;
125 } 102 }
126 103
127 RegionOversetState RenderRegion::regionOversetState() const
128 {
129 if (isValid() && element())
130 return element()->regionOversetState();
131
132 return RegionUndefined;
133 }
134
135 void RenderRegion::setRegionOversetState(RegionOversetState state)
136 {
137 if (element())
138 element()->setRegionOversetState(state);
139 }
140
141 Element* RenderRegion::element() const
142 {
143 ASSERT(nodeForRegion() && nodeForRegion()->isElementNode());
144 return toElement(nodeForRegion());
145 }
146
147 LayoutUnit RenderRegion::pageLogicalTopForOffset(LayoutUnit /* offset */) const 104 LayoutUnit RenderRegion::pageLogicalTopForOffset(LayoutUnit /* offset */) const
148 { 105 {
149 return flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x(); 106 return flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x();
150 } 107 }
151 108
152 bool RenderRegion::isFirstRegion() const 109 bool RenderRegion::isFirstRegion() const
153 { 110 {
154 ASSERT(isValid()); 111 ASSERT(isValid());
155 112
156 return m_flowThread->firstRegion() == this; 113 return m_flowThread->firstRegion() == this;
157 } 114 }
158 115
159 bool RenderRegion::isLastRegion() const 116 bool RenderRegion::isLastRegion() const
160 { 117 {
161 ASSERT(isValid()); 118 ASSERT(isValid());
162 119
163 return m_flowThread->lastRegion() == this; 120 return m_flowThread->lastRegion() == this;
164 } 121 }
165 122
166 static bool shouldPaintRegionContentsInPhase(PaintPhase phase)
167 {
168 return phase == PaintPhaseForeground
169 || phase == PaintPhaseSelection
170 || phase == PaintPhaseTextClip;
171 }
172
173 void RenderRegion::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOff set)
174 {
175 if (style()->visibility() != VISIBLE)
176 return;
177
178 RenderBlock::paintObject(paintInfo, paintOffset);
179
180 if (!isValid())
181 return;
182
183 // Delegate painting of content in region to RenderFlowThread.
184 // RenderFlowThread is a self painting layer (being a positioned object) who is painting its children, the collected objects.
185 // Since we do not want to paint the flow thread content multiple times (for each painting phase of the region object),
186 // we allow the flow thread painting only in certain phases.
187 if (!shouldPaintRegionContentsInPhase(paintInfo.phase))
188 return;
189
190 setRegionObjectsRegionStyle();
191 m_flowThread->paintFlowThreadPortionInRegion(paintInfo, this, flowThreadPort ionRect(), flowThreadPortionOverflowRect(), LayoutPoint(paintOffset.x() + border Left() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop()));
192 restoreRegionObjectsOriginalStyle();
193 }
194
195 // Hit Testing
196 bool RenderRegion::hitTestFlowThreadContents(const HitTestRequest& request, HitT estResult& result, const HitTestLocation& locationInContainer, const LayoutPoint & accumulatedOffset, HitTestAction action)
197 {
198 if (!isValid() || action != HitTestForeground)
199 return false;
200
201 LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region());
202 boundsRect.moveBy(accumulatedOffset);
203 if (visibleToHitTesting() && locationInContainer.intersects(boundsRect)) {
204 if (m_flowThread->hitTestFlowThreadPortionInRegion(this, flowThreadPorti onRect(), flowThreadPortionOverflowRect(), request, result,
205 locationInContainer, LayoutPoint(accumulatedOffset.x() + borderLeft( ) + paddingLeft(), accumulatedOffset.y() + borderTop() + paddingTop())))
206 return true;
207 }
208
209 return false;
210 }
211
212 void RenderRegion::checkRegionStyle()
213 {
214 ASSERT(m_flowThread);
215 bool customRegionStyle = false;
216
217 // FIXME: Region styling doesn't work for pseudo elements.
218 if (isElementBasedRegion())
219 customRegionStyle = view()->document().ensureStyleResolver().checkRegion Style(this->element());
220
221 setHasCustomRegionStyle(customRegionStyle);
222 m_flowThread->checkRegionsWithStyling();
223 }
224
225 void RenderRegion::incrementAutoLogicalHeightCount()
226 {
227 ASSERT(isValid());
228 ASSERT(m_hasAutoLogicalHeight);
229
230 m_flowThread->incrementAutoLogicalHeightRegions();
231 }
232
233 void RenderRegion::decrementAutoLogicalHeightCount()
234 {
235 ASSERT(isValid());
236
237 m_flowThread->decrementAutoLogicalHeightRegions();
238 }
239
240 void RenderRegion::updateRegionHasAutoLogicalHeightFlag()
241 {
242 ASSERT(m_flowThread);
243
244 if (!isValid())
245 return;
246
247 bool didHaveAutoLogicalHeight = m_hasAutoLogicalHeight;
248 m_hasAutoLogicalHeight = shouldHaveAutoLogicalHeight();
249 if (m_hasAutoLogicalHeight != didHaveAutoLogicalHeight) {
250 if (m_hasAutoLogicalHeight) {
251 incrementAutoLogicalHeightCount();
252 } else {
253 clearComputedAutoHeight();
254 decrementAutoLogicalHeightCount();
255 }
256 }
257 }
258
259 bool RenderRegion::shouldHaveAutoLogicalHeight() const
260 {
261 bool hasSpecifiedEndpointsForHeight = style()->logicalTop().isSpecified() && style()->logicalBottom().isSpecified();
262 bool hasAnchoredEndpointsForHeight = isOutOfFlowPositioned() && hasSpecified EndpointsForHeight;
263 bool hasAutoHeightStyle = style()->logicalHeight().isAuto() || style()->logi calHeight().isFitContent()
264 || style()->logicalHeight().isMaxContent() || style()->logicalHeight().i sMinContent();
265 return hasAutoHeightStyle && !hasAnchoredEndpointsForHeight;
266 }
267
268 void RenderRegion::styleDidChange(StyleDifference diff, const RenderStyle* oldSt yle)
269 {
270 RenderBlock::styleDidChange(diff, oldStyle);
271
272 // If the region is not attached to any thread, there is no need to check
273 // whether the region has region styling since no content will be displayed
274 // into the region.
275 if (!m_flowThread) {
276 setHasCustomRegionStyle(false);
277 return;
278 }
279
280 checkRegionStyle();
281 updateRegionHasAutoLogicalHeightFlag();
282
283 if (oldStyle && oldStyle->writingMode() != style()->writingMode())
284 m_flowThread->regionChangedWritingMode(this);
285 }
286
287 void RenderRegion::layoutBlock(bool relayoutChildren) 123 void RenderRegion::layoutBlock(bool relayoutChildren)
288 { 124 {
289 RenderBlockFlow::layoutBlock(relayoutChildren); 125 RenderBlockFlow::layoutBlock(relayoutChildren);
290 126
291 if (isValid()) {
292 LayoutRect oldRegionRect(flowThreadPortionRect());
293 if (!isHorizontalWritingMode())
294 oldRegionRect = oldRegionRect.transposedRect();
295
296 if (hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
297 m_flowThread->invalidateRegions();
298 clearComputedAutoHeight();
299 return;
300 }
301
302 if (!isRenderRegionSet() && (oldRegionRect.width() != pageLogicalWidth() || oldRegionRect.height() != pageLogicalHeight())) {
303 // This can happen even if we are in the inConstrainedLayoutPhase an d it will trigger a pathological layout of the flow thread.
304 m_flowThread->invalidateRegions();
305 }
306 }
307
308 // FIXME: We need to find a way to set up overflow properly. Our flow thread hasn't gotten a layout 127 // FIXME: We need to find a way to set up overflow properly. Our flow thread hasn't gotten a layout
309 // yet, so we can't look to it for correct information. It's possible we cou ld wait until after the RenderFlowThread 128 // yet, so we can't look to it for correct information. It's possible we cou ld wait until after the RenderFlowThread
310 // gets a layout, and then try to propagate overflow information back to the region, and then mark for a second layout. 129 // gets a layout, and then try to propagate overflow information back to the region, and then mark for a second layout.
311 // That second layout would then be able to use the information from the Ren derFlowThread to set up overflow. 130 // That second layout would then be able to use the information from the Ren derFlowThread to set up overflow.
312 // 131 //
313 // The big problem though is that overflow needs to be region-specific. We c an't simply use the RenderFlowThread's global 132 // The big problem though is that overflow needs to be region-specific. We c an't simply use the RenderFlowThread's global
314 // overflow values, since then we'd always think any narrow region had huge overflow (all the way to the width of the 133 // overflow values, since then we'd always think any narrow region had huge overflow (all the way to the width of the
315 // RenderFlowThread itself). 134 // RenderFlowThread itself).
316 //
317 // We'll need to expand RenderBoxRegionInfo to also hold left and right over flow values.
318 } 135 }
319 136
320 void RenderRegion::repaintFlowThreadContent(const LayoutRect& repaintRect) const 137 void RenderRegion::repaintFlowThreadContent(const LayoutRect& repaintRect) const
321 { 138 {
322 repaintFlowThreadContentRectangle(repaintRect, flowThreadPortionRect(), flow ThreadPortionOverflowRect(), contentBoxRect().location()); 139 repaintFlowThreadContentRectangle(repaintRect, flowThreadPortionRect(), flow ThreadPortionOverflowRect(), contentBoxRect().location());
323 } 140 }
324 141
325 void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRe ct, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortion OverflowRect, const LayoutPoint& regionLocation) const 142 void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRe ct, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortion OverflowRect, const LayoutPoint& regionLocation) const
326 { 143 {
327 ASSERT(isValid()); 144 ASSERT(isValid());
(...skipping 12 matching lines...) Expand all
340 // Put the region rect into the region's physical coordinate space. 157 // Put the region rect into the region's physical coordinate space.
341 clippedRect.setLocation(regionLocation + (clippedRect.location() - flippedFl owThreadPortionRect.location())); 158 clippedRect.setLocation(regionLocation + (clippedRect.location() - flippedFl owThreadPortionRect.location()));
342 159
343 // Now switch to the region's writing mode coordinate space and let it repai nt itself. 160 // Now switch to the region's writing mode coordinate space and let it repai nt itself.
344 flipForWritingMode(clippedRect); 161 flipForWritingMode(clippedRect);
345 162
346 // Issue the repaint. 163 // Issue the repaint.
347 repaintRectangle(clippedRect); 164 repaintRectangle(clippedRect);
348 } 165 }
349 166
350 void RenderRegion::installFlowThread()
351 {
352 ASSERT(view());
353
354 m_flowThread = view()->flowThreadController()->ensureRenderFlowThreadWithNam e(style()->regionThread());
355
356 // By now the flow thread should already be added to the rendering tree,
357 // so we go up the rendering parents and check that this region is not part of the same
358 // flow that it actually needs to display. It would create a circular refere nce.
359 RenderObject* parentObject = parent();
360 m_parentNamedFlowThread = 0;
361 for ( ; parentObject; parentObject = parentObject->parent()) {
362 if (parentObject->isRenderNamedFlowThread()) {
363 m_parentNamedFlowThread = toRenderNamedFlowThread(parentObject);
364 // Do not take into account a region that links a flow with itself. The dependency
365 // cannot change, so it is not worth adding it to the list.
366 if (m_flowThread == m_parentNamedFlowThread)
367 m_flowThread = 0;
368 break;
369 }
370 }
371 }
372
373 void RenderRegion::attachRegion() 167 void RenderRegion::attachRegion()
374 { 168 {
375 if (documentBeingDestroyed()) 169 if (documentBeingDestroyed())
376 return; 170 return;
377 171
378 // A region starts off invalid. 172 // A region starts off invalid.
379 setIsValid(false); 173 setIsValid(false);
380 174
381 // Initialize the flow thread reference and create the flow thread object if needed.
382 // The flow thread lifetime is influenced by the number of regions attached to it,
383 // and we are attaching the region to the flow thread.
384 installFlowThread();
385
386 if (!m_flowThread) 175 if (!m_flowThread)
387 return; 176 return;
388 177
389 // Only after adding the region to the thread, the region is marked to be va lid. 178 // Only after adding the region to the thread, the region is marked to be va lid.
390 m_flowThread->addRegionToThread(this); 179 m_flowThread->addRegionToThread(this);
391
392 // The region just got attached to the flow thread, lets check whether
393 // it has region styling rules associated.
394 checkRegionStyle();
395
396 if (!isValid())
397 return;
398
399 m_hasAutoLogicalHeight = shouldHaveAutoLogicalHeight();
400 if (hasAutoLogicalHeight())
401 incrementAutoLogicalHeightCount();
402 } 180 }
403 181
404 void RenderRegion::detachRegion() 182 void RenderRegion::detachRegion()
405 { 183 {
406 if (m_flowThread) { 184 if (m_flowThread) {
407 m_flowThread->removeRegionFromThread(this); 185 m_flowThread->removeRegionFromThread(this);
408 if (hasAutoLogicalHeight()) 186 m_flowThread = 0;
409 decrementAutoLogicalHeightCount();
410 } 187 }
411 m_flowThread = 0;
412 }
413
414 RenderBoxRegionInfo* RenderRegion::renderBoxRegionInfo(const RenderBox* box) con st
415 {
416 ASSERT(isValid());
417 return m_renderBoxRegionInfo.get(box);
418 }
419
420 RenderBoxRegionInfo* RenderRegion::setRenderBoxRegionInfo(const RenderBox* box, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset,
421 bool containingBlockChainIsInset)
422 {
423 ASSERT(isValid());
424
425 OwnPtr<RenderBoxRegionInfo>& boxInfo = m_renderBoxRegionInfo.add(box, nullpt r).iterator->value;
426 if (boxInfo)
427 *boxInfo = RenderBoxRegionInfo(logicalLeftInset, logicalRightInset, cont ainingBlockChainIsInset);
428 else
429 boxInfo = adoptPtr(new RenderBoxRegionInfo(logicalLeftInset, logicalRigh tInset, containingBlockChainIsInset));
430
431 return boxInfo.get();
432 }
433
434 PassOwnPtr<RenderBoxRegionInfo> RenderRegion::takeRenderBoxRegionInfo(const Rend erBox* box)
435 {
436 return m_renderBoxRegionInfo.take(box);
437 }
438
439 void RenderRegion::removeRenderBoxRegionInfo(const RenderBox* box)
440 {
441 m_renderBoxRegionInfo.remove(box);
442 }
443
444 void RenderRegion::deleteAllRenderBoxRegionInfo()
445 {
446 m_renderBoxRegionInfo.clear();
447 } 188 }
448 189
449 LayoutUnit RenderRegion::logicalTopOfFlowThreadContentRect(const LayoutRect& rec t) const 190 LayoutUnit RenderRegion::logicalTopOfFlowThreadContentRect(const LayoutRect& rec t) const
450 { 191 {
451 ASSERT(isValid()); 192 ASSERT(isValid());
452 return flowThread()->isHorizontalWritingMode() ? rect.y() : rect.x(); 193 return flowThread()->isHorizontalWritingMode() ? rect.y() : rect.x();
453 } 194 }
454 195
455 LayoutUnit RenderRegion::logicalBottomOfFlowThreadContentRect(const LayoutRect& rect) const 196 LayoutUnit RenderRegion::logicalBottomOfFlowThreadContentRect(const LayoutRect& rect) const
456 { 197 {
457 ASSERT(isValid()); 198 ASSERT(isValid());
458 return flowThread()->isHorizontalWritingMode() ? rect.maxY() : rect.maxX(); 199 return flowThread()->isHorizontalWritingMode() ? rect.maxY() : rect.maxX();
459 } 200 }
460 201
461 void RenderRegion::setRegionObjectsRegionStyle()
462 {
463 if (!hasCustomRegionStyle())
464 return;
465
466 // Start from content nodes and recursively compute the style in region for the render objects below.
467 // If the style in region was already computed, used that style instead of c omputing a new one.
468 RenderNamedFlowThread* namedFlow = view()->flowThreadController()->ensureRen derFlowThreadWithName(style()->regionThread());
469 const NamedFlowContentNodes& contentNodes = namedFlow->contentNodes();
470
471 for (NamedFlowContentNodes::const_iterator iter = contentNodes.begin(), end = contentNodes.end(); iter != end; ++iter) {
472 const Node* node = *iter;
473 // The list of content nodes contains also the nodes with display:none.
474 if (!node->renderer())
475 continue;
476
477 RenderObject* object = node->renderer();
478 // If the content node does not flow any of its children in this region,
479 // we do not compute any style for them in this region.
480 if (!flowThread()->objectInFlowRegion(object, this))
481 continue;
482
483 // If the object has style in region, use that instead of computing a ne w one.
484 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find (object);
485 RefPtr<RenderStyle> objectStyleInRegion;
486 bool objectRegionStyleCached = false;
487 if (it != m_renderObjectRegionStyle.end()) {
488 objectStyleInRegion = it->value.style;
489 ASSERT(it->value.cached);
490 objectRegionStyleCached = true;
491 } else {
492 objectStyleInRegion = computeStyleInRegion(object);
493 }
494
495 setObjectStyleInRegion(object, objectStyleInRegion, objectRegionStyleCac hed);
496
497 computeChildrenStyleInRegion(object);
498 }
499 }
500
501 void RenderRegion::restoreRegionObjectsOriginalStyle()
502 {
503 if (!hasCustomRegionStyle())
504 return;
505
506 RenderObjectRegionStyleMap temp;
507 for (RenderObjectRegionStyleMap::iterator iter = m_renderObjectRegionStyle.b egin(), end = m_renderObjectRegionStyle.end(); iter != end; ++iter) {
508 RenderObject* object = const_cast<RenderObject*>(iter->key);
509 RefPtr<RenderStyle> objectRegionStyle = object->style();
510 RefPtr<RenderStyle> objectOriginalStyle = iter->value.style;
511 object->setStyleInternal(objectOriginalStyle);
512
513 bool shouldCacheRegionStyle = iter->value.cached;
514 if (!shouldCacheRegionStyle) {
515 // Check whether we should cache the computed style in region.
516 unsigned changedContextSensitiveProperties = ContextSensitivePropert yNone;
517 StyleDifference styleDiff = objectOriginalStyle->diff(objectRegionSt yle.get(), changedContextSensitiveProperties);
518 if (styleDiff < StyleDifferenceLayoutPositionedMovementOnly)
519 shouldCacheRegionStyle = true;
520 }
521 if (shouldCacheRegionStyle) {
522 ObjectRegionStyleInfo styleInfo;
523 styleInfo.style = objectRegionStyle;
524 styleInfo.cached = true;
525 temp.set(object, styleInfo);
526 }
527 }
528
529 m_renderObjectRegionStyle.swap(temp);
530 }
531
532 void RenderRegion::insertedIntoTree() 202 void RenderRegion::insertedIntoTree()
533 { 203 {
534 RenderBlock::insertedIntoTree(); 204 RenderBlock::insertedIntoTree();
535 205
536 attachRegion(); 206 attachRegion();
537 } 207 }
538 208
539 void RenderRegion::willBeRemovedFromTree() 209 void RenderRegion::willBeRemovedFromTree()
540 { 210 {
541 RenderBlock::willBeRemovedFromTree(); 211 RenderBlock::willBeRemovedFromTree();
542 212
543 detachRegion(); 213 detachRegion();
544 } 214 }
545 215
546 PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderObject* o bject)
547 {
548 ASSERT(object);
549 ASSERT(object->view());
550 ASSERT(!object->isAnonymous());
551 ASSERT(object->node() && object->node()->isElementNode());
552
553 // FIXME: Region styling fails for pseudo-elements because the renderers don 't have a node.
554 Element* element = toElement(object->node());
555 RefPtr<RenderStyle> renderObjectRegionStyle = object->view()->document().ens ureStyleResolver().styleForElement(element, 0, DisallowStyleSharing, MatchAllRul es, this);
556
557 return renderObjectRegionStyle.release();
558 }
559
560 void RenderRegion::computeChildrenStyleInRegion(const RenderObject* object)
561 {
562 for (RenderObject* child = object->lastChild(); child; child = child->previo usSibling()) {
563
564 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find (child);
565
566 RefPtr<RenderStyle> childStyleInRegion;
567 bool objectRegionStyleCached = false;
568 if (it != m_renderObjectRegionStyle.end()) {
569 childStyleInRegion = it->value.style;
570 objectRegionStyleCached = true;
571 } else {
572 if (child->isAnonymous() || child->isInFlowRenderFlowThread())
573 childStyleInRegion = RenderStyle::createAnonymousStyleWithDispla y(object->style(), child->style()->display());
574 else if (child->isText())
575 childStyleInRegion = RenderStyle::clone(object->style());
576 else
577 childStyleInRegion = computeStyleInRegion(child);
578 }
579
580 setObjectStyleInRegion(child, childStyleInRegion, objectRegionStyleCache d);
581
582 computeChildrenStyleInRegion(child);
583 }
584 }
585
586 void RenderRegion::setObjectStyleInRegion(RenderObject* object, PassRefPtr<Rende rStyle> styleInRegion, bool objectRegionStyleCached)
587 {
588 ASSERT(object->flowThreadContainingBlock());
589
590 RefPtr<RenderStyle> objectOriginalStyle = object->style();
591 object->setStyleInternal(styleInRegion);
592
593 if (object->isBoxModelObject() && !object->hasBoxDecorations()) {
594 bool hasBoxDecorations = object->isTableCell()
595 || object->style()->hasBackground()
596 || object->style()->hasBorder()
597 || object->style()->hasAppearance()
598 || object->style()->boxShadow();
599 object->setHasBoxDecorations(hasBoxDecorations);
600 }
601
602 ObjectRegionStyleInfo styleInfo;
603 styleInfo.style = objectOriginalStyle;
604 styleInfo.cached = objectRegionStyleCached;
605 m_renderObjectRegionStyle.set(object, styleInfo);
606 }
607
608 void RenderRegion::clearObjectStyleInRegion(const RenderObject* object)
609 {
610 ASSERT(object);
611 m_renderObjectRegionStyle.remove(object);
612
613 // Clear the style for the children of this object.
614 for (RenderObject* child = object->lastChild(); child; child = child->previo usSibling())
615 clearObjectStyleInRegion(child);
616 }
617
618 void RenderRegion::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, La youtUnit& maxLogicalWidth) const 216 void RenderRegion::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, La youtUnit& maxLogicalWidth) const
619 { 217 {
620 if (!isValid()) { 218 if (!isValid()) {
621 RenderBlock::computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWi dth); 219 RenderBlock::computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWi dth);
622 return; 220 return;
623 } 221 }
624 222
625 minLogicalWidth = m_flowThread->minPreferredLogicalWidth(); 223 minLogicalWidth = m_flowThread->minPreferredLogicalWidth();
626 maxLogicalWidth = m_flowThread->maxPreferredLogicalWidth(); 224 maxLogicalWidth = m_flowThread->maxPreferredLogicalWidth();
627 } 225 }
628 226
629 void RenderRegion::getRanges(Vector<RefPtr<Range> >& rangeObjects) const
630 {
631 RenderNamedFlowThread* namedFlow = view()->flowThreadController()->ensureRen derFlowThreadWithName(style()->regionThread());
632 namedFlow->getRanges(rangeObjects, this);
633 }
634
635 void RenderRegion::updateLogicalHeight()
636 {
637 RenderBlock::updateLogicalHeight();
638
639 if (!hasAutoLogicalHeight())
640 return;
641
642 // We want to update the logical height based on the computed auto-height
643 // only if the view is in the layout phase in which all the
644 // auto logical height regions have a computed auto-height.
645 if (!m_flowThread->inConstrainedLayoutPhase())
646 return;
647
648 // There may be regions with auto logical height that during the prerequisit e layout phase
649 // did not have the chance to layout flow thread content. Because of that, t hese regions do not
650 // have a computedAutoHeight and they will not be able to fragment any flow
651 // thread content.
652 if (!hasComputedAutoHeight())
653 return;
654
655 LayoutUnit autoHeight = hasOverrideHeight() ? overrideLogicalContentHeight() : computedAutoHeight();
656
657 LayoutUnit newLogicalHeight = autoHeight + borderAndPaddingLogicalHeight();
658 ASSERT(newLogicalHeight < RenderFlowThread::maxLogicalHeight());
659 if (newLogicalHeight > logicalHeight()) {
660 setLogicalHeight(newLogicalHeight);
661 // Recalculate position of the render block after new logical height is set.
662 // (needed in absolute positioning case with bottom alignment for exampl e)
663 RenderBlock::updateLogicalHeight();
664 }
665 }
666
667 Node* RenderRegion::nodeForRegion() const
668 {
669 if (parent() && isRenderNamedFlowFragment())
670 return parent()->node();
671 return node();
672 }
673
674 Node* RenderRegion::generatingNodeForRegion() const
675 {
676 if (parent() && isRenderNamedFlowFragment())
677 return parent()->generatingNode();
678 return generatingNode();
679 }
680
681 bool RenderRegion::isElementBasedRegion() const
682 {
683 Node* node = nodeForRegion();
684 return node && node->isElementNode() && !node->isPseudoElement();
685 }
686
687 } // namespace WebCore 227 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderRegion.h ('k') | Source/core/rendering/RenderRegionSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698