summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_func.cpp58
-rw-r--r--core/fpdfapi/fpdf_page/pageint.h56
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp5
-rw-r--r--core/fxge/agg/fx_agg_driver.h2
-rw-r--r--core/fxge/apple/apple_int.h2
-rw-r--r--core/fxge/ge/fx_ge_device.cpp31
-rw-r--r--core/fxge/skia/fx_skia_device.cpp163
-rw-r--r--core/fxge/skia/fx_skia_device.h5
-rw-r--r--core/fxge/win32/win32_int.h4
-rw-r--r--core/include/fxge/fx_ge.h25
10 files changed, 276 insertions, 75 deletions
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
index 96aad6d87f..08eafad6ac 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -520,11 +520,12 @@ class CPDF_SampledFunc : public CPDF_Function {
CPDF_StreamAcc* m_pSampleStream;
};
-CPDF_SampledFunc::CPDF_SampledFunc() {
+CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {
m_pSampleStream = NULL;
m_pEncodeInfo = NULL;
m_pDecodeInfo = NULL;
}
+
CPDF_SampledFunc::~CPDF_SampledFunc() {
delete m_pSampleStream;
FX_Free(m_pEncodeInfo);
@@ -665,6 +666,7 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
class CPDF_PSFunc : public CPDF_Function {
public:
// CPDF_Function
+ CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
@@ -694,25 +696,14 @@ FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
return TRUE;
}
-class CPDF_ExpIntFunc : public CPDF_Function {
- public:
- CPDF_ExpIntFunc();
- ~CPDF_ExpIntFunc() override;
-
- // CPDF_Function
- FX_BOOL v_Init(CPDF_Object* pObj) override;
- FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
-
- FX_FLOAT m_Exponent;
- FX_FLOAT* m_pBeginValues;
- FX_FLOAT* m_pEndValues;
- int m_nOrigOutputs;
-};
+} // namespace
-CPDF_ExpIntFunc::CPDF_ExpIntFunc() {
+CPDF_ExpIntFunc::CPDF_ExpIntFunc()
+ : CPDF_Function(Type::kType2ExpotentialInterpolation) {
m_pBeginValues = NULL;
m_pEndValues = NULL;
}
+
CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
FX_Free(m_pBeginValues);
FX_Free(m_pEndValues);
@@ -755,26 +746,11 @@ FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
return TRUE;
}
-class CPDF_StitchFunc : public CPDF_Function {
- public:
- CPDF_StitchFunc();
- ~CPDF_StitchFunc() override;
-
- // CPDF_Function
- FX_BOOL v_Init(CPDF_Object* pObj) override;
- FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
-
- std::vector<CPDF_Function*> m_pSubFunctions;
- FX_FLOAT* m_pBounds;
- FX_FLOAT* m_pEncode;
-
- static const int kRequiredNumInputs = 1;
-};
-
-CPDF_StitchFunc::CPDF_StitchFunc() {
+CPDF_StitchFunc::CPDF_StitchFunc() : CPDF_Function(Type::kType3Stitching) {
m_pBounds = NULL;
m_pEncode = NULL;
}
+
CPDF_StitchFunc::~CPDF_StitchFunc() {
for (auto& sub : m_pSubFunctions) {
delete sub;
@@ -859,13 +835,10 @@ FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const {
return TRUE;
}
-} // namespace
-
CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) {
if (!pFuncObj) {
return NULL;
}
- CPDF_Function* pFunc = NULL;
int type;
if (CPDF_Stream* pStream = pFuncObj->AsStream()) {
type = pStream->GetDict()->GetIntegerBy("FunctionType");
@@ -874,14 +847,15 @@ CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) {
} else {
return NULL;
}
+ CPDF_Function* pFunc = NULL;
if (type == 0) {
- pFunc = new CPDF_SampledFunc;
+ pFunc = new CPDF_SampledFunc();
} else if (type == 2) {
- pFunc = new CPDF_ExpIntFunc;
+ pFunc = new CPDF_ExpIntFunc();
} else if (type == 3) {
- pFunc = new CPDF_StitchFunc;
+ pFunc = new CPDF_StitchFunc();
} else if (type == 4) {
- pFunc = new CPDF_PSFunc;
+ pFunc = new CPDF_PSFunc();
} else {
return NULL;
}
@@ -891,10 +865,12 @@ CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) {
}
return pFunc;
}
-CPDF_Function::CPDF_Function() {
+
+CPDF_Function::CPDF_Function(Type type) : m_Type(type) {
m_pDomains = NULL;
m_pRanges = NULL;
}
+
CPDF_Function::~CPDF_Function() {
FX_Free(m_pDomains);
FX_Free(m_pRanges);
diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h
index d254477dc3..297b1e2e77 100644
--- a/core/fpdfapi/fpdf_page/pageint.h
+++ b/core/fpdfapi/fpdf_page/pageint.h
@@ -377,24 +377,68 @@ class CPDF_DocPageData {
class CPDF_Function {
public:
+ enum class Type {
+ kType0Sampled,
+ kType2ExpotentialInterpolation,
+ kType3Stitching,
+ kType4PostScript,
+ };
+
static CPDF_Function* Load(CPDF_Object* pFuncObj);
virtual ~CPDF_Function();
FX_BOOL Call(FX_FLOAT* inputs,
int ninputs,
FX_FLOAT* results,
int& nresults) const;
- int CountInputs() { return m_nInputs; }
- int CountOutputs() { return m_nOutputs; }
+ int CountInputs() const { return m_nInputs; }
+ int CountOutputs() const { return m_nOutputs; }
+ FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; }
+ Type GetType() const { return m_Type; }
protected:
- CPDF_Function();
- int m_nInputs, m_nOutputs;
- FX_FLOAT* m_pDomains;
- FX_FLOAT* m_pRanges;
+ CPDF_Function(Type type);
FX_BOOL Init(CPDF_Object* pObj);
virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0;
virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0;
+
+ int m_nInputs;
+ int m_nOutputs;
+ FX_FLOAT* m_pDomains;
+ FX_FLOAT* m_pRanges;
+ Type m_Type;
+};
+
+class CPDF_ExpIntFunc : public CPDF_Function {
+ public:
+ CPDF_ExpIntFunc();
+ ~CPDF_ExpIntFunc() override;
+
+ // CPDF_Function
+ FX_BOOL v_Init(CPDF_Object* pObj) override;
+ FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
+
+ int m_nOrigOutputs;
+ FX_FLOAT m_Exponent;
+ FX_FLOAT* m_pBeginValues;
+ FX_FLOAT* m_pEndValues;
+};
+
+class CPDF_StitchFunc : public CPDF_Function {
+ public:
+ CPDF_StitchFunc();
+ ~CPDF_StitchFunc() override;
+
+ // CPDF_Function
+ FX_BOOL v_Init(CPDF_Object* pObj) override;
+ FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
+
+ std::vector<CPDF_Function*> m_pSubFunctions;
+ FX_FLOAT* m_pBounds;
+ FX_FLOAT* m_pEncode;
+
+ static const int kRequiredNumInputs = 1;
};
+
class CPDF_IccProfile {
public:
CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize);
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
index d4dd8ec211..94f38c5186 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
@@ -859,6 +859,11 @@ void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
rect.Transform(pMatrix);
clip_rect.Intersect(rect.GetOutterRect());
}
+ if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING &&
+ m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, alpha,
+ bAlphaMode)) {
+ return;
+ }
CPDF_DeviceBuffer buffer;
buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
CFX_Matrix FinalMatrix = *pMatrix;
diff --git a/core/fxge/agg/fx_agg_driver.h b/core/fxge/agg/fx_agg_driver.h
index ea4c36059b..2b6b6683f6 100644
--- a/core/fxge/agg/fx_agg_driver.h
+++ b/core/fxge/agg/fx_agg_driver.h
@@ -122,7 +122,7 @@ class CFX_AggDeviceDriver : public IFX_RenderDeviceDriver {
FX_DWORD color,
int alpha_flag,
void* pIccTransform) override;
- int GetDriverType() override { return 1; }
+ int GetDriverType() const override { return 1; }
FX_BOOL RenderRasterizer(agg::rasterizer_scanline_aa& rasterizer,
FX_DWORD color,
diff --git a/core/fxge/apple/apple_int.h b/core/fxge/apple/apple_int.h
index 037eca767f..c4f95d6d26 100644
--- a/core/fxge/apple/apple_int.h
+++ b/core/fxge/apple/apple_int.h
@@ -173,7 +173,7 @@ class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver {
FX_DWORD color,
int alpha_flag = 0,
void* pIccTransform = NULL) override;
- void* GetPlatformSurface() override { return NULL; }
+ void* GetPlatformSurface() const override { return NULL; }
void ClearDriver() override;
protected:
diff --git a/core/fxge/ge/fx_ge_device.cpp b/core/fxge/ge/fx_ge_device.cpp
index b8ddfec841..eefac5c033 100644
--- a/core/fxge/ge/fx_ge_device.cpp
+++ b/core/fxge/ge/fx_ge_device.cpp
@@ -109,6 +109,7 @@ void CFX_RenderDevice::UpdateClipBox() {
m_ClipBox.right = m_Width;
m_ClipBox.bottom = m_Height;
}
+
FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData,
const CFX_Matrix* pObject2Device,
const CFX_GraphStateData* pGraphState,
@@ -224,6 +225,31 @@ FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData,
}
if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff &&
(fill_mode & FX_FILL_STROKE)) {
+ if (m_RenderCaps & FXRC_FILLSTROKE_PATH) {
+ return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
+ fill_color, stroke_color, fill_mode,
+ alpha_flag, pIccTransform, blend_type);
+ }
+ return DrawFillStrokePath(pPathData, pObject2Device, pGraphState,
+ fill_color, stroke_color, fill_mode, alpha_flag,
+ pIccTransform, blend_type);
+ }
+ return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
+ fill_color, stroke_color, fill_mode,
+ alpha_flag, pIccTransform, blend_type);
+}
+
+// This can be removed once PDFium entirely relies on Skia
+FX_BOOL CFX_RenderDevice::DrawFillStrokePath(
+ const CFX_PathData* pPathData,
+ const CFX_Matrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type) {
if (!(m_RenderCaps & FXRC_GET_BITS)) {
return FALSE;
}
@@ -272,11 +298,8 @@ FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData,
FXSYS_round(rect.Height() * fScaleY));
return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left,
rect.top, FXDIB_BLEND_NORMAL);
- }
- return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
- fill_color, stroke_color, fill_mode,
- alpha_flag, pIccTransform, blend_type);
}
+
FX_BOOL CFX_RenderDevice::SetPixel(int x,
int y,
FX_DWORD color,
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index f0c7d4e442..ed6ff82fd0 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -7,6 +7,10 @@
#if defined(_SKIA_SUPPORT_)
#include "core/include/fxcodec/fx_codec.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fxge/agg/fx_agg_driver.h"
#include "core/fxge/skia/fx_skia_device.h"
@@ -18,6 +22,8 @@
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "third_party/skia/include/pathops/SkPathOps.h"
namespace {
@@ -150,6 +156,53 @@ SkXfermode::Mode GetSkiaBlendMode(int blend_type) {
}
}
+bool AddColors(const CPDF_Function* pFunc, SkTDArray<SkColor>* skColors) {
+ if (pFunc->CountInputs() != 1)
+ return false;
+ ASSERT(CPDF_Function::Type::kType2ExpotentialInterpolation ==
+ pFunc->GetType());
+ const CPDF_ExpIntFunc* expIntFunc =
+ static_cast<const CPDF_ExpIntFunc*>(pFunc);
+ if (expIntFunc->m_Exponent != 1)
+ return false;
+ if (expIntFunc->m_nOrigOutputs != 3)
+ return false;
+ skColors->push(SkColorSetARGB(
+ 0xFF, SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[0]),
+ SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[1]),
+ SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[2])));
+ skColors->push(
+ SkColorSetARGB(0xFF, SkUnitScalarClampToByte(expIntFunc->m_pEndValues[0]),
+ SkUnitScalarClampToByte(expIntFunc->m_pEndValues[1]),
+ SkUnitScalarClampToByte(expIntFunc->m_pEndValues[2])));
+ return true;
+}
+
+bool AddStitching(const CPDF_Function* pFunc,
+ SkTDArray<SkColor>* skColors,
+ SkTDArray<SkScalar>* skPos) {
+ int inputs = pFunc->CountInputs();
+ ASSERT(CPDF_Function::Type::kType3Stitching == pFunc->GetType());
+ const CPDF_StitchFunc* stitchFunc =
+ static_cast<const CPDF_StitchFunc*>(pFunc);
+ FX_FLOAT boundsStart = stitchFunc->GetDomain(0);
+
+ for (int i = 0; i < inputs; ++i) {
+ const CPDF_Function* pSubFunc = stitchFunc->m_pSubFunctions[i];
+ if (pSubFunc->GetType() !=
+ CPDF_Function::Type::kType2ExpotentialInterpolation)
+ return false;
+ if (!AddColors(pSubFunc, skColors))
+ return false;
+ FX_FLOAT boundsEnd =
+ i < inputs - 1 ? stitchFunc->m_pBounds[i] : stitchFunc->GetDomain(1);
+ skPos->push(boundsStart);
+ skPos->push(boundsEnd);
+ boundsStart = boundsEnd;
+ }
+ return true;
+}
+
} // namespace
// convert a stroking path to scanlines
@@ -303,7 +356,8 @@ int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) {
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;
+ FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT |
+ FXRC_FILLSTROKE_PATH | FXRC_SHADING;
case FXDC_DITHER_BITS:
return m_ditherBits;
}
@@ -385,32 +439,44 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath(
SkIRect rect;
rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH),
GetDeviceCaps(FXDC_PIXEL_HEIGHT));
+ SkMatrix skMatrix = ToSkMatrix(*pObject2Device);
+ SkPaint skPaint;
+ skPaint.setAntiAlias(true);
+ int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag)
+ ? FXGETFLAG_ALPHA_STROKE(alpha_flag)
+ : FXARGB_A(stroke_color);
+ if (pGraphState && stroke_alpha)
+ PaintStroke(&skPaint, pGraphState, skMatrix);
SkPath skPath = BuildPath(pPathData);
- SkPaint spaint;
- spaint.setAntiAlias(true);
- spaint.setXfermodeMode(GetSkiaBlendMode(blend_type));
m_pCanvas->save();
- SkMatrix skMatrix = ToSkMatrix(*pObject2Device);
m_pCanvas->concat(skMatrix);
if ((fill_mode & 3) && fill_color) {
skPath.setFillType((fill_mode & 3) == FXFILL_WINDING
? SkPath::kWinding_FillType
: SkPath::kEvenOdd_FillType);
-
- spaint.setStyle(SkPaint::kFill_Style);
- spaint.setColor(fill_color);
- m_pCanvas->drawPath(skPath, spaint);
+ SkPath strokePath;
+ const SkPath* fillPath = &skPath;
+ if (pGraphState && stroke_alpha) {
+ SkAlpha fillA = SkColorGetA(fill_color);
+ SkAlpha strokeA = SkColorGetA(stroke_color);
+ if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) {
+ skPaint.getFillPath(skPath, &strokePath);
+ if (Op(skPath, strokePath, SkPathOp::kDifference_SkPathOp,
+ &strokePath)) {
+ fillPath = &strokePath;
+ }
+ }
+ }
+ skPaint.setStyle(SkPaint::kFill_Style);
+ skPaint.setColor(fill_color);
+ m_pCanvas->drawPath(*fillPath, skPaint);
}
- int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag)
- ? FXGETFLAG_ALPHA_STROKE(alpha_flag)
- : FXARGB_A(stroke_color);
-
if (pGraphState && stroke_alpha) {
- spaint.setColor(stroke_color);
- PaintStroke(&spaint, pGraphState, skMatrix);
DebugShowSkiaPath(skPath);
DebugShowCanvasMatrix(m_pCanvas);
- m_pCanvas->drawPath(skPath, spaint);
+ skPaint.setStyle(SkPaint::kStroke_Style);
+ skPaint.setColor(stroke_color);
+ m_pCanvas->drawPath(skPath, skPaint);
}
m_pCanvas->restore();
return TRUE;
@@ -432,6 +498,71 @@ FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect,
return TRUE;
}
+FX_BOOL CFX_SkiaDeviceDriver::DrawShading(CPDF_ShadingPattern* pPattern,
+ CFX_Matrix* pMatrix,
+ int alpha,
+ FX_BOOL bAlphaMode) {
+ CPDF_Function** pFuncs = pPattern->m_pFunctions;
+ int nFuncs = pPattern->m_nFuncs;
+ if (nFuncs != 1) // TODO(caryclark) remove this restriction
+ return false;
+ CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict();
+ CPDF_Array* pCoords = pDict->GetArrayBy("Coords");
+ if (!pCoords)
+ return true;
+ FX_FLOAT start_x = pCoords->GetNumberAt(0);
+ FX_FLOAT start_y = pCoords->GetNumberAt(1);
+ FX_FLOAT end_x = pCoords->GetNumberAt(2);
+ FX_FLOAT end_y = pCoords->GetNumberAt(3);
+ FX_FLOAT t_min = 0;
+ FX_FLOAT t_max = 1;
+ CPDF_Array* pArray = pDict->GetArrayBy("Domain");
+ if (pArray) {
+ t_min = pArray->GetNumberAt(0);
+ t_max = pArray->GetNumberAt(1);
+ }
+ FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
+ pArray = pDict->GetArrayBy("Extend");
+ if (pArray) {
+ bStartExtend = pArray->GetIntegerAt(0);
+ bEndExtend = pArray->GetIntegerAt(1);
+ }
+ SkTDArray<SkColor> skColors;
+ SkTDArray<SkScalar> skPos;
+ for (int j = 0; j < nFuncs; j++) {
+ const CPDF_Function* pFunc = pFuncs[j];
+ if (!pFunc)
+ continue;
+ switch (pFunc->GetType()) {
+ case CPDF_Function::Type::kType2ExpotentialInterpolation:
+ if (!AddColors(pFunc, &skColors))
+ return false;
+ skPos.push(0);
+ skPos.push(1);
+ break;
+ case CPDF_Function::Type::kType3Stitching:
+ if (!AddStitching(pFunc, &skColors, &skPos))
+ return false;
+ break;
+ default:
+ return false;
+ }
+ }
+ SkMatrix skMatrix = ToSkMatrix(*pMatrix);
+ SkPoint pts[] = {{start_x, start_y}, {end_x, end_y}};
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setShader(SkGradientShader::MakeLinear(pts, skColors.begin(),
+ skPos.begin(), skColors.count(),
+ SkShader::kClamp_TileMode));
+ paint.setAlpha(alpha);
+ m_pCanvas->save();
+ m_pCanvas->concat(skMatrix);
+ m_pCanvas->drawRect(SkRect::MakeWH(1, 1), paint);
+ m_pCanvas->restore();
+ return true;
+}
+
FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) {
// TODO(caryclark) call m_canvas->getClipDeviceBounds() instead
pRect->left = 0;
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index 012e370717..8ce7c6c61f 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -128,6 +128,11 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver {
int alpha_flag = 0,
void* pIccTransform = NULL) override;
+ FX_BOOL DrawShading(CPDF_ShadingPattern* pPattern,
+ CFX_Matrix* pMatrix,
+ int alpha,
+ FX_BOOL bAlphaMode) override;
+
virtual uint8_t* GetBuffer() const { return m_pAggDriver->GetBuffer(); }
void PaintStroke(SkPaint* spaint,
const CFX_GraphStateData* pGraphState,
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index 923aa84f33..d903d3abf5 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -145,7 +145,7 @@ class CGdiDeviceDriver : public IFX_RenderDeviceDriver {
void* pIccTransform,
int blend_type) override;
FX_BOOL GetClipBox(FX_RECT* pRect) override;
- void* GetPlatformSurface() override { return (void*)m_hDC; }
+ void* GetPlatformSurface() const override { return (void*)m_hDC; }
virtual void* GetClipRgn();
virtual FX_BOOL SetClipRgn(void* pRgn);
@@ -352,7 +352,7 @@ class CPSPrinterDriver : public IFX_RenderDeviceDriver {
FX_DWORD color,
int alpha_flag,
void* pIccTransform) override;
- void* GetPlatformSurface() override { return (void*)m_hDC; }
+ void* GetPlatformSurface() const override { return (void*)m_hDC; }
HDC m_hDC;
FX_BOOL m_bCmykOutput;
diff --git a/core/include/fxge/fx_ge.h b/core/include/fxge/fx_ge.h
index 8e9df8c544..d824d08228 100644
--- a/core/include/fxge/fx_ge.h
+++ b/core/include/fxge/fx_ge.h
@@ -14,6 +14,7 @@ class CFX_Font;
class CFX_FontMgr;
class CFX_FontCache;
class CFX_FaceCache;
+class CPDF_ShadingPattern;
class IFX_RenderDeviceDriver;
class CCodec_ModuleMgr;
class SkPictureRecorder;
@@ -215,6 +216,8 @@ class CFX_GraphStateData {
#define FXRC_BITMASK_OUTPUT 0x400
#define FXRC_BYTEMASK_OUTPUT 0x800
#define FXRENDER_IMAGE_LOSSY 0x1000
+#define FXRC_FILLSTROKE_PATH 0x2000
+#define FXRC_SHADING 0x4000
#define FXFILL_ALTERNATE 1
#define FXFILL_WINDING 2
#define FXFILL_FULLCOVER 4
@@ -397,6 +400,15 @@ class CFX_RenderDevice {
private:
void InitDeviceInfo();
void UpdateClipBox();
+ FX_BOOL DrawFillStrokePath(const CFX_PathData* pPathData,
+ const CFX_Matrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type);
CFX_DIBitmap* m_pBitmap;
int m_Width;
@@ -587,11 +599,16 @@ class IFX_RenderDeviceDriver {
return FALSE;
}
- virtual void* GetPlatformSurface() { return NULL; }
-
- virtual int GetDriverType() { return 0; }
-
+ virtual void* GetPlatformSurface() const { return NULL; }
+ virtual int GetDriverType() const { return 0; }
virtual void ClearDriver() {}
+
+ virtual FX_BOOL DrawShading(CPDF_ShadingPattern* pPattern,
+ CFX_Matrix* pMatrix,
+ int alpha,
+ FX_BOOL bAlphaMode) {
+ return false;
+ }
};
class IFX_PSOutput {