14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2016 PDFium Authors. All rights reserved. 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file. 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include <tuple> 1033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include <utility> 1133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 1233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include "core/fpdfapi/font/cpdf_font.h" 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_docpagedata.h" 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_image.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_imageobject.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_page.h" 1733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include "core/fpdfapi/page/cpdf_path.h" 1833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include "core/fpdfapi/page/cpdf_pathobject.h" 1933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include "core/fpdfapi/page/cpdf_textobject.h" 20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fpdfapi/parser/cpdf_array.h" 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_dictionary.h" 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_document.h" 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_name.h" 2433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_number.h" 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_reference.h" 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_stream.h" 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/fpdf_parser_decode.h" 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace { 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::ostream& operator<<(std::ostream& ar, const CFX_Matrix& matrix) { 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ar << matrix.a << " " << matrix.b << " " << matrix.c << " " << matrix.d << " " 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann << matrix.e << " " << matrix.f; 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return ar; 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool GetColor(const CPDF_Color* pColor, float* rgb) { 3833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann int intRGB[3]; 3933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (!pColor || 4033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann pColor->GetColorSpace() != CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB) || 41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann !pColor->GetRGB(&intRGB[0], &intRGB[1], &intRGB[2])) { 4233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann return false; 4333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 4433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann rgb[0] = intRGB[0] / 255.0f; 4533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann rgb[1] = intRGB[1] / 255.0f; 4633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann rgb[2] = intRGB[2] / 255.0f; 4733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann return true; 4833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann} 4933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCPDF_PageContentGenerator::CPDF_PageContentGenerator( 53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_PageObjectHolder* pObjHolder) 54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann : m_pObjHolder(pObjHolder), m_pDocument(pObjHolder->m_pDocument.Get()) { 55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (const auto& pObj : *pObjHolder->GetPageObjectList()) { 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pObj) 57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pageObjects.emplace_back(pObj.get()); 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDF_PageContentGenerator::~CPDF_PageContentGenerator() {} 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CPDF_PageContentGenerator::GenerateContent() { 64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ASSERT(m_pObjHolder->IsPage()); 65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Document* pDoc = m_pDocument.Get(); 67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::ostringstream buf; 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Set the default graphic state values 70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann buf << "q\n"; 71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!m_pObjHolder->GetLastCTM().IsIdentity()) 72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann buf << m_pObjHolder->GetLastCTM().GetInverse() << " cm\n"; 73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ProcessDefaultGraphics(&buf); 74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Process the page objects 76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!ProcessPageObjects(&buf)) 77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Return graphics to original state 80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann buf << "Q\n"; 81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Add buffer to a stream in page's 'Contents' 83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Dictionary* pPageDict = m_pObjHolder->m_pFormDict.Get(); 84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Object* pContent = 85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageDict ? pPageDict->GetObjectFor("Contents") : nullptr; 86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(); 87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pStream->SetData(&buf); 88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (pContent) { 89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Array* pArray = ToArray(pContent); 90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (pArray) { 91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum()); 92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Reference* pReference = ToReference(pContent); 95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!pReference) { 96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(), 97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pStream->GetObjNum()); 98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Object* pDirectObj = pReference->GetDirect(); 101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!pDirectObj) { 102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(), 103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pStream->GetObjNum()); 104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Array* pObjArray = pDirectObj->AsArray(); 107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (pObjArray) { 108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pObjArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum()); 109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (pDirectObj->IsStream()) { 112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>(); 113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum()); 114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum()); 115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageDict->SetNewFor<CPDF_Reference>("Contents", pDoc, 116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pContentArray->GetObjNum()); 117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(), 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pStream->GetObjNum()); 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 124d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString CPDF_PageContentGenerator::RealizeResource( 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t dwResourceObjNum, 126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const ByteString& bsType) { 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ASSERT(dwResourceObjNum); 128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!m_pObjHolder->m_pResources) { 129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_pResources = m_pDocument->NewIndirect<CPDF_Dictionary>(); 130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_pFormDict->SetNewFor<CPDF_Reference>( 131d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann "Resources", m_pDocument.Get(), 132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_pResources->GetObjNum()); 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Dictionary* pResList = m_pObjHolder->m_pResources->GetDictFor(bsType); 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pResList) 136d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pResList = m_pObjHolder->m_pResources->SetNewFor<CPDF_Dictionary>(bsType); 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString name; 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int idnum = 1; 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (1) { 141d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann name = ByteString::Format("FX%c%d", bsType[0], idnum); 142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!pResList->KeyExist(name)) 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 144d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann idnum++; 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pResList->SetNewFor<CPDF_Reference>(name, m_pDocument.Get(), 148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann dwResourceObjNum); 1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return name; 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CPDF_PageContentGenerator::ProcessPageObjects(std::ostringstream* buf) { 153d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann bool bDirty = false; 154d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (auto& pPageObj : m_pageObjects) { 155d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (m_pObjHolder->IsPage() && !pPageObj->IsDirty()) 156d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann continue; 157d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 158d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann bDirty = true; 159d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (CPDF_ImageObject* pImageObject = pPageObj->AsImage()) 160d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ProcessImage(buf, pImageObject); 161d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else if (CPDF_PathObject* pPathObj = pPageObj->AsPath()) 162d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ProcessPath(buf, pPathObj); 163d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else if (CPDF_TextObject* pTextObj = pPageObj->AsText()) 164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ProcessText(buf, pTextObj); 165d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageObj->SetDirty(false); 166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return bDirty; 168d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 170d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageContentGenerator::ProcessImage(std::ostringstream* buf, 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_ImageObject* pImageObj) { 1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((pImageObj->matrix().a == 0 && pImageObj->matrix().b == 0) || 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (pImageObj->matrix().c == 0 && pImageObj->matrix().d == 0)) { 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *buf << "q " << pImageObj->matrix() << " cm "; 1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 178d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann RetainPtr<CPDF_Image> pImage = pImageObj->GetImage(); 1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pImage->IsInline()) 1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_Stream* pStream = pImage->GetStream(); 1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pStream) 1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bWasInline = pStream->IsInline(); 1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bWasInline) 1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pImage->ConvertStreamToIndirectObject(); 1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t dwObjNum = pStream->GetObjNum(); 191d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString name = RealizeResource(dwObjNum, "XObject"); 1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bWasInline) 193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pImageObj->SetImage(m_pDocument->GetPageData()->GetImage(dwObjNum)); 1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *buf << "/" << PDF_NameEncode(name) << " Do Q\n"; 1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 19833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Processing path with operators from Tables 4.9 and 4.10 of PDF spec 1.7: 19933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "re" appends a rectangle (here, used only if the whole path is a rectangle) 20033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "m" moves current point to the given coordinates 20133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "l" creates a line from current point to the new point 20233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "c" adds a Bezier curve from current to last point, using the two other 20333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// points as the Bezier control points 20433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Note: "l", "c" change the current point 20533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "h" closes the subpath (appends a line from current to starting point) 20633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Path painting operators: "S", "n", "B", "f", "B*", "f*", depending on 20733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// the filling mode and whether we want stroking the path or not. 20833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "Q" restores the graphics state imposed by the ProcessGraphics method. 209d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageContentGenerator::ProcessPath(std::ostringstream* buf, 21033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CPDF_PathObject* pPathObj) { 21133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann ProcessGraphics(buf, pPathObj); 212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << pPathObj->m_Matrix << " cm "; 214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 21533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann auto& pPoints = pPathObj->m_Path.GetPoints(); 21633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (pPathObj->m_Path.IsRect()) { 21733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point; 21833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x 21933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << " " << diff.y << " re"; 22033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } else { 22133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann for (size_t i = 0; i < pPoints.size(); i++) { 22233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (i > 0) 22333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " "; 22433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y; 22533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann FXPT_TYPE pointType = pPoints[i].m_Type; 22633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (pointType == FXPT_TYPE::MoveTo) { 22733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " m"; 22833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } else if (pointType == FXPT_TYPE::LineTo) { 22933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " l"; 23033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } else if (pointType == FXPT_TYPE::BezierTo) { 23133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (i + 2 >= pPoints.size() || 23233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann !pPoints[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) || 23333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann !pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) || 23433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann pPoints[i + 2].m_Type != FXPT_TYPE::BezierTo) { 23533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann // If format is not supported, close the path and paint 23633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " h"; 23733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann break; 23833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 23933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " " << pPoints[i + 1].m_Point.x << " " 24033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << pPoints[i + 1].m_Point.y << " " << pPoints[i + 2].m_Point.x 24133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << " " << pPoints[i + 2].m_Point.y << " c"; 24233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann i += 2; 24333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 24433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (pPoints[i].m_CloseFigure) 24533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " h"; 24633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 24733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 24833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (pPathObj->m_FillType == 0) 24933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << (pPathObj->m_bStroke ? " S" : " n"); 25033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann else if (pPathObj->m_FillType == FXFILL_WINDING) 25133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << (pPathObj->m_bStroke ? " B" : " f"); 25233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann else if (pPathObj->m_FillType == FXFILL_ALTERNATE) 25333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << (pPathObj->m_bStroke ? " B*" : " f*"); 25433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << " Q\n"; 25533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann} 25633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 25733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// This method supports color operators rg and RGB from Table 4.24 of PDF spec 25833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// 1.7. A color will not be set if the colorspace is not DefaultRGB or the RGB 25933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// values cannot be obtained. The method also adds an external graphics 26033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// dictionary, as described in Section 4.3.4. 26133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "rg" sets the fill color, "RG" sets the stroke color (using DefaultRGB) 26233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "w" sets the stroke line width. 26333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "ca" sets the fill alpha, "CA" sets the stroke alpha. 26433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// "q" saves the graphics state, so that the settings can later be reversed 265d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageContentGenerator::ProcessGraphics(std::ostringstream* buf, 26633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CPDF_PageObject* pPageObj) { 26733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << "q "; 268d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float fillColor[3]; 26933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (GetColor(pPageObj->m_ColorState.GetFillColor(), fillColor)) { 27033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << fillColor[0] << " " << fillColor[1] << " " << fillColor[2] 27133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << " rg "; 27233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 273d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float strokeColor[3]; 27433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (GetColor(pPageObj->m_ColorState.GetStrokeColor(), strokeColor)) { 27533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << strokeColor[0] << " " << strokeColor[1] << " " << strokeColor[2] 27633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << " RG "; 27733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float lineWidth = pPageObj->m_GraphState.GetLineWidth(); 27933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (lineWidth != 1.0f) 28033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << lineWidth << " w "; 281d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CFX_GraphStateData::LineCap lineCap = pPageObj->m_GraphState.GetLineCap(); 282d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (lineCap != CFX_GraphStateData::LineCapButt) 283d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << static_cast<int>(lineCap) << " J "; 284d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CFX_GraphStateData::LineJoin lineJoin = pPageObj->m_GraphState.GetLineJoin(); 285d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (lineJoin != CFX_GraphStateData::LineJoinMiter) 286d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << static_cast<int>(lineJoin) << " j "; 28733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 28833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann GraphicsData graphD; 28933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann graphD.fillAlpha = pPageObj->m_GeneralState.GetFillAlpha(); 29033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann graphD.strokeAlpha = pPageObj->m_GeneralState.GetStrokeAlpha(); 291d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann graphD.blendType = pPageObj->m_GeneralState.GetBlendType(); 292d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (graphD.fillAlpha == 1.0f && graphD.strokeAlpha == 1.0f && 293d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann (graphD.blendType == FXDIB_BLEND_UNSUPPORTED || 294d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann graphD.blendType == FXDIB_BLEND_NORMAL)) { 29533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann return; 296d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 29733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 298d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString name; 299d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto it = m_pObjHolder->m_GraphicsMap.find(graphD); 300d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (it != m_pObjHolder->m_GraphicsMap.end()) { 30133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann name = it->second; 30233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } else { 30333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>(); 304d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (graphD.fillAlpha != 1.0f) 305d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Number>("ca", graphD.fillAlpha); 306d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 307d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (graphD.strokeAlpha != 1.0f) 308d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Number>("CA", graphD.strokeAlpha); 309d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 310d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (graphD.blendType != FXDIB_BLEND_UNSUPPORTED && 311d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann graphD.blendType != FXDIB_BLEND_NORMAL) { 312d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Name>("BM", 313d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pPageObj->m_GeneralState.GetBlendMode()); 314d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 31533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict)); 31633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann uint32_t dwObjNum = pDict->GetObjNum(); 31733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann name = RealizeResource(dwObjNum, "ExtGState"); 318d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_GraphicsMap[graphD] = name; 31933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 32033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << "/" << PDF_NameEncode(name) << " gs "; 32133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann} 32233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 323d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageContentGenerator::ProcessDefaultGraphics( 324d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::ostringstream* buf) { 325d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << "0 0 0 RG 0 0 0 rg 1 w " 326d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann << static_cast<int>(CFX_GraphStateData::LineCapButt) << " J " 327d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann << static_cast<int>(CFX_GraphStateData::LineJoinMiter) << " j\n"; 328d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann GraphicsData defaultGraphics; 329d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann defaultGraphics.fillAlpha = 1.0f; 330d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann defaultGraphics.strokeAlpha = 1.0f; 331d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann defaultGraphics.blendType = FXDIB_BLEND_NORMAL; 332d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto it = m_pObjHolder->m_GraphicsMap.find(defaultGraphics); 333d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString name; 334d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (it != m_pObjHolder->m_GraphicsMap.end()) { 335d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann name = it->second; 336d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } else { 337d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>(); 338d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Number>("ca", defaultGraphics.fillAlpha); 339d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Number>("CA", defaultGraphics.strokeAlpha); 340d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann gsDict->SetNewFor<CPDF_Name>("BM", "Normal"); 341d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict)); 342d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann uint32_t dwObjNum = pDict->GetObjNum(); 343d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann name = RealizeResource(dwObjNum, "ExtGState"); 344d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_GraphicsMap[defaultGraphics] = name; 345d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 346d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << "/" << PDF_NameEncode(name).c_str() << " gs "; 347d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 348d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 34933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// This method adds text to the buffer, BT begins the text object, ET ends it. 35033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Tm sets the text matrix (allows positioning and transforming text). 35133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Tf sets the font name (from Font in Resources) and font size. 35233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann// Tj sets the actual text, <####...> is used when specifying charcodes. 353d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageContentGenerator::ProcessText(std::ostringstream* buf, 35433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CPDF_TextObject* pTextObj) { 355d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ProcessGraphics(buf, pTextObj); 35633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << "BT " << pTextObj->GetTextMatrix() << " Tm "; 35733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CPDF_Font* pFont = pTextObj->GetFont(); 35833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann if (!pFont) 359d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pFont = CPDF_Font::GetStockFont(m_pDocument.Get(), "Helvetica"); 36033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann FontData fontD; 361d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (pFont->IsType1Font()) 362d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontD.type = "Type1"; 363d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else if (pFont->IsTrueTypeFont()) 364d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontD.type = "TrueType"; 365d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else if (pFont->IsCIDFont()) 366d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontD.type = "Type0"; 367d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else 368d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 36933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann fontD.baseFont = pFont->GetBaseFont(); 370d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto it = m_pObjHolder->m_FontsMap.find(fontD); 371d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString dictName; 372d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (it != m_pObjHolder->m_FontsMap.end()) { 37333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann dictName = it->second; 37433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } else { 375d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann uint32_t dwObjNum = pFont->GetFontDict()->GetObjNum(); 376d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!dwObjNum) { 377d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // In this case we assume it must be a standard font 378d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto fontDict = pdfium::MakeUnique<CPDF_Dictionary>(); 379d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontDict->SetNewFor<CPDF_Name>("Type", "Font"); 380d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontDict->SetNewFor<CPDF_Name>("Subtype", fontD.type); 381d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fontDict->SetNewFor<CPDF_Name>("BaseFont", fontD.baseFont); 382d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(fontDict)); 383d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann dwObjNum = pDict->GetObjNum(); 384d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 38533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann dictName = RealizeResource(dwObjNum, "Font"); 386d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pObjHolder->m_FontsMap[fontD] = dictName; 38733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 38833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann *buf << "/" << PDF_NameEncode(dictName) << " " << pTextObj->GetFontSize() 38933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann << " Tf "; 390d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString text; 391d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (uint32_t charcode : pTextObj->GetCharCodes()) { 392d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (charcode != CPDF_Font::kInvalidCharCode) 393d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pFont->AppendChar(&text, charcode); 39433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann } 395d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << PDF_EncodeString(text, true) << " Tj ET"; 396d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *buf << " Q\n"; 39733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann} 398