
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */



#ifndef NOFILTER_BITMAP_SHADER_PREAMBLE
    #define NOFILTER_BITMAP_SHADER_PREAMBLE(bitmap, rb)
#endif
#ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE
    #define NOFILTER_BITMAP_SHADER_POSTAMBLE(bitmap)
#endif
#ifndef NOFILTER_BITMAP_SHADER_PREAMBLE16
    #define NOFILTER_BITMAP_SHADER_PREAMBLE16(bitmap, rb)
#endif
#ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE16
    #define NOFILTER_BITMAP_SHADER_POSTAMBLE16(bitmap)
#endif

class NOFILTER_BITMAP_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
public:
    NOFILTER_BITMAP_SHADER_CLASS(const SkBitmap& src)
        : HasSpan16_Sampler_BitmapShader(src, false,
                                         NOFILTER_BITMAP_SHADER_TILEMODE,
                                         NOFILTER_BITMAP_SHADER_TILEMODE)
    {
    }
    
    virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
    {
        if (!this->INHERITED::setContext(device, paint, matrix))
            return false;

#ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
        this->computeUnitInverse();
#endif
        return true;
    }

    virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
    {
        SkASSERT(count > 0);

#ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC32
        if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0)
        {
            NOFILTER_BITMAP_SHADER_SPRITEPROC32(this, x, y, dstC, count);
            return;
        }
#endif

        unsigned        scale = SkAlpha255To256(this->getPaintAlpha());
#ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
        const SkMatrix& inv = this->getUnitInverse();
        SkMatrix::MapPtProc invProc = this->getUnitInverseProc();
#else
        const SkMatrix& inv = this->getTotalInverse();
        SkMatrix::MapPtProc invProc = this->getInverseMapPtProc();
#endif
        const SkBitmap& srcBitmap = this->getSrcBitmap();
        unsigned        srcMaxX = srcBitmap.width() - 1;
        unsigned        srcMaxY = srcBitmap.height() - 1;
        unsigned        srcRB = srcBitmap.rowBytes();
        SkFixed         fx, fy, dx, dy;

        const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels();
        NOFILTER_BITMAP_SHADER_PREAMBLE(srcBitmap, srcRB);

        if (this->getInverseClass() == kPerspective_MatrixClass)
        {
            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
                                    SkIntToScalar(y) + SK_ScalarHalf, count);
            while ((count = iter.next()) != 0)
            {
                const SkFixed* srcXY = iter.getXY();

/*  Do I need this?
#ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
            fx >>= level;
            fy >>= level;
#endif
*/
                if (256 == scale)
                {
                    while (--count >= 0)
                    {
                        fx = *srcXY++;
                        fy = *srcXY++;
                        unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                        unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                        *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
                    }
                }
                else
                {
                    while (--count >= 0)
                    {
                        fx = *srcXY++;
                        fy = *srcXY++;
                        unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                        unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                        uint32_t c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
                        *dstC++ = SkAlphaMulQ(c, scale);
                    }
                }
            }
            return;
        }

        // now init fx, fy, dx, dy
        {
            SkPoint srcPt;
            invProc(inv, SkIntToScalar(x) + SK_ScalarHalf,
                         SkIntToScalar(y) + SK_ScalarHalf, &srcPt);

            fx = SkScalarToFixed(srcPt.fX);
            fy = SkScalarToFixed(srcPt.fY);

            if (this->getInverseClass() == kFixedStepInX_MatrixClass)
                (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
            else
            {
                dx = SkScalarToFixed(inv.getScaleX());
                dy = SkScalarToFixed(inv.getSkewY());
            }
        }

#ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
        {   int level = this->getMipLevel() >> 16;
            fx >>= level;
            fy >>= level;
            dx >>= level;
            dy >>= level;
        }
#endif

        if (dy == 0)
        {
            int y_index = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
//          SkDEBUGF(("fy = %g, srcMaxY = %d, y_index = %d\n", SkFixedToFloat(fy), srcMaxY, y_index));
            srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + y_index * srcRB);
            if (scale == 256)
                while (--count >= 0)
                {
                    unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                    fx += dx;
                    *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x);
                }
            else
                while (--count >= 0)
                {
                    unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                    SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x);
                    fx += dx;
                    *dstC++ = SkAlphaMulQ(c, scale);
                }
        }
        else    // dy != 0
        {
            if (scale == 256)
                while (--count >= 0)
                {
                    unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                    unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                    fx += dx;
                    fy += dy;
                    *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
                }
            else
                while (--count >= 0)
                {
                    unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                    unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                    SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
                    fx += dx;
                    fy += dy;
                    *dstC++ = SkAlphaMulQ(c, scale);
                }
        }

        NOFILTER_BITMAP_SHADER_POSTAMBLE(srcBitmap);
    }

    virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
    {
        SkASSERT(count > 0);
        SkASSERT(this->getFlags() & SkShader::kHasSpan16_Flag);

#ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC16
        if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0)
        {
            NOFILTER_BITMAP_SHADER_SPRITEPROC16(this, x, y, dstC, count);
            return;
        }
#endif

#ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
        const SkMatrix& inv = this->getUnitInverse();
        SkMatrix::MapPtProc invProc = this->getUnitInverseProc();
#else
        const SkMatrix& inv = this->getTotalInverse();
        SkMatrix::MapPtProc invProc = this->getInverseMapPtProc();
#endif
        const SkBitmap& srcBitmap = this->getSrcBitmap();
        unsigned        srcMaxX = srcBitmap.width() - 1;
        unsigned        srcMaxY = srcBitmap.height() - 1;
        unsigned        srcRB = srcBitmap.rowBytes();
        SkFixed         fx, fy, dx, dy;

        const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels();
        NOFILTER_BITMAP_SHADER_PREAMBLE16(srcBitmap, srcRB);

        if (this->getInverseClass() == kPerspective_MatrixClass)
        {
            SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
                                    SkIntToScalar(y) + SK_ScalarHalf, count);
            while ((count = iter.next()) != 0)
            {
                const SkFixed* srcXY = iter.getXY();
                
                while (--count >= 0)
                {
                    fx = *srcXY++;
                    fy = *srcXY++;
                    unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                    unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                    *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB);
                }
            }
            return;
        }

        // now init fx, fy, dx, dy
        {
            SkPoint srcPt;
            invProc(inv, SkIntToScalar(x) + SK_ScalarHalf,
                         SkIntToScalar(y) + SK_ScalarHalf, &srcPt);

            fx = SkScalarToFixed(srcPt.fX);
            fy = SkScalarToFixed(srcPt.fY);

            if (this->getInverseClass() == kFixedStepInX_MatrixClass)
                (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
            else
            {
                dx = SkScalarToFixed(inv.getScaleX());
                dy = SkScalarToFixed(inv.getSkewY());
            }
        }

#ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
        {   int level = this->getMipLevel() >> 16;
            fx >>= level;
            fy >>= level;
            dx >>= level;
            dy >>= level;
        }
#endif

        if (dy == 0)
        {
            srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY) * srcRB);
            do {
                unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                fx += dx;
                *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X16(srcPixels, x);
            } while (--count != 0);
        }
        else    // dy != 0
        {
            do {
                unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
                unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
                fx += dx;
                fy += dy;
                *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB);
            } while (--count != 0);
        }

        NOFILTER_BITMAP_SHADER_POSTAMBLE16(srcBitmap);
    }
private:
    typedef HasSpan16_Sampler_BitmapShader INHERITED;
};

#undef NOFILTER_BITMAP_SHADER_CLASS
#undef NOFILTER_BITMAP_SHADER_TYPE
#undef NOFILTER_BITMAP_SHADER_PREAMBLE
#undef NOFILTER_BITMAP_SHADER_POSTAMBLE
#undef NOFILTER_BITMAP_SHADER_SAMPLE_X      //(x)
#undef NOFILTER_BITMAP_SHADER_SAMPLE_XY     //(x, y, rowBytes)
#undef NOFILTER_BITMAP_SHADER_TILEMODE
#undef NOFILTER_BITMAP_SHADER_TILEPROC

#undef NOFILTER_BITMAP_SHADER_PREAMBLE16
#undef NOFILTER_BITMAP_SHADER_POSTAMBLE16
#undef NOFILTER_BITMAP_SHADER_SAMPLE_X16        //(x)
#undef NOFILTER_BITMAP_SHADER_SAMPLE_XY16       //(x, y, rowBytes)

#undef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
#undef NOFILTER_BITMAP_SHADER_SPRITEPROC16
#undef NOFILTER_BITMAP_SHADER_SPRITEPROC32
