void DrawTargetSkia::CopySurface(SourceSurface *aSurface, const IntRect& aSourceRect, const IntPoint &aDestination) { //TODO: We could just use writePixels() here if the sourceRect is the entire source if (aSurface->GetType() != SurfaceType::SKIA) { return; } MarkChanged(); TempBitmap bitmap = GetBitmapForSurface(aSurface); mCanvas->save(); mCanvas->resetMatrix(); SkRect dest = IntRectToSkRect(IntRect(aDestination.x, aDestination.y, aSourceRect.width, aSourceRect.height)); SkIRect source = IntRectToSkIRect(aSourceRect); mCanvas->clipRect(dest, SkRegion::kReplace_Op); SkPaint paint; if (mCanvas->getDevice()->config() == SkBitmap::kRGB_565_Config) { // Set the xfermode to SOURCE_OVER to workaround // http://code.google.com/p/skia/issues/detail?id=628 // RGB565 is opaque so they're equivalent anyway paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); } else { paint.setXfermodeMode(SkXfermode::kSrc_Mode); } mCanvas->drawBitmapRect(bitmap.mBitmap, &source, dest, &paint); mCanvas->restore(); }
void DrawTargetSkia::CopySurface(SourceSurface *aSurface, const IntRect& aSourceRect, const IntPoint &aDestination) { //TODO: We could just use writePixels() here if the sourceRect is the entire source if (aSurface->GetType() != SurfaceType::SKIA && aSurface->GetType() != SurfaceType::DATA) { return; } MarkChanged(); TempBitmap bitmap = GetBitmapForSurface(aSurface); // This is a fast path that is disabled for now to mimimize risk if (false && !bitmap.mBitmap.getTexture() && mCanvas->getDevice()->config() == bitmap.mBitmap.config()) { SkBitmap bm(bitmap.mBitmap); bm.lockPixels(); if (bm.getPixels()) { SkImageInfo info = bm.info(); info.fWidth = aSourceRect.width; info.fHeight = aSourceRect.height; uint8_t* pixels = static_cast<uint8_t*>(bm.getPixels()); // adjust pixels for the source offset pixels += aSourceRect.x + aSourceRect.y*bm.rowBytes(); mCanvas->writePixels(info, pixels, bm.rowBytes(), aDestination.x, aDestination.y); return; } } mCanvas->save(); mCanvas->resetMatrix(); SkRect dest = IntRectToSkRect(IntRect(aDestination.x, aDestination.y, aSourceRect.width, aSourceRect.height)); SkIRect source = IntRectToSkIRect(aSourceRect); mCanvas->clipRect(dest, SkRegion::kReplace_Op); SkPaint paint; if (mCanvas->getDevice()->config() == SkBitmap::kRGB_565_Config) { // Set the xfermode to SOURCE_OVER to workaround // http://code.google.com/p/skia/issues/detail?id=628 // RGB565 is opaque so they're equivalent anyway paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); } else { paint.setXfermodeMode(SkXfermode::kSrc_Mode); } // drawBitmapRect with A8 bitmaps ends up doing a mask operation // so we need to clear before if (bitmap.mBitmap.config() == SkBitmap::kA8_Config) { SkPaint clearPaint; clearPaint.setColor(SkColorSetARGB(0, 0, 0, 0)); clearPaint.setXfermodeMode(SkXfermode::kSrc_Mode); mCanvas->drawPaint(clearPaint); } mCanvas->drawBitmapRect(bitmap.mBitmap, &source, dest, &paint); mCanvas->restore(); }
static void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, TempBitmap& aTmpBitmap, Float aAlpha = 1.0) { switch (aPattern.GetType()) { case PatternType::COLOR: { Color color = static_cast<const ColorPattern&>(aPattern).mColor; aPaint.setColor(ColorToSkColor(color, aAlpha)); break; } case PatternType::LINEAR_GRADIENT: { const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern); GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get()); SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode); if (stops->mCount >= 2) { SkPoint points[2]; points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y)); points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y)); SkShader* shader = SkGradientShader::CreateLinear(points, &stops->mColors.front(), &stops->mPositions.front(), stops->mCount, mode); if (shader) { SkMatrix mat; GfxMatrixToSkiaMatrix(pat.mMatrix, mat); SkShader* matrixShader = SkShader::CreateLocalMatrixShader(shader, mat); SkSafeUnref(shader); SkSafeUnref(aPaint.setShader(matrixShader)); } } else { aPaint.setColor(SkColorSetARGB(0, 0, 0, 0)); } break; } case PatternType::RADIAL_GRADIENT: { const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern); GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get()); SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode); if (stops->mCount >= 2) { SkPoint points[2]; points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y)); points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y)); SkShader* shader = SkGradientShader::CreateTwoPointConical(points[0], SkFloatToScalar(pat.mRadius1), points[1], SkFloatToScalar(pat.mRadius2), &stops->mColors.front(), &stops->mPositions.front(), stops->mCount, mode); if (shader) { SkMatrix mat; GfxMatrixToSkiaMatrix(pat.mMatrix, mat); SkShader* matrixShader = SkShader::CreateLocalMatrixShader(shader, mat); SkSafeUnref(shader); SkSafeUnref(aPaint.setShader(matrixShader)); } } else { aPaint.setColor(SkColorSetARGB(0, 0, 0, 0)); } break; } case PatternType::SURFACE: { const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern); aTmpBitmap = GetBitmapForSurface(pat.mSurface); SkBitmap& bitmap = aTmpBitmap.mBitmap; SkMatrix mat; GfxMatrixToSkiaMatrix(pat.mMatrix, mat); if (!pat.mSamplingRect.IsEmpty()) { SkIRect rect = IntRectToSkIRect(pat.mSamplingRect); bitmap.extractSubset(&bitmap, rect); mat.preTranslate(rect.x(), rect.y()); } SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode); SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode); SkShader* matrixShader = SkShader::CreateLocalMatrixShader(shader, mat); SkSafeUnref(shader); SkSafeUnref(aPaint.setShader(matrixShader)); if (pat.mFilter == Filter::POINT) { aPaint.setFilterLevel(SkPaint::kNone_FilterLevel); } break; } } }