Source/WebCore/ChangeLog

 12012-03-27 Nikolas Zimmermann <nzimmermann@rim.com>
 2
 3 <img style='width: 100%' src='foo.svg'> gets pixellated when stretched
 4 https://bugs.webkit.org/show_bug.cgi?id=81631
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Final cleanup of RenderReplaced after the intrinsic size negotiation patch series from some weeks/months ago.
 9 Stop tracking whether a RenderReplaced has an intrinsic size or not with an extra-bool, instead assume each
 10 RenderReplaced derived class has an intrinsic size. If not, the class should override
 11 computeIntrinsicRatioInformation() for any custom logic - currently only done by RenderImage.
 12
 13 Remove all logic depending on m_hasIntrinsicSize from computeReplacedLogicalWidth/Height, which was used
 14 to support different sizing models depending on if the replaced element is a RenderImage or a RenderPart.
 15 Unify all of this in computeIntrinsicRatioInformation right in RenderReplaced. This allows to remove
 16 a hack from RenderImage::computeReplacedLogicalWidth(), which forced the synchroniziation of the intrinsicSize()
 17 before calling the base classes RenderReplaced::computeReplacedLogicalWidth().
 18 Now RenderImage just overrides the layout() method, calls RenderReplaced::layout() and then sets the container
 19 size of the image resources to [contentWidth(), contentHeight()] - reflecting the actual result of the layout.
 20 Furthermore this now allows us to unify CachedImage::imageSizeForRenderer() again for both SVG and non-SVG images.
 21
 22 Propagating the right container size to the image resource fixes the actual bug, that the SVGImage got pixellated.
 23 Adding new tests covering percentage width or height set on an <img> embedding an external SVG, no more pixelation.
 24
 25 Tests: svg/as-image/img-relative-height-expected.html
 26 svg/as-image/img-relative-height.html
 27 svg/as-image/img-relative-width-expected.html
 28 svg/as-image/img-relative-width.html
 29
 30 * loader/cache/CachedImage.cpp:
 31 (WebCore::CachedImage::imageSizeForRenderer):
 32 * rendering/RenderEmbeddedObject.cpp:
 33 (WebCore::RenderEmbeddedObject::RenderEmbeddedObject):
 34 * rendering/RenderImage.cpp:
 35 (WebCore::RenderImage::layout):
 36 (WebCore::RenderImage::computeIntrinsicRatioInformation):
 37 * rendering/RenderImage.h:
 38 (RenderImage):
 39 * rendering/RenderReplaced.cpp:
 40 (WebCore::RenderReplaced::RenderReplaced):
 41 (WebCore::rendererHasAspectRatio):
 42 (WebCore):
 43 (WebCore::RenderReplaced::computeIntrinsicRatioInformationForRenderBox):
 44 (WebCore::RenderReplaced::computeIntrinsicRatioInformation):
 45 (WebCore::RenderReplaced::computeReplacedLogicalWidth):
 46 (WebCore::RenderReplaced::computeReplacedLogicalHeight):
 47 * rendering/RenderReplaced.h:
 48 (WebCore::RenderReplaced::intrinsicSize):
 49 (RenderReplaced):
 50 (WebCore::RenderReplaced::setIntrinsicSize):
 51 * svg/graphics/SVGImage.cpp:
 52 (WebCore::SVGImage::setContainerSize):
 53 * svg/graphics/SVGImage.h:
 54 (WebCore::SVGImage::usesContainerSize):
 55
1562012-03-27 Ilya Tikhonovsky <loislo@chromium.org>
257
358 Web Inspector: HeapSnapshot: speed-up distanceToWindow calculation.

Source/WebCore/loader/cache/CachedImage.cpp

@@IntSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float mu
240240
241241 if (!m_image)
242242 return IntSize();
 243
 244 IntSize imageSize = m_image->size();
 245
243246#if ENABLE(SVG)
244247 if (m_image->isSVGImage()) {
245  // SVGImages already includes the zooming in its intrinsic size.
246248 SVGImageCache::SizeAndZoom sizeAndZoom = m_svgImageCache->requestedSizeAndZoom(renderer);
247  if (sizeAndZoom.size.isEmpty())
248  return m_image->size();
249  if (sizeAndZoom.zoom == 1)
250  return sizeAndZoom.size;
251  if (multiplier == 1) {
252  // Consumer wants unscaled coordinates.
253  sizeAndZoom.size.setWidth(sizeAndZoom.size.width() / sizeAndZoom.zoom);
254  sizeAndZoom.size.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom);
255  return sizeAndZoom.size;
 249 if (!sizeAndZoom.size.isEmpty()) {
 250 imageSize.setWidth(sizeAndZoom.size.width() / sizeAndZoom.zoom);
 251 imageSize.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom);
256252 }
257  return sizeAndZoom.size;
258253 }
259254#else
260255 UNUSED_PARAM(renderer);
261256#endif
262257
263258 if (multiplier == 1.0f)
264  return m_image->size();
 259 return imageSize;
265260
266261 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed.
267  bool hasWidth = m_image->size().width() > 0;
268  bool hasHeight = m_image->size().height() > 0;
269  int width = m_image->size().width() * (m_image->hasRelativeWidth() ? 1.0f : multiplier);
270  int height = m_image->size().height() * (m_image->hasRelativeHeight() ? 1.0f : multiplier);
 262 bool hasWidth = imageSize.width() > 0;
 263 bool hasHeight = imageSize.height() > 0;
 264 int width = imageSize.width() * (m_image->hasRelativeWidth() ? 1.0f : multiplier);
 265 int height = imageSize.height() * (m_image->hasRelativeHeight() ? 1.0f : multiplier);
271266 if (hasWidth)
272267 width = max(1, width);
273268 if (hasHeight)

Source/WebCore/rendering/RenderEmbeddedObject.cpp

5353#include "Text.h"
5454#include "TextRun.h"
5555
56 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
57 #include "HTMLVideoElement.h"
58 #endif
59 
6056namespace WebCore {
6157
6258using namespace HTMLNames;

@@RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
8379 , m_mouseDownWasInMissingPluginIndicator(false)
8480{
8581 view()->frameView()->setIsVisuallyNonEmpty();
86 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
87  if (element->hasTagName(videoTag) || element->hasTagName(audioTag))
88  setHasIntrinsicSize();
89 #endif
9082}
9183
9284RenderEmbeddedObject::~RenderEmbeddedObject()

Source/WebCore/rendering/RenderImage.cpp

66 * (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
77 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
88 * Copyright (C) 2010 Google Inc. All rights reserved.
 9 * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
910 *
1011 * This library is free software; you can redistribute it and/or
1112 * modify it under the terms of the GNU Library General Public

@@void RenderImage::updateAltText()
503504 m_altText = static_cast<HTMLImageElement*>(node())->altText();
504505}
505506
506 LayoutUnit RenderImage::computeReplacedLogicalWidth(bool includeMaxWidth) const
 507void RenderImage::layout()
507508{
508  // If we've got an explicit width/height assigned, propagate it to the image resource.
509  if (style()->logicalWidth().isSpecified() && style()->logicalHeight().isSpecified()) {
510  LayoutUnit width = RenderReplaced::computeReplacedLogicalWidth(includeMaxWidth);
511  m_imageResource->setContainerSizeForRenderer(IntSize(width, computeReplacedLogicalHeight()));
512  return width;
513  }
 509 RenderReplaced::layout();
514510
515  IntSize containerSize;
516  if (m_imageResource->imageHasRelativeWidth() || m_imageResource->imageHasRelativeHeight()) {
517  // Propagate the containing block size to the image resource, otherwhise we can't compute our own intrinsic size, if it's relative.
518  RenderObject* containingBlock = isPositioned() ? container() : this->containingBlock();
519  if (containingBlock->isBox()) {
520  RenderBox* box = toRenderBox(containingBlock);
521  containerSize = IntSize(box->availableWidth(), box->availableHeight()); // Already contains zooming information.
522  }
523  } else {
524  // Propagate the current zoomed image size to the image resource, otherwhise the image size will remain the same on-screen.
525  CachedImage* cachedImage = m_imageResource->cachedImage();
526  if (cachedImage && cachedImage->image()) {
527  containerSize = cachedImage->image()->size();
528  // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
529  containerSize.setWidth(roundToInt(containerSize.width() * style()->effectiveZoom()));
530  containerSize.setHeight(roundToInt(containerSize.height() * style()->effectiveZoom()));
531  }
532  }
533 
534  if (!containerSize.isEmpty()) {
 511 // Propagate container size to image resource.
 512 IntSize containerSize = IntSize(contentWidth(), contentHeight());
 513 if (!containerSize.isEmpty())
535514 m_imageResource->setContainerSizeForRenderer(containerSize);
536  const_cast<RenderImage*>(this)->updateIntrinsicSizeIfNeeded(containerSize, false);
537  }
538 
539  return RenderReplaced::computeReplacedLogicalWidth(includeMaxWidth);
540515}
541516
542517void RenderImage::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
543518{
544  // Assure this method is never used for SVGImages.
545  ASSERT(!embeddedContentBox());
546  isPercentageIntrinsicSize = false;
547  CachedImage* cachedImage = m_imageResource ? m_imageResource->cachedImage() : 0;
548  if (!cachedImage || !cachedImage->image())
 519 RenderReplaced::computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
 520
 521 // Our intrinsicSize is empty if we're rendering generated images with relative width/height. Figure out the right intrinsic size to use.
 522 if (intrinsicSize.isEmpty() && (m_imageResource->imageHasRelativeWidth() || m_imageResource->imageHasRelativeHeight())) {
 523 RenderObject* containingBlock = isPositioned() ? container() : this->containingBlock();
 524 if (containingBlock->isBox()) {
 525 RenderBox* box = toRenderBox(containingBlock);
 526 intrinsicSize.setWidth(box->availableLogicalWidth());
 527 intrinsicSize.setHeight(box->availableLogicalHeight());
 528 }
 529 }
 530 // Don't compute an intrinsic ratio to preserve historical WebKit behavior if we're painting alt text and/or a broken image.
 531 if (m_imageResource && m_imageResource->errorOccurred()) {
 532 intrinsicRatio = 1;
549533 return;
550  intrinsicSize = cachedImage->image()->size();
551  intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
 534 }
552535}
553536
554537bool RenderImage::needsPreferredWidthsRecalculation() const

Source/WebCore/rendering/RenderImage.h

@@protected:
6868
6969 virtual void paintIntoRect(GraphicsContext*, const LayoutRect&);
7070 virtual void paint(PaintInfo&, const LayoutPoint&);
 71 virtual void layout();
7172
7273 virtual void intrinsicSizeChanged()
7374 {

@@private:
9091 virtual void notifyFinished(CachedResource*);
9192 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
9293
93  virtual LayoutUnit computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
94 
9594 IntSize imageSizeForError(CachedImage*) const;
9695 void imageDimensionsChanged(bool imageSizeChanged, const IntRect* = 0);
9796 bool updateIntrinsicSizeIfNeeded(const IntSize&, bool imageSizeChanged);

Source/WebCore/rendering/RenderReplaced.cpp

22 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
33 * Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
44 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
 5 * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
56 *
67 * This library is free software; you can redistribute it and/or
78 * modify it under the terms of the GNU Library General Public

@@const int cDefaultHeight = 150;
4344RenderReplaced::RenderReplaced(Node* node)
4445 : RenderBox(node)
4546 , m_intrinsicSize(cDefaultWidth, cDefaultHeight)
46  , m_hasIntrinsicSize(false)
4747{
4848 setReplaced(true);
4949}

@@RenderReplaced::RenderReplaced(Node* node)
5151RenderReplaced::RenderReplaced(Node* node, const IntSize& intrinsicSize)
5252 : RenderBox(node)
5353 , m_intrinsicSize(intrinsicSize)
54  , m_hasIntrinsicSize(true)
5554{
5655 setReplaced(true);
5756}

@@bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, const LayoutPoint& paintO
202201 return true;
203202}
204203
205 int RenderReplaced::computeIntrinsicLogicalWidth(RenderBox* contentRenderer, bool includeMaxWidth) const
206 {
207  if (m_hasIntrinsicSize)
208  return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth);
209  ASSERT(contentRenderer);
210  ASSERT(contentRenderer->style());
211  return contentRenderer->computeReplacedLogicalWidthRespectingMinMaxWidth(contentRenderer->computeReplacedLogicalWidthUsing(contentRenderer->style()->logicalWidth()), includeMaxWidth);
212 }
213 
214 int RenderReplaced::computeIntrinsicLogicalHeight(RenderBox* contentRenderer) const
215 {
216  if (m_hasIntrinsicSize)
217  return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight());
218  ASSERT(contentRenderer);
219  ASSERT(contentRenderer->style());
220  return contentRenderer->computeReplacedLogicalHeightRespectingMinMaxHeight(contentRenderer->computeReplacedLogicalHeightUsing(contentRenderer->style()->logicalHeight()));
221 }
222 
223204static inline RenderBlock* firstContainingBlockWithLogicalWidth(const RenderReplaced* replaced)
224205{
225206 // We have to lookup the containing block, which has an explicit width, which must not be equal to our direct containing block.

@@bool RenderReplaced::hasReplacedLogicalHeight() const
282263 return false;
283264}
284265
 266static inline bool rendererHasAspectRatio(const RenderObject* renderer)
 267{
 268 ASSERT(renderer);
 269 return renderer->isImage() || renderer->isCanvas() || renderer->isVideo();
 270}
 271
 272void RenderReplaced::computeIntrinsicRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
 273{
 274 if (contentRenderer) {
 275 contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
 276 if (intrinsicRatio)
 277 ASSERT(!isPercentageIntrinsicSize);
 278
 279 // Handle zoom & vertical writing modes here, as the embedded document doesn't know about them.
 280 if (!isPercentageIntrinsicSize)
 281 intrinsicSize.scale(style()->effectiveZoom());
 282
 283 if (intrinsicRatio && !isHorizontalWritingMode())
 284 intrinsicRatio = 1 / intrinsicRatio;
 285
 286 if (rendererHasAspectRatio(this) && isPercentageIntrinsicSize)
 287 intrinsicRatio = 1;
 288 return;
 289 }
 290
 291 // This code path can't yield percentage intrinsic sizes, assert that.
 292 computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
 293 ASSERT(!isPercentageIntrinsicSize);
 294}
 295
 296void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
 297{
 298 // If there's an embeddedContentBox() of a remote, referenced document available, this code-path should never be used.
 299 ASSERT(!embeddedContentBox());
 300 isPercentageIntrinsicSize = false;
 301 intrinsicSize = FloatSize(intrinsicLogicalWidth(), intrinsicLogicalHeight());
 302
 303 // Figure out if we need to compute an intrinsic ratio.
 304 if (intrinsicSize.isEmpty() || !rendererHasAspectRatio(this))
 305 return;
 306
 307 intrinsicRatio = intrinsicSize.width() / intrinsicSize.height();
 308 if (style()->logicalWidth().isAuto() && style()->logicalHeight().isAuto()) {
 309 // We can't multiply or divide by 'intrinsicRatio' here, it breaks tests, like fast/images/zoomed-img-size.html, which
 310 // can only be fixed once subpixel precision is available for things like intrinsicWidth/Height - which include zoom!
 311 intrinsicSize.setWidth(RenderBox::computeReplacedLogicalHeight() * intrinsicLogicalWidth() / intrinsicLogicalHeight());
 312 intrinsicSize.setHeight(RenderBox::computeReplacedLogicalWidth() * intrinsicLogicalHeight() / intrinsicLogicalWidth());
 313 }
 314}
 315
285316LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) const
286317{
287318 if (style()->logicalWidth().isSpecified())

@@LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
293324 bool isPercentageIntrinsicSize = false;
294325 double intrinsicRatio = 0;
295326 FloatSize intrinsicSize;
296  if (contentRenderer)
297  contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
298  else
299  computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
300 
301  if (intrinsicRatio && !isHorizontalWritingMode())
302  intrinsicRatio = 1 / intrinsicRatio;
 327 computeIntrinsicRatioInformationForRenderBox(contentRenderer, intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
303328
 329 // FIXME: Remove unnecessary round/roundToInt calls from this method when layout is off ints: webkit.org/b/63656
304330 if (style()->logicalWidth().isAuto()) {
305331 bool heightIsAuto = style()->logicalHeight().isAuto();
306  bool hasIntrinsicWidth = m_hasIntrinsicSize || (!isPercentageIntrinsicSize && intrinsicSize.width() > 0);
 332 bool hasIntrinsicWidth = !isPercentageIntrinsicSize && intrinsicSize.width() > 0;
307333
308334 // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
309  if (heightIsAuto && hasIntrinsicWidth) {
310  if (m_hasIntrinsicSize)
311  return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth);
312  return static_cast<LayoutUnit>(intrinsicSize.width() * style()->effectiveZoom());
313  }
 335 if (heightIsAuto && hasIntrinsicWidth)
 336 return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(intrinsicSize.width()), includeMaxWidth);
314337
315  bool hasIntrinsicHeight = m_hasIntrinsicSize || (!isPercentageIntrinsicSize && intrinsicSize.height() > 0);
 338 bool hasIntrinsicHeight = !isPercentageIntrinsicSize && intrinsicSize.height() > 0;
316339 if (intrinsicRatio || isPercentageIntrinsicSize) {
317340 // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
318341 // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value
319342 // of 'width' is: (used height) * (intrinsic ratio)
320343 if (intrinsicRatio && ((heightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !heightIsAuto)) {
321344 LayoutUnit logicalHeight = computeReplacedLogicalHeightUsing(style()->logicalHeight());
322  return computeReplacedLogicalWidthRespectingMinMaxWidth(static_cast<LayoutUnit>(ceil(logicalHeight * intrinsicRatio)));
 345 return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)));
323346 }
324347
325348 // If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of

@@LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
339362 LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), logicalWidth);
340363 logicalWidth = max(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth())));
341364 if (isPercentageIntrinsicSize)
342  // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
343  logicalWidth = static_cast<LayoutUnit>(round(logicalWidth * intrinsicSize.width() / 100));
344  return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth);
 365 logicalWidth = roundToInt(logicalWidth * intrinsicSize.width() / 100);
 366 return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, includeMaxWidth);
345367 }
346368 }
347369
348370 // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
349  if (hasIntrinsicWidth) {
350  if (isPercentageIntrinsicSize || m_hasIntrinsicSize)
351  return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth);
352  return static_cast<LayoutUnit>(intrinsicSize.width() * style()->effectiveZoom());
353  }
 371 if (hasIntrinsicWidth)
 372 return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(intrinsicSize.width()), includeMaxWidth);
354373
355374 // Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300px is too
356375 // wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
357  return computeReplacedLogicalWidthRespectingMinMaxWidth(cDefaultWidth, includeMaxWidth);
 376 // Note: We fall through and instead return intrinsicLogicalWidth() here - to preserve existing WebKit behavior, which might or might not be correct, or desired.
 377 // Changing this to return cDefaultWidth, will affect lots of test results. Eg. some tests assume that a blank <img> tag (which implies width/height=auto)
 378 // has no intrinsic size, which is wrong per CSS 2.1, but matches our behavior since a long time.
358379 }
359380
360381 return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), includeMaxWidth);

@@LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
372393 bool isPercentageIntrinsicSize = false;
373394 double intrinsicRatio = 0;
374395 FloatSize intrinsicSize;
375  if (contentRenderer)
376  contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
377  else
378  computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
379 
380  if (intrinsicRatio && !isHorizontalWritingMode())
381  intrinsicRatio = 1 / intrinsicRatio;
 396 computeIntrinsicRatioInformationForRenderBox(contentRenderer, intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
382397
 398 // FIXME: Remove unnecessary round/roundToInt calls from this method when layout is off ints: webkit.org/b/63656
383399 bool widthIsAuto = style()->logicalWidth().isAuto();
384  bool hasIntrinsicHeight = m_hasIntrinsicSize || (!isPercentageIntrinsicSize && intrinsicSize.height() > 0);
 400 bool hasIntrinsicHeight = !isPercentageIntrinsicSize && intrinsicSize.height() > 0;
385401
386402 // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
387  if (widthIsAuto && hasIntrinsicHeight) {
388  if (m_hasIntrinsicSize)
389  return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight());
390  return static_cast<LayoutUnit>(intrinsicSize.height() * style()->effectiveZoom());
391  }
 403 if (widthIsAuto && hasIntrinsicHeight)
 404 return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(intrinsicSize.height()));
392405
393406 // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is:
394407 // (used width) / (intrinsic ratio)
395  if (intrinsicRatio && !isPercentageIntrinsicSize) {
396  // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
397  return computeReplacedLogicalHeightRespectingMinMaxHeight(round(availableLogicalWidth() / intrinsicRatio));
398  }
 408 if (intrinsicRatio)
 409 return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(round(availableLogicalWidth() / intrinsicRatio)));
399410
400411 // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
401  if (hasIntrinsicHeight) {
402  if (m_hasIntrinsicSize)
403  return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight());
404  return static_cast<LayoutUnit>(intrinsicSize.height() * style()->effectiveZoom());
405  }
 412 if (hasIntrinsicHeight)
 413 return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(intrinsicSize.height()));
406414
407415 // Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to the height
408416 // of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
409  return computeReplacedLogicalHeightRespectingMinMaxHeight(cDefaultHeight);
410 }
411 
412 int RenderReplaced::calcAspectRatioLogicalWidth() const
413 {
414  int intrinsicWidth = intrinsicLogicalWidth();
415  int intrinsicHeight = intrinsicLogicalHeight();
416  if (!intrinsicHeight)
417  return 0;
418  return RenderBox::computeReplacedLogicalHeight() * intrinsicWidth / intrinsicHeight;
419 }
420 
421 int RenderReplaced::calcAspectRatioLogicalHeight() const
422 {
423  int intrinsicWidth = intrinsicLogicalWidth();
424  int intrinsicHeight = intrinsicLogicalHeight();
425  if (!intrinsicWidth)
426  return 0;
427  return RenderBox::computeReplacedLogicalWidth() * intrinsicHeight / intrinsicWidth;
 417 return computeReplacedLogicalHeightRespectingMinMaxHeight(intrinsicLogicalHeight());
428418}
429419
430420void RenderReplaced::computePreferredLogicalWidths()

@@bool RenderReplaced::isSelected() const
537527 return false;
538528}
539529
540 IntSize RenderReplaced::intrinsicSize() const
541 {
542  return m_intrinsicSize;
543 }
544 
545 void RenderReplaced::setIntrinsicSize(const IntSize& size)
546 {
547  ASSERT(m_hasIntrinsicSize);
548  m_intrinsicSize = size;
549 }
550 
551530LayoutRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const
552531{
553532 if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())

Source/WebCore/rendering/RenderReplaced.h

@@protected:
4343
4444 virtual void layout();
4545
46  virtual IntSize intrinsicSize() const;
 46 virtual IntSize intrinsicSize() const { return m_intrinsicSize; }
 47 virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
4748
4849 virtual int minimumReplacedHeight() const { return 0; }
4950

@@protected:
5354
5455 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
5556
56  void setIntrinsicSize(const IntSize&);
 57 void setIntrinsicSize(const IntSize& intrinsicSize) { m_intrinsicSize = intrinsicSize; }
5758 virtual void intrinsicSizeChanged();
58  void setHasIntrinsicSize() { m_hasIntrinsicSize = true; }
5959
6060 virtual void paint(PaintInfo&, const LayoutPoint&);
6161 bool shouldPaint(PaintInfo&, const LayoutPoint&);

@@protected:
6363
6464private:
6565 virtual RenderBox* embeddedContentBox() const { return 0; }
66  int computeIntrinsicLogicalWidth(RenderBox* contentRenderer, bool includeMaxWidth) const;
67  int computeIntrinsicLogicalHeight(RenderBox* contentRenderer) const;
68 
6966 virtual const char* renderName() const { return "RenderReplaced"; }
7067
7168 virtual bool canHaveChildren() const { return false; }
7269
7370 virtual void computePreferredLogicalWidths();
74 
75  int calcAspectRatioLogicalWidth() const;
76  int calcAspectRatioLogicalHeight() const;
77 
7871 virtual void paintReplaced(PaintInfo&, const LayoutPoint&) { }
7972
8073 virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const;

@@private:
8477 virtual bool canBeSelectionLeaf() const { return true; }
8578
8679 virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
 80 void computeIntrinsicRatioInformationForRenderBox(RenderBox*, FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
8781
8882 IntSize m_intrinsicSize;
89  bool m_hasIntrinsicSize;
9083};
9184
9285}

Source/WebCore/svg/graphics/SVGImage.cpp

@@SVGImage::~SVGImage()
102102
103103void SVGImage::setContainerSize(const IntSize&)
104104{
 105 // SVGImageCache already intercepted this call, as it stores & caches the desired container sizes & zoom levels.
105106 ASSERT_NOT_REACHED();
106107}
107108
108 bool SVGImage::usesContainerSize() const
109 {
110  if (!m_page)
111  return false;
112  Frame* frame = m_page->mainFrame();
113  SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement();
114  if (!rootElement)
115  return false;
116  if (RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()))
117  return !renderer->containerSize().isEmpty();
118  return false;
119 }
120 
121109IntSize SVGImage::size() const
122110{
123111 if (!m_page)

Source/WebCore/svg/graphics/SVGImage.h

@@private:
6969 virtual String filenameExtension() const;
7070
7171 virtual void setContainerSize(const IntSize&);
72  virtual bool usesContainerSize() const;
 72 virtual bool usesContainerSize() const { return true; }
7373 virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio, float scaleFactor = 1);
7474
7575 virtual bool dataChanged(bool allDataReceived);

LayoutTests/ChangeLog

112012-03-27 Nikolas Zimmermann <nzimmermann@rim.com>
22
 3 <img style='width: 100%' src='foo.svg'> gets pixellated when stretched
 4 https://bugs.webkit.org/show_bug.cgi?id=81631
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Add new tests covering setting only one of width/height to a percentage when embedding SVGs into <img>s.
 9
 10 * platform/chromium/test_expectations.txt: Update expectations.
 11 * platform/mac/fast/repaint/block-layout-inline-children-replaced-expected.txt: Update changed result - slight rounding difference.
 12 * platform/mac/fast/table/quote-text-around-iframe-expected.png: Update changed result, now the default intrinsic size respects scaling.
 13 * platform/mac/fast/table/quote-text-around-iframe-expected.txt: Ditto.
 14 * svg/as-image/img-relative-height-expected.html: Added.
 15 * svg/as-image/img-relative-height.html: Added.
 16 * svg/as-image/img-relative-width-expected.html: Added.
 17 * svg/as-image/img-relative-width.html: Added.
 18 * svg/as-image/resources/island.svg: Added.
 19 * svg/as-image/svg-non-integer-scaled-image-expected.png:
 20 * svg/as-image/svg-non-integer-scaled-image-expected.txt:
 21
 222012-03-27 Nikolas Zimmermann <nzimmermann@rim.com>
 23
324 SVGAnimatedType should support SVGAnimatedIntegerOptionalInteger animation
425 https://bugs.webkit.org/show_bug.cgi?id=67563
526

LayoutTests/platform/chromium/test_expectations.txt

@@BUGWK72761 : accessibility/anonymous-render-block-in-continuation-causes-crash.h
36523652BUGWK77110 WIN DEBUG : accessibility/loading-iframe-sends-notification.html = PASS TEXT
36533653
36543654BUGWK73494 : svg/text/non-bmp-positioning-lists.svg = IMAGE+TEXT IMAGE
3655 BUGWK73494 : svg/as-image/svg-non-integer-scaled-image.html = IMAGE PASS
 3655// BUGWK73494 : svg/as-image/svg-non-integer-scaled-image.html = IMAGE PASS
36563656
36573657BUGWK73872 LINUX : svg/custom/linking-uri-01-b.svg = PASS TIMEOUT
36583658

@@BUGYANGGUO WIN : svg/css/stars-with-shadow.html = TEXT
41314131BUGWK81325 : fast/canvas/webgl/context-lost.html = TEXT
41324132
41334133// Needs rebaseline due to a progression
4134 BUGWK43022 WIN : tables/mozilla_expected_failures/bugs/bug85016.html = IMAGE
4135 BUGWK43022 MAC : tables/mozilla_expected_failures/bugs/bug85016.html = IMAGE+TEXT
 4134// BUGWK43022 WIN : tables/mozilla_expected_failures/bugs/bug85016.html = IMAGE
 4135// BUGWK43022 MAC : tables/mozilla_expected_failures/bugs/bug85016.html = IMAGE+TEXT
41364136
41374137// flaky tests
41384138BUGWK81493 LINUX : svg/custom/js-late-gradient-creation.svg = PASS IMAGE

@@BUGWK37244 : tables/mozilla/bugs/bug27038-2.html = IMAGE+TEXT
42064206// New test, flaky since added in r110965.
42074207BUGWK82097 : editing/selection/move-by-word-visually-crash-test-5.html = PASS TIMEOUT
42084208
 4209// Just needs a rebaseline. The iframe size is now 600x300, before it was 300x150 - as we properly zoom the default intrinsic size now.
 4210BUGWK81631 : fast/table/quote-text-around-iframe.html = IMAGE IMAGE+TEXT PASS
 4211// Size should be 100 now, instead of 101 - if so, only needs a rebaseline.
 4212BUGWK81631 : svg/as-image/svg-non-integer-scaled-image.html = IMAGE IMAGE+TEXT PASS
 4213// Size changed from 93 to 92 due rounding, just needs a rebaseline.
 4214BUGWK81631 : fast/repaint/block-layout-inline-children-replaced.html = IMAGE IMAGE+TEXT PASS
 4215// Just needs a rebaseline, no visible changes.
 4216BUGWK81631 : fast/writing-mode/block-level-images.html = IMAGE IMAGE+TEXT PASS
 4217// Slight change in image size due to rounding - just needs a rebaseline.
 4218BUGWK81631 : tables/mozilla_expected_failures/bugs/bug85016.html = IMAGE IMAGE+TEXT PASS
 4219
42094220// Temporary: generate platform specific IETestCenter results, then
42104221// remove when bots produce reference.
42114222BUGWK81936 : ietestcenter/css3/text/textshadow-001.htm = FAIL MISSING

LayoutTests/platform/mac/fast/repaint/block-layout-inline-children-replaced-expected.txt

@@layer at (0,0) size 800x600
1111 text run at (220,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=40142"
1212 RenderBlock {DIV} at (0,34) size 800x152
1313 RenderBlock {DIV} at (0,0) size 402x152 [border: (1px solid #DDDDDD)]
14  RenderImage {IMG} at (155,1) size 93x100
 14 RenderImage {IMG} at (155,1) size 92x100

LayoutTests/platform/mac/fast/table/quote-text-around-iframe-expected.png

b63960236d926622b6a7429b023aaee7

44d52bfe1113f4be9bba8a30ed11cf8e

LayoutTests/platform/mac/fast/table/quote-text-around-iframe-expected.txt

11layer at (0,0) size 800x600
22 RenderView at (0,0) size 800x600
3 layer at (0,0) size 800x198
4  RenderBlock {HTML} at (0,0) size 800x198
5  RenderBody {BODY} at (16,16) size 768x166
6  RenderTable at (0,0) size 394x166
7  RenderTableSection (anonymous) at (0,0) size 394x166
8  RenderTableRow {Q} at (0,0) size 394x166
9  RenderTableCell (anonymous) at (0,0) size 394x166 [r=0 c=0 rs=1 cs=1]
 3layer at (0,0) size 800x348
 4 RenderBlock {HTML} at (0,0) size 800x348
 5 RenderBody {BODY} at (16,16) size 768x316
 6 RenderTable at (0,0) size 694x316
 7 RenderTableSection (anonymous) at (0,0) size 694x316
 8 RenderTableRow {Q} at (0,0) size 694x316
 9 RenderTableCell (anonymous) at (0,0) size 694x316 [r=0 c=0 rs=1 cs=1]
1010 RenderInline (generated) at (0,0) size 13x37
11  RenderQuote at (0,129) size 13x37
12  text run at (0,129) width 13: "\""
13  RenderText {#text} at (13,129) size 31x37
14  text run at (13,129) width 31: " A"
15  RenderPartObject {IFRAME} at (44,0) size 308x158 [border: (4px inset #000000)]
16  layer at (0,0) size 300x150
17  RenderView at (0,0) size 300x150
18  layer at (0,0) size 300x150
19  RenderBlock {HTML} at (0,0) size 300x150
20  RenderBody {BODY} at (8,8) size 284x134
21  RenderText {#text} at (352,129) size 29x37
22  text run at (352,129) width 29: "B "
 11 RenderQuote at (0,279) size 13x37
 12 text run at (0,279) width 13: "\""
 13 RenderText {#text} at (13,279) size 31x37
 14 text run at (13,279) width 31: " A"
 15 RenderPartObject {IFRAME} at (44,0) size 608x308 [border: (4px inset #000000)]
 16 layer at (0,0) size 600x300
 17 RenderView at (0,0) size 600x300
 18 layer at (0,0) size 600x300
 19 RenderBlock {HTML} at (0,0) size 600x300
 20 RenderBody {BODY} at (8,8) size 584x284
 21 RenderText {#text} at (652,279) size 29x37
 22 text run at (652,279) width 29: "B "
2323 RenderInline (generated) at (0,0) size 13x37
24  RenderQuote at (381,129) size 13x37
25  text run at (381,129) width 13: "\""
 24 RenderQuote at (681,279) size 13x37
 25 text run at (681,279) width 13: "\""

LayoutTests/svg/as-image/img-relative-height-expected.html

 1<!DOCTYPE html>
 2<html>
 3<body style="margin: 0; overflow: hidden;">
 4<img style='width: 800px; height: 600px' src='resources/island.svg'>
 5</body>
 6</html>

LayoutTests/svg/as-image/img-relative-height.html

 1<!DOCTYPE html>
 2<html>
 3<body style="margin: 0; height: 600px; overflow: hidden;">
 4<img style='height: 100%;' src='resources/island.svg'>
 5</body>
 6</html>

LayoutTests/svg/as-image/img-relative-width-expected.html

 1<!DOCTYPE html>
 2<html>
 3<body style="margin: 0; overflow: hidden;">
 4<img style='width: 800px; height: 600px' src='resources/island.svg'>
 5</body>
 6</html>

LayoutTests/svg/as-image/img-relative-width.html

 1<!DOCTYPE html>
 2<html>
 3<body style="margin: 0; overflow: hidden;">
 4<img style='width: 100%;' src='resources/island.svg'>
 5</body>
 6</html>

LayoutTests/svg/as-image/resources/island.svg

 1<svg width="4" height="3" viewBox='0 0 400 300' xmlns="http://www.w3.org/2000/svg">
 2<circle cx="200" cy="150" r="100" fill="green"/>
 3</svg>

LayoutTests/svg/as-image/svg-non-integer-scaled-image-expected.png

Exception raised during decoding git binary patch:
Error running git apply --directory=.
with patch:
diff --git a/PrettyPatch20260703-38101-e5tliy.bin b/PrettyPatch20260703-38101-1i3tl7a.bin
copy from PrettyPatch20260703-38101-e5tliy.bin
+++ b/PrettyPatch20260703-38101-1i3tl7a.bin
index a51f330d2960c595accc40ef7d8032d3d73fe86c..3392da3ef66b587871915e403ccec41521b8db30
GIT binary patch
delta 152
zcmaDO`Cf8@QKF$mifMA1sewUqilu?ErG=qcQmU~<vO$`uNves7QKE>k&SwS&o<>g>
z$B>FSZ*OkoZ4MA&aeTZ_kg-;9$HwPcH~NqGuufl>cYA&9x%)pKN<N!$RhWU{f!Y15
z%nS?--vu^rWMX9Eo|&7L_LT!DE^7l6P~)0>fJs#JUrQ_h@~;z5tYiQJPgg&ebxsLQ
E0L...
error: ./PrettyPatch20260703-38101-e5tliy.bin: No such file or directory

/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:989:in `block in run_git_apply_on_patch'
/usr/share/ruby/tmpdir.rb:93:in `mktmpdir'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:978:in `run_git_apply_on_patch'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:1035:in `extract_contents_from_git_binary_delta_chunk'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:1058:in `extract_contents_of_to_revision'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:718:in `initialize'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:850:in `new'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:850:in `block in parse'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:850:in `collect'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:850:in `parse'
/var/www/bugs.webkit.org/Websites/bugs.webkit.org/PrettyPatch/PrettyPatch.rb:25:in `prettify'
/var/www/html/PrettyPatch/prettify.rb:30:in `<main>'

LayoutTests/svg/as-image/svg-non-integer-scaled-image-expected.txt

@@layer at (0,0) size 800x600
33layer at (0,0) size 800x600
44 RenderBlock {HTML} at (0,0) size 800x600
55 RenderBody {BODY} at (0,0) size 800x600
6  RenderImage {IMG} at (0,0) size 100x101
 6 RenderImage {IMG} at (0,0) size 100x100
77 RenderText {#text} at (0,0) size 0x0