summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_image.cpp22
-rw-r--r--core/fxge/ge/cfx_renderdevice.cpp11
-rw-r--r--core/fxge/ifx_renderdevicedriver.cpp9
-rw-r--r--core/fxge/include/cfx_fxgedevice.h7
-rw-r--r--core/fxge/include/cfx_renderdevice.h6
-rw-r--r--core/fxge/include/ifx_renderdevicedriver.h6
-rw-r--r--core/fxge/skia/fx_skia_device.cpp298
-rw-r--r--core/fxge/skia/fx_skia_device.h13
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);