Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_annot.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "public/fpdf_annot.h"
6
7#include <array>
8#include <memory>
9#include <sstream>
10#include <utility>
11#include <vector>
12
13#include "constants/annotation_common.h"
14#include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h"
15#include "core/fpdfapi/page/cpdf_annotcontext.h"
16#include "core/fpdfapi/page/cpdf_form.h"
17#include "core/fpdfapi/page/cpdf_page.h"
18#include "core/fpdfapi/page/cpdf_pageobject.h"
19#include "core/fpdfapi/parser/cpdf_array.h"
20#include "core/fpdfapi/parser/cpdf_boolean.h"
21#include "core/fpdfapi/parser/cpdf_dictionary.h"
22#include "core/fpdfapi/parser/cpdf_document.h"
23#include "core/fpdfapi/parser/cpdf_name.h"
24#include "core/fpdfapi/parser/cpdf_number.h"
25#include "core/fpdfapi/parser/cpdf_reference.h"
26#include "core/fpdfapi/parser/cpdf_stream.h"
27#include "core/fpdfapi/parser/cpdf_string.h"
28#include "core/fpdfapi/parser/fpdf_parser_utility.h"
29#include "core/fpdfdoc/cpdf_annot.h"
30#include "core/fpdfdoc/cpdf_color_utils.h"
31#include "core/fpdfdoc/cpdf_formfield.h"
32#include "core/fpdfdoc/cpdf_generateap.h"
33#include "core/fpdfdoc/cpdf_interactiveform.h"
34#include "core/fxcrt/check.h"
35#include "core/fxcrt/containers/contains.h"
36#include "core/fxcrt/fx_safe_types.h"
37#include "core/fxcrt/fx_string_wrappers.h"
38#include "core/fxcrt/numerics/safe_conversions.h"
39#include "core/fxcrt/ptr_util.h"
40#include "core/fxcrt/stl_util.h"
41#include "core/fxge/cfx_color.h"
42#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
43#include "fpdfsdk/cpdfsdk_helpers.h"
44#include "fpdfsdk/cpdfsdk_interactiveform.h"
45
46namespace {
47
48// These checks ensure the consistency of annotation subtype values across core/
49// and public.
50static_assert(static_cast<int>(CPDF_Annot::Subtype::UNKNOWN) ==
52 "CPDF_Annot::UNKNOWN value mismatch");
53static_assert(static_cast<int>(CPDF_Annot::Subtype::TEXT) == FPDF_ANNOT_TEXT,
54 "CPDF_Annot::TEXT value mismatch");
55static_assert(static_cast<int>(CPDF_Annot::Subtype::LINK) == FPDF_ANNOT_LINK,
56 "CPDF_Annot::LINK value mismatch");
57static_assert(static_cast<int>(CPDF_Annot::Subtype::FREETEXT) ==
59 "CPDF_Annot::FREETEXT value mismatch");
60static_assert(static_cast<int>(CPDF_Annot::Subtype::LINE) == FPDF_ANNOT_LINE,
61 "CPDF_Annot::LINE value mismatch");
62static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUARE) ==
64 "CPDF_Annot::SQUARE value mismatch");
65static_assert(static_cast<int>(CPDF_Annot::Subtype::CIRCLE) ==
67 "CPDF_Annot::CIRCLE value mismatch");
68static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYGON) ==
70 "CPDF_Annot::POLYGON value mismatch");
71static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYLINE) ==
73 "CPDF_Annot::POLYLINE value mismatch");
74static_assert(static_cast<int>(CPDF_Annot::Subtype::HIGHLIGHT) ==
76 "CPDF_Annot::HIGHLIGHT value mismatch");
77static_assert(static_cast<int>(CPDF_Annot::Subtype::UNDERLINE) ==
79 "CPDF_Annot::UNDERLINE value mismatch");
80static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUIGGLY) ==
82 "CPDF_Annot::SQUIGGLY value mismatch");
83static_assert(static_cast<int>(CPDF_Annot::Subtype::STRIKEOUT) ==
85 "CPDF_Annot::STRIKEOUT value mismatch");
86static_assert(static_cast<int>(CPDF_Annot::Subtype::STAMP) == FPDF_ANNOT_STAMP,
87 "CPDF_Annot::STAMP value mismatch");
88static_assert(static_cast<int>(CPDF_Annot::Subtype::CARET) == FPDF_ANNOT_CARET,
89 "CPDF_Annot::CARET value mismatch");
90static_assert(static_cast<int>(CPDF_Annot::Subtype::INK) == FPDF_ANNOT_INK,
91 "CPDF_Annot::INK value mismatch");
92static_assert(static_cast<int>(CPDF_Annot::Subtype::POPUP) == FPDF_ANNOT_POPUP,
93 "CPDF_Annot::POPUP value mismatch");
94static_assert(static_cast<int>(CPDF_Annot::Subtype::FILEATTACHMENT) ==
96 "CPDF_Annot::FILEATTACHMENT value mismatch");
97static_assert(static_cast<int>(CPDF_Annot::Subtype::SOUND) == FPDF_ANNOT_SOUND,
98 "CPDF_Annot::SOUND value mismatch");
99static_assert(static_cast<int>(CPDF_Annot::Subtype::MOVIE) == FPDF_ANNOT_MOVIE,
100 "CPDF_Annot::MOVIE value mismatch");
101static_assert(static_cast<int>(CPDF_Annot::Subtype::WIDGET) ==
103 "CPDF_Annot::WIDGET value mismatch");
104static_assert(static_cast<int>(CPDF_Annot::Subtype::SCREEN) ==
106 "CPDF_Annot::SCREEN value mismatch");
107static_assert(static_cast<int>(CPDF_Annot::Subtype::PRINTERMARK) ==
109 "CPDF_Annot::PRINTERMARK value mismatch");
110static_assert(static_cast<int>(CPDF_Annot::Subtype::TRAPNET) ==
112 "CPDF_Annot::TRAPNET value mismatch");
113static_assert(static_cast<int>(CPDF_Annot::Subtype::WATERMARK) ==
115 "CPDF_Annot::WATERMARK value mismatch");
116static_assert(static_cast<int>(CPDF_Annot::Subtype::THREED) ==
118 "CPDF_Annot::THREED value mismatch");
119static_assert(static_cast<int>(CPDF_Annot::Subtype::RICHMEDIA) ==
121 "CPDF_Annot::RICHMEDIA value mismatch");
122static_assert(static_cast<int>(CPDF_Annot::Subtype::XFAWIDGET) ==
124 "CPDF_Annot::XFAWIDGET value mismatch");
125static_assert(static_cast<int>(CPDF_Annot::Subtype::REDACT) ==
127 "CPDF_Annot::REDACT value mismatch");
128
129// These checks ensure the consistency of annotation appearance mode values
130// across core/ and public.
131static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::kNormal) ==
133 "CPDF_Annot::AppearanceMode::Normal value mismatch");
134static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::kRollover) ==
136 "CPDF_Annot::AppearanceMode::Rollover value mismatch");
137static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::kDown) ==
139 "CPDF_Annot::AppearanceMode::Down value mismatch");
140
141// These checks ensure the consistency of dictionary value types across core/
142// and public/.
143static_assert(static_cast<int>(CPDF_Object::Type::kBoolean) ==
145 "CPDF_Object::kBoolean value mismatch");
146static_assert(static_cast<int>(CPDF_Object::Type::kNumber) ==
148 "CPDF_Object::kNumber value mismatch");
149static_assert(static_cast<int>(CPDF_Object::Type::kString) ==
151 "CPDF_Object::kString value mismatch");
152static_assert(static_cast<int>(CPDF_Object::Type::kName) == FPDF_OBJECT_NAME,
153 "CPDF_Object::kName value mismatch");
154static_assert(static_cast<int>(CPDF_Object::Type::kArray) == FPDF_OBJECT_ARRAY,
155 "CPDF_Object::kArray value mismatch");
156static_assert(static_cast<int>(CPDF_Object::Type::kDictionary) ==
158 "CPDF_Object::kDictionary value mismatch");
159static_assert(static_cast<int>(CPDF_Object::Type::kStream) ==
161 "CPDF_Object::kStream value mismatch");
162static_assert(static_cast<int>(CPDF_Object::Type::kNullobj) ==
164 "CPDF_Object::kNullobj value mismatch");
165static_assert(static_cast<int>(CPDF_Object::Type::kReference) ==
167 "CPDF_Object::kReference value mismatch");
168
169// These checks ensure the consistency of annotation additional action event
170// values across core/ and public.
171static_assert(static_cast<int>(CPDF_AAction::kKeyStroke) ==
173 "CPDF_AAction::kKeyStroke value mismatch");
174static_assert(static_cast<int>(CPDF_AAction::kFormat) ==
176 "CPDF_AAction::kFormat value mismatch");
177static_assert(static_cast<int>(CPDF_AAction::kValidate) ==
179 "CPDF_AAction::kValidate value mismatch");
180static_assert(static_cast<int>(CPDF_AAction::kCalculate) ==
182 "CPDF_AAction::kCalculate value mismatch");
183
184bool HasAPStream(CPDF_Dictionary* pAnnotDict) {
185 return !!GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::kNormal);
186}
187
188void UpdateContentStream(CPDF_Form* pForm, CPDF_Stream* pStream) {
189 DCHECK(pForm);
190 DCHECK(pStream);
191
192 CPDF_PageContentGenerator generator(pForm);
193 fxcrt::ostringstream buf;
194 generator.ProcessPageObjects(&buf);
195 pStream->SetDataFromStringstreamAndRemoveFilter(&buf);
196}
197
198void SetQuadPointsAtIndex(CPDF_Array* array,
199 size_t quad_index,
200 const FS_QUADPOINTSF* quad_points) {
201 DCHECK(array);
202 DCHECK(quad_points);
203 DCHECK(IsValidQuadPointsIndex(array, quad_index));
204
205 size_t nIndex = quad_index * 8;
206 array->SetNewAt<CPDF_Number>(nIndex, quad_points->x1);
207 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->y1);
208 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->x2);
209 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->y2);
210 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->x3);
211 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->y3);
212 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->x4);
213 array->SetNewAt<CPDF_Number>(++nIndex, quad_points->y4);
214}
215
216void AppendQuadPoints(CPDF_Array* array, const FS_QUADPOINTSF* quad_points) {
217 DCHECK(quad_points);
218 DCHECK(array);
219
220 array->AppendNew<CPDF_Number>(quad_points->x1);
221 array->AppendNew<CPDF_Number>(quad_points->y1);
222 array->AppendNew<CPDF_Number>(quad_points->x2);
223 array->AppendNew<CPDF_Number>(quad_points->y2);
224 array->AppendNew<CPDF_Number>(quad_points->x3);
225 array->AppendNew<CPDF_Number>(quad_points->y3);
226 array->AppendNew<CPDF_Number>(quad_points->x4);
227 array->AppendNew<CPDF_Number>(quad_points->y4);
228}
229
230void UpdateBBox(CPDF_Dictionary* annot_dict) {
231 DCHECK(annot_dict);
232 // Update BBox entry in appearance stream based on the bounding rectangle
233 // of the annotation's quadpoints.
234 RetainPtr<CPDF_Stream> pStream =
235 GetAnnotAP(annot_dict, CPDF_Annot::AppearanceMode::kNormal);
236 if (pStream) {
237 CFX_FloatRect boundingRect =
239 if (boundingRect.Contains(pStream->GetDict()->GetRectFor("BBox")))
240 pStream->GetMutableDict()->SetRectFor("BBox", boundingRect);
241 }
242}
243
244const CPDF_Dictionary* GetAnnotDictFromFPDFAnnotation(
245 const FPDF_ANNOTATION annot) {
247 return context ? context->GetAnnotDict() : nullptr;
248}
249
250RetainPtr<CPDF_Dictionary> GetMutableAnnotDictFromFPDFAnnotation(
251 FPDF_ANNOTATION annot) {
253 return context ? context->GetMutableAnnotDict() : nullptr;
254}
255
256RetainPtr<CPDF_Dictionary> SetExtGStateInResourceDict(
257 CPDF_Document* pDoc,
258 const CPDF_Dictionary* pAnnotDict,
259 const ByteString& sBlendMode) {
260 auto pGSDict =
261 pdfium::MakeRetain<CPDF_Dictionary>(pAnnotDict->GetByteStringPool());
262
263 // ExtGState represents a graphics state parameter dictionary.
264 pGSDict->SetNewFor<CPDF_Name>("Type", "ExtGState");
265
266 // CA respresents current stroking alpha specifying constant opacity
267 // value that should be used in transparent imaging model.
268 float fOpacity = pAnnotDict->GetFloatFor("CA");
269
270 pGSDict->SetNewFor<CPDF_Number>("CA", fOpacity);
271
272 // ca represents fill color alpha specifying constant opacity
273 // value that should be used in transparent imaging model.
274 pGSDict->SetNewFor<CPDF_Number>("ca", fOpacity);
275
276 // AIS represents alpha source flag specifying whether current alpha
277 // constant shall be interpreted as shape value (true) or opacity value
278 // (false).
279 pGSDict->SetNewFor<CPDF_Boolean>("AIS", false);
280
281 // BM represents Blend Mode
282 pGSDict->SetNewFor<CPDF_Name>("BM", sBlendMode);
283
284 auto pExtGStateDict =
285 pdfium::MakeRetain<CPDF_Dictionary>(pAnnotDict->GetByteStringPool());
286
287 pExtGStateDict->SetFor("GS", pGSDict);
288
289 auto pResourceDict = pDoc->New<CPDF_Dictionary>();
290 pResourceDict->SetFor("ExtGState", pExtGStateDict);
291 return pResourceDict;
292}
293
294CPDF_FormField* GetFormField(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot) {
295 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
296 if (!pAnnotDict)
297 return nullptr;
298
299 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
300 if (!pForm)
301 return nullptr;
302
304 return pPDFForm->GetFieldByDict(pAnnotDict);
305}
306
307// If `allowed_types` is empty, then match all types.
308const CPDFSDK_Widget* GetWidgetOfTypes(
309 FPDF_FORMHANDLE hHandle,
310 FPDF_ANNOTATION annot,
311 pdfium::span<const CPDF_FormField::Type> allowed_types) {
312 const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
313 if (!annot_dict) {
314 return nullptr;
315 }
316
317 CPDFSDK_InteractiveForm* form = FormHandleToInteractiveForm(hHandle);
318 if (!form) {
319 return nullptr;
320 }
321
323 CPDF_FormField* form_field = pdf_form->GetFieldByDict(annot_dict);
324 if (!form_field) {
325 return nullptr;
326 }
327
328 if (!allowed_types.empty()) {
329 if (!pdfium::Contains(allowed_types, form_field->GetType())) {
330 return nullptr;
331 }
332 }
333
334 CPDF_FormControl* form_control = pdf_form->GetControlByDict(annot_dict);
335 return form_control ? form->GetWidget(form_control) : nullptr;
336}
337
338const CPDFSDK_Widget* GetRadioButtonOrCheckBoxWidget(FPDF_FORMHANDLE handle,
339 FPDF_ANNOTATION annot) {
340 constexpr std::array<CPDF_FormField::Type, 2> kAllowedTypes = {
342 return GetWidgetOfTypes(handle, annot, kAllowedTypes);
343}
344
345RetainPtr<const CPDF_Array> GetInkList(FPDF_ANNOTATION annot) {
346 FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
347 if (subtype != FPDF_ANNOT_INK)
348 return nullptr;
349
350 const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
351 return annot_dict ? annot_dict->GetArrayFor(pdfium::annotation::kInkList)
352 : nullptr;
353}
354
355} // namespace
356
358FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype) {
359 // The supported subtypes must also be communicated in the user doc.
360 switch (subtype) {
365 case FPDF_ANNOT_INK:
366 case FPDF_ANNOT_LINK:
367 case FPDF_ANNOT_POPUP:
370 case FPDF_ANNOT_STAMP:
372 case FPDF_ANNOT_TEXT:
374 return true;
375 default:
376 return false;
377 }
378}
379
380FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
381FPDFPage_CreateAnnot(FPDF_PAGE page, FPDF_ANNOTATION_SUBTYPE subtype) {
382 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
383 if (!pPage || !FPDFAnnot_IsSupportedSubtype(subtype))
384 return nullptr;
385
386 auto pDict = pPage->GetDocument()->New<CPDF_Dictionary>();
387 pDict->SetNewFor<CPDF_Name>(pdfium::annotation::kType, "Annot");
388 pDict->SetNewFor<CPDF_Name>(pdfium::annotation::kSubtype,
390 static_cast<CPDF_Annot::Subtype>(subtype)));
391 auto pNewAnnot =
392 std::make_unique<CPDF_AnnotContext>(pDict, IPDFPageFromFPDFPage(page));
393
394 RetainPtr<CPDF_Array> pAnnotList = pPage->GetOrCreateAnnotsArray();
395 pAnnotList->Append(pDict);
396
397 // Caller takes ownership.
398 return FPDFAnnotationFromCPDFAnnotContext(pNewAnnot.release());
399}
400
402 const CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
403 if (!pPage)
404 return 0;
405
406 RetainPtr<const CPDF_Array> pAnnots = pPage->GetAnnotsArray();
407 return pAnnots ? fxcrt::CollectionSize<int>(*pAnnots) : 0;
408}
409
410FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFPage_GetAnnot(FPDF_PAGE page,
411 int index) {
412 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
413 if (!pPage || index < 0)
414 return nullptr;
415
416 RetainPtr<CPDF_Array> pAnnots = pPage->GetMutableAnnotsArray();
417 if (!pAnnots || static_cast<size_t>(index) >= pAnnots->size())
418 return nullptr;
419
421 ToDictionary(pAnnots->GetMutableDirectObjectAt(index));
422 if (!pDict)
423 return nullptr;
424
425 auto pNewAnnot = std::make_unique<CPDF_AnnotContext>(
426 std::move(pDict), IPDFPageFromFPDFPage(page));
427
428 // Caller takes ownership.
429 return FPDFAnnotationFromCPDFAnnotContext(pNewAnnot.release());
430}
431
433 FPDF_ANNOTATION annot) {
434 const CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
435 if (!pPage)
436 return -1;
437
438 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
439 if (!pAnnotDict)
440 return -1;
441
442 RetainPtr<const CPDF_Array> pAnnots = pPage->GetAnnotsArray();
443 if (!pAnnots)
444 return -1;
445
446 CPDF_ArrayLocker locker(pAnnots);
447 auto it = std::find_if(locker.begin(), locker.end(),
448 [pAnnotDict](const RetainPtr<CPDF_Object>& candidate) {
449 return candidate->GetDirect() == pAnnotDict;
450 });
451
452 if (it == locker.end())
453 return -1;
454
455 return pdfium::checked_cast<int>(it - locker.begin());
456}
457
458FPDF_EXPORT void FPDF_CALLCONV FPDFPage_CloseAnnot(FPDF_ANNOTATION annot) {
460}
461
463 int index) {
464 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
465 if (!pPage || index < 0)
466 return false;
467
468 RetainPtr<CPDF_Array> pAnnots = pPage->GetMutableAnnotsArray();
469 if (!pAnnots || static_cast<size_t>(index) >= pAnnots->size())
470 return false;
471
472 pAnnots->RemoveAt(index);
473 return true;
474}
475
476FPDF_EXPORT FPDF_ANNOTATION_SUBTYPE FPDF_CALLCONV
477FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) {
478 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
479 if (!pAnnotDict)
480 return FPDF_ANNOT_UNKNOWN;
481
482 return static_cast<FPDF_ANNOTATION_SUBTYPE>(CPDF_Annot::StringToAnnotSubtype(
484}
485
487FPDFAnnot_IsObjectSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype) {
488 // The supported subtypes must also be communicated in the user doc.
489 return subtype == FPDF_ANNOT_INK || subtype == FPDF_ANNOT_STAMP;
490}
491
493FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj) {
496 if (!pAnnot || !pAnnot->HasForm() || !pObj)
497 return false;
498
499 // Check that the annotation type is supported by this method.
501 return false;
502
503 // Check that the annotation already has an appearance stream, since an
504 // existing object is to be updated.
505 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
506 RetainPtr<CPDF_Stream> pStream =
507 GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
508 if (!pStream)
509 return false;
510
511 // Check that the object is already in this annotation's object list.
512 CPDF_Form* pForm = pAnnot->GetForm();
513 if (!pdfium::Contains(*pForm, fxcrt::MakeFakeUniquePtr(pObj)))
514 return false;
515
516 // Update the content stream data in the annotation's AP stream.
517 UpdateContentStream(pForm, pStream.Get());
518 return true;
519}
520
522 const FS_POINTF* points,
523 size_t point_count) {
524 if (FPDFAnnot_GetSubtype(annot) != FPDF_ANNOT_INK || !points ||
525 point_count == 0 ||
526 !pdfium::IsValueInRangeForNumericType<int32_t>(point_count)) {
527 return -1;
528 }
529
530 RetainPtr<CPDF_Dictionary> annot_dict =
531 GetMutableAnnotDictFromFPDFAnnotation(annot);
532 RetainPtr<CPDF_Array> inklist = annot_dict->GetOrCreateArrayFor("InkList");
533 FX_SAFE_SIZE_T safe_ink_size = inklist->size();
534 safe_ink_size += 1;
535 if (!safe_ink_size.IsValid<int32_t>())
536 return -1;
537
538 // SAFETY: required from caller.
539 auto points_span = UNSAFE_BUFFERS(pdfium::make_span(points, point_count));
540 auto ink_coord_list = inklist->AppendNew<CPDF_Array>();
541 for (const auto& point : points_span) {
542 ink_coord_list->AppendNew<CPDF_Number>(point.x);
543 ink_coord_list->AppendNew<CPDF_Number>(point.y);
544 }
545 return static_cast<int>(inklist->size() - 1);
546}
547
549FPDFAnnot_RemoveInkList(FPDF_ANNOTATION annot) {
551 return false;
552
553 RetainPtr<CPDF_Dictionary> annot_dict =
554 CPDFAnnotContextFromFPDFAnnotation(annot)->GetMutableAnnotDict();
555 annot_dict->RemoveFor("InkList");
556 return true;
557}
558
560FPDFAnnot_AppendObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj) {
563 if (!pAnnot || !pObj)
564 return false;
565
566 // Check that the annotation type is supported by this method.
568 return false;
569
570 // If the annotation does not have an AP stream yet, generate and set it.
571 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
572 RetainPtr<CPDF_Stream> pStream =
573 GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
574 if (!pStream) {
576 pAnnotDict.Get());
577 pStream = GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
578 if (!pStream)
579 return false;
580 }
581
582 // Get the annotation's corresponding form object for parsing its AP stream.
583 if (!pAnnot->HasForm())
584 pAnnot->SetForm(pStream);
585
586 // Check that the object did not come from the same annotation. If this check
587 // succeeds, then it is assumed that the object came from
588 // FPDFPageObj_CreateNew{Path|Rect}() or FPDFPageObj_New{Text|Image}Obj().
589 // Note that an object that came from a different annotation must not be
590 // passed here, since an object cannot belong to more than one annotation.
591 CPDF_Form* pForm = pAnnot->GetForm();
592 if (pdfium::Contains(*pForm, fxcrt::MakeFakeUniquePtr(pObj)))
593 return false;
594
595 // Append the object to the object list.
596 pForm->AppendPageObject(pdfium::WrapUnique(pObj));
597
598 // Set the content stream data in the annotation's AP stream.
599 UpdateContentStream(pForm, pStream.Get());
600 return true;
601}
602
605 if (!pAnnot)
606 return 0;
607
608 if (!pAnnot->HasForm()) {
609 RetainPtr<CPDF_Dictionary> pDict = pAnnot->GetMutableAnnotDict();
610 RetainPtr<CPDF_Stream> pStream =
611 GetAnnotAP(pDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
612 if (!pStream)
613 return 0;
614
615 pAnnot->SetForm(std::move(pStream));
616 }
617 return pdfium::checked_cast<int>(pAnnot->GetForm()->GetPageObjectCount());
618}
619
620FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
621FPDFAnnot_GetObject(FPDF_ANNOTATION annot, int index) {
623 if (!pAnnot || index < 0)
624 return nullptr;
625
626 if (!pAnnot->HasForm()) {
627 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
628 RetainPtr<CPDF_Stream> pStream =
629 GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
630 if (!pStream)
631 return nullptr;
632
633 pAnnot->SetForm(std::move(pStream));
634 }
635
636 return FPDFPageObjectFromCPDFPageObject(
637 pAnnot->GetForm()->GetPageObjectByIndex(index));
638}
639
641FPDFAnnot_RemoveObject(FPDF_ANNOTATION annot, int index) {
643 if (!pAnnot || !pAnnot->HasForm() || index < 0)
644 return false;
645
646 // Check that the annotation type is supported by this method.
648 return false;
649
650 // Check that the annotation already has an appearance stream, since an
651 // existing object is to be deleted.
652 RetainPtr<CPDF_Dictionary> pAnnotDict = pAnnot->GetMutableAnnotDict();
653 RetainPtr<CPDF_Stream> pStream =
654 GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
655 if (!pStream)
656 return false;
657
658 if (!pAnnot->GetForm()->ErasePageObjectAtIndex(index))
659 return false;
660
661 UpdateContentStream(pAnnot->GetForm(), pStream.Get());
662 return true;
663}
664
665FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetColor(FPDF_ANNOTATION annot,
666 FPDFANNOT_COLORTYPE type,
667 unsigned int R,
668 unsigned int G,
669 unsigned int B,
670 unsigned int A) {
671 RetainPtr<CPDF_Dictionary> pAnnotDict =
672 GetMutableAnnotDictFromFPDFAnnotation(annot);
673
674 if (!pAnnotDict || R > 255 || G > 255 || B > 255 || A > 255)
675 return false;
676
677 // For annotations with their appearance streams already defined, the path
678 // stream's own color definitions take priority over the annotation color
679 // definitions set by this method, hence this method will simply fail.
680 if (HasAPStream(pAnnotDict.Get()))
681 return false;
682
683 // Set the opacity of the annotation.
684 pAnnotDict->SetNewFor<CPDF_Number>("CA", A / 255.f);
685
686 // Set the color of the annotation.
687 ByteString key = type == FPDFANNOT_COLORTYPE_InteriorColor ? "IC" : "C";
688 RetainPtr<CPDF_Array> pColor = pAnnotDict->GetMutableArrayFor(key);
689 if (pColor)
690 pColor->Clear();
691 else
692 pColor = pAnnotDict->SetNewFor<CPDF_Array>(key);
693
694 pColor->AppendNew<CPDF_Number>(R / 255.f);
695 pColor->AppendNew<CPDF_Number>(G / 255.f);
696 pColor->AppendNew<CPDF_Number>(B / 255.f);
697
698 return true;
699}
700
701FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetColor(FPDF_ANNOTATION annot,
702 FPDFANNOT_COLORTYPE type,
703 unsigned int* R,
704 unsigned int* G,
705 unsigned int* B,
706 unsigned int* A) {
707 RetainPtr<CPDF_Dictionary> pAnnotDict =
708 GetMutableAnnotDictFromFPDFAnnotation(annot);
709
710 if (!pAnnotDict || !R || !G || !B || !A)
711 return false;
712
713 // For annotations with their appearance streams already defined, the path
714 // stream's own color definitions take priority over the annotation color
715 // definitions retrieved by this method, hence this method will simply fail.
716 if (HasAPStream(pAnnotDict.Get()))
717 return false;
718
719 RetainPtr<const CPDF_Array> pColor = pAnnotDict->GetArrayFor(
720 type == FPDFANNOT_COLORTYPE_InteriorColor ? "IC" : "C");
721 *A = (pAnnotDict->KeyExist("CA") ? pAnnotDict->GetFloatFor("CA") : 1) * 255.f;
722 if (!pColor) {
723 // Use default color. The default colors must be consistent with the ones
724 // used to generate AP. See calls to GetColorStringWithDefault() in
725 // CPDF_GenerateAP::Generate*AP().
726 if (pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) == "Highlight") {
727 *R = 255;
728 *G = 255;
729 *B = 0;
730 } else {
731 *R = 0;
732 *G = 0;
733 *B = 0;
734 }
735 return true;
736 }
737
739 switch (color.nColorType) {
741 *R = color.fColor1 * 255.f;
742 *G = color.fColor2 * 255.f;
743 *B = color.fColor3 * 255.f;
744 break;
746 *R = 255.f * color.fColor1;
747 *G = 255.f * color.fColor1;
748 *B = 255.f * color.fColor1;
749 break;
751 *R = 255.f * (1 - color.fColor1) * (1 - color.fColor4);
752 *G = 255.f * (1 - color.fColor2) * (1 - color.fColor4);
753 *B = 255.f * (1 - color.fColor3) * (1 - color.fColor4);
754 break;
756 *R = 0;
757 *G = 0;
758 *B = 0;
759 break;
760 }
761 return true;
762}
763
765FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot) {
766 if (!annot)
767 return false;
768
769 FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
770 return subtype == FPDF_ANNOT_LINK || subtype == FPDF_ANNOT_HIGHLIGHT ||
771 subtype == FPDF_ANNOT_UNDERLINE || subtype == FPDF_ANNOT_SQUIGGLY ||
772 subtype == FPDF_ANNOT_STRIKEOUT;
773}
774
776FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot,
777 size_t quad_index,
778 const FS_QUADPOINTSF* quad_points) {
779 if (!FPDFAnnot_HasAttachmentPoints(annot) || !quad_points)
780 return false;
781
782 RetainPtr<CPDF_Dictionary> pAnnotDict =
783 CPDFAnnotContextFromFPDFAnnotation(annot)->GetMutableAnnotDict();
784 RetainPtr<CPDF_Array> pQuadPointsArray =
785 GetMutableQuadPointsArrayFromDictionary(pAnnotDict.Get());
786 if (!IsValidQuadPointsIndex(pQuadPointsArray.Get(), quad_index))
787 return false;
788
789 SetQuadPointsAtIndex(pQuadPointsArray.Get(), quad_index, quad_points);
790 UpdateBBox(pAnnotDict.Get());
791 return true;
792}
793
796 const FS_QUADPOINTSF* quad_points) {
797 if (!FPDFAnnot_HasAttachmentPoints(annot) || !quad_points)
798 return false;
799
800 RetainPtr<CPDF_Dictionary> pAnnotDict =
801 CPDFAnnotContextFromFPDFAnnotation(annot)->GetMutableAnnotDict();
802 RetainPtr<CPDF_Array> pQuadPointsArray =
803 GetMutableQuadPointsArrayFromDictionary(pAnnotDict.Get());
804 if (!pQuadPointsArray)
805 pQuadPointsArray = AddQuadPointsArrayToDictionary(pAnnotDict.Get());
806 AppendQuadPoints(pQuadPointsArray.Get(), quad_points);
807 UpdateBBox(pAnnotDict.Get());
808 return true;
809}
810
812FPDFAnnot_CountAttachmentPoints(FPDF_ANNOTATION annot) {
814 return 0;
815
816 const CPDF_Dictionary* pAnnotDict =
818 RetainPtr<const CPDF_Array> pArray =
819 GetQuadPointsArrayFromDictionary(pAnnotDict);
820 return pArray ? pArray->size() / 8 : 0;
821}
822
824FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot,
825 size_t quad_index,
826 FS_QUADPOINTSF* quad_points) {
827 if (!FPDFAnnot_HasAttachmentPoints(annot) || !quad_points)
828 return false;
829
830 const CPDF_Dictionary* pAnnotDict =
832 RetainPtr<const CPDF_Array> pArray =
833 GetQuadPointsArrayFromDictionary(pAnnotDict);
834 if (!pArray)
835 return false;
836
837 return GetQuadPointsAtIndex(std::move(pArray), quad_index, quad_points);
838}
839
840FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetRect(FPDF_ANNOTATION annot,
841 const FS_RECTF* rect) {
842 RetainPtr<CPDF_Dictionary> pAnnotDict =
843 GetMutableAnnotDictFromFPDFAnnotation(annot);
844 if (!pAnnotDict || !rect)
845 return false;
846
848
849 // Update the "Rect" entry in the annotation dictionary.
850 pAnnotDict->SetRectFor(pdfium::annotation::kRect, newRect);
851
852 // If the annotation's appearance stream is defined, the annotation is of a
853 // type that does not have quadpoints, and the new rectangle is bigger than
854 // the current bounding box, then update the "BBox" entry in the AP
855 // dictionary too, since its "BBox" entry comes from annotation dictionary's
856 // "Rect" entry.
858 return true;
859
860 RetainPtr<CPDF_Stream> pStream =
861 GetAnnotAP(pAnnotDict.Get(), CPDF_Annot::AppearanceMode::kNormal);
862 if (pStream && newRect.Contains(pStream->GetDict()->GetRectFor("BBox")))
863 pStream->GetMutableDict()->SetRectFor("BBox", newRect);
864 return true;
865}
866
867FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetRect(FPDF_ANNOTATION annot,
868 FS_RECTF* rect) {
869 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
870 if (!pAnnotDict || !rect)
871 return false;
872
875 return true;
876}
877
878FPDF_EXPORT unsigned long FPDF_CALLCONV
879FPDFAnnot_GetVertices(FPDF_ANNOTATION annot,
880 FS_POINTF* buffer,
881 unsigned long length) {
882 FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
883 if (subtype != FPDF_ANNOT_POLYGON && subtype != FPDF_ANNOT_POLYLINE)
884 return 0;
885
886 const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
887 if (!annot_dict)
888 return 0;
889
890 RetainPtr<const CPDF_Array> vertices =
891 annot_dict->GetArrayFor(pdfium::annotation::kVertices);
892 if (!vertices)
893 return 0;
894
895 // Truncate to an even number.
896 const unsigned long points_len =
897 fxcrt::CollectionSize<unsigned long>(*vertices) / 2;
898 if (buffer && length >= points_len) {
899 // SAFETY: required from caller.
900 auto buffer_span = UNSAFE_BUFFERS(pdfium::make_span(buffer, length));
901 for (unsigned long i = 0; i < points_len; ++i) {
902 buffer_span[i].x = vertices->GetFloatAt(i * 2);
903 buffer_span[i].y = vertices->GetFloatAt(i * 2 + 1);
904 }
905 }
906 return points_len;
907}
908
909FPDF_EXPORT unsigned long FPDF_CALLCONV
910FPDFAnnot_GetInkListCount(FPDF_ANNOTATION annot) {
911 RetainPtr<const CPDF_Array> ink_list = GetInkList(annot);
912 return ink_list ? fxcrt::CollectionSize<unsigned long>(*ink_list) : 0;
913}
914
915FPDF_EXPORT unsigned long FPDF_CALLCONV
916FPDFAnnot_GetInkListPath(FPDF_ANNOTATION annot,
917 unsigned long path_index,
918 FS_POINTF* buffer,
919 unsigned long length) {
920 RetainPtr<const CPDF_Array> ink_list = GetInkList(annot);
921 if (!ink_list)
922 return 0;
923
924 RetainPtr<const CPDF_Array> path = ink_list->GetArrayAt(path_index);
925 if (!path)
926 return 0;
927
928 // Truncate to an even number.
929 const unsigned long points_len =
930 fxcrt::CollectionSize<unsigned long>(*path) / 2;
931 if (buffer && length >= points_len) {
932 // SAFETY: required from caller.
933 auto buffer_span = UNSAFE_BUFFERS(pdfium::make_span(buffer, length));
934 for (unsigned long i = 0; i < points_len; ++i) {
935 buffer_span[i].x = path->GetFloatAt(i * 2);
936 buffer_span[i].y = path->GetFloatAt(i * 2 + 1);
937 }
938 }
939 return points_len;
940}
941
942FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetLine(FPDF_ANNOTATION annot,
943 FS_POINTF* start,
944 FS_POINTF* end) {
945 if (!start || !end)
946 return false;
947
948 FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
949 if (subtype != FPDF_ANNOT_LINE)
950 return false;
951
952 const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
953 if (!annot_dict)
954 return false;
955
956 RetainPtr<const CPDF_Array> line =
957 annot_dict->GetArrayFor(pdfium::annotation::kL);
958 if (!line || line->size() < 4)
959 return false;
960
961 start->x = line->GetFloatAt(0);
962 start->y = line->GetFloatAt(1);
963 end->x = line->GetFloatAt(2);
964 end->y = line->GetFloatAt(3);
965 return true;
966}
967
968FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetBorder(FPDF_ANNOTATION annot,
969 float horizontal_radius,
970 float vertical_radius,
971 float border_width) {
972 RetainPtr<CPDF_Dictionary> annot_dict =
973 GetMutableAnnotDictFromFPDFAnnotation(annot);
974 if (!annot_dict)
975 return false;
976
977 // Remove the appearance stream. Otherwise PDF viewers will render that and
978 // not use the border values.
979 annot_dict->RemoveFor(pdfium::annotation::kAP);
980
981 auto border = annot_dict->SetNewFor<CPDF_Array>(pdfium::annotation::kBorder);
982 border->AppendNew<CPDF_Number>(horizontal_radius);
983 border->AppendNew<CPDF_Number>(vertical_radius);
984 border->AppendNew<CPDF_Number>(border_width);
985 return true;
986}
987
989FPDFAnnot_GetBorder(FPDF_ANNOTATION annot,
990 float* horizontal_radius,
991 float* vertical_radius,
992 float* border_width) {
993 if (!horizontal_radius || !vertical_radius || !border_width)
994 return false;
995
996 const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
997 if (!annot_dict)
998 return false;
999
1000 RetainPtr<const CPDF_Array> border =
1001 annot_dict->GetArrayFor(pdfium::annotation::kBorder);
1002 if (!border || border->size() < 3)
1003 return false;
1004
1005 *horizontal_radius = border->GetFloatAt(0);
1006 *vertical_radius = border->GetFloatAt(1);
1007 *border_width = border->GetFloatAt(2);
1008 return true;
1009}
1010
1011FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_HasKey(FPDF_ANNOTATION annot,
1012 FPDF_BYTESTRING key) {
1013 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
1014 return pAnnotDict && pAnnotDict->KeyExist(key);
1015}
1016
1017FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV
1018FPDFAnnot_GetValueType(FPDF_ANNOTATION annot, FPDF_BYTESTRING key) {
1019 if (!FPDFAnnot_HasKey(annot, key))
1020 return FPDF_OBJECT_UNKNOWN;
1021
1023 RetainPtr<const CPDF_Object> pObj = pAnnot->GetAnnotDict()->GetObjectFor(key);
1024 return pObj ? pObj->GetType() : FPDF_OBJECT_UNKNOWN;
1025}
1026
1027FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1028FPDFAnnot_SetStringValue(FPDF_ANNOTATION annot,
1029 FPDF_BYTESTRING key,
1030 FPDF_WIDESTRING value) {
1031 RetainPtr<CPDF_Dictionary> pAnnotDict =
1032 GetMutableAnnotDictFromFPDFAnnotation(annot);
1033 if (!pAnnotDict)
1034 return false;
1035
1036 // SAFETY: required from caller.
1037 pAnnotDict->SetNewFor<CPDF_String>(
1038 key, UNSAFE_BUFFERS(WideStringFromFPDFWideString(value).AsStringView()));
1039 return true;
1040}
1041
1042FPDF_EXPORT unsigned long FPDF_CALLCONV
1043FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot,
1044 FPDF_BYTESTRING key,
1045 FPDF_WCHAR* buffer,
1046 unsigned long buflen) {
1047 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
1048 if (!pAnnotDict) {
1049 return 0;
1050 }
1051 // SAFETY: required from caller.
1052 return Utf16EncodeMaybeCopyAndReturnLength(
1053 pAnnotDict->GetUnicodeTextFor(key),
1054 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1055}
1056
1057FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1058FPDFAnnot_GetNumberValue(FPDF_ANNOTATION annot,
1059 FPDF_BYTESTRING key,
1060 float* value) {
1061 if (!value)
1062 return false;
1063
1064 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
1065 if (!pAnnotDict)
1066 return false;
1067
1068 RetainPtr<const CPDF_Object> p = pAnnotDict->GetObjectFor(key);
1069 if (!p || p->GetType() != FPDF_OBJECT_NUMBER)
1070 return false;
1071
1072 *value = p->GetNumber();
1073 return true;
1074}
1075
1076FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1077FPDFAnnot_SetAP(FPDF_ANNOTATION annot,
1078 FPDF_ANNOT_APPEARANCEMODE appearanceMode,
1079 FPDF_WIDESTRING value) {
1080 RetainPtr<CPDF_Dictionary> pAnnotDict =
1081 GetMutableAnnotDictFromFPDFAnnotation(annot);
1082 if (!pAnnotDict)
1083 return false;
1084
1085 if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT)
1086 return false;
1087
1088 static constexpr auto kModeKeyForMode =
1089 fxcrt::ToArray<const char*>({"N", "R", "D"});
1090 static_assert(kModeKeyForMode.size() == FPDF_ANNOT_APPEARANCEMODE_COUNT,
1091 "length of kModeKeyForMode should be equal to "
1092 "FPDF_ANNOT_APPEARANCEMODE_COUNT");
1093
1094 const char* mode_key = kModeKeyForMode[appearanceMode];
1095
1096 RetainPtr<CPDF_Dictionary> pApDict =
1097 pAnnotDict->GetMutableDictFor(pdfium::annotation::kAP);
1098
1099 // If `value` is null, then the action is to remove.
1100 if (!value) {
1101 if (pApDict) {
1102 if (appearanceMode == FPDF_ANNOT_APPEARANCEMODE_NORMAL) {
1103 pAnnotDict->RemoveFor(pdfium::annotation::kAP);
1104 } else {
1105 pApDict->RemoveFor(mode_key);
1106 }
1107 }
1108 return true;
1109 }
1110
1111 // Otherwise, add/update when `value` is non-null.
1112 //
1113 // Annotation object's non-empty bounding rect will be used as the /BBox
1114 // for the associated /XObject object
1115 CFX_FloatRect rect = pAnnotDict->GetRectFor(pdfium::annotation::kRect);
1116 constexpr float kMinSize = 0.000001f;
1117 if (rect.Width() < kMinSize || rect.Height() < kMinSize) {
1118 return false;
1119 }
1120
1122
1123 CPDF_Document* pDoc = pAnnotContext->GetPage()->GetDocument();
1124 if (!pDoc) {
1125 return false;
1126 }
1127
1128 auto stream_dict = pdfium::MakeRetain<CPDF_Dictionary>();
1129 stream_dict->SetNewFor<CPDF_Name>(pdfium::annotation::kType, "XObject");
1130 stream_dict->SetNewFor<CPDF_Name>(pdfium::annotation::kSubtype, "Form");
1131 stream_dict->SetRectFor("BBox", rect);
1132 // Transparency values are specified in range [0.0f, 1.0f]. We are strictly
1133 // checking for value < 1 and not <= 1 so that the output PDF size does not
1134 // unnecessarily bloat up by creating a new dictionary in case of solid
1135 // color.
1136 if (pAnnotDict->KeyExist("CA") && pAnnotDict->GetFloatFor("CA") < 1.0f) {
1137 stream_dict->SetFor("Resources", SetExtGStateInResourceDict(
1138 pDoc, pAnnotDict.Get(), "Normal"));
1139 }
1140 // SAFETY: required from caller.
1141 ByteString new_stream_data = PDF_EncodeText(
1142 UNSAFE_BUFFERS(WideStringFromFPDFWideString(value).AsStringView()));
1143 auto new_stream = pDoc->NewIndirect<CPDF_Stream>(std::move(stream_dict));
1144 new_stream->SetData(new_stream_data.unsigned_span());
1145
1146 // Storing reference to indirect object in annotation's AP
1147 if (!pApDict) {
1148 pApDict = pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
1149 }
1150 pApDict->SetNewFor<CPDF_Reference>(mode_key, pDoc, new_stream->GetObjNum());
1151
1152 return true;
1153}
1154
1155FPDF_EXPORT unsigned long FPDF_CALLCONV
1156FPDFAnnot_GetAP(FPDF_ANNOTATION annot,
1157 FPDF_ANNOT_APPEARANCEMODE appearanceMode,
1158 FPDF_WCHAR* buffer,
1159 unsigned long buflen) {
1160 RetainPtr<CPDF_Dictionary> pAnnotDict =
1161 GetMutableAnnotDictFromFPDFAnnotation(annot);
1162 if (!pAnnotDict)
1163 return 0;
1164
1165 if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT)
1166 return 0;
1167
1169 static_cast<CPDF_Annot::AppearanceMode>(appearanceMode);
1170
1171 RetainPtr<CPDF_Stream> pStream = GetAnnotAPNoFallback(pAnnotDict.Get(), mode);
1172 // SAFETY: required from caller.
1173 return Utf16EncodeMaybeCopyAndReturnLength(
1174 pStream ? pStream->GetUnicodeText() : WideString(),
1175 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1176}
1177
1178FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
1179FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_BYTESTRING key) {
1181 if (!pAnnot)
1182 return nullptr;
1183
1184 RetainPtr<CPDF_Dictionary> pLinkedDict =
1185 pAnnot->GetMutableAnnotDict()->GetMutableDictFor(key);
1186 if (!pLinkedDict || pLinkedDict->GetNameFor("Type") != "Annot")
1187 return nullptr;
1188
1189 auto pLinkedAnnot = std::make_unique<CPDF_AnnotContext>(
1190 std::move(pLinkedDict), pAnnot->GetPage());
1191
1192 // Caller takes ownership.
1193 return FPDFAnnotationFromCPDFAnnotContext(pLinkedAnnot.release());
1194}
1195
1197 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
1198 return pAnnotDict ? pAnnotDict->GetIntegerFor(pdfium::annotation::kF)
1200}
1201
1202FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetFlags(FPDF_ANNOTATION annot,
1203 int flags) {
1204 RetainPtr<CPDF_Dictionary> pAnnotDict =
1205 GetMutableAnnotDictFromFPDFAnnotation(annot);
1206 if (!pAnnotDict)
1207 return false;
1208
1209 pAnnotDict->SetNewFor<CPDF_Number>(pdfium::annotation::kF, flags);
1210 return true;
1211}
1212
1214FPDFAnnot_GetFormFieldFlags(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot) {
1215 CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1216 return pFormField ? pFormField->GetFieldFlags() : FPDF_FORMFLAG_NONE;
1217}
1218
1219FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
1220FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
1221 FPDF_PAGE page,
1222 const FS_POINTF* point) {
1223 if (!point)
1224 return nullptr;
1225
1226 const CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
1227 if (!pForm)
1228 return nullptr;
1229
1230 const CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
1231 if (!pPage)
1232 return nullptr;
1233
1234 const CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
1235 int annot_index = -1;
1236 const CPDF_FormControl* pFormCtrl = pPDFForm->GetControlAtPoint(
1237 pPage, CFXPointFFromFSPointF(*point), &annot_index);
1238 if (!pFormCtrl || annot_index == -1)
1239 return nullptr;
1240 return FPDFPage_GetAnnot(page, annot_index);
1241}
1242
1243FPDF_EXPORT unsigned long FPDF_CALLCONV
1244FPDFAnnot_GetFormFieldName(FPDF_FORMHANDLE hHandle,
1245 FPDF_ANNOTATION annot,
1246 FPDF_WCHAR* buffer,
1247 unsigned long buflen) {
1248 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1249 if (!pFormField) {
1250 return 0;
1251 }
1252 // SAFETY: required from caller.
1253 return Utf16EncodeMaybeCopyAndReturnLength(
1254 pFormField->GetFullName(),
1255 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1256}
1257
1259FPDFAnnot_GetFormFieldType(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot) {
1260 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1261 return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1;
1262}
1263
1264FPDF_EXPORT unsigned long FPDF_CALLCONV
1266 FPDF_ANNOTATION annot,
1267 int event,
1268 FPDF_WCHAR* buffer,
1269 unsigned long buflen) {
1270 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1271 if (!pFormField)
1272 return 0;
1273
1274 if (event < FPDF_ANNOT_AACTION_KEY_STROKE ||
1276 return 0;
1277 }
1278
1279 auto type = static_cast<CPDF_AAction::AActionType>(event);
1280 CPDF_AAction additional_action = pFormField->GetAdditionalAction();
1281 CPDF_Action action = additional_action.GetAction(type);
1282 // SAFETY: required from caller.
1283 return Utf16EncodeMaybeCopyAndReturnLength(
1284 action.GetJavaScript(),
1285 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1286}
1287
1288FPDF_EXPORT unsigned long FPDF_CALLCONV
1290 FPDF_ANNOTATION annot,
1291 FPDF_WCHAR* buffer,
1292 unsigned long buflen) {
1293 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1294 if (!pFormField) {
1295 return 0;
1296 }
1297 // SAFETY: required from caller.
1298 return Utf16EncodeMaybeCopyAndReturnLength(
1299 pFormField->GetAlternateName(),
1300 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1301}
1302
1303FPDF_EXPORT unsigned long FPDF_CALLCONV
1304FPDFAnnot_GetFormFieldValue(FPDF_FORMHANDLE hHandle,
1305 FPDF_ANNOTATION annot,
1306 FPDF_WCHAR* buffer,
1307 unsigned long buflen) {
1308 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1309 if (!pFormField) {
1310 return 0;
1311 }
1312 // SAFETY: required from caller.
1313 return Utf16EncodeMaybeCopyAndReturnLength(
1314 pFormField->GetValue(),
1315 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1316}
1317
1319 FPDF_ANNOTATION annot) {
1320 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1321 return pFormField ? pFormField->CountOptions() : -1;
1322}
1323
1324FPDF_EXPORT unsigned long FPDF_CALLCONV
1325FPDFAnnot_GetOptionLabel(FPDF_FORMHANDLE hHandle,
1326 FPDF_ANNOTATION annot,
1327 int index,
1328 FPDF_WCHAR* buffer,
1329 unsigned long buflen) {
1330 if (index < 0)
1331 return 0;
1332
1333 const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1334 if (!pFormField || index >= pFormField->CountOptions())
1335 return 0;
1336
1337 // SAFETY: required from caller.
1338 return Utf16EncodeMaybeCopyAndReturnLength(
1339 pFormField->GetOptionLabel(index),
1340 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
1341}
1342
1343FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1344FPDFAnnot_IsOptionSelected(FPDF_FORMHANDLE handle,
1345 FPDF_ANNOTATION annot,
1346 int index) {
1347 if (index < 0) {
1348 return false;
1349 }
1350
1351 const CPDF_FormField* form_field = GetFormField(handle, annot);
1352 if (!form_field) {
1353 return false;
1354 }
1355
1356 if (form_field->GetFieldType() != FormFieldType::kComboBox &&
1358 return false;
1359 }
1360
1361 return index < form_field->CountOptions() &&
1362 form_field->IsItemSelected(index);
1363}
1364
1365FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1366FPDFAnnot_GetFontSize(FPDF_FORMHANDLE hHandle,
1367 FPDF_ANNOTATION annot,
1368 float* value) {
1369 if (!value) {
1370 return false;
1371 }
1372
1373 const CPDFSDK_Widget* widget = GetWidgetOfTypes(hHandle, annot, {});
1374 if (!widget) {
1375 return false;
1376 }
1377
1378 *value = widget->GetFontSize();
1379 return true;
1380}
1381
1382FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1383FPDFAnnot_GetFontColor(FPDF_FORMHANDLE hHandle,
1384 FPDF_ANNOTATION annot,
1385 unsigned int* R,
1386 unsigned int* G,
1387 unsigned int* B) {
1388 if (!R || !G || !B) {
1389 return false;
1390 }
1391
1392 const CPDFSDK_Widget* widget = GetWidgetOfTypes(hHandle, annot, {});
1393 if (!widget) {
1394 return false;
1395 }
1396
1397 std::optional<FX_COLORREF> text_color = widget->GetTextColor();
1398 if (!text_color) {
1399 return false;
1400 }
1401
1402 *R = FXSYS_GetRValue(*text_color);
1403 *G = FXSYS_GetGValue(*text_color);
1404 *B = FXSYS_GetBValue(*text_color);
1405 return true;
1406}
1407
1408FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_IsChecked(FPDF_FORMHANDLE hHandle,
1409 FPDF_ANNOTATION annot) {
1410 const CPDFSDK_Widget* pWidget =
1411 GetRadioButtonOrCheckBoxWidget(hHandle, annot);
1412 return pWidget && pWidget->IsChecked();
1413}
1414
1415FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1416FPDFAnnot_SetFocusableSubtypes(FPDF_FORMHANDLE hHandle,
1417 const FPDF_ANNOTATION_SUBTYPE* subtypes,
1418 size_t count) {
1419 CPDFSDK_FormFillEnvironment* pFormFillEnv =
1421 if (!pFormFillEnv)
1422 return false;
1423
1424 if (count > 0 && !subtypes)
1425 return false;
1426
1427 // SAFETY: required from caller.
1428 auto subtypes_span = UNSAFE_BUFFERS(pdfium::make_span(subtypes, count));
1429 std::vector<CPDF_Annot::Subtype> focusable_annot_types;
1430 focusable_annot_types.reserve(count);
1431 for (size_t i = 0; i < count; ++i) {
1432 focusable_annot_types.push_back(
1433 static_cast<CPDF_Annot::Subtype>(subtypes_span[i]));
1434 }
1435
1436 pFormFillEnv->SetFocusableAnnotSubtypes(focusable_annot_types);
1437 return true;
1438}
1439
1441FPDFAnnot_GetFocusableSubtypesCount(FPDF_FORMHANDLE hHandle) {
1442 CPDFSDK_FormFillEnvironment* pFormFillEnv =
1444 if (!pFormFillEnv)
1445 return -1;
1446
1447 return fxcrt::CollectionSize<int>(pFormFillEnv->GetFocusableAnnotSubtypes());
1448}
1449
1450FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
1451FPDFAnnot_GetFocusableSubtypes(FPDF_FORMHANDLE hHandle,
1452 FPDF_ANNOTATION_SUBTYPE* subtypes,
1453 size_t count) {
1454 CPDFSDK_FormFillEnvironment* pFormFillEnv =
1456 if (!pFormFillEnv)
1457 return false;
1458
1459 if (!subtypes)
1460 return false;
1461
1462 const std::vector<CPDF_Annot::Subtype>& focusable_annot_types =
1463 pFormFillEnv->GetFocusableAnnotSubtypes();
1464
1465 // Host should allocate enough memory to get the list of currently supported
1466 // focusable subtypes.
1467 if (count < focusable_annot_types.size())
1468 return false;
1469
1470 // SAFETY: required from caller.
1471 auto subtypes_span = UNSAFE_BUFFERS(pdfium::make_span(subtypes, count));
1472 for (size_t i = 0; i < focusable_annot_types.size(); ++i) {
1473 subtypes_span[i] =
1474 static_cast<FPDF_ANNOTATION_SUBTYPE>(focusable_annot_types[i]);
1475 }
1476 return true;
1477}
1478
1479FPDF_EXPORT FPDF_LINK FPDF_CALLCONV FPDFAnnot_GetLink(FPDF_ANNOTATION annot) {
1481 return nullptr;
1482
1483 // Unretained reference in public API. NOLINTNEXTLINE
1484 return FPDFLinkFromCPDFDictionary(
1485 CPDFAnnotContextFromFPDFAnnotation(annot)->GetMutableAnnotDict());
1486}
1487
1489FPDFAnnot_GetFormControlCount(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot) {
1490 CPDF_FormField* pFormField = GetFormField(hHandle, annot);
1491 return pFormField ? pFormField->CountControls() : -1;
1492}
1493
1495FPDFAnnot_GetFormControlIndex(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot) {
1496 const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
1497 if (!pAnnotDict)
1498 return -1;
1499
1500 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
1501 if (!pForm)
1502 return -1;
1503
1505 CPDF_FormField* pFormField = pPDFForm->GetFieldByDict(pAnnotDict);
1506 CPDF_FormControl* pFormControl = pPDFForm->GetControlByDict(pAnnotDict);
1507 return pFormField ? pFormField->GetControlIndex(pFormControl) : -1;
1508}
1509
1510FPDF_EXPORT unsigned long FPDF_CALLCONV
1512 FPDF_ANNOTATION annot,
1513 FPDF_WCHAR* buffer,
1514 unsigned long buflen) {
1515 const CPDFSDK_Widget* pWidget =
1516 GetRadioButtonOrCheckBoxWidget(hHandle, annot);
1517 if (!pWidget) {
1518 return 0;
1519 }
1520 // SAFETY: required from caller.
1521 return Utf16EncodeMaybeCopyAndReturnLength(
1522 pWidget->GetExportValue(),
1523 UNSAFE_TODO(SpanFromFPDFApiArgs(buffer, buflen)));
1524}
1525
1526FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetURI(FPDF_ANNOTATION annot,
1527 const char* uri) {
1528 if (!uri || FPDFAnnot_GetSubtype(annot) != FPDF_ANNOT_LINK)
1529 return false;
1530
1531 RetainPtr<CPDF_Dictionary> annot_dict =
1532 GetMutableAnnotDictFromFPDFAnnotation(annot);
1533 auto action = annot_dict->SetNewFor<CPDF_Dictionary>("A");
1534 action->SetNewFor<CPDF_Name>("Type", "Action");
1535 action->SetNewFor<CPDF_Name>("S", "URI");
1536 action->SetNewFor<CPDF_String>("URI", uri);
1537 return true;
1538}
1539
1540FPDF_EXPORT FPDF_ATTACHMENT FPDF_CALLCONV
1541FPDFAnnot_GetFileAttachment(FPDF_ANNOTATION annot) {
1543 return nullptr;
1544 }
1545
1546 RetainPtr<CPDF_Dictionary> annot_dict =
1547 GetMutableAnnotDictFromFPDFAnnotation(annot);
1548 if (!annot_dict) {
1549 return nullptr;
1550 }
1551
1552 return FPDFAttachmentFromCPDFObject(
1553 annot_dict->GetMutableDirectObjectFor("FS"));
1554}
1555
1556FPDF_EXPORT FPDF_ATTACHMENT FPDF_CALLCONV
1557FPDFAnnot_AddFileAttachment(FPDF_ANNOTATION annot, FPDF_WIDESTRING name) {
1559 return nullptr;
1560 }
1561
1563 if (!context) {
1564 return nullptr;
1565 }
1566
1567 RetainPtr<CPDF_Dictionary> annot_dict = context->GetMutableAnnotDict();
1568 if (!annot_dict) {
1569 return nullptr;
1570 }
1571
1572 // SAFETY: required from caller.
1574 if (ws_name.IsEmpty()) {
1575 return nullptr;
1576 }
1577
1579 auto fs_obj = doc->NewIndirect<CPDF_Dictionary>();
1580
1581 fs_obj->SetNewFor<CPDF_Name>("Type", "Filespec");
1582 fs_obj->SetNewFor<CPDF_String>("UF", ws_name.AsStringView());
1583 fs_obj->SetNewFor<CPDF_String>("F", ws_name.AsStringView());
1584
1585 annot_dict->SetNewFor<CPDF_Reference>("FS", doc, fs_obj->GetObjNum());
1586 return FPDFAttachmentFromCPDFObject(fs_obj);
1587}
fxcrt::ByteString ByteString
Definition bytestring.h:180
#define DCHECK
Definition check.h:33
float Width() const
float Height() const
CPDFSDK_Widget * GetWidget(CPDF_FormControl *pControl) const
CPDF_InteractiveForm * GetInteractiveForm() const
bool IsChecked() const
float GetFontSize() const
CPDF_Action GetAction(AActionType eType) const
void SetForm(RetainPtr< CPDF_Stream > pStream)
CPDF_Form * GetForm() const
IPDF_Page * GetPage() const
const CPDF_Dictionary * GetAnnotDict() const
static ByteString AnnotSubtypeToString(Subtype nSubtype)
static Subtype StringToAnnotSubtype(const ByteString &sSubtype)
static CFX_FloatRect BoundingRectFromQuadPoints(const CPDF_Dictionary *pAnnotDict)
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
bool KeyExist(const ByteString &key) const
int GetIntegerFor(const ByteString &key) const
float GetFloatFor(const ByteString &key) const
RetainPtr< const CPDF_Array > GetArrayFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
CFX_FloatRect GetRectFor(const ByteString &key) const
ByteString GetNameFor(const ByteString &key) const
int CountOptions() const
int CountControls() const
uint32_t GetFieldFlags() const
int GetControlIndex(const CPDF_FormControl *pControl) const
bool IsItemSelected(int index) const
Type GetType() const
FormFieldType GetFieldType() const
CPDF_AAction GetAdditionalAction() const
static void GenerateEmptyAP(CPDF_Document *pDoc, CPDF_Dictionary *pAnnotDict)
const CPDF_FormControl * GetControlAtPoint(const CPDF_Page *pPage, const CFX_PointF &point, int *z_order) const
CPDF_FormControl * GetControlByDict(const CPDF_Dictionary *pWidgetDict) const
CPDF_FormField * GetFieldByDict(const CPDF_Dictionary *pFieldDict) const
CPDF_Document * GetDocument() const override
Definition cpdf_page.cpp:51
virtual CPDF_Document * GetDocument() const =0
#define UNSAFE_BUFFERS(...)
#define UNSAFE_TODO(...)
FormFieldType
UNSAFE_BUFFER_USAGE WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string)
IPDF_Page * IPDFPageFromFPDFPage(FPDF_PAGE page)
CPDFSDK_FormFillEnvironment * CPDFSDKFormFillEnvironmentFromFPDFFormHandle(FPDF_FORMHANDLE handle)
CPDF_AnnotContext * CPDFAnnotContextFromFPDFAnnotation(FPDF_ANNOTATION annot)
FS_RECTF FSRectFFromCFXFloatRect(const CFX_FloatRect &rect)
CFX_FloatRect CFXFloatRectFromFSRectF(const FS_RECTF &rect)
CPDF_Page * CPDFPageFromFPDFPage(FPDF_PAGE page)
CPDF_PageObject * CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object)
CPDFSDK_InteractiveForm * FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetFocusableSubtypes(FPDF_FORMHANDLE hHandle, const FPDF_ANNOTATION_SUBTYPE *subtypes, size_t count)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot, size_t quad_index, FS_QUADPOINTSF *quad_points)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_AddInkStroke(FPDF_ANNOTATION annot, const FS_POINTF *points, size_t point_count)
FPDF_EXPORT size_t FPDF_CALLCONV FPDFAnnot_CountAttachmentPoints(FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetFocusableSubtypes(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION_SUBTYPE *subtypes, size_t count)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, size_t quad_index, const FS_QUADPOINTSF *quad_points)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFormControlCount(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetFontSize(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, float *value)
#define FPDF_ANNOT_FILEATTACHMENT
Definition fpdf_annot.h:37
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetRect(FPDF_ANNOTATION annot, const FS_RECTF *rect)
#define FPDF_ANNOT_RICHMEDIA
Definition fpdf_annot.h:46
#define FPDF_ANNOT_STAMP
Definition fpdf_annot.h:33
#define FPDF_ANNOT_MOVIE
Definition fpdf_annot.h:39
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_RemoveAnnot(FPDF_PAGE page, int index)
#define FPDF_ANNOT_THREED
Definition fpdf_annot.h:45
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetBorder(FPDF_ANNOTATION annot, float *horizontal_radius, float *vertical_radius, float *border_width)
#define FPDF_ANNOT_APPEARANCEMODE_COUNT
Definition fpdf_annot.h:65
#define FPDF_ANNOT_APPEARANCEMODE_ROLLOVER
Definition fpdf_annot.h:63
#define FPDF_ANNOT_STRIKEOUT
Definition fpdf_annot.h:32
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFocusableSubtypesCount(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetOptionCount(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetVertices(FPDF_ANNOTATION annot, FS_POINTF *buffer, unsigned long length)
#define FPDF_ANNOT_UNDERLINE
Definition fpdf_annot.h:30
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFAnnot_GetObject(FPDF_ANNOTATION annot, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetFlags(FPDF_ANNOTATION annot, int flags)
#define FPDF_ANNOT_LINE
Definition fpdf_annot.h:24
#define FPDF_ANNOT_UNKNOWN
Definition fpdf_annot.h:20
#define FPDF_ANNOT_SCREEN
Definition fpdf_annot.h:41
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetFormFieldName(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, FPDF_WCHAR *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_HasKey(FPDF_ANNOTATION annot, FPDF_BYTESTRING key)
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_BYTESTRING key)
FPDF_EXPORT FPDF_ATTACHMENT FPDF_CALLCONV FPDFAnnot_AddFileAttachment(FPDF_ANNOTATION annot, FPDF_WIDESTRING name)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetObjectCount(FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_RemoveObject(FPDF_ANNOTATION annot, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetAnnotCount(FPDF_PAGE page)
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFPage_CreateAnnot(FPDF_PAGE page, FPDF_ANNOTATION_SUBTYPE subtype)
#define FPDF_ANNOT_WATERMARK
Definition fpdf_annot.h:44
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_IsChecked(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetFormFieldAlternateName(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, FPDF_WCHAR *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_LINK FPDF_CALLCONV FPDFAnnot_GetLink(FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetAP(FPDF_ANNOTATION annot, FPDF_ANNOT_APPEARANCEMODE appearanceMode, FPDF_WIDESTRING value)
FPDF_EXPORT FPDF_ANNOTATION_SUBTYPE FPDF_CALLCONV FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot)
#define FPDF_ANNOT_XFAWIDGET
Definition fpdf_annot.h:47
#define FPDF_ANNOT_WIDGET
Definition fpdf_annot.h:40
FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV FPDFAnnot_GetValueType(FPDF_ANNOTATION annot, FPDF_BYTESTRING key)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_AppendAttachmentPoints(FPDF_ANNOTATION annot, const FS_QUADPOINTSF *quad_points)
#define FPDF_ANNOT_HIGHLIGHT
Definition fpdf_annot.h:29
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetFontColor(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, unsigned int *R, unsigned int *G, unsigned int *B)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot)
#define FPDF_ANNOT_TRAPNET
Definition fpdf_annot.h:43
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetColor(FPDF_ANNOTATION annot, FPDFANNOT_COLORTYPE type, unsigned int *R, unsigned int *G, unsigned int *B, unsigned int *A)
#define FPDF_ANNOT_SQUIGGLY
Definition fpdf_annot.h:31
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFormFieldFlags(FPDF_FORMHANDLE handle, FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetStringValue(FPDF_ANNOTATION annot, FPDF_BYTESTRING key, FPDF_WIDESTRING value)
#define FPDF_ANNOT_SOUND
Definition fpdf_annot.h:38
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetOptionLabel(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, int index, FPDF_WCHAR *buffer, unsigned long buflen)
#define FPDF_ANNOT_INK
Definition fpdf_annot.h:35
#define FPDF_ANNOT_APPEARANCEMODE_NORMAL
Definition fpdf_annot.h:62
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetInkListPath(FPDF_ANNOTATION annot, unsigned long path_index, FS_POINTF *buffer, unsigned long length)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_IsOptionSelected(FPDF_FORMHANDLE handle, FPDF_ANNOTATION annot, int index)
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFPage_GetAnnot(FPDF_PAGE page, int index)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetFormFieldExportValue(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, FPDF_WCHAR *buffer, unsigned long buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFlags(FPDF_ANNOTATION annot)
#define FPDF_ANNOT_SQUARE
Definition fpdf_annot.h:25
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot, FPDF_BYTESTRING key, FPDF_WCHAR *buffer, unsigned long buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFormControlIndex(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot)
#define FPDF_ANNOT_FREETEXT
Definition fpdf_annot.h:23
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_CloseAnnot(FPDF_ANNOTATION annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetNumberValue(FPDF_ANNOTATION annot, FPDF_BYTESTRING key, float *value)
#define FPDF_ANNOT_AACTION_FORMAT
Definition fpdf_annot.h:91
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFormFieldType(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot)
#define FPDF_ANNOT_AACTION_VALIDATE
Definition fpdf_annot.h:92
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetURI(FPDF_ANNOTATION annot, const char *uri)
#define FPDF_ANNOT_AACTION_CALCULATE
Definition fpdf_annot.h:93
#define FPDF_ANNOT_APPEARANCEMODE_DOWN
Definition fpdf_annot.h:64
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetFormFieldValue(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, FPDF_WCHAR *buffer, unsigned long buflen)
#define FPDF_ANNOT_FLAG_NONE
Definition fpdf_annot.h:51
#define FPDF_FORMFLAG_NONE
Definition fpdf_annot.h:69
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetRect(FPDF_ANNOTATION annot, FS_RECTF *rect)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetAP(FPDF_ANNOTATION annot, FPDF_ANNOT_APPEARANCEMODE appearanceMode, FPDF_WCHAR *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_IsObjectSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype)
#define FPDF_ANNOT_REDACT
Definition fpdf_annot.h:48
#define FPDF_ANNOT_POLYGON
Definition fpdf_annot.h:27
#define FPDF_ANNOT_CARET
Definition fpdf_annot.h:34
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetLine(FPDF_ANNOTATION annot, FS_POINTF *start, FS_POINTF *end)
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetAnnotIndex(FPDF_PAGE page, FPDF_ANNOTATION annot)
#define FPDF_ANNOT_POPUP
Definition fpdf_annot.h:36
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, const FS_POINTF *point)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetInkListCount(FPDF_ANNOTATION annot)
@ FPDFANNOT_COLORTYPE_InteriorColor
Definition fpdf_annot.h:97
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetBorder(FPDF_ANNOTATION annot, float horizontal_radius, float vertical_radius, float border_width)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_AppendObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj)
#define FPDF_ANNOT_AACTION_KEY_STROKE
Definition fpdf_annot.h:90
#define FPDF_ANNOT_CIRCLE
Definition fpdf_annot.h:26
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetColor(FPDF_ANNOTATION annot, FPDFANNOT_COLORTYPE type, unsigned int R, unsigned int G, unsigned int B, unsigned int A)
FPDF_EXPORT FPDF_ATTACHMENT FPDF_CALLCONV FPDFAnnot_GetFileAttachment(FPDF_ANNOTATION annot)
#define FPDF_ANNOT_TEXT
Definition fpdf_annot.h:21
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj)
#define FPDF_ANNOT_PRINTERMARK
Definition fpdf_annot.h:42
#define FPDF_ANNOT_LINK
Definition fpdf_annot.h:22
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_RemoveInkList(FPDF_ANNOTATION annot)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAnnot_GetFormAdditionalActionJavaScript(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, int event, FPDF_WCHAR *buffer, unsigned long buflen)
#define FPDF_ANNOT_POLYLINE
Definition fpdf_annot.h:28
#define FPDF_OBJECT_STREAM
Definition fpdfview.h:43
#define FPDF_OBJECT_REFERENCE
Definition fpdfview.h:45
#define FPDF_OBJECT_NUMBER
Definition fpdfview.h:38
#define FPDF_OBJECT_NULLOBJ
Definition fpdfview.h:44
#define FPDF_OBJECT_NAME
Definition fpdfview.h:40
#define FPDF_OBJECT_BOOLEAN
Definition fpdfview.h:37
#define FPDF_CALLCONV
Definition fpdfview.h:229
#define FPDF_EXPORT
Definition fpdfview.h:223
#define FPDF_OBJECT_UNKNOWN
Definition fpdfview.h:36
#define FPDF_OBJECT_STRING
Definition fpdfview.h:39
#define FPDF_OBJECT_ARRAY
Definition fpdfview.h:41
#define FPDF_OBJECT_DICTIONARY
Definition fpdfview.h:42
uint32_t FX_COLORREF
Definition fx_dib.h:42
CFX_Color CFXColorFromArray(const CPDF_Array &array)
float fColor4
Definition cfx_color.h:58
float fColor3
Definition cfx_color.h:57
Type nColorType
Definition cfx_color.h:54
float fColor2
Definition cfx_color.h:56
float fColor1
Definition cfx_color.h:55
fxcrt::WideString WideString
Definition widestring.h:207