Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-47094

SVG images naturalWidth/Height bug + proposed solution

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Do
    • Icon: P4: Low P4: Low
    • None
    • 5.3.1
    • WebKit
    • None
    • Linux

      Hi team,

      I am using the latest PhantomJS project, which uses QT Webkit 5.3.1.

      There seems to be a bug when querying the natural width and natural height of an SVG image when the <img> node has a CSS-defined width/height. This URL is a live test example:

      http://staticpages.diffbot.com/smoketest/2943/index_svg.html

      Basically, WebKit thinks the natural width/height of the SVG image is always the width/height of its container, when its not always the case. In this test page, an <img> node points to an external 48x48 SVG image resource, so its natural width/height should be 48 pixels. However, since the <img> was stylized with width:100%, WebKit thinks the natural width of the SVG image is 800+ pixels.

      I don't know SVG documents that well, but believe the part of code that can fix this is in SVGImageCache.cpp. Here is the original source:

      SVGImageCache.cpp
      IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const
      {
          IntSize imageSize = m_svgImage->size();
          if (!renderer)
              return imageSize;
      
          ImageForContainerMap::const_iterator it = m_imageForContainerMap.find(renderer);
          if (it == m_imageForContainerMap.end())
              return imageSize;
      
          RefPtr<SVGImageForContainer> imageForContainer = it->value;
          ASSERT(!imageForContainer->size().isEmpty());
          return imageForContainer->size();
      }
      

      This function always gets the size of the container of the SVG image (if it exists), rather than the size of the image itself. I believe it should first check of the SVG image is just an external image file loaded by an <img> node. If it is just an external image file, then it should just return the size of the image itself; however, if it is created by an SVG document, then it should return the size of its container. Here is my modified code that I compiled and tested on the live test URL (as well as random URLs), and it seems to fix the bug without introducing any new bugs:

      SVGImageCache.cpp
      IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const
      {
          IntSize imageSize = m_svgImage->size();
          if (!renderer)
              return imageSize;
          if (renderer->resourceClientType() != CachedResourceClient::SVGDocumentType)
              return imageSize;
      
          ImageForContainerMap::const_iterator it = m_imageForContainerMap.find(renderer);
          if (it == m_imageForContainerMap.end())
              return imageSize;
      
          RefPtr<SVGImageForContainer> imageForContainer = it->value;
          ASSERT(!imageForContainer->size().isEmpty());
          return imageForContainer->size();
      }
      

      I simply added a check if the resourceClientType is an SVG Document – if it s not of type SVG Document, then it is probably an external image resource, so it returns imageSize.

      If there is a better solution, please keep me updated on this ticket. Would love to see how this bug can be fixed, and I'll help contribute to the project any way I can.

      Thanks!

      Best,
      Kevin

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            albisser Zeno Albisser
            knt261 Kevin Truong
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes