From 399be5bf559f72d4649a60320a3d802f6b21780b Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Mon, 14 Mar 2016 16:51:29 -0400 Subject: Add bitmaps and skp output to Skia port This is a first-cut at supporting bitmaps. Also added a --skp option to pdfium_test to generate a Skia picture file. The picture file can be loaded in Skia's SampleApp, debugger, or skiaserver to examine the generated picture. (This also includes fixes suggested in the prior Skia CL. My apologies for fat-fingers abandoning that one.) R=dsinclair@chromium.org, tsepez@chromium.org, dsinclair Review URL: https://codereview.chromium.org/1776313002 . --- core/fxge/agg/fx_agg_driver.h | 1 + core/fxge/skia/fx_skia_device.cpp | 342 ++++++++++++++++++++++++++++---------- core/fxge/skia/fx_skia_device.h | 8 +- core/include/fxge/fx_ge.h | 6 + 4 files changed, 265 insertions(+), 92 deletions(-) (limited to 'core') diff --git a/core/fxge/agg/fx_agg_driver.h b/core/fxge/agg/fx_agg_driver.h index 3631016fea..ea4c36059b 100644 --- a/core/fxge/agg/fx_agg_driver.h +++ b/core/fxge/agg/fx_agg_driver.h @@ -134,6 +134,7 @@ class CFX_AggDeviceDriver : public IFX_RenderDeviceDriver { void SetClipMask(agg::rasterizer_scanline_aa& rasterizer); virtual uint8_t* GetBuffer() const; + const CFX_DIBitmap* GetBitmap() const { return m_pBitmap; } private: CFX_DIBitmap* m_pBitmap; diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index 10eebe496c..acebf35eb8 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp @@ -10,10 +10,57 @@ #include "core/fxge/agg/fx_agg_driver.h" #include "core/fxge/skia/fx_skia_device.h" -#include "SkCanvas.h" -#include "SkDashPathEffect.h" -#include "SkPaint.h" -#include "SkPath.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColorPriv.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/SkStream.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "third_party/skia/include/effects/SkDashPathEffect.h" + +#define SHOW_SKIA_PATH 0 // set to 1 to print the path contents +#define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip + +static void DebugShowSkiaPath(const SkPath& path) { +#if SHOW_SKIA_PATH + char buffer[4096]; + sk_bzero(buffer, sizeof(buffer)); + SkMemoryWStream stream(buffer, sizeof(buffer)); + path.dump(&stream, false, false); + printf("%s\n", buffer); +#endif // SHOW_SKIA_PATH +} + +#if DRAW_SKIA_CLIP + +static SkPaint DebugClipPaint() { + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(SK_ColorGREEN); + paint.setStyle(SkPaint::kStroke_Style); + return paint; +} + +static void DebugDrawSkiaClipRect(SkCanvas* canvas, const SkRect& rect) { + SkPaint paint = DebugClipPaint(); + canvas->drawRect(rect, paint); +} + +static void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) { + SkPaint paint = DebugClipPaint(); + canvas->drawPath(path, paint); +} + +#else // DRAW_SKIA_CLIP + +static void DebugDrawSkiaClipRect(SkCanvas* canvas, const SkRect& rect) {} +static void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) {} + +#endif // DRAW_SKIA_CLIP + +#undef SHOW_SKIA_PATH +#undef DRAW_SKIA_CLIP static SkPath BuildPath(const CFX_PathData* pPathData, const CFX_Matrix* pObject2Device) { @@ -97,7 +144,7 @@ void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, ->unref(); } spaint->setStyle(SkPaint::kStroke_Style); - spaint->setAntiAlias(TRUE); + spaint->setAntiAlias(true); spaint->setStrokeWidth(width); spaint->setStrokeMiter(pGraphState->m_MiterLimit); spaint->setStrokeCap(cap); @@ -108,24 +155,40 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, - FX_BOOL bGroupKnockout) { + FX_BOOL bGroupKnockout) + : m_pRecorder(nullptr) { m_pAggDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); SkBitmap skBitmap; - const CFX_DIBitmap* bitmap = m_pAggDriver->m_pBitmap; + const CFX_DIBitmap* bitmap = m_pAggDriver->GetBitmap(); SkImageInfo imageInfo = SkImageInfo::Make(bitmap->GetWidth(), bitmap->GetHeight(), kN32_SkColorType, kOpaque_SkAlphaType); skBitmap.installPixels(imageInfo, bitmap->GetBuffer(), bitmap->GetPitch(), nullptr, /* to do : set color table */ nullptr, nullptr); - m_canvas = new SkCanvas(skBitmap); + m_pCanvas = new SkCanvas(skBitmap); + m_ditherBits = dither_bits; +} + +CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y) + : m_pRecorder(new SkPictureRecorder) { + m_pAggDriver = nullptr; + m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y)); + m_pCanvas = m_pRecorder->getRecordingCanvas(); + m_ditherBits = 0; +} + +CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder) + : m_pRecorder(recorder) { + m_pAggDriver = nullptr; + m_pCanvas = m_pRecorder->getRecordingCanvas(); + m_ditherBits = 0; } CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { -#if 0 // TODO(caryclark) : mismatch on allocator ? - delete m_canvas; -#endif + if (!m_pRecorder) + delete m_pCanvas; delete m_pAggDriver; } @@ -138,66 +201,97 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, FX_DWORD color, int alpha_flag, void* pIccTransform) { - return m_pAggDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, - pObject2Device, font_size, color, - alpha_flag, pIccTransform); + SkAutoTUnref typeface(SkTypeface::CreateFromStream( + new SkMemoryStream(pFont->GetFontData(), pFont->GetSize()))); + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(color); + paint.setTypeface(typeface); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + paint.setTextSize(font_size); + m_pCanvas->save(); + SkMatrix skMatrix; + const CFX_Matrix& m = *pObject2Device; + // note that PDF's y-axis goes up; Skia's y-axis goes down + skMatrix.setAll(m.a, m.b, m.e, -m.c, -m.d, m.f, 0, 0, 1); + m_pCanvas->concat(skMatrix); + for (int index = 0; index < nChars; ++index) { + const FXTEXT_CHARPOS& cp = pCharPos[index]; + uint16_t glyph = (uint16_t)cp.m_GlyphIndex; + m_pCanvas->drawText(&glyph, 2, cp.m_OriginX, cp.m_OriginY, paint); + } + m_pCanvas->restore(); + return TRUE; } int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) { - return m_pAggDriver->GetDeviceCaps(caps_id); + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return FXDC_DISPLAY; + case FXDC_PIXEL_WIDTH: + return m_pCanvas->imageInfo().width(); + case FXDC_PIXEL_HEIGHT: + return m_pCanvas->imageInfo().height(); + case FXDC_BITS_PIXEL: + return 32; + case FXDC_HORZ_SIZE: + case FXDC_VERT_SIZE: + return 0; + case FXDC_RENDER_CAPS: + return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | + FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT; + case FXDC_DITHER_BITS: + return m_ditherBits; + } + return 0; } void CFX_SkiaDeviceDriver::SaveState() { - m_canvas->save(); - m_pAggDriver->SaveState(); + m_pCanvas->save(); + if (m_pAggDriver) + m_pAggDriver->SaveState(); } void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { - m_pAggDriver->RestoreState(bKeepSaved); - m_canvas->restore(); + if (m_pAggDriver) + m_pAggDriver->RestoreState(bKeepSaved); + m_pCanvas->restore(); + if (bKeepSaved) + m_pCanvas->save(); } void CFX_SkiaDeviceDriver::SetClipMask( agg::rasterizer_scanline_aa& rasterizer) { - m_pAggDriver->SetClipMask(rasterizer); + if (m_pAggDriver) + m_pAggDriver->SetClipMask(rasterizer); } FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( const CFX_PathData* pPathData, // path info - const CFX_Matrix* pObject2Device, // optional transformation + const CFX_Matrix* pObject2Device, // flips object's y-axis int fill_mode // fill mode, WINDING or ALTERNATE ) { - if (!m_pAggDriver->m_pClipRgn) { - m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( - GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { CFX_FloatRect rectf; if (pPathData->IsRect(pObject2Device, &rectf)) { rectf.Intersect( CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - FX_RECT rect = rectf.GetOutterRect(); - m_pAggDriver->m_pClipRgn->IntersectRect(rect); + // note that PDF's y-axis goes up; Skia's y-axis goes down + SkRect skClipRect = + SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top); + DebugDrawSkiaClipRect(m_pCanvas, skClipRect); + m_pCanvas->clipRect(skClipRect); return TRUE; } } - SkPath clip = BuildPath(pPathData, pObject2Device); - clip.setFillType((fill_mode & 3) == FXFILL_WINDING - ? SkPath::kWinding_FillType - : SkPath::kEvenOdd_FillType); - const CFX_Matrix& m = *pObject2Device; -#if 0 - // TODO(caryclark) : don't clip quite yet - // need to understand how to save/restore to balance the clip - printf("m:(%g,%g,%g) (%g,%g,%g)\n", m.a, m.b, m.c, m.d, m.e, m.f); - clip.dump(); - SkMatrix skMatrix; - skMatrix.setAll(m.a, m.b, m.c, m.d, m.e, m.f, 0, 0, 1); - m_canvas->setMatrix(skMatrix); - m_canvas->clipPath(clip, SkRegion::kReplace_Op); -#endif + SkPath skClipPath = BuildPath(pPathData, pObject2Device); + skClipPath.setFillType((fill_mode & 3) == FXFILL_WINDING + ? SkPath::kWinding_FillType + : SkPath::kEvenOdd_FillType); + DebugShowSkiaPath(skClipPath); + DebugDrawSkiaClipPath(m_pCanvas, skClipPath); + m_pCanvas->clipPath(skClipPath); return TRUE; } @@ -207,11 +301,6 @@ FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( const CFX_Matrix* pObject2Device, // optional transformation const CFX_GraphStateData* pGraphState // graphic state, for pen attributes ) { - if (!m_pAggDriver->m_pClipRgn) { - m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( - GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - // build path data SkPath skPath = BuildPath(pPathData, NULL); skPath.setFillType(SkPath::kWinding_FillType); @@ -220,15 +309,8 @@ FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( PaintStroke(&spaint, pGraphState); SkPath dst_path; spaint.getFillPath(skPath, &dst_path); -#if 01 - SkMatrix skMatrix; - const CFX_Matrix& m = *pObject2Device; - skMatrix.setAll(m.a, m.b, m.c, m.d, m.e, m.f, 0, 0, 1); - m_canvas->setMatrix(skMatrix); - // TODO(caryclark) : don't clip quite yet - // need to understand how to save/restore so that clip is later undone - m_canvas->clipPath(dst_path, SkRegion::kReplace_Op); -#endif + DebugDrawSkiaClipPath(m_pCanvas, dst_path); + m_pCanvas->clipPath(dst_path); return TRUE; } @@ -239,8 +321,10 @@ FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer( FX_BOOL bGroupKnockout, int alpha_flag, void* pIccTransform) { - return m_pAggDriver->RenderRasterizer( - rasterizer, color, bFullCover, bGroupKnockout, alpha_flag, pIccTransform); + return m_pAggDriver && + m_pAggDriver->RenderRasterizer(rasterizer, color, bFullCover, + bGroupKnockout, alpha_flag, + pIccTransform); } FX_BOOL CFX_SkiaDeviceDriver::DrawPath( @@ -253,14 +337,12 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath( int alpha_flag, void* pIccTransform, int blend_type) { - if (!GetBuffer()) - return TRUE; SkIRect rect; rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); SkPath skPath = BuildPath(pPathData, pObject2Device); SkPaint spaint; - spaint.setAntiAlias(TRUE); + spaint.setAntiAlias(true); if ((fill_mode & 3) && fill_color) { skPath.setFillType((fill_mode & 3) == FXFILL_WINDING ? SkPath::kWinding_FillType @@ -268,7 +350,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath( spaint.setStyle(SkPaint::kFill_Style); spaint.setColor(fill_color); - m_canvas->drawPath(skPath, spaint); + m_pCanvas->drawPath(skPath, spaint); } int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) @@ -277,7 +359,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath( if (pGraphState && stroke_alpha) { spaint.setColor(stroke_color); PaintStroke(&spaint, pGraphState); - m_canvas->drawPath(skPath, spaint); + m_pCanvas->drawPath(skPath, spaint); } return TRUE; @@ -288,7 +370,8 @@ FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, FX_DWORD color, int alpha_flag, void* pIccTransform) { - return m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); + return m_pAggDriver && + m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); } FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, @@ -300,14 +383,20 @@ FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, spaint.setAntiAlias(true); spaint.setColor(fill_color); - m_canvas->drawRect( + m_pCanvas->drawRect( SkRect::MakeLTRB(pRect->left, pRect->top, pRect->right, pRect->bottom), spaint); return TRUE; } FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) { - return m_pAggDriver->GetClipBox(pRect); + // TODO(caryclark) call m_canvas->getClipDeviceBounds() instead + pRect->left = 0; + pRect->top = 0; + const SkImageInfo& canvasSize = m_pCanvas->imageInfo(); + pRect->right = canvasSize.width(); + pRect->bottom = canvasSize.height(); + return TRUE; } FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, @@ -315,7 +404,8 @@ FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int top, void* pIccTransform, FX_BOOL bDEdge) { - return m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); + return m_pAggDriver && + m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); } FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, @@ -326,7 +416,8 @@ FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, int blend_type, int alpha_flag, void* pIccTransform) { - return m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, + return m_pAggDriver && + m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, alpha_flag, pIccTransform); } @@ -341,7 +432,8 @@ FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, int alpha_flag, void* pIccTransform, int blend_type) { - return m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, + return m_pAggDriver && + m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, dest_width, dest_height, pClipRect, flags, alpha_flag, pIccTransform, blend_type); } @@ -355,23 +447,98 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, int alpha_flag, void* pIccTransform, int blend_type) { - return m_pAggDriver->StartDIBits(pSource, bitmap_alpha, argb, pMatrix, - render_flags, handle, alpha_flag, - pIccTransform, blend_type); + SkColorType colorType; + void* buffer = pSource->GetBuffer(); + std::unique_ptr dst8Storage; + std::unique_ptr 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(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; + colorType = SkColorType::kGray_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(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; + } break; + case 32: + colorType = SkColorType::kN32_SkColorType; + break; + default: + colorType = SkColorType::kUnknown_SkColorType; + } + SkImageInfo imageInfo = + SkImageInfo::Make(width, height, colorType, kOpaque_SkAlphaType); + SkBitmap skBitmap; + skBitmap.installPixels(imageInfo, buffer, rowBytes, + nullptr, /* TODO(caryclark) : set color table */ + nullptr, nullptr); + m_pCanvas->save(); + bool landscape = !pMatrix->a; + if (landscape) + m_pCanvas->translate(m_pCanvas->imageInfo().width(), 0); + else + m_pCanvas->translate(pMatrix->e, pMatrix->f + pMatrix->d); + + SkMatrix skMatrix = SkMatrix::MakeScale(1.f / width, 1.f / height); + m_pCanvas->concat(skMatrix); + const CFX_Matrix& m = *pMatrix; + // note that PDF's y-axis goes up; Skia's y-axis goes down + if (landscape) + skMatrix.setAll(-m.a, -m.b, m.e, m.c, m.d, m.f, 0, 0, 1); + else + skMatrix.setAll(m.a, m.b, 0, -m.c, -m.d, 0, 0, 0, 1); + m_pCanvas->concat(skMatrix); + SkPaint paint; + paint.setAntiAlias(true); + paint.setFilterQuality(kLow_SkFilterQuality); + m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); + m_pCanvas->restore(); + return TRUE; } FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) { - return m_pAggDriver->ContinueDIBits(pHandle, pPause); + return m_pAggDriver && m_pAggDriver->ContinueDIBits(pHandle, pPause); } void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) { - m_pAggDriver->CancelDIBits(pHandle); + if (m_pAggDriver) + m_pAggDriver->CancelDIBits(pHandle); } CFX_SkiaDevice::CFX_SkiaDevice() { m_bOwnedBitmap = FALSE; } +SkPictureRecorder* CFX_SkiaDevice::CreateRecorder(int size_x, int size_y) { + CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); + SetDeviceDriver(skDriver); + return skDriver->GetRecorder(); +} + FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, @@ -380,9 +547,15 @@ FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, if (!pBitmap) return FALSE; SetBitmap(pBitmap); - CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver( - pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); - SetDeviceDriver(pDriver); + SetDeviceDriver(new CFX_SkiaDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, + pOriDevice, bGroupKnockout)); + return TRUE; +} + +FX_BOOL CFX_SkiaDevice::AttachRecorder(SkPictureRecorder* recorder) { + if (!recorder) + return FALSE; + SetDeviceDriver(new CFX_SkiaDeviceDriver(recorder)); return TRUE; } @@ -409,17 +582,4 @@ CFX_SkiaDevice::~CFX_SkiaDevice() { delete GetBitmap(); } -#if 0 -#include -#include - -void SkDebugf(const char format[], ...) { - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); -} - -#endif - #endif diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h index 1a36fbe85b..bb0a651263 100644 --- a/core/fxge/skia/fx_skia_device.h +++ b/core/fxge/skia/fx_skia_device.h @@ -10,6 +10,7 @@ class SkCanvas; class SkPaint; class SkPath; +class SkPictureRecorder; struct SkIRect; class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { @@ -19,6 +20,8 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout); + CFX_SkiaDeviceDriver(SkPictureRecorder* recorder); + CFX_SkiaDeviceDriver(int size_x, int size_y); ~CFX_SkiaDeviceDriver() override; /** Options */ @@ -139,10 +142,13 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { void SetClipMask(SkPath& skPath, SkPaint* spaint); virtual uint8_t* GetBuffer() const { return m_pAggDriver->GetBuffer(); } void PaintStroke(SkPaint* spaint, const CFX_GraphStateData* pGraphState); + SkPictureRecorder* GetRecorder() const { return m_pRecorder; } private: CFX_AggDeviceDriver* m_pAggDriver; - SkCanvas* m_canvas; + SkCanvas* m_pCanvas; + SkPictureRecorder* const m_pRecorder; + int m_ditherBits; }; #endif // defined(_SKIA_SUPPORT_) diff --git a/core/include/fxge/fx_ge.h b/core/include/fxge/fx_ge.h index 8a62f13d14..8e9df8c544 100644 --- a/core/include/fxge/fx_ge.h +++ b/core/include/fxge/fx_ge.h @@ -16,6 +16,7 @@ class CFX_FontCache; class CFX_FaceCache; class IFX_RenderDeviceDriver; class CCodec_ModuleMgr; +class SkPictureRecorder; class CFX_GEModule { public: @@ -427,6 +428,7 @@ class CFX_FxgeDevice : public CFX_RenderDevice { protected: bool m_bOwnedBitmap; }; + class CFX_SkiaDevice : public CFX_RenderDevice { public: CFX_SkiaDevice(); @@ -438,12 +440,16 @@ class CFX_SkiaDevice : public CFX_RenderDevice { CFX_DIBitmap* pOriDevice = NULL, FX_BOOL bGroupKnockout = FALSE); + FX_BOOL AttachRecorder(SkPictureRecorder* recorder); + FX_BOOL Create(int width, int height, FXDIB_Format format, int dither_bits = 0, CFX_DIBitmap* pOriDevice = NULL); + SkPictureRecorder* CreateRecorder(int size_x, int size_y); + protected: FX_BOOL m_bOwnedBitmap; }; -- cgit v1.2.3