Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Unified Diff: core/src/fxge/skia/fx_skia_device.cpp

Issue 1776313002: Add bitmaps and skp output to Skia port (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: wip; add skp output to test framework Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: core/src/fxge/skia/fx_skia_device.cpp
diff --git a/core/src/fxge/skia/fx_skia_device.cpp b/core/src/fxge/skia/fx_skia_device.cpp
index 9938298c12b70b2a03ccbd70ffaa1b98cb36b1bf..a1f914658aa1edd8b96815f263ac59e152d98302 100644
--- a/core/src/fxge/skia/fx_skia_device.cpp
+++ b/core/src/fxge/skia/fx_skia_device.cpp
@@ -10,10 +10,57 @@
#include "core/src/fxge/agg/fx_agg_driver.h"
#include "core/src/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) {
@@ -121,8 +168,19 @@ CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap,
nullptr, /* to do : set color table */
nullptr, nullptr);
m_canvas = new SkCanvas(skBitmap);
+ m_ditherBits = dither_bits;
+ m_recorder = nullptr;
}
+CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y, void* recorder) {
+ m_pAggDriver = nullptr;
+ m_recorder = recorder ? (SkPictureRecorder*) recorder : new SkPictureRecorder;
+ m_recorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y));
+ m_canvas = m_recorder->getRecordingCanvas();
+ m_ditherBits = 0;
+}
+
+
CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() {
#if 0 // TODO(caryclark) : mismatch on allocator ?
delete m_canvas;
@@ -139,40 +197,80 @@ 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<SkTypeface> 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_canvas->save();
+ SkMatrix skMatrix;
+ const CFX_Matrix& m = *pObject2Device;
+ // note that PDF's y-axis goes up; Skia's y-axis goes down
dsinclair 2016/03/10 14:38:54 In the long run, should we add a toSkia on the CFX
caryclark 2016/03/10 20:44:55 It's not so clear to me what the correct solution
dsinclair 2016/03/10 20:47:12 Figuring it out later is fine, just something we s
+ skMatrix.setAll(m.a, m.b, m.e, -m.c, -m.d, m.f, 0, 0, 1);
+ m_canvas->concat(skMatrix);
+ for (int index = 0; index < nChars; ++index) {
+ const FXTEXT_CHARPOS& cp = pCharPos[index];
+ uint16_t glyph = (uint16_t)cp.m_GlyphIndex;
+ m_canvas->drawText(&glyph, 2, cp.m_OriginX, cp.m_OriginY, paint);
+ }
+ m_canvas->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_canvas->getBaseLayerSize().fWidth;
+ case FXDC_PIXEL_HEIGHT:
+ return m_canvas->getBaseLayerSize().fHeight;
+ 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();
+ if (m_pAggDriver)
+ m_pAggDriver->SaveState();
}
void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) {
- m_pAggDriver->RestoreState(bKeepSaved);
+ if (m_pAggDriver)
+ m_pAggDriver->RestoreState(bKeepSaved);
m_canvas->restore();
+ if (bKeepSaved)
+ m_canvas->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) {
+ if (m_pAggDriver && !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)) {
@@ -180,25 +278,23 @@ FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill(
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);
+ if (m_pAggDriver)
+ 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_canvas, skClipRect);
+ m_canvas->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_canvas, skClipPath);
+ m_canvas->clipPath(skClipPath);
return TRUE;
}
@@ -208,7 +304,7 @@ 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) {
+ if (m_pAggDriver && !m_pAggDriver->m_pClipRgn) {
m_pAggDriver->m_pClipRgn = new CFX_ClipRgn(
GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT));
}
@@ -221,15 +317,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_canvas, dst_path);
+ m_canvas->clipPath(dst_path);
return TRUE;
}
@@ -240,7 +329,7 @@ FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer(
FX_BOOL bGroupKnockout,
int alpha_flag,
void* pIccTransform) {
- return m_pAggDriver->RenderRasterizer(
+ return m_pAggDriver && m_pAggDriver->RenderRasterizer(
rasterizer, color, bFullCover, bGroupKnockout, alpha_flag, pIccTransform);
}
@@ -254,8 +343,6 @@ 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));
@@ -289,7 +376,7 @@ 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,
@@ -298,7 +385,7 @@ FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect,
void* pIccTransform,
int blend_type) {
SkPaint spaint;
- spaint.setAntiAlias(true);
+ spaint.setAntiAlias(TRUE);
dsinclair 2016/03/10 14:38:54 If setAntiAlias takes a bool, you can leave this a
caryclark 2016/03/10 20:44:55 Done.
spaint.setColor(fill_color);
m_canvas->drawRect(
@@ -308,7 +395,12 @@ FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect,
}
FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) {
- return m_pAggDriver->GetClipBox(pRect);
+ pRect->left = 0;
dsinclair 2016/03/10 14:38:54 Does this need a todo to take the pRect into accou
caryclark 2016/03/10 20:44:55 Done.
+ pRect->top = 0;
+ const SkISize& canvasSize = m_canvas->getBaseLayerSize();
+ pRect->right = canvasSize.fWidth;
+ pRect->bottom = canvasSize.fHeight;
+ return TRUE;
}
FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap,
@@ -316,7 +408,7 @@ 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,
@@ -327,7 +419,7 @@ 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);
}
@@ -342,7 +434,7 @@ 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);
}
@@ -356,21 +448,94 @@ 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;
+ const uint8_t* buffer = pSource->GetBuffer();
+ uint8_t* dstStorage = nullptr;
dsinclair 2016/03/10 14:38:54 std::unique_ptr then we can drop the if/free at th
caryclark 2016/03/10 20:44:55 Done.
+ int width = pSource->GetWidth();
+ int height = pSource->GetHeight();
+ int rowBytes = pSource->GetPitch();
+ switch (pSource->GetBPP()) {
+ case 1: {
+ dstStorage = (uint8_t*) malloc(width * height);
+ uint8_t* dst8Pixels = dstStorage;
+ for (int y = 0; y < height; ++y) {
+ const uint8_t* srcRow = 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 = const_cast<const uint8_t*>(dstStorage);
+ rowBytes = width;
+ colorType = SkColorType::kGray_8_SkColorType;
+ } break;
+ case 24: {
+ dstStorage = (uint8_t*) malloc(width * height * sizeof(uint32_t));
+ uint32_t* dst32Pixels = (uint32_t*) dstStorage;
+ for (int y = 0; y < height; ++y) {
+ const uint8_t* srcRow = 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 = const_cast<const uint8_t*>(dstStorage);
+ 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, (void*)buffer, rowBytes,
+ nullptr, /* TODO(caryclark) : set color table */
+ nullptr, nullptr);
+ m_canvas->save();
+ bool landscape = !pMatrix->a;
+ if (landscape)
+ m_canvas->translate(m_canvas->getBaseLayerSize().fWidth, 0);
+ else
+ m_canvas->translate(pMatrix->e, pMatrix->f + pMatrix->d);
+ SkMatrix skMatrix = SkMatrix::MakeScale(1.f / width, 1.f / height);
dsinclair 2016/03/10 14:38:54 nit: we try to leave 1 blank line after un-{}'d bo
caryclark 2016/03/10 20:44:55 Done.
+ m_canvas->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_canvas->concat(skMatrix);
+ SkPaint paint;
+ paint.setAntiAlias(TRUE);
+ paint.setFilterQuality(kHigh_SkFilterQuality);
+ m_canvas->drawBitmap(skBitmap, 0, 0, &paint);
+ m_canvas->restore();
+ if (dstStorage)
+ free(dstStorage);
+ 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;
+ m_recorder = nullptr;
+}
+
+CFX_SkiaDevice::CFX_SkiaDevice(int size_x, int size_y, void* recorder) {
+ CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver(size_x, size_y, recorder);
+ SetDeviceDriver(pDriver);
+ m_bOwnedBitmap = FALSE;
+ m_recorder = pDriver->GetRecorder();
}
FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap,

Powered by Google App Engine
This is Rietveld 408576698