| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/rendering/LayoutState.h" | 27 #include "core/rendering/LayoutState.h" |
| 28 | 28 |
| 29 #include "core/rendering/RenderInline.h" | 29 #include "core/rendering/RenderInline.h" |
| 30 #include "core/rendering/RenderLayer.h" | 30 #include "core/rendering/RenderLayer.h" |
| 31 #include "core/rendering/RenderView.h" | 31 #include "core/rendering/RenderView.h" |
| 32 #include "platform/Partitions.h" | 32 #include "platform/Partitions.h" |
| 33 | 33 |
| 34 namespace WebCore { | 34 namespace WebCore { |
| 35 | 35 |
| 36 LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
e& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnIn
fo* columnInfo) | 36 LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
e& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged) |
| 37 : m_columnInfo(columnInfo) | 37 : m_lineGrid(0) |
| 38 , m_lineGrid(0) | |
| 39 , m_next(prev) | 38 , m_next(prev) |
| 40 , m_shapeInsideInfo(0) | 39 , m_shapeInsideInfo(0) |
| 41 #ifndef NDEBUG | 40 #ifndef NDEBUG |
| 42 , m_renderer(renderer) | 41 , m_renderer(renderer) |
| 43 #endif | 42 #endif |
| 44 { | 43 { |
| 45 ASSERT(m_next); | 44 ASSERT(m_next); |
| 46 | 45 |
| 47 bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->positio
n() == FixedPosition; | 46 bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->positio
n() == FixedPosition; |
| 48 if (fixed) { | 47 if (fixed) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 77 else { | 76 else { |
| 78 m_clipRect = clipRect; | 77 m_clipRect = clipRect; |
| 79 m_clipped = true; | 78 m_clipped = true; |
| 80 } | 79 } |
| 81 | 80 |
| 82 m_paintOffset -= renderer->scrolledContentOffset(); | 81 m_paintOffset -= renderer->scrolledContentOffset(); |
| 83 } | 82 } |
| 84 | 83 |
| 85 // If we establish a new page height, then cache the offset to the top of th
e first page. | 84 // If we establish a new page height, then cache the offset to the top of th
e first page. |
| 86 // We can compare this later on to figure out what part of the page we're ac
tually on, | 85 // We can compare this later on to figure out what part of the page we're ac
tually on, |
| 87 if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) { | 86 if (pageLogicalHeight || renderer->isRenderFlowThread()) { |
| 88 m_pageLogicalHeight = pageLogicalHeight; | 87 m_pageLogicalHeight = pageLogicalHeight; |
| 89 bool isFlipped = renderer->style()->isFlippedBlocksWritingMode(); | 88 bool isFlipped = renderer->style()->isFlippedBlocksWritingMode(); |
| 90 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->
paddingRight()), | 89 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->
paddingRight()), |
| 91 m_layoutOffset.height() + (!isFlipped ? renderer-
>borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->pad
dingBottom())); | 90 m_layoutOffset.height() + (!isFlipped ? renderer-
>borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->pad
dingBottom())); |
| 92 m_pageLogicalHeightChanged = pageLogicalHeightChanged; | 91 m_pageLogicalHeightChanged = pageLogicalHeightChanged; |
| 93 } else { | 92 } else { |
| 94 // If we don't establish a new page height, then propagate the old page
height and offset down. | 93 // If we don't establish a new page height, then propagate the old page
height and offset down. |
| 95 m_pageLogicalHeight = m_next->m_pageLogicalHeight; | 94 m_pageLogicalHeight = m_next->m_pageLogicalHeight; |
| 96 m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; | 95 m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; |
| 97 m_pageOffset = m_next->m_pageOffset; | 96 m_pageOffset = m_next->m_pageOffset; |
| 98 | 97 |
| 99 // Disable pagination for objects we don't support. For now this include
s overflow:scroll/auto, inline blocks and | 98 // Disable pagination for objects we don't support. For now this include
s overflow:scroll/auto, inline blocks and |
| 100 // writing mode roots. | 99 // writing mode roots. |
| 101 if (renderer->isUnsplittableForPagination()) | 100 if (renderer->isUnsplittableForPagination()) |
| 102 m_pageLogicalHeight = 0; | 101 m_pageLogicalHeight = 0; |
| 103 } | 102 } |
| 104 | 103 |
| 105 // Propagate line grid information. | 104 // Propagate line grid information. |
| 106 propagateLineGridInfo(renderer); | 105 propagateLineGridInfo(renderer); |
| 107 | 106 |
| 108 if (!m_columnInfo) | |
| 109 m_columnInfo = m_next->m_columnInfo; | |
| 110 | |
| 111 if (renderer->isRenderBlock()) { | 107 if (renderer->isRenderBlock()) { |
| 112 const RenderBlock* renderBlock = toRenderBlock(renderer); | 108 const RenderBlock* renderBlock = toRenderBlock(renderer); |
| 113 m_shapeInsideInfo = renderBlock->shapeInsideInfo(); | 109 m_shapeInsideInfo = renderBlock->shapeInsideInfo(); |
| 114 if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allo
wsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner())) | 110 if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allo
wsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner())) |
| 115 m_shapeInsideInfo = m_next->m_shapeInsideInfo; | 111 m_shapeInsideInfo = m_next->m_shapeInsideInfo; |
| 116 } | 112 } |
| 117 | 113 |
| 118 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { | 114 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { |
| 119 m_layoutDelta = m_next->m_layoutDelta; | 115 m_layoutDelta = m_next->m_layoutDelta; |
| 120 #if !ASSERT_DISABLED | 116 #if !ASSERT_DISABLED |
| 121 m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated; | 117 m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated; |
| 122 m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated; | 118 m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated; |
| 123 #endif | 119 #endif |
| 124 } | 120 } |
| 125 | 121 |
| 126 m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlo
wThread(); | 122 m_isPaginated = m_pageLogicalHeight || renderer->isRenderFlowThread(); |
| 127 | |
| 128 if (lineGrid() && renderer->hasColumns() && renderer->style()->hasInlineColu
mnAxis()) | |
| 129 computeLineGridPaginationOrigin(renderer); | |
| 130 | 123 |
| 131 // If we have a new grid to track, then add it to our set. | 124 // If we have a new grid to track, then add it to our set. |
| 132 if (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && rende
rer->isRenderBlockFlow()) | 125 if (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && rende
rer->isRenderBlockFlow()) |
| 133 establishLineGrid(toRenderBlockFlow(renderer)); | 126 establishLineGrid(toRenderBlockFlow(renderer)); |
| 134 | 127 |
| 135 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. | 128 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. |
| 136 } | 129 } |
| 137 | 130 |
| 138 LayoutState::LayoutState(RenderObject* root) | 131 LayoutState::LayoutState(RenderObject* root) |
| 139 : m_clipped(false) | 132 : m_clipped(false) |
| 140 , m_isPaginated(false) | 133 , m_isPaginated(false) |
| 141 , m_pageLogicalHeightChanged(false) | 134 , m_pageLogicalHeightChanged(false) |
| 142 #if !ASSERT_DISABLED | 135 #if !ASSERT_DISABLED |
| 143 , m_layoutDeltaXSaturated(false) | 136 , m_layoutDeltaXSaturated(false) |
| 144 , m_layoutDeltaYSaturated(false) | 137 , m_layoutDeltaYSaturated(false) |
| 145 #endif | 138 #endif |
| 146 , m_columnInfo(0) | |
| 147 , m_lineGrid(0) | 139 , m_lineGrid(0) |
| 148 , m_next(0) | 140 , m_next(0) |
| 149 , m_shapeInsideInfo(0) | 141 , m_shapeInsideInfo(0) |
| 150 , m_pageLogicalHeight(0) | 142 , m_pageLogicalHeight(0) |
| 151 #ifndef NDEBUG | 143 #ifndef NDEBUG |
| 152 , m_renderer(root) | 144 , m_renderer(root) |
| 153 #endif | 145 #endif |
| 154 { | 146 { |
| 155 RenderObject* container = root->container(); | 147 RenderObject* container = root->container(); |
| 156 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); | 148 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 167 void* LayoutState::operator new(size_t sz) | 159 void* LayoutState::operator new(size_t sz) |
| 168 { | 160 { |
| 169 return partitionAlloc(Partitions::getRenderingPartition(), sz); | 161 return partitionAlloc(Partitions::getRenderingPartition(), sz); |
| 170 } | 162 } |
| 171 | 163 |
| 172 void LayoutState::operator delete(void* ptr) | 164 void LayoutState::operator delete(void* ptr) |
| 173 { | 165 { |
| 174 partitionFree(ptr); | 166 partitionFree(ptr); |
| 175 } | 167 } |
| 176 | 168 |
| 177 void LayoutState::clearPaginationInformation() | |
| 178 { | |
| 179 m_pageLogicalHeight = m_next->m_pageLogicalHeight; | |
| 180 m_pageOffset = m_next->m_pageOffset; | |
| 181 m_columnInfo = m_next->m_columnInfo; | |
| 182 } | |
| 183 | |
| 184 LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogi
calOffset) const | 169 LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogi
calOffset) const |
| 185 { | 170 { |
| 186 if (child->isHorizontalWritingMode()) | 171 if (child->isHorizontalWritingMode()) |
| 187 return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.heigh
t(); | 172 return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.heigh
t(); |
| 188 return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width(); | 173 return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width(); |
| 189 } | 174 } |
| 190 | 175 |
| 191 void LayoutState::addForcedColumnBreak(RenderBox* child, LayoutUnit childLogical
Offset) | |
| 192 { | |
| 193 if (!m_columnInfo || m_columnInfo->columnHeight()) | |
| 194 return; | |
| 195 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); | |
| 196 } | |
| 197 | |
| 198 void LayoutState::propagateLineGridInfo(RenderBox* renderer) | 176 void LayoutState::propagateLineGridInfo(RenderBox* renderer) |
| 199 { | 177 { |
| 200 // Disable line grids for objects we don't support. For now this includes ov
erflow:scroll/auto, inline blocks and | 178 // Disable line grids for objects we don't support. For now this includes ov
erflow:scroll/auto, inline blocks and |
| 201 // writing mode roots. | 179 // writing mode roots. |
| 202 if (!m_next || renderer->isUnsplittableForPagination()) | 180 if (!m_next || renderer->isUnsplittableForPagination()) |
| 203 return; | 181 return; |
| 204 | 182 |
| 205 m_lineGrid = m_next->m_lineGrid; | 183 m_lineGrid = m_next->m_lineGrid; |
| 206 m_lineGridOffset = m_next->m_lineGridOffset; | 184 m_lineGridOffset = m_next->m_lineGridOffset; |
| 207 m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin; | 185 m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 226 return; | 204 return; |
| 227 } | 205 } |
| 228 } | 206 } |
| 229 } | 207 } |
| 230 | 208 |
| 231 // We didn't find an already-established grid with this identifier. Our rend
er object establishes the grid. | 209 // We didn't find an already-established grid with this identifier. Our rend
er object establishes the grid. |
| 232 m_lineGrid = block; | 210 m_lineGrid = block; |
| 233 m_lineGridOffset = m_layoutOffset; | 211 m_lineGridOffset = m_layoutOffset; |
| 234 } | 212 } |
| 235 | 213 |
| 236 void LayoutState::computeLineGridPaginationOrigin(RenderBox* renderer) | |
| 237 { | |
| 238 // We need to cache a line grid pagination origin so that we understand how
to reset the line grid | |
| 239 // at the top of each column. | |
| 240 // Get the current line grid and offset. | |
| 241 if (!lineGrid() || lineGrid()->style()->writingMode() != renderer->style()->
writingMode()) | |
| 242 return; | |
| 243 | |
| 244 // Get the hypothetical line box used to establish the grid. | |
| 245 RootInlineBox* lineGridBox = lineGrid()->lineGridBox(); | |
| 246 if (!lineGridBox) | |
| 247 return; | |
| 248 | |
| 249 bool isHorizontalWritingMode = lineGrid()->isHorizontalWritingMode(); | |
| 250 | |
| 251 LayoutUnit lineGridBlockOffset = isHorizontalWritingMode ? lineGridOffset().
height() : lineGridOffset().width(); | |
| 252 | |
| 253 // Now determine our position on the grid. Our baseline needs to be adjusted
to the nearest baseline multiple | |
| 254 // as established by the line box. | |
| 255 // FIXME: Need to handle crazy line-box-contain values that cause the root l
ine box to not be considered. I assume | |
| 256 // the grid should honor line-box-contain. | |
| 257 LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridB
ox->lineTopWithLeading(); | |
| 258 if (!gridLineHeight) | |
| 259 return; | |
| 260 | |
| 261 LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->line
TopWithLeading(); | |
| 262 | |
| 263 if (isPaginated() && pageLogicalHeight()) { | |
| 264 LayoutUnit pageLogicalTop = renderer->isHorizontalWritingMode() ? m_page
Offset.height() : m_pageOffset.width(); | |
| 265 if (pageLogicalTop > firstLineTopWithLeading) { | |
| 266 // Shift to the next highest line grid multiple past the page logica
l top. Cache the delta | |
| 267 // between this new value and the page logical top as the pagination
origin. | |
| 268 LayoutUnit remainder = roundToInt(pageLogicalTop - firstLineTopWithL
eading) % roundToInt(gridLineHeight); | |
| 269 LayoutUnit paginationDelta = gridLineHeight - remainder; | |
| 270 if (isHorizontalWritingMode) | |
| 271 m_lineGridPaginationOrigin.setHeight(paginationDelta); | |
| 272 else | |
| 273 m_lineGridPaginationOrigin.setWidth(paginationDelta); | |
| 274 } | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 } // namespace WebCore | 214 } // namespace WebCore |
| OLD | NEW |