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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
diff --git a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
index 47910c1ad54de667a3421a97a92af6158a3d3f0c..e4e53fff0e8652e4db32a32d6eaf8ad22b5ca79d 100644
--- a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
+++ b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
@@ -7,6 +7,8 @@
#include "core/frame/FrameView.h"
#include "core/layout/LayoutBox.h"
#include "core/layout/LayoutBoxModelObject.h"
+#include "core/layout/LayoutTableCell.h"
+#include "core/layout/LayoutTableCol.h"
#include "core/layout/LayoutView.h"
#include "core/layout/compositing/CompositedLayerMapping.h"
#include "core/paint/PaintLayer.h"
@@ -213,13 +215,16 @@ void BackgroundImageGeometry::setRepeatX(const FillLayer& fillLayer,
LayoutUnit unsnappedTileWidth,
LayoutUnit snappedAvailableWidth,
LayoutUnit unsnappedAvailableWidth,
- LayoutUnit extraOffset) {
+ LayoutUnit extraOffset,
+ LayoutUnit offsetForCell) {
// We would like to identify the phase as a fraction of the image size in the
// absence of snapping, then re-apply it to the snapped values. This is to
// handle large positions.
if (unsnappedTileWidth) {
- LayoutUnit computedXPosition = roundedMinimumValueForLength(
- fillLayer.xPosition(), unsnappedAvailableWidth);
+ LayoutUnit computedXPosition =
+ roundedMinimumValueForLength(fillLayer.xPosition(),
+ unsnappedAvailableWidth) -
+ offsetForCell;
if (fillLayer.backgroundXOrigin() == RightEdge) {
float numberOfTilesInPosition =
(snappedAvailableWidth - computedXPosition + extraOffset).toFloat() /
@@ -247,13 +252,16 @@ void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer,
LayoutUnit unsnappedTileHeight,
LayoutUnit snappedAvailableHeight,
LayoutUnit unsnappedAvailableHeight,
- LayoutUnit extraOffset) {
+ LayoutUnit extraOffset,
+ LayoutUnit offsetForCell) {
// We would like to identify the phase as a fraction of the image size in the
// absence of snapping, then re-apply it to the snapped values. This is to
// handle large positions.
if (unsnappedTileHeight) {
- LayoutUnit computedYPosition = roundedMinimumValueForLength(
- fillLayer.yPosition(), unsnappedAvailableHeight);
+ LayoutUnit computedYPosition =
+ roundedMinimumValueForLength(fillLayer.yPosition(),
+ unsnappedAvailableHeight) -
+ offsetForCell;
if (fillLayer.backgroundYOrigin() == BottomEdge) {
float numberOfTilesInPosition =
(snappedAvailableHeight - computedYPosition + extraOffset).toFloat() /
@@ -313,8 +321,97 @@ void BackgroundImageGeometry::useFixedAttachment(
setPhase(LayoutPoint(roundedIntPoint(m_phase)));
}
+enum ColumnGroupDirection { ColumnGroupStart, ColumnGroupEnd };
+
+static void expandToTableColumnGroup(const LayoutTableCell& cell,
+ const LayoutTableCol& columnGroup,
+ LayoutUnit& value,
+ ColumnGroupDirection columnDirection) {
+ auto siblingCell = columnDirection == ColumnGroupStart
+ ? &LayoutTableCell::previousCell
+ : &LayoutTableCell::nextCell;
+ for (const auto* sibling = (cell.*siblingCell)(); sibling;
+ sibling = (sibling->*siblingCell)()) {
+ if (cell.table()
+ ->colElementAtAbsoluteColumn(sibling->absoluteColumnIndex())
+ .innermostColOrColGroup()
+ ->enclosingColumnGroup() != columnGroup)
+ break;
+ value += sibling->size().width();
+ }
+}
+
+LayoutPoint BackgroundImageGeometry::getOffsetForCell(
+ const LayoutTableCell& cell,
+ const LayoutBox& positioningBox) {
+ LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(),
+ cell.table()->vBorderSpacing());
+ if (positioningBox.isTableSection())
+ return cell.location() - borderSpacing;
+ if (positioningBox.isTableRow()) {
+ return LayoutPoint(cell.location().x(), LayoutUnit()) -
+ LayoutSize(borderSpacing.width(), LayoutUnit());
+ }
+
+ LayoutRect sectionsRect(LayoutPoint(), cell.table()->size());
+ cell.table()->subtractCaptionRect(sectionsRect);
+ LayoutUnit heightOfCaptions =
+ cell.table()->size().height() - sectionsRect.height();
+ LayoutPoint offsetInBackground = LayoutPoint(
+ LayoutUnit(), (cell.section()->location().y() -
+ cell.table()->borderBefore() - heightOfCaptions) +
+ cell.location().y());
+
+ DCHECK(positioningBox.isLayoutTableCol());
+ if (toLayoutTableCol(positioningBox).isTableColumn()) {
+ return offsetInBackground -
+ LayoutSize(LayoutUnit(), borderSpacing.height());
+ }
+
+ DCHECK(toLayoutTableCol(positioningBox).isTableColumnGroup());
+ LayoutUnit offset = offsetInBackground.x();
+ expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), offset,
+ ColumnGroupStart);
+ offsetInBackground.move(offset, LayoutUnit());
+ return offsetInBackground - LayoutSize(LayoutUnit(), borderSpacing.height());
+}
+
+LayoutSize BackgroundImageGeometry::getBackgroundObjectDimensions(
+ const LayoutTableCell& cell,
+ const LayoutBox& positioningBox) {
+ LayoutSize borderSpacing = LayoutSize(cell.table()->hBorderSpacing(),
+ cell.table()->vBorderSpacing());
+ if (positioningBox.isTableSection())
+ return positioningBox.size() - borderSpacing - borderSpacing;
+
+ if (positioningBox.isTableRow()) {
+ return positioningBox.size() -
+ LayoutSize(borderSpacing.width(), LayoutUnit()) -
+ LayoutSize(borderSpacing.width(), LayoutUnit());
+ }
+
+ DCHECK(positioningBox.isLayoutTableCol());
+ LayoutRect sectionsRect(LayoutPoint(), cell.table()->size());
+ cell.table()->subtractCaptionRect(sectionsRect);
+ LayoutUnit columnHeight = sectionsRect.height() -
+ cell.table()->borderBefore() -
+ borderSpacing.height() - borderSpacing.height();
+ if (toLayoutTableCol(positioningBox).isTableColumn())
+ return LayoutSize(cell.size().width(), columnHeight);
+
+ DCHECK(toLayoutTableCol(positioningBox).isTableColumnGroup());
+ LayoutUnit width = cell.size().width();
+ expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), width,
+ ColumnGroupStart);
+ expandToTableColumnGroup(cell, toLayoutTableCol(positioningBox), width,
+ ColumnGroupEnd);
+
+ return LayoutSize(width, columnHeight);
+}
+
void BackgroundImageGeometry::calculate(
const LayoutBoxModelObject& obj,
+ const LayoutObject* backgroundObject,
const LayoutBoxModelObject* paintContainer,
const GlobalPaintFlags globalPaintFlags,
const FillLayer& fillLayer,
@@ -332,9 +429,19 @@ void BackgroundImageGeometry::calculate(
DCHECK(documentElement->layoutObject()->isBox());
rootBox = toLayoutBox(documentElement->layoutObject());
}
- const LayoutBoxModelObject& positioningBox =
- isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj;
+ bool cellUsingContainerBackground =
+ obj.isTableCell() && backgroundObject && !backgroundObject->isTableCell();
+ const LayoutBoxModelObject& positioningBox =
+ isLayoutView ? *rootBox
+ : cellUsingContainerBackground
+ ? toLayoutBoxModelObject(*backgroundObject)
+ : obj;
+ LayoutPoint offsetInBackground =
+ cellUsingContainerBackground
+ ? getOffsetForCell(toLayoutTableCell(obj),
+ toLayoutBox(positioningBox))
+ : LayoutPoint();
// Determine the background positioning area and set destRect to the
// background painting area. destRect will be adjusted later if the
// background is non-repeating.
@@ -374,8 +481,7 @@ void BackgroundImageGeometry::calculate(
// entire canvas and will be painted by the view object, but the we should
// still use the root element box for positioning.
positioningAreaSize =
- rootBox->size() - LayoutSize(left + right, top + bottom),
- rootBox->location();
+ rootBox->size() - LayoutSize(left + right, top + bottom);
// The input paint rect is specified in root element local coordinate
// (i.e. a transform is applied on the context for painting), and is
// expanded to cover the whole canvas. Since left/top is relative to the
@@ -384,7 +490,11 @@ void BackgroundImageGeometry::calculate(
top -= paintRect.y();
} else {
positioningAreaSize =
- paintRect.size() - LayoutSize(left + right, top + bottom);
+ (cellUsingContainerBackground
+ ? getBackgroundObjectDimensions(toLayoutTableCell(obj),
+ toLayoutBox(positioningBox))
+ : paintRect.size()) -
+ LayoutSize(left + right, top + bottom);
}
} else {
setHasNonLocalGeometry();
@@ -430,7 +540,8 @@ void BackgroundImageGeometry::calculate(
positioningAreaSize.height() - tileSize().height();
LayoutUnit computedXPosition =
- roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth);
+ roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth) -
+ offsetInBackground.x();
if (backgroundRepeatX == RoundFill &&
positioningAreaSize.width() > LayoutUnit() &&
fillTileSize.width() > LayoutUnit()) {
@@ -456,7 +567,8 @@ void BackgroundImageGeometry::calculate(
}
LayoutUnit computedYPosition =
- roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight);
+ roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight) -
+ offsetInBackground.y();
if (backgroundRepeatY == RoundFill &&
positioningAreaSize.height() > LayoutUnit() &&
fillTileSize.height() > LayoutUnit()) {
@@ -482,7 +594,7 @@ void BackgroundImageGeometry::calculate(
if (backgroundRepeatX == RepeatFill) {
setRepeatX(fillLayer, fillTileSize.width(), availableWidth,
- unsnappedAvailableWidth, left);
+ unsnappedAvailableWidth, left, offsetInBackground.x());
} else if (backgroundRepeatX == SpaceFill &&
tileSize().width() > LayoutUnit()) {
LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(),
@@ -497,11 +609,13 @@ void BackgroundImageGeometry::calculate(
? availableWidth - computedXPosition
: computedXPosition;
setNoRepeatX(left + xOffset);
+ if (offsetInBackground.x() > tileSize().width())
+ setDestRect(LayoutRect());
}
if (backgroundRepeatY == RepeatFill) {
setRepeatY(fillLayer, fillTileSize.height(), availableHeight,
- unsnappedAvailableHeight, top);
+ unsnappedAvailableHeight, top, offsetInBackground.y());
} else if (backgroundRepeatY == SpaceFill &&
tileSize().height() > LayoutUnit()) {
LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(),
@@ -516,6 +630,8 @@ void BackgroundImageGeometry::calculate(
? availableHeight - computedYPosition
: computedYPosition;
setNoRepeatY(top + yOffset);
+ if (offsetInBackground.y() > tileSize().height())
+ setDestRect(LayoutRect());
}
if (fixedAttachment)
« 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