[CSS Shapes] Shape images are now <image> types, not just URIs
authorhmuller@adobe.com <hmuller@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jan 2014 18:16:42 +0000 (18:16 +0000)
committerhmuller@adobe.com <hmuller@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jan 2014 18:16:42 +0000 (18:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=125224

Reviewed by Andreas Kling.

Source/WebCore:

Added support for image-set valued shapes. Added an optional ResourceLoaderOptions
parameter to CSSImageSetValue::cachedImageSet() to enable CORS-enabled fetch of
image-set images. This change is based on a similar patch for ordinary shape image values:
https://bugs.webkit.org/show_bug.cgi?id=123114.

Tests: fast/shapes/shape-inside/shape-inside-image-set.html
       fast/shapes/shape-outside-floats/shape-outside-image-set.html

* css/CSSImageSetValue.cpp:
(WebCore::CSSImageSetValue::cachedImageSet):
* css/CSSImageSetValue.h:
* css/CSSParser.cpp:
(WebCore::CSSParser::parseShapeProperty):
* css/DeprecatedStyleBuilder.cpp:
(WebCore::ApplyPropertyShape::applyValue):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::loadPendingImage):
(WebCore::StyleResolver::loadPendingShapeImage):
* css/StyleResolver.h:
* rendering/shapes/Shape.cpp:
(WebCore::Shape::createShape):

LayoutTests:

* fast/shapes/shape-inside/shape-inside-image-set-expected.html: Added.
* fast/shapes/shape-inside/shape-inside-image-set.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-image-set-expected.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-image-set.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@161980 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/shapes/shape-inside/shape-inside-image-set-expected.html [new file with mode: 0644]
LayoutTests/fast/shapes/shape-inside/shape-inside-image-set.html [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set-expected.html [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSImageSetValue.cpp
Source/WebCore/css/CSSImageSetValue.h
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/DeprecatedStyleBuilder.cpp
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/rendering/shapes/Shape.cpp
Source/WebCore/rendering/shapes/Shape.h
Source/WebCore/rendering/shapes/ShapeInfo.cpp

index 4f0c300..e9de517 100644 (file)
@@ -1,3 +1,15 @@
+2014-01-14  Hans Muller  <hmuller@adobe.com>
+
+        [CSS Shapes] Shape images are now <image> types, not just URIs
+        https://bugs.webkit.org/show_bug.cgi?id=125224
+
+        Reviewed by Andreas Kling.
+
+        * fast/shapes/shape-inside/shape-inside-image-set-expected.html: Added.
+        * fast/shapes/shape-inside/shape-inside-image-set.html: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-image-set-expected.html: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-image-set.html: Added.
+
 2014-01-14  Brent Fulgham  <bfulgham@apple.com>
 
         [WebGL] Invalid range checking in WebGLRenderContext::validateTexFunctionLevel
diff --git a/LayoutTests/fast/shapes/shape-inside/shape-inside-image-set-expected.html b/LayoutTests/fast/shapes/shape-inside/shape-inside-image-set-expected.html
new file mode 100644 (file)
index 0000000..9fee239
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #image-shape-inside {
+        padding-left: 20px;
+        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140px' height='50px'><rect x='20' y='0' width='120' height='50' fill='blue'/></svg>");
+        background-repeat: no-repeat;
+        width: 150px; 
+        height: 50px; 
+    }
+</style>
+</head>
+<body>
+  <p>The white "Hello World" should appear in the upper left of the blue rectangle.</p>
+  <div style="color: white">
+      <div id="image-shape-inside">Hello World</div>
+  </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/shapes/shape-inside/shape-inside-image-set.html b/LayoutTests/fast/shapes/shape-inside/shape-inside-image-set.html
new file mode 100644 (file)
index 0000000..fde5b12
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #image-shape-inside {
+        -webkit-shape-inside: -webkit-image-set(url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140px' height='50px'><rect x='20' y='0' width='120' height='50' fill='blue'/></svg>") 1x);
+        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140px' height='50px'><rect x='20' y='0' width='120' height='50' fill='blue'/></svg>");
+        background-repeat: no-repeat;
+        width: 150px; 
+        height: 50px; 
+    }
+</style>
+</head>
+<body>
+  <p>The white "Hello World" should appear in the upper left of the blue rectangle.</p>
+  <div style="color: white">
+      <div id="image-shape-inside">Hello World</div>
+  </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set-expected.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set-expected.html
new file mode 100644 (file)
index 0000000..1e793bd
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #image-shape-outside {
+        float: left;
+        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120px' height='50px'><rect x='0' y='0' width='120' height='50' fill='blue'/></svg>");
+        background-repeat: no-repeat;
+        width: 120px; 
+        height: 50px; 
+    }
+</style>
+</head>
+<body>
+  <p>The green "Hello World" should appear to the right of the blue rectangle.</p>
+  <div style="color: green">
+      <div id="image-shape-outside"></div>
+      Hello World
+  </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-image-set.html
new file mode 100644 (file)
index 0000000..9939d76
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #image-shape-outside {
+        float: left;
+        /* The shape-outside image's width is smaller than the float's width (120 < 150) to make it
+           clear that the shape-outside defines the starting location for the text, not the float.
+        */
+        -webkit-shape-outside: -webkit-image-set(url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120px' height='50px'><rect x='0' y='0' width='120' height='50' fill='blue'/></svg>") 1x);
+        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120px' height='50px'><rect x='0' y='0' width='120' height='50' fill='blue'/></svg>");
+        background-repeat: no-repeat;
+        width: 150px; 
+        height: 50px; 
+    }
+</style>
+</head>
+<body>
+  <p>The green "Hello World" should appear to the right of the blue rectangle.</p>
+  <div style="color: green">
+      <div id="image-shape-outside"></div>
+      Hello World
+  </div>
+</body>
+</html>
index 14f7ed1..5cff3c9 100644 (file)
@@ -1,3 +1,32 @@
+2014-01-14  Hans Muller  <hmuller@adobe.com>
+
+        [CSS Shapes] Shape images are now <image> types, not just URIs
+        https://bugs.webkit.org/show_bug.cgi?id=125224
+
+        Reviewed by Andreas Kling.
+
+        Added support for image-set valued shapes. Added an optional ResourceLoaderOptions
+        parameter to CSSImageSetValue::cachedImageSet() to enable CORS-enabled fetch of
+        image-set images. This change is based on a similar patch for ordinary shape image values:
+        https://bugs.webkit.org/show_bug.cgi?id=123114.
+
+        Tests: fast/shapes/shape-inside/shape-inside-image-set.html
+               fast/shapes/shape-outside-floats/shape-outside-image-set.html
+
+        * css/CSSImageSetValue.cpp:
+        (WebCore::CSSImageSetValue::cachedImageSet):
+        * css/CSSImageSetValue.h:
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseShapeProperty):
+        * css/DeprecatedStyleBuilder.cpp:
+        (WebCore::ApplyPropertyShape::applyValue):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::loadPendingImage):
+        (WebCore::StyleResolver::loadPendingShapeImage):
+        * css/StyleResolver.h:
+        * rendering/shapes/Shape.cpp:
+        (WebCore::Shape::createShape):
+
 2014-01-13  Chris Fleizach  <cfleizach@apple.com>
 
         AX: Modernize AccessibilityChildrenVector loops
index 3e6c181..b031cc2 100644 (file)
@@ -34,6 +34,7 @@
 #include "CachedResourceLoader.h"
 #include "CachedResourceRequest.h"
 #include "CachedResourceRequestInitiators.h"
+#include "CrossOriginAccessControl.h"
 #include "Document.h"
 #include "Page.h"
 #include "StyleCachedImageSet.h"
@@ -100,7 +101,7 @@ CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
     return image;
 }
 
-StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* loader)
+StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* loader, const ResourceLoaderOptions& options)
 {
     ASSERT(loader);
 
@@ -118,8 +119,10 @@ StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* load
         // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(),
         // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
         ImageWithScale image = bestImageForScaleFactor();
-        CachedResourceRequest request(ResourceRequest(document->completeURL(image.imageURL)));
+        CachedResourceRequest request(ResourceRequest(document->completeURL(image.imageURL)), options);
         request.setInitiator(cachedResourceRequestInitiators().css);
+        if (options.requestOriginPolicy == PotentiallyCrossOriginEnabled)
+            updateRequestForAccessControl(request.mutableResourceRequest(), document->securityOrigin(), options.allowCredentials);
         if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) {
             detachPendingImage();
             m_imageSet = StyleCachedImageSet::create(cachedImage.get(), image.scaleFactor, this);
@@ -130,6 +133,11 @@ StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* load
     return (m_imageSet && m_imageSet->isCachedImageSet()) ? static_cast<StyleCachedImageSet*>(m_imageSet.get()) : 0;
 }
 
+StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* loader)
+{
+    return cachedImageSet(loader, CachedResourceLoader::defaultCachedResourceOptions());
+}
+
 StyleImage* CSSImageSetValue::cachedOrPendingImageSet(Document& document)
 {
     if (!m_imageSet)
index 41c0c18..c1899f3 100644 (file)
@@ -36,6 +36,7 @@ class CachedResourceLoader;
 class Document;
 class StyleCachedImageSet;
 class StyleImage;
+struct ResourceLoaderOptions;
 
 class CSSImageSetValue : public CSSValueList {
 public:
@@ -46,6 +47,7 @@ public:
     }
     ~CSSImageSetValue();
 
+    StyleCachedImageSet* cachedImageSet(CachedResourceLoader*, const ResourceLoaderOptions&);
     StyleCachedImageSet* cachedImageSet(CachedResourceLoader*);
 
     // Returns a StyleCachedImageSet if the best fit image has been cached already, otherwise a StylePendingImage.
index b706ae2..bec638c 100644 (file)
@@ -5881,8 +5881,8 @@ PassRefPtr<CSSValue> CSSParser::parseShapeProperty(CSSPropertyID propId)
         return keywordValue.release();
     }
 
-    if (value->unit == CSSPrimitiveValue::CSS_URI) {
-        RefPtr<CSSImageValue> imageValue = CSSImageValue::create(completeURL(value->string));
+    RefPtr<CSSValue> imageValue;
+    if (valueId != CSSValueNone && parseFillImage(m_valueList.get(), imageValue)) {
         m_valueList->next();
         return imageValue.release();
     }
index 38c08c8..9f2ea63 100644 (file)
@@ -2151,7 +2151,7 @@ public:
                 RefPtr<ShapeValue> shape = ShapeValue::createShapeValue(basicShapeForValue(styleResolver->style(), styleResolver->rootElementStyle(), primitiveValue->getShapeValue()));
                 setValue(styleResolver->style(), shape.release());
             }
-        } else if (value->isImageValue()) {
+        } else if (value->isImageValue() || value->isImageSetValue()) {
             RefPtr<ShapeValue> shape = ShapeValue::createImageValue(styleResolver->styleImage(property, value));
             setValue(styleResolver->style(), shape.release());
         }
index 01d60c2..6bfa304 100644 (file)
@@ -3935,10 +3935,10 @@ bool StyleResolver::createFilterOperations(CSSValue* inValue, FilterOperations&
 
 #endif
 
-PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage)
+PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage, const ResourceLoaderOptions& options)
 {
     if (auto imageValue = pendingImage->cssImageValue())
-        return imageValue->cachedImage(m_state.document().cachedResourceLoader());
+        return imageValue->cachedImage(m_state.document().cachedResourceLoader(), options);
 
     if (auto imageGeneratorValue = pendingImage->cssImageGeneratorValue()) {
         imageGeneratorValue->loadSubimages(m_state.document().cachedResourceLoader());
@@ -3950,12 +3950,16 @@ PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendin
 
 #if ENABLE(CSS_IMAGE_SET)
     if (CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue())
-        return imageSetValue->cachedImageSet(m_state.document().cachedResourceLoader());
+        return imageSetValue->cachedImageSet(m_state.document().cachedResourceLoader(), options);
 #endif
 
     return nullptr;
 }
 
+PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage)
+{
+    return loadPendingImage(pendingImage, CachedResourceLoader::defaultCachedResourceOptions());
+}
 
 #if ENABLE(CSS_SHAPES)
 void StyleResolver::loadPendingShapeImage(ShapeValue* shapeValue)
@@ -3968,14 +3972,12 @@ void StyleResolver::loadPendingShapeImage(ShapeValue* shapeValue)
         return;
 
     StylePendingImage* pendingImage = static_cast<StylePendingImage*>(image);
-    CSSImageValue* cssImageValue =  pendingImage->cssImageValue();
-    CachedResourceLoader* cachedResourceLoader = m_state.document().cachedResourceLoader();
 
     ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
     options.requestOriginPolicy = PotentiallyCrossOriginEnabled;
     options.allowCredentials = DoNotAllowStoredCredentials;
 
-    shapeValue->setImage(cssImageValue->cachedImage(cachedResourceLoader, options));
+    shapeValue->setImage(loadPendingImage(pendingImage, options));
 }
 #endif
 
index 1a03339..ca186e9 100644 (file)
@@ -539,6 +539,7 @@ private:
     void applySVGProperty(CSSPropertyID, CSSValue*);
 #endif
 
+    PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*, const ResourceLoaderOptions&);
     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*);
     void loadPendingImages();
 #if ENABLE(CSS_SHAPES)
index 7bc7445..0793543 100644 (file)
@@ -251,11 +251,12 @@ PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
     return shape.release();
 }
 
-PassOwnPtr<Shape> Shape::createRasterShape(const StyleImage* styleImage, float threshold, const LayoutSize&, WritingMode writingMode, Length margin, Length padding)
+PassOwnPtr<Shape> Shape::createRasterShape(const StyleImage& styleImage, float threshold, const LayoutSize&, WritingMode writingMode, Length margin, Length padding)
 {
-    ASSERT(styleImage && styleImage->isCachedImage() && styleImage->cachedImage() && styleImage->cachedImage()->image());
+    ASSERT(styleImage.cachedImage());
+    ASSERT(styleImage.cachedImage()->hasImage());
 
-    Image* image = styleImage->cachedImage()->image();
+    Image* image = styleImage.cachedImage()->image();
     const IntSize& imageSize = image->size();
 
     OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(imageSize.height()));
index 97af6f8..44ae624 100644 (file)
@@ -68,7 +68,7 @@ public:
     };
 
     static PassOwnPtr<Shape> createShape(const BasicShape*, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
-    static PassOwnPtr<Shape> createRasterShape(const StyleImage*, float threshold, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
+    static PassOwnPtr<Shape> createRasterShape(const StyleImage&, float threshold, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
     static PassOwnPtr<Shape> createLayoutBoxShape(const RoundedRect&, WritingMode, Length margin, Length padding);
 
     virtual ~Shape() { }
index b194bd7..e76df6a 100644 (file)
@@ -74,7 +74,7 @@ const Shape& ShapeInfo<RenderType>::computedShape() const
         break;
     case ShapeValue::Image:
         ASSERT(shapeValue->image());
-        m_shape = Shape::createRasterShape(shapeValue->image(), shapeImageThreshold, m_shapeLogicalSize, writingMode, margin, padding);
+        m_shape = Shape::createRasterShape(*(shapeValue->image()), shapeImageThreshold, m_shapeLogicalSize, writingMode, margin, padding);
         break;
     case ShapeValue::Box: {
         const RoundedRect& shapeRect = m_renderer.style().getRoundedBorderFor(LayoutRect(LayoutPoint(), m_shapeLogicalSize), &(m_renderer.view()));