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

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 ? *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
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
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
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