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::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource, const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) { if (!(aSurface->GetType() == SurfaceType::SKIA || aSurface->GetType() == SurfaceType::DATA)) { return; } if (aSource.IsEmpty()) { return; } MarkChanged(); SkRect destRect = RectToSkRect(aDest); SkRect sourceRect = RectToSkRect(aSource); TempBitmap bitmap = GetBitmapForSurface(aSurface); AutoPaintSetup paint(mCanvas.get(), aOptions); if (aSurfOptions.mFilter == Filter::POINT) { paint.mPaint.setFilterBitmap(false); } mCanvas->drawBitmapRectToRect(bitmap.mBitmap, &sourceRect, destRect, &paint.mPaint); }
void DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest, const Color &aColor, const Point &aOffset, Float aSigma, CompositionOp aOperator) { if (!(aSurface->GetType() == SurfaceType::SKIA || aSurface->GetType() == SurfaceType::DATA)) { return; } MarkChanged(); mCanvas->save(SkCanvas::kMatrix_SaveFlag); mCanvas->resetMatrix(); TempBitmap bitmap = GetBitmapForSurface(aSurface); SkPaint paint; SkImageFilter* filter = SkDropShadowImageFilter::Create(aOffset.x, aOffset.y, aSigma, ColorToSkColor(aColor, 1.0)); paint.setImageFilter(filter); paint.setXfermodeMode(GfxOpToSkiaOp(aOperator)); mCanvas->drawBitmap(bitmap.mBitmap, aDest.x, aDest.y, &paint); mCanvas->restore(); }
void DrawTargetSkia::MaskSurface(const Pattern &aSource, SourceSurface *aMask, Point aOffset, const DrawOptions &aOptions) { MarkChanged(); AutoPaintSetup paint(mCanvas.get(), aOptions, aSource); TempBitmap bitmap = GetBitmapForSurface(aMask); if (bitmap.mBitmap.colorType() == kAlpha_8_SkColorType) { mCanvas->drawBitmap(bitmap.mBitmap, aOffset.x, aOffset.y, &paint.mPaint); } else { SkPaint maskPaint; TempBitmap tmpBitmap; SetPaintPattern(maskPaint, SurfacePattern(aMask, ExtendMode::CLAMP), tmpBitmap); SkMatrix transform = maskPaint.getShader()->getLocalMatrix(); transform.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y)); maskPaint.getShader()->setLocalMatrix(transform); SkLayerRasterizer::Builder builder; builder.addLayer(maskPaint); SkAutoTUnref<SkRasterizer> raster(builder.detachRasterizer()); paint.mPaint.setRasterizer(raster.get()); IntSize size = aMask->GetSize(); Rect rect = Rect(aOffset.x, aOffset.y, size.width, size.height); mCanvas->drawRect(RectToSkRect(rect), paint.mPaint); } }
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(); }
void DrawTargetSkia::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource, const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) { RefPtr<SourceSurface> dataSurface; if (!(aSurface->GetType() == SurfaceType::SKIA || aSurface->GetType() == SurfaceType::DATA)) { dataSurface = aSurface->GetDataSurface(); if (!dataSurface) { gfxDebug() << *this << ": DrawSurface() can't draw surface"; return; } aSurface = dataSurface.get(); } if (aSource.IsEmpty()) { return; } MarkChanged(); SkRect destRect = RectToSkRect(aDest); SkRect sourceRect = RectToSkRect(aSource); TempBitmap bitmap = GetBitmapForSurface(aSurface); AutoPaintSetup paint(mCanvas.get(), aOptions, &aDest); if (aSurfOptions.mFilter == Filter::POINT) { paint.mPaint.setFilterLevel(SkPaint::kNone_FilterLevel); } mCanvas->drawBitmapRectToRect(bitmap.mBitmap, &sourceRect, destRect, &paint.mPaint); }
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); shader->setLocalMatrix(mat); SkSafeUnref(aPaint.setShader(shader)); } } 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); shader->setLocalMatrix(mat); SkSafeUnref(aPaint.setShader(shader)); } } else { aPaint.setColor(SkColorSetARGB(0, 0, 0, 0)); } break; } case PatternType::SURFACE: { const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern); aTmpBitmap = GetBitmapForSurface(pat.mSurface); const SkBitmap& bitmap = aTmpBitmap.mBitmap; SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode); SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode); SkMatrix mat; GfxMatrixToSkiaMatrix(pat.mMatrix, mat); shader->setLocalMatrix(mat); SkSafeUnref(aPaint.setShader(shader)); if (pat.mFilter == Filter::POINT) { aPaint.setFilterLevel(SkPaint::kNone_FilterLevel); } break; } } }
void DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest, const Color &aColor, const Point &aOffset, Float aSigma, CompositionOp aOperator) { MarkChanged(); mCanvas->save(SkCanvas::kMatrix_SaveFlag); mCanvas->resetMatrix(); uint32_t blurFlags = SkBlurMaskFilter::kHighQuality_BlurFlag | SkBlurMaskFilter::kIgnoreTransform_BlurFlag; TempBitmap bitmap = GetBitmapForSurface(aSurface); SkShader* shader = SkShader::CreateBitmapShader(bitmap.mBitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkMatrix matrix; matrix.reset(); matrix.setTranslateX(SkFloatToScalar(aDest.x)); matrix.setTranslateY(SkFloatToScalar(aDest.y)); shader->setLocalMatrix(matrix); SkLayerDrawLooper* dl = new SkLayerDrawLooper; SkLayerDrawLooper::LayerInfo info; info.fPaintBits |= SkLayerDrawLooper::kShader_Bit; SkPaint *layerPaint = dl->addLayer(info); layerPaint->setShader(shader); info.fPaintBits = 0; info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit; info.fColorMode = SkXfermode::kDst_Mode; info.fOffset.set(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y)); info.fPostTranslate = true; SkMaskFilter* mf = SkBlurMaskFilter::Create(aSigma, SkBlurMaskFilter::kNormal_BlurStyle, blurFlags); SkColor color = ColorToSkColor(aColor, 1); SkColorFilter* cf = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode); layerPaint = dl->addLayer(info); SkSafeUnref(layerPaint->setMaskFilter(mf)); SkSafeUnref(layerPaint->setColorFilter(cf)); layerPaint->setColor(color); // TODO: This is using the rasterizer to calculate an alpha mask // on both the shadow and normal layers. We should fix this // properly so it only happens for the shadow layer SkLayerRasterizer *raster = new SkLayerRasterizer(); SkPaint maskPaint; SkSafeUnref(maskPaint.setShader(shader)); raster->addLayer(maskPaint, 0, 0); SkPaint paint; paint.setAntiAlias(true); SkSafeUnref(paint.setRasterizer(raster)); paint.setXfermodeMode(GfxOpToSkiaOp(aOperator)); SkSafeUnref(paint.setLooper(dl)); SkRect rect = RectToSkRect(Rect(Float(aDest.x), Float(aDest.y), Float(bitmap.mBitmap.width()), Float(bitmap.mBitmap.height()))); mCanvas->drawRect(rect, paint); mCanvas->restore(); }