OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkMagnifierImageFilter.h" | 9 #include "SkMagnifierImageFilter.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
11 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
12 #include "SkWriteBuffer.h" | 12 #include "SkWriteBuffer.h" |
13 #include "SkValidationUtils.h" | 13 #include "SkValidationUtils.h" |
14 | 14 |
15 //////////////////////////////////////////////////////////////////////////////// | 15 //////////////////////////////////////////////////////////////////////////////// |
16 #if SK_SUPPORT_GPU | 16 #if SK_SUPPORT_GPU |
17 #include "GrInvariantOutput.h" | 17 #include "GrInvariantOutput.h" |
18 #include "effects/GrSingleTextureEffect.h" | 18 #include "effects/GrSingleTextureEffect.h" |
19 #include "gl/GrGLProcessor.h" | 19 #include "gl/GrGLProcessor.h" |
20 #include "gl/GrGLSL.h" | 20 #include "gl/GrGLSL.h" |
21 #include "gl/GrGLTexture.h" | 21 #include "gl/GrGLTexture.h" |
22 #include "gl/builders/GrGLProgramBuilder.h" | 22 #include "gl/builders/GrGLProgramBuilder.h" |
23 | 23 |
24 class GrMagnifierEffect : public GrSingleTextureEffect { | 24 class GrMagnifierEffect : public GrSingleTextureEffect { |
25 | 25 |
26 public: | 26 public: |
27 static GrFragmentProcessor* Create(GrTexture* texture, | 27 static GrFragmentProcessor* Create(GrTexture* texture, |
28 const SkRect& bounds, | |
29 float xOffset, | 28 float xOffset, |
30 float yOffset, | 29 float yOffset, |
31 float xInvZoom, | 30 float xInvZoom, |
32 float yInvZoom, | 31 float yInvZoom, |
33 float xInvInset, | 32 float xInvInset, |
34 float yInvInset) { | 33 float yInvInset) { |
35 return SkNEW_ARGS(GrMagnifierEffect, (texture, | 34 return SkNEW_ARGS(GrMagnifierEffect, (texture, |
36 bounds, | |
37 xOffset, | 35 xOffset, |
38 yOffset, | 36 yOffset, |
39 xInvZoom, | 37 xInvZoom, |
40 yInvZoom, | 38 yInvZoom, |
41 xInvInset, | 39 xInvInset, |
42 yInvInset)); | 40 yInvInset)); |
43 } | 41 } |
44 | 42 |
45 virtual ~GrMagnifierEffect() {}; | 43 virtual ~GrMagnifierEffect() {}; |
46 | 44 |
47 const char* name() const override { return "Magnifier"; } | 45 const char* name() const override { return "Magnifier"; } |
48 | 46 |
49 void getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder*) const overri
de; | 47 void getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder*) const overri
de; |
50 | 48 |
51 GrGLFragmentProcessor* createGLInstance() const override; | 49 GrGLFragmentProcessor* createGLInstance() const override; |
52 | 50 |
53 const SkRect& bounds() const { return fBounds; } // Bounds of source imag
e. | |
54 // Offset to apply to zoomed pixels, (srcRect position / texture size). | |
55 float x_offset() const { return fXOffset; } | 51 float x_offset() const { return fXOffset; } |
56 float y_offset() const { return fYOffset; } | 52 float y_offset() const { return fYOffset; } |
57 | |
58 // Scale to apply to zoomed pixels (srcRect size / bounds size). | |
59 float x_inv_zoom() const { return fXInvZoom; } | 53 float x_inv_zoom() const { return fXInvZoom; } |
60 float y_inv_zoom() const { return fYInvZoom; } | 54 float y_inv_zoom() const { return fYInvZoom; } |
61 | |
62 // 1/radius over which to transition from unzoomed to zoomed pixels (bounds
size / inset). | |
63 float x_inv_inset() const { return fXInvInset; } | 55 float x_inv_inset() const { return fXInvInset; } |
64 float y_inv_inset() const { return fYInvInset; } | 56 float y_inv_inset() const { return fYInvInset; } |
65 | 57 |
66 private: | 58 private: |
67 GrMagnifierEffect(GrTexture* texture, | 59 GrMagnifierEffect(GrTexture* texture, |
68 const SkRect& bounds, | |
69 float xOffset, | 60 float xOffset, |
70 float yOffset, | 61 float yOffset, |
71 float xInvZoom, | 62 float xInvZoom, |
72 float yInvZoom, | 63 float yInvZoom, |
73 float xInvInset, | 64 float xInvInset, |
74 float yInvInset) | 65 float yInvInset) |
75 : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMat
rix(texture)) | 66 : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMat
rix(texture)) |
76 , fBounds(bounds) | |
77 , fXOffset(xOffset) | 67 , fXOffset(xOffset) |
78 , fYOffset(yOffset) | 68 , fYOffset(yOffset) |
79 , fXInvZoom(xInvZoom) | 69 , fXInvZoom(xInvZoom) |
80 , fYInvZoom(yInvZoom) | 70 , fYInvZoom(yInvZoom) |
81 , fXInvInset(xInvInset) | 71 , fXInvInset(xInvInset) |
82 , fYInvInset(yInvInset) { | 72 , fYInvInset(yInvInset) { |
83 this->initClassID<GrMagnifierEffect>(); | 73 this->initClassID<GrMagnifierEffect>(); |
84 } | 74 } |
85 | 75 |
86 bool onIsEqual(const GrFragmentProcessor&) const override; | 76 bool onIsEqual(const GrFragmentProcessor&) const override; |
87 | 77 |
88 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 78 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
89 | 79 |
90 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 80 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
91 | 81 |
92 SkRect fBounds; | |
93 float fXOffset; | 82 float fXOffset; |
94 float fYOffset; | 83 float fYOffset; |
95 float fXInvZoom; | 84 float fXInvZoom; |
96 float fYInvZoom; | 85 float fYInvZoom; |
97 float fXInvInset; | 86 float fXInvInset; |
98 float fYInvInset; | 87 float fYInvInset; |
99 | 88 |
100 typedef GrSingleTextureEffect INHERITED; | 89 typedef GrSingleTextureEffect INHERITED; |
101 }; | 90 }; |
102 | 91 |
(...skipping 10 matching lines...) Expand all Loading... |
113 const char* inputColor, | 102 const char* inputColor, |
114 const TransformedCoordsArray&, | 103 const TransformedCoordsArray&, |
115 const TextureSamplerArray&) override; | 104 const TextureSamplerArray&) override; |
116 | 105 |
117 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 106 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
118 | 107 |
119 private: | 108 private: |
120 UniformHandle fOffsetVar; | 109 UniformHandle fOffsetVar; |
121 UniformHandle fInvZoomVar; | 110 UniformHandle fInvZoomVar; |
122 UniformHandle fInvInsetVar; | 111 UniformHandle fInvInsetVar; |
123 UniformHandle fBoundsVar; | |
124 | 112 |
125 typedef GrGLFragmentProcessor INHERITED; | 113 typedef GrGLFragmentProcessor INHERITED; |
126 }; | 114 }; |
127 | 115 |
128 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrProcessor&) { | 116 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrProcessor&) { |
129 } | 117 } |
130 | 118 |
131 void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder, | 119 void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder, |
132 const GrFragmentProcessor&, | 120 const GrFragmentProcessor&, |
133 const char* outputColor, | 121 const char* outputColor, |
134 const char* inputColor, | 122 const char* inputColor, |
135 const TransformedCoordsArray& coords, | 123 const TransformedCoordsArray& coords, |
136 const TextureSamplerArray& samplers) { | 124 const TextureSamplerArray& samplers) { |
137 fOffsetVar = builder->addUniform( | 125 fOffsetVar = builder->addUniform( |
138 GrGLProgramBuilder::kFragment_Visibility | | 126 GrGLProgramBuilder::kFragment_Visibility | |
139 GrGLProgramBuilder::kVertex_Visibility, | 127 GrGLProgramBuilder::kVertex_Visibility, |
140 kVec2f_GrSLType, kDefault_GrSLPrecision, "Offset"); | 128 kVec2f_GrSLType, kDefault_GrSLPrecision, "Offset"); |
141 fInvZoomVar = builder->addUniform( | 129 fInvZoomVar = builder->addUniform( |
142 GrGLProgramBuilder::kFragment_Visibility | | 130 GrGLProgramBuilder::kFragment_Visibility | |
143 GrGLProgramBuilder::kVertex_Visibility, | 131 GrGLProgramBuilder::kVertex_Visibility, |
144 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvZoom"); | 132 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvZoom"); |
145 fInvInsetVar = builder->addUniform( | 133 fInvInsetVar = builder->addUniform( |
146 GrGLProgramBuilder::kFragment_Visibility | | 134 GrGLProgramBuilder::kFragment_Visibility | |
147 GrGLProgramBuilder::kVertex_Visibility, | 135 GrGLProgramBuilder::kVertex_Visibility, |
148 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset"); | 136 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset"); |
149 fBoundsVar = builder->addUniform( | |
150 GrGLProgramBuilder::kFragment_Visibility | | |
151 GrGLProgramBuilder::kVertex_Visibility, | |
152 kVec4f_GrSLType, kDefault_GrSLPrecision, "Bounds"); | |
153 | 137 |
154 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 138 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
155 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); | 139 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); |
156 fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); | 140 fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); |
157 fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n", | 141 fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n", |
158 builder->getUniformCStr(fOffsetVar), | 142 builder->getUniformCStr(fOffsetVar), |
159 coords2D.c_str(), | 143 coords2D.c_str(), |
160 builder->getUniformCStr(fInvZoomVar)); | 144 builder->getUniformCStr(fInvZoomVar)); |
161 const char* bounds = builder->getUniformCStr(fBoundsVar); | 145 |
162 fsBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds
, bounds); | 146 fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\
n"); |
163 fsBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n"); | 147 |
164 fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(
fInvInsetVar)); | 148 fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(
fInvInsetVar)); |
165 | 149 |
166 fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n"); | 150 fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n"); |
167 fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); | 151 fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); |
168 fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); | 152 fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); |
169 fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n"); | 153 fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n"); |
170 fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); | 154 fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); |
171 fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); | 155 fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); |
172 fsBuilder->codeAppend("\t\t} else {\n"); | 156 fsBuilder->codeAppend("\t\t} else {\n"); |
173 fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); | 157 fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); |
(...skipping 10 matching lines...) Expand all Loading... |
184 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); | 168 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); |
185 fsBuilder->codeAppend(modulate.c_str()); | 169 fsBuilder->codeAppend(modulate.c_str()); |
186 } | 170 } |
187 | 171 |
188 void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman, | 172 void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman, |
189 const GrProcessor& effect) { | 173 const GrProcessor& effect) { |
190 const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>(); | 174 const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>(); |
191 pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); | 175 pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); |
192 pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom()); | 176 pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom()); |
193 pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset()); | 177 pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset()); |
194 pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(), | |
195 zoom.bounds().width(), zoom.bounds().height()); | |
196 } | 178 } |
197 | 179 |
198 ///////////////////////////////////////////////////////////////////// | 180 ///////////////////////////////////////////////////////////////////// |
199 | 181 |
200 void GrMagnifierEffect::getGLProcessorKey(const GrGLCaps& caps, | 182 void GrMagnifierEffect::getGLProcessorKey(const GrGLCaps& caps, |
201 GrProcessorKeyBuilder* b) const { | 183 GrProcessorKeyBuilder* b) const { |
202 GrGLMagnifierEffect::GenKey(*this, caps, b); | 184 GrGLMagnifierEffect::GenKey(*this, caps, b); |
203 } | 185 } |
204 | 186 |
205 GrGLFragmentProcessor* GrMagnifierEffect::createGLInstance() const { | 187 GrGLFragmentProcessor* GrMagnifierEffect::createGLInstance() const { |
(...skipping 11 matching lines...) Expand all Loading... |
217 const int kMaxHeight = 200; | 199 const int kMaxHeight = 200; |
218 const int kMaxInset = 20; | 200 const int kMaxInset = 20; |
219 uint32_t width = random->nextULessThan(kMaxWidth); | 201 uint32_t width = random->nextULessThan(kMaxWidth); |
220 uint32_t height = random->nextULessThan(kMaxHeight); | 202 uint32_t height = random->nextULessThan(kMaxHeight); |
221 uint32_t x = random->nextULessThan(kMaxWidth - width); | 203 uint32_t x = random->nextULessThan(kMaxWidth - width); |
222 uint32_t y = random->nextULessThan(kMaxHeight - height); | 204 uint32_t y = random->nextULessThan(kMaxHeight - height); |
223 uint32_t inset = random->nextULessThan(kMaxInset); | 205 uint32_t inset = random->nextULessThan(kMaxInset); |
224 | 206 |
225 GrFragmentProcessor* effect = GrMagnifierEffect::Create( | 207 GrFragmentProcessor* effect = GrMagnifierEffect::Create( |
226 texture, | 208 texture, |
227 SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)), | |
228 (float) width / texture->width(), | 209 (float) width / texture->width(), |
229 (float) height / texture->height(), | 210 (float) height / texture->height(), |
230 texture->width() / (float) x, | 211 texture->width() / (float) x, |
231 texture->height() / (float) y, | 212 texture->height() / (float) y, |
232 (float) inset / texture->width(), | 213 (float) inset / texture->width(), |
233 (float) inset / texture->height()); | 214 (float) inset / texture->height()); |
234 SkASSERT(effect); | 215 SkASSERT(effect); |
235 return effect; | 216 return effect; |
236 } | 217 } |
237 | 218 |
238 /////////////////////////////////////////////////////////////////////////////// | 219 /////////////////////////////////////////////////////////////////////////////// |
239 | 220 |
240 bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { | 221 bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { |
241 const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>(); | 222 const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>(); |
242 return (this->fBounds == s.fBounds && | 223 return (this->fXOffset == s.fXOffset && |
243 this->fXOffset == s.fXOffset && | |
244 this->fYOffset == s.fYOffset && | 224 this->fYOffset == s.fYOffset && |
245 this->fXInvZoom == s.fXInvZoom && | 225 this->fXInvZoom == s.fXInvZoom && |
246 this->fYInvZoom == s.fYInvZoom && | 226 this->fYInvZoom == s.fYInvZoom && |
247 this->fXInvInset == s.fXInvInset && | 227 this->fXInvInset == s.fXInvInset && |
248 this->fYInvInset == s.fYInvInset); | 228 this->fYInvInset == s.fYInvInset); |
249 } | 229 } |
250 | 230 |
251 void GrMagnifierEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 231 void GrMagnifierEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
252 this->updateInvariantOutputForModulation(inout); | 232 this->updateInvariantOutputForModulation(inout); |
253 } | 233 } |
(...skipping 17 matching lines...) Expand all Loading... |
271 | 251 |
272 | 252 |
273 SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i
nset, | 253 SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i
nset, |
274 SkImageFilter* input) | 254 SkImageFilter* input) |
275 : INHERITED(1, &input), fSrcRect(srcRect), fInset(inset) { | 255 : INHERITED(1, &input), fSrcRect(srcRect), fInset(inset) { |
276 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); | 256 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); |
277 } | 257 } |
278 | 258 |
279 #if SK_SUPPORT_GPU | 259 #if SK_SUPPORT_GPU |
280 bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTex
ture* texture, | 260 bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTex
ture* texture, |
281 const SkMatrix&, const SkIRect&
bounds) const { | 261 const SkMatrix&, const SkIRect&
) const { |
282 if (fp) { | 262 if (fp) { |
283 SkScalar yOffset = texture->origin() == kTopLeft_GrSurfaceOrigin ? fSrcR
ect.y() : | 263 SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSr
cRect.y() : |
284 texture->height() - fSrcRect.height() * texture->height() / bounds.he
ight() | 264 (texture->height() - (fSrcRect.y() + fSrcRect.height(
))); |
285 - fSrcRect.y(); | |
286 int boundsY = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? bounds.y
() : | |
287 (texture->height() - bounds.height()); | |
288 SkRect effectBounds = SkRect::MakeXYWH( | |
289 SkIntToScalar(bounds.x()) / texture->width(), | |
290 SkIntToScalar(boundsY) / texture->height(), | |
291 SkIntToScalar(texture->width()) / bounds.width(), | |
292 SkIntToScalar(texture->height()) / bounds.height()); | |
293 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1; | 265 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1; |
294 *fp = GrMagnifierEffect::Create(texture, | 266 *fp = GrMagnifierEffect::Create(texture, |
295 effectBounds, | |
296 fSrcRect.x() / texture->width(), | 267 fSrcRect.x() / texture->width(), |
297 yOffset / texture->height(), | 268 yOffset / texture->height(), |
298 fSrcRect.width() / bounds.width(), | 269 fSrcRect.width() / texture->width(), |
299 fSrcRect.height() / bounds.height(), | 270 fSrcRect.height() / texture->height(), |
300 bounds.width() * invInset, | 271 texture->width() * invInset, |
301 bounds.height() * invInset); | 272 texture->height() * invInset); |
302 } | 273 } |
303 return true; | 274 return true; |
304 } | 275 } |
305 #endif | 276 #endif |
306 | 277 |
307 SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) { | 278 SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) { |
308 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); | 279 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); |
309 SkRect src; | 280 SkRect src; |
310 buffer.readRect(&src); | 281 buffer.readRect(&src); |
311 return Create(src, buffer.readScalar(), common.getInput(0)); | 282 return Create(src, buffer.readScalar(), common.getInput(0)); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 | 356 |
386 #ifndef SK_IGNORE_TO_STRING | 357 #ifndef SK_IGNORE_TO_STRING |
387 void SkMagnifierImageFilter::toString(SkString* str) const { | 358 void SkMagnifierImageFilter::toString(SkString* str) const { |
388 str->appendf("SkMagnifierImageFilter: ("); | 359 str->appendf("SkMagnifierImageFilter: ("); |
389 str->appendf("src: (%f,%f,%f,%f) ", | 360 str->appendf("src: (%f,%f,%f,%f) ", |
390 fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBotto
m); | 361 fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBotto
m); |
391 str->appendf("inset: %f", fInset); | 362 str->appendf("inset: %f", fInset); |
392 str->append(")"); | 363 str->append(")"); |
393 } | 364 } |
394 #endif | 365 #endif |
OLD | NEW |