3 * Copyright 2011 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
9 class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader {
11 ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap& src)
12 : SkBitmapShader(src, true,
13 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)
16 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
19 SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
20 const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table);
21 SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
22 const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table)
27 const SkPMColor *p00, *p01, *p10, *p11;
29 p00 = p01 = ((const SkPMColor*)((const char*)srcPixels
30 + SkClampMax(iy, srcMaxY) * srcRB))
31 + SkClampMax(ix, srcMaxX);
33 if ((unsigned)ix < srcMaxX)
37 if ((unsigned)iy < srcMaxY)
39 p10 = (const SkPMColor*)((const char*)p10 + srcRB);
40 p11 = (const SkPMColor*)((const char*)p11 + srcRB);
43 SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(proc_table, fx, fy);
44 return proc(p00, p01, p10, p11);
47 static inline SkPMColor sample_bilerpx(SkFixed fx, unsigned srcMaxX, const SkPMColor* srcPixels,
48 int srcRB, const SkFilterPtrProc* proc_table)
52 const SkPMColor *p00, *p01, *p10, *p11;
54 p00 = p01 = srcPixels + SkClampMax(ix, srcMaxX);
55 if ((unsigned)ix < srcMaxX)
58 p10 = (const SkPMColor*)((const char*)p00 + srcRB);
59 p11 = (const SkPMColor*)((const char*)p01 + srcRB);
61 SkFilterPtrProc proc = SkGetBilinearFilterPtrXProc(proc_table, fx);
62 return proc(p00, p01, p10, p11);
65 void ARGB32_Clamp_Bilinear_BitmapShader::shadeSpan(int x, int y, SkPMColor dstC[], int count)
69 unsigned srcScale = SkAlpha255To256(this->getPaintAlpha());
71 const SkMatrix& inv = this->getTotalInverse();
72 const SkBitmap& srcBitmap = this->getSrcBitmap();
73 unsigned srcMaxX = srcBitmap.width() - 1;
74 unsigned srcMaxY = srcBitmap.height() - 1;
75 unsigned srcRB = srcBitmap.rowBytes();
77 const SkFilterPtrProc* proc_table = SkGetBilinearFilterPtrProcTable();
78 const SkPMColor* srcPixels = (const SkPMColor*)srcBitmap.getPixels();
80 if (this->getInverseClass() == kPerspective_MatrixClass)
82 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
83 SkIntToScalar(y) + SK_ScalarHalf, count);
87 while ((count = iter.next()) != 0)
89 const SkFixed* srcXY = iter.getXY();
92 SkFixed fx = *srcXY++ - SK_FixedHalf;
93 SkFixed fy = *srcXY++ - SK_FixedHalf;
94 *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
98 else // scale by srcScale
100 while ((count = iter.next()) != 0)
102 const SkFixed* srcXY = iter.getXY();
105 SkFixed fx = *srcXY++ - SK_FixedHalf;
106 SkFixed fy = *srcXY++ - SK_FixedHalf;
107 SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
108 *dstC++ = SkAlphaMulQ(c, srcScale);
115 SkFixed fx, fy, dx, dy;
117 // now init fx, fy, dx, dy
120 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
121 SkIntToScalar(y) + SK_ScalarHalf,
124 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
125 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
127 if (this->getInverseClass() == kFixedStepInX_MatrixClass)
128 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
131 dx = SkScalarToFixed(inv.getScaleX());
132 dy = SkScalarToFixed(inv.getSkewY());
136 if (dy == 0 && (unsigned)(fy >> 16) < srcMaxY)
138 srcPixels = (const SkPMColor*)((const char*)srcPixels + (fy >> 16) * srcRB);
139 proc_table = SkGetBilinearFilterPtrProcYTable(proc_table, fy);
143 *dstC++ = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
145 } while (--count != 0);
150 SkPMColor c = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
151 *dstC++ = SkAlphaMulQ(c, srcScale);
153 } while (--count != 0);
161 *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
164 } while (--count != 0);
169 SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
170 *dstC++ = SkAlphaMulQ(c, srcScale);
173 } while (--count != 0);