Make MarkData::mMarks a vector of RetainPtr<CPDF_ContentMarkItem>

It is currently a vector of CPDF_ContentMarkItem.

Copying MarkData whenever a content mark is opened or closed is
inefficient since each MarkData will have copies of the same
CPDF_ContentMarkItems.

This CL changes the vector inside MarkData to contains only pointers
to the CPDF_ContentMarkItems rather than copies of those items. More
importantly, this unifies the dictionaries of each content mark.
Previously, there were as many copies of those dictionaries as content
marks scope changes inside the mark with parameters.

Bug: pdfium:1037
Change-Id: Ia6f79b401d4e14ac07dbba81bbd97df965b77c94
Reviewed-on: https://pdfium-review.googlesource.com/37135
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_contentmark.cpp b/core/fpdfapi/page/cpdf_contentmark.cpp
index 0b17c2b..6021dc8 100644
--- a/core/fpdfapi/page/cpdf_contentmark.cpp
+++ b/core/fpdfapi/page/cpdf_contentmark.cpp
@@ -72,12 +72,12 @@
 
 const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(
     size_t index) const {
-  return m_Marks[index];
+  return *m_Marks[index];
 }
 
 int CPDF_ContentMark::MarkData::GetMarkedContentID() const {
-  for (const auto& mark : m_Marks) {
-    const CPDF_Dictionary* pDict = mark.GetParam();
+  for (const auto pMark : m_Marks) {
+    const CPDF_Dictionary* pDict = pMark->GetParam();
     if (pDict && pDict->KeyExist("MCID"))
       return pDict->GetIntegerFor("MCID");
   }
@@ -87,15 +87,15 @@
 void CPDF_ContentMark::MarkData::AddMark(ByteString name,
                                          const CPDF_Dictionary* pDict,
                                          bool bDirect) {
-  CPDF_ContentMarkItem item;
-  item.SetName(std::move(name));
+  auto pItem = pdfium::MakeRetain<CPDF_ContentMarkItem>();
+  pItem->SetName(std::move(name));
   if (pDict) {
     if (bDirect)
-      item.SetDirectDict(ToDictionary(pDict->Clone()));
+      pItem->SetDirectDict(ToDictionary(pDict->Clone()));
     else
-      item.SetPropertiesDict(pDict);
+      pItem->SetPropertiesDict(pDict);
   }
-  m_Marks.push_back(std::move(item));
+  m_Marks.push_back(pItem);
 }
 
 void CPDF_ContentMark::MarkData::DeleteLastMark() {
diff --git a/core/fpdfapi/page/cpdf_contentmark.h b/core/fpdfapi/page/cpdf_contentmark.h
index 27116af..ac21151 100644
--- a/core/fpdfapi/page/cpdf_contentmark.h
+++ b/core/fpdfapi/page/cpdf_contentmark.h
@@ -46,7 +46,7 @@
     void DeleteLastMark();
 
    private:
-    std::vector<CPDF_ContentMarkItem> m_Marks;
+    std::vector<RetainPtr<CPDF_ContentMarkItem>> m_Marks;
   };
 
   RetainPtr<MarkData> m_pMarkData;
diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.cpp b/core/fpdfapi/page/cpdf_contentmarkitem.cpp
index 205f14d..4f56eea 100644
--- a/core/fpdfapi/page/cpdf_contentmarkitem.cpp
+++ b/core/fpdfapi/page/cpdf_contentmarkitem.cpp
@@ -12,14 +12,6 @@
 
 CPDF_ContentMarkItem::CPDF_ContentMarkItem() {}
 
-CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that)
-    : m_MarkName(that.m_MarkName),
-      m_ParamType(that.m_ParamType),
-      m_pPropertiesDict(that.m_pPropertiesDict) {
-  if (that.m_pDirectDict)
-    m_pDirectDict = ToDictionary(that.m_pDirectDict->Clone());
-}
-
 CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {}
 
 const CPDF_Dictionary* CPDF_ContentMarkItem::GetParam() const {
diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.h b/core/fpdfapi/page/cpdf_contentmarkitem.h
index 5dcc7d4..72548ce 100644
--- a/core/fpdfapi/page/cpdf_contentmarkitem.h
+++ b/core/fpdfapi/page/cpdf_contentmarkitem.h
@@ -12,19 +12,17 @@
 #include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 
 class CPDF_Dictionary;
 
-class CPDF_ContentMarkItem {
+class CPDF_ContentMarkItem : public Retainable {
  public:
   enum ParamType { None, PropertiesDict, DirectDict };
 
   CPDF_ContentMarkItem();
-  CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that);
-  ~CPDF_ContentMarkItem();
-
-  CPDF_ContentMarkItem& operator=(CPDF_ContentMarkItem&& other) = default;
+  ~CPDF_ContentMarkItem() override;
 
   ByteString GetName() const { return m_MarkName; }
   ParamType GetParamType() const { return m_ParamType; }