Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / ARGB32_Clamp_Bilinear_BitmapShader.h
1
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader {
10 public:
11     ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap& src)
12         : SkBitmapShader(src, true,
13                          SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)
14     {}
15
16     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
17 };
18
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)
23 {
24     int ix = fx >> 16;
25     int iy = fy >> 16;
26
27     const SkPMColor *p00, *p01, *p10, *p11;
28
29     p00 = p01 = ((const SkPMColor*)((const char*)srcPixels
30                                     + SkClampMax(iy, srcMaxY) * srcRB))
31                                     + SkClampMax(ix, srcMaxX);
32
33     if ((unsigned)ix < srcMaxX)
34         p01 += 1;
35     p10 = p00;
36     p11 = p01;
37     if ((unsigned)iy < srcMaxY)
38     {
39         p10 = (const SkPMColor*)((const char*)p10 + srcRB);
40         p11 = (const SkPMColor*)((const char*)p11 + srcRB);
41     }
42
43     SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(proc_table, fx, fy);
44     return proc(p00, p01, p10, p11);
45 }
46
47 static inline SkPMColor sample_bilerpx(SkFixed fx, unsigned srcMaxX, const SkPMColor* srcPixels,
48                                        int srcRB, const SkFilterPtrProc* proc_table)
49 {
50     int ix = fx >> 16;
51
52     const SkPMColor *p00, *p01, *p10, *p11;
53
54     p00 = p01 = srcPixels + SkClampMax(ix, srcMaxX);
55     if ((unsigned)ix < srcMaxX)
56         p01 += 1;
57
58     p10 = (const SkPMColor*)((const char*)p00 + srcRB);
59     p11 = (const SkPMColor*)((const char*)p01 + srcRB);
60
61     SkFilterPtrProc proc = SkGetBilinearFilterPtrXProc(proc_table, fx);
62     return proc(p00, p01, p10, p11);
63 }
64
65 void ARGB32_Clamp_Bilinear_BitmapShader::shadeSpan(int x, int y, SkPMColor dstC[], int count)
66 {
67     SkASSERT(count > 0);
68
69     unsigned srcScale = SkAlpha255To256(this->getPaintAlpha());
70
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();
76
77     const SkFilterPtrProc* proc_table = SkGetBilinearFilterPtrProcTable();
78     const SkPMColor* srcPixels = (const SkPMColor*)srcBitmap.getPixels();
79
80     if (this->getInverseClass() == kPerspective_MatrixClass)
81     {
82         SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
83                                 SkIntToScalar(y) + SK_ScalarHalf, count);
84
85         if (256 == srcScale)
86         {
87             while ((count = iter.next()) != 0)
88             {
89                 const SkFixed* srcXY = iter.getXY();
90                 while (--count >= 0)
91                 {
92                     SkFixed fx = *srcXY++ - SK_FixedHalf;
93                     SkFixed fy = *srcXY++ - SK_FixedHalf;
94                     *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
95                 }
96             }
97         }
98         else    // scale by srcScale
99         {
100             while ((count = iter.next()) != 0)
101             {
102                 const SkFixed* srcXY = iter.getXY();
103                 while (--count >= 0)
104                 {
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);
109                 }
110             }
111         }
112     }
113     else    // linear case
114     {
115         SkFixed fx, fy, dx, dy;
116
117         // now init fx, fy, dx, dy
118         {
119             SkPoint srcPt;
120             this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
121                                              SkIntToScalar(y) + SK_ScalarHalf,
122                                              &srcPt);
123
124             fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
125             fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
126
127             if (this->getInverseClass() == kFixedStepInX_MatrixClass)
128                 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
129             else
130             {
131                 dx = SkScalarToFixed(inv.getScaleX());
132                 dy = SkScalarToFixed(inv.getSkewY());
133             }
134         }
135
136         if (dy == 0 && (unsigned)(fy >> 16) < srcMaxY)
137         {
138             srcPixels = (const SkPMColor*)((const char*)srcPixels + (fy >> 16) * srcRB);
139             proc_table = SkGetBilinearFilterPtrProcYTable(proc_table, fy);
140             if (256 == srcScale)
141             {
142                 do {
143                     *dstC++ = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
144                     fx += dx;
145                 } while (--count != 0);
146             }
147             else
148             {
149                 do {
150                     SkPMColor c = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
151                     *dstC++ = SkAlphaMulQ(c, srcScale);
152                     fx += dx;
153                 } while (--count != 0);
154             }
155         }
156         else    // dy is != 0
157         {
158             if (256 == srcScale)
159             {
160                 do {
161                     *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
162                     fx += dx;
163                     fy += dy;
164                 } while (--count != 0);
165             }
166             else
167             {
168                 do {
169                     SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
170                     *dstC++ = SkAlphaMulQ(c, srcScale);
171                     fx += dx;
172                     fy += dy;
173                 } while (--count != 0);
174             }
175         }
176     }
177 }