• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader {
3 public:
ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap & src)4     ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap& src)
5         : SkBitmapShader(src, true,
6                          SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)
7     {}
8 
9     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
10 };
11 
12 SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
13                         const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table);
sample_bilerp(SkFixed fx,SkFixed fy,unsigned srcMaxX,unsigned srcMaxY,const SkPMColor * srcPixels,int srcRB,const SkFilterPtrProc * proc_table)14 SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
15                         const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table)
16 {
17     int ix = fx >> 16;
18     int iy = fy >> 16;
19 
20     const SkPMColor *p00, *p01, *p10, *p11;
21 
22     p00 = p01 = ((const SkPMColor*)((const char*)srcPixels
23                                     + SkClampMax(iy, srcMaxY) * srcRB))
24                                     + SkClampMax(ix, srcMaxX);
25 
26     if ((unsigned)ix < srcMaxX)
27         p01 += 1;
28     p10 = p00;
29     p11 = p01;
30     if ((unsigned)iy < srcMaxY)
31     {
32         p10 = (const SkPMColor*)((const char*)p10 + srcRB);
33         p11 = (const SkPMColor*)((const char*)p11 + srcRB);
34     }
35 
36     SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(proc_table, fx, fy);
37     return proc(p00, p01, p10, p11);
38 }
39 
sample_bilerpx(SkFixed fx,unsigned srcMaxX,const SkPMColor * srcPixels,int srcRB,const SkFilterPtrProc * proc_table)40 static inline SkPMColor sample_bilerpx(SkFixed fx, unsigned srcMaxX, const SkPMColor* srcPixels,
41                                        int srcRB, const SkFilterPtrProc* proc_table)
42 {
43     int ix = fx >> 16;
44 
45     const SkPMColor *p00, *p01, *p10, *p11;
46 
47     p00 = p01 = srcPixels + SkClampMax(ix, srcMaxX);
48     if ((unsigned)ix < srcMaxX)
49         p01 += 1;
50 
51     p10 = (const SkPMColor*)((const char*)p00 + srcRB);
52     p11 = (const SkPMColor*)((const char*)p01 + srcRB);
53 
54     SkFilterPtrProc proc = SkGetBilinearFilterPtrXProc(proc_table, fx);
55     return proc(p00, p01, p10, p11);
56 }
57 
shadeSpan(int x,int y,SkPMColor dstC[],int count)58 void ARGB32_Clamp_Bilinear_BitmapShader::shadeSpan(int x, int y, SkPMColor dstC[], int count)
59 {
60     SkASSERT(count > 0);
61 
62     unsigned srcScale = SkAlpha255To256(this->getPaintAlpha());
63 
64     const SkMatrix& inv = this->getTotalInverse();
65     const SkBitmap& srcBitmap = this->getSrcBitmap();
66     unsigned        srcMaxX = srcBitmap.width() - 1;
67     unsigned        srcMaxY = srcBitmap.height() - 1;
68     unsigned        srcRB = srcBitmap.rowBytes();
69 
70     const SkFilterPtrProc* proc_table = SkGetBilinearFilterPtrProcTable();
71     const SkPMColor* srcPixels = (const SkPMColor*)srcBitmap.getPixels();
72 
73     if (this->getInverseClass() == kPerspective_MatrixClass)
74     {
75         SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
76                                 SkIntToScalar(y) + SK_ScalarHalf, count);
77 
78         if (256 == srcScale)
79         {
80             while ((count = iter.next()) != 0)
81             {
82                 const SkFixed* srcXY = iter.getXY();
83                 while (--count >= 0)
84                 {
85                     SkFixed fx = *srcXY++ - SK_FixedHalf;
86                     SkFixed fy = *srcXY++ - SK_FixedHalf;
87                     *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
88                 }
89             }
90         }
91         else    // scale by srcScale
92         {
93             while ((count = iter.next()) != 0)
94             {
95                 const SkFixed* srcXY = iter.getXY();
96                 while (--count >= 0)
97                 {
98                     SkFixed fx = *srcXY++ - SK_FixedHalf;
99                     SkFixed fy = *srcXY++ - SK_FixedHalf;
100                     SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
101                     *dstC++ = SkAlphaMulQ(c, srcScale);
102                 }
103             }
104         }
105     }
106     else    // linear case
107     {
108         SkFixed fx, fy, dx, dy;
109 
110         // now init fx, fy, dx, dy
111         {
112             SkPoint srcPt;
113             this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
114                                              SkIntToScalar(y) + SK_ScalarHalf,
115                                              &srcPt);
116 
117             fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
118             fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
119 
120             if (this->getInverseClass() == kFixedStepInX_MatrixClass)
121                 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
122             else
123             {
124                 dx = SkScalarToFixed(inv.getScaleX());
125                 dy = SkScalarToFixed(inv.getSkewY());
126             }
127         }
128 
129         if (dy == 0 && (unsigned)(fy >> 16) < srcMaxY)
130         {
131             srcPixels = (const SkPMColor*)((const char*)srcPixels + (fy >> 16) * srcRB);
132             proc_table = SkGetBilinearFilterPtrProcYTable(proc_table, fy);
133             if (256 == srcScale)
134             {
135                 do {
136                     *dstC++ = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
137                     fx += dx;
138                 } while (--count != 0);
139             }
140             else
141             {
142                 do {
143                     SkPMColor c = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
144                     *dstC++ = SkAlphaMulQ(c, srcScale);
145                     fx += dx;
146                 } while (--count != 0);
147             }
148         }
149         else    // dy is != 0
150         {
151             if (256 == srcScale)
152             {
153                 do {
154                     *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
155                     fx += dx;
156                     fy += dy;
157                 } while (--count != 0);
158             }
159             else
160             {
161                 do {
162                     SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
163                     *dstC++ = SkAlphaMulQ(c, srcScale);
164                     fx += dx;
165                     fy += dy;
166                 } while (--count != 0);
167             }
168         }
169     }
170 }
171 
172