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

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

Issue 2392443009: reflow comments in core/paint (Closed)
Patch Set: Created 4 years, 2 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/LayoutView.h" 10 #include "core/layout/LayoutView.h"
11 #include "core/layout/compositing/CompositedLayerMapping.h" 11 #include "core/layout/compositing/CompositedLayerMapping.h"
12 #include "core/paint/PaintLayer.h" 12 #include "core/paint/PaintLayer.h"
13 #include "platform/LayoutUnit.h" 13 #include "platform/LayoutUnit.h"
14 #include "platform/geometry/LayoutRect.h" 14 #include "platform/geometry/LayoutRect.h"
15 15
16 namespace blink { 16 namespace blink {
17 17
18 namespace { 18 namespace {
19 19
20 // Return the amount of space to leave between image tiles for the background-re peat: space property. 20 // Return the amount of space to leave between image tiles for the
21 // background-repeat: space property.
21 inline LayoutUnit getSpaceBetweenImageTiles(LayoutUnit areaSize, 22 inline LayoutUnit getSpaceBetweenImageTiles(LayoutUnit areaSize,
22 LayoutUnit tileSize) { 23 LayoutUnit tileSize) {
23 int numberOfTiles = (areaSize / tileSize).toInt(); 24 int numberOfTiles = (areaSize / tileSize).toInt();
24 LayoutUnit space(-1); 25 LayoutUnit space(-1);
25 26
26 if (numberOfTiles > 1) { 27 if (numberOfTiles > 1) {
27 // Spec doesn't specify rounding, so use the same method as for background-r epeat: round. 28 // Spec doesn't specify rounding, so use the same method as for
29 // background-repeat: round.
28 space = (areaSize - numberOfTiles * tileSize) / (numberOfTiles - 1); 30 space = (areaSize - numberOfTiles * tileSize) / (numberOfTiles - 1);
29 } 31 }
30 32
31 return space; 33 return space;
32 } 34 }
33 35
34 bool fixedBackgroundPaintsInLocalCoordinates( 36 bool fixedBackgroundPaintsInLocalCoordinates(
35 const LayoutObject& obj, 37 const LayoutObject& obj,
36 const GlobalPaintFlags globalPaintFlags) { 38 const GlobalPaintFlags globalPaintFlags) {
37 if (!obj.isLayoutView()) 39 if (!obj.isLayoutView())
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 101 }
100 } else if (layerWidth.isAuto() && layerHeight.isAuto()) { 102 } else if (layerWidth.isAuto() && layerHeight.isAuto()) {
101 // If both width and height are auto, use the image's intrinsic size. 103 // If both width and height are auto, use the image's intrinsic size.
102 tileSize = imageIntrinsicSize; 104 tileSize = imageIntrinsicSize;
103 } 105 }
104 106
105 tileSize.clampNegativeToZero(); 107 tileSize.clampNegativeToZero();
106 return tileSize; 108 return tileSize;
107 } 109 }
108 case SizeNone: { 110 case SizeNone: {
109 // If both values are 'auto' then the intrinsic width and/or height of the image should be used, if any. 111 // If both values are 'auto' then the intrinsic width and/or height of the
112 // image should be used, if any.
110 if (!imageIntrinsicSize.isEmpty()) 113 if (!imageIntrinsicSize.isEmpty())
111 return imageIntrinsicSize; 114 return imageIntrinsicSize;
112 115
113 // If the image has neither an intrinsic width nor an intrinsic height, it s size is determined as for 'contain'. 116 // If the image has neither an intrinsic width nor an intrinsic height,
117 // its size is determined as for 'contain'.
114 type = Contain; 118 type = Contain;
115 } 119 }
116 case Contain: 120 case Contain:
117 case Cover: { 121 case Cover: {
118 float horizontalScaleFactor = 122 float horizontalScaleFactor =
119 imageIntrinsicSize.width() 123 imageIntrinsicSize.width()
120 ? positioningAreaSize.width().toFloat() / 124 ? positioningAreaSize.width().toFloat() /
121 imageIntrinsicSize.width() 125 imageIntrinsicSize.width()
122 : 1.0f; 126 : 1.0f;
123 float verticalScaleFactor = imageIntrinsicSize.height() 127 float verticalScaleFactor = imageIntrinsicSize.height()
124 ? positioningAreaSize.height().toFloat() / 128 ? positioningAreaSize.height().toFloat() /
125 imageIntrinsicSize.height() 129 imageIntrinsicSize.height()
126 : 1.0f; 130 : 1.0f;
127 // Force the dimension that determines the size to exactly match the 131 // Force the dimension that determines the size to exactly match the
128 // positioningAreaSize in that dimension, so that rounding of floating poi nt 132 // positioningAreaSize in that dimension, so that rounding of floating
129 // approximation to LayoutUnit do not shrink the image to smaller than the 133 // point approximation to LayoutUnit do not shrink the image to smaller
130 // positioningAreaSize. 134 // than the positioningAreaSize.
131 if (type == Contain) { 135 if (type == Contain) {
132 if (horizontalScaleFactor < verticalScaleFactor) 136 if (horizontalScaleFactor < verticalScaleFactor)
133 return LayoutSize( 137 return LayoutSize(
134 positioningAreaSize.width(), 138 positioningAreaSize.width(),
135 LayoutUnit(std::max( 139 LayoutUnit(std::max(
136 1.0f, imageIntrinsicSize.height() * horizontalScaleFactor))); 140 1.0f, imageIntrinsicSize.height() * horizontalScaleFactor)));
137 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width() * 141 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width() *
138 verticalScaleFactor)), 142 verticalScaleFactor)),
139 positioningAreaSize.height()); 143 positioningAreaSize.height());
140 } 144 }
(...skipping 21 matching lines...) Expand all
162 for (const LayoutBlock* block = object.containingBlock(); block; 166 for (const LayoutBlock* block = object.containingBlock(); block;
163 block = block->containingBlock()) { 167 block = block->containingBlock()) {
164 if (block->hasOverflowClip()) 168 if (block->hasOverflowClip())
165 result += block->scrolledContentOffset(); 169 result += block->scrolledContentOffset();
166 if (block == container) 170 if (block == container)
167 break; 171 break;
168 } 172 }
169 return result; 173 return result;
170 } 174 }
171 175
172 // When we match the sub-pixel fraction of the destination rect in a dimension, we 176 // When we match the sub-pixel fraction of the destination rect in a dimension,
173 // snap the same way. This commonly occurs when the background is meant to fill the 177 // we snap the same way. This commonly occurs when the background is meant to
174 // padding box but there's a border (which in Blink is always stored as an integ er). 178 // fill the padding box but there's a border (which in Blink is always stored as
175 // Otherwise we floor to avoid growing our tile size. Often these tiles are from a 179 // an integer). Otherwise we floor to avoid growing our tile size. Often these
176 // sprite map, and bleeding adjacent sprites is visually worse than clipping the 180 // tiles are from a sprite map, and bleeding adjacent sprites is visually worse
177 // intended one. 181 // than clipping the intended one.
178 LayoutSize applySubPixelHeuristicToImageSize(const LayoutSize& size, 182 LayoutSize applySubPixelHeuristicToImageSize(const LayoutSize& size,
179 const LayoutRect& destination) { 183 const LayoutRect& destination) {
180 LayoutSize snappedSize = 184 LayoutSize snappedSize =
181 LayoutSize(size.width().fraction() == destination.width().fraction() 185 LayoutSize(size.width().fraction() == destination.width().fraction()
182 ? snapSizeToPixel(size.width(), destination.x()) 186 ? snapSizeToPixel(size.width(), destination.x())
183 : size.width().floor(), 187 : size.width().floor(),
184 size.height().fraction() == destination.height().fraction() 188 size.height().fraction() == destination.height().fraction()
185 ? snapSizeToPixel(size.height(), destination.y()) 189 ? snapSizeToPixel(size.height(), destination.y())
186 : size.height().floor()); 190 : size.height().floor());
187 return snappedSize; 191 return snappedSize;
(...skipping 15 matching lines...) Expand all
203 setPhaseY(LayoutUnit(-std::min(roundedOffset, 0))); 207 setPhaseY(LayoutUnit(-std::min(roundedOffset, 0)));
204 m_destRect.setHeight(m_tileSize.height() + std::min(roundedOffset, 0)); 208 m_destRect.setHeight(m_tileSize.height() + std::min(roundedOffset, 0));
205 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit())); 209 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
206 } 210 }
207 211
208 void BackgroundImageGeometry::setRepeatX(const FillLayer& fillLayer, 212 void BackgroundImageGeometry::setRepeatX(const FillLayer& fillLayer,
209 LayoutUnit unsnappedTileWidth, 213 LayoutUnit unsnappedTileWidth,
210 LayoutUnit snappedAvailableWidth, 214 LayoutUnit snappedAvailableWidth,
211 LayoutUnit unsnappedAvailableWidth, 215 LayoutUnit unsnappedAvailableWidth,
212 LayoutUnit extraOffset) { 216 LayoutUnit extraOffset) {
213 // We would like to identify the phase as a fraction of the image size in the absence of snapping, 217 // We would like to identify the phase as a fraction of the image size in the
214 // then re-apply it to the snapped values. This is to handle large positions. 218 // absence of snapping, then re-apply it to the snapped values. This is to
219 // handle large positions.
215 if (unsnappedTileWidth) { 220 if (unsnappedTileWidth) {
216 LayoutUnit computedXPosition = roundedMinimumValueForLength( 221 LayoutUnit computedXPosition = roundedMinimumValueForLength(
217 fillLayer.xPosition(), unsnappedAvailableWidth); 222 fillLayer.xPosition(), unsnappedAvailableWidth);
218 if (fillLayer.backgroundXOrigin() == RightEdge) { 223 if (fillLayer.backgroundXOrigin() == RightEdge) {
219 float numberOfTilesInPosition = 224 float numberOfTilesInPosition =
220 (snappedAvailableWidth - computedXPosition + extraOffset).toFloat() / 225 (snappedAvailableWidth - computedXPosition + extraOffset).toFloat() /
221 unsnappedTileWidth.toFloat(); 226 unsnappedTileWidth.toFloat();
222 float fractionalPositionWithinTile = 227 float fractionalPositionWithinTile =
223 numberOfTilesInPosition - truncf(numberOfTilesInPosition); 228 numberOfTilesInPosition - truncf(numberOfTilesInPosition);
224 setPhaseX(LayoutUnit( 229 setPhaseX(LayoutUnit(
(...skipping 11 matching lines...) Expand all
236 setPhaseX(LayoutUnit()); 241 setPhaseX(LayoutUnit());
237 } 242 }
238 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height())); 243 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height()));
239 } 244 }
240 245
241 void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer, 246 void BackgroundImageGeometry::setRepeatY(const FillLayer& fillLayer,
242 LayoutUnit unsnappedTileHeight, 247 LayoutUnit unsnappedTileHeight,
243 LayoutUnit snappedAvailableHeight, 248 LayoutUnit snappedAvailableHeight,
244 LayoutUnit unsnappedAvailableHeight, 249 LayoutUnit unsnappedAvailableHeight,
245 LayoutUnit extraOffset) { 250 LayoutUnit extraOffset) {
246 // We would like to identify the phase as a fraction of the image size in the absence of snapping, 251 // We would like to identify the phase as a fraction of the image size in the
247 // then re-apply it to the snapped values. This is to handle large positions. 252 // absence of snapping, then re-apply it to the snapped values. This is to
253 // handle large positions.
248 if (unsnappedTileHeight) { 254 if (unsnappedTileHeight) {
249 LayoutUnit computedYPosition = roundedMinimumValueForLength( 255 LayoutUnit computedYPosition = roundedMinimumValueForLength(
250 fillLayer.yPosition(), unsnappedAvailableHeight); 256 fillLayer.yPosition(), unsnappedAvailableHeight);
251 if (fillLayer.backgroundYOrigin() == BottomEdge) { 257 if (fillLayer.backgroundYOrigin() == BottomEdge) {
252 float numberOfTilesInPosition = 258 float numberOfTilesInPosition =
253 (snappedAvailableHeight - computedYPosition + extraOffset).toFloat() / 259 (snappedAvailableHeight - computedYPosition + extraOffset).toFloat() /
254 unsnappedTileHeight.toFloat(); 260 unsnappedTileHeight.toFloat();
255 float fractionalPositionWithinTile = 261 float fractionalPositionWithinTile =
256 numberOfTilesInPosition - truncf(numberOfTilesInPosition); 262 numberOfTilesInPosition - truncf(numberOfTilesInPosition);
257 setPhaseY(LayoutUnit( 263 setPhaseY(LayoutUnit(
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 // It is only possible reach here when root element has a box. 328 // It is only possible reach here when root element has a box.
323 Element* documentElement = obj.document().documentElement(); 329 Element* documentElement = obj.document().documentElement();
324 DCHECK(documentElement); 330 DCHECK(documentElement);
325 DCHECK(documentElement->layoutObject()); 331 DCHECK(documentElement->layoutObject());
326 DCHECK(documentElement->layoutObject()->isBox()); 332 DCHECK(documentElement->layoutObject()->isBox());
327 rootBox = toLayoutBox(documentElement->layoutObject()); 333 rootBox = toLayoutBox(documentElement->layoutObject());
328 } 334 }
329 const LayoutBoxModelObject& positioningBox = 335 const LayoutBoxModelObject& positioningBox =
330 isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj; 336 isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj;
331 337
332 // Determine the background positioning area and set destRect to the backgroun d painting area. 338 // Determine the background positioning area and set destRect to the
333 // destRect will be adjusted later if the background is non-repeating. 339 // background painting area. destRect will be adjusted later if the
334 // FIXME: transforms spec says that fixed backgrounds behave like scroll insid e transforms. 340 // background is non-repeating.
341 // FIXME: transforms spec says that fixed backgrounds behave like scroll
342 // inside transforms.
335 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; 343 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment;
336 344
337 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { 345 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
338 // As a side effect of an optimization to blit on scroll, we do not honor th e CSS 346 // As a side effect of an optimization to blit on scroll, we do not honor
339 // property "background-attachment: fixed" because it may result in renderin g 347 // the CSS property "background-attachment: fixed" because it may result in
340 // artifacts. Note, these artifacts only appear if we are blitting on scroll of 348 // rendering artifacts. Note, these artifacts only appear if we are blitting
341 // a page that has fixed background images. 349 // on scroll of a page that has fixed background images.
342 fixedAttachment = false; 350 fixedAttachment = false;
343 } 351 }
344 352
345 if (!fixedAttachment) { 353 if (!fixedAttachment) {
346 setDestRect(paintRect); 354 setDestRect(paintRect);
347 355
348 LayoutUnit right; 356 LayoutUnit right;
349 LayoutUnit bottom; 357 LayoutUnit bottom;
350 // Scroll and Local. 358 // Scroll and Local.
351 if (fillLayer.origin() != BorderFillBox) { 359 if (fillLayer.origin() != BorderFillBox) {
352 left = LayoutUnit(positioningBox.borderLeft()); 360 left = LayoutUnit(positioningBox.borderLeft());
353 right = LayoutUnit(positioningBox.borderRight()); 361 right = LayoutUnit(positioningBox.borderRight());
354 top = LayoutUnit(positioningBox.borderTop()); 362 top = LayoutUnit(positioningBox.borderTop());
355 bottom = LayoutUnit(positioningBox.borderBottom()); 363 bottom = LayoutUnit(positioningBox.borderBottom());
356 if (fillLayer.origin() == ContentFillBox) { 364 if (fillLayer.origin() == ContentFillBox) {
357 left += positioningBox.paddingLeft(); 365 left += positioningBox.paddingLeft();
358 right += positioningBox.paddingRight(); 366 right += positioningBox.paddingRight();
359 top += positioningBox.paddingTop(); 367 top += positioningBox.paddingTop();
360 bottom += positioningBox.paddingBottom(); 368 bottom += positioningBox.paddingBottom();
361 } 369 }
362 } 370 }
363 371
364 if (isLayoutView) { 372 if (isLayoutView) {
365 // The background of the box generated by the root element covers the enti re canvas and will 373 // The background of the box generated by the root element covers the
366 // be painted by the view object, but the we should still use the root ele ment box for 374 // entire canvas and will be painted by the view object, but the we should
367 // positioning. 375 // still use the root element box for positioning.
368 positioningAreaSize = 376 positioningAreaSize =
369 rootBox->size() - LayoutSize(left + right, top + bottom), 377 rootBox->size() - LayoutSize(left + right, top + bottom),
370 rootBox->location(); 378 rootBox->location();
371 // The input paint rect is specified in root element local coordinate (i.e . a transform 379 // The input paint rect is specified in root element local coordinate
372 // is applied on the context for painting), and is expanded to cover the w hole canvas. 380 // (i.e. a transform is applied on the context for painting), and is
373 // Since left/top is relative to the paint rect, we need to offset them ba ck. 381 // expanded to cover the whole canvas. Since left/top is relative to the
382 // paint rect, we need to offset them back.
374 left -= paintRect.x(); 383 left -= paintRect.x();
375 top -= paintRect.y(); 384 top -= paintRect.y();
376 } else { 385 } else {
377 positioningAreaSize = 386 positioningAreaSize =
378 paintRect.size() - LayoutSize(left + right, top + bottom); 387 paintRect.size() - LayoutSize(left + right, top + bottom);
379 } 388 }
380 } else { 389 } else {
381 setHasNonLocalGeometry(); 390 setHasNonLocalGeometry();
382 391
383 LayoutRect viewportRect = obj.viewRect(); 392 LayoutRect viewportRect = obj.viewRect();
(...skipping 11 matching lines...) Expand all
395 if (paintContainer) 404 if (paintContainer)
396 viewportRect.moveBy( 405 viewportRect.moveBy(
397 LayoutPoint(-paintContainer->localToAbsolute(FloatPoint()))); 406 LayoutPoint(-paintContainer->localToAbsolute(FloatPoint())));
398 407
399 setDestRect(viewportRect); 408 setDestRect(viewportRect);
400 positioningAreaSize = destRect().size(); 409 positioningAreaSize = destRect().size();
401 } 410 }
402 411
403 LayoutSize fillTileSize( 412 LayoutSize fillTileSize(
404 calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize)); 413 calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize));
405 // It's necessary to apply the heuristic here prior to any further calculation s to avoid 414 // It's necessary to apply the heuristic here prior to any further
406 // incorrectly using sub-pixel values that won't be present in the painted til e. 415 // calculations to avoid incorrectly using sub-pixel values that won't be
416 // present in the painted tile.
407 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); 417 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect));
408 418
409 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); 419 EFillRepeat backgroundRepeatX = fillLayer.repeatX();
410 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); 420 EFillRepeat backgroundRepeatY = fillLayer.repeatY();
411 LayoutUnit unsnappedAvailableWidth = 421 LayoutUnit unsnappedAvailableWidth =
412 positioningAreaSize.width() - fillTileSize.width(); 422 positioningAreaSize.width() - fillTileSize.width();
413 LayoutUnit unsnappedAvailableHeight = 423 LayoutUnit unsnappedAvailableHeight =
414 positioningAreaSize.height() - fillTileSize.height(); 424 positioningAreaSize.height() - fillTileSize.height();
415 positioningAreaSize = 425 positioningAreaSize =
416 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), 426 LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 useFixedAttachment(paintRect.location()); 522 useFixedAttachment(paintRect.location());
513 523
514 // Clip the final output rect to the paint rect 524 // Clip the final output rect to the paint rect
515 m_destRect.intersect(paintRect); 525 m_destRect.intersect(paintRect);
516 526
517 // Snap as-yet unsnapped values. 527 // Snap as-yet unsnapped values.
518 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); 528 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect)));
519 } 529 }
520 530
521 } // namespace blink 531 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698