diff options
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 450 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp | 251 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/pageint.h | 1 |
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_ |