CPDF_ContentParser::Stage CPDF_ContentParser::CheckClip() { if (m_pType3Char) { m_pType3Char->InitializeFromStreamData(m_pParser->IsColored(), m_pParser->GetType3Data()); } for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) { if (!pObj->m_ClipPath.HasRef()) continue; if (pObj->m_ClipPath.GetPathCount() != 1) continue; if (pObj->m_ClipPath.GetTextCount() > 0) continue; CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); if (!ClipPath.IsRect() || pObj->IsShading()) continue; CFX_PointF point0 = ClipPath.GetPoint(0); CFX_PointF point2 = ClipPath.GetPoint(2); CFX_FloatRect old_rect(point0.x, point0.y, point2.x, point2.y); if (old_rect.Contains(pObj->GetRect())) pObj->m_ClipPath.SetNull(); } return Stage::kComplete; }
void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path) { const CFX_PathData* pPathData = path; if (!pPathData) return; FX_PATHPOINT* pPoints = pPathData->GetPoints(); if (path.IsRect()) { buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " " << (pPoints[2].m_PointX - pPoints[0].m_PointX) << " " << (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re\n"; return; } CFX_ByteString temp; for (int i = 0; i < pPathData->GetPointCount(); i++) { buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY); int point_type = pPoints[i].m_Flag & FXPT_TYPE; if (point_type == FXPT_MOVETO) buf << " m\n"; else if (point_type == FXPT_BEZIERTO) { buf << " " << (pPoints[i + 1].m_PointX) << " " << (pPoints[i + 1].m_PointY) << " " << (pPoints[i + 2].m_PointX) << " " << (pPoints[i + 2].m_PointY); if (pPoints[i + 2].m_Flag & FXPT_CLOSEFIGURE) buf << " c h\n"; else buf << " c\n"; i += 2; } else if (point_type == FXPT_LINETO) { if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) buf << " l h\n"; else buf << " l\n"; } } }
void OutputPath(std::ostringstream& buf, CPDF_Path path) { const CFX_PathData* pPathData = path.GetObject(); if (!pPathData) return; const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints(); if (path.IsRect()) { CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point; buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x << " " << diff.y << " re\n"; return; } ByteString temp; for (size_t i = 0; i < pPoints.size(); i++) { buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y; FXPT_TYPE point_type = pPoints[i].m_Type; if (point_type == FXPT_TYPE::MoveTo) { buf << " m\n"; } else if (point_type == FXPT_TYPE::BezierTo) { buf << " " << pPoints[i + 1].m_Point.x << " " << pPoints[i + 1].m_Point.y << " " << pPoints[i + 2].m_Point.x << " " << pPoints[i + 2].m_Point.y; buf << " c"; if (pPoints[i + 2].m_CloseFigure) buf << " h"; buf << "\n"; i += 2; } else if (point_type == FXPT_TYPE::LineTo) { buf << " l"; if (pPoints[i].m_CloseFigure) buf << " h"; buf << "\n"; } } }
void CPDF_ContentParser::Continue(IFX_Pause* pPause) { while (m_Status == ToBeContinued) { if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { if (m_pStreamFilter == NULL) { if (m_CurrentOffset == m_nStreams) { m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; if (m_pType3Char) { m_pType3Char->m_bColored = m_pParser->m_bColored; m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000); m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000); m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000); m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000); m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000); m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing; } delete m_pParser; m_pParser = NULL; continue; } CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); if (pContent->GetType() == PDFOBJ_STREAM) { m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter(); } else { CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_CurrentOffset); if (pStream == NULL) { m_CurrentOffset ++; continue; } m_pStreamFilter = pStream->GetStreamFilter(); } } FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, STREAM_PARSE_BUFSIZE); m_pParser->InputData(m_pParser->m_pStreamBuf, len); if (m_pParser->m_bAbort) { delete m_pStreamFilter; m_pStreamFilter = NULL; m_Status = Done; delete m_pParser; m_pParser = NULL; return; } if (len < STREAM_PARSE_BUFSIZE) { m_pParser->Finish(); m_CurrentOffset ++; delete m_pStreamFilter; m_pStreamFilter = NULL; } if (pPause && pPause->NeedToPauseNow()) { return; } } if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); while (pos) { CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); if (pObj == NULL) { continue; } if (pObj->m_ClipPath.IsNull()) { continue; } if (pObj->m_ClipPath.GetPathCount() != 1) { continue; } if (pObj->m_ClipPath.GetTextCount()) { continue; } CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { continue; } CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), ClipPath.GetPointX(2), ClipPath.GetPointY(2)); CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); if (old_rect.Contains(obj_rect)) { pObj->m_ClipPath.SetNull(); } } if (m_pObjects->m_ObjectList.GetCount() == 1) { CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetAt(m_pObjects->m_ObjectList.GetHeadPosition()); if (pObj && pObj->m_Type == PDFPAGE_TEXT) { CPDF_TextObject* pText = (CPDF_TextObject*)pObj; } } m_Status = Done; return; } } }
void CPDF_ContentParser::Continue(IFX_Pause* pPause) { int steps = 0; while (m_Status == ToBeContinued) { if (m_InternalStage == STAGE_GETCONTENT) { if (m_CurrentOffset == m_nStreams) { if (!m_StreamArray.empty()) { FX_SAFE_UINT32 safeSize = 0; for (const auto& stream : m_StreamArray) { safeSize += stream->GetSize(); safeSize += 1; } if (!safeSize.IsValid()) { m_Status = Done; return; } m_Size = safeSize.ValueOrDie(); m_pData = FX_Alloc(uint8_t, m_Size); uint32_t pos = 0; for (const auto& stream : m_StreamArray) { FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize()); pos += stream->GetSize(); m_pData[pos++] = ' '; } m_StreamArray.clear(); } else { m_pData = (uint8_t*)m_pSingleStream->GetData(); m_Size = m_pSingleStream->GetSize(); } m_InternalStage = STAGE_PARSE; m_CurrentOffset = 0; } else { CPDF_Array* pContent = m_pObjectHolder->m_pFormDict->GetArrayFor("Contents"); m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc); CPDF_Stream* pStreamObj = ToStream( pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, false); m_CurrentOffset++; } } if (m_InternalStage == STAGE_PARSE) { if (!m_pParser) { m_pParser.reset(new CPDF_StreamContentParser( m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, &m_pObjectHolder->m_BBox, nullptr, 0)); m_pParser->GetCurStates()->m_ColorState.SetDefault(); } if (m_CurrentOffset >= m_Size) { m_InternalStage = STAGE_CHECKCLIP; } else { m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); } } if (m_InternalStage == STAGE_CHECKCLIP) { if (m_pType3Char) { m_pType3Char->m_bColored = m_pParser->IsColored(); m_pType3Char->m_Width = FXSYS_round(m_pParser->GetType3Data()[0] * 1000); m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->GetType3Data()[2] * 1000); m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->GetType3Data()[3] * 1000); m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->GetType3Data()[4] * 1000); m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->GetType3Data()[5] * 1000); } for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) { if (!pObj->m_ClipPath) continue; if (pObj->m_ClipPath.GetPathCount() != 1) continue; if (pObj->m_ClipPath.GetTextCount()) continue; CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); if (!ClipPath.IsRect() || pObj->IsShading()) continue; CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), ClipPath.GetPointX(2), ClipPath.GetPointY(2)); CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); if (old_rect.Contains(obj_rect)) pObj->m_ClipPath.SetNull(); } m_Status = Done; return; } steps++; if (pPause && pPause->NeedToPauseNow()) break; } }