Changeset 264280 in webkit
- Timestamp:
- Jul 12, 2020, 10:28:02 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r264279 r264280 1 2020-07-12 Darin Adler <[email protected]> 2 3 Simplify and improve Gradient, some other small color-related removals 4 https://bugs.webkit.org/show_bug.cgi?id=214221 5 6 Reviewed by Sam Weinig. 7 8 * css/CSSGradientValue.cpp: Removed some unneeded includes. 9 10 * html/ColorInputType.cpp: 11 (WebCore::ColorInputType::currentColor): Deleted. 12 (WebCore::ColorInputType::shouldShowSuggestions const): Deleted. 13 * html/ColorInputType.h: Updated for the above. 14 15 * html/HTMLDocument.cpp: Removed unneeded include of HashTools.h. 16 17 * html/canvas/CanvasGradient.cpp: 18 (WebCore::CanvasGradient::create): Moved these functions out of the 19 header since inlining should be the same or better with them here. 20 (WebCore::CanvasGradient::~CanvasGradient): Moved this out of the 21 header so we don't need to include Gradient.h in the header. 22 (WebCore::CanvasGradient::addColorStop): Updated for change to 23 Gradient::addColorStop and move Color rather than copying it. 24 25 * html/canvas/CanvasGradient.h: Removed include of Gradient.h. 26 Moved things out of the header to make that work. 27 28 * inspector/InspectorCanvas.cpp: 29 (WebCore::InspectorCanvas::buildArrayForCanvasGradient): Removed 30 use of Gradient::type and instead unify the type string code with 31 the code that interprets the data for the different types. 32 33 * page/FrameView.cpp: 34 (WebCore::FrameView::recalculateScrollbarOverlayStyle): Refactored 35 to eliminate the multiple redundant code paths, otherwising leaving 36 the logic unchanged. 37 38 * platform/ColorChooserClient.h: Remove unneeded includes and unused 39 currentColor and shouldShowSuggestions functions. 40 41 * platform/graphics/Gradient.cpp: 42 (WebCore::Gradient::create): Replaced create functions that take 43 type-specific data structure with one that takes the variant Data. 44 (WebCore::Gradient::Gradient): Ditto. Also removed platformInit. 45 (WebCore::Gradient::~Gradient): Removed platformDestroy. 46 (WebCore::Gradient::type const): Deleted. 47 (WebCore::Gradient::addColorStop): Take an rvalue reference to cut down 48 a little bit on reference count churn. Replaced the platformDestroy 49 function with a new stopsChanged function. Removed an unneeded overload 50 that takes the two parts of a ColorStop separately. 51 (WebCore::Gradient::setSortedColorStops): Use stopsChanged. 52 (WebCore::Gradient::sortStops const): Simplify a bit, using a lambda. 53 Also gave this a shorter name; it still optimizes by not sorting if 54 the vector is already sorted. 55 (WebCore::Gradient::hasAlpha const): Deleted. 56 (WebCore::Gradient::setSpreadMethod): Removed some slightly overzealous 57 code checking this isn't used after creating the platform-specific gradient. 58 Decided not to bother with this for now. 59 (WebCore::Gradient::setGradientSpaceTransform): Tweaked formatting. 60 (WebCore::add): Added overloads to add(Hasher&) so we can use computeHash. 61 (WebCore::Gradient::hash const): Use computeHash instead of hashMemory. 62 63 * platform/graphics/Gradient.h: Use RetainPtr, COMPtr, and RefPtr instead 64 of manually managing the lifetimes of the platform-specific underlying 65 gradient objects. Also removed the unhelpful PlatformGradient type. This 66 pattern, all too common in our platform library, provides no useful 67 abstraction here. Removed unneeded constructors from ColorStop. 68 Updated for changes above. Added platform-specific functions createBrush, 69 createPattern, and createCGGradient. Simplify encoding and decoding by 70 taking advantage of the support for encoding/decoding variants. 71 Remove the enum Gradient::Type entirely. Removed the invalidateHash 72 function because it's only used in a few setters and setting the hash 73 to 0 is a fine way to write it there. 74 75 * platform/graphics/GraphicsContext.cpp: 76 (WebCore::GraphicsContextState::GraphicsContextState): Moved here from 77 the header so we don't need to include Gradient.h in the header. 78 (WebCore::GraphicsContextState::~GraphicsContextState): Ditto. 79 (WebCore::GraphicsContextState::operator=): Ditto. 80 81 * platform/graphics/GraphicsContext.h: Removed include of Gradient.h. 82 Moved things out of the header to make that work. 83 84 * platform/graphics/cairo/CairoOperations.cpp: 85 (WebCore::Cairo::FillSource::FillSource): Use createPattern instead of 86 createPlatformGradient. 87 (WebCore::Cairo::StrokeSource::StrokeSource): Ditto. 88 89 * platform/graphics/cairo/GradientCairo.cpp: 90 (WebCore::Gradient::stopsChanged): Renamed from platformDestroy. 91 (WebCore::interpolateColorStop): Rewrote to use existing blend functions. 92 (WebCore::createConic): Changed return type to RefPtr. Tweaked to match 93 WebKit coding style a bit better, use auto, use Vector::first/last, and 94 updated for removal of the Gradient::ColorStop constructor. 95 (WebCore::Gradient::createPattern): Renamed from createPlatformGradient. 96 Changed to return a RefPtr instead of a raw pointer the caller needs to 97 adopt at each call site. Refactored so it no longer uses Gradient::type. 98 (WebCore::Gradient::fill): Use createPattern. 99 * platform/graphics/cairo/GraphicsContextImplCairo.cpp: 100 (WebCore::GraphicsContextImplCairo::fillRect): Ditto. 101 102 * platform/graphics/cg/GradientCG.cpp: 103 (WebCore::Gradient::stopsChanged): Renamed from platformDestroy, and 104 simplified implementation now that we use RetainPtr. 105 (WebCore::Gradient::createCGGradient): Renamed from platformGradient, 106 got rid of the return value, and made it caller responsibility to only 107 call this when a gradeitn needs to be allocated. 108 (WebCore::Gradient::paint): Updated to use the above. 109 110 * platform/graphics/cg/GraphicsContextCG.cpp: Add include of Gradient.h. 111 112 * platform/graphics/displaylists/DisplayListItems.h: 113 Added include of Gradient.h since the function templates in this file 114 encode and decode gradients. 115 116 * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp: 117 (Nicosia::CairoOperationRecorder::fillRect): Use createPattern. 118 119 * platform/graphics/win/Direct2DOperations.cpp: 120 (WebCore::Direct2D::FillSource::FillSource): Use createBrush 121 (WebCore::Direct2D::StrokeSource::StrokeSource): Ditto. 122 123 * platform/graphics/win/GradientDirect2D.cpp: 124 (WebCore::Gradient::stopsChanged): Renamed from platformDestroy and 125 simplified implementation now that we use COMPtr. 126 (WebCore::Gradient::platformGradient): Deleted. 127 (WebCore::Gradient::createPlatformGradientIfNecessary): Deleted. 128 (WebCore::Gradient::createBrush): Renamed from generateGradient and 129 added a return value. Simplified now that we use COMPtr, optimized 130 the code a bit, and added some FIXME about mistakes I noticed. 131 (WebCore::Gradient::fill): Use createBrush and m_brush. 132 * platform/graphics/win/GraphicsContextImplDirect2D.cpp: 133 (WebCore::GraphicsContextImplDirect2D::fillRect): Use createBrush. 134 135 * platform/mac/ScrollAnimatorMac.mm: Added include of Gradient.h. 136 137 * rendering/RenderThemeIOS.mm: 138 (WebCore::RenderThemeIOS::paintProgressBar): Updated for changes to 139 addColorStop. Also remove a lot of unnecessary conversion from float 140 to double and back to float. 141 142 * rendering/svg/RenderSVGResourceGradient.cpp: 143 (WebCore::RenderSVGResourceGradient::addStops): Update to make 144 and move a new color stop instead of copying it, modifying it in 145 place, and then copying it again. 146 * rendering/svg/RenderSVGResourceGradient.cpp: Removed include of 147 Gradient.h. 148 149 * svg/SVGGradientElement.cpp: 150 (WebCore::SVGGradientElement::buildStops): Use std::clamp to convert 151 the offsets into monotonically increasing ones in a more direct way, 152 using variable names instead of comments to clarify what we are doing. 153 1 154 2020-07-12 Yusuke Suzuki <[email protected]> 2 155 -
trunk/Source/WebCore/css/CSSGradientValue.cpp
r263776 r264280 31 31 #include "CSSValueKeywords.h" 32 32 #include "ColorBlending.h" 33 #include "FloatSize.h"34 #include "Gradient.h"35 33 #include "GradientImage.h" 36 34 #include "NodeRenderStyle.h" -
trunk/Source/WebCore/html/ColorInputType.cpp
r264136 r264280 271 271 } 272 272 273 Color ColorInputType::currentColor()274 {275 return valueAsColor();276 }277 278 bool ColorInputType::shouldShowSuggestions() const279 {280 #if ENABLE(DATALIST_ELEMENT)281 ASSERT(element());282 return element()->hasAttributeWithoutSynchronization(listAttr);283 #else284 return false;285 #endif286 }287 288 273 Vector<Color> ColorInputType::suggestedColors() const 289 274 { -
trunk/Source/WebCore/html/ColorInputType.h
r246490 r264280 49 49 void didEndChooser() final; 50 50 IntRect elementRectRelativeToRootView() const final; 51 Color currentColor() final;52 bool shouldShowSuggestions() const final;53 51 Vector<Color> suggestedColors() const final; 54 52 bool isMouseFocusable() const final; -
trunk/Source/WebCore/html/HTMLDocument.cpp
r262683 r264280 75 75 #include "HTMLIFrameElement.h" 76 76 #include "HTMLNames.h" 77 #include "HashTools.h"78 77 #include "ScriptController.h" 79 78 #include "StyleResolver.h" -
trunk/Source/WebCore/html/canvas/CanvasGradient.cpp
r252856 r264280 30 30 #include "CanvasBase.h" 31 31 #include "CanvasStyle.h" 32 #include "Gradient.h" 32 33 33 34 namespace WebCore { … … 45 46 } 46 47 48 Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase) 49 { 50 return adoptRef(*new CanvasGradient(p0, p1, canvasBase)); 51 } 52 53 Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase) 54 { 55 return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase)); 56 } 57 58 CanvasGradient::~CanvasGradient() = default; 59 47 60 ExceptionOr<void> CanvasGradient::addColorStop(float value, const String& colorString) 48 61 { … … 55 68 return Exception { SyntaxError }; 56 69 57 m_gradient->addColorStop( value, color);70 m_gradient->addColorStop({ value, WTFMove(color) }); 58 71 return { }; 59 72 } -
trunk/Source/WebCore/html/canvas/CanvasGradient.h
r252856 r264280 28 28 29 29 #include "ExceptionOr.h" 30 #include " Gradient.h"30 #include "FloatPoint.h" 31 31 32 32 namespace WebCore { 33 33 34 34 class CanvasBase; 35 class Gradient; 35 36 36 37 class CanvasGradient : public RefCounted<CanvasGradient> { 37 38 public: 38 static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase) 39 { 40 return adoptRef(*new CanvasGradient(p0, p1, canvasBase)); 41 } 42 static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase) 43 { 44 return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase)); 45 } 39 static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase&); 40 static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase&); 41 ~CanvasGradient(); 46 42 47 43 Gradient& gradient() { return m_gradient; } … … 56 52 Ref<Gradient> m_gradient; 57 53 CanvasBase& m_canvas; 58 59 54 }; 60 55 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
r259845 r264280 37 37 #include "CSSParser.h" 38 38 #include "CSSPropertyNames.h" 39 #include "Gradient.h" 39 40 #include "ImageBuffer.h" 40 41 #include "ImageData.h" -
trunk/Source/WebCore/inspector/InspectorCanvas.cpp
r263788 r264280 1159 1159 Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildArrayForCanvasGradient(const CanvasGradient& canvasGradient) 1160 1160 { 1161 const auto& gradient = canvasGradient.gradient(); 1162 1163 String type = gradient.type() == Gradient::Type::Radial ? "radial-gradient"_s : gradient.type() == Gradient::Type::Linear ? "linear-gradient"_s : "conic-gradient"_s; 1164 1161 ASCIILiteral type = "linear-gradient"_s; 1165 1162 auto parameters = JSON::ArrayOf<float>::create(); 1166 WTF::switchOn( gradient.data(),1167 [& parameters] (const Gradient::LinearData& data) {1163 WTF::switchOn(canvasGradient.gradient().data(), 1164 [&] (const Gradient::LinearData& data) { 1168 1165 parameters->addItem(data.point0.x()); 1169 1166 parameters->addItem(data.point0.y()); … … 1171 1168 parameters->addItem(data.point1.y()); 1172 1169 }, 1173 [¶meters] (const Gradient::RadialData& data) { 1170 [&] (const Gradient::RadialData& data) { 1171 type = "radial-gradient"_s; 1174 1172 parameters->addItem(data.point0.x()); 1175 1173 parameters->addItem(data.point0.y()); … … 1179 1177 parameters->addItem(data.endRadius); 1180 1178 }, 1181 [¶meters] (const Gradient::ConicData& data) { 1179 [&] (const Gradient::ConicData& data) { 1180 type = "conic-gradient"_s; 1182 1181 parameters->addItem(data.point0.x()); 1183 1182 parameters->addItem(data.point0.y()); … … 1187 1186 1188 1187 auto stops = JSON::ArrayOf<JSON::Value>::create(); 1189 for (auto& colorStop : gradient.stops()) {1188 for (auto& colorStop : canvasGradient.gradient().stops()) { 1190 1189 auto stop = JSON::ArrayOf<JSON::Value>::create(); 1191 1190 stop->addItem(colorStop.offset); -
trunk/Source/WebCore/page/FrameView.cpp
r264203 r264280 351 351 void FrameView::recalculateScrollbarOverlayStyle() 352 352 { 353 ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle(); 354 Optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : WTF::nullopt; 355 if (clientOverlayStyle) { 356 if (clientOverlayStyle.value() != oldOverlayStyle) 357 setScrollbarOverlayStyle(clientOverlayStyle.value()); 358 return; 359 } 360 361 ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault; 362 363 Color backgroundColor = documentBackgroundColor(); 364 if (backgroundColor.isValid()) { 365 // Reduce the background color from RGB to a lightness value 366 // and determine which scrollbar style to use based on a lightness 367 // heuristic. 368 if (backgroundColor.lightness() <= .5f && backgroundColor.isVisible()) 369 computedOverlayStyle = ScrollbarOverlayStyleLight; 370 else if (!backgroundColor.isVisible() && useDarkAppearance()) 371 computedOverlayStyle = ScrollbarOverlayStyleLight; 372 } 373 374 if (oldOverlayStyle != computedOverlayStyle) 375 setScrollbarOverlayStyle(computedOverlayStyle); 353 auto style = [this] { 354 if (auto page = frame().page()) { 355 if (auto clientStyle = page->chrome().client().preferredScrollbarOverlayStyle()) 356 return *clientStyle; 357 } 358 auto background = documentBackgroundColor(); 359 if (background.isVisible()) { 360 if (background.lightness() <= .5f) 361 return ScrollbarOverlayStyleLight; 362 } else { 363 if (useDarkAppearance()) 364 return ScrollbarOverlayStyleLight; 365 } 366 return ScrollbarOverlayStyleDefault; 367 }(); 368 if (scrollbarOverlayStyle() != style) 369 setScrollbarOverlayStyle(style); 376 370 } 377 371 378 372 #if ENABLE(DARK_MODE_CSS) 373 379 374 void FrameView::recalculateBaseBackgroundColor() 380 375 { … … 389 384 updateBackgroundRecursively(backgroundColor); 390 385 } 386 391 387 #endif 392 388 -
trunk/Source/WebCore/platform/ColorChooserClient.h
r235004 r264280 28 28 */ 29 29 30 #ifndef ColorChooserClient_h 31 #define ColorChooserClient_h 30 #pragma once 32 31 33 32 #if ENABLE(INPUT_TYPE_COLOR) 34 33 35 #include "IntRect.h" 36 #include <wtf/Vector.h> 34 #include <wtf/Forward.h> 37 35 38 36 namespace WebCore { 39 37 40 38 class Color; 39 class IntRect; 41 40 42 41 class ColorChooserClient { … … 47 46 virtual void didEndChooser() = 0; 48 47 virtual IntRect elementRectRelativeToRootView() const = 0; 49 virtual Color currentColor() = 0;50 virtual bool shouldShowSuggestions() const = 0;51 48 virtual Vector<Color> suggestedColors() const = 0; 52 49 }; … … 55 52 56 53 #endif // ENABLE(INPUT_TYPE_COLOR) 57 58 #endif // ColorChooserClient_h -
trunk/Source/WebCore/platform/graphics/Gradient.cpp
r235877 r264280 37 37 namespace WebCore { 38 38 39 Ref<Gradient> Gradient::create( LinearData&& data)39 Ref<Gradient> Gradient::create(Data&& data) 40 40 { 41 41 return adoptRef(*new Gradient(WTFMove(data))); 42 42 } 43 43 44 Ref<Gradient> Gradient::create(RadialData&& data) 44 Gradient::Gradient(Data&& data) 45 : m_data(WTFMove(data)) 45 46 { 46 return adoptRef(*new Gradient(WTFMove(data)));47 47 } 48 48 49 Ref<Gradient> Gradient::create(ConicData&& data) 50 { 51 return adoptRef(*new Gradient(WTFMove(data))); 52 } 53 54 Gradient::Gradient(LinearData&& data) 55 : m_data(WTFMove(data)) 56 { 57 platformInit(); 58 } 59 60 Gradient::Gradient(RadialData&& data) 61 : m_data(WTFMove(data)) 62 { 63 platformInit(); 64 } 65 66 Gradient::Gradient(ConicData&& data) 67 : m_data(WTFMove(data)) 68 { 69 platformInit(); 70 } 71 72 Gradient::~Gradient() 73 { 74 platformDestroy(); 75 } 76 77 auto Gradient::type() const -> Type 78 { 79 return WTF::switchOn(m_data, 80 [] (const LinearData&) { 81 return Type::Linear; 82 }, 83 [] (const RadialData&) { 84 return Type::Radial; 85 }, 86 [] (const ConicData&) { 87 return Type::Conic; 88 } 89 ); 90 } 49 Gradient::~Gradient() = default; 91 50 92 51 void Gradient::adjustParametersForTiledDrawing(FloatSize& size, FloatRect& srcRect, const FloatSize& spacing) … … 135 94 } 136 95 137 void Gradient::addColorStop( float offset, const Color& color)96 void Gradient::addColorStop(Gradient::ColorStop&& stop) 138 97 { 139 addColorStop({ offset, color }); 140 } 141 142 void Gradient::addColorStop(const Gradient::ColorStop& stop) 143 { 144 m_stops.append(stop); 145 98 m_stops.append(WTFMove(stop)); 146 99 m_stopsSorted = false; 147 148 platformDestroy(); 149 invalidateHash(); 100 m_cachedHash = 0; 101 stopsChanged(); 150 102 } 151 103 … … 153 105 { 154 106 m_stops = WTFMove(stops); 155 156 107 m_stopsSorted = true; 157 158 platformDestroy(); 159 invalidateHash(); 108 m_cachedHash = 0; 109 stopsChanged(); 160 110 } 161 111 162 static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b) 163 { 164 return a.offset < b.offset; 165 } 166 167 void Gradient::sortStopsIfNecessary() 112 void Gradient::sortStops() const 168 113 { 169 114 if (m_stopsSorted) 170 115 return; 171 172 116 m_stopsSorted = true; 173 174 if (!m_stops.size()) 175 return; 176 177 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); 178 invalidateHash(); 179 } 180 181 bool Gradient::hasAlpha() const 182 { 183 for (const auto& stop : m_stops) { 184 if (!stop.color.isOpaque()) 185 return true; 186 } 187 188 return false; 117 std::stable_sort(m_stops.begin(), m_stops.end(), [] (auto& a, auto& b) { 118 return a.offset < b.offset; 119 }); 189 120 } 190 121 191 122 void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod) 192 123 { 193 // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.194 ASSERT(m_gradient == 0);195 196 124 if (m_spreadMethod == spreadMethod) 197 125 return; 198 199 126 m_spreadMethod = spreadMethod; 200 201 invalidateHash(); 127 m_cachedHash = 0; 202 128 } 203 129 … … 206 132 if (m_gradientSpaceTransformation == gradientSpaceTransformation) 207 133 return; 134 m_gradientSpaceTransformation = gradientSpaceTransformation; 135 m_cachedHash = 0; 136 } 208 137 209 m_gradientSpaceTransformation = gradientSpaceTransformation; 138 // FIXME: Instead of these add(Hasher) functions, consider using encode functions to compute the hash. 210 139 211 invalidateHash(); 140 static void add(Hasher& hasher, const Color& color) 141 { 142 // FIXME: We don't want to hash a hash; do better. 143 add(hasher, color.hash()); 144 } 145 146 static void add(Hasher& hasher, const FloatPoint& point) 147 { 148 add(hasher, point.x(), point.y()); 149 } 150 151 static void add(Hasher& hasher, const AffineTransform& transform) 152 { 153 add(hasher, transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f()); 154 } 155 156 static void add(Hasher& hasher, const Gradient::ColorStop& stop) 157 { 158 add(hasher, stop.offset, stop.color); 159 } 160 161 static void add(Hasher& hasher, const Gradient::LinearData& data) 162 { 163 add(hasher, data.point0, data.point1); 164 } 165 166 static void add(Hasher& hasher, const Gradient::RadialData& data) 167 { 168 add(hasher, data.point0, data.point1, data.startRadius, data.endRadius, data.aspectRatio); 169 } 170 171 static void add(Hasher& hasher, const Gradient::ConicData& data) 172 { 173 add(hasher, data.point0, data.angleRadians); 212 174 } 213 175 214 176 unsigned Gradient::hash() const 215 177 { 216 if (m_cachedHash) 217 return m_cachedHash; 218 219 struct { 220 Type type; 221 FloatPoint point0; 222 FloatPoint point1; 223 float startRadius; 224 float endRadius; 225 float aspectRatio; 226 float angleRadians; 227 GradientSpreadMethod spreadMethod; 228 AffineTransform gradientSpaceTransformation; 229 } parameters; 230 231 // StringHasher requires that the memory it hashes be a multiple of two in size. 232 COMPILE_ASSERT(!(sizeof(parameters) % 2), Gradient_parameters_size_should_be_multiple_of_two); 233 COMPILE_ASSERT(!(sizeof(ColorStop) % 2), Color_stop_size_should_be_multiple_of_two); 234 235 // Ensure that any padding in the struct is zero-filled, so it will not affect the hash value. 236 // FIXME: This is asking for trouble, because it is a nontrivial type. 237 memset(static_cast<void*>(¶meters), 0, sizeof(parameters)); 238 239 WTF::switchOn(m_data, 240 [¶meters] (const LinearData& data) { 241 parameters.point0 = data.point0; 242 parameters.point1 = data.point1; 243 parameters.startRadius = 0; 244 parameters.endRadius = 0; 245 parameters.aspectRatio = 0; 246 parameters.angleRadians = 0; 247 parameters.type = Type::Linear; 248 }, 249 [¶meters] (const RadialData& data) { 250 parameters.point0 = data.point0; 251 parameters.point1 = data.point1; 252 parameters.startRadius = data.startRadius; 253 parameters.endRadius = data.endRadius; 254 parameters.aspectRatio = data.aspectRatio; 255 parameters.angleRadians = 0; 256 parameters.type = Type::Radial; 257 }, 258 [¶meters] (const ConicData& data) { 259 parameters.point0 = data.point0; 260 parameters.point1 = {0, 0}; 261 parameters.startRadius = 0; 262 parameters.endRadius = 0; 263 parameters.aspectRatio = 0; 264 parameters.angleRadians = data.angleRadians; 265 parameters.type = Type::Conic; 266 } 267 ); 268 269 parameters.spreadMethod = m_spreadMethod; 270 parameters.gradientSpaceTransformation = m_gradientSpaceTransformation; 271 272 unsigned parametersHash = StringHasher::hashMemory(¶meters, sizeof(parameters)); 273 unsigned stopHash = StringHasher::hashMemory(m_stops.data(), m_stops.size() * sizeof(ColorStop)); 274 275 m_cachedHash = pairIntHash(parametersHash, stopHash); 276 178 if (!m_cachedHash) { 179 sortStops(); 180 m_cachedHash = computeHash(m_data, m_spreadMethod, m_gradientSpaceTransformation, m_stops); 181 } 277 182 return m_cachedHash; 278 183 } -
trunk/Source/WebCore/platform/graphics/Gradient.h
r262684 r264280 32 32 #include "FloatPoint.h" 33 33 #include "GraphicsTypes.h" 34 #include <wtf/EnumTraits.h>35 #include <wtf/RefCounted.h>36 34 #include <wtf/Variant.h> 37 35 #include <wtf/Vector.h> 38 36 39 37 #if USE(CG) 38 #include <wtf/RetainPtr.h> 39 #endif 40 41 #if USE(DIRECT2D) 42 #include "COMPtr.h" 43 #endif 44 45 #if USE(CG) 40 46 typedef struct CGContext* CGContextRef; 41 47 typedef struct CGGradient* CGGradientRef; 42 typedef CGGradientRef PlatformGradient; 43 #elif USE(DIRECT2D) 48 #endif 49 50 #if USE(DIRECT2D) 44 51 interface ID2D1Brush; 45 52 interface ID2D1RenderTarget; 46 typedef ID2D1Brush* PlatformGradient; 47 #elif USE(CAIRO) 53 #endif 54 55 #if USE(CAIRO) 48 56 typedef struct _cairo_pattern cairo_pattern_t; 49 typedef cairo_pattern_t* PlatformGradient;50 #else51 typedef void* PlatformGradient;52 57 #endif 53 58 54 59 namespace WebCore { 55 60 56 class Color;57 61 class FloatRect; 58 62 class GraphicsContext; … … 60 64 class Gradient : public RefCounted<Gradient> { 61 65 public: 62 // FIXME: ExtendedColor - A color stop needs a notion of color space.63 66 struct ColorStop { 64 67 float offset { 0 }; 65 68 Color color; 66 69 67 ColorStop() = default; 68 ColorStop(float offset, const Color& color) 69 : offset(offset) 70 , color(color) 71 { 72 } 73 74 template<class Encoder> void encode(Encoder&) const; 75 template<class Decoder> static Optional<ColorStop> decode(Decoder&); 70 template<typename Encoder> void encode(Encoder&) const; 71 template<typename Decoder> static Optional<ColorStop> decode(Decoder&); 76 72 }; 77 73 … … 82 78 FloatPoint point1; 83 79 84 template< classEncoder> void encode(Encoder&) const;85 template< classDecoder> static Optional<LinearData> decode(Decoder&);80 template<typename Encoder> void encode(Encoder&) const; 81 template<typename Decoder> static Optional<LinearData> decode(Decoder&); 86 82 }; 87 83 … … 93 89 float aspectRatio; // For elliptical gradient, width / height. 94 90 95 template< classEncoder> void encode(Encoder&) const;96 template< classDecoder> static Optional<RadialData> decode(Decoder&);91 template<typename Encoder> void encode(Encoder&) const; 92 template<typename Decoder> static Optional<RadialData> decode(Decoder&); 97 93 }; 98 94 99 95 struct ConicData { 100 96 FloatPoint point0; 101 97 float angleRadians; 102 98 103 template< classEncoder> void encode(Encoder&) const;104 template< classDecoder> static Optional<ConicData> decode(Decoder&);99 template<typename Encoder> void encode(Encoder&) const; 100 template<typename Decoder> static Optional<ConicData> decode(Decoder&); 105 101 }; 106 102 107 103 using Data = Variant<LinearData, RadialData, ConicData>; 108 104 109 enum class Type { Linear, Radial, Conic }; 110 111 WEBCORE_EXPORT static Ref<Gradient> create(LinearData&&); 112 WEBCORE_EXPORT static Ref<Gradient> create(RadialData&&); 113 WEBCORE_EXPORT static Ref<Gradient> create(ConicData&&); 105 WEBCORE_EXPORT static Ref<Gradient> create(Data&&); 114 106 115 107 WEBCORE_EXPORT ~Gradient(); 116 108 117 WEBCORE_EXPORT Type type() const;118 119 bool hasAlpha() const;120 109 bool isZeroSize() const; 121 110 122 111 const Data& data() const { return m_data; } 123 112 124 WEBCORE_EXPORT void addColorStop(const ColorStop&); 125 WEBCORE_EXPORT void addColorStop(float, const Color&); 113 WEBCORE_EXPORT void addColorStop(ColorStop&&); 126 114 WEBCORE_EXPORT void setSortedColorStops(ColorStopVector&&); 127 115 … … 131 119 GradientSpreadMethod spreadMethod() const { return m_spreadMethod; } 132 120 133 // CG needs to transform the gradient at draw time.134 121 WEBCORE_EXPORT void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation); 135 122 const AffineTransform& gradientSpaceTransform() const { return m_gradientSpaceTransformation; } … … 139 126 140 127 unsigned hash() const; 141 void invalidateHash() { m_cachedHash = 0; } 128 129 #if USE(CAIRO) 130 RefPtr<cairo_pattern_t> createPattern(float globalAlpha); 131 #endif 142 132 143 133 #if USE(CG) 144 134 void paint(GraphicsContext&); 145 135 void paint(CGContextRef); 146 #e lif USE(DIRECT2D)147 PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*); 148 # elif USE(CAIRO)149 PlatformGradient createPlatformGradient(float globalAlpha);150 #endif 151 152 template< classEncoder> void encode(Encoder&) const;153 template< classDecoder> static Optional<Ref<Gradient>> decode(Decoder&);136 #endif 137 138 #if USE(DIRECT2D) 139 ID2D1Brush* createBrush(ID2D1RenderTarget*); 140 #endif 141 142 template<typename Encoder> void encode(Encoder&) const; 143 template<typename Decoder> static Optional<Ref<Gradient>> decode(Decoder&); 154 144 155 145 private: 156 Gradient(LinearData&&); 157 Gradient(RadialData&&); 158 Gradient(ConicData&&); 159 160 PlatformGradient platformGradient(); 161 void platformInit() { m_gradient = nullptr; } 162 void platformDestroy(); 163 164 void sortStopsIfNecessary(); 165 166 #if USE(DIRECT2D) 167 void generateGradient(ID2D1RenderTarget*); 146 explicit Gradient(Data&&); 147 148 void sortStops() const; 149 void stopsChanged(); 150 151 #if USE(CG) 152 void createCGGradient(); 168 153 #endif 169 154 170 155 Data m_data; 171 172 156 mutable ColorStopVector m_stops; 173 157 mutable bool m_stopsSorted { false }; 174 158 GradientSpreadMethod m_spreadMethod { GradientSpreadMethod::Pad }; 159 mutable unsigned m_cachedHash { 0 }; 175 160 AffineTransform m_gradientSpaceTransformation; 176 161 177 mutable unsigned m_cachedHash { 0 }; 178 179 PlatformGradient m_gradient; 162 #if USE(CG) 163 RetainPtr<CGGradientRef> m_gradient; 164 #endif 165 166 #if USE(DIRECT2D) 167 COMPtr<ID2D1Brush> m_brush; 168 #endif 180 169 }; 181 170 182 template<class Encoder> 183 void Gradient::ColorStop::encode(Encoder& encoder) const 171 template<typename Encoder> void Gradient::ColorStop::encode(Encoder& encoder) const 184 172 { 185 173 encoder << offset; … … 187 175 } 188 176 189 template<class Decoder> 190 Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder) 177 template<typename Decoder> Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder) 191 178 { 192 179 Optional<float> offset; … … 203 190 } 204 191 205 template<class Encoder> 206 void Gradient::LinearData::encode(Encoder& encoder) const 192 template<typename Encoder> void Gradient::LinearData::encode(Encoder& encoder) const 207 193 { 208 194 encoder << point0; … … 210 196 } 211 197 212 template<class Decoder> 213 Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder) 198 template<typename Decoder> Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder) 214 199 { 215 200 Optional<FloatPoint> point0; … … 226 211 } 227 212 228 template<class Encoder> 229 void Gradient::RadialData::encode(Encoder& encoder) const 213 template<typename Encoder> void Gradient::RadialData::encode(Encoder& encoder) const 230 214 { 231 215 encoder << point0; … … 236 220 } 237 221 238 template<class Decoder> 239 Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder) 222 template<typename Decoder> Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder) 240 223 { 241 224 Optional<FloatPoint> point0; … … 267 250 } 268 251 269 template<class Encoder> 270 void Gradient::ConicData::encode(Encoder& encoder) const 252 template<typename Encoder> void Gradient::ConicData::encode(Encoder& encoder) const 271 253 { 272 254 encoder << point0; … … 274 256 } 275 257 276 template<class Decoder> 277 Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder) 258 template<typename Decoder> Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder) 278 259 { 279 260 Optional<FloatPoint> point0; … … 290 271 } 291 272 292 template<class Encoder> 293 void Gradient::encode(Encoder& encoder) const 294 { 295 auto type = this->type(); 296 encoder << type; 297 switch (type) { 298 case Type::Linear: 299 encoder << WTF::get<Gradient::LinearData>(m_data); 300 break; 301 case Type::Radial: 302 encoder << WTF::get<Gradient::RadialData>(m_data); 303 break; 304 case Type::Conic: 305 encoder << WTF::get<Gradient::ConicData>(m_data); 306 break; 307 } 273 template<typename Encoder> void Gradient::encode(Encoder& encoder) const 274 { 275 encoder << m_data; 308 276 encoder << m_stops; 309 277 encoder << m_stopsSorted; … … 312 280 } 313 281 314 template<class Decoder> 315 Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder) 316 { 317 Optional<Gradient::Type> type; 318 decoder >> type; 319 if (!type) 320 return WTF::nullopt; 321 322 RefPtr<Gradient> gradient; 323 switch (*type) { 324 case Type::Linear: { 325 Optional<LinearData> linearData; 326 decoder >> linearData; 327 if (!linearData) 328 return WTF::nullopt; 329 330 gradient = Gradient::create(WTFMove(*linearData)); 331 break; 332 } 333 case Type::Radial: { 334 Optional<RadialData> radialData; 335 decoder >> radialData; 336 if (!radialData) 337 return WTF::nullopt; 338 339 gradient = Gradient::create(WTFMove(*radialData)); 340 break; 341 } 342 case Type::Conic: { 343 Optional<ConicData> conicData; 344 decoder >> conicData; 345 if (!conicData) 346 return WTF::nullopt; 347 348 gradient = Gradient::create(WTFMove(*conicData)); 349 break; 350 } 351 } 352 353 if (!gradient) { 354 ASSERT_NOT_REACHED(); 355 return WTF::nullopt; 356 } 282 template<typename Decoder> Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder) 283 { 284 Optional<Data> data; 285 decoder >> data; 286 if (!data) 287 return WTF::nullopt; 288 auto gradient = Gradient::create(WTFMove(*data)); 357 289 358 290 Optional<ColorStopVector> stops; … … 360 292 if (!stops) 361 293 return WTF::nullopt; 362 363 294 Optional<bool> stopsSorted; 364 295 decoder >> stopsSorted; 365 296 if (!stopsSorted.hasValue()) 366 297 return WTF::nullopt; 367 368 if (stopsSorted.value()) 298 if (*stopsSorted) 369 299 gradient->setSortedColorStops(WTFMove(*stops)); 370 300 else { 371 301 for (auto& stop : *stops) 372 gradient->addColorStop( stop);302 gradient->addColorStop(WTFMove(stop)); 373 303 } 374 304 … … 376 306 if (!decoder.decode(spreadMethod)) 377 307 return WTF::nullopt; 378 379 308 gradient->setSpreadMethod(spreadMethod); 380 309 … … 383 312 if (!gradientSpaceTransformation) 384 313 return WTF::nullopt; 385 386 314 gradient->setGradientSpaceTransform(WTFMove(*gradientSpaceTransformation)); 387 return gradient.releaseNonNull(); 315 316 return WTFMove(gradient); 388 317 } 389 318 390 319 } // namespace WebCore 391 392 namespace WTF {393 394 template<> struct EnumTraits<WebCore::Gradient::Type> {395 using values = EnumValues<396 WebCore::Gradient::Type,397 WebCore::Gradient::Type::Linear,398 WebCore::Gradient::Type::Radial,399 WebCore::Gradient::Type::Conic400 >;401 };402 403 } // namespace WTF -
trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp
r261162 r264280 76 76 changeFlags.add(GraphicsContextState::flag); 77 77 78 GraphicsContextState::GraphicsContextState() 79 : shouldAntialias(true) 80 , shouldSmoothFonts(true) 81 , shouldSubpixelQuantizeFonts(true) 82 , shadowsIgnoreTransforms(false) 83 #if USE(CG) 84 // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>), 85 // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow. 86 , shadowsUseLegacyRadius(false) 87 #endif 88 , drawLuminanceMask(false) 89 { 90 } 91 92 GraphicsContextState::~GraphicsContextState() = default; 93 GraphicsContextState::GraphicsContextState(const GraphicsContextState&) = default; 94 GraphicsContextState::GraphicsContextState(GraphicsContextState&&) = default; 95 GraphicsContextState& GraphicsContextState::operator=(const GraphicsContextState&) = default; 96 GraphicsContextState& GraphicsContextState::operator=(GraphicsContextState&&) = default; 97 78 98 GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState& state) const 79 99 { -
trunk/Source/WebCore/platform/graphics/GraphicsContext.h
r263208 r264280 30 30 #include "FloatRect.h" 31 31 #include "FontCascade.h" 32 #include "Gradient.h"33 32 #include "GraphicsTypes.h" 34 33 #include "Image.h" … … 99 98 class TransformationMatrix; 100 99 100 namespace DisplayList { 101 class Recorder; 102 } 103 101 104 enum class TextDrawingMode : uint8_t { 102 105 Fill = 1 << 0, … … 154 157 } 155 158 156 namespace DisplayList {157 class Recorder;158 }159 160 159 struct GraphicsContextState { 161 GraphicsContextState() 162 : shouldAntialias(true) 163 , shouldSmoothFonts(true) 164 , shouldSubpixelQuantizeFonts(true) 165 , shadowsIgnoreTransforms(false) 166 #if USE(CG) 167 // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>), 168 // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow. 169 , shadowsUseLegacyRadius(false) 170 #endif 171 , drawLuminanceMask(false) 172 { 173 } 160 WEBCORE_EXPORT GraphicsContextState(); 161 WEBCORE_EXPORT ~GraphicsContextState(); 162 163 GraphicsContextState(const GraphicsContextState&); 164 GraphicsContextState(GraphicsContextState&&); 165 166 GraphicsContextState& operator=(const GraphicsContextState&); 167 GraphicsContextState& operator=(GraphicsContextState&&); 174 168 175 169 enum Change : uint32_t { … … 198 192 #endif 199 193 }; 200 typedef OptionSet<Change> StateChangeFlags;194 using StateChangeFlags = OptionSet<Change>; 201 195 202 196 RefPtr<Gradient> strokeGradient; … … 309 303 310 304 void setStrokeGradient(Ref<Gradient>&&); 311 RefPtr<Gradient> strokeGradient() const { return m_state.strokeGradient; }305 Gradient* strokeGradient() const { return m_state.strokeGradient.get(); } 312 306 313 307 void setFillRule(WindRule); … … 321 315 322 316 WEBCORE_EXPORT void setFillGradient(Ref<Gradient>&&); 323 RefPtr<Gradient> fillGradient() const { return m_state.fillGradient; }317 Gradient* fillGradient() const { return m_state.fillGradient.get(); } 324 318 325 319 void setShadowsIgnoreTransforms(bool); -
trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp
r263471 r264280 41 41 #include "FloatConversion.h" 42 42 #include "FloatRect.h" 43 #include "Gradient.h" 43 44 #include "GraphicsContext.h" 44 45 #include "GraphicsContextPlatformPrivateCairo.h" … … 569 570 pattern.repeatY = state.fillPattern->repeatY(); 570 571 } else if (state.fillGradient) { 571 gradient.base = adoptRef(state.fillGradient->createPlatformGradient(1));572 gradient.base = state.fillGradient->createPattern(1); 572 573 if (state.alpha != 1) 573 gradient.alphaAdjusted = adoptRef(state.fillGradient->createPlatformGradient(state.alpha));574 gradient.alphaAdjusted = state.fillGradient->createPattern(state.alpha); 574 575 } else 575 576 color = state.fillColor; … … 582 583 pattern = adoptRef(state.strokePattern->createPlatformPattern(AffineTransform())); 583 584 else if (state.strokeGradient) { 584 gradient.base = adoptRef(state.strokeGradient->createPlatformGradient(1));585 gradient.base = state.strokeGradient->createPattern(1); 585 586 if (state.alpha != 1) 586 gradient.alphaAdjusted = adoptRef(state.strokeGradient->createPlatformGradient(state.alpha));587 gradient.alphaAdjusted = state.strokeGradient->createPattern(state.alpha); 587 588 } else 588 589 color = state.strokeColor; -
trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp
r264273 r264280 31 31 #if USE(CAIRO) 32 32 33 #include "AnimationUtilities.h" 33 34 #include "CairoOperations.h" 34 35 #include "CairoUtilities.h" 36 #include "ColorBlending.h" 35 37 #include "GraphicsContext.h" 36 38 #include "PlatformContextCairo.h" … … 39 41 namespace WebCore { 40 42 41 void Gradient:: platformDestroy()43 void Gradient::stopsChanged() 42 44 { 43 45 } … … 133 135 } 134 136 135 static Gradient::ColorStop interpolateColorStop(Gradient::ColorStop from, Gradient::ColorStop to) 136 { 137 auto [r1, g1, b1, a1] = from.color.toSRGBALossy<float>(); 138 auto [r2, g2, b2, a2] = to.color.toSRGBALossy<float>(); 139 140 float offset = from.offset + (to.offset - from.offset) * 0.5f; 141 float r = r1 + (r2 - r1) * 0.5f; 142 float g = g1 + (g2 - g1) * 0.5f; 143 float b = b1 + (b2 - b1) * 0.5f; 144 float a = a1 + (a2 - a1) * 0.5f; 145 146 return Gradient::ColorStop(offset, makeSimpleColor(SRGBA { r, g, b, a })); 147 } 148 149 static cairo_pattern_t* createConic(float xo, float yo, float r, float angleRadians, 137 static Gradient::ColorStop interpolateColorStop(const Gradient::ColorStop& from, const Gradient::ColorStop& to) 138 { 139 return { blend(from.offset, to.offset, 0.5), blend(from.color, to.color, 0.5) }; 140 } 141 142 static RefPtr<cairo_pattern_t> createConic(float xo, float yo, float r, float angleRadians, 150 143 Gradient::ColorStopVector stops, float globalAlpha) 151 144 { 152 cairo_pattern_t* gradient = cairo_pattern_create_mesh(); 153 Gradient::ColorStop from, to; 154 155 /* It's not possible to paint an entire circle with a single Bezier curve. 156 * To have a good approximation to a circle it's necessary to use at least 157 * four Bezier curves. So three additional stops with interpolated colors 158 * are added to force painting of four Bezier curves. */ 145 // It's not possible to paint an entire circle with a single Bezier curve. 146 // To have a good approximation to a circle it's necessary to use at least 147 // four Bezier curves. So three additional stops with interpolated colors 148 // are added to force painting of four Bezier curves. 159 149 if (stops.size() == 2) { 160 Gradient::ColorStop first = stops.at(0); 161 Gradient::ColorStop last = stops.at(1); 162 Gradient::ColorStop third = interpolateColorStop(first, last); 163 Gradient::ColorStop second = interpolateColorStop(first, third); 164 Gradient::ColorStop fourth = interpolateColorStop(third, last); 165 stops.insert(1, fourth); 166 stops.insert(1, third); 167 stops.insert(1, second); 150 auto third = interpolateColorStop(stops.first(), stops.last()); 151 auto second = interpolateColorStop(stops.first(), third); 152 auto fourth = interpolateColorStop(third, stops.last()); 153 stops.insert(1, WTFMove(fourth)); 154 stops.insert(1, WTFMove(third)); 155 stops.insert(1, WTFMove(second)); 168 156 } 169 157 170 // Add extra color stop at the beginning if first element offset is not zero. 171 if (stops.at(0).offset > 0) 172 stops.insert(0, Gradient::ColorStop(0, stops.at(0).color)); 173 // Add extra color stop at the end if last element offset is not zero. 174 if (stops.at(stops.size() - 1).offset < 1) 175 stops.append(Gradient::ColorStop(1, stops.at(stops.size() - 1).color)); 176 177 for (size_t i = 0; i < stops.size() - 1; i++) { 178 from = stops.at(i), to = stops.at(i + 1); 179 addConicSector(gradient, xo, yo, r, angleRadians, from, to, globalAlpha); 180 } 181 158 if (stops.first().offset > 0.0f) 159 stops.insert(0, Gradient::ColorStop { 0.0f, stops.first().color }); 160 if (stops.last().offset < 1.0f) 161 stops.append({ 1.0f, stops.last().color }); 162 163 auto gradient = adoptRef(cairo_pattern_create_mesh()); 164 for (size_t i = 0; i < stops.size() - 1; i++) 165 addConicSector(gradient.get(), xo, yo, r, angleRadians, stops[i], stops[i + 1], globalAlpha); 182 166 return gradient; 183 167 } 184 168 185 cairo_pattern_t* Gradient::createPlatformGradient(float globalAlpha) 186 { 187 cairo_pattern_t* gradient = WTF::switchOn(m_data, 188 [&] (const LinearData& data) -> cairo_pattern_t* { 189 return cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y()); 169 RefPtr<cairo_pattern_t> Gradient::createPattern(float globalAlpha) 170 { 171 auto gradient = WTF::switchOn(m_data, 172 [&] (const LinearData& data) { 173 auto gradient = adoptRef(cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y())); 174 for (auto& stop : stops()) 175 addColorStopRGBA(gradient.get(), stop, globalAlpha); 176 return gradient; 190 177 }, 191 [&] (const RadialData& data) -> cairo_pattern_t* { 192 return cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius); 178 [&] (const RadialData& data) { 179 auto gradient = adoptRef(cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius)); 180 for (auto& stop : stops()) 181 addColorStopRGBA(gradient.get(), stop, globalAlpha); 182 return gradient; 193 183 }, 194 [&] (const ConicData& data) -> cairo_pattern_t*{184 [&] (const ConicData& data) { 195 185 // FIXME: data passed for a Conic gradient doesn't contain a radius. That's apparently correct because the W3C spec 196 186 // (https://www.w3.org/TR/css-images-4/#conic-gradients) states a conic gradient is only defined by its position and angle. … … 202 192 ); 203 193 204 if (type() != Type::Conic) {205 for (const auto& stop : stops()) {206 addColorStopRGBA(gradient, stop, globalAlpha);207 }208 }209 210 194 switch (m_spreadMethod) { 211 195 case GradientSpreadMethod::Pad: 212 cairo_pattern_set_extend(gradient , CAIRO_EXTEND_PAD);196 cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_PAD); 213 197 break; 214 198 case GradientSpreadMethod::Reflect: 215 cairo_pattern_set_extend(gradient , CAIRO_EXTEND_REFLECT);199 cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REFLECT); 216 200 break; 217 201 case GradientSpreadMethod::Repeat: 218 cairo_pattern_set_extend(gradient , CAIRO_EXTEND_REPEAT);202 cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REPEAT); 219 203 break; 220 204 } … … 222 206 cairo_matrix_t matrix = toCairoMatrix(m_gradientSpaceTransformation); 223 207 cairo_matrix_invert(&matrix); 224 cairo_pattern_set_matrix(gradient , &matrix);208 cairo_pattern_set_matrix(gradient.get(), &matrix); 225 209 226 210 return gradient; … … 229 213 void Gradient::fill(GraphicsContext& context, const FloatRect& rect) 230 214 { 231 RefPtr<cairo_pattern_t> platformGradient = adoptRef(createPlatformGradient(1.0));232 if (!p latformGradient)215 auto pattern = createPattern(1.0); 216 if (!pattern) 233 217 return; 234 218 … … 237 221 238 222 Cairo::save(platformContext); 239 Cairo::fillRect(platformContext, rect, p latformGradient.get());223 Cairo::fillRect(platformContext, rect, pattern.get()); 240 224 Cairo::restore(platformContext); 241 225 } -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp
r256892 r264280 34 34 #include "Font.h" 35 35 #include "GlyphBuffer.h" 36 #include "Gradient.h" 36 37 #include "GraphicsContextPlatformPrivateCairo.h" 37 38 #include "ImageBuffer.h" 38 39 #include "IntRect.h" 39 40 40 41 41 namespace WebCore { … … 155 155 void GraphicsContextImplCairo::fillRect(const FloatRect& rect, Gradient& gradient) 156 156 { 157 RefPtr<cairo_pattern_t> platformGradient = adoptRef(gradient.createPlatformGradient(1.0));158 if (!p latformGradient)157 auto pattern = gradient.createPattern(1.0); 158 if (!pattern) 159 159 return; 160 160 161 161 Cairo::save(m_platformContext); 162 Cairo::fillRect(m_platformContext, rect, p latformGradient.get());162 Cairo::fillRect(m_platformContext, rect, pattern.get()); 163 163 Cairo::restore(m_platformContext); 164 164 } -
trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp
r262684 r264280 36 36 namespace WebCore { 37 37 38 void Gradient:: platformDestroy()38 void Gradient::stopsChanged() 39 39 { 40 CGGradientRelease(m_gradient);41 40 m_gradient = nullptr; 42 41 } 43 42 44 CGGradientRef Gradient::platformGradient()43 void Gradient::createCGGradient() 45 44 { 46 if (m_gradient) 47 return m_gradient; 48 49 sortStopsIfNecessary(); 45 sortStops(); 50 46 51 47 auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks)); … … 83 79 84 80 if (hasExtendedColors) 85 m_gradient = CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data());81 m_gradient = adoptCF(CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data())); 86 82 else 87 m_gradient = CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops); 88 89 return m_gradient; 83 m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops)); 90 84 } 91 85 … … 104 98 { 105 99 CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; 106 CGGradientRef gradient = platformGradient(); 100 101 if (!m_gradient) 102 createCGGradient(); 107 103 108 104 WTF::switchOn(m_data, … … 147 143 CGPoint right = CGPointMake(flip ? start : start + width, boundingBox.origin.y); 148 144 149 CGContextDrawLinearGradient(platformContext, gradient, left, right, extendOptions);145 CGContextDrawLinearGradient(platformContext, m_gradient.get(), left, right, extendOptions); 150 146 151 147 if (m_spreadMethod == GradientSpreadMethod::Reflect) … … 159 155 } 160 156 case GradientSpreadMethod::Pad: 161 CGContextDrawLinearGradient(platformContext, gradient, data.point0, data.point1, extendOptions);157 CGContextDrawLinearGradient(platformContext, m_gradient.get(), data.point0, data.point1, extendOptions); 162 158 } 163 159 }, … … 174 170 } 175 171 176 CGContextDrawRadialGradient(platformContext, gradient, data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);172 CGContextDrawRadialGradient(platformContext, m_gradient.get(), data.point0, data.startRadius, data.point1, data.endRadius, extendOptions); 177 173 178 174 if (needScaling) … … 187 183 CGContextRotateCTM(platformContext, (CGFloat)-M_PI_2); 188 184 CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y()); 189 CGContextDrawConicGradient(platformContext, platformGradient(), data.point0, data.angleRadians);185 CGContextDrawConicGradient(platformContext, m_gradient.get(), data.point0, data.angleRadians); 190 186 CGContextRestoreGState(platformContext); 191 187 #else -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r263211 r264280 33 33 #include "DisplayListRecorder.h" 34 34 #include "FloatConversion.h" 35 #include "Gradient.h" 35 36 #include "GraphicsContextPlatformPrivateCG.h" 36 37 #include "ImageBuffer.h" -
trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h
r262994 r264280 28 28 #include "AlphaPremultiplication.h" 29 29 #include "DisplayList.h" 30 #include "FloatPoint.h"31 30 #include "FloatRoundedRect.h" 32 31 #include "Font.h" 33 32 #include "GlyphBuffer.h" 33 #include "Gradient.h" 34 34 #include "Image.h" 35 35 #include "ImageData.h" 36 36 #include "Pattern.h" 37 37 #include "SharedBuffer.h" 38 #include <wtf/RefCounted.h>39 38 #include <wtf/TypeCasts.h> 40 39 -
trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp
r254506 r264280 32 32 #include "CairoOperations.h" 33 33 #include "FloatRoundedRect.h" 34 #include "Gradient.h" 34 35 #include "ImageBuffer.h" 35 36 #include "NicosiaPaintingOperationReplayCairo.h" … … 292 293 }; 293 294 294 append(createCommand<FillRect>(rect, adoptRef(gradient.createPlatformGradient(1.0))));295 append(createCommand<FillRect>(rect, gradient.createPattern(1.0))); 295 296 } 296 297 -
trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp
r262108 r264280 302 302 brush = state.fillPattern->createPlatformPattern(context, state.alpha, userToBaseCTM); 303 303 } else if (state.fillGradient && !state.fillGradient->stops().isEmpty()) 304 brush = state.fillGradient->create PlatformGradientIfNecessary(platformContext.renderTarget());304 brush = state.fillGradient->createBrush(platformContext.renderTarget()); 305 305 else 306 306 brush = platformContext.brushWithColor(color); … … 319 319 brush = state.strokePattern->createPlatformPattern(context, state.alpha, userToBaseCTM); 320 320 } else if (state.strokeGradient) 321 brush = state.strokeGradient->create PlatformGradientIfNecessary(platformContext.renderTarget());321 brush = state.strokeGradient->createBrush(platformContext.renderTarget()); 322 322 else 323 323 brush = platformContext.brushWithColor(color); -
trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp
r263941 r264280 32 32 #include <d2d1.h> 33 33 #include <wtf/MathExtras.h> 34 #include <wtf/RetainPtr.h>35 34 36 35 #define GRADIENT_DRAWING 3 … … 38 37 namespace WebCore { 39 38 40 void Gradient::platformDestroy() 41 { 42 if (m_gradient) 43 m_gradient->Release(); 44 m_gradient = nullptr; 45 } 46 47 ID2D1Brush* Gradient::platformGradient() 48 { 49 ASSERT(m_gradient); 50 return m_gradient; 51 } 52 53 ID2D1Brush* Gradient::createPlatformGradientIfNecessary(ID2D1RenderTarget* context) 54 { 55 generateGradient(context); 56 return m_gradient; 39 void Gradient::stopsChanged() 40 { 41 m_brush = nullptr; 57 42 } 58 43 … … 66 51 } 67 52 68 void Gradient::generateGradient(ID2D1RenderTarget* renderTarget)69 { 70 sortStops IfNecessary();53 ID2D1Brush* Gradient::createBrush(ID2D1RenderTarget* renderTarget) 54 { 55 sortStops(); 71 56 72 57 Vector<D2D1_GRADIENT_STOP> gradientStops; 73 // FIXME: Add support for ExtendedColor. 74 for (auto stop : m_stops) { 58 gradientStops.reserveInitialCapacity(m_stops.size()); 59 for (auto& stop : m_stops) { 60 // FIXME: Add support for non-sRGBA color spaces. 75 61 auto [r, g, b, a] stop.color.toSRGBALossy<float>(); 76 gradientStops. append(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a)));62 gradientStops.gradientStops.uncheckedAppend(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a))); 77 63 } 78 64 … … 122 108 HRESULT hr = renderTarget->CreateGradientStopCollection(gradientStops.data(), gradientStops.size(), &gradientStopCollection); 123 109 RELEASE_ASSERT(SUCCEEDED(hr)); 124 125 if (m_gradient) {126 m_gradient->Release();127 m_gradient = nullptr;128 }129 110 130 111 WTF::switchOn(m_data, … … 136 117 &linearGradient); 137 118 RELEASE_ASSERT(SUCCEEDED(hr)); 138 m_ gradient = linearGradient;119 m_brush = adoptCOM(linearGradient); 139 120 }, 140 121 [&] (const RadialData& data) { … … 155 136 &radialGradient); 156 137 RELEASE_ASSERT(SUCCEEDED(hr)); 157 m_ gradient = radialGradient;138 m_brush = adoptCOM(radialGradient); 158 139 }, 159 140 [&] (const ConicData&) { 160 141 // FIXME: implement conic gradient rendering. 142 m_brush = nullptr; 161 143 } 162 144 ); 163 145 164 hash();146 return m_brush.get(); 165 147 } 166 148 … … 171 153 WTF::switchOn(m_data, 172 154 [&] (const LinearData& data) { 173 if (!m_cachedHash || !m_gradient) 174 generateGradient(d2dContext); 155 // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context? 156 if (!m_brush) 157 createBrush(d2dContext); 175 158 176 159 #if ASSERT_ENABLED … … 179 162 180 163 const D2D1_RECT_F d2dRect = rect; 181 d2dContext->FillRectangle(&d2dRect, m_ gradient);164 d2dContext->FillRectangle(&d2dRect, m_brush.get()); 182 165 }, 183 166 [&] (const RadialData& data) { … … 200 183 } 201 184 202 if (!m_cachedHash || !m_gradient) 203 generateGradient(d2dContext); 185 // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context? 186 if (!m_brush) 187 createBrush(d2dContext); 204 188 205 189 #if ASSERT_ENABLED … … 208 192 209 193 const D2D1_RECT_F d2dRect = rect; 210 d2dContext->FillRectangle(&d2dRect, m_ gradient);194 d2dContext->FillRectangle(&d2dRect, m_brush.get()); 211 195 212 196 if (needScaling) -
trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp
r250188 r264280 156 156 void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, Gradient& gradient) 157 157 { 158 COMPtr<ID2D1Brush> platformGradient = gradient.createPlatformGradientIfNecessary(m_platformContext.renderTarget());159 if (! platformGradient)158 auto brush = gradient.createBrush(m_platformContext.renderTarget()); 159 if (!brush) 160 160 return; 161 161 162 Direct2D::fillRectWithGradient(m_platformContext, rect, platformGradient.get());162 Direct2D::fillRectWithGradient(m_platformContext, rect, brush.get()); 163 163 } 164 164 -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
r264190 r264280 29 29 #if ENABLE(SMOOTH_SCROLLING) 30 30 31 #import " FloatPoint.h"31 #import "Gradient.h" 32 32 #import "GraphicsLayer.h" 33 33 #import "Logging.h" -
trunk/Source/WebCore/rendering/RenderThemeIOS.mm
r264050 r264280 901 901 902 902 const int progressBarHeight = 9; 903 const float verticalOffset = (rect.height() - progressBarHeight) / 2.0 ;903 const float verticalOffset = (rect.height() - progressBarHeight) / 2.0f; 904 904 905 905 GraphicsContextStateSaver stateSaver(paintInfo.context()); … … 913 913 // 1.1) Draw the white background with grey gradient border. 914 914 GraphicsContext& context = paintInfo.context(); 915 context.setStrokeThickness(0.68 );915 context.setStrokeThickness(0.68f); 916 916 context.setStrokeStyle(SolidStroke); 917 917 918 918 const float verticalRenderingPosition = rect.y() + verticalOffset; 919 919 auto strokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) }); 920 strokeGradient->addColorStop( 0.0, makeSimpleColor(141, 141, 141));921 strokeGradient->addColorStop( 0.45, makeSimpleColor(238, 238, 238));922 strokeGradient->addColorStop( 0.55, makeSimpleColor(238, 238, 238));923 strokeGradient->addColorStop( 1.0, makeSimpleColor(141, 141, 141));920 strokeGradient->addColorStop({ 0.0f, makeSimpleColor(141, 141, 141) }); 921 strokeGradient->addColorStop({ 0.45f, makeSimpleColor(238, 238, 238) }); 922 strokeGradient->addColorStop({ 0.55f, makeSimpleColor(238, 238, 238) }); 923 strokeGradient->addColorStop({ 1.0f, makeSimpleColor(141, 141, 141) }); 924 924 context.setStrokeGradient(WTFMove(strokeGradient)); 925 925 … … 927 927 928 928 Path trackPath; 929 FloatRect trackRect(rect.x() + 0.25 , verticalRenderingPosition + 0.25, rect.width() - 0.5, progressBarHeight - 0.5);929 FloatRect trackRect(rect.x() + 0.25f, verticalRenderingPosition + 0.25f, rect.width() - 0.5f, progressBarHeight - 0.5f); 930 930 FloatSize roundedCornerRadius(5, 4); 931 931 trackPath.addRoundedRect(trackRect, roundedCornerRadius); … … 937 937 938 938 float upperGradientHeight = progressBarHeight / 2.; 939 auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5 ), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });940 upperGradient->addColorStop( 0.0, makeSimpleColor(133, 133, 133, 188));941 upperGradient->addColorStop( 1.0, makeSimpleColor(18, 18, 18, 51));939 auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) }); 940 upperGradient->addColorStop({ 0.0f, makeSimpleColor(133, 133, 133, 188) }); 941 upperGradient->addColorStop({ 1.0f, makeSimpleColor(18, 18, 18, 51) }); 942 942 context.setFillGradient(WTFMove(upperGradient)); 943 943 … … 948 948 // 2) Draw the progress bar. 949 949 double position = clampTo(renderProgress.position(), 0.0, 1.0); 950 doublebarWidth = position * rect.width();951 auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5 ), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });952 barGradient->addColorStop( 0.0, makeSimpleColor(195, 217, 247));953 barGradient->addColorStop( 0.45, makeSimpleColor(118, 164, 228));954 barGradient->addColorStop( 0.49, makeSimpleColor(118, 164, 228));955 barGradient->addColorStop( 0.51, makeSimpleColor(36, 114, 210));956 barGradient->addColorStop( 0.55, makeSimpleColor(36, 114, 210));957 barGradient->addColorStop( 1.0, makeSimpleColor(57, 142, 244));950 float barWidth = position * rect.width(); 951 auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) }); 952 barGradient->addColorStop({ 0.0f, makeSimpleColor(195, 217, 247) }); 953 barGradient->addColorStop({ 0.45f, makeSimpleColor(118, 164, 228) }); 954 barGradient->addColorStop({ 0.49f, makeSimpleColor(118, 164, 228) }); 955 barGradient->addColorStop({ 0.51f, makeSimpleColor(36, 114, 210) }); 956 barGradient->addColorStop({ 0.55f, makeSimpleColor(36, 114, 210) }); 957 barGradient->addColorStop({ 1.0f, makeSimpleColor(57, 142, 244) }); 958 958 context.setFillGradient(WTFMove(barGradient)); 959 959 960 960 auto barStrokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) }); 961 barStrokeGradient->addColorStop( 0.0, makeSimpleColor(95, 107, 183));962 barStrokeGradient->addColorStop( 0.5, makeSimpleColor(66, 106, 174, 240));963 barStrokeGradient->addColorStop( 1.0, makeSimpleColor(38, 104, 166));961 barStrokeGradient->addColorStop({ 0.0f, makeSimpleColor(95, 107, 183) }); 962 barStrokeGradient->addColorStop({ 0.5f, makeSimpleColor(66, 106, 174, 240) }); 963 barStrokeGradient->addColorStop({ 1.0f, makeSimpleColor(38, 104, 166) }); 964 964 context.setStrokeGradient(WTFMove(barStrokeGradient)); 965 965 … … 968 968 if (!renderProgress.style().isLeftToRightDirection()) 969 969 left = rect.maxX() - barWidth; 970 FloatRect barRect(left + 0.25 , verticalRenderingPosition + 0.25, std::max(barWidth - 0.5, 0.0), progressBarHeight - 0.5);970 FloatRect barRect(left + 0.25f, verticalRenderingPosition + 0.25f, std::max(barWidth - 0.5f, 0.0f), progressBarHeight - 0.5f); 971 971 barPath.addRoundedRect(barRect, roundedCornerRadius); 972 972 context.drawPath(barPath); -
trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
r262684 r264280 235 235 void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vector<Gradient::ColorStop>& stops, const RenderStyle& style) const 236 236 { 237 ASSERT(gradientData); 237 238 ASSERT(gradientData->gradient); 238 239 for (Gradient::ColorStop stop : stops) { 240 stop.color = style.colorByApplyingColorFilter(stop.color); 241 gradientData->gradient->addColorStop(stop); 242 } 239 for (auto& stop : stops) 240 gradientData->gradient->addColorStop({ stop.offset, style.colorByApplyingColorFilter(stop.color) }); 243 241 } 244 242 -
trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
r231153 r264280 22 22 #pragma once 23 23 24 #include "Gradient.h"25 24 #include "ImageBuffer.h" 26 25 #include "RenderSVGResourceContainer.h" -
trunk/Source/WebCore/svg/SVGGradientElement.cpp
r251318 r264280 103 103 Vector<Gradient::ColorStop> stops; 104 104 float previousOffset = 0.0f; 105 106 105 for (auto& stop : childrenOfType<SVGStopElement>(*this)) { 107 const Color& color = stop.stopColorIncludingOpacity(); 108 109 // Figure out right monotonic offset. 110 float offset = stop.offset(); 111 offset = std::min(std::max(previousOffset, offset), 1.0f); 112 previousOffset = offset; 113 114 stops.append(Gradient::ColorStop(offset, color)); 106 auto monotonicallyIncreasingOffset = std::clamp(stop.offset(), previousOffset, 1.0f); 107 previousOffset = monotonicallyIncreasingOffset; 108 stops.append({ monotonicallyIncreasingOffset, stop.stopColorIncludingOpacity() }); 115 109 } 116 117 110 return stops; 118 111 }
Note:
See TracChangeset
for help on using the changeset viewer.