| 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 148f6231241d388bc9f4ad9cadbbd56d8a272e4b..222c8466e0d25bf050a448f1b35ab2312e9a3935 100644
|
| --- a/core/fxge/skia/fx_skia_device.cpp
|
| +++ b/core/fxge/skia/fx_skia_device.cpp
|
| @@ -86,41 +86,18 @@ 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());
|
| + bitmap->DebugVerifyBitmapIsPreMultiplied();
|
| }
|
| }
|
| if (device) {
|
| SkASSERT(device->GetBPP() == 8 || device->GetBPP() == 32);
|
| if (device->GetBPP() == 32) {
|
| - DebugVerifyBitmapIsPreMultiplied(device->GetBuffer(), device->GetWidth(),
|
| - device->GetHeight());
|
| + device->DebugVerifyBitmapIsPreMultiplied();
|
| }
|
| }
|
| }
|
| @@ -291,98 +268,6 @@ bool AddStitching(const CPDF_StitchFunc* pFunc,
|
| return true;
|
| }
|
|
|
| -void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap,
|
| - int dest_left,
|
| - int dest_top,
|
| - int width,
|
| - int height,
|
| - const CFX_DIBSource* pSrcBitmap,
|
| - int src_left,
|
| - int src_top) {
|
| - if (!pBitmap)
|
| - return;
|
| - pBitmap->GetOverlapRect(dest_left, dest_top, width, height,
|
| - pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
|
| - src_left, src_top, nullptr);
|
| - if (width == 0 || height == 0)
|
| - return;
|
| - int Bpp = pBitmap->GetBPP() / 8;
|
| - FXDIB_Format dest_format = pBitmap->GetFormat();
|
| - FXDIB_Format src_format = pSrcBitmap->GetFormat();
|
| - int pitch = pBitmap->GetPitch();
|
| - uint8_t* buffer = pBitmap->GetBuffer();
|
| - if (dest_format == src_format) {
|
| - for (int row = 0; row < height; row++) {
|
| - uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp;
|
| - uint8_t* src_scan =
|
| - (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
|
| - if (Bpp == 4) {
|
| - for (int col = 0; col < width; col++) {
|
| - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0],
|
| - src_scan[1], src_scan[2]));
|
| - dest_scan += 4;
|
| - src_scan += 4;
|
| - }
|
| - } else {
|
| - for (int col = 0; col < width; col++) {
|
| - *dest_scan++ = src_scan[2];
|
| - *dest_scan++ = src_scan[1];
|
| - *dest_scan++ = src_scan[0];
|
| - src_scan += 3;
|
| - }
|
| - }
|
| - }
|
| - return;
|
| - }
|
| - uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp;
|
| - if (dest_format == FXDIB_Rgb) {
|
| - if (src_format == FXDIB_Rgb32) {
|
| - for (int row = 0; row < height; row++) {
|
| - uint8_t* dest_scan = dest_buf + row * pitch;
|
| - uint8_t* src_scan =
|
| - (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
|
| - for (int col = 0; col < width; col++) {
|
| - *dest_scan++ = src_scan[2];
|
| - *dest_scan++ = src_scan[1];
|
| - *dest_scan++ = src_scan[0];
|
| - src_scan += 4;
|
| - }
|
| - }
|
| - } else {
|
| - ASSERT(FALSE);
|
| - }
|
| - } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) {
|
| - if (src_format == FXDIB_Rgb) {
|
| - for (int row = 0; row < height; row++) {
|
| - uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch);
|
| - uint8_t* src_scan =
|
| - (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
|
| - for (int col = 0; col < width; col++) {
|
| - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1],
|
| - src_scan[2]));
|
| - dest_scan += 4;
|
| - src_scan += 3;
|
| - }
|
| - }
|
| - } else if (src_format == FXDIB_Rgb32) {
|
| - ASSERT(dest_format == FXDIB_Argb);
|
| - for (int row = 0; row < height; row++) {
|
| - uint8_t* dest_scan = dest_buf + row * pitch;
|
| - uint8_t* src_scan =
|
| - (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4);
|
| - for (int col = 0; col < width; col++) {
|
| - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1],
|
| - src_scan[2]));
|
| - src_scan += 4;
|
| - dest_scan += 4;
|
| - }
|
| - }
|
| - }
|
| - } else {
|
| - ASSERT(FALSE);
|
| - }
|
| -}
|
| -
|
| // see https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
|
| SkScalar LineSide(const SkPoint line[2], const SkPoint& pt) {
|
| return (line[1].fY - line[0].fY) * pt.fX - (line[1].fX - line[0].fX) * pt.fY +
|
| @@ -525,11 +410,13 @@ class SkiaState {
|
| m_skPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE
|
| ? SkPath::kEvenOdd_FillType
|
| : SkPath::kWinding_FillType);
|
| - m_drawState = *pDrawState;
|
| + if (pDrawState)
|
| + m_drawState.Copy(*pDrawState);
|
| m_fillColor = fill_color;
|
| m_strokeColor = stroke_color;
|
| m_blendType = blend_type;
|
| - m_drawMatrix = *pMatrix;
|
| + if (pMatrix)
|
| + m_drawMatrix = *pMatrix;
|
| }
|
| SkPath skPath = BuildPath(pPathData);
|
| SkPoint delta;
|
| @@ -633,6 +520,7 @@ class SkiaState {
|
| skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| skPaint.setTextSize(m_fontSize);
|
| skPaint.setSubpixelText(true);
|
| + skPaint.setHinting(SkPaint::kNo_Hinting);
|
| SkCanvas* skCanvas = pDriver->SkiaCanvas();
|
| skCanvas->save();
|
| skCanvas->concat(skMatrix);
|
| @@ -690,6 +578,9 @@ class SkiaState {
|
| }
|
|
|
| bool MatrixOffset(const CFX_Matrix* pMatrix, SkPoint* delta) {
|
| + CFX_Matrix identityMatrix;
|
| + if (!pMatrix)
|
| + pMatrix = &identityMatrix;
|
| delta->set(pMatrix->e - m_drawMatrix.e, pMatrix->f - m_drawMatrix.f);
|
| if (!delta->fX && !delta->fY)
|
| return true;
|
| @@ -789,12 +680,18 @@ class SkiaState {
|
| }
|
|
|
| bool MatrixChanged(const CFX_Matrix* pMatrix, const CFX_Matrix& refMatrix) {
|
| + CFX_Matrix identityMatrix;
|
| + if (!pMatrix)
|
| + pMatrix = &identityMatrix;
|
| return pMatrix->a != refMatrix.a || pMatrix->b != refMatrix.b ||
|
| pMatrix->c != refMatrix.c || pMatrix->d != refMatrix.d;
|
| }
|
|
|
| bool StateChanged(const CFX_GraphStateData* pState,
|
| const CFX_GraphStateData& refState) {
|
| + CFX_GraphStateData identityState;
|
| + if (!pState)
|
| + pState = &identityState;
|
| return pState->m_LineWidth != refState.m_LineWidth ||
|
| pState->m_LineCap != refState.m_LineCap ||
|
| pState->m_LineJoin != refState.m_LineJoin ||
|
| @@ -804,9 +701,10 @@ class SkiaState {
|
|
|
| bool DashChanged(const CFX_GraphStateData* pState,
|
| const CFX_GraphStateData& refState) {
|
| - if (!pState->m_DashArray && !refState.m_DashArray)
|
| + bool dashArray = pState && pState->m_DashArray;
|
| + if (!dashArray && !refState.m_DashArray)
|
| return false;
|
| - if (!pState->m_DashArray || !refState.m_DashArray)
|
| + if (!dashArray || !refState.m_DashArray)
|
| return true;
|
| if (pState->m_DashPhase != refState.m_DashPhase ||
|
| pState->m_DashCount != refState.m_DashCount) {
|
| @@ -946,7 +844,6 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap,
|
| m_pOriDevice(pOriDevice),
|
| m_pRecorder(nullptr),
|
| m_pCache(new SkiaState),
|
| - m_bRgbByteOrder(bRgbByteOrder),
|
| m_bGroupKnockout(bGroupKnockout) {
|
| SkBitmap skBitmap;
|
| SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32);
|
| @@ -967,7 +864,6 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y)
|
| m_pOriDevice(nullptr),
|
| m_pRecorder(new SkPictureRecorder),
|
| m_pCache(new SkiaState),
|
| - m_bRgbByteOrder(FALSE),
|
| m_bGroupKnockout(FALSE) {
|
| m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y));
|
| m_pCanvas = m_pRecorder->getRecordingCanvas();
|
| @@ -978,7 +874,6 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder)
|
| m_pOriDevice(nullptr),
|
| m_pRecorder(recorder),
|
| m_pCache(new SkiaState),
|
| - m_bRgbByteOrder(FALSE),
|
| m_bGroupKnockout(FALSE) {
|
| m_pCanvas = m_pRecorder->getRecordingCanvas();
|
| }
|
| @@ -1012,6 +907,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars,
|
| paint.setColor(color);
|
| paint.setTypeface(typeface);
|
| paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| + paint.setHinting(SkPaint::kNo_Hinting);
|
| paint.setTextSize(font_size);
|
| paint.setSubpixelText(true);
|
| m_pCanvas->save();
|
| @@ -1354,35 +1250,33 @@ FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) {
|
| FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap,
|
| int left,
|
| int top) {
|
| - if (!m_pBitmap || !m_pBitmap->GetBuffer())
|
| + if (!m_pBitmap)
|
| return TRUE;
|
| -
|
| - FX_RECT rect(left, top, left + pBitmap->GetWidth(),
|
| - top + pBitmap->GetHeight());
|
| - std::unique_ptr<CFX_DIBitmap> pBack;
|
| - if (m_pOriDevice) {
|
| - pBack.reset(m_pOriDevice->Clone(&rect));
|
| - if (!pBack)
|
| - return TRUE;
|
| -
|
| - pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(),
|
| - m_pBitmap, 0, 0);
|
| - } else {
|
| - pBack.reset(m_pBitmap->Clone(&rect));
|
| - if (!pBack)
|
| - return TRUE;
|
| - }
|
| -
|
| - left = std::min(left, 0);
|
| - top = std::min(top, 0);
|
| - if (m_bRgbByteOrder) {
|
| - RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(),
|
| - pBack.get(), left, top);
|
| + uint8_t* srcBuffer = m_pBitmap->GetBuffer();
|
| + if (!srcBuffer)
|
| return TRUE;
|
| - }
|
| -
|
| - return pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack.get(),
|
| - left, top);
|
| + int srcWidth = m_pBitmap->GetWidth();
|
| + int srcHeight = m_pBitmap->GetHeight();
|
| + int srcRowBytes = srcWidth * sizeof(uint32_t);
|
| + SkImageInfo srcImageInfo = SkImageInfo::Make(
|
| + srcWidth, srcHeight, SkColorType::kN32_SkColorType, kPremul_SkAlphaType);
|
| + SkBitmap skSrcBitmap;
|
| + skSrcBitmap.installPixels(srcImageInfo, srcBuffer, srcRowBytes, nullptr,
|
| + nullptr, nullptr);
|
| + SkASSERT(pBitmap);
|
| + uint8_t* dstBuffer = pBitmap->GetBuffer();
|
| + SkASSERT(dstBuffer);
|
| + int dstWidth = pBitmap->GetWidth();
|
| + int dstHeight = pBitmap->GetHeight();
|
| + int dstRowBytes = dstWidth * sizeof(uint32_t);
|
| + SkImageInfo dstImageInfo = SkImageInfo::Make(
|
| + dstWidth, dstHeight, SkColorType::kN32_SkColorType, kPremul_SkAlphaType);
|
| + SkBitmap skDstBitmap;
|
| + skDstBitmap.installPixels(dstImageInfo, dstBuffer, dstRowBytes, nullptr,
|
| + nullptr, nullptr);
|
| + SkCanvas canvas(skDstBitmap);
|
| + canvas.drawBitmap(skSrcBitmap, left, top, nullptr);
|
| + return TRUE;
|
| }
|
|
|
| CFX_DIBitmap* CFX_SkiaDeviceDriver::GetBackDrop() {
|
| @@ -1491,7 +1385,7 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
|
| case 32:
|
| colorType = SkColorType::kN32_SkColorType;
|
| alphaType = kPremul_SkAlphaType;
|
| - DebugVerifyBitmapIsPreMultiplied(buffer, width, height);
|
| + pSource->DebugVerifyBitmapIsPreMultiplied(buffer);
|
| break;
|
| default:
|
| SkASSERT(0); // TODO(caryclark) ensure that all cases are covered
|
| @@ -1528,10 +1422,6 @@ FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) {
|
| return FALSE;
|
| }
|
|
|
| -void CFX_SkiaDeviceDriver::PreMultiply() {
|
| - PreMultiply(m_pBitmap);
|
| -}
|
| -
|
| void CFX_SkiaDeviceDriver::PreMultiply(CFX_DIBitmap* pDIBitmap) {
|
| void* buffer = pDIBitmap->GetBuffer();
|
| if (!buffer)
|
| @@ -1549,7 +1439,7 @@ void CFX_SkiaDeviceDriver::PreMultiply(CFX_DIBitmap* pDIBitmap) {
|
| SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
|
| SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
|
| unpremultiplied.readPixels(premultiplied);
|
| - DebugVerifyBitmapIsPreMultiplied(buffer, width, height);
|
| + pDIBitmap->DebugVerifyBitmapIsPreMultiplied();
|
| }
|
|
|
| void CFX_SkiaDeviceDriver::Dump() const {
|
| @@ -1559,6 +1449,11 @@ void CFX_SkiaDeviceDriver::Dump() const {
|
| #endif
|
| }
|
|
|
| +void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const {
|
| + if (m_pOriDevice)
|
| + m_pOriDevice->DebugVerifyBitmapIsPreMultiplied();
|
| +}
|
| +
|
| CFX_FxgeDevice::CFX_FxgeDevice() {
|
| m_bOwnedBitmap = FALSE;
|
| }
|
| @@ -1606,12 +1501,42 @@ bool CFX_FxgeDevice::Create(int width,
|
| }
|
|
|
| CFX_FxgeDevice::~CFX_FxgeDevice() {
|
| + Flush();
|
| + // call destructor of CFX_RenderDevice / CFX_SkiaDeviceDriver immediately
|
| if (m_bOwnedBitmap && GetBitmap())
|
| delete GetBitmap();
|
| }
|
|
|
| -void CFX_FxgeDevice::PreMultiply() {
|
| - (static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()))->PreMultiply();
|
| +void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const {
|
| +#ifdef SK_DEBUG
|
| + CFX_SkiaDeviceDriver* skDriver =
|
| + static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
|
| + if (skDriver)
|
| + skDriver->DebugVerifyBitmapIsPreMultiplied();
|
| +#endif
|
| +}
|
| +
|
| +void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const {
|
| +#ifdef SK_DEBUG
|
| + SkASSERT(32 == GetBPP());
|
| + const uint32_t* buffer = (const uint32_t*)(opt ? opt : GetBuffer());
|
| + int width = GetWidth();
|
| + int height = GetHeight();
|
| + // verify that input is really premultiplied
|
| + for (int y = 0; y < height; ++y) {
|
| + const uint32_t* srcRow = 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
|
| }
|
|
|
| #endif
|
|
|