Home | History | Annotate | Download | only in core
      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