dvi2bitmap dvi2bitmap1.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

DviFile.h
Go to the documentation of this file.
1 /* This file is part of dvi2bitmap; see README for copyrights and licence */
2
3 #ifndef DVI_FILE_HEADER_READ
4 #define DVI_FILE_HEADER_READ 1
5
6 #include <config.h>
7
8 #ifdef HAVE_CSTD_INCLUDE
9 #include <cctype>
10 #else
11 #include <ctype.h>
12 #endif
13
14 #include <string>
15
16 #include <stack>
17 #include <list>
18 #include <map>
19
20 #include <Byte.h>
21 #include <DviError.h>
22 #include <FileByteStream.h>
23 #include <PkFont.h>
24 #include <verbosity.h>
25
26 // I think the GCC 2.8.1 stack implementation may be buggy.
27 // Setting this to 1 switches on a home-made version.
28 // This hasn't received _extensive_ testing, but seems to work OK.
29 // This is pretty crappy, though, and I intend to remove it next time
30 // I'm feeling brave. If you have to enable this to get this library
31 // to compile, therefore, tell me (norman@astro.gla.ac.uk) so that I
32 // don't discard this. If you need to enable this, then you should
33 // probably call the DviFile constructors with read_post true, so
34 // that the maximum stack size can be read from the postamble, and
35 // the homemade posstack therefore initialised to the correct length.
36 #ifndef HOMEMADE_POSSTATESTACK
37 #define HOMEMADE_POSSTATESTACK 0
38 #endif
39
40 class DviFileEvent;
41 class DviFilePreamble;
42
51 class DviFile {
52 public:
53 DviFile (string& s,
54 int resolution=0,
55 double magmag=1.0,
56 bool read_postamble=true,
57 bool seekable=true)
58 throw (DviError);
59 ~DviFile();
60 bool eof();
61 DviFileEvent *getEvent();
62 DviFileEvent *getEndOfPage();
68 enum DviUnits {
72 unit_BAD,
76 unit_pt,
80 unit_pc,
84 unit_in,
89 unit_bp,
93 unit_cm,
100 unit_mm,
104 unit_dd,
108 unit_cc,
119 unit_sp,
124 unit_pixels,
135 unit_dvi
136 };
137 static DviUnits unitType(string unitString);
138 static string unitString(DviUnits unit);
154 int currH(DviUnits units=unit_pixels) const
155 throw (DviError) {
156 int r;
157 switch (units) {
158 case unit_pixels:
159 r = hh_; /* device units */
160 break;
161 case unit_dvi:
162 r = h_;
163 break;
164 case unit_sp:
165 r = (netmag_ == 1.0 ? h_ : static_cast<int>(h_*netmag_));
166 break;
167 default:
168 throw DviError("Bad unit in currH");
169 }
170 return r;
171 }
176 int currV(DviUnits units=unit_pixels) const
177 throw (DviError) {
178 int r;
179 switch (units) {
180 case unit_pixels:
181 r = vv_; /* device units */
182 break;
183 case unit_dvi:
184 r = v_;
185 break;
186 case unit_sp:
187 r = (netmag_ == 1.0 ? v_ : static_cast<int>(v_*netmag_));
188 break;
189 default:
190 throw DviError("Bad unit in currV");
191 }
192 return r;
193 }
194 int hSize();
195 int vSize();
196 static double convertFromScaledPoints(int sp, DviUnits units,
197 DviFile *dvif=0)
198 throw (DviError);
199 static int convertToScaledPoints(double length, DviUnits units,
200 DviFile *dvif=0)
201 throw (DviError);
202 static double convertUnits(double length,
203 DviUnits from_units,
204 DviUnits to_units,
205 DviFile *dvif=0)
206 throw (DviError);
207 static verbosities verbosity(const verbosities level);
213 double magnification() const { return netmag_; }
221 int pt2px(double npt) const
222 {
223 return static_cast<int>
224 (npt * dviu_per_pt_ / dviu_per_px_ + 0.5);
225 }
230 const string *filename () const { return &fileName_; }
231
232 const PkFont* getFallbackFont(const PkFont* desired);
233
245 bool haveReadPostamble() const { return have_preread_postamble_; }
246
247 private:
248 string fileName_;
253 int h_, v_, w_, x_, y_, z_;
257 int hh_, vv_;
259 int pending_hupdate_;
261 int pending_hhupdate_;
262 PkFont *current_font_;
263 InputByteStream *dvif_;
272 double dviu_per_pt_;
273
281 double dviu_per_px_;
287 double dviu_per_sp_;
288
289 double dviu_per_(DviUnits unit);
290
296 const double extmag_;
301 double netmag_;
302
303 // tell getEvent to skip this page
304 bool skipPage_;
305
309 int max_drift_;
310
316 int widest_page_;
323 int deepest_page_;
324
325 Byte getByte();
326 signed int getSIU(int), getSIS(int);
327 unsigned int getUIU(int);
328 struct {
329 unsigned int mag, l, u, s, t;
330 } postamble_;
331 struct {
332 unsigned int i, num, den, mag;
333 string comment;
334 } preamble_;
335 void read_postamble()
336 throw (DviError);
337 bool have_preread_postamble_; /* we sought to it at beginning */
338 bool have_read_to_postamble_; /* we have read through to end */
339 void process_preamble(DviFilePreamble *);
340 void fnt_def_(double fontmag, int nbytes);
341 void check_duplicate_font(int);
342 int pixel_round(int);
343 int charWidth_ (int charno);
344 int charEscapement_ (int charno);
345 // updateH/V update the horizontal position by an amount in DVI units
346 void updateH_ (int hup, int hhup);
347 void updateV_ (int y);
348 struct PosState {
349 const int h, v, w, x, y, z, hh, vv;
350 PosState(int h, int v, int w, int x, int y, int z, int hh, int vv)
351 : h(h),v(v),w(w),x(x),y(y),z(z),hh(hh),vv(vv) { }
352 };
353 #if HOMEMADE_POSSTATESTACK
354 class PosStateStack {
355 // It seems wrong to implement a stack rather than using the standard
356 // one, but either I'm doing something wrong the way
357 // I use the STL stack, or else it's (horrors!) buggy. In any case,
358 // it's reasonable to use a non-extendable stack, since the DVI
359 // postamble specifies the maximum stack size required.
360 public:
361 PosStateStack(int size);
362 void push(const PosState *p);
363 const PosState *pop();
364 bool empty() const { return i == 0; }
365 void clear();
366 private:
367 unsigned int size, i;
368 const PosState **s;
369 };
370 PosStateStack *posStack_;
371 #else
372 STD::stack<PosState> posStack_;
373 #endif
374 static verbosities verbosity_;
375
376 public:
380 class FontSet {
381 private:
382 FontSet();
383 ~FontSet();
384 void add(int fnt_num, PkFont* newfont);
385 PkFont* get(int fnt_num);
386 friend class DviFile;
387 typedef STD::map<int,PkFont*> FontMap;
388 FontMap fontMap_;
389 public:
394 bool empty() const { return fontMap_.empty(); }
399 size_t size() const { return fontMap_.size(); }
403 class const_iterator;
404 friend class DviFile::FontSet::const_iterator; /* so it sees FontMap */
405 class const_iterator {
406 public:
407 const PkFont* operator*() const throw (DviError);
408 const_iterator& operator++() throw (DviError);
409 bool operator==(const const_iterator& it) const;
410 bool operator!=(const const_iterator& it) const;
411 ~const_iterator();
412 private:
413 const_iterator();
414 const_iterator(FontMap m);
415 STD::list<PkFont*> fontlist_;
416 friend class DviFile::FontSet;
417 };
418 const_iterator begin() const;
419 const_iterator end() const;
420 private:
421 mutable const_iterator* myIter_;
422 };
423 private:
424 FontSet fontSet_;
425 public:
435 const FontSet* getFontSet() const { return &fontSet_; }
436 // Why can't I have 'FontSet& getFontSet() const { return fontSet_; };'?
437
438 #if 0
439 public:
440 class const_iterator {
441 public:
442 const PkFont* operator*() const throw (DviBug);
443 const_iterator& operator++();
444 bool operator==(const const_iterator& it) const;
445 bool operator!=(const const_iterator& it) const;
446 #if 0
447 bool operator==(const const_iterator& it) const
448 { return finished_ == it.finished_; }
449 bool operator!=(const const_iterator& it) const
450 { return finished_ != it.finished_; }
451 #endif
452 private:
453 /* These should be implementable more compactly, since we're
454 just using map's iterator, but there's some visibility
455 subtlety that escapes me... */
456 const_iterator(FontMap::const_iterator m,
457 FontMap::const_iterator me) {
458 mapiter_ = m;
459 endmapiter_ = me;
460 finished_ = false;
461 };
462 const_iterator() : finished_(true) { }
463 FontMap::const_iterator mapiter_;
464 FontMap::const_iterator endmapiter_;
465 bool finished_;
466 friend class DviFile;
467 };
475 const_iterator begin() {
476 return const_iterator(fontMap_.begin(), fontMap_.end());
477 }
484 const_iterator end() const { return const_iterator(); };
485 friend class const_iterator;
486 #endif
487 };
488
489
490 /* DviFileEvent is what is returned to the client from the DVI reading class.
491 * Declare one derived class for each type of event.
492 *
493 * This is rather bad design - these classes should be subclasses of DviFile
494 * above.
495 * DviFileEvent is a virtual class, so these derived classes should have
496 * non-virtual destructors.
497 * XXX these shouldn't be subclasses of DviFile, I don't think, but
498 * they should have DviFile as a friend (correct?), so that only
499 * DviFile can create instances
500 */
517 class DviFileEvent {
518 public:
519 enum eventTypes { setchar, setrule, fontchange, special,
520 page, preamble, postamble };
524 virtual void debug() const;
525
534 eventTypes type() const { return type_; }
535
540 const unsigned char opcode() const { return opcode_; }
541
542 void release();
543
544 static verbosities verbosity(const verbosities level);
545
546 protected:
547 DviFileEvent(unsigned char opcode, eventTypes t, DviFile *dp=0);
548 static verbosities verbosity_;
549
550 private:
551 const unsigned char opcode_;
552 DviFile *dviFile_;
553 const eventTypes type_;
554
555 static void releaseEvent(DviFileEvent *e);
556 };
557
559 class DviFileSetChar : public DviFileEvent {
560 public:
566 DviFileSetChar(int charno, DviFile *dptr);
567 DviFileSetChar(int opcode, int charno, DviFile *dptr);
568 void debug() const;
573 const int charno() const { return charno_; }
574 private:
575 const int charno_;
576 };
577
579 class DviFileSetRule: public DviFileEvent {
580 public:
585 const int h;
590 const int w;
591 DviFileSetRule(unsigned char opcode, DviFile *dptr, int h, int w)
592 : DviFileEvent(opcode, setrule, dptr), h(h), w(w) { }
593 void debug() const;
594 };
595
597 class DviFileFontChange : public DviFileEvent {
598 public:
599 DviFileFontChange(unsigned char opcode, PkFont *f)
600 : DviFileEvent(opcode, fontchange), font(f) { }
601 void debug() const;
603 const PkFont *font;
604 };
605
607 class DviFileSpecial : public DviFileEvent {
608 public:
609 DviFileSpecial(unsigned char opcode, string str)
610 : DviFileEvent(opcode, special), specialString(str) { }
612 const string specialString;
613 void debug() const;
614 };
615
617 class DviFilePage : public DviFileEvent {
618 public:
619 DviFilePage(unsigned char opcode, bool isStart)
620 : DviFileEvent(opcode, page), isStart(isStart) { }
621 void debug() const;
628 const bool isStart;
633 signed int count[10];
639 signed int previous;
640 };
641
643 class DviFilePreamble : public DviFileEvent {
644 public:
645 DviFilePreamble()
646 : DviFileEvent(247, preamble) { }
647 void debug() const;
652 unsigned int dviType;
656 unsigned int num;
660 unsigned int den;
665 unsigned int mag;
669 string comment;
670 };
671
673 class DviFilePostamble : public DviFileEvent {
674 public:
675 DviFilePostamble()
676 : DviFileEvent(248, postamble) { }
677 };
678
679 #endif //#ifndef DVI_FILE_HEADER_READ