blob: 54937ef91a228f77a960869e1cd88b342ca63bfd [file] [log] [blame]
Nicolas Pena55e026b2017-02-07 14:59:23 -05001// Copyright 2017 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "public/fpdf_edit.h"
6
7#include "core/fpdfapi/page/cpdf_path.h"
8#include "core/fpdfapi/page/cpdf_pathobject.h"
9#include "core/fxcrt/fx_system.h"
Tom Sepezfe91c6c2017-05-16 15:33:20 -070010#include "third_party/base/ptr_util.h"
Nicolas Pena55e026b2017-02-07 14:59:23 -050011
12DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewPath(float x, float y) {
Tom Sepezfe91c6c2017-05-16 15:33:20 -070013 auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
dan sinclairb147e072017-02-22 19:56:15 -050014 pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::MoveTo, false);
Nicolas Pena0fc185e2017-02-08 12:13:20 -050015 pPathObj->DefaultStates();
Tom Sepezfe91c6c2017-05-16 15:33:20 -070016 return pPathObj.release(); // Caller takes ownership.
Nicolas Pena55e026b2017-02-07 14:59:23 -050017}
18
19DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x,
20 float y,
21 float w,
22 float h) {
Tom Sepezfe91c6c2017-05-16 15:33:20 -070023 auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
Nicolas Pena55e026b2017-02-07 14:59:23 -050024 pPathObj->m_Path.AppendRect(x, y, x + w, y + h);
Nicolas Pena0fc185e2017-02-08 12:13:20 -050025 pPathObj->DefaultStates();
Tom Sepezfe91c6c2017-05-16 15:33:20 -070026 return pPathObj.release(); // Caller takes ownership.
Nicolas Pena55e026b2017-02-07 14:59:23 -050027}
28
29DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path,
30 unsigned int R,
31 unsigned int G,
32 unsigned int B,
33 unsigned int A) {
34 if (!path || R > 255 || G > 255 || B > 255 || A > 255)
35 return false;
36
Tom Sepezfe91c6c2017-05-16 15:33:20 -070037 float rgb[3] = {R / 255.f, G / 255.f, B / 255.f};
Nicolas Pena46abb662017-05-17 17:23:22 -040038 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Nicolas Pena55e026b2017-02-07 14:59:23 -050039 pPathObj->m_GeneralState.SetStrokeAlpha(A / 255.f);
Nicolas Pena55e026b2017-02-07 14:59:23 -050040 pPathObj->m_ColorState.SetStrokeColor(
41 CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
42 return true;
43}
44
Nicolas Pena2eb1a702017-02-09 18:17:33 -050045DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) {
46 if (!path || width < 0.0f)
47 return false;
48
Nicolas Pena46abb662017-05-17 17:23:22 -040049 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Nicolas Pena2eb1a702017-02-09 18:17:33 -050050 pPathObj->m_GraphState.SetLineWidth(width);
51 return true;
52}
53
Nicolas Pena55e026b2017-02-07 14:59:23 -050054DLLEXPORT FPDF_BOOL FPDFPath_SetFillColor(FPDF_PAGEOBJECT path,
55 unsigned int R,
56 unsigned int G,
57 unsigned int B,
58 unsigned int A) {
59 if (!path || R > 255 || G > 255 || B > 255 || A > 255)
60 return false;
61
Tom Sepezfe91c6c2017-05-16 15:33:20 -070062 float rgb[3] = {R / 255.f, G / 255.f, B / 255.f};
Nicolas Pena46abb662017-05-17 17:23:22 -040063 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Nicolas Pena55e026b2017-02-07 14:59:23 -050064 pPathObj->m_GeneralState.SetFillAlpha(A / 255.f);
Nicolas Pena55e026b2017-02-07 14:59:23 -050065 pPathObj->m_ColorState.SetFillColor(
66 CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
67 return true;
68}
69
Miklos Vajnaed4705b2017-04-05 09:24:50 +020070DLLEXPORT FPDF_BOOL FPDFPath_GetFillColor(FPDF_PAGEOBJECT path,
71 unsigned int* R,
72 unsigned int* G,
73 unsigned int* B,
74 unsigned int* A) {
75 if (!path || !R || !G || !B || !A)
76 return false;
77
Nicolas Pena46abb662017-05-17 17:23:22 -040078 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Miklos Vajnaed4705b2017-04-05 09:24:50 +020079 uint32_t fillRGB = pPathObj->m_ColorState.GetFillRGB();
80 *R = FXSYS_GetRValue(fillRGB);
81 *G = FXSYS_GetGValue(fillRGB);
82 *B = FXSYS_GetBValue(fillRGB);
83 *A = static_cast<unsigned int>(pPathObj->m_GeneralState.GetFillAlpha() *
84 255.f);
85 return true;
86}
87
Nicolas Pena55e026b2017-02-07 14:59:23 -050088DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y) {
89 if (!path)
90 return false;
91
Nicolas Pena46abb662017-05-17 17:23:22 -040092 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
dan sinclairb147e072017-02-22 19:56:15 -050093 pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::MoveTo, false);
Nicolas Pena55e026b2017-02-07 14:59:23 -050094 return true;
95}
96
97DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y) {
98 if (!path)
99 return false;
100
Nicolas Pena46abb662017-05-17 17:23:22 -0400101 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
dan sinclairb147e072017-02-22 19:56:15 -0500102 pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::LineTo, false);
Nicolas Pena55e026b2017-02-07 14:59:23 -0500103 return true;
104}
105
106DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path,
107 float x1,
108 float y1,
109 float x2,
110 float y2,
111 float x3,
112 float y3) {
113 if (!path)
114 return false;
115
Nicolas Pena46abb662017-05-17 17:23:22 -0400116 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
dan sinclairb147e072017-02-22 19:56:15 -0500117 pPathObj->m_Path.AppendPoint(CFX_PointF(x1, y1), FXPT_TYPE::BezierTo, false);
118 pPathObj->m_Path.AppendPoint(CFX_PointF(x2, y2), FXPT_TYPE::BezierTo, false);
119 pPathObj->m_Path.AppendPoint(CFX_PointF(x3, y3), FXPT_TYPE::BezierTo, false);
Nicolas Pena55e026b2017-02-07 14:59:23 -0500120 return true;
121}
122
123DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path) {
124 if (!path)
125 return false;
126
Nicolas Pena46abb662017-05-17 17:23:22 -0400127 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Dan Sinclaire4602322017-02-15 11:07:32 -0500128 if (pPathObj->m_Path.GetPoints().empty())
Nicolas Pena55e026b2017-02-07 14:59:23 -0500129 return false;
130
Dan Sinclaire4602322017-02-15 11:07:32 -0500131 pPathObj->m_Path.ClosePath();
Nicolas Pena55e026b2017-02-07 14:59:23 -0500132 return true;
133}
134
135DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path,
136 int fillmode,
137 FPDF_BOOL stroke) {
138 if (!path)
139 return false;
140
Nicolas Pena46abb662017-05-17 17:23:22 -0400141 auto* pPathObj = static_cast<CPDF_PathObject*>(path);
Nicolas Pena55e026b2017-02-07 14:59:23 -0500142
143 if (fillmode == FPDF_FILLMODE_ALTERNATE)
144 pPathObj->m_FillType = FXFILL_ALTERNATE;
145 else if (fillmode == FPDF_FILLMODE_WINDING)
146 pPathObj->m_FillType = FXFILL_WINDING;
147 else
148 pPathObj->m_FillType = 0;
149 pPathObj->m_bStroke = stroke != 0;
150 return true;
151}
wileyrya22a237f2017-05-26 09:26:27 -0500152
153DLLEXPORT void STDCALL FPDFPath_SetLineJoin(FPDF_PAGEOBJECT path,
154 int line_join) {
155 if (!path)
156 return;
157 if (line_join <
158 static_cast<int>(CFX_GraphStateData::LineJoin::LineJoinMiter) ||
159 line_join >
160 static_cast<int>(CFX_GraphStateData::LineJoin::LineJoinBevel)) {
161 return;
162 }
163 auto* pPathObj = static_cast<CPDF_PageObject*>(path);
164 CFX_GraphStateData::LineJoin lineJoin =
165 static_cast<CFX_GraphStateData::LineJoin>(line_join);
166 pPathObj->m_GraphState.SetLineJoin(lineJoin);
167}
168
169DLLEXPORT void STDCALL FPDFPath_SetLineCap(FPDF_PAGEOBJECT path, int line_cap) {
170 if (!path)
171 return;
172 if (line_cap < static_cast<int>(CFX_GraphStateData::LineCap::LineCapButt) ||
173 line_cap > static_cast<int>(CFX_GraphStateData::LineCap::LineCapSquare)) {
174 return;
175 }
176 auto* pPathObj = static_cast<CPDF_PageObject*>(path);
177 CFX_GraphStateData::LineCap lineCap =
178 static_cast<CFX_GraphStateData::LineCap>(line_cap);
179 pPathObj->m_GraphState.SetLineCap(lineCap);
180}