1 /*
2  * Copyright (C) 2000, Matias Atria
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 #ifndef _MDVI_DVI_H
19 #define _MDVI_DVI_H 1
20 
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <math.h>
24 
25 #include "sysdeps.h"
26 #include "bitmap.h"
27 #include "common.h"
28 #include "defaults.h"
29 #include "dviopcodes.h"
30 
31 typedef struct _DviGlyph DviGlyph;
32 typedef struct _DviDevice DviDevice;
33 typedef struct _DviFontChar DviFontChar;
34 typedef struct _DviFontRef DviFontRef;
35 typedef struct _DviFontInfo DviFontInfo;
36 typedef struct _DviFont DviFont;
37 typedef struct _DviState DviState;
38 typedef struct _DviPageSpec *DviPageSpec;
39 typedef struct _DviParams DviParams;
40 typedef struct _DviBuffer DviBuffer;
41 typedef struct _DviContext DviContext;
42 typedef struct _DviRange DviRange;
43 typedef struct _DviColorPair DviColorPair;
44 typedef struct _DviSection DviSection;
45 typedef struct _TFMChar TFMChar;
46 typedef struct _TFMInfo TFMInfo;
47 typedef struct _DviFontSearch DviFontSearch;
48 /* this is an opaque type */
49 typedef struct _DviFontClass DviFontClass;
50 
51 typedef void (*DviFreeFunc) __PROTO((void *));
52 typedef void (*DviFree2Func) __PROTO((void *, void *));
53 
54 typedef Ulong	DviColor;
55 
56 #ifdef TRUE
57 #undef TRUE
58 #endif
59 #ifdef FALSE
60 #undef FALSE
61 #endif
62 
63 typedef enum {
64 	FALSE	= 0,
65 	TRUE	= 1
66 } DviBool;
67 
68 #include "hash.h"
69 #include "paper.h"
70 
71 /*
72  * information about a page:
73  *   pagenum[0] = offset to BOP
74  *   pagenum[1], ..., pagenum[10] = TeX \counters
75  */
76 typedef long	PageNum[11];
77 
78 /* this structure contains the platform-specific information
79  * required to interpret a DVI file */
80 
81 typedef void (*DviGlyphDraw)	__PROTO((DviContext *context,
82 				          DviFontChar *glyph,
83 				          int x, int y));
84 
85 typedef void (*DviRuleDraw)	__PROTO((DviContext *context,
86 				          int x, int y,
87 				          Uint width, Uint height, int fill));
88 
89 typedef int (*DviColorScale) 	__PROTO((void *device_data,
90 				         Ulong *pixels,
91 				         int npixels,
92 				         Ulong foreground,
93 				         Ulong background,
94 				         double gamma,
95 				         int density));
96 typedef void *(*DviCreateImage)	__PROTO((void *device_data,
97 				         Uint width,
98 				         Uint height,
99 				         Uint bpp));
100 typedef void (*DviFreeImage)	__PROTO((void *image));
101 typedef void (*DviPutPixel)	__PROTO((void *image, int x, int y, Ulong color));
102 typedef void (*DviImageDone)    __PROTO((void *image));
103 typedef void (*DviDevDestroy)   __PROTO((void *data));
104 typedef void (*DviRefresh)      __PROTO((DviContext *dvi, void *device_data));
105 typedef void (*DviSetColor)	__PROTO((void *device_data, Ulong, Ulong));
106 typedef void (*DviPSDraw)       __PROTO((DviContext *context,
107 					 const char *filename,
108 					 int x, int y,
109 					 Uint width, Uint height));
110 
111 struct _DviDevice {
112 	DviGlyphDraw	draw_glyph;
113 	DviRuleDraw	draw_rule;
114 	DviColorScale	alloc_colors;
115 	DviCreateImage	create_image;
116 	DviFreeImage	free_image;
117 	DviPutPixel	put_pixel;
118         DviImageDone    image_done;
119 	DviDevDestroy	dev_destroy;
120 	DviRefresh	refresh;
121 	DviSetColor	set_color;
122 	DviPSDraw       draw_ps;
123 	void *		device_data;
124 };
125 
126 /*
127  * Fonts
128  */
129 
130 #include "fontmap.h"
131 
132 struct _TFMChar {
133 	Int32	present;
134 	Int32	advance;	/* advance */
135 	Int32	height;		/* ascent */
136 	Int32	depth;		/* descent */
137 	Int32	left;		/* leftSideBearing */
138 	Int32	right;		/* rightSideBearing */
139 };
140 
141 struct _TFMInfo {
142 	int	type; /* DviFontAFM, DviFontTFM, DviFontOFM */
143 	Uint32	checksum;
144 	Uint32	design;
145 	int	loc;
146 	int	hic;
147 	char	coding[64];
148 	char	family[64];
149 	TFMChar *chars;
150 };
151 
152 struct _DviGlyph {
153 	short	x, y;	/* origin */
154 	Uint	w, h;	/* dimensions */
155 	void	*data;	/* bitmap or XImage */
156 };
157 
158 typedef void (*DviFontShrinkFunc)
159 	__PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
160 typedef int (*DviFontLoadFunc) __PROTO((DviParams *, DviFont *));
161 typedef int (*DviFontGetGlyphFunc) __PROTO((DviParams *, DviFont *, int));
162 typedef void (*DviFontFreeFunc) __PROTO((DviFont *));
163 typedef void (*DviFontResetFunc) __PROTO((DviFont *));
164 typedef char *(*DviFontLookupFunc) __PROTO((const char *, Ushort *, Ushort *));
165 typedef int (*DviFontEncodeFunc) __PROTO((DviParams *, DviFont *, DviEncoding *));
166 
167 struct _DviFontInfo {
168 	char	*name;	/* human-readable format identifying string */
169 	int	scalable; /* does it support scaling natively? */
170 	DviFontLoadFunc		load;
171 	DviFontGetGlyphFunc	getglyph;
172 	DviFontShrinkFunc 	shrink0;
173 	DviFontShrinkFunc 	shrink1;
174 	DviFontFreeFunc		freedata;
175 	DviFontResetFunc	reset;
176 	DviFontLookupFunc	lookup;
177 	int			kpse_type;
178 	void *			private;
179 };
180 
181 struct _DviFontChar {
182 	Uint32	offset;
183 	Int16	code;		/* format-dependent, not used by MDVI */
184 	Int16	width;
185 	Int16	height;
186 	Int16	x;
187 	Int16	y;
188 	Int32	tfmwidth;
189 	Ushort	flags;
190 #ifdef __STRICT_ANSI__
191 	Ushort	loaded;
192 	Ushort	missing;
193 #else
194 	Ushort	loaded : 1,
195 		missing : 1;
196 #endif
197 	Ulong	fg;
198 	Ulong	bg;
199 	BITMAP	*glyph_data;
200 	/* data for shrunk bitimaps */
201 	DviGlyph glyph;
202 	DviGlyph shrunk;
203 	DviGlyph grey;
204 };
205 
206 struct _DviFontRef {
207 	DviFontRef *next;
208 	DviFont	*ref;
209 	Int32	fontid;
210 };
211 
212 typedef enum {
213 	DviFontAny  = -1,
214 	DviFontPK   = 0,
215 	DviFontGF   = 1,
216 	DviFontVF   = 2,
217 	DviFontTFM  = 3,
218 	DviFontT1   = 4,
219 	DviFontTT   = 5,
220 	DviFontAFM  = 6,
221 	DviFontOFM  = 7
222 } DviFontType;
223 
224 struct _DviFontSearch {
225 	int	id;
226 	Ushort	hdpi;
227 	Ushort	vdpi;
228 	Ushort	actual_hdpi;
229 	Ushort	actual_vdpi;
230 	const char *wanted_name;
231 	const char *actual_name;
232 	DviFontClass *curr;
233 	DviFontInfo  *info;
234 };
235 
236 /* this is a kludge, I know */
237 #define ISVIRTUAL(font)	((font)->search.info->getglyph == NULL)
238 #define SEARCH_DONE(s)	((s).id < 0)
239 #define SEARCH_INIT(s, name, h, v) do { \
240 	(s).id = 0; \
241 	(s).curr = NULL; \
242 	(s).hdpi = (h); \
243 	(s).vdpi = (v); \
244 	(s).wanted_name = (name); \
245 	(s).actual_name = NULL; \
246 	} while(0)
247 
248 struct _DviFont {
249 	DviFont *next;
250 	DviFont *prev;
251 	int	type;
252 	Int32	checksum;
253 	int	hdpi;
254 	int	vdpi;
255 	Int32	scale;
256 	Int32	design;
257 	FILE	*in;
258 	char	*fontname;
259 	char	*filename;
260 	int	links;
261 	int	loc;
262 	int	hic;
263 	Uint	flags;
264 	DviFontSearch	search;
265 	DviFontChar	*chars;
266 	DviFontRef	*subfonts;
267 	void	*private;
268 };
269 
270 /*
271  * Dvi context
272  */
273 
274 typedef enum {
275 	MDVI_ORIENT_TBLR  = 0,	/* top to bottom, left to right */
276 	MDVI_ORIENT_TBRL  = 1,	/* top to bottom, right to left */
277 	MDVI_ORIENT_BTLR  = 2,	/* bottom to top, left to right */
278 	MDVI_ORIENT_BTRL  = 3,	/* bottom to top, right to left */
279 	MDVI_ORIENT_RP90  = 4,	/* rotated +90 degrees (counter-clockwise) */
280 	MDVI_ORIENT_RM90  = 5,	/* rotated -90 degrees (clockwise) */
281 	MDVI_ORIENT_IRP90 = 6,	/* flip horizontally, then rotate by +90 */
282 	MDVI_ORIENT_IRM90 = 7	/* rotate by -90, then flip horizontally */
283 } DviOrientation;
284 
285 typedef enum {
286 	MDVI_PAGE_SORT_UP,	/* up, using \counter0 */
287 	MDVI_PAGE_SORT_DOWN,	/* down, using \counter0 */
288 	MDVI_PAGE_SORT_RANDOM,	/* randomly */
289 	MDVI_PAGE_SORT_DVI_UP,	/* up, by location in DVI file */
290 	MDVI_PAGE_SORT_DVI_DOWN,	/* down, by location in DVI file */
291 	MDVI_PAGE_SORT_NONE	/* don't sort */
292 } DviPageSort;
293 
294 struct _DviParams {
295 	double	mag;		/* magnification */
296 	double	conv;		/* horizontal DVI -> pixel */
297 	double	vconv;		/* vertical DVI -> pixel */
298 	double	tfm_conv;	/* TFM -> DVI */
299 	double	gamma;		/* gamma correction factor */
300 	Uint	dpi;		/* horizontal resolution */
301 	Uint	vdpi;		/* vertical resolution */
302 	int	hshrink;	/* horizontal shrinking factor */
303 	int	vshrink;	/* vertical shrinking factor */
304 	Uint	density;	/* pixel density */
305 	Uint	flags;		/* flags (see MDVI_PARAM macros) */
306 	int	hdrift;		/* max. horizontal drift */
307 	int	vdrift;		/* max. vertical drift */
308 	int	vsmallsp;	/* small vertical space */
309 	int	thinsp;		/* small horizontal space */
310 	int	layer;		/* visible layer (for layered DVI files) */
311 	Ulong	fg;		/* foreground color */
312 	Ulong	bg;		/* background color */
313 	DviOrientation	orientation;	/* page orientation */
314 	int	base_x;
315 	int	base_y;
316 };
317 
318 typedef enum {
319 	MDVI_PARAM_LAST		= 0,
320 	MDVI_SET_DPI    	= 1,
321 	MDVI_SET_XDPI   	= 2,
322 	MDVI_SET_YDPI   	= 3,
323 	MDVI_SET_SHRINK		= 4,
324 	MDVI_SET_XSHRINK	= 5,
325 	MDVI_SET_YSHRINK	= 6,
326 	MDVI_SET_GAMMA		= 7,
327 	MDVI_SET_DENSITY	= 8,
328 	MDVI_SET_MAGNIFICATION	= 9,
329 	MDVI_SET_DRIFT		= 10,
330 	MDVI_SET_HDRIFT		= 11,
331 	MDVI_SET_VDRIFT		= 12,
332 	MDVI_SET_ORIENTATION	= 13,
333 	MDVI_SET_FOREGROUND	= 14,
334 	MDVI_SET_BACKGROUND	= 15
335 } DviParamCode;
336 
337 struct _DviBuffer {
338 	Uchar	*data;
339 	size_t	size;		/* allocated size */
340 	size_t	length;		/* amount of data buffered */
341 	size_t	pos;		/* current position in buffer */
342 	int	frozen;		/* can we free this data? */
343 };
344 
345 /* DVI registers */
346 struct _DviState {
347 	int	h;
348 	int	v;
349 	int	hh;
350 	int	vv;
351 	int	w;
352 	int	x;
353 	int	y;
354 	int	z;
355 };
356 
357 struct _DviColorPair {
358 	Ulong	fg;
359 	Ulong	bg;
360 };
361 
362 struct _DviContext {
363 	char	*filename;	/* name of the DVI file */
364 	FILE	*in;		/* from here we read */
365 	char	*fileid;	/* from preamble */
366 	int	npages;		/* number of pages */
367 	int	currpage;	/* current page (0 based) */
368 	int	depth;		/* recursion depth */
369 	DviBuffer buffer;	/* input buffer */
370 	DviParams params;	/* parameters */
371 	DviPaper  paper;	/* paper type */
372 	Int32	num;		/* numerator */
373 	Int32	den;		/* denominator */
374 	DviFontRef *fonts;	/* fonts used in this file */
375 	DviFontRef **fontmap;	/* for faster id lookups */
376 	DviFontRef *currfont;	/* current font */
377 	int	nfonts;		/* # of fonts used in this job */
378 	Int32	dvimag;		/* original magnification */
379 	double	dviconv;	/* unshrunk scaling factor */
380 	double	dvivconv;	/* unshrunk scaling factor (vertical) */
381 	int	dvi_page_w;	/* unscaled page width */
382 	int	dvi_page_h;	/* unscaled page height */
383 	Ulong	modtime;	/* file modification time */
384 	PageNum	*pagemap;	/* page table */
385 	DviState pos;		/* registers */
386 	DviPageSpec *pagesel;	/* page selection data */
387 	int	curr_layer;	/* current layer */
388 	DviState *stack;	/* DVI stack */
389 	int	stacksize;	/* stack depth */
390 	int	stacktop;	/* stack pointer */
391 	DviDevice device;	/* device-specific routines */
392 	Ulong	curr_fg;	/* rendering color */
393 	Ulong	curr_bg;
394 
395 	DviColorPair *color_stack;
396 	int	color_top;
397 	int	color_size;
398 
399 	DviFontRef *(*findref) __PROTO((DviContext *, Int32));
400 	void	*user_data;	/* client data attached to this context */
401 };
402 
403 typedef enum {
404 	MDVI_RANGE_BOUNDED,	/* range is finite */
405 	MDVI_RANGE_LOWER,	/* range has a lower bound */
406 	MDVI_RANGE_UPPER,	/* range has an upper bound */
407 	MDVI_RANGE_UNBOUNDED	/* range has no bounds at all */
408 } DviRangeType;
409 
410 struct _DviRange {
411 	DviRangeType type;	/* one of the above */
412 	int	from;		/* lower bound */
413 	int	to;		/* upper bound */
414 	int	step;		/* step */
415 };
416 
417 
418 typedef void (*DviSpecialHandler)
419 	__PROTO((DviContext *dvi, const char *prefix, const char *arg));
420 
421 #define RANGE_HAS_LOWER(x) \
422 	((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_LOWER)
423 #define RANGE_HAS_UPPER(x) \
424 	((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_UPPER)
425 
426 /*
427  * Macros and prototypes
428  */
429 
430 #define MDVI_PARAM_ANTIALIASED	1
431 #define MDVI_PARAM_MONO		2
432 #define MDVI_PARAM_CHARBOXES	4
433 #define MDVI_PARAM_SHOWUNDEF	8
434 #define MDVI_PARAM_DELAYFONTS	16
435 
436 /*
437  * The FALLBACK priority class is reserved for font formats that
438  * contain no glyph information and are to be used as a last
439  * resort (e.g. TFM, AFM)
440  */
441 #define MDVI_FONTPRIO_FALLBACK	-3
442 #define MDVI_FONTPRIO_LOWEST	-2
443 #define MDVI_FONTPRIO_LOW	-1
444 #define MDVI_FONTPRIO_NORMAL	0
445 #define MDVI_FONTPRIO_HIGH	1
446 #define MDVI_FONTPRIO_HIGHEST	2
447 
448 #define MDVI_FONT_ENCODED	(1 << 0)
449 
450 #define MDVI_GLYPH_EMPTY	((void *)1)
451 /* does the glyph have a non-empty bitmap/image? */
452 #define MDVI_GLYPH_NONEMPTY(x)	((x) && (x) != MDVI_GLYPH_EMPTY)
453 /* has the glyph been loaded from disk? */
454 #define MDVI_GLYPH_UNSET(x)	((x) == NULL)
455 /* do we have only a bounding box for this glyph? */
456 #define MDVI_GLYPH_ISEMPTY(x)	((x) == MDVI_GLYPH_EMPTY)
457 
458 #define MDVI_ENABLED(d,x)	((d)->params.flags & (x))
459 #define MDVI_DISABLED(d,x)	!MDVI_ENABLED((d), (x))
460 
461 #define MDVI_LASTPAGE(d)	((d)->npages - 1)
462 #define MDVI_NPAGES(d)		(d)->npages
463 #define MDVI_VALIDPAGE(d,p)	((p) >= 0 && (p) <= MDVI_LASTPAGE(d))
464 #define MDVI_FLAGS(d)		(d)->params.flags
465 #define MDVI_SHRINK_FROM_DPI(d)	Max(1, (d) / 75)
466 #define MDVI_CURRFG(d)		(d)->curr_fg
467 #define MDVI_CURRBG(d)		(d)->curr_bg
468 
469 #define pixel_round(d,v)	(int)((d)->params.conv * (v) + 0.5)
470 #define vpixel_round(d,v)	(int)((d)->params.vconv * (v) + 0.5)
471 #define rule_round(d,v)		(int)((d)->params.conv * (v) + 0.99999) /*9999999)*/
472 #define vrule_round(d,v)	(int)((d)->params.vconv * (v) + 0.99999)
473 
474 extern int	mdvi_reload __PROTO((DviContext *, DviParams *));
475 extern void	mdvi_setpage __PROTO((DviContext *, int));
476 extern int  	mdvi_dopage __PROTO((DviContext *, int));
477 extern void 	mdvi_shrink_glyph __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
478 extern void	mdvi_shrink_box __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
479 extern void 	mdvi_shrink_glyph_grey __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
480 extern int	mdvi_find_tex_page __PROTO((DviContext *, int));
481 extern int	mdvi_configure __PROTO((DviContext *, DviParamCode, ...));
482 
483 extern int	get_tfm_chars __PROTO((DviParams *, DviFont *, TFMInfo *, int));
484 extern int 	tfm_load_file __PROTO((const char *, TFMInfo *));
485 extern int	afm_load_file __PROTO((const char *, TFMInfo *));
486 extern TFMInfo *get_font_metrics __PROTO((const char *, int, const char *));
487 extern char    *lookup_font_metrics __PROTO((const char *, int *));
488 extern void	free_font_metrics __PROTO((TFMInfo *));
489 extern void	flush_font_metrics __PROTO((void));
490 
491 #define get_metrics(name)	get_font_metrics((name), DviFontAny, NULL)
492 
493 extern void	mdvi_sort_pages __PROTO((DviContext *, DviPageSort));
494 
495 extern void mdvi_init_kpathsea __PROTO((const char *, const char *, const char *, int, const char *));
496 
497 extern DviContext* mdvi_init_context __PROTO((DviParams *, DviPageSpec *, const char *));
498 extern void 	mdvi_destroy_context __PROTO((DviContext *));
499 
500 /* helper macros that call mdvi_configure() */
501 #define mdvi_config_one(d,x,y)	mdvi_configure((d), (x), (y), MDVI_PARAM_LAST)
502 #define mdvi_set_dpi(d,x)	mdvi_config_one((d), MDVI_SET_DPI, (x))
503 #define mdvi_set_xdpi(d,x)	mdvi_config_one((d), MDVI_SET_XDPI, (x))
504 #define mdvi_set_ydpi(d,x)	mdvi_config_one((d), MDVI_SET_YDPI, (x))
505 #define mdvi_set_hshrink(d,h)	mdvi_config_one((d), MDVI_SET_XSHRINK, (h))
506 #define mdvi_set_vshrink(d,h)	mdvi_config_one((d), MDVI_SET_YSHRINK, (h))
507 #define mdvi_set_gamma(d,g)	mdvi_config_one((d), MDVI_SET_GAMMA, (g))
508 #define mdvi_set_density(d,x)	mdvi_config_one((d), MDVI_SET_DENSITY, (x))
509 #define mdvi_set_drift(d,x)	mdvi_config_one((d), MDVI_SET_DRIFT, (x))
510 #define mdvi_set_hdrift(d,h)	mdvi_config_one((d), MDVI_SET_HDRIFT, (h))
511 #define mdvi_set_vdrift(d,v)	mdvi_config_one((d), MDVI_SET_VDRIFT, (v))
512 #define mdvi_set_mag(d,m) \
513 	mdvi_config_one((d), MDVI_SET_MAGNIFICATION, (m))
514 #define mdvi_set_foreground(d,x) \
515 	mdvi_config_one((d), MDVI_SET_FOREGROUND, (x))
516 #define mdvi_set_background(d,x) \
517 	mdvi_config_one((d), MDVI_SET_BACKGROUND, (x))
518 #define mdvi_set_orientation(d,x) \
519 	mdvi_config_one((d), MDVI_SET_ORIENTATION, (x))
520 #define mdvi_set_shrink(d,h,v)	\
521 	mdvi_configure((d), MDVI_SET_XSHRINK, (h), \
522 	MDVI_SET_YSHRINK, (v), MDVI_PARAM_LAST)
523 
524 extern DviRange* mdvi_parse_range __PROTO((const char *, DviRange *, int *, char **));
525 extern DviPageSpec* mdvi_parse_page_spec __PROTO((const char *));
526 extern void mdvi_free_page_spec __PROTO((DviPageSpec *));
527 extern int mdvi_in_range __PROTO((DviRange *, int, int));
528 extern int mdvi_range_length __PROTO((DviRange *, int));
529 extern int mdvi_page_selected __PROTO((DviPageSpec *, PageNum, int));
530 
531 /* Specials */
532 extern int mdvi_register_special __PROTO((
533 	const char *label,
534 	const char *prefix,
535 	const char *regex,
536 	DviSpecialHandler handler,
537 	int replace));
538 extern int mdvi_unregister_special __PROTO((const char *prefix));
539 extern int mdvi_do_special __PROTO((DviContext *dvi, char *dvi_special));
540 extern void mdvi_flush_specials __PROTO((void));
541 
542 /* Fonts */
543 
544 #define MDVI_FONTSEL_BITMAP	(1 << 0)
545 #define MDVI_FONTSEL_GREY	(1 << 1)
546 #define MDVI_FONTSEL_GLYPH	(1 << 2)
547 
548 #define FONTCHAR(font, code)	\
549 	(((code) < font->loc || (code) > font->hic || !(font)->chars) ? \
550 		NULL : &font->chars[(code) - (font)->loc])
551 #define FONT_GLYPH_COUNT(font) ((font)->hic - (font)->loc + 1)
552 
553 #define glyph_present(x) ((x) && (x)->offset)
554 
555 /* create a reference to a font */
556 extern DviFontRef *font_reference __PROTO((DviParams *params,
557                                            Int32 dvi_id,
558                                            const char *font_name,
559                                            Int32 checksum,
560                                            int xdpi,
561                                            int ydpi,
562                                            Int32 scale_factor));
563 
564 /* drop a reference to a font */
565 extern void font_drop_one __PROTO((DviFontRef *));
566 
567 /* drop a chain of references */
568 extern void font_drop_chain __PROTO((DviFontRef *));
569 
570 /* destroy selected information for a glyph */
571 extern void font_reset_one_glyph __PROTO((DviDevice *, DviFontChar *, int));
572 
573 /* destroy selected information for all glyphs in a font */
574 extern void font_reset_font_glyphs __PROTO((DviDevice *, DviFont *, int));
575 
576 /* same for a chain of font references */
577 extern void font_reset_chain_glyphs __PROTO((DviDevice *, DviFontRef *, int));
578 
579 extern void font_finish_definitions __PROTO((DviContext *));
580 
581 /* lookup an id # in a reference chain */
582 extern DviFontRef* font_find_flat __PROTO((DviContext *, Int32));
583 extern DviFontRef* font_find_mapped __PROTO((DviContext *, Int32));
584 
585 /* called to reopen (or rewind) a font file */
586 extern int font_reopen __PROTO((DviFont *));
587 
588 /* reads a glyph from a font, and makes all necessary transformations */
589 extern DviFontChar* font_get_glyph __PROTO((DviContext *, DviFont *, int));
590 
591 /* transform a glyph according to the given orientation */
592 extern void font_transform_glyph __PROTO((DviOrientation, DviGlyph *));
593 
594 /* destroy all fonts that are not being used, returns number of fonts freed */
595 extern int font_free_unused __PROTO((DviDevice *));
596 
597 #define font_free_glyph(dev, font, code) \
598 	font_reset_one_glyph((dev), \
599 	FONTCHAR((font), (code)), MDVI_FONTSEL_GLYPH)
600 
601 extern int mdvi_encode_font __PROTO((DviParams *, DviFont *));
602 
603 
604 /* font lookup functions */
605 extern int mdvi_register_font_type __PROTO((DviFontInfo *, int));
606 extern char **mdvi_list_font_class __PROTO((int));
607 extern int mdvi_get_font_classes __PROTO((void));
608 extern int mdvi_unregister_font_type __PROTO((const char *, int));
609 extern char *mdvi_lookup_font __PROTO((DviFontSearch *));
610 extern DviFont *mdvi_add_font __PROTO((const char *, Int32, int, int, Int32));
611 extern int mdvi_font_retry __PROTO((DviParams *, DviFont *));
612 
613 /* Miscellaneous */
614 
615 extern int mdvi_set_logfile __PROTO((const char *));
616 extern int mdvi_set_logstream __PROTO((FILE *));
617 extern int mdvi_set_loglevel __PROTO((int));
618 
619 #define mdvi_stop_logging(x) mdvi_set_logstream(NULL)
620 
621 /* this will check the environment and then `texmf.cnf' for
622  * the given name changed to lowercase, and `_' changed to `-' */
623 extern char* mdvi_getenv __PROTO((const char *));
624 
625 #endif /* _MDVI_DVI_H */
626