/// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "page.h" #include "fileerrors.h" #include "loader.h" #include "document.h" /// \todo Remove if/when possible #include "util/stringutil.h" #include "util/warning.h" #include #ifdef PNUM_HACK namespace { struct PNumHack { //page numbering hack static const int xpos=40; //points static const int ypos=40; //points static std::string font; static const int font_size=10; } pnum_hack; // std::string PNumHack::font="Palatino-Italic"; std::string PNumHack::font="URWPalladioL-Ital"; } #endif template<> std::string TypeInfo::name() { return "Guide orientation"; } std::istream& operator >> (std::istream& in, Guide::Orientation& o) { char ch; if(in.get(ch)) switch(ch) { case 'h': o = Guide::HORIZONTAL; break; case 'v': o = Guide::VERTICAL; break; default: in.setstate(in.badbit); } return in; } std::ostream& operator << (std::ostream& out, const Guide::Orientation& o) { return out << (o == Guide::HORIZONTAL ? 'h' : 'v'); } Guide::Guide(const ElementWrap& xml) : orientation(xml.get_attribute("orientation", VERTICAL)), position(xml.get_required_attribute("pos")) {} int Page::get_page_num() const { return document.get_page_num_of_page(this); } Page::Page(Document& d) :Group(0, ""), document(d) {} Page::Page(const ElementWrap& xml, Document& d) :Group(0, ""), document(d) { // Note: Default name for a Page is "", which differs from Group. name = xml.get_attribute("name"); const xmlpp::Node::NodeList children = xml.element().get_children(); for(xmlpp::Node::NodeList::const_iterator i = children.begin(); i != children.end(); i++) { if(const xmlpp::Element* elem = dynamic_cast(*i)) { const std::string name = elem->get_name(); if(name == "frame") { add(load(ElementWrap(xml, *elem), this)); } else if(name == "guide") { guides.push_back(Guide(ElementWrap(xml, *elem))); } else { warning << "Unknown node <" << name << "> ignored in ." << std::endl; } } } /// \todo Maybe throw an error if *i was a text node (but not if it was a /// comment) ... } Page::~Page() {} xmlpp::Element *Page::save(xmlpp::Element& parent_node, const FileContext &context) { xmlpp::Element *node = parent_node.add_child("page"); for(Guides::const_iterator i = guides.begin(); i != guides.end(); i++) { xmlpp::Element *guide_node = node->add_child("guide"); guide_node->set_attribute("orientation", tostr(i->orientation)); guide_node->set_attribute("pos", tostr(i->position)); } save_childs(*node, context); if(!name.empty()) node->set_attribute("name", name); return node; } void Page::print(std::ostream &out, bool grayscale) { #ifdef PNUM_HACK // Page numbering hack: { int page_num=get_page_num(); bool odd=page_num%2; int xpos=odd?(int) get_width()-pnum_hack.xpos:pnum_hack.xpos; int ypos=pnum_hack.ypos; out << '/' << pnum_hack.font << " findfont " << pnum_hack.font_size << " scalefont setfont" << std::endl << xpos << ' ' << ypos << " moveto (" << page_num << ") show" << std::endl; } #endif Group::print(out, grayscale); out << std::endl << "showpage" << std::endl << std::endl; } void Page::print_pdf(PDF::Document::Ptr pdf) const { PDF::Content::Ptr result = pdf->add_page(int(get_width()), int(get_height())); #ifdef PNUM_HACK // Page numbering hack: { int page_num=get_page_num(); bool odd=page_num%2; int xpos=odd?(int) get_width()-pnum_hack.xpos:pnum_hack.xpos; int ypos=pnum_hack.ypos; result->beginText(); result->selectfont(font::FontInfo(pnum_hack.font, pnum_hack.font_size)); result->moveto(xpos, ypos); result->show(to(tostr(page_num))); result->endText(); } #endif Group::print_pdf(result); /// \todo implement the page num hack (or make "real" page numbering) } std::string Page::get_name() { /// \todo is this a bad idea? return name.empty() ? tostr(get_page_num()) : std::string(name); } float Page::get_width() const { return document.get_width(); } float Page::get_height() const { return document.get_height(); } float Page::get_xpos() const { return 0; } float Page::get_ypos() const { return 0; } void Page::addObject(Pagent* obj) { add(obj); Document::containing(*this).select(obj); } void Page::select_all(bool select) { document.select_all_on_page(this, select); } Page& Page::containing(Pagent& obj) { try { if(Page* result = dynamic_cast(&obj)) return *result; else return Page::containing(obj.get_parent()); } catch(const Error::NoParent& err) { throw std::logic_error ("Tried to get Page containing pagent that was not on a Page."); } } const Page& Page::containing(const Pagent& obj) { try { if(const Page* result = dynamic_cast(&obj)) return *result; else return Page::containing(obj.get_parent()); } catch(const Error::NoParent& err) { throw std::logic_error ("Tried to get Page containing pagent that was not on a Page."); } }