示例#1
0
CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const
{
    if (m_ObjNum) {
        return FX_NEW CPDF_Reference(pDoc, m_ObjNum);
    }
    return Clone();
}
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
{
	if(!page)
		return FALSE;

	CFX_ByteTextBuf textBuf;
	textBuf<<"q ";
	CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
	rect.Normalize();
	CFX_ByteString bsClipping;
	bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height());
	textBuf<<bsClipping;

	CFX_ByteString bsMatix;
	bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,matrix->c,matrix->d,matrix->e,matrix->f);
	textBuf<<bsMatix;
	

	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return FALSE;
	
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return FALSE;
	pDoc->AddIndirectObject(pStream);

	pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pEndStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pEndStream->SetData((FX_LPCBYTE)" Q", 2, FALSE, FALSE);
	pDoc->AddIndirectObject(pEndStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		pContentArray->AddReference(pDoc,pEndStream);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				pContentArray->AddReference(pDoc,pEndStream);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pContentArray->AddReference(pDoc, pEndStream);
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	

	//Need to transform the patterns as well.
	CPDF_Dictionary* pRes = pPageDic->GetDict(FX_BSTRC("Resources"));
	if(pRes)
	{
		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
		if(pPattenDict)
		{
			FX_POSITION pos = pPattenDict->GetStartPos();
			while(pos)
			{
				CPDF_Dictionary* pDict = NULL;
				CFX_ByteString key;
				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
				if(pObj->GetType() == PDFOBJ_REFERENCE)
					pObj = pObj->GetDirect();
				if(pObj->GetType() == PDFOBJ_DICTIONARY)
				{
					pDict = (CPDF_Dictionary*)pObj;
				}
				else if(pObj->GetType() == PDFOBJ_STREAM)
				{
					pDict = ((CPDF_Stream*)pObj)->GetDict();
				}
				else
					continue;
				
				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
				m.Concat(t);
				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
			}
		}
	}

	return TRUE;
}
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
{
	if(!page)
		return;
	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return;

	CFX_ByteTextBuf strClip;
	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
	FX_DWORD i;
	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
		CPDF_Path path = pClipPath->GetPath(i);
		int iClipType = pClipPath->GetClipType(i);
		if (path.GetPointCount() == 0) {
			// Empty clipping (totally clipped out)
			strClip << "0 0 m W n ";
		} else {
			OutputPath(strClip, path);
			if (iClipType == FXFILL_WINDING)
				strClip << "W n\n";
			else
				strClip << "W* n\n";
		}
	}
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return;
	pDoc->AddIndirectObject(pStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	
}
void CPDF_Dictionary::AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
{
    AddValue(key, FX_NEW CPDF_Reference(pDoc, objnum));
}
void CPDF_Dictionary::SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
{
    SetAt(key, FX_NEW CPDF_Reference(pDoc, objnum));
}
void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
{
    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
    Add(FX_NEW CPDF_Reference(pDoc, objnum));
}
CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const
{
    if (this == NULL) {
        return NULL;
    }
    switch (m_Type) {
        case PDFOBJ_BOOLEAN:
            return FX_NEW CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
        case PDFOBJ_NUMBER:
            return FX_NEW CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer);
        case PDFOBJ_STRING:
            return FX_NEW CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex());
        case PDFOBJ_NAME:
            return FX_NEW CPDF_Name(((CPDF_Name*)this)->m_Name);
        case PDFOBJ_ARRAY: {
                CPDF_Array* pCopy = FX_NEW CPDF_Array();
                CPDF_Array* pThis = (CPDF_Array*)this;
                int n = pThis->GetCount();
                for (int i = 0; i < n; i ++) {
                    CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
                    pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_DICTIONARY: {
                CPDF_Dictionary* pCopy = FX_NEW CPDF_Dictionary();
                CPDF_Dictionary* pThis = (CPDF_Dictionary*)this;
                FX_POSITION pos = pThis->m_Map.GetStartPosition();
                while (pos) {
                    CFX_ByteString key;
                    CPDF_Object* value;
                    pThis->m_Map.GetNextAssoc(pos, key, (void*&)value);
                    pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_NULL: {
                return FX_NEW CPDF_Null;
            }
        case PDFOBJ_STREAM: {
                CPDF_Stream* pThis = (CPDF_Stream*)this;
                CPDF_StreamAcc acc;
                acc.LoadAllData(pThis, TRUE);
                FX_DWORD streamSize = acc.GetSize();
                CPDF_Stream* pObj = FX_NEW CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
                return pObj;
            }
        case PDFOBJ_REFERENCE: {
                CPDF_Reference* pRef = (CPDF_Reference*)this;
                FX_DWORD obj_num = pRef->m_RefObjNum;
                if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) {
                    visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1);
                    CPDF_Object* ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
                    return ret;
                } else {
                    return FX_NEW CPDF_Reference(pRef->m_pObjList, obj_num);
                }
            }
    }
    return NULL;
}