Title: [134482] trunk/Source/WebCore
Revision
134482
Author
[email protected]
Date
2012-11-13 14:14:05 -0800 (Tue, 13 Nov 2012)

Log Message

[CSS Regions] Add Region info for RootLineBoxes and pack the pagination data
https://bugs.webkit.org/show_bug.cgi?id=101332

Patch by Andrei Bucur <[email protected]> on 2012-11-13
Reviewed by David Hyatt.

Currently the pagination information for lines is spread between the RootInlineBox and InlineFlowBox classes, consuming memory even though
the boxes were not the result of an pagination layout. To overcome this, a new struct (LineFragmentationData) is created that wraps all the data,
including a new member, the containing Region for the line.
The containing Region is used to detect if a line changed the Region where it resides. This will be helpful especially when implementing region
styling for layout properties (e.g. the font-size property https://bugs.webkit.org/show_bug.cgi?id=95559 ).
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
the task of updating the containing Region to the block.

Tests: No new tests because there is no functional change.

* rendering/InlineFlowBox.cpp:
(SameSizeAsInlineFlowBox):
* rendering/InlineFlowBox.h:
(WebCore::InlineFlowBox::InlineFlowBox):
(InlineFlowBox):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::lineWidthForPaginatedLineChanged):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::layoutRunsAndFloatsInRange):
(WebCore::RenderBlock::linkToEndLineIfNeeded):
(WebCore::RenderBlock::determineStartPosition):
* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::RootInlineBox):
(WebCore::RootInlineBox::setContainingRegion):
(WebCore):
* rendering/RootInlineBox.h:
(WebCore):
(WebCore::RootInlineBox::paginationStrut):
(WebCore::RootInlineBox::setPaginationStrut):
(WebCore::RootInlineBox::isFirstAfterPageBreak):
(WebCore::RootInlineBox::setIsFirstAfterPageBreak):
(WebCore::RootInlineBox::paginatedLineWidth):
(WebCore::RootInlineBox::setPaginatedLineWidth):
(RootInlineBox):
(WebCore::RootInlineBox::containingRegion):
(WebCore::RootInlineBox::ensureLineFragmentationData):
(LineFragmentationData):
(WebCore::RootInlineBox::LineFragmentationData::LineFragmentationData):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (134481 => 134482)


--- trunk/Source/WebCore/ChangeLog	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/ChangeLog	2012-11-13 22:14:05 UTC (rev 134482)
@@ -1,3 +1,49 @@
+2012-11-13  Andrei Bucur  <[email protected]>
+
+        [CSS Regions] Add Region info for RootLineBoxes and pack the pagination data
+        https://bugs.webkit.org/show_bug.cgi?id=101332
+
+        Reviewed by David Hyatt.
+
+        Currently the pagination information for lines is spread between the RootInlineBox and InlineFlowBox classes, consuming memory even though
+        the boxes were not the result of an pagination layout. To overcome this, a new struct (LineFragmentationData) is created that wraps all the data,
+        including a new member, the containing Region for the line.
+        The containing Region is used to detect if a line changed the Region where it resides. This will be helpful especially when implementing region
+        styling for layout properties (e.g. the font-size property https://bugs.webkit.org/show_bug.cgi?id=95559 ).
+        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
+        the task of updating the containing Region to the block.
+
+        Tests: No new tests because there is no functional change.
+
+        * rendering/InlineFlowBox.cpp:
+        (SameSizeAsInlineFlowBox):
+        * rendering/InlineFlowBox.h:
+        (WebCore::InlineFlowBox::InlineFlowBox):
+        (InlineFlowBox):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::lineWidthForPaginatedLineChanged):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::layoutRunsAndFloatsInRange):
+        (WebCore::RenderBlock::linkToEndLineIfNeeded):
+        (WebCore::RenderBlock::determineStartPosition):
+        * rendering/RootInlineBox.cpp:
+        (WebCore::RootInlineBox::RootInlineBox):
+        (WebCore::RootInlineBox::setContainingRegion):
+        (WebCore):
+        * rendering/RootInlineBox.h:
+        (WebCore):
+        (WebCore::RootInlineBox::paginationStrut):
+        (WebCore::RootInlineBox::setPaginationStrut):
+        (WebCore::RootInlineBox::isFirstAfterPageBreak):
+        (WebCore::RootInlineBox::setIsFirstAfterPageBreak):
+        (WebCore::RootInlineBox::paginatedLineWidth):
+        (WebCore::RootInlineBox::setPaginatedLineWidth):
+        (RootInlineBox):
+        (WebCore::RootInlineBox::containingRegion):
+        (WebCore::RootInlineBox::ensureLineFragmentationData):
+        (LineFragmentationData):
+        (WebCore::RootInlineBox::LineFragmentationData::LineFragmentationData):
+
 2012-11-13  Milian Wolff  <[email protected]>
 
         [Qt] QNX build fails due to signature change in gl2.h header (glShaderSource)

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (134481 => 134482)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2012-11-13 22:14:05 UTC (rev 134482)
@@ -48,7 +48,7 @@
 
 struct SameSizeAsInlineFlowBox : public InlineBox {
     void* pointers[5];
-    uint32_t bitfields : 24;
+    uint32_t bitfields : 23;
 };
 
 COMPILE_ASSERT(sizeof(InlineFlowBox) == sizeof(SameSizeAsInlineFlowBox), InlineFlowBox_should_stay_small);

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.h (134481 => 134482)


--- trunk/Source/WebCore/rendering/InlineFlowBox.h	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.h	2012-11-13 22:14:05 UTC (rev 134482)
@@ -52,7 +52,6 @@
         , m_baselineType(AlphabeticBaseline)
         , m_hasAnnotationsBefore(false)
         , m_hasAnnotationsAfter(false)
-        , m_isFirstAfterPageBreak(false)
 #ifndef NDEBUG
         , m_hasBadChildList(false)
 #endif
@@ -325,7 +324,6 @@
     // If the line contains any ruby runs, then this will be true.
     unsigned m_hasAnnotationsBefore : 1;
     unsigned m_hasAnnotationsAfter : 1;
-    unsigned m_isFirstAfterPageBreak : 1;
 
     unsigned m_lineBreakBidiStatusEor : 5; // WTF::Unicode::Direction
     unsigned m_lineBreakBidiStatusLastStrong : 5; // WTF::Unicode::Direction

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (134481 => 134482)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-11-13 22:14:05 UTC (rev 134482)
@@ -7245,7 +7245,12 @@
     if (!inRenderFlowThread())
         return false;
 
-    return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(rootBox->lineTopWithLeading() + lineDelta);
+    ASSERT(rootBox->containingRegion());
+    RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
+    // Just bail if the region didn't change.
+    if (rootBox->containingRegion() == currentRegion)
+        return false;
+    return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion, offsetFromLogicalTopOfFirstPage());
 }
 
 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (134481 => 134482)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-11-13 22:14:05 UTC (rev 134482)
@@ -1508,6 +1508,9 @@
 
                         setLogicalHeight(lineBox->lineBottomWithLeading());
                     }
+
+                    if (inRenderFlowThread())
+                        lineBox->setContainingRegion(regionAtBlockOffset(lineBox->lineTopWithLeading()));
                 }
             }
 
@@ -1562,6 +1565,8 @@
                     layoutState.updateRepaintRangeFromBox(line, delta);
                     line->adjustBlockDirectionPosition(delta);
                 }
+                if (inRenderFlowThread())
+                    line->setContainingRegion(regionAtBlockOffset(line->lineTopWithLeading()));
                 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
                     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
                     for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
@@ -1599,6 +1604,8 @@
             LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
             LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
             trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
+            if (inRenderFlowThread())
+                trailingFloatsLineBox->setContainingRegion(regionAtBlockOffset(trailingFloatsLineBox->lineTopWithLeading()));
         }
 
         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
@@ -1793,6 +1800,8 @@
                     layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
                     curr->adjustBlockDirectionPosition(paginationDelta);
                 }
+                if (inRenderFlowThread())
+                    curr->setContainingRegion(regionAtBlockOffset(curr->lineTopWithLeading()));
             }
 
             // If a new float has been inserted before this line or before its last known float, just do a full layout.

Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (134481 => 134482)


--- trunk/Source/WebCore/rendering/RootInlineBox.cpp	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp	2012-11-13 22:14:05 UTC (rev 134482)
@@ -52,8 +52,6 @@
     , m_lineBottom(0)
     , m_lineTopWithLeading(0)
     , m_lineBottomWithLeading(0)
-    , m_paginationStrut(0)
-    , m_paginatedLineWidth(0)
 {
     setIsHorizontal(block->isHorizontalWritingMode());
 }
@@ -251,6 +249,13 @@
     }
 }
 
+void RootInlineBox::setContainingRegion(RenderRegion* region)
+{
+    ASSERT(!isDirty());
+    ASSERT(block()->inRenderFlowThread());
+    ensureLineFragmentationData()->m_containingRegion = region;
+}
+
 LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
 {
 #if ENABLE(SVG)

Modified: trunk/Source/WebCore/rendering/RootInlineBox.h (134481 => 134482)


--- trunk/Source/WebCore/rendering/RootInlineBox.h	2012-11-13 22:05:13 UTC (rev 134481)
+++ trunk/Source/WebCore/rendering/RootInlineBox.h	2012-11-13 22:14:05 UTC (rev 134482)
@@ -28,6 +28,7 @@
 
 class EllipsisBox;
 class HitTestResult;
+class RenderRegion;
 
 struct BidiStatus;
 struct GapRects;
@@ -53,15 +54,18 @@
     LayoutUnit lineTopWithLeading() const { return m_lineTopWithLeading; }
     LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; }
     
-    LayoutUnit paginationStrut() const { return m_paginationStrut; }
-    void setPaginationStrut(LayoutUnit s) { m_paginationStrut = s; }
+    LayoutUnit paginationStrut() const { return m_fragmentationData ? m_fragmentationData->m_paginationStrut : LayoutUnit(0); }
+    void setPaginationStrut(LayoutUnit strut) { ensureLineFragmentationData()->m_paginationStrut = strut; }
 
-    bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; }
-    void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { m_isFirstAfterPageBreak = isFirstAfterPageBreak; }
+    bool isFirstAfterPageBreak() const { return m_fragmentationData ? m_fragmentationData->m_isFirstAfterPageBreak : false; }
+    void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { ensureLineFragmentationData()->m_isFirstAfterPageBreak = isFirstAfterPageBreak; }
 
-    LayoutUnit paginatedLineWidth() const { return m_paginatedLineWidth; }
-    void setPaginatedLineWidth(LayoutUnit width) { m_paginatedLineWidth = width; }
+    LayoutUnit paginatedLineWidth() const { return m_fragmentationData ? m_fragmentationData->m_paginatedLineWidth : LayoutUnit(0); }
+    void setPaginatedLineWidth(LayoutUnit width) { ensureLineFragmentationData()->m_paginatedLineWidth = width; }
 
+    RenderRegion* containingRegion() const { return m_fragmentationData ? m_fragmentationData->m_containingRegion : 0; }
+    void setContainingRegion(RenderRegion*);
+
     LayoutUnit selectionTop() const;
     LayoutUnit selectionBottom() const;
     LayoutUnit selectionHeight() const { return max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
@@ -193,6 +197,15 @@
 
     LayoutUnit beforeAnnotationsAdjustment() const;
 
+    struct LineFragmentationData;
+    LineFragmentationData* ensureLineFragmentationData()
+    {
+        if (!m_fragmentationData)
+            m_fragmentationData = adoptPtr(new LineFragmentationData());
+
+        return m_fragmentationData.get();
+    }
+
     // This folds into the padding at the end of InlineFlowBox on 64-bit.
     unsigned m_lineBreakPos;
 
@@ -207,9 +220,26 @@
     LayoutUnit m_lineTopWithLeading;
     LayoutUnit m_lineBottomWithLeading;
 
-    LayoutUnit m_paginationStrut;
-    LayoutUnit m_paginatedLineWidth;
+    struct LineFragmentationData {
+        WTF_MAKE_NONCOPYABLE(LineFragmentationData); WTF_MAKE_FAST_ALLOCATED;
+    public:
+        LineFragmentationData()
+            : m_containingRegion(0)
+            , m_paginationStrut(0)
+            , m_paginatedLineWidth(0)
+            , m_isFirstAfterPageBreak(false)
+        {
 
+        }
+
+        RenderRegion* m_containingRegion;
+        LayoutUnit m_paginationStrut;
+        LayoutUnit m_paginatedLineWidth;
+        bool m_isFirstAfterPageBreak;
+    };
+
+    OwnPtr<LineFragmentationData> m_fragmentationData;
+
     // Floats hanging off the line are pushed into this vector during layout. It is only
     // good for as long as the line has not been marked dirty.
     OwnPtr<Vector<RenderBox*> > m_floats;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to