blob: 7b034f46e401c335a257c209a0855c0105188050 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_edit.h"
8
thestigc54bb432016-07-29 19:34:20 -07009#include <algorithm>
10#include <memory>
11#include <utility>
Lei Zhang996c9302018-04-13 15:44:36 +000012#include <vector>
thestigc54bb432016-07-29 19:34:20 -070013
Lei Zhangfc615c62018-06-08 20:40:15 +000014#include "constants/page_object.h"
dsinclair24154352016-10-04 11:01:48 -070015#include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h"
Tom Sepeze912b622019-05-22 19:57:35 +000016#include "core/fpdfapi/page/cpdf_colorspace.h"
Tom Sepez3c24e5c2019-06-06 21:29:05 +000017#include "core/fpdfapi/page/cpdf_docpagedata.h"
dsinclair41872fa2016-10-04 11:29:35 -070018#include "core/fpdfapi/page/cpdf_form.h"
19#include "core/fpdfapi/page/cpdf_formobject.h"
20#include "core/fpdfapi/page/cpdf_imageobject.h"
21#include "core/fpdfapi/page/cpdf_page.h"
22#include "core/fpdfapi/page/cpdf_pageobject.h"
23#include "core/fpdfapi/page/cpdf_pathobject.h"
24#include "core/fpdfapi/page/cpdf_shadingobject.h"
Lei Zhangc8601bf2021-06-29 23:19:27 +000025#include "core/fpdfapi/page/cpdf_textobject.h"
dsinclair488b7ad2016-10-04 11:55:50 -070026#include "core/fpdfapi/parser/cpdf_array.h"
Lei Zhang81535612018-10-09 21:15:17 +000027#include "core/fpdfapi/parser/cpdf_dictionary.h"
dsinclair488b7ad2016-10-04 11:55:50 -070028#include "core/fpdfapi/parser/cpdf_document.h"
Lei Zhang34ee5db2021-04-24 02:05:31 +000029#include "core/fpdfapi/parser/cpdf_name.h"
dsinclair488b7ad2016-10-04 11:55:50 -070030#include "core/fpdfapi/parser/cpdf_number.h"
31#include "core/fpdfapi/parser/cpdf_string.h"
Tom Sepez3c24e5c2019-06-06 21:29:05 +000032#include "core/fpdfapi/render/cpdf_docrenderdata.h"
Tom Sepez0208b0c2019-07-23 21:52:50 +000033#include "core/fpdfapi/render/cpdf_pagerendercache.h"
dsinclair1727aee2016-09-29 13:12:56 -070034#include "core/fpdfdoc/cpdf_annot.h"
35#include "core/fpdfdoc/cpdf_annotlist.h"
Ryan Harrisonf36a4642018-08-10 19:03:47 +000036#include "core/fxcrt/fx_extension.h"
Tom Sepez8ef63b92022-03-08 19:53:34 +000037#include "core/fxcrt/stl_util.h"
Dan Sinclair00d47a62018-03-28 18:39:04 +000038#include "fpdfsdk/cpdfsdk_helpers.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080039#include "public/fpdf_formfill.h"
Lei Zhangefd44232021-07-30 17:04:57 +000040#include "third_party/base/cxx17_backports.h"
Tom Sepez8ef63b92022-03-08 19:53:34 +000041#include "third_party/base/numerics/safe_conversions.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080042
Tom Sepez51da0932015-11-25 16:05:49 -080043#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -070044#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070045#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080046#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047
thestigc54bb432016-07-29 19:34:20 -070048namespace {
49
Lei Zhangf3b59672022-02-22 18:48:42 +000050static_assert(FPDF_PAGEOBJ_TEXT ==
51 static_cast<int>(CPDF_PageObject::Type::kText),
thestigc54bb432016-07-29 19:34:20 -070052 "FPDF_PAGEOBJ_TEXT/CPDF_PageObject::TEXT mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000053static_assert(FPDF_PAGEOBJ_PATH ==
54 static_cast<int>(CPDF_PageObject::Type::kPath),
thestigc54bb432016-07-29 19:34:20 -070055 "FPDF_PAGEOBJ_PATH/CPDF_PageObject::PATH mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000056static_assert(FPDF_PAGEOBJ_IMAGE ==
57 static_cast<int>(CPDF_PageObject::Type::kImage),
thestigc54bb432016-07-29 19:34:20 -070058 "FPDF_PAGEOBJ_IMAGE/CPDF_PageObject::IMAGE mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000059static_assert(FPDF_PAGEOBJ_SHADING ==
60 static_cast<int>(CPDF_PageObject::Type::kShading),
thestigc54bb432016-07-29 19:34:20 -070061 "FPDF_PAGEOBJ_SHADING/CPDF_PageObject::SHADING mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000062static_assert(FPDF_PAGEOBJ_FORM ==
63 static_cast<int>(CPDF_PageObject::Type::kForm),
thestigc54bb432016-07-29 19:34:20 -070064 "FPDF_PAGEOBJ_FORM/CPDF_PageObject::FORM mismatch");
65
66bool IsPageObject(CPDF_Page* pPage) {
Lei Zhange5c0fa92018-05-08 00:00:16 +000067 if (!pPage)
thestigc54bb432016-07-29 19:34:20 -070068 return false;
69
Henrique Nakashima888af472018-06-07 19:43:42 +000070 const CPDF_Dictionary* pFormDict = pPage->GetDict();
Lei Zhang34ee5db2021-04-24 02:05:31 +000071 if (!pFormDict->KeyExist(pdfium::page_object::kType))
Lei Zhange5c0fa92018-05-08 00:00:16 +000072 return false;
73
Tom Sepeze3e7fc02022-09-06 19:37:13 +000074 RetainPtr<const CPDF_Name> pName =
Lei Zhang34ee5db2021-04-24 02:05:31 +000075 ToName(pFormDict->GetObjectFor(pdfium::page_object::kType)->GetDirect());
76 return pName && pName->GetString() == "Page";
thestigc54bb432016-07-29 19:34:20 -070077}
78
wileyryae858aa42017-05-31 14:49:05 -050079void CalcBoundingBox(CPDF_PageObject* pPageObj) {
80 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +000081 case CPDF_PageObject::Type::kText: {
wileyryae858aa42017-05-31 14:49:05 -050082 break;
83 }
Lei Zhangf3b59672022-02-22 18:48:42 +000084 case CPDF_PageObject::Type::kPath: {
wileyryae858aa42017-05-31 14:49:05 -050085 CPDF_PathObject* pPathObj = pPageObj->AsPath();
86 pPathObj->CalcBoundingBox();
87 break;
88 }
Lei Zhangf3b59672022-02-22 18:48:42 +000089 case CPDF_PageObject::Type::kImage: {
wileyryae858aa42017-05-31 14:49:05 -050090 CPDF_ImageObject* pImageObj = pPageObj->AsImage();
91 pImageObj->CalcBoundingBox();
92 break;
93 }
Lei Zhangf3b59672022-02-22 18:48:42 +000094 case CPDF_PageObject::Type::kShading: {
wileyryae858aa42017-05-31 14:49:05 -050095 CPDF_ShadingObject* pShadingObj = pPageObj->AsShading();
96 pShadingObj->CalcBoundingBox();
97 break;
98 }
Lei Zhangf3b59672022-02-22 18:48:42 +000099 case CPDF_PageObject::Type::kForm: {
wileyryae858aa42017-05-31 14:49:05 -0500100 CPDF_FormObject* pFormObj = pPageObj->AsForm();
101 pFormObj->CalcBoundingBox();
102 break;
103 }
wileyryae858aa42017-05-31 14:49:05 -0500104 }
105}
106
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000107RetainPtr<CPDF_Dictionary> GetMarkParamDict(FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000108 CPDF_ContentMarkItem* pMarkItem =
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000109 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbfeb9342018-07-14 00:07:17 +0000110 return pMarkItem ? pMarkItem->GetParam() : nullptr;
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000111}
112
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000113RetainPtr<CPDF_Dictionary> GetOrCreateMarkParamsDict(FPDF_DOCUMENT document,
114 FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashima144107d2018-07-10 21:04:05 +0000115 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
116 if (!pDoc)
117 return nullptr;
118
119 CPDF_ContentMarkItem* pMarkItem =
120 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
121 if (!pMarkItem)
122 return nullptr;
123
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000124 RetainPtr<CPDF_Dictionary> pParams = pMarkItem->GetParam();
Henrique Nakashima144107d2018-07-10 21:04:05 +0000125 if (!pParams) {
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000126 pParams = pDoc->New<CPDF_Dictionary>();
127 pMarkItem->SetDirectDict(pParams);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000128 }
Henrique Nakashima144107d2018-07-10 21:04:05 +0000129 return pParams;
130}
131
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000132bool PageObjectContainsMark(CPDF_PageObject* pPageObj,
133 FPDF_PAGEOBJECTMARK mark) {
134 const CPDF_ContentMarkItem* pMarkItem =
135 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Tom Sepez6eb915b2021-04-30 00:11:34 +0000136 return pMarkItem && pPageObj->GetContentMarks()->ContainsItem(pMarkItem);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000137}
138
Lei Zhang22375412018-10-24 17:26:50 +0000139CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
140 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
141 return pPageObj ? pPageObj->AsForm() : nullptr;
142}
143
Tom Sepeza733d822019-05-06 19:43:33 +0000144const CPDF_PageObjectHolder* CPDFPageObjHolderFromFPDFFormObject(
Miklos Vajna1d273f12018-07-16 19:20:36 +0000145 FPDF_PAGEOBJECT page_object) {
Lei Zhang22375412018-10-24 17:26:50 +0000146 CPDF_FormObject* pFormObject = CPDFFormObjectFromFPDFPageObject(page_object);
Tom Sepeza733d822019-05-06 19:43:33 +0000147 return pFormObject ? pFormObject->form() : nullptr;
Miklos Vajna1d273f12018-07-16 19:20:36 +0000148}
149
thestigc54bb432016-07-29 19:34:20 -0700150} // namespace
151
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400152FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDF_CreateNewDocument() {
Tom Sepez5af95432020-05-15 22:55:16 +0000153 auto pDoc =
154 std::make_unique<CPDF_Document>(std::make_unique<CPDF_DocRenderData>(),
155 std::make_unique<CPDF_DocPageData>());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 pDoc->CreateNewDoc();
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700157
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 time_t currentTime;
Ryan Harrison275e2602017-09-18 14:23:18 -0400159 ByteString DateStr;
Tom Sepez69a4a702019-07-31 17:59:49 +0000160 if (IsPDFSandboxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
Ryan Harrisonf36a4642018-08-10 19:03:47 +0000161 if (FXSYS_time(&currentTime) != -1) {
Tom Sepez706e1872018-10-22 19:34:53 +0000162 tm* pTM = FXSYS_localtime(&currentTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 if (pTM) {
Dan Sinclair1c4735a2017-11-16 22:08:07 +0000164 DateStr = ByteString::Format(
165 "D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900, pTM->tm_mon + 1,
166 pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 }
168 }
169 }
Tom Sepezbdeeb8a2015-05-27 12:25:00 -0700170
Tom Sepezd9ccef42022-09-21 00:53:35 +0000171 RetainPtr<CPDF_Dictionary> pInfoDict = pDoc->GetInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 if (pInfoDict) {
Tom Sepez69a4a702019-07-31 17:59:49 +0000173 if (IsPDFSandboxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
tsepez0e606b52016-11-18 16:22:41 -0800174 pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false);
175 pInfoDict->SetNewFor<CPDF_String>("Creator", L"PDFium");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700177
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700178 // Caller takes ownership of pDoc.
179 return FPDFDocumentFromCPDFDocument(pDoc.release());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180}
181
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400182FPDF_EXPORT void FPDF_CALLCONV FPDFPage_Delete(FPDF_DOCUMENT document,
183 int page_index) {
Tom Sepezfe06d512018-05-01 17:25:25 +0000184 auto* pDoc = CPDFDocumentFromFPDFDocument(document);
185 if (!pDoc)
186 return;
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000187
Tom Sepez2e118e82018-05-01 21:24:14 +0000188 CPDF_Document::Extension* pExtension = pDoc->GetExtension();
189 if (pExtension) {
190 pExtension->DeletePage(page_index);
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000191 return;
192 }
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000193
Tom Sepezfe06d512018-05-01 17:25:25 +0000194 pDoc->DeletePage(page_index);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700195}
196
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400197FPDF_EXPORT FPDF_PAGE FPDF_CALLCONV FPDFPage_New(FPDF_DOCUMENT document,
198 int page_index,
199 double width,
200 double height) {
Tom Sepez471a1032015-10-15 16:17:18 -0700201 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
202 if (!pDoc)
203 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204
Lei Zhang85f019a2017-03-17 15:14:19 -0700205 page_index = pdfium::clamp(page_index, 0, pDoc->GetPageCount());
Tom Sepez61d8ae82022-07-19 23:24:33 +0000206 RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(page_index));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 if (!pPageDict)
thestig1cd352e2016-06-07 17:53:06 -0700208 return nullptr;
thestigc54bb432016-07-29 19:34:20 -0700209
Lei Zhangfc615c62018-06-08 20:40:15 +0000210 pPageDict->SetRectFor(pdfium::page_object::kMediaBox,
211 CFX_FloatRect(0, 0, width, height));
212 pPageDict->SetNewFor<CPDF_Number>(pdfium::page_object::kRotate, 0);
213 pPageDict->SetNewFor<CPDF_Dictionary>(pdfium::page_object::kResources);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700214
Tom Sepez40e9ff32015-11-30 12:39:54 -0800215#ifdef PDF_ENABLE_XFA
Tom Sepez9bf01812019-08-19 18:59:27 +0000216 if (pDoc->GetExtension()) {
217 auto pXFAPage = pdfium::MakeRetain<CPDFXFA_Page>(pDoc, page_index);
Lei Zhang30540a92018-10-04 22:31:12 +0000218 pXFAPage->LoadPDFPageFromDict(pPageDict);
Tom Sepez101535f2018-06-12 13:36:05 +0000219 return FPDFPageFromIPDFPage(pXFAPage.Leak()); // Caller takes ownership.
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000220 }
Tom Sepezef9fe9e2018-06-12 20:26:56 +0000221#endif // PDF_ENABLE_XFA
222
Tom Sepez0208b0c2019-07-23 21:52:50 +0000223 auto pPage = pdfium::MakeRetain<CPDF_Page>(pDoc, pPageDict);
Tom Sepez5af95432020-05-15 22:55:16 +0000224 pPage->SetRenderCache(std::make_unique<CPDF_PageRenderCache>(pPage.Get()));
Tom Sepezf06ed6d2018-06-04 18:26:07 +0000225 pPage->ParseContent();
Tom Sepez0208b0c2019-07-23 21:52:50 +0000226
Tom Sepez101535f2018-06-12 13:36:05 +0000227 return FPDFPageFromIPDFPage(pPage.Leak()); // Caller takes ownership.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400230FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetRotation(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700231 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700232 return IsPageObject(pPage) ? pPage->GetPageRotation() : -1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400235FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertObject(FPDF_PAGE page,
236 FPDF_PAGEOBJECT page_obj) {
Jane Liu1a084022017-06-29 19:47:12 -0400237 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_obj);
Lei Zhang997de612015-11-04 18:17:53 -0800238 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240
thestigc54bb432016-07-29 19:34:20 -0700241 std::unique_ptr<CPDF_PageObject> pPageObjHolder(pPageObj);
242 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
243 if (!IsPageObject(pPage))
244 return;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000245
Lei Zhang22375412018-10-24 17:26:50 +0000246 pPageObj->SetDirty(true);
Henrique Nakashima2c47fb22018-03-26 20:17:29 +0000247 pPage->AppendPageObject(std::move(pPageObjHolder));
wileyryae858aa42017-05-31 14:49:05 -0500248 CalcBoundingBox(pPageObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700249}
250
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000251FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
252FPDFPage_RemoveObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj) {
253 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_obj);
254 if (!pPageObj)
255 return false;
256
257 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
258 if (!IsPageObject(pPage))
259 return false;
260
Henrique Nakashima2c47fb22018-03-26 20:17:29 +0000261 return pPage->RemovePageObject(pPageObj);
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000262}
263
Miklos Vajna92627612017-09-25 12:59:29 +0200264FPDF_EXPORT int FPDF_CALLCONV FPDFPage_CountObjects(FPDF_PAGE page) {
Tom Sepezbf59a072015-10-21 14:07:23 -0700265 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700266 if (!IsPageObject(pPage))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 return -1;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000268
Tom Sepez8ef63b92022-03-08 19:53:34 +0000269 return pdfium::base::checked_cast<int>(pPage->GetPageObjectCount());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700270}
271
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400272FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPage_GetObject(FPDF_PAGE page,
273 int index) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700274 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700275 if (!IsPageObject(pPage))
Tom Sepez2398d892016-02-17 16:46:26 -0800276 return nullptr;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000277
Tom Sepez525147a2018-05-03 17:19:53 +0000278 return FPDFPageObjectFromCPDFPageObject(pPage->GetPageObjectByIndex(index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279}
280
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400281FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_HasTransparency(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700282 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
283 return pPage && pPage->BackgroundAlphaNeeded();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700284}
285
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400286FPDF_EXPORT void FPDF_CALLCONV FPDFPageObj_Destroy(FPDF_PAGEOBJECT page_obj) {
Jane Liu2e5f0ae2017-08-08 15:23:27 -0400287 delete CPDFPageObjectFromFPDFPageObject(page_obj);
288}
289
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000290FPDF_EXPORT int FPDF_CALLCONV
291FPDFPageObj_CountMarks(FPDF_PAGEOBJECT page_object) {
Lei Zhang22375412018-10-24 17:26:50 +0000292 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
293 if (!pPageObj)
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000294 return -1;
295
Tom Sepez8ef63b92022-03-08 19:53:34 +0000296 return pdfium::base::checked_cast<int>(
297 pPageObj->GetContentMarks()->CountItems());
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000298}
299
300FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
301FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index) {
Lei Zhang22375412018-10-24 17:26:50 +0000302 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
303 if (!pPageObj)
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000304 return nullptr;
305
Tom Sepez6eb915b2021-04-30 00:11:34 +0000306 CPDF_ContentMarks* pMarks = pPageObj->GetContentMarks();
307 if (index >= pMarks->CountItems())
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000308 return nullptr;
309
Tom Sepez6eb915b2021-04-30 00:11:34 +0000310 return FPDFPageObjectMarkFromCPDFContentMarkItem(pMarks->GetItem(index));
Henrique Nakashima144107d2018-07-10 21:04:05 +0000311}
312
313FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
314FPDFPageObj_AddMark(FPDF_PAGEOBJECT page_object, FPDF_BYTESTRING name) {
Henrique Nakashimad8df8c32018-07-12 22:15:09 +0000315 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
316 if (!pPageObj)
Henrique Nakashima144107d2018-07-10 21:04:05 +0000317 return nullptr;
318
Tom Sepez6eb915b2021-04-30 00:11:34 +0000319 CPDF_ContentMarks* pMarks = pPageObj->GetContentMarks();
320 pMarks->AddMark(name);
Henrique Nakashimad8df8c32018-07-12 22:15:09 +0000321 pPageObj->SetDirty(true);
Tom Sepez6eb915b2021-04-30 00:11:34 +0000322
Tom Sepez8ef63b92022-03-08 19:53:34 +0000323 const size_t index = pMarks->CountItems() - 1;
Tom Sepez6eb915b2021-04-30 00:11:34 +0000324 return FPDFPageObjectMarkFromCPDFContentMarkItem(pMarks->GetItem(index));
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000325}
326
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000327FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
328FPDFPageObj_RemoveMark(FPDF_PAGEOBJECT page_object, FPDF_PAGEOBJECTMARK mark) {
329 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
330 CPDF_ContentMarkItem* pMarkItem =
331 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
332 if (!pPageObj || !pMarkItem)
333 return false;
334
Tom Sepez6eb915b2021-04-30 00:11:34 +0000335 if (!pPageObj->GetContentMarks()->RemoveMark(pMarkItem))
336 return false;
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000337
Tom Sepez6eb915b2021-04-30 00:11:34 +0000338 pPageObj->SetDirty(true);
339 return true;
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000340}
341
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000342FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000343FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark,
344 void* buffer,
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000345 unsigned long buflen,
346 unsigned long* out_buflen) {
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000347 const CPDF_ContentMarkItem* pMarkItem =
348 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbc3d8402020-06-18 17:17:28 +0000349 if (!pMarkItem || !out_buflen)
350 return false;
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000351
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000352 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000353 WideString::FromUTF8(pMarkItem->GetName().AsStringView()), buffer,
354 buflen);
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000355 return true;
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000356}
357
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000358FPDF_EXPORT int FPDF_CALLCONV
359FPDFPageObjMark_CountParams(FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000360 const CPDF_ContentMarkItem* pMarkItem =
361 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbc3d8402020-06-18 17:17:28 +0000362 if (!pMarkItem)
363 return -1;
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000364
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000365 RetainPtr<const CPDF_Dictionary> pParams = pMarkItem->GetParam();
Tom Sepez8ef63b92022-03-08 19:53:34 +0000366 return pParams ? fxcrt::CollectionSize<int>(*pParams) : 0;
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000367}
368
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000369FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000370FPDFPageObjMark_GetParamKey(FPDF_PAGEOBJECTMARK mark,
371 unsigned long index,
372 void* buffer,
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000373 unsigned long buflen,
374 unsigned long* out_buflen) {
375 if (!out_buflen)
376 return false;
377
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000378 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashimad8882192018-07-11 22:35:59 +0000379 if (!pParams)
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000380 return false;
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000381
Tom Sepez5ae6c562018-10-17 17:57:51 +0000382 CPDF_DictionaryLocker locker(pParams);
383 for (auto& it : locker) {
Henrique Nakashimad8882192018-07-11 22:35:59 +0000384 if (index == 0) {
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000385 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
Henrique Nakashimad8882192018-07-11 22:35:59 +0000386 WideString::FromUTF8(it.first.AsStringView()), buffer, buflen);
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000387 return true;
Henrique Nakashimad8882192018-07-11 22:35:59 +0000388 }
389 --index;
390 }
391
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000392 return false;
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000393}
394
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000395FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000396FPDFPageObjMark_GetParamValueType(FPDF_PAGEOBJECTMARK mark,
397 FPDF_BYTESTRING key) {
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000398 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000399 if (!pParams)
400 return FPDF_OBJECT_UNKNOWN;
401
Tom Sepez3f90d432022-09-19 20:53:13 +0000402 RetainPtr<const CPDF_Object> pObject = pParams->GetObjectFor(key);
Lei Zhangbfeb9342018-07-14 00:07:17 +0000403 return pObject ? pObject->GetType() : FPDF_OBJECT_UNKNOWN;
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000404}
405
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000406FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000407FPDFPageObjMark_GetParamIntValue(FPDF_PAGEOBJECTMARK mark,
408 FPDF_BYTESTRING key,
409 int* out_value) {
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000410 if (!out_value)
411 return false;
412
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000413 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000414 if (!pParams)
415 return false;
416
Tom Sepez3f90d432022-09-19 20:53:13 +0000417 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000418 if (!pObj || !pObj->IsNumber())
419 return false;
420
421 *out_value = pObj->GetInteger();
422 return true;
423}
424
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400425FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000426FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark,
427 FPDF_BYTESTRING key,
428 void* buffer,
429 unsigned long buflen,
430 unsigned long* out_buflen) {
Henrique Nakashima07520f62018-07-12 19:45:29 +0000431 if (!out_buflen)
432 return false;
433
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000434 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000435 if (!pParams)
436 return false;
437
Tom Sepez3f90d432022-09-19 20:53:13 +0000438 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000439 if (!pObj || !pObj->IsString())
440 return false;
441
442 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
443 WideString::FromUTF8(pObj->GetString().AsStringView()), buffer, buflen);
444 return true;
445}
446
447FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima07520f62018-07-12 19:45:29 +0000448FPDFPageObjMark_GetParamBlobValue(FPDF_PAGEOBJECTMARK mark,
449 FPDF_BYTESTRING key,
450 void* buffer,
451 unsigned long buflen,
452 unsigned long* out_buflen) {
453 if (!out_buflen)
454 return false;
455
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000456 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000457 if (!pParams)
458 return false;
459
Tom Sepez3f90d432022-09-19 20:53:13 +0000460 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000461 if (!pObj || !pObj->IsString())
462 return false;
463
464 ByteString result = pObj->GetString();
Tom Sepez8ef63b92022-03-08 19:53:34 +0000465 const unsigned long len =
466 pdfium::base::checked_cast<unsigned long>(result.GetLength());
Henrique Nakashima07520f62018-07-12 19:45:29 +0000467
468 if (buffer && len <= buflen)
469 memcpy(buffer, result.c_str(), len);
470
471 *out_buflen = len;
472 return true;
473}
474
475FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000476FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT page_object) {
477 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000478 if (!pPageObj)
tsepez4cf55152016-11-02 14:37:54 -0700479 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700480
Lei Zhang0c327652018-10-25 19:02:50 +0000481 if (pPageObj->m_GeneralState.GetBlendType() != BlendMode::kNormal)
tsepez4cf55152016-11-02 14:37:54 -0700482 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700483
Tom Sepezdd844b82022-08-11 08:32:01 +0000484 const CPDF_Dictionary* pSMaskDict = pPageObj->m_GeneralState.GetSoftMask();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485 if (pSMaskDict)
tsepez4cf55152016-11-02 14:37:54 -0700486 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700487
tsepezbbee4452016-09-02 15:22:00 -0700488 if (pPageObj->m_GeneralState.GetFillAlpha() != 1.0f)
tsepez4cf55152016-11-02 14:37:54 -0700489 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700490
Lei Zhang0c327652018-10-25 19:02:50 +0000491 if (pPageObj->IsPath() && pPageObj->m_GeneralState.GetStrokeAlpha() != 1.0f)
tsepez4cf55152016-11-02 14:37:54 -0700492 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700493
Lei Zhang0c327652018-10-25 19:02:50 +0000494 if (!pPageObj->IsForm())
495 return false;
thestigc54bb432016-07-29 19:34:20 -0700496
Lei Zhang0c327652018-10-25 19:02:50 +0000497 const CPDF_Form* pForm = pPageObj->AsForm()->form();
498 if (!pForm)
499 return false;
500
501 const CPDF_Transparency& trans = pForm->GetTransparency();
502 return trans.IsGroup() || trans.IsIsolated();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700503}
504
Henrique Nakashima144107d2018-07-10 21:04:05 +0000505FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
506FPDFPageObjMark_SetIntParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000507 FPDF_PAGEOBJECT page_object,
Henrique Nakashima144107d2018-07-10 21:04:05 +0000508 FPDF_PAGEOBJECTMARK mark,
509 FPDF_BYTESTRING key,
510 int value) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000511 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
512 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
513 return false;
514
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000515 RetainPtr<CPDF_Dictionary> pParams =
516 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000517 if (!pParams)
518 return false;
519
520 pParams->SetNewFor<CPDF_Number>(key, value);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000521 pPageObj->SetDirty(true);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000522 return true;
523}
524
525FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
526FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000527 FPDF_PAGEOBJECT page_object,
Henrique Nakashima144107d2018-07-10 21:04:05 +0000528 FPDF_PAGEOBJECTMARK mark,
529 FPDF_BYTESTRING key,
530 FPDF_BYTESTRING value) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000531 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
532 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
533 return false;
534
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000535 RetainPtr<CPDF_Dictionary> pParams =
536 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000537 if (!pParams)
538 return false;
539
540 pParams->SetNewFor<CPDF_String>(key, value, false);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000541 pPageObj->SetDirty(true);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000542 return true;
543}
544
Henrique Nakashima07520f62018-07-12 19:45:29 +0000545FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
546FPDFPageObjMark_SetBlobParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000547 FPDF_PAGEOBJECT page_object,
Henrique Nakashima07520f62018-07-12 19:45:29 +0000548 FPDF_PAGEOBJECTMARK mark,
549 FPDF_BYTESTRING key,
550 void* value,
551 unsigned long value_len) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000552 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
553 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
554 return false;
555
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000556 RetainPtr<CPDF_Dictionary> pParams =
557 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000558 if (!pParams)
559 return false;
560
561 if (!value && value_len > 0)
562 return false;
563
564 pParams->SetNewFor<CPDF_String>(
565 key, ByteString(static_cast<const char*>(value), value_len), true);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000566 pPageObj->SetDirty(true);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000567 return true;
568}
569
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000570FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
571FPDFPageObjMark_RemoveParam(FPDF_PAGEOBJECT page_object,
572 FPDF_PAGEOBJECTMARK mark,
573 FPDF_BYTESTRING key) {
574 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
575 if (!pPageObj)
576 return false;
577
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000578 RetainPtr<CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000579 if (!pParams)
580 return false;
581
582 auto removed = pParams->RemoveFor(key);
583 if (!removed)
584 return false;
585
586 pPageObj->SetDirty(true);
587 return true;
588}
589
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000590FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT page_object) {
591 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b59672022-02-22 18:48:42 +0000592 return pPageObj ? static_cast<int>(pPageObj->GetType())
593 : FPDF_PAGEOBJ_UNKNOWN;
Miklos Vajna14233192017-04-03 16:02:39 +0200594}
595
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400596FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GenerateContent(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700597 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700598 if (!IsPageObject(pPage))
tsepez4cf55152016-11-02 14:37:54 -0700599 return false;
thestigc54bb432016-07-29 19:34:20 -0700600
Tom Sepeze19e06e2016-01-21 10:49:56 -0800601 CPDF_PageContentGenerator CG(pPage);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700602 CG.GenerateContent();
tsepez4cf55152016-11-02 14:37:54 -0700603 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700604}
605
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400606FPDF_EXPORT void FPDF_CALLCONV
607FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
608 double a,
609 double b,
610 double c,
611 double d,
612 double e,
613 double f) {
Jane Liu1a084022017-06-29 19:47:12 -0400614 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang997de612015-11-04 18:17:53 -0800615 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700616 return;
Lei Zhangcb78ef52015-10-02 10:10:49 -0700617
Dan Sinclair05df0752017-03-14 14:43:42 -0400618 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700619 pPageObj->Transform(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700620}
thestigc54bb432016-07-29 19:34:20 -0700621
Lei Zhangc8601bf2021-06-29 23:19:27 +0000622FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
623FPDFPageObj_GetMatrix(FPDF_PAGEOBJECT page_object, FS_MATRIX* matrix) {
624 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
625 if (!pPageObj || !matrix)
626 return false;
627
628 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +0000629 case CPDF_PageObject::Type::kText:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000630 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsText()->GetTextMatrix());
631 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000632 case CPDF_PageObject::Type::kPath:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000633 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsPath()->matrix());
634 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000635 case CPDF_PageObject::Type::kImage:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000636 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsImage()->matrix());
637 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000638 case CPDF_PageObject::Type::kShading:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000639 return false;
Lei Zhangf3b59672022-02-22 18:48:42 +0000640 case CPDF_PageObject::Type::kForm:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000641 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsForm()->form_matrix());
642 return true;
Lei Zhangc8601bf2021-06-29 23:19:27 +0000643 }
644}
645
646FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
647FPDFPageObj_SetMatrix(FPDF_PAGEOBJECT page_object, const FS_MATRIX* matrix) {
648 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
649 if (!pPageObj || !matrix)
650 return false;
651
652 CFX_Matrix cmatrix = CFXMatrixFromFSMatrix(*matrix);
653 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +0000654 case CPDF_PageObject::Type::kText:
Lei Zhangcfd08172021-06-30 04:11:21 +0000655 pPageObj->AsText()->SetTextMatrix(cmatrix);
656 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000657 case CPDF_PageObject::Type::kPath:
Lei Zhangf36132a2021-06-30 04:45:57 +0000658 pPageObj->AsPath()->SetPathMatrix(cmatrix);
Lei Zhangc8601bf2021-06-29 23:19:27 +0000659 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000660 case CPDF_PageObject::Type::kImage:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000661 pPageObj->AsImage()->SetImageMatrix(cmatrix);
662 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000663 case CPDF_PageObject::Type::kShading:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000664 return false;
Lei Zhangf3b59672022-02-22 18:48:42 +0000665 case CPDF_PageObject::Type::kForm:
Lei Zhang2193da92021-06-30 01:03:07 +0000666 pPageObj->AsForm()->SetFormMatrix(cmatrix);
667 break;
Lei Zhangc8601bf2021-06-29 23:19:27 +0000668 }
669 pPageObj->SetDirty(true);
670 return true;
671}
672
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400673FPDF_EXPORT void FPDF_CALLCONV
674FPDFPageObj_SetBlendMode(FPDF_PAGEOBJECT page_object,
675 FPDF_BYTESTRING blend_mode) {
Jane Liu1a084022017-06-29 19:47:12 -0400676 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
wileyrya06bbdef2017-05-26 15:20:23 -0500677 if (!pPageObj)
678 return;
679
680 pPageObj->m_GeneralState.SetBlendMode(blend_mode);
wileyryae858aa42017-05-31 14:49:05 -0500681 pPageObj->SetDirty(true);
wileyrya06bbdef2017-05-26 15:20:23 -0500682}
683
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400684FPDF_EXPORT void FPDF_CALLCONV FPDFPage_TransformAnnots(FPDF_PAGE page,
685 double a,
686 double b,
687 double c,
688 double d,
689 double e,
690 double f) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700691 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700692 if (!pPage)
693 return;
thestigc54bb432016-07-29 19:34:20 -0700694
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700695 CPDF_AnnotList AnnotList(pPage);
Lei Zhang1b700c32015-10-30 23:55:35 -0700696 for (size_t i = 0; i < AnnotList.Count(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700697 CPDF_Annot* pAnnot = AnnotList.GetAt(i);
Dan Sinclair05df0752017-03-14 14:43:42 -0400698 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e,
699 (float)f);
Jane Liu878b27d2017-08-22 10:50:06 -0400700 CFX_FloatRect rect = matrix.TransformRect(pAnnot->GetRect());
tsepez8021a642016-10-17 16:13:21 -0700701
Tom Sepezb5649d92022-07-19 00:45:22 +0000702 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
Tom Sepez3d64afa2022-06-24 16:40:17 +0000703 RetainPtr<CPDF_Array> pRectArray = pAnnotDict->GetMutableArrayFor("Rect");
Jane Liueda65252017-06-07 11:31:27 -0400704 if (pRectArray)
Lei Zhang59c1ac02017-06-09 11:04:41 -0700705 pRectArray->Clear();
Jane Liueda65252017-06-07 11:31:27 -0400706 else
Tom Sepez8aad22a2022-09-22 18:56:16 +0000707 pRectArray = pAnnotDict->SetNewFor<CPDF_Array>("Rect");
tsepez0e606b52016-11-18 16:22:41 -0800708
Lei Zhang61ce22a2020-03-31 19:18:32 +0000709 pRectArray->AppendNew<CPDF_Number>(rect.left);
710 pRectArray->AppendNew<CPDF_Number>(rect.bottom);
711 pRectArray->AppendNew<CPDF_Number>(rect.right);
712 pRectArray->AppendNew<CPDF_Number>(rect.top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700713
Dan Sinclair85c8e7f2016-11-21 13:50:32 -0500714 // TODO(unknown): Transform AP's rectangle
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700715 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700716}
Bo Xu394010d2014-06-12 13:41:50 -0700717
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400718FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetRotation(FPDF_PAGE page,
719 int rotate) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700720 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700721 if (!IsPageObject(pPage))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700722 return;
thestigc54bb432016-07-29 19:34:20 -0700723
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700724 rotate %= 4;
Tom Sepeza22da902022-06-30 18:08:32 +0000725 pPage->GetMutableDict()->SetNewFor<CPDF_Number>(pdfium::page_object::kRotate,
726 rotate * 90);
Lei Zhangae3945f2018-12-21 19:12:45 +0000727 pPage->UpdateDimensions();
Nico Weber0ce77e32014-07-16 13:19:08 -0700728}
wileyrya864e9fb2017-05-26 11:38:14 -0500729
730FPDF_BOOL FPDFPageObj_SetFillColor(FPDF_PAGEOBJECT page_object,
731 unsigned int R,
732 unsigned int G,
733 unsigned int B,
734 unsigned int A) {
Lei Zhang22375412018-10-24 17:26:50 +0000735 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
736 if (!pPageObj || R > 255 || G > 255 || B > 255 || A > 255)
wileyrya864e9fb2017-05-26 11:38:14 -0500737 return false;
738
Lei Zhang996c9302018-04-13 15:44:36 +0000739 std::vector<float> rgb = {R / 255.f, G / 255.f, B / 255.f};
wileyrya864e9fb2017-05-26 11:38:14 -0500740 pPageObj->m_GeneralState.SetFillAlpha(A / 255.f);
741 pPageObj->m_ColorState.SetFillColor(
Tom Sepezd30786c2021-05-18 23:05:54 +0000742 CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceRGB), rgb);
wileyryae858aa42017-05-31 14:49:05 -0500743 pPageObj->SetDirty(true);
wileyrya864e9fb2017-05-26 11:38:14 -0500744 return true;
745}
wileyryaf1697fa2017-05-26 12:27:40 -0500746
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400747FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000748FPDFPageObj_GetFillColor(FPDF_PAGEOBJECT page_object,
749 unsigned int* R,
750 unsigned int* G,
751 unsigned int* B,
752 unsigned int* A) {
753 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
754 if (!pPageObj || !R || !G || !B || !A)
755 return false;
756
Lei Zhangb6aa0742019-11-12 23:15:31 +0000757 if (!pPageObj->m_ColorState.HasRef())
758 return false;
759
760 FX_COLORREF fill_color = pPageObj->m_ColorState.GetFillColorRef();
761 *R = FXSYS_GetRValue(fill_color);
762 *G = FXSYS_GetGValue(fill_color);
763 *B = FXSYS_GetBValue(fill_color);
Benjamin Beaudryf5ad5c12019-09-13 17:37:58 +0000764 *A = FXSYS_GetUnsignedAlpha(pPageObj->m_GeneralState.GetFillAlpha());
Nicolas Penadf1298a2018-05-08 22:22:41 +0000765 return true;
766}
767
768FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000769FPDFPageObj_GetBounds(FPDF_PAGEOBJECT page_object,
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400770 float* left,
771 float* bottom,
772 float* right,
773 float* top) {
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000774 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000775 if (!pPageObj)
wileyryaf1697fa2017-05-26 12:27:40 -0500776 return false;
777
Lei Zhangd9826492018-10-06 00:32:16 +0000778 const CFX_FloatRect& bbox = pPageObj->GetRect();
wileyryaf1697fa2017-05-26 12:27:40 -0500779 *left = bbox.left;
780 *bottom = bbox.bottom;
781 *right = bbox.right;
782 *top = bbox.top;
783 return true;
784}
Nicolas Penadf1298a2018-05-08 22:22:41 +0000785
786FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Lei Zhangce725272022-06-21 21:32:16 +0000787FPDFPageObj_GetRotatedBounds(FPDF_PAGEOBJECT page_object,
788 FS_QUADPOINTSF* quad_points) {
789 CPDF_PageObject* cpage_object = CPDFPageObjectFromFPDFPageObject(page_object);
790 if (!cpage_object || !quad_points)
791 return false;
792
793 CFX_Matrix matrix;
794 switch (cpage_object->GetType()) {
795 case CPDF_PageObject::Type::kText:
796 matrix = cpage_object->AsText()->GetTextMatrix();
797 break;
798 case CPDF_PageObject::Type::kImage:
799 matrix = cpage_object->AsImage()->matrix();
800 break;
801 default:
802 // TODO(crbug.com/pdfium/1840): Support more object types.
803 return false;
804 }
805
806 const CFX_FloatRect& bbox = cpage_object->GetOriginalRect();
807 const CFX_PointF bottom_left = matrix.Transform({bbox.left, bbox.bottom});
808 const CFX_PointF bottom_right = matrix.Transform({bbox.right, bbox.bottom});
809 const CFX_PointF top_right = matrix.Transform({bbox.right, bbox.top});
810 const CFX_PointF top_left = matrix.Transform({bbox.left, bbox.top});
811
812 // See PDF 32000-1:2008, figure 64 for the QuadPoints ordering.
813 quad_points->x1 = bottom_left.x;
814 quad_points->y1 = bottom_left.y;
815 quad_points->x2 = bottom_right.x;
816 quad_points->y2 = bottom_right.y;
817 quad_points->x3 = top_right.x;
818 quad_points->y3 = top_right.y;
819 quad_points->x4 = top_left.x;
820 quad_points->y4 = top_left.y;
821 return true;
822}
823
824FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000825FPDFPageObj_SetStrokeColor(FPDF_PAGEOBJECT page_object,
826 unsigned int R,
827 unsigned int G,
828 unsigned int B,
829 unsigned int A) {
830 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
831 if (!pPageObj || R > 255 || G > 255 || B > 255 || A > 255)
832 return false;
833
834 std::vector<float> rgb = {R / 255.f, G / 255.f, B / 255.f};
835 pPageObj->m_GeneralState.SetStrokeAlpha(A / 255.f);
836 pPageObj->m_ColorState.SetStrokeColor(
Tom Sepezd30786c2021-05-18 23:05:54 +0000837 CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceRGB), rgb);
Nicolas Penadf1298a2018-05-08 22:22:41 +0000838 pPageObj->SetDirty(true);
839 return true;
840}
841
842FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
843FPDFPageObj_GetStrokeColor(FPDF_PAGEOBJECT page_object,
844 unsigned int* R,
845 unsigned int* G,
846 unsigned int* B,
847 unsigned int* A) {
848 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
849 if (!pPageObj || !R || !G || !B || !A)
850 return false;
851
Lei Zhangb6aa0742019-11-12 23:15:31 +0000852 if (!pPageObj->m_ColorState.HasRef())
853 return false;
854
855 FX_COLORREF stroke_color = pPageObj->m_ColorState.GetStrokeColorRef();
856 *R = FXSYS_GetRValue(stroke_color);
857 *G = FXSYS_GetGValue(stroke_color);
858 *B = FXSYS_GetBValue(stroke_color);
Benjamin Beaudryf5ad5c12019-09-13 17:37:58 +0000859 *A = FXSYS_GetUnsignedAlpha(pPageObj->m_GeneralState.GetStrokeAlpha());
Nicolas Penadf1298a2018-05-08 22:22:41 +0000860 return true;
861}
862
863FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
864FPDFPageObj_SetStrokeWidth(FPDF_PAGEOBJECT page_object, float width) {
865 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
866 if (!pPageObj || width < 0.0f)
867 return false;
868
869 pPageObj->m_GraphState.SetLineWidth(width);
870 pPageObj->SetDirty(true);
871 return true;
872}
873
874FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Miklos Vajna366df7f2018-05-22 14:27:29 +0000875FPDFPageObj_GetStrokeWidth(FPDF_PAGEOBJECT page_object, float* width) {
876 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
877 if (!pPageObj || !width)
878 return false;
879
880 *width = pPageObj->m_GraphState.GetLineWidth();
881 return true;
882}
883
Lei Zhang57360832018-10-24 17:27:39 +0000884FPDF_EXPORT int FPDF_CALLCONV
885FPDFPageObj_GetLineJoin(FPDF_PAGEOBJECT page_object) {
886 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Tom Sepeza7a7c922021-08-26 20:36:04 +0000887 return pPageObj ? static_cast<int>(pPageObj->m_GraphState.GetLineJoin()) : -1;
Lei Zhang57360832018-10-24 17:27:39 +0000888}
889
Miklos Vajna366df7f2018-05-22 14:27:29 +0000890FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000891FPDFPageObj_SetLineJoin(FPDF_PAGEOBJECT page_object, int line_join) {
Nicolas Penadf1298a2018-05-08 22:22:41 +0000892 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000893 if (!pPageObj)
894 return false;
895
Tom Sepeza7a7c922021-08-26 20:36:04 +0000896 if (line_join < FPDF_LINEJOIN_MITER || line_join > FPDF_LINEJOIN_BEVEL)
Lei Zhang22375412018-10-24 17:26:50 +0000897 return false;
898
899 pPageObj->m_GraphState.SetLineJoin(
900 static_cast<CFX_GraphStateData::LineJoin>(line_join));
Nicolas Penadf1298a2018-05-08 22:22:41 +0000901 pPageObj->SetDirty(true);
902 return true;
903}
904
Lei Zhangcd11df62018-10-24 17:30:11 +0000905FPDF_EXPORT int FPDF_CALLCONV
906FPDFPageObj_GetLineCap(FPDF_PAGEOBJECT page_object) {
907 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Tom Sepeza7a7c922021-08-26 20:36:04 +0000908 return pPageObj ? static_cast<int>(pPageObj->m_GraphState.GetLineCap()) : -1;
Lei Zhangcd11df62018-10-24 17:30:11 +0000909}
910
Nicolas Penadf1298a2018-05-08 22:22:41 +0000911FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
912FPDFPageObj_SetLineCap(FPDF_PAGEOBJECT page_object, int line_cap) {
Nicolas Penadf1298a2018-05-08 22:22:41 +0000913 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000914 if (!pPageObj)
915 return false;
916
Tom Sepeza7a7c922021-08-26 20:36:04 +0000917 if (line_cap < FPDF_LINECAP_BUTT ||
918 line_cap > FPDF_LINECAP_PROJECTING_SQUARE) {
Lei Zhang22375412018-10-24 17:26:50 +0000919 return false;
Tom Sepeza7a7c922021-08-26 20:36:04 +0000920 }
Lei Zhang22375412018-10-24 17:26:50 +0000921 pPageObj->m_GraphState.SetLineCap(
922 static_cast<CFX_GraphStateData::LineCap>(line_cap));
Nicolas Penadf1298a2018-05-08 22:22:41 +0000923 pPageObj->SetDirty(true);
924 return true;
925}
Miklos Vajnab66077d2018-07-11 13:25:02 +0000926
Robert Collyer5c4111b2021-06-24 23:18:28 +0000927FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
928FPDFPageObj_GetDashPhase(FPDF_PAGEOBJECT page_object, float* phase) {
929 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
930 if (!pPageObj || !phase)
931 return false;
932
933 *phase = pPageObj->m_GraphState.GetLineDashPhase();
934 return true;
935}
936
937FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
938FPDFPageObj_SetDashPhase(FPDF_PAGEOBJECT page_object, float phase) {
939 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
940 if (!pPageObj)
941 return false;
942
943 pPageObj->m_GraphState.SetLineDashPhase(phase);
944 pPageObj->SetDirty(true);
945 return true;
946}
947
948FPDF_EXPORT int FPDF_CALLCONV
949FPDFPageObj_GetDashCount(FPDF_PAGEOBJECT page_object) {
950 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Tom Sepez8ef63b92022-03-08 19:53:34 +0000951 return pPageObj ? pdfium::base::checked_cast<int>(
952 pPageObj->m_GraphState.GetLineDashSize())
953 : -1;
Robert Collyer5c4111b2021-06-24 23:18:28 +0000954}
955
956FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
957FPDFPageObj_GetDashArray(FPDF_PAGEOBJECT page_object,
958 float* dash_array,
959 size_t dash_count) {
960 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
961 if (!pPageObj || !dash_array)
962 return false;
963
964 auto dash_vector = pPageObj->m_GraphState.GetLineDashArray();
965 if (dash_vector.size() > dash_count)
966 return false;
967
968 memcpy(dash_array, dash_vector.data(), dash_vector.size() * sizeof(float));
969 return true;
970}
971
972FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
973FPDFPageObj_SetDashArray(FPDF_PAGEOBJECT page_object,
974 const float* dash_array,
975 size_t dash_count,
976 float phase) {
977 if (dash_count > 0 && !dash_array)
978 return false;
979
980 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
981 if (!pPageObj)
982 return false;
983
984 std::vector<float> dashes;
985 if (dash_count > 0) {
986 dashes.reserve(dash_count);
987 dashes.assign(dash_array, dash_array + dash_count);
988 }
989
990 pPageObj->m_GraphState.SetLineDash(dashes, phase, 1.0f);
991
992 pPageObj->SetDirty(true);
993 return true;
994}
995
Miklos Vajnab66077d2018-07-11 13:25:02 +0000996FPDF_EXPORT int FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000997FPDFFormObj_CountObjects(FPDF_PAGEOBJECT form_object) {
998 const auto* pObjectList = CPDFPageObjHolderFromFPDFFormObject(form_object);
Tom Sepez8ef63b92022-03-08 19:53:34 +0000999 return pObjectList ? pdfium::base::checked_cast<int>(
1000 pObjectList->GetPageObjectCount())
1001 : -1;
Miklos Vajnab66077d2018-07-11 13:25:02 +00001002}
Miklos Vajna1d273f12018-07-16 19:20:36 +00001003
1004FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
1005FPDFFormObj_GetObject(FPDF_PAGEOBJECT form_object, unsigned long index) {
Tom Sepeza733d822019-05-06 19:43:33 +00001006 const auto* pObjectList = CPDFPageObjHolderFromFPDFFormObject(form_object);
Miklos Vajna1d273f12018-07-16 19:20:36 +00001007 if (!pObjectList)
1008 return nullptr;
1009
1010 return FPDFPageObjectFromCPDFPageObject(
1011 pObjectList->GetPageObjectByIndex(index));
1012}