pdf.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: pdf.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:03:41  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: pdf.cpp,v 1000.2 2004/06/01 21:03:41 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software / database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software / database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Peter Meric
  35.  *
  36.  * File Description:
  37.  *   CPdf - Adobe PDF output
  38.  *
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <gui/print/pdf.hpp>
  42. #include <gui/print/vector_object.hpp>
  43. #include "pdf_object.hpp"
  44. #include "page_handler.hpp"
  45. #include "pdf_object_writer.hpp"
  46. BEGIN_NCBI_SCOPE
  47. CPdf::CPdf()
  48.     : m_ObjectWriter(new CPdfObjectWriter()),
  49.       m_PageDictionary(new CPdfDictionary())
  50. {
  51.     m_PageHandler.reset(new CPageHandler(*m_PageBuffers,
  52.                                          *m_ObjectWriter,
  53.                                          m_ObjIdGenerator
  54.                                         )
  55.                        );
  56. }
  57. CPdf::~CPdf()
  58. {
  59. }
  60. void CPdf::SetOptions(const CPrintOptions& options)
  61. {
  62.     CPostscript::SetOptions(options);
  63.     m_PageHandler->SetOptions(m_Options);
  64. }
  65. void CPdf::SetOutputStream(CNcbiOstream* ostream)
  66. {
  67.     CPostscript::SetOutputStream(ostream);
  68.     m_ObjectWriter->SetOutputStream(ostream);
  69. }
  70. void CPdf::BeginDocument()
  71. {
  72.     *m_Strm << "%PDF-1.3" << pdfeol;
  73.     // output binary characters in a comment to alert programs this is a binary file
  74.     *m_Strm << '%';
  75.     const unsigned int N = 10;
  76.     const char binchar[N] =
  77.     {
  78.         char(0x80), char(0x81), char(0x82), char(0x83), char(0x84),
  79.         char(0x85), char(0x86), char(0x87), char(0x88), char(0x89)
  80.     };
  81.     m_Strm->write(binchar, N);
  82.     *m_Strm << pdfeol;
  83.     // create objects
  84.     TPdfObjectRef info(new CPdfObject(m_ObjIdGenerator.NextId()));
  85.     m_Catalog.Reset(new CPdfObject(m_ObjIdGenerator.NextId()));
  86.     TPdfObjectRef outlines(new CPdfObject(m_ObjIdGenerator.NextId()));
  87.     // populate info
  88.     CPdfObject& _info = *info;
  89.     _info["Author"] = new CPdfString("National Center for Biotechnology Information");
  90.     _info["Creator"] = new CPdfString("NCBI Genome Workbench");
  91.     _info["Producer"] = new CPdfString("NCBI PDF Generator(meric@ncbi.nlm.nih.gov)");
  92.     _info["Title"] = new CPdfString(m_Options.GetTitle());
  93.     _info["CreationDate"] = new CPdfString("D:20030603123400 - 05'00'");
  94.     m_ObjectWriter->WriteObject(info);
  95.     // populate catalog
  96.     CPdfObject& catalog = *m_Catalog;
  97.     catalog["Type"] = new CPdfName("Catalog");
  98.     catalog["Outlines"] = new CPdfIndirectObj(outlines);
  99.     catalog["Pages"] = new CPdfIndirectObj(m_PageHandler->GetObject());
  100.     catalog["PageLayout"] = new CPdfName(m_Options.GetNumPages() > 1 ? "OneColumn" : "SinglePage");
  101.     catalog["PageMode"] = new CPdfName("UseNone");
  102.     catalog["ViewerPreferences"] = new CPdfObj("<</DisplayDocTitle true>>");
  103.     if (m_Options.GetPrintOutput()) {
  104.         // Add print action to Catalog dictionary
  105.         catalog["OpenAction"] = new CPdfObj("<</S/Named /N/Print>>");
  106.     }
  107.     catalog["PageLabels"] = new CPdfObj("<</Nums[0<</S/D/P(Panel )>>]>>");
  108.     m_ObjectWriter->WriteObject(m_Catalog);
  109.     // populate outlines
  110.     CPdfObject& ol = *outlines;
  111.     ol["Type"] = new CPdfName("Outlines");
  112.     ol["Count"] = new CPdfNumber(int(0));
  113.     m_ObjectWriter->WriteObject(outlines);
  114.     // populate trailer
  115.     m_Trailer.Reset(new CPdfTrailer());
  116.     CPdfTrailer& trailer = *m_Trailer;
  117.     trailer["Info"] = new CPdfIndirectObj(info);
  118.     trailer["Root"] = new CPdfIndirectObj(m_Catalog);
  119.     TPdfObjectRef f1(new CPdfObject(m_ObjIdGenerator.NextId()));
  120.     CPdfObject& _f1 = *f1;
  121.     _f1["Type"] = new CPdfName("Font");
  122.     _f1["Subtype"] = new CPdfName("Type1");
  123.     _f1["Name"] = new CPdfName("F1");
  124.     _f1["BaseFont"] = new CPdfName("Helvetica");
  125.     TPdfObjectRef f2(new CPdfObject(m_ObjIdGenerator.NextId()));
  126.     CPdfObject& _f2 = *f2;
  127.     _f2["Type"] = new CPdfName("Font");
  128.     _f2["Subtype"] = new CPdfName("Type1");
  129.     _f2["Name"] = new CPdfName("F2");
  130.     _f2["BaseFont"] = new CPdfName("Courier");
  131.     m_Fonts.Reset(new CPdfObject(m_ObjIdGenerator.NextId()));
  132.     CPdfObject& fonts = *m_Fonts;
  133.     fonts["F1"] = new CPdfIndirectObj(f1);
  134.     fonts["F2"] = new CPdfIndirectObj(f2);
  135.     m_PrintInEndDoc.push_back(f1);
  136.     m_PrintInEndDoc.push_back(f2);
  137.     m_PrintInEndDoc.push_back(m_Fonts);
  138.     CRef<CPdfDictionary> resources(new CPdfDictionary());
  139.     CPdfDictionary& res = *resources;
  140.     res["Font"] = new CPdfIndirectObj(m_Fonts);
  141.     (*m_PageDictionary)["Resources"] = resources;
  142. }
  143. void CPdf::BeginPage()
  144. {
  145.     //enum CPdfObject::EPdfObjectFormat type = CPdfObject::eUncompressed;
  146.     m_Content.Reset(new CPdfObject(m_ObjIdGenerator.NextId()));
  147. }
  148. void CPdf::EndPage()
  149. {
  150.     if ( !m_Content ) {
  151.         return;
  152.     }
  153.     m_PageHandler->SetContent(m_Content);
  154.     //m_PageCount += m_PageHandler->WritePages(m_PageCount + 1);
  155.     m_PageCount += m_PageHandler->WritePages();
  156. }
  157. void CPdf::PrintObject(const CObject* obj, CPrintState& state)
  158. {
  159.     //CRgbaColor& curr_nonstipple = state.m_NonStipple;
  160.     const CPVecText* txt = dynamic_cast < const CPVecText*>(obj);
  161.     if (txt) {
  162.         x_PrintText(txt, state);
  163.         return;
  164.     }
  165.     const CPVecPoint* point = dynamic_cast < const CPVecPoint*>(obj);
  166.     if (point) {
  167.         /*
  168.            const CRgbaColor& color = point->GetColor();
  169.            if ( !(color == curr_nonstipple) ) {
  170.            const float* c = color.GetColorArray();
  171.            color.PrintTo(*m_Strm, false);
  172.          *m_Strm << " rg" << endl;
  173.          curr_nonstipple = color;
  174.          }
  175.          *m_Strm << point << " P" << pdfeol;
  176.          */
  177.         //cerr << "point: " << *point << pdfeol;
  178.         return;
  179.     }
  180.     const CPVecLine* line = dynamic_cast < const CPVecLine*>(obj);
  181.     if (line) {
  182.         x_PrintLine(line, state);
  183.         return;
  184.     }
  185.     const CPVecPolygon* poly = dynamic_cast < const CPVecPolygon*>(obj);
  186.     if ( !poly ) {
  187.         return;
  188.     }
  189.     x_PrintPolygon(poly, state);
  190. }
  191. void CPdf::x_PrintText(const CPVecText* txt, CPrintState& state)
  192. {
  193.     CRgbaColor& curr_nonstipple = state.m_NonStipple;
  194.     CNcbiOstream& out = m_Content->GetWriteBuffer();
  195.     // set the text color
  196.     const CRgbaColor& color = txt->GetColor();
  197.     if ( !(color == curr_nonstipple) ) {
  198.         color.PrintTo(out, false);
  199.         out << " rg" << pdfeol;
  200.         curr_nonstipple = color;
  201.     }
  202.     // output the text, font and font size
  203.     out << "BT" << pdfeol;
  204.     out << "/F1 8 Tf" << pdfeol;
  205.     const float* p = txt->GetPosition();
  206.     out << p[0] << ' ' << p[1] << " Td" << pdfeol;
  207.     out << '(' << txt->GetText() << ") Tj" << pdfeol;
  208.     out << "ET" << pdfeol;
  209. }
  210. void CPdf::x_PrintLine(const CPVecLine* line, CPrintState& state)
  211. {
  212.     CRgbaColor& curr_stipple = state.m_Stipple;
  213.     const pair<CPVecPoint, CPVecPoint> p(line->GetPoints());
  214.     CNcbiOstream& out = m_Content->GetWriteBuffer();
  215.     const CRgbaColor& color = p.first.GetColor();
  216.     if ( !(color == curr_stipple) ) {
  217.         color.PrintTo(out, false);
  218.         out << " RG" << pdfeol;
  219.         curr_stipple = color;
  220.     }
  221.     // only print X, Y coordinates
  222.     p.first.PrintTo(out, CPVecPoint::eCoordXY);
  223.     out << " m ";
  224.     p.second.PrintTo(out, CPVecPoint::eCoordXY);
  225.     out << " l s" << pdfeol;
  226. }
  227. void CPdf::x_PrintPolygon(const CPVecPolygon* poly, CPrintState& state)
  228. {
  229.     CRgbaColor& curr_nonstipple = state.m_NonStipple;
  230.     if (poly->IsFlatColored()) {
  231.         CNcbiOstream& out = m_Content->GetWriteBuffer();
  232.         const CRgbaColor& color = (*poly->begin())->GetColor();
  233.         if ( !(color == curr_nonstipple) ) {
  234.             color.PrintTo(out, false);
  235.             out << " rg" << pdfeol;
  236.             curr_nonstipple = color;
  237.         }
  238.         bool first = true;
  239.         ITERATE(CPVecPolygon, it, *poly) {
  240.             const CPVecPoint* p = *it;
  241.             if ( !first ) {
  242.                 out << ' ';
  243.             }
  244.             p->PrintTo(out, CPVecPoint::eCoordXY); // only print X, Y coordinates
  245.             if (first) {
  246.                 out << " m";
  247.                 first = false;
  248.             } else {
  249.                 out << " l";
  250.             }
  251.         }
  252.         out << " h f" << pdfeol;
  253.     }
  254. }
  255. void CPdf::EndDocument()
  256. {
  257.     m_PageHandler->WritePageTree(m_PageDictionary);
  258.     ITERATE(vector<TPdfObjectRef>, it, m_PrintInEndDoc) {
  259.         m_ObjectWriter->WriteObject(*it);
  260.     }
  261.     // the number of objects is defined as one more than the highest
  262.     // object number
  263.     const unsigned int num_objects = m_ObjIdGenerator.NextId();
  264.     // write the cross reference
  265.     const CT_POS_TYPE xref_start = m_ObjectWriter->WriteXRef(num_objects);
  266.     // write the trailer
  267.     (*m_Trailer)["Size"] = new CPdfNumber(num_objects);
  268.     *m_Strm << *m_Trailer;
  269.     // output the location of the last xref section
  270.     *m_Strm << "startxref" << endl << (xref_start - CT_POS_TYPE(0)) << endl;
  271.     *m_Strm << "%%EOF" << pdfeol;
  272. }
  273. END_NCBI_SCOPE
  274. /*
  275.  * ===========================================================================
  276.  * $Log: pdf.cpp,v $
  277.  * Revision 1000.2  2004/06/01 21:03:41  gouriano
  278.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  279.  *
  280.  * Revision 1.17  2004/05/21 22:27:50  gorelenk
  281.  * Added PCH ncbi_pch.hpp
  282.  *
  283.  * Revision 1.16  2004/02/20 20:03:27  ucko
  284.  * Fix to compile with stricter implementations of CT_POS_TYPE
  285.  *
  286.  * Revision 1.15  2003/08/15 17:02:16  meric
  287.  * Updates include paths for print-related files from gui/utils to gui/print
  288.  *
  289.  * Revision 1.14  2003/07/16 21:36:25  meric
  290.  * Cast contants to char to avoid warnings regarding truncation of constants
  291.  *
  292.  * Revision 1.13  2003/07/16 20:03:13  meric
  293.  * Modify writing of binary char comment in at top of PDF file
  294.  *
  295.  * Revision 1.12  2003/06/25 18:02:51  meric
  296.  * Source rearrangement: move "private" headers into the src/ tree
  297.  *
  298.  * Revision 1.11  2003/06/24 22:34:27  meric
  299.  * modified char array to int array, casting to char upon use
  300.  *
  301.  * Revision 1.10  2003/06/24 21:46:52  meric
  302.  * Moved includes from pdf.hpp where practical
  303.  *
  304.  * Revision 1.9  2003/06/24 18:34:11  meric
  305.  * Write binary chars in comment at top of PDF file
  306.  * Prefix page numbers with "Panel "
  307.  *
  308.  * Revision 1.8  2003/06/18 17:25:38  meric
  309.  * Final phase of print reorg: remove dependence on gui/opengl and OpenGL
  310.  *
  311.  * Revision 1.7  2003/06/18 16:40:33  meric
  312.  * First phase of print reorg: remove dependence on gui/opengl and OpenGL
  313.  * except for class COpenGLPrintBuffer
  314.  *
  315.  * Revision 1.6  2003/06/17 20:07:39  meric
  316.  * Remove unused variables
  317.  *
  318.  * Revision 1.5  2003/06/17 19:33:01  meric
  319.  * Insert Print action in PDF document when print option set
  320.  *
  321.  * Revision 1.4  2003/06/16 21:46:07  meric
  322.  * Changed catalog options
  323.  *
  324.  * Revision 1.3  2003/06/16 21:15:25  meric
  325.  * Fixed %%PDF comment
  326.  *
  327.  * Revision 1.2  2003/06/16 12:44:52  dicuccio
  328.  * Clean-up after initial commit
  329.  *
  330.  * Revision 1.1  2003 / 06 / 13 18:13:56  meric
  331.  * Initial version
  332.  *
  333.  *
  334.  * ===========================================================================
  335.  */