Changeset 94084 in webkit


Ignore:
Timestamp:
Aug 30, 2011 9:57:37 AM (13 years ago)
Author:
hyatt@apple.com
Message:

<rdar://problem/8832814> With large line-height, column break can happen anywhere in the
inter-line gap, causing staggered lines.

https://bugs.webkit.org/show_bug.cgi?id=67202 Handle positive leading when paginating lines.

Technically we should paginate lines based solely off their line top and line bottom with
leading included. However there are two issues with always doing so. The first is that overflow
can cause lines to overlap, and the second is that negative leading can cause lines to overlap.

Since we're incapable of dealing with overlap until we stop clipping column boxes and allow them
to have a form of specialized overflow, we still have to at least factor in overflow and ignore
negative leading for now. However we can at least honor positive leading when the lines don't
overlap. This patch provides basic support for paginating when positive leading is involved.

Reviewed by Dan Bernstein.

Added fast/multicol/positive-leading.html.

Source/WebCore:

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::markLinesDirtyInBlockRange):
Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.

(WebCore::RenderBlock::adjustLinePositionForPagination):
Grow the top and extent of the line to include our leading when deciding how to paginate
the line.

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::computeBlockDirectionPositionsForLine):
(WebCore::RenderBlock::layoutRunsAndFloatsInRange):
(WebCore::RenderBlock::linkToEndLineIfNeeded):
(WebCore::RenderBlock::checkFloatsInCleanLine):
(WebCore::RenderBlock::determineStartPosition):
(WebCore::RenderBlock::determineEndPosition):
(WebCore::RenderBlock::matchedEndLine):
Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.

  • rendering/RootInlineBox.cpp:

(WebCore::RootInlineBox::RootInlineBox):
(WebCore::RootInlineBox::adjustPosition):
(WebCore::RootInlineBox::alignBoxesInBlockDirection):

  • rendering/RootInlineBox.h:

(WebCore::RootInlineBox::lineTopWithLeading):
(WebCore::RootInlineBox::lineBottomWithLeading):
(WebCore::RootInlineBox::setLineTopBottomPositions):
Instead of one member variable, blockLogicalHeight(), RootInlineBoxes now know both their top and
bottom including leading. These values are obtainable using lineTopWithLeading() and lineBottomWithLeading().
Add these two values to the setLineTopBottomPositions setter and remove setBlockLogicalHeight.

  • rendering/svg/SVGRootInlineBox.cpp:

(WebCore::SVGRootInlineBox::layoutRootBox):
Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.

LayoutTests:

  • fast/multicol/positive-leading.html: Added.
  • platform/mac/fast/multicol/positive-leading-expected.png: Added.
  • platform/mac/fast/multicol/positive-leading-expected.txt: Added.
Location:
trunk
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r94081 r94084  
     12011-08-30  David Hyatt  <hyatt@apple.com>
     2
     3        <rdar://problem/8832814> With large line-height, column break can happen anywhere in the
     4        inter-line gap, causing staggered lines.
     5       
     6        https://bugs.webkit.org/show_bug.cgi?id=67202 Handle positive leading when paginating lines.
     7       
     8        Technically we should paginate lines based solely off their line top and line bottom with
     9        leading included. However there are two issues with always doing so. The first is that overflow
     10        can cause lines to overlap, and the second is that negative leading can cause lines to overlap.
     11
     12        Since we're incapable of dealing with overlap until we stop clipping column boxes and allow them
     13        to have a form of specialized overflow, we still have to at least factor in overflow and ignore
     14        negative leading for now. However we can at least honor positive leading when the lines don't
     15        overlap. This patch provides basic support for paginating when positive leading is involved.
     16
     17        Reviewed by Dan Bernstein.
     18
     19        Added fast/multicol/positive-leading.html.
     20
     21        * fast/multicol/positive-leading.html: Added.
     22        * platform/mac/fast/multicol/positive-leading-expected.png: Added.
     23        * platform/mac/fast/multicol/positive-leading-expected.txt: Added.
     24
    1252011-08-30  Young Han Lee  <joybro@company100.net>
    226
  • trunk/Source/WebCore/ChangeLog

    r94083 r94084  
     12011-08-30  David Hyatt  <hyatt@apple.com>
     2
     3        <rdar://problem/8832814> With large line-height, column break can happen anywhere in the
     4        inter-line gap, causing staggered lines.
     5       
     6        https://bugs.webkit.org/show_bug.cgi?id=67202 Handle positive leading when paginating lines.
     7       
     8        Technically we should paginate lines based solely off their line top and line bottom with
     9        leading included. However there are two issues with always doing so. The first is that overflow
     10        can cause lines to overlap, and the second is that negative leading can cause lines to overlap.
     11
     12        Since we're incapable of dealing with overlap until we stop clipping column boxes and allow them
     13        to have a form of specialized overflow, we still have to at least factor in overflow and ignore
     14        negative leading for now. However we can at least honor positive leading when the lines don't
     15        overlap. This patch provides basic support for paginating when positive leading is involved.
     16
     17        Reviewed by Dan Bernstein.
     18
     19        Added fast/multicol/positive-leading.html.
     20
     21        * rendering/RenderBlock.cpp:
     22        (WebCore::RenderBlock::markLinesDirtyInBlockRange):
     23        Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.
     24
     25        (WebCore::RenderBlock::adjustLinePositionForPagination):
     26        Grow the top and extent of the line to include our leading when deciding how to paginate
     27        the line.
     28
     29        * rendering/RenderBlockLineLayout.cpp:
     30        (WebCore::RenderBlock::computeBlockDirectionPositionsForLine):
     31        (WebCore::RenderBlock::layoutRunsAndFloatsInRange):
     32        (WebCore::RenderBlock::linkToEndLineIfNeeded):
     33        (WebCore::RenderBlock::checkFloatsInCleanLine):
     34        (WebCore::RenderBlock::determineStartPosition):
     35        (WebCore::RenderBlock::determineEndPosition):
     36        (WebCore::RenderBlock::matchedEndLine):
     37        Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.
     38
     39        * rendering/RootInlineBox.cpp:
     40        (WebCore::RootInlineBox::RootInlineBox):
     41        (WebCore::RootInlineBox::adjustPosition):
     42        (WebCore::RootInlineBox::alignBoxesInBlockDirection):
     43        * rendering/RootInlineBox.h:
     44        (WebCore::RootInlineBox::lineTopWithLeading):
     45        (WebCore::RootInlineBox::lineBottomWithLeading):
     46        (WebCore::RootInlineBox::setLineTopBottomPositions):
     47        Instead of one member variable, blockLogicalHeight(), RootInlineBoxes now know both their top and
     48        bottom including leading. These values are obtainable using lineTopWithLeading() and lineBottomWithLeading().
     49        Add these two values to the setLineTopBottomPositions setter and remove setBlockLogicalHeight.
     50
     51        * rendering/svg/SVGRootInlineBox.cpp:
     52        (WebCore::SVGRootInlineBox::layoutRootBox):
     53        Renamed blockLogicalHeight() to lineBottomWithLeading(). The value is the same.
     54
    1552011-08-29  Chris Marrin  <cmarrin@apple.com>
    256
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r93943 r94084  
    36503650    RootInlineBox* lowestDirtyLine = lastRootBox();
    36513651    RootInlineBox* afterLowest = lowestDirtyLine;
    3652     while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<LayoutUnit>::max()) {
     3652    while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < numeric_limits<LayoutUnit>::max()) {
    36533653        afterLowest = lowestDirtyLine;
    36543654        lowestDirtyLine = lowestDirtyLine->prevRootBox();
    36553655    }
    36563656
    3657     while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
     3657    while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
    36583658        afterLowest->markDirty();
    36593659        afterLowest = afterLowest->prevRootBox();
     
    61926192    // of the first column.
    61936193    //
    6194     // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
     6194    // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
    61956195    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
    61966196    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
     
    62006200    // content that paints in a previous column (and content that paints in the following column).
    62016201    //
     6202    // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
     6203    // at least make positive leading work in typical cases.
     6204    //
    62026205    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
    62036206    // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
     
    62066209    LayoutUnit pageLogicalHeight = layoutState->m_pageLogicalHeight;
    62076210    LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
    6208     LayoutUnit logicalOffset = logicalVisualOverflow.y();
    6209     LayoutUnit lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
     6211    LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
     6212    LayoutUnit lineHeight = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY()) - logicalOffset;
    62106213    if (layoutState->m_columnInfo)
    62116214        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r93820 r94084  
    666666{
    667667    setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
    668     lineBox->setBlockLogicalHeight(logicalHeight());
    669668
    670669    // Now make sure we place replaced render objects correctly.
     
    10791078                        }
    10801079
    1081                         setLogicalHeight(lineBox->blockLogicalHeight());
     1080                        setLogicalHeight(lineBox->lineBottomWithLeading());
    10821081                    }
    10831082                }
     
    11461145                }
    11471146            }
    1148             setLogicalHeight(lastRootBox()->blockLogicalHeight());
     1147            setLogicalHeight(lastRootBox()->lineBottomWithLeading());
    11491148        } else {
    11501149            // Delete all the remaining lines.
     
    11701169            IntRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
    11711170            trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
    1172             trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
    11731171        }
    11741172
     
    13121310            floatHeight = min(floatHeight, numeric_limits<int>::max() - floatTop);
    13131311            line->markDirty();
    1314             markLinesDirtyInBlockRange(line->blockLogicalHeight(), floatTop + floatHeight, line);
     1312            markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
    13151313            floats[floatIndex].rect.setSize(newSize);
    13161314            dirtiedByFloat = true;
     
    14231421
    14241422    if (last) {
    1425         setLogicalHeight(last->blockLogicalHeight());
     1423        setLogicalHeight(last->lineBottomWithLeading());
    14261424        resolver.setPosition(InlineIterator(this, last->lineBreakObj(), last->lineBreakPos()));
    14271425        resolver.setStatus(last->lineBreakBidiStatus());
     
    14661464    cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
    14671465    cleanLineBidiStatus = prev->lineBreakBidiStatus();
    1468     layoutState.setEndLineLogicalTop(prev->blockLogicalHeight());
     1466    layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
    14691467
    14701468    for (RootInlineBox* line = last; line; line = line->nextRootBox())
     
    14921490            lastLine = nextLine;
    14931491
    1494         int logicalBottom = lastLine->blockLogicalHeight() + abs(delta);
     1492        int logicalBottom = lastLine->lineBottomWithLeading() + abs(delta);
    14951493
    14961494        const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
     
    15181516            // Set our logical top to be the block height of endLine.
    15191517            if (result)
    1520                 layoutState.setEndLineLogicalTop(line->blockLogicalHeight());
     1518                layoutState.setEndLineLogicalTop(line->lineBottomWithLeading());
    15211519
    15221520            int delta = logicalHeight() - layoutState.endLineLogicalTop();
     
    15291527                    lastLine = nextLine;
    15301528
    1531                 int logicalBottom = lastLine->blockLogicalHeight() + abs(delta);
     1529                int logicalBottom = lastLine->lineBottomWithLeading() + abs(delta);
    15321530
    15331531                const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
  • trunk/Source/WebCore/rendering/RootInlineBox.cpp

    r91417 r94084  
    4949    , m_lineTop(0)
    5050    , m_lineBottom(0)
     51    , m_lineTopWithLeading(0)
     52    , m_lineBottomWithLeading(0)
    5153    , m_paginationStrut(0)
    52     , m_blockLogicalHeight(0)
    5354    , m_baselineType(AlphabeticBaseline)
    5455    , m_hasAnnotationsBefore(false)
     
    204205{
    205206    InlineFlowBox::adjustPosition(dx, dy);
    206     int blockDirectionDelta = isHorizontal() ? dy : dx; // The block direction delta will always be integral.
     207    LayoutUnit blockDirectionDelta = isHorizontal() ? dy : dx; // The block direction delta is a LayoutUnit.
    207208    m_lineTop += blockDirectionDelta;
    208209    m_lineBottom += blockDirectionDelta;
    209     m_blockLogicalHeight += blockDirectionDelta;
     210    m_lineTopWithLeading += blockDirectionDelta;
     211    m_lineBottomWithLeading += blockDirectionDelta;
    210212}
    211213
     
    259261    m_hasAnnotationsBefore = hasAnnotationsBefore;
    260262    m_hasAnnotationsAfter = hasAnnotationsAfter;
    261     setLineTopBottomPositions(lineTop, lineBottom);
     263   
     264    maxHeight = max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessary?
     265
     266    setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock + maxHeight);
    262267
    263268    int annotationsAdjustment = beforeAnnotationsAdjustment();
     
    268273        heightOfBlock += annotationsAdjustment;
    269274    }
    270 
    271     maxHeight = max<LayoutUnit>(0, maxHeight);
    272275
    273276    return heightOfBlock + maxHeight;
  • trunk/Source/WebCore/rendering/RootInlineBox.h

    r93014 r94084  
    5151    LayoutUnit lineBottom() const { return m_lineBottom; }
    5252
     53    LayoutUnit lineTopWithLeading() const { return m_lineTopWithLeading; }
     54    LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; }
     55   
    5356    int paginationStrut() const { return m_paginationStrut; }
    5457    void setPaginationStrut(int s) { m_paginationStrut = s; }
     
    6164
    6265    LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
    63     void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom)
     66    void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit topWithLeading, LayoutUnit bottomWithLeading)
    6467    {
    6568        m_lineTop = top;
    66         m_lineBottom = bottom;
     69        m_lineBottom = bottom;
     70        m_lineTopWithLeading = topWithLeading;
     71        m_lineBottomWithLeading = bottomWithLeading;
    6772    }
    6873
     
    7580    unsigned lineBreakPos() const { return m_lineBreakPos; }
    7681    void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
    77 
    78     int blockLogicalHeight() const { return m_blockLogicalHeight; }
    79     void setBlockLogicalHeight(int h) { m_blockLogicalHeight = h; }
    8082
    8183    bool endsWithBreak() const { return m_endsWithBreak; }
     
    187189    LayoutUnit m_lineBottom;
    188190
     191    LayoutUnit m_lineTopWithLeading;
     192    LayoutUnit m_lineBottomWithLeading;
     193
    189194    int m_paginationStrut;
    190195
     
    192197    // good for as long as the line has not been marked dirty.
    193198    OwnPtr<Vector<RenderBox*> > m_floats;
    194 
    195     // The logical height of the block at the end of this line.  This is where the next line starts.
    196     int m_blockLogicalHeight;
    197199
    198200    // Whether or not this line uses alphabetic or ideographic baselines by default.
  • trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp

    r93050 r94084  
    197197    setLogicalWidth(widthBlock);
    198198    setLogicalHeight(heightBlock);
    199     setBlockLogicalHeight(heightBlock);
    200     setLineTopBottomPositions(0, heightBlock);
     199    setLineTopBottomPositions(0, heightBlock, 0, heightBlock);
    201200}
    202201
Note: See TracChangeset for help on using the changeset viewer.