EStatusCode ObjectsContext::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID) { EStatusCode status; do { inStateWriter->StartNewIndirectObject(inObjectID); ObjectIDType referencesRegistryObjectID = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID(); ObjectIDType subsetFontsNameSequanceID = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID(); DictionaryContext* objectsContextDict = inStateWriter->StartDictionary(); objectsContextDict->WriteKey("Type"); objectsContextDict->WriteNameValue("ObjectsContext"); objectsContextDict->WriteKey("mReferencesRegistry"); objectsContextDict->WriteNewObjectReferenceValue(referencesRegistryObjectID); objectsContextDict->WriteKey("mCompressStreams"); objectsContextDict->WriteBooleanValue(mCompressStreams); objectsContextDict->WriteKey("mSubsetFontsNamesSequance"); objectsContextDict->WriteNewObjectReferenceValue(subsetFontsNameSequanceID); inStateWriter->EndDictionary(objectsContextDict); inStateWriter->EndIndirectObject(); status = mReferencesRegistry.WriteState(inStateWriter,referencesRegistryObjectID); if(status != PDFHummus::eSuccess) break; // write subset fonts names sequance inStateWriter->StartNewIndirectObject(subsetFontsNameSequanceID); DictionaryContext* sequanceDict = inStateWriter->StartDictionary(); sequanceDict->WriteKey("Type"); sequanceDict->WriteNameValue("UppercaseSequance"); sequanceDict->WriteKey("mSequanceString"); sequanceDict->WriteLiteralStringValue(mSubsetFontsNamesSequance.ToString()); inStateWriter->EndDictionary(sequanceDict); inStateWriter->EndIndirectObject(); }while(false); return status; }
PDFStream* ObjectsContext::StartUnfilteredPDFStream(DictionaryContext* inStreamDictionary) { // write stream header and allocate PDF stream. // PDF stream will take care of maintaining state for the stream till writing is finished // Write the stream header // Write Stream Dictionary (note that inStreamDictionary is optionally used) DictionaryContext* streamDictionaryContext = (NULL == inStreamDictionary ? StartDictionary() : inStreamDictionary); // Length (write as an indirect object) streamDictionaryContext->WriteKey(scLength); ObjectIDType lengthObjectID = mReferencesRegistry.AllocateNewObjectID(); streamDictionaryContext->WriteNewObjectReferenceValue(lengthObjectID); EndDictionary(streamDictionaryContext); // Write Stream Content WriteKeyword(scStream); // now begin the stream itself PDFStream* result = new PDFStream(false,mOutputStream, mEncryptionHelper,lengthObjectID,NULL); // break encryption, if any, when writing a stream, cause if encryption is desired, only top level elements should be encrypted. hence - the stream itself is, but its contents do not re-encrypt if(mEncryptionHelper) mEncryptionHelper->PauseEncryption(); return result; }
EStatusCode PDFUsedFont::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID) { inStateWriter->StartNewIndirectObject(inObjectID); DictionaryContext* pdfUsedFontObject = inStateWriter->StartDictionary(); pdfUsedFontObject->WriteKey("Type"); pdfUsedFontObject->WriteNameValue("PDFUsedFont"); ObjectIDType writtenFontObject; if(mWrittenFont) { writtenFontObject = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID(); pdfUsedFontObject->WriteKey("mWrittenFont"); pdfUsedFontObject->WriteNewObjectReferenceValue(writtenFontObject); } inStateWriter->EndDictionary(pdfUsedFontObject); inStateWriter->EndIndirectObject(); if(mWrittenFont) mWrittenFont->WriteState(inStateWriter,writtenFontObject); return PDFHummus::eSuccess; }
PDFStream* ObjectsContext::StartPDFStream(DictionaryContext* inStreamDictionary,bool inForceDirectExtentObject) { // write stream header and allocate PDF stream. // PDF stream will take care of maintaining state for the stream till writing is finished // Write the stream header // Write Stream Dictionary (note that inStreamDictionary is optionally used) DictionaryContext* streamDictionaryContext = (NULL == inStreamDictionary ? StartDictionary() : inStreamDictionary); // Compression (if necessary) if(mCompressStreams) { streamDictionaryContext->WriteKey(scFilter); streamDictionaryContext->WriteNameValue(scFlateDecode); } PDFStream* result = NULL; if(!inForceDirectExtentObject) { // Length (write as an indirect object) streamDictionaryContext->WriteKey(scLength); ObjectIDType lengthObjectID = mReferencesRegistry.AllocateNewObjectID(); streamDictionaryContext->WriteNewObjectReferenceValue(lengthObjectID); EndDictionary(streamDictionaryContext); // Write Stream Content WriteKeyword(scStream); result = new PDFStream(mCompressStreams,mOutputStream, mEncryptionHelper,lengthObjectID,mExtender); } else result = new PDFStream(mCompressStreams,mOutputStream, mEncryptionHelper,streamDictionaryContext,mExtender); // break encryption, if any, when writing a stream, cause if encryption is desired, only top level elements should be encrypted. hence - the stream itself is, but its contents do not re-encrypt if (mEncryptionHelper) mEncryptionHelper->PauseEncryption(); return result; }
PDFStream* ObjectsContext::StartUnfilteredPDFStream(DictionaryContext* inStreamDictionary) { // write stream header and allocate PDF stream. // PDF stream will take care of maintaining state for the stream till writing is finished // Write the stream header // Write Stream Dictionary (note that inStreamDictionary is optionally used) DictionaryContext* streamDictionaryContext = (NULL == inStreamDictionary ? StartDictionary() : inStreamDictionary); // Length (write as an indirect object) streamDictionaryContext->WriteKey(scLength); ObjectIDType lengthObjectID = mReferencesRegistry.AllocateNewObjectID(); streamDictionaryContext->WriteNewObjectReferenceValue(lengthObjectID); EndDictionary(streamDictionaryContext); // Write Stream Content WriteKeyword(scStream); // now begin the stream itself return new PDFStream(false,mOutputStream,lengthObjectID,NULL); }
PDFStream* ObjectsContext::StartPDFStream(DictionaryContext* inStreamDictionary,bool inForceDirectExtentObject) { // write stream header and allocate PDF stream. // PDF stream will take care of maintaining state for the stream till writing is finished // Write the stream header // Write Stream Dictionary (note that inStreamDictionary is optionally used) DictionaryContext* streamDictionaryContext = (NULL == inStreamDictionary ? StartDictionary() : inStreamDictionary); // Compression (if necessary) if(mCompressStreams) { streamDictionaryContext->WriteKey(scFilter); streamDictionaryContext->WriteNameValue(scFlateDecode); } if(!inForceDirectExtentObject) { // Length (write as an indirect object) streamDictionaryContext->WriteKey(scLength); ObjectIDType lengthObjectID = mReferencesRegistry.AllocateNewObjectID(); streamDictionaryContext->WriteNewObjectReferenceValue(lengthObjectID); EndDictionary(streamDictionaryContext); // Write Stream Content WriteKeyword(scStream); return new PDFStream(mCompressStreams,mOutputStream,lengthObjectID,mExtender); } else return new PDFStream(mCompressStreams,mOutputStream,streamDictionaryContext,mExtender); }
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; }
EStatusCode CIDFontWriter::WriteFont(FreeTypeFaceWrapper& inFontInfo, WrittenFontRepresentation* inFontOccurrence, ObjectsContext* inObjectsContext, IDescendentFontWriter* inDescendentFontWriter) { EStatusCode status = PDFHummus::eSuccess; inObjectsContext->StartNewIndirectObject(inFontOccurrence->mWrittenObjectID); mFontInfo = &inFontInfo; mFontOccurrence = inFontOccurrence; mObjectsContext = inObjectsContext; do { DictionaryContext* fontContext = inObjectsContext->StartDictionary(); // Type fontContext->WriteKey(scType); fontContext->WriteNameValue(scFont); // SubType fontContext->WriteKey(scSubtype); fontContext->WriteNameValue(scType0); // BaseFont fontContext->WriteKey(scBaseFont); const char* postscriptFontName = FT_Get_Postscript_Name(inFontInfo); if(!postscriptFontName) { TRACE_LOG("CIDFontWriter::WriteFont, unexpected failure. no postscript font name for font"); status = PDFHummus::eFailure; break; } std::string subsetFontName = inObjectsContext->GenerateSubsetFontPrefix() + scPlus + postscriptFontName; fontContext->WriteNameValue(subsetFontName); WriteEncoding(fontContext); // DescendantFonts ObjectIDType descendantFontID = mObjectsContext->GetInDirectObjectsRegistry().AllocateNewObjectID(); fontContext->WriteKey(scDescendantFonts); mObjectsContext->StartArray(); mObjectsContext->WriteNewIndirectObjectReference(descendantFontID); mObjectsContext->EndArray(eTokenSeparatorEndLine); CalculateCharacterEncodingArray(); // put the charachter in the order of encoding, for the ToUnicode map // ToUnicode fontContext->WriteKey(scToUnicode); ObjectIDType toUnicodeMapObjectID = mObjectsContext->GetInDirectObjectsRegistry().AllocateNewObjectID(); fontContext->WriteNewObjectReferenceValue(toUnicodeMapObjectID); status = inObjectsContext->EndDictionary(fontContext); if(status != PDFHummus::eSuccess) { TRACE_LOG("CIDFontWriter::WriteFont, unexpected failure. Failed to end dictionary in font write."); break; } inObjectsContext->EndIndirectObject(); WriteToUnicodeMap(toUnicodeMapObjectID); // Write the descendant font status = inDescendentFontWriter->WriteFont(descendantFontID,subsetFontName,*mFontInfo,mCharactersVector,mObjectsContext); } while(false); return status; }