From 55e026b7b6eec17b012c819c4a7d39e63094b5c4 Mon Sep 17 00:00:00 2001 From: Nicolas Pena Date: Tue, 7 Feb 2017 14:59:23 -0500 Subject: Add APIs for path construction and painting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added methods to create paths, set their colors, determine whether they will be stroked and/or filled. FPDFPage_InsertObject should be used to add a path to a page. BUG=pdfium:661 Change-Id: I8fd17b33a09c5126e517bfd1a69a893216c160e8 Reviewed-on: https://pdfium-review.googlesource.com/2534 Reviewed-by: Tom Sepez Commit-Queue: Nicolás Peña --- BUILD.gn | 1 + core/fpdfapi/page/cpdf_path.cpp | 10 ++++ core/fpdfapi/page/cpdf_path.h | 1 + fpdfsdk/fpdfeditpath.cpp | 126 ++++++++++++++++++++++++++++++++++++++++ fpdfsdk/fpdfview_c_api_test.c | 9 +++ public/fpdf_edit.h | 118 +++++++++++++++++++++++++++++++++++++ 6 files changed, 265 insertions(+) create mode 100644 fpdfsdk/fpdfeditpath.cpp diff --git a/BUILD.gn b/BUILD.gn index aa75afc555..cd3fa3f5a5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -112,6 +112,7 @@ static_library("pdfium") { "fpdfsdk/fpdfdoc.cpp", "fpdfsdk/fpdfeditimg.cpp", "fpdfsdk/fpdfeditpage.cpp", + "fpdfsdk/fpdfeditpath.cpp", "fpdfsdk/fpdfformfill.cpp", "fpdfsdk/fpdfppo.cpp", "fpdfsdk/fpdfsave.cpp", diff --git a/core/fpdfapi/page/cpdf_path.cpp b/core/fpdfapi/page/cpdf_path.cpp index 8151ae46d7..96d6b72abb 100644 --- a/core/fpdfapi/page/cpdf_path.cpp +++ b/core/fpdfapi/page/cpdf_path.cpp @@ -67,3 +67,13 @@ void CPDF_Path::AppendRect(FX_FLOAT left, FX_FLOAT top) { m_Ref.GetPrivateCopy()->AppendRect(left, bottom, right, top); } + +void CPDF_Path::AppendPoint(FX_FLOAT x, + FX_FLOAT y, + FXPT_TYPE type, + bool close) { + CFX_PathData data; + data.SetPointCount(1); + data.SetPoint(0, x, y, type, close); + Append(&data, nullptr); +} diff --git a/core/fpdfapi/page/cpdf_path.h b/core/fpdfapi/page/cpdf_path.h index 252be2673c..21a94becac 100644 --- a/core/fpdfapi/page/cpdf_path.h +++ b/core/fpdfapi/page/cpdf_path.h @@ -38,6 +38,7 @@ class CPDF_Path { void Append(const CPDF_Path& other, const CFX_Matrix* pMatrix); void Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix); void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top); + void AppendPoint(FX_FLOAT x, FX_FLOAT y, FXPT_TYPE type, bool close); // TODO(tsepez): Remove when all access thru this class. const CFX_PathData* GetObject() const { return m_Ref.GetObject(); } diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp new file mode 100644 index 0000000000..1641510ca1 --- /dev/null +++ b/fpdfsdk/fpdfeditpath.cpp @@ -0,0 +1,126 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "public/fpdf_edit.h" + +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fxcrt/fx_system.h" + +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewPath(float x, float y) { + CPDF_PathObject* pPathObj = new CPDF_PathObject; + pPathObj->m_Path.AppendPoint(x, y, FXPT_TYPE::MoveTo, false); + return pPathObj; +} + +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x, + float y, + float w, + float h) { + CPDF_PathObject* pPathObj = new CPDF_PathObject; + pPathObj->m_Path.AppendRect(x, y, x + w, y + h); + return pPathObj; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A) { + if (!path || R > 255 || G > 255 || B > 255 || A > 255) + return false; + + auto pPathObj = reinterpret_cast(path); + pPathObj->m_GeneralState.SetStrokeAlpha(A / 255.f); + FX_FLOAT rgb[3] = {R / 255.f, G / 255.f, B / 255.f}; + pPathObj->m_ColorState.SetStrokeColor( + CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetFillColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A) { + if (!path || R > 255 || G > 255 || B > 255 || A > 255) + return false; + + auto pPathObj = reinterpret_cast(path); + pPathObj->m_GeneralState.SetFillAlpha(A / 255.f); + FX_FLOAT rgb[3] = {R / 255.f, G / 255.f, B / 255.f}; + pPathObj->m_ColorState.SetFillColor( + CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast(path); + pPathObj->m_Path.AppendPoint(x, y, FXPT_TYPE::MoveTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast(path); + pPathObj->m_Path.AppendPoint(x, y, FXPT_TYPE::LineTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast(path); + pPathObj->m_Path.AppendPoint(x1, y1, FXPT_TYPE::BezierTo, false); + pPathObj->m_Path.AppendPoint(x2, y2, FXPT_TYPE::BezierTo, false); + pPathObj->m_Path.AppendPoint(x3, y3, FXPT_TYPE::BezierTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast(path); + int numPoints = pPathObj->m_Path.GetPointCount(); + if (numPoints == 0) + return false; + + FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints(); + if (pPoints[numPoints - 1].m_CloseFigure) + return true; + + pPoints[numPoints - 1].m_CloseFigure = true; + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + int fillmode, + FPDF_BOOL stroke) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast(path); + + if (fillmode == FPDF_FILLMODE_ALTERNATE) + pPathObj->m_FillType = FXFILL_ALTERNATE; + else if (fillmode == FPDF_FILLMODE_WINDING) + pPathObj->m_FillType = FXFILL_WINDING; + else + pPathObj->m_FillType = 0; + pPathObj->m_bStroke = stroke != 0; + return true; +} diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 98478f0410..8ec3a26d3a 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -85,6 +85,15 @@ int CheckPDFiumCApi() { CHK(FPDFImageObj_LoadJpegFile); CHK(FPDFImageObj_SetMatrix); CHK(FPDFImageObj_SetBitmap); + CHK(FPDFPageObj_CreateNewPath); + CHK(FPDFPageObj_CreateNewRect); + CHK(FPDFPath_SetStrokeColor); + CHK(FPDFPath_SetFillColor); + CHK(FPDFPath_MoveTo); + CHK(FPDFPath_LineTo); + CHK(FPDFPath_BezierTo); + CHK(FPDFPath_Close); + CHK(FPDFPath_SetDrawMode); // fpdf_ext.h CHK(FSDK_SetUnSpObjProcessHandler); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index 640d97ed05..d151c5c6ab 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -27,6 +27,9 @@ #define FPDF_PAGEOBJ_SHADING 4 #define FPDF_PAGEOBJ_FORM 5 +#define FPDF_FILLMODE_ALTERNATE 1 +#define FPDF_FILLMODE_WINDING 2 + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -260,6 +263,121 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages, FPDF_PAGEOBJECT image_object, FPDF_BITMAP bitmap); +// Create a new path object at an initial position. +// +// x - initial horizontal position. +// y - initial vertical position. +// +// Returns a handle to a new path object. +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewPath(float x, float y); + +// Create a closed path consisting of a rectangle. +// +// x - horizontal position for the left boundary of the rectangle. +// y - vertical position for the bottom boundary of the rectangle. +// w - width of the rectangle. +// h - height of the rectangle. +// +// Returns a handle to the new path object. +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x, + float y, + float w, + float h); + +// Set the stroke RGBA of a path. Range of values: 0 - 255. +// +// path - the handle to the path object. +// R - the red component for the path stroke color. +// G - the green component for the path stroke color. +// B - the blue component for the path stroke color. +// A - the stroke alpha for the path. +// +// Returns TRUE on success. +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A); + +// Set the fill RGBA of a path. Range of values: 0 - 255. +// +// path - the handle to the path object. +// R - the red component for the path fill color. +// G - the green component for the path fill color. +// B - the blue component for the path fill color. +// A - the fill alpha for the path. +// +// Returns TRUE on success. +DLLEXPORT FPDF_BOOL FPDFPath_SetFillColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A); + +// Move a path's current point. +// +// path - the handle to the path object. +// x - the horizontal position of the new current point. +// y - the vertical position of the new current point. +// +// Note that no line will be created between the previous current point and the +// new one. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y); + +// Add a line between the current point and a new point in the path. +// +// path - the handle to the path object. +// x - the horizontal position of the new point. +// y - the vertical position of the new point. +// +// The path's current point is changed to (x, y). +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y); + +// Add a cubic Bezier curve to the given path, starting at the current point. +// +// path - the handle to the path object. +// x1 - the horizontal position of the first Bezier control point. +// y1 - the vertical position of the first Bezier control point. +// x2 - the horizontal position of the second Bezier control point. +// y2 - the vertical position of the second Bezier control point. +// x3 - the horizontal position of the ending point of the Bezier curve. +// y3 - the vertical position of the ending point of the Bezier curve. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3); + +// Close the current subpath of a given path. +// +// path - the handle to the path object. +// +// This will add a line between the current point and the initial point of the +// subpath, thus terminating the current subpath. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path); + +// Set the drawing mode of a path. +// +// path - the handle to the path object. +// fillmode - the filling mode to be set: 0 for no fill, 1 for alternate, 2 for +// winding. +// stroke - a boolean specifying if the path should be stroked or not. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + int fillmode, + FPDF_BOOL stroke); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus -- cgit v1.2.3