#ifndef TEXTSTREAM_H // -*- c++ -*- #define TEXTSTREAM_H /// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "util/filewatcher.h" #include "util/xmlwrap.h" #include "xml2ps/pscanvas.hh" #include "ps/pdf.h" #include "filecontext.h" #include class TextFrame; class TypesetterThread; namespace xml2ps { class PDFCanvas; } /** * A source of text associated with a set of TextFrame s. * TextStream keeps a list of TextFrames. When association is set, * TextStream runs an XSLT transformation (external xsltproc, so far) to * convert the association into the xml2ps dtd. * Then xml2ps (internally linked) reads the output from the transform and * produces postscript for the actual TextFrames (which will emit signals to * be redrawn). * * When the docview tells the page to draw itself, the text frame * looks at its ps_exists member to detemine if it should read its * parsed_file. If it is false, the frame calls * TextStream::generate_ps_request which will run xml2ps if * necessary. This also happens when a frame is resized. */ class TextStream: public sigc::trackable { public: /** * Create a new TextStream. * \param _name the name of the stream (for the user). * \param _association the source XML file associated with the stream. * \param _transform the XSLT stylesheet to apply. */ TextStream(const std::string& _name, const std::string& _association, const std::string& _transform); /** * Load a TextStream from XML. * \param node the XML element containing information about the TextStream. * \param context information about the file we are loading from, for * relative URIs etc. */ TextStream(const ElementWrap& xml); ~TextStream(); /** * Save this TextStream to its XML format. * \param parent_node the XML node that will contain the saved node. * \param context file context for relative URIs. */ xmlpp::Element *save(xmlpp::Element& parent_node, const FileContext &context) const; void add_frame(TextFrame *text_frame); void remove_frame(TextFrame *text_frame); void generate_ps_request(TextFrame *frame = 0); void set_association(const std::string &s); const std::string &get_association() const; void set_name(const std::string &s); const std::string &get_name() const; void set_transform(const std::string& s); const std::string &get_transform() const; void set_parameter(const std::string& name, const std::string& value); // This doesn't really feel good, for an interface ... typedef std::map ParamMap; typedef ParamMap::const_iterator ParamIter; ParamIter param_begin() const { return parameters.begin(); } ParamIter param_end() const { return parameters.end(); } void run_typesetter(); // public, so DocumentView can run it const font::Fonts &get_used_fonts() const {return used_fonts;} /** Get the raw postscript data for a specific frame from the canvas */ void outputPageRaw(std::ostream& out, const TextFrame* frame); /** Get the eps data for a specific frame from the canvas */ void outputPageEps(std::ostream& out, const TextFrame* frame); void print_pdf(PDF::Document::Ptr pdfdoc); PDF::Object::Ptr getPagePDF(const TextFrame* frame); private: typedef std::list FramePtrs; std::string name, association, transform; FramePtrs frames; bool failed; // true if the last attempt to typeset failed FileWatcher association_watcher, transform_watcher; std::string typesetter_error; void on_typesetter_done(Glib::ustring error, Glib::RefPtr, bool truncated); void on_file_modified(); bool on_idle(); font::Fonts used_fonts; ParamMap parameters; Glib::RefPtr canvas; std::map pageno_map; Glib::RefPtr typesetter_thread; std::auto_ptr pdfcanvas; // Undefined ctors, avoid defaults TextStream(const TextStream&); TextStream(); void operator = (const TextStream&); }; #endif