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 } 178 179