diff options
-rw-r--r-- | Build/source/texk/xdvipdfmx/ChangeLog | 7 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/dpxfile.c | 154 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/dpxfile.h | 5 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/dvi.c | 4 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/dvicodes.h | 2 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/dvipdfmx.c | 14 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/pdfximage.c | 69 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/spc_dvips.c | 38 | ||||
-rw-r--r-- | Build/source/texk/xdvipdfmx/src/vf.c | 2 |
9 files changed, 229 insertions, 66 deletions
diff --git a/Build/source/texk/xdvipdfmx/ChangeLog b/Build/source/texk/xdvipdfmx/ChangeLog index 780a78c495b..80920c21040 100644 --- a/Build/source/texk/xdvipdfmx/ChangeLog +++ b/Build/source/texk/xdvipdfmx/ChangeLog @@ -1,3 +1,10 @@ +2013-03-26 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + * src/dpxfile.c, src/dpxfile.h, src/dvi.c, src/dvicodes.h + src/dvipdfmx.c, src/pdfximage.c, src/spc_dvips.c src/vf.c: + Apply speed up patch for dvipdfmx by N. Tsuchimura also on + xdvipdfmx. + 2013-03-24 Akira Kakuto <kakuto@fuk.kindai.ac.jp> * src/dpxfile.c: Change dpx_create_temp_file() because tmpnam() diff --git a/Build/source/texk/xdvipdfmx/src/dpxfile.c b/Build/source/texk/xdvipdfmx/src/dpxfile.c index 04c0027eb8c..56d2f899d64 100644 --- a/Build/source/texk/xdvipdfmx/src/dpxfile.c +++ b/Build/source/texk/xdvipdfmx/src/dpxfile.c @@ -26,6 +26,12 @@ #include "config.h" #endif +#ifdef _MSC_VER +#include <kpathsea/dirent.h> +#endif + +#include <time.h> + #include "system.h" #include "error.h" #include "mem.h" @@ -34,6 +40,8 @@ #include "mfileio.h" #include "dpxfile.h" +#include "dpxcrypt.h" +#define MAX_KEY_LEN 16 #include <kpathsea/lib.h> #include <string.h> @@ -53,6 +61,7 @@ #endif static int verbose = 0; +int keep_cache = false; void dpx_file_set_verbose (void) @@ -640,6 +649,8 @@ is_absolute_path(const char *filename) return 1; if (filename[0] == '\\' && filename[1] == '\\') return 1; + if (filename[0] == '/' && filename[1] == '/') + return 1; #else if (filename[0] == '/') return 1; @@ -653,7 +664,7 @@ dpx_find_type1_file (const char *filename) char *fqpn = NULL; if (is_absolute_path(filename)) - fqpn = strdup(filename); + fqpn = xstrdup(filename); else fqpn = kpse_find_file(filename, kpse_type1_format, 0); if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_T1FONT)) { @@ -671,7 +682,7 @@ dpx_find_truetype_file (const char *filename) char *fqpn = NULL; if (is_absolute_path(filename)) - fqpn = strdup(filename); + fqpn = xstrdup(filename); else fqpn = kpse_find_file(filename, kpse_truetype_format, 0); if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_TTFONT)) { @@ -692,7 +703,7 @@ dpx_find_opentype_file (const char *filename) q = ensuresuffix(filename, ".otf"); #ifndef MIKTEX if (is_absolute_path(q)) - fqpn = strdup(q); + fqpn = xstrdup(q); else fqpn = kpse_find_file(q, kpse_opentype_format, 0); if (!fqpn) { @@ -737,11 +748,37 @@ dpx_find_dfont_file (const char *filename) return fqpn; } +static char * +dpx_get_tmpdir (void) +{ +# ifdef WIN32 +# define __TMPDIR "." +# else /* WIN32 */ +# define __TMPDIR "/tmp" +#endif /* WIN32 */ + char *_tmpd; + +# ifdef HAVE_GETENV + _tmpd = getenv("TMPDIR"); +# ifdef WIN32 + if (!_tmpd) + _tmpd = getenv("TMP"); + if (!_tmpd) + _tmpd = getenv("TEMP"); +# endif /* WIN32 */ + if (!_tmpd) + _tmpd = __TMPDIR; +# else /* HAVE_GETENV */ + _tmpd = __TMPDIR; +# endif /* HAVE_GETENV */ + return _tmpd; +} #ifdef HAVE_MKSTEMP # include <stdlib.h> #endif +#if 0 /* Not used */ char * dpx_create_temp_file (void) { @@ -753,18 +790,11 @@ dpx_create_temp_file (void) miktex_create_temp_file_name(tmp); /* FIXME_FIXME */ } #elif defined(HAVE_MKSTEMP) -# define __TMPDIR "/tmp" -# define TEMPLATE "/dvipdfmx.XXXXXX" +# define TEMPLATE "/dvipdfmx.XXXXXXXX" { const char *_tmpd; int _fd = -1; -# ifdef HAVE_GETENV - _tmpd = getenv("TMPDIR"); - if (!_tmpd) - _tmpd = __TMPDIR; -# else - _tmpd = __TMPDIR; -# endif /* HAVE_GETENV */ + _tmpd = dpx_get_tmpdir(); tmp = NEW(strlen(_tmpd) + strlen(TEMPLATE) + 1, char); strcpy(tmp, _tmpd); strcat(tmp, TEMPLATE); @@ -786,18 +816,8 @@ dpx_create_temp_file (void) # define __TMPDIR "." const char *_tmpd; char *p; -# ifdef HAVE_GETENV - _tmpd = getenv ("TMPDIR"); - if (!_tmpd) - _tmpd = getenv ("TMP"); - if (!_tmpd) - _tmpd = getenv ("TEMP"); - if (!_tmpd) - _tmpd = __TMPDIR; -# else /* HAVE_GETENV */ - _tmpd = __TMPDIR; -# endif /* HAVE_GETENV */ - tmp = _tempnam (_tmpd, "dpxtmp."); + _tmpd = dpx_get_tmpdir(); + tmp = _tempnam (_tmpd, "dvipdfmx."); for (p = tmp; *p; p++) { if (IS_KANJI (p)) p++; @@ -815,13 +835,95 @@ dpx_create_temp_file (void) return tmp; } +#endif /* 0 */ + +char * +dpx_create_fix_temp_file (char *filename) +{ +#define PREFIX "xdvipdfmx." + static char *dir = NULL; + static char *cwd = NULL; + char *ret, *s; + int i; + MD5_CONTEXT state; + unsigned char digest[MAX_KEY_LEN]; +#ifdef WIN32 + char *p; +#endif + + if (!dir) { + dir = dpx_get_tmpdir(); + cwd = xgetcwd(); + } + + MD5_init(&state); + MD5_write(&state, (unsigned char *)cwd, strlen(cwd)); + MD5_write(&state, (unsigned char *)filename, strlen(filename)); + MD5_final(digest, &state); + + ret = NEW(strlen(dir)+1+strlen(PREFIX)+MAX_KEY_LEN*2 + 1, char); + sprintf(ret, "%s/%s", dir, PREFIX); + s = ret + strlen(ret); + for (i=0; i<MAX_KEY_LEN; i++) { + sprintf(s, "%02x", digest[i]); + s += 2; + } +#ifdef WIN32 + for (p = ret; *p; p++) { + if (IS_KANJI (p)) + p++; + else if (*p == '\\') + *p = '/'; + } +#endif + /* printf("dpx_create_fix_temp_file: %s\n", ret); */ + return ret; +} + +int +dpx_clear_cache_filter (const struct dirent *ent) { + int plen = strlen(PREFIX); + if (strlen(ent->d_name) != plen + MAX_KEY_LEN * 2) return 0; +#ifdef WIN32 + return strncasecmp(ent->d_name, PREFIX, plen) == 0; +#else + return strncmp(ent->d_name, PREFIX, plen) == 0; +#endif +} + +void +dpx_delete_old_cache (int life) +{ + const char *dir = dpx_get_tmpdir(); + char *pathname = NEW(strlen(dir)+1+strlen(PREFIX)+MAX_KEY_LEN*2 + 1, char); + DIR *dp; + struct dirent *de; + time_t limit = time(NULL) - life * 60 * 60; + + if (life >= 0) keep_cache = true; + if ((dp = opendir(dir)) != NULL) { + while((de = readdir(dp)) != NULL) { + if (dpx_clear_cache_filter(de)) { + struct stat sb; + sprintf(pathname, "%s/%s", dir, de->d_name); + stat(pathname, &sb); + if (sb.st_mtime < limit) { + remove(pathname); + /* printf("remove: %s\n", pathname); */ + } + } + } + closedir(dp); + } + RELEASE(pathname); +} void -dpx_delete_temp_file (char *tmp) +dpx_delete_temp_file (char *tmp, int force) { if (!tmp) return; - remove (tmp); + if (force || !keep_cache) remove (tmp); RELEASE(tmp); return; diff --git a/Build/source/texk/xdvipdfmx/src/dpxfile.h b/Build/source/texk/xdvipdfmx/src/dpxfile.h index a165d42c61b..04d812156cd 100644 --- a/Build/source/texk/xdvipdfmx/src/dpxfile.h +++ b/Build/source/texk/xdvipdfmx/src/dpxfile.h @@ -62,6 +62,9 @@ extern int dpx_file_apply_filter (const char *cmdtmpl, const char *input, const char *output, unsigned char version); extern char *dpx_create_temp_file (void); -extern void dpx_delete_temp_file (char *tmp); /* tmp freed here */ +extern char *dpx_create_fix_temp_file (char *filename); +extern void dpx_delete_old_cache (int life); +extern void dpx_delete_temp_file (char *tmp, int force); /* tmp freed here */ +extern int keep_cache; #endif /* _DPXFILE_H_ */ diff --git a/Build/source/texk/xdvipdfmx/src/dvi.c b/Build/source/texk/xdvipdfmx/src/dvi.c index 8e56fae4bc1..5bb8d9aad5e 100644 --- a/Build/source/texk/xdvipdfmx/src/dvi.c +++ b/Build/source/texk/xdvipdfmx/src/dvi.c @@ -2168,7 +2168,7 @@ dvi_do_page (long n, case FNT_DEF4: do_fntdef4(0); break; /* pTeX extension */ - case DIR: + case PTEXDIR: do_dir(); break; @@ -2715,7 +2715,7 @@ dvi_scan_specials (long page_no, } break; #endif - case DIR: + case PTEXDIR: get_and_buffer_unsigned_byte(fp); break; diff --git a/Build/source/texk/xdvipdfmx/src/dvicodes.h b/Build/source/texk/xdvipdfmx/src/dvicodes.h index 4de92c5bd0c..964da579b15 100644 --- a/Build/source/texk/xdvipdfmx/src/dvicodes.h +++ b/Build/source/texk/xdvipdfmx/src/dvicodes.h @@ -119,7 +119,7 @@ Version byte (same as preamble) Padded by four or more 223's to the end of the file. */ #define PADDING 223 -#define DIR 255 /* Ascii pTeX DIR command */ +#define PTEXDIR 255 /* Ascii pTeX DIR command */ #ifdef XETEX #define XDV_PIC_FILE 251 /* include graphic or PDF file */ diff --git a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c index 376a9308a5d..932237574d3 100644 --- a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c +++ b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c @@ -89,6 +89,11 @@ static int really_quiet = 0; */ static int pdfdecimaldigits = 2; +/* Image cache life in hours */ +/* 0 means erase all old images and leave new images */ +/* -1 means erase all old images and also erase new images */ +static int image_cache_life = 48; + /* Encryption */ static int do_encryption = 0; static unsigned key_bits = 40; @@ -186,6 +191,9 @@ usage (int exit_code) fprintf (stdout, "\t\tAnd negative values replace old values.\n"); fprintf (stdout, "-D template\tPS->PDF conversion command line template [none]\n"); fprintf (stdout, "-E \t\tAlways try to embed fonts, regardless of licensing flags.\n"); + fprintf (stdout, "-I number\tImage cache life in hours [48]\n"); + fprintf (stdout, " \t 0: erase all old images and leave new images\n"); + fprintf (stdout, " \t-1: erase all old images and also erase new images\n"); fprintf (stdout, "-K number\tEncryption key length [40]\n"); fprintf (stdout, "-O number\tSet maximum depth of open bookmark items [0]\n"); fprintf (stdout, "-P number\tSet permission flags for PDF encryption [0x003C]\n"); @@ -524,6 +532,11 @@ do_args (int argc, char *argv[]) POP_ARG(); } break; + case 'I': + CHECK_ARG(1, "image cache life in hours"); + image_cache_life = (unsigned) atoi(argv[1]); + POP_ARG(); + break; case 'S': do_encryption = 1; break; @@ -865,6 +878,7 @@ main (int argc, char *argv[]) kpse_set_program_enabled(kpse_pk_format, true, kpse_src_texmf_cnf); #endif pdf_font_set_dpi(font_dpi); + dpx_delete_old_cache(image_cache_life); if (dvi_filename == NULL) { if (verbose) diff --git a/Build/source/texk/xdvipdfmx/src/pdfximage.c b/Build/source/texk/xdvipdfmx/src/pdfximage.c index 73cf63ff98b..6ac7b87f481 100644 --- a/Build/source/texk/xdvipdfmx/src/pdfximage.c +++ b/Build/source/texk/xdvipdfmx/src/pdfximage.c @@ -81,6 +81,8 @@ struct pdf_ximage_ pdf_obj *reference; pdf_obj *resource; pdf_obj *attr_dict; + + char tempfile; }; @@ -132,6 +134,18 @@ pdf_init_ximage_struct (pdf_ximage *I, const char *ident, const char *filename, I->attr.xdensity = I->attr.ydensity = 1.0; I->attr.bbox.llx = I->attr.bbox.lly = 0; I->attr.bbox.urx = I->attr.bbox.ury = 0; + + I->tempfile = 0; +} + +static void +pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename) +{ + if (I->filename) + RELEASE(I->filename); + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); + I->tempfile = 1; } static void @@ -166,19 +180,34 @@ pdf_close_images (void) struct ic_ *ic = &_ic; if (ic->ximages) { int i; - for (i = 0; i < ic->count; i++) - pdf_clean_ximage_struct(&ic->ximages[i]); + for (i = 0; i < ic->count; i++) { + pdf_ximage *I = ic->ximages+i; + if (I->tempfile) { + /* + * It is important to remove temporary files at the end because + * we cache file names. Since we use mkstemp to create them, we + * might get the same file name again if delete the first file. + * (This happens on NetBSD, reported by Jukka Salmi.) + * We also use this to convert a PS file only once if multiple + * pages are imported from that file. + */ + if (_opts.verbose > 1 && !keep_cache) + MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename); + dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */ + I->filename = NULL; + } + pdf_clean_ximage_struct(I); + } RELEASE(ic->ximages); + ic->ximages = NULL; + ic->count = ic->capacity = 0; } - ic->ximages = NULL; - ic->count = ic->capacity = 0; if (_opts.cmdtmpl) RELEASE(_opts.cmdtmpl); _opts.cmdtmpl = NULL; } - static int source_image_type (FILE *fp) { @@ -812,6 +841,7 @@ ps_include_page (pdf_ximage *ximage, const char *filename) char *temp; FILE *fp; int error = 0; + struct stat stat_o, stat_t; if (!distiller_template) { WARN("No image converter available for converting file \"%s\" to PDF format.", filename); @@ -819,7 +849,7 @@ ps_include_page (pdf_ximage *ximage, const char *filename) return -1; } - temp = dpx_create_temp_file(); + temp = dpx_create_fix_temp_file(filename); if (!temp) { WARN("Failed to create temporary file for image conversion: %s", filename); return -1; @@ -842,28 +872,35 @@ ps_include_page (pdf_ximage *ximage, const char *filename) } } #endif - error = dpx_file_apply_filter(distiller_template, filename, temp, + if (stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0 + && stat_t.st_mtime > stat_o.st_mtime) { + /* cache exist */ + /*printf("\nLast file modification: %s", ctime(&stat_o.st_mtime)); + printf("Last file modification: %s", ctime(&stat_t.st_mtime));*/ + } else { + error = dpx_file_apply_filter(distiller_template, filename, temp, (unsigned char) pdf_get_version()); - if (error) { - WARN("Image format conversion for \"%s\" failed...", filename); - dpx_delete_temp_file(temp); - return error; + if (error) { + WARN("Image format conversion for \"%s\" failed...", filename); + dpx_delete_temp_file(temp, true); + return error; + } } fp = MFOPEN(temp, FOPEN_RBIN_MODE); if (!fp) { WARN("Could not open conversion result \"%s\" for image \"%s\". Why?", temp, filename); - dpx_delete_temp_file(temp); + dpx_delete_temp_file(temp, true); return -1; } + pdf_set_ximage_tempfile(ximage, temp); // error = pdf_include_page(ximage, fp, 0, pdfbox_crop); error = pdf_include_page(ximage, fp); MFCLOSE(fp); - if (_opts.verbose > 1) { - MESG("pdf_image>> deleting file \"%s\"", temp); - } - dpx_delete_temp_file(temp); /* temp freed here */ + /* See pdf_close_images for why we cannot delete temporary files here. */ + + RELEASE(temp); if (error) { WARN("Failed to include image file \"%s\"", filename); diff --git a/Build/source/texk/xdvipdfmx/src/spc_dvips.c b/Build/source/texk/xdvipdfmx/src/spc_dvips.c index 94d21ae98da..24c415d3699 100644 --- a/Build/source/texk/xdvipdfmx/src/spc_dvips.c +++ b/Build/source/texk/xdvipdfmx/src/spc_dvips.c @@ -320,7 +320,7 @@ spc_handler_ps_tricks_pdef (struct spc_env *spe, struct spc_arg *args) pdf_concatmatrix(&M, &T); if (!page_defs) - page_defs = dpx_create_temp_file(); + page_defs = dpx_create_fix_temp_file("page_defs"); if (!page_defs) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -340,7 +340,7 @@ spc_handler_ps_tricks_tdef (struct spc_env *spe, struct spc_arg *args) { FILE* fp; if (!temporary_defs) - temporary_defs = dpx_create_temp_file(); + temporary_defs = dpx_create_fix_temp_file("temp_defs"); if (!temporary_defs) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -374,7 +374,7 @@ spc_handler_ps_tricks_bput (struct spc_env *spe, struct spc_arg *args, int must_ } if (pre_def == 0) { - dpx_delete_temp_file(temporary_defs); + dpx_delete_temp_file(temporary_defs, true); temporary_defs = 0; } @@ -400,7 +400,7 @@ spc_handler_ps_tricks_bput (struct spc_env *spe, struct spc_arg *args, int must_ if (must_def != 0) { FILE* fp; if (!temporary_defs) - temporary_defs = dpx_create_temp_file(); + temporary_defs = dpx_create_fix_temp_file("temp_defs_a"); if (!temporary_defs) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -545,7 +545,7 @@ spc_handler_ps_tricks_parse_path (struct spc_env *spe, struct spc_arg *args, pdf_dev_currentmatrix(&M); if (!gs_in) { - gs_in = dpx_create_temp_file(); + gs_in = dpx_create_fix_temp_file("gs_in"); if (!gs_in) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -583,7 +583,7 @@ spc_handler_ps_tricks_parse_path (struct spc_env *spe, struct spc_arg *args, } fclose(fp); - gs_out = dpx_create_temp_file(); + gs_out = dpx_create_fix_temp_file("gs_out"); if (!gs_out) { WARN("Failed to create temporary output file for PSTricks image conversion."); RELEASE(gs_in); @@ -620,8 +620,8 @@ spc_handler_ps_tricks_parse_path (struct spc_env *spe, struct spc_arg *args, } fclose(fp); - dpx_delete_temp_file(gs_out); - dpx_delete_temp_file(gs_in); + dpx_delete_temp_file(gs_out, true); + dpx_delete_temp_file(gs_in, true); gs_in = 0; return 0; @@ -639,7 +639,7 @@ spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args) pdf_dev_currentmatrix(&M); if (!gs_in) { - gs_in = dpx_create_temp_file(); + gs_in = dpx_create_fix_temp_file("gs_in_a"); if (!gs_in) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -671,7 +671,7 @@ spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args) fclose(fp); - gs_out = dpx_create_temp_file(); + gs_out = dpx_create_fix_temp_file("gs_out_a"); if (!gs_out) { WARN("Failed to create temporary output file for PSTricks image conversion."); RELEASE(gs_in); @@ -708,8 +708,8 @@ spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args) } pdf_dev_put_image(form_id, &p, 0, 0); - dpx_delete_temp_file(gs_out); - dpx_delete_temp_file(gs_in); + dpx_delete_temp_file(gs_out, true); + dpx_delete_temp_file(gs_in, true); gs_in = 0; } @@ -873,7 +873,7 @@ int spc_dvips_at_begin_page (void) { if (page_defs) { - dpx_delete_temp_file(page_defs); + dpx_delete_temp_file(page_defs, true); page_defs = 0; } @@ -887,7 +887,7 @@ spc_dvips_at_end_page (void) { mps_eop_cleanup(); if (!temporary_defs) { - dpx_delete_temp_file(temporary_defs); + dpx_delete_temp_file(temporary_defs, true); temporary_defs = 0; } return 0; @@ -899,7 +899,7 @@ spc_dvips_at_begin_document (void) FILE* fp; /* This, together with \pscharpath support code, must be moved to xtex.pro header. */ - global_defs = dpx_create_temp_file(); + global_defs = dpx_create_fix_temp_file("global_defs"); if (!global_defs) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -920,8 +920,8 @@ spc_dvips_at_end_document (void) free(ps_headers); ps_headers = NULL; } - dpx_delete_temp_file(global_defs); - dpx_delete_temp_file(page_defs); + dpx_delete_temp_file(global_defs, true); + dpx_delete_temp_file(page_defs, true); return 0; } @@ -1021,7 +1021,7 @@ int calculate_PS (char *string, int length, double *res1, double *res2, double * if (res1 == 0 && res2 == 0) return -1; - formula = dpx_create_temp_file(); + formula = dpx_create_fix_temp_file("formula"); if (!formula) { WARN("Failed to create temporary input file for PSTricks image conversion."); return -1; @@ -1066,6 +1066,6 @@ int calculate_PS (char *string, int length, double *res1, double *res2, double * pclose(coord); RELEASE(cmd); - dpx_delete_temp_file(formula); + dpx_delete_temp_file(formula, true); return 0; } diff --git a/Build/source/texk/xdvipdfmx/src/vf.c b/Build/source/texk/xdvipdfmx/src/vf.c index bfd735b8ab2..fea4f2739df 100644 --- a/Build/source/texk/xdvipdfmx/src/vf.c +++ b/Build/source/texk/xdvipdfmx/src/vf.c @@ -986,7 +986,7 @@ void vf_set_char(SIGNED_QUAD ch, int vf_font) case XXX4: vf_xxx4(&start, end); break; - case DIR: + case PTEXDIR: vf_dir(&start, end); break; default: |