| 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, | 
|  | 327                                      const LayoutTableCol& columnGroup, | 
|  | 328                                      LayoutUnit& value, | 
|  | 329                                      ColumnGroupDirection columnDirection) { | 
|  | 330   auto siblingCell = columnDirection == ColumnGroupStart | 
|  | 331                          ? &LayoutTableCell::previousCell | 
|  | 332                          : &LayoutTableCell::nextCell; | 
|  | 333   for (const auto* sibling = (cell.*siblingCell)(); sibling; | 
|  | 334        sibling = (sibling->*siblingCell)()) { | 
|  | 335     if (cell.table() | 
|  | 336             ->colElementAtAbsoluteColumn(sibling->absoluteColumnIndex()) | 
|  | 337             .innermostColOrColGroup() | 
|  | 338             ->enclosingColumnGroup() != columnGroup) | 
|  | 339       break; | 
|  | 340     value += sibling->size().width(); | 
|  | 341   } | 
|  | 342 } | 
|  | 343 | 
|  | 344 LayoutPoint BackgroundImageGeometry::getOffsetForCell( | 
|  | 345     const LayoutTableCell& cell, | 
|  | 346     const LayoutBox& positioningBox) { | 
|  | 347   LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(), | 
|  | 348                                         cell.table()->vBorderSpacing()); | 
|  | 349   if (positioningBox.isTableSection()) | 
|  | 350     return cell.location() - borderSpacing; | 
|  | 351   if (positioningBox.isTableRow()) { | 
|  | 352     return LayoutPoint(cell.location().x(), LayoutUnit()) - | 
|  | 353            LayoutSize(borderSpacing.width(), LayoutUnit()); | 
|  | 354   } | 
|  | 355 | 
|  | 356   LayoutRect sectionsRect(LayoutPoint(), cell.table()->size()); | 
|  | 357   cell.table()->subtractCaptionRect(sectionsRect); | 
|  | 358   LayoutUnit heightOfCaptions = | 
|  | 359       cell.table()->size().height() - sectionsRect.height(); | 
|  | 360   LayoutPoint offsetInBackground = LayoutPoint( | 
|  | 361       LayoutUnit(), (cell.section()->location().y() - | 
|  | 362                      cell.table()->borderBefore() - heightOfCaptions) + | 
|  | 363                         cell.location().y()); | 
|  | 364 | 
|  | 365   DCHECK(positioningBox.isLayoutTableCol()); | 
|  | 366   if (toLayoutTableCol(positioningBox).isTableColumn()) { | 
|  | 367     return offsetInBackground - | 
|  | 368            LayoutSize(LayoutUnit(), borderSpacing.height()); | 
|  | 369   } | 
|  | 370 | 
|  | 371   DCHECK(toLayoutTableCol(positioningBox).isTableColumnGroup()); | 
|  | 372   LayoutUnit offset = offsetInBackground.x(); | 
|  | 373   expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), offset, | 
|  | 374                            ColumnGroupStart); | 
|  | 375   offsetInBackground.move(offset, LayoutUnit()); | 
|  | 376   return offsetInBackground - LayoutSize(LayoutUnit(), borderSpacing.height()); | 
|  | 377 } | 
|  | 378 | 
|  | 379 LayoutSize BackgroundImageGeometry::getBackgroundObjectDimensions( | 
|  | 380     const LayoutTableCell& cell, | 
|  | 381     const LayoutBox& positioningBox) { | 
|  | 382   LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(), | 
|  | 383                                         cell.table()->vBorderSpacing()); | 
|  | 384   if (positioningBox.isTableSection()) | 
|  | 385     return positioningBox.size() - borderSpacing - borderSpacing; | 
|  | 386 | 
|  | 387   if (positioningBox.isTableRow()) { | 
|  | 388     return positioningBox.size() - | 
|  | 389            LayoutSize(borderSpacing.width(), LayoutUnit()) - | 
|  | 390            LayoutSize(borderSpacing.width(), LayoutUnit()); | 
|  | 391   } | 
|  | 392 | 
|  | 393   DCHECK(positioningBox.isLayoutTableCol()); | 
|  | 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 (toLayoutTableCol(positioningBox).isTableColumn()) | 
|  | 400     return LayoutSize(cell.size().width(), columnHeight); | 
|  | 401 | 
|  | 402   DCHECK(toLayoutTableCol(positioningBox).isTableColumnGroup()); | 
|  | 403   LayoutUnit width = cell.size().width(); | 
|  | 404   expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), width, | 
|  | 405                            ColumnGroupStart); | 
|  | 406   expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), width, | 
|  | 407                            ColumnGroupEnd); | 
|  | 408 | 
|  | 409   return LayoutSize(width, columnHeight); | 
|  | 410 } | 
|  | 411 | 
| 316 void BackgroundImageGeometry::calculate( | 412 void BackgroundImageGeometry::calculate( | 
| 317     const LayoutBoxModelObject& obj, | 413     const LayoutBoxModelObject& obj, | 
|  | 414     const LayoutObject* backgroundObject, | 
| 318     const LayoutBoxModelObject* paintContainer, | 415     const LayoutBoxModelObject* paintContainer, | 
| 319     const GlobalPaintFlags globalPaintFlags, | 416     const GlobalPaintFlags globalPaintFlags, | 
| 320     const FillLayer& fillLayer, | 417     const FillLayer& fillLayer, | 
| 321     const LayoutRect& paintRect) { | 418     const LayoutRect& paintRect) { | 
| 322   LayoutUnit left; | 419   LayoutUnit left; | 
| 323   LayoutUnit top; | 420   LayoutUnit top; | 
| 324   LayoutSize positioningAreaSize; | 421   LayoutSize positioningAreaSize; | 
| 325   bool isLayoutView = obj.isLayoutView(); | 422   bool isLayoutView = obj.isLayoutView(); | 
| 326   const LayoutBox* rootBox = nullptr; | 423   const LayoutBox* rootBox = nullptr; | 
| 327   if (isLayoutView) { | 424   if (isLayoutView) { | 
| 328     // It is only possible reach here when root element has a box. | 425     // It is only possible reach here when root element has a box. | 
| 329     Element* documentElement = obj.document().documentElement(); | 426     Element* documentElement = obj.document().documentElement(); | 
| 330     DCHECK(documentElement); | 427     DCHECK(documentElement); | 
| 331     DCHECK(documentElement->layoutObject()); | 428     DCHECK(documentElement->layoutObject()); | 
| 332     DCHECK(documentElement->layoutObject()->isBox()); | 429     DCHECK(documentElement->layoutObject()->isBox()); | 
| 333     rootBox = toLayoutBox(documentElement->layoutObject()); | 430     rootBox = toLayoutBox(documentElement->layoutObject()); | 
| 334   } | 431   } | 
|  | 432 | 
|  | 433   bool cellUsingContainerBackground = | 
|  | 434       obj.isTableCell() && backgroundObject && !backgroundObject->isTableCell(); | 
| 335   const LayoutBoxModelObject& positioningBox = | 435   const LayoutBoxModelObject& positioningBox = | 
| 336       isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj; | 436       isLayoutView ? *rootBox | 
| 337 | 437                    : cellUsingContainerBackground | 
|  | 438                          ? toLayoutBoxModelObject(*backgroundObject) | 
|  | 439                          : obj; | 
|  | 440   LayoutPoint offsetInBackground = | 
|  | 441       cellUsingContainerBackground | 
|  | 442           ? getOffsetForCell(toLayoutTableCell(obj), | 
|  | 443                              toLayoutBox(positioningBox)) | 
|  | 444           : LayoutPoint(); | 
| 338   // Determine the background positioning area and set destRect to the | 445   // Determine the background positioning area and set destRect to the | 
| 339   // background painting area.  destRect will be adjusted later if the | 446   // background painting area.  destRect will be adjusted later if the | 
| 340   // background is non-repeating. | 447   // background is non-repeating. | 
| 341   // FIXME: transforms spec says that fixed backgrounds behave like scroll | 448   // FIXME: transforms spec says that fixed backgrounds behave like scroll | 
| 342   // inside transforms. | 449   // inside transforms. | 
| 343   bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; | 450   bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; | 
| 344 | 451 | 
| 345   if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { | 452   if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { | 
| 346     // As a side effect of an optimization to blit on scroll, we do not honor | 453     // 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 | 454     // the CSS property "background-attachment: fixed" because it may result in | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 367         top += positioningBox.paddingTop(); | 474         top += positioningBox.paddingTop(); | 
| 368         bottom += positioningBox.paddingBottom(); | 475         bottom += positioningBox.paddingBottom(); | 
| 369       } | 476       } | 
| 370     } | 477     } | 
| 371 | 478 | 
| 372     if (isLayoutView) { | 479     if (isLayoutView) { | 
| 373       // The background of the box generated by the root element covers the | 480       // The background of the box generated by the root element covers the | 
| 374       // entire canvas and will be painted by the view object, but the we should | 481       // entire canvas and will be painted by the view object, but the we should | 
| 375       // still use the root element box for positioning. | 482       // still use the root element box for positioning. | 
| 376       positioningAreaSize = | 483       positioningAreaSize = | 
| 377           rootBox->size() - LayoutSize(left + right, top + bottom), | 484           rootBox->size() - LayoutSize(left + right, top + bottom); | 
| 378       rootBox->location(); |  | 
| 379       // The input paint rect is specified in root element local coordinate | 485       // 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 | 486       // (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 | 487       // expanded to cover the whole canvas.  Since left/top is relative to the | 
| 382       // paint rect, we need to offset them back. | 488       // paint rect, we need to offset them back. | 
| 383       left -= paintRect.x(); | 489       left -= paintRect.x(); | 
| 384       top -= paintRect.y(); | 490       top -= paintRect.y(); | 
| 385     } else { | 491     } else { | 
| 386       positioningAreaSize = | 492       positioningAreaSize = | 
| 387           paintRect.size() - LayoutSize(left + right, top + bottom); | 493           (cellUsingContainerBackground | 
|  | 494                ? getBackgroundObjectDimensions(toLayoutTableCell(obj), | 
|  | 495                                                toLayoutBox(positioningBox)) | 
|  | 496                : paintRect.size()) - | 
|  | 497           LayoutSize(left + right, top + bottom); | 
| 388     } | 498     } | 
| 389   } else { | 499   } else { | 
| 390     setHasNonLocalGeometry(); | 500     setHasNonLocalGeometry(); | 
| 391 | 501 | 
| 392     LayoutRect viewportRect = obj.viewRect(); | 502     LayoutRect viewportRect = obj.viewRect(); | 
| 393     if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { | 503     if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { | 
| 394       viewportRect.setLocation(LayoutPoint()); | 504       viewportRect.setLocation(LayoutPoint()); | 
| 395     } else { | 505     } else { | 
| 396       if (FrameView* frameView = obj.view()->frameView()) | 506       if (FrameView* frameView = obj.view()->frameView()) | 
| 397         viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); | 507         viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 423   LayoutUnit unsnappedAvailableHeight = | 533   LayoutUnit unsnappedAvailableHeight = | 
| 424       positioningAreaSize.height() - fillTileSize.height(); | 534       positioningAreaSize.height() - fillTileSize.height(); | 
| 425   positioningAreaSize = | 535   positioningAreaSize = | 
| 426       LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), | 536       LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), | 
| 427                  snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); | 537                  snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); | 
| 428   LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); | 538   LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); | 
| 429   LayoutUnit availableHeight = | 539   LayoutUnit availableHeight = | 
| 430       positioningAreaSize.height() - tileSize().height(); | 540       positioningAreaSize.height() - tileSize().height(); | 
| 431 | 541 | 
| 432   LayoutUnit computedXPosition = | 542   LayoutUnit computedXPosition = | 
| 433       roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth); | 543       roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth) - | 
|  | 544       offsetInBackground.x(); | 
| 434   if (backgroundRepeatX == RoundFill && | 545   if (backgroundRepeatX == RoundFill && | 
| 435       positioningAreaSize.width() > LayoutUnit() && | 546       positioningAreaSize.width() > LayoutUnit() && | 
| 436       fillTileSize.width() > LayoutUnit()) { | 547       fillTileSize.width() > LayoutUnit()) { | 
| 437     int nrTiles = std::max( | 548     int nrTiles = std::max( | 
| 438         1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); | 549         1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); | 
| 439     LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; | 550     LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; | 
| 440 | 551 | 
| 441     // Maintain aspect ratio if background-size: auto is set | 552     // Maintain aspect ratio if background-size: auto is set | 
| 442     if (fillLayer.size().size.height().isAuto() && | 553     if (fillLayer.size().size.height().isAuto() && | 
| 443         backgroundRepeatY != RoundFill) { | 554         backgroundRepeatY != RoundFill) { | 
| 444       fillTileSize.setHeight(fillTileSize.height() * roundedWidth / | 555       fillTileSize.setHeight(fillTileSize.height() * roundedWidth / | 
| 445                              fillTileSize.width()); | 556                              fillTileSize.width()); | 
| 446     } | 557     } | 
| 447     fillTileSize.setWidth(roundedWidth); | 558     fillTileSize.setWidth(roundedWidth); | 
| 448 | 559 | 
| 449     setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 560     setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 
| 450     setPhaseX(tileSize().width() | 561     setPhaseX(tileSize().width() | 
| 451                   ? LayoutUnit(roundf( | 562                   ? LayoutUnit(roundf( | 
| 452                         tileSize().width() - | 563                         tileSize().width() - | 
| 453                         fmodf((computedXPosition + left), tileSize().width()))) | 564                         fmodf((computedXPosition + left), tileSize().width()))) | 
| 454                   : LayoutUnit()); | 565                   : LayoutUnit()); | 
| 455     setSpaceSize(LayoutSize()); | 566     setSpaceSize(LayoutSize()); | 
| 456   } | 567   } | 
| 457 | 568 | 
| 458   LayoutUnit computedYPosition = | 569   LayoutUnit computedYPosition = | 
| 459       roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight); | 570       roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight) - | 
|  | 571       offsetInBackground.y(); | 
| 460   if (backgroundRepeatY == RoundFill && | 572   if (backgroundRepeatY == RoundFill && | 
| 461       positioningAreaSize.height() > LayoutUnit() && | 573       positioningAreaSize.height() > LayoutUnit() && | 
| 462       fillTileSize.height() > LayoutUnit()) { | 574       fillTileSize.height() > LayoutUnit()) { | 
| 463     int nrTiles = std::max( | 575     int nrTiles = std::max( | 
| 464         1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); | 576         1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); | 
| 465     LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; | 577     LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; | 
| 466     // Maintain aspect ratio if background-size: auto is set | 578     // Maintain aspect ratio if background-size: auto is set | 
| 467     if (fillLayer.size().size.width().isAuto() && | 579     if (fillLayer.size().size.width().isAuto() && | 
| 468         backgroundRepeatX != RoundFill) { | 580         backgroundRepeatX != RoundFill) { | 
| 469       fillTileSize.setWidth(fillTileSize.width() * roundedHeight / | 581       fillTileSize.setWidth(fillTileSize.width() * roundedHeight / | 
| 470                             fillTileSize.height()); | 582                             fillTileSize.height()); | 
| 471     } | 583     } | 
| 472     fillTileSize.setHeight(roundedHeight); | 584     fillTileSize.setHeight(roundedHeight); | 
| 473 | 585 | 
| 474     setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 586     setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); | 
| 475     setPhaseY(tileSize().height() | 587     setPhaseY(tileSize().height() | 
| 476                   ? LayoutUnit(roundf( | 588                   ? LayoutUnit(roundf( | 
| 477                         tileSize().height() - | 589                         tileSize().height() - | 
| 478                         fmodf((computedYPosition + top), tileSize().height()))) | 590                         fmodf((computedYPosition + top), tileSize().height()))) | 
| 479                   : LayoutUnit()); | 591                   : LayoutUnit()); | 
| 480     setSpaceSize(LayoutSize()); | 592     setSpaceSize(LayoutSize()); | 
| 481   } | 593   } | 
| 482 | 594 | 
| 483   if (backgroundRepeatX == RepeatFill) { | 595   if (backgroundRepeatX == RepeatFill) { | 
| 484     setRepeatX(fillLayer, fillTileSize.width(), availableWidth, | 596     setRepeatX(fillLayer, fillTileSize.width(), availableWidth, | 
| 485                unsnappedAvailableWidth, left); | 597                unsnappedAvailableWidth, left, offsetInBackground.x()); | 
| 486   } else if (backgroundRepeatX == SpaceFill && | 598   } else if (backgroundRepeatX == SpaceFill && | 
| 487              tileSize().width() > LayoutUnit()) { | 599              tileSize().width() > LayoutUnit()) { | 
| 488     LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), | 600     LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), | 
| 489                                                  tileSize().width()); | 601                                                  tileSize().width()); | 
| 490     if (space >= LayoutUnit()) | 602     if (space >= LayoutUnit()) | 
| 491       setSpaceX(space, availableWidth, left); | 603       setSpaceX(space, availableWidth, left); | 
| 492     else | 604     else | 
| 493       backgroundRepeatX = NoRepeatFill; | 605       backgroundRepeatX = NoRepeatFill; | 
| 494   } | 606   } | 
| 495   if (backgroundRepeatX == NoRepeatFill) { | 607   if (backgroundRepeatX == NoRepeatFill) { | 
| 496     LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge | 608     LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge | 
| 497                              ? availableWidth - computedXPosition | 609                              ? availableWidth - computedXPosition | 
| 498                              : computedXPosition; | 610                              : computedXPosition; | 
| 499     setNoRepeatX(left + xOffset); | 611     setNoRepeatX(left + xOffset); | 
|  | 612     if (offsetInBackground.x() > tileSize().width()) | 
|  | 613       setDestRect(LayoutRect()); | 
| 500   } | 614   } | 
| 501 | 615 | 
| 502   if (backgroundRepeatY == RepeatFill) { | 616   if (backgroundRepeatY == RepeatFill) { | 
| 503     setRepeatY(fillLayer, fillTileSize.height(), availableHeight, | 617     setRepeatY(fillLayer, fillTileSize.height(), availableHeight, | 
| 504                unsnappedAvailableHeight, top); | 618                unsnappedAvailableHeight, top, offsetInBackground.y()); | 
| 505   } else if (backgroundRepeatY == SpaceFill && | 619   } else if (backgroundRepeatY == SpaceFill && | 
| 506              tileSize().height() > LayoutUnit()) { | 620              tileSize().height() > LayoutUnit()) { | 
| 507     LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), | 621     LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), | 
| 508                                                  tileSize().height()); | 622                                                  tileSize().height()); | 
| 509     if (space >= LayoutUnit()) | 623     if (space >= LayoutUnit()) | 
| 510       setSpaceY(space, availableHeight, top); | 624       setSpaceY(space, availableHeight, top); | 
| 511     else | 625     else | 
| 512       backgroundRepeatY = NoRepeatFill; | 626       backgroundRepeatY = NoRepeatFill; | 
| 513   } | 627   } | 
| 514   if (backgroundRepeatY == NoRepeatFill) { | 628   if (backgroundRepeatY == NoRepeatFill) { | 
| 515     LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge | 629     LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge | 
| 516                              ? availableHeight - computedYPosition | 630                              ? availableHeight - computedYPosition | 
| 517                              : computedYPosition; | 631                              : computedYPosition; | 
| 518     setNoRepeatY(top + yOffset); | 632     setNoRepeatY(top + yOffset); | 
|  | 633     if (offsetInBackground.y() > tileSize().height()) | 
|  | 634       setDestRect(LayoutRect()); | 
| 519   } | 635   } | 
| 520 | 636 | 
| 521   if (fixedAttachment) | 637   if (fixedAttachment) | 
| 522     useFixedAttachment(paintRect.location()); | 638     useFixedAttachment(paintRect.location()); | 
| 523 | 639 | 
| 524   // Clip the final output rect to the paint rect | 640   // Clip the final output rect to the paint rect | 
| 525   m_destRect.intersect(paintRect); | 641   m_destRect.intersect(paintRect); | 
| 526 | 642 | 
| 527   // Snap as-yet unsnapped values. | 643   // Snap as-yet unsnapped values. | 
| 528   setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); | 644   setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); | 
| 529 } | 645 } | 
| 530 | 646 | 
| 531 }  // namespace blink | 647 }  // namespace blink | 
| OLD | NEW | 
|---|