summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-07-10 21:04:05 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-07-10 21:04:05 +0000
commit144107d3ca6ddd2724a460c4da4a20e6e1b7f1b7 (patch)
tree7fc11c898c7d5397f8b910d447eccfd04680f288
parent416cbeab1d93b1261dfb4584e0c8e47d9cd4720f (diff)
downloadpdfium-144107d3ca6ddd2724a460c4da4a20e6e1b7f1b7.tar.xz
Create API for adding content marks and setting their params.chromium/3488
This CL creates the following new functions in the public API: - FPDFPageObj_AddMark - FPDFPageObjMark_SetIntParam - FPDFPageObjMark_SetStringParam Bug: pdfium:1037 Change-Id: Icabf3fdd8e8153b9156bab807a3708d38a9365d8 Reviewed-on: https://pdfium-review.googlesource.com/37330 Commit-Queue: Henrique Nakashima <hnakashima@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r--core/fpdfapi/page/cpdf_contentmark.cpp19
-rw-r--r--core/fpdfapi/page/cpdf_contentmark.h14
-rw-r--r--core/fpdfapi/page/cpdf_contentmarkitem.cpp14
-rw-r--r--core/fpdfapi/page/cpdf_contentmarkitem.h7
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp4
-rw-r--r--core/fpdfdoc/cpdf_occontext.cpp8
-rw-r--r--core/fpdftext/cpdf_textpage.cpp10
-rw-r--r--fpdfsdk/cpdfsdk_helpers.h6
-rw-r--r--fpdfsdk/fpdf_edit_embeddertest.cpp77
-rw-r--r--fpdfsdk/fpdf_editpage.cpp64
-rw-r--r--fpdfsdk/fpdf_view_c_api_test.c3
-rw-r--r--public/fpdf_edit.h47
-rw-r--r--public/fpdfview.h2
13 files changed, 244 insertions, 31 deletions
diff --git a/core/fpdfapi/page/cpdf_contentmark.cpp b/core/fpdfapi/page/cpdf_contentmark.cpp
index 6021dc893d..912cc0ea03 100644
--- a/core/fpdfapi/page/cpdf_contentmark.cpp
+++ b/core/fpdfapi/page/cpdf_contentmark.cpp
@@ -29,7 +29,12 @@ size_t CPDF_ContentMark::CountItems() const {
return m_pMarkData->CountItems();
}
-const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(size_t i) const {
+CPDF_ContentMarkItem* CPDF_ContentMark::GetItem(size_t i) {
+ ASSERT(i < CountItems());
+ return m_pMarkData->GetItem(i);
+}
+
+const CPDF_ContentMarkItem* CPDF_ContentMark::GetItem(size_t i) const {
ASSERT(i < CountItems());
return m_pMarkData->GetItem(i);
}
@@ -42,7 +47,7 @@ int CPDF_ContentMark::GetMarkedContentID() const {
}
void CPDF_ContentMark::AddMark(ByteString name,
- const CPDF_Dictionary* pDict,
+ CPDF_Dictionary* pDict,
bool bDirect) {
if (!m_pMarkData)
m_pMarkData.Reset(new MarkData());
@@ -70,9 +75,13 @@ size_t CPDF_ContentMark::MarkData::CountItems() const {
return m_Marks.size();
}
-const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(
+CPDF_ContentMarkItem* CPDF_ContentMark::MarkData::GetItem(size_t index) {
+ return m_Marks[index].Get();
+}
+
+const CPDF_ContentMarkItem* CPDF_ContentMark::MarkData::GetItem(
size_t index) const {
- return *m_Marks[index];
+ return m_Marks[index].Get();
}
int CPDF_ContentMark::MarkData::GetMarkedContentID() const {
@@ -85,7 +94,7 @@ int CPDF_ContentMark::MarkData::GetMarkedContentID() const {
}
void CPDF_ContentMark::MarkData::AddMark(ByteString name,
- const CPDF_Dictionary* pDict,
+ CPDF_Dictionary* pDict,
bool bDirect) {
auto pItem = pdfium::MakeRetain<CPDF_ContentMarkItem>();
pItem->SetName(std::move(name));
diff --git a/core/fpdfapi/page/cpdf_contentmark.h b/core/fpdfapi/page/cpdf_contentmark.h
index ac21151ede..e0ae1bf549 100644
--- a/core/fpdfapi/page/cpdf_contentmark.h
+++ b/core/fpdfapi/page/cpdf_contentmark.h
@@ -24,9 +24,12 @@ class CPDF_ContentMark {
std::unique_ptr<CPDF_ContentMark> Clone();
int GetMarkedContentID() const;
size_t CountItems() const;
- const CPDF_ContentMarkItem& GetItem(size_t i) const;
- void AddMark(ByteString name, const CPDF_Dictionary* pDict, bool bDirect);
+ // The returned pointer is never null.
+ CPDF_ContentMarkItem* GetItem(size_t i);
+ const CPDF_ContentMarkItem* GetItem(size_t i) const;
+
+ void AddMark(ByteString name, CPDF_Dictionary* pDict, bool bDirect);
void DeleteLastMark();
private:
@@ -37,12 +40,11 @@ class CPDF_ContentMark {
~MarkData() override;
size_t CountItems() const;
- const CPDF_ContentMarkItem& GetItem(size_t index) const;
+ CPDF_ContentMarkItem* GetItem(size_t index);
+ const CPDF_ContentMarkItem* GetItem(size_t index) const;
int GetMarkedContentID() const;
- void AddMark(ByteString name,
- const CPDF_Dictionary* pDict,
- bool bDictNeedClone);
+ void AddMark(ByteString name, CPDF_Dictionary* pDict, bool bDictNeedClone);
void DeleteLastMark();
private:
diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.cpp b/core/fpdfapi/page/cpdf_contentmarkitem.cpp
index 4f56eea919..dd9f7e884c 100644
--- a/core/fpdfapi/page/cpdf_contentmarkitem.cpp
+++ b/core/fpdfapi/page/cpdf_contentmarkitem.cpp
@@ -26,6 +26,18 @@ const CPDF_Dictionary* CPDF_ContentMarkItem::GetParam() const {
}
}
+CPDF_Dictionary* CPDF_ContentMarkItem::GetParam() {
+ switch (m_ParamType) {
+ case PropertiesDict:
+ return m_pPropertiesDict.Get();
+ case DirectDict:
+ return m_pDirectDict.get();
+ case None:
+ default:
+ return nullptr;
+ }
+}
+
bool CPDF_ContentMarkItem::HasMCID() const {
const CPDF_Dictionary* pDict = GetParam();
return pDict && pDict->KeyExist("MCID");
@@ -37,7 +49,7 @@ void CPDF_ContentMarkItem::SetDirectDict(
m_pDirectDict = std::move(pDict);
}
-void CPDF_ContentMarkItem::SetPropertiesDict(const CPDF_Dictionary* pDict) {
+void CPDF_ContentMarkItem::SetPropertiesDict(CPDF_Dictionary* pDict) {
m_ParamType = PropertiesDict;
m_pPropertiesDict = pDict;
}
diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.h b/core/fpdfapi/page/cpdf_contentmarkitem.h
index 72548cef9c..343db9d1a6 100644
--- a/core/fpdfapi/page/cpdf_contentmarkitem.h
+++ b/core/fpdfapi/page/cpdf_contentmarkitem.h
@@ -27,17 +27,18 @@ class CPDF_ContentMarkItem : public Retainable {
ByteString GetName() const { return m_MarkName; }
ParamType GetParamType() const { return m_ParamType; }
const CPDF_Dictionary* GetParam() const;
+ CPDF_Dictionary* GetParam();
bool HasMCID() const;
void SetName(const ByteString& name) { m_MarkName = name; }
void SetDirectDict(std::unique_ptr<CPDF_Dictionary> pDict);
- void SetPropertiesDict(const CPDF_Dictionary* pDict);
+ void SetPropertiesDict(CPDF_Dictionary* pDict);
private:
ByteString m_MarkName;
ParamType m_ParamType = None;
- UnownedPtr<const CPDF_Dictionary> m_pPropertiesDict;
- std::unique_ptr<const CPDF_Dictionary> m_pDirectDict;
+ UnownedPtr<CPDF_Dictionary> m_pPropertiesDict;
+ std::unique_ptr<CPDF_Dictionary> m_pDirectDict;
};
#endif // CORE_FPDFAPI_PAGE_CPDF_CONTENTMARKITEM_H_
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index ba7388cf15..01fb347a9a 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -603,7 +603,7 @@ void CPDF_StreamContentParser::Handle_EOFillStrokePath() {
void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() {
ByteString tag = GetString(1);
- const CPDF_Object* pProperty = GetObject(0);
+ CPDF_Object* pProperty = GetObject(0);
if (!pProperty)
return;
@@ -614,7 +614,7 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() {
return;
bDirect = false;
}
- if (const CPDF_Dictionary* pDict = pProperty->AsDictionary()) {
+ if (CPDF_Dictionary* pDict = pProperty->AsDictionary()) {
std::unique_ptr<CPDF_ContentMark> new_marks =
m_ContentMarksStack.top()->Clone();
new_marks->AddMark(std::move(tag), pDict, bDirect);
diff --git a/core/fpdfdoc/cpdf_occontext.cpp b/core/fpdfdoc/cpdf_occontext.cpp
index 2aac2131a1..727696bdae 100644
--- a/core/fpdfdoc/cpdf_occontext.cpp
+++ b/core/fpdfdoc/cpdf_occontext.cpp
@@ -182,10 +182,10 @@ bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) {
bool CPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) {
for (size_t i = 0; i < pObj->m_ContentMark.CountItems(); ++i) {
- const CPDF_ContentMarkItem& item = pObj->m_ContentMark.GetItem(i);
- if (item.GetName() == "OC" &&
- item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict &&
- !CheckOCGVisible(item.GetParam())) {
+ const CPDF_ContentMarkItem* item = pObj->m_ContentMark.GetItem(i);
+ if (item->GetName() == "OC" &&
+ item->GetParamType() == CPDF_ContentMarkItem::PropertiesDict &&
+ !CheckOCGVisible(item->GetParam())) {
return false;
}
}
diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp
index 4c3196427a..2894160437 100644
--- a/core/fpdftext/cpdf_textpage.cpp
+++ b/core/fpdftext/cpdf_textpage.cpp
@@ -846,8 +846,8 @@ FPDFText_MarkedContent CPDF_TextPage::PreMarkedContent(PDFTEXT_Obj Obj) {
bool bExist = false;
const CPDF_Dictionary* pDict = nullptr;
for (size_t i = 0; i < nContentMark; ++i) {
- const CPDF_ContentMarkItem& item = pTextObj->m_ContentMark.GetItem(i);
- pDict = item.GetParam();
+ const CPDF_ContentMarkItem* item = pTextObj->m_ContentMark.GetItem(i);
+ pDict = item->GetParam();
if (!pDict)
continue;
const CPDF_String* temp = ToString(pDict->GetObjectFor("ActualText"));
@@ -862,7 +862,7 @@ FPDFText_MarkedContent CPDF_TextPage::PreMarkedContent(PDFTEXT_Obj Obj) {
if (m_pPreTextObj) {
const CPDF_ContentMark& mark = m_pPreTextObj->m_ContentMark;
if (mark.CountItems() == nContentMark &&
- mark.GetItem(nContentMark - 1).GetParam() == pDict) {
+ mark.GetItem(nContentMark - 1)->GetParam() == pDict) {
return FPDFText_MarkedContent::Done;
}
}
@@ -904,8 +904,8 @@ void CPDF_TextPage::ProcessMarkedContent(PDFTEXT_Obj Obj) {
WideString actText;
for (size_t n = 0; n < nContentMark; n++) {
- const CPDF_ContentMarkItem& item = pTextObj->m_ContentMark.GetItem(n);
- const CPDF_Dictionary* pDict = item.GetParam();
+ const CPDF_ContentMarkItem* item = pTextObj->m_ContentMark.GetItem(n);
+ const CPDF_Dictionary* pDict = item->GetParam();
if (pDict)
actText = pDict->GetUnicodeTextFor("ActualText");
}
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 88e05302fe..4fd85cfc72 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -139,12 +139,12 @@ inline CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(
}
inline FPDF_PAGEOBJECTMARK FPDFPageObjectMarkFromCPDFContentMarkItem(
- const CPDF_ContentMarkItem* mark) {
+ CPDF_ContentMarkItem* mark) {
return reinterpret_cast<FPDF_PAGEOBJECTMARK>(mark);
}
-inline const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
+inline CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
FPDF_PAGEOBJECTMARK mark) {
- return reinterpret_cast<const CPDF_ContentMarkItem*>(mark);
+ return reinterpret_cast<CPDF_ContentMarkItem*>(mark);
}
inline FPDF_PAGERANGE FPDFPageRangeFromCPDFArray(const CPDF_Array* range) {
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index a490162e15..a9eca92a4e 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -2021,6 +2021,83 @@ TEST_F(FPDFEditEmbeddertest, SaveAndRender) {
VerifySavedDocument(612, 792, md5);
}
+TEST_F(FPDFEditEmbeddertest, AddMarkedText) {
+ // Start with a blank page.
+ FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
+
+ const CPDF_Font* stock_font = CPDF_Font::GetStockFont(cpdf_doc(), "Arial");
+ const uint8_t* data = stock_font->GetFont()->GetFontData();
+ const uint32_t size = stock_font->GetFont()->GetSize();
+ ScopedFPDFFont font(
+ FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 0));
+ ASSERT_TRUE(font.get());
+
+ // Add some text to the page.
+ FPDF_PAGEOBJECT text_object =
+ FPDFPageObj_CreateTextObj(document(), font.get(), 12.0f);
+
+ EXPECT_TRUE(text_object);
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text1 =
+ GetFPDFWideString(L"I am testing my loaded font, WEE.");
+ EXPECT_TRUE(FPDFText_SetText(text_object, text1.get()));
+ FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 400, 400);
+ FPDFPage_InsertObject(page, text_object);
+
+ // Add a mark with the tag "TestMarkName" to that text.
+ EXPECT_EQ(0, FPDFPageObj_CountMarks(text_object));
+ FPDF_PAGEOBJECTMARK mark = FPDFPageObj_AddMark(text_object, "TestMarkName");
+ EXPECT_TRUE(mark);
+ EXPECT_EQ(1, FPDFPageObj_CountMarks(text_object));
+ EXPECT_EQ(mark, FPDFPageObj_GetMark(text_object, 0));
+ char buffer[256];
+ EXPECT_GT(FPDFPageObjMark_GetName(mark, buffer, 256), 0u);
+ std::wstring name =
+ GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ EXPECT_EQ(L"TestMarkName", name);
+
+ // Add parameters:
+ // - int "IntKey" : 42
+ // - string "StringKey": "StringValue"
+ EXPECT_EQ(0, FPDFPageObjMark_CountParams(mark));
+ EXPECT_TRUE(FPDFPageObjMark_SetIntParam(document(), mark, "IntKey", 42));
+ EXPECT_TRUE(FPDFPageObjMark_SetStringParam(document(), mark, "StringKey",
+ "StringValue"));
+ EXPECT_EQ(2, FPDFPageObjMark_CountParams(mark));
+
+ // Check the two parameters can be retrieved.
+ EXPECT_EQ(FPDF_OBJECT_NUMBER,
+ FPDFPageObjMark_GetParamValueTypeByKey(mark, "IntKey"));
+ int int_value;
+ EXPECT_TRUE(
+ FPDFPageObjMark_GetParamIntValueByKey(mark, "IntKey", &int_value));
+ EXPECT_EQ(42, int_value);
+
+ EXPECT_EQ(FPDF_OBJECT_STRING,
+ FPDFPageObjMark_GetParamValueTypeByKey(mark, "StringKey"));
+ unsigned long out_buffer_len;
+ EXPECT_TRUE(FPDFPageObjMark_GetParamStringValueByKey(
+ mark, "StringKey", buffer, 256, &out_buffer_len));
+ EXPECT_GT(out_buffer_len, 0u);
+ name = GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ EXPECT_EQ(L"StringValue", name);
+
+// Render and check the bitmap is the expected one.
+#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
+ const char md5[] = "17d2b6cd574cf66170b09c8927529a94";
+#else
+ const char md5[] = "70592859010ffbf532a2237b8118bcc4";
+#endif
+ {
+ ScopedFPDFBitmap page_bitmap = RenderPageWithFlags(page, nullptr, 0);
+ CompareBitmap(page_bitmap.get(), 612, 792, md5);
+ }
+
+ FPDF_ClosePage(page);
+
+ // TODO(pdfium:1118): Save, then re-open the file and check the changes were
+ // kept in the saved .pdf.
+}
+
TEST_F(FPDFEditEmbeddertest, ExtractImageBitmap) {
ASSERT_TRUE(OpenDocument("embedded_images.pdf"));
FPDF_PAGE page = LoadPage(0);
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index d275559107..8a1200885a 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -125,6 +125,30 @@ GetMarkParamPairAtIndex(FPDF_PAGEOBJECTMARK mark, unsigned long index) {
return nullptr;
}
+CPDF_Dictionary* GetOrCreateMarkParamsDict(FPDF_DOCUMENT document,
+ FPDF_PAGEOBJECTMARK mark) {
+ CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+ if (!pDoc)
+ return nullptr;
+
+ CPDF_ContentMarkItem* pMarkItem =
+ CPDFContentMarkItemFromFPDFPageObjectMark(mark);
+ if (!pMarkItem)
+ return nullptr;
+
+ CPDF_Dictionary* pParams = pMarkItem->GetParam();
+
+ // If the Params dict does not exist, create a new one.
+ if (!pParams) {
+ auto new_dict =
+ pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
+ pParams = new_dict.get();
+ pMarkItem->SetDirectDict(std::move(new_dict));
+ }
+
+ return pParams;
+}
+
unsigned int GetUnsignedAlpha(float alpha) {
return static_cast<unsigned int>(alpha * 255.f + 0.5f);
}
@@ -293,7 +317,19 @@ FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index) {
if (index >= mark->CountItems())
return nullptr;
- return FPDFPageObjectMarkFromCPDFContentMarkItem(&mark->GetItem(index));
+ return FPDFPageObjectMarkFromCPDFContentMarkItem(mark->GetItem(index));
+}
+
+FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
+FPDFPageObj_AddMark(FPDF_PAGEOBJECT page_object, FPDF_BYTESTRING name) {
+ if (!page_object)
+ return nullptr;
+
+ auto* mark = &CPDFPageObjectFromFPDFPageObject(page_object)->m_ContentMark;
+ mark->AddMark(name, nullptr, true);
+ unsigned long index = mark->CountItems() - 1;
+
+ return FPDFPageObjectMarkFromCPDFContentMarkItem(mark->GetItem(index));
}
FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -456,6 +492,32 @@ FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) {
return false;
}
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPageObjMark_SetIntParam(FPDF_DOCUMENT document,
+ FPDF_PAGEOBJECTMARK mark,
+ FPDF_BYTESTRING key,
+ int value) {
+ CPDF_Dictionary* pParams = GetOrCreateMarkParamsDict(document, mark);
+ if (!pParams)
+ return false;
+
+ pParams->SetNewFor<CPDF_Number>(key, value);
+ return true;
+}
+
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document,
+ FPDF_PAGEOBJECTMARK mark,
+ FPDF_BYTESTRING key,
+ FPDF_BYTESTRING value) {
+ CPDF_Dictionary* pParams = GetOrCreateMarkParamsDict(document, mark);
+ if (!pParams)
+ return false;
+
+ pParams->SetNewFor<CPDF_String>(key, value, false);
+ return true;
+}
+
FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT pageObject) {
if (!pageObject)
return FPDF_PAGEOBJ_UNKNOWN;
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index 51b5884e80..53d5a77cfd 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -145,6 +145,9 @@ int CheckPDFiumCApi() {
CHK(FPDFPageObjMark_GetParamStringValueByKey);
CHK(FPDFPageObjMark_GetParamValueType);
CHK(FPDFPageObjMark_GetParamValueTypeByKey);
+ CHK(FPDFPageObjMark_SetIntParam);
+ CHK(FPDFPageObjMark_SetStringParam);
+ CHK(FPDFPageObj_AddMark);
CHK(FPDFPageObj_CountMarks);
CHK(FPDFPageObj_CreateNewPath);
CHK(FPDFPageObj_CreateNewRect);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index 380a0a236e..b85537d0b9 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -317,6 +317,19 @@ FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index);
// Experimental API.
+// Add a new content mark to a |page_object|.
+//
+// page_object - handle to a page object.
+// name - the name (tag) of the mark.
+//
+// Returns the handle to the content mark, or NULL on failure. The handle is
+// still owned by the library, and it should not be freed directly. It becomes
+// invalid if the page object is destroyed, either directly or indirectly by
+// unloading the page.
+FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV
+FPDFPageObj_AddMark(FPDF_PAGEOBJECT page_object, FPDF_BYTESTRING name);
+
+// Experimental API.
// Get name of a content mark. |buffer| is only modified if |buflen| is longer
// than the length of the name.
//
@@ -441,6 +454,40 @@ FPDFPageObjMark_GetParamStringValueByKey(FPDF_PAGEOBJECTMARK mark,
unsigned long buflen,
unsigned long* out_buflen);
+// Experimental API.
+// Set the value of an int property in a content mark by key. If a parameter
+// with key |key| exists, its value is set to |value|. Otherwise, it is added as
+// a new parameter.
+//
+// document - handle to the document.
+// mark - handle to a content mark.
+// key - string key of the property.
+// value - int value to set.
+//
+// Returns TRUE if the operation succeeded, FALSE otherwise.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPageObjMark_SetIntParam(FPDF_DOCUMENT document,
+ FPDF_PAGEOBJECTMARK mark,
+ FPDF_BYTESTRING key,
+ int value);
+
+// Experimental API.
+// Set the value of a string property in a content mark by key. If a parameter
+// with key |key| exists, its value is set to |value|. Otherwise, it is added as
+// a new parameter.
+//
+// document - handle to the document.
+// mark - handle to a content mark.
+// key - string key of the property.
+// value - string value to set.
+//
+// Returns TRUE if the operation succeeded, FALSE otherwise.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document,
+ FPDF_PAGEOBJECTMARK mark,
+ FPDF_BYTESTRING key,
+ FPDF_BYTESTRING value);
+
// Load an image from a JPEG image file and then set it into |image_object|.
//
// pages - pointer to the start of all loaded pages, may be NULL.
diff --git a/public/fpdfview.h b/public/fpdfview.h
index de0421eb32..a35e34acc3 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -48,7 +48,7 @@ typedef struct fpdf_link_t__* FPDF_LINK;
typedef struct fpdf_page_t__* FPDF_PAGE;
typedef struct fpdf_pagelink_t__* FPDF_PAGELINK;
typedef struct fpdf_pageobject_t__* FPDF_PAGEOBJECT; // (text, path, etc.)
-typedef const struct fpdf_pageobjectmark_t__* FPDF_PAGEOBJECTMARK;
+typedef struct fpdf_pageobjectmark_t__* FPDF_PAGEOBJECTMARK;
typedef const struct fpdf_pagerange_t__* FPDF_PAGERANGE;
typedef const struct fpdf_pathsegment_t* FPDF_PATHSEGMENT;
typedef void* FPDF_RECORDER; // Passed into skia.