From 5b9a0a9c12960e303d312656da4d49c8997b617d Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Wed, 12 Sep 2018 19:09:06 +0000 Subject: Optimize CPDF_CMapParser In this parser, a vector of CodeRange values are built up during operations that need to be sync'd with the CPDF_CMap that is being initialized. In the existing implementation, the vector being built as a member var for the parser, and copying the values over to the cmap whenever there is a change. When profiling, this copy is where the code spends most of its time. The code has been rewritten to have the parser reference/modify the instance of the vector in the cmap instead of having its own copy. This removes all of the copies and significantly speeds things up. BUG=chromium:881678 Change-Id: Ib8e75962507ca3d3b1ed066fd1faa4fbb7141122 Reviewed-on: https://pdfium-review.googlesource.com/42350 Commit-Queue: Ryan Harrison Reviewed-by: Henrique Nakashima --- core/fpdfapi/font/cpdf_cmap.h | 7 +++++-- core/fpdfapi/font/cpdf_cmapparser.cpp | 11 +++++++---- core/fpdfapi/font/cpdf_cmapparser.h | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/fpdfapi/font/cpdf_cmap.h b/core/fpdfapi/font/cpdf_cmap.h index 228c207876..68ad26cfa3 100644 --- a/core/fpdfapi/font/cpdf_cmap.h +++ b/core/fpdfapi/font/cpdf_cmap.h @@ -66,8 +66,11 @@ class CPDF_CMap final : public Retainable { void SetVertical(bool vert) { m_bVertical = vert; } void SetCodingScheme(CodingScheme scheme) { m_CodingScheme = scheme; } - void SetMixedFourByteLeadingRanges(std::vector range) { - m_MixedFourByteLeadingRanges = range; + const std::vector& GetMixedFourByteLeadingRanges() { + return m_MixedFourByteLeadingRanges; + } + void AppendMixedFourByteLeadingRanges(const CodeRange& range) { + m_MixedFourByteLeadingRanges.push_back(range); } int GetCoding() const { return m_Coding; } diff --git a/core/fpdfapi/font/cpdf_cmapparser.cpp b/core/fpdfapi/font/cpdf_cmapparser.cpp index a88448c5bd..5bfe17b34f 100644 --- a/core/fpdfapi/font/cpdf_cmapparser.cpp +++ b/core/fpdfapi/font/cpdf_cmapparser.cpp @@ -109,14 +109,17 @@ void CPDF_CMapParser::ParseWord(const ByteStringView& word) { m_Status = 0; } else if (m_Status == 7) { if (word == "endcodespacerange") { - size_t nSegs = m_CodeRanges.size(); + auto code_ranges = m_pCMap->GetMixedFourByteLeadingRanges(); + size_t nSegs = code_ranges.size(); if (nSegs == 1) { - m_pCMap->SetCodingScheme((m_CodeRanges[0].m_CharSize == 2) + m_pCMap->SetCodingScheme((code_ranges[0].m_CharSize == 2) ? CPDF_CMap::TwoBytes : CPDF_CMap::OneByte); } else if (nSegs > 1) { m_pCMap->SetCodingScheme(CPDF_CMap::MixedFourBytes); - m_pCMap->SetMixedFourByteLeadingRanges(m_CodeRanges); + for (auto range : m_PendingRanges) + m_pCMap->AppendMixedFourByteLeadingRanges(range); + m_PendingRanges.clear(); } m_Status = 0; } else { @@ -126,7 +129,7 @@ void CPDF_CMapParser::ParseWord(const ByteStringView& word) { if (m_CodeSeq % 2) { CPDF_CMap::CodeRange range; if (GetCodeRange(range, m_LastWord.AsStringView(), word)) - m_CodeRanges.push_back(range); + m_PendingRanges.push_back(range); } m_CodeSeq++; } diff --git a/core/fpdfapi/font/cpdf_cmapparser.h b/core/fpdfapi/font/cpdf_cmapparser.h index c70d408f90..fae65cfe00 100644 --- a/core/fpdfapi/font/cpdf_cmapparser.h +++ b/core/fpdfapi/font/cpdf_cmapparser.h @@ -40,7 +40,7 @@ class CPDF_CMapParser { UnownedPtr const m_pCMap; int m_Status; int m_CodeSeq; - std::vector m_CodeRanges; + std::vector m_PendingRanges; std::vector m_AdditionalCharcodeToCIDMappings; ByteString m_LastWord; uint32_t m_CodePoints[4]; -- cgit v1.2.3