aboutsummaryrefslogtreecommitdiff
path: root/lib/pdf/writer.hh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pdf/writer.hh')
-rw-r--r--lib/pdf/writer.hh165
1 files changed, 165 insertions, 0 deletions
diff --git a/lib/pdf/writer.hh b/lib/pdf/writer.hh
new file mode 100644
index 0000000..f62c471
--- /dev/null
+++ b/lib/pdf/writer.hh
@@ -0,0 +1,165 @@
+// writer.hh -- putting PDF objects in a file
+// Copyright (C) 2008 SEIKO EPSON CORPORATION
+//
+// This file is part of the 'iscan' program.
+//
+// The 'iscan' program is free-ish software.
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation;
+// either version 2 of the License or at your option any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of FITNESS
+// FOR A PARTICULAR PURPOSE or MERCHANTABILITY.
+// See the GNU General Public License for more details.
+//
+// You should have received a verbatim copy of the GNU General Public
+// License along with this program; if not, write to:
+//
+// Free Software Foundation, Inc.
+// 59 Temple Place, Suite 330
+// Boston, MA 02111-1307 USA
+//
+// As a special exception, the copyright holders give permission
+// to link the code of this program with the esmod library and
+// distribute linked combinations including the two. You must obey
+// the GNU General Public License in all respects for all of the
+// code used other than esmod.
+
+#ifndef iscan_pdf_writer_hh_included
+#define iscan_pdf_writer_hh_included
+
+#ifndef __cplusplus
+#error "This is a C++ header file; use a C++ compiler to compile it."
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "object.hh"
+#include "primitive.hh"
+#include "dictionary.hh"
+
+#include <map>
+
+namespace iscan
+{
+
+namespace pdf
+{
+ using std::string;
+
+/*! Writes PDF objects to a file.
+ * See section 3.4 of the PDF Reference version 1.7 for details on the basic
+ * file structure of a PDF file.
+ *
+ * There are two writing modes: object mode and stream mode.
+ * The default mode is object mode. When begin_stream() is called, the current
+ * mode is set to stream mode. When end_stream() is called, the mode is reset
+ * to object mode.
+ *
+ * In object mode, PDF objects are written all at once. Stream mode allows the
+ * writing of PDF stream objects which can be written incrementally.
+ */
+class writer
+{
+private:
+ typedef std::map<size_t, size_t> xref;
+
+ xref _xref;
+ size_t _xref_pos;
+ size_t _last_xref_pos;
+
+ FILE *_file;
+ size_t _saved_pos;
+
+ primitive* _stream_len_obj;
+
+ typedef enum {
+ object_mode,
+ stream_mode
+ } write_mode;
+
+ write_mode _mode;
+
+public:
+ /*! Creates a new pdf::writer object which will write to the given stream.
+ */
+ writer (FILE *file);
+
+ ~writer ();
+
+ /*! Writes a pdf::object to the file as an indirect object [p 63].
+ *
+ * Recursively writes any child objects to the file.
+ * Can only be called while in object mode, which is the default
+ * mode. If this method is called between calls to begin_stream() and
+ * end_stream() a std::runtime_error exception is thrown.
+ */
+ void write (object& object);
+
+ /*! Initializes a PDF stream [p 60] and sets the current mode to stream mode.
+ *
+ * Pass a pdf::dictionary object, \a dict, defining the stream properties,
+ * omitting the mandatory "Length" property which is automatically
+ * calculated and written to the file. If this method is called when already
+ * in stream mode, a std::runtime_error exception is thrown.
+ */
+ void begin_stream (dictionary& dict);
+
+ /*! Writes \a n bytes from \a buf to the file as part of a PDF stream.
+ *
+ * Can only be called while in stream mode.
+ * Calls to this method must be contained within calls to
+ * begin_stream() and end_stream(). If not, a std::runtime_error
+ * exception is thrown.
+ */
+ void write (const char* buf, size_t n);
+
+ /*! Writes a string \a s to the file as part of a PDF stream.
+ *
+ * Can only be called while in stream mode.
+ * Calls to this method must be contained within calls to
+ * begin_stream() and end_stream(). If not, a std::runtime_error
+ * exception is thrown.
+ */
+ void write (const string& s);
+
+ /*! Finishes writing a PDF stream and sets the current mode to object mode.
+ *
+ * The "Length" property of the stream is written at this point as an
+ * indirect object. Can only be called when in stream mode, if not, a
+ * std::runtime_error exception is thrown.
+ */
+ void end_stream ();
+
+ /*! Writes the PDF header [p 92].
+ *
+ * A std::runtime_error exception is thrown if this method is called while
+ * in stream mode.
+ */
+ void header ();
+
+ /*! Writes the PDF trailer [p 96] and xref table [p 93].
+ *
+ * Also sets the "Prev" entry in \a trailer_dict and clears the internal
+ * xref table. A std::runtime_error exception is thrown if this method is
+ * called while in stream mode.
+ *
+ * \param trailer_dict The trailer entries to be written.
+ */
+ void trailer (dictionary& trailer_dict);
+
+private:
+ // Writes the cross-reference table [p 93].
+ void write_xref ();
+
+ // Writes the file trailer [p 96].
+ void write_trailer (dictionary& trailer_dict);
+};
+
+} // namespace pdf
+} // namespace iscan
+
+#endif // iscan_pdf_writer_hh_included