Changeset 135750 in webkit
- Timestamp:
- Nov 26, 2012 12:00:49 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r135749 r135750 1 2012-11-26 Andrei Bucur <abucur@adobe.com> 2 3 [CSS Regions] Add Region info for RootLineBoxes and pack the pagination data 4 https://bugs.webkit.org/show_bug.cgi?id=101332 5 6 Reviewed by David Hyatt. 7 8 The test checks if there is a crash when doing a line layout if: 9 - the flow has no region 10 - the flow has a region but the lines have no containing region 11 - the flow has no region but the lines have a containing region 12 13 * fast/regions/line-containing-region-crash-expected.txt: Added. 14 * fast/regions/line-containing-region-crash.html: Added. 15 1 16 2012-11-26 Michelangelo De Simone <michelangelo@webkit.org> 2 17 -
trunk/Source/WebCore/ChangeLog
r135749 r135750 1 2012-11-26 Andrei Bucur <abucur@adobe.com> 2 3 [CSS Regions] Add Region info for RootLineBoxes and pack the pagination data 4 https://bugs.webkit.org/show_bug.cgi?id=101332 5 6 Reviewed by David Hyatt. 7 8 Currently the pagination information for lines is spread between the RootInlineBox and InlineFlowBox classes, consuming memory even though 9 the boxes were not the result of an pagination layout. To overcome this, a new struct (LineFragmentationData) is created that wraps all the data, 10 including two new members, the containing Region for the line and a boolean that states if the line was laid out in a Region or not. 11 The flag is necessary because the sanitize function on LineFragmentationData resets the containing Region to 0 if the Region was removed from 12 chain (so a value of 0 for the containing Region means two things). The sanitize function should prevent access to an invalid address. 13 The containing Region is used to detect if a line changed the Region where it resides. This will be helpful especially when implementing region 14 styling for layout properties (e.g. the font-size property https://bugs.webkit.org/show_bug.cgi?id=95559 ). 15 A line can change the region when it is shifted inside the containing block or if the entire block moves. This means it's better to delegate 16 the task of updating the containing Region to the block. 17 18 Tests: fast/regions/line-containing-region-crash.html 19 20 * rendering/InlineFlowBox.cpp: 21 (SameSizeAsInlineFlowBox): 22 * rendering/InlineFlowBox.h: 23 (WebCore::InlineFlowBox::InlineFlowBox): 24 (InlineFlowBox): 25 * rendering/RenderBlock.cpp: 26 (WebCore::RenderBlock::lineWidthForPaginatedLineChanged): 27 * rendering/RenderBlockLineLayout.cpp: 28 (WebCore::RenderBlock::layoutRunsAndFloatsInRange): 29 (WebCore::RenderBlock::linkToEndLineIfNeeded): 30 (WebCore::RenderBlock::determineStartPosition): 31 * rendering/RootInlineBox.cpp: 32 (WebCore::RootInlineBox::RootInlineBox): 33 (WebCore::RootInlineBox::setContainingRegion): 34 (WebCore): 35 (WebCore::RootInlineBox::LineFragmentationData::sanitize): This is an O(1) function that checks if the containig Region is still valid pointer. 36 * rendering/RootInlineBox.h: 37 (WebCore): 38 (WebCore::RootInlineBox::paginationStrut): 39 (WebCore::RootInlineBox::setPaginationStrut): 40 (WebCore::RootInlineBox::isFirstAfterPageBreak): 41 (WebCore::RootInlineBox::setIsFirstAfterPageBreak): 42 (WebCore::RootInlineBox::paginatedLineWidth): 43 (WebCore::RootInlineBox::setPaginatedLineWidth): 44 (RootInlineBox): 45 (WebCore::RootInlineBox::containingRegion): 46 (WebCore::RootInlineBox::hasContainingRegion): Use this to determine if the line has a region or not. 47 (WebCore::RootInlineBox::ensureLineFragmentationData): 48 (LineFragmentationData): 49 (WebCore::RootInlineBox::LineFragmentationData::LineFragmentationData): 50 51 1 52 2012-11-26 Michelangelo De Simone <michelangelo@webkit.org> 2 53 -
trunk/Source/WebCore/rendering/InlineFlowBox.cpp
r134505 r135750 49 49 struct SameSizeAsInlineFlowBox : public InlineBox { 50 50 void* pointers[5]; 51 uint32_t bitfields : 2 4;51 uint32_t bitfields : 23; 52 52 }; 53 53 -
trunk/Source/WebCore/rendering/InlineFlowBox.h
r134505 r135750 53 53 , m_hasAnnotationsBefore(false) 54 54 , m_hasAnnotationsAfter(false) 55 , m_isFirstAfterPageBreak(false)56 55 #ifndef NDEBUG 57 56 , m_hasBadChildList(false) … … 326 325 unsigned m_hasAnnotationsBefore : 1; 327 326 unsigned m_hasAnnotationsAfter : 1; 328 unsigned m_isFirstAfterPageBreak : 1;329 327 330 328 unsigned m_lineBreakBidiStatusEor : 5; // WTF::Unicode::Direction -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r135670 r135750 7246 7246 return false; 7247 7247 7248 return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(rootBox->lineTopWithLeading() + lineDelta); 7248 RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta); 7249 // Just bail if we still don't have a region. 7250 if (!rootBox->hasContainingRegion() && !currentRegion) 7251 return false; 7252 // Just bail if the region didn't change. 7253 if (rootBox->hasContainingRegion() && rootBox->containingRegion() == currentRegion) 7254 return false; 7255 return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion, offsetFromLogicalTopOfFirstPage()); 7249 7256 } 7250 7257 -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r135684 r135750 1509 1509 setLogicalHeight(lineBox->lineBottomWithLeading()); 1510 1510 } 1511 1512 if (inRenderFlowThread()) 1513 lineBox->setContainingRegion(regionAtBlockOffset(lineBox->lineTopWithLeading())); 1511 1514 } 1512 1515 } … … 1563 1566 line->adjustBlockDirectionPosition(delta); 1564 1567 } 1568 if (inRenderFlowThread()) 1569 line->setContainingRegion(regionAtBlockOffset(line->lineTopWithLeading())); 1565 1570 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { 1566 1571 Vector<RenderBox*>::iterator end = cleanLineFloats->end(); … … 1600 1605 LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight); 1601 1606 trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom()); 1607 if (inRenderFlowThread()) 1608 trailingFloatsLineBox->setContainingRegion(regionAtBlockOffset(trailingFloatsLineBox->lineTopWithLeading())); 1602 1609 } 1603 1610 … … 1794 1801 curr->adjustBlockDirectionPosition(paginationDelta); 1795 1802 } 1803 if (inRenderFlowThread()) 1804 curr->setContainingRegion(regionAtBlockOffset(curr->lineTopWithLeading())); 1796 1805 } 1797 1806 -
trunk/Source/WebCore/rendering/RootInlineBox.cpp
r134505 r135750 34 34 #include "RenderArena.h" 35 35 #include "RenderBlock.h" 36 #include "RenderFlowThread.h" 36 37 #include "RenderView.h" 37 38 #include "VerticalPositionCache.h" … … 53 54 , m_lineTopWithLeading(0) 54 55 , m_lineBottomWithLeading(0) 55 , m_paginationStrut(0)56 , m_paginatedLineWidth(0)57 56 { 58 57 setIsHorizontal(block->isHorizontalWritingMode()); … … 250 249 prev->markDirty(); 251 250 } 251 } 252 253 void RootInlineBox::setContainingRegion(RenderRegion* region) 254 { 255 ASSERT(!isDirty()); 256 ASSERT(block()->inRenderFlowThread()); 257 LineFragmentationData* fragmentationData = ensureLineFragmentationData(); 258 fragmentationData->m_containingRegion = region; 259 fragmentationData->m_hasContainingRegion = !!region; 260 } 261 262 RootInlineBox::LineFragmentationData* RootInlineBox::LineFragmentationData::sanitize(const RenderBlock* block) 263 { 264 ASSERT(block->inRenderFlowThread()); 265 if (!m_containingRegion) 266 return this; 267 268 RenderFlowThread* flowThread = block->enclosingRenderFlowThread(); 269 const RenderRegionList& regionList = flowThread->renderRegionList(); 270 // For pointer types the hash function is |safeToCompareToEmptyOrDeleted|. There shouldn't be any problems if m_containingRegion was deleted. 271 if (!regionList.contains(m_containingRegion)) 272 m_containingRegion = 0; 273 274 return this; 252 275 } 253 276 -
trunk/Source/WebCore/rendering/RootInlineBox.h
r134505 r135750 29 29 class EllipsisBox; 30 30 class HitTestResult; 31 class RenderRegion; 31 32 32 33 struct BidiStatus; … … 54 55 LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; } 55 56 56 LayoutUnit paginationStrut() const { return m_paginationStrut; } 57 void setPaginationStrut(LayoutUnit s) { m_paginationStrut = s; } 58 59 bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; } 60 void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { m_isFirstAfterPageBreak = isFirstAfterPageBreak; } 61 62 LayoutUnit paginatedLineWidth() const { return m_paginatedLineWidth; } 63 void setPaginatedLineWidth(LayoutUnit width) { m_paginatedLineWidth = width; } 57 LayoutUnit paginationStrut() const { return m_fragmentationData ? m_fragmentationData->m_paginationStrut : LayoutUnit(0); } 58 void setPaginationStrut(LayoutUnit strut) { ensureLineFragmentationData()->m_paginationStrut = strut; } 59 60 bool isFirstAfterPageBreak() const { return m_fragmentationData ? m_fragmentationData->m_isFirstAfterPageBreak : false; } 61 void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { ensureLineFragmentationData()->m_isFirstAfterPageBreak = isFirstAfterPageBreak; } 62 63 LayoutUnit paginatedLineWidth() const { return m_fragmentationData ? m_fragmentationData->m_paginatedLineWidth : LayoutUnit(0); } 64 void setPaginatedLineWidth(LayoutUnit width) { ensureLineFragmentationData()->m_paginatedLineWidth = width; } 65 66 RenderRegion* containingRegion() const { return m_fragmentationData ? m_fragmentationData->sanitize(block())->m_containingRegion : 0; } 67 bool hasContainingRegion() const { return m_fragmentationData ? m_fragmentationData->m_hasContainingRegion : false; } 68 void setContainingRegion(RenderRegion*); 64 69 65 70 LayoutUnit selectionTop() const; … … 194 199 LayoutUnit beforeAnnotationsAdjustment() const; 195 200 201 struct LineFragmentationData; 202 LineFragmentationData* ensureLineFragmentationData() 203 { 204 if (!m_fragmentationData) 205 m_fragmentationData = adoptPtr(new LineFragmentationData()); 206 207 return m_fragmentationData.get(); 208 } 209 196 210 // This folds into the padding at the end of InlineFlowBox on 64-bit. 197 211 unsigned m_lineBreakPos; … … 208 222 LayoutUnit m_lineBottomWithLeading; 209 223 210 LayoutUnit m_paginationStrut; 211 LayoutUnit m_paginatedLineWidth; 224 struct LineFragmentationData { 225 WTF_MAKE_NONCOPYABLE(LineFragmentationData); WTF_MAKE_FAST_ALLOCATED; 226 public: 227 LineFragmentationData() 228 : m_containingRegion(0) 229 , m_paginationStrut(0) 230 , m_paginatedLineWidth(0) 231 , m_isFirstAfterPageBreak(false) 232 , m_hasContainingRegion(false) 233 { 234 235 } 236 237 LineFragmentationData* sanitize(const RenderBlock*); 238 239 // It should not be assumed the |containingRegion| is always valid. 240 // It can also be 0 if the flow has no region chain or an invalid pointer if the region is no longer in the chain. 241 // Use |sanitize| to filter an invalid region. 242 RenderRegion* m_containingRegion; 243 LayoutUnit m_paginationStrut; 244 LayoutUnit m_paginatedLineWidth; 245 unsigned m_isFirstAfterPageBreak : 1; 246 unsigned m_hasContainingRegion : 1; // We need to keep this to differentiate between the case of a void region and an invalid region. 247 }; 248 249 OwnPtr<LineFragmentationData> m_fragmentationData; 212 250 213 251 // Floats hanging off the line are pushed into this vector during layout. It is only
Note: See TracChangeset
for help on using the changeset viewer.