blob: c79fc0cfcec42ee50db89e46a22cb1494fdef1ae [file] [log] [blame]
K. Moon832a6942022-10-31 20:11:31 +00001// Copyright 2014 The PDFium Authors
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002// 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"
Tom Sepez167a5602022-10-21 22:42:55 +000022#include "core/fpdfapi/page/cpdf_pageimagecache.h"
dsinclair41872fa2016-10-04 11:29:35 -070023#include "core/fpdfapi/page/cpdf_pageobject.h"
24#include "core/fpdfapi/page/cpdf_pathobject.h"
25#include "core/fpdfapi/page/cpdf_shadingobject.h"
Lei Zhangc8601bf2021-06-29 23:19:27 +000026#include "core/fpdfapi/page/cpdf_textobject.h"
dsinclair488b7ad2016-10-04 11:55:50 -070027#include "core/fpdfapi/parser/cpdf_array.h"
Lei Zhang81535612018-10-09 21:15:17 +000028#include "core/fpdfapi/parser/cpdf_dictionary.h"
dsinclair488b7ad2016-10-04 11:55:50 -070029#include "core/fpdfapi/parser/cpdf_document.h"
Lei Zhang34ee5db2021-04-24 02:05:31 +000030#include "core/fpdfapi/parser/cpdf_name.h"
dsinclair488b7ad2016-10-04 11:55:50 -070031#include "core/fpdfapi/parser/cpdf_number.h"
32#include "core/fpdfapi/parser/cpdf_string.h"
Tom Sepez3c24e5c2019-06-06 21:29:05 +000033#include "core/fpdfapi/render/cpdf_docrenderdata.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 Sepez3abb4492023-07-20 16:54:46 +000037#include "core/fxcrt/fx_memcpy_wrappers.h"
Tom Sepez8ef63b92022-03-08 19:53:34 +000038#include "core/fxcrt/stl_util.h"
Dan Sinclair00d47a62018-03-28 18:39:04 +000039#include "fpdfsdk/cpdfsdk_helpers.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080040#include "public/fpdf_formfill.h"
Lei Zhangb3dea942023-09-27 20:32:21 +000041#include "third_party/base/containers/span.h"
Tom Sepez8ef63b92022-03-08 19:53:34 +000042#include "third_party/base/numerics/safe_conversions.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080043
Tom Sepez51da0932015-11-25 16:05:49 -080044#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -070045#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070046#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080047#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048
thestigc54bb432016-07-29 19:34:20 -070049namespace {
50
Lei Zhangf3b59672022-02-22 18:48:42 +000051static_assert(FPDF_PAGEOBJ_TEXT ==
52 static_cast<int>(CPDF_PageObject::Type::kText),
thestigc54bb432016-07-29 19:34:20 -070053 "FPDF_PAGEOBJ_TEXT/CPDF_PageObject::TEXT mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000054static_assert(FPDF_PAGEOBJ_PATH ==
55 static_cast<int>(CPDF_PageObject::Type::kPath),
thestigc54bb432016-07-29 19:34:20 -070056 "FPDF_PAGEOBJ_PATH/CPDF_PageObject::PATH mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000057static_assert(FPDF_PAGEOBJ_IMAGE ==
58 static_cast<int>(CPDF_PageObject::Type::kImage),
thestigc54bb432016-07-29 19:34:20 -070059 "FPDF_PAGEOBJ_IMAGE/CPDF_PageObject::IMAGE mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000060static_assert(FPDF_PAGEOBJ_SHADING ==
61 static_cast<int>(CPDF_PageObject::Type::kShading),
thestigc54bb432016-07-29 19:34:20 -070062 "FPDF_PAGEOBJ_SHADING/CPDF_PageObject::SHADING mismatch");
Lei Zhangf3b59672022-02-22 18:48:42 +000063static_assert(FPDF_PAGEOBJ_FORM ==
64 static_cast<int>(CPDF_PageObject::Type::kForm),
thestigc54bb432016-07-29 19:34:20 -070065 "FPDF_PAGEOBJ_FORM/CPDF_PageObject::FORM mismatch");
66
67bool IsPageObject(CPDF_Page* pPage) {
Lei Zhange5c0fa92018-05-08 00:00:16 +000068 if (!pPage)
thestigc54bb432016-07-29 19:34:20 -070069 return false;
70
Tom Sepez4ede0792022-10-07 20:25:36 +000071 RetainPtr<const CPDF_Dictionary> pFormDict = pPage->GetDict();
Lei Zhang34ee5db2021-04-24 02:05:31 +000072 if (!pFormDict->KeyExist(pdfium::page_object::kType))
Lei Zhange5c0fa92018-05-08 00:00:16 +000073 return false;
74
Tom Sepeze3e7fc02022-09-06 19:37:13 +000075 RetainPtr<const CPDF_Name> pName =
Lei Zhang34ee5db2021-04-24 02:05:31 +000076 ToName(pFormDict->GetObjectFor(pdfium::page_object::kType)->GetDirect());
77 return pName && pName->GetString() == "Page";
thestigc54bb432016-07-29 19:34:20 -070078}
79
wileyryae858aa42017-05-31 14:49:05 -050080void CalcBoundingBox(CPDF_PageObject* pPageObj) {
81 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +000082 case CPDF_PageObject::Type::kText: {
wileyryae858aa42017-05-31 14:49:05 -050083 break;
84 }
Lei Zhangf3b59672022-02-22 18:48:42 +000085 case CPDF_PageObject::Type::kPath: {
wileyryae858aa42017-05-31 14:49:05 -050086 CPDF_PathObject* pPathObj = pPageObj->AsPath();
87 pPathObj->CalcBoundingBox();
88 break;
89 }
Lei Zhangf3b59672022-02-22 18:48:42 +000090 case CPDF_PageObject::Type::kImage: {
wileyryae858aa42017-05-31 14:49:05 -050091 CPDF_ImageObject* pImageObj = pPageObj->AsImage();
92 pImageObj->CalcBoundingBox();
93 break;
94 }
Lei Zhangf3b59672022-02-22 18:48:42 +000095 case CPDF_PageObject::Type::kShading: {
wileyryae858aa42017-05-31 14:49:05 -050096 CPDF_ShadingObject* pShadingObj = pPageObj->AsShading();
97 pShadingObj->CalcBoundingBox();
98 break;
99 }
Lei Zhangf3b59672022-02-22 18:48:42 +0000100 case CPDF_PageObject::Type::kForm: {
wileyryae858aa42017-05-31 14:49:05 -0500101 CPDF_FormObject* pFormObj = pPageObj->AsForm();
102 pFormObj->CalcBoundingBox();
103 break;
104 }
wileyryae858aa42017-05-31 14:49:05 -0500105 }
106}
107
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000108RetainPtr<CPDF_Dictionary> GetMarkParamDict(FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000109 CPDF_ContentMarkItem* pMarkItem =
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000110 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbfeb9342018-07-14 00:07:17 +0000111 return pMarkItem ? pMarkItem->GetParam() : nullptr;
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000112}
113
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000114RetainPtr<CPDF_Dictionary> GetOrCreateMarkParamsDict(FPDF_DOCUMENT document,
115 FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashima144107d2018-07-10 21:04:05 +0000116 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
117 if (!pDoc)
118 return nullptr;
119
120 CPDF_ContentMarkItem* pMarkItem =
121 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
122 if (!pMarkItem)
123 return nullptr;
124
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000125 RetainPtr<CPDF_Dictionary> pParams = pMarkItem->GetParam();
Henrique Nakashima144107d2018-07-10 21:04:05 +0000126 if (!pParams) {
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000127 pParams = pDoc->New<CPDF_Dictionary>();
128 pMarkItem->SetDirectDict(pParams);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000129 }
Henrique Nakashima144107d2018-07-10 21:04:05 +0000130 return pParams;
131}
132
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000133bool PageObjectContainsMark(CPDF_PageObject* pPageObj,
134 FPDF_PAGEOBJECTMARK mark) {
135 const CPDF_ContentMarkItem* pMarkItem =
136 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Tom Sepez6eb915b2021-04-30 00:11:34 +0000137 return pMarkItem && pPageObj->GetContentMarks()->ContainsItem(pMarkItem);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000138}
139
Lei Zhang22375412018-10-24 17:26:50 +0000140CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
141 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
142 return pPageObj ? pPageObj->AsForm() : nullptr;
143}
144
Tom Sepeza733d822019-05-06 19:43:33 +0000145const CPDF_PageObjectHolder* CPDFPageObjHolderFromFPDFFormObject(
Miklos Vajna1d273f12018-07-16 19:20:36 +0000146 FPDF_PAGEOBJECT page_object) {
Lei Zhang22375412018-10-24 17:26:50 +0000147 CPDF_FormObject* pFormObject = CPDFFormObjectFromFPDFPageObject(page_object);
Tom Sepeza733d822019-05-06 19:43:33 +0000148 return pFormObject ? pFormObject->form() : nullptr;
Miklos Vajna1d273f12018-07-16 19:20:36 +0000149}
150
thestigc54bb432016-07-29 19:34:20 -0700151} // namespace
152
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400153FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDF_CreateNewDocument() {
Tom Sepez5af95432020-05-15 22:55:16 +0000154 auto pDoc =
155 std::make_unique<CPDF_Document>(std::make_unique<CPDF_DocRenderData>(),
156 std::make_unique<CPDF_DocPageData>());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 pDoc->CreateNewDoc();
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 time_t currentTime;
Ryan Harrison275e2602017-09-18 14:23:18 -0400160 ByteString DateStr;
Tom Sepez69a4a702019-07-31 17:59:49 +0000161 if (IsPDFSandboxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
Ryan Harrisonf36a4642018-08-10 19:03:47 +0000162 if (FXSYS_time(&currentTime) != -1) {
Tom Sepez706e1872018-10-22 19:34:53 +0000163 tm* pTM = FXSYS_localtime(&currentTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 if (pTM) {
Dan Sinclair1c4735a2017-11-16 22:08:07 +0000165 DateStr = ByteString::Format(
166 "D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900, pTM->tm_mon + 1,
167 pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 }
169 }
170 }
Tom Sepezbdeeb8a2015-05-27 12:25:00 -0700171
Tom Sepezd9ccef42022-09-21 00:53:35 +0000172 RetainPtr<CPDF_Dictionary> pInfoDict = pDoc->GetInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (pInfoDict) {
Tom Sepez69a4a702019-07-31 17:59:49 +0000174 if (IsPDFSandboxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
tsepez0e606b52016-11-18 16:22:41 -0800175 pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false);
176 pInfoDict->SetNewFor<CPDF_String>("Creator", L"PDFium");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700178
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700179 // Caller takes ownership of pDoc.
180 return FPDFDocumentFromCPDFDocument(pDoc.release());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700181}
182
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400183FPDF_EXPORT void FPDF_CALLCONV FPDFPage_Delete(FPDF_DOCUMENT document,
184 int page_index) {
Tom Sepezfe06d512018-05-01 17:25:25 +0000185 auto* pDoc = CPDFDocumentFromFPDFDocument(document);
186 if (!pDoc)
187 return;
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000188
Tom Sepez2e118e82018-05-01 21:24:14 +0000189 CPDF_Document::Extension* pExtension = pDoc->GetExtension();
190 if (pExtension) {
191 pExtension->DeletePage(page_index);
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000192 return;
193 }
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000194
Tom Sepezfe06d512018-05-01 17:25:25 +0000195 pDoc->DeletePage(page_index);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700196}
197
Lei Zhangb3dea942023-09-27 20:32:21 +0000198FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Lei Zhang1aa7ef92023-09-27 22:45:51 +0000199FPDF_MovePages(FPDF_DOCUMENT document,
200 const int* page_indices,
201 unsigned long page_indices_len,
202 int dest_page_index) {
Lei Zhangb3dea942023-09-27 20:32:21 +0000203 auto* doc = CPDFDocumentFromFPDFDocument(document);
204 if (!doc) {
205 return false;
206 }
207
208 return doc->MovePages({page_indices, page_indices_len}, dest_page_index);
209}
210
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400211FPDF_EXPORT FPDF_PAGE FPDF_CALLCONV FPDFPage_New(FPDF_DOCUMENT document,
212 int page_index,
213 double width,
214 double height) {
Tom Sepez471a1032015-10-15 16:17:18 -0700215 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
216 if (!pDoc)
217 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218
Lei Zhang41e44fc2023-08-01 00:47:23 +0000219 page_index = std::clamp(page_index, 0, pDoc->GetPageCount());
Tom Sepez61d8ae82022-07-19 23:24:33 +0000220 RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(page_index));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 if (!pPageDict)
thestig1cd352e2016-06-07 17:53:06 -0700222 return nullptr;
thestigc54bb432016-07-29 19:34:20 -0700223
Lei Zhangfc615c62018-06-08 20:40:15 +0000224 pPageDict->SetRectFor(pdfium::page_object::kMediaBox,
225 CFX_FloatRect(0, 0, width, height));
226 pPageDict->SetNewFor<CPDF_Number>(pdfium::page_object::kRotate, 0);
227 pPageDict->SetNewFor<CPDF_Dictionary>(pdfium::page_object::kResources);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228
Tom Sepez40e9ff32015-11-30 12:39:54 -0800229#ifdef PDF_ENABLE_XFA
Tom Sepez9bf01812019-08-19 18:59:27 +0000230 if (pDoc->GetExtension()) {
231 auto pXFAPage = pdfium::MakeRetain<CPDFXFA_Page>(pDoc, page_index);
Lei Zhang30540a92018-10-04 22:31:12 +0000232 pXFAPage->LoadPDFPageFromDict(pPageDict);
Tom Sepez101535f2018-06-12 13:36:05 +0000233 return FPDFPageFromIPDFPage(pXFAPage.Leak()); // Caller takes ownership.
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000234 }
Tom Sepezef9fe9e2018-06-12 20:26:56 +0000235#endif // PDF_ENABLE_XFA
236
Tom Sepez0208b0c2019-07-23 21:52:50 +0000237 auto pPage = pdfium::MakeRetain<CPDF_Page>(pDoc, pPageDict);
Tom Sepez8482a832022-10-24 22:10:52 +0000238 pPage->AddPageImageCache();
Tom Sepezf06ed6d2018-06-04 18:26:07 +0000239 pPage->ParseContent();
Tom Sepez0208b0c2019-07-23 21:52:50 +0000240
Tom Sepez101535f2018-06-12 13:36:05 +0000241 return FPDFPageFromIPDFPage(pPage.Leak()); // Caller takes ownership.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242}
243
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400244FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetRotation(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700245 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700246 return IsPageObject(pPage) ? pPage->GetPageRotation() : -1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247}
248
Lei Zhang2c8f0032023-12-11 22:36:34 +0000249FPDF_EXPORT void FPDF_CALLCONV
250FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_object) {
251 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang997de612015-11-04 18:17:53 -0800252 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254
thestigc54bb432016-07-29 19:34:20 -0700255 std::unique_ptr<CPDF_PageObject> pPageObjHolder(pPageObj);
256 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
257 if (!IsPageObject(pPage))
258 return;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000259
Lei Zhang22375412018-10-24 17:26:50 +0000260 pPageObj->SetDirty(true);
Henrique Nakashima2c47fb22018-03-26 20:17:29 +0000261 pPage->AppendPageObject(std::move(pPageObjHolder));
wileyryae858aa42017-05-31 14:49:05 -0500262 CalcBoundingBox(pPageObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263}
264
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000265FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Lei Zhang2c8f0032023-12-11 22:36:34 +0000266FPDFPage_RemoveObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_object) {
267 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000268 if (!pPageObj)
269 return false;
270
271 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
272 if (!IsPageObject(pPage))
273 return false;
274
Tom Sepez52370c12022-10-14 19:40:31 +0000275 // Caller takes ownership.
276 return !!pPage->RemovePageObject(pPageObj).release();
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000277}
278
Miklos Vajna92627612017-09-25 12:59:29 +0200279FPDF_EXPORT int FPDF_CALLCONV FPDFPage_CountObjects(FPDF_PAGE page) {
Tom Sepezbf59a072015-10-21 14:07:23 -0700280 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700281 if (!IsPageObject(pPage))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 return -1;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000283
Tom Sepez8ef63b92022-03-08 19:53:34 +0000284 return pdfium::base::checked_cast<int>(pPage->GetPageObjectCount());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285}
286
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400287FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPage_GetObject(FPDF_PAGE page,
288 int index) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700289 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700290 if (!IsPageObject(pPage))
Tom Sepez2398d892016-02-17 16:46:26 -0800291 return nullptr;
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000292
Tom Sepez525147a2018-05-03 17:19:53 +0000293 return FPDFPageObjectFromCPDFPageObject(pPage->GetPageObjectByIndex(index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700294}
295
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400296FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_HasTransparency(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700297 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
298 return pPage && pPage->BackgroundAlphaNeeded();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700299}
300
Lei Zhang2c8f0032023-12-11 22:36:34 +0000301FPDF_EXPORT void FPDF_CALLCONV
302FPDFPageObj_Destroy(FPDF_PAGEOBJECT page_object) {
303 delete CPDFPageObjectFromFPDFPageObject(page_object);
Jane Liu2e5f0ae2017-08-08 15:23:27 -0400304}
305
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000306FPDF_EXPORT int FPDF_CALLCONV
307FPDFPageObj_CountMarks(FPDF_PAGEOBJECT page_object) {
Lei Zhang22375412018-10-24 17:26:50 +0000308 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
309 if (!pPageObj)
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000310 return -1;
311
Tom Sepez8ef63b92022-03-08 19:53:34 +0000312 return pdfium::base::checked_cast<int>(
313 pPageObj->GetContentMarks()->CountItems());
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000314}
315
316FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
317FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index) {
Lei Zhang22375412018-10-24 17:26:50 +0000318 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
319 if (!pPageObj)
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000320 return nullptr;
321
Tom Sepez6eb915b2021-04-30 00:11:34 +0000322 CPDF_ContentMarks* pMarks = pPageObj->GetContentMarks();
323 if (index >= pMarks->CountItems())
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000324 return nullptr;
325
Tom Sepez6eb915b2021-04-30 00:11:34 +0000326 return FPDFPageObjectMarkFromCPDFContentMarkItem(pMarks->GetItem(index));
Henrique Nakashima144107d2018-07-10 21:04:05 +0000327}
328
329FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
330FPDFPageObj_AddMark(FPDF_PAGEOBJECT page_object, FPDF_BYTESTRING name) {
Henrique Nakashimad8df8c32018-07-12 22:15:09 +0000331 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
332 if (!pPageObj)
Henrique Nakashima144107d2018-07-10 21:04:05 +0000333 return nullptr;
334
Tom Sepez6eb915b2021-04-30 00:11:34 +0000335 CPDF_ContentMarks* pMarks = pPageObj->GetContentMarks();
336 pMarks->AddMark(name);
Henrique Nakashimad8df8c32018-07-12 22:15:09 +0000337 pPageObj->SetDirty(true);
Tom Sepez6eb915b2021-04-30 00:11:34 +0000338
Tom Sepez8ef63b92022-03-08 19:53:34 +0000339 const size_t index = pMarks->CountItems() - 1;
Tom Sepez6eb915b2021-04-30 00:11:34 +0000340 return FPDFPageObjectMarkFromCPDFContentMarkItem(pMarks->GetItem(index));
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000341}
342
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000343FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
344FPDFPageObj_RemoveMark(FPDF_PAGEOBJECT page_object, FPDF_PAGEOBJECTMARK mark) {
345 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
346 CPDF_ContentMarkItem* pMarkItem =
347 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
348 if (!pPageObj || !pMarkItem)
349 return false;
350
Tom Sepez6eb915b2021-04-30 00:11:34 +0000351 if (!pPageObj->GetContentMarks()->RemoveMark(pMarkItem))
352 return false;
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000353
Tom Sepez6eb915b2021-04-30 00:11:34 +0000354 pPageObj->SetDirty(true);
355 return true;
Henrique Nakashimafed4adb2018-07-13 19:47:22 +0000356}
357
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000358FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000359FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark,
360 void* buffer,
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000361 unsigned long buflen,
362 unsigned long* out_buflen) {
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000363 const CPDF_ContentMarkItem* pMarkItem =
364 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbc3d8402020-06-18 17:17:28 +0000365 if (!pMarkItem || !out_buflen)
366 return false;
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000367
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000368 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000369 WideString::FromUTF8(pMarkItem->GetName().AsStringView()), buffer,
370 buflen);
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000371 return true;
Henrique Nakashimac90adc52018-03-27 16:26:44 +0000372}
373
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000374FPDF_EXPORT int FPDF_CALLCONV
375FPDFPageObjMark_CountParams(FPDF_PAGEOBJECTMARK mark) {
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000376 const CPDF_ContentMarkItem* pMarkItem =
377 CPDFContentMarkItemFromFPDFPageObjectMark(mark);
Lei Zhangbc3d8402020-06-18 17:17:28 +0000378 if (!pMarkItem)
379 return -1;
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000380
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000381 RetainPtr<const CPDF_Dictionary> pParams = pMarkItem->GetParam();
Tom Sepez8ef63b92022-03-08 19:53:34 +0000382 return pParams ? fxcrt::CollectionSize<int>(*pParams) : 0;
Henrique Nakashimaaed62532018-04-17 20:34:38 +0000383}
384
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000385FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000386FPDFPageObjMark_GetParamKey(FPDF_PAGEOBJECTMARK mark,
387 unsigned long index,
388 void* buffer,
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000389 unsigned long buflen,
390 unsigned long* out_buflen) {
391 if (!out_buflen)
392 return false;
393
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000394 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashimad8882192018-07-11 22:35:59 +0000395 if (!pParams)
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000396 return false;
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000397
Tom Sepez5ae6c562018-10-17 17:57:51 +0000398 CPDF_DictionaryLocker locker(pParams);
399 for (auto& it : locker) {
Henrique Nakashimad8882192018-07-11 22:35:59 +0000400 if (index == 0) {
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000401 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
Henrique Nakashimad8882192018-07-11 22:35:59 +0000402 WideString::FromUTF8(it.first.AsStringView()), buffer, buflen);
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000403 return true;
Henrique Nakashimad8882192018-07-11 22:35:59 +0000404 }
405 --index;
406 }
407
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000408 return false;
Henrique Nakashima132c38e2018-04-23 16:35:56 +0000409}
410
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000411FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000412FPDFPageObjMark_GetParamValueType(FPDF_PAGEOBJECTMARK mark,
413 FPDF_BYTESTRING key) {
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000414 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000415 if (!pParams)
416 return FPDF_OBJECT_UNKNOWN;
417
Tom Sepez3f90d432022-09-19 20:53:13 +0000418 RetainPtr<const CPDF_Object> pObject = pParams->GetObjectFor(key);
Lei Zhangbfeb9342018-07-14 00:07:17 +0000419 return pObject ? pObject->GetType() : FPDF_OBJECT_UNKNOWN;
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000420}
421
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000422FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000423FPDFPageObjMark_GetParamIntValue(FPDF_PAGEOBJECTMARK mark,
424 FPDF_BYTESTRING key,
425 int* out_value) {
Henrique Nakashimac3099d12018-09-18 18:08:15 +0000426 if (!out_value)
427 return false;
428
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000429 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000430 if (!pParams)
431 return false;
432
Tom Sepez3f90d432022-09-19 20:53:13 +0000433 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000434 if (!pObj || !pObj->IsNumber())
435 return false;
436
437 *out_value = pObj->GetInteger();
438 return true;
439}
440
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400441FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima94230e52018-07-11 22:02:02 +0000442FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark,
443 FPDF_BYTESTRING key,
444 void* buffer,
445 unsigned long buflen,
446 unsigned long* out_buflen) {
Henrique Nakashima07520f62018-07-12 19:45:29 +0000447 if (!out_buflen)
448 return false;
449
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000450 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000451 if (!pParams)
452 return false;
453
Tom Sepez3f90d432022-09-19 20:53:13 +0000454 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima7007fd52018-07-05 18:04:19 +0000455 if (!pObj || !pObj->IsString())
456 return false;
457
458 *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
459 WideString::FromUTF8(pObj->GetString().AsStringView()), buffer, buflen);
460 return true;
461}
462
463FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Henrique Nakashima07520f62018-07-12 19:45:29 +0000464FPDFPageObjMark_GetParamBlobValue(FPDF_PAGEOBJECTMARK mark,
465 FPDF_BYTESTRING key,
466 void* buffer,
467 unsigned long buflen,
468 unsigned long* out_buflen) {
469 if (!out_buflen)
470 return false;
471
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000472 RetainPtr<const CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000473 if (!pParams)
474 return false;
475
Tom Sepez3f90d432022-09-19 20:53:13 +0000476 RetainPtr<const CPDF_Object> pObj = pParams->GetObjectFor(key);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000477 if (!pObj || !pObj->IsString())
478 return false;
479
480 ByteString result = pObj->GetString();
Tom Sepez8ef63b92022-03-08 19:53:34 +0000481 const unsigned long len =
482 pdfium::base::checked_cast<unsigned long>(result.GetLength());
Henrique Nakashima07520f62018-07-12 19:45:29 +0000483
484 if (buffer && len <= buflen)
485 memcpy(buffer, result.c_str(), len);
486
487 *out_buflen = len;
488 return true;
489}
490
491FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000492FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT page_object) {
493 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000494 if (!pPageObj) {
tsepez4cf55152016-11-02 14:37:54 -0700495 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000496 }
497 if (pPageObj->general_state().GetBlendType() != BlendMode::kNormal) {
tsepez4cf55152016-11-02 14:37:54 -0700498 return true;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000499 }
500 if (pPageObj->general_state().GetSoftMask()) {
tsepez4cf55152016-11-02 14:37:54 -0700501 return true;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000502 }
503 if (pPageObj->general_state().GetFillAlpha() != 1.0f) {
tsepez4cf55152016-11-02 14:37:54 -0700504 return true;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000505 }
506 if (pPageObj->IsPath() &&
507 pPageObj->general_state().GetStrokeAlpha() != 1.0f) {
tsepez4cf55152016-11-02 14:37:54 -0700508 return true;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000509 }
510 if (!pPageObj->IsForm()) {
Lei Zhang0c327652018-10-25 19:02:50 +0000511 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000512 }
thestigc54bb432016-07-29 19:34:20 -0700513
Lei Zhang0c327652018-10-25 19:02:50 +0000514 const CPDF_Form* pForm = pPageObj->AsForm()->form();
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000515 if (!pForm) {
Lei Zhang0c327652018-10-25 19:02:50 +0000516 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000517 }
Lei Zhang0c327652018-10-25 19:02:50 +0000518
519 const CPDF_Transparency& trans = pForm->GetTransparency();
520 return trans.IsGroup() || trans.IsIsolated();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521}
522
Henrique Nakashima144107d2018-07-10 21:04:05 +0000523FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
524FPDFPageObjMark_SetIntParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000525 FPDF_PAGEOBJECT page_object,
Henrique Nakashima144107d2018-07-10 21:04:05 +0000526 FPDF_PAGEOBJECTMARK mark,
527 FPDF_BYTESTRING key,
528 int value) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000529 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
530 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
531 return false;
532
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000533 RetainPtr<CPDF_Dictionary> pParams =
534 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000535 if (!pParams)
536 return false;
537
538 pParams->SetNewFor<CPDF_Number>(key, value);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000539 pPageObj->SetDirty(true);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000540 return true;
541}
542
543FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
544FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000545 FPDF_PAGEOBJECT page_object,
Henrique Nakashima144107d2018-07-10 21:04:05 +0000546 FPDF_PAGEOBJECTMARK mark,
547 FPDF_BYTESTRING key,
548 FPDF_BYTESTRING value) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000549 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
550 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
551 return false;
552
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000553 RetainPtr<CPDF_Dictionary> pParams =
554 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000555 if (!pParams)
556 return false;
557
558 pParams->SetNewFor<CPDF_String>(key, value, false);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000559 pPageObj->SetDirty(true);
Henrique Nakashima144107d2018-07-10 21:04:05 +0000560 return true;
561}
562
Henrique Nakashima07520f62018-07-12 19:45:29 +0000563FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
564FPDFPageObjMark_SetBlobParam(FPDF_DOCUMENT document,
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000565 FPDF_PAGEOBJECT page_object,
Henrique Nakashima07520f62018-07-12 19:45:29 +0000566 FPDF_PAGEOBJECTMARK mark,
567 FPDF_BYTESTRING key,
568 void* value,
569 unsigned long value_len) {
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000570 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
571 if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
572 return false;
573
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000574 RetainPtr<CPDF_Dictionary> pParams =
575 GetOrCreateMarkParamsDict(document, mark);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000576 if (!pParams)
577 return false;
578
579 if (!value && value_len > 0)
580 return false;
581
582 pParams->SetNewFor<CPDF_String>(
583 key, ByteString(static_cast<const char*>(value), value_len), true);
Henrique Nakashimaa3406772018-07-13 19:10:53 +0000584 pPageObj->SetDirty(true);
Henrique Nakashima07520f62018-07-12 19:45:29 +0000585 return true;
586}
587
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000588FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
589FPDFPageObjMark_RemoveParam(FPDF_PAGEOBJECT page_object,
590 FPDF_PAGEOBJECTMARK mark,
591 FPDF_BYTESTRING key) {
592 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
593 if (!pPageObj)
594 return false;
595
Tom Sepezb7ee8d62022-09-26 19:31:53 +0000596 RetainPtr<CPDF_Dictionary> pParams = GetMarkParamDict(mark);
Henrique Nakashimacf403ba2018-07-13 20:12:41 +0000597 if (!pParams)
598 return false;
599
600 auto removed = pParams->RemoveFor(key);
601 if (!removed)
602 return false;
603
604 pPageObj->SetDirty(true);
605 return true;
606}
607
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000608FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT page_object) {
609 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b59672022-02-22 18:48:42 +0000610 return pPageObj ? static_cast<int>(pPageObj->GetType())
611 : FPDF_PAGEOBJ_UNKNOWN;
Miklos Vajna14233192017-04-03 16:02:39 +0200612}
613
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400614FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GenerateContent(FPDF_PAGE page) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700615 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700616 if (!IsPageObject(pPage))
tsepez4cf55152016-11-02 14:37:54 -0700617 return false;
thestigc54bb432016-07-29 19:34:20 -0700618
Tom Sepeze19e06e2016-01-21 10:49:56 -0800619 CPDF_PageContentGenerator CG(pPage);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700620 CG.GenerateContent();
tsepez4cf55152016-11-02 14:37:54 -0700621 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700622}
623
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400624FPDF_EXPORT void FPDF_CALLCONV
625FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
626 double a,
627 double b,
628 double c,
629 double d,
630 double e,
631 double f) {
Jane Liu1a084022017-06-29 19:47:12 -0400632 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang997de612015-11-04 18:17:53 -0800633 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700634 return;
Lei Zhangcb78ef52015-10-02 10:10:49 -0700635
Dan Sinclair05df0752017-03-14 14:43:42 -0400636 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700637 pPageObj->Transform(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700638}
thestigc54bb432016-07-29 19:34:20 -0700639
Lei Zhangc8601bf2021-06-29 23:19:27 +0000640FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
641FPDFPageObj_GetMatrix(FPDF_PAGEOBJECT page_object, FS_MATRIX* matrix) {
642 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
643 if (!pPageObj || !matrix)
644 return false;
645
646 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +0000647 case CPDF_PageObject::Type::kText:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000648 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsText()->GetTextMatrix());
649 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000650 case CPDF_PageObject::Type::kPath:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000651 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsPath()->matrix());
652 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000653 case CPDF_PageObject::Type::kImage:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000654 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsImage()->matrix());
655 return true;
Lei Zhangf3b59672022-02-22 18:48:42 +0000656 case CPDF_PageObject::Type::kShading:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000657 return false;
Lei Zhangf3b59672022-02-22 18:48:42 +0000658 case CPDF_PageObject::Type::kForm:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000659 *matrix = FSMatrixFromCFXMatrix(pPageObj->AsForm()->form_matrix());
660 return true;
Lei Zhangc8601bf2021-06-29 23:19:27 +0000661 }
662}
663
664FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
665FPDFPageObj_SetMatrix(FPDF_PAGEOBJECT page_object, const FS_MATRIX* matrix) {
666 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
667 if (!pPageObj || !matrix)
668 return false;
669
670 CFX_Matrix cmatrix = CFXMatrixFromFSMatrix(*matrix);
671 switch (pPageObj->GetType()) {
Lei Zhangf3b59672022-02-22 18:48:42 +0000672 case CPDF_PageObject::Type::kText:
Lei Zhangcfd08172021-06-30 04:11:21 +0000673 pPageObj->AsText()->SetTextMatrix(cmatrix);
674 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000675 case CPDF_PageObject::Type::kPath:
Lei Zhangf36132a2021-06-30 04:45:57 +0000676 pPageObj->AsPath()->SetPathMatrix(cmatrix);
Lei Zhangc8601bf2021-06-29 23:19:27 +0000677 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000678 case CPDF_PageObject::Type::kImage:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000679 pPageObj->AsImage()->SetImageMatrix(cmatrix);
680 break;
Lei Zhangf3b59672022-02-22 18:48:42 +0000681 case CPDF_PageObject::Type::kShading:
Lei Zhangc8601bf2021-06-29 23:19:27 +0000682 return false;
Lei Zhangf3b59672022-02-22 18:48:42 +0000683 case CPDF_PageObject::Type::kForm:
Lei Zhang2193da92021-06-30 01:03:07 +0000684 pPageObj->AsForm()->SetFormMatrix(cmatrix);
685 break;
Lei Zhangc8601bf2021-06-29 23:19:27 +0000686 }
687 pPageObj->SetDirty(true);
688 return true;
689}
690
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400691FPDF_EXPORT void FPDF_CALLCONV
692FPDFPageObj_SetBlendMode(FPDF_PAGEOBJECT page_object,
693 FPDF_BYTESTRING blend_mode) {
Jane Liu1a084022017-06-29 19:47:12 -0400694 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
wileyrya06bbdef2017-05-26 15:20:23 -0500695 if (!pPageObj)
696 return;
697
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000698 pPageObj->mutable_general_state().SetBlendMode(blend_mode);
wileyryae858aa42017-05-31 14:49:05 -0500699 pPageObj->SetDirty(true);
wileyrya06bbdef2017-05-26 15:20:23 -0500700}
701
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400702FPDF_EXPORT void FPDF_CALLCONV FPDFPage_TransformAnnots(FPDF_PAGE page,
703 double a,
704 double b,
705 double c,
706 double d,
707 double e,
708 double f) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700709 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700710 if (!pPage)
711 return;
thestigc54bb432016-07-29 19:34:20 -0700712
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700713 CPDF_AnnotList AnnotList(pPage);
Lei Zhang1b700c32015-10-30 23:55:35 -0700714 for (size_t i = 0; i < AnnotList.Count(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700715 CPDF_Annot* pAnnot = AnnotList.GetAt(i);
Dan Sinclair05df0752017-03-14 14:43:42 -0400716 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e,
717 (float)f);
Jane Liu878b27d2017-08-22 10:50:06 -0400718 CFX_FloatRect rect = matrix.TransformRect(pAnnot->GetRect());
tsepez8021a642016-10-17 16:13:21 -0700719
Tom Sepezb5649d92022-07-19 00:45:22 +0000720 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
Tom Sepez3d64afa2022-06-24 16:40:17 +0000721 RetainPtr<CPDF_Array> pRectArray = pAnnotDict->GetMutableArrayFor("Rect");
Jane Liueda65252017-06-07 11:31:27 -0400722 if (pRectArray)
Lei Zhang59c1ac02017-06-09 11:04:41 -0700723 pRectArray->Clear();
Jane Liueda65252017-06-07 11:31:27 -0400724 else
Tom Sepez8aad22a2022-09-22 18:56:16 +0000725 pRectArray = pAnnotDict->SetNewFor<CPDF_Array>("Rect");
tsepez0e606b52016-11-18 16:22:41 -0800726
Lei Zhang61ce22a2020-03-31 19:18:32 +0000727 pRectArray->AppendNew<CPDF_Number>(rect.left);
728 pRectArray->AppendNew<CPDF_Number>(rect.bottom);
729 pRectArray->AppendNew<CPDF_Number>(rect.right);
730 pRectArray->AppendNew<CPDF_Number>(rect.top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700731
Dan Sinclair85c8e7f2016-11-21 13:50:32 -0500732 // TODO(unknown): Transform AP's rectangle
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700733 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700734}
Bo Xu394010d2014-06-12 13:41:50 -0700735
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400736FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetRotation(FPDF_PAGE page,
737 int rotate) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700738 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
thestigc54bb432016-07-29 19:34:20 -0700739 if (!IsPageObject(pPage))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700740 return;
thestigc54bb432016-07-29 19:34:20 -0700741
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700742 rotate %= 4;
Tom Sepeza22da902022-06-30 18:08:32 +0000743 pPage->GetMutableDict()->SetNewFor<CPDF_Number>(pdfium::page_object::kRotate,
744 rotate * 90);
Lei Zhangae3945f2018-12-21 19:12:45 +0000745 pPage->UpdateDimensions();
Nico Weber0ce77e32014-07-16 13:19:08 -0700746}
wileyrya864e9fb2017-05-26 11:38:14 -0500747
748FPDF_BOOL FPDFPageObj_SetFillColor(FPDF_PAGEOBJECT page_object,
749 unsigned int R,
750 unsigned int G,
751 unsigned int B,
752 unsigned int A) {
Lei Zhang22375412018-10-24 17:26:50 +0000753 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
754 if (!pPageObj || R > 255 || G > 255 || B > 255 || A > 255)
wileyrya864e9fb2017-05-26 11:38:14 -0500755 return false;
756
Lei Zhang996c9302018-04-13 15:44:36 +0000757 std::vector<float> rgb = {R / 255.f, G / 255.f, B / 255.f};
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000758 pPageObj->mutable_general_state().SetFillAlpha(A / 255.f);
759 pPageObj->mutable_color_state().SetFillColor(
Tom Sepez2f7efe52022-10-12 19:19:07 +0000760 CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceRGB),
761 std::move(rgb));
wileyryae858aa42017-05-31 14:49:05 -0500762 pPageObj->SetDirty(true);
wileyrya864e9fb2017-05-26 11:38:14 -0500763 return true;
764}
wileyryaf1697fa2017-05-26 12:27:40 -0500765
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400766FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000767FPDFPageObj_GetFillColor(FPDF_PAGEOBJECT page_object,
768 unsigned int* R,
769 unsigned int* G,
770 unsigned int* B,
771 unsigned int* A) {
772 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
773 if (!pPageObj || !R || !G || !B || !A)
774 return false;
775
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000776 if (!pPageObj->color_state().HasRef()) {
Lei Zhangb6aa0742019-11-12 23:15:31 +0000777 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000778 }
Lei Zhangb6aa0742019-11-12 23:15:31 +0000779
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000780 FX_COLORREF fill_color = pPageObj->color_state().GetFillColorRef();
Lei Zhangb6aa0742019-11-12 23:15:31 +0000781 *R = FXSYS_GetRValue(fill_color);
782 *G = FXSYS_GetGValue(fill_color);
783 *B = FXSYS_GetBValue(fill_color);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000784 *A = FXSYS_GetUnsignedAlpha(pPageObj->general_state().GetFillAlpha());
Nicolas Penadf1298a2018-05-08 22:22:41 +0000785 return true;
786}
787
788FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000789FPDFPageObj_GetBounds(FPDF_PAGEOBJECT page_object,
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400790 float* left,
791 float* bottom,
792 float* right,
793 float* top) {
Andrew Weintraubfe111d92019-06-24 17:19:20 +0000794 CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000795 if (!pPageObj)
wileyryaf1697fa2017-05-26 12:27:40 -0500796 return false;
797
Lei Zhangd9826492018-10-06 00:32:16 +0000798 const CFX_FloatRect& bbox = pPageObj->GetRect();
wileyryaf1697fa2017-05-26 12:27:40 -0500799 *left = bbox.left;
800 *bottom = bbox.bottom;
801 *right = bbox.right;
802 *top = bbox.top;
803 return true;
804}
Nicolas Penadf1298a2018-05-08 22:22:41 +0000805
806FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Lei Zhangce725272022-06-21 21:32:16 +0000807FPDFPageObj_GetRotatedBounds(FPDF_PAGEOBJECT page_object,
808 FS_QUADPOINTSF* quad_points) {
809 CPDF_PageObject* cpage_object = CPDFPageObjectFromFPDFPageObject(page_object);
810 if (!cpage_object || !quad_points)
811 return false;
812
813 CFX_Matrix matrix;
814 switch (cpage_object->GetType()) {
815 case CPDF_PageObject::Type::kText:
816 matrix = cpage_object->AsText()->GetTextMatrix();
817 break;
818 case CPDF_PageObject::Type::kImage:
819 matrix = cpage_object->AsImage()->matrix();
820 break;
821 default:
822 // TODO(crbug.com/pdfium/1840): Support more object types.
823 return false;
824 }
825
826 const CFX_FloatRect& bbox = cpage_object->GetOriginalRect();
827 const CFX_PointF bottom_left = matrix.Transform({bbox.left, bbox.bottom});
828 const CFX_PointF bottom_right = matrix.Transform({bbox.right, bbox.bottom});
829 const CFX_PointF top_right = matrix.Transform({bbox.right, bbox.top});
830 const CFX_PointF top_left = matrix.Transform({bbox.left, bbox.top});
831
832 // See PDF 32000-1:2008, figure 64 for the QuadPoints ordering.
833 quad_points->x1 = bottom_left.x;
834 quad_points->y1 = bottom_left.y;
835 quad_points->x2 = bottom_right.x;
836 quad_points->y2 = bottom_right.y;
837 quad_points->x3 = top_right.x;
838 quad_points->y3 = top_right.y;
839 quad_points->x4 = top_left.x;
840 quad_points->y4 = top_left.y;
841 return true;
842}
843
844FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000845FPDFPageObj_SetStrokeColor(FPDF_PAGEOBJECT page_object,
846 unsigned int R,
847 unsigned int G,
848 unsigned int B,
849 unsigned int A) {
850 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
851 if (!pPageObj || R > 255 || G > 255 || B > 255 || A > 255)
852 return false;
853
854 std::vector<float> rgb = {R / 255.f, G / 255.f, B / 255.f};
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000855 pPageObj->mutable_general_state().SetStrokeAlpha(A / 255.f);
856 pPageObj->mutable_color_state().SetStrokeColor(
Tom Sepez2f7efe52022-10-12 19:19:07 +0000857 CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceRGB),
858 std::move(rgb));
Nicolas Penadf1298a2018-05-08 22:22:41 +0000859 pPageObj->SetDirty(true);
860 return true;
861}
862
863FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
864FPDFPageObj_GetStrokeColor(FPDF_PAGEOBJECT page_object,
865 unsigned int* R,
866 unsigned int* G,
867 unsigned int* B,
868 unsigned int* A) {
869 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000870 if (!pPageObj || !R || !G || !B || !A) {
Nicolas Penadf1298a2018-05-08 22:22:41 +0000871 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000872 }
873 if (!pPageObj->color_state().HasRef()) {
Lei Zhangb6aa0742019-11-12 23:15:31 +0000874 return false;
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000875 }
Lei Zhangb6aa0742019-11-12 23:15:31 +0000876
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000877 FX_COLORREF stroke_color = pPageObj->color_state().GetStrokeColorRef();
Lei Zhangb6aa0742019-11-12 23:15:31 +0000878 *R = FXSYS_GetRValue(stroke_color);
879 *G = FXSYS_GetGValue(stroke_color);
880 *B = FXSYS_GetBValue(stroke_color);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000881 *A = FXSYS_GetUnsignedAlpha(pPageObj->general_state().GetStrokeAlpha());
Nicolas Penadf1298a2018-05-08 22:22:41 +0000882 return true;
883}
884
885FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
886FPDFPageObj_SetStrokeWidth(FPDF_PAGEOBJECT page_object, float width) {
887 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
888 if (!pPageObj || width < 0.0f)
889 return false;
890
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000891 pPageObj->mutable_graph_state().SetLineWidth(width);
Nicolas Penadf1298a2018-05-08 22:22:41 +0000892 pPageObj->SetDirty(true);
893 return true;
894}
895
896FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Miklos Vajna366df7f2018-05-22 14:27:29 +0000897FPDFPageObj_GetStrokeWidth(FPDF_PAGEOBJECT page_object, float* width) {
898 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
899 if (!pPageObj || !width)
900 return false;
901
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000902 *width = pPageObj->graph_state().GetLineWidth();
Miklos Vajna366df7f2018-05-22 14:27:29 +0000903 return true;
904}
905
Lei Zhang57360832018-10-24 17:27:39 +0000906FPDF_EXPORT int FPDF_CALLCONV
907FPDFPageObj_GetLineJoin(FPDF_PAGEOBJECT page_object) {
908 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000909 return pPageObj ? static_cast<int>(pPageObj->graph_state().GetLineJoin())
910 : -1;
Lei Zhang57360832018-10-24 17:27:39 +0000911}
912
Miklos Vajna366df7f2018-05-22 14:27:29 +0000913FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
Nicolas Penadf1298a2018-05-08 22:22:41 +0000914FPDFPageObj_SetLineJoin(FPDF_PAGEOBJECT page_object, int line_join) {
Nicolas Penadf1298a2018-05-08 22:22:41 +0000915 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000916 if (!pPageObj)
917 return false;
918
Tom Sepeza7a7c922021-08-26 20:36:04 +0000919 if (line_join < FPDF_LINEJOIN_MITER || line_join > FPDF_LINEJOIN_BEVEL)
Lei Zhang22375412018-10-24 17:26:50 +0000920 return false;
921
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000922 pPageObj->mutable_graph_state().SetLineJoin(
Lei Zhang22375412018-10-24 17:26:50 +0000923 static_cast<CFX_GraphStateData::LineJoin>(line_join));
Nicolas Penadf1298a2018-05-08 22:22:41 +0000924 pPageObj->SetDirty(true);
925 return true;
926}
927
Lei Zhangcd11df62018-10-24 17:30:11 +0000928FPDF_EXPORT int FPDF_CALLCONV
929FPDFPageObj_GetLineCap(FPDF_PAGEOBJECT page_object) {
930 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000931 return pPageObj ? static_cast<int>(pPageObj->graph_state().GetLineCap()) : -1;
Lei Zhangcd11df62018-10-24 17:30:11 +0000932}
933
Nicolas Penadf1298a2018-05-08 22:22:41 +0000934FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
935FPDFPageObj_SetLineCap(FPDF_PAGEOBJECT page_object, int line_cap) {
Nicolas Penadf1298a2018-05-08 22:22:41 +0000936 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Lei Zhang22375412018-10-24 17:26:50 +0000937 if (!pPageObj)
938 return false;
939
Tom Sepeza7a7c922021-08-26 20:36:04 +0000940 if (line_cap < FPDF_LINECAP_BUTT ||
941 line_cap > FPDF_LINECAP_PROJECTING_SQUARE) {
Lei Zhang22375412018-10-24 17:26:50 +0000942 return false;
Tom Sepeza7a7c922021-08-26 20:36:04 +0000943 }
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000944 pPageObj->mutable_graph_state().SetLineCap(
Lei Zhang22375412018-10-24 17:26:50 +0000945 static_cast<CFX_GraphStateData::LineCap>(line_cap));
Nicolas Penadf1298a2018-05-08 22:22:41 +0000946 pPageObj->SetDirty(true);
947 return true;
948}
Miklos Vajnab66077d2018-07-11 13:25:02 +0000949
Robert Collyer5c4111b2021-06-24 23:18:28 +0000950FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
951FPDFPageObj_GetDashPhase(FPDF_PAGEOBJECT page_object, float* phase) {
952 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
953 if (!pPageObj || !phase)
954 return false;
955
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000956 *phase = pPageObj->graph_state().GetLineDashPhase();
Robert Collyer5c4111b2021-06-24 23:18:28 +0000957 return true;
958}
959
960FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
961FPDFPageObj_SetDashPhase(FPDF_PAGEOBJECT page_object, float phase) {
962 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
963 if (!pPageObj)
964 return false;
965
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000966 pPageObj->mutable_graph_state().SetLineDashPhase(phase);
Robert Collyer5c4111b2021-06-24 23:18:28 +0000967 pPageObj->SetDirty(true);
968 return true;
969}
970
971FPDF_EXPORT int FPDF_CALLCONV
972FPDFPageObj_GetDashCount(FPDF_PAGEOBJECT page_object) {
973 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
Tom Sepez8ef63b92022-03-08 19:53:34 +0000974 return pPageObj ? pdfium::base::checked_cast<int>(
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000975 pPageObj->graph_state().GetLineDashSize())
Tom Sepez8ef63b92022-03-08 19:53:34 +0000976 : -1;
Robert Collyer5c4111b2021-06-24 23:18:28 +0000977}
978
979FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
980FPDFPageObj_GetDashArray(FPDF_PAGEOBJECT page_object,
981 float* dash_array,
982 size_t dash_count) {
983 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
984 if (!pPageObj || !dash_array)
985 return false;
986
Lei Zhangf3b5f3d2023-11-11 03:02:12 +0000987 auto dash_vector = pPageObj->graph_state().GetLineDashArray();
Robert Collyer5c4111b2021-06-24 23:18:28 +0000988 if (dash_vector.size() > dash_count)
989 return false;
990
Tom Sepez3abb4492023-07-20 16:54:46 +0000991 FXSYS_memcpy(dash_array, dash_vector.data(),
992 dash_vector.size() * sizeof(float));
Robert Collyer5c4111b2021-06-24 23:18:28 +0000993 return true;
994}
995
996FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
997FPDFPageObj_SetDashArray(FPDF_PAGEOBJECT page_object,
998 const float* dash_array,
999 size_t dash_count,
1000 float phase) {
1001 if (dash_count > 0 && !dash_array)
1002 return false;
1003
1004 auto* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
1005 if (!pPageObj)
1006 return false;
1007
1008 std::vector<float> dashes;
1009 if (dash_count > 0) {
1010 dashes.reserve(dash_count);
1011 dashes.assign(dash_array, dash_array + dash_count);
1012 }
1013
Lei Zhangf3b5f3d2023-11-11 03:02:12 +00001014 pPageObj->mutable_graph_state().SetLineDash(dashes, phase, 1.0f);
Robert Collyer5c4111b2021-06-24 23:18:28 +00001015
1016 pPageObj->SetDirty(true);
1017 return true;
1018}
1019
Miklos Vajnab66077d2018-07-11 13:25:02 +00001020FPDF_EXPORT int FPDF_CALLCONV
Andrew Weintraubfe111d92019-06-24 17:19:20 +00001021FPDFFormObj_CountObjects(FPDF_PAGEOBJECT form_object) {
1022 const auto* pObjectList = CPDFPageObjHolderFromFPDFFormObject(form_object);
Tom Sepez8ef63b92022-03-08 19:53:34 +00001023 return pObjectList ? pdfium::base::checked_cast<int>(
1024 pObjectList->GetPageObjectCount())
1025 : -1;
Miklos Vajnab66077d2018-07-11 13:25:02 +00001026}
Miklos Vajna1d273f12018-07-16 19:20:36 +00001027
1028FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
1029FPDFFormObj_GetObject(FPDF_PAGEOBJECT form_object, unsigned long index) {
Tom Sepeza733d822019-05-06 19:43:33 +00001030 const auto* pObjectList = CPDFPageObjHolderFromFPDFFormObject(form_object);
Miklos Vajna1d273f12018-07-16 19:20:36 +00001031 if (!pObjectList)
1032 return nullptr;
1033
1034 return FPDFPageObjectFromCPDFPageObject(
1035 pObjectList->GetPageObjectByIndex(index));
1036}