Changeset 134205 in webkit
- Timestamp:
- Nov 12, 2012 4:08:15 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r134199 r134205 1 2012-11-12 Mihnea Ovidenie <mihnea@adobe.com> 2 3 [CSSRegions]Add support for text-shadow in region styling 4 https://bugs.webkit.org/show_bug.cgi?id=94472 5 6 Reviewed by David Hyatt. 7 8 Original patch by Andrei Onea. 9 Added tests for region styling using the text-shadow property. 10 11 * fast/regions/region-style-text-shadow-expected.html: Added. 12 * fast/regions/region-style-text-shadow.html: Added. 13 1 14 2012-11-12 Pavel Feldman <pfeldman@chromium.org> 2 15 -
trunk/Source/WebCore/ChangeLog
r134204 r134205 1 2012-11-12 Mihnea Ovidenie <mihnea@adobe.com> 2 3 [CSSRegions]Add support for text-shadow in region styling 4 https://bugs.webkit.org/show_bug.cgi?id=94472 5 6 Reviewed by David Hyatt. 7 8 Original patch by Andrei Onea. 9 Add support for text-shadow in region styling (@-webkit-region rule). 10 In addition to the previously supported region styling properties (background-color and color), 11 text-shadow requires the computation of an element style in region at layout time. 12 13 This patch adds a new method on RenderRegion - ensureRegionStyleForObject - that 14 can be used to retrieve the object style in region (if already cached) or to compute it 15 on the spot. When computing the object style in region, we need to compute the style in region 16 also for the object ancestor, up to the content nodes. 17 18 This patch also refactors the way styles in region are computed and stored, because 19 we can compute the style in region not only at paint time, but also at layout time. 20 21 Test: fast/regions/region-style-text-shadow.html 22 23 * css/StyleResolver.cpp: 24 (WebCore::StyleResolver::isValidRegionStyleProperty): 25 Allow text-shadow to be used in region styling. 26 * rendering/InlineBox.cpp: 27 (WebCore::InlineBox::styleInRegion): 28 Retrieve the region style for an InlineBox's renderer, given its RenderRegion. 29 Compute the style in region if not computed yet. 30 (WebCore::InlineBox::regionDuringLayout): 31 Retrieve the region in which an InlineBox is being flowed. 32 * rendering/InlineBox.h: 33 * rendering/InlineFlowBox.cpp: Take region styling into account. 34 (WebCore::InlineFlowBox::addToLine): 35 (WebCore::InlineFlowBox::addTextBoxVisualOverflow): 36 * rendering/RenderRegion.cpp: 37 (WebCore::RenderRegion::setRegionObjectsRegionStyle): 38 (WebCore::canCacheObjectStyleInRegion): 39 Test if we can cache the computed style in region. 40 (WebCore::RenderRegion::restoreRegionObjectsOriginalStyle): 41 (WebCore::RenderRegion::computeStyleInRegion): 42 (WebCore::RenderRegion::setChildrenStyleInRegion): 43 (WebCore::setObjectHasBoxDecorationsFlag): 44 (WebCore::RenderRegion::setObjectStyleInRegion): 45 (WebCore::RenderRegion::clearObjectStyleInRegion): 46 (WebCore::RenderRegion::ensureRegionStyleForObject): 47 * rendering/RenderRegion.h: 48 1 49 2012-11-12 Sheriff Bot <webkit.review.bot@gmail.com> 2 50 -
trunk/Source/WebCore/css/StyleResolver.cpp
r134190 r134205 2681 2681 case CSSPropertyBackgroundColor: 2682 2682 case CSSPropertyColor: 2683 case CSSPropertyTextShadow: 2683 2684 return true; 2684 2685 default: -
trunk/Source/WebCore/rendering/InlineBox.cpp
r132112 r134205 29 29 #include "RenderArena.h" 30 30 #include "RenderBlock.h" 31 #include "RenderFlowThread.h" 32 #include "RenderRegion.h" 33 #include "RenderStyle.h" 34 #include "RenderView.h" 31 35 #include "RootInlineBox.h" 32 36 … … 244 248 } 245 249 250 RenderStyle* InlineBox::styleInRegion(RenderRegion* region) const 251 { 252 if (!region || !renderer()->inRenderFlowThread()) 253 return renderer()->style(isFirstLineStyle()); 254 255 // Find the first parent element. 256 RenderObject* elementRenderer = renderer(); 257 while (elementRenderer && (elementRenderer->isAnonymous() || !elementRenderer->node() || !elementRenderer->node()->isElementNode())) 258 elementRenderer = elementRenderer->parent(); 259 260 if (!elementRenderer) 261 return renderer()->style(isFirstLineStyle()); 262 263 // FIXME: We should be taking into account isFirstLine 264 return region->ensureRegionStyleForObject(elementRenderer); 265 } 266 267 RenderRegion* InlineBox::regionDuringLayout() const 268 { 269 // This assumes that the box has not been positioned yet 270 // so it uses the containing block's current logical height to get the region. 271 ASSERT(renderer() && renderer()->view() && renderer()->view()->layoutState()); 272 if (!renderer()->inRenderFlowThread()) 273 return 0; 274 275 RenderFlowThread* flowThread = renderer()->enclosingRenderFlowThread(); 276 ASSERT(flowThread); 277 278 RenderBlock* containingBlock = renderer()->containingBlock(); 279 return flowThread->regionAtBlockOffset(containingBlock->offsetFromLogicalTopOfFirstPage() + containingBlock->logicalHeight()); 280 } 281 246 282 bool InlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) 247 283 { -
trunk/Source/WebCore/rendering/InlineBox.h
r132112 r134205 29 29 class HitTestRequest; 30 30 class HitTestResult; 31 class RenderRegion; 32 class RenderStyle; 31 33 class RootInlineBox; 32 34 … … 97 99 virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom); 98 100 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom); 101 102 RenderStyle* styleInRegion(RenderRegion*) const; 103 RenderRegion* regionDuringLayout() const; 99 104 100 105 // Overloaded new operator. -
trunk/Source/WebCore/rendering/InlineFlowBox.cpp
r133779 r134205 124 124 if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer()->isOutOfFlowPositioned()) { 125 125 RenderStyle* parentStyle = renderer()->style(isFirstLineStyle()); 126 RenderStyle* childStyle = child-> renderer()->style(isFirstLineStyle());126 RenderStyle* childStyle = child->styleInRegion(child->regionDuringLayout()); 127 127 bool shouldClearDescendantsHaveSameLineHeightAndBaseline = false; 128 128 if (child->renderer()->isReplaced()) … … 822 822 return; 823 823 824 RenderStyle* style = textBox-> renderer()->style(isFirstLineStyle());824 RenderStyle* style = textBox->styleInRegion(textBox->regionDuringLayout()); 825 825 826 826 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(textBox); -
trunk/Source/WebCore/rendering/RenderRegion.cpp
r133779 r134205 404 404 continue; 405 405 406 // If the object has style in region, use that instead of computing a new one.407 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(object);408 RefPtr<RenderStyle> objectStyleInRegion;409 bool objectRegionStyleCached = false; 410 if (it != m_renderObjectRegionStyle.end()) { 411 objectStyleInRegion = it->value.style; 412 ASSERT(it->value.cached); 413 objectRegionStyleCached = true;414 } else415 objectStyleInRegion = computeStyleInRegion(object); 416 417 setObjectStyleInRegion(object, objectStyleInRegion, objectRegionStyleCached);418 419 computeChildrenStyleInRegion(object); 420 } 421 } 422 406 setObjectStyleInRegion(object); 407 setChildrenStyleInRegion(object); 408 } 409 } 410 411 static bool canCacheObjectStyleInRegion(const RenderStyle* styleInRegion, const RenderStyle* originalStyle) 412 { 413 ASSERT(styleInRegion); 414 ASSERT(originalStyle); 415 416 unsigned changedContextSensitiveProperties = ContextSensitivePropertyNone; 417 StyleDifference styleDiff = originalStyle->diff(styleInRegion, changedContextSensitiveProperties); 418 return styleDiff < StyleDifferenceLayoutPositionedMovementOnly; 419 } 420 421 // Restore the objects original style and cache the style in region for the objects 422 // for which it is safe to cache that style. 423 423 void RenderRegion::restoreRegionObjectsOriginalStyle() 424 424 { … … 433 433 object->setStyleInternal(objectOriginalStyle); 434 434 435 bool shouldCacheRegionStyle = iter->value.cached; 436 if (!shouldCacheRegionStyle) { 437 // Check whether we should cache the computed style in region. 438 unsigned changedContextSensitiveProperties = ContextSensitivePropertyNone; 439 StyleDifference styleDiff = objectOriginalStyle->diff(objectRegionStyle.get(), changedContextSensitiveProperties); 440 if (styleDiff < StyleDifferenceLayoutPositionedMovementOnly) 441 shouldCacheRegionStyle = true; 442 } 443 if (shouldCacheRegionStyle) { 435 if (iter->value.canBeCached || canCacheObjectStyleInRegion(objectRegionStyle.get(), objectOriginalStyle.get())) { 444 436 ObjectRegionStyleInfo styleInfo; 445 437 styleInfo.style = objectRegionStyle; 446 styleInfo.cached = true; 438 styleInfo.canBeCached = true; 439 styleInfo.originalStyle = false; 447 440 temp.set(object, styleInfo); 448 441 } … … 466 459 } 467 460 461 // We also need to compute parent's region style to inherit styling information. 462 // The computation of styles in region should not exceed content nodes boundaries. 468 463 PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderObject* object) 469 464 { … … 471 466 ASSERT(object->view()); 472 467 ASSERT(object->view()->document()); 473 ASSERT(!object->isAnonymous()); 468 469 if (object->isAnonymous()) 470 return RenderStyle::createAnonymousStyleWithDisplay(ensureRegionStyleForObject(object->parent()), object->style()->display()); 471 472 if (object->isText()) 473 return RenderStyle::clone(ensureRegionStyleForObject(object->parent())); 474 475 // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node. 474 476 ASSERT(object->node() && object->node()->isElementNode()); 475 476 // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node.477 477 Element* element = toElement(object->node()); 478 RefPtr<RenderStyle> renderObjectRegionStyle = object->view()->document()->styleResolver()->styleForElement(element, 0, DisallowStyleSharing, MatchAllRules, this); 478 RefPtr<RenderStyle> renderObjectRegionStyle = object->view()->document()->styleResolver()->styleForElement(element, 479 element->inNamedFlow() ? 0 : ensureRegionStyleForObject(object->parent()) /*parent style in region*/, DisallowStyleSharing, MatchAllRules, this); 479 480 480 481 return renderObjectRegionStyle.release(); 481 482 } 482 483 483 void RenderRegion:: computeChildrenStyleInRegion(const RenderObject* object)484 void RenderRegion::setChildrenStyleInRegion(const RenderObject* object) 484 485 { 485 486 for (RenderObject* child = object->firstChild(); child; child = child->nextSibling()) { 486 487 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(child); 488 489 RefPtr<RenderStyle> childStyleInRegion; 490 bool objectRegionStyleCached = false; 491 if (it != m_renderObjectRegionStyle.end()) { 492 childStyleInRegion = it->value.style; 493 objectRegionStyleCached = true; 494 } else { 495 if (child->isAnonymous()) 496 childStyleInRegion = RenderStyle::createAnonymousStyleWithDisplay(object->style(), child->style()->display()); 497 else if (child->isText()) 498 childStyleInRegion = RenderStyle::clone(object->style()); 499 else 500 childStyleInRegion = computeStyleInRegion(child); 501 } 502 503 setObjectStyleInRegion(child, childStyleInRegion, objectRegionStyleCached); 504 505 computeChildrenStyleInRegion(child); 506 } 507 } 508 509 void RenderRegion::setObjectStyleInRegion(RenderObject* object, PassRefPtr<RenderStyle> styleInRegion, bool objectRegionStyleCached) 510 { 487 setObjectStyleInRegion(child); 488 setChildrenStyleInRegion(child); 489 } 490 } 491 492 static void setObjectHasBoxDecorationsFlag(RenderObject* object) 493 { 494 ASSERT(object); 511 495 ASSERT(object->inRenderFlowThread()); 512 if (!object->inRenderFlowThread()) 513 return; 514 515 RefPtr<RenderStyle> objectOriginalStyle = object->style(); 516 object->setStyleInternal(styleInRegion); 517 518 if (object->isBoxModelObject() && !object->hasBoxDecorations()) { 519 bool hasBoxDecorations = object->isTableCell() 496 497 if (!object->isBoxModelObject() || object->hasBoxDecorations()) 498 return; 499 500 bool hasBoxDecorations = object->isTableCell() 520 501 || object->style()->hasBackground() 521 502 || object->style()->hasBorder() 522 503 || object->style()->hasAppearance() 523 504 || object->style()->boxShadow(); 524 object->setHasBoxDecorations(hasBoxDecorations); 525 } 526 527 ObjectRegionStyleInfo styleInfo; 528 styleInfo.style = objectOriginalStyle; 529 styleInfo.cached = objectRegionStyleCached; 530 m_renderObjectRegionStyle.set(object, styleInfo); 531 } 532 505 object->setHasBoxDecorations(hasBoxDecorations); 506 } 507 508 // Set the current style for the object to be the style in region. 509 // If the style in region is not computed yet, compute it before replacing the original style. 510 // The original object style is stored so that it can be restored later. 511 void RenderRegion::setObjectStyleInRegion(RenderObject* object) 512 { 513 ASSERT(object->inRenderFlowThread()); 514 ASSERT(!object->isRenderFlowThread()); 515 516 RefPtr<RenderStyle> objectOriginalStyle = object->style(); 517 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(object); 518 519 if (it == m_renderObjectRegionStyle.end()) { 520 ensureRegionStyleForObject(object); 521 it = m_renderObjectRegionStyle.find(object); 522 } 523 524 object->setStyleInternal(it->value.style); 525 setObjectHasBoxDecorationsFlag(object); 526 527 it->value.style = objectOriginalStyle; 528 it->value.originalStyle = true; 529 } 530 531 // Clear the style for the children of this object. 533 532 void RenderRegion::clearObjectStyleInRegion(const RenderObject* object) 534 533 { … … 536 535 m_renderObjectRegionStyle.remove(object); 537 536 538 // Clear the style for the children of this object.539 537 for (RenderObject* child = object->firstChild(); child; child = child->nextSibling()) 540 538 clearObjectStyleInRegion(child); 539 } 540 541 RenderStyle* RenderRegion::ensureRegionStyleForObject(const RenderObject* object) 542 { 543 ASSERT(object); 544 ASSERT(object->inRenderFlowThread()); 545 546 if (object->isRenderFlowThread()) 547 return object->style(); 548 549 RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(object); 550 if (it != m_renderObjectRegionStyle.end()) { 551 // If the current value stored is the original style, it means that we already 552 // switched styles and the style in region can be retrived using style(). 553 return it->value.originalStyle ? object->style() : it->value.style.get(); 554 } 555 556 RefPtr<RenderStyle> objectStyleInRegion = computeStyleInRegion(object); 557 558 ObjectRegionStyleInfo styleInfo; 559 styleInfo.style = objectStyleInRegion; 560 styleInfo.originalStyle = false; 561 styleInfo.canBeCached = canCacheObjectStyleInRegion(objectStyleInRegion.get(), object->style()); 562 m_renderObjectRegionStyle.add(object, styleInfo); 563 564 return objectStyleInRegion.get(); 541 565 } 542 566 -
trunk/Source/WebCore/rendering/RenderRegion.h
r131348 r134205 139 139 virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const; 140 140 141 RenderStyle* ensureRegionStyleForObject(const RenderObject*); 142 141 143 protected: 142 144 void setRegionObjectsRegionStyle(); … … 162 164 163 165 PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*); 164 void computeChildrenStyleInRegion(const RenderObject*); 165 void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached); 166 void printRegionObjectsStyles(); 166 void setChildrenStyleInRegion(const RenderObject*); 167 void setObjectStyleInRegion(RenderObject*); 167 168 168 169 void checkRegionStyle(); … … 193 194 // when necessary. 194 195 RefPtr<RenderStyle> style; 195 // True if the computed style in region is cached. 196 bool cached; 196 197 // True if the computed style in region can be cached. 198 bool canBeCached : 1; 199 200 // True if style keeps the original object style, false if style keeps 201 // the object style in region. 202 bool originalStyle : 1; 197 203 }; 198 204 typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
Note: See TracChangeset
for help on using the changeset viewer.