| Index: core/fxge/skia/fx_skia_device.cpp
|
| diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
|
| index 452472e40ccd7fc544ea40e86c9cca89229340f2..86a8269b7947573a820a40497dd720fb36997bca 100644
|
| --- a/core/fxge/skia/fx_skia_device.cpp
|
| +++ b/core/fxge/skia/fx_skia_device.cpp
|
| @@ -81,6 +81,45 @@ void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) {}
|
| #undef SHOW_SKIA_PATH
|
| #undef DRAW_SKIA_CLIP
|
|
|
| +static void DebugVerifyBitmapIsPreMultiplied(void* buffer,
|
| + int width,
|
| + int height) {
|
| +#ifdef SK_DEBUG
|
| + // verify that input is really premultiplied
|
| + for (int y = 0; y < height; ++y) {
|
| + const uint32_t* srcRow = static_cast<const uint32_t*>(buffer) + y * width;
|
| + for (int x = 0; x < width; ++x) {
|
| + uint8_t a = SkGetPackedA32(srcRow[x]);
|
| + uint8_t r = SkGetPackedR32(srcRow[x]);
|
| + uint8_t g = SkGetPackedG32(srcRow[x]);
|
| + uint8_t b = SkGetPackedB32(srcRow[x]);
|
| + SkA32Assert(a);
|
| + SkASSERT(r <= a);
|
| + SkASSERT(g <= a);
|
| + SkASSERT(b <= a);
|
| + }
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +static void DebugValidate(const CFX_DIBitmap* bitmap,
|
| + const CFX_DIBitmap* device) {
|
| + if (bitmap) {
|
| + SkASSERT(bitmap->GetBPP() == 8 || bitmap->GetBPP() == 32);
|
| + if (bitmap->GetBPP() == 32) {
|
| + DebugVerifyBitmapIsPreMultiplied(bitmap->GetBuffer(), bitmap->GetWidth(),
|
| + bitmap->GetHeight());
|
| + }
|
| + }
|
| + if (device) {
|
| + SkASSERT(device->GetBPP() == 8 || device->GetBPP() == 32);
|
| + if (device->GetBPP() == 32) {
|
| + DebugVerifyBitmapIsPreMultiplied(device->GetBuffer(), device->GetWidth(),
|
| + device->GetHeight());
|
| + }
|
| + }
|
| +}
|
| +
|
| SkPath BuildPath(const CFX_PathData* pPathData) {
|
| SkPath skPath;
|
| const CFX_PathData* pFPath = pPathData;
|
| @@ -509,9 +548,11 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap,
|
| m_bRgbByteOrder(bRgbByteOrder),
|
| m_bGroupKnockout(bGroupKnockout) {
|
| SkBitmap skBitmap;
|
| - SkImageInfo imageInfo =
|
| - SkImageInfo::Make(pBitmap->GetWidth(), pBitmap->GetHeight(),
|
| - kN32_SkColorType, kOpaque_SkAlphaType);
|
| + SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32);
|
| + SkImageInfo imageInfo = SkImageInfo::Make(
|
| + pBitmap->GetWidth(), pBitmap->GetHeight(),
|
| + pBitmap->GetBPP() == 8 ? kAlpha_8_SkColorType : kN32_SkColorType,
|
| + kOpaque_SkAlphaType);
|
| skBitmap.installPixels(imageInfo, pBitmap->GetBuffer(), pBitmap->GetPitch(),
|
| nullptr, /* to do : set color table */
|
| nullptr, nullptr);
|
| @@ -553,7 +594,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars,
|
| uint32_t color,
|
| int alpha_flag,
|
| void* pIccTransform) {
|
| - CFX_TypeFace* typeface = pCache->GetDeviceCache(pFont);
|
| + sk_sp<SkTypeface> typeface(SkSafeRef(pCache->GetDeviceCache(pFont)));
|
| SkPaint paint;
|
| paint.setAntiAlias(true);
|
| paint.setColor(color);
|
| @@ -932,15 +973,12 @@ FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
|
| void* pIccTransform) {
|
| if (!m_pBitmap || !m_pBitmap->GetBuffer())
|
| return TRUE;
|
| - if (pBitmap->IsAlphaMask()) {
|
| - return m_pBitmap->CompositeMask(
|
| - left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb,
|
| - pSrcRect->left, pSrcRect->top, blend_type, nullptr, m_bRgbByteOrder,
|
| - alpha_flag, pIccTransform);
|
| - }
|
| - return m_pBitmap->CompositeBitmap(
|
| - left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, pSrcRect->left,
|
| - pSrcRect->top, blend_type, nullptr, m_bRgbByteOrder, pIccTransform);
|
| +
|
| + CFX_Matrix m(pBitmap->GetWidth(), 0, 0, -pBitmap->GetHeight(), left,
|
| + top + pBitmap->GetHeight());
|
| + void* dummy;
|
| + return this->StartDIBits(pBitmap, 0xFF, argb, &m, 0, dummy, alpha_flag,
|
| + pIccTransform, blend_type);
|
| }
|
|
|
| FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource,
|
| @@ -956,27 +994,19 @@ FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource,
|
| int blend_type) {
|
| if (!m_pBitmap->GetBuffer())
|
| return TRUE;
|
| - if (dest_width == pSource->GetWidth() &&
|
| - dest_height == pSource->GetHeight()) {
|
| - FX_RECT rect(0, 0, dest_width, dest_height);
|
| - return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type,
|
| - alpha_flag, pIccTransform);
|
| - }
|
| - FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width,
|
| - dest_top + dest_height);
|
| - dest_rect.Normalize();
|
| - FX_RECT dest_clip = dest_rect;
|
| - dest_clip.Intersect(*pClipRect);
|
| - CFX_BitmapComposer composer;
|
| - composer.Compose(m_pBitmap, nullptr, 255, argb, dest_clip, FALSE, FALSE,
|
| - FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform,
|
| - blend_type);
|
| - dest_clip.Offset(-dest_rect.left, -dest_rect.top);
|
| - CFX_ImageStretcher stretcher(&composer, pSource, dest_width, dest_height,
|
| - dest_clip, flags);
|
| - if (stretcher.Start())
|
| - stretcher.Continue(nullptr);
|
| - return TRUE;
|
| + CFX_Matrix m(dest_width, 0, 0, -dest_height, dest_left,
|
| + dest_top + dest_height);
|
| +
|
| + m_pCanvas->save();
|
| + SkRect skClipRect = SkRect::MakeLTRB(pClipRect->left, pClipRect->bottom,
|
| + pClipRect->right, pClipRect->top);
|
| + m_pCanvas->clipRect(skClipRect);
|
| + void* dummy;
|
| + FX_BOOL result = this->StartDIBits(pSource, 0xFF, argb, &m, 0, dummy,
|
| + alpha_flag, pIccTransform, blend_type);
|
| + m_pCanvas->restore();
|
| +
|
| + return result;
|
| }
|
|
|
| FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
|
| @@ -988,9 +1018,12 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
|
| int alpha_flag,
|
| void* pIccTransform,
|
| 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();
|
| std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage;
|
| @@ -1025,23 +1058,27 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
|
| 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)
|
| + 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;
|
| + DebugVerifyBitmapIsPreMultiplied(buffer, width, height);
|
| break;
|
| default:
|
| + SkASSERT(0); // TODO(caryclark) ensure that all cases are covered
|
| colorType = SkColorType::kUnknown_SkColorType;
|
| }
|
| - SkImageInfo imageInfo = SkImageInfo::Make(
|
| - width, height, colorType,
|
| - pSource->IsAlphaMask() ? kPremul_SkAlphaType : kOpaque_SkAlphaType);
|
| + SkImageInfo imageInfo =
|
| + SkImageInfo::Make(width, height, colorType, alphaType);
|
| SkBitmap skBitmap;
|
| skBitmap.installPixels(imageInfo, buffer, rowBytes, ct, nullptr, nullptr);
|
| m_pCanvas->save();
|
| @@ -1063,19 +1100,28 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
|
| m_pCanvas->restore();
|
| if (ct)
|
| ct->unref();
|
| + DebugValidate(m_pBitmap, m_pOriDevice);
|
| return TRUE;
|
| }
|
|
|
| -FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) {
|
| - if (!m_pBitmap->GetBuffer())
|
| - return TRUE;
|
| - return ((CFX_ImageRenderer*)pHandle)->Continue(pPause);
|
| -}
|
| -
|
| -void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) {
|
| - if (!m_pBitmap->GetBuffer())
|
| +void CFX_SkiaDeviceDriver::PreMultiply() {
|
| + void* buffer = m_pBitmap->GetBuffer();
|
| + if (!buffer)
|
| return;
|
| - delete (CFX_ImageRenderer*)pHandle;
|
| + if (m_pBitmap->GetBPP() != 32) {
|
| + return;
|
| + }
|
| + int height = m_pBitmap->GetHeight();
|
| + int width = m_pBitmap->GetWidth();
|
| + int rowBytes = m_pBitmap->GetPitch();
|
| + SkImageInfo unpremultipliedInfo =
|
| + SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
|
| + SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes);
|
| + SkImageInfo premultipliedInfo =
|
| + SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
|
| + SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
|
| + unpremultiplied.readPixels(premultiplied);
|
| + DebugVerifyBitmapIsPreMultiplied(buffer, width, height);
|
| }
|
|
|
| CFX_FxgeDevice::CFX_FxgeDevice() {
|
| @@ -1129,4 +1175,8 @@ CFX_FxgeDevice::~CFX_FxgeDevice() {
|
| delete GetBitmap();
|
| }
|
|
|
| +void CFX_FxgeDevice::PreMultiply() {
|
| + (static_cast<CFX_SkiaDeviceDriver*>(this->GetDeviceDriver()))->PreMultiply();
|
| +}
|
| +
|
| #endif
|
|
|