diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-07-06 20:32:29 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-07-06 20:32:29 +0000 |
commit | 4caa1200938a397d7f2f193872355129adb768ed (patch) | |
tree | 4f3a3d3e3d8d0a6eb3ef3e30a114562cd69ca38e /core/fpdfapi | |
parent | 05aa09d3ebfd587dd8e1116b6cac8053a2944a1a (diff) | |
download | pdfium-4caa1200938a397d7f2f193872355129adb768ed.tar.xz |
Maintain a stack of CPDF_ContentMark while parsing a stream.
This avoids copying the CPDF_ContentMark every time a mark is closed.
Another benefit is that the same CPDF_ContentMarkItem vector will be
shared by page objects before and after a nested mark.
Bug: pdfium:1037
Change-Id: I6197f0b9a4693ef84da9269f86a2629aa50d8685
Reviewed-on: https://pdfium-review.googlesource.com/37190
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'core/fpdfapi')
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.cpp | 24 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.h | 3 |
2 files changed, 18 insertions, 9 deletions
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index c698c52370..640b7f7109 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -258,7 +258,6 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( m_ParamStartPos(0), m_ParamCount(0), m_pCurStates(pdfium::MakeUnique<CPDF_AllStates>()), - m_pCurContentMark(pdfium::MakeUnique<CPDF_ContentMark>()), m_DefFontSize(0), m_PathStartX(0.0f), m_PathStartY(0.0f), @@ -284,6 +283,9 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { m_Type3Data[i] = 0.0; } + + // Add the sentinel. + m_ContentMarksStack.push(pdfium::MakeUnique<CPDF_ContentMark>()); } CPDF_StreamContentParser::~CPDF_StreamContentParser() { @@ -435,7 +437,7 @@ void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, bool bGraph) { pObj->m_GeneralState = m_pCurStates->m_GeneralState; pObj->m_ClipPath = m_pCurStates->m_ClipPath; - pObj->m_ContentMark = *m_pCurContentMark; + pObj->m_ContentMark = *m_ContentMarksStack.top(); if (bColor) { pObj->m_ColorState = m_pCurStates->m_ColorState; } @@ -608,8 +610,10 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { bDirect = false; } if (const CPDF_Dictionary* pDict = pProperty->AsDictionary()) { - m_pCurContentMark = m_pCurContentMark->Clone(); - m_pCurContentMark->AddMark(std::move(tag), pDict, bDirect); + std::unique_ptr<CPDF_ContentMark> new_marks = + m_ContentMarksStack.top()->Clone(); + new_marks->AddMark(std::move(tag), pDict, bDirect); + m_ContentMarksStack.push(std::move(new_marks)); } } @@ -674,8 +678,10 @@ void CPDF_StreamContentParser::Handle_BeginImage() { } void CPDF_StreamContentParser::Handle_BeginMarkedContent() { - m_pCurContentMark = m_pCurContentMark->Clone(); - m_pCurContentMark->AddMark(GetString(0), nullptr, false); + std::unique_ptr<CPDF_ContentMark> new_marks = + m_ContentMarksStack.top()->Clone(); + new_marks->AddMark(GetString(0), nullptr, false); + m_ContentMarksStack.push(std::move(new_marks)); } void CPDF_StreamContentParser::Handle_BeginText() { @@ -868,8 +874,10 @@ void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {} void CPDF_StreamContentParser::Handle_EndImage() {} void CPDF_StreamContentParser::Handle_EndMarkedContent() { - m_pCurContentMark = m_pCurContentMark->Clone(); - m_pCurContentMark->DeleteLastMark(); + // First element is a sentinel, so do not pop it, ever. This may come up if + // the EMCs are mismatched with the BMC/BDCs. + if (m_ContentMarksStack.size() > 1) + m_ContentMarksStack.pop(); } void CPDF_StreamContentParser::Handle_EndText() { diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h index ae0a7f39af..238999b846 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.h +++ b/core/fpdfapi/page/cpdf_streamcontentparser.h @@ -10,6 +10,7 @@ #include <map> #include <memory> #include <set> +#include <stack> #include <vector> #include "core/fpdfapi/page/cpdf_contentmark.h" @@ -219,7 +220,7 @@ class CPDF_StreamContentParser { uint32_t m_ParamCount; UnownedPtr<CPDF_StreamParser> m_pSyntax; std::unique_ptr<CPDF_AllStates> m_pCurStates; - std::unique_ptr<CPDF_ContentMark> m_pCurContentMark; + std::stack<std::unique_ptr<CPDF_ContentMark>> m_ContentMarksStack; std::vector<std::unique_ptr<CPDF_TextObject>> m_ClipTextList; UnownedPtr<CPDF_TextObject> m_pLastTextObject; float m_DefFontSize; |