Logo Search packages:      
Sourcecode: passepartout version File versions  Download package

page.cc

///
// 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 <algorithm>

#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<Guide::Orientation>::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>("orientation", VERTICAL)),
    position(xml.get_required_attribute<float>("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<string>("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<const xmlpp::Element*>(*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 <page>." << 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<Glib::ustring>(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<Page*>(&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<const Page*>(&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.");
  }
}

Generated by  Doxygen 1.6.0   Back to index