diff options
Diffstat (limited to 'core/fxge')
-rw-r--r-- | core/fxge/agg/fx_agg_driver.h | 2 | ||||
-rw-r--r-- | core/fxge/apple/apple_int.h | 2 | ||||
-rw-r--r-- | core/fxge/ge/fx_ge_device.cpp | 31 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.cpp | 163 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.h | 5 | ||||
-rw-r--r-- | core/fxge/win32/win32_int.h | 4 |
6 files changed, 183 insertions, 24 deletions
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; |