Changeset 254861 in webkit
- Timestamp:
- Jan 21, 2020 10:28:17 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 16 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r254860 r254861 1 2020-01-21 Noam Rosenthal <noam@webkit.org> 2 3 -webkit-image-set should support all the image functions WebKit supports, not just url() 4 https://bugs.webkit.org/show_bug.cgi?id=81941 5 6 Reviewed by Darin Adler. 7 8 * fast/css/cursor-parsing-expected.txt: 9 * fast/css/cursor-parsing.html: 10 Added parsing test to ensure arrow image-sets disable generated images 11 12 * fast/css/image-set-parsing-generated-expected.txt: Added. 13 * fast/css/image-set-parsing-generated.html: Added. 14 * fast/css/image-set-parsing-invalid-expected.txt: 15 * fast/css/image-set-parsing-invalid.html: 16 Added parsing tests for new generated-inside-image-set use cases 17 Test that image-set inside image-set is not supported 18 19 * fast/hidpi/image-set-cross-fade-expected.html: Added. 20 * fast/hidpi/image-set-cross-fade.html: Added. 21 * fast/hidpi/image-set-gradient-expected.html: Added. 22 * fast/hidpi/image-set-gradient-multi-expected.html: Added. 23 * fast/hidpi/image-set-gradient-multi.html: Added. 24 * fast/hidpi/image-set-gradient-single-expected.html: Added. 25 * fast/hidpi/image-set-gradient-single.html: Added. 26 * fast/hidpi/image-set-gradient.html: Added. 27 Added ref-tests for several generated-inside-image-set use-cases 28 1 29 2020-01-21 Chris Dumez <cdumez@apple.com> 2 30 -
trunk/LayoutTests/fast/css/cursor-parsing-expected.txt
r231359 r254861 63 63 PASS roundtripCssRule("cursor: url(file:///foo.png) x y;").cssText is "" 64 64 PASS roundtripCssRule("cursor: url(file:///foo.png) auto;").cssText is "" 65 66 Test a bunch of cursor rules with generated images. 67 PASS roundtripCssRule("cursor: linear-gradient(red, white) -1 -1, pointer;").cssText is "" 68 PASS roundtripCssRule("cursor: image-set(linear-gradient(red, white) 1x) -1 -1, pointer;").cssText is "" 65 69 PASS successfullyParsed is true 66 70 -
trunk/LayoutTests/fast/css/cursor-parsing.html
r231359 r254861 106 106 testInvalidCursorRule('url(file:///foo.png) auto'); 107 107 108 debug(''); 109 debug('Test a bunch of cursor rules with generated images.'); 110 testInvalidCursorRule('linear-gradient(red, white) -1 -1, pointer'); 111 testInvalidCursorRule('image-set(linear-gradient(red, white) 1x) -1 -1, pointer'); 112 108 113 successfullyParsed = true; 109 114 </script> -
trunk/LayoutTests/fast/css/image-set-parsing-invalid-expected.txt
r254406 r254861 19 19 Scale factor is 0 : url('#a') 0x 20 20 PASS cssRule is null 21 22 Generated image for cursor : linear-gradient(black, white) 1x 23 PASS cssRule is null 24 25 Image-set inside image-set : image-set(image-set(url('#a') 1x) 1x) 26 PASS cssRule is null 21 27 PASS successfullyParsed is true 22 28 -
trunk/LayoutTests/fast/css/image-set-parsing-invalid.html
r254406 r254861 33 33 testInvalidImageSet("Too many scale factor parameters", "background-image", "url('#a') 1x 2x"); 34 34 testInvalidImageSet("Scale factor is 0", "background-image", "url('#a') 0x"); 35 testInvalidImageSet("Generated image for cursor", "cursor", "linear-gradient(black, white) 1x"); 36 testInvalidImageSet("Image-set inside image-set", "background-image", "image-set(image-set(url('#a') 1x) 1x)"); 35 37 36 38 successfullyParsed = true; -
trunk/Source/WebCore/ChangeLog
r254859 r254861 1 2020-01-21 Noam Rosenthal <noam@webkit.org> 2 3 -webkit-image-set should support all the image functions WebKit supports, not just url() 4 https://bugs.webkit.org/show_bug.cgi?id=81941 5 6 Reviewed by Darin Adler. 7 8 Separate StyleCachedImage to 4 classes: 9 - StyleCachedImage: for single images only 10 - StyleMultiImage: for values that can contain multiple images: like cursor/image-set 11 - StyleImageSet 12 - StyleCursorImage 13 14 The new classes only deal with their own value type. Before, ImageSet and cursor were resolved 15 as a StyleCachedImage, which is no longer a valid assumption if image-set can contain generated images. 16 Though cursors still can only contain cached images, it was cleaner to refactor it out as well. 17 18 Refactored best-fit image selection from loading. Now StyleCachedImage is in charge of loading 19 the actual image, and StyleImageSet/StyleCursorImage perform the source selection. 20 21 Also, added the necessary logic in the CSS parser to consume generated images inside image-sets, excluding 22 when the image-set is a cursor value. 23 24 Tests: fast/css/image-set-parsing-generated.html 25 fast/hidpi/image-set-cross-fade.html 26 fast/hidpi/image-set-gradient-multi.html 27 fast/hidpi/image-set-gradient-single.html 28 fast/hidpi/image-set-gradient.html 29 30 * Sources.txt: 31 * WebCore.xcodeproj/project.pbxproj: 32 Added new files 33 34 * css/CSSCursorImageValue.cpp: 35 (WebCore::CSSCursorImageValue::selectBestFitImage): 36 (WebCore::CSSCursorImageValue::loadImage): Deleted. 37 * css/CSSCursorImageValue.h: 38 Instead of cursor loading the image, it selects an image CSS value 39 40 * css/CSSImageSetValue.cpp: 41 (WebCore::CSSImageSetValue::CSSImageSetValue): 42 (WebCore::CSSImageSetValue::fillImageSet): 43 (WebCore::CSSImageSetValue::cachedImage const): 44 (WebCore::CSSImageSetValue::selectBestFitImage): 45 (WebCore::CSSImageSetValue::updateDeviceScaleFactor): 46 (WebCore::CSSImageSetValue::imageSetWithStylesResolved): 47 (WebCore::CSSImageSetValue::traverseSubresources const): 48 (WebCore::CSSImageSetValue::loadBestFitImage): Deleted. 49 * css/CSSImageSetValue.h: 50 Refactor CSSImageSetValue to include non-cachedImage images 51 52 * css/parser/CSSPropertyParser.cpp: 53 (WebCore::consumeCursor): 54 * css/parser/CSSPropertyParserHelpers.cpp: 55 (WebCore::CSSPropertyParserHelpers::consumeImageSet): 56 (WebCore::CSSPropertyParserHelpers::consumeImage): 57 (WebCore::CSSPropertyParserHelpers::consumeUrlOrStringAsStringView): Deleted. 58 * css/parser/CSSPropertyParserHelpers.h: 59 60 * page/animation/CSSPropertyAnimation.cpp: 61 (WebCore::blendFunc): 62 When blending two images, get the selected images in case it is an image-set 63 64 * rendering/RenderBoxModelObject.cpp: 65 (WebCore::RenderBoxModelObject::paintFillLayerExtended): 66 * rendering/RenderImageResourceStyleImage.cpp: 67 (WebCore::RenderImageResourceStyleImage::initialize): 68 * rendering/RenderLayerBacking.cpp: 69 (WebCore::canDirectlyCompositeBackgroundBackgroundImage): 70 * rendering/style/ShapeValue.cpp: 71 (WebCore::ShapeValue::isImageValid const): 72 Use hasCachedImage() instead of isCachedImage() as a StyleImageSet is no longer an isCachedImage() 73 74 * rendering/style/StyleCachedImage.cpp: 75 (WebCore::StyleCachedImage::StyleCachedImage): 76 (WebCore::StyleCachedImage::imageURL): 77 (WebCore::StyleCachedImage::load): 78 * rendering/style/StyleCachedImage.h: 79 * rendering/style/StyleCursorImage.h: 80 * rendering/style/StyleCursorImage.cpp: 81 * rendering/style/StyleMultiImage.h: 82 * rendering/style/StyleMultiImage.cpp: 83 * rendering/style/StyleImageSet.h: 84 * rendering/style/StyleImageSet.cpp: 85 * rendering/style/StyleImage.h: 86 (WebCore::StyleImage::selectedImage): 87 (WebCore::StyleImage::selectedImage const): 88 (WebCore::StyleImage::isCursorImage const): 89 (WebCore::StyleImage::isImageSet const): 90 (WebCore::StyleImage::hasCachedImage const): 91 (WebCore::StyleImage::StyleImage): 92 Separate cursor/image-set related stuff away from StyleCachedImage. 93 94 * style/StyleBuilderCustom.h: 95 (WebCore::Style::BuilderCustom::applyValueContent): 96 * style/StyleBuilderState.cpp: 97 (WebCore::Style::BuilderState::resolveImageStyles): 98 (WebCore::Style::BuilderState::createStyleImage): 99 * style/StyleBuilderState.h: 100 Match the CSS values with the correct Style class. Also, ensure image-sets resolve their 101 images' styles as they may contain gradients and other context-aware values. 102 1 103 2020-01-21 Chris Dumez <cdumez@apple.com> 2 104 -
trunk/Source/WebCore/Sources.txt
r254849 r254861 2263 2263 rendering/style/StyleBoxData.cpp 2264 2264 rendering/style/StyleCachedImage.cpp 2265 rendering/style/StyleCursorImage.cpp 2265 2266 rendering/style/StyleDeprecatedFlexibleBoxData.cpp 2266 2267 rendering/style/StyleFilterData.cpp … … 2269 2270 rendering/style/StyleGridData.cpp 2270 2271 rendering/style/StyleGridItemData.cpp 2272 rendering/style/StyleImageSet.cpp 2271 2273 rendering/style/StyleInheritedData.cpp 2272 2274 rendering/style/StyleMarqueeData.cpp 2273 2275 rendering/style/StyleMultiColData.cpp 2276 rendering/style/StyleMultiImage.cpp 2274 2277 rendering/style/StyleRareInheritedData.cpp 2275 2278 rendering/style/StyleRareNonInheritedData.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r254817 r254861 13723 13723 C9DADBCA1B1D3B25001F17D8 /* JSMediaSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaSession.h; sourceTree = "<group>"; }; 13724 13724 C9F87CFD1B28E5F600979B83 /* MediaSessionEvents.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = MediaSessionEvents.h; sourceTree = "<group>"; }; 13725 CA091D8623CF907800AD4346 /* StyleImageSet.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleImageSet.cpp; sourceTree = "<group>"; }; 13726 CA091D8923CF908800AD4346 /* StyleImageSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleImageSet.h; sourceTree = "<group>"; }; 13725 13727 CA1635DC2072E76900E7D2CE /* ReferrerPolicy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReferrerPolicy.cpp; sourceTree = "<group>"; }; 13726 13728 CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; }; 13727 13729 CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; }; 13730 CA52BAE523D0AF1600DE0B84 /* StyleCursorImage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleCursorImage.cpp; sourceTree = "<group>"; }; 13731 CA52BAE723D0AF1700DE0B84 /* StyleMultiImage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleMultiImage.cpp; sourceTree = "<group>"; }; 13732 CA52BAE823D0AF1800DE0B84 /* StyleMultiImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleMultiImage.h; sourceTree = "<group>"; }; 13733 CA52BAE923D0AF1900DE0B84 /* StyleCursorImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleCursorImage.h; sourceTree = "<group>"; }; 13728 13734 CA6C152F220B4A550055CBFC /* JSIDBRequestCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBRequestCustom.cpp; sourceTree = "<group>"; }; 13729 13735 CA6C1537220D1EB30055CBFC /* JSIDBCursorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorCustom.cpp; sourceTree = "<group>"; }; … … 25563 25569 1C0AA16A21940DC700896829 /* StyleColorScheme.h */, 25564 25570 9DAC7C561AF2CB6400437C44 /* StyleContentAlignmentData.h */, 25571 CA52BAE523D0AF1600DE0B84 /* StyleCursorImage.cpp */, 25572 CA52BAE923D0AF1900DE0B84 /* StyleCursorImage.h */, 25565 25573 BC779E151BB226A200CAA8BF /* StyleCustomPropertyData.h */, 25566 25574 BC5EB8B60E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.cpp */, … … 25577 25585 A110DB9A14F5DF7700A03B93 /* StyleGridItemData.h */, 25578 25586 BCEF43CE0E673DA1001C1287 /* StyleImage.h */, 25587 CA091D8623CF907800AD4346 /* StyleImageSet.cpp */, 25588 CA091D8923CF908800AD4346 /* StyleImageSet.h */, 25579 25589 BC2273010E82F1E600E7F975 /* StyleInheritedData.cpp */, 25580 25590 BC2273020E82F1E600E7F975 /* StyleInheritedData.h */, … … 25583 25593 BC5EB74B0E81E06700B25965 /* StyleMultiColData.cpp */, 25584 25594 BC5EB74C0E81E06700B25965 /* StyleMultiColData.h */, 25595 CA52BAE723D0AF1700DE0B84 /* StyleMultiImage.cpp */, 25596 CA52BAE823D0AF1800DE0B84 /* StyleMultiImage.h */, 25585 25597 BC2272E10E82EE9B00E7F975 /* StyleRareInheritedData.cpp */, 25586 25598 BC2272E20E82EE9B00E7F975 /* StyleRareInheritedData.h */, … … 31369 31381 6F26BB6C23343E6F002F2BEA /* LayoutContext.h in Headers */, 31370 31382 11310CF520BA4A4C0065A8D0 /* LayoutDescendantIterator.h in Headers */, 31383 E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */, 31371 31384 E4ABABDD236088FE00FA4345 /* LayoutIntegrationLineLayout.h in Headers */, 31372 31385 11310CF420BA4A3D0065A8D0 /* LayoutIterator.h in Headers */, … … 32063 32076 0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */, 32064 32077 AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */, 32065 E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,32066 32078 31955A88160D199200858025 /* RenderSnapshottedPlugIn.h in Headers */, 32067 32079 BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */, -
trunk/Source/WebCore/css/CSSCursorImageValue.cpp
r246034 r254861 96 96 } 97 97 98 std::pair<CachedImage*, float> CSSCursorImageValue::loadImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options)98 ImageWithScale CSSCursorImageValue::selectBestFitImage(const Document& document) 99 99 { 100 100 if (is<CSSImageSetValue>(m_imageValue.get())) 101 return downcast<CSSImageSetValue>(m_imageValue.get()). loadBestFitImage(loader, options);101 return downcast<CSSImageSetValue>(m_imageValue.get()).selectBestFitImage(document); 102 102 103 if (auto* cursorElement = updateCursorElement( *loader.document())) {103 if (auto* cursorElement = updateCursorElement(document)) { 104 104 if (cursorElement->href() != downcast<CSSImageValue>(m_imageValue.get()).url()) 105 m_imageValue = CSSImageValue::create( loader.document()->completeURL(cursorElement->href()), m_loadedFromOpaqueSource);105 m_imageValue = CSSImageValue::create(document.completeURL(cursorElement->href()), m_loadedFromOpaqueSource); 106 106 } 107 107 108 return { downcast<CSSImageValue>(m_imageValue.get()).loadImage(loader, options), 1 };108 return { m_imageValue.ptr() , 1 }; 109 109 } 110 110 -
trunk/Source/WebCore/css/CSSCursorImageValue.h
r238698 r254861 35 35 class SVGElement; 36 36 37 struct ImageWithScale; 38 39 namespace Style { 40 class BuilderState; 41 } 42 37 43 class CSSCursorImageValue final : public CSSValue { 38 44 public: … … 57 63 String customCSSText() const; 58 64 59 std::pair<CachedImage*, float> loadImage(CachedResourceLoader&, const ResourceLoaderOptions&);65 ImageWithScale selectBestFitImage(const Document&); 60 66 61 67 void removeReferencedElement(SVGElement*); -
trunk/Source/WebCore/css/CSSImageSetValue.cpp
r238698 r254861 29 29 #include "CSSImageValue.h" 30 30 #include "CSSPrimitiveValue.h" 31 #include "CachedImage.h"32 #include "CachedResourceLoader.h"33 #include "CachedResourceRequest.h"34 #include "CachedResourceRequestInitiators.h"35 31 #include "Document.h" 36 32 #include "Page.h" 33 #include "StyleBuilderState.h" 37 34 #include <wtf/text/StringBuilder.h> 38 35 39 36 namespace WebCore { 40 37 41 CSSImageSetValue::CSSImageSetValue(LoadedFromOpaqueSource loadedFromOpaqueSource) 38 Ref<CSSImageSetValue> CSSImageSetValue::create() 39 { 40 return adoptRef(*new CSSImageSetValue); 41 } 42 43 CSSImageSetValue::CSSImageSetValue() 42 44 : CSSValueList(ImageSetClass, CommaSeparator) 43 , m_loadedFromOpaqueSource(loadedFromOpaqueSource)44 45 { 45 46 } … … 53 54 while (i < length) { 54 55 CSSValue* imageValue = item(i); 55 URL imageURL = downcast<CSSImageValue>(*imageValue).url(); 56 56 ASSERT(is<CSSImageValue>(imageValue) || is<CSSImageGeneratorValue>(imageValue)); 57 57 ++i; 58 58 ASSERT_WITH_SECURITY_IMPLICATION(i < length); … … 61 61 62 62 ImageWithScale image; 63 image. imageURL = imageURL;63 image.value = imageValue; 64 64 image.scaleFactor = scaleFactor; 65 65 m_imagesInSet.append(image); … … 71 71 } 72 72 73 CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()73 ImageWithScale CSSImageSetValue::bestImageForScaleFactor() 74 74 { 75 75 if (!m_imagesInSet.size()) … … 86 86 } 87 87 88 std::pair<CachedImage*, float> CSSImageSetValue::loadBestFitImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options) 88 CachedImage* CSSImageSetValue::cachedImage() const 89 89 { 90 Document* document = loader.document(); 91 ASSERT(document); 90 if (is<CSSImageValue>(m_selectedImageValue)) 91 return downcast<CSSImageValue>(*m_selectedImageValue).cachedImage(); 92 return nullptr; 93 } 92 94 93 updateDeviceScaleFactor(*document); 95 ImageWithScale CSSImageSetValue::selectBestFitImage(const Document& document) 96 { 97 updateDeviceScaleFactor(document); 94 98 95 99 if (!m_accessedBestFitImage) { 96 100 m_accessedBestFitImage = true; 101 m_bestFitImage = bestImageForScaleFactor(); 102 } 97 103 98 // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here. 99 // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(), 100 // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 101 ImageWithScale image = bestImageForScaleFactor(); 102 103 ResourceLoaderOptions loadOptions = options; 104 loadOptions.loadedFromOpaqueSource = m_loadedFromOpaqueSource; 105 CachedResourceRequest request(ResourceRequest(document->completeURL(image.imageURL)), loadOptions); 106 request.setInitiator(cachedResourceRequestInitiators().css); 107 if (options.mode == FetchOptions::Mode::Cors) 108 request.updateForAccessControl(*document); 109 110 m_cachedImage = loader.requestImage(WTFMove(request)).value_or(nullptr); 111 m_bestFitImageScaleFactor = image.scaleFactor; 112 } 113 return { m_cachedImage.get(), m_bestFitImageScaleFactor }; 104 return m_bestFitImage; 114 105 } 115 106 116 107 void CSSImageSetValue::updateDeviceScaleFactor(const Document& document) 117 108 { 109 110 // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here. 111 // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(), 112 // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 118 113 float deviceScaleFactor = document.page() ? document.page()->deviceScaleFactor() : 1; 119 114 if (deviceScaleFactor == m_deviceScaleFactor) … … 121 116 m_deviceScaleFactor = deviceScaleFactor; 122 117 m_accessedBestFitImage = false; 123 m_cachedImage = nullptr; 118 m_selectedImageValue = nullptr; 119 } 120 121 Ref<CSSImageSetValue> CSSImageSetValue::imageSetWithStylesResolved(Style::BuilderState& builderState) 122 { 123 Ref<CSSImageSetValue> result = CSSImageSetValue::create(); 124 size_t length = this->length(); 125 for (size_t i = 0; i + 1 < length; i += 2) { 126 result->append(builderState.resolveImageStyles(*itemWithoutBoundsCheck(i))); 127 result->append(*itemWithoutBoundsCheck(i + 1)); 128 } 129 130 return result; 124 131 } 125 132 … … 156 163 bool CSSImageSetValue::traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const 157 164 { 158 if (!m_cachedImage) 159 return false; 160 return handler(*m_cachedImage); 165 return m_selectedImageValue && m_selectedImageValue->traverseSubresources(handler); 161 166 } 162 167 -
trunk/Source/WebCore/css/CSSImageSetValue.h
r238698 r254861 30 30 #include "ResourceLoaderOptions.h" 31 31 #include <wtf/Function.h> 32 #include <wtf/RefPtr.h> 32 33 33 34 namespace WebCore { … … 35 36 class CachedImage; 36 37 class CachedResourceLoader; 38 class CSSImageValue; 37 39 class Document; 40 41 namespace Style { 42 class BuilderState; 43 } 44 45 struct ImageWithScale { 46 RefPtr<CSSValue> value; 47 float scaleFactor { 1 }; 48 }; 38 49 39 50 class CSSImageSetValue final : public CSSValueList { 40 51 public: 41 static Ref<CSSImageSetValue> create(LoadedFromOpaqueSource loadedFromOpaqueSource) 42 { 43 return adoptRef(*new CSSImageSetValue(loadedFromOpaqueSource)); 44 } 52 static Ref<CSSImageSetValue> create(); 45 53 ~CSSImageSetValue(); 46 54 47 std::pair<CachedImage*, float> loadBestFitImage(CachedResourceLoader&, const ResourceLoaderOptions&);48 CachedImage* cachedImage() const { return m_cachedImage.get(); }55 ImageWithScale selectBestFitImage(const Document&); 56 CachedImage* cachedImage() const; 49 57 50 58 String customCSSText() const; 51 52 struct ImageWithScale {53 URL imageURL;54 float scaleFactor;55 };56 59 57 60 bool traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const; … … 59 62 void updateDeviceScaleFactor(const Document&); 60 63 61 URL bestImageForScaleFactorURL() { return bestImageForScaleFactor().imageURL; }64 Ref<CSSImageSetValue> imageSetWithStylesResolved(Style::BuilderState&); 62 65 63 66 protected: … … 65 68 66 69 private: 67 explicit CSSImageSetValue(LoadedFromOpaqueSource);70 CSSImageSetValue(); 68 71 69 72 void fillImageSet(); 70 73 static inline bool compareByScaleFactor(ImageWithScale first, ImageWithScale second) { return first.scaleFactor < second.scaleFactor; } 71 74 72 CachedResourceHandle<CachedImage> m_cachedImage;75 RefPtr<CSSValue> m_selectedImageValue; 73 76 bool m_accessedBestFitImage { false }; 74 float m_bestFitImageScaleFactor { 1 };77 ImageWithScale m_bestFitImage; 75 78 float m_deviceScaleFactor { 1 }; 76 77 79 Vector<ImageWithScale> m_imagesInSet; 78 LoadedFromOpaqueSource m_loadedFromOpaqueSource { LoadedFromOpaqueSource::No };79 80 }; 80 81 -
trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp
r254790 r254861 2152 2152 { 2153 2153 RefPtr<CSSValueList> list; 2154 while (RefPtr<CSSValue> image = consumeImage(range, context, ConsumeGeneratedImage::Forbid)) {2154 while (RefPtr<CSSValue> image = consumeImage(range, context, { AllowedImageType::URLFunction, AllowedImageType::ImageSet })) { 2155 2155 double num; 2156 2156 IntPoint hotSpot(-1, -1); -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r254406 r254861 1480 1480 } 1481 1481 1482 static StringView consumeUrlOrStringAsStringView(CSSParserTokenRange& args) 1483 { 1484 if (args.peek().type() == StringToken) 1485 return args.consumeIncludingWhitespace().value(); 1486 return consumeUrlAsStringView(args); 1487 } 1488 1489 static RefPtr<CSSValue> consumeImageSet(CSSParserTokenRange& range, const CSSParserContext& context) 1482 static RefPtr<CSSValue> consumeImageSet(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageType) 1490 1483 { 1491 1484 CSSParserTokenRange rangeCopy = range; 1492 1485 CSSParserTokenRange args = consumeFunction(rangeCopy); 1493 RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create( context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);1486 RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create(); 1494 1487 do { 1495 AtomString urlValue = consumeUrlOrStringAsStringView(args).toAtomString(); 1496 if (urlValue.isNull()) 1497 return nullptr; 1498 1499 RefPtr<CSSValue> image = CSSImageValue::create(completeURL(context, urlValue), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No); 1488 RefPtr<CSSValue> image = consumeImage(args, context, (allowedImageType | AllowedImageType::RawStringAsURL) - AllowedImageType::ImageSet); 1489 if (!image) 1490 return nullptr; 1491 1500 1492 imageSet->append(image.releaseNonNull()); 1501 1493 … … 1712 1704 } 1713 1705 1714 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context, ConsumeGeneratedImage generatedImage) 1715 { 1716 AtomString uri = consumeUrlAsStringView(range).toAtomString(); 1717 if (!uri.isNull()) 1718 return CSSImageValue::create(completeURL(context, uri), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No); 1706 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context, OptionSet<AllowedImageType> AllowedImageType) 1707 { 1708 if ((range.peek().type() == StringToken) && (AllowedImageType & AllowedImageType::RawStringAsURL)) 1709 return CSSImageValue::create(completeURL(context, range.consumeIncludingWhitespace().value().toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No); 1719 1710 1720 1711 if (range.peek().type() == FunctionToken) { 1721 1712 CSSValueID id = range.peek().functionId(); 1722 if ( id == CSSValueWebkitImageSet || id == CSSValueImageSet)1723 return consumeImageSet(range, context );1724 if ( generatedImage == ConsumeGeneratedImage::Allow&& isGeneratedImage(id))1713 if ((AllowedImageType & AllowedImageType::ImageSet) && (id == CSSValueWebkitImageSet || id == CSSValueImageSet)) 1714 return consumeImageSet(range, context, AllowedImageType); 1715 if ((AllowedImageType & AllowedImageType::GeneratedImage) && isGeneratedImage(id)) 1725 1716 return consumeGeneratedImage(range, context); 1726 1717 } 1718 1719 if (AllowedImageType & AllowedImageType::URLFunction) { 1720 auto uri = consumeUrlAsStringView(range); 1721 if (!uri.isNull()) 1722 return CSSImageValue::create(completeURL(context, uri.toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No); 1723 } 1724 1727 1725 return nullptr; 1728 1726 } -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h
r252983 r254861 37 37 #include "CSSValuePool.h" 38 38 #include "Length.h" // For ValueRange 39 #include <wtf/OptionSet.h> 39 40 40 41 namespace WebCore { … … 90 91 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY); 91 92 92 enum class ConsumeGeneratedImage { 93 Allow, 94 Forbid 93 enum class AllowedImageType : uint8_t { 94 URLFunction = 1 << 0, 95 RawStringAsURL = 1 << 1, 96 ImageSet = 1 << 2, 97 GeneratedImage = 1 << 3 95 98 }; 96 99 97 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, ConsumeGeneratedImage = ConsumeGeneratedImage::Allow); 100 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage }); 101 98 102 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, CSSParserContext); 99 103 -
trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
r252724 r254861 334 334 return to; 335 335 336 from = from->selectedImage(); 337 to = to->selectedImage(); 338 339 if (!from || !to) 340 return to; 341 336 342 // Animation between two generated images. Cross fade for all other cases. 337 343 if (is<StyleGeneratedImage>(*from) && is<StyleGeneratedImage>(*to)) { -
trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp
r254559 r254861 963 963 auto drawResult = context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), options); 964 964 if (drawResult == ImageDrawResult::DidRequestDecoding) { 965 ASSERT(bgImage-> isCachedImage());965 ASSERT(bgImage->hasCachedImage()); 966 966 bgImage->cachedImage()->addClientWaitingForAsyncDecoding(*this); 967 967 } -
trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp
r225872 r254861 45 45 void RenderImageResourceStyleImage::initialize(RenderElement& renderer) 46 46 { 47 RenderImageResource::initialize(renderer, m_styleImage-> isCachedImage() ? m_styleImage.get().cachedImage() : nullptr);47 RenderImageResource::initialize(renderer, m_styleImage->hasCachedImage() ? m_styleImage.get().cachedImage() : nullptr); 48 48 m_styleImage->addClient(this->renderer()); 49 49 } -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r254087 r254861 2108 2108 // FIXME: support gradients with isGeneratedImage. 2109 2109 auto* styleImage = fillLayer.image(); 2110 if (!styleImage-> isCachedImage())2110 if (!styleImage->hasCachedImage()) 2111 2111 return false; 2112 2112 -
trunk/Source/WebCore/rendering/style/ShapeValue.cpp
r210469 r254861 36 36 if (!m_image) 37 37 return false; 38 if (m_image-> isCachedImage()) {38 if (m_image->hasCachedImage()) { 39 39 auto* cachedImage = m_image->cachedImage(); 40 40 return cachedImage && cachedImage->hasImage(); -
trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp
r223728 r254861 25 25 #include "StyleCachedImage.h" 26 26 27 #include "CSSCursorImageValue.h"28 #include "CSSImageSetValue.h"29 27 #include "CSSImageValue.h" 30 28 #include "CachedImage.h" … … 34 32 namespace WebCore { 35 33 36 StyleCachedImage::StyleCachedImage(CSSValue& cssValue) 34 Ref<StyleCachedImage> StyleCachedImage::create(CSSImageValue& cssValue, float scaleFactor) 35 { 36 return adoptRef(*new StyleCachedImage(cssValue, scaleFactor)); 37 } 38 39 StyleCachedImage::StyleCachedImage(CSSImageValue& cssValue, float scaleFactor) 37 40 : m_cssValue(cssValue) 41 , m_scaleFactor(scaleFactor) 38 42 { 39 ASSERT(is<CSSImageValue>(m_cssValue) || is<CSSImageSetValue>(m_cssValue) || is<CSSCursorImageValue>(m_cssValue));40 41 43 m_isCachedImage = true; 42 43 // CSSImageValue doesn't get invalidated so we can grab the CachedImage immediately if it exists. 44 if (is<CSSImageValue>(m_cssValue)) { 45 m_cachedImage = downcast<CSSImageValue>(m_cssValue.get()).cachedImage(); 46 if (m_cachedImage) 47 m_isPending = false; 48 } 44 m_cachedImage = m_cssValue->cachedImage(); 45 if (m_cachedImage) 46 m_isPending = false; 49 47 } 50 48 … … 69 67 URL StyleCachedImage::imageURL() 70 68 { 71 if (is<CSSImageValue>(m_cssValue)) 72 return downcast<CSSImageValue>(m_cssValue.get()).url(); 73 74 if (is<CSSImageSetValue>(m_cssValue)) 75 return downcast<CSSImageSetValue>(m_cssValue.get()).bestImageForScaleFactorURL(); 76 77 if (is<CSSCursorImageValue>(m_cssValue.get())) 78 return downcast<CSSCursorImageValue>(m_cssValue.get()).imageURL(); 79 80 ASSERT_NOT_REACHED(); 81 return { }; 69 return m_cssValue->url(); 82 70 } 83 71 … … 86 74 ASSERT(m_isPending); 87 75 m_isPending = false; 88 89 if (is<CSSImageValue>(m_cssValue)) { 90 auto& imageValue = downcast<CSSImageValue>(m_cssValue.get()); 91 m_cachedImage = imageValue.loadImage(loader, options); 92 return; 93 } 94 95 if (is<CSSImageSetValue>(m_cssValue)) { 96 auto& imageSetValue = downcast<CSSImageSetValue>(m_cssValue.get()); 97 std::tie(m_cachedImage, m_scaleFactor) = imageSetValue.loadBestFitImage(loader, options); 98 return; 99 } 100 101 if (is<CSSCursorImageValue>(m_cssValue.get())) { 102 auto& cursorValue = downcast<CSSCursorImageValue>(m_cssValue.get()); 103 std::tie(m_cachedImage, m_scaleFactor) = cursorValue.loadImage(loader, options); 104 return; 105 } 76 m_cachedImage = m_cssValue->loadImage(loader, options); 106 77 } 107 78 -
trunk/Source/WebCore/rendering/style/StyleCachedImage.h
r221377 r254861 30 30 31 31 class CSSValue; 32 class CSSImageValue; 32 33 class CachedImage; 33 34 class Document; … … 36 37 WTF_MAKE_FAST_ALLOCATED; 37 38 public: 38 static Ref<StyleCachedImage> create(CSS Value& cssValue) { return adoptRef(*new StyleCachedImage(cssValue)); }39 static Ref<StyleCachedImage> create(CSSImageValue& cssValue, float scaleFactor = 1); 39 40 virtual ~StyleCachedImage(); 40 41 … … 65 66 66 67 private: 67 StyleCachedImage(CSS Value&);68 StyleCachedImage(CSSImageValue&, float); 68 69 URL imageURL(); 69 70 70 Ref<CSS Value> m_cssValue;71 Ref<CSSImageValue> m_cssValue; 71 72 bool m_isPending { true }; 72 73 mutable float m_scaleFactor { 1 }; -
trunk/Source/WebCore/rendering/style/StyleImage.h
r223728 r254861 68 68 virtual bool knownToBeOpaque(const RenderElement*) const = 0; 69 69 virtual CachedImage* cachedImage() const { return 0; } 70 virtual StyleImage* selectedImage() { return this; } 71 virtual const StyleImage* selectedImage() const { return this; } 70 72 71 73 ALWAYS_INLINE bool isCachedImage() const { return m_isCachedImage; } 72 74 ALWAYS_INLINE bool isGeneratedImage() const { return m_isGeneratedImage; } 75 ALWAYS_INLINE bool isCursorImage() const { return m_isCursorImage; } 76 ALWAYS_INLINE bool isImageSet() const { return m_isImageSet; } 77 78 bool hasCachedImage() const { return m_isCachedImage || selectedImage()->isCachedImage(); } 73 79 74 80 protected: … … 76 82 : m_isCachedImage(false) 77 83 , m_isGeneratedImage(false) 84 , m_isImageSet(false) 85 , m_isCursorImage(false) 78 86 { 79 87 } 80 88 bool m_isCachedImage : 1; 81 89 bool m_isGeneratedImage : 1; 90 bool m_isImageSet : 1; 91 bool m_isCursorImage : 1; 82 92 }; 83 93 -
trunk/Source/WebCore/style/StyleBuilderCustom.h
r252392 r254861 47 47 #include "StyleBuilderConverter.h" 48 48 #include "StyleCachedImage.h" 49 #include "StyleCursorImage.h" 49 50 #include "StyleFontSizeFunctions.h" 50 51 #include "StyleGeneratedImage.h" 52 #include "StyleImageSet.h" 51 53 #include "StyleResolver.h" 52 54 #include "WillChangeData.h" … … 1325 1327 builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(item.get())), didSet); 1326 1328 didSet = true; 1327 } else if (is<CSSImageSetValue>(item)) { 1328 builderState.style().setContent(StyleCachedImage::create(item), didSet); 1329 } 1330 1331 if (is<CSSImageSetValue>(item)) { 1332 builderState.style().setContent(StyleImageSet::create(downcast<CSSImageSetValue>(item.get()).imageSetWithStylesResolved(builderState)), didSet); 1329 1333 didSet = true; 1330 1334 } 1331 1335 1332 1336 if (is<CSSImageValue>(item)) { 1333 builderState.style().setContent(StyleCachedImage::create( item), didSet);1337 builderState.style().setContent(StyleCachedImage::create(downcast<CSSImageValue>(item.get())), didSet); 1334 1338 didSet = true; 1335 1339 continue; -
trunk/Source/WebCore/style/StyleBuilderState.cpp
r253538 r254861 46 46 #include "StyleBuilder.h" 47 47 #include "StyleCachedImage.h" 48 #include "StyleCursorImage.h" 48 49 #include "StyleFontSizeFunctions.h" 49 50 #include "StyleGeneratedImage.h" 51 #include "StyleImageSet.h" 50 52 #include "TransformFunctions.h" 51 53 … … 80 82 } 81 83 84 Ref<CSSValue> BuilderState::resolveImageStyles(CSSValue& value) 85 { 86 if (is<CSSGradientValue>(value)) 87 return downcast<CSSGradientValue>(value).gradientWithStylesResolved(*this); 88 89 if (is<CSSImageSetValue>(value)) 90 return downcast<CSSImageSetValue>(value).imageSetWithStylesResolved(*this); 91 92 // Creating filter operations doesn't create a new CSSValue reference. 93 if (is<CSSFilterImageValue>(value)) 94 downcast<CSSFilterImageValue>(value).createFilterOperations(*this); 95 96 return makeRef(value); 97 } 98 82 99 RefPtr<StyleImage> BuilderState::createStyleImage(CSSValue& value) 83 100 { 84 if (is<CSSImageGeneratorValue>(value)) { 85 if (is<CSSGradientValue>(value)) 86 return StyleGeneratedImage::create(downcast<CSSGradientValue>(value).gradientWithStylesResolved(*this)); 87 88 if (is<CSSFilterImageValue>(value)) { 89 // FilterImage needs to calculate FilterOperations. 90 downcast<CSSFilterImageValue>(value).createFilterOperations(*this); 91 } 92 return StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(value)); 93 } 94 95 if (is<CSSImageValue>(value) || is<CSSImageSetValue>(value) || is<CSSCursorImageValue>(value)) 96 return StyleCachedImage::create(value); 101 if (is<CSSImageValue>(value)) 102 return StyleCachedImage::create(downcast<CSSImageValue>(value)); 103 104 if (is<CSSCursorImageValue>(value)) 105 return StyleCursorImage::create(downcast<CSSCursorImageValue>(value)); 106 107 if (is<CSSImageGeneratorValue>(value)) 108 return StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(resolveImageStyles(value).get())); 109 110 if (is<CSSImageSetValue>(value)) 111 return StyleImageSet::create(downcast<CSSImageSetValue>(resolveImageStyles(value).get())); 97 112 98 113 return nullptr; -
trunk/Source/WebCore/style/StyleBuilderState.h
r252313 r254861 83 83 ScopeOrdinal styleScopeOrdinal() const { return m_styleScopeOrdinal; } 84 84 85 Ref<CSSValue> resolveImageStyles(CSSValue&); 85 86 RefPtr<StyleImage> createStyleImage(CSSValue&); 86 87 bool createFilterOperations(const CSSValue&, FilterOperations& outOperations);
Note: See TracChangeset
for help on using the changeset viewer.