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

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

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