EStatusCode IndirectObjectsReferenceRegistry::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID) { ObjectIDTypeList objects; inStateWriter->StartNewIndirectObject(inObjectID); DictionaryContext* myDictionary = inStateWriter->StartDictionary(); myDictionary->WriteKey("Type"); myDictionary->WriteNameValue("IndirectObjectsReferenceRegistry"); myDictionary->WriteKey("mObjectsWritesRegistry"); ObjectWriteInformationVector::iterator it = mObjectsWritesRegistry.begin(); inStateWriter->StartArray(); for(; it != mObjectsWritesRegistry.end(); ++it) { ObjectIDType objectWriteEntry = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID(); inStateWriter->WriteIndirectObjectReference(objectWriteEntry); objects.push_back(objectWriteEntry); } inStateWriter->EndArray(eTokenSeparatorEndLine); inStateWriter->EndDictionary(myDictionary); inStateWriter->EndIndirectObject(); ObjectIDTypeList::iterator itIDs = objects.begin(); it = mObjectsWritesRegistry.begin(); for(; it != mObjectsWritesRegistry.end(); ++it,++itIDs) { inStateWriter->StartNewIndirectObject(*itIDs); DictionaryContext* registryDictionary = inStateWriter->StartDictionary(); registryDictionary->WriteKey("Type"); registryDictionary->WriteNameValue("ObjectWriteInformation"); registryDictionary->WriteKey("mObjectWritten"); registryDictionary->WriteBooleanValue(it->mObjectWritten); if(it->mObjectWritten) { registryDictionary->WriteKey("mWritePosition"); registryDictionary->WriteIntegerValue(it->mWritePosition); } registryDictionary->WriteKey("mObjectReferenceType"); registryDictionary->WriteIntegerValue(it->mObjectReferenceType); inStateWriter->EndDictionary(registryDictionary); inStateWriter->EndIndirectObject(); } return PDFHummus::eSuccess; }
void ObjectsContext::EndPDFStream(PDFStream* inStream) { // finalize the stream write to end stream context and calculate length inStream->FinalizeStreamWrite(); if(inStream->GetExtentObjectID() == 0) { DictionaryContext* streamDictionaryContext = inStream->GetStreamDictionaryForDirectExtentStream(); // Length (write as a direct object) streamDictionaryContext->WriteKey(scLength); streamDictionaryContext->WriteIntegerValue(inStream->GetLength()); EndDictionary(streamDictionaryContext); // Write Stream Content WriteKeyword(scStream); inStream->FlushStreamContentForDirectExtentStream(); EndLine(); WriteKeyword(scEndStream); EndIndirectObject(); } else { WritePDFStreamEndWithoutExtent(); EndIndirectObject(); WritePDFStreamExtent(inStream); } }
EStatusCode TrueTypeEmbeddedFontWriter::WriteEmbeddedFont( FreeTypeFaceWrapper& inFontInfo, const UIntVector& inSubsetGlyphIDs, ObjectsContext* inObjectsContext, ObjectIDType& outEmbeddedFontObjectID) { MyStringBuf rawFontProgram; bool notEmbedded; EStatusCode status; do { status = CreateTrueTypeSubset(inFontInfo,inSubsetGlyphIDs,notEmbedded,rawFontProgram); if(status != PDFHummus::eSuccess) { TRACE_LOG("TrueTypeEmbeddedFontWriter::WriteEmbeddedFont, failed to write embedded font program"); break; } if(notEmbedded) { // can't embed. mark succesful, and go back empty outEmbeddedFontObjectID = 0; TRACE_LOG("TrueTypeEmbeddedFontWriter::WriteEmbeddedFont, font may not be embedded. so not embedding"); return PDFHummus::eSuccess; } outEmbeddedFontObjectID = inObjectsContext->StartNewIndirectObject(); DictionaryContext* fontProgramDictionaryContext = inObjectsContext->StartDictionary(); // Length1 (decompressed true type program length) fontProgramDictionaryContext->WriteKey(scLength1); fontProgramDictionaryContext->WriteIntegerValue(rawFontProgram.GetCurrentWritePosition()); rawFontProgram.pubseekoff(0,std::ios_base::beg); PDFStream* pdfStream = inObjectsContext->StartPDFStream(fontProgramDictionaryContext); // now copy the created font program to the output stream InputStringBufferStream fontProgramStream(&rawFontProgram); OutputStreamTraits streamCopier(pdfStream->GetWriteStream()); status = streamCopier.CopyToOutputStream(&fontProgramStream); if(status != PDFHummus::eSuccess) { TRACE_LOG("TrueTypeEmbeddedFontWriter::WriteEmbeddedFont, failed to copy font program into pdf stream"); break; } inObjectsContext->EndPDFStream(pdfStream); delete pdfStream; }while(false); return status; }
EStatusCode WrittenFontCFF::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID) { inStateWriter->StartNewIndirectObject(inObjectID); DictionaryContext* writtenFontDictionary = inStateWriter->StartDictionary(); writtenFontDictionary->WriteKey("Type"); writtenFontDictionary->WriteNameValue("WrittenFontCFF"); writtenFontDictionary->WriteKey("mAvailablePositionsCount"); writtenFontDictionary->WriteIntegerValue(mAvailablePositionsCount); writtenFontDictionary->WriteKey("mFreeList"); inStateWriter->StartArray(); UCharAndUCharList::iterator it = mFreeList.begin(); for(; it != mFreeList.end();++it) { inStateWriter->WriteInteger(it->first); inStateWriter->WriteInteger(it->second); } inStateWriter->EndArray(eTokenSeparatorEndLine); writtenFontDictionary->WriteKey("mAssignedPositions"); inStateWriter->StartArray(); for(int i=0;i<256;++i) inStateWriter->WriteInteger(mAssignedPositions[i]); inStateWriter->EndArray(eTokenSeparatorEndLine); writtenFontDictionary->WriteKey("mAssignedPositionsAvailable"); inStateWriter->StartArray(); for(int i=0;i<256;++i) inStateWriter->WriteBoolean(mAssignedPositionsAvailable[i]); inStateWriter->EndArray(eTokenSeparatorEndLine); writtenFontDictionary->WriteKey("mIsCID"); writtenFontDictionary->WriteBooleanValue(mIsCID); EStatusCode status = AbstractWrittenFont::WriteStateInDictionary(inStateWriter,writtenFontDictionary); if(PDFHummus::eSuccess == status) { inStateWriter->EndDictionary(writtenFontDictionary); inStateWriter->EndIndirectObject(); status = AbstractWrittenFont::WriteStateAfterDictionary(inStateWriter); } return status; }
void DescendentFontWriter::WriteCIDSystemInfo(ObjectIDType inCIDSystemInfoObjectID) { FT_Bool isCID; const char* registry; const char* ordering; FT_Int supplement; if(FT_Get_CID_Is_Internally_CID_Keyed(*mFontInfo,&isCID) != 0) isCID = false; if(isCID && FT_Get_CID_Registry_Ordering_Supplement(*mFontInfo,®istry,&ordering,&supplement) != 0) isCID = false; if(!isCID) { registry = scAdobe; ordering = scIdentity; supplement = 0; } mObjectsContext->StartNewIndirectObject(inCIDSystemInfoObjectID); DictionaryContext* systemInfoContext = mObjectsContext->StartDictionary(); // Registry systemInfoContext->WriteKey(scRegistry); systemInfoContext->WriteLiteralStringValue(registry); // Ordering systemInfoContext->WriteKey(scOrdering); systemInfoContext->WriteLiteralStringValue(ordering); // Supplement systemInfoContext->WriteKey(scSupplement); systemInfoContext->WriteIntegerValue(supplement); mObjectsContext->EndDictionary(systemInfoContext); mObjectsContext->EndIndirectObject(); }
void FontDescriptorWriter::WriteFontDescriptor( ObjectIDType inFontDescriptorObjectID, const string& inFontPostscriptName, FreeTypeFaceWrapper* inFontInfo, const UIntAndGlyphEncodingInfoVector& inEncodedGlyphs, ObjectsContext* inObjectsContext, IFontDescriptorHelper* inDescriptorHelper) { DictionaryContext* fontDescriptorDictionary; inObjectsContext->StartNewIndirectObject(inFontDescriptorObjectID); fontDescriptorDictionary = inObjectsContext->StartDictionary(); // FontName fontDescriptorDictionary->WriteKey(scFontName); fontDescriptorDictionary->WriteNameValue(inFontPostscriptName); // FontFamily fontDescriptorDictionary->WriteKey(scFontFamily); fontDescriptorDictionary->WriteLiteralStringValue((*inFontInfo)->family_name); // FontStretch fontDescriptorDictionary->WriteKey(scFontStretch); fontDescriptorDictionary->WriteNameValue(scFontStretchLabels[inFontInfo->GetFontStretch()]); // FontWeight fontDescriptorDictionary->WriteKey(scFontWeight); fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetFontWeight()); // FontBBox fontDescriptorDictionary->WriteKey(scFontBBox); fontDescriptorDictionary->WriteRectangleValue( PDFRectangle( inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.xMin), inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.yMin), inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.xMax), inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.yMax))); // ItalicAngle fontDescriptorDictionary->WriteKey(scItalicAngle); fontDescriptorDictionary->WriteDoubleValue(inFontInfo->GetItalicAngle()); // Ascent fontDescriptorDictionary->WriteKey(scAscent); fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetInPDFMeasurements((*inFontInfo)->ascender)); // Descent fontDescriptorDictionary->WriteKey(scDescent); fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetInPDFMeasurements((*inFontInfo)->descender)); // CapHeight BoolAndFTShort result = inFontInfo->GetCapHeight(); if(result.first) { fontDescriptorDictionary->WriteKey(scCapHeight); fontDescriptorDictionary->WriteIntegerValue(result.second); } // XHeight result = inFontInfo->GetxHeight(); if(result.first) { fontDescriptorDictionary->WriteKey(scXHeight); fontDescriptorDictionary->WriteIntegerValue(result.second); } // StemV fontDescriptorDictionary->WriteKey(scStemV); fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetStemV()); // ChartSet writing (variants according to ANSI/CID) inDescriptorHelper->WriteCharSet(fontDescriptorDictionary,inObjectsContext,inFontInfo,inEncodedGlyphs); // Flags fontDescriptorDictionary->WriteKey(scFlags); fontDescriptorDictionary->WriteIntegerValue(CalculateFlags(inFontInfo,inEncodedGlyphs)); // font embedding [may not happen due to font embedding restrictions. helper is supposed to avoid reference as well] inDescriptorHelper->WriteFontFileReference(fontDescriptorDictionary,inObjectsContext); inObjectsContext->EndDictionary(fontDescriptorDictionary); inObjectsContext->EndIndirectObject(); }
EStatusCode PDFWriter::Shutdown(const std::string& inStateFilePath) { EStatusCode status; do { StateWriter writer; status = writer.Start(inStateFilePath); if(status != eSuccess) { TRACE_LOG("PDFWriter::Shutdown, cant start state writing"); break; } ObjectIDType rootObjectID = writer.GetObjectsWriter()->StartNewIndirectObject(); DictionaryContext* pdfWriterDictionary = writer.GetObjectsWriter()->StartDictionary(); pdfWriterDictionary->WriteKey("Type"); pdfWriterDictionary->WriteNameValue("PDFWriter"); ObjectIDType objectsContextID = writer.GetObjectsWriter()->GetInDirectObjectsRegistry().AllocateNewObjectID(); ObjectIDType DocumentContextID = writer.GetObjectsWriter()->GetInDirectObjectsRegistry().AllocateNewObjectID(); pdfWriterDictionary->WriteKey("mObjectsContext"); pdfWriterDictionary->WriteNewObjectReferenceValue(objectsContextID); pdfWriterDictionary->WriteKey("mDocumentContext"); pdfWriterDictionary->WriteNewObjectReferenceValue(DocumentContextID); pdfWriterDictionary->WriteKey("mIsModified"); pdfWriterDictionary->WriteBooleanValue(mIsModified); if(mIsModified) { pdfWriterDictionary->WriteKey("mModifiedFileVersion"); pdfWriterDictionary->WriteIntegerValue(mModifiedFileVersion); } writer.GetObjectsWriter()->EndDictionary(pdfWriterDictionary); writer.GetObjectsWriter()->EndIndirectObject(); writer.SetRootObject(rootObjectID); status = mObjectsContext.WriteState(writer.GetObjectsWriter(),objectsContextID); if(status != eSuccess) break; status = mDocumentContext.WriteState(writer.GetObjectsWriter(),DocumentContextID); if(status != eSuccess) break; status = writer.Finish(); if(status != eSuccess) { TRACE_LOG("PDFWriter::Shutdown, cant finish state writing"); } }while(false); if(status != eSuccess) { mOutputFile.CloseFile(); TRACE_LOG("PDFWriter::Shutdown, Could not end PDF"); } else status = mOutputFile.CloseFile(); //ReleaseLog(); return status; }