00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#ifndef DVI_FILE_HEADER_READ
00029 #define DVI_FILE_HEADER_READ 1
00030
00031
#include <config.h>
00032
00033
#ifdef HAVE_CSTD_INCLUDE
00034
#include <cctype>
00035
#else
00036
#include <ctype.h>
00037
#endif
00038
00039
#include <string>
00040
00041
#include <stack>
00042
#include <list>
00043
#include <map>
00044
00045
#include <Byte.h>
00046
#include <DviError.h>
00047
#include <FileByteStream.h>
00048
#include <PkFont.h>
00049
#include <verbosity.h>
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
#ifndef HOMEMADE_POSSTATESTACK
00062 #define HOMEMADE_POSSTATESTACK 0
00063
#endif
00064
00065
class DviFileEvent;
00066
class DviFilePreamble;
00067
00076 class DviFile {
00077
public:
00078
DviFile (string& s,
00079
int resolution=0,
00080
double magmag=1.0,
00081
bool read_postamble=
true,
00082
bool seekable=
true)
00083
throw (
DviError);
00084
~DviFile();
00085
bool eof();
00086
DviFileEvent *
getEvent();
00087
DviFileEvent *
getEndOfPage();
00093 enum DviUnits {
00097
unit_BAD,
00101
unit_pt,
00105
unit_pc,
00109
unit_in,
00114
unit_bp,
00118
unit_cm,
00125
unit_mm,
00129
unit_dd,
00133
unit_cc,
00144
unit_sp,
00149
unit_pixels,
00160
unit_dvi
00161 };
00162
static DviUnits
unitType(string unitString);
00163
static string
unitString(DviUnits unit);
00179 int currH(DviUnits units=unit_pixels)
const
00180
throw (
DviError) {
00181
int r;
00182
switch (units) {
00183
case unit_pixels:
00184 r = hh_;
00185
break;
00186
case unit_dvi:
00187 r = h_;
00188
break;
00189
case unit_sp:
00190 r = (netmag_ == 1.0 ? h_ : static_cast<int>(h_*netmag_));
00191
break;
00192
default:
00193
throw DviError(
"Bad unit in currH");
00194 }
00195
return r;
00196 }
00201 int currV(DviUnits units=unit_pixels)
const
00202
throw (
DviError) {
00203
int r;
00204
switch (units) {
00205
case unit_pixels:
00206 r = vv_;
00207
break;
00208
case unit_dvi:
00209 r = v_;
00210
break;
00211
case unit_sp:
00212 r = (netmag_ == 1.0 ? v_ : static_cast<int>(v_*netmag_));
00213
break;
00214
default:
00215
throw DviError(
"Bad unit in currV");
00216 }
00217
return r;
00218 }
00219
int hSize();
00220
int vSize();
00221
static double convertFromScaledPoints(
int sp, DviUnits units,
00222
DviFile *dvif=0)
00223
throw (
DviError);
00224
static double convertToScaledPoints(
double length, DviUnits units,
00225
DviFile *dvif=0)
00226
throw (
DviError);
00227
static double convertUnits(
double length,
00228 DviUnits from_units,
00229 DviUnits to_units,
00230
DviFile *dvif=0)
00231
throw (
DviError);
00232
static verbosities verbosity(
const verbosities level);
00238 double magnification()
const {
return netmag_; }
00246 int pt2px(
double npt)
const
00247
{
00248
return static_cast<int>
00249 (npt * dviu_per_pt_ / dviu_per_px_ + 0.5);
00250 }
00255 const string *
filename ()
const {
return &fileName_; }
00256
00257
const PkFont*
getFallbackFont(
const PkFont* desired);
00258
00270 bool haveReadPostamble()
const {
return have_preread_postamble_; }
00271
00272
private:
00273 string fileName_;
00278
int h_, v_, w_, x_, y_, z_;
00282
int hh_, vv_;
00284
int pending_hupdate_;
00286
int pending_hhupdate_;
00287
PkFont *current_font_;
00288
InputByteStream *dvif_;
00297
double dviu_per_pt_;
00298
00306
double dviu_per_px_;
00312
double dviu_per_sp_;
00313
00314
double dviu_per_(DviUnits unit);
00315
00321
const double extmag_;
00326
double netmag_;
00327
00328
00329
bool skipPage_;
00330
00334
int max_drift_;
00335
00341
int widest_page_;
00348
int deepest_page_;
00349
00350
Byte getByte();
00351
signed int getSIU(
int), getSIS(
int);
00352
unsigned int getUIU(
int);
00353
struct {
00354
unsigned int mag, l, u, s, t;
00355 } postamble_;
00356
struct {
00357
unsigned int i, num, den, mag;
00358 string comment;
00359 } preamble_;
00360
void read_postamble()
00361 throw (
DviError);
00362
bool have_preread_postamble_;
00363
bool have_read_to_postamble_;
00364
void process_preamble(
DviFilePreamble *);
00365
void fnt_def_(
double fontmag,
int nbytes);
00366
void check_duplicate_font(
int);
00367
int pixel_round(
int);
00368
int charWidth_ (
int charno);
00369
int charEscapement_ (
int charno);
00370
00371
void updateH_ (
int hup,
int hhup);
00372
void updateV_ (
int y);
00373 struct PosState {
00374
const int h, v, w, x, y, z, hh, vv;
00375 PosState(
int h,
int v,
int w,
int x,
int y,
int z,
int hh,
int vv)
00376 : h(h),v(v),w(w),x(x),y(y),z(z),hh(hh),vv(vv) { }
00377 };
00378
#if HOMEMADE_POSSTATESTACK
00379
class PosStateStack {
00380
00381
00382
00383
00384
00385
public:
00386 PosStateStack(
int size);
00387
void push(
const PosState *p);
00388
const PosState *pop();
00389
bool empty()
const {
return i == 0; }
00390
void clear();
00391
private:
00392
unsigned int size, i;
00393
const PosState **s;
00394 };
00395 PosStateStack *posStack_;
00396
#else
00397
STD::stack<PosState> posStack_;
00398
#endif
00399
static verbosities verbosity_;
00400
00401
public:
00405 class FontSet {
00406
private:
00407
FontSet();
00408 ~
FontSet();
00409
void add(
int fnt_num,
PkFont* newfont);
00410
PkFont* get(
int fnt_num);
00411
friend class DviFile;
00412
typedef STD::map<int,PkFont*> FontMap;
00413 FontMap fontMap_;
00414
public:
00419 bool empty()
const {
return fontMap_.empty(); }
00424 size_t
size()
const {
return fontMap_.size(); }
00428
class const_iterator;
00429
friend class DviFile::FontSet::const_iterator;
00430 class const_iterator {
00431
public:
00432
const PkFont*
operator*()
const throw (
DviError);
00433
const_iterator&
operator++()
throw (
DviError);
00434
bool operator==(
const const_iterator& it)
const;
00435
bool operator!=(
const const_iterator& it)
const;
00436
~const_iterator();
00437
private:
00438
const_iterator();
00439
const_iterator(FontMap m);
00440 STD::list<PkFont*> fontlist_;
00441
friend class DviFile::FontSet;
00442 };
00443
const_iterator begin() const;
00444
const_iterator end() const;
00445 private:
00446 mutable
const_iterator* myIter_;
00447 };
00448 private:
00449
FontSet fontSet_;
00450 public:
00460 const
FontSet* getFontSet()
const {
return &fontSet_; }
00461
00462
00463
#if 0
00464
public:
00465
class const_iterator {
00466
public:
00467
const PkFont*
operator*() const throw (
DviBug);
00468 const_iterator& operator++();
00469
bool operator==(const const_iterator& it) const;
00470
bool operator!=(const const_iterator& it) const;
00471 #if 0
00472
bool operator==(const const_iterator& it)
const
00473
{
return finished_ == it.finished_; }
00474
bool operator!=(
const const_iterator& it)
const
00475
{
return finished_ != it.finished_; }
00476
#endif
00477
private:
00478
00479
00480
00481 const_iterator(FontMap::const_iterator m,
00482 FontMap::const_iterator me) {
00483 mapiter_ = m;
00484 endmapiter_ = me;
00485 finished_ =
false;
00486 };
00487 const_iterator() : finished_(true) { }
00488 FontMap::const_iterator mapiter_;
00489 FontMap::const_iterator endmapiter_;
00490
bool finished_;
00491
friend class DviFile;
00492 };
00500 const_iterator
begin() {
00501
return const_iterator(fontMap_.begin(), fontMap_.end());
00502 }
00509 const_iterator
end()
const {
return const_iterator(); };
00510
friend class const_iterator;
00511
#endif
00512
};
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00542 class DviFileEvent {
00543
public:
00544 enum eventTypes { setchar, setrule, fontchange, special,
00545 page, preamble, postamble };
00549
virtual void debug() const;
00550
00559 eventTypes type()
const {
return type_; }
00560
00565 const unsigned char opcode()
const {
return opcode_; }
00566
00567
void release();
00568
00569
static verbosities verbosity(
const verbosities level);
00570
00571
protected:
00572
DviFileEvent(
unsigned char opcode, eventTypes t,
DviFile *dp=0);
00573
static verbosities verbosity_;
00574
00575
private:
00576
const unsigned char opcode_;
00577
DviFile *dviFile_;
00578
const eventTypes type_;
00579
00580
static void releaseEvent(
DviFileEvent *e);
00581 };
00582 class DviFileSetChar :
public DviFileEvent {
00583
public:
00589
DviFileSetChar(
int charno,
DviFile *dptr);
00590
DviFileSetChar(
int opcode,
int charno,
DviFile *dptr);
00591
void debug()
const;
00596 const int charno()
const {
return charno_; }
00597
private:
00598
const int charno_;
00599 };
00600 class DviFileSetRule:
public DviFileEvent {
00601
public:
00606 const int h;
00611 const int w;
00612 DviFileSetRule(
unsigned char opcode,
DviFile *dptr,
int h,
int w)
00613 :
DviFileEvent(opcode, setrule, dptr), h(h), w(w) { }
00614
void debug() const;
00615 };
00616 class
DviFileFontChange : public
DviFileEvent {
00617
public:
00618 DviFileFontChange(
unsigned char opcode,
PkFont *f)
00619 : DviFileEvent(opcode, fontchange), font(f) { }
00620
void debug() const;
00622 const
PkFont *font;
00623 };
00624 class
DviFileSpecial : public DviFileEvent {
00625
public:
00626 DviFileSpecial(
unsigned char opcode, string str)
00627 : DviFileEvent(opcode, special), specialString(str) { }
00629 const string specialString;
00630
void debug() const;
00631 };
00632 class
DviFilePage : public DviFileEvent {
00633
public:
00634 DviFilePage(
unsigned char opcode,
bool isStart)
00635 : DviFileEvent(opcode, page), isStart(isStart) { }
00636
void debug() const;
00643 const
bool isStart;
00648 signed int count[10];
00654 signed int previous;
00655 };
00656 class
DviFilePreamble : public DviFileEvent {
00657
public:
00658 DviFilePreamble()
00659 : DviFileEvent(247, preamble) { }
00660
void debug() const;
00665 unsigned int dviType;
00669 unsigned int num;
00673 unsigned int den;
00678 unsigned int mag;
00682 string comment;
00683 };
00684 class
DviFilePostamble : public DviFileEvent {
00685
public:
00686 DviFilePostamble()
00687 : DviFileEvent(248, postamble) { }
00688 };
00689
00690
#endif //#ifndef DVI_FILE_HEADER_READ