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(); }
EStatusCodeAndObjectIDType PDFCommentWriter::WriteCommentsTree(PDFComment* inComment) { EStatusCodeAndObjectIDType result; ObjectIDType repliedTo = 0; // if already written, return PDFCommentToObjectIDTypeMap::iterator it = mCommentsForNextPage.find(inComment); if(it != mCommentsForNextPage.end()) { result.first = eSuccess; result.second = it->second; return result; } // if has a referred comment, write it first if(inComment->ReplyTo != NULL) { EStatusCodeAndObjectIDType repliedtoResult = WriteCommentsTree(inComment->ReplyTo); if(repliedtoResult.first != eSuccess) { result.first = eFailure; result.second = 0; return result; } else repliedTo = repliedtoResult.second; } do { ObjectsContext& objectsContext = mPDFWriter->GetObjectsContext(); // Start new InDirect object for annotation dictionary result.second = objectsContext.StartNewIndirectObject(); DictionaryContext* dictionaryContext = objectsContext.StartDictionary(); // Type dictionaryContext->WriteKey("Type"); dictionaryContext->WriteNameValue("Annot"); // SubType dictionaryContext->WriteKey("Subtype"); dictionaryContext->WriteNameValue("Text"); // Rect dictionaryContext->WriteKey("Rect"); dictionaryContext->WriteRectangleValue( PDFRectangle(inComment->FrameBoundings[0], inComment->FrameBoundings[1], inComment->FrameBoundings[2], inComment->FrameBoundings[3])); // Contents dictionaryContext->WriteKey("Contents"); dictionaryContext->WriteLiteralStringValue(PDFTextString(inComment->Text).ToString()); // C (color) dictionaryContext->WriteKey("C"); objectsContext.StartArray(); if(inComment->Color.UseCMYK) { objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[0]/255); objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[1]/255); objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[2]/255); objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[3]/255); } else { objectsContext.WriteDouble((double)inComment->Color.RGBComponents[0]/255); objectsContext.WriteDouble((double)inComment->Color.RGBComponents[1]/255); objectsContext.WriteDouble((double)inComment->Color.RGBComponents[2]/255); } objectsContext.EndArray(eTokenSeparatorEndLine); // T dictionaryContext->WriteKey("T"); dictionaryContext->WriteLiteralStringValue(PDFTextString(inComment->CommentatorName).ToString()); // M dictionaryContext->WriteKey("M"); dictionaryContext->WriteLiteralStringValue(inComment->Time.ToString()); if(inComment->ReplyTo != NULL) { // IRT dictionaryContext->WriteKey("IRT"); dictionaryContext->WriteObjectReferenceValue(repliedTo); // RT (we're doing always "reply" at this point, being a reply to comment dictionaryContext->WriteKey("RT"); dictionaryContext->WriteNameValue("R"); } // Open (we'll have them all closed to begin with) dictionaryContext->WriteKey("Open"); dictionaryContext->WriteBooleanValue(false); // Name dictionaryContext->WriteKey("Name"); dictionaryContext->WriteNameValue("Comment"); if(objectsContext.EndDictionary(dictionaryContext) != eSuccess) { result.first = eFailure; TRACE_LOG("PDFCommentWriter::WriteCommentsTree, Exception in ending comment dictionary"); break; } objectsContext.EndIndirectObject(); mCommentsForNextPage.insert(PDFCommentToObjectIDTypeMap::value_type(inComment,result.second)); result.first = eSuccess; }while(false); return result; }