Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/dvilib
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2004-12-21 23:57:26 (GMT)
committer Søren Sandmann Pedersen <ssp@src.gnome.org>2004-12-21 23:57:26 (GMT)
commit4296951e94a43c723e9522b588cab178eb66d144 (patch)
tree63ba229741d10df67fe87f24b6241903e16e9764 /dvi/dvilib
parent3e73e947a3a8c03da8f35f52e2a42ba066e2be2a (diff)
New directory with the beginning of a .dvi backend.
Tue Dec 21 18:55:06 2004 Søren Sandmann <sandmann@redhat.com> * dvi/*: New directory with the beginning of a .dvi backend.
Diffstat (limited to 'dvi/dvilib')
-rw-r--r--dvi/dvilib/TODO2
-rwxr-xr-xdvi/dvilib/dl-dvi-file.cc50
-rwxr-xr-xdvi/dvilib/dl-dvi-file.hh99
-rwxr-xr-xdvi/dvilib/dl-dvi-fontdefinition.cc3
-rwxr-xr-xdvi/dvilib/dl-dvi-fontdefinition.hh22
-rwxr-xr-xdvi/dvilib/dl-dvi-parser.cc581
-rwxr-xr-xdvi/dvilib/dl-dvi-parser.hh35
-rwxr-xr-xdvi/dvilib/dl-dvi-program.cc30
-rwxr-xr-xdvi/dvilib/dl-dvi-program.hh272
-rwxr-xr-xdvi/dvilib/dl-dvi-runtime.cc2
-rwxr-xr-xdvi/dvilib/dl-dvi-runtime.hh45
-rwxr-xr-xdvi/dvilib/dl-font.hh27
-rwxr-xr-xdvi/dvilib/dl-loader.cc196
-rwxr-xr-xdvi/dvilib/dl-loader.hh59
-rwxr-xr-xdvi/dvilib/dl-pkfont.cc379
-rwxr-xr-xdvi/dvilib/dl-pkfont.hh104
-rwxr-xr-xdvi/dvilib/dl-refcounted.hh37
-rwxr-xr-xdvi/dvilib/dl-vffont.cc16
-rwxr-xr-xdvi/dvilib/dl-vffont.hh55
19 files changed, 2014 insertions, 0 deletions
diff --git a/dvi/dvilib/TODO b/dvi/dvilib/TODO
new file mode 100644
index 0000000..fb58cb3
--- /dev/null
+++ b/dvi/dvilib/TODO
@@ -0,0 +1,2 @@
+- Add a cache so we don't call kpsewhich for each font
+- possibly make cache persistent so we don't have to call kpsewhich on startup
diff --git a/dvi/dvilib/dl-dvi-file.cc b/dvi/dvilib/dl-dvi-file.cc
new file mode 100755
index 0000000..1739be9
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-file.cc
@@ -0,0 +1,50 @@
+#include "dl-dvi-file.hh"
+#include "dl-dvi-parser.hh"
+
+using namespace DviLib;
+
+DviFile::DviFile (AbstractLoader& l) :
+ loader (l)
+{
+ DviParser parser (loader);
+
+ preamble = parser.parse_preamble ();
+ postamble = parser.parse_postamble ();
+
+ n_pages = 0;
+ uint page_pointer = postamble->last_page_address;
+
+ cout << page_pointer << endl;
+
+ while (page_pointer != (uint)-1)
+ {
+ loader.goto_from_start (page_pointer);
+
+ page_headers[n_pages++] =
+ parser.parse_page_header (&page_pointer);
+ }
+}
+
+DviPage *
+DviFile::get_page (uint n)
+{
+ DviPage *page = pages[n];
+
+ if (n > get_n_pages())
+ return 0;
+
+ if (page == 0)
+ {
+ DviParser parser (loader);
+ DviPageHeader *header;
+ DviProgram *program;
+
+ header = page_headers[n];
+ loader.goto_from_start (header->address + 45);
+ program = parser.parse_program ();
+
+ page = new DviPage (*header, *program);
+ }
+
+ return page;
+}
diff --git a/dvi/dvilib/dl-dvi-file.hh b/dvi/dvilib/dl-dvi-file.hh
new file mode 100755
index 0000000..d6c0201
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-file.hh
@@ -0,0 +1,99 @@
+#ifndef DL_DVI_FILE_HH
+#define DL_DVI_FILE_HH
+
+#include "dl-dvi-program.hh"
+#include <map>
+#include <list>
+#include <algorithm>
+#include "dl-dvi-fontdefinition.hh"
+#include "dl-loader.hh"
+
+namespace DviLib {
+ const uint N_PAGE_COUNTERS = 10; // \count0 ... \count9
+
+ class DviPageHeader : public RefCounted {
+ public:
+ int count[N_PAGE_COUNTERS];
+ uint address; // address of this page, not the preceding
+ };
+
+ class DviPage : public AbstractDviProgram {
+ DviProgram& program;
+ int count[N_PAGE_COUNTERS]; // \count0 ... \count9
+ public:
+ DviPage (DviProgram& p, int c[N_PAGE_COUNTERS]) :
+ program (p)
+ {
+ for (uint i=0; i<N_PAGE_COUNTERS; ++i)
+ count[i] = c[i];
+ }
+ DviPage (DviPageHeader& h, DviProgram& p) :
+ program (p)
+ {
+ for (uint i=0; i<N_PAGE_COUNTERS; ++i)
+ count[i] = h.count[i];
+ }
+ virtual void execute (DviRuntime& runtime)
+ {
+ program.execute (runtime);
+ }
+ int get_page_count (int i) { return count[i]; }
+ };
+
+ enum DviType {
+ NORMAL_DVI = 2, // FIXME: this should be 2
+ TEX_XET_DVI = 2 // FIXME: is this correct?
+ };
+
+ class DviFilePreamble : public RefCounted {
+ public:
+ // preamble
+ DviType type;
+ uint magnification;
+ uint numerator;
+ uint denominator;
+ string comment;
+ };
+
+ class DviFilePostamble : public RefCounted {
+ public:
+ // postamble
+ DviType type;
+ uint magnification;
+ uint numerator;
+ uint denominator;
+
+ uint last_page_address;
+ uint max_height;
+ uint max_width;
+ uint stack_height;
+ map <uint, DviFontdefinition *> fontdefinitions;
+ };
+
+ class DviFile : public RefCounted {
+ AbstractLoader &loader;
+
+ DviFilePreamble *preamble;
+ DviFilePostamble *postamble;
+
+ uint n_pages;
+ map <uint, DviPageHeader *> page_headers;
+ map <uint, DviPage *> pages;
+
+ public:
+ DviFile (AbstractLoader& l);
+ DviPage *get_page (uint n); /* unref it when done */
+ ~DviFile (void) {}
+ uint get_n_pages () { return n_pages; }
+ DviFontdefinition *get_fontdefinition (uint n)
+ {
+ return postamble->fontdefinitions[n];
+ }
+ uint get_numerator () { return postamble->numerator; }
+ uint get_denominator () { return postamble->denominator; }
+ uint get_magnification () { return postamble->magnification; }
+ };
+
+}
+#endif // DL_DVI_FILE_HH
+
diff --git a/dvi/dvilib/dl-dvi-fontdefinition.cc b/dvi/dvilib/dl-dvi-fontdefinition.cc
new file mode 100755
index 0000000..553ea28
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-fontdefinition.cc
@@ -0,0 +1,3 @@
+#include "dl-dvi-fontdefinition.hh"
+
+using namespace DviLib;
diff --git a/dvi/dvilib/dl-dvi-fontdefinition.hh b/dvi/dvilib/dl-dvi-fontdefinition.hh
new file mode 100755
index 0000000..e6bb0d6
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-fontdefinition.hh
@@ -0,0 +1,22 @@
+#ifndef DL_FONT_DEFINITION_HH__
+#define DL_FONT_DEFINITION_HH__
+
+#include <string>
+
+#include "dl-refcounted.hh"
+
+namespace DviLib {
+
+ class DviFontdefinition : public RefCounted {
+ public:
+ uint fontnum;
+ uint checksum;
+ uint at_size; /* if 300 dpi base,
+ * load at at_size * 300 / 1000 */
+ uint design_size;
+ string directory;
+ string name;
+ };
+
+}
+#endif // DL_FONT_DEFINITION_HH__
diff --git a/dvi/dvilib/dl-dvi-parser.cc b/dvi/dvilib/dl-dvi-parser.cc
new file mode 100755
index 0000000..7caac02
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-parser.cc
@@ -0,0 +1,581 @@
+#include "dl-dvi-parser.hh"
+
+using namespace DviLib;
+
+enum DviOpcode {
+ DVI_SETCHAR0 = 0, /* 128 of these */
+ DVI_SETCHAR127 = 127,
+ DVI_SET1,
+ DVI_SET2,
+ DVI_SET3,
+ DVI_SET4,
+ DVI_SETRULE,
+ DVI_PUT1,
+ DVI_PUT2,
+ DVI_PUT3,
+ DVI_PUT4,
+ DVI_PUTRULE,
+ DVI_NOP,
+ DVI_BOP,
+ DVI_EOP,
+ DVI_PUSH,
+ DVI_POP,
+ DVI_RIGHT1,
+ DVI_RIGHT2,
+ DVI_RIGHT3,
+ DVI_RIGHT4,
+ DVI_W0,
+ DVI_W1,
+ DVI_W2,
+ DVI_W3,
+ DVI_W4,
+ DVI_X0,
+ DVI_X1,
+ DVI_X2,
+ DVI_X3,
+ DVI_X4,
+ DVI_DOWN1,
+ DVI_DOWN2,
+ DVI_DOWN3,
+ DVI_DOWN4,
+ DVI_Y0,
+ DVI_Y1,
+ DVI_Y2,
+ DVI_Y3,
+ DVI_Y4,
+ DVI_Z0,
+ DVI_Z1,
+ DVI_Z2,
+ DVI_Z3,
+ DVI_Z4,
+ DVI_FONTNUM0 = 171, /* 64 of these */
+ DVI_FONTNUM63 = 234,
+ DVI_FNT1,
+ DVI_FNT2,
+ DVI_FNT3,
+ DVI_FNT4,
+ DVI_XXX1,
+ DVI_XXX2,
+ DVI_XXX3,
+ DVI_XXX4,
+ DVI_FNTDEF1,
+ DVI_FNTDEF2,
+ DVI_FNTDEF3,
+ DVI_FNTDEF4,
+ DVI_PRE,
+ DVI_POST,
+ DVI_POSTPOST = 249
+};
+
+static void
+skip_font_definition (AbstractLoader& l, uint *count)
+{
+ *count += 12;
+ l.skip_n (12);
+
+ *count += 2;
+ uint dl = l.get_uint8();
+ uint nl = l.get_uint8();
+
+ *count += dl+nl;
+ l.skip_n (dl+nl);
+}
+
+static DviCommand *
+parse_command (AbstractLoader &l, uint *count, DviOpcode *opcode)
+{
+ int h, w;
+ string error;
+ string s;
+
+ *opcode = (DviOpcode)l.get_uint8 ();
+ *count += 1;
+
+ if (DVI_SETCHAR0 <= *opcode && *opcode <= DVI_SETCHAR127)
+ return new DviSetCharCommand (*opcode);
+ else if (DVI_FONTNUM0 <= *opcode && *opcode <= DVI_FONTNUM63)
+ return new DviFontNumCommand (*opcode - DVI_FONTNUM0);
+ else switch (*opcode) {
+ case DVI_SET1:
+ *count += 1;
+ return new DviSetCharCommand (l.get_uint8());
+ break;
+ case DVI_SET2:
+ *count += 2;
+ return new DviSetCharCommand (l.get_uint16());
+ break;
+ case DVI_SET3:
+ *count += 3;
+ return new DviSetCharCommand (l.get_uint24());
+ break;
+ case DVI_SET4:
+ *count += 4;
+ return new DviSetCharCommand (l.get_uint32());
+ break;
+ case DVI_SETRULE:
+ *count += 8;
+ h = l.get_int32 ();
+ w = l.get_int32 ();
+ return new DviSetRuleCommand (h, w);
+ break;
+ case DVI_PUT1:
+ *count += 1;
+ return new DviPutCharCommand (l.get_uint8());
+ break;
+ case DVI_PUT2:
+ *count += 2;
+ return new DviPutCharCommand (l.get_uint16());
+ break;
+ case DVI_PUT3:
+ *count += 3;
+ return new DviPutCharCommand (l.get_uint24());
+ break;
+ case DVI_PUT4:
+ *count += 4;
+ return new DviPutCharCommand (l.get_uint32());
+ break;
+ case DVI_PUTRULE:
+ *count += 8;
+ h = l.get_int32();
+ w = l.get_int32();
+ return new DviPutRuleCommand (h, w);
+ break;
+ case DVI_PUSH:
+ return new DviPushCommand();
+ break;
+ case DVI_POP:
+ return new DviPopCommand();
+ break;
+ case DVI_RIGHT1:
+ *count += 1;
+ return new DviRightCommand (l.get_int8());
+ break;
+ case DVI_RIGHT2:
+ *count += 2;
+ return new DviRightCommand (l.get_int16());
+ break;
+ case DVI_RIGHT3:
+ *count += 3;
+ return new DviRightCommand (l.get_int24());
+ break;
+ case DVI_RIGHT4:
+ *count += 4;
+ return new DviRightCommand (l.get_int32());
+ break;
+ case DVI_W0:
+ return new DviWRepCommand ();
+ break;
+ case DVI_W1:
+ *count += 1;
+ return new DviWCommand (l.get_int8());
+ break;
+ case DVI_W2:
+ *count += 2;
+ return new DviWCommand (l.get_int16());
+ break;
+ case DVI_W3:
+ *count += 3;
+ return new DviWCommand (l.get_int24());
+ break;
+ case DVI_W4:
+ *count += 4;
+ return new DviWCommand (l.get_int32());
+ break;
+ case DVI_X0:
+ return new DviXRepCommand ();
+ break;
+ case DVI_X1:
+ *count += 1;
+ return new DviXCommand (l.get_int8());
+ break;
+ case DVI_X2:
+ *count += 2;
+ return new DviXCommand (l.get_int16());
+ break;
+ case DVI_X3:
+ *count += 3;
+ return new DviXCommand (l.get_int24());
+ break;
+ case DVI_X4:
+ *count += 4;
+ return new DviXCommand (l.get_int32());
+ break;
+ case DVI_DOWN1:
+ *count += 1;
+ return new DviDownCommand (l.get_int8());
+ break;
+ case DVI_DOWN2:
+ *count += 2;
+ return new DviDownCommand (l.get_int16());
+ break;
+ case DVI_DOWN3:
+ *count += 3;
+ return new DviDownCommand (l.get_int24());
+ break;
+ case DVI_DOWN4:
+ *count += 4;
+ return new DviDownCommand (l.get_int32());
+ break;
+ case DVI_Y0:
+ return new DviYRepCommand ();
+ break;
+ case DVI_Y1:
+ *count += 1;
+ return new DviYCommand (l.get_int8());
+ break;
+ case DVI_Y2:
+ *count += 2;
+ return new DviYCommand (l.get_int16());
+ break;
+ case DVI_Y3:
+ *count += 3;
+ return new DviYCommand (l.get_int24());
+ break;
+ case DVI_Y4:
+ *count += 4;
+ return new DviYCommand (l.get_int32());
+ break;
+ case DVI_Z0:
+ return new DviZRepCommand ();
+ break;
+ case DVI_Z1:
+ *count += 1;
+ return new DviZCommand (l.get_int8());
+ break;
+ case DVI_Z2:
+ *count += 2;
+ return new DviZCommand (l.get_int16());
+ break;
+ case DVI_Z3:
+ *count += 3;
+ return new DviZCommand (l.get_int24());
+ break;
+ case DVI_Z4:
+ *count += 4;
+ return new DviZCommand (l.get_int32());
+ break;
+ case DVI_FNT1:
+ *count += 1;
+ return new DviFontNumCommand (l.get_uint8());
+ break;
+ case DVI_FNT2:
+ *count += 2;
+ return new DviFontNumCommand (l.get_uint16());
+ break;
+ case DVI_FNT3:
+ *count += 3;
+ return new DviFontNumCommand (l.get_uint24());
+ break;
+ case DVI_FNT4:
+ *count += 4;
+ return new DviFontNumCommand (l.get_uint32());
+ break;
+ case DVI_XXX1:
+ s = l.get_string8();
+ *count += s.length() + 1;
+ return new DviSpecialCommand (s);
+ break;
+ case DVI_XXX2:
+ s = l.get_string16();
+ *count += s.length() + 2;
+ return new DviSpecialCommand (s);
+ break;
+ case DVI_XXX3:
+ s = l.get_string24();
+ *count += s.length() + 3;
+ return new DviSpecialCommand (s);
+ break;
+ case DVI_XXX4:
+ s = l.get_string32();
+ *count += s.length() + 4;
+ return new DviSpecialCommand (s);
+ break;
+ case DVI_FNTDEF1:
+ l.get_uint8 ();
+ skip_font_definition (l, count);
+ break;
+ case DVI_FNTDEF2:
+ l.get_uint16 ();
+ skip_font_definition (l, count);
+ break;
+ case DVI_FNTDEF3:
+ l.get_uint24 ();
+ skip_font_definition (l, count);
+ break;
+ case DVI_FNTDEF4:
+ l.get_uint32 ();
+ skip_font_definition (l, count);
+ break;
+ case DVI_BOP: // BOP and EOP are not considered commands
+ case DVI_EOP:
+ case DVI_NOP: // NOP is ignored
+ case DVI_PRE: // PRE, POST and POSTPOST are not supposed to happen
+ case DVI_POST:
+ case DVI_POSTPOST:
+ break;
+ default:
+ printf ("%u\n", *opcode);
+ throw string ("Unknown command");
+ break;
+ }
+ return 0;
+}
+
+DviProgram *
+DviParser::parse_program (void)
+{
+ DviProgram *program = new DviProgram ();
+ DviOpcode opcode;
+
+ do
+ {
+ DviCommand *cmd;
+ uint dummy;
+
+ cmd = parse_command (loader, &dummy, &opcode);
+ if (cmd)
+ {
+ program->add_command (cmd);
+ cmd->unref();
+ }
+
+ } while (opcode != DVI_EOP);
+
+ return program;
+}
+
+DviProgram *
+DviParser::parse_program (uint n_bytes)
+{
+ DviProgram *program = new DviProgram ();
+ uint count = 0;
+
+ while (count < n_bytes)
+ {
+ DviOpcode opcode;
+ DviCommand *cmd;
+
+ cmd = parse_command (loader, &count, &opcode);
+ if (cmd)
+ {
+ cout << opcode << endl;
+ program->add_command (cmd);
+ cmd->unref();
+ }
+ }
+
+ return program;
+}
+
+DviPageHeader *
+DviParser::parse_page_header (uint *page_pointer)
+{
+ DviOpcode c;
+
+ DviPageHeader *header = new DviPageHeader();
+
+ header->address = *page_pointer;
+
+ c = (DviOpcode)loader.get_uint8();
+ if (c != DVI_BOP)
+ throw string ("Expected BOP not found");
+ for (uint i=0; i<N_PAGE_COUNTERS; ++i)
+ header->count[i] = loader.get_uint32 ();
+
+ *page_pointer = loader.get_uint32 ();
+
+ return header;
+}
+
+DviFontdefinition *
+DviParser::parse_fontdefinition (void)
+{
+ DviFontdefinition *fontdef = new DviFontdefinition;
+ DviOpcode c = (DviOpcode)loader.get_uint8 ();
+
+ switch (c) {
+ case DVI_FNTDEF1:
+ fontdef->fontnum = loader.get_uint8 ();
+ break;
+ case DVI_FNTDEF2:
+ fontdef->fontnum = loader.get_uint16 ();
+ break;
+ case DVI_FNTDEF3:
+ fontdef->fontnum = loader.get_uint24 ();
+ break;
+ case DVI_FNTDEF4:
+ fontdef->fontnum = loader.get_uint32 ();
+ break;
+ default:
+ throw string ("DVI_FNTDEF? expected");
+ break;
+ }
+ fontdef->checksum = loader.get_uint32 ();
+ fontdef->at_size = loader.get_uint32 ();
+ fontdef->design_size = loader.get_uint32 ();
+
+ uint dirlength = loader.get_uint8 ();
+ uint namelength = loader.get_uint8 ();
+
+ fontdef->directory = "";
+ fontdef->name = "";
+
+ for (uint i=0; i<dirlength; ++i)
+ fontdef->directory += loader.get_uint8();
+ for (uint i=0; i<namelength; ++i)
+ fontdef->name += loader.get_uint8();
+
+ cout << "parsed fd: " << fontdef->name << " " << fontdef->fontnum << endl;
+
+ return fontdef;
+}
+
+DviFilePreamble *
+DviParser::parse_preamble (void)
+{
+ DviFilePreamble *preamble = new DviFilePreamble;
+
+ DviOpcode c = (DviOpcode)loader.get_uint8 ();
+ if (c != DVI_PRE)
+ {
+ string asdf ("asdf");
+ throw string ("Corrupt .dvi file - first byte is not DVI_PRE" + asdf);
+ }
+
+ preamble->type = (DviType)loader.get_uint8 ();
+ if (preamble->type != NORMAL_DVI)
+ {
+ string asdf ("asdf");
+ cout << asdf;
+ throw string ("Unknown .dvi format" + asdf);
+ }
+
+ preamble->numerator = loader.get_uint32 ();
+ preamble->denominator = loader.get_uint32 ();
+ preamble->magnification = loader.get_uint32 ();
+ preamble->comment = loader.get_string8 ();
+
+ return preamble;
+}
+
+DviFilePostamble *
+DviParser::parse_postamble (void)
+{
+ DviFilePostamble *postamble = new DviFilePostamble;
+
+ loader.goto_from_end (-5);
+
+ int i;
+ do {
+ i = loader.get_uint8 ();
+ loader.goto_from_current (-2);
+ } while (i == 223);
+
+ postamble->type = (DviType)i;
+
+ loader.goto_from_current (-3);
+ loader.goto_from_start (loader.get_uint32() + 1);
+
+ postamble->last_page_address = loader.get_uint32();
+ postamble->numerator = loader.get_uint32();
+ postamble->denominator = loader.get_uint32();
+ postamble->magnification = loader.get_uint32();
+ postamble->max_height = loader.get_uint32();
+ postamble->max_width = loader.get_uint32();
+ postamble->stack_height = loader.get_uint16();
+
+ loader.get_uint16 (); // skip number of pages (we count them instead)
+
+ while (true)
+ {
+ DviOpcode c = (DviOpcode)loader.get_uint8 ();
+
+ if (c == DVI_NOP)
+ continue;
+ else if (DVI_FNTDEF1 <= c && c <= DVI_FNTDEF4)
+ {
+ loader.goto_from_current (-1);
+ DviFontdefinition *fd = parse_fontdefinition ();
+
+ postamble->fontdefinitions[fd->fontnum] = fd;
+ cout << fd->name << endl;
+ cout << postamble->fontdefinitions[fd->fontnum]->name;
+ }
+ else
+ {
+ loader.goto_from_current (-1);
+ break;
+ }
+ }
+ return postamble;
+}
+
+VfFontPreamble *
+DviParser::parse_vf_font_preamble (void)
+{
+ DviOpcode c;
+ VfFontPreamble *preamble = new VfFontPreamble;
+
+ c = (DviOpcode)loader.get_uint8 ();
+ if (c != DVI_PRE)
+ throw string ("Not a .vf file");
+ c = (DviOpcode)loader.get_uint8 ();
+ if (c != 202)
+ throw string ("Not a .vf file");
+
+ preamble->comment = loader.get_string8 ();
+ preamble->checksum = loader.get_uint32 ();
+ preamble->design_size = loader.get_uint32 ();
+
+ while (true)
+ {
+ DviOpcode c = (DviOpcode)loader.get_uint8 ();
+
+ if (DVI_FNTDEF1 <= c && c <= DVI_FNTDEF4)
+ {
+ loader.goto_from_current (-1);
+ DviFontdefinition *fd = parse_fontdefinition ();
+
+ preamble->fontdefinitions.push_back (fd);
+ }
+ else
+ {
+ loader.goto_from_current (-1);
+ break;
+ }
+ }
+ return preamble;
+}
+
+VfChar *
+DviParser::parse_vf_char (void)
+{
+ DviOpcode c;
+
+ c = (DviOpcode)loader.get_uint8 ();
+
+ VfChar *ch = new VfChar;
+
+ if (c == DVI_POST)
+ return 0;
+ else if (c > 242)
+ throw string ("Corrupt .vf file");
+ else
+ {
+ uint packet_length;
+ if (c == 242)
+ {
+ packet_length = loader.get_uint32 ();
+ ch->character_code = loader.get_uint32 ();
+ ch->tfm_width = loader.get_uint32 ();
+ }
+ else
+ {
+ packet_length = c;
+ ch->character_code = loader.get_uint8 ();
+ ch->tfm_width = loader.get_uint24 ();
+ }
+ ch->program = parse_program (packet_length);
+ }
+ return ch;
+}
diff --git a/dvi/dvilib/dl-dvi-parser.hh b/dvi/dvilib/dl-dvi-parser.hh
new file mode 100755
index 0000000..32e065f
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-parser.hh
@@ -0,0 +1,35 @@
+#ifndef DL_DVI_PARSER_HH
+#define DL_DVI_PARSER_HH
+
+#include "dl-loader.hh"
+#include "dl-refcounted.hh"
+#include "dl-dvi-program.hh"
+#include "dl-dvi-fontdefinition.hh"
+#include "dl-dvi-file.hh"
+#include "dl-vffont.hh"
+
+namespace DviLib {
+
+ class DviParser : public RefCounted {
+ AbstractLoader& loader;
+ public:
+ DviParser (AbstractLoader& l) : loader (l)
+ {
+ };
+
+ DviFontdefinition * parse_fontdefinition (void);
+ DviProgram * parse_program (void);
+ DviProgram * parse_program (uint max);
+ DviPageHeader * parse_page_header (uint *prev_page);
+ DviFilePreamble * parse_preamble (void);
+ DviFilePostamble * parse_postamble (void);
+ VfFontPreamble * parse_vf_font_preamble (void);
+ VfChar * parse_vf_char (void);
+
+ ~DviParser (void)
+ {
+ };
+ };
+}
+
+#endif
diff --git a/dvi/dvilib/dl-dvi-program.cc b/dvi/dvilib/dl-dvi-program.cc
new file mode 100755
index 0000000..cb1f07f
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-program.cc
@@ -0,0 +1,30 @@
+#include "dl-dvi-program.hh"
+#include <algorithm>
+
+using namespace DviLib;
+
+typedef vector<DviCommand *>::iterator It;
+
+void
+DviProgram::execute (DviRuntime& runtime)
+{
+ for (It i = commands.begin(); i != commands.end(); ++i)
+ {
+ (*i)->execute (runtime);
+ }
+}
+
+void
+DviProgram::add_command (DviCommand *cmd)
+{
+ cmd->ref();
+ commands.push_back (cmd);
+}
+
+DviProgram::~DviProgram (void)
+{
+ for (It i = commands.begin(); i != commands.end(); ++i)
+ {
+ (*i)->unref ();
+ }
+}
diff --git a/dvi/dvilib/dl-dvi-program.hh b/dvi/dvilib/dl-dvi-program.hh
new file mode 100755
index 0000000..afe5fdb
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-program.hh
@@ -0,0 +1,272 @@
+#ifndef DL_DVI_PROGRAM_HH__
+#define DL_DVI_PROGRAM_HH__
+
+using namespace std;
+
+#include <string>
+#include <vector>
+
+#include <iostream>
+
+#include "dl-refcounted.hh"
+#include "dl-dvi-runtime.hh"
+
+namespace DviLib
+{
+ class DviCommand : public RefCounted
+ {
+ public:
+ virtual void execute (DviRuntime& runtime) = 0;
+ virtual ~DviCommand() {};
+ };
+
+ class AbstractDviProgram : public RefCounted
+ {
+ public:
+ virtual void execute (DviRuntime &runtime) = 0;
+ virtual ~AbstractDviProgram (void) {};
+ };
+
+ class DviProgram : public AbstractDviProgram
+ {
+ public:
+ vector <DviCommand *> commands;
+ void add_command (DviCommand *cmd);
+ virtual void execute (DviRuntime& runtime);
+ virtual ~DviProgram (void);
+ };
+
+ class DviCharCommand : public DviCommand
+ {
+ private:
+ uint c;
+
+ public:
+ DviCharCommand (uint c_arg)
+ {
+ c = c_arg;
+ }
+ uint get_c (void) const { return c; }
+ };
+
+ class DviPutCharCommand : public DviCharCommand
+ {
+ public:
+ DviPutCharCommand (uint ch) : DviCharCommand (ch) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.put_char (get_c());
+ }
+ };
+
+ class DviSetCharCommand : public DviCharCommand
+ {
+ public:
+ DviSetCharCommand (uint ch) : DviCharCommand (ch) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.set_char (get_c());
+ }
+ };
+
+ class DviRuleCommand : public DviCommand
+ {
+ private:
+ int h, w;
+
+ public:
+ DviRuleCommand (int h_arg, int w_arg) : h(h_arg), w(w_arg)
+ {
+ std::cout << "rule cmd " << h << " " << w << std::endl;
+ }
+ int get_h (void) const { return h; }
+ int get_w (void) const { return w; }
+ };
+
+ class DviPutRuleCommand : public DviRuleCommand
+ {
+ public:
+ DviPutRuleCommand (int h, int w) : DviRuleCommand (h, w) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.put_rule (get_h(), get_w());
+ }
+ };
+
+ class DviSetRuleCommand : public DviRuleCommand
+ {
+ public:
+ DviSetRuleCommand (int h, int w) : DviRuleCommand (h, w) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.set_rule (get_h(), get_w());
+ }
+ };
+
+ class DviPushCommand : public DviCommand
+ {
+ public:
+ DviPushCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.push ();
+ }
+ };
+
+ class DviPopCommand : public DviCommand
+ {
+ public:
+ DviPopCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.pop ();
+ }
+ };
+
+ class DviMoveCommand : public DviCommand
+ {
+ private:
+ int len;
+
+ public:
+ DviMoveCommand (int len_arg) : len (len_arg) {};
+ int get_len (void) { return len; }
+ };
+
+ class DviRightCommand : public DviMoveCommand
+ {
+ public:
+ DviRightCommand (int len) : DviMoveCommand (len)
+ {
+#if 0
+ cout << "right command " << get_len() << endl;
+#endif
+ };
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.right (get_len());
+ }
+ };
+
+ class DviWCommand : public DviMoveCommand
+ {
+ public:
+ DviWCommand (int len) : DviMoveCommand (len) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.w (get_len());
+ }
+ };
+
+ class DviXCommand : public DviMoveCommand
+ {
+ public:
+ DviXCommand (int len) : DviMoveCommand (len) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.x (get_len());
+ }
+ };
+
+ class DviDownCommand : public DviMoveCommand
+ {
+ public:
+ DviDownCommand (int len) : DviMoveCommand (len)
+ {
+#if 0
+ cout << "down command " << get_len() << endl;
+#endif
+ };
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.down (get_len());
+ }
+ };
+
+ class DviYCommand : public DviMoveCommand
+ {
+ public:
+ DviYCommand (int len) : DviMoveCommand (len) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.y (get_len());
+ }
+ };
+
+ class DviZCommand : public DviMoveCommand
+ {
+ public:
+ DviZCommand (int len) : DviMoveCommand (len) {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.z (get_len());
+ }
+ };
+
+ class DviFontNumCommand : public DviCommand
+ {
+ private:
+ int num;
+
+ public:
+ DviFontNumCommand (int num_arg) : num (num_arg) {}
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.font_num (num);
+ }
+ };
+
+ class DviSpecialCommand : public DviCommand
+ {
+ string spc;
+ public:
+ DviSpecialCommand (string s) : spc (s) {};
+ virtual ~DviSpecialCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.special (spc);
+ }
+ };
+
+ class DviWRepCommand : public DviCommand
+ {
+ public:
+ DviWRepCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.w_rep ();
+ }
+ };
+
+ class DviXRepCommand : public DviCommand
+ {
+ public:
+ DviXRepCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.x_rep ();
+ }
+ };
+
+ class DviYRepCommand : public DviCommand
+ {
+ public:
+ DviYRepCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.y_rep ();
+ }
+ };
+
+ class DviZRepCommand : public DviCommand
+ {
+ public:
+ DviZRepCommand () {};
+ virtual void execute (DviRuntime& runtime)
+ {
+ runtime.z_rep ();
+ }
+ };
+
+}
+#endif // DL_DVI_PROGRAM_HH__
diff --git a/dvi/dvilib/dl-dvi-runtime.cc b/dvi/dvilib/dl-dvi-runtime.cc
new file mode 100755
index 0000000..52b2620
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-runtime.cc
@@ -0,0 +1,2 @@
+#include "dl-dvi-runtime.hh"
+
diff --git a/dvi/dvilib/dl-dvi-runtime.hh b/dvi/dvilib/dl-dvi-runtime.hh
new file mode 100755
index 0000000..abb8c71
--- /dev/null
+++ b/dvi/dvilib/dl-dvi-runtime.hh
@@ -0,0 +1,45 @@
+#ifndef DL_DVI_STACK_HH
+#define DL_DVI_STACK_HH
+
+#include "dl-refcounted.hh"
+#include "dl-dvi-fontdefinition.hh"
+#include <string>
+#include <map>
+
+namespace DviLib {
+ class DviRuntime : public RefCounted
+ {
+ public:
+ virtual void set_char (int ch) = 0; // typeset ch, move w
+ virtual void put_char (int ch) = 0; // typeset ch, don't move
+ virtual void set_rule (int height,
+ int width) = 0; // rule, move (height, width)
+ virtual void put_rule (int height,
+ int width) = 0; // rule, don't move
+ virtual void push (void) = 0; // push current context
+ virtual void pop (void) = 0; // pop ccontext
+ virtual void right (int len) = 0; // move right len
+ virtual void w (int len) = 0; // move right len, set w = len
+ virtual void w_rep () = 0; // move right w
+ virtual void x (int len) = 0; // move right len, set x = len
+ virtual void x_rep () = 0; // move right x
+ virtual void down (int len) = 0; // move down len
+ virtual void y (int len) = 0; // move down len, set y = len
+ virtual void y_rep () = 0; // move down y
+ virtual void z (int len) = 0; // move down len, set z = len
+ virtual void z_rep () = 0; // move down z
+ virtual void push_fontmap (std::map<int, DviFontdefinition *> fontmap) = 0;
+ virtual void font_num (int num) = 0; // f = num
+ virtual void special (std::string spc) = 0; // do something special
+
+ virtual void paint_bitmap (const unsigned char *data,
+ uint width,
+ uint height,
+ int hoffset,
+ int voffseth) = 0;
+
+ virtual ~DviRuntime () {};
+ };
+}
+
+#endif
diff --git a/dvi/dvilib/dl-font.hh b/dvi/dvilib/dl-font.hh
new file mode 100755
index 0000000..855ab73
--- /dev/null
+++ b/dvi/dvilib/dl-font.hh
@@ -0,0 +1,27 @@
+#ifndef DL_FONT_HH__
+#define DL_FONT_HH__
+
+#include "dl-loader.hh"
+#include "dl-refcounted.hh"
+#include "dl-dvi-runtime.hh"
+
+#include <vector>
+#include <map>
+
+namespace DviLib {
+
+ class AbstractCharacter : public RefCounted {
+ public:
+ virtual void paint (DviRuntime &runtime) = 0;
+ virtual int get_tfm_width () = 0;
+ };
+
+ class AbstractFont : public RefCounted {
+ public:
+ virtual int get_at_size () = 0;
+ virtual int get_design_size () = 0;
+ virtual AbstractCharacter *get_char (int ccode) = 0;
+ };
+}
+
+#endif /* DL_PKFONT_HH__ */
diff --git a/dvi/dvilib/dl-loader.cc b/dvi/dvilib/dl-loader.cc
new file mode 100755
index 0000000..ce29a43
--- /dev/null
+++ b/dvi/dvilib/dl-loader.cc
@@ -0,0 +1,196 @@
+#include "dl-loader.hh"
+#include <errno.h>
+#include <iostream>
+
+using namespace DviLib;
+
+/* Abstract loader */
+/* =============== */
+
+/* unsigned integers */
+int
+AbstractLoader::get_uint16 ()
+{
+ return (get_uint8() << 8) | get_uint8();
+}
+
+int
+AbstractLoader::get_uint24 ()
+{
+ return (get_uint16() << 8) | get_uint8();
+}
+int
+AbstractLoader::get_uint32 ()
+{
+ return (get_uint16() << 16) | get_uint16();
+}
+
+/* signed integers */
+int
+AbstractLoader::get_int16 ()
+{
+ return (get_int8() << 8) | get_uint8();
+}
+
+int
+AbstractLoader::get_int24 ()
+{
+ return (get_int16() << 8) | get_uint8();
+}
+
+int
+AbstractLoader::get_int32 ()
+{
+ return (get_int16() << 16) | get_uint16();
+}
+
+/* (Pascal) strings */
+string
+AbstractLoader::get_string8 ()
+{
+ return get_n (get_uint8());
+}
+
+string
+AbstractLoader::get_string16 ()
+{
+ return get_n (get_uint16());
+}
+
+string
+AbstractLoader::get_string24 ()
+{
+ return get_n (get_uint24());
+}
+
+string
+AbstractLoader::get_string32 ()
+{
+ return get_n (get_uint32());
+}
+
+void
+AbstractLoader::skip_string8 ()
+{
+ get_string8();
+}
+
+void
+AbstractLoader::skip_string16 ()
+{
+ get_string16();
+}
+
+void
+AbstractLoader::skip_string24 ()
+{
+ get_string24();
+}
+
+void
+AbstractLoader::skip_string32 ()
+{
+ get_string32();
+}
+
+
+/* "n" */
+void
+AbstractLoader::skip_n (int n)
+{
+ get_n(n);
+}
+
+string
+AbstractLoader::get_n (int n)
+{
+ string r;
+
+ while (n--)
+ r += get_uint8 ();
+
+ return r;
+}
+
+void
+AbstractLoader::get_n (int n, unsigned char *v)
+{
+ while (n--)
+ *v++ = (unsigned char)get_uint8 ();
+}
+
+/* File loader */
+
+/* FIXME
+ *
+ * do not use C style files (?)
+ * what exceptions should we throw?
+ */
+
+FileLoader::FileLoader (const string &name)
+{
+ filename = name;
+ f = fopen (filename.c_str(), "r");
+ if (!f)
+ {
+ string s (strerror (errno));
+ throw string ("Could not open " + filename + ": " + s);
+ }
+}
+
+FileLoader::~FileLoader ()
+{
+ std::cout << "hej" << std::endl;
+ if (fclose (f) == EOF)
+ throw string ("Error closing " + filename);
+}
+
+int
+FileLoader::get_int8 ()
+{
+ int c;
+
+ if ((c = fgetc (f)) == EOF)
+ throw string ("Unexpected end of file");
+ else
+ return (signed char)c;
+}
+
+int
+FileLoader::get_uint8 ()
+{
+ return (unsigned char)get_int8();
+}
+
+void
+FileLoader::goto_from_start (int n)
+{
+ if (fseek (f, n, SEEK_SET) < 0)
+ {
+ string error = "fseek failed: ";
+ error += strerror (errno);
+ throw error;
+ }
+}
+
+void
+FileLoader::goto_from_current (int n)
+{
+ if (fseek (f, n, SEEK_CUR) < 0)
+ {
+ string error = "fseek failed: ";
+ error += strerror (errno);
+ throw error;
+ }
+}
+
+void
+FileLoader::goto_from_end (int n)
+{
+ if (fseek (f, n, SEEK_END) < 0)
+ {
+ string error = "fseek failed: ";
+ error += strerror (errno);
+ throw error;
+ }
+}
diff --git a/dvi/dvilib/dl-loader.hh b/dvi/dvilib/dl-loader.hh
new file mode 100755
index 0000000..f0ac956
--- /dev/null
+++ b/dvi/dvilib/dl-loader.hh
@@ -0,0 +1,59 @@
+#ifndef DL_LOADER_HH
+#define DL_LOADER_HH
+
+#include <string>
+#include <cstdio>
+#include <vector>
+
+#include "dl-refcounted.hh"
+
+namespace DviLib {
+
+ class AbstractLoader : public RefCounted {
+ public:
+ virtual int get_uint8 () = 0;
+ virtual int get_uint16 ();
+ virtual int get_uint24 ();
+ virtual int get_uint32 ();
+
+ virtual int get_int8 () = 0;
+ virtual int get_int16 ();
+ virtual int get_int24 ();
+ virtual int get_int32 ();
+
+ virtual string get_string8 ();
+ virtual string get_string16 ();
+ virtual string get_string24 ();
+ virtual string get_string32 ();
+
+ virtual void skip_string8 ();
+ virtual void skip_string16 ();
+ virtual void skip_string24 ();
+ virtual void skip_string32 ();
+
+ virtual void goto_from_start (int i) = 0;
+ virtual void goto_from_end (int i) = 0;
+ virtual void goto_from_current (int i) = 0;
+
+ virtual void skip_n (int n);
+ virtual string get_n (int n);
+ virtual void get_n (int n, unsigned char *v);
+
+ virtual ~AbstractLoader() {};
+ };
+
+ class FileLoader : public AbstractLoader {
+ FILE *f;
+ string filename;
+ public:
+ FileLoader (const string &name);
+ virtual int get_int8 ();
+ virtual int get_uint8 ();
+ virtual void goto_from_start (int i);
+ virtual void goto_from_end (int i);
+ virtual void goto_from_current (int i);
+
+ virtual ~FileLoader ();
+ };
+}
+#endif // DL_LOADER_HH
diff --git a/dvi/dvilib/dl-pkfont.cc b/dvi/dvilib/dl-pkfont.cc
new file mode 100755
index 0000000..2544e35
--- /dev/null
+++ b/dvi/dvilib/dl-pkfont.cc
@@ -0,0 +1,379 @@
+#include "dl-pkfont.hh"
+#include <algorithm>
+#include <iostream>
+
+using namespace DviLib;
+
+enum PkOpcode {
+ DL_PK_FIRST_COMMAND = 240,
+ DL_PK_XXX1 = 240,
+ DL_PK_XXX2,
+ DL_PK_XXX3,
+ DL_PK_XXX4,
+ DL_PK_YYY,
+ DL_PK_POST,
+ DL_PK_NOP,
+ DL_PK_PRE
+};
+
+enum Color {
+ BLACK,
+ WHITE
+};
+
+class Bitmap {
+ uint *data;
+ uint width;
+public:
+ Bitmap (uint width_arg, uint height)
+ {
+ width = width_arg;
+ data = new uint [width * height];
+ std::fill (data, data + width * height, 0x00000000);
+ }
+ uchar *steal_pixels (void)
+ {
+ uchar *r = (uchar *)data;
+ data = 0;
+ return r;
+ }
+ ~Bitmap ()
+ {
+ }
+ void fill_black (uint index, uint len)
+ {
+#if 0
+ cout << "filling: " << len << endl;
+#endif
+ std::fill (data + index,
+ data + index + len,
+ 0xff000000);
+ }
+ void copy (uint src_index, uint len, uint dest_index)
+ {
+ std::copy (data + src_index,
+ data + (src_index + len),
+ data + dest_index);
+ }
+ uint x (uint index)
+ {
+ return index % width;
+ }
+#if 0
+ uint y (uint index)
+ {
+ return (index * 4) / (width * 4);
+ }
+#endif
+ bool pixel (uint index) {
+ return *(data + index) == 0xff000000;
+ }
+};
+
+class DviLib::RleContext {
+ uchar *data;
+ bool first;
+ uchar nyb0 (uchar x) { return x >> 4; };
+ uchar nyb1 (uchar x) { return x & 15; };
+ Bitmap& bitmap;
+public:
+ uint index;
+ Color color;
+ RleContext (uchar *data_arg,
+ Color color_arg,
+ Bitmap &bitmap_arg) :
+ data (data_arg),
+ first (true),
+ bitmap (bitmap_arg),
+
+ index (0),
+ color (color_arg)
+ { }
+ uchar get_nybble (void)
+ {
+ if (first)
+ {
+ first = false;
+ return nyb0 (*data);
+ }
+ else
+ {
+ first = true;
+ return nyb1 (*data++);
+ }
+ }
+ Bitmap& get_bitmap () { return bitmap; }
+};
+
+inline CountType
+PkChar::get_count (RleContext& nr, uint *count)
+{
+ CountType result = RUN_COUNT;
+ uint i;
+
+ i = nr.get_nybble();
+ if (i == 15)
+ {
+ *count = 1;
+ return REPEAT_COUNT;
+ }
+ else if (i == 14)
+ {
+ result = REPEAT_COUNT;
+ i = nr.get_nybble();
+ }
+ switch (i) {
+ case 15: case 14:
+ throw string ("Duplicated repeat count");
+ break;
+ case 0:
+ for (i = 1; (*count = nr.get_nybble()) == 0; ++i)
+ ;
+ while (i-- > 0)
+ *count = (*count << 4) + nr.get_nybble();
+ *count = *count - 15 + (13 - dyn_f)*16 + dyn_f;
+ break;
+ default:
+ if (i <= dyn_f)
+ *count = i;
+ else
+ *count = (i - dyn_f - 1)*16 + nr.get_nybble() + dyn_f + 1;
+ break;
+ }
+ return result;
+}
+
+void
+PkChar::unpack_rle (RleContext& nr)
+{
+ uint count;
+
+ while (nr.index < height * width)
+ {
+ CountType count_type = get_count (nr, &count);
+ Bitmap& bm = nr.get_bitmap ();
+
+ switch (count_type) {
+ case RUN_COUNT:
+ if (nr.color == BLACK)
+ {
+ bm.fill_black (nr.index, count);
+ nr.color = WHITE;
+ }
+ else
+ nr.color = BLACK;
+ nr.index += count;
+ break;
+ case REPEAT_COUNT:
+ uint temp = nr.index;
+
+ nr.index += count * width;
+ unpack_rle (nr);
+
+ uint x = bm.x(temp);
+
+ if (bm.pixel (temp - x))
+ bm.fill_black (temp + count * width - x, x);
+
+ for (uint i = 0; i < count; ++i)
+ bm.copy (temp + count * width - x, width,
+ temp - x + i * width);
+ return;
+ break;
+ }
+ }
+}
+
+void
+PkChar::unpack_bitmap (void)
+{
+ uint i, weight;
+
+ uchar *bitmap
+ = new uchar [4 * width * height];
+ fill (bitmap, bitmap + 4 * width * height, 0xFF);
+
+ weight = 128;
+
+ for (i=0; i < height * width; i+=4)
+ {
+ if ((*data.packed & weight) != 0)
+ bitmap[i] = bitmap[i+1] =
+ bitmap[i+2] = bitmap[i+3] = 0x00;
+ weight = (weight == 1)?
+ (data.packed++, 128) : weight >> 1;
+ }
+ data.bitmap = bitmap;
+}
+
+void
+PkChar::unpack (void)
+{
+ if (unpacked)
+ return;
+
+ if (dyn_f == 14)
+ unpack_bitmap();
+ else
+ {
+ Bitmap bitmap (width, height);
+
+ RleContext nr (data.packed,
+ first_is_black? BLACK : WHITE,
+ bitmap);
+ unpack_rle (nr);
+ unpacked = true;
+ data.bitmap = bitmap.steal_pixels ();
+ }
+}
+
+PkChar::PkChar (AbstractLoader &loader)
+{
+ uint flag_byte = loader.get_uint8 ();
+
+ dyn_f = flag_byte >> 4;
+ if (dyn_f == 15)
+ throw string ("Corrupt .pk file");
+
+ first_is_black = (flag_byte & 8)? true : false;
+
+ uint length = 0; // to quiet gcc
+
+ switch (flag_byte & 7)
+ {
+ case 0: case 1: case 2: case 3:
+ /* short preamble */
+ length = loader.get_uint8 () + ((flag_byte & 3) << 8) - 8;
+ character_code = loader.get_uint8 ();
+ tfm_width = loader.get_uint24 ();
+ dx = loader.get_uint8 () << 16;
+ dy = 0;
+ width = loader.get_uint8 ();
+ height = loader.get_uint8 ();
+ hoffset = loader.get_int8 ();
+ voffset = loader.get_int8 ();
+ break;
+
+ case 4: case 5: case 6:
+ /* extended short preamble */
+ length = loader.get_uint16 () + ((flag_byte & 3) << 16) - 13;
+ cout << length;
+ character_code = loader.get_uint8 ();
+ cout << ',' << character_code;
+ tfm_width = loader.get_uint24 ();
+ dx = loader.get_uint16 () << 16;
+ dy = 0;
+ width = loader.get_uint16 ();
+ height = loader.get_uint16 ();
+ hoffset = loader.get_int16 ();
+ voffset = loader.get_int16 ();
+ break;
+
+ case 7:
+ /* long preamble */
+ length = loader.get_int32 () - 28;
+ character_code = loader.get_int32 ();
+ tfm_width = loader.get_int32 ();
+ dx = loader.get_int32 ();
+ dy = loader.get_int32 ();
+ width = loader.get_int32 ();
+ height = loader.get_int32 ();
+ hoffset = loader.get_int32 ();
+ voffset = loader.get_int32 ();
+ break;
+
+ default:
+ /* should not be reached */
+ break;
+ }
+ unpacked = false;
+ data.packed = new uchar[length];
+ loader.get_n (length, data.packed);
+}
+
+void
+PkChar::paint (DviRuntime &runtime)
+{
+ const unsigned char *bitmap;
+ bitmap = get_bitmap ();
+ runtime.paint_bitmap (bitmap,
+ get_width(), get_height(),
+ get_hoffset(), get_voffset());
+
+}
+void
+PkFont::load (void)
+{
+ PkOpcode c;
+
+ c = (PkOpcode) loader.get_uint8 ();
+ if (c != DL_PK_PRE)
+ throw string ("Not a .pk file (no pre)");
+
+ id = loader.get_uint8 ();
+ if (id != 89)
+ throw string ("Not a .pk file (incorrect id)");
+
+ comment = loader.get_string8 ();
+ design_size = loader.get_uint32 ();
+ checksum = loader.get_uint32 ();
+ hppp = loader.get_uint32 ();
+ vppp = loader.get_uint32 ();
+
+ do
+ {
+ c = (PkOpcode)loader.get_uint8 ();
+ switch (c)
+ {
+ case DL_PK_XXX1:
+ loader.skip_string8 ();
+ break;
+ case DL_PK_XXX2:
+ loader.skip_string16 ();
+ break;
+ case DL_PK_XXX3:
+ loader.skip_string24 ();
+ break;
+ case DL_PK_XXX4:
+ loader.skip_string32 ();
+ break;
+ case DL_PK_YYY:
+ loader.get_uint32 ();
+ break;
+ case DL_PK_POST:
+ break;
+ case DL_PK_NOP:
+ break;
+ case DL_PK_PRE:
+ throw string ("Unexpected PRE");
+ break;
+ default:
+ loader.goto_from_current (-1);
+ if (c <= DL_PK_FIRST_COMMAND)
+ {
+ PkChar *pkc = new PkChar (loader);
+ chars[pkc->get_character_code()] = pkc;
+#if 0
+ cout << '[' << pkc->get_character_code() << ']';
+#endif
+ }
+ else
+ throw string ("Undefined PK command");
+ break;
+ }
+ } while (c != DL_PK_POST);
+}
+
+PkFont::PkFont (AbstractLoader& l, int at_size_arg) :
+ loader (l),
+ at_size (at_size_arg)
+{
+ load ();
+}
+
+PkFont::PkFont (AbstractLoader& l) :
+ loader (l)
+{
+ load ();
+ at_size = design_size;
+}
diff --git a/dvi/dvilib/dl-pkfont.hh b/dvi/dvilib/dl-pkfont.hh
new file mode 100755
index 0000000..66cd69b
--- /dev/null
+++ b/dvi/dvilib/dl-pkfont.hh
@@ -0,0 +1,104 @@
+#ifndef DL_PKFONT_HH__
+#define DL_PKFONT_HH__
+
+#include "dl-loader.hh"
+#include "dl-refcounted.hh"
+#include "dl-font.hh"
+
+#include <vector>
+#include <map>
+
+namespace DviLib {
+
+ class RleContext;
+
+ enum CountType {
+ RUN_COUNT,
+ REPEAT_COUNT
+ };
+
+ class PkChar : public AbstractCharacter {
+ uint dyn_f;
+ bool first_is_black; // if first run count is black or white
+ int character_code;
+ int tfm_width; // in what units? FIXME
+ uint dx; // escapement - what is this? FIXME
+ uint dy;
+ uint width; // in pixels
+ uint height; // in pixels
+ int hoffset;
+ int voffset;
+
+ bool unpacked;
+ union {
+ unsigned char *bitmap; // 32 bit/pixel ARGB format
+ unsigned char *packed;
+ } data;
+
+ CountType get_count (RleContext& nr, uint *count);
+ void unpack_rle (RleContext& nr);
+ void unpack_bitmap (void);
+ void unpack (void);
+ public:
+ PkChar (AbstractLoader &l);
+ virtual void paint (DviRuntime &runtime);
+ const unsigned char *get_bitmap (void)
+ {
+ if (!unpacked)
+ unpack ();
+ return data.bitmap;
+ }
+ uint get_width (void)
+ {
+ return width;
+ }
+ uint get_height (void)
+ {
+ return height;
+ }
+ virtual int get_tfm_width (void)
+ {
+ return tfm_width;
+ }
+ int get_hoffset (void)
+ {
+ return hoffset;
+ }
+ int get_voffset (void)
+ {
+ return voffset;
+ }
+ int get_character_code (void) { return character_code; }
+ };
+
+ class PkFont : public AbstractFont {
+ AbstractLoader& loader;
+ uint id;
+ string comment;
+ uint design_size;
+ uint checksum;
+ uint hppp; /* horizontal pixels per point */
+ uint vppp; /* vertical pixels per point */
+ map <uint, PkChar *> chars;
+ int at_size;
+ void load (void);
+ public:
+ PkFont (AbstractLoader& l);
+ PkFont (AbstractLoader& l, int at_size);
+ virtual PkChar *get_char (int ccode)
+ {
+ return chars[ccode];
+ }
+ virtual int get_design_size (void)
+ {
+ return design_size;
+ }
+ virtual int get_at_size (void)
+ {
+ return at_size;
+ }
+ virtual ~PkFont () {}
+ };
+}
+
+#endif /* DL_PKFONT_HH__ */
diff --git a/dvi/dvilib/dl-refcounted.hh b/dvi/dvilib/dl-refcounted.hh
new file mode 100755
index 0000000..068ac2e
--- /dev/null
+++ b/dvi/dvilib/dl-refcounted.hh
@@ -0,0 +1,37 @@
+#ifndef DL_REFCOUNTED_HH
+#define DL_REFCOUNTED_HH
+
+using namespace std;
+
+typedef unsigned int uint;
+typedef unsigned char uchar;
+
+namespace DviLib {
+
+ class RefCounted
+ {
+ int refcount;
+
+ public:
+
+ RefCounted (void)
+ {
+ refcount = 1;
+ }
+
+ RefCounted *ref (void)
+ {
+ refcount++;
+ return this;
+ }
+
+ void unref (void)
+ {
+ refcount--;
+ if (!refcount)
+ delete this;
+ }
+ };
+}
+
+#endif // DL_REFCOUNTED_HH
diff --git a/dvi/dvilib/dl-vffont.cc b/dvi/dvilib/dl-vffont.cc
new file mode 100755
index 0000000..91109d8
--- /dev/null
+++ b/dvi/dvilib/dl-vffont.cc
@@ -0,0 +1,16 @@
+#include "dl-vffont.hh"
+#include "dl-dvi-parser.hh"
+
+using namespace DviLib;
+
+VfFont::VfFont (AbstractLoader &l, int at_size_arg) :
+ at_size (at_size_arg)
+{
+ DviParser parser (l);
+ preamble = parser.parse_vf_font_preamble ();
+
+ VfChar *ch;
+ while ((ch = parser.parse_vf_char ()) != NULL)
+ chars[ch->character_code] = ch;
+}
+
diff --git a/dvi/dvilib/dl-vffont.hh b/dvi/dvilib/dl-vffont.hh
new file mode 100755
index 0000000..185e4a9
--- /dev/null
+++ b/dvi/dvilib/dl-vffont.hh
@@ -0,0 +1,55 @@
+#ifndef DL_VFFONT_HH__
+#define DL_VFFONT_HH__
+
+#include "dl-dvi-file.hh"
+#include "dl-dvi-fontdefinition.hh"
+#include "dl-font.hh"
+
+namespace DviLib {
+
+ class VfChar : public AbstractCharacter {
+ public:
+ int tfm_width;
+ DviProgram *program;
+ int character_code;
+
+ virtual void paint (DviRuntime& runtime)
+ {
+ runtime.push();
+ program->execute (runtime); // FIXME push, pop, etc.
+ runtime.pop();
+ }
+ virtual int get_tfm_width () { return tfm_width; }
+ };
+
+ class VfFontPreamble : public RefCounted {
+ public:
+ string comment;
+ uint checksum;
+ uint design_size;
+ vector <DviFontdefinition *> fontdefinitions;
+ };
+
+ class VfFont : public AbstractFont {
+ VfFontPreamble *preamble;
+ map <int, VfChar *> chars;
+ int at_size;
+ public:
+ VfFont (AbstractLoader& l, int at_size);
+ virtual VfChar *get_char (int ccode)
+ {
+ return chars[ccode];
+ };
+ int get_design_size ()
+ {
+ return preamble->design_size;
+ }
+ virtual int get_at_size ()
+ {
+ /* FIXME (what is the correct thing to do here?) */
+ return at_size;
+ }
+ virtual ~VfFont () {}
+ };
+}
+#endif /* DL_VFFONT_HH__ */