/// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// // XML for the layout engine #ifndef X2P_XLY #define X2P_XLY #include #include #include #include #include #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 NodeVect; typedef enum { left, justify, right, center } Align; typedef std::pair 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. 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". */ 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