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

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,
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
337 437 ? static_cast<const LayoutBoxModelObject&>(*rootBox)
438 : cellUsingContainerBackground
439 ? static_cast<const LayoutBoxModelObject&>(*backgroundObject)
440 : obj;
Xianzhu 2017/01/17 18:21:19 I found why toLayoutBoxModelObject for the first o
441 LayoutPoint offsetInBackground =
442 cellUsingContainerBackground
443 ? getOffsetForCell(toLayoutTableCell(obj),
444 toLayoutBox(positioningBox))
445 : LayoutPoint();
338 // Determine the background positioning area and set destRect to the 446 // Determine the background positioning area and set destRect to the
339 // background painting area. destRect will be adjusted later if the 447 // background painting area. destRect will be adjusted later if the
340 // background is non-repeating. 448 // background is non-repeating.
341 // FIXME: transforms spec says that fixed backgrounds behave like scroll 449 // FIXME: transforms spec says that fixed backgrounds behave like scroll
342 // inside transforms. 450 // inside transforms.
343 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; 451 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment;
344 452
345 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { 453 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
346 // As a side effect of an optimization to blit on scroll, we do not honor 454 // 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 455 // the CSS property "background-attachment: fixed" because it may result in
(...skipping 20 matching lines...) Expand all
368 bottom += positioningBox.paddingBottom(); 476 bottom += positioningBox.paddingBottom();
369 } 477 }
370 } 478 }
371 479
372 if (isLayoutView) { 480 if (isLayoutView) {
373 // The background of the box generated by the root element covers the 481 // 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 482 // entire canvas and will be painted by the view object, but the we should
375 // still use the root element box for positioning. 483 // still use the root element box for positioning.
376 positioningAreaSize = 484 positioningAreaSize =
377 rootBox->size() - LayoutSize(left + right, top + bottom), 485 rootBox->size() - LayoutSize(left + right, top + bottom),
378 rootBox->location(); 486 rootBox->location();
Xianzhu 2017/01/17 18:21:19 Not your fault, can you fix the above two lines?
379 // The input paint rect is specified in root element local coordinate 487 // 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 488 // (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 489 // expanded to cover the whole canvas. Since left/top is relative to the
382 // paint rect, we need to offset them back. 490 // paint rect, we need to offset them back.
383 left -= paintRect.x(); 491 left -= paintRect.x();
384 top -= paintRect.y(); 492 top -= paintRect.y();
385 } else { 493 } else {
386 positioningAreaSize = 494 positioningAreaSize =
387 paintRect.size() - LayoutSize(left + right, top + bottom); 495 (cellUsingContainerBackground
496 ? getBackgroundObjectDimensions(toLayoutTableCell(obj),
497 toLayoutBox(positioningBox))
498 : paintRect.size()) -
499 LayoutSize(left + right, top + bottom);
388 } 500 }
389 } else { 501 } else {
390 setHasNonLocalGeometry(); 502 setHasNonLocalGeometry();
391 503
392 LayoutRect viewportRect = obj.viewRect(); 504 LayoutRect viewportRect = obj.viewRect();
393 if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { 505 if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) {
394 viewportRect.setLocation(LayoutPoint()); 506 viewportRect.setLocation(LayoutPoint());
395 } else { 507 } else {
396 if (FrameView* frameView = obj.view()->frameView()) 508 if (FrameView* frameView = obj.view()->frameView())
397 viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); 509 viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt()));
(...skipping 25 matching lines...) Expand all
423 LayoutUnit unsnappedAvailableHeight = 535 LayoutUnit unsnappedAvailableHeight =
424 positioningAreaSize.height() - fillTileSize.height(); 536 positioningAreaSize.height() - fillTileSize.height();
425 positioningAreaSize = 537 positioningAreaSize =
426 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), 538 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()),
427 snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); 539 snapSizeToPixel(positioningAreaSize.height(), m_destRect.y()));
428 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); 540 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width();
429 LayoutUnit availableHeight = 541 LayoutUnit availableHeight =
430 positioningAreaSize.height() - tileSize().height(); 542 positioningAreaSize.height() - tileSize().height();
431 543
432 LayoutUnit computedXPosition = 544 LayoutUnit computedXPosition =
433 roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth); 545 roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth) -
546 offsetInBackground.x();
434 if (backgroundRepeatX == RoundFill && 547 if (backgroundRepeatX == RoundFill &&
435 positioningAreaSize.width() > LayoutUnit() && 548 positioningAreaSize.width() > LayoutUnit() &&
436 fillTileSize.width() > LayoutUnit()) { 549 fillTileSize.width() > LayoutUnit()) {
437 int nrTiles = std::max( 550 int nrTiles = std::max(
438 1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); 551 1, roundToInt(positioningAreaSize.width() / fillTileSize.width()));
439 LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; 552 LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles;
440 553
441 // Maintain aspect ratio if background-size: auto is set 554 // Maintain aspect ratio if background-size: auto is set
442 if (fillLayer.size().size.height().isAuto() && 555 if (fillLayer.size().size.height().isAuto() &&
443 backgroundRepeatY != RoundFill) { 556 backgroundRepeatY != RoundFill) {
444 fillTileSize.setHeight(fillTileSize.height() * roundedWidth / 557 fillTileSize.setHeight(fillTileSize.height() * roundedWidth /
445 fillTileSize.width()); 558 fillTileSize.width());
446 } 559 }
447 fillTileSize.setWidth(roundedWidth); 560 fillTileSize.setWidth(roundedWidth);
448 561
449 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); 562 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect));
450 setPhaseX(tileSize().width() 563 setPhaseX(tileSize().width()
451 ? LayoutUnit(roundf( 564 ? LayoutUnit(roundf(
452 tileSize().width() - 565 tileSize().width() -
453 fmodf((computedXPosition + left), tileSize().width()))) 566 fmodf((computedXPosition + left), tileSize().width())))
454 : LayoutUnit()); 567 : LayoutUnit());
455 setSpaceSize(LayoutSize()); 568 setSpaceSize(LayoutSize());
456 } 569 }
457 570
458 LayoutUnit computedYPosition = 571 LayoutUnit computedYPosition =
459 roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight); 572 roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight) -
573 offsetInBackground.y();
460 if (backgroundRepeatY == RoundFill && 574 if (backgroundRepeatY == RoundFill &&
461 positioningAreaSize.height() > LayoutUnit() && 575 positioningAreaSize.height() > LayoutUnit() &&
462 fillTileSize.height() > LayoutUnit()) { 576 fillTileSize.height() > LayoutUnit()) {
463 int nrTiles = std::max( 577 int nrTiles = std::max(
464 1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); 578 1, roundToInt(positioningAreaSize.height() / fillTileSize.height()));
465 LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; 579 LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles;
466 // Maintain aspect ratio if background-size: auto is set 580 // Maintain aspect ratio if background-size: auto is set
467 if (fillLayer.size().size.width().isAuto() && 581 if (fillLayer.size().size.width().isAuto() &&
468 backgroundRepeatX != RoundFill) { 582 backgroundRepeatX != RoundFill) {
469 fillTileSize.setWidth(fillTileSize.width() * roundedHeight / 583 fillTileSize.setWidth(fillTileSize.width() * roundedHeight /
470 fillTileSize.height()); 584 fillTileSize.height());
471 } 585 }
472 fillTileSize.setHeight(roundedHeight); 586 fillTileSize.setHeight(roundedHeight);
473 587
474 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); 588 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect));
475 setPhaseY(tileSize().height() 589 setPhaseY(tileSize().height()
476 ? LayoutUnit(roundf( 590 ? LayoutUnit(roundf(
477 tileSize().height() - 591 tileSize().height() -
478 fmodf((computedYPosition + top), tileSize().height()))) 592 fmodf((computedYPosition + top), tileSize().height())))
479 : LayoutUnit()); 593 : LayoutUnit());
480 setSpaceSize(LayoutSize()); 594 setSpaceSize(LayoutSize());
481 } 595 }
482 596
483 if (backgroundRepeatX == RepeatFill) { 597 if (backgroundRepeatX == RepeatFill) {
484 setRepeatX(fillLayer, fillTileSize.width(), availableWidth, 598 setRepeatX(fillLayer, fillTileSize.width(), availableWidth,
485 unsnappedAvailableWidth, left); 599 unsnappedAvailableWidth, left, offsetInBackground.x());
486 } else if (backgroundRepeatX == SpaceFill && 600 } else if (backgroundRepeatX == SpaceFill &&
487 tileSize().width() > LayoutUnit()) { 601 tileSize().width() > LayoutUnit()) {
488 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), 602 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(),
489 tileSize().width()); 603 tileSize().width());
490 if (space >= LayoutUnit()) 604 if (space >= LayoutUnit())
491 setSpaceX(space, availableWidth, left); 605 setSpaceX(space, availableWidth, left);
492 else 606 else
493 backgroundRepeatX = NoRepeatFill; 607 backgroundRepeatX = NoRepeatFill;
494 } 608 }
495 if (backgroundRepeatX == NoRepeatFill) { 609 if (backgroundRepeatX == NoRepeatFill) {
496 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge 610 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge
497 ? availableWidth - computedXPosition 611 ? availableWidth - computedXPosition
498 : computedXPosition; 612 : computedXPosition;
499 setNoRepeatX(left + xOffset); 613 setNoRepeatX(left + xOffset);
614 if (offsetInBackground.x() > tileSize().width())
615 setDestRect(LayoutRect());
500 } 616 }
501 617
502 if (backgroundRepeatY == RepeatFill) { 618 if (backgroundRepeatY == RepeatFill) {
503 setRepeatY(fillLayer, fillTileSize.height(), availableHeight, 619 setRepeatY(fillLayer, fillTileSize.height(), availableHeight,
504 unsnappedAvailableHeight, top); 620 unsnappedAvailableHeight, top, offsetInBackground.y());
505 } else if (backgroundRepeatY == SpaceFill && 621 } else if (backgroundRepeatY == SpaceFill &&
506 tileSize().height() > LayoutUnit()) { 622 tileSize().height() > LayoutUnit()) {
507 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), 623 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(),
508 tileSize().height()); 624 tileSize().height());
509 if (space >= LayoutUnit()) 625 if (space >= LayoutUnit())
510 setSpaceY(space, availableHeight, top); 626 setSpaceY(space, availableHeight, top);
511 else 627 else
512 backgroundRepeatY = NoRepeatFill; 628 backgroundRepeatY = NoRepeatFill;
513 } 629 }
514 if (backgroundRepeatY == NoRepeatFill) { 630 if (backgroundRepeatY == NoRepeatFill) {
515 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge 631 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge
516 ? availableHeight - computedYPosition 632 ? availableHeight - computedYPosition
517 : computedYPosition; 633 : computedYPosition;
518 setNoRepeatY(top + yOffset); 634 setNoRepeatY(top + yOffset);
635 if (offsetInBackground.y() > tileSize().height())
636 setDestRect(LayoutRect());
519 } 637 }
520 638
521 if (fixedAttachment) 639 if (fixedAttachment)
522 useFixedAttachment(paintRect.location()); 640 useFixedAttachment(paintRect.location());
523 641
524 // Clip the final output rect to the paint rect 642 // Clip the final output rect to the paint rect
525 m_destRect.intersect(paintRect); 643 m_destRect.intersect(paintRect);
526 644
527 // Snap as-yet unsnapped values. 645 // Snap as-yet unsnapped values.
528 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); 646 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect)));
529 } 647 }
530 648
531 } // namespace blink 649 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/BackgroundImageGeometry.h ('k') | third_party/WebKit/Source/core/paint/BoxPainter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698