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

psstream.cc

///
// Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING
///
#include "psstream.hh"
#include <algorithm>          // max?
#include <iomanip>

xml2ps::PsStream::PsStream(const int& out_width, const int& out_height)
  : page_no_(0), width_max(out_width), height_max(out_height)
{
  // There is no page #0.
  page_size.push_back(std::make_pair(0, 0));
}

xml2ps::PsStream::~PsStream() {}

namespace xml2ps {

void
PsStream::newPage(const int& width, const int& height) {
  ++page_no_;
  split();
  page_size.push_back(std::make_pair(width, height));
  width_max=std::max(width_max, width); 
  height_max=std::max(height_max, height);
}

void 
PsStream::require_font(const std::string &fontname)
{
  require_fonts.insert(fontname);
}

void 
PsStream::include_font(const std::string &fontname) // can't include yet
{
  include_fonts.insert(fontname);
}
}

namespace {                   // local
  typedef std::set<std::string> FontSet;
  
  /** Write the comments block that starts a postscript file. */
  void psComments(std::ostream& out, unsigned pages, const std::string& title,
              float width, float height, 
              const FontSet& require_fonts, const FontSet& include_fonts)
  {
    out << "%!PS-Adobe-3.0\n"
      << "%%Creator: xml2ps by rasmus@kaj.se\n"
      << "%%LanguageLevel: 2\n"
      << "%%Pages: " << pages << '\n'
      << "%%BoundingBox: 0 0 " << width << ' ' << height << '\n';
    /// \todo split font comments into several lines, if necessary.
    if(!require_fonts.empty()) {
      out << "%%DocumentNeededResources: font";
      for(FontSet::const_iterator i=require_fonts.begin();
        i!=require_fonts.end();
        i++)
      out << ' ' << *i;
      out << '\n';
    }
    if(!include_fonts.empty()) {
      out << "%%DocumentSuppliedResources: font";
      for(FontSet::const_iterator i=include_fonts.begin();
        i!=include_fonts.end();
        i++)
      out << ' ' << *i;
      out << '\n';
    }
    out << "%%EndComments\n\n";
  }
  
  /** Write the postscript setup block for xml2ps. */
  void psSetup(std::ostream& out, const FontSet& require_fonts) {
    out << "%%BeginSetup\n";
    
    /// \todo respect include_fonts
    for(FontSet::const_iterator i=require_fonts.begin();
      i!=require_fonts.end();
      i++)
      out << "%%IncludeResource: font " << *i << '\n';
    
    out << "0 setlinewidth\n"
      << "%%EndSetup\n\n";
  }
}

void xml2ps::PsStream::psProlog(std::ostream& out) {
  out << "/S { show } bind def\n"
      << "/GS { glyphshow } bind def\n"
      << "/M { moveto } bind def\n"
      << "/WS { 0 rmoveto } bind def\n"
      << "/F { findfont exch scalefont setfont } bind def\n"
      << "/UFROM { currentpoint 3 -1 roll add } bind def\n"
      << "/UTO { 4 2 roll currentpoint 2 copy 6 4 roll moveto\n"
      << "   5 -1 roll add lineto 3 -1 roll setlinewidth stroke moveto"
      << "} bind def\n\n";
}

void xml2ps::PsStream::merge(std::ostream& out) const {
  psComments(out, page_no_, "An xml2ps document", width_max, height_max,
           require_fonts, include_fonts);
  out << "%%BeginProlog\n";
  psProlog(out);
  out << "%%EndProlog\n\n";
  psSetup(out, require_fonts);
  
  for(int p = 1; p <= page_no_; ++p) {
    out << "%%Page: " << p << ' ' << p << '\n'
      << "%%PageBoundingBox: 0 0 " << page_size[p].first
      << ' ' << page_size[p].second << '\n'
      << "gsave\n";
    PagedStream::appendPage(p, out);
    out << "showpage\n"
      << "grestore\n";
  }
  out << "%%Trailer\n"
      << "%%EOF" << std::endl;
}

void xml2ps::PsStream::pageEps(unsigned page_no, std::ostream& out) {
  psComments(out, 1, "An xml2ps page",
           page_size[page_no].first, page_size[page_no].second,
           require_fonts, include_fonts);
  psProlog(out);
  psSetup(out, require_fonts);
  
  out << "%%Page: \"" << page_no << "\" 1\n";
  PagedStream::appendPage(page_no, out);
  out << "showpage\n"
      << "%%Trailer\n"
      << "%%EOF" << std::endl;
}

Generated by  Doxygen 1.6.0   Back to index