summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h
blob: 4a1a5f5f899b0230bbea4f90b9854cd487169906 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*************************************************************************
** DVIReader.h                                                          **
**                                                                      **
** This file is part of dvisvgm -- the DVI to SVG converter             **
** Copyright (C) 2005-2015 Martin Gieseking <martin.gieseking@uos.de>   **
**                                                                      **
** This program is free 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 3 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           **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         **
** GNU General Public License for more details.                         **
**                                                                      **
** You should have received a copy of the GNU General Public License    **
** along with this program; if not, see <http://www.gnu.org/licenses/>. **
*************************************************************************/

#ifndef DVISVGM_DVIREADER_H
#define DVISVGM_DVIREADER_H

#include <limits>
#include <map>
#include <stack>
#include <string>
#include "BasicDVIReader.h"
#include "MessageException.h"
#include "StreamReader.h"
#include "VFActions.h"
#include "types.h"


struct DVIActions;

class DVIReader : public BasicDVIReader, protected VFActions
{
	enum WritingMode {WMODE_LR=0, WMODE_TB=1, WMODE_BT=3};

	struct DVIState
	{
		double h, v;        ///< horizontal and vertical cursor position
		double x, w, y, z;  ///< additional registers to store horizontal (x, w) and vertical (y, z) positions
		WritingMode d;      ///< direction: 0: horizontal, 1: vertical(top->bottom), 3: vertical (bottom->top)
		DVIState ()   {reset();}
		void reset () {h = v = x = w = y = z = 0.0; d=WMODE_LR;}
	};

	public:
		DVIReader (std::istream &is, DVIActions *a=0);

		bool executeDocument ();
		void executeAll ();
		void executePreamble ();
		void executePostamble ();
		bool executePage (unsigned n);
		bool inPostamble () const              {return _inPostamble;}
		double getXPos () const;
		double getYPos () const;
		void finishLine ()                     {_prevYPos = std::numeric_limits<double>::min();}
		void translateToX (double x)           {_tx = x-_dviState.h-_tx;}
		void translateToY (double y)           {_ty = y-_dviState.v-_ty;}
		double getPageWidth () const           {return _pageWidth;}
		double getPageHeight () const          {return _pageHeight;}
		int getStackDepth () const             {return _stateStack.size();}
		int getCurrentFontNumber () const      {return _currFontNum;}
		unsigned getCurrentPageNumber () const {return _currPageNum;}
		unsigned numberOfPages () const        {return _bopOffsets.empty() ? 0 : _bopOffsets.size()-1;}
		DVIActions* getActions () const        {return _actions;}
		DVIActions* replaceActions (DVIActions *a);

	protected:
		void collectBopOffsets ();
		size_t numberOfPageBytes (int n) const {return _bopOffsets.size() > 1 ? _bopOffsets[n+1]-_bopOffsets[n] : 0;}
		int executeCommand ();
		void moveRight (double dx);
		void moveDown (double dy);
		void putChar (UInt32 c, bool moveCursor);
		void putGlyphArray (bool xonly);
		void defineFont (UInt32 fontnum, const std::string &name, UInt32 cs, double ds, double ss);
		virtual void beginPage (unsigned pageno, Int32 *c) {}
		virtual void endPage (unsigned pageno) {}

		// VFAction methods
		void defineVFFont (UInt32 fontnum, std::string path, std::string name, UInt32 checksum, double dsize, double ssize);
		void defineVFChar (UInt32 c, std::vector<UInt8> *dvi);

		// the following methods represent the DVI commands
		// they are called by executeCommand and should not be used directly
		void cmdSetChar0 (int c);
		void cmdSetChar (int len);
		void cmdPutChar (int len);
		void cmdSetRule (int len);
		void cmdPutRule (int len);
		void cmdNop (int len);
		void cmdBop (int len);
		void cmdEop (int len);
		void cmdPush (int len);
		void cmdPop (int len);
		void cmdDir (int len);
		void cmdRight (int len);
		void cmdDown (int len);
		void cmdX0 (int len);
		void cmdY0 (int len);
		void cmdW0 (int len);
		void cmdZ0 (int len);
		void cmdX (int len);
		void cmdY (int len);
		void cmdW (int len);
		void cmdZ (int len);
		void cmdFontDef (int len);
		void cmdFontNum0 (int n);
		void cmdFontNum (int len);
		void cmdXXX (int len);
		void cmdPre (int len);
		void cmdPost (int len);
		void cmdPostPost (int len);
		void cmdXPic (int len);
		void cmdXFontDef (int len);
		void cmdXGlyphArray (int len);
		void cmdXGlyphString (int len);

	private:
		DVIActions *_actions;    ///< actions to be performed on various DVI events
		bool _inPage;            ///< true if between bop and eop
		unsigned _currPageNum;   ///< current page number (1 is first page)
		int _currFontNum;        ///< current font number
		double _dvi2bp;          ///< factor to convert dvi units to PS points
		UInt32 _mag;             ///< magnification factor * 1000
		bool _inPostamble;       ///< true if stream pointer is inside the postamble
		double _pageHeight, _pageWidth;  ///< page height and width in PS points
		DVIState _dviState;      ///< current cursor position
		std::stack<DVIState> _stateStack;
		std::vector<UInt32> _bopOffsets;
		double _prevYPos;        ///< previous vertical cursor position
		double _tx, _ty;         ///< tranlation of cursor position
		std::streampos _pagePos; ///< distance of current DVI command from bop (in bytes)

	public:
		static bool COMPUTE_PROGRESS;  ///< if true, an action to handle the progress ratio of a page is triggered
};

#endif