/* * Copyright (C) 2000, Matias Atria * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MDVI_DVI_H #define _MDVI_DVI_H 1 #include <stdio.h> #include <sys/types.h> #include <math.h> #include "sysdeps.h" #include "bitmap.h" #include "common.h" #include "defaults.h" #include "dviopcodes.h" typedef struct _DviGlyph DviGlyph; typedef struct _DviDevice DviDevice; typedef struct _DviFontChar DviFontChar; typedef struct _DviFontRef DviFontRef; typedef struct _DviFontInfo DviFontInfo; typedef struct _DviFont DviFont; typedef struct _DviState DviState; typedef struct _DviPageSpec *DviPageSpec; typedef struct _DviParams DviParams; typedef struct _DviBuffer DviBuffer; typedef struct _DviContext DviContext; typedef struct _DviRange DviRange; typedef struct _DviColorPair DviColorPair; typedef struct _DviSection DviSection; typedef struct _TFMChar TFMChar; typedef struct _TFMInfo TFMInfo; typedef struct _DviFontSearch DviFontSearch; /* this is an opaque type */ typedef struct _DviFontClass DviFontClass; typedef void (*DviFreeFunc) __PROTO((void *)); typedef void (*DviFree2Func) __PROTO((void *, void *)); typedef Ulong DviColor; #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif typedef enum { FALSE = 0, TRUE = 1 } DviBool; #include "hash.h" #include "paper.h" /* * information about a page: * pagenum[0] = offset to BOP * pagenum[1], ..., pagenum[10] = TeX \counters */ typedef long PageNum[11]; /* this structure contains the platform-specific information * required to interpret a DVI file */ typedef void (*DviGlyphDraw) __PROTO((DviContext *context, DviFontChar *glyph, int x, int y)); typedef void (*DviRuleDraw) __PROTO((DviContext *context, int x, int y, Uint width, Uint height, int fill)); typedef int (*DviColorScale) __PROTO((void *device_data, Ulong *pixels, int npixels, Ulong foreground, Ulong background, double gamma, int density)); typedef void *(*DviCreateImage) __PROTO((void *device_data, Uint width, Uint height, Uint bpp)); typedef void (*DviFreeImage) __PROTO((void *image)); typedef void (*DviPutPixel) __PROTO((void *image, int x, int y, Ulong color)); typedef void (*DviImageDone) __PROTO((void *image)); typedef void (*DviDevDestroy) __PROTO((void *data)); typedef void (*DviRefresh) __PROTO((DviContext *dvi, void *device_data)); typedef void (*DviSetColor) __PROTO((void *device_data, Ulong, Ulong)); typedef void (*DviPSDraw) __PROTO((DviContext *context, const char *filename, int x, int y, Uint width, Uint height)); struct _DviDevice { DviGlyphDraw draw_glyph; DviRuleDraw draw_rule; DviColorScale alloc_colors; DviCreateImage create_image; DviFreeImage free_image; DviPutPixel put_pixel; DviImageDone image_done; DviDevDestroy dev_destroy; DviRefresh refresh; DviSetColor set_color; DviPSDraw draw_ps; void * device_data; }; /* * Fonts */ #include "fontmap.h" struct _TFMChar { Int32 present; Int32 advance; /* advance */ Int32 height; /* ascent */ Int32 depth; /* descent */ Int32 left; /* leftSideBearing */ Int32 right; /* rightSideBearing */ }; struct _TFMInfo { int type; /* DviFontAFM, DviFontTFM, DviFontOFM */ Uint32 checksum; Uint32 design; int loc; int hic; char coding[64]; char family[64]; TFMChar *chars; }; struct _DviGlyph { short x, y; /* origin */ Uint w, h; /* dimensions */ void *data; /* bitmap or XImage */ }; typedef void (*DviFontShrinkFunc) __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); typedef int (*DviFontLoadFunc) __PROTO((DviParams *, DviFont *)); typedef int (*DviFontGetGlyphFunc) __PROTO((DviParams *, DviFont *, int)); typedef void (*DviFontFreeFunc) __PROTO((DviFont *)); typedef void (*DviFontResetFunc) __PROTO((DviFont *)); typedef char *(*DviFontLookupFunc) __PROTO((const char *, Ushort *, Ushort *)); typedef int (*DviFontEncodeFunc) __PROTO((DviParams *, DviFont *, DviEncoding *)); struct _DviFontInfo { char *name; /* human-readable format identifying string */ int scalable; /* does it support scaling natively? */ DviFontLoadFunc load; DviFontGetGlyphFunc getglyph; DviFontShrinkFunc shrink0; DviFontShrinkFunc shrink1; DviFontFreeFunc freedata; DviFontResetFunc reset; DviFontLookupFunc lookup; int kpse_type; void * private; }; struct _DviFontChar { Uint32 offset; Int16 code; /* format-dependent, not used by MDVI */ Int16 width; Int16 height; Int16 x; Int16 y; Int32 tfmwidth; Ushort flags; #ifdef __STRICT_ANSI__ Ushort loaded; Ushort missing; #else Ushort loaded : 1, missing : 1; #endif Ulong fg; Ulong bg; BITMAP *glyph_data; /* data for shrunk bitimaps */ DviGlyph glyph; DviGlyph shrunk; DviGlyph grey; }; struct _DviFontRef { DviFontRef *next; DviFont *ref; Int32 fontid; }; typedef enum { DviFontAny = -1, DviFontPK = 0, DviFontGF = 1, DviFontVF = 2, DviFontTFM = 3, DviFontT1 = 4, DviFontTT = 5, DviFontAFM = 6, DviFontOFM = 7 } DviFontType; struct _DviFontSearch { int id; Ushort hdpi; Ushort vdpi; Ushort actual_hdpi; Ushort actual_vdpi; const char *wanted_name; const char *actual_name; DviFontClass *curr; DviFontInfo *info; }; /* this is a kludge, I know */ #define ISVIRTUAL(font) ((font)->search.info->getglyph == NULL) #define SEARCH_DONE(s) ((s).id < 0) #define SEARCH_INIT(s, name, h, v) do { \ (s).id = 0; \ (s).curr = NULL; \ (s).hdpi = (h); \ (s).vdpi = (v); \ (s).wanted_name = (name); \ (s).actual_name = NULL; \ } while(0) struct _DviFont { DviFont *next; DviFont *prev; int type; Int32 checksum; int hdpi; int vdpi; Int32 scale; Int32 design; FILE *in; char *fontname; char *filename; int links; int loc; int hic; Uint flags; DviFontSearch search; DviFontChar *chars; DviFontRef *subfonts; void *private; }; /* * Dvi context */ typedef enum { MDVI_ORIENT_TBLR = 0, /* top to bottom, left to right */ MDVI_ORIENT_TBRL = 1, /* top to bottom, right to left */ MDVI_ORIENT_BTLR = 2, /* bottom to top, left to right */ MDVI_ORIENT_BTRL = 3, /* bottom to top, right to left */ MDVI_ORIENT_RP90 = 4, /* rotated +90 degrees (counter-clockwise) */ MDVI_ORIENT_RM90 = 5, /* rotated -90 degrees (clockwise) */ MDVI_ORIENT_IRP90 = 6, /* flip horizontally, then rotate by +90 */ MDVI_ORIENT_IRM90 = 7 /* rotate by -90, then flip horizontally */ } DviOrientation; typedef enum { MDVI_PAGE_SORT_UP, /* up, using \counter0 */ MDVI_PAGE_SORT_DOWN, /* down, using \counter0 */ MDVI_PAGE_SORT_RANDOM, /* randomly */ MDVI_PAGE_SORT_DVI_UP, /* up, by location in DVI file */ MDVI_PAGE_SORT_DVI_DOWN, /* down, by location in DVI file */ MDVI_PAGE_SORT_NONE /* don't sort */ } DviPageSort; struct _DviParams { double mag; /* magnification */ double conv; /* horizontal DVI -> pixel */ double vconv; /* vertical DVI -> pixel */ double tfm_conv; /* TFM -> DVI */ double gamma; /* gamma correction factor */ Uint dpi; /* horizontal resolution */ Uint vdpi; /* vertical resolution */ int hshrink; /* horizontal shrinking factor */ int vshrink; /* vertical shrinking factor */ Uint density; /* pixel density */ Uint flags; /* flags (see MDVI_PARAM macros) */ int hdrift; /* max. horizontal drift */ int vdrift; /* max. vertical drift */ int vsmallsp; /* small vertical space */ int thinsp; /* small horizontal space */ int layer; /* visible layer (for layered DVI files) */ Ulong fg; /* foreground color */ Ulong bg; /* background color */ DviOrientation orientation; /* page orientation */ int base_x; int base_y; }; typedef enum { MDVI_PARAM_LAST = 0, MDVI_SET_DPI = 1, MDVI_SET_XDPI = 2, MDVI_SET_YDPI = 3, MDVI_SET_SHRINK = 4, MDVI_SET_XSHRINK = 5, MDVI_SET_YSHRINK = 6, MDVI_SET_GAMMA = 7, MDVI_SET_DENSITY = 8, MDVI_SET_MAGNIFICATION = 9, MDVI_SET_DRIFT = 10, MDVI_SET_HDRIFT = 11, MDVI_SET_VDRIFT = 12, MDVI_SET_ORIENTATION = 13, MDVI_SET_FOREGROUND = 14, MDVI_SET_BACKGROUND = 15 } DviParamCode; struct _DviBuffer { Uchar *data; size_t size; /* allocated size */ size_t length; /* amount of data buffered */ size_t pos; /* current position in buffer */ int frozen; /* can we free this data? */ }; /* DVI registers */ struct _DviState { int h; int v; int hh; int vv; int w; int x; int y; int z; }; struct _DviColorPair { Ulong fg; Ulong bg; }; struct _DviContext { char *filename; /* name of the DVI file */ FILE *in; /* from here we read */ char *fileid; /* from preamble */ int npages; /* number of pages */ int currpage; /* currrent page (0 based) */ int depth; /* recursion depth */ DviBuffer buffer; /* input buffer */ DviParams params; /* parameters */ DviPaper paper; /* paper type */ Int32 num; /* numerator */ Int32 den; /* denominator */ DviFontRef *fonts; /* fonts used in this file */ DviFontRef **fontmap; /* for faster id lookups */ DviFontRef *currfont; /* current font */ int nfonts; /* # of fonts used in this job */ Int32 dvimag; /* original magnification */ double dviconv; /* unshrunk scaling factor */ double dvivconv; /* unshrunk scaling factor (vertical) */ int dvi_page_w; /* unscaled page width */ int dvi_page_h; /* unscaled page height */ Ulong modtime; /* file modification time */ PageNum *pagemap; /* page table */ DviState pos; /* registers */ DviPageSpec *pagesel; /* page selection data */ int curr_layer; /* current layer */ DviState *stack; /* DVI stack */ int stacksize; /* stack depth */ int stacktop; /* stack pointer */ DviDevice device; /* device-specific routines */ Ulong curr_fg; /* rendering color */ Ulong curr_bg; DviColorPair *color_stack; int color_top; int color_size; DviFontRef *(*findref) __PROTO((DviContext *, Int32)); void *user_data; /* client data attached to this context */ }; typedef enum { MDVI_RANGE_BOUNDED, /* range is finite */ MDVI_RANGE_LOWER, /* range has a lower bound */ MDVI_RANGE_UPPER, /* range has an upper bound */ MDVI_RANGE_UNBOUNDED /* range has no bounds at all */ } DviRangeType; struct _DviRange { DviRangeType type; /* one of the above */ int from; /* lower bound */ int to; /* upper bound */ int step; /* step */ }; typedef void (*DviSpecialHandler) __PROTO((DviContext *dvi, const char *prefix, const char *arg)); #define RANGE_HAS_LOWER(x) \ ((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_LOWER) #define RANGE_HAS_UPPER(x) \ ((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_UPPER) /* * Macros and prototypes */ #define MDVI_PARAM_ANTIALIASED 1 #define MDVI_PARAM_MONO 2 #define MDVI_PARAM_CHARBOXES 4 #define MDVI_PARAM_SHOWUNDEF 8 #define MDVI_PARAM_DELAYFONTS 16 /* * The FALLBACK priority class is reserved for font formats that * contain no glyph information and are to be used as a last * resort (e.g. TFM, AFM) */ #define MDVI_FONTPRIO_FALLBACK -3 #define MDVI_FONTPRIO_LOWEST -2 #define MDVI_FONTPRIO_LOW -1 #define MDVI_FONTPRIO_NORMAL 0 #define MDVI_FONTPRIO_HIGH 1 #define MDVI_FONTPRIO_HIGHEST 2 #define MDVI_FONT_ENCODED (1 << 0) #define MDVI_GLYPH_EMPTY ((void *)1) /* does the glyph have a non-empty bitmap/image? */ #define MDVI_GLYPH_NONEMPTY(x) ((x) && (x) != MDVI_GLYPH_EMPTY) /* has the glyph been loaded from disk? */ #define MDVI_GLYPH_UNSET(x) ((x) == NULL) /* do we have only a bounding box for this glyph? */ #define MDVI_GLYPH_ISEMPTY(x) ((x) == MDVI_GLYPH_EMPTY) #define MDVI_ENABLED(d,x) ((d)->params.flags & (x)) #define MDVI_DISABLED(d,x) !MDVI_ENABLED((d), (x)) #define MDVI_LASTPAGE(d) ((d)->npages - 1) #define MDVI_NPAGES(d) (d)->npages #define MDVI_VALIDPAGE(d,p) ((p) >= 0 && (p) <= MDVI_LASTPAGE(d)) #define MDVI_FLAGS(d) (d)->params.flags #define MDVI_SHRINK_FROM_DPI(d) Max(1, (d) / 75) #define MDVI_CURRFG(d) (d)->curr_fg #define MDVI_CURRBG(d) (d)->curr_bg #define pixel_round(d,v) (int)((d)->params.conv * (v) + 0.5) #define vpixel_round(d,v) (int)((d)->params.vconv * (v) + 0.5) #define rule_round(d,v) (int)((d)->params.conv * (v) + 0.99999) /*9999999)*/ #define vrule_round(d,v) (int)((d)->params.vconv * (v) + 0.99999) extern int mdvi_reload __PROTO((DviContext *, DviParams *)); extern void mdvi_setpage __PROTO((DviContext *, int)); extern int mdvi_dopage __PROTO((DviContext *, int)); extern void mdvi_shrink_glyph __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); extern void mdvi_shrink_box __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); extern void mdvi_shrink_glyph_grey __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); extern int mdvi_find_tex_page __PROTO((DviContext *, int)); extern int mdvi_configure __PROTO((DviContext *, DviParamCode, ...)); extern int get_tfm_chars __PROTO((DviParams *, DviFont *, TFMInfo *, int)); extern int tfm_load_file __PROTO((const char *, TFMInfo *)); extern int afm_load_file __PROTO((const char *, TFMInfo *)); extern TFMInfo *get_font_metrics __PROTO((const char *, int, const char *)); extern char *lookup_font_metrics __PROTO((const char *, int *)); extern void free_font_metrics __PROTO((TFMInfo *)); extern void flush_font_metrics __PROTO((void)); #define get_metrics(name) get_font_metrics((name), DviFontAny, NULL) extern void mdvi_sort_pages __PROTO((DviContext *, DviPageSort)); extern void mdvi_init_kpathsea __PROTO((const char *, const char *, const char *, int, const char *)); extern DviContext* mdvi_init_context __PROTO((DviParams *, DviPageSpec *, const char *)); extern void mdvi_destroy_context __PROTO((DviContext *)); /* helper macros that call mdvi_configure() */ #define mdvi_config_one(d,x,y) mdvi_configure((d), (x), (y), MDVI_PARAM_LAST) #define mdvi_set_dpi(d,x) mdvi_config_one((d), MDVI_SET_DPI, (x)) #define mdvi_set_xdpi(d,x) mdvi_config_one((d), MDVI_SET_XDPI, (x)) #define mdvi_set_ydpi(d,x) mdvi_config_one((d), MDVI_SET_YDPI, (x)) #define mdvi_set_hshrink(d,h) mdvi_config_one((d), MDVI_SET_XSHRINK, (h)) #define mdvi_set_vshrink(d,h) mdvi_config_one((d), MDVI_SET_YSHRINK, (h)) #define mdvi_set_gamma(d,g) mdvi_config_one((d), MDVI_SET_GAMMA, (g)) #define mdvi_set_density(d,x) mdvi_config_one((d), MDVI_SET_DENSITY, (x)) #define mdvi_set_drift(d,x) mdvi_config_one((d), MDVI_SET_DRIFT, (x)) #define mdvi_set_hdrift(d,h) mdvi_config_one((d), MDVI_SET_HDRIFT, (h)) #define mdvi_set_vdrift(d,v) mdvi_config_one((d), MDVI_SET_VDRIFT, (v)) #define mdvi_set_mag(d,m) \ mdvi_config_one((d), MDVI_SET_MAGNIFICATION, (m)) #define mdvi_set_foreground(d,x) \ mdvi_config_one((d), MDVI_SET_FOREGROUND, (x)) #define mdvi_set_background(d,x) \ mdvi_config_one((d), MDVI_SET_BACKGROUND, (x)) #define mdvi_set_orientation(d,x) \ mdvi_config_one((d), MDVI_SET_ORIENTATION, (x)) #define mdvi_set_shrink(d,h,v) \ mdvi_configure((d), MDVI_SET_XSHRINK, (h), \ MDVI_SET_YSHRINK, (v), MDVI_PARAM_LAST) extern DviRange* mdvi_parse_range __PROTO((const char *, DviRange *, int *, char **)); extern DviPageSpec* mdvi_parse_page_spec __PROTO((const char *)); extern void mdvi_free_page_spec __PROTO((DviPageSpec *)); extern int mdvi_in_range __PROTO((DviRange *, int, int)); extern int mdvi_range_length __PROTO((DviRange *, int)); extern int mdvi_page_selected __PROTO((DviPageSpec *, PageNum, int)); /* Specials */ extern int mdvi_register_special __PROTO(( const char *label, const char *prefix, const char *regex, DviSpecialHandler handler, int replace)); extern int mdvi_unregister_special __PROTO((const char *prefix)); extern int mdvi_do_special __PROTO((DviContext *dvi, char *dvi_special)); extern void mdvi_flush_specials __PROTO((void)); /* Fonts */ #define MDVI_FONTSEL_BITMAP (1 << 0) #define MDVI_FONTSEL_GREY (1 << 1) #define MDVI_FONTSEL_GLYPH (1 << 2) #define FONTCHAR(font, code) \ (((code) < font->loc || (code) > font->hic || !(font)->chars) ? \ NULL : &font->chars[(code) - (font)->loc]) #define FONT_GLYPH_COUNT(font) ((font)->hic - (font)->loc + 1) #define glyph_present(x) ((x) && (x)->offset) /* create a reference to a font */ extern DviFontRef *font_reference __PROTO((DviParams *params, Int32 dvi_id, const char *font_name, Int32 checksum, int xdpi, int ydpi, Int32 scale_factor)); /* drop a reference to a font */ extern void font_drop_one __PROTO((DviFontRef *)); /* drop a chain of references */ extern void font_drop_chain __PROTO((DviFontRef *)); /* destroy selected information for a glyph */ extern void font_reset_one_glyph __PROTO((DviDevice *, DviFontChar *, int)); /* destroy selected information for all glyphs in a font */ extern void font_reset_font_glyphs __PROTO((DviDevice *, DviFont *, int)); /* same for a chain of font references */ extern void font_reset_chain_glyphs __PROTO((DviDevice *, DviFontRef *, int)); extern void font_finish_definitions __PROTO((DviContext *)); /* lookup an id # in a reference chain */ extern DviFontRef* font_find_flat __PROTO((DviContext *, Int32)); extern DviFontRef* font_find_mapped __PROTO((DviContext *, Int32)); /* called to reopen (or rewind) a font file */ extern int font_reopen __PROTO((DviFont *)); /* reads a glyph from a font, and makes all necessary transformations */ extern DviFontChar* font_get_glyph __PROTO((DviContext *, DviFont *, int)); /* transform a glyph according to the given orientation */ extern void font_transform_glyph __PROTO((DviOrientation, DviGlyph *)); /* destroy all fonts that are not being used, returns number of fonts freed */ extern int font_free_unused __PROTO((DviDevice *)); #define font_free_glyph(dev, font, code) \ font_reset_one_glyph((dev), \ FONTCHAR((font), (code)), MDVI_FONTSEL_GLYPH) extern int mdvi_encode_font __PROTO((DviParams *, DviFont *)); /* font lookup functions */ extern int mdvi_register_font_type __PROTO((DviFontInfo *, int)); extern char **mdvi_list_font_class __PROTO((int)); extern int mdvi_get_font_classes __PROTO((void)); extern int mdvi_unregister_font_type __PROTO((const char *, int)); extern char *mdvi_lookup_font __PROTO((DviFontSearch *)); extern DviFont *mdvi_add_font __PROTO((const char *, Int32, int, int, Int32)); extern int mdvi_font_retry __PROTO((DviParams *, DviFont *)); /* Miscellaneous */ extern int mdvi_set_logfile __PROTO((const char *)); extern int mdvi_set_logstream __PROTO((FILE *)); extern int mdvi_set_loglevel __PROTO((int)); #define mdvi_stop_logging(x) mdvi_set_logstream(NULL) /* this will check the environment and then `texmf.cnf' for * the given name changed to lowercase, and `_' changed to `-' */ extern char* mdvi_getenv __PROTO((const char *)); #endif /* _MDVI_DVI_H */