SkPDFShader::State::State(const SkShader& shader,
                          const SkMatrix& canvasTransform, const SkIRect& bbox)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    shader.getLocalMatrix(&fShaderTransform);
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes, NULL);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            fImage.reset();
            return;
        }
        SkASSERT(matrix.isIdentity());
        fPixelGeneration = fImage.getGenerationID();
    } else {
        fColorData.set(sk_malloc_throw(
                    fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
        fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
        fInfo.fColorOffsets =
            reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
        shader.asAGradient(&fInfo);
    }
}
Beispiel #2
0
SkPDFShader::State::State(const SkShader& shader,
                          const SkMatrix& canvasTransform, const SkIRect& bbox)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    fShaderTransform = shader.getLocalMatrix();
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            fImage.reset();
            return;
        }
        SkASSERT(matrix.isIdentity());
        fPixelGeneration = fImage.getGenerationID();
    } else {
        AllocateGradientInfoStorage();
        shader.asAGradient(&fInfo);
    }
}
 void addBitmapFromPaint(const SkPaint& paint) {
     SkShader* shader = paint.getShader();
     if (shader) {
         SkBitmap bm;
         // Check whether the shader is a gradient in order to short-circuit
         // call to asABitmap to prevent generation of bitmaps from
         // gradient shaders, which implement asABitmap.
         if (SkShader::kNone_GradientType == shader->asAGradient(NULL) &&
             shader->asABitmap(&bm, NULL, NULL)) {
             fPRSet->add(bm.pixelRef());
         }
     }
 }
Beispiel #4
0
static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
                                    size_t bitmapSizeThreshold) {
    if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
        (bitmap->getSize() > bitmapSizeThreshold))) {
        return true;
    }
    if (paint) {
        SkShader* shader = paint->getShader();
        // Here we detect the case where the shader is an SkBitmapProcShader
        // with a gpu texture attached.  Checking this without RTTI
        // requires making the assumption that only gradient shaders
        // and SkBitmapProcShader implement asABitmap().  The following
        // code may need to be revised if that assumption is ever broken.
        if (shader && !shader->asAGradient(NULL)) {
            SkBitmap bm;
            if (shader->asABitmap(&bm, NULL, NULL) &&
                bm.getTexture()) {
                return true;
            }
        }
    }
    return false;
}
Beispiel #5
0
SkPDFShader::State::State(const SkShader& shader, const SkMatrix& canvasTransform,
                          const SkIRect& bbox, SkScalar rasterScale)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    fShaderTransform = shader.getLocalMatrix();
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            // Generic fallback for unsupported shaders:
            //  * allocate a bbox-sized bitmap
            //  * shade the whole area
            //  * use the result as a bitmap shader

            // bbox is in device space. While that's exactly what we want for sizing our bitmap,
            // we need to map it into shader space for adjustments (to match
            // SkPDFImageShader::Create's behavior).
            SkRect shaderRect = SkRect::Make(bbox);
            if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
                fImage.reset();
                return;
            }

            // Clamp the bitmap size to about 1M pixels
            static const SkScalar kMaxBitmapArea = 1024 * 1024;
            SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
            if (bitmapArea > kMaxBitmapArea) {
                rasterScale *= SkScalarSqrt(SkScalarDiv(kMaxBitmapArea, bitmapArea));
            }

            SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.width()),
                                         SkScalarRoundToInt(rasterScale * bbox.height()));
            SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(),
                                        SkIntToScalar(size.height()) / shaderRect.height());

            fImage.allocN32Pixels(size.width(), size.height());
            fImage.eraseColor(SK_ColorTRANSPARENT);

            SkPaint p;
            p.setShader(const_cast<SkShader*>(&shader));

            SkCanvas canvas(fImage);
            canvas.scale(scale.width(), scale.height());
            canvas.translate(-shaderRect.x(), -shaderRect.y());
            canvas.drawPaint(p);

            fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
            fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
        } else {
            SkASSERT(matrix.isIdentity());
        }
        fPixelGeneration = fImage.getGenerationID();
    } else {
        AllocateGradientInfoStorage();
        shader.asAGradient(&fInfo);
    }
}