| 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 "SkFlattenableBuffers.h" | 11 #include "SkFlattenableBuffers.h" |
| 12 | 12 |
| 13 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
| 14 #if SK_SUPPORT_GPU | 14 #if SK_SUPPORT_GPU |
| 15 #include "effects/GrSingleTextureEffect.h" | 15 #include "effects/GrSingleTextureEffect.h" |
| 16 #include "gl/GrGLEffect.h" | 16 #include "gl/GrGLEffect.h" |
| 17 #include "gl/GrGLSL.h" | 17 #include "gl/GrGLSL.h" |
| 18 #include "gl/GrGLTexture.h" | 18 #include "gl/GrGLTexture.h" |
| 19 #include "GrTBackendEffectFactory.h" | 19 #include "GrTBackendEffectFactory.h" |
| 20 | 20 |
| 21 class GrGLMagnifierEffect; | 21 class GrGLMagnifierEffect; |
| 22 | 22 |
| 23 class GrMagnifierEffect : public GrSingleTextureEffect { | 23 class GrMagnifierEffect : public GrSingleTextureEffect { |
| 24 | 24 |
| 25 public: | 25 public: |
| 26 static GrEffectRef* Create(GrTexture* texture, | 26 static GrEffectRef* Create(GrTexture* texture, |
| 27 float xOffset, | 27 float xOffset, |
| 28 float yOffset, | 28 float yOffset, |
| 29 float xZoom, | 29 float xInvZoom, |
| 30 float yZoom, | 30 float yInvZoom, |
| 31 float xInset, | 31 float xInvInset, |
| 32 float yInset) { | 32 float yInvInset) { |
| 33 AutoEffectUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture, | 33 AutoEffectUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture, |
| 34 xOffset, | 34 xOffset, |
| 35 yOffset, | 35 yOffset, |
| 36 xZoom, | 36 xInvZoom, |
| 37 yZoom, | 37 yInvZoom, |
| 38 xInset, | 38 xInvInset, |
| 39 yInset))); | 39 yInvInset))); |
| 40 return CreateEffectRef(effect); | 40 return CreateEffectRef(effect); |
| 41 } | 41 } |
| 42 | 42 |
| 43 virtual ~GrMagnifierEffect() {}; | 43 virtual ~GrMagnifierEffect() {}; |
| 44 | 44 |
| 45 static const char* Name() { return "Magnifier"; } | 45 static const char* Name() { return "Magnifier"; } |
| 46 | 46 |
| 47 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 47 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 48 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 48 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 49 | 49 |
| 50 float x_offset() const { return fXOffset; } | 50 float x_offset() const { return fXOffset; } |
| 51 float y_offset() const { return fYOffset; } | 51 float y_offset() const { return fYOffset; } |
| 52 float x_zoom() const { return fXZoom; } | 52 float x_inv_zoom() const { return fXInvZoom; } |
| 53 float y_zoom() const { return fYZoom; } | 53 float y_inv_zoom() const { return fYInvZoom; } |
| 54 float x_inset() const { return fXInset; } | 54 float x_inv_inset() const { return fXInvInset; } |
| 55 float y_inset() const { return fYInset; } | 55 float y_inv_inset() const { return fYInvInset; } |
| 56 | 56 |
| 57 typedef GrGLMagnifierEffect GLEffect; | 57 typedef GrGLMagnifierEffect GLEffect; |
| 58 | 58 |
| 59 private: | 59 private: |
| 60 GrMagnifierEffect(GrTexture* texture, | 60 GrMagnifierEffect(GrTexture* texture, |
| 61 float xOffset, | 61 float xOffset, |
| 62 float yOffset, | 62 float yOffset, |
| 63 float xZoom, | 63 float xInvZoom, |
| 64 float yZoom, | 64 float yInvZoom, |
| 65 float xInset, | 65 float xInvInset, |
| 66 float yInset) | 66 float yInvInset) |
| 67 : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture)) | 67 : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture)) |
| 68 , fXOffset(xOffset) | 68 , fXOffset(xOffset) |
| 69 , fYOffset(yOffset) | 69 , fYOffset(yOffset) |
| 70 , fXZoom(xZoom) | 70 , fXInvZoom(xInvZoom) |
| 71 , fYZoom(yZoom) | 71 , fYInvZoom(yInvZoom) |
| 72 , fXInset(xInset) | 72 , fXInvInset(xInvInset) |
| 73 , fYInset(yInset) {} | 73 , fYInvInset(yInvInset) {} |
| 74 | 74 |
| 75 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 75 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 76 | 76 |
| 77 GR_DECLARE_EFFECT_TEST; | 77 GR_DECLARE_EFFECT_TEST; |
| 78 | 78 |
| 79 float fXOffset; | 79 float fXOffset; |
| 80 float fYOffset; | 80 float fYOffset; |
| 81 float fXZoom; | 81 float fXInvZoom; |
| 82 float fYZoom; | 82 float fYInvZoom; |
| 83 float fXInset; | 83 float fXInvInset; |
| 84 float fYInset; | 84 float fYInvInset; |
| 85 | 85 |
| 86 typedef GrSingleTextureEffect INHERITED; | 86 typedef GrSingleTextureEffect INHERITED; |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 // For brevity | 89 // For brevity |
| 90 typedef GrGLUniformManager::UniformHandle UniformHandle; | 90 typedef GrGLUniformManager::UniformHandle UniformHandle; |
| 91 | 91 |
| 92 class GrGLMagnifierEffect : public GrGLEffect { | 92 class GrGLMagnifierEffect : public GrGLEffect { |
| 93 public: | 93 public: |
| 94 GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 94 GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| 95 | 95 |
| 96 virtual void emitCode(GrGLShaderBuilder*, | 96 virtual void emitCode(GrGLShaderBuilder*, |
| 97 const GrDrawEffect&, | 97 const GrDrawEffect&, |
| 98 EffectKey, | 98 EffectKey, |
| 99 const char* outputColor, | 99 const char* outputColor, |
| 100 const char* inputColor, | 100 const char* inputColor, |
| 101 const TransformedCoordsArray&, | 101 const TransformedCoordsArray&, |
| 102 const TextureSamplerArray&) SK_OVERRIDE; | 102 const TextureSamplerArray&) SK_OVERRIDE; |
| 103 | 103 |
| 104 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 104 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
| 105 | 105 |
| 106 private: | 106 private: |
| 107 UniformHandle fOffsetVar; | 107 UniformHandle fOffsetVar; |
| 108 UniformHandle fZoomVar; | 108 UniformHandle fInvZoomVar; |
| 109 UniformHandle fInsetVar; | 109 UniformHandle fInvInsetVar; |
| 110 | 110 |
| 111 typedef GrGLEffect INHERITED; | 111 typedef GrGLEffect INHERITED; |
| 112 }; | 112 }; |
| 113 | 113 |
| 114 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect&) | 114 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect&) |
| 115 : INHERITED(factory) { | 115 : INHERITED(factory) { |
| 116 } | 116 } |
| 117 | 117 |
| 118 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder, | 118 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder, |
| 119 const GrDrawEffect&, | 119 const GrDrawEffect&, |
| 120 EffectKey key, | 120 EffectKey key, |
| 121 const char* outputColor, | 121 const char* outputColor, |
| 122 const char* inputColor, | 122 const char* inputColor, |
| 123 const TransformedCoordsArray& coords, | 123 const TransformedCoordsArray& coords, |
| 124 const TextureSamplerArray& samplers) { | 124 const TextureSamplerArray& samplers) { |
| 125 SkString coords2D = builder->ensureFSCoords2D(coords, 0); | 125 SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
| 126 fOffsetVar = builder->addUniform( | 126 fOffsetVar = builder->addUniform( |
| 127 GrGLShaderBuilder::kFragment_Visibility | | 127 GrGLShaderBuilder::kFragment_Visibility | |
| 128 GrGLShaderBuilder::kVertex_Visibility, | 128 GrGLShaderBuilder::kVertex_Visibility, |
| 129 kVec2f_GrSLType, "uOffset"); | 129 kVec2f_GrSLType, "Offset"); |
| 130 fZoomVar = builder->addUniform( | 130 fInvZoomVar = builder->addUniform( |
| 131 GrGLShaderBuilder::kFragment_Visibility | | 131 GrGLShaderBuilder::kFragment_Visibility | |
| 132 GrGLShaderBuilder::kVertex_Visibility, | 132 GrGLShaderBuilder::kVertex_Visibility, |
| 133 kVec2f_GrSLType, "uZoom"); | 133 kVec2f_GrSLType, "InvZoom"); |
| 134 fInsetVar = builder->addUniform( | 134 fInvInsetVar = builder->addUniform( |
| 135 GrGLShaderBuilder::kFragment_Visibility | | 135 GrGLShaderBuilder::kFragment_Visibility | |
| 136 GrGLShaderBuilder::kVertex_Visibility, | 136 GrGLShaderBuilder::kVertex_Visibility, |
| 137 kVec2f_GrSLType, "uInset"); | 137 kVec2f_GrSLType, "InvInset"); |
| 138 | 138 |
| 139 builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); | 139 builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); |
| 140 builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s / %s;\n", | 140 builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n", |
| 141 builder->getUniformCStr(fOffsetVar), | 141 builder->getUniformCStr(fOffsetVar), |
| 142 coords2D.c_str(), | 142 coords2D.c_str(), |
| 143 builder->getUniformCStr(fZoomVar)); | 143 builder->getUniformCStr(fInvZoomVar)); |
| 144 | 144 |
| 145 builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\
n"); | 145 builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\
n"); |
| 146 | 146 |
| 147 builder->fsCodeAppendf("\t\tdelta = delta / %s;\n", builder->getUniformCStr(
fInsetVar)); | 147 builder->fsCodeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(
fInvInsetVar)); |
| 148 | 148 |
| 149 builder->fsCodeAppend("\t\tfloat weight = 0.0;\n"); | 149 builder->fsCodeAppend("\t\tfloat weight = 0.0;\n"); |
| 150 builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); | 150 builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); |
| 151 builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); | 151 builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); |
| 152 builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n"); | 152 builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n"); |
| 153 builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); | 153 builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); |
| 154 builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); | 154 builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); |
| 155 builder->fsCodeAppend("\t\t} else {\n"); | 155 builder->fsCodeAppend("\t\t} else {\n"); |
| 156 builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); | 156 builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); |
| 157 builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.s, delta_squared
.y), 1.0);\n"); | 157 builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared
.y), 1.0);\n"); |
| 158 builder->fsCodeAppend("\t\t}\n"); | 158 builder->fsCodeAppend("\t\t}\n"); |
| 159 | 159 |
| 160 builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\
n"); | 160 builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\
n"); |
| 161 builder->fsCodeAppend("\t\tvec4 output_color = "); | 161 builder->fsCodeAppend("\t\tvec4 output_color = "); |
| 162 builder->fsAppendTextureLookup(samplers[0], "mix_coord"); | 162 builder->fsAppendTextureLookup(samplers[0], "mix_coord"); |
| 163 builder->fsCodeAppend(";\n"); | 163 builder->fsCodeAppend(";\n"); |
| 164 | 164 |
| 165 builder->fsCodeAppendf("\t\t%s = output_color;", outputColor); | 165 builder->fsCodeAppendf("\t\t%s = output_color;", outputColor); |
| 166 SkString modulate; | 166 SkString modulate; |
| 167 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); | 167 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); |
| 168 builder->fsCodeAppend(modulate.c_str()); | 168 builder->fsCodeAppend(modulate.c_str()); |
| 169 } | 169 } |
| 170 | 170 |
| 171 void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman, | 171 void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman, |
| 172 const GrDrawEffect& drawEffect) { | 172 const GrDrawEffect& drawEffect) { |
| 173 const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>(); | 173 const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>(); |
| 174 uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); | 174 uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); |
| 175 uman.set2f(fZoomVar, zoom.x_zoom(), zoom.y_zoom()); | 175 uman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom()); |
| 176 uman.set2f(fInsetVar, zoom.x_inset(), zoom.y_inset()); | 176 uman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset()); |
| 177 } | 177 } |
| 178 | 178 |
| 179 ///////////////////////////////////////////////////////////////////// | 179 ///////////////////////////////////////////////////////////////////// |
| 180 | 180 |
| 181 GR_DEFINE_EFFECT_TEST(GrMagnifierEffect); | 181 GR_DEFINE_EFFECT_TEST(GrMagnifierEffect); |
| 182 | 182 |
| 183 GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random, | 183 GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random, |
| 184 GrContext* context, | 184 GrContext* context, |
| 185 const GrDrawTargetCaps&, | 185 const GrDrawTargetCaps&, |
| 186 GrTexture** textures) { | 186 GrTexture** textures) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 210 | 210 |
| 211 const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const { | 211 const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const { |
| 212 return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance(); | 212 return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance(); |
| 213 } | 213 } |
| 214 | 214 |
| 215 bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const { | 215 bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const { |
| 216 const GrMagnifierEffect& s = CastEffect<GrMagnifierEffect>(sBase); | 216 const GrMagnifierEffect& s = CastEffect<GrMagnifierEffect>(sBase); |
| 217 return (this->texture(0) == s.texture(0) && | 217 return (this->texture(0) == s.texture(0) && |
| 218 this->fXOffset == s.fXOffset && | 218 this->fXOffset == s.fXOffset && |
| 219 this->fYOffset == s.fYOffset && | 219 this->fYOffset == s.fYOffset && |
| 220 this->fXZoom == s.fXZoom && | 220 this->fXInvZoom == s.fXInvZoom && |
| 221 this->fYZoom == s.fYZoom && | 221 this->fYInvZoom == s.fYInvZoom && |
| 222 this->fXInset == s.fXInset && | 222 this->fXInvInset == s.fXInvInset && |
| 223 this->fYInset == s.fYInset); | 223 this->fYInvInset == s.fYInvInset); |
| 224 } | 224 } |
| 225 | 225 |
| 226 void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { | 226 void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { |
| 227 this->updateConstantColorComponentsForModulation(color, validFlags); | 227 this->updateConstantColorComponentsForModulation(color, validFlags); |
| 228 } | 228 } |
| 229 | 229 |
| 230 #endif | 230 #endif |
| 231 | 231 |
| 232 //////////////////////////////////////////////////////////////////////////////// | 232 //////////////////////////////////////////////////////////////////////////////// |
| 233 SkMagnifierImageFilter::SkMagnifierImageFilter(SkFlattenableReadBuffer& buffer) | 233 SkMagnifierImageFilter::SkMagnifierImageFilter(SkFlattenableReadBuffer& buffer) |
| 234 : INHERITED(buffer) { | 234 : INHERITED(buffer) { |
| 235 float x = buffer.readScalar(); | 235 float x = buffer.readScalar(); |
| 236 float y = buffer.readScalar(); | 236 float y = buffer.readScalar(); |
| 237 float width = buffer.readScalar(); | 237 float width = buffer.readScalar(); |
| 238 float height = buffer.readScalar(); | 238 float height = buffer.readScalar(); |
| 239 fSrcRect = SkRect::MakeXYWH(x, y, width, height); | 239 fSrcRect = SkRect::MakeXYWH(x, y, width, height); |
| 240 fInset = buffer.readScalar(); | 240 fInset = buffer.readScalar(); |
| 241 } | 241 } |
| 242 | 242 |
| 243 // FIXME: implement single-input semantics | 243 // FIXME: implement single-input semantics |
| 244 SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset) | 244 SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset) |
| 245 : INHERITED(0), fSrcRect(srcRect), fInset(inset) { | 245 : INHERITED(0), fSrcRect(srcRect), fInset(inset) { |
| 246 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); | 246 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); |
| 247 } | 247 } |
| 248 | 248 |
| 249 #if SK_SUPPORT_GPU | 249 #if SK_SUPPORT_GPU |
| 250 bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* textur
e, const SkMatrix&, const SkIRect&) const { | 250 bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* textur
e, const SkMatrix&, const SkIRect&) const { |
| 251 if (effect) { | 251 if (effect) { |
| 252 SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSr
cRect.y() : |
| 253 (texture->height() - (fSrcRect.y() + fSrcRect.height(
))); |
| 254 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1; |
| 252 *effect = GrMagnifierEffect::Create(texture, | 255 *effect = GrMagnifierEffect::Create(texture, |
| 253 fSrcRect.x() / texture->width(), | 256 fSrcRect.x() / texture->width(), |
| 254 fSrcRect.y() / texture->height(), | 257 yOffset / texture->height(), |
| 255 texture->width() / fSrcRect.width(), | 258 fSrcRect.width() / texture->width(), |
| 256 texture->height() / fSrcRect.height(
), | 259 fSrcRect.height() / texture->height(
), |
| 257 fInset / texture->width(), | 260 texture->width() * invInset, |
| 258 fInset / texture->height()); | 261 texture->height() * invInset); |
| 259 } | 262 } |
| 260 return true; | 263 return true; |
| 261 } | 264 } |
| 262 #endif | 265 #endif |
| 263 | 266 |
| 264 void SkMagnifierImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { | 267 void SkMagnifierImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { |
| 265 this->INHERITED::flatten(buffer); | 268 this->INHERITED::flatten(buffer); |
| 266 buffer.writeScalar(fSrcRect.x()); | 269 buffer.writeScalar(fSrcRect.x()); |
| 267 buffer.writeScalar(fSrcRect.y()); | 270 buffer.writeScalar(fSrcRect.y()); |
| 268 buffer.writeScalar(fSrcRect.width()); | 271 buffer.writeScalar(fSrcRect.width()); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 331 |
| 329 int x_val = SkMin32(SkScalarFloorToInt(x_interp), width - 1); | 332 int x_val = SkMin32(SkScalarFloorToInt(x_interp), width - 1); |
| 330 int y_val = SkMin32(SkScalarFloorToInt(y_interp), height - 1); | 333 int y_val = SkMin32(SkScalarFloorToInt(y_interp), height - 1); |
| 331 | 334 |
| 332 *dptr = sptr[y_val * width + x_val]; | 335 *dptr = sptr[y_val * width + x_val]; |
| 333 dptr++; | 336 dptr++; |
| 334 } | 337 } |
| 335 } | 338 } |
| 336 return true; | 339 return true; |
| 337 } | 340 } |
| OLD | NEW |