Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/BackgroundImageGeometry.h" | 5 #include "core/paint/BackgroundImageGeometry.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/layout/LayoutBox.h" | 8 #include "core/layout/LayoutBox.h" |
| 9 #include "core/layout/LayoutBoxModelObject.h" | 9 #include "core/layout/LayoutBoxModelObject.h" |
| 10 #include "core/layout/LayoutTableCell.h" | |
| 11 #include "core/layout/LayoutTableCol.h" | |
| 10 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
| 11 #include "core/layout/compositing/CompositedLayerMapping.h" | 13 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 12 #include "core/paint/PaintLayer.h" | 14 #include "core/paint/PaintLayer.h" |
| 13 #include "platform/LayoutUnit.h" | 15 #include "platform/LayoutUnit.h" |
| 14 #include "platform/geometry/LayoutRect.h" | 16 #include "platform/geometry/LayoutRect.h" |
| 15 | 17 |
| 16 namespace blink { | 18 namespace blink { |
| 17 | 19 |
| 18 namespace { | 20 namespace { |
| 19 | 21 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 m_destRect.move(0, std::max(roundedOffset, 0)); | 208 m_destRect.move(0, std::max(roundedOffset, 0)); |
| 207 setPhaseY(LayoutUnit(-std::min(roundedOffset, 0))); | 209 setPhaseY(LayoutUnit(-std::min(roundedOffset, 0))); |
| 208 m_destRect.setHeight(m_tileSize.height() + std::min(roundedOffset, 0)); | 210 m_destRect.setHeight(m_tileSize.height() + std::min(roundedOffset, 0)); |
| 209 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit())); | 211 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit())); |
| 210 } | 212 } |
| 211 | 213 |
| 212 void BackgroundImageGeometry::setRepeatX(const FillLayer& fillLayer, | 214 void BackgroundImageGeometry::setRepeatX(const FillLayer& fillLayer, |
| 213 LayoutUnit unsnappedTileWidth, | 215 LayoutUnit unsnappedTileWidth, |
| 214 LayoutUnit snappedAvailableWidth, | 216 LayoutUnit snappedAvailableWidth, |
| 215 LayoutUnit unsnappedAvailableWidth, | 217 LayoutUnit unsnappedAvailableWidth, |
| 216 LayoutUnit extraOffset) { | 218 LayoutUnit extraOffset, |
| 219 LayoutUnit offsetForCell) { | |
| 217 // We would like to identify the phase as a fraction of the image size in the | 220 // We would like to identify the phase as a fraction of the image size in the |
| 218 // absence of snapping, then re-apply it to the snapped values. This is to | 221 // absence of snapping, then re-apply it to the snapped values. This is to |
| 219 // handle large positions. | 222 // handle large positions. |
| 220 if (unsnappedTileWidth) { | 223 if (unsnappedTileWidth) { |
| 221 LayoutUnit computedXPosition = roundedMinimumValueForLength( | 224 LayoutUnit computedXPosition = |
| 222 fillLayer.xPosition(), unsnappedAvailableWidth); | 225 roundedMinimumValueForLength(fillLayer.xPosition(), |
| 226 unsnappedAvailableWidth) - | |
| 227 offsetForCell; | |
| 223 if (fillLayer.backgroundXOrigin() == RightEdge) { | 228 if (fillLayer.backgroundXOrigin() == RightEdge) { |
| 224 float numberOfTilesInPosition = | 229 float numberOfTilesInPosition = |
| 225 (snappedAvailableWidth - computedXPosition + extraOffset).toFloat() / | 230 (snappedAvailableWidth - computedXPosition + extraOffset).toFloat() / |
| 226 unsnappedTileWidth.toFloat(); | 231 unsnappedTileWidth.toFloat(); |
| 227 float fractionalPositionWithinTile = | 232 float fractionalPositionWithinTile = |
| 228 numberOfTilesInPosition - truncf(numberOfTilesInPosition); | 233 numberOfTilesInPosition - truncf(numberOfTilesInPosition); |
| 229 setPhaseX(LayoutUnit( | 234 setPhaseX(LayoutUnit( |
| 230 roundf(fractionalPositionWithinTile * tileSize().width()))); | 235 roundf(fractionalPositionWithinTile * tileSize().width()))); |
| 231 } else { | 236 } else { |
| 232 float numberOfTilesInPosition = | 237 float numberOfTilesInPosition = |
| 233 (computedXPosition + extraOffset).toFloat() / | 238 (computedXPosition + extraOffset).toFloat() / |
| 234 unsnappedTileWidth.toFloat(); | 239 unsnappedTileWidth.toFloat(); |
| 235 float fractionalPositionWithinTile = | 240 float fractionalPositionWithinTile = |
| 236 1.0f - (numberOfTilesInPosition - truncf(numberOfTilesInPosition)); | 241 1.0f - (numberOfTilesInPosition - truncf(numberOfTilesInPosition)); |
| 237 setPhaseX(LayoutUnit( | 242 setPhaseX(LayoutUnit( |
| 238 roundf(fractionalPositionWithinTile * tileSize().width()))); | 243 roundf(fractionalPositionWithinTile * tileSize().width()))); |
| 239 } | 244 } |
| 240 } else { | 245 } else { |
| 241 setPhaseX(LayoutUnit()); | 246 setPhaseX(LayoutUnit()); |
| 242 } | 247 } |
| 243 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height())); | 248 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height())); |
| 244 } | 249 } |
| 245 | 250 |
| 246 void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer, | 251 void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer, |
| 247 LayoutUnit unsnappedTileHeight, | 252 LayoutUnit unsnappedTileHeight, |
| 248 LayoutUnit snappedAvailableHeight, | 253 LayoutUnit snappedAvailableHeight, |
| 249 LayoutUnit unsnappedAvailableHeight, | 254 LayoutUnit unsnappedAvailableHeight, |
| 250 LayoutUnit extraOffset) { | 255 LayoutUnit extraOffset, |
| 256 LayoutUnit offsetForCell) { | |
| 251 // We would like to identify the phase as a fraction of the image size in the | 257 // We would like to identify the phase as a fraction of the image size in the |
| 252 // absence of snapping, then re-apply it to the snapped values. This is to | 258 // absence of snapping, then re-apply it to the snapped values. This is to |
| 253 // handle large positions. | 259 // handle large positions. |
| 254 if (unsnappedTileHeight) { | 260 if (unsnappedTileHeight) { |
| 255 LayoutUnit computedYPosition = roundedMinimumValueForLength( | 261 LayoutUnit computedYPosition = |
| 256 fillLayer.yPosition(), unsnappedAvailableHeight); | 262 roundedMinimumValueForLength(fillLayer.yPosition(), |
| 263 unsnappedAvailableHeight) - | |
| 264 offsetForCell; | |
| 257 if (fillLayer.backgroundYOrigin() == BottomEdge) { | 265 if (fillLayer.backgroundYOrigin() == BottomEdge) { |
| 258 float numberOfTilesInPosition = | 266 float numberOfTilesInPosition = |
| 259 (snappedAvailableHeight - computedYPosition + extraOffset).toFloat() / | 267 (snappedAvailableHeight - computedYPosition + extraOffset).toFloat() / |
| 260 unsnappedTileHeight.toFloat(); | 268 unsnappedTileHeight.toFloat(); |
| 261 float fractionalPositionWithinTile = | 269 float fractionalPositionWithinTile = |
| 262 numberOfTilesInPosition - truncf(numberOfTilesInPosition); | 270 numberOfTilesInPosition - truncf(numberOfTilesInPosition); |
| 263 setPhaseY(LayoutUnit( | 271 setPhaseY(LayoutUnit( |
| 264 roundf(fractionalPositionWithinTile * tileSize().height()))); | 272 roundf(fractionalPositionWithinTile * tileSize().height()))); |
| 265 } else { | 273 } else { |
| 266 float numberOfTilesInPosition = | 274 float numberOfTilesInPosition = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 } | 314 } |
| 307 | 315 |
| 308 void BackgroundImageGeometry::useFixedAttachment( | 316 void BackgroundImageGeometry::useFixedAttachment( |
| 309 const LayoutPoint& attachmentPoint) { | 317 const LayoutPoint& attachmentPoint) { |
| 310 LayoutPoint alignedPoint = attachmentPoint; | 318 LayoutPoint alignedPoint = attachmentPoint; |
| 311 m_phase.move(std::max(alignedPoint.x() - m_destRect.x(), LayoutUnit()), | 319 m_phase.move(std::max(alignedPoint.x() - m_destRect.x(), LayoutUnit()), |
| 312 std::max(alignedPoint.y() - m_destRect.y(), LayoutUnit())); | 320 std::max(alignedPoint.y() - m_destRect.y(), LayoutUnit())); |
| 313 setPhase(LayoutPoint(roundedIntPoint(m_phase))); | 321 setPhase(LayoutPoint(roundedIntPoint(m_phase))); |
| 314 } | 322 } |
| 315 | 323 |
| 324 enum ColumnGroupDirection { ColumnGroupStart, ColumnGroupEnd }; | |
| 325 | |
| 326 static void expandToTableColumnGroup(const LayoutTableCell* cell, | |
|
Xianzhu
2017/01/15 20:45:58
s/*/&/
| |
| 327 const LayoutTableCol& columnGroup, | |
| 328 LayoutUnit& value, | |
| 329 ColumnGroupDirection columnDirection) { | |
| 330 std::function<LayoutTableCell*(LayoutTableCell*)> siblingCell = | |
| 331 columnDirection == ColumnGroupStart ? &LayoutTableCell::previousCell | |
| 332 : &LayoutTableCell::nextCell; | |
|
Xianzhu
2017/01/15 20:45:57
Wdyt using the following:
auto siblingCell = ..
| |
| 333 for (LayoutTableCell* sibling = | |
| 334 siblingCell(const_cast<LayoutTableCell*>(cell)); | |
| 335 sibling; sibling = siblingCell(sibling)) { | |
| 336 if (cell->table() | |
| 337 ->colElementAtAbsoluteColumn(sibling->absoluteColumnIndex()) | |
| 338 .innermostColOrColGroup() | |
| 339 ->enclosingColumnGroup() != columnGroup) | |
| 340 break; | |
| 341 value += sibling->size().width(); | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 LayoutPoint BackgroundImageGeometry::getOffsetForCell( | |
| 346 const LayoutTableCell& cell, | |
| 347 const LayoutBox& positioningBox) { | |
| 348 LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(), | |
| 349 cell.table()->vBorderSpacing()); | |
| 350 if (positioningBox.isTableSection()) | |
| 351 return cell.location() - borderSpacing; | |
| 352 if (positioningBox.isTableRow()) { | |
| 353 return LayoutPoint(cell.location().x(), LayoutUnit()) - | |
| 354 LayoutSize(borderSpacing.width(), LayoutUnit()); | |
| 355 } | |
| 356 | |
|
Xianzhu
2017/01/15 20:45:58
DCHECK(positioningBox.isLayoutTableCol());
| |
| 357 LayoutRect sectionsRect(LayoutPoint(), cell.table()->size()); | |
| 358 cell.table()->subtractCaptionRect(sectionsRect); | |
| 359 LayoutUnit heightOfCaptions = | |
| 360 cell.table()->size().height() - sectionsRect.height(); | |
| 361 LayoutPoint offsetInBackground = LayoutPoint( | |
| 362 LayoutUnit(), (cell.section()->location().y() - | |
| 363 cell.table()->borderBefore() - heightOfCaptions) + | |
| 364 cell.location().y()); | |
| 365 if (positioningBox.isLayoutTableCol() && | |
|
Xianzhu
2017/01/15 20:45:58
Remove 'positioningBox.isLayoutTableCol() &&'.
| |
| 366 toLayoutTableCol(positioningBox).isTableColumn()) { | |
| 367 return offsetInBackground - | |
| 368 LayoutSize(LayoutUnit(), borderSpacing.height()); | |
| 369 } | |
| 370 | |
| 371 DCHECK(positioningBox.isLayoutTableCol() && | |
|
Xianzhu
2017/01/15 20:45:57
Remove 'positioningBox.isLayoutTableCol() &&'.
| |
| 372 toLayoutTableCol(positioningBox).isTableColumnGroup()); | |
| 373 LayoutUnit offset = offsetInBackground.x(); | |
| 374 expandToTableColumnGroup(&cell, toLayoutTableCol(positioningBox), offset, | |
| 375 ColumnGroupStart); | |
| 376 offsetInBackground.move(offset, LayoutUnit()); | |
| 377 return offsetInBackground - LayoutSize(LayoutUnit(), borderSpacing.height()); | |
| 378 } | |
| 379 | |
| 380 LayoutSize BackgroundImageGeometry::getPositioningAreaSizeForCell( | |
| 381 const LayoutTableCell& cell, | |
| 382 const LayoutBox& positioningBox) { | |
| 383 LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(), | |
| 384 cell.table()->vBorderSpacing()); | |
| 385 if (positioningBox.isTableSection()) | |
| 386 return positioningBox.size() - borderSpacing - borderSpacing; | |
| 387 | |
| 388 if (positioningBox.isTableRow()) { | |
| 389 return positioningBox.size() - | |
| 390 LayoutSize(borderSpacing.width(), LayoutUnit()) - | |
| 391 LayoutSize(borderSpacing.width(), LayoutUnit()); | |
| 392 } | |
| 393 | |
|
Xianzhu
2017/01/15 20:45:57
Ditto comments as in getOffsetForCell().
| |
| 394 LayoutRect sectionsRect(LayoutPoint(), cell.table()->size()); | |
| 395 cell.table()->subtractCaptionRect(sectionsRect); | |
| 396 LayoutUnit columnHeight = sectionsRect.height() - | |
| 397 cell.table()->borderBefore() - | |
| 398 borderSpacing.height() - borderSpacing.height(); | |
| 399 if (positioningBox.isLayoutTableCol() && | |
| 400 toLayoutTableCol(positioningBox).isTableColumn()) | |
| 401 return LayoutSize(cell.size().width(), columnHeight); | |
| 402 | |
| 403 DCHECK(positioningBox.isLayoutTableCol() && | |
| 404 toLayoutTableCol(positioningBox).isTableColumnGroup()); | |
| 405 LayoutUnit width = cell.size().width(); | |
| 406 expandToTableColumnGroup(&cell, toLayoutTableCol(positioningBox), width, | |
| 407 ColumnGroupStart); | |
| 408 expandToTableColumnGroup(&cell, toLayoutTableCol(positioningBox), width, | |
| 409 ColumnGroupEnd); | |
| 410 | |
| 411 return LayoutSize(width, columnHeight); | |
| 412 } | |
| 413 | |
| 316 void BackgroundImageGeometry::calculate( | 414 void BackgroundImageGeometry::calculate( |
| 317 const LayoutBoxModelObject& obj, | 415 const LayoutBoxModelObject& obj, |
| 416 const LayoutObject* backgroundObject, | |
| 318 const LayoutBoxModelObject* paintContainer, | 417 const LayoutBoxModelObject* paintContainer, |
| 319 const GlobalPaintFlags globalPaintFlags, | 418 const GlobalPaintFlags globalPaintFlags, |
| 320 const FillLayer& fillLayer, | 419 const FillLayer& fillLayer, |
| 321 const LayoutRect& paintRect) { | 420 const LayoutRect& paintRect) { |
| 322 LayoutUnit left; | 421 LayoutUnit left; |
| 323 LayoutUnit top; | 422 LayoutUnit top; |
| 324 LayoutSize positioningAreaSize; | 423 LayoutSize positioningAreaSize; |
| 325 bool isLayoutView = obj.isLayoutView(); | 424 bool isLayoutView = obj.isLayoutView(); |
| 326 const LayoutBox* rootBox = nullptr; | 425 const LayoutBox* rootBox = nullptr; |
| 327 if (isLayoutView) { | 426 if (isLayoutView) { |
| 328 // It is only possible reach here when root element has a box. | 427 // It is only possible reach here when root element has a box. |
| 329 Element* documentElement = obj.document().documentElement(); | 428 Element* documentElement = obj.document().documentElement(); |
| 330 DCHECK(documentElement); | 429 DCHECK(documentElement); |
| 331 DCHECK(documentElement->layoutObject()); | 430 DCHECK(documentElement->layoutObject()); |
| 332 DCHECK(documentElement->layoutObject()->isBox()); | 431 DCHECK(documentElement->layoutObject()->isBox()); |
| 333 rootBox = toLayoutBox(documentElement->layoutObject()); | 432 rootBox = toLayoutBox(documentElement->layoutObject()); |
| 334 } | 433 } |
| 434 | |
| 435 bool cellUsingContainerBackground = | |
| 436 obj.isTableCell() && backgroundObject && !backgroundObject->isTableCell(); | |
| 335 const LayoutBoxModelObject& positioningBox = | 437 const LayoutBoxModelObject& positioningBox = |
| 336 isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj; | 438 isLayoutView |
| 337 | 439 ? static_cast<const LayoutBoxModelObject&>(*rootBox) |
|
Xianzhu
2017/01/15 20:45:58
s/static_cast<const LayoutBoxModelObject&>(...)/to
| |
| 440 : cellUsingContainerBackground | |
| 441 ? static_cast<const LayoutBoxModelObject&>(*backgroundObject) | |
|
Xianzhu
2017/01/15 20:45:57
Ditto.
| |
| 442 : obj; | |
| 443 LayoutPoint offsetInBackground = | |
| 444 cellUsingContainerBackground | |
| 445 ? getOffsetForCell(toLayoutTableCell(obj), | |
| 446 toLayoutBox(positioningBox)) | |
| 447 : LayoutPoint(); | |
| 338 // Determine the background positioning area and set destRect to the | 448 // Determine the background positioning area and set destRect to the |
| 339 // background painting area. destRect will be adjusted later if the | 449 // background painting area. destRect will be adjusted later if the |
| 340 // background is non-repeating. | 450 // background is non-repeating. |
| 341 // FIXME: transforms spec says that fixed backgrounds behave like scroll | 451 // FIXME: transforms spec says that fixed backgrounds behave like scroll |
| 342 // inside transforms. | 452 // inside transforms. |
| 343 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; | 453 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; |
| 344 | 454 |
| 345 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { | 455 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { |
| 346 // As a side effect of an optimization to blit on scroll, we do not honor | 456 // As a side effect of an optimization to blit on scroll, we do not honor |
| 347 // the CSS property "background-attachment: fixed" because it may result in | 457 // the CSS property "background-attachment: fixed" because it may result in |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 377 rootBox->size() - LayoutSize(left + right, top + bottom), | 487 rootBox->size() - LayoutSize(left + right, top + bottom), |
| 378 rootBox->location(); | 488 rootBox->location(); |
| 379 // The input paint rect is specified in root element local coordinate | 489 // The input paint rect is specified in root element local coordinate |
| 380 // (i.e. a transform is applied on the context for painting), and is | 490 // (i.e. a transform is applied on the context for painting), and is |
| 381 // expanded to cover the whole canvas. Since left/top is relative to the | 491 // expanded to cover the whole canvas. Since left/top is relative to the |
| 382 // paint rect, we need to offset them back. | 492 // paint rect, we need to offset them back. |
| 383 left -= paintRect.x(); | 493 left -= paintRect.x(); |
| 384 top -= paintRect.y(); | 494 top -= paintRect.y(); |
| 385 } else { | 495 } else { |
| 386 positioningAreaSize = | 496 positioningAreaSize = |
| 387 paintRect.size() - LayoutSize(left + right, top + bottom); | 497 (cellUsingContainerBackground |
| 498 ? getPositioningAreaSizeForCell(toLayoutTableCell(obj), | |
| 499 toLayoutBox(positioningBox)) | |
| 500 : paintRect.size()) - | |
|
Xianzhu
2017/01/15 20:45:58
I doubt if the name getPositionAreaSizeForCell() i
| |
| 501 LayoutSize(left + right, top + bottom); | |
| 388 } | 502 } |
| 389 } else { | 503 } else { |
| 390 setHasNonLocalGeometry(); | 504 setHasNonLocalGeometry(); |
| 391 | 505 |
| 392 LayoutRect viewportRect = obj.viewRect(); | 506 LayoutRect viewportRect = obj.viewRect(); |
| 393 if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { | 507 if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { |
| 394 viewportRect.setLocation(LayoutPoint()); | 508 viewportRect.setLocation(LayoutPoint()); |
| 395 } else { | 509 } else { |
| 396 if (FrameView* frameView = obj.view()->frameView()) | 510 if (FrameView* frameView = obj.view()->frameView()) |
| 397 viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); | 511 viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 423 LayoutUnit unsnappedAvailableHeight = | 537 LayoutUnit unsnappedAvailableHeight = |
| 424 positioningAreaSize.height() - fillTileSize.height(); | 538 positioningAreaSize.height() - fillTileSize.height(); |
| 425 positioningAreaSize = | 539 positioningAreaSize = |
| 426 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), | 540 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), |
| 427 snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); | 541 snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); |
| 428 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); | 542 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); |
| 429 LayoutUnit availableHeight = | 543 LayoutUnit availableHeight = |
| 430 positioningAreaSize.height() - tileSize().height(); | 544 positioningAreaSize.height() - tileSize().height(); |
| 431 | 545 |
| 432 LayoutUnit computedXPosition = | 546 LayoutUnit computedXPosition = |
| 433 roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth); | 547 roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth) - |
| 548 offsetInBackground.x(); | |
| 434 if (backgroundRepeatX == RoundFill && | 549 if (backgroundRepeatX == RoundFill && |
| 435 positioningAreaSize.width() > LayoutUnit() && | 550 positioningAreaSize.width() > LayoutUnit() && |
| 436 fillTileSize.width() > LayoutUnit()) { | 551 fillTileSize.width() > LayoutUnit()) { |
| 437 int nrTiles = std::max( | 552 int nrTiles = std::max( |
| 438 1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); | 553 1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); |
| 439 LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; | 554 LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; |
| 440 | 555 |
| 441 // Maintain aspect ratio if background-size: auto is set | 556 // Maintain aspect ratio if background-size: auto is set |
| 442 if (fillLayer.size().size.height().isAuto() && | 557 if (fillLayer.size().size.height().isAuto() && |
| 443 backgroundRepeatY != RoundFill) { | 558 backgroundRepeatY != RoundFill) { |
| 444 fillTileSize.setHeight(fillTileSize.height() * roundedWidth / | 559 fillTileSize.setHeight(fillTileSize.height() * roundedWidth / |
| 445 fillTileSize.width()); | 560 fillTileSize.width()); |
| 446 } | 561 } |
| 447 fillTileSize.setWidth(roundedWidth); | 562 fillTileSize.setWidth(roundedWidth); |
| 448 | 563 |
| 449 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 564 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); |
| 450 setPhaseX(tileSize().width() | 565 setPhaseX(tileSize().width() |
| 451 ? LayoutUnit(roundf( | 566 ? LayoutUnit(roundf( |
| 452 tileSize().width() - | 567 tileSize().width() - |
| 453 fmodf((computedXPosition + left), tileSize().width()))) | 568 fmodf((computedXPosition + left), tileSize().width()))) |
| 454 : LayoutUnit()); | 569 : LayoutUnit()); |
| 455 setSpaceSize(LayoutSize()); | 570 setSpaceSize(LayoutSize()); |
| 456 } | 571 } |
| 457 | 572 |
| 458 LayoutUnit computedYPosition = | 573 LayoutUnit computedYPosition = |
| 459 roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight); | 574 roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight) - |
| 575 offsetInBackground.y(); | |
| 460 if (backgroundRepeatY == RoundFill && | 576 if (backgroundRepeatY == RoundFill && |
| 461 positioningAreaSize.height() > LayoutUnit() && | 577 positioningAreaSize.height() > LayoutUnit() && |
| 462 fillTileSize.height() > LayoutUnit()) { | 578 fillTileSize.height() > LayoutUnit()) { |
| 463 int nrTiles = std::max( | 579 int nrTiles = std::max( |
| 464 1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); | 580 1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); |
| 465 LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; | 581 LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; |
| 466 // Maintain aspect ratio if background-size: auto is set | 582 // Maintain aspect ratio if background-size: auto is set |
| 467 if (fillLayer.size().size.width().isAuto() && | 583 if (fillLayer.size().size.width().isAuto() && |
| 468 backgroundRepeatX != RoundFill) { | 584 backgroundRepeatX != RoundFill) { |
| 469 fillTileSize.setWidth(fillTileSize.width() * roundedHeight / | 585 fillTileSize.setWidth(fillTileSize.width() * roundedHeight / |
| 470 fillTileSize.height()); | 586 fillTileSize.height()); |
| 471 } | 587 } |
| 472 fillTileSize.setHeight(roundedHeight); | 588 fillTileSize.setHeight(roundedHeight); |
| 473 | 589 |
| 474 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 590 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); |
| 475 setPhaseY(tileSize().height() | 591 setPhaseY(tileSize().height() |
| 476 ? LayoutUnit(roundf( | 592 ? LayoutUnit(roundf( |
| 477 tileSize().height() - | 593 tileSize().height() - |
| 478 fmodf((computedYPosition + top), tileSize().height()))) | 594 fmodf((computedYPosition + top), tileSize().height()))) |
| 479 : LayoutUnit()); | 595 : LayoutUnit()); |
| 480 setSpaceSize(LayoutSize()); | 596 setSpaceSize(LayoutSize()); |
| 481 } | 597 } |
| 482 | 598 |
| 483 if (backgroundRepeatX == RepeatFill) { | 599 if (backgroundRepeatX == RepeatFill) { |
| 484 setRepeatX(fillLayer, fillTileSize.width(), availableWidth, | 600 setRepeatX(fillLayer, fillTileSize.width(), availableWidth, |
| 485 unsnappedAvailableWidth, left); | 601 unsnappedAvailableWidth, left, offsetInBackground.x()); |
| 486 } else if (backgroundRepeatX == SpaceFill && | 602 } else if (backgroundRepeatX == SpaceFill && |
| 487 tileSize().width() > LayoutUnit()) { | 603 tileSize().width() > LayoutUnit()) { |
| 488 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), | 604 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), |
| 489 tileSize().width()); | 605 tileSize().width()); |
| 490 if (space >= LayoutUnit()) | 606 if (space >= LayoutUnit()) |
| 491 setSpaceX(space, availableWidth, left); | 607 setSpaceX(space, availableWidth, left); |
| 492 else | 608 else |
| 493 backgroundRepeatX = NoRepeatFill; | 609 backgroundRepeatX = NoRepeatFill; |
| 494 } | 610 } |
| 495 if (backgroundRepeatX == NoRepeatFill) { | 611 if (backgroundRepeatX == NoRepeatFill) { |
| 496 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge | 612 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge |
| 497 ? availableWidth - computedXPosition | 613 ? availableWidth - computedXPosition |
| 498 : computedXPosition; | 614 : computedXPosition; |
| 499 setNoRepeatX(left + xOffset); | 615 setNoRepeatX(left + xOffset); |
| 616 if (offsetInBackground.x() > tileSize().width()) | |
| 617 setDestRect(LayoutRect()); | |
| 500 } | 618 } |
| 501 | 619 |
| 502 if (backgroundRepeatY == RepeatFill) { | 620 if (backgroundRepeatY == RepeatFill) { |
| 503 setRepeatY(fillLayer, fillTileSize.height(), availableHeight, | 621 setRepeatY(fillLayer, fillTileSize.height(), availableHeight, |
| 504 unsnappedAvailableHeight, top); | 622 unsnappedAvailableHeight, top, offsetInBackground.y()); |
| 505 } else if (backgroundRepeatY == SpaceFill && | 623 } else if (backgroundRepeatY == SpaceFill && |
| 506 tileSize().height() > LayoutUnit()) { | 624 tileSize().height() > LayoutUnit()) { |
| 507 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), | 625 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), |
| 508 tileSize().height()); | 626 tileSize().height()); |
| 509 if (space >= LayoutUnit()) | 627 if (space >= LayoutUnit()) |
| 510 setSpaceY(space, availableHeight, top); | 628 setSpaceY(space, availableHeight, top); |
| 511 else | 629 else |
| 512 backgroundRepeatY = NoRepeatFill; | 630 backgroundRepeatY = NoRepeatFill; |
| 513 } | 631 } |
| 514 if (backgroundRepeatY == NoRepeatFill) { | 632 if (backgroundRepeatY == NoRepeatFill) { |
| 515 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge | 633 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge |
| 516 ? availableHeight - computedYPosition | 634 ? availableHeight - computedYPosition |
| 517 : computedYPosition; | 635 : computedYPosition; |
| 518 setNoRepeatY(top + yOffset); | 636 setNoRepeatY(top + yOffset); |
| 637 if (offsetInBackground.y() > tileSize().height()) | |
| 638 setDestRect(LayoutRect()); | |
| 519 } | 639 } |
| 520 | 640 |
| 521 if (fixedAttachment) | 641 if (fixedAttachment) |
| 522 useFixedAttachment(paintRect.location()); | 642 useFixedAttachment(paintRect.location()); |
| 523 | 643 |
| 524 // Clip the final output rect to the paint rect | 644 // Clip the final output rect to the paint rect |
| 525 m_destRect.intersect(paintRect); | 645 m_destRect.intersect(paintRect); |
| 526 | 646 |
| 527 // Snap as-yet unsnapped values. | 647 // Snap as-yet unsnapped values. |
| 528 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); | 648 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); |
| 529 } | 649 } |
| 530 | 650 |
| 531 } // namespace blink | 651 } // namespace blink |
| OLD | NEW |