page_handler.cpp
来自「ncbi源码」· C++ 代码 · 共 774 行 · 第 1/2 页
CPP
774 行
/* * =========================================================================== * PRODUCTION $Log: page_handler.cpp,v $ * PRODUCTION Revision 1000.1 2004/06/01 21:03:36 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17 * PRODUCTION * =========================================================================== *//* $Id: page_handler.cpp,v 1000.1 2004/06/01 21:03:36 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software / database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software / database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Peter Meric * * File Description: * CPageHandler - manage pages in a PDF document */#include <ncbi_pch.hpp>#include <gui/print/print_options.hpp>#include <gui/print/print_utils.hpp>#include <gui/utils/id_generator.hpp>#include "page_handler.hpp"#include "pdf_object.hpp"#include "pdf_object_writer.hpp"#include "pdf_obj.hpp"#include "panel_grid.hpp"BEGIN_NCBI_SCOPECPageHandler::CPageHandler(const CPageBuffers& buffers, CPdfObjectWriter& obj_writer, CIdGenerator& objid_gen ): m_ObjWriter(&obj_writer), m_ObjIdGenerator(&objid_gen), m_PageTreeRootObj(new CPdfObject(m_ObjIdGenerator->NextId())), m_PageBuffers(&buffers){}CPageHandler::~CPageHandler(){}CPageHandler::TPdfObjectRef CPageHandler::GetObject(void) const{ return m_PageTreeRootObj;}void CPageHandler::SetOptions(const CPrintOptions& options){ m_Options = &options; const unsigned int pg_wide = m_Options->GetPagesWide(); const unsigned int pg_tall = m_Options->GetPagesTall(); m_PanelGrid.Reset(new CPanelGrid(*m_ObjIdGenerator, pg_wide, pg_tall));}void CPageHandler::x_Update(const CRef<CPdfDictionary>& pagedict){ x_UpdatePageTreeRoot(pagedict);}void CPageHandler::x_UpdatePageTreeRoot(const CRef<CPdfDictionary>& pagedict){ CPdfObject& root = *m_PageTreeRootObj; root["Type"] = new CPdfName("Pages"); root["Count"] = new CPdfNumber(int(m_Pages.size())); root["Rotate"] = new CPdfNumber(int(m_Options->GetPageOrientation())); CRef<CPdfArray> kids(new CPdfArray()); ITERATE(vector<TPdfObjectRef>, it, m_Pages) { kids->GetArray().push_back(CRef<CPdfObj>(new CPdfIndirectObj(*it))); } root["Kids"] = kids; CRef<CPdfArray> mediabox(new CPdfArray()); CPdfArray::TArray& mbarr = mediabox->GetArray(); mbarr.push_back(CRef<CPdfObj>(new CPdfNumber(int(0)))); mbarr.push_back(CRef<CPdfObj>(new CPdfNumber(int(0)))); mbarr.push_back(CRef<CPdfObj>(new CPdfNumber(int(m_Options->GetMediaWidth())))); mbarr.push_back(CRef<CPdfObj>(new CPdfNumber(int(m_Options->GetMediaHeight())))); root["MediaBox"] = mediabox; /* root << " %/TrimBox [ " << xs.first << ' ' << ys.first << ' ' << xs.second << ' ' << ys.second << " ]" << endl; */ CRef<CPdfArray> procset(new CPdfArray()); CPdfArray::TArray& pset = procset->GetArray(); pset.push_back(CRef<CPdfObj>(new CPdfObj("/PDF"))); pset.push_back(CRef<CPdfObj>(new CPdfObj("/Text"))); //res["ProcSet"] = procset; CPdfDictionary& dict = root.GetDictionary(); dict.Add(pagedict); CRef<CPdfObj>& res = dict["Resources"]; if ( !res ) { CRef<CPdfDictionary> resources(new CPdfDictionary()); (*resources)["ProcSet"] = procset; res = resources; } else { CRef<CPdfDictionary> _res(dynamic_cast < CPdfDictionary*>(res.GetPointer())); (*_res)["ProcSet"] = procset; }}CPageHandler::TPdfObjectRef CPageHandler::x_CreateHeaderFooter(void){ TPdfObjectRef hf_obj; const string header(m_Options->GetHeader()); const string footer(m_Options->GetFooter()); const bool has_header = header.length() > 0; const bool has_footer = footer.length() > 0; if (has_header || has_footer) { hf_obj.Reset(new CPdfObject(m_ObjIdGenerator->NextId())); CPdfObject& obj = *hf_obj; obj << "0 0 m n" << pdfbrk; obj << "0 0 0 rg" << pdfbrk; if (has_header) { obj << "BT" << pdfbrk; const TPdfUnit font_size = 8; obj << "/F1 " << font_size << " Tf" << pdfbrk; const TPdfUnit str_w = font_size * header.length(); obj << (m_Options->GetMediaWidth() - str_w) / 2 << ' ' << m_Options->GetMediaHeight() - m_Options->GetHeaderOffset() - font_size << " Td" << pdfbrk; obj << CPdfString(header) << "Tj" << pdfbrk; obj << "ET" << pdfbrk; } if (has_footer) { obj << "BT" << pdfbrk; const TPdfUnit font_size = 8; obj << "/F2 " << font_size << " Tf" << pdfbrk; const TPdfUnit str_w = font_size * footer.length(); obj << (m_Options->GetMediaWidth() - str_w) / 2 << ' ' << m_Options->GetFooterOffset() << " Td" << pdfbrk; obj << CPdfString(footer) << "Tj" << pdfbrk; obj << "ET" << pdfbrk; } } return hf_obj;}CPageHandler::TPdfObjectRef CPageHandler::x_CreatePrintersMarks(const CRef<CPanel>& panel){ TPdfObjectRef pmarks_obj(new CPdfObject(m_ObjIdGenerator->NextId())); CPdfObject& pmarks = *pmarks_obj; // create printer's marks, page alignment etc pmarks << "0 0 m n" << pdfbrk; pmarks << "0 0 0 rg" << pdfbrk; pmarks << "BT" << pdfbrk; pmarks << CPdfName("F1") << ' ' << CPdfNumber(8) << " Tf" << pdfbrk; // // output current panel number // const string pstr("Panel " + NStr::IntToString(panel->m_PanelNum) + " of " + NStr::IntToString(m_Options->GetNumPages()) ); const string::size_type pstr_len(pstr.length() * 8); pmarks << CPdfNumber(m_Options->GetMediaWidth() - pstr_len - 30) << ' ' << CPdfNumber(m_Options->GetMediaHeight() - 20) << " Td" << pdfbrk; pmarks << CPdfString(pstr) << "Tj" << pdfbrk; pmarks << "ET" << pdfbrk; // // corner crop marks // x_DrawCornerCropMarks(pmarks, 8); // // print neighbour pointers (links) // const CPanelGrid::SNeighbours n = m_PanelGrid->GetNeighbours(panel->m_Col, panel->m_Row); TPdfObjectRef panelref = panel->m_Panel; CPdfObject& panelobj = *panelref; CRef<CPdfArray> annots(new CPdfArray()); const TPdfUnit link_margin = 30; // draw top if (n.top) { const TPdfUnit x = m_Options->GetMediaWidth() / 2; const TPdfUnit y = m_Options->GetMediaHeight() - link_margin; annots->Add(x_DrawPanelLink(pmarks, n.top->m_PanelNum, x, y)); } // draw bottom if (n.bottom) { const TPdfUnit x = m_Options->GetMediaWidth() / 2; const TPdfUnit y = link_margin - 10; annots->Add(x_DrawPanelLink(pmarks, n.bottom->m_PanelNum, x, y, eBottom)); } // draw left if (n.left) { const TPdfUnit x = link_margin; const TPdfUnit y = m_Options->GetMediaHeight() / 2; annots->Add(x_DrawPanelLink(pmarks, n.left->m_PanelNum, x, y, eLeft)); } // draw right if (n.right) { const TPdfUnit x = m_Options->GetMediaWidth() - link_margin; const TPdfUnit y = m_Options->GetMediaHeight() / 2; annots->Add(x_DrawPanelLink(pmarks, n.right->m_PanelNum, x, y, eRight)); } if (annots->GetArray().size() > 0) { panelobj["Annots"] = annots; } return pmarks_obj;}void CPageHandler::x_DrawCornerCropMarks(CPdfObject& obj, TPdfUnit margin) const{ const TPdfUnit cmark_len = 20; const TPdfUnit cm_l = m_Options->GetMarginLeft(); const TPdfUnit cm_lm = cm_l - margin; const TPdfUnit cm_t = m_Options->GetMediaHeight() - m_Options->GetMarginTop(); const TPdfUnit cm_tm = cm_t + margin; const TPdfUnit cm_r = m_Options->GetMediaWidth() - m_Options->GetMarginRight(); const TPdfUnit cm_rm = cm_r + margin; const TPdfUnit cm_b = m_Options->GetMarginBottom(); const TPdfUnit cm_bm = cm_b - margin; // top left obj << cm_lm - cmark_len << ' ' << cm_t << " m " << cm_lm << ' ' << cm_t << " l s" << pdfbrk; obj << cm_l << ' ' << cm_tm + cmark_len << " m " << cm_l << ' ' << cm_tm << " l s" << pdfbrk; // top right obj << cm_rm + cmark_len << ' ' << cm_t << " m " << cm_rm << ' ' << cm_t << " l s" << pdfbrk; obj << cm_r << ' ' << cm_tm + cmark_len << " m " << cm_r << ' ' << cm_tm << " l s" << pdfbrk; // bottom left obj << cm_lm - cmark_len << ' ' << cm_b << " m " << cm_lm << ' ' << cm_b << " l s" << pdfbrk; obj << cm_l << ' ' << cm_bm - cmark_len << " m " << cm_l << ' ' << cm_bm << " l s" << pdfbrk; // bottom right obj << cm_rm + cmark_len << ' ' << cm_b << " m " << cm_rm << ' ' << cm_b << " l s" << pdfbrk; obj << cm_r << ' ' << cm_bm - cmark_len << " m " << cm_r << ' ' << cm_bm << " l s" << pdfbrk;}CRef<CPdfArray> CPageHandler::x_DrawPanelLink(CPdfObject& obj, unsigned int panel_num, TPdfUnit x, TPdfUnit y, enum Side side ) const{ const TPdfUnit link_width = 44; const TPdfUnit link_width2 = link_width / 2; const TPdfUnit fnt_h = 8; TPdfUnit xlate_x; TPdfUnit xlate_y; int rot; switch (side) { case (eTop): case (eBottom): rot = (side == eTop) ? 0 : 180; xlate_x = x - link_width2; xlate_y = y; break; case (eLeft): rot = 90; xlate_x = x; xlate_y = y - link_width2; break; case (eRight): rot = 270; xlate_x = x; xlate_y = y + link_width2; break; } obj << CPdfObj("q") << pdfbrk; obj << CPdfTranslate(xlate_x, xlate_y) << pdfbrk; if (side == eLeft || side == eRight) { obj << CPdfRotate(rot) << pdfbrk; rot = 0; // don't rotate again } obj << "BT" << pdfbrk; //obj << CPdfName("F1") << ' ' << CPdfNumber(8) << " Tf" << pdfbrk; const string txt("Panel " + NStr::IntToString(panel_num)); obj << "4 1 Td" << pdfbrk; obj << CPdfString(txt) << "Tj" << pdfbrk; obj << "ET" << pdfbrk; if (rot != 0) { obj << CPdfRotate(rot) << pdfbrk; } if (side == eBottom) { // if upside down, then offset the triangles according to the text obj << CPdfTranslate(-int(link_width), -int(fnt_h)) << pdfbrk; } obj << CPdfObj("0.416 0.549 0.792 rg") << pdfbrk; const TPdfUnit _margin = 3; const TPdfUnit tri_w = 16; const TPdfUnit tri_h = 8; x_DrawTriangle(obj, link_width / 2, fnt_h + _margin, tri_w, tri_h); CRef<CPdfArray> annots(new CPdfArray()); CRef<CPdfDictionary> link_annot(new CPdfDictionary()); CPdfDictionary& link = *link_annot; link["Type"] = new CPdfName("Annot"); link["Subtype"] = new CPdfName("Link"); string _x1, _x2, _y1, _y2; switch (side) { case (eTop): case (eBottom): _x1 = NStr::IntToString(int(x - link_width2 - _margin)); _y1 = NStr::IntToString(int(y - _margin)); _x2 = NStr::IntToString(int(x + link_width2 + _margin)); _y2 = NStr::IntToString(int(y + fnt_h + _margin)); break; case (eLeft): case (eRight): { const bool left = (side == eLeft); _x1 = NStr::IntToString(int(x + (left ? 1 : -1) * _margin)); _y1 = NStr::IntToString(int(y + link_width2 + _margin)); _x2 = NStr::IntToString(int(x + (left ? -1 : 1) * (fnt_h + _margin))); _y2 = NStr::IntToString(int(y - link_width2 - _margin));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?