void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect,
                        const TransformationMatrix& patternTransform,
                        const FloatPoint& phase, CompositeOperator compositeOp,
                        const FloatRect& destRect)
{
    SkBitmapRef* image = this->nativeImageForCurrentFrame();
    if (!image) { // If it's too early we won't have an image yet.
        return;
    }
    
    // in case we get called with an incomplete bitmap
    const SkBitmap& bitmap = image->bitmap();
    if (bitmap.getPixels() == NULL && bitmap.pixelRef() == NULL) {
        return;
    }
    
    SkRect  dstR;    
    android_setrect(&dstR, destRect);
    if (dstR.isEmpty()) {
        return;
    }
    
    SkCanvas*   canvas = ctxt->platformContext()->mCanvas;
    SkPaint     paint;
    
    SkShader* shader = SkShader::CreateBitmapShader(bitmap,
                                                    SkShader::kRepeat_TileMode,
                                                    SkShader::kRepeat_TileMode);
    paint.setShader(shader)->unref();
    // now paint is the only owner of shader
    paint.setPorterDuffXfermode(android_convert_compositeOp(compositeOp));
    paint.setFilterBitmap(true);
    
    SkMatrix matrix(patternTransform);
    
    float scaleX = (float)image->origWidth() / bitmap.width();
    float scaleY = (float)image->origHeight() / bitmap.height();
    matrix.preScale(SkFloatToScalar(scaleX), SkFloatToScalar(scaleY));
    
    matrix.postTranslate(SkFloatToScalar(phase.x()),
                         SkFloatToScalar(phase.y()));
    shader->setLocalMatrix(matrix);
    canvas->drawRect(dstR, paint);
    
#ifdef TRACE_SUBSAMPLED_BITMAPS
    if (bitmap.width() != image->origWidth() ||
        bitmap.height() != image->origHeight()) {
        SkDebugf("--- Image::drawPattern [%d %d] orig [%d %d] dst [%g %g]\n",
                 bitmap.width(), bitmap.height(),
                 image->origWidth(), image->origHeight(),
                 SkScalarToFloat(dstR.width()), SkScalarToFloat(dstR.height()));
    }
#endif
}
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
                       const FloatRect& srcRect, CompositeOperator compositeOp)
{
    startAnimation();

    SkBitmapRef* image = this->nativeImageForCurrentFrame();
    if (!image) { // If it's too early we won't have an image yet.
        return;
    }

    // in case we get called with an incomplete bitmap
    const SkBitmap& bitmap = image->bitmap();
    if (bitmap.getPixels() == NULL && bitmap.pixelRef() == NULL) {
#ifdef TRACE_SKIPPED_BITMAPS
        SkDebugf("----- skip bitmapimage: [%d %d] pixels %p pixelref %p\n",
                 bitmap.width(), bitmap.height(),
                 bitmap.getPixels(), bitmap.pixelRef());
#endif
        return;
    }

    SkIRect srcR;
    SkRect  dstR;    
    float invScaleX = (float)bitmap.width() / image->origWidth();
    float invScaleY = (float)bitmap.height() / image->origHeight();

    android_setrect(&dstR, dstRect);
    android_setrect_scaled(&srcR, srcRect, invScaleX, invScaleY);
    if (srcR.isEmpty() || dstR.isEmpty()) {
#ifdef TRACE_SKIPPED_BITMAPS
        SkDebugf("----- skip bitmapimage: [%d %d] src-empty %d dst-empty %d\n",
                 bitmap.width(), bitmap.height(),
                 srcR.isEmpty(), dstR.isEmpty());
#endif
        return;
    }

    SkCanvas*   canvas = ctxt->platformContext()->mCanvas;
    SkPaint     paint;

    paint.setFilterBitmap(true);
    paint.setPorterDuffXfermode(android_convert_compositeOp(compositeOp));
    canvas->drawBitmapRect(bitmap, &srcR, dstR, &paint);

#ifdef TRACE_SUBSAMPLED_BITMAPS
    if (bitmap.width() != image->origWidth() ||
        bitmap.height() != image->origHeight()) {
        SkDebugf("--- BitmapImage::draw [%d %d] orig [%d %d]\n",
                 bitmap.width(), bitmap.height(),
                 image->origWidth(), image->origHeight());
    }
#endif
}
Esempio n. 3
0
void Image::drawPattern(GraphicsContext* gc, const FloatRect& srcRect,
                        const AffineTransform& patternTransform,
                        const FloatPoint& phase, ColorSpace,
                        CompositeOperator compositeOp, const FloatRect& destRect)
{
    SkBitmapRef* image = this->nativeImageForCurrentFrame();
    if (!image || destRect.isEmpty())
        return;

    // in case we get called with an incomplete bitmap
    const SkBitmap& origBitmap = image->bitmap();
    if (origBitmap.getPixels() == NULL && origBitmap.pixelRef() == NULL)
        return;

    SkIRect srcR;
    // we may have to scale if the image has been subsampled (so save RAM)
    bool imageIsSubSampled = image->origWidth() != origBitmap.width() ||
                             image->origHeight() != origBitmap.height();
    float scaleX = 1;
    float scaleY = 1;
    if (imageIsSubSampled) {
        scaleX = (float)image->origWidth() / origBitmap.width();
        scaleY = (float)image->origHeight() / origBitmap.height();
        round_scaled(&srcR, srcRect, 1 / scaleX, 1 / scaleY);
    } else
        round(&srcR, srcRect);

    // now extract the proper subset of the src image
    SkBitmap bitmap;
    if (!origBitmap.extractSubset(&bitmap, srcR)) {
        SkDebugf("--- Image::drawPattern calling extractSubset failed\n");
        return;
    }

    SkMatrix matrix(patternTransform);

    if (imageIsSubSampled) {
        matrix.preScale(SkFloatToScalar(scaleX), SkFloatToScalar(scaleY));
    }
    // We also need to translate it such that the origin of the pattern is the
    // origin of the destination rect, which is what WebKit expects. Skia uses
    // the coordinate system origin as the base for the patter. If WebKit wants
    // a shifted image, it will shift it from there using the patternTransform.
    float tx = phase.x() + srcRect.x() * patternTransform.a();
    float ty = phase.y() + srcRect.y() * patternTransform.d();
    matrix.postTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty));

    gc->platformContext()->drawBitmapPattern(bitmap, matrix, compositeOp, destRect);
}
Esempio n. 4
0
void BitmapImage::draw(GraphicsContext* gc, const FloatRect& dstRect,
                       const FloatRect& srcRect, ColorSpace,
                       CompositeOperator compositeOp)
{
    startAnimation();

    SkBitmapRef* image = this->nativeImageForCurrentFrame();
    if (!image) { // If it's too early we won't have an image yet.
        return;
    }

    // in case we get called with an incomplete bitmap
    const SkBitmap& bitmap = image->bitmap();
    if (bitmap.getPixels() == NULL && bitmap.pixelRef() == NULL) {
#ifdef TRACE_SKIPPED_BITMAPS
        SkDebugf("----- skip bitmapimage: [%d %d] pixels %p pixelref %p\n",
                 bitmap.width(), bitmap.height(),
                 bitmap.getPixels(), bitmap.pixelRef());
#endif
        return;
    }

    SkIRect srcR;
    SkRect  dstR(dstRect);
    float invScaleX = (float)bitmap.width() / image->origWidth();
    float invScaleY = (float)bitmap.height() / image->origHeight();

    round_scaled(&srcR, srcRect, invScaleX, invScaleY);
    if (srcR.isEmpty() || dstR.isEmpty()) {
#ifdef TRACE_SKIPPED_BITMAPS
        SkDebugf("----- skip bitmapimage: [%d %d] src-empty %d dst-empty %d\n",
                 bitmap.width(), bitmap.height(),
                 srcR.isEmpty(), dstR.isEmpty());
#endif
        return;
    }

    gc->platformContext()->drawBitmapRect(bitmap, &srcR, dstR, compositeOp);

#ifdef TRACE_SUBSAMPLED_BITMAPS
    if (bitmap.width() != image->origWidth() ||
            bitmap.height() != image->origHeight()) {
        SkDebugf("--- BitmapImage::draw [%d %d] orig [%d %d]\n",
                 bitmap.width(), bitmap.height(),
                 image->origWidth(), image->origHeight());
    }
#endif
}