Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/dvilib/dl-dvi-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dvi/dvilib/dl-dvi-parser.cc')
-rwxr-xr-xdvi/dvilib/dl-dvi-parser.cc581
1 files changed, 581 insertions, 0 deletions
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;
+}