diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2018-03-28 19:23:25 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-03-28 19:23:25 +0000 |
commit | 971a674ef17526ad37ce55ba90110830b94889d0 (patch) | |
tree | d99fabf665cc63825b48dd087daadf664bb80ee8 /fpdfsdk/fpdfannot.cpp | |
parent | 7d12532362545273e0ceac93fae2154661323fd1 (diff) | |
download | pdfium-971a674ef17526ad37ce55ba90110830b94889d0.tar.xz |
Rename fpdfsdk/fpdf* files to be consistent
This CL makes the fpdfsdk/fpdf* files to be consistently prefixed with
fpdf_ instead of randomly dropping the _.
Change-Id: I23e3c8a0831b56bcd17c788d9fe874b2ab8b24fc
Reviewed-on: https://pdfium-review.googlesource.com/29390
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Diffstat (limited to 'fpdfsdk/fpdfannot.cpp')
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 887 |
1 files changed, 0 insertions, 887 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp deleted file mode 100644 index 2ab0bca454..0000000000 --- a/fpdfsdk/fpdfannot.cpp +++ /dev/null @@ -1,887 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "public/fpdf_annot.h" - -#include <memory> -#include <utility> - -#include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" -#include "core/fpdfapi/page/cpdf_form.h" -#include "core/fpdfapi/page/cpdf_page.h" -#include "core/fpdfapi/page/cpdf_pageobject.h" -#include "core/fpdfapi/parser/cpdf_array.h" -#include "core/fpdfapi/parser/cpdf_dictionary.h" -#include "core/fpdfapi/parser/cpdf_document.h" -#include "core/fpdfapi/parser/cpdf_name.h" -#include "core/fpdfapi/parser/cpdf_number.h" -#include "core/fpdfapi/parser/cpdf_string.h" -#include "core/fpdfdoc/cpdf_annot.h" -#include "core/fpdfdoc/cpdf_formfield.h" -#include "core/fpdfdoc/cpdf_interform.h" -#include "core/fpdfdoc/cpvt_generateap.h" -#include "core/fxge/cfx_color.h" -#include "fpdfsdk/cpdfsdk_helpers.h" - -namespace { - -// These checks ensure the consistency of annotation subtype values across core/ -// and public. -static_assert(static_cast<int>(CPDF_Annot::Subtype::UNKNOWN) == - FPDF_ANNOT_UNKNOWN, - "CPDF_Annot::UNKNOWN value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::TEXT) == FPDF_ANNOT_TEXT, - "CPDF_Annot::TEXT value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::LINK) == FPDF_ANNOT_LINK, - "CPDF_Annot::LINK value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::FREETEXT) == - FPDF_ANNOT_FREETEXT, - "CPDF_Annot::FREETEXT value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::LINE) == FPDF_ANNOT_LINE, - "CPDF_Annot::LINE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUARE) == - FPDF_ANNOT_SQUARE, - "CPDF_Annot::SQUARE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::CIRCLE) == - FPDF_ANNOT_CIRCLE, - "CPDF_Annot::CIRCLE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYGON) == - FPDF_ANNOT_POLYGON, - "CPDF_Annot::POLYGON value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYLINE) == - FPDF_ANNOT_POLYLINE, - "CPDF_Annot::POLYLINE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::HIGHLIGHT) == - FPDF_ANNOT_HIGHLIGHT, - "CPDF_Annot::HIGHLIGHT value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::UNDERLINE) == - FPDF_ANNOT_UNDERLINE, - "CPDF_Annot::UNDERLINE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUIGGLY) == - FPDF_ANNOT_SQUIGGLY, - "CPDF_Annot::SQUIGGLY value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::STRIKEOUT) == - FPDF_ANNOT_STRIKEOUT, - "CPDF_Annot::STRIKEOUT value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::STAMP) == FPDF_ANNOT_STAMP, - "CPDF_Annot::STAMP value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::CARET) == FPDF_ANNOT_CARET, - "CPDF_Annot::CARET value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::INK) == FPDF_ANNOT_INK, - "CPDF_Annot::INK value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::POPUP) == FPDF_ANNOT_POPUP, - "CPDF_Annot::POPUP value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::FILEATTACHMENT) == - FPDF_ANNOT_FILEATTACHMENT, - "CPDF_Annot::FILEATTACHMENT value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::SOUND) == FPDF_ANNOT_SOUND, - "CPDF_Annot::SOUND value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::MOVIE) == FPDF_ANNOT_MOVIE, - "CPDF_Annot::MOVIE value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::WIDGET) == - FPDF_ANNOT_WIDGET, - "CPDF_Annot::WIDGET value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::SCREEN) == - FPDF_ANNOT_SCREEN, - "CPDF_Annot::SCREEN value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::PRINTERMARK) == - FPDF_ANNOT_PRINTERMARK, - "CPDF_Annot::PRINTERMARK value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::TRAPNET) == - FPDF_ANNOT_TRAPNET, - "CPDF_Annot::TRAPNET value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::WATERMARK) == - FPDF_ANNOT_WATERMARK, - "CPDF_Annot::WATERMARK value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::THREED) == - FPDF_ANNOT_THREED, - "CPDF_Annot::THREED value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::RICHMEDIA) == - FPDF_ANNOT_RICHMEDIA, - "CPDF_Annot::RICHMEDIA value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::Subtype::XFAWIDGET) == - FPDF_ANNOT_XFAWIDGET, - "CPDF_Annot::XFAWIDGET value mismatch"); - -// These checks ensure the consistency of annotation appearance mode values -// across core/ and public. -static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Normal) == - FPDF_ANNOT_APPEARANCEMODE_NORMAL, - "CPDF_Annot::AppearanceMode::Normal value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Rollover) == - FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, - "CPDF_Annot::AppearanceMode::Rollover value mismatch"); -static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Down) == - FPDF_ANNOT_APPEARANCEMODE_DOWN, - "CPDF_Annot::AppearanceMode::Down value mismatch"); - -// These checks ensure the consistency of dictionary value types across core/ -// and public/. -static_assert(static_cast<int>(CPDF_Object::Type::BOOLEAN) == - FPDF_OBJECT_BOOLEAN, - "CPDF_Object::BOOLEAN value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::NUMBER) == FPDF_OBJECT_NUMBER, - "CPDF_Object::NUMBER value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::STRING) == FPDF_OBJECT_STRING, - "CPDF_Object::STRING value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::NAME) == FPDF_OBJECT_NAME, - "CPDF_Object::NAME value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::ARRAY) == FPDF_OBJECT_ARRAY, - "CPDF_Object::ARRAY value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::DICTIONARY) == - FPDF_OBJECT_DICTIONARY, - "CPDF_Object::DICTIONARY value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::STREAM) == FPDF_OBJECT_STREAM, - "CPDF_Object::STREAM value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::NULLOBJ) == - FPDF_OBJECT_NULLOBJ, - "CPDF_Object::NULLOBJ value mismatch"); -static_assert(static_cast<int>(CPDF_Object::Type::REFERENCE) == - FPDF_OBJECT_REFERENCE, - "CPDF_Object::REFERENCE value mismatch"); - -class CPDF_AnnotContext { - public: - CPDF_AnnotContext(CPDF_Dictionary* pAnnotDict, - CPDF_Page* pPage, - CPDF_Stream* pStream) - : m_pAnnotDict(pAnnotDict), m_pPage(pPage) { - SetForm(pStream); - } - ~CPDF_AnnotContext() {} - - bool HasForm() const { return !!m_pAnnotForm; } - - void SetForm(CPDF_Stream* pStream) { - if (!pStream) - return; - - // Reset the annotation matrix to be the identity matrix, since the - // appearance stream already takes matrix into account. - pStream->GetDict()->SetMatrixFor("Matrix", CFX_Matrix()); - - m_pAnnotForm = pdfium::MakeUnique<CPDF_Form>( - m_pPage->m_pDocument.Get(), m_pPage->m_pResources.Get(), pStream); - m_pAnnotForm->ParseContent(); - } - - CPDF_Form* GetForm() const { return m_pAnnotForm.get(); } - CPDF_Dictionary* GetAnnotDict() const { return m_pAnnotDict.Get(); } - CPDF_Page* GetPage() const { return m_pPage.Get(); } - - private: - std::unique_ptr<CPDF_Form> m_pAnnotForm; - UnownedPtr<CPDF_Dictionary> m_pAnnotDict; - UnownedPtr<CPDF_Page> m_pPage; -}; - -CPDF_AnnotContext* CPDFAnnotContextFromFPDFAnnotation(FPDF_ANNOTATION annot) { - return static_cast<CPDF_AnnotContext*>(annot); -} - -bool HasAPStream(const CPDF_Dictionary* pAnnotDict) { - return !!FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); -} - -void UpdateContentStream(CPDF_Form* pForm, CPDF_Stream* pStream) { - ASSERT(pForm); - ASSERT(pStream); - - CPDF_PageContentGenerator generator(pForm); - std::ostringstream buf; - generator.ProcessPageObjects(&buf); - pStream->SetDataAndRemoveFilter(&buf); -} - -} // namespace - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype) { - // The supported subtypes must also be communicated in the user doc. - return subtype == FPDF_ANNOT_CIRCLE || subtype == FPDF_ANNOT_FREETEXT || - subtype == FPDF_ANNOT_HIGHLIGHT || subtype == FPDF_ANNOT_INK || - subtype == FPDF_ANNOT_POPUP || subtype == FPDF_ANNOT_SQUARE || - subtype == FPDF_ANNOT_SQUIGGLY || subtype == FPDF_ANNOT_STAMP || - subtype == FPDF_ANNOT_STRIKEOUT || subtype == FPDF_ANNOT_TEXT || - subtype == FPDF_ANNOT_UNDERLINE; -} - -FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV -FPDFPage_CreateAnnot(FPDF_PAGE page, FPDF_ANNOTATION_SUBTYPE subtype) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!pPage || !FPDFAnnot_IsSupportedSubtype(subtype)) - return nullptr; - - auto pDict = pdfium::MakeUnique<CPDF_Dictionary>( - pPage->m_pDocument->GetByteStringPool()); - pDict->SetNewFor<CPDF_Name>("Type", "Annot"); - pDict->SetNewFor<CPDF_Name>("Subtype", - CPDF_Annot::AnnotSubtypeToString( - static_cast<CPDF_Annot::Subtype>(subtype))); - auto pNewAnnot = - pdfium::MakeUnique<CPDF_AnnotContext>(pDict.get(), pPage, nullptr); - - CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArrayFor("Annots"); - if (!pAnnotList) - pAnnotList = pPage->m_pFormDict->SetNewFor<CPDF_Array>("Annots"); - - pAnnotList->Add(std::move(pDict)); - return pNewAnnot.release(); -} - -FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetAnnotCount(FPDF_PAGE page) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!pPage || !pPage->m_pFormDict) - return 0; - - CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); - return pAnnots ? pAnnots->GetCount() : 0; -} - -FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFPage_GetAnnot(FPDF_PAGE page, - int index) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!pPage || !pPage->m_pFormDict || index < 0) - return nullptr; - - CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); - if (!pAnnots || static_cast<size_t>(index) >= pAnnots->GetCount()) - return nullptr; - - CPDF_Dictionary* pDict = ToDictionary(pAnnots->GetDirectObjectAt(index)); - auto pNewAnnot = pdfium::MakeUnique<CPDF_AnnotContext>(pDict, pPage, nullptr); - return pNewAnnot.release(); -} - -FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetAnnotIndex(FPDF_PAGE page, - FPDF_ANNOTATION annot) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pPage || !pPage->m_pFormDict || !pAnnot || !pAnnot->GetAnnotDict()) - return -1; - - CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); - if (!pAnnots) - return -1; - - CPDF_Dictionary* pDict = pAnnot->GetAnnotDict(); - auto it = - std::find_if(pAnnots->begin(), pAnnots->end(), - [pDict](const std::unique_ptr<CPDF_Object>& candidate) { - return candidate->GetDirect() == pDict; - }); - - if (it == pAnnots->end()) - return -1; - - return it - pAnnots->begin(); -} - -FPDF_EXPORT void FPDF_CALLCONV FPDFPage_CloseAnnot(FPDF_ANNOTATION annot) { - delete CPDFAnnotContextFromFPDFAnnotation(annot); -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_RemoveAnnot(FPDF_PAGE page, - int index) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!pPage || !pPage->m_pFormDict || index < 0) - return false; - - CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); - if (!pAnnots || static_cast<size_t>(index) >= pAnnots->GetCount()) - return false; - - pAnnots->RemoveAt(index); - return true; -} - -FPDF_EXPORT FPDF_ANNOTATION_SUBTYPE FPDF_CALLCONV -FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) { - if (!annot) - return FPDF_ANNOT_UNKNOWN; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return FPDF_ANNOT_UNKNOWN; - - return static_cast<FPDF_ANNOTATION_SUBTYPE>( - CPDF_Annot::StringToAnnotSubtype(pAnnotDict->GetStringFor("Subtype"))); -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_IsObjectSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype) { - // The supported subtypes must also be communicated in the user doc. - return subtype == FPDF_ANNOT_INK || subtype == FPDF_ANNOT_STAMP; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(obj); - if (!pAnnot || !pAnnot->GetAnnotDict() || !pAnnot->HasForm() || !pObj) - return false; - - // Check that the annotation type is supported by this method. - if (!FPDFAnnot_IsObjectSupportedSubtype(FPDFAnnot_GetSubtype(annot))) - return false; - - // Check that the annotation already has an appearance stream, since an - // existing object is to be updated. - CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(pAnnot->GetAnnotDict(), - CPDF_Annot::AppearanceMode::Normal); - if (!pStream) - return false; - - // Check that the object is already in this annotation's object list. - CPDF_Form* pForm = pAnnot->GetForm(); - CPDF_PageObjectList* pObjList = pForm->GetPageObjectList(); - auto it = - std::find_if(pObjList->begin(), pObjList->end(), - [pObj](const std::unique_ptr<CPDF_PageObject>& candidate) { - return candidate.get() == pObj; - }); - if (it == pObjList->end()) - return false; - - // Update the content stream data in the annotation's AP stream. - UpdateContentStream(pForm, pStream); - return true; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_AppendObject(FPDF_ANNOTATION annot, FPDF_PAGEOBJECT obj) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(obj); - if (!pAnnot || !pObj) - return false; - - CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict(); - CPDF_Page* pPage = pAnnot->GetPage(); - if (!pAnnotDict || !pPage) - return false; - - // Check that the annotation type is supported by this method. - if (!FPDFAnnot_IsObjectSupportedSubtype(FPDFAnnot_GetSubtype(annot))) - return false; - - // If the annotation does not have an AP stream yet, generate and set it. - CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(pAnnot->GetAnnotDict(), - CPDF_Annot::AppearanceMode::Normal); - if (!pStream) { - CPVT_GenerateAP::GenerateEmptyAP(pPage->m_pDocument.Get(), pAnnotDict); - pStream = - FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); - if (!pStream) - return false; - } - - // Get the annotation's corresponding form object for parsing its AP stream. - if (!pAnnot->HasForm()) - pAnnot->SetForm(pStream); - - // Check that the object did not come from the same annotation. If this check - // succeeds, then it is assumed that the object came from - // FPDFPageObj_CreateNew{Path|Rect}() or FPDFPageObj_New{Text|Image}Obj(). - // Note that an object that came from a different annotation must not be - // passed here, since an object cannot belong to more than one annotation. - CPDF_Form* pForm = pAnnot->GetForm(); - CPDF_PageObjectList* pObjList = pForm->GetPageObjectList(); - auto it = - std::find_if(pObjList->begin(), pObjList->end(), - [pObj](const std::unique_ptr<CPDF_PageObject>& candidate) { - return candidate.get() == pObj; - }); - if (it != pObjList->end()) - return false; - - // Append the object to the object list. - std::unique_ptr<CPDF_PageObject> pPageObjHolder(pObj); - pObjList->push_back(std::move(pPageObjHolder)); - - // Set the content stream data in the annotation's AP stream. - UpdateContentStream(pForm, pStream); - return true; -} - -FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetObjectCount(FPDF_ANNOTATION annot) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot || !pAnnot->GetAnnotDict()) - return 0; - - if (!pAnnot->HasForm()) { - CPDF_Stream* pStream = FPDFDOC_GetAnnotAP( - pAnnot->GetAnnotDict(), CPDF_Annot::AppearanceMode::Normal); - if (!pStream) - return 0; - - pAnnot->SetForm(pStream); - } - return pdfium::CollectionSize<int>(*pAnnot->GetForm()->GetPageObjectList()); -} - -FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV -FPDFAnnot_GetObject(FPDF_ANNOTATION annot, int index) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot || !pAnnot->GetAnnotDict() || index < 0) - return nullptr; - - if (!pAnnot->HasForm()) { - CPDF_Stream* pStream = FPDFDOC_GetAnnotAP( - pAnnot->GetAnnotDict(), CPDF_Annot::AppearanceMode::Normal); - if (!pStream) - return nullptr; - - pAnnot->SetForm(pStream); - } - - return pAnnot->GetForm()->GetPageObjectList()->GetPageObjectByIndex(index); -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_RemoveObject(FPDF_ANNOTATION annot, int index) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot || !pAnnot->GetAnnotDict() || !pAnnot->HasForm() || index < 0) - return false; - - // Check that the annotation type is supported by this method. - if (!FPDFAnnot_IsObjectSupportedSubtype(FPDFAnnot_GetSubtype(annot))) - return false; - - // Check that the annotation already has an appearance stream, since an - // existing object is to be deleted. - CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(pAnnot->GetAnnotDict(), - CPDF_Annot::AppearanceMode::Normal); - if (!pStream) - return false; - - CPDF_PageObjectList* pObjList = pAnnot->GetForm()->GetPageObjectList(); - if (static_cast<size_t>(index) >= pObjList->size()) - return false; - - pObjList->erase(pObjList->begin() + index); - UpdateContentStream(pAnnot->GetForm(), pStream); - return true; -} - -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) { - if (!annot || R > 255 || G > 255 || B > 255 || A > 255) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - // For annotations with their appearance streams already defined, the path - // stream's own color definitions take priority over the annotation color - // definitions set by this method, hence this method will simply fail. - if (HasAPStream(pAnnotDict)) - return false; - - // Set the opacity of the annotation. - pAnnotDict->SetNewFor<CPDF_Number>("CA", A / 255.f); - - // Set the color of the annotation. - ByteString key = type == FPDFANNOT_COLORTYPE_InteriorColor ? "IC" : "C"; - CPDF_Array* pColor = pAnnotDict->GetArrayFor(key); - if (pColor) - pColor->Clear(); - else - pColor = pAnnotDict->SetNewFor<CPDF_Array>(key); - - pColor->AddNew<CPDF_Number>(R / 255.f); - pColor->AddNew<CPDF_Number>(G / 255.f); - pColor->AddNew<CPDF_Number>(B / 255.f); - - return true; -} - -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) { - if (!annot || !R || !G || !B || !A) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - // For annotations with their appearance streams already defined, the path - // stream's own color definitions take priority over the annotation color - // definitions retrieved by this method, hence this method will simply fail. - if (HasAPStream(pAnnotDict)) - return false; - - CPDF_Array* pColor = pAnnotDict->GetArrayFor( - type == FPDFANNOT_COLORTYPE_InteriorColor ? "IC" : "C"); - *A = - (pAnnotDict->KeyExist("CA") ? pAnnotDict->GetNumberFor("CA") : 1) * 255.f; - if (!pColor) { - // Use default color. The default colors must be consistent with the ones - // used to generate AP. See calls to GetColorStringWithDefault() in - // CPVT_GenerateAP::Generate*AP(). - if (pAnnotDict->GetStringFor("Subtype") == "Highlight") { - *R = 255; - *G = 255; - *B = 0; - } else { - *R = 0; - *G = 0; - *B = 0; - } - return true; - } - - CFX_Color color = CFX_Color::ParseColor(*pColor); - switch (color.nColorType) { - case CFX_Color::kRGB: - *R = color.fColor1 * 255.f; - *G = color.fColor2 * 255.f; - *B = color.fColor3 * 255.f; - break; - case CFX_Color::kGray: - *R = 255.f * color.fColor1; - *G = 255.f * color.fColor1; - *B = 255.f * color.fColor1; - break; - case CFX_Color::kCMYK: - *R = 255.f * (1 - color.fColor1) * (1 - color.fColor4); - *G = 255.f * (1 - color.fColor2) * (1 - color.fColor4); - *B = 255.f * (1 - color.fColor3) * (1 - color.fColor4); - break; - case CFX_Color::kTransparent: - *R = 0; - *G = 0; - *B = 0; - break; - } - return true; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot) { - if (!annot) - return false; - - FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot); - return subtype == FPDF_ANNOT_LINK || subtype == FPDF_ANNOT_HIGHLIGHT || - subtype == FPDF_ANNOT_UNDERLINE || subtype == FPDF_ANNOT_SQUIGGLY || - subtype == FPDF_ANNOT_STRIKEOUT; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, - const FS_QUADPOINTSF* quad_points) { - if (!FPDFAnnot_HasAttachmentPoints(annot) || !quad_points) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - // Update the "QuadPoints" entry in the annotation dictionary. - CPDF_Array* pQuadPoints = pAnnotDict->GetArrayFor("QuadPoints"); - if (pQuadPoints) - pQuadPoints->Clear(); - else - pQuadPoints = pAnnotDict->SetNewFor<CPDF_Array>("QuadPoints"); - - pQuadPoints->AddNew<CPDF_Number>(quad_points->x1); - pQuadPoints->AddNew<CPDF_Number>(quad_points->y1); - pQuadPoints->AddNew<CPDF_Number>(quad_points->x2); - pQuadPoints->AddNew<CPDF_Number>(quad_points->y2); - pQuadPoints->AddNew<CPDF_Number>(quad_points->x3); - pQuadPoints->AddNew<CPDF_Number>(quad_points->y3); - pQuadPoints->AddNew<CPDF_Number>(quad_points->x4); - pQuadPoints->AddNew<CPDF_Number>(quad_points->y4); - - // If the annotation's appearance stream is defined, and the new quadpoints - // defines a bigger bounding box than the appearance stream currently - // specifies, then update the "BBox" entry in the AP dictionary too, since it - // comes from annotation dictionary's "QuadPoints" entry. - CPDF_Stream* pStream = - FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); - if (pStream) { - CFX_FloatRect newRect = CPDF_Annot::BoundingRectFromQuadPoints(pAnnotDict); - if (newRect.Contains(pStream->GetDict()->GetRectFor("BBox"))) - pStream->GetDict()->SetRectFor("BBox", newRect); - } - return true; -} - -FPDF_EXPORT size_t FPDF_CALLCONV -FPDFAnnot_CountAttachmentPoints(FPDF_ANNOTATION annot) { - if (!FPDFAnnot_HasAttachmentPoints(annot)) - return 0; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - const CPDF_Array* pArray = GetQuadPointsArrayFromDictionary(pAnnotDict); - return pArray ? pArray->GetCount() / 8 : 0; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot, - FS_QUADPOINTSF* quad_points) { - if (!FPDFAnnot_HasAttachmentPoints(annot) || !quad_points) - return false; - - return GetQuadPointsFromDictionary( - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(), 0, - quad_points); -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetRect(FPDF_ANNOTATION annot, - const FS_RECTF* rect) { - if (!annot || !rect) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - CFX_FloatRect newRect = CFXFloatRectFromFSRECTF(*rect); - - // Update the "Rect" entry in the annotation dictionary. - pAnnotDict->SetRectFor("Rect", newRect); - - // If the annotation's appearance stream is defined, the annotation is of a - // type that does not have quadpoints, and the new rectangle is bigger than - // the current bounding box, then update the "BBox" entry in the AP - // dictionary too, since its "BBox" entry comes from annotation dictionary's - // "Rect" entry. - if (FPDFAnnot_HasAttachmentPoints(annot)) - return true; - - CPDF_Stream* pStream = - FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); - if (pStream && newRect.Contains(pStream->GetDict()->GetRectFor("BBox"))) - pStream->GetDict()->SetRectFor("BBox", newRect); - return true; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetRect(FPDF_ANNOTATION annot, - FS_RECTF* rect) { - if (!annot || !rect) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - FSRECTFFromCFXFloatRect(pAnnotDict->GetRectFor("Rect"), rect); - return true; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_HasKey(FPDF_ANNOTATION annot, - FPDF_BYTESTRING key) { - if (!annot) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - return pAnnotDict->KeyExist(key); -} - -FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV -FPDFAnnot_GetValueType(FPDF_ANNOTATION annot, FPDF_BYTESTRING key) { - if (!FPDFAnnot_HasKey(annot, key)) - return FPDF_OBJECT_UNKNOWN; - - auto* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - CPDF_Object* pObj = pAnnot->GetAnnotDict()->GetObjectFor(key); - return pObj ? pObj->GetType() : FPDF_OBJECT_UNKNOWN; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_SetStringValue(FPDF_ANNOTATION annot, - FPDF_BYTESTRING key, - FPDF_WIDESTRING value) { - if (!annot) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - pAnnotDict->SetNewFor<CPDF_String>( - key, CFXByteStringFromFPDFWideString(value), false); - return true; -} - -FPDF_EXPORT unsigned long FPDF_CALLCONV -FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot, - FPDF_BYTESTRING key, - void* buffer, - unsigned long buflen) { - if (!annot) - return 0; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return 0; - - return Utf16EncodeMaybeCopyAndReturnLength(pAnnotDict->GetUnicodeTextFor(key), - buffer, buflen); -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -FPDFAnnot_SetAP(FPDF_ANNOTATION annot, - FPDF_ANNOT_APPEARANCEMODE appearanceMode, - FPDF_WIDESTRING value) { - if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT) - return false; - - if (!annot) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - constexpr const char* modeKeyForMode[] = {"N", "R", "D"}; - static_assert(FX_ArraySize(modeKeyForMode) == FPDF_ANNOT_APPEARANCEMODE_COUNT, - "length of modeKeyForMode should be equal to " - "FPDF_ANNOT_APPEARANCEMODE_COUNT"); - const char* modeKey = modeKeyForMode[appearanceMode]; - - CPDF_Dictionary* pApDict = pAnnotDict->GetDictFor("AP"); - - // If value is null, we're in remove mode. Otherwise, we're in add/update - // mode. - if (value) { - if (!pApDict) - pApDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP"); - - ByteString newValue = CFXByteStringFromFPDFWideString(value); - auto pNewApStream = pdfium::MakeUnique<CPDF_Stream>(); - pNewApStream->SetData(newValue.raw_str(), newValue.GetLength()); - pApDict->SetFor(modeKey, std::move(pNewApStream)); - } else { - if (pApDict) { - if (appearanceMode == FPDF_ANNOT_APPEARANCEMODE_NORMAL) - pAnnotDict->RemoveFor("AP"); - else - pApDict->RemoveFor(modeKey); - } - } - - return true; -} - -FPDF_EXPORT unsigned long FPDF_CALLCONV -FPDFAnnot_GetAP(FPDF_ANNOTATION annot, - FPDF_ANNOT_APPEARANCEMODE appearanceMode, - void* buffer, - unsigned long buflen) { - if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT) - return 0; - - if (!annot) - return 0; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return 0; - - CPDF_Annot::AppearanceMode mode = - static_cast<CPDF_Annot::AppearanceMode>(appearanceMode); - - CPDF_Stream* pStream = FPDFDOC_GetAnnotAPNoFallback(pAnnotDict, mode); - return Utf16EncodeMaybeCopyAndReturnLength( - pStream ? pStream->GetUnicodeText() : L"", buffer, buflen); -} - -FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV -FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_BYTESTRING key) { - CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot || !pAnnot->GetAnnotDict()) - return nullptr; - - CPDF_Dictionary* pLinkedDict = pAnnot->GetAnnotDict()->GetDictFor(key); - if (!pLinkedDict || pLinkedDict->GetStringFor("Type") != "Annot") - return nullptr; - - auto pLinkedAnnot = pdfium::MakeUnique<CPDF_AnnotContext>( - pLinkedDict, pAnnot->GetPage(), nullptr); - return pLinkedAnnot.release(); -} - -FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFlags(FPDF_ANNOTATION annot) { - if (!annot) - return FPDF_ANNOT_FLAG_NONE; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - return pAnnotDict ? pAnnotDict->GetIntegerFor("F") : FPDF_ANNOT_FLAG_NONE; -} - -FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetFlags(FPDF_ANNOTATION annot, - int flags) { - if (!annot) - return false; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return false; - - pAnnotDict->SetNewFor<CPDF_Number>("F", flags); - return true; -} - -FPDF_EXPORT int FPDF_CALLCONV -FPDFAnnot_GetFormFieldFlags(FPDF_PAGE page, FPDF_ANNOTATION annot) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!pPage || !annot) - return FPDF_FORMFLAG_NONE; - - CPDF_Dictionary* pAnnotDict = - CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict(); - if (!pAnnotDict) - return FPDF_FORMFLAG_NONE; - - CPDF_InterForm interform(pPage->m_pDocument.Get()); - CPDF_FormField* pFormField = interform.GetFieldByDict(pAnnotDict); - return pFormField ? pFormField->GetFieldFlags() : FPDF_FORMFLAG_NONE; -} - -FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV -FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle, - FPDF_PAGE page, - double page_x, - double page_y) { - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); - if (!hHandle || !pPage) - return nullptr; - - CPDF_InterForm interform(pPage->m_pDocument.Get()); - int annot_index = -1; - CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint( - pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)), - &annot_index); - if (!pFormCtrl || annot_index == -1) - return nullptr; - return FPDFPage_GetAnnot(page, annot_index); -} |