Changeset 107160 in webkit


Ignore:
Timestamp:
Feb 8, 2012 5:50:05 PM (12 years ago)
Author:
hyatt@apple.com
Message:

Source/WebCore: https://bugs.webkit.org/show_bug.cgi?id=78157

Make multi-column layout work with line grids that are outside of the multi-column
block.

Reviewed by Dan Bernstein.

Added new tests in fast/line-grid.

  • rendering/LayoutState.cpp:

(WebCore::LayoutState::LayoutState):
(WebCore::LayoutState::propagateLineGridInfo):
(WebCore::LayoutState::establishLineGrid):
(WebCore):
(WebCore::LayoutState::computeLineGridPaginationOrigin):

  • rendering/LayoutState.h:

(WebCore::LayoutState::LayoutState):
(WebCore::LayoutState::lineGrid):
(WebCore::LayoutState::lineGridOffset):
(WebCore::LayoutState::lineGridPaginationOrigin):
(WebCore::LayoutState::needsBlockDirectionLocationSetBeforeLayout):
(LayoutState):

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::layoutBlockChildren):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::layoutInlineChildren):

  • rendering/RenderView.h:

(WebCore::RenderView::pushLayoutState):

  • rendering/RootInlineBox.cpp:

(WebCore::RootInlineBox::lineGridSnapAdjustment):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=78157

Make multi-column layout work with line grids that are outside of the multi-column
block.

Reviewed by Dan Bernstein.

  • fast/line-grid/line-grid-into-columns.html: Added.
  • platform/mac/fast/line-grid/line-grid-into-columns-expected.png: Added.
  • platform/mac/fast/line-grid/line-grid-into-columns-expected.txt: Added.
Location:
trunk
Files:
3 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r107159 r107160  
     12012-02-08  David Hyatt  <hyatt@apple.com>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=78157
     4       
     5        Make multi-column layout work with line grids that are outside of the multi-column
     6        block.
     7 
     8        Reviewed by Dan Bernstein.
     9
     10        * fast/line-grid/line-grid-into-columns.html: Added.
     11        * platform/mac/fast/line-grid/line-grid-into-columns-expected.png: Added.
     12        * platform/mac/fast/line-grid/line-grid-into-columns-expected.txt: Added.
     13
    1142012-02-08  Matt Falkenhagen  <falken@chromium.org>
    215
  • trunk/Source/WebCore/ChangeLog

    r107157 r107160  
     12012-02-08  David Hyatt  <hyatt@apple.com>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=78157
     4       
     5        Make multi-column layout work with line grids that are outside of the multi-column
     6        block.
     7
     8        Reviewed by Dan Bernstein.
     9
     10        Added new tests in fast/line-grid.
     11
     12        * rendering/LayoutState.cpp:
     13        (WebCore::LayoutState::LayoutState):
     14        (WebCore::LayoutState::propagateLineGridInfo):
     15        (WebCore::LayoutState::establishLineGrid):
     16        (WebCore):
     17        (WebCore::LayoutState::computeLineGridPaginationOrigin):
     18        * rendering/LayoutState.h:
     19        (WebCore::LayoutState::LayoutState):
     20        (WebCore::LayoutState::lineGrid):
     21        (WebCore::LayoutState::lineGridOffset):
     22        (WebCore::LayoutState::lineGridPaginationOrigin):
     23        (WebCore::LayoutState::needsBlockDirectionLocationSetBeforeLayout):
     24        (LayoutState):
     25        * rendering/RenderBlock.cpp:
     26        (WebCore::RenderBlock::layoutBlockChildren):
     27        * rendering/RenderBlockLineLayout.cpp:
     28        (WebCore::RenderBlock::layoutInlineChildren):
     29        * rendering/RenderView.h:
     30        (WebCore::RenderView::pushLayoutState):
     31        * rendering/RootInlineBox.cpp:
     32        (WebCore::RootInlineBox::lineGridSnapAdjustment):
     33
    1342012-02-08  Matthew Delaney  <mdelaney@apple.com>
    235
  • trunk/Source/WebCore/rendering/LayoutState.cpp

    r105420 r107160  
    3838LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
    3939    : m_columnInfo(columnInfo)
    40     , m_currentLineGrid(0)
     40    , m_lineGrid(0)
    4141    , m_next(prev)
    4242#ifndef NDEBUG
     
    103103    }
    104104   
     105    // Propagate line grid information.
     106    propagateLineGridInfo(renderer);
     107
    105108    if (!m_columnInfo)
    106109        m_columnInfo = m_next->m_columnInfo;
     
    110113    m_isPaginated = m_pageLogicalHeight || m_columnInfo;
    111114
    112     // Propagate line grid information.
    113     propagateLineGridInfo(renderer);
     115    if (lineGrid() && renderer->hasColumns() && renderer->style()->hasInlineColumnAxis())
     116        computeLineGridPaginationOrigin(renderer);
    114117
    115118    // If we have a new grid to track, then add it to our set.
     
    126129    , m_pageLogicalHeightChanged(regionsChanged)
    127130    , m_columnInfo(0)
    128     , m_currentLineGrid(0)
     131    , m_lineGrid(0)
    129132    , m_next(prev)
    130133#ifndef NDEBUG
     
    143146    , m_pageLogicalHeightChanged(false)
    144147    , m_columnInfo(0)
    145     , m_currentLineGrid(0)
     148    , m_lineGrid(0)
    146149    , m_next(0)
    147150#ifndef NDEBUG
     
    214217        return;
    215218
    216     m_currentLineGrid = m_next->m_currentLineGrid;
    217     m_currentLineGridOffset = m_next->m_currentLineGridOffset;
     219    m_lineGrid = m_next->m_lineGrid;
     220    m_lineGridOffset = m_next->m_lineGridOffset;
     221    m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin;
    218222}
    219223
     
    221225{
    222226    // First check to see if this grid has been established already.
    223     if (m_currentLineGrid) {
    224         if (m_currentLineGrid->style()->lineGrid() == block->style()->lineGrid())
     227    if (m_lineGrid) {
     228        if (m_lineGrid->style()->lineGrid() == block->style()->lineGrid())
    225229            return;
    226         RenderBlock* currentGrid = m_currentLineGrid;
     230        RenderBlock* currentGrid = m_lineGrid;
    227231        for (LayoutState* currentState = m_next; currentState; currentState = currentState->m_next) {
    228             if (currentState->m_currentLineGrid == currentGrid)
     232            if (currentState->m_lineGrid == currentGrid)
    229233                continue;
    230             currentGrid = currentState->m_currentLineGrid;
     234            currentGrid = currentState->m_lineGrid;
    231235            if (!currentGrid)
    232236                break;
    233237            if (currentGrid->style()->lineGrid() == block->style()->lineGrid()) {
    234                 m_currentLineGrid = currentGrid;
    235                 m_currentLineGridOffset = currentState->m_currentLineGridOffset;
     238                m_lineGrid = currentGrid;
     239                m_lineGridOffset = currentState->m_lineGridOffset;
    236240                return;
    237241            }
     
    240244   
    241245    // We didn't find an already-established grid with this identifier. Our render object establishes the grid.
    242     m_currentLineGrid = block;
    243     m_currentLineGridOffset = m_layoutOffset;
     246    m_lineGrid = block;
     247    m_lineGridOffset = m_layoutOffset;
     248}
     249
     250void LayoutState::computeLineGridPaginationOrigin(RenderBox* renderer)
     251{
     252    // We need to cache a line grid pagination origin so that we understand how to reset the line grid
     253    // at the top of each column.
     254    // Get the current line grid and offset.
     255    if (!lineGrid() || lineGrid()->style()->writingMode() != renderer->style()->writingMode())
     256        return;
     257
     258    // Get the hypothetical line box used to establish the grid.
     259    RootInlineBox* lineGridBox = lineGrid()->lineGridBox();
     260    if (!lineGridBox)
     261        return;
     262   
     263    bool isHorizontalWritingMode = lineGrid()->isHorizontalWritingMode();
     264
     265    LayoutUnit lineGridBlockOffset = isHorizontalWritingMode ? lineGridOffset().height() : lineGridOffset().width();
     266
     267    // Now determine our position on the grid. Our baseline needs to be adjusted to the nearest baseline multiple
     268    // as established by the line box.
     269    // FIXME: Need to handle crazy line-box-contain values that cause the root line box to not be considered. I assume
     270    // the grid should honor line-box-contain.
     271    LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridBox->lineTopWithLeading();
     272    if (!gridLineHeight)
     273        return;
     274
     275    LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading();
     276   
     277    if (isPaginated() && pageLogicalHeight()) {
     278        LayoutUnit pageLogicalTop = renderer->isHorizontalWritingMode() ? m_pageOffset.height() : m_pageOffset.width();
     279        if (pageLogicalTop > firstLineTopWithLeading) {
     280            // Shift to the next highest line grid multiple past the page logical top. Cache the delta
     281            // between this new value and the page logical top as the pagination origin.
     282            LayoutUnit remainder = (pageLogicalTop - firstLineTopWithLeading) % gridLineHeight;
     283            LayoutUnit paginationDelta = gridLineHeight - remainder;
     284            if (isHorizontalWritingMode)
     285                m_lineGridPaginationOrigin.setHeight(paginationDelta);
     286            else
     287                m_lineGridPaginationOrigin.setWidth(paginationDelta);
     288        }
     289    }
    244290}
    245291
  • trunk/Source/WebCore/rendering/LayoutState.h

    r106511 r107160  
    4949        , m_pageLogicalHeightChanged(false)
    5050        , m_columnInfo(0)
    51         , m_currentLineGrid(0)
     51        , m_lineGrid(0)
    5252        , m_next(0)
    5353#ifndef NDEBUG
     
    8282    bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
    8383
    84     RenderBlock* currentLineGrid() const { return m_currentLineGrid; }
    85     LayoutSize currentLineGridOffset() const { return m_currentLineGridOffset; }
     84    RenderBlock* lineGrid() const { return m_lineGrid; }
     85    LayoutSize lineGridOffset() const { return m_lineGridOffset; }
     86    LayoutSize lineGridPaginationOrigin() const { return m_lineGridPaginationOrigin; }
    8687
    8788    LayoutSize layoutOffset() const { return m_layoutOffset; }
    8889
    89     bool needsBlockDirectionLocationSetBeforeLayout() const { return m_currentLineGrid || (m_isPaginated && m_pageLogicalHeight); }
     90    bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
    9091
    9192private:
     
    9596    void propagateLineGridInfo(RenderBox*);
    9697    void establishLineGrid(RenderBlock*);
     98
     99    void computeLineGridPaginationOrigin(RenderBox*);
    97100
    98101public:
     
    120123
    121124    // The current line grid that we're snapping to and the offset of the start of the grid.
    122     RenderBlock* m_currentLineGrid;
    123     LayoutSize m_currentLineGridOffset;
    124    
     125    RenderBlock* m_lineGrid;
     126    LayoutSize m_lineGridOffset;
     127    LayoutSize m_lineGridPaginationOrigin;
     128
    125129    LayoutState* m_next;
    126130#ifndef NDEBUG
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r107072 r107160  
    20232023   
    20242024    // Lay out our hypothetical grid line as though it occurs at the top of the block.
    2025     if (view()->layoutState()->currentLineGrid() == this)
     2025    if (view()->layoutState()->lineGrid() == this)
    20262026        layoutLineGridBox();
    20272027
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r107032 r107160  
    14511451   
    14521452    // Lay out our hypothetical grid line as though it occurs at the top of the block.
    1453     if (view()->layoutState() && view()->layoutState()->currentLineGrid() == this)
     1453    if (view()->layoutState() && view()->layoutState()->lineGrid() == this)
    14541454        layoutLineGridBox();
    14551455
  • trunk/Source/WebCore/rendering/RenderView.h

    r106511 r107160  
    209209        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
    210210        if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->inRenderFlowThread()
    211             || m_layoutState->currentLineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())) {
     211            || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())) {
    212212            m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
    213213            return true;
  • trunk/Source/WebCore/rendering/RootInlineBox.cpp

    r107099 r107160  
    336336    // Get the current line grid and offset.
    337337    LayoutState* layoutState = block()->view()->layoutState();
    338     RenderBlock* lineGrid = layoutState->currentLineGrid();
    339     LayoutSize lineGridOffset = layoutState->currentLineGridOffset();
     338    RenderBlock* lineGrid = layoutState->lineGrid();
     339    LayoutSize lineGridOffset = layoutState->lineGridOffset();
    340340    if (!lineGrid || lineGrid->style()->writingMode() != block()->style()->writingMode())
    341341        return 0;
     
    360360    LayoutUnit lineGridFontHeight = lineGridBox->logicalHeight();
    361361    LayoutUnit firstTextTop = lineGridBlockOffset + lineGridBox->logicalTop();
     362    LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading();
    362363    LayoutUnit firstBaselinePosition = firstTextTop + lineGridFontAscent;
    363364
     
    365366    LayoutUnit currentFontAscent = block()->style()->fontMetrics().ascent(baselineType());
    366367    LayoutUnit currentBaselinePosition = currentTextTop + currentFontAscent;
     368
     369    LayoutUnit lineGridPaginationOrigin = isHorizontal() ? layoutState->lineGridPaginationOrigin().height() : layoutState->lineGridPaginationOrigin().width();
    367370
    368371    // If we're paginated, see if we're on a page after the first one. If so, the grid resets on subsequent pages.
     
    370373    LayoutUnit pageLogicalTop = 0;
    371374    if (layoutState->isPaginated() && layoutState->pageLogicalHeight()) {
    372         pageLogicalTop = block()->pageLogicalTopForOffset(logicalTop() + delta);
    373         if (pageLogicalTop > firstTextTop)
    374             firstTextTop = pageLogicalTop + lineGridBox->logicalTop() - lineGrid->borderBefore() - lineGrid->paddingBefore();
     375        pageLogicalTop = block()->pageLogicalTopForOffset(lineTopWithLeading() + delta);
     376        if (pageLogicalTop > firstLineTopWithLeading)
     377            firstTextTop = pageLogicalTop + lineGridBox->logicalTop() - lineGrid->borderBefore() - lineGrid->paddingBefore() + lineGridPaginationOrigin;
    375378    }
    376379
     
    406409        return result;
    407410   
    408     // We may have shifted to a new page. We need to do a re-snap when that happens.
    409     LayoutUnit newPageLogicalTop = block()->pageLogicalTopForOffset(logicalTop() + result);
     411    // We may end up shifted to a new page. We need to do a re-snap when that happens.
     412    LayoutUnit newPageLogicalTop = block()->pageLogicalTopForOffset(lineBottomWithLeading() + result);
    410413    if (newPageLogicalTop == pageLogicalTop)
    411414        return result;
    412415   
    413416    // Put ourselves at the top of the next page to force a snap onto the new grid established by that page.
    414     return lineGridSnapAdjustment(newPageLogicalTop - (blockOffset + logicalTop()));
     417    return lineGridSnapAdjustment(newPageLogicalTop - (blockOffset + lineTopWithLeading()));
    415418}
    416419
Note: See TracChangeset for help on using the changeset viewer.