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

xly.hh

///
// Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING
///
// XML for the layout engine
#ifndef X2P_XLY
#define X2P_XLY
#include <glibmm/ustring.h>
#include <cassert>
#include <vector>
#include <libxml++/libxml++.h>
#include <fonts/fontinfo.hh>
#include "canvas.hh"

namespace xml2ps {
  
  class Attributes {
  public:
    Attributes(const xmlpp::SaxParser::AttributeList& p) : p_(p) {}
    
    Glib::ustring get(const Glib::ustring& name, 
                  const Glib::ustring& defaultvalue = "") const;    
    float get(const Glib::ustring& name, const float& defaultvalue,
            const float embase = 0) const;
    
  private:
    const xmlpp::SaxParser::AttributeList p_;
  };
  
  class Element;
  
  class Node {
  public:
    Node(Element* parent) : parent_(parent) {}
    
    virtual ~Node() {}
    Element& getParent() const   { 
      assert(parent_);
      return *parent_; 
    }
    Node* nodeBefore() const;
    virtual float getWidth() const = 0;
  private:
    Element* parent_;
    
    Node();
    Node(const Node&);
    void operator= (const Node&);
  };

  class TextNode : public Node {
  public:
    TextNode(Element& parent, const Glib::ustring& text)
      : Node(&parent), text_(text) {}
    const Glib::ustring& getContent() const { return text_; }
    const font::FontInfo& getFont() const;
    float getWidth() const { return getFont().getWidth(text_); }
    
  private:
    Glib::ustring text_;
  };

  class WhiteSpaceNode : public TextNode {
  public:
    explicit WhiteSpaceNode(Element& parent) : TextNode(parent, " ") {}
  };
  
  class Element : public Node {
  public:
    typedef std::vector<Node*> NodeVect;
    typedef enum { left, justify, right, center } Align;
    typedef std::pair<int, int> CharSpaceCount;
    
    Element(Element& parent, const Glib::ustring& n, const Attributes& attr);
    Element(Element& parent, const Glib::ustring&n, const font::FontInfo& fi);
    
    virtual void add(Node* node);
    virtual void debug(std::ostream& out, bool nl = true);
    virtual void close();

    NodeVect::const_iterator begin() const { return nodes.begin(); }
    NodeVect::const_iterator end() const { return nodes.end(); }
    Node* nodeBefore(const Node* node = 0) const;
    
    const font::FontInfo& getFont() const { return font_info; }
    const std::string& getFontName() const { return font_info.getName(); }
    const float& getFontSize() const { return font_info.getSize(); }
    Align getAlign() const { return align; }
    
    float getWidth() const;

    // Returns (number of non-whitespace characters, number of whitespace)
    CharSpaceCount countChars(const Node* from, const Node* to) const;

    virtual const Node* printPart(Canvas& canvas, const Node* from,
                          const Node* to, const float& wh_width,
                          const float& cwidth) const;
    Glib::ustring d() const;
  private:
    Glib::ustring name;
    font::FontInfo font_info;
    Align align;
    bool underline;
    float baseline;           // relative to parent / hbox
    float gray;               // 0 is black, 1 is white.
  protected:
    NodeVect nodes;
  };
  
  /// An empty block level element.
00110   class PageBreak : public Element {
  public:
    PageBreak(Element& parent, Canvas& out);
    float getWidth() const { return 0; }
  };
  
  class BreakPoint : public Element {
  public:
    BreakPoint(Element& parent) : Element(parent, "bp", parent.getFont()) {}
    const Node* printPart(Canvas& canvas, const Node* from, const Node* to,
                    const float& whitewidth, const float& cwidth) const;
  };
  
  class LeaderNode : public Element {
  public:
    LeaderNode(Element& parent, const Attributes& attr);
    float getWidth() const { return width_; }

    const Node* printPart(Canvas& canvas, const Node* from, const Node* to,
                    const float& whitewidth, const float& cwidth) const;
  private:
    float width_;
  };

  class LineBreak : public Element {
  public:
    LineBreak(Element& parent) : 
      Element(parent, "linebreak", parent.getFont()) 
    {}
    const Node* printPart(Canvas& canvas, const Node* from, const Node* to,
                    const float& whitewidth, const float& cwidth) const;
  };

  class PageNum : public Element {
  public:
    PageNum(Element& parent, const Attributes& attr);
    float getWidth() const;
    const Node* printPart(Canvas& canvas, const Node* from, const Node* to,
                    const float& whitewidth, const float& cwidth) const;
  private:
    enum Type {ARABIC, ROMAN_LOWER, ROMAN_UPPER};
    Type type;
    std::string getStr(int num) const;
  };

  /**
   * Add an obstacle - i.e. an area that wont be written over.  The area is
   * created "at print time", so it can only be "below the current point".
   */
00159   class ObstacleNode : public Element {
  public:
    ObstacleNode(Element& parent, const Attributes& attr);
    
    const Node* printPart(Canvas& canvas, const Node* from, const Node* to,
                    const float& whitewidth, const float& cwidth) const;
  private:
    float left_, right_, top_, bottom_;
  };

  // An element that can contain both text and other Elements
  // text contents is automatically split into textnodes.
  class TextContainer : public Element {
  public:
    TextContainer(Element& parent, const Glib::ustring& n, 
              const Attributes& attr)
      : Element(parent, n, attr) {}

    void add(const Glib::ustring& newtext) { text += newtext; }
    virtual void add(Node* node);
    virtual void close();
    
  private:
    void makeTextParts();
    
    Glib::ustring text;
  };
  
  
}

#endif

Generated by  Doxygen 1.6.0   Back to index