diff options
-rw-r--r-- | core/fpdfapi/fpdf_render/fpdf_render_image.cpp | 22 | ||||
-rw-r--r-- | core/fxge/ge/cfx_renderdevice.cpp | 11 | ||||
-rw-r--r-- | core/fxge/ifx_renderdevicedriver.cpp | 9 | ||||
-rw-r--r-- | core/fxge/include/cfx_fxgedevice.h | 7 | ||||
-rw-r--r-- | core/fxge/include/cfx_renderdevice.h | 6 | ||||
-rw-r--r-- | core/fxge/include/ifx_renderdevicedriver.h | 6 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.cpp | 298 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.h | 13 |
8 files changed, 289 insertions, 83 deletions
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp index c93600f2a1..8d638f62f8 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp @@ -646,6 +646,7 @@ FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); return FALSE; } + FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { @@ -665,7 +666,11 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { if (!bitmap_device1.Create(width, height, FXDIB_Rgb32, nullptr)) return TRUE; +#if defined _SKIA_SUPPORT_ + bitmap_device1.Clear(0xffffff); +#else bitmap_device1.GetBitmap()->Clear(0xffffff); +#endif { CPDF_RenderStatus bitmap_render; bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, @@ -682,7 +687,11 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb, nullptr)) return TRUE; +#if defined _SKIA_SUPPORT_ + bitmap_device2.Clear(0); +#else bitmap_device2.GetBitmap()->Clear(0); +#endif CPDF_RenderStatus bitmap_render; bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, nullptr, nullptr, nullptr, nullptr, nullptr, 0, @@ -731,17 +740,21 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { } } } +#ifdef _SKIA_SUPPORT_ + m_pRenderStatus->m_pDevice->SetBitsWithMask( + bitmap_device1.GetBitmap(), bitmap_device2.GetBitmap(), rect.left, + rect.top, m_BitmapAlpha, m_BlendType); + } +#else bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); -#ifdef _SKIA_SUPPORT_ - CFX_SkiaDeviceDriver::PreMultiply(bitmap_device1.GetBitmap()); -#endif if (m_BitmapAlpha < 255) { bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha); } } m_pRenderStatus->m_pDevice->SetDIBitsWithBlend( bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); +#endif // _SKIA_SUPPORT_ return FALSE; } @@ -756,7 +769,8 @@ FX_BOOL CPDF_ImageRenderer::StartDIBSource() { } #ifdef _SKIA_SUPPORT_ CFX_DIBitmap* premultiplied = m_pDIBSource->Clone(); - CFX_SkiaDeviceDriver::PreMultiply(premultiplied); + if (m_pDIBSource->HasAlpha()) + CFX_SkiaDeviceDriver::PreMultiply(premultiplied); if (m_pRenderStatus->m_pDevice->StartDIBitsWithBlend( premultiplied, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags, m_DeviceHandle, m_BlendType)) { diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp index f04f4bab9a..53ee039cd3 100644 --- a/core/fxge/ge/cfx_renderdevice.cpp +++ b/core/fxge/ge/cfx_renderdevice.cpp @@ -811,10 +811,19 @@ void CFX_RenderDevice::CancelDIBits(void* handle) { } #ifdef _SKIA_SUPPORT_ - void CFX_RenderDevice::DebugVerifyBitmapIsPreMultiplied() const { SkASSERT(0); } + +bool CFX_RenderDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type) { + return m_pDeviceDriver->SetBitsWithMask(pBitmap, pMask, left, top, + bitmap_alpha, blend_type); +} #endif FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, diff --git a/core/fxge/ifx_renderdevicedriver.cpp b/core/fxge/ifx_renderdevicedriver.cpp index 9b7f985aee..25c3a4a23c 100644 --- a/core/fxge/ifx_renderdevicedriver.cpp +++ b/core/fxge/ifx_renderdevicedriver.cpp @@ -92,3 +92,12 @@ FX_BOOL IFX_RenderDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern, FX_BOOL bAlphaMode) { return false; } + +bool IFX_RenderDeviceDriver::SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type) { + return false; +} diff --git a/core/fxge/include/cfx_fxgedevice.h b/core/fxge/include/cfx_fxgedevice.h index a5dba37c3e..7f34f1ca4a 100644 --- a/core/fxge/include/cfx_fxgedevice.h +++ b/core/fxge/include/cfx_fxgedevice.h @@ -28,8 +28,15 @@ class CFX_FxgeDevice : public CFX_RenderDevice { #ifdef _SKIA_SUPPORT_ bool AttachRecorder(SkPictureRecorder* recorder); + void Clear(uint32_t color); SkPictureRecorder* CreateRecorder(int size_x, int size_y); void DebugVerifyBitmapIsPreMultiplied() const override; + bool SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type) override; #endif private: diff --git a/core/fxge/include/cfx_renderdevice.h b/core/fxge/include/cfx_renderdevice.h index fafa6260e1..390d39b69d 100644 --- a/core/fxge/include/cfx_renderdevice.h +++ b/core/fxge/include/cfx_renderdevice.h @@ -253,6 +253,12 @@ class CFX_RenderDevice { #ifdef _SKIA_SUPPORT_ virtual void DebugVerifyBitmapIsPreMultiplied() const; + virtual bool SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type); void Flush(); #endif diff --git a/core/fxge/include/ifx_renderdevicedriver.h b/core/fxge/include/ifx_renderdevicedriver.h index 572469b8c0..8b20cf0838 100644 --- a/core/fxge/include/ifx_renderdevicedriver.h +++ b/core/fxge/include/ifx_renderdevicedriver.h @@ -99,6 +99,12 @@ class IFX_RenderDeviceDriver { const FX_RECT& clip_rect, int alpha, FX_BOOL bAlphaMode); + virtual bool SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type); }; #endif // CORE_FXGE_INCLUDE_IFX_RENDERDEVICEDRIVER_H_ diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index 49c4639866..3effa0a6a6 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp @@ -24,9 +24,11 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorPriv.h" +#include "third_party/skia/include/core/SkMaskFilter.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPictureRecorder.h" +#include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypeface.h" #include "third_party/skia/include/effects/SkDashPathEffect.h" @@ -140,9 +142,10 @@ SkMatrix ToSkMatrix(const CFX_Matrix& m) { } // use when pdf's y-axis points up insead of down -SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m) { +SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m, SkScalar flip) { SkMatrix skMatrix; - skMatrix.setAll(m.a, -m.c, m.e, m.b, -m.d, m.f, 0, 0, 1); + skMatrix.setAll(m.a * flip, -m.c * flip, m.e, m.b * flip, -m.d * flip, m.f, 0, + 0, 1); return skMatrix; } @@ -367,6 +370,107 @@ void ClipAngledGradient(const SkPoint pts[2], clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); } +void SetBitmapMatrix(const CFX_Matrix* pMatrix, + int width, + int height, + SkMatrix* skMatrix) { + const CFX_Matrix& m = *pMatrix; + skMatrix->setAll(m.a / width, -m.c / height, m.c + m.e, m.b / width, + -m.d / height, m.d + m.f, 0, 0, 1); +} + +void SetBitmapPaint(bool isAlphaMask, + uint32_t argb, + int bitmap_alpha, + int blend_type, + SkPaint* paint) { + paint->setAntiAlias(true); + if (isAlphaMask) { + paint->setColorFilter( + SkColorFilter::MakeModeFilter(argb, SkXfermode::kSrc_Mode)); + } + // paint->setFilterQuality(kHigh_SkFilterQuality); + paint->setXfermodeMode(GetSkiaBlendMode(blend_type)); + paint->setAlpha(bitmap_alpha); +} + +bool Upsample(const CFX_DIBSource* pSource, + std::unique_ptr<uint8_t, FxFreeDeleter>& dst8Storage, + std::unique_ptr<uint32_t, FxFreeDeleter>& dst32Storage, + SkColorTable** ctPtr, + SkBitmap* skBitmap, + int* widthPtr, + int* heightPtr, + bool forceAlpha) { + void* buffer = pSource->GetBuffer(); + if (!buffer) + return false; + SkColorType colorType = forceAlpha || pSource->IsAlphaMask() + ? SkColorType::kAlpha_8_SkColorType + : SkColorType::kGray_8_SkColorType; + SkAlphaType alphaType = + pSource->IsAlphaMask() ? kPremul_SkAlphaType : kOpaque_SkAlphaType; + int width = pSource->GetWidth(); + int height = pSource->GetHeight(); + int rowBytes = pSource->GetPitch(); + switch (pSource->GetBPP()) { + case 1: { + dst8Storage.reset(FX_Alloc2D(uint8_t, width, height)); + uint8_t* dst8Pixels = dst8Storage.get(); + for (int y = 0; y < height; ++y) { + const uint8_t* srcRow = + static_cast<const uint8_t*>(buffer) + y * rowBytes; + uint8_t* dstRow = dst8Pixels + y * width; + for (int x = 0; x < width; ++x) + dstRow[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? 0xFF : 0x00; + } + buffer = dst8Storage.get(); + rowBytes = width; + break; + } + case 8: + if (pSource->GetPalette()) { + *ctPtr = + new SkColorTable(pSource->GetPalette(), pSource->GetPaletteSize()); + colorType = SkColorType::kIndex_8_SkColorType; + } + break; + case 24: { + dst32Storage.reset(FX_Alloc2D(uint32_t, width, height)); + uint32_t* dst32Pixels = dst32Storage.get(); + for (int y = 0; y < height; ++y) { + const uint8_t* srcRow = + static_cast<const uint8_t*>(buffer) + y * rowBytes; + uint32_t* dstRow = dst32Pixels + y * width; + for (int x = 0; x < width; ++x) { + dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1], + srcRow[x * 3 + 0]); + } + } + buffer = dst32Storage.get(); + rowBytes = width * sizeof(uint32_t); + colorType = SkColorType::kN32_SkColorType; + alphaType = kOpaque_SkAlphaType; + break; + } + case 32: + colorType = SkColorType::kN32_SkColorType; + alphaType = kPremul_SkAlphaType; + pSource->DebugVerifyBitmapIsPreMultiplied(buffer); + break; + default: + SkASSERT(0); // TODO(caryclark) ensure that all cases are covered + colorType = SkColorType::kUnknown_SkColorType; + } + SkImageInfo imageInfo = + SkImageInfo::Make(width, height, colorType, alphaType); + skBitmap->installPixels(imageInfo, buffer, rowBytes, *ctPtr, nullptr, + nullptr); + *widthPtr = width; + *heightPtr = height; + return true; +} + } // namespace // Encapsulate the state used for successive text and path draws so that @@ -500,22 +604,24 @@ class SkiaState { int count = m_positions.count(); m_positions.setCount(nChars + count); m_glyphs.setCount(nChars + count); + SkScalar flip = m_fontSize < 0 ? -1 : 1; for (int index = 0; index < nChars; ++index) { const FXTEXT_CHARPOS& cp = pCharPos[index]; - m_positions[index + count] = {cp.m_OriginX, cp.m_OriginY}; + m_positions[index + count] = {cp.m_OriginX * flip, cp.m_OriginY * flip}; m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; } SkPoint delta; if (MatrixOffset(pMatrix, &delta)) { for (int index = 0; index < nChars; ++index) - m_positions[index + count].offset(delta.fX, -delta.fY); + m_positions[index + count].offset(delta.fX * flip, -delta.fY * flip); } m_drawText = true; return true; } void FlushText(CFX_SkiaDeviceDriver* pDriver) { - SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix); + SkScalar flip = m_fontSize < 0 ? -1 : 1; + SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix, flip); SkPaint skPaint; skPaint.setAntiAlias(true); skPaint.setColor(m_fillColor); @@ -919,7 +1025,8 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, paint.setTextSize(font_size); paint.setSubpixelText(true); m_pCanvas->save(); - SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); + SkScalar flip = font_size < 0 ? -1 : 1; + SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device, flip); m_pCanvas->concat(skMatrix); SkTDArray<SkPoint> positions; positions.setCount(nChars); @@ -927,7 +1034,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, glyphs.setCount(nChars); for (int index = 0; index < nChars; ++index) { const FXTEXT_CHARPOS& cp = pCharPos[index]; - positions[index] = {cp.m_OriginX, cp.m_OriginY}; + positions[index] = {cp.m_OriginX * flip, cp.m_OriginY * flip}; glyphs[index] = (uint16_t)cp.m_GlyphIndex; } m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint); @@ -1339,86 +1446,39 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, void*& handle, int blend_type) { DebugValidate(m_pBitmap, m_pOriDevice); - SkColorType colorType = pSource->IsAlphaMask() - ? SkColorType::kAlpha_8_SkColorType - : SkColorType::kGray_8_SkColorType; - SkAlphaType alphaType = - pSource->IsAlphaMask() ? kPremul_SkAlphaType : kOpaque_SkAlphaType; SkColorTable* ct = nullptr; - void* buffer = pSource->GetBuffer(); - if (!buffer) - return FALSE; std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage; std::unique_ptr<uint32_t, FxFreeDeleter> dst32Storage; - int width = pSource->GetWidth(); - int height = pSource->GetHeight(); - int rowBytes = pSource->GetPitch(); - switch (pSource->GetBPP()) { - case 1: { - dst8Storage.reset(FX_Alloc2D(uint8_t, width, height)); - uint8_t* dst8Pixels = dst8Storage.get(); - for (int y = 0; y < height; ++y) { - const uint8_t* srcRow = - static_cast<const uint8_t*>(buffer) + y * rowBytes; - uint8_t* dstRow = dst8Pixels + y * width; - for (int x = 0; x < width; ++x) - dstRow[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? 0xFF : 0x00; - } - buffer = dst8Storage.get(); - rowBytes = width; - } break; - case 8: - if (pSource->GetPalette()) { - ct = new SkColorTable(pSource->GetPalette(), pSource->GetPaletteSize()); - colorType = SkColorType::kIndex_8_SkColorType; - } - break; - case 24: { - dst32Storage.reset(FX_Alloc2D(uint32_t, width, height)); - uint32_t* dst32Pixels = dst32Storage.get(); - for (int y = 0; y < height; ++y) { - const uint8_t* srcRow = - static_cast<const uint8_t*>(buffer) + y * rowBytes; - uint32_t* dstRow = dst32Pixels + y * width; - for (int x = 0; x < width; ++x) { - dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1], - srcRow[x * 3 + 0]); - } - } - buffer = dst32Storage.get(); - rowBytes = width * sizeof(uint32_t); - colorType = SkColorType::kN32_SkColorType; - alphaType = kOpaque_SkAlphaType; - } break; - case 32: - colorType = SkColorType::kN32_SkColorType; - alphaType = kPremul_SkAlphaType; - pSource->DebugVerifyBitmapIsPreMultiplied(buffer); - break; - default: - SkASSERT(0); // TODO(caryclark) ensure that all cases are covered - colorType = SkColorType::kUnknown_SkColorType; - } - SkImageInfo imageInfo = - SkImageInfo::Make(width, height, colorType, alphaType); SkBitmap skBitmap; - skBitmap.installPixels(imageInfo, buffer, rowBytes, ct, nullptr, nullptr); + int width, height; + if (!Upsample(pSource, dst8Storage, dst32Storage, &ct, &skBitmap, &width, + &height, false)) { + return FALSE; + } m_pCanvas->save(); SkMatrix skMatrix; - const CFX_Matrix& m = *pMatrix; - skMatrix.setAll(m.a / width, -m.c / height, m.c + m.e, m.b / width, - -m.d / height, m.d + m.f, 0, 0, 1); + SetBitmapMatrix(pMatrix, width, height, &skMatrix); m_pCanvas->concat(skMatrix); SkPaint paint; - paint.setAntiAlias(true); - if (pSource->IsAlphaMask()) { - paint.setColorFilter( - SkColorFilter::MakeModeFilter(argb, SkXfermode::kSrc_Mode)); + SetBitmapPaint(pSource->IsAlphaMask(), argb, bitmap_alpha, blend_type, + &paint); + // TODO(caryclark) Once Skia supports 8 bit src to 8 bit dst remove this + if (m_pBitmap->GetBPP() == 8 && pSource->GetBPP() == 8) { + SkMatrix inv; + SkAssertResult(skMatrix.invert(&inv)); + for (int y = 0; y < m_pBitmap->GetHeight(); ++y) { + for (int x = 0; x < m_pBitmap->GetWidth(); ++x) { + SkPoint src = {x + 0.5f, y + 0.5f}; + inv.mapPoints(&src, 1); + // TODO(caryclark) Why does the matrix map require clamping? + src.fX = SkTMax(0.5f, SkTMin(src.fX, width - 0.5f)); + src.fY = SkTMax(0.5f, SkTMin(src.fY, height - 0.5f)); + m_pBitmap->SetPixel(x, y, skBitmap.getColor(src.fX, src.fY)); + } + } + } else { + m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); } - // paint.setFilterQuality(kHigh_SkFilterQuality); - paint.setXfermodeMode(GetSkiaBlendMode(blend_type)); - paint.setAlpha(bitmap_alpha); - m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); m_pCanvas->restore(); if (ct) ct->unref(); @@ -1450,6 +1510,68 @@ void CFX_SkiaDeviceDriver::PreMultiply(CFX_DIBitmap* pDIBitmap) { pDIBitmap->DebugVerifyBitmapIsPreMultiplied(); } +bool CFX_SkiaDeviceDriver::DrawBitsWithMask(const CFX_DIBSource* pSource, + const CFX_DIBSource* pMask, + int bitmap_alpha, + const CFX_Matrix* pMatrix, + int blend_type) { + DebugValidate(m_pBitmap, m_pOriDevice); + SkColorTable* srcCt = nullptr; + SkColorTable* maskCt = nullptr; + std::unique_ptr<uint8_t, FxFreeDeleter> src8Storage, mask8Storage; + std::unique_ptr<uint32_t, FxFreeDeleter> src32Storage, mask32Storage; + SkBitmap skBitmap, skMask; + int srcWidth, srcHeight, maskWidth, maskHeight; + if (!Upsample(pSource, src8Storage, src32Storage, &srcCt, &skBitmap, + &srcWidth, &srcHeight, false)) { + return false; + } + if (!Upsample(pMask, mask8Storage, mask32Storage, &maskCt, &skMask, + &maskWidth, &maskHeight, true)) { + return false; + } + m_pCanvas->save(); + SkMatrix skMatrix; + SetBitmapMatrix(pMatrix, srcWidth, srcHeight, &skMatrix); + m_pCanvas->concat(skMatrix); + SkPaint paint; + SetBitmapPaint(pSource->IsAlphaMask(), 0xFFFFFFFF, bitmap_alpha, blend_type, + &paint); + sk_sp<SkImage> skSrc = SkImage::MakeFromBitmap(skBitmap); + sk_sp<SkShader> skSrcShader = + skSrc->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); + sk_sp<SkImage> skMaskImage = SkImage::MakeFromBitmap(skMask); + sk_sp<SkShader> skMaskShader = skMaskImage->makeShader( + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); + sk_sp<SkXfermode> dstInMode = SkXfermode::Make(SkXfermode::kSrcIn_Mode); + paint.setShader( + SkShader::MakeComposeShader(skMaskShader, skSrcShader, dstInMode)); + SkRect r = {0, 0, SkIntToScalar(srcWidth), SkIntToScalar(srcHeight)}; + m_pCanvas->drawRect(r, paint); + m_pCanvas->restore(); + if (srcCt) + srcCt->unref(); + DebugValidate(m_pBitmap, m_pOriDevice); + return true; +} + +bool CFX_SkiaDeviceDriver::SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int dest_left, + int dest_top, + int bitmap_alpha, + int blend_type) { + if (!m_pBitmap || !m_pBitmap->GetBuffer()) + return true; + CFX_Matrix m(pBitmap->GetWidth(), 0, 0, -pBitmap->GetHeight(), dest_left, + dest_top + pBitmap->GetHeight()); + return DrawBitsWithMask(pBitmap, pMask, bitmap_alpha, &m, blend_type); +} + +void CFX_SkiaDeviceDriver::Clear(uint32_t color) { + m_pCanvas->clear(color); +} + void CFX_SkiaDeviceDriver::Dump() const { #ifdef SK_DEBUG if (m_pCache) @@ -1466,6 +1588,12 @@ CFX_FxgeDevice::CFX_FxgeDevice() { m_bOwnedBitmap = FALSE; } +void CFX_FxgeDevice::Clear(uint32_t color) { + CFX_SkiaDeviceDriver* skDriver = + static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); + skDriver->Clear(color); +} + SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); SetDeviceDriver(WrapUnique(skDriver)); @@ -1523,6 +1651,20 @@ void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const { #endif } +bool CFX_FxgeDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int left, + int top, + int bitmap_alpha, + int blend_type) { + CFX_SkiaDeviceDriver* skDriver = + static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); + if (skDriver) + return skDriver->SetBitsWithMask(pBitmap, pMask, left, top, bitmap_alpha, + blend_type); + return false; +} + void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const { #ifdef SK_DEBUG SkASSERT(32 == GetBPP()); diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h index 661cf2e3b9..6e112f5f62 100644 --- a/core/fxge/skia/fx_skia_device.h +++ b/core/fxge/skia/fx_skia_device.h @@ -84,6 +84,12 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { int dest_left, int dest_top, int blend_type) override; + bool SetBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int dest_left, + int dest_top, + int bitmap_alpha, + int blend_type) override; FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, uint32_t color, int dest_left, @@ -106,6 +112,12 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { void CancelDIBits(void* handle) override {} + bool DrawBitsWithMask(const CFX_DIBSource* pBitmap, + const CFX_DIBSource* pMask, + int bitmap_alpha, + const CFX_Matrix* pMatrix, + int blend_type); + FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, @@ -125,6 +137,7 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { void PaintStroke(SkPaint* spaint, const CFX_GraphStateData* pGraphState, const SkMatrix& matrix); + void Clear(uint32_t color); void Flush(); SkPictureRecorder* GetRecorder() const { return m_pRecorder; } static void PreMultiply(CFX_DIBitmap* pDIBitmap); |