blob: 2eeb1feff54208ab634166e1e68276fedea78cc9 [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "pageint.h"
#if defined(_FPDFAPI_MINI_)
extern const FX_LPCSTR _PDF_CharType;
void CPDF_StreamContentParser::InputData(FX_LPCBYTE src_buf, FX_DWORD src_size)
{
if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
return;
}
for (FX_DWORD i = 0; i < src_size; i ++) {
int ch = src_buf[i];
int type = _PDF_CharType[ch];
start:
switch (m_WordState) {
case 0:
if (type == 'W') {
} else if (type == 'N') {
m_WordState = 5;
m_pWordBuf[0] = ch;
m_WordSize = 1;
} else if (type == 'R') {
m_WordState = 4;
m_pWordBuf[0] = ch;
m_WordSize = 1;
} else switch (ch) {
case '/':
m_WordState = 2;
m_WordSize = 0;
break;
case '[':
StartArray();
break;
case ']':
EndArray();
break;
case '(':
m_WordState = 7;
m_StringLevel = 1;
m_StringState = 0;
m_StringBuf.Clear();
break;
case '<':
m_WordState = 3;
break;
case '>':
m_WordState = 8;
break;
case '%':
m_WordState = 1;
break;
}
break;
case 1:
if (ch == '\n' || ch == '\r') {
m_WordState = 0;
}
break;
case 2:
if (type != 'R' && type != 'N') {
EndName();
m_WordState = 0;
goto start;
}
if (m_WordSize < 256) {
m_pWordBuf[m_WordSize++] = ch;
}
break;
case 3:
if (ch == '<') {
StartDict();
m_WordState = 0;
} else {
m_StringBuf.Clear();
m_WordState = 6;
goto start;
}
break;
case 4:
if (type != 'R' && type != 'N') {
m_WordState = 0;
EndKeyword();
if (m_bAbort) {
return;
}
goto start;
}
if (m_WordSize < 256) {
m_pWordBuf[m_WordSize++] = ch;
}
break;
case 5:
if (type != 'N') {
EndNumber();
m_WordState = 0;
goto start;
}
if (m_WordSize < 256) {
m_pWordBuf[m_WordSize++] = ch;
}
break;
case 6:
if (ch == '>') {
EndHexString();
m_WordState = 0;
} else {
m_StringBuf.AppendByte(ch);
}
break;
case 7:
switch (m_StringState) {
case 0:
if (ch == ')') {
m_StringLevel --;
if (m_StringLevel == 0) {
EndString();
m_WordState = 0;
break;
}
m_StringBuf.AppendByte(')');
} else if (ch == '(') {
m_StringLevel ++;
m_StringBuf.AppendByte('(');
} else if (ch == '\\') {
m_StringState = 1;
} else {
m_StringBuf.AppendByte((char)ch);
}
break;
case 1:
if (ch >= '0' && ch <= '7') {
m_EscCode = ch - '0';
m_StringState = 2;
break;
}
if (ch == 'n') {
m_StringBuf.AppendByte('\n');
} else if (ch == 'r') {
m_StringBuf.AppendByte('\r');
} else if (ch == 't') {
m_StringBuf.AppendByte('\t');
} else if (ch == 'b') {
m_StringBuf.AppendByte('\b');
} else if (ch == 'f') {
m_StringBuf.AppendByte('\f');
} else if (ch == '\\') {
m_StringBuf.AppendByte('\\');
} else if (ch == '(') {
m_StringBuf.AppendByte('(');
} else if (ch == ')') {
m_StringBuf.AppendByte(')');
} else if (ch == '\r') {
m_StringState = 4;
break;
} else if (ch == '\n') {
} else {
m_StringBuf.AppendByte(ch);
}
m_StringState = 0;
break;
case 2:
if (ch >= '0' && ch <= '7') {
m_EscCode = m_EscCode * 8 + ch - '0';
m_StringState = 3;
} else {
m_StringBuf.AppendByte(m_EscCode);
m_StringState = 0;
goto start;
}
break;
case 3:
if (ch >= '0' && ch <= '7') {
m_EscCode = m_EscCode * 8 + ch - '0';
m_StringBuf.AppendByte(m_EscCode);
m_StringState = 0;
} else {
m_StringBuf.AppendByte(m_EscCode);
m_StringState = 0;
goto start;
}
break;
case 4:
m_StringState = 0;
if (ch != '\n') {
goto start;
}
break;
}
break;
case 8:
m_WordState = 0;
if (ch == '>') {
EndDict();
} else {
goto start;
}
break;
case 9:
switch (m_InlineImageState) {
case 0:
if (type == 'W' || type == 'D') {
m_InlineImageState = 1;
m_InlineWhiteChar = ch;
} else {
m_StringBuf.AppendByte(ch);
}
break;
case 1:
m_StringBuf.AppendByte(m_InlineWhiteChar);
if (ch == 'I') {
m_InlineImageState = 2;
} else {
m_InlineImageState = 0;
goto start;
}
break;
case 2:
if (ch == 'D') {
m_InlineImageState = 3;
} else {
m_StringBuf.AppendByte('I');
m_InlineImageState = 0;
goto start;
}
break;
case 3:
EndImageDict();
break;
}
break;
case 10:
switch (m_InlineImageState) {
case 0:
if (type == 'W') {
m_InlineImageState = 1;
m_InlineWhiteChar = ch;
} else {
m_ImageSrcBuf.AppendByte(ch);
}
break;
case 1:
if (ch == 'E') {
m_InlineImageState = 2;
} else {
m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
m_InlineImageState = 0;
goto start;
}
break;
case 2:
if (ch == 'I') {
m_InlineImageState = 3;
} else {
m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
m_ImageSrcBuf.AppendByte('E');
m_InlineImageState = 0;
goto start;
}
break;
case 3:
if (type == 'W') {
EndInlineImage();
} else {
m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
m_ImageSrcBuf.AppendByte('E');
m_ImageSrcBuf.AppendByte('I');
m_InlineImageState = 0;
goto start;
}
break;
}
break;
case 11:
if (m_InlineImageState < m_ImageSrcBuf.GetSize()) {
m_ImageSrcBuf.GetBuffer()[m_InlineImageState ++] = ch;
} else {
if (ch == 'I') {
EndInlineImage();
}
}
break;
}
}
}
void CPDF_StreamContentParser::Finish()
{
switch (m_WordState) {
case 0:
break;
case 1:
break;
case 2:
EndName();
break;
case 3:
break;
case 4:
EndKeyword();
break;
case 5:
EndNumber();
break;
case 6:
EndHexString();
break;
case 7:
EndString();
break;
case 8:
break;
case 9:
break;
case 10:
EndInlineImage();
break;
}
m_WordState = 0;
}
void CPDF_StreamContentParser::AddContainer(CPDF_Object* pObject)
{
if (m_ObjectSize) {
m_pObjectState[m_ObjectSize] = SetToCurObj(pObject);
}
FXSYS_assert(m_ObjectSize < _FPDF_MAX_OBJECT_STACK_SIZE_);
m_pObjectStack[m_ObjectSize++] = pObject;
}
FX_BOOL CPDF_StreamContentParser::SetToCurObj(CPDF_Object* pObject)
{
if (m_ObjectSize == 0) {
AddObjectParam(pObject);
return TRUE;
}
FX_BOOL bInArrayOrDict = TRUE;
CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
if (pCurObj->GetType() == PDFOBJ_ARRAY) {
((CPDF_Array*)pCurObj)->Add(pObject, m_pDocument);
} else {
if (!m_bDictName && m_pDictName[0]) {
((CPDF_Dictionary*)pCurObj)->SetAt((FX_LPCSTR)m_pDictName, pObject, m_pDocument);
} else {
bInArrayOrDict = FALSE;
}
m_bDictName = TRUE;
}
return bInArrayOrDict;
}
void CPDF_StreamContentParser::StartArray()
{
if (m_ObjectSize)
if (m_pObjectStack[0]->GetType() != PDFOBJ_DICTIONARY && m_pObjectStack[m_ObjectSize - 1]->GetType() == PDFOBJ_ARRAY) {
return;
}
CPDF_Array* pArray = FX_NEW CPDF_Array;
AddContainer(pArray);
}
void CPDF_StreamContentParser::EndArray()
{
if (m_ObjectSize == 0) {
return;
}
CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
if (pCurObj->GetType() != PDFOBJ_ARRAY) {
return;
}
m_ObjectSize --;
if (m_ObjectSize == 0) {
AddObjectParam(pCurObj);
} else {
if (!m_pObjectState[m_ObjectSize]) {
pCurObj->Release();
}
}
m_pObjectState[m_ObjectSize] = FALSE;
}
void CPDF_StreamContentParser::StartDict()
{
CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
AddContainer(pDict);
m_bDictName = TRUE;
}
void CPDF_StreamContentParser::EndDict()
{
if (m_ObjectSize == 0) {
return;
}
CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
if (pCurObj->GetType() != PDFOBJ_DICTIONARY) {
return;
}
m_ObjectSize --;
if (m_ObjectSize == 0) {
AddObjectParam(pCurObj);
} else {
if (!m_pObjectState[m_ObjectSize]) {
pCurObj->Release();
}
}
m_pObjectState[m_ObjectSize] = FALSE;
}
void CPDF_StreamContentParser::EndName()
{
if (m_ObjectSize == 0) {
AddNameParam((FX_LPCSTR)m_pWordBuf, m_WordSize);
return;
}
CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
if (pCurObj->GetType() == PDFOBJ_ARRAY) {
((CPDF_Array*)pCurObj)->AddName(CFX_ByteString(m_pWordBuf, m_WordSize));
} else {
if (m_bDictName) {
FXSYS_memcpy32(m_pDictName, m_pWordBuf, m_WordSize);
m_pDictName[m_WordSize] = 0;
} else {
if (m_pDictName[0] != 0) {
((CPDF_Dictionary*)pCurObj)->SetAtName((FX_LPCSTR)m_pDictName, CFX_ByteString(m_pWordBuf, m_WordSize));
}
}
m_bDictName = !m_bDictName;
}
}
void CPDF_StreamContentParser::EndNumber()
{
if (m_ObjectSize == 0) {
AddNumberParam((FX_LPCSTR)m_pWordBuf, m_WordSize);
return;
}
CPDF_Number *pObj = FX_NEW CPDF_Number(CFX_ByteStringC(m_pWordBuf, m_WordSize));
if (!SetToCurObj(pObj)) {
pObj->Release();
}
}
extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf);
void CPDF_StreamContentParser::EndHexString()
{
CPDF_String *pObj = FX_NEW CPDF_String(_FPDF_ByteStringFromHex(m_StringBuf), TRUE);
if (!SetToCurObj(pObj)) {
pObj->Release();
}
}
void CPDF_StreamContentParser::EndString()
{
CPDF_String *pObj = FX_NEW CPDF_String(m_StringBuf.GetByteString());
if (!SetToCurObj(pObj)) {
pObj->Release();
}
}
void CPDF_StreamContentParser::Handle_BeginImage(void)
{
m_WordState = 9;
m_InlineImageState = 0;
m_StringBuf.Clear();
}
void _PDF_ReplaceAbbr(CPDF_Object* pObj);
void CPDF_StreamContentParser::EndImageDict()
{
if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() ||
FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(), m_StringBuf.GetSize())) {
m_WordState = 0;
StartDict();
InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize());
Finish();
m_bSameLastDict = FALSE;
if (m_pLastImageDict && m_bReleaseLastDict) {
m_pLastImageDict->Release();
m_pLastImageDict = NULL;
}
if (!m_ObjectSize) {
m_InlineImageState = 0;
return;
}
m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize];
m_bReleaseLastDict = !m_pObjectState[m_ObjectSize];
m_pObjectState[m_ObjectSize] = FALSE;
_PDF_ReplaceAbbr(m_pLastImageDict);
m_LastImageDict.TakeOver(m_StringBuf);
if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) {
CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
if (pCSObj->GetType() == PDFOBJ_NAME) {
CFX_ByteString name = pCSObj->GetString();
if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) {
pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
if (pCSObj) {
if (!pCSObj->GetObjNum()) {
pCSObj = pCSObj->Clone();
}
m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument);
}
}
}
}
} else {
m_bSameLastDict = TRUE;
}
m_ImageSrcBuf.Clear();
if (m_pLastCloneImageDict) {
m_pLastCloneImageDict->Release();
}
m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone();
if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) {
m_WordState = 10;
m_InlineImageState = 0;
} else {
int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width"));
int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height"));
int OrigSize = 0;
CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
if (pCSObj != NULL) {
int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent"));
int nComponents = 1;
CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj);
if (pCS == NULL) {
nComponents = 3;
} else {
nComponents = pCS->CountComponents();
m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
}
int pitch = (width * bpc * nComponents + 7) / 8;
OrigSize = pitch * height;
} else {
OrigSize = ((width + 7) / 8) * height;
}
m_ImageSrcBuf.AppendBlock(NULL, OrigSize);
m_WordState = 11;
m_InlineImageState = 0;
}
}
void CPDF_StreamContentParser::EndInlineImage()
{
CFX_AffineMatrix ImageMatrix;
ImageMatrix.Copy(m_pCurStates->m_CTM);
ImageMatrix.Concat(m_mtContentToUser);
m_LastImageData.CopyData(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize());
CPDF_Stream* pStream = CPDF_Stream::Create(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize(),
m_pLastCloneImageDict);
m_ImageSrcBuf.DetachBuffer();
m_pLastCloneImageDict = NULL;
CPDF_InlineImages* pImages = FX_NEW CPDF_InlineImages;
pImages->m_pStream = pStream;
SetGraphicStates(pImages, !m_pLastCloneImageDict->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE);
pImages->AddMatrix(ImageMatrix);
m_pObjectList->m_ObjectList.AddTail(pImages);
m_WordState = 0;
}
#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274)
#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e)
#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166)
void CPDF_StreamContentParser::EndKeyword()
{
CPDF_Object *pObj = NULL;
if (m_WordSize == 4) {
if (*(FX_DWORD*)m_pWordBuf == FXDWORD_TRUE) {
pObj = CPDF_Boolean::Create(TRUE);
if (!SetToCurObj(pObj)) {
pObj->Release();
}
return;
} else if (*(FX_DWORD*)m_pWordBuf == FXDWORD_NULL) {
pObj = CPDF_Null::Create();
if (!SetToCurObj(pObj)) {
pObj->Release();
}
return;
}
} else if (m_WordSize == 5) {
if (*(FX_DWORD*)m_pWordBuf == FXDWORD_FALS && m_pWordBuf[4] == 'e') {
pObj = CPDF_Boolean::Create(FALSE);
if (!SetToCurObj(pObj)) {
pObj->Release();
}
return;
}
}
m_pWordBuf[m_WordSize] = 0;
OnOperator((char*)m_pWordBuf);
ClearAllParams();
}
#define PAGEPARSE_STAGE_PARSE 2
#define PAGEPARSE_STAGE_CHECKCLIP 3
CPDF_ContentParser::CPDF_ContentParser()
{
m_pParser = NULL;
m_Status = Ready;
m_pStreamFilter = NULL;
m_pType3Char = NULL;
}
CPDF_ContentParser::~CPDF_ContentParser()
{
Clear();
}
void CPDF_ContentParser::Clear()
{
if (m_pParser) {
delete m_pParser;
}
if (m_pStreamFilter) {
delete m_pStreamFilter;
}
m_pParser = NULL;
m_Status = Ready;
}
void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions)
{
if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) {
m_Status = Done;
return;
}
m_pObjects = pPage;
m_bForm = FALSE;
if (pOptions) {
m_Options = *pOptions;
}
CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
if (pContent == NULL) {
m_Status = Done;
return;
}
if (pContent->GetType() == PDFOBJ_STREAM) {
m_nStreams = 1;
} else if (pContent->GetType() == PDFOBJ_ARRAY) {
m_nStreams = ((CPDF_Array*)pContent)->GetCount();
} else {
m_Status = Done;
return;
}
m_Status = ToBeContinued;
m_InternalStage = PAGEPARSE_STAGE_PARSE;
m_CurrentOffset = 0;
m_pParser = FX_NEW CPDF_StreamContentParser;
m_pParser->Initialize();
m_pParser->PrepareParse(pPage->m_pDocument, pPage->m_pResources, NULL, NULL, pPage,
pPage->m_pResources, &pPage->m_BBox, &m_Options, NULL, 0);
m_pParser->m_pCurStates->m_ColorState.GetModify()->Default();
}
void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
{
m_pType3Char = pType3Char;
m_pObjects = pForm;
m_bForm = TRUE;
CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix"));
if (pGraphicStates) {
form_matrix.Concat(pGraphicStates->m_CTM);
}
CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox"));
CFX_FloatRect form_bbox;
CPDF_Path ClipPath;
if (pBBox) {
form_bbox = pBBox->GetRect();
ClipPath.New();
ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top);
ClipPath.Transform(&form_matrix);
if (pParentMatrix) {
ClipPath.Transform(pParentMatrix);
}
form_bbox.Transform(&form_matrix);
}
CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
m_pParser = FX_NEW CPDF_StreamContentParser;
m_pParser->Initialize();
m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm,
pResources, &form_bbox, pOptions, pGraphicStates, level);
m_pParser->m_pCurStates->m_CTM = form_matrix;
if (ClipPath.NotNull()) {
m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE);
}
if (pForm->m_Transparency & PDFTRANS_GROUP) {
CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify();
pData->m_BlendType = FXDIB_BLEND_NORMAL;
pData->m_StrokeAlpha = 1.0f;
pData->m_FillAlpha = 1.0f;
pData->m_pSoftMask = NULL;
}
m_pStreamFilter = pForm->m_pFormStream->GetStreamFilter();
m_nStreams = 1;
m_Status = ToBeContinued;
m_InternalStage = PAGEPARSE_STAGE_PARSE;
m_CurrentOffset = 0;
}
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;
}
}
}
int CPDF_ContentParser::EstimateProgress()
{
if (m_Status == Ready) {
return 0;
}
if (m_Status == Done) {
return 100;
}
if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
return 90;
}
if (m_pStreamFilter == NULL) {
return 90 * m_CurrentOffset / m_nStreams;
}
int total_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_nStreams;
int parsed_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_CurrentOffset +
m_pStreamFilter->GetSrcPos();
return 90 * parsed_raw_size / total_raw_size;
}
CPDF_InlineImages::CPDF_InlineImages()
{
m_Type = PDFPAGE_INLINES;
m_pStream = NULL;
m_pBitmap = NULL;
}
CPDF_InlineImages::~CPDF_InlineImages()
{
if (m_pStream) {
m_pStream->Release();
}
if (m_pBitmap) {
delete m_pBitmap;
}
}
void CPDF_InlineImages::AddMatrix(CFX_AffineMatrix& matrix)
{
m_Matrices.Add(matrix);
CFX_FloatRect rect = matrix.GetUnitRect();
if (m_Matrices.GetSize() > 1) {
CFX_FloatRect rect1(m_Left, m_Bottom, m_Right, m_Top);
rect.Union(rect1);
}
m_Left = rect.left;
m_Right = rect.right;
m_Top = rect.top;
m_Bottom = rect.bottom;
}
#endif