Changeset 27781 in webkit
- Timestamp:
- Nov 13, 2007 7:48:44 PM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r27779 r27781 1 2007-11-13 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Anders. 4 5 <rdar://problem/5365030> calling dataWithPDFInsideRect on an SVG with a gradient crashes (14780) 6 7 When drawing directly to PDF CG may delay the use of the gradient function until outside our 8 standard drawing path, which in turn could let us invalidate the caches before they were used. 9 10 To work around this we now store the cached stops in a RefCounted object, so that we can ensure 11 that cache exists as long as required. 12 13 * platform/graphics/svg/SVGPaintServerGradient.cpp: 14 (WebCore::SVGPaintServerGradient::SVGPaintServerGradient): 15 * platform/graphics/svg/SVGPaintServerGradient.h: 16 * platform/graphics/svg/cg/SVGPaintServerGradientCg.cpp: 17 (WebCore::cgGradientCallback): 18 (WebCore::CGShadingRefForLinearGradient): 19 (WebCore::CGShadingRefForRadialGradient): 20 (WebCore::SVGPaintServerGradient::updateQuartzGradientStopsCache): 21 1 22 2007-11-13 Anders Carlsson <andersca@apple.com> 2 23 -
trunk/WebCore/platform/graphics/svg/SVGPaintServerGradient.cpp
r19855 r27781 67 67 #if PLATFORM(CG) 68 68 , m_stopsCache(0) 69 , m_stopsCount(0)70 69 , m_shadingCache(0) 71 70 , m_savedContext(0) … … 79 78 { 80 79 #if PLATFORM(CG) 81 delete m_stopsCache;82 80 CGShadingRelease(m_shadingCache); 83 81 #endif -
trunk/WebCore/platform/graphics/svg/SVGPaintServerGradient.h
r26446 r27781 32 32 #include "Color.h" 33 33 #include "SVGPaintServer.h" 34 35 #include <wtf/RefCounted.h> 36 #include <wtf/RefPtr.h> 34 37 35 38 #if PLATFORM(QT) … … 111 114 CGFloat previousDeltaInverse; 112 115 } QuartzGradientStop; 116 117 struct SharedStopCache : public RefCounted<SharedStopCache> { 118 Vector<QuartzGradientStop> m_stops; 119 }; 113 120 114 QuartzGradientStop* m_stopsCache; 115 int m_stopsCount; 121 RefPtr<SharedStopCache> m_stopsCache; 116 122 117 123 CGShadingRef m_shadingCache; -
trunk/WebCore/platform/graphics/svg/cg/SVGPaintServerGradientCg.cpp
r26749 r27781 41 41 namespace WebCore { 42 42 43 static void releaseCachedStops(void* info) 44 { 45 reinterpret_cast<SVGPaintServerGradient::SharedStopCache*>(info)->deref(); 46 } 47 43 48 static void cgGradientCallback(void* info, const CGFloat* inValues, CGFloat* outColor) 44 49 { 45 const SVGPaintServerGradient* server = reinterpret_cast<const SVGPaintServerGradient*>(info); 46 SVGPaintServerGradient::QuartzGradientStop* stops = server->m_stopsCache; 47 int stopsCount = server->m_stopsCount; 50 SVGPaintServerGradient::SharedStopCache* stopsCache = reinterpret_cast<SVGPaintServerGradient::SharedStopCache*>(info); 51 52 SVGPaintServerGradient::QuartzGradientStop* stops = stopsCache->m_stops.data(); 53 54 int stopsCount = stopsCache->m_stops.size(); 48 55 49 56 CGFloat inValue = inValues[0]; … … 87 94 CGPoint end = CGPoint(server->gradientEnd()); 88 95 89 CGFunctionCallbacks callbacks = {0, cgGradientCallback, NULL};96 CGFunctionCallbacks callbacks = {0, cgGradientCallback, releaseCachedStops}; 90 97 CGFloat domainLimits[2] = {0, 1}; 91 98 CGFloat rangeLimits[8] = {0, 1, 0, 1, 0, 1, 0, 1}; 92 CGFunctionRef shadingFunction = CGFunctionCreate((void *)server, 1, domainLimits, 4, rangeLimits, &callbacks); 99 server->m_stopsCache->ref(); 100 CGFunctionRef shadingFunction = CGFunctionCreate(server->m_stopsCache.get(), 1, domainLimits, 4, rangeLimits, &callbacks); 93 101 94 102 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); … … 116 124 } 117 125 118 CGFunctionCallbacks callbacks = {0, cgGradientCallback, NULL};126 CGFunctionCallbacks callbacks = {0, cgGradientCallback, releaseCachedStops}; 119 127 CGFloat domainLimits[2] = {0, 1}; 120 128 CGFloat rangeLimits[8] = {0, 1, 0, 1, 0, 1, 0, 1}; 121 CGFunctionRef shadingFunction = CGFunctionCreate((void *)server, 1, domainLimits, 4, rangeLimits, &callbacks); 129 server->m_stopsCache->ref(); 130 CGFunctionRef shadingFunction = CGFunctionCreate(server->m_stopsCache.get(), 1, domainLimits, 4, rangeLimits, &callbacks); 122 131 123 132 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); … … 130 139 void SVGPaintServerGradient::updateQuartzGradientStopsCache(const Vector<SVGGradientStop>& stops) 131 140 { 132 delete m_stopsCache; 133 134 m_stopsCount = stops.size(); 135 m_stopsCache = new SVGPaintServerGradient::QuartzGradientStop[m_stopsCount]; 136 141 m_stopsCache = new SharedStopCache; 142 Vector<QuartzGradientStop>& stopsCache = m_stopsCache->m_stops; 143 stopsCache.resize(stops.size()); 137 144 CGFloat previousOffset = 0.0f; 138 145 for (unsigned i = 0; i < stops.size(); ++i) { 139 146 CGFloat currOffset = min(max(stops[i].first, previousOffset), static_cast<CGFloat>(1.0)); 140 m_stopsCache[i].offset = currOffset;141 m_stopsCache[i].previousDeltaInverse = 1.0f / (currOffset - previousOffset);147 stopsCache[i].offset = currOffset; 148 stopsCache[i].previousDeltaInverse = 1.0f / (currOffset - previousOffset); 142 149 previousOffset = currOffset; 143 CGFloat* ca = m_stopsCache[i].colorArray;150 CGFloat* ca = stopsCache[i].colorArray; 144 151 stops[i].second.getRGBA(ca[0], ca[1], ca[2], ca[3]); 145 152 } … … 322 329 { 323 330 // Invalidate caches 324 delete m_stopsCache;325 331 CGShadingRelease(m_shadingCache); 326 332
Note: See TracChangeset
for help on using the changeset viewer.