Changeset 74154 in webkit
- Timestamp:
- Dec 15, 2010 3:48:29 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 10 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r74146 r74154 1 2010-12-15 Helder Correia <helder@sencha.com> 2 3 Reviewed by Ariya Hidayat. 4 5 [Qt] Canvas shadow offset should not be affected by any transformation 6 https://bugs.webkit.org/show_bug.cgi?id=50422 7 8 On a canvas context, shadows are currently affected by all 9 transformations except scaling. According to the spec: 10 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#shadows 11 12 "The shadowOffsetX and shadowOffsetY attributes specify the distance 13 that the shadow will be offset in the positive horizontal and positive 14 vertical distance respectively. Their values are in coordinate space 15 units. They are not affected by the current transformation matrix." 16 17 NOTE: this applies only to canvas, not to box shadows. 18 19 Add new test to ensure that shadows are correctly transformed keeping 20 the relative offset to the shape. 21 22 * fast/canvas/canvas-scale-strokePath-shadow-expected.txt: 23 * fast/canvas/canvas-transforms-fillRect-shadow-expected.txt: Added. 24 * fast/canvas/canvas-transforms-fillRect-shadow.html: Added. 25 * fast/canvas/script-tests/canvas-scale-fillPath-shadow.js: 26 * fast/canvas/script-tests/canvas-scale-fillRect-shadow.js: 27 * fast/canvas/script-tests/canvas-scale-strokePath-shadow.js: Now using 28 a lineWidth > 1 to make it easier to test and more fair among all 29 ports, since there can be different transformation smoothness or 30 aliasing settings. 31 * fast/canvas/script-tests/canvas-transforms-fillRect-shadow.js: Added. 32 1 33 2010-12-15 Kenji Imasaki <imasaki@chromium.org> 2 34 -
trunk/LayoutTests/fast/canvas/canvas-scale-strokePath-shadow-expected.txt
r74054 r74154 31 31 PASS d[1] is 0 32 32 PASS d[2] is 0 33 PASS d[3] is around 2033 PASS d[3] is around 149 34 34 PASS d[0] is 255 35 35 PASS d[1] is 0 36 36 PASS d[2] is 0 37 PASS d[3] is around 2237 PASS d[3] is around 116 38 38 PASS d[0] is 255 39 39 PASS d[1] is 0 40 40 PASS d[2] is 0 41 PASS d[3] is around 2841 PASS d[3] is around 115 42 42 PASS d[0] is 255 43 43 PASS d[1] is 0 44 44 PASS d[2] is 0 45 PASS d[3] is around 2245 PASS d[3] is around 70 46 46 PASS d[0] is 255 47 47 PASS d[1] is 0 48 48 PASS d[2] is 0 49 PASS d[3] is around 1549 PASS d[3] is around 70 50 50 PASS d[0] is 255 51 51 PASS d[1] is 0 52 52 PASS d[2] is 0 53 PASS d[3] is around 1753 PASS d[3] is around 69 54 54 PASS successfullyParsed is true 55 55 -
trunk/LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow-expected.txt
r74153 r74154 1 Ensure correct behavior of canvas with path stroke + shadow afterscaling. A blue and red checkered pattern should be displayed.1 Ensure correct behavior of canvas with fillRect+shadow after translation+rotation+scaling. A blue and red checkered pattern should be displayed. 2 2 3 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". … … 19 19 PASS d[1] is 0 20 20 PASS d[2] is 0 21 PASS d[3] is around 7621 PASS d[3] is around 127 22 22 PASS d[0] is 255 23 23 PASS d[1] is 0 24 24 PASS d[2] is 0 25 PASS d[3] is around 7625 PASS d[3] is around 127 26 26 PASS d[0] is 255 27 27 PASS d[1] is 0 28 28 PASS d[2] is 0 29 PASS d[3] is around 7629 PASS d[3] is around 127 30 30 PASS d[0] is 255 31 31 PASS d[1] is 0 32 32 PASS d[2] is 0 33 PASS d[3] is around 2033 PASS d[3] is around 106 34 34 PASS d[0] is 255 35 35 PASS d[1] is 0 36 36 PASS d[2] is 0 37 PASS d[3] is around 2237 PASS d[3] is around 106 38 38 PASS d[0] is 255 39 39 PASS d[1] is 0 40 40 PASS d[2] is 0 41 PASS d[3] is around 2841 PASS d[3] is around 83 42 42 PASS d[0] is 255 43 43 PASS d[1] is 0 44 44 PASS d[2] is 0 45 PASS d[3] is around 2245 PASS d[3] is around 36 46 46 PASS d[0] is 255 47 47 PASS d[1] is 0 48 48 PASS d[2] is 0 49 PASS d[3] is around 1549 PASS d[3] is around 36 50 50 PASS d[0] is 255 51 51 PASS d[1] is 0 52 52 PASS d[2] is 0 53 PASS d[3] is around 1753 PASS d[3] is around 36 54 54 PASS successfullyParsed is true 55 55 -
trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-fillPath-shadow.js
r74054 r74154 80 80 shouldBe('d[3]', '255'); 81 81 82 d = ctx.getImageData(29 9, 295, 1, 1).data;82 d = ctx.getImageData(298, 295, 1, 1).data; 83 83 shouldBe('d[0]', '255'); 84 84 shouldBe('d[1]', '0'); … … 86 86 shouldBe('d[3]', '255'); 87 87 88 d = ctx.getImageData(200, 29 9, 1, 1).data;88 d = ctx.getImageData(200, 298, 1, 1).data; 89 89 shouldBe('d[0]', '255'); 90 90 shouldBe('d[1]', '0'); … … 99 99 shouldBeAround('d[3]', '76'); 100 100 101 d = ctx.getImageData(29 9, 405, 1, 1).data;101 d = ctx.getImageData(298, 405, 1, 1).data; 102 102 shouldBe('d[0]', '255'); 103 103 shouldBe('d[1]', '0'); … … 105 105 shouldBeAround('d[3]', '76'); 106 106 107 d = ctx.getImageData(205, 49 9, 1, 1).data;107 d = ctx.getImageData(205, 498, 1, 1).data; 108 108 shouldBe('d[0]', '255'); 109 109 shouldBe('d[1]', '0'); -
trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-fillRect-shadow.js
r74054 r74154 59 59 shouldBe('d[3]', '255'); 60 60 61 d = ctx.getImageData(29 9, 295, 1, 1).data;61 d = ctx.getImageData(298, 298, 1, 1).data; 62 62 shouldBe('d[0]', '255'); 63 63 shouldBe('d[1]', '0'); … … 65 65 shouldBe('d[3]', '255'); 66 66 67 d = ctx.getImageData(20 0, 299, 1, 1).data;67 d = ctx.getImageData(201, 298, 1, 1).data; 68 68 shouldBe('d[0]', '255'); 69 69 shouldBe('d[1]', '0'); … … 78 78 shouldBeAround('d[3]', '76'); 79 79 80 d = ctx.getImageData(29 9, 405, 1, 1).data;80 d = ctx.getImageData(298, 405, 1, 1).data; 81 81 shouldBe('d[0]', '255'); 82 82 shouldBe('d[1]', '0'); … … 84 84 shouldBeAround('d[3]', '76'); 85 85 86 d = ctx.getImageData(205, 49 9, 1, 1).data;86 d = ctx.getImageData(205, 498, 1, 1).data; 87 87 shouldBe('d[0]', '255'); 88 88 shouldBe('d[1]', '0'); -
trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-strokePath-shadow.js
r74054 r74154 36 36 ctx.shadowOffsetY = 100; 37 37 ctx.strokeStyle = 'rgba(0, 0, 255, 1)'; 38 ctx.lineWidth = 5; 38 39 39 40 ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; … … 77 78 78 79 // Verify solid shadow. 79 d = ctx.getImageData(2 00, 205, 1, 1).data;80 d = ctx.getImageData(250, 200, 1, 1).data; 80 81 shouldBe('d[0]', '255'); 81 82 shouldBe('d[1]', '0'); … … 83 84 shouldBe('d[3]', '255'); 84 85 85 d = ctx.getImageData( 299, 295, 1, 1).data;86 d = ctx.getImageData(300, 290, 1, 1).data; 86 87 shouldBe('d[0]', '255'); 87 88 shouldBe('d[1]', '0'); … … 89 90 shouldBe('d[3]', '255'); 90 91 91 d = ctx.getImageData(20 1, 299, 1, 1).data;92 d = ctx.getImageData(200, 250, 1, 1).data; 92 93 shouldBe('d[0]', '255'); 93 94 shouldBe('d[1]', '0'); … … 96 97 97 98 // Verify solid alpha shadow. 98 d = ctx.getImageData(20 0, 405, 1, 1).data;99 d = ctx.getImageData(201, 405, 1, 1).data; 99 100 shouldBe('d[0]', '255'); 100 101 shouldBe('d[1]', '0'); … … 102 103 shouldBeAround('d[3]', '76'); 103 104 104 d = ctx.getImageData(2 99, 405, 1, 1).data;105 d = ctx.getImageData(201, 500, 1, 1).data; 105 106 shouldBe('d[0]', '255'); 106 107 shouldBe('d[1]', '0'); … … 108 109 shouldBeAround('d[3]', '76'); 109 110 110 d = ctx.getImageData( 205, 499, 1, 1).data;111 d = ctx.getImageData(300, 499, 1, 1).data; 111 112 shouldBe('d[0]', '255'); 112 113 shouldBe('d[1]', '0'); … … 115 116 116 117 // Verify blurry shadow. 117 d = ctx.getImageData( 394, 208, 1, 1).data;118 d = ctx.getImageData(404, 210, 1, 1).data; 118 119 shouldBe('d[0]', '255'); 119 120 shouldBe('d[1]', '0'); 120 121 shouldBe('d[2]', '0'); 121 shouldBeAround('d[3]', ' 20');122 shouldBeAround('d[3]', '149'); 122 123 123 d = ctx.getImageData(50 3, 301, 1, 1).data;124 d = ctx.getImageData(505, 250, 1, 1).data; 124 125 shouldBe('d[0]', '255'); 125 126 shouldBe('d[1]', '0'); 126 127 shouldBe('d[2]', '0'); 127 shouldBeAround('d[3]', ' 22');128 shouldBeAround('d[3]', '116'); 128 129 129 d = ctx.getImageData( 504, 250, 1, 1).data;130 d = ctx.getImageData(450, 205, 1, 1).data; 130 131 shouldBe('d[0]', '255'); 131 132 shouldBe('d[1]', '0'); 132 133 shouldBe('d[2]', '0'); 133 shouldBeAround('d[3]', ' 28');134 shouldBeAround('d[3]', '115'); 134 135 135 136 // Verify blurry alpha shadow. 136 d = ctx.getImageData( 405, 405, 1, 1).data;137 d = ctx.getImageData(505, 450, 1, 1).data; 137 138 shouldBe('d[0]', '255'); 138 139 shouldBe('d[1]', '0'); 139 140 shouldBe('d[2]', '0'); 140 shouldBeAround('d[3]', ' 22');141 shouldBeAround('d[3]', '70'); 141 142 142 d = ctx.getImageData( 415, 495, 1, 1).data;143 d = ctx.getImageData(505, 450, 1, 1).data; 143 144 shouldBe('d[0]', '255'); 144 145 shouldBe('d[1]', '0'); 145 146 shouldBe('d[2]', '0'); 146 shouldBeAround('d[3]', ' 15');147 shouldBeAround('d[3]', '70'); 147 148 148 d = ctx.getImageData(450, 504, 1, 1).data;149 d = ctx.getImageData(450, 405, 1, 1).data; 149 150 shouldBe('d[0]', '255'); 150 151 shouldBe('d[1]', '0'); 151 152 shouldBe('d[2]', '0'); 152 shouldBeAround('d[3]', ' 17');153 shouldBeAround('d[3]', '69'); 153 154 154 155 var successfullyParsed = true; -
trunk/LayoutTests/fast/canvas/script-tests/canvas-transforms-fillRect-shadow.js
r74153 r74154 1 description("Ensure correct behavior of canvas with fillRect+shadow after scaling. A blue and red checkered pattern should be displayed.");1 description("Ensure correct behavior of canvas with fillRect+shadow after translation+rotation+scaling. A blue and red checkered pattern should be displayed."); 2 2 3 3 function print(message, color) … … 28 28 var canvas = document.createElement('canvas'); 29 29 document.body.appendChild(canvas); 30 canvas.setAttribute('width', ' 1000');31 canvas.setAttribute('height', ' 1000');30 canvas.setAttribute('width', '600'); 31 canvas.setAttribute('height', '600'); 32 32 var ctx = canvas.getContext('2d'); 33 33 34 ctx. scale(2, 2);34 ctx.fillStyle = 'rgba(0, 0, 255, 1.0)'; 35 35 ctx.shadowOffsetX = 100; 36 36 ctx.shadowOffsetY = 100; 37 ctx.fillStyle = 'rgba(0, 0, 255, 1)'; 37 38 ctx.translate(-100, -100); 39 ctx.rotate(Math.PI/2); 40 ctx.scale(2, 2); 38 41 39 42 ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; 40 ctx.fillRect( 50,50, 50, 50);43 ctx.fillRect(100, -150, 50, 50); 41 44 42 ctx.shadowColor = 'rgba(255, 0, 0, 0. 3)';43 ctx.fillRect( 50,150, 50, 50);45 ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; 46 ctx.fillRect(200, -150, 50, 50); 44 47 48 ctx.shadowBlur = 5; 45 49 ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; 46 ctx.shadowBlur = 10; 47 ctx.fillRect(150, 50, 50, 50); 50 ctx.fillRect(100, -250, 50, 50); 48 51 49 ctx.shadowColor = 'rgba(255, 0, 0, 0. 3)';50 ctx.fillRect( 150, 150, 50, 50);52 ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; 53 ctx.fillRect(200, -250, 50, 50); 51 54 52 55 var d; // imageData.data … … 59 62 shouldBe('d[3]', '255'); 60 63 61 d = ctx.getImageData(29 9, 295, 1, 1).data;64 d = ctx.getImageData(298, 298, 1, 1).data; 62 65 shouldBe('d[0]', '255'); 63 66 shouldBe('d[1]', '0'); … … 65 68 shouldBe('d[3]', '255'); 66 69 67 d = ctx.getImageData(20 0, 299, 1, 1).data;70 d = ctx.getImageData(201, 298, 1, 1).data; 68 71 shouldBe('d[0]', '255'); 69 72 shouldBe('d[1]', '0'); … … 72 75 73 76 // Verify solid alpha shadow. 74 d = ctx.getImageData(20 0, 405, 1, 1).data;77 d = ctx.getImageData(201, 401, 1, 1).data; 75 78 shouldBe('d[0]', '255'); 76 79 shouldBe('d[1]', '0'); 77 80 shouldBe('d[2]', '0'); 78 shouldBeAround('d[3]', ' 76');81 shouldBeAround('d[3]', '127'); 79 82 80 d = ctx.getImageData(299, 4 05, 1, 1).data;83 d = ctx.getImageData(299, 450, 1, 1).data; 81 84 shouldBe('d[0]', '255'); 82 85 shouldBe('d[1]', '0'); 83 86 shouldBe('d[2]', '0'); 84 shouldBeAround('d[3]', ' 76');87 shouldBeAround('d[3]', '127'); 85 88 86 d = ctx.getImageData(205, 49 9, 1, 1).data;89 d = ctx.getImageData(205, 498, 1, 1).data; 87 90 shouldBe('d[0]', '255'); 88 91 shouldBe('d[1]', '0'); 89 92 shouldBe('d[2]', '0'); 90 shouldBeAround('d[3]', ' 76');93 shouldBeAround('d[3]', '127'); 91 94 92 95 // Verify blurry shadow. 93 d = ctx.getImageData(398, 205, 1, 1).data; 96 d = ctx.getImageData(399, 205, 1, 1).data; 97 shouldBe('d[0]', '255'); 98 shouldBe('d[1]', '0'); 99 shouldBe('d[2]', '0'); 100 shouldBeAround('d[3]', '106'); 101 102 d = ctx.getImageData(500, 205, 1, 1).data; 103 shouldBe('d[0]', '255'); 104 shouldBe('d[1]', '0'); 105 shouldBe('d[2]', '0'); 106 shouldBeAround('d[3]', '106'); 107 108 d = ctx.getImageData(499, 299, 1, 1).data; 94 109 shouldBe('d[0]', '255'); 95 110 shouldBe('d[1]', '0'); 96 111 shouldBe('d[2]', '0'); 97 112 shouldBeAround('d[3]', '83'); 98 99 d = ctx.getImageData(501, 205, 1, 1).data;100 shouldBe('d[0]', '255');101 shouldBe('d[1]', '0');102 shouldBe('d[2]', '0');103 shouldBeAround('d[3]', '83');104 105 d = ctx.getImageData(500, 300, 1, 1).data;106 shouldBe('d[0]', '255');107 shouldBe('d[1]', '0');108 shouldBe('d[2]', '0');109 shouldBeAround('d[3]', '53');110 113 111 114 // Verify blurry alpha shadow. … … 114 117 shouldBe('d[1]', '0'); 115 118 shouldBe('d[2]', '0'); 116 shouldBeAround('d[3]', ' 24');119 shouldBeAround('d[3]', '36'); 117 120 118 121 d = ctx.getImageData(405, 501, 1, 1).data; … … 120 123 shouldBe('d[1]', '0'); 121 124 shouldBe('d[2]', '0'); 122 shouldBeAround('d[3]', ' 24');125 shouldBeAround('d[3]', '36'); 123 126 124 127 d = ctx.getImageData(405, 501, 1, 1).data; … … 126 129 shouldBe('d[1]', '0'); 127 130 shouldBe('d[2]', '0'); 128 shouldBeAround('d[3]', ' 24');131 shouldBeAround('d[3]', '36'); 129 132 130 133 var successfullyParsed = true; -
trunk/WebCore/ChangeLog
r74153 r74154 1 2010-12-15 Helder Correia <helder@sencha.com> 2 3 Reviewed by Ariya Hidayat. 4 5 [Qt] Canvas shadow offset should not be affected by any transformation 6 https://bugs.webkit.org/show_bug.cgi?id=50422 7 8 On a canvas context, shadows are currently affected by all 9 transformations except scaling. According to the spec: 10 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#shadows 11 12 "The shadowOffsetX and shadowOffsetY attributes specify the distance 13 that the shadow will be offset in the positive horizontal and positive 14 vertical distance respectively. Their values are in coordinate space 15 units. They are not affected by the current transformation matrix." 16 17 NOTE: this applies only to canvas, not to box shadows. 18 19 Test: fast/canvas/canvas-transforms-fillRect-shadow.html 20 21 * platform/graphics/ContextShadow.cpp: 22 (WebCore::ContextShadow::ContextShadow): 23 (WebCore::ContextShadow::calculateLayerBoundingRect): 24 * platform/graphics/ContextShadow.h: 25 (WebCore::ContextShadow::setShadowsIgnoreTransforms): 26 (WebCore::ContextShadow::shadowsIgnoreTransforms): 27 (WebCore::ContextShadow::offset): 28 * platform/graphics/qt/ContextShadowQt.cpp: 29 (WebCore::ContextShadow::beginShadowLayer): 30 (WebCore::ContextShadow::endShadowLayer): 31 * platform/graphics/qt/GraphicsContextQt.cpp: 32 (WebCore::mustUseContextShadow): 33 (WebCore::GraphicsContext::fillPath): 34 (WebCore::GraphicsContext::strokePath): 35 (WebCore::GraphicsContext::fillRect): 36 (WebCore::GraphicsContext::fillRoundedRect): 37 (WebCore::GraphicsContext::setPlatformShadow): 38 1 39 2010-12-15 Timothy Hatcher <timothy@apple.com> 2 40 -
trunk/WebCore/platform/graphics/ContextShadow.cpp
r74054 r74154 42 42 , m_blurDistance(0) 43 43 , m_layerContext(0) 44 , m_shadowsIgnoreTransforms(false) 44 45 { 45 46 } … … 50 51 , m_offset(offset) 51 52 , m_layerContext(0) 53 , m_shadowsIgnoreTransforms(false) 52 54 { 53 55 // See comments in http://webkit.org/b/40793, it seems sensible … … 150 152 } 151 153 154 #if PLATFORM(QT) 155 IntRect ContextShadow::calculateLayerBoundingRect(const PlatformContext p, const FloatRect& layerArea, const IntRect& clipRect) 156 { 157 // Calculate the destination of the blurred and/or transformed layer. 158 FloatRect layerFloatRect; 159 float inflation = 0; 160 161 const QTransform transform = p->transform(); 162 if (m_shadowsIgnoreTransforms && !transform.isIdentity()) { 163 QPolygonF transformedPolygon = transform.map(QPolygonF(layerArea)); 164 transformedPolygon.translate(offset()); 165 layerFloatRect = transform.inverted().map(transformedPolygon).boundingRect(); 166 } else { 167 layerFloatRect = layerArea; 168 layerFloatRect.move(m_offset); 169 } 170 171 // We expand the area by the blur radius to give extra space for the blur transition. 172 if (m_type == BlurShadow) { 173 layerFloatRect.inflate(m_blurDistance); 174 inflation += m_blurDistance; 175 } 176 177 FloatRect unclippedLayerRect = layerFloatRect; 178 179 if (!clipRect.contains(enclosingIntRect(layerFloatRect))) { 180 // No need to have the buffer larger than the clip. 181 layerFloatRect.intersect(clipRect); 182 183 // If we are totally outside the clip region, we aren't painting at all. 184 if (layerFloatRect.isEmpty()) 185 return IntRect(0, 0, 0, 0); 186 187 // We adjust again because the pixels at the borders are still 188 // potentially affected by the pixels outside the buffer. 189 if (m_type == BlurShadow) { 190 layerFloatRect.inflate(m_blurDistance); 191 unclippedLayerRect.inflate(m_blurDistance); 192 inflation += m_blurDistance; 193 } 194 } 195 196 const int frameSize = inflation * 2; 197 m_sourceRect = IntRect(0, 0, layerArea.width() + frameSize, layerArea.height() + frameSize); 198 199 m_layerOrigin = FloatPoint(layerFloatRect.x(), layerFloatRect.y()); 200 201 const FloatPoint m_unclippedLayerOrigin = FloatPoint(unclippedLayerRect.x(), unclippedLayerRect.y()); 202 const FloatSize clippedOut = m_unclippedLayerOrigin - m_layerOrigin; 203 204 // Set the origin as the top left corner of the scratch image, or, in case there's a clipped 205 // out region, set the origin accordingly to the full bounding rect's top-left corner. 206 const float translationX = -layerArea.x() + inflation - fabsf(clippedOut.width()); 207 const float translationY = -layerArea.y() + inflation - fabsf(clippedOut.height()); 208 m_layerContextTranslation = FloatPoint(translationX, translationY); 209 210 return enclosingIntRect(layerFloatRect); 211 } 212 #endif 213 214 #if PLATFORM(CAIRO) 152 215 void ContextShadow::calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect) 153 216 { … … 174 237 } 175 238 } 239 #endif 176 240 177 241 } // namespace WebCore -
trunk/WebCore/platform/graphics/ContextShadow.h
r74054 r74154 107 107 void endShadowLayer(PlatformContext); 108 108 static void purgeScratchBuffer(); 109 void setShadowsIgnoreTransforms(bool enable) { m_shadowsIgnoreTransforms = enable; } 110 bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; } 109 111 #if PLATFORM(CAIRO) 110 112 void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize()); 111 113 #endif 112 113 114 #if PLATFORM(QT) 114 QPointF offset() { return QPointF(m_offset.width(), m_offset.height()); }115 QPointF offset() const { return QPointF(m_offset.width(), m_offset.height()); } 115 116 #endif 116 117 117 118 118 119 private: 120 // Buffer to where the temporary shadow will be drawn to. 121 PlatformImage m_layerImage; 122 // Context used to paint the shadow to the layer image. 123 PlatformContext m_layerContext; 124 #if PLATFORM(QT) 125 // Sub-rect of m_layerImage that contains the shadow pixels. 126 FloatRect m_sourceRect; 127 // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to. 128 FloatPoint m_layerOrigin; 129 // Translation to apply to m_layerContext for the shadow to be correctly clipped. 130 FloatPoint m_layerContextTranslation; 131 #endif 132 #if PLATFORM(CAIRO) 133 // Enclosing int rect where shadow needs to be drawn to using the layer context. 119 134 IntRect m_layerRect; 120 PlatformImage m_layerImage;121 PlatformContext m_layerContext;122 123 135 // Used for reference when canvas scale(x,y) was called. 124 136 FloatRect m_unscaledLayerRect; 137 #endif 138 bool m_shadowsIgnoreTransforms; 125 139 126 140 void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride); 141 #if PLATFORM(CAIRO) 127 142 void calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect); 128 #if PLATFORM(CAIRO)129 143 void drawRectShadowWithoutTiling(PlatformContext context, const IntRect& shadowRect, const IntSize& topLeftRadius, const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius, float alpha); 144 #else 145 IntRect calculateLayerBoundingRect(const PlatformContext, const FloatRect& layerArea, const IntRect& clipRect); 130 146 #endif 131 147 }; -
trunk/WebCore/platform/graphics/qt/ContextShadowQt.cpp
r74054 r74154 115 115 clipRect = p->transform().inverted().mapRect(p->window()); 116 116 117 m_unscaledLayerRect = layerArea; 118 calculateLayerBoundingRect(layerArea, IntRect(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height())); 117 // Set m_layerOrigin, m_layerContextTranslation, m_sourceRect. 118 IntRect clip(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); 119 IntRect layerRect = calculateLayerBoundingRect(p, layerArea, clip); 119 120 120 121 // Don't paint if we are totally outside the clip region. 121 if ( m_layerRect.isEmpty())122 if (layerRect.isEmpty()) 122 123 return 0; 123 124 124 125 ShadowBuffer* shadowBuffer = scratchShadowBuffer(); 125 QImage* shadowImage = shadowBuffer->scratchImage( m_layerRect.size());126 QImage* shadowImage = shadowBuffer->scratchImage(layerRect.size()); 126 127 m_layerImage = QImage(*shadowImage); 127 128 … … 129 130 m_layerContext->begin(&m_layerImage); 130 131 m_layerContext->setFont(p->font()); 131 m_layerContext->translate(m_offset.width(), m_offset.height()); 132 133 // The origin is now the top left corner of the scratch image. 134 m_layerContext->translate(-m_layerRect.x(), -m_layerRect.y()); 135 132 m_layerContext->translate(m_layerContextTranslation); 136 133 return m_layerContext; 137 134 } … … 156 153 } 157 154 158 const QTransform transform = p->transform(); 159 if (transform.isScaling()) { 160 qreal x = m_unscaledLayerRect.x() + m_offset.width() / transform.m11() - m_blurDistance; 161 qreal y = m_unscaledLayerRect.y() + m_offset.height() / transform.m22() - m_blurDistance; 162 p->drawImage(QPointF(x, y), m_layerImage); 163 } else 164 p->drawImage(m_layerRect.topLeft(), m_layerImage); 155 p->drawImage(m_layerOrigin, m_layerImage, m_sourceRect); 165 156 166 157 scratchShadowBuffer()->schedulePurge(); -
trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
r74069 r74154 54 54 55 55 #include <QBrush> 56 #include <QDebug>57 56 #include <QGradient> 58 57 #include <QPaintDevice> … … 176 175 } 177 176 177 static inline bool mustUseContextShadow(QPainter* painter, ContextShadow* shadow) 178 { 179 if (shadow->m_type == ContextShadow::BlurShadow) 180 // We can't avoid ContextShadow, since the shadow has blur. 181 return true; 182 if (!shadow->shadowsIgnoreTransforms()) 183 // We can avoid ContextShadow and optimize, since we're not drawing on a canvas and box 184 // shadows are affected by the transformation matrix. 185 return false; 186 if (painter->transform().isIdentity()) 187 // We can avoid ContextShadow, since there are no transformations to apply to the canvas. 188 return false; 189 // Otherwise, no chance avoiding ContextShadow. 190 return true; 191 } 192 178 193 class GraphicsContextPlatformPrivate : public Noncopyable { 179 194 public: … … 507 522 if (m_data->hasShadow()) { 508 523 ContextShadow* shadow = contextShadow(); 509 if (shadow->m_type != ContextShadow::BlurShadow 510 && !m_state.fillPattern && !m_state.fillGradient) 524 if (mustUseContextShadow(p, shadow) || m_state.fillPattern || m_state.fillGradient) 511 525 { 512 QPointF offset = shadow->offset();513 const QTransform& transform = p->transform();514 if (transform.isScaling()) {515 // If scaling is required, find the new coord for shadow origin,516 // so that the relative offset to its shape is kept.517 QPointF translatedOffset(offset.x() / transform.m11(),518 offset.y() / transform.m22());519 platformPath.translate(translatedOffset);520 p->fillPath(platformPath, QColor(shadow->m_color));521 platformPath.translate(-translatedOffset);522 } else {523 p->translate(offset);524 p->fillPath(platformPath, QColor(shadow->m_color));525 p->translate(-offset);526 }527 } else {528 526 QPainter* shadowPainter = shadow->beginShadowLayer(p, platformPath.controlPointRect()); 529 527 if (shadowPainter) { … … 532 530 shadow->endShadowLayer(p); 533 531 } 532 } else { 533 QPointF offset = shadow->offset(); 534 p->translate(offset); 535 p->fillPath(platformPath, QColor(shadow->m_color)); 536 p->translate(-offset); 534 537 } 535 536 538 } 537 539 if (m_state.fillPattern) { … … 558 560 if (m_data->hasShadow()) { 559 561 ContextShadow* shadow = contextShadow(); 560 561 if (shadow->m_type != ContextShadow::BlurShadow 562 && !m_state.strokePattern && !m_state.strokeGradient) 562 if (mustUseContextShadow(p, shadow) || m_state.strokePattern || m_state.strokeGradient) 563 563 { 564 QPen shadowPen(pen);565 shadowPen.setColor(m_data->shadow.m_color);566 QPointF offset = shadow->offset();567 const QTransform& transform = p->transform();568 if (transform.isScaling()) {569 // If scaling is required, find the new coord for shadow origin,570 // so that the relative offset to its shape is kept.571 QPointF translatedOffset(offset.x() / transform.m11(),572 offset.y() / transform.m22());573 platformPath.translate(translatedOffset);574 p->strokePath(platformPath, shadowPen);575 platformPath.translate(-translatedOffset);576 } else {577 p->translate(offset);578 p->strokePath(platformPath, shadowPen);579 p->translate(-offset);580 }581 } else {582 564 FloatRect boundingRect = platformPath.controlPointRect(); 583 565 boundingRect.inflate(pen.miterLimit() + pen.widthF()); … … 588 570 shadow->endShadowLayer(p); 589 571 } 572 } else { 573 QPen shadowPen(pen); 574 shadowPen.setColor(m_data->shadow.m_color); 575 QPointF offset = shadow->offset(); 576 p->translate(offset); 577 p->strokePath(platformPath, shadowPen); 578 p->translate(-offset); 590 579 } 591 580 } … … 707 696 } else { 708 697 if (m_data->hasShadow()) { 709 if ( shadow->m_type == ContextShadow::BlurShadow) {698 if (mustUseContextShadow(p, shadow)) { 710 699 QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect); 711 700 if (shadowPainter) { … … 715 704 } 716 705 } else { 717 // Solid rectangle fill with no blur shadow can be done faster718 // without using the shadow layer at all.706 // Solid rectangle fill with no blur shadow or transformations applied can be done 707 // faster without using the shadow layer at all. 719 708 QColor shadowColor = shadow->m_color; 720 709 shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF()); 721 const QTransform& transform = p->transform(); 722 if (transform.isScaling()) { 723 p->fillRect(normalizedRect.translated(static_cast<qreal>(shadow->offset().x()) / transform.m11(), 724 static_cast<qreal>(shadow->offset().y() / transform.m22())), 725 shadowColor); 726 } else 727 p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor); 710 p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor); 728 711 } 729 712 } … … 745 728 if (m_data->hasShadow()) { 746 729 ContextShadow* shadow = contextShadow(); 747 748 if (shadow->m_type != ContextShadow::BlurShadow) { 749 // We do not need any layer for simple shadow. 750 p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color); 751 } else { 730 if (mustUseContextShadow(p, shadow)) { 752 731 QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect); 753 732 if (shadowPainter) { … … 756 735 shadow->endShadowLayer(p); 757 736 } 758 } 737 } else 738 p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color); 759 739 } 760 740 … … 772 752 if (m_data->hasShadow()) { 773 753 ContextShadow* shadow = contextShadow(); 774 775 if (shadow->m_type != ContextShadow::BlurShadow) { 776 // We do not need any layer for simple shadow. 777 p->translate(m_data->shadow.offset()); 778 p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color)); 779 p->translate(-m_data->shadow.offset()); 780 } else { 754 if (mustUseContextShadow(p, shadow)) { 781 755 QPainter* shadowPainter = shadow->beginShadowLayer(p, rect); 782 756 if (shadowPainter) { … … 785 759 shadow->endShadowLayer(p); 786 760 } 761 } else { 762 p->translate(m_data->shadow.offset()); 763 p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color)); 764 p->translate(-m_data->shadow.offset()); 787 765 } 788 766 } … … 954 932 m_state.shadowOffset = FloatSize(size.width(), -size.height()); 955 933 m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height())); 956 } else {934 } else 957 935 m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height())); 958 } 936 937 m_data->shadow.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms); 959 938 } 960 939
Note: See TracChangeset
for help on using the changeset viewer.