summaryrefslogtreecommitdiff
path: root/fpdfsdk/fpdfannot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/fpdfannot.cpp')
-rw-r--r--fpdfsdk/fpdfannot.cpp65
1 files changed, 48 insertions, 17 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp
index b8043b0a66..faa4f4c8fb 100644
--- a/fpdfsdk/fpdfannot.cpp
+++ b/fpdfsdk/fpdfannot.cpp
@@ -176,6 +176,15 @@ CFX_ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING text) {
return CFX_WideString::FromUTF16LE(text, CFX_WideString::WStringLength(text))
.UTF8Encode();
}
+void UpdateContentStream(CPDF_Form* pForm, CPDF_Stream* pStream) {
+ ASSERT(pForm);
+ ASSERT(pStream);
+
+ CPDF_PageContentGenerator generator(pForm);
+ std::ostringstream buf;
+ generator.ProcessPageObjects(&buf);
+ pStream->SetData(&buf);
+}
} // namespace
@@ -266,6 +275,12 @@ FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) {
CPDF_Annot::StringToAnnotSubtype(pAnnotDict->GetStringFor("Subtype")));
}
+DLLEXPORT FPDF_BOOL STDCALL
+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;
+}
+
DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot,
FPDF_PAGEOBJECT obj) {
CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot);
@@ -274,8 +289,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot,
return false;
// Check that the annotation type is supported by this method.
- FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
- if (subtype != FPDF_ANNOT_INK && subtype != FPDF_ANNOT_STAMP)
+ if (!FPDFAnnot_IsObjectSupportedSubtype(FPDFAnnot_GetSubtype(annot)))
return false;
// Check that the annotation already has an appearance stream, since an
@@ -286,7 +300,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot,
return false;
// Check that the object is already in this annotation's object list.
- CPDF_PageObjectList* pObjList = pAnnot->GetForm()->GetPageObjectList();
+ 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) {
@@ -296,11 +311,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot,
return false;
// Update the content stream data in the annotation's AP stream.
- CPDF_PageContentGenerator generator(pAnnot->GetForm());
- std::ostringstream buf;
- generator.ProcessPageObjects(&buf);
- pStream->SetData(reinterpret_cast<const uint8_t*>(buf.str().c_str()),
- buf.tellp());
+ UpdateContentStream(pForm, pStream);
return true;
}
@@ -317,8 +328,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendObject(FPDF_ANNOTATION annot,
return false;
// Check that the annotation type is supported by this method.
- FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
- if (subtype != FPDF_ANNOT_INK && subtype != FPDF_ANNOT_STAMP)
+ if (!FPDFAnnot_IsObjectSupportedSubtype(FPDFAnnot_GetSubtype(annot)))
return false;
// If the annotation does not have an AP stream yet, generate and set it.
@@ -343,13 +353,12 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendObject(FPDF_ANNOTATION annot,
if (!pAnnot->HasForm())
pAnnot->SetForm(pStream);
- CPDF_Form* pForm = pAnnot->GetForm();
-
// 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(),
@@ -364,11 +373,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendObject(FPDF_ANNOTATION annot,
pObjList->push_back(std::move(pPageObjHolder));
// Set the content stream data in the annotation's AP stream.
- CPDF_PageContentGenerator generator(pForm);
- std::ostringstream buf;
- generator.ProcessPageObjects(&buf);
- pStream->SetData(reinterpret_cast<const uint8_t*>(buf.str().c_str()),
- buf.tellp());
+ UpdateContentStream(pForm, pStream);
return true;
}
@@ -406,6 +411,32 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetObject(FPDF_ANNOTATION annot,
return pAnnot->GetForm()->GetPageObjectList()->GetPageObjectByIndex(index);
}
+DLLEXPORT FPDF_BOOL STDCALL 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;
+}
+
DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetColor(FPDF_ANNOTATION annot,
FPDFANNOT_COLORTYPE type,
unsigned int R,