summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp450
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp251
-rw-r--r--core/src/fpdfapi/fpdf_page/pageint.h1
3 files changed, 406 insertions, 296 deletions
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
index 4ac9de9e95..6ed3d3fc0e 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
@@ -12,6 +12,14 @@
namespace {
+const char kPathOperatorSubpath = 'm';
+const char kPathOperatorLine = 'l';
+const char kPathOperatorCubicBezier1 = 'c';
+const char kPathOperatorCubicBezier2 = 'v';
+const char kPathOperatorCubicBezier3 = 'y';
+const char kPathOperatorClosePath = 'h';
+const char kPathOperatorRectangle[] = "re";
+
struct _FX_BSTR {
const FX_CHAR* m_Ptr;
int m_Size;
@@ -56,6 +64,19 @@ struct AbbrReplacementOp {
CFX_ByteStringC replacement;
};
+class CPDF_StreamParserAutoClearer {
+ public:
+ CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable,
+ CPDF_StreamParser* new_parser)
+ : scoped_variable_(scoped_variable) {
+ *scoped_variable_ = new_parser;
+ }
+ ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; }
+
+ private:
+ CPDF_StreamParser** scoped_variable_;
+};
+
CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPairs* table,
size_t count,
const CFX_ByteStringC& abbr) {
@@ -71,6 +92,23 @@ CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPairs* table,
} // namespace
+bool IsPathOperator(const uint8_t* buf, size_t len) {
+ if (len == 1) {
+ uint8_t op = buf[0];
+ if (op == kPathOperatorSubpath || op == kPathOperatorLine ||
+ op == kPathOperatorCubicBezier1 || op == kPathOperatorCubicBezier2 ||
+ op == kPathOperatorCubicBezier3) {
+ return true;
+ }
+ } else if (len == 2) {
+ if (buf[0] == kPathOperatorRectangle[0] &&
+ buf[1] == kPathOperatorRectangle[1]) {
+ return true;
+ }
+ }
+ return false;
+}
+
CPDF_StreamContentParser::CPDF_StreamContentParser(
CPDF_Document* pDocument,
CPDF_Dictionary* pPageResources,
@@ -143,6 +181,7 @@ CPDF_StreamContentParser::~CPDF_StreamContentParser() {
m_pLastCloneImageDict->Release();
}
}
+
int CPDF_StreamContentParser::GetNextParamPos() {
if (m_ParamCount == PARAM_BUF_SIZE) {
m_ParamStartPos++;
@@ -162,6 +201,7 @@ int CPDF_StreamContentParser::GetNextParamPos() {
m_ParamCount++;
return index;
}
+
void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) {
int index = GetNextParamPos();
if (len > 32) {
@@ -181,6 +221,7 @@ void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) {
}
}
}
+
void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) {
int index = GetNextParamPos();
m_ParamBuf1[index].m_Type = PDFOBJ_NUMBER;
@@ -207,6 +248,7 @@ void CPDF_StreamContentParser::ClearAllParams() {
m_ParamStartPos = 0;
m_ParamCount = 0;
}
+
CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index) {
if (index >= m_ParamCount) {
return NULL;
@@ -238,6 +280,7 @@ CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index) {
ASSERT(FALSE);
return NULL;
}
+
CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index) {
if (index >= m_ParamCount) {
return CFX_ByteString();
@@ -255,6 +298,7 @@ CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index) {
}
return CFX_ByteString();
}
+
FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index) {
if (index >= m_ParamCount) {
return 0;
@@ -273,9 +317,11 @@ FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index) {
}
return 0;
}
+
FX_FLOAT CPDF_StreamContentParser::GetNumber16(FX_DWORD index) {
return GetNumber(index);
}
+
void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj,
FX_BOOL bColor,
FX_BOOL bText,
@@ -404,6 +450,7 @@ const CPDF_StreamContentParser::OpCode CPDF_StreamContentParser::g_OpCodes[] = {
{FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth},
{FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13},
};
+
FX_BOOL CPDF_StreamContentParser::OnOperator(const FX_CHAR* op) {
int i = 0;
FX_DWORD opid = 0;
@@ -431,6 +478,7 @@ FX_BOOL CPDF_StreamContentParser::OnOperator(const FX_CHAR* op) {
}
return m_CompatCount != 0;
}
+
void CPDF_StreamContentParser::Handle_CloseFillStrokePath() {
if (m_Options.m_bTextOnly) {
return;
@@ -438,12 +486,14 @@ void CPDF_StreamContentParser::Handle_CloseFillStrokePath() {
Handle_ClosePath();
AddPathObject(FXFILL_WINDING, TRUE);
}
+
void CPDF_StreamContentParser::Handle_FillStrokePath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(FXFILL_WINDING, TRUE);
}
+
void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() {
if (m_Options.m_bTextOnly) {
return;
@@ -451,12 +501,14 @@ void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() {
AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE);
AddPathObject(FXFILL_ALTERNATE, TRUE);
}
+
void CPDF_StreamContentParser::Handle_EOFillStrokePath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(FXFILL_ALTERNATE, TRUE);
}
+
void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() {
if (!m_Options.m_bMarkedContent) {
return;
@@ -477,74 +529,91 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() {
m_CurContentMark.GetModify()->AddMark(tag, pDict, bDirect);
}
}
-void CPDF_StreamContentParser::Handle_BeginMarkedContent() {
- if (!m_Options.m_bMarkedContent) {
- return;
- }
- CFX_ByteString tag = GetString(0);
- m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE);
-}
-void PDF_ReplaceAbbr(CPDF_Object* pObj) {
- switch (pObj->GetType()) {
- case PDFOBJ_DICTIONARY: {
- CPDF_Dictionary* pDict = pObj->AsDictionary();
- std::vector<AbbrReplacementOp> replacements;
- for (const auto& it : *pDict) {
- CFX_ByteString key = it.first;
- CPDF_Object* value = it.second;
- CFX_ByteStringC fullname = PDF_FindFullName(
- PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key);
- if (!fullname.IsEmpty()) {
- AbbrReplacementOp op;
- op.is_replace_key = true;
- op.key = key;
- op.replacement = fullname;
- replacements.push_back(op);
- key = fullname;
- }
-
- if (value->IsName()) {
- CFX_ByteString name = value->GetString();
- fullname = PDF_FindFullName(PDF_InlineValueAbbr,
- FX_ArraySize(PDF_InlineValueAbbr), name);
- if (!fullname.IsEmpty()) {
- AbbrReplacementOp op;
- op.is_replace_key = false;
- op.key = key;
- op.replacement = fullname;
- replacements.push_back(op);
- }
- } else {
- PDF_ReplaceAbbr(value);
- }
- }
- for (const auto& op : replacements) {
- if (op.is_replace_key)
- pDict->ReplaceKey(op.key, op.replacement);
- else
- pDict->SetAtName(op.key, op.replacement);
+void CPDF_StreamContentParser::Handle_BeginImage() {
+ FX_FILESIZE savePos = m_pSyntax->GetPos();
+ CPDF_Dictionary* pDict = new CPDF_Dictionary;
+ while (1) {
+ CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
+ if (type == CPDF_StreamParser::Keyword) {
+ CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(),
+ m_pSyntax->GetWordSize());
+ if (bsKeyword != "ID") {
+ m_pSyntax->SetPos(savePos);
+ pDict->Release();
+ return;
}
+ }
+ if (type != CPDF_StreamParser::Name) {
break;
}
- case PDFOBJ_ARRAY: {
- CPDF_Array* pArray = pObj->AsArray();
- for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
- CPDF_Object* pElement = pArray->GetElement(i);
- if (pElement->IsName()) {
- CFX_ByteString name = pElement->GetString();
- CFX_ByteStringC fullname = PDF_FindFullName(
- PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name);
- if (!fullname.IsEmpty()) {
- pArray->SetAt(i, new CPDF_Name(fullname));
- }
- } else {
- PDF_ReplaceAbbr(pElement);
+ CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1,
+ m_pSyntax->GetWordSize() - 1);
+ std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj(
+ m_pSyntax->ReadNextObject());
+ if (!key.IsEmpty()) {
+ FX_DWORD dwObjNum = pObj ? pObj->GetObjNum() : 0;
+ if (dwObjNum)
+ pDict->SetAtReference(key, m_pDocument, dwObjNum);
+ else
+ pDict->SetAt(key, pObj.release());
+ }
+ }
+ PDF_ReplaceAbbr(pDict);
+ CPDF_Object* pCSObj = NULL;
+ if (pDict->KeyExist("ColorSpace")) {
+ pCSObj = pDict->GetElementValue("ColorSpace");
+ if (pCSObj->IsName()) {
+ CFX_ByteString name = pCSObj->GetString();
+ if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") {
+ pCSObj = FindResourceObj("ColorSpace", name);
+ if (pCSObj && !pCSObj->GetObjNum()) {
+ pCSObj = pCSObj->Clone();
+ pDict->SetAt("ColorSpace", pCSObj);
}
}
+ }
+ }
+ CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(
+ m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage);
+ while (1) {
+ CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
+ if (type == CPDF_StreamParser::EndOfData) {
+ break;
+ }
+ if (type != CPDF_StreamParser::Keyword) {
+ continue;
+ }
+ if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &&
+ m_pSyntax->GetWordBuf()[1] == 'I') {
break;
}
}
+ if (m_Options.m_bTextOnly) {
+ if (pStream) {
+ pStream->Release();
+ } else {
+ pDict->Release();
+ }
+ return;
+ }
+ pDict->SetAtName("Subtype", "Image");
+ CPDF_ImageObject* pImgObj = AddImage(pStream, NULL, TRUE);
+ if (!pImgObj) {
+ if (pStream) {
+ pStream->Release();
+ } else {
+ pDict->Release();
+ }
+ }
+}
+
+void CPDF_StreamContentParser::Handle_BeginMarkedContent() {
+ if (!m_Options.m_bMarkedContent) {
+ return;
+ }
+ CFX_ByteString tag = GetString(0);
+ m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE);
}
void CPDF_StreamContentParser::Handle_BeginText() {
@@ -555,9 +624,11 @@ void CPDF_StreamContentParser::Handle_BeginText() {
m_pCurStates->m_TextLineX = 0;
m_pCurStates->m_TextLineY = 0;
}
+
void CPDF_StreamContentParser::Handle_BeginSectionUndefined() {
m_CompatCount++;
}
+
void CPDF_StreamContentParser::Handle_CurveTo_123() {
if (m_Options.m_bTextOnly) {
return;
@@ -566,6 +637,7 @@ void CPDF_StreamContentParser::Handle_CurveTo_123() {
AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
+
void CPDF_StreamContentParser::Handle_ConcatMatrix() {
FX_FLOAT a2 = GetNumber16(5), b2 = GetNumber16(4), c2 = GetNumber16(3),
d2 = GetNumber16(2);
@@ -575,6 +647,7 @@ void CPDF_StreamContentParser::Handle_ConcatMatrix() {
m_pCurStates->m_CTM = new_matrix;
OnChangeTextMatrix();
}
+
void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() {
if (m_Options.m_bTextOnly) {
return;
@@ -586,6 +659,7 @@ void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() {
}
m_pCurStates->m_ColorState.GetModify()->m_FillColor.SetColorSpace(pCS);
}
+
void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() {
if (m_Options.m_bTextOnly) {
return;
@@ -597,6 +671,7 @@ void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() {
}
m_pCurStates->m_ColorState.GetModify()->m_StrokeColor.SetColorSpace(pCS);
}
+
void CPDF_StreamContentParser::Handle_SetDash() {
if (m_Options.m_bTextOnly) {
return;
@@ -607,17 +682,20 @@ void CPDF_StreamContentParser::Handle_SetDash() {
}
m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f);
}
+
void CPDF_StreamContentParser::Handle_SetCharWidth() {
m_Type3Data[0] = GetNumber(1);
m_Type3Data[1] = GetNumber(0);
m_bColored = TRUE;
}
+
void CPDF_StreamContentParser::Handle_SetCachedDevice() {
for (int i = 0; i < 6; i++) {
m_Type3Data[i] = GetNumber(5 - i);
}
m_bColored = FALSE;
}
+
void CPDF_StreamContentParser::Handle_ExecuteXObject() {
CFX_ByteString name = GetString(0);
if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() &&
@@ -668,6 +746,7 @@ void CPDF_StreamContentParser::Handle_ExecuteXObject() {
return;
}
}
+
void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) {
if (!m_Options.m_bSeparateForm) {
CPDF_Dictionary* pResources = pStream->GetDict()->GetDict("Resources");
@@ -720,6 +799,7 @@ void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) {
SetGraphicStates(pFormObj, TRUE, TRUE, TRUE);
m_pObjectList->m_ObjectList.AddTail(pFormObj);
}
+
CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream,
CPDF_Image* pImage,
FX_BOOL bInline) {
@@ -745,8 +825,11 @@ CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream,
m_pObjectList->m_ObjectList.AddTail(pImageObj);
return pImageObj;
}
+
void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {}
+
void CPDF_StreamContentParser::Handle_EndImage() {}
+
void CPDF_StreamContentParser::Handle_EndMarkedContent() {
if (!m_Options.m_bMarkedContent) {
return;
@@ -761,6 +844,7 @@ void CPDF_StreamContentParser::Handle_EndMarkedContent() {
}
m_CurContentMark.GetModify()->DeleteLastMark();
}
+
void CPDF_StreamContentParser::Handle_EndText() {
int count = m_ClipTextList.GetSize();
if (count == 0) {
@@ -775,39 +859,46 @@ void CPDF_StreamContentParser::Handle_EndText() {
}
m_ClipTextList.RemoveAll();
}
+
void CPDF_StreamContentParser::Handle_EndSectionUndefined() {
if (m_CompatCount) {
m_CompatCount--;
}
}
+
void CPDF_StreamContentParser::Handle_FillPath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(FXFILL_WINDING, FALSE);
}
+
void CPDF_StreamContentParser::Handle_FillPathOld() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(FXFILL_WINDING, FALSE);
}
+
void CPDF_StreamContentParser::Handle_EOFillPath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(FXFILL_ALTERNATE, FALSE);
}
+
void CPDF_StreamContentParser::Handle_SetGray_Fill() {
FX_FLOAT value = GetNumber(0);
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1);
}
+
void CPDF_StreamContentParser::Handle_SetGray_Stroke() {
FX_FLOAT value = GetNumber(0);
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1);
}
+
void CPDF_StreamContentParser::Handle_SetExtendGraphState() {
CFX_ByteString name = GetString(0);
CPDF_Dictionary* pGS = ToDictionary(FindResourceObj("ExtGState", name));
@@ -817,6 +908,7 @@ void CPDF_StreamContentParser::Handle_SetExtendGraphState() {
}
m_pCurStates->ProcessExtGS(pGS, this);
}
+
void CPDF_StreamContentParser::Handle_ClosePath() {
if (m_Options.m_bTextOnly) {
return;
@@ -830,18 +922,23 @@ void CPDF_StreamContentParser::Handle_ClosePath() {
m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
}
}
+
void CPDF_StreamContentParser::Handle_SetFlat() {
m_pCurStates->m_GeneralState.GetModify()->m_Flatness = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_BeginImageData() {}
+
void CPDF_StreamContentParser::Handle_SetLineJoin() {
m_pCurStates->m_GraphState.GetModify()->m_LineJoin =
(CFX_GraphStateData::LineJoin)GetInteger(0);
}
+
void CPDF_StreamContentParser::Handle_SetLineCap() {
m_pCurStates->m_GraphState.GetModify()->m_LineCap =
(CFX_GraphStateData::LineCap)GetInteger(0);
}
+
void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() {
if (m_ParamCount != 4)
return;
@@ -853,6 +950,7 @@ void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() {
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4);
}
+
void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() {
if (m_ParamCount != 4)
return;
@@ -864,6 +962,7 @@ void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() {
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4);
}
+
void CPDF_StreamContentParser::Handle_LineTo() {
if (m_ParamCount != 2)
return;
@@ -873,6 +972,7 @@ void CPDF_StreamContentParser::Handle_LineTo() {
}
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO);
}
+
void CPDF_StreamContentParser::Handle_MoveTo() {
if (m_ParamCount != 2)
return;
@@ -884,21 +984,26 @@ void CPDF_StreamContentParser::Handle_MoveTo() {
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO);
ParsePathObject();
}
+
void CPDF_StreamContentParser::Handle_SetMiterLimit() {
m_pCurStates->m_GraphState.GetModify()->m_MiterLimit = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_MarkPlace() {}
+
void CPDF_StreamContentParser::Handle_EndPath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(0, FALSE);
}
+
void CPDF_StreamContentParser::Handle_SaveGraphState() {
std::unique_ptr<CPDF_AllStates> pStates(new CPDF_AllStates);
pStates->Copy(*m_pCurStates);
m_StateStack.push_back(std::move(pStates));
}
+
void CPDF_StreamContentParser::Handle_RestoreGraphState() {
if (m_StateStack.empty())
return;
@@ -906,6 +1011,7 @@ void CPDF_StreamContentParser::Handle_RestoreGraphState() {
m_StateStack.pop_back();
m_pCurStates->Copy(*pStates);
}
+
void CPDF_StreamContentParser::Handle_Rectangle() {
if (m_Options.m_bTextOnly) {
return;
@@ -914,6 +1020,7 @@ void CPDF_StreamContentParser::Handle_Rectangle() {
FX_FLOAT w = GetNumber(1), h = GetNumber(0);
AddPathRect(x, y, w, h);
}
+
void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x,
FX_FLOAT y,
FX_FLOAT w,
@@ -924,6 +1031,7 @@ void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x,
AddPathPoint(x, y + h, FXPT_LINETO);
AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE);
}
+
void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() {
if (m_ParamCount != 3)
return;
@@ -935,6 +1043,7 @@ void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() {
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3);
}
+
void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() {
if (m_ParamCount != 3)
return;
@@ -946,7 +1055,9 @@ void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() {
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3);
}
+
void CPDF_StreamContentParser::Handle_SetRenderIntent() {}
+
void CPDF_StreamContentParser::Handle_CloseStrokePath() {
if (m_Options.m_bTextOnly) {
return;
@@ -954,12 +1065,14 @@ void CPDF_StreamContentParser::Handle_CloseStrokePath() {
Handle_ClosePath();
AddPathObject(0, TRUE);
}
+
void CPDF_StreamContentParser::Handle_StrokePath() {
if (m_Options.m_bTextOnly) {
return;
}
AddPathObject(0, TRUE);
}
+
void CPDF_StreamContentParser::Handle_SetColor_Fill() {
if (m_Options.m_bTextOnly) {
return;
@@ -974,6 +1087,7 @@ void CPDF_StreamContentParser::Handle_SetColor_Fill() {
}
m_pCurStates->m_ColorState.SetFillColor(NULL, values, nargs);
}
+
void CPDF_StreamContentParser::Handle_SetColor_Stroke() {
if (m_Options.m_bTextOnly) {
return;
@@ -988,6 +1102,7 @@ void CPDF_StreamContentParser::Handle_SetColor_Stroke() {
}
m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nargs);
}
+
void CPDF_StreamContentParser::Handle_SetColorPS_Fill() {
if (m_Options.m_bTextOnly) {
return;
@@ -1018,6 +1133,7 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Fill() {
}
FX_Free(values);
}
+
void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() {
if (m_Options.m_bTextOnly) {
return;
@@ -1048,6 +1164,7 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() {
}
FX_Free(values);
}
+
CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream,
ShadingType type,
const CFX_Matrix* pMatrix,
@@ -1096,19 +1213,23 @@ void CPDF_StreamContentParser::Handle_ShadeFill() {
pObj->m_Bottom = bbox.bottom;
m_pObjectList->m_ObjectList.AddTail(pObj);
}
+
void CPDF_StreamContentParser::Handle_SetCharSpace() {
m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_MoveTextPoint() {
m_pCurStates->m_TextLineX += GetNumber(1);
m_pCurStates->m_TextLineY += GetNumber(0);
m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
}
+
void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() {
Handle_MoveTextPoint();
m_pCurStates->m_TextLeading = -GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_SetFont() {
FX_FLOAT fs = GetNumber(0);
if (fs == 0) {
@@ -1120,6 +1241,7 @@ void CPDF_StreamContentParser::Handle_SetFont() {
m_pCurStates->m_TextState.SetFont(pFont);
}
}
+
CPDF_Object* CPDF_StreamContentParser::FindResourceObj(
const CFX_ByteStringC& type,
const CFX_ByteString& name) {
@@ -1149,6 +1271,7 @@ CPDF_Object* CPDF_StreamContentParser::FindResourceObj(
CPDF_Object* pRes = pList->GetElementValue(name);
return pRes;
}
+
CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) {
CPDF_Dictionary* pFontDict = ToDictionary(FindResourceObj("Font", name));
if (!pFontDict) {
@@ -1163,6 +1286,7 @@ CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) {
}
return pFont;
}
+
CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace(
const CFX_ByteString& name) {
if (name == "Pattern") {
@@ -1190,6 +1314,7 @@ CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace(
}
return m_pDocument->LoadColorSpace(pCSObj);
}
+
CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name,
FX_BOOL bShading) {
CPDF_Object* pPattern =
@@ -1201,14 +1326,17 @@ CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name,
return m_pDocument->LoadPattern(pPattern, bShading,
&m_pCurStates->m_ParentMatrix);
}
+
void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) {
m_pCurStates->m_TextMatrix.Transform(x, y, x, y);
ConvertUserSpace(x, y);
}
+
void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) {
m_pCurStates->m_CTM.Transform(x, y, x, y);
m_mtContentToUser.Transform(x, y, x, y);
}
+
void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs,
FX_FLOAT fInitKerning,
FX_FLOAT* pKerning,
@@ -1276,6 +1404,7 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs,
}
}
}
+
void CPDF_StreamContentParser::Handle_ShowText() {
CFX_ByteString str = GetString(0);
if (str.IsEmpty()) {
@@ -1283,6 +1412,7 @@ void CPDF_StreamContentParser::Handle_ShowText() {
}
AddTextObject(&str, 0, NULL, 1);
}
+
void CPDF_StreamContentParser::Handle_ShowText_Positioning() {
CPDF_Array* pArray = GetObject(0) ? GetObject(0)->GetArray() : NULL;
if (!pArray) {
@@ -1329,9 +1459,11 @@ void CPDF_StreamContentParser::Handle_ShowText_Positioning() {
delete[] pStrs;
FX_Free(pKerning);
}
+
void CPDF_StreamContentParser::Handle_SetTextLeading() {
m_pCurStates->m_TextLeading = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_SetTextMatrix() {
m_pCurStates->m_TextMatrix.Set(GetNumber16(5), GetNumber16(4), GetNumber16(3),
GetNumber16(2), GetNumber(1), GetNumber(0));
@@ -1341,6 +1473,7 @@ void CPDF_StreamContentParser::Handle_SetTextMatrix() {
m_pCurStates->m_TextLineX = 0;
m_pCurStates->m_TextLineY = 0;
}
+
void CPDF_StreamContentParser::OnChangeTextMatrix() {
CFX_Matrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f);
@@ -1353,6 +1486,7 @@ void CPDF_StreamContentParser::OnChangeTextMatrix() {
pTextMatrix[2] = text_matrix.b;
pTextMatrix[3] = text_matrix.d;
}
+
void CPDF_StreamContentParser::Handle_SetTextRenderMode() {
int mode = GetInteger(0);
if (mode < 0 || mode > 7) {
@@ -1360,12 +1494,15 @@ void CPDF_StreamContentParser::Handle_SetTextRenderMode() {
}
m_pCurStates->m_TextState.GetModify()->m_TextMode = mode;
}
+
void CPDF_StreamContentParser::Handle_SetTextRise() {
m_pCurStates->m_TextRise = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_SetWordSpace() {
m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(0);
}
+
void CPDF_StreamContentParser::Handle_SetHorzScale() {
if (m_ParamCount != 1) {
return;
@@ -1373,11 +1510,13 @@ void CPDF_StreamContentParser::Handle_SetHorzScale() {
m_pCurStates->m_TextHorzScale = GetNumber(0) / 100;
OnChangeTextMatrix();
}
+
void CPDF_StreamContentParser::Handle_MoveToNextLine() {
m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading;
m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
}
+
void CPDF_StreamContentParser::Handle_CurveTo_23() {
if (m_Options.m_bTextOnly) {
return;
@@ -1386,16 +1525,20 @@ void CPDF_StreamContentParser::Handle_CurveTo_23() {
AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
+
void CPDF_StreamContentParser::Handle_SetLineWidth() {
FX_FLOAT width = GetNumber(0);
m_pCurStates->m_GraphState.GetModify()->m_LineWidth = width;
}
+
void CPDF_StreamContentParser::Handle_Clip() {
m_PathClipType = FXFILL_WINDING;
}
+
void CPDF_StreamContentParser::Handle_EOClip() {
m_PathClipType = FXFILL_ALTERNATE;
}
+
void CPDF_StreamContentParser::Handle_CurveTo_13() {
if (m_Options.m_bTextOnly) {
return;
@@ -1404,16 +1547,20 @@ void CPDF_StreamContentParser::Handle_CurveTo_13() {
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
+
void CPDF_StreamContentParser::Handle_NextLineShowText() {
Handle_MoveToNextLine();
Handle_ShowText();
}
+
void CPDF_StreamContentParser::Handle_NextLineShowText_Space() {
m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(2);
m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(1);
Handle_NextLineShowText();
}
+
void CPDF_StreamContentParser::Handle_Invalid() {}
+
void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) {
m_PathCurrentX = x;
m_PathCurrentY = y;
@@ -1445,6 +1592,7 @@ void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) {
m_pPathPoints[m_PathPointCount - 1].m_PointX = x;
m_pPathPoints[m_PathPointCount - 1].m_PointY = y;
}
+
void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) {
int PathPointCount = m_PathPointCount, PathClipType = m_PathClipType;
m_PathPointCount = 0;
@@ -1486,3 +1634,187 @@ void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) {
m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE);
}
}
+
+FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData,
+ FX_DWORD dwSize,
+ FX_DWORD max_cost) {
+ if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
+ return dwSize;
+ }
+ FX_DWORD InitObjCount = m_pObjectList->CountObjects();
+ CPDF_StreamParser syntax(pData, dwSize);
+ CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax);
+ m_CompatCount = 0;
+ while (1) {
+ FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount;
+ if (max_cost && cost >= max_cost) {
+ break;
+ }
+ switch (syntax.ParseNextElement()) {
+ case CPDF_StreamParser::EndOfData:
+ return m_pSyntax->GetPos();
+ case CPDF_StreamParser::Keyword:
+ OnOperator((char*)syntax.GetWordBuf());
+ ClearAllParams();
+ break;
+ case CPDF_StreamParser::Number:
+ AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize());
+ break;
+ case CPDF_StreamParser::Name:
+ AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1,
+ syntax.GetWordSize() - 1);
+ break;
+ default:
+ AddObjectParam(syntax.GetObject());
+ }
+ }
+ return m_pSyntax->GetPos();
+}
+
+void CPDF_StreamContentParser::ParsePathObject() {
+ FX_FLOAT params[6] = {};
+ int nParams = 0;
+ int last_pos = m_pSyntax->GetPos();
+ while (1) {
+ CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
+ FX_BOOL bProcessed = TRUE;
+ switch (type) {
+ case CPDF_StreamParser::EndOfData:
+ return;
+ case CPDF_StreamParser::Keyword: {
+ int len = m_pSyntax->GetWordSize();
+ if (len == 1) {
+ switch (m_pSyntax->GetWordBuf()[0]) {
+ case kPathOperatorSubpath:
+ AddPathPoint(params[0], params[1], FXPT_MOVETO);
+ nParams = 0;
+ break;
+ case kPathOperatorLine:
+ AddPathPoint(params[0], params[1], FXPT_LINETO);
+ nParams = 0;
+ break;
+ case kPathOperatorCubicBezier1:
+ AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
+ AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
+ AddPathPoint(params[4], params[5], FXPT_BEZIERTO);
+ nParams = 0;
+ break;
+ case kPathOperatorCubicBezier2:
+ AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
+ AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
+ AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
+ nParams = 0;
+ break;
+ case kPathOperatorCubicBezier3:
+ AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
+ AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
+ AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
+ nParams = 0;
+ break;
+ case kPathOperatorClosePath:
+ Handle_ClosePath();
+ nParams = 0;
+ break;
+ default:
+ bProcessed = FALSE;
+ break;
+ }
+ } else if (len == 2) {
+ if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] &&
+ m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) {
+ AddPathRect(params[0], params[1], params[2], params[3]);
+ nParams = 0;
+ } else {
+ bProcessed = FALSE;
+ }
+ } else {
+ bProcessed = FALSE;
+ }
+ if (bProcessed) {
+ last_pos = m_pSyntax->GetPos();
+ }
+ break;
+ }
+ case CPDF_StreamParser::Number: {
+ if (nParams == 6) {
+ break;
+ }
+ FX_BOOL bInteger;
+ int value;
+ FX_atonum(
+ CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()),
+ bInteger, &value);
+ params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value;
+ break;
+ }
+ default:
+ bProcessed = FALSE;
+ }
+ if (!bProcessed) {
+ m_pSyntax->SetPos(last_pos);
+ return;
+ }
+ }
+}
+
+void PDF_ReplaceAbbr(CPDF_Object* pObj) {
+ switch (pObj->GetType()) {
+ case PDFOBJ_DICTIONARY: {
+ CPDF_Dictionary* pDict = pObj->AsDictionary();
+ std::vector<AbbrReplacementOp> replacements;
+ for (const auto& it : *pDict) {
+ CFX_ByteString key = it.first;
+ CPDF_Object* value = it.second;
+ CFX_ByteStringC fullname = PDF_FindFullName(
+ PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key);
+ if (!fullname.IsEmpty()) {
+ AbbrReplacementOp op;
+ op.is_replace_key = true;
+ op.key = key;
+ op.replacement = fullname;
+ replacements.push_back(op);
+ key = fullname;
+ }
+
+ if (value->IsName()) {
+ CFX_ByteString name = value->GetString();
+ fullname = PDF_FindFullName(PDF_InlineValueAbbr,
+ FX_ArraySize(PDF_InlineValueAbbr), name);
+ if (!fullname.IsEmpty()) {
+ AbbrReplacementOp op;
+ op.is_replace_key = false;
+ op.key = key;
+ op.replacement = fullname;
+ replacements.push_back(op);
+ }
+ } else {
+ PDF_ReplaceAbbr(value);
+ }
+ }
+ for (const auto& op : replacements) {
+ if (op.is_replace_key)
+ pDict->ReplaceKey(op.key, op.replacement);
+ else
+ pDict->SetAtName(op.key, op.replacement);
+ }
+ break;
+ }
+ case PDFOBJ_ARRAY: {
+ CPDF_Array* pArray = pObj->AsArray();
+ for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
+ CPDF_Object* pElement = pArray->GetElement(i);
+ if (pElement->IsName()) {
+ CFX_ByteString name = pElement->GetString();
+ CFX_ByteStringC fullname = PDF_FindFullName(
+ PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name);
+ if (!fullname.IsEmpty()) {
+ pArray->SetAt(i, new CPDF_Name(fullname));
+ }
+ } else {
+ PDF_ReplaceAbbr(pElement);
+ }
+ }
+ break;
+ }
+ }
+}
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index 33a566c87b..9e9b55177b 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -14,239 +14,19 @@
#include "core/include/fxcrt/fx_ext.h"
#include "core/include/fxcrt/fx_safe_types.h"
-namespace {
-
-const char kPathOperatorSubpath = 'm';
-const char kPathOperatorLine = 'l';
-const char kPathOperatorCubicBezier1 = 'c';
-const char kPathOperatorCubicBezier2 = 'v';
-const char kPathOperatorCubicBezier3 = 'y';
-const char kPathOperatorClosePath = 'h';
-const char kPathOperatorRectangle[] = "re";
-
-} // namespace
-
-class CPDF_StreamParserAutoClearer {
- public:
- CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable,
- CPDF_StreamParser* new_parser)
- : scoped_variable_(scoped_variable) {
- *scoped_variable_ = new_parser;
- }
- ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; }
-
- private:
- CPDF_StreamParser** scoped_variable_;
-};
-FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData,
- FX_DWORD dwSize,
- FX_DWORD max_cost) {
- if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
- return dwSize;
- }
- FX_DWORD InitObjCount = m_pObjectList->CountObjects();
- CPDF_StreamParser syntax(pData, dwSize);
- CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax);
- m_CompatCount = 0;
- while (1) {
- FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount;
- if (max_cost && cost >= max_cost) {
- break;
- }
- switch (syntax.ParseNextElement()) {
- case CPDF_StreamParser::EndOfData:
- return m_pSyntax->GetPos();
- case CPDF_StreamParser::Keyword:
- OnOperator((char*)syntax.GetWordBuf());
- ClearAllParams();
- break;
- case CPDF_StreamParser::Number:
- AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize());
- break;
- case CPDF_StreamParser::Name:
- AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1,
- syntax.GetWordSize() - 1);
- break;
- default:
- AddObjectParam(syntax.GetObject());
- }
- }
- return m_pSyntax->GetPos();
-}
-
-void CPDF_StreamContentParser::Handle_BeginImage() {
- FX_FILESIZE savePos = m_pSyntax->GetPos();
- CPDF_Dictionary* pDict = new CPDF_Dictionary;
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- if (type == CPDF_StreamParser::Keyword) {
- CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(),
- m_pSyntax->GetWordSize());
- if (bsKeyword != "ID") {
- m_pSyntax->SetPos(savePos);
- pDict->Release();
- return;
- }
- }
- if (type != CPDF_StreamParser::Name) {
- break;
- }
- CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1,
- m_pSyntax->GetWordSize() - 1);
- std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj(
- m_pSyntax->ReadNextObject());
- if (!key.IsEmpty()) {
- FX_DWORD dwObjNum = pObj ? pObj->GetObjNum() : 0;
- if (dwObjNum)
- pDict->SetAtReference(key, m_pDocument, dwObjNum);
- else
- pDict->SetAt(key, pObj.release());
- }
- }
- PDF_ReplaceAbbr(pDict);
- CPDF_Object* pCSObj = NULL;
- if (pDict->KeyExist("ColorSpace")) {
- pCSObj = pDict->GetElementValue("ColorSpace");
- if (pCSObj->IsName()) {
- CFX_ByteString name = pCSObj->GetString();
- if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") {
- pCSObj = FindResourceObj("ColorSpace", name);
- if (pCSObj && !pCSObj->GetObjNum()) {
- pCSObj = pCSObj->Clone();
- pDict->SetAt("ColorSpace", pCSObj);
- }
- }
- }
- }
- CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(
- m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage);
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- if (type == CPDF_StreamParser::EndOfData) {
- break;
- }
- if (type != CPDF_StreamParser::Keyword) {
- continue;
- }
- if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &&
- m_pSyntax->GetWordBuf()[1] == 'I') {
- break;
- }
- }
- if (m_Options.m_bTextOnly) {
- if (pStream) {
- pStream->Release();
- } else {
- pDict->Release();
- }
- return;
- }
- pDict->SetAtName("Subtype", "Image");
- CPDF_ImageObject* pImgObj = AddImage(pStream, NULL, TRUE);
- if (!pImgObj) {
- if (pStream) {
- pStream->Release();
- } else {
- pDict->Release();
- }
- }
-}
-void CPDF_StreamContentParser::ParsePathObject() {
- FX_FLOAT params[6] = {};
- int nParams = 0;
- int last_pos = m_pSyntax->GetPos();
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- FX_BOOL bProcessed = TRUE;
- switch (type) {
- case CPDF_StreamParser::EndOfData:
- return;
- case CPDF_StreamParser::Keyword: {
- int len = m_pSyntax->GetWordSize();
- if (len == 1) {
- switch (m_pSyntax->GetWordBuf()[0]) {
- case kPathOperatorSubpath:
- AddPathPoint(params[0], params[1], FXPT_MOVETO);
- nParams = 0;
- break;
- case kPathOperatorLine:
- AddPathPoint(params[0], params[1], FXPT_LINETO);
- nParams = 0;
- break;
- case kPathOperatorCubicBezier1:
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- AddPathPoint(params[4], params[5], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case kPathOperatorCubicBezier2:
- AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case kPathOperatorCubicBezier3:
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case kPathOperatorClosePath:
- Handle_ClosePath();
- nParams = 0;
- break;
- default:
- bProcessed = FALSE;
- break;
- }
- } else if (len == 2) {
- if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] &&
- m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) {
- AddPathRect(params[0], params[1], params[2], params[3]);
- nParams = 0;
- } else {
- bProcessed = FALSE;
- }
- } else {
- bProcessed = FALSE;
- }
- if (bProcessed) {
- last_pos = m_pSyntax->GetPos();
- }
- break;
- }
- case CPDF_StreamParser::Number: {
- if (nParams == 6) {
- break;
- }
- FX_BOOL bInteger;
- int value;
- FX_atonum(
- CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()),
- bInteger, &value);
- params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value;
- break;
- }
- default:
- bProcessed = FALSE;
- }
- if (!bProcessed) {
- m_pSyntax->SetPos(last_pos);
- return;
- }
- }
-}
CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) {
m_pBuf = pData;
m_Size = dwSize;
m_Pos = 0;
m_pLastObj = NULL;
}
+
CPDF_StreamParser::~CPDF_StreamParser() {
if (m_pLastObj) {
m_pLastObj->Release();
}
}
+
FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder,
uint8_t*& dest_buf,
FX_DWORD& dest_size) {
@@ -275,6 +55,7 @@ FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder,
delete pDecoder;
return srcoff;
}
+
ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(
const uint8_t* src_buf,
FX_DWORD src_size,
@@ -323,6 +104,7 @@ FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf,
dest_buf = 0;
return (FX_DWORD)-1;
}
+
CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc,
CPDF_Dictionary* pDict,
CPDF_Object* pCSObj,
@@ -574,27 +356,16 @@ void CPDF_StreamParser::SkipPathObject() {
ch = m_pBuf[m_Pos++];
}
- if (m_Pos - op_startpos == 2) {
- int op = m_pBuf[op_startpos];
- if (op == kPathOperatorSubpath || op == kPathOperatorLine ||
- op == kPathOperatorCubicBezier1 ||
- op == kPathOperatorCubicBezier2 ||
- op == kPathOperatorCubicBezier3) {
- command_startpos = m_Pos;
- break;
- }
- } else if (m_Pos - op_startpos == 3) {
- if (m_pBuf[op_startpos] == kPathOperatorRectangle[0] &&
- m_pBuf[op_startpos + 1] == kPathOperatorRectangle[1]) {
- command_startpos = m_Pos;
- break;
- }
+ if (IsPathOperator(&m_pBuf[op_startpos], m_Pos - 1 - op_startpos)) {
+ command_startpos = m_Pos;
+ break;
}
m_Pos = command_startpos;
return;
}
}
}
+
CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray,
FX_BOOL bInArray) {
FX_BOOL bIsNumber;
@@ -678,6 +449,7 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray,
}
return NULL;
}
+
void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) {
m_WordSize = 0;
bIsNumber = TRUE;
@@ -852,6 +624,7 @@ CFX_ByteString CPDF_StreamParser::ReadString() {
}
return buf.GetByteString();
}
+
CFX_ByteString CPDF_StreamParser::ReadHexString() {
if (!PositionIsInBounds())
return CFX_ByteString();
@@ -899,10 +672,12 @@ CPDF_ContentParser::CPDF_ContentParser()
m_pData(nullptr),
m_Size(0),
m_CurrentOffset(0) {}
+
CPDF_ContentParser::~CPDF_ContentParser() {
if (!m_pSingleStream)
FX_Free(m_pData);
}
+
void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
if (m_Status != Ready || !pPage || !pPage->m_pDocument ||
!pPage->m_pFormDict) {
@@ -937,6 +712,7 @@ void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
m_Status = Done;
}
}
+
void CPDF_ContentParser::Start(CPDF_Form* pForm,
CPDF_AllStates* pGraphicStates,
CFX_Matrix* pParentMatrix,
@@ -995,6 +771,7 @@ void CPDF_ContentParser::Start(CPDF_Form* pForm,
m_InternalStage = STAGE_PARSE;
m_CurrentOffset = 0;
}
+
void CPDF_ContentParser::Continue(IFX_Pause* pPause) {
int steps = 0;
while (m_Status == ToBeContinued) {
diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h
index 863cac88b5..49f7a0e42c 100644
--- a/core/src/fpdfapi/fpdf_page/pageint.h
+++ b/core/src/fpdfapi/fpdf_page/pageint.h
@@ -456,5 +456,6 @@ class CPDF_PatternCS : public CPDF_ColorSpace {
};
void PDF_ReplaceAbbr(CPDF_Object* pObj);
+bool IsPathOperator(const uint8_t* buf, size_t len);
#endif // CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_