/* * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "mdvi.h" #include "private.h" #include "defaults.h" #include "version.h" #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H) #include #endif int profiling = 0; int batch_mode = 0; int registered_fonts = 0; #if WITH_TYPE1_FONTS extern char *T1_GetLibIdent(); #endif extern char *kpathsea_version_string; extern int init_x11(void); extern void view_page(DviContext *, int); extern int mdvi_create_window(DviContext *, const char *); extern Ulong get_color_byname __PROTO((const char *)); /* font types */ extern DviFontInfo pk_font_info; extern DviFontInfo pkn_font_info; extern DviFontInfo gf_font_info; extern DviFontInfo vf_font_info; #ifdef WITH_OMEGA extern DviFontInfo ovf_font_info; #endif #ifdef WITH_TRUETYPE_FONTS extern DviFontInfo tt_font_info; #endif #ifdef WITH_TYPE1_FONTS extern DviFontInfo t1_font_info; #endif #ifdef WITH_AFM_FILES extern DviFontInfo afm_font_info; #endif extern DviFontInfo tfm_font_info; #ifdef WITH_OMEGA extern DviFontInfo ofm_font_info; #endif static struct fontinfo { DviFontInfo *info; char *desc; int klass; } known_fonts[] = { {&vf_font_info, "Virtual fonts", 0}, #ifdef WITH_OMEGA {&ovf_font_info, "Omega's virtual fonts", 0}, #endif #ifdef WITH_TRUETYPE_FONTS {&tt_font_info, "TrueType fonts", 0}, #endif #ifdef WITH_TYPE1_FONTS {&t1_font_info, "Type1 PostScript fonts", 0}, #endif {&pk_font_info, "Packed bitmap (auto-generated)", 1}, {&pkn_font_info, "Packed bitmap", -2}, {&gf_font_info, "Metafont's generic font format", 1}, #ifdef WITH_OMEGA {&ofm_font_info, "Omega font metrics", -1}, #endif {&tfm_font_info, "TeX font metrics", -1}, #ifdef WITH_AFM_FILES {&afm_font_info, "Adobe font metrics", -1}, #endif {0, 0} }; static int print_info_only = 0; char *logfile; DviAppConfig *mdvi_app; char *program_name; static char mdvi_banner[] = "mdvi " MDVI_VERSION " -- A TeX DVI previewer for Unix\n" "Copyright (C) 2000 Matias Atria\n" "This program is free software; you can redistribute it and/or modify\n" "it under certain conditions. Try `mdvi --info' for details\n\n"; static char mdvi_long_banner[] = "mdvi " MDVI_VERSION " -- A TeX DVI previewer for Unix\n" "Copyright (C) 2000 Matias Atria\n\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n" "PARTICULAR PURPOSE.\n\n"; static const char *orientstr[] = { "tblr", "tbrl", "btlr", "btrl", "rp90", "rm90", "irp90", "irm90" }; static const char usage_help[] = "Usage: mdvi [OPTION] ... DVIFILE\n\n" "Options:\n" " -a, --font-types=FONTS\n" " specify which font types to use\n" " -A, --fonts-omitted[=FONTS]\n" " specify which font types not to use by default\n" " -b, --boxes\n" " see the world through TeX's eyes\n" " -B, --bg=COLOR\n" " set background color\n" " -d, --debug=MASK\n" " set debug mask (see --explain debug for more info)\n" " -D, --dpi=DPI\n" " set resolution to DPI pixels per inch\n" " -e, --explain=TOPIC\n" " give more detailed help on a particular topic, use topic `list' to\n" " see the list of known topics\n" " -f, --fallback-font=FONT-NAME\n" " font to use when one is missing\n" " -F, --fg=COLOR\n" " set foreground color\n" " -G, --gamma=NUMBER\n" " gamma correction for antialiased glyphs\n" " -h, --help[=TOPIC]\n" " display help on a command line option. TOPIC may be the long name of an\n" " option, or one of `papers' or `units'.\n" " -H, --horizontal-margin=UNIT\n" " size of horizontal margins\n" " -i, --info\n" " display licensing information and default settings\n" " -l, --log-file=[LEVEL:]FILE\n" " save all messages with priority at least LEVEL to FILE\n" " -m, --mf-mode=MODE\n" " Metafont mode to use when creating fonts\n" " -M, --magnification=NUMBER\n" " magnification factor (NUMBER = TeX's NUMBER/1000.0)\n" " -N, --mono\n" " to force monochrome configuration\n" " -o, --orientation=ORIENTATION\n" " set document on-screen orientation\n" " --orientation=help\n" " print option details and exit\n" " -p, --paper=NAME\n" " paper type to use\n" " --paper=list\n" " print known paper types and exit\n" " -P, --page=NUMBER\n" " start viewing page NUMBER\n" " -r, --page-range=RANGE\n" " specify which files should be read\n" " --page-range=help\n" " print option details and exit\n" " -s, --shrink=NUMBER\n" " shrinking factor for glyphs\n" " -S, --sort-pages[=TYPE]\n" " set page sorting type, where `TYPE' is one of up, down, random,\n" " dviup, dvidown or none. If `TYPE' is not specified, `up' is assumed\n" " -t, --pixel-density=NUMBER\n" " pixel density for antialiased glyphs (0 <= NUMBER <= 100)\n" " -T, --tex-page=NUMBER\n" " start viewing TeX's (i.e. document's) page NUMBER\n" " -V, --vertical-margin=UNIT\n" " size of vertical margins\n" " -x, --xdpi=DPI\n" " set horizontal resolution\n" " -y, --ydpi=DPI\n" " set vertical resolution\n" " -z, --batch\n" " run in batch mode (no UI)\n"; static const char debug_help[] = "Debugging masks: -d MASK, --debug=MASK\n" " MASK is a numerical value, obtained by ORing the values given below\n" "or a series of mask names separated by commas or by `|'. The masks known\n" "to MDVI are:\n\n" " Name Value Description\n" "------------------------------------------------------------------------\n" " opcode 1 DVI opcodes and arguments in `dvitype' style\n" " fonts 2 messages related to the management of fonts\n" " files 4 file operations\n" " dvi 8 operations on DVI files\n" " params 16 manipulation of DVI parameters\n" " special 32 DVI specials\n" " device 64 device-specific messages\n" " glyphs 128 loading of glyphs (lots of output)\n" " paths 256 paths configuration in kpathsea\n" " search 512 file searches by kpathsea\n" " vars 1024 traces environment variables (MDVI and kpathsea)\n" " bitops 2048 bitmap operations (scaling, flipping, etc)\n" " bitdata 4096 bitmap bits (MASSIVE amounts of output)\n" " type1 8192 management of Type1 fonts\n" " tt 16384 management of TrueType fonts\n" " --- 32768 unused\n" " fontmaps 65536 things involving font maps and encodings\n"; static const char orientation_help[] = "Orientation options: -o ORIENTATION, --orienation=ORIENTATION\n" " ORIENTATION is one of TBLR, TBRL, BTLR, BTRL, RP90, RM90, IRP90 or\n" "IRM90, where TB=top-to-bottom, LR=left-to-right, etc.,\n" "RP=rotate-positively (i.e. counter-clockwise), RM=rotate-negatively,\n" "and the last two are the same than these, after a reflection with\n" "respect to an imaginary vertical axis. The values Portrait, Landscape\n" "and Seascape are synonyms for TBLR, RM90 and RP90, respectively.\n"; static const char range_help[] = "Page range selection options: -r RANGE-SPEC, --page-range=RANGE-SPEC\n" " RANGE-SPEC consists of up to 11 RANGE-LIST strings, separated by dots.\n" "If there is only one list, it is assumed to apply to DVI page numbers.\n" "Otherwise, each list applies to the corresponding TeX page \\counter (10 per\n" "page). A RANGE-LIST is either empty or a comma-separated list of ranges, at\n" "least one of which must contain the page counter in order for the page to be\n" "processed. A range has the form LOWER:UPPER:STEP, which specifies the\n" "sequence LOWER + STEP * n, for 0 <= n <= (UPPER - LOWER) / STEP. A\n" "RANGE-LIST may optionally be written inside braces, for clarity, but no\n" "white space is allowed anywhere in a RANGE-SPEC. Any part of a range (except\n" "for the `:') may be omitted, in which case LOWER, UPPER and STEP take the\n" "default values -INFINITY, +INFINITY and 1, respectively, except in two\n" "cases: (1) The form ::STEP specifies the sequence `STEP * n' for `n' an\n" "arbitrary integer, and (2) In the form :UPPER:STEP, LOWER is set to\n" "`PREV_UPPER + 1' if the preceding range had a finite upper bound, and to\n" "-INFINITY otherwise. An empty RANGE-LIST (written as `*') is equivalent\n" "to {::}.\n" " If the first RANGE-LIST begins with `D' or `d', it is assumed to apply to \n" "DVI page numbers, regardless of whether it is the only RANGE-LIST in the \n" "RANGE-SPEC.\n" "Examples:\n" " ::2 Matches all even DVI page numbers.\n" " 1::2 Matches all odd DVI page numbers.\n" " {1:4}.*.{1:11:2,:15}.*\n" " Matches \\counter0=1,2,3,4, and \\counter1=1,3,5,7,11,12,13,14,15\n" " D{::2}.{5:}.*\n" " Matches all even DVI page numbers AND \\counter0 >= 5.\n"; static const char units_help[] = "Units:\n" " MDVI recognizes all TeX units, plus some more:\n" " Metric units: meters (mt), centimeters (cm), milimeters (mm)\n" " US units: yard (yd), feet (ft), inches (in)\n" " TeX units: points (pt), picas (pc), didot points (dd),\n" " ciceros (cc), scaled points (sp)\n" " Other units: big/PostScript points (bp), charspace (cs)\n"; static const char log_help[] = "Logfile option: -l, --log-file=[LEVEL:]FILE\n" " Tells MDVI to save all messages with priority at least LEVEL to FILE.\n" "LEVEL is one of `info', `warn', `err' and `debug'. FILE can be the name\n" "of a file or the values 1 (standard output) or 2 (standard error). The\n" "name `-' is equivalent to `1'.\n"; static const char font_type_help[] = "Font support option: -a, --font-types=FONTS\n" " Tells MDVI which font types should be supported. FONTS is a comma\n" "separated list of font `families' that MDVI is to recognize during this\n" "run. A type name can be preceded by a class ID, which will become the\n" "default class for all fonts in the FONTS specification after that ID.\n" "Examples:\n" " --font-types=0:vf,t1,tt,1:pk,m:tfm\n" "This entry means: put the font types vf (virtual fonts), t1 (Type1) and\n" "tt (TrueType) in class 0 (highest priority). In class 1, put type pk\n" "(packet bitmap format). Finally, put type tfm (TeX font metric format)\n" "in the metric class. Thus, MDVI will not lookup fonts other than these\n" "to resolve the font references in the DVI file.\n" "\n" "To see the list of all font types known to MDVI, and their default class,\n" "use `--font-types=list'. For a brief description of the font lookup\n" "mechanism, use `--explain=fonts'.\n"; static struct { const char *topic; const char *desc; const char *string; } topics[] = { {"log", "log file options", log_help}, {"mdvi", "command line options", usage_help}, {"units", "units supported by MDVI and their syntax", units_help}, {"orientation", "syntax for specifying orientations", orientation_help}, {"ranges", "syntax for specifying page ranges", range_help}, {"debug", "debugging options", debug_help}, {"font-types", "font support selection", font_type_help}, {0, 0} }; static void print_paper_specs(const char *title, DviPaperSpec *spec) { int i; char buf[256]; int len = 0; printf("%s:\n", title); for(i = 0; spec[i].name; i++) { int n; n = sprintf(buf, " %10s: %6s x %s", spec[i].name, spec[i].width, spec[i].height); while(n < 30) buf[n++] = ' '; buf[n] = 0; printf("%s", buf); if(len || n >= 78) { fputc('\n', stdout); len = 0; } else len = n; } if(len) fputc('\n', stdout); } static void print_fonts(void) { struct fontinfo *fi; printf("Known font formats:\n\n"); printf("%8s %-30s Class\n", "Name", "Description"); printf("-----------------------------------------------\n"); for(fi = known_fonts; fi->info; fi++) { printf("%8s %-30s ", fi->info->name, fi->desc); if(fi->klass == -1) putchar('M'); else if(fi->klass < -1) putchar('-'); else printf("%d", fi->klass); putchar('\n'); } putchar('\n'); printf("Priority classes: 0 (highest) - %d (lowest), M (metric)\n", mdvi_get_font_classes()); } static void print_papers(void) { DviPaperSpec *spec; spec = mdvi_get_paper_specs(MDVI_PAPER_CLASS_ISO); if(spec != NULL) { print_paper_specs(_("ISO paper types"), spec); mdvi_free_paper_specs(spec); } spec = mdvi_get_paper_specs(MDVI_PAPER_CLASS_US); if(spec != NULL) { print_paper_specs(_("US paper types"), spec); mdvi_free_paper_specs(spec); } printf( "Custom paper types:\n" " x (e.g., 210x292.7mm)\n" " , (e.g., 208.5mm,13in)\n"); } static void usage(const char *string, int exit_code) { const char *help = NULL; int i; if(string == NULL) help = usage_help; else for(i = 0; topics[i].topic; i++) { if(STRCEQ(string, topics[i].topic)) { help = topics[i].string; break; } } printf("%s", mdvi_banner); if(help == NULL) fprintf(stderr, _("%s: I don't know about that\n"), string); else printf("%s", help); exit(exit_code); } void print_config(DviAppConfig *app) { int i; printf("%s", mdvi_long_banner); printf( "Environment variables, and compiled defaults:\n" " MDVI_DPI resolution (in pixels per inch) %d\n" " MDVI_VDPI vertical resolution %d\n" " MDVI_MAGNIFICATION magnification (1.0 = normal) %.2f\n" " MDVI_SHRINKING shrinking factor %d\n" " MDVI_HSHRINK horizontal shrinking factor %d\n" " MDVI_VSHRINK vertical shrinking factor %d\n" " MDVI_HDRIFT horizontal drifting tolerance %d\n" " MDVI_VDRIFT vertical drifting tolerance %d\n" " MDVI_PIXEL_DENSITY pixel density %d\n" " MDVI_GAMMA gamma correction factor %.2f\n" " MDVI_PAPER paper name %s\n" " MDVI_HMARGIN horizontal margins around pages %s\n" " MDVI_VMARGIN vertical margins around pages %s\n" " MDVI_FALLBACK_FONT font to use when one is missing %s\n" " MDVI_MFMODE default metafont mode %s\n" " MDVI_HRUNITS units for horizontal rulers %s\n" " MDVI_VRUNITS units for vertical rulers %s\n" " MDVI_ORIENTATION page on-screen orientation %s\n" " MDVI_FONTSPEC default font configuration builtin\n" " MDVI_FONTOMIT fonts types omitted by default PKN\n" " MDVI_FOREGROUND foreground color %s\n" " MDVI_BACKGROUND background color %s\n" " MDVI_DEBUG debug mask\n", MDVI_DPI, MDVI_VDPI, MDVI_MAGNIFICATION, MDVI_DEFAULT_SHRINKING, -1, /* HSHRINK */ -1, /* VSHRINK */ -1, /* HDRIFT */ -1, /* VDRIFT */ MDVI_DEFAULT_DENSITY, MDVI_DEFAULT_GAMMA, MDVI_PAPERNAME, MDVI_HMARGIN, MDVI_VMARGIN, MDVI_FALLBACK_FONT, MDVI_MFMODE ? MDVI_MFMODE : "auto", MDVI_HRUNITS, MDVI_VRUNITS, MDVI_ORIENTATION, MDVI_FOREGROUND, MDVI_BACKGROUND); putchar('\n'); printf("Current configuration:\n"); printf(" dpi: %d\n", app->params.dpi); printf(" vdpi: %d\n", app->params.vdpi); printf(" magnification: %.2f\n", app->params.mag); printf(" hshrink: %d\n", app->params.hshrink); printf(" vshrink: %d\n", app->params.vshrink); printf(" hdrift: %d\n", app->params.hdrift); printf(" vdrift: %d\n", app->params.vdrift); printf(" pixel density: %d\n", app->params.density); printf(" gamma factor: %.2f\n", app->params.gamma); printf(" paper type: %s\n", app->paper.name); printf(" margins: (%s,%s)\n", app->hmargin, app->vmargin); printf(" fallback font: %s\n", app->fallback_font); printf(" Metafont mode: %s\n", app->mfmode ? app->mfmode : "auto"); printf(" ruler units: (%s,%s)\n", app->hrule_units, app->vrule_units); printf(" orientation: %s\n", orientstr[app->params.orientation]); printf(" font types: %s\n", app->fontspec ? app->fontspec : "all"); printf(" fonts omitted: %s\n", app->fontunspec ? app->fontunspec : "none"); printf(" foreground: %s\n", app->fgcolor); printf(" background: %s\n", app->bgcolor); putchar('\n'); printf("Fonts supported in this configuration:\n"); for(i = -1; i <= mdvi_get_font_classes(); i++) { char ** list; int j; list = mdvi_list_font_class(i); if(list == NULL) break; printf(" Class "); if(i == -1) printf("M: "); else printf("%d: ", i); if(list[0] == NULL) printf("None"); else for(j = 0; list[j]; j++) { printf("%s%s", j ? ", " : "", list[j]); xfree(list[j]); } xfree(list); putchar('\n'); } } int process_options(DviAppConfig *app, int argc, char **argv) { static struct option dviopts[] = { {"batch", 0, 0, 'z'}, {"debug", 1, 0, 'd'}, {"help", 2, 0, 'h'}, {"info", 0, 0, 'i'}, {"bg", 1, 0, 'B'}, {"boxes", 0, 0, 'b'}, {"dpi", 1, 0, 'D'}, {"debug", 2, 0, 'd'}, {"explain", 1, 0, 'e'}, {"fallback-font", 1, 0, 'f'}, {"fg", 1, 0, 'F'}, {"font-types", 2, 0, 'a'}, {"fonts-omitted", 2, 0, 'A'}, {"gamma", 1, 0, 'G'}, {"horizontal-margin", 1, 0, 'H'}, {"log-file", 1, 0, 'l'}, {"magnification", 1, 0, 'M'}, {"mf-mode", 1, 0, 'm'}, {"mono", 0, 0, 'N'}, {"orientation", 1, 0, 'o'}, {"page", 1, 0, 'P'}, {"page-range", 1, 0, 'r'}, {"paper", 1, 0, 'p'}, {"pixel-density", 1, 0, 't'}, {"shrink", 1, 0, 's'}, {"sort-pages", 2, 0, 'S'}, {"tex-page", 1, 0, 'T'}, {"vertical-margin", 1, 0, 'V'}, {"xdpi", 1, 0, 'x'}, {"ydpi", 1, 0, 'y'}, {"version", 0, 0, 'v'}, {0, 0, 0, 0} }; while(1) { int c; int ndx; char *arg; c = getopt_long(argc, argv, "a::A::d:hiB:bD:e:f:F:G:H:il:M:m:No:P:r:p:t:s:S:T:V:x:y:zv", dviopts, &ndx); arg = optarg; if(c == -1) break; switch(c) { case 'A': case 'a': if(arg && STRCEQ(arg, "list")) { printf("%s", mdvi_banner); print_fonts(); exit(EXIT_SUCCESS); } else if(arg && STRCEQ(arg, "help")) usage("font-types", EXIT_SUCCESS); if(c == 'a') registered_fonts += configure_fonts(arg, 1); else configure_fonts(arg, 0); break; case 'b': app->params.flags |= MDVI_PARAM_CHARBOXES; break; case 'B': app->bgcolor = arg; break; case 'd': { long mask; if(STREQ(arg, "list")) usage("debug", EXIT_SUCCESS); if(mdvi_getint(arg, &mask) < 0) mask = (long)mdvi_get_debugmask(arg); add_debug_mask((Uint32)mask); break; } case 'x': case 'y': case 'D': { long dpi; if(mdvi_getint(arg, &dpi) < 0 || dpi <= 0) warning(_("resolution must be a positive integer\n")); else if(c == 'x') app->params.dpi = (Uint)dpi; else if(c == 'y') app->params.vdpi = (Uint)dpi; else app->params.dpi = app->params.vdpi = (Uint)dpi; break; } case 'e': if(STRCEQ(arg, "list")) { int i; printf("%s", mdvi_banner); printf(_("Known topics\n")); for(i = 0; topics[i].topic; i++) printf(" %-12s: %s\n", topics[i].topic, topics[i].desc); exit(EXIT_SUCCESS); } else usage(arg, EXIT_SUCCESS); break; case 'f': app->fallback_font = arg; break; case 'F': app->fgcolor = arg; break; case 'g': /* UNUSED */ break; case 'G': app->params.gamma = strtod(arg, NULL); break; case 'h': usage(NULL, EXIT_SUCCESS); break; case 'H': app->hmargin = arg; break; case 'i': print_info_only = 1; break; case 'l': if(STRNEQ(arg, "info:", 5)) { arg += 5; mdvi_set_loglevel(LOG_INFO); } else if(STRNEQ(arg, "warn:", 5)) { arg += 5; mdvi_set_loglevel(LOG_WARN); } else if(STRNEQ(arg, "err:", 4)) { arg += 4; mdvi_set_loglevel(LOG_ERROR); } else if(STRNEQ(arg, "debug:", 6)) { arg += 6; mdvi_set_loglevel(LOG_DEBUG); } else mdvi_set_loglevel(LOG_WARN); if(*arg == 0 || STREQ(arg, "-") || atoi(arg) == 1) mdvi_set_logstream(stdout); else if(atoi(arg) == 2) mdvi_set_logstream(stderr); else mdvi_set_logfile(arg); break; case 'm': app->mfmode = arg; break; case 'M': { double mag; if(mdvi_getfloat(arg, &mag) < 0 || mag <= 0) { warning(_("magnification must be positive\n")); } else app->params.mag = mag; break; } case 'N': app->params.flags &= ~MDVI_PARAM_ANTIALIASED; app->params.flags |= MDVI_PARAM_MONO; break; case 'o': if(STRCEQ(arg, "help")) usage("orientation", EXIT_SUCCESS); app->params.orientation = mdvi_getorient(arg); break; case 'p': if(STRCEQ(arg, "help") || STRCEQ(arg, "list")) { print_papers(); exit(EXIT_SUCCESS); } app->paper.name = arg; break; case 'P': if(mdvi_getint(arg, (long *)&app->first_page) < 0) { warning(_("page number must be a positive integer\n")); app->first_page = 0; } else app->use_tex_page = 0; break; case 'r': if(STRCEQ(arg, "help")) usage("ranges", EXIT_SUCCESS); app->page_ranges = arg; break; case 's': { long h, v; if(sscanf(arg, "%ld,%ld", &h, &v) == 2) { app->params.vshrink = (Uint)v; app->params.hshrink = (Uint)h; } else if(mdvi_getint(arg, &h) < 0 || h < 0) { warning(_("shrinking factor must be a non-negative number\n")); } else app->params.vshrink = app->params.hshrink = (Uint)h; break; } case 'S': { int v; if(arg == NULL) app->page_sort = MDVI_PAGE_SORT_UP; else if((v = mdvi_get_pagesort(arg)) < 0) { warning(_("unknown sorting type `%s'\n"), arg); app->page_sort = MDVI_PAGE_SORT_NONE; } else app->page_sort = v; break; } case 't': { long s; if(mdvi_getint(arg, &s) < 0 || s < 0) warning(_("pixel density must be a non-negative number\n")); else if(s > 100) { warning(_("pixel density should be less than 100\n")); s = 100; } app->params.density = (Uint)s; break; } case 'T': { long s; if(mdvi_getint(arg, &s) < 0) warning(_("tex-page must be an integer\n")); else { app->first_page = (int)s; app->use_tex_page = 1; } break; } case 'V': app->vmargin = arg; break; case 'v': { char *a, *b; printf("%s", mdvi_long_banner); /* Check the library versions and report any differences */ a = strrchr(KPSE_VERSION, ' '); a = (a ? a + 1 : KPSE_VERSION); b = strrchr(kpathsea_version_string, ' '); b = (b ? b + 1 : kpathsea_version_string); printf("Compiled with kpathsea %s", a); if(!STREQ(a, b)) printf(", using %s", b); fputc('\n', stdout); printf("Additional features:\n"); #ifdef WITH_TYPE1_FONTS printf("\tType1 fonts (t1lib %s)", T1LIB_VERSION); b = T1_GetLibIdent(); if(!STREQ(T1LIB_VERSION, b)) printf(", using %s", b); fputc('\n', stdout); #endif #ifdef WITH_TRUETYPE_FONTS printf("\tTrueType fonts (Freetype 1.x)\n"); #endif #ifdef WITH_AFM_FILES printf("\tAFM files\n"); #endif #ifdef WITH_OMEGA printf("\tOmega file formats\n"); #endif #ifdef WITH_REGEX_SPECIALS printf("\tRegex \\specials\n"); #endif printf("Using %dbit bitmap units\n", BITMAP_BITS); exit(EXIT_SUCCESS); break; } case 'z': batch_mode = 1; break; default: usage(NULL, EXIT_FAILURE); break; } } return optind; } int configure_fonts(const char *spec, int enabled) { int done = 0; int klass = -2; /* unspecified */ int nclasses; const char *ptr; const char *text; struct fontinfo *type; int count = 0; nclasses = mdvi_get_font_classes(); if(spec == NULL || STRCEQ(spec, "all")) { for(type = known_fonts; type->info; type++) { if(!enabled) type->klass = -2; else if(type->klass != -2) mdvi_register_font_type(type->info, type->klass); count++; } if(!enabled) DEBUG((DBG_FONTS, "all font types disabled by default\n")); } else for(ptr = text = spec; !done; ptr++) { int len; int k; int status; char *name; if(*ptr && *ptr != ',') continue; if(*ptr == 0) done = 1; if((len = ptr - text) == 0) continue; if(len >= 2 && text[1] == ':') { switch(text[0]) { case 'm': case 'M': k = -1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': k = *text - '0'; break; default: text -= 2; /* will be fixed later */ break; } if(k < -1 || k > nclasses) { k = klass; warning("font class %d does not exist\n"); } klass = k; text += 2; } else if(*text == ':') k = klass = -3; else k = klass; for(type = known_fonts; type->info; type++) { if(STRNCEQ(type->info->name, text, len)) break; } text = ptr + 1; if(type->info == NULL) continue; name = type->info->name; if(!enabled) { DEBUG((DBG_FONTS, "%s fonts disabled by default\n", name)); type->klass = -2; continue; } if(k < -2) k = type->klass; /* if the user wants to put a metric font in a real class, * or the other way around, give a warning */ if(type->klass < 0 && k >= 0) { warning("adding %s fonts to `real' class %d\n", name, k); } else if(type->klass >= 0 && k < 0) { warning("adding %s fonts to the metric class\n", name); } status = mdvi_register_font_type(type->info, k); if(status < 0) { warning("could not register font type `%s' in class %d\n", name, k); } else { DEBUG((DBG_FONTS, "%s: added to font class %d\n", name, k)); count++; } } return count; } int main(int argc, char **argv) { DviPageSpec *spec; DviContext *ctx; char *dvifile; char *ptr; int i; #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif program_name = strrchr(argv[0], '/'); if(program_name == NULL) program_name = argv[0]; else program_name++; /* get as integer */ ptr = getenv("MDVI_DEBUG"); if(ptr != NULL) { long x; if(mdvi_getint(ptr, &x) < 0) x = (long)mdvi_get_debugmask(ptr); set_debug_mask((Uint32)x); } mdvi_app = mdvi_init_app(program_name, "mdvi"); if(mdvi_app->fontunspec) configure_fonts(mdvi_app->fontunspec, 0); i = process_options(mdvi_app, argc, argv); if(i < 0) exit(EXIT_FAILURE); dvifile = argv[i]; /* check that everything is alright */ if(mdvi_check_config(mdvi_app) < 0) exit(EXIT_FAILURE); if(mdvi_app->page_ranges != NULL) spec = mdvi_parse_page_spec(mdvi_app->page_ranges); else spec = NULL; if(mdvi_app->fallback_font == NULL) mdvi_set_fallback_font(mdvi_app->fallback_font); #ifdef MDVI_FALLBACK_FONT else mdvi_set_fallback_font(MDVI_FALLBACK_FONT); #endif /* if no fonts have been registered, do that now */ if(!registered_fonts) registered_fonts = configure_fonts(mdvi_app->fontspec, 1); if(!registered_fonts) fatal("no font types registered\n"); if(print_info_only) { print_config(mdvi_app); exit(EXIT_SUCCESS); } if(dvifile == NULL) { fprintf(stderr, _("%s: no DVI file specified\n"), program_name); fprintf(stderr, _("Try `%s --help' for more information\n"), program_name); exit(EXIT_FAILURE); } ctx = mdvi_init_context(&mdvi_app->params, spec, dvifile); if(ctx == NULL) exit(1); ctx->paper = mdvi_app->paper; if(!batch_mode && init_x11() == -1) exit(EXIT_FAILURE); if(mdvi_app->page_sort != MDVI_PAGE_SORT_NONE) mdvi_sort_pages(ctx, mdvi_app->page_sort); if(mdvi_app->use_tex_page) mdvi_app->first_page = mdvi_find_tex_page(ctx, mdvi_app->first_page); else if(mdvi_app->first_page < 0) mdvi_app->first_page += MDVI_LASTPAGE(ctx) + 1; if(!MDVI_VALIDPAGE(ctx, mdvi_app->first_page)) mdvi_app->first_page = 0; if(batch_mode == 0) { /* beginning of device-specific code */ ctx->params.fg = get_color_byname(mdvi_app->fgcolor); ctx->params.bg = get_color_byname(mdvi_app->bgcolor); mdvi_create_window(ctx, NULL); mdvi_reset_color(ctx); view_page(ctx, mdvi_app->first_page); /* end of device-specific code */ } else { ctx->params.fg = (Ulong)-1; ctx->params.bg = 0; if(DEBUGGING(DVI)) { printf("%s", ctx->filename); for(i = 0; i < ctx->npages; i++) { mdvi_dopage(ctx, i); printf(" [%d]", ctx->pagemap[i][1]); } } else for(i = 0; i < ctx->npages; i++) mdvi_dopage(ctx, i); fputc('\n', stdout); } mdvi_destroy_context(ctx); mdvi_flush_fontmaps(); mdvi_flush_encodings(); mdvi_ps_flush_fonts(); flush_color_table(); exit(0); }