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

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

Issue 1847983003: Fix for phase in background tiling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code now better Created 4 years, 8 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
« no previous file with comments | « third_party/WebKit/Source/core/paint/BackgroundImageGeometry.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (horizontalScaleFactor < verticalScaleFactor) 117 if (horizontalScaleFactor < verticalScaleFactor)
118 return LayoutSize(positioningAreaSize.width(), LayoutUnit(std::m ax(1.0f, imageIntrinsicSize.height() * horizontalScaleFactor))); 118 return LayoutSize(positioningAreaSize.width(), LayoutUnit(std::m ax(1.0f, imageIntrinsicSize.height() * horizontalScaleFactor)));
119 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width () * verticalScaleFactor)), positioningAreaSize.height()); 119 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width () * verticalScaleFactor)), positioningAreaSize.height());
120 } 120 }
121 if (horizontalScaleFactor > verticalScaleFactor) 121 if (horizontalScaleFactor > verticalScaleFactor)
122 return LayoutSize(positioningAreaSize.width(), LayoutUnit(std::max(1 .0f, imageIntrinsicSize.height() * horizontalScaleFactor))); 122 return LayoutSize(positioningAreaSize.width(), LayoutUnit(std::max(1 .0f, imageIntrinsicSize.height() * horizontalScaleFactor)));
123 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width() * verticalScaleFactor)), positioningAreaSize.height()); 123 return LayoutSize(LayoutUnit(std::max(1.0f, imageIntrinsicSize.width() * verticalScaleFactor)), positioningAreaSize.height());
124 } 124 }
125 } 125 }
126 126
127 ASSERT_NOT_REACHED(); 127 NOTREACHED();
128 return LayoutSize(); 128 return LayoutSize();
129 } 129 }
130 130
131 IntPoint accumulatedScrollOffsetForFixedBackground(const LayoutBoxModelObject& o bject, const LayoutBoxModelObject* container) 131 IntPoint accumulatedScrollOffsetForFixedBackground(const LayoutBoxModelObject& o bject, const LayoutBoxModelObject* container)
132 { 132 {
133 IntPoint result; 133 IntPoint result;
134 if (&object == container) 134 if (&object == container)
135 return result; 135 return result;
136 for (const LayoutBlock* block = object.containingBlock(); block; block = blo ck->containingBlock()) { 136 for (const LayoutBlock* block = object.containingBlock(); block; block = blo ck->containingBlock()) {
137 if (block->hasOverflowClip()) 137 if (block->hasOverflowClip())
(...skipping 18 matching lines...) Expand all
156 return snappedSize; 156 return snappedSize;
157 } 157 }
158 158
159 } // anonymous namespace 159 } // anonymous namespace
160 160
161 void BackgroundImageGeometry::setNoRepeatX(LayoutUnit xOffset) 161 void BackgroundImageGeometry::setNoRepeatX(LayoutUnit xOffset)
162 { 162 {
163 m_destRect.move(std::max(xOffset, LayoutUnit()), LayoutUnit()); 163 m_destRect.move(std::max(xOffset, LayoutUnit()), LayoutUnit());
164 m_phase.setX(-std::min(xOffset, LayoutUnit())); 164 m_phase.setX(-std::min(xOffset, LayoutUnit()));
165 m_destRect.setWidth(m_tileSize.width() + std::min(xOffset, LayoutUnit())); 165 m_destRect.setWidth(m_tileSize.width() + std::min(xOffset, LayoutUnit()));
166 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height()));
166 } 167 }
167 168
168 void BackgroundImageGeometry::setNoRepeatY(LayoutUnit yOffset) 169 void BackgroundImageGeometry::setNoRepeatY(LayoutUnit yOffset)
169 { 170 {
170 m_destRect.move(LayoutUnit(), std::max(yOffset, LayoutUnit())); 171 m_destRect.move(LayoutUnit(), std::max(yOffset, LayoutUnit()));
171 m_phase.setY(-std::min(yOffset, LayoutUnit())); 172 m_phase.setY(-std::min(yOffset, LayoutUnit()));
172 m_destRect.setHeight(m_tileSize.height() + std::min(yOffset, LayoutUnit())); 173 m_destRect.setHeight(m_tileSize.height() + std::min(yOffset, LayoutUnit()));
174 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
175 }
176
177 void BackgroundImageGeometry::setRepeatX(
178 const FillLayer& fillLayer,
179 LayoutUnit unsnappedTileWidth,
180 LayoutUnit snappedAvailableWidth,
181 LayoutUnit unsnappedAvailableWidth,
182 LayoutUnit extraOffset)
183 {
184 // We would like to identify the phase as a fraction of the image size in th e absence of snapping,
185 // then re-apply it to the snapped values. This is to handle large positions .
186 if (unsnappedTileWidth) {
187 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xP osition(), unsnappedAvailableWidth);
188 if (fillLayer.backgroundXOrigin() == RightEdge) {
189 float numberOfTilesInPosition = (snappedAvailableWidth - computedXPo sition + extraOffset).toFloat() / unsnappedTileWidth.toFloat();
190 float fractionalPositionWithinTile = numberOfTilesInPosition - trunc f(numberOfTilesInPosition);
191 setPhaseX(LayoutUnit(fractionalPositionWithinTile * tileSize().width ()));
192 } else {
193 float numberOfTilesInPosition = (computedXPosition + extraOffset).to Float() / unsnappedTileWidth.toFloat();
194 float fractionalPositionWithinTile = 1.0f - (numberOfTilesInPosition - truncf(numberOfTilesInPosition));
195 setPhaseX(LayoutUnit(fractionalPositionWithinTile * tileSize().width ()));
196 }
197 } else {
198 setPhaseX(LayoutUnit());
199 }
200 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height()));
201 }
202
203 void BackgroundImageGeometry::setRepeatY(
204 const FillLayer& fillLayer,
205 LayoutUnit unsnappedTileHeight,
206 LayoutUnit snappedAvailableHeight,
207 LayoutUnit unsnappedAvailableHeight,
208 LayoutUnit extraOffset)
209 {
210 // We would like to identify the phase as a fraction of the image size in th e absence of snapping,
211 // then re-apply it to the snapped values. This is to handle large positions .
212 if (unsnappedTileHeight) {
213 LayoutUnit computedYPosition = roundedMinimumValueForLength(fillLayer.yP osition(), unsnappedAvailableHeight);
214 if (fillLayer.backgroundYOrigin() == BottomEdge) {
215 float numberOfTilesInPosition = (snappedAvailableHeight - computedYP osition + extraOffset).toFloat() / unsnappedTileHeight.toFloat();
216 float fractionalPositionWithinTile = numberOfTilesInPosition - trunc f(numberOfTilesInPosition);
217 setPhaseY(LayoutUnit(fractionalPositionWithinTile * tileSize().heigh t()));
218 } else {
219 float numberOfTilesInPosition = (computedYPosition + extraOffset).to Float() / unsnappedTileHeight.toFloat();
220 float fractionalPositionWithinTile = 1.0f - (numberOfTilesInPosition - truncf(numberOfTilesInPosition));
221 setPhaseY(LayoutUnit(fractionalPositionWithinTile * tileSize().heigh t()));
222 }
223 } else {
224 setPhaseY(LayoutUnit());
225 }
226 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
227 }
228
229 void BackgroundImageGeometry::setSpaceX(LayoutUnit space, LayoutUnit availableWi dth, LayoutUnit extraOffset)
230 {
231 LayoutUnit computedXPosition = roundedMinimumValueForLength(Length(), availa bleWidth);
232 setSpaceSize(LayoutSize(space.round(), spaceSize().height()));
233 LayoutUnit actualWidth = tileSize().width() + space;
234 setPhaseX(actualWidth ? LayoutUnit(actualWidth - fmodf((computedXPosition + extraOffset), actualWidth)) : LayoutUnit());
235 }
236
237 void BackgroundImageGeometry::setSpaceY(LayoutUnit space, LayoutUnit availableHe ight, LayoutUnit extraOffset)
238 {
239 LayoutUnit computedYPosition = roundedMinimumValueForLength(Length(), availa bleHeight);
240 setSpaceSize(LayoutSize(spaceSize().width(), space.round()));
241 LayoutUnit actualHeight = tileSize().height() + space;
242 setPhaseY(actualHeight ? LayoutUnit(actualHeight - fmodf((computedYPosition + extraOffset), actualHeight)) : LayoutUnit());
173 } 243 }
174 244
175 void BackgroundImageGeometry::useFixedAttachment(const LayoutPoint& attachmentPo int) 245 void BackgroundImageGeometry::useFixedAttachment(const LayoutPoint& attachmentPo int)
176 { 246 {
177 LayoutPoint alignedPoint = attachmentPoint; 247 LayoutPoint alignedPoint = attachmentPoint;
178 m_phase.move(std::max(alignedPoint.x() - m_destRect.x(), LayoutUnit()), std: :max(alignedPoint.y() - m_destRect.y(), LayoutUnit())); 248 m_phase.move(std::max(alignedPoint.x() - m_destRect.x(), LayoutUnit()), std: :max(alignedPoint.y() - m_destRect.y(), LayoutUnit()));
179 } 249 }
180 250
181 void BackgroundImageGeometry::calculate(const LayoutBoxModelObject& obj, const L ayoutBoxModelObject* paintContainer, 251 void BackgroundImageGeometry::calculate(const LayoutBoxModelObject& obj, const L ayoutBoxModelObject* paintContainer,
182 const GlobalPaintFlags globalPaintFlags, const FillLayer& fillLayer, const L ayoutRect& paintRect) 252 const GlobalPaintFlags globalPaintFlags, const FillLayer& fillLayer, const L ayoutRect& paintRect)
183 { 253 {
184 LayoutUnit left; 254 LayoutUnit left;
185 LayoutUnit top; 255 LayoutUnit top;
186 LayoutSize positioningAreaSize; 256 LayoutSize positioningAreaSize;
187 bool isLayoutView = obj.isLayoutView(); 257 bool isLayoutView = obj.isLayoutView();
188 const LayoutBox* rootBox = nullptr; 258 const LayoutBox* rootBox = nullptr;
189 if (isLayoutView) { 259 if (isLayoutView) {
190 // It is only possible reach here when root element has a box. 260 // It is only possible reach here when root element has a box.
191 Element* documentElement = obj.document().documentElement(); 261 Element* documentElement = obj.document().documentElement();
192 ASSERT(documentElement); 262 DCHECK(documentElement);
193 ASSERT(documentElement->layoutObject()); 263 DCHECK(documentElement->layoutObject());
194 ASSERT(documentElement->layoutObject()->isBox()); 264 DCHECK(documentElement->layoutObject()->isBox());
195 rootBox = toLayoutBox(documentElement->layoutObject()); 265 rootBox = toLayoutBox(documentElement->layoutObject());
196 } 266 }
197 const LayoutBoxModelObject& positioningBox = isLayoutView ? static_cast<cons t LayoutBoxModelObject&>(*rootBox) : obj; 267 const LayoutBoxModelObject& positioningBox = isLayoutView ? static_cast<cons t LayoutBoxModelObject&>(*rootBox) : obj;
198 268
199 // Determine the background positioning area and set destRect to the backgro und painting area. 269 // Determine the background positioning area and set destRect to the backgro und painting area.
200 // destRect will be adjusted later if the background is non-repeating. 270 // destRect will be adjusted later if the background is non-repeating.
201 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins ide transforms. 271 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins ide transforms.
202 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; 272 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment;
203 273
204 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { 274 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 positioningAreaSize = destRect().size(); 332 positioningAreaSize = destRect().size();
263 } 333 }
264 334
265 LayoutSize fillTileSize(calculateFillTileSize(positioningBox, fillLayer, pos itioningAreaSize)); 335 LayoutSize fillTileSize(calculateFillTileSize(positioningBox, fillLayer, pos itioningAreaSize));
266 // It's necessary to apply the heuristic here prior to any further calculati ons to avoid 336 // It's necessary to apply the heuristic here prior to any further calculati ons to avoid
267 // incorrectly using sub-pixel values that won't be present in the painted t ile. 337 // incorrectly using sub-pixel values that won't be present in the painted t ile.
268 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); 338 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect));
269 339
270 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); 340 EFillRepeat backgroundRepeatX = fillLayer.repeatX();
271 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); 341 EFillRepeat backgroundRepeatY = fillLayer.repeatY();
342 LayoutUnit unsnappedAvailableWidth = positioningAreaSize.width() - fillTileS ize.width();
343 LayoutUnit unsnappedAvailableHeight = positioningAreaSize.height() - fillTil eSize.height();
272 positioningAreaSize = LayoutSize(snapSizeToPixel(positioningAreaSize.width() , m_destRect.x()), snapSizeToPixel(positioningAreaSize.height(), m_destRect.y()) ); 344 positioningAreaSize = LayoutSize(snapSizeToPixel(positioningAreaSize.width() , m_destRect.x()), snapSizeToPixel(positioningAreaSize.height(), m_destRect.y()) );
273 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width() ; 345 LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width() ;
274 LayoutUnit availableHeight = positioningAreaSize.height() - tileSize().heigh t(); 346 LayoutUnit availableHeight = positioningAreaSize.height() - tileSize().heigh t();
275 347
276 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit ion(), availableWidth); 348 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit ion(), availableWidth);
277 if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > LayoutUn it() && fillTileSize.width() > LayoutUnit()) { 349 if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > LayoutUn it() && fillTileSize.width() > LayoutUnit()) {
278 int nrTiles = std::max(1, roundToInt(positioningAreaSize.width() / fillT ileSize.width())); 350 int nrTiles = std::max(1, roundToInt(positioningAreaSize.width() / fillT ileSize.width()));
279 351
280 fillTileSize.setWidth(positioningAreaSize.width() / nrTiles); 352 fillTileSize.setWidth(positioningAreaSize.width() / nrTiles);
281 353
(...skipping 17 matching lines...) Expand all
299 if (fillLayer.size().size.width().isAuto() && backgroundRepeatX != Round Fill) { 371 if (fillLayer.size().size.width().isAuto() && backgroundRepeatX != Round Fill) {
300 fillTileSize.setWidth(fillTileSize.width() * positioningAreaSize.hei ght() / (nrTiles * fillTileSize.height())); 372 fillTileSize.setWidth(fillTileSize.width() * positioningAreaSize.hei ght() / (nrTiles * fillTileSize.height()));
301 } 373 }
302 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)) ; 374 setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)) ;
303 setPhaseY(tileSize().height() ? LayoutUnit(tileSize().height() - fmodf(( computedYPosition + top), tileSize().height())) 375 setPhaseY(tileSize().height() ? LayoutUnit(tileSize().height() - fmodf(( computedYPosition + top), tileSize().height()))
304 : LayoutUnit()); 376 : LayoutUnit());
305 setSpaceSize(LayoutSize()); 377 setSpaceSize(LayoutSize());
306 } 378 }
307 379
308 if (backgroundRepeatX == RepeatFill) { 380 if (backgroundRepeatX == RepeatFill) {
309 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge ? availa bleWidth - computedXPosition : computedXPosition; 381 setRepeatX(fillLayer, fillTileSize.width(), availableWidth, unsnappedAva ilableWidth, left);
310 setPhaseX(tileSize().width() ? LayoutUnit(tileSize().width() - fmodf((xO ffset + left), tileSize().width()))
311 : LayoutUnit());
312 setSpaceSize(LayoutSize());
313 } else if (backgroundRepeatX == SpaceFill && tileSize().width() > LayoutUnit ()) { 382 } else if (backgroundRepeatX == SpaceFill && tileSize().width() > LayoutUnit ()) {
314 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width() , tileSize().width()); 383 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width() , tileSize().width());
315 LayoutUnit actualWidth = tileSize().width() + space; 384 if (space >= LayoutUnit())
316 385 setSpaceX(space, availableWidth, left);
317 if (space >= LayoutUnit()) { 386 else
318 computedXPosition = roundedMinimumValueForLength(Length(), available Width);
319 setSpaceSize(LayoutSize(space.round(), LayoutUnit()));
320 setPhaseX(actualWidth ? LayoutUnit(actualWidth - fmodf((computedXPos ition + left), actualWidth)) : LayoutUnit());
321 } else {
322 backgroundRepeatX = NoRepeatFill; 387 backgroundRepeatX = NoRepeatFill;
323 }
324 } 388 }
325 if (backgroundRepeatX == NoRepeatFill) { 389 if (backgroundRepeatX == NoRepeatFill) {
326 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge ? availa bleWidth - computedXPosition : computedXPosition; 390 LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge ? availa bleWidth - computedXPosition : computedXPosition;
327 setNoRepeatX(left + xOffset); 391 setNoRepeatX(left + xOffset);
328 setSpaceSize(LayoutSize(LayoutUnit(), spaceSize().height()));
329 } 392 }
330 393
331 if (backgroundRepeatY == RepeatFill) { 394 if (backgroundRepeatY == RepeatFill) {
332 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge ? avail ableHeight - computedYPosition : computedYPosition; 395 setRepeatY(fillLayer, fillTileSize.height(), availableHeight, unsnappedA vailableHeight, top);
333 setPhaseY(tileSize().height() ? LayoutUnit(tileSize().height() - fmodf(( yOffset + top), tileSize().height()))
334 : LayoutUnit());
335 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
336 } else if (backgroundRepeatY == SpaceFill && tileSize().height() > LayoutUni t()) { 396 } else if (backgroundRepeatY == SpaceFill && tileSize().height() > LayoutUni t()) {
337 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height( ), tileSize().height()); 397 LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height( ), tileSize().height());
338 LayoutUnit actualHeight = tileSize().height() + space; 398 if (space >= LayoutUnit())
339 399 setSpaceY(space, availableHeight, top);
340 if (space >= LayoutUnit()) { 400 else
341 computedYPosition = roundedMinimumValueForLength(Length(), available Height);
342 setSpaceSize(LayoutSize(spaceSize().width(), space.round()));
343 setPhaseY(actualHeight ? LayoutUnit(actualHeight - fmodf((computedYP osition + top), actualHeight)) : LayoutUnit());
344 } else {
345 backgroundRepeatY = NoRepeatFill; 401 backgroundRepeatY = NoRepeatFill;
346 }
347 } 402 }
348 if (backgroundRepeatY == NoRepeatFill) { 403 if (backgroundRepeatY == NoRepeatFill) {
349 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge ? avail ableHeight - computedYPosition : computedYPosition; 404 LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge ? avail ableHeight - computedYPosition : computedYPosition;
350 setNoRepeatY(top + yOffset); 405 setNoRepeatY(top + yOffset);
351 setSpaceSize(LayoutSize(spaceSize().width(), LayoutUnit()));
352 } 406 }
353 407
354 if (fixedAttachment) 408 if (fixedAttachment)
355 useFixedAttachment(paintRect.location()); 409 useFixedAttachment(paintRect.location());
356 410
357 // Clip the final output rect to the paint rect 411 // Clip the final output rect to the paint rect
358 m_destRect.intersect(paintRect); 412 m_destRect.intersect(paintRect);
359 413
360 // Snap as-yet unsnapped values. 414 // Snap as-yet unsnapped values.
361 setPhase(LayoutPoint(roundedIntPoint(m_phase))); 415 setPhase(LayoutPoint(roundedIntPoint(m_phase)));
362 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); 416 setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect)));
363 417
364 } 418 }
365 419
366 } // namespace blink 420 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/BackgroundImageGeometry.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698