1 2 class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader { 3 public: 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); 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 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 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