1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file. 4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/include/fpdfapi/fpdf_module.h" 8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/include/fpdfapi/fpdf_page.h" 9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/include/fpdfapi/fpdf_serial.h" 10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/src/fpdfapi/fpdf_page/pageint.h" 11ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 12ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& ar, CFX_Matrix& matrix) { 13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ar << matrix.a << " " << matrix.b << " " << matrix.c << " " << matrix.d << " " 14ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann << matrix.e << " " << matrix.f; 15ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ar; 16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCPDF_PageContentGenerate::CPDF_PageContentGenerate(CPDF_Page* pPage) 18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann : m_pPage(pPage) { 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pDocument = NULL; 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pPage) { 21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pDocument = m_pPage->m_pDocument; 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_POSITION pos = pPage->GetFirstObjectPosition(); 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (pos) { 25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann InsertPageObject(pPage->GetNextObject(pos)); 26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCPDF_PageContentGenerate::~CPDF_PageContentGenerate() {} 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannFX_BOOL CPDF_PageContentGenerate::InsertPageObject( 30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_PageObject* pPageObject) { 31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pPageObject) { 32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return FALSE; 33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return m_pageObjects.Add(pPageObject); 35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CPDF_PageContentGenerate::GenerateContent() { 37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_ByteTextBuf buf; 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict; 39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int i = 0; i < m_pageObjects.GetSize(); ++i) { 40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_PageObject* pPageObj = m_pageObjects[i]; 41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pPageObj || pPageObj->m_Type != PDFPAGE_IMAGE) { 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ProcessImage(buf, (CPDF_ImageObject*)pPageObj); 45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Object* pContent = 47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pPageDict ? pPageDict->GetElementValue("Contents") : NULL; 48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pContent) { 49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pPageDict->RemoveAt("Contents"); 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, NULL); 52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE); 53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pDocument->AddIndirectObject(pStream); 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pPageDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum()); 55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_ByteString CPDF_PageContentGenerate::RealizeResource( 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Object* pResourceObj, 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const FX_CHAR* szType) { 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!m_pPage->m_pResources) { 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPage->m_pResources = new CPDF_Dictionary; 61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int objnum = m_pDocument->AddIndirectObject(m_pPage->m_pResources); 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPage->m_pFormDict->SetAtReference("Resources", m_pDocument, objnum); 63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDict(szType); 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pResList) { 66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pResList = new CPDF_Dictionary; 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPage->m_pResources->SetAt(szType, pResList); 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pDocument->AddIndirectObject(pResourceObj); 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_ByteString name; 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int idnum = 1; 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann name.Format("FX%c%d", szType[0], idnum); 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pResList->KeyExist(name)) { 75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann idnum++; 78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pResList->AddReference(name, m_pDocument, pResourceObj->GetObjNum()); 80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return name; 81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CPDF_PageContentGenerate::ProcessImage(CFX_ByteTextBuf& buf, 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_ImageObject* pImageObj) { 84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ((pImageObj->m_Matrix.a == 0 && pImageObj->m_Matrix.b == 0) || 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (pImageObj->m_Matrix.c == 0 && pImageObj->m_Matrix.d == 0)) { 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann buf << "q " << pImageObj->m_Matrix << " cm "; 89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pImageObj->m_pImage->IsInline()) { 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Stream* pStream = pImageObj->m_pImage->GetStream(); 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_DWORD dwSavedObjNum = pStream->GetObjNum(); 92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov CFX_ByteString name = RealizeResource(pStream, "XObject"); 93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (dwSavedObjNum == 0) { 94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pImageObj->m_pImage) 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pImageObj->m_pImage->Release(); 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pStream); 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov buf << "/" << PDF_NameEncode(name) << " Do Q\n"; 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CPDF_PageContentGenerate::ProcessForm(CFX_ByteTextBuf& buf, 102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* data, 103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_DWORD size, 104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_Matrix& matrix) { 105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!data || !size) { 106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, NULL); 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Dictionary* pFormDict = new CPDF_Dictionary; 110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pFormDict->SetAtName("Type", "XObject"); 111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pFormDict->SetAtName("Subtype", "Form"); 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_FloatRect bbox = m_pPage->GetPageBBox(); 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann matrix.TransformRect(bbox); 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pFormDict->SetAtRect("BBox", bbox); 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pStream->InitStream((uint8_t*)data, size, pFormDict); 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann buf << "q " << matrix << " cm "; 117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_ByteString name = RealizeResource(pStream, "XObject"); 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann buf << "/" << PDF_NameEncode(name) << " Do Q\n"; 119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CPDF_PageContentGenerate::TransformContent(CFX_Matrix& matrix) { 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Dictionary* pDict = m_pPage->m_pFormDict; 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Object* pContent = pDict ? pDict->GetElementValue("Contents") : NULL; 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pContent) 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_ByteTextBuf buf; 127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (CPDF_Array* pArray = pContent->AsArray()) { 128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int iCount = pArray->GetCount(); 129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_StreamAcc** pContentArray = FX_Alloc(CPDF_StreamAcc*, iCount); 130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int size = 0; 131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int i = 0; 132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (i = 0; i < iCount; ++i) { 133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pContent = pArray->GetElement(i); 134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Stream* pStream = ToStream(pContent); 135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!pStream) 136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_StreamAcc* pStreamAcc = new CPDF_StreamAcc(); 139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pStreamAcc->LoadAllData(pStream); 140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pContentArray[i] = pStreamAcc; 141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size += pContentArray[i]->GetSize() + 1; 142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int pos = 0; 144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* pBuf = FX_Alloc(uint8_t, size); 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (i = 0; i < iCount; ++i) { 146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(pBuf + pos, pContentArray[i]->GetData(), 147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pContentArray[i]->GetSize()); 148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pos += pContentArray[i]->GetSize() + 1; 149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pBuf[pos - 1] = ' '; 150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann delete pContentArray[i]; 151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ProcessForm(buf, pBuf, size, matrix); 153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(pBuf); 154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(pContentArray); 155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (CPDF_Stream* pStream = pContent->AsStream()) { 156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_StreamAcc contentStream; 157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann contentStream.LoadAllData(pStream); 158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ProcessForm(buf, contentStream.GetData(), contentStream.GetSize(), matrix); 159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, NULL); 161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE); 162ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pDocument->AddIndirectObject(pStream); 163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPage->m_pFormDict->SetAtReference("Contents", m_pDocument, 164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pStream->GetObjNum()); 165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 166