Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp

Issue 2600903002: Paint the whole of a table-part background image behind the cells in a table (Closed)
Patch Set: Paint the whole of an image behind the cells in a table Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698