Make CPDF_CMap initialization slightly more efficient.

CPDF_CMapParser is a short lived class that initializes a CPDF_CMap. For
a CPDF_CMap's |m_MixedFourByteLeadingRanges| vector, the parser
initializes it by reading out of it and then appending to it. This
requires CPDF_CMap to have 2 public methods, with the append method
appending one element at a time.

Improve upon this by removing those two methods and instead first let
CPDF_CMapParser hold on to the vector as |m_Ranges|. Since the parser
has direct access to both |m_Ranges| and |m_PendingRanges|, it can move
elements into |m_Ranges| in bulk. When the parser is done, it can use
the newly added CPDF_CMap::SetMixedFourByteLeadingRanges() to move
|m_Ranges| to CPDF_CMap.

Change-Id: I6e6e339296a08a210b925efc278b490a457f8026
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59513
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cmap.cpp b/core/fpdfapi/font/cpdf_cmap.cpp
index 3fb122f..81ee02d 100644
--- a/core/fpdfapi/font/cpdf_cmap.cpp
+++ b/core/fpdfapi/font/cpdf_cmap.cpp
@@ -475,3 +475,7 @@
   }
   return 0;
 }
+
+void CPDF_CMap::SetMixedFourByteLeadingRanges(std::vector<CodeRange> ranges) {
+  m_MixedFourByteLeadingRanges = std::move(ranges);
+}
diff --git a/core/fpdfapi/font/cpdf_cmap.h b/core/fpdfapi/font/cpdf_cmap.h
index f0f3a94..c9dc61f 100644
--- a/core/fpdfapi/font/cpdf_cmap.h
+++ b/core/fpdfapi/font/cpdf_cmap.h
@@ -62,12 +62,7 @@
 
   void SetVertical(bool vert) { m_bVertical = vert; }
   void SetCodingScheme(CodingScheme scheme) { m_CodingScheme = scheme; }
-  const std::vector<CodeRange>& GetMixedFourByteLeadingRanges() const {
-    return m_MixedFourByteLeadingRanges;
-  }
-  void AppendMixedFourByteLeadingRanges(const CodeRange& range) {
-    m_MixedFourByteLeadingRanges.push_back(range);
-  }
+  void SetMixedFourByteLeadingRanges(std::vector<CodeRange> ranges);
 
   int GetCoding() const { return m_Coding; }
   const FXCMAP_CMap* GetEmbedMap() const { return m_pEmbedMap.Get(); }
diff --git a/core/fpdfapi/font/cpdf_cmapparser.cpp b/core/fpdfapi/font/cpdf_cmapparser.cpp
index 1936ee6..1ef8a7c 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.cpp
+++ b/core/fpdfapi/font/cpdf_cmapparser.cpp
@@ -28,7 +28,9 @@
 
 CPDF_CMapParser::CPDF_CMapParser(CPDF_CMap* pCMap) : m_pCMap(pCMap) {}
 
-CPDF_CMapParser::~CPDF_CMapParser() = default;
+CPDF_CMapParser::~CPDF_CMapParser() {
+  m_pCMap->SetMixedFourByteLeadingRanges(std::move(m_Ranges));
+}
 
 void CPDF_CMapParser::ParseWord(ByteStringView word) {
   ASSERT(!word.IsEmpty());
@@ -119,17 +121,17 @@
     return;
   }
 
-  const auto& code_ranges = m_pCMap->GetMixedFourByteLeadingRanges();
-  size_t nSegs = code_ranges.size() + m_PendingRanges.size();
+  size_t nSegs = m_Ranges.size() + m_PendingRanges.size();
   if (nSegs == 1) {
     const auto& first_range =
-        !code_ranges.empty() ? code_ranges[0] : m_PendingRanges[0];
+        !m_Ranges.empty() ? m_Ranges[0] : m_PendingRanges[0];
     m_pCMap->SetCodingScheme(first_range.m_CharSize == 2 ? CPDF_CMap::TwoBytes
                                                          : CPDF_CMap::OneByte);
   } else if (nSegs > 1) {
     m_pCMap->SetCodingScheme(CPDF_CMap::MixedFourBytes);
-    for (const auto& range : m_PendingRanges)
-      m_pCMap->AppendMixedFourByteLeadingRanges(range);
+    m_Ranges.reserve(nSegs);
+    std::move(m_PendingRanges.begin(), m_PendingRanges.end(),
+              std::back_inserter(m_Ranges));
     m_PendingRanges.clear();
   }
   m_Status = kStart;
diff --git a/core/fpdfapi/font/cpdf_cmapparser.h b/core/fpdfapi/font/cpdf_cmapparser.h
index 2fe37a4..f24a93b 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.h
+++ b/core/fpdfapi/font/cpdf_cmapparser.h
@@ -55,6 +55,7 @@
   Status m_Status = kStart;
   int m_CodeSeq = 0;
   UnownedPtr<CPDF_CMap> const m_pCMap;
+  std::vector<CPDF_CMap::CodeRange> m_Ranges;
   std::vector<CPDF_CMap::CodeRange> m_PendingRanges;
   std::vector<CPDF_CMap::CIDRange> m_AdditionalCharcodeToCIDMappings;
   ByteString m_LastWord;