summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-07-06 20:32:29 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-07-06 20:32:29 +0000
commit4caa1200938a397d7f2f193872355129adb768ed (patch)
tree4f3a3d3e3d8d0a6eb3ef3e30a114562cd69ca38e
parent05aa09d3ebfd587dd8e1116b6cac8053a2944a1a (diff)
downloadpdfium-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>
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp24
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.h3
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;