Changeset 126177 in webkit


Ignore:
Timestamp:
Aug 21, 2012 11:15:39 AM (12 years ago)
Author:
hyatt@apple.com
Message:

[New Multicolumn] Make column rules paint properly.
https://bugs.webkit.org/show_bug.cgi?id=94616

Reviewed by Simon Fraser.

Make the new multi-column code paint column rules and also prepare it for painting
the actual column contents.

  • rendering/RenderMultiColumnBlock.cpp:

(WebCore::RenderMultiColumnBlock::ensureColumnSets):
Remove the addRegionToThread call, since this is now done automatically in RenderRegion::insertedIntoTree.

  • rendering/RenderMultiColumnBlock.h:

(WebCore::RenderMultiColumnBlock::flowThread):
Make public so that RenderMultiColumnSet can access it.

(RenderMultiColumnBlock):

  • rendering/RenderMultiColumnSet.cpp:

(WebCore::RenderMultiColumnSet::columnGap):
Add a column gap fetch method. It's identical to the one on RenderBlock (which will eventually go away
when we kill the old multi-column code).

(WebCore::RenderMultiColumnSet::columnRectAt):
Also identical to the RenderBlock version of this method. Gets the rect for the nth column.

(WebCore::RenderMultiColumnSet::paintReplaced):
Subclass paintReplaced in order to do column rules and contents painting.

(WebCore::RenderMultiColumnSet::paintColumnRules):
(WebCore::RenderMultiColumnSet::paintColumnContents):
Similar to the methods on RenderBlock. The former paints the rules and the latter paints the contents of
the flow thread into the columns.

  • rendering/RenderMultiColumnSet.h:

(RenderMultiColumnSet):
Add the declarations of all the new methods.

  • rendering/RenderRegion.cpp:

(WebCore::RenderRegion::installFlowThread):
Added a new virtual function for installing flow threads when they didn't exist at construction time.
This only applies to actual CSS Regions, so the subclass of the method in RenderRegionSet just does
nothing.

(WebCore::RenderRegion::attachRegion):
Get the named flow thread code out of attachRegion, since it broke multi-column. Moved it into a
virtual function, installFlowThread, that is only used by actual CSS regions. Eventually we may
want a RenderRegion subclass that represents a region for a named flow thread only, but for now
let the code sit in installFlowThread in the base class.

  • rendering/RenderRegion.h:

(RenderRegion):
Add installFlowThread declaration.

  • rendering/RenderRegionSet.cpp:

(WebCore::RenderRegionSet::installFlowThread):
installFlowThread for region sets just does nothing, since we don't use named flow threads.

  • rendering/RenderRegionSet.h:

(RenderRegionSet):
Add the override of installFlowThread.

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r126175 r126177  
     12012-08-21  David Hyatt  <hyatt@apple.com>
     2
     3        [New Multicolumn] Make column rules paint properly.
     4        https://bugs.webkit.org/show_bug.cgi?id=94616
     5
     6        Reviewed by Simon Fraser.
     7
     8        Make the new multi-column code paint column rules and also prepare it for painting
     9        the actual column contents.
     10
     11        * rendering/RenderMultiColumnBlock.cpp:
     12        (WebCore::RenderMultiColumnBlock::ensureColumnSets):
     13        Remove the addRegionToThread call, since this is now done automatically in RenderRegion::insertedIntoTree.
     14       
     15        * rendering/RenderMultiColumnBlock.h:
     16        (WebCore::RenderMultiColumnBlock::flowThread):
     17        Make public so that RenderMultiColumnSet can access it.
     18       
     19        (RenderMultiColumnBlock):
     20        * rendering/RenderMultiColumnSet.cpp:
     21        (WebCore::RenderMultiColumnSet::columnGap):
     22        Add a column gap fetch method. It's identical to the one on RenderBlock (which will eventually go away
     23        when we kill the old multi-column code).
     24       
     25        (WebCore::RenderMultiColumnSet::columnRectAt):
     26        Also identical to the RenderBlock version of this method. Gets the rect for the nth column.
     27       
     28        (WebCore::RenderMultiColumnSet::paintReplaced):
     29        Subclass paintReplaced in order to do column rules and contents painting.
     30       
     31        (WebCore::RenderMultiColumnSet::paintColumnRules):
     32        (WebCore::RenderMultiColumnSet::paintColumnContents):
     33        Similar to the methods on RenderBlock. The former paints the rules and the latter paints the contents of
     34        the flow thread into the columns.
     35       
     36        * rendering/RenderMultiColumnSet.h:
     37        (RenderMultiColumnSet):
     38        Add the declarations of all the new methods.
     39       
     40        * rendering/RenderRegion.cpp:
     41        (WebCore::RenderRegion::installFlowThread):
     42        Added a new virtual function for installing flow threads when they didn't exist at construction time.
     43        This only applies to actual CSS Regions, so the subclass of the method in RenderRegionSet just does
     44        nothing.
     45       
     46        (WebCore::RenderRegion::attachRegion):
     47        Get the named flow thread code out of attachRegion, since it broke multi-column. Moved it into a
     48        virtual function, installFlowThread, that is only used by actual CSS regions. Eventually we may
     49        want a RenderRegion subclass that represents a region for a named flow thread only, but for now
     50        let the code sit in installFlowThread in the base class.
     51       
     52        * rendering/RenderRegion.h:
     53        (RenderRegion):
     54        Add installFlowThread declaration.
     55       
     56        * rendering/RenderRegionSet.cpp:
     57        (WebCore::RenderRegionSet::installFlowThread):
     58        installFlowThread for region sets just does nothing, since we don't use named flow threads.
     59       
     60        * rendering/RenderRegionSet.h:
     61        (RenderRegionSet):
     62        Add the override of installFlowThread.
     63
    1642012-08-21  Patrick Gansterer  <paroga@webkit.org>
    265
  • trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp

    r121123 r126177  
    145145        columnSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
    146146        RenderBlock::addChild(columnSet, firstChild());
    147         flowThread()->addRegionToThread(columnSet);
    148147    }
    149148}
  • trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h

    r118950 r126177  
    4444    unsigned columnCount() const { return m_columnCount; }
    4545
     46    RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
     47
    4648private:
    4749    virtual bool isRenderMultiColumnBlock() const { return true; }
     
    5860
    5961    void ensureColumnSets();
    60 
    61     RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
    6262
    6363    RenderMultiColumnFlowThread* m_flowThread;
  • trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp

    r118839 r126177  
    2525
    2626#include "config.h"
     27#include "PaintInfo.h"
     28#include "RenderMultiColumnFlowThread.h"
    2729#include "RenderMultiColumnSet.h"
    2830#include "RenderMultiColumnBlock.h"
     
    6163}
    6264
     65LayoutUnit RenderMultiColumnSet::columnGap() const
     66{
     67    if (style()->hasNormalColumnGap())
     68        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
     69    return static_cast<int>(style()->columnGap());
     70}
     71
     72LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
     73{
     74    LayoutUnit colLogicalWidth = columnWidth();
     75    LayoutUnit colLogicalHeight = columnHeight();
     76    LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
     77    LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft();
     78    int colGap = columnGap();
     79    if (style()->isLeftToRightDirection())
     80        colLogicalLeft += index * (colLogicalWidth + colGap);
     81    else
     82        colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
     83
     84    if (isHorizontalWritingMode())
     85        return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
     86    return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
     87}
     88
     89void RenderMultiColumnSet::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     90{
     91    // FIXME: RenderRegions are replaced elements right now and so they only paint in the foreground phase.
     92    // Columns should technically respect phases and allow for background/float/foreground overlap etc., just like
     93    // RenderBlocks do. We can't correct this, however, until RenderRegions are changed to actually be
     94    // RenderBlocks. Note this is a pretty minor issue, since the old column implementation clipped columns
     95    // anyway, thus making it impossible for them to overlap one another. It's also really unlikely that the columns
     96    // would overlap another block.
     97    setRegionObjectsRegionStyle();
     98    paintColumnRules(paintInfo, paintOffset);
     99    paintColumnContents(paintInfo, paintOffset);
     100    restoreRegionObjectsOriginalStyle();
     101}
     102
     103void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     104{
     105    if (paintInfo.context->paintingDisabled())
     106        return;
     107
     108    RenderStyle* blockStyle = toRenderMultiColumnBlock(parent())->style();
     109    const Color& ruleColor = blockStyle->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
     110    bool ruleTransparent = blockStyle->columnRuleIsTransparent();
     111    EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
     112    LayoutUnit ruleThickness = blockStyle->columnRuleWidth();
     113    LayoutUnit colGap = columnGap();
     114    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleThickness <= colGap;
     115    if (!renderRule)
     116        return;
     117
     118    unsigned colCount = columnCount();
     119
     120    bool antialias = shouldAntialiasLines(paintInfo.context);
     121
     122    bool leftToRight = style()->isLeftToRightDirection();
     123    LayoutUnit currLogicalLeftOffset = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
     124    LayoutUnit ruleAdd = borderAndPaddingLogicalLeft();
     125    LayoutUnit ruleLogicalLeft = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
     126    LayoutUnit inlineDirectionSize = columnWidth();
     127    BoxSide boxSide = isHorizontalWritingMode()
     128        ? leftToRight ? BSLeft : BSRight
     129        : leftToRight ? BSTop : BSBottom;
     130
     131    for (unsigned i = 0; i < colCount; i++) {
     132        // Move to the next position.
     133        if (leftToRight) {
     134            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
     135            currLogicalLeftOffset += inlineDirectionSize + colGap;
     136        } else {
     137            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
     138            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
     139        }
     140       
     141        // Now paint the column rule.
     142        if (i < colCount - 1) {
     143            LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
     144            LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
     145            LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
     146            LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
     147            IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
     148            drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
     149        }
     150       
     151        ruleLogicalLeft = currLogicalLeftOffset;
     152    }
     153}
     154
     155void RenderMultiColumnSet::paintColumnContents(PaintInfo& /* paintInfo */, const LayoutPoint& /* paintOffset */)
     156{
     157    // For each rectangle, set it as the region rectangle and then let flow thread painting do the rest.
     158    // We make multiple calls to paintIntoRegion, changing the rectangles each time.
     159    if (!columnCount())
     160        return;
     161       
     162    // FIXME: Implement.
     163}
     164
    63165const char* RenderMultiColumnSet::renderName() const
    64166{   
  • trunk/Source/WebCore/rendering/RenderMultiColumnSet.h

    r118839 r126177  
    6666    virtual void computeLogicalHeight() OVERRIDE;
    6767
     68    virtual void paintReplaced(PaintInfo&, const LayoutPoint& paintOffset) OVERRIDE;
     69
    6870    virtual LayoutUnit logicalWidthForFlowThreadContent() const OVERRIDE { return m_columnWidth; }
    6971    virtual LayoutUnit logicalHeightForFlowThreadContent() const OVERRIDE { return m_columnHeight; } // FIXME: Will be wrong once we have multiple sets.
    7072
    7173    virtual const char* renderName() const;
     74   
     75    void paintColumnRules(PaintInfo&, const LayoutPoint& paintOffset);
     76    void paintColumnContents(PaintInfo&, const LayoutPoint& paintOffset);
     77
     78    LayoutUnit columnGap() const;
     79    LayoutRect columnRectAt( unsigned index) const;
    7280   
    7381    unsigned m_columnCount;
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r126107 r126177  
    192192}
    193193
    194 void RenderRegion::attachRegion()
     194void RenderRegion::installFlowThread()
    195195{
    196196    ASSERT(view());
    197     ASSERT(!m_flowThread);
    198     // Initialize the flow thread reference and create the flow thread object if needed.
    199     // The flow thread lifetime is influenced by the number of regions attached to it,
    200     // and we are attaching the region to the flow thread.
     197
    201198    m_flowThread = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread());
    202 
    203     // A region is valid if it is not part of a circular reference, which is checked below
    204     // and in RenderNamedFlowThread::addRegionToThread.
    205     setIsValid(false);
    206199
    207200    // By now the flow thread should already be added to the rendering tree,
     
    215208            // Do not take into account a region that links a flow with itself. The dependency
    216209            // cannot change, so it is not worth adding it to the list.
    217             if (m_flowThread == m_parentNamedFlowThread) {
     210            if (m_flowThread == m_parentNamedFlowThread)
    218211                m_flowThread = 0;
    219                 // This region is not valid for this flow thread (as being part of a circular dependency).
    220                 setIsValid(false);
    221                 return;
    222             }
    223212            break;
    224213        }
    225214    }
     215}
     216
     217void RenderRegion::attachRegion()
     218{
     219    if (documentBeingDestroyed())
     220        return;
     221   
     222    // A region starts off invalid.
     223    setIsValid(false);
     224
     225    // Initialize the flow thread reference and create the flow thread object if needed.
     226    // The flow thread lifetime is influenced by the number of regions attached to it,
     227    // and we are attaching the region to the flow thread.
     228    installFlowThread();
     229   
     230    if (!m_flowThread)
     231        return;
    226232
    227233    m_flowThread->addRegionToThread(this);
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r126048 r126177  
    9898    virtual LayoutUnit logicalHeightForFlowThreadContent() const;
    9999
     100protected:
     101    void setRegionObjectsRegionStyle();
     102    void restoreRegionObjectsOriginalStyle();
     103   
    100104private:
    101105    virtual const char* renderName() const { return "RenderRegion"; }
     
    104108    virtual void willBeRemovedFromTree() OVERRIDE;
    105109
     110    virtual void installFlowThread();
     111
    106112    PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
    107113    void computeChildrenStyleInRegion(const RenderObject*);
    108     void setRegionObjectsRegionStyle();
    109     void restoreRegionObjectsOriginalStyle();
    110114    void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
    111115    void printRegionObjectsStyles();
     
    113117    void checkRegionStyle();
    114118
     119protected:
    115120    RenderFlowThread* m_flowThread;
    116121
     122private:
    117123    // If this RenderRegion is displayed as part of another named flow,
    118124    // we need to create a dependency tree, so that layout of the
  • trunk/Source/WebCore/rendering/RenderRegionSet.cpp

    r111240 r126177  
    3434}
    3535
     36void RenderRegionSet::installFlowThread()
     37{
     38    // We don't have to do anything, since we were able to connect the flow thread
     39    // in the constructor.
    3640}
     41
     42}
  • trunk/Source/WebCore/rendering/RenderRegionSet.h

    r111240 r126177  
    5151   
    5252private:
     53    virtual void installFlowThread() OVERRIDE;
     54
    5355    virtual const char* renderName() const = 0;
    5456};
Note: See TracChangeset for help on using the changeset viewer.