Back to index

texmacs  1.0.7.15
dpxfile.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/dpxfile.c,v 1.26 2010/05/29 20:56:41 matthias Exp $
00002     
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014     
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU General Public License for more details.
00019     
00020     You should have received a copy of the GNU General Public License
00021     along with this program; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00023 */
00024 
00025 #if HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028 
00029 #include <unistd.h>
00030 
00031 #include "system.h"
00032 #include "error.h"
00033 #include "mem.h"
00034 
00035 #include "dpxutil.h"
00036 #include "mfileio.h"
00037 
00038 #include "dpxfile.h"
00039 
00040 static int verbose = 0;
00041 
00042 void
00043 dpx_file_set_verbose (void)
00044 {
00045   verbose++;
00046 }
00047 
00048 
00049 /* Kpathsea library does not check file type. */
00050 static int qcheck_filetype (const char *fqpn, int type);
00051 
00052 /* For testing MIKTEX enabled compilation */
00053 #if defined(TESTCOMPILE) && !defined(MIKTEX)
00054 #  define MIKTEX        1
00055 #  define PATH_SEP_CHR  '/'
00056 #  define _MAX_PATH     256
00057 
00058 static int
00059 miktex_get_acrobat_font_dir (char *buf)
00060 {
00061   strcpy(buf, "/usr/share/ghostscript/Resource/Font/");
00062   return  1;
00063 }
00064 
00065 static int
00066 miktex_find_file (const char *filename, const char *dirlist, char *buf)
00067 {
00068   int    r = 0;
00069   char  *fqpn;
00070 
00071   fqpn = kpse_path_search(dirlist, filename, 0);
00072   if (!fqpn)
00073     return  0;
00074   if (strlen(fqpn) > _MAX_PATH)
00075     r = 0;
00076   else {
00077     strcpy(buf, fqpn);
00078     r = 1;
00079   }
00080   RELEASE(fqpn);
00081 
00082   return  r;
00083 }
00084 
00085 static int
00086 miktex_find_app_input_file (const char *progname, const char *filename, char *buf)
00087 {
00088   int    r = 0;
00089   char  *fqpn;
00090 
00091   kpse_reset_program_name(progname);
00092   fqpn = kpse_find_file  (filename, kpse_program_text_format, false);
00093   kpse_reset_program_name(PACKAGE);
00094 
00095   if (!fqpn)
00096     return  0;
00097   if (strlen(fqpn) > _MAX_PATH)
00098     r = 0;
00099   else {
00100     strcpy(buf, fqpn);
00101     r = 1;
00102   }
00103   RELEASE(fqpn);
00104 
00105   return  r;
00106 }
00107 
00108 static int
00109 miktex_find_psheader_file (const char *filename, char *buf)
00110 {
00111   int    r;
00112   char  *fqpn;
00113 
00114   fqpn = kpse_find_file(filename, kpse_tex_ps_header_format, 0);
00115 
00116   if (!fqpn)
00117     return  0;
00118   if (strlen(fqpn) > _MAX_PATH)
00119     r = 0;
00120   else {
00121     strcpy(buf, fqpn);
00122     r = 1;
00123   }
00124   RELEASE(fqpn);
00125 
00126   return  r; 
00127 }
00128 
00129 #endif /* TESTCOMPILE */
00130 
00131 #ifdef  MIKTEX
00132 #ifndef PATH_SEP_CHR
00133 #  define PATH_SEP_CHR '\\'
00134 #endif
00135 static char  _tmpbuf[_MAX_PATH+1];
00136 #endif /* MIKTEX */
00137 
00138 
00139 /* ensuresuffix() returns a copy of basename if sfx is "". */
00140 static char *
00141 ensuresuffix (const char *basename, const char *sfx)
00142 {
00143   char  *q, *p;
00144 
00145   p = NEW(strlen(basename) + strlen(sfx) + 1, char);
00146   strcpy(p, basename);
00147   q = strrchr(p, '.');
00148   if (!q && sfx[0])
00149     strcat(p, sfx);
00150 
00151   return  p;
00152 }
00153 
00154 #ifdef  MIKTEX
00155 static char *
00156 dpx_find__app__xyz (const char *filename,
00157                     const char *suffix, int is_text)
00158 {
00159   char  *fqpn = NULL;
00160   int    r;
00161   char  *q;
00162 
00163   q = ensuresuffix(filename, suffix);
00164   r = miktex_find_app_input_file(PACKAGE, q, _tmpbuf);
00165   if (!r && strcmp(q, filename))
00166     r = miktex_find_app_input_file(PACKAGE, filename, _tmpbuf);
00167   if (r) {
00168     fqpn = NEW(strlen(_tmpbuf) + 1, char);
00169     strcpy(fqpn, _tmpbuf);
00170   }
00171   RELEASE(q);
00172 
00173   return  fqpn;
00174 }
00175 
00176 static char *
00177 dpx_foolsearch (const char  *foolname,
00178                 const char  *filename,
00179                 int          is_text)
00180 {
00181   char  *fqpn = NULL;
00182   int    r;
00183 
00184   r = miktex_find_app_input_file(foolname, filename, _tmpbuf);
00185   if (r) {
00186     fqpn = NEW(strlen(_tmpbuf) + 1, char);
00187     strcpy(fqpn, _tmpbuf);
00188   }
00189 
00190   return  fqpn;
00191 }
00192 #else /* TEXK */
00193 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00194 #  define TDS11DOC "http://www.tug.org/ftp/tex/tds-1.1/tds.html#Fonts"
00195 static void
00196 insistupdate (const char      *filename,
00197               const char      *fqpn,
00198               const char      *foolname,
00199               kpse_file_format_type foolformat,
00200               kpse_file_format_type realformat)
00201 {
00202   kpse_format_info_type *fif;
00203   kpse_format_info_type *fir;
00204   if (verbose < 1)
00205     return;
00206   fif = &kpse_format_info[foolformat];
00207   fir = &kpse_format_info[realformat];
00208   WARN("File name=\"%s\" format=\"%s\" might be found in different location than I expected:",
00209        filename, fir->type);
00210   WARN(">>   %s", fqpn);
00211   WARN(">> Please adjust your TEXMF as conformant with:");
00212   WARN(">>   " TDS11DOC);
00213   WARN(">> I searched it with fooling kpathsea as progname=\"%s\" format=\"%s\".",
00214        foolname, fif->type);
00215   WARN(">> Default search path for this format file is:");
00216   WARN(">>   %s", fir->default_path);
00217   WARN(">> Please read \"README\" file.");
00218 }
00219 #endif /* TDS 1.1 */
00220 
00221 static char *
00222 dpx_find__app__xyz (const char *filename,
00223                     const char *suffix, int is_text)
00224 {
00225 #ifdef NOKPSE
00226   char  *fqpn = NULL;
00227   char  *q;
00228 
00229   q    = ensuresuffix(filename, suffix);
00230   fqpn = kpse_find_file(q,
00231                          (is_text ?
00232                             kpse_program_text_format : kpse_program_binary_format), 0);
00233   if (!fqpn && strcmp(q, filename))
00234     fqpn = kpse_find_file(filename,
00235                            (is_text ?
00236                               kpse_program_text_format : kpse_program_binary_format), 0);   
00237   RELEASE(q);
00238 
00239   return  fqpn;
00240 #else
00241   return NULL;
00242 #endif
00243 }
00244 
00245 static char *
00246 dpx_foolsearch (const char  *foolname,
00247                 const char  *filename,
00248                 int          is_text)
00249 {
00250 #ifdef NOKPSE
00251   char  *fqpn = NULL;
00252 
00253   kpse_reset_program_name(foolname);
00254   fqpn = kpse_find_file  (filename,
00255                           (is_text ?
00256                               kpse_program_text_format :
00257                               kpse_program_binary_format),
00258                           false);
00259   kpse_reset_program_name(PACKAGE);
00260 
00261   return  fqpn;
00262 #else
00263   return NULL;
00264 #endif
00265 }
00266 #endif /* MIKTEX */
00267 
00268 static char *dpx_find_fontmap_file  (const char *filename);
00269 static char *dpx_find_agl_file      (const char *filename);
00270 static char *dpx_find_sfd_file      (const char *filename);
00271 static char *dpx_find_cmap_file     (const char *filename);
00272 static char *dpx_find_enc_file      (const char *filename);
00273 static char *dpx_find_opentype_file (const char *filename);
00274 static char *dpx_find_truetype_file (const char *filename);
00275 static char *dpx_find_type1_file    (const char *filename);
00276 static char *dpx_find_iccp_file     (const char *filename);
00277 static char *dpx_find_dfont_file    (const char *filename);
00278 
00279 FILE *
00280 dpx_open_file (const char *filename, int type)
00281 {
00282 #ifdef NOKPSE
00283   FILE  *fp   = NULL;
00284   char  *fqpn = NULL;
00285 
00286   switch (type) {
00287   case DPX_RES_TYPE_FONTMAP:
00288     fqpn = dpx_find_fontmap_file(filename);
00289     break;
00290   case DPX_RES_TYPE_T1FONT:
00291     fqpn = dpx_find_type1_file(filename);
00292     break;
00293   case DPX_RES_TYPE_TTFONT:
00294     fqpn = dpx_find_truetype_file(filename);
00295     break;
00296   case DPX_RES_TYPE_OTFONT:
00297     fqpn = dpx_find_opentype_file(filename);
00298     break;
00299   case DPX_RES_TYPE_PKFONT:
00300     break;
00301   case DPX_RES_TYPE_CMAP:
00302     fqpn = dpx_find_cmap_file(filename);
00303     break;
00304   case DPX_RES_TYPE_ENC:
00305     fqpn = dpx_find_enc_file(filename);
00306     break;
00307   case DPX_RES_TYPE_SFD:
00308     fqpn = dpx_find_sfd_file(filename);
00309     break;
00310   case DPX_RES_TYPE_AGL:
00311     fqpn = dpx_find_agl_file(filename);
00312     break;
00313   case DPX_RES_TYPE_ICCPROFILE:
00314     fqpn = dpx_find_iccp_file(filename);
00315     break;
00316   case DPX_RES_TYPE_DFONT:
00317     fqpn = dpx_find_dfont_file(filename);
00318     break;
00319   case DPX_RES_TYPE_BINARY:
00320     fqpn = dpx_find__app__xyz(filename, "", 0);
00321     break;
00322   case DPX_RES_TYPE_TEXT:
00323     fqpn = dpx_find__app__xyz(filename, "", 1);
00324     break;
00325   default:
00326     ERROR("Unknown resource type: %d", type);
00327     break;
00328   }
00329   if (fqpn) {
00330     fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
00331     RELEASE(fqpn);
00332   }
00333 
00334   return  fp;
00335 #else
00336   return NULL;
00337 #endif
00338 }
00339 
00340 
00341 static char *
00342 dpx_find_iccp_file (const char *filename)
00343 {
00344   char  *fqpn = NULL;
00345 
00346   fqpn = dpx_find__app__xyz(filename, "", 0);
00347   if (fqpn || strrchr(filename, '.'))
00348     return  fqpn;
00349 
00350   fqpn = dpx_find__app__xyz(filename, ".icc", 0);
00351   if (fqpn)
00352     return  fqpn;
00353 
00354   fqpn = dpx_find__app__xyz(filename, ".icm", 0);
00355 
00356   return  fqpn;
00357 }
00358 
00359 
00360 static char *
00361 dpx_find_fontmap_file (const char *filename)
00362 {
00363 #ifdef NOKPSE
00364   char  *fqpn = NULL;
00365   char  *q;
00366 
00367   q = ensuresuffix(filename, ".map");
00368 #ifdef  MIKTEX
00369   fqpn = dpx_find__app__xyz(q, ".map", 1);
00370 #else /* !MIKTEX */
00371   fqpn = kpse_find_file(q, kpse_fontmap_format, 0);
00372   if (!fqpn) {
00373     fqpn = dpx_find__app__xyz(q, ".map", 1);
00374 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00375     if (fqpn)
00376       insistupdate(q, fqpn, PACKAGE,
00377                    kpse_program_text_format, kpse_fontmap_format); 
00378 #endif
00379   }
00380 #endif /* MIKETEX */
00381   RELEASE(q);
00382 
00383   return  fqpn;
00384 #else
00385   return NULL;
00386 #endif
00387 }
00388 
00389 
00390 static char *
00391 dpx_find_agl_file (const char *filename)
00392 {
00393 #ifdef NOKPSE
00394   char  *fqpn = NULL;
00395   char  *q;
00396 
00397   q = ensuresuffix(filename, ".txt");
00398 #ifdef  MIKTEX
00399   fqpn = dpx_find__app__xyz(q, ".txt", 1);
00400 #else /* !MIKTEX */
00401   fqpn = kpse_find_file(q, kpse_fontmap_format, 0);
00402   if (!fqpn) {
00403     fqpn = dpx_find__app__xyz(q, ".txt", 1);
00404 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00405     if (fqpn)
00406       insistupdate(q, fqpn, PACKAGE,
00407                    kpse_program_text_format, kpse_fontmap_format); 
00408 #endif
00409   }
00410 #endif /* MIKETEX */
00411   RELEASE(q);
00412 
00413   return  fqpn;
00414 #else
00415   return NULL;
00416 #endif
00417 }
00418 
00419 
00420 /* cmap.sty put files into tex/latex/cmap */
00421 static char *
00422 dpx_find_cmap_file (const char *filename)
00423 {
00424   char  *fqpn = NULL;
00425   static const char *fools[] = {
00426     "cmap", "tex", NULL
00427   };
00428   int    i;
00429 
00430 #if  defined(MIKTEX)
00431   /* Find in Acrobat's Resource/CMap dir */
00432   {
00433     char  _acrodir[_MAX_PATH+1];
00434     char  *q;
00435     int    r;
00436 
00437     memset(_acrodir, 0, _MAX_PATH+1);
00438     r = miktex_get_acrobat_font_dir(_acrodir);
00439     if (r &&
00440         strlen(_acrodir) > strlen("Font")) {
00441       /* ....\Font\ */
00442       q = strrchr(_acrodir, PATH_SEP_CHR);
00443       if (q && q[1] == '\0')
00444         q[0] = '\0';
00445       q = strrchr(_acrodir, PATH_SEP_CHR);
00446       if (q && !strcmp(q + 1, "Font")) {
00447         sprintf(q, "%cCMap%c", PATH_SEP_CHR, PATH_SEP_CHR);
00448         r = miktex_find_file(filename, _acrodir, _tmpbuf);
00449         if (r) {
00450           fqpn = NEW(strlen(_tmpbuf) + 1, char);
00451           strcpy(fqpn, _tmpbuf);
00452         }
00453       }
00454     }
00455     memset(_tmpbuf, 0, _MAX_PATH+1);
00456   }
00457 #else
00458 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L  
00459   fqpn = kpse_find_file(filename, kpse_cmap_format, 0); 
00460 #endif  
00461 #endif
00462 
00463   /* Files found above are assumed to be CMap,
00464    * if it's not really CMap it will cause an error.
00465    */
00466   for (i = 0; !fqpn && fools[i]; i++) { 
00467     fqpn = dpx_foolsearch(fools[i], filename, 1);
00468     if (fqpn) {
00469 #ifndef  MIKTEX
00470 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00471       insistupdate(filename, fqpn, fools[i],
00472                    kpse_program_text_format, kpse_cmap_format); 
00473 #endif
00474 #endif
00475       if (!qcheck_filetype(fqpn, DPX_RES_TYPE_CMAP)) {
00476         WARN("Found file \"%s\" for PostScript CMap but it doesn't look like a CMap...", fqpn);
00477         RELEASE(fqpn);
00478         fqpn = NULL;
00479       }
00480     }
00481   }
00482 
00483   return  fqpn;
00484 }
00485 
00486 
00487 /* Search order:
00488  *   SFDFONTS (TDS 1.1)
00489  *   ttf2pk   (text file)
00490  *   ttf2tfm  (text file)
00491  *   dvipdfm  (text file)   
00492  */
00493 static char *
00494 dpx_find_sfd_file (const char *filename)
00495 {
00496   char  *fqpn = NULL;
00497   char  *q;
00498   static const char *fools[] = {
00499     "ttf2pk", "ttf2tfm", NULL
00500   };
00501   int    i;
00502 
00503   q    = ensuresuffix(filename, ".sfd");
00504 #ifndef  MIKTEX
00505 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00506   fqpn = kpse_find_file(q, kpse_sfd_format, 0);
00507 #endif
00508 #endif /* !MIKTEX */
00509 
00510   for (i = 0; !fqpn && fools[i]; i++) { 
00511     fqpn = dpx_foolsearch(fools[i], q, 1);
00512 #ifndef  MIKTEX
00513 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00514     if (fqpn)
00515       insistupdate(filename, fqpn, fools[i],
00516                    kpse_program_text_format, kpse_sfd_format); 
00517 #endif
00518 #endif
00519   }
00520   RELEASE(q);
00521 
00522   return  fqpn;
00523 }
00524 
00525 
00526 static char *
00527 dpx_find_enc_file (const char *filename)
00528 {
00529 #ifdef NOKPSE
00530   char  *fqpn = NULL;
00531   char  *q;
00532   static const char *fools[] = {
00533     "dvips", NULL
00534   };
00535   int    i;
00536 
00537   q = ensuresuffix(filename, ".enc");
00538 #ifdef  MIKTEX
00539   if (miktex_find_psheader_file(q, _tmpbuf)) {
00540     fqpn = NEW(strlen(_tmpbuf) + 1, char);
00541     strcpy(fqpn, _tmpbuf);
00542   }
00543 #else
00544 # if defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00545   fqpn = kpse_find_file(q, kpse_enc_format, 0);
00546 # else
00547   fqpn = kpse_find_file(q, kpse_tex_ps_header_format, 0);
00548 # endif
00549 #endif /* MIKTEX */
00550 
00551   for (i = 0; !fqpn && fools[i]; i++) { 
00552     fqpn = dpx_foolsearch(fools[i], q, 1);
00553 #ifndef  MIKTEX
00554 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00555     if (fqpn)
00556       insistupdate(filename, fqpn, fools[i],
00557                    kpse_program_text_format, kpse_enc_format); 
00558 #endif
00559 #endif
00560   }
00561   RELEASE(q);
00562 
00563   return  fqpn;
00564 #else
00565   return NULL;
00566 #endif
00567 }
00568 
00569 
00570 
00571 static char *
00572 dpx_find_type1_file (const char *filename)
00573 {
00574 #ifdef NOKPSE
00575   char  *fqpn = NULL;
00576 
00577   fqpn = kpse_find_file(filename, kpse_type1_format, 0);
00578   if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_T1FONT)) {
00579     RELEASE(fqpn);
00580     fqpn = NULL;
00581   }
00582 
00583   return  fqpn;
00584 #else
00585   return NULL;
00586 #endif
00587 }
00588 
00589 
00590 static char *
00591 dpx_find_truetype_file (const char *filename)
00592 {
00593 #ifdef NOKPSE
00594   char  *fqpn = NULL;
00595 
00596   fqpn = kpse_find_file(filename, kpse_truetype_format, 0);
00597   if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_TTFONT)) {
00598     RELEASE(fqpn);
00599     fqpn = NULL;
00600   }
00601 
00602   return  fqpn;
00603 #else
00604   return NULL;
00605 #endif
00606 }
00607 
00608 
00609 static char *
00610 dpx_find_opentype_file (const char *filename)
00611 {
00612   char  *fqpn = NULL;
00613   char  *q;
00614 
00615   q = ensuresuffix(filename, ".otf");
00616 #ifndef MIKTEX
00617 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00618   fqpn = kpse_find_file(q, kpse_opentype_format, 0);
00619   if (!fqpn) {
00620 #endif
00621 #endif
00622     fqpn = dpx_foolsearch(PACKAGE, q, 0);
00623 #ifndef  MIKTEX
00624 #if  defined(__TDS_VERSION__) && __TDS_VERSION__ >= 0x200406L
00625     if (fqpn)
00626       insistupdate(filename, fqpn, PACKAGE,
00627                    kpse_program_binary_format, kpse_opentype_format); 
00628   }
00629 #endif
00630 #endif
00631   RELEASE(q);
00632 
00633   /* *We* use "opentype" for ".otf" (CFF). */
00634   if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_OTFONT)) {
00635     RELEASE(fqpn);
00636     fqpn = NULL;
00637   }
00638 
00639   return  fqpn;
00640 }
00641 
00642 
00643 static char *
00644 dpx_find_dfont_file (const char *filename)
00645 {
00646 #ifdef NOKPSE
00647   char *fqpn = NULL;
00648 
00649   fqpn = kpse_find_file(filename, kpse_truetype_format, 0);
00650   if (fqpn) {
00651     int len = strlen(fqpn);
00652     if (len > 6 && strncmp(fqpn+len-6, ".dfont", 6)) {
00653       fqpn = RENEW(fqpn, len+6, char);
00654       strcat(fqpn, "/rsrc");
00655     }
00656   }
00657   if (!qcheck_filetype(fqpn, DPX_RES_TYPE_DFONT)) {
00658     RELEASE(fqpn);
00659     fqpn = NULL;
00660   }
00661   return fqpn;
00662 #else
00663   return NULL;
00664 #endif
00665 }
00666  
00667 
00668 #ifdef  HAVE_MKSTEMP
00669 #  include <stdlib.h>
00670 /* extern int mkstemp(const char *); */
00671 #endif
00672 
00673 /* Please fix: GCC warning
00674  *   warning: implicit declaration of function `mkstemp'
00675  * mkstemp may not be declared in stdlib.h. 
00676  */
00677 char *
00678 dpx_create_temp_file (void)
00679 {
00680   char  *tmp = NULL;
00681 
00682 #if   defined(MIKTEX)
00683   {
00684     tmp = NEW(_MAX_PATH + 1, char);
00685     miktex_create_temp_file_name(tmp); /* FIXME_FIXME */
00686   }
00687 #elif defined(HAVE_MKSTEMP)
00688 #  define __TMPDIR     "/tmp"
00689 #  define TEMPLATE     "/dvipdfmx.XXXXXX"
00690   {
00691     char *_tmpd;
00692     int   _fd = -1;
00693 #  ifdef  HAVE_GETENV
00694     _tmpd = getenv("TMPDIR");
00695     if (!_tmpd)
00696       _tmpd = (char *) __TMPDIR;
00697 #  else
00698     _tmpd = (char *) __TMPDIR;
00699 #  endif /* HAVE_GETENV */
00700     tmp = NEW(strlen(_tmpd) + strlen(TEMPLATE) + 1, char);
00701     strcpy(tmp, _tmpd);
00702     strcat(tmp, TEMPLATE);
00703     _fd  = mkstemp(tmp);
00704     if (_fd != -1)
00705 #ifdef WIN32
00706       _close(_fd);
00707 #else
00708       close(_fd);
00709 #endif /* WIN32 */
00710     else {
00711       RELEASE(tmp);
00712       tmp = NULL;
00713     }
00714   }
00715 #else /* use tmpnam */
00716   {
00717     char *_tmpa = NEW(L_tmpnam + 1, char);
00718     tmp = tmpnam(_tmpa);
00719     if (!tmp)
00720       RELEASE(_tmpa);
00721   }
00722 #endif /* MIKTEX */
00723 
00724   return  tmp;
00725 }
00726 
00727 void
00728 dpx_delete_temp_file (char *tmp)
00729 {
00730   if (!tmp)
00731     return;
00732   remove (tmp);
00733   RELEASE(tmp);
00734 
00735   return;
00736 }
00737 
00738 #define HAVE_SYSTEM 1
00739 #ifdef HAVE_SYSTEM
00740 /* dpx_file_apply_filter() is used for converting unsupported graphics
00741  * format to one of the formats that dvipdfmx can natively handle.
00742  * 'input' is the filename of the original file and 'output' is actually
00743  * temporal files 'generated' by the above routine.   
00744  * This should be system dependent. (MiKTeX may want something different)
00745  * Please modify as appropriate (see also pdfximage.c and dvipdfmx.c).
00746  */
00747 int
00748 dpx_file_apply_filter (const char *cmdtmpl,
00749                       const char *input, const char *output,
00750                       unsigned short version)
00751 {
00752   char   *cmd = NULL;
00753   char   *p, *q;
00754   size_t  n, size;
00755   int     error = 0;
00756 
00757   if (!cmdtmpl)
00758     return -1;
00759   else if (!input || !output)
00760     return -1;
00761 
00762   size = strlen(cmdtmpl) + strlen(input) + strlen(output) + 3;
00763   cmd  = NEW(size, char);
00764   memset(cmd, 0, size);
00765   for (n = 0, p = (char *) cmdtmpl; *p != 0; p++) {
00766 #define need(s,l,m,n) \
00767 if ((l) + (n) >= (m)) { \
00768   (m) += (n) + 128; \
00769   (s)  = RENEW((s), (m), char); \
00770 }
00771     if (p[0] == '%') {
00772       p++;
00773       switch (p[0]) {
00774       case 'o': /* Output file name */
00775         need(cmd, n, size, strlen(output));
00776         strcpy(cmd + n, output); n += strlen(output);
00777         break;
00778       case 'i': /* Input filename */
00779         need(cmd, n, size, strlen(input));
00780         strcpy(cmd + n, input);  n += strlen(input);
00781         break;
00782       case 'b':
00783         need(cmd, n, size, strlen(input));
00784         q = strrchr(input, '.'); /* wrong */
00785         if (q) {
00786           memcpy(cmd + n, input, (int) (q - input));
00787           n += (int) (q - input);
00788         } else {
00789           strcpy(cmd + n, input); n += strlen(input);
00790         }
00791       case  'v': /* Version number, e.g. 1.4 */ {
00792        char buf[16];
00793        sprintf(buf, "1.%hu", version);
00794        need(cmd, n, size, strlen(buf));
00795        strcpy(cmd + n, buf);  n += strlen(buf);
00796        break;
00797       }
00798       case  0:
00799         break;
00800       case '%':
00801         need(cmd, n, size, 1);
00802         cmd[n] = '%'; n++;
00803         break;
00804       }
00805     } else {
00806       need(cmd, n, size, 1);
00807       cmd[n] = p[0]; n++;
00808     }
00809   }
00810   need(cmd, n, size, 1);
00811   cmd[n] = '\0';
00812   if (strlen(cmd) == 0) {
00813     RELEASE(cmd);
00814     return -1;
00815   }
00816 
00817   error = system(cmd);
00818   if (error)
00819     WARN("Filtering file via command -->%s<-- failed.", cmd);
00820   RELEASE(cmd);
00821 
00822   return  error;
00823 }
00824 #else
00825 int
00826 dpx_file_apply_filter (const char *cmdtmpl, const char *input, const char *output)
00827 {
00828   WARN("Your system does not have system().");
00829   return  -1;
00830 }
00831 #endif /* HAVE_SYSTEM */
00832 
00833 static char _sbuf[128];
00834 /*
00835  * SFNT type sigs:
00836  *  `true' (0x74727565): TrueType (Mac)
00837  *  `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
00838  *  0x00010000: TrueType (Win)/OpenType
00839  *  `OTTO': PostScript CFF font with OpenType wrapper
00840  *  `ttcf': TrueType Collection
00841  */
00842 static int
00843 istruetype (FILE *fp)
00844 {
00845   int   n;
00846 
00847   rewind(fp);
00848   n = fread(_sbuf, 1, 4, fp);
00849   rewind(fp);
00850 
00851   if (n != 4)
00852     return  0;
00853   else if (!memcmp(_sbuf, "true", 4) ||
00854            !memcmp(_sbuf, "\0\1\0\0", 4)) /* This doesn't help... */
00855     return  1;
00856   else if (!memcmp(_sbuf, "ttcf", 4))
00857     return  1;
00858 
00859   return  0;
00860 }
00861       
00862 /* "OpenType" is only for ".otf" here */
00863 static int
00864 isopentype (FILE *fp)
00865 {
00866   int   n;
00867 
00868   rewind(fp);
00869   n = fread(_sbuf, 1, 4, fp);
00870   rewind(fp);
00871 
00872   if (n != 4)
00873     return  0;
00874   else if (!memcmp(_sbuf, "OTTO", 4))
00875     return  1;
00876   else
00877     return  0;
00878 }
00879 
00880 static int
00881 ist1binary (FILE *fp)
00882 {
00883   char *p;
00884   int   n;
00885 
00886   rewind(fp);
00887   n = fread(_sbuf, 1, 21, fp);
00888   rewind(fp);
00889 
00890   p = _sbuf;
00891   if (n != 21)
00892     return  0;
00893   else if (p[0] != (char) 0x80 || p[1] < 0 || p[1] > 3)
00894     return  0;
00895   else if (!memcmp(p + 6, "%!PS-AdobeFont", 14) ||
00896            !memcmp(p + 6, "%!FontType1", 11))
00897     return  1;
00898   else if (!memcmp(p + 6, "%!PS", 4)) {
00899 #if  0
00900     p[20] = '\0'; p += 6;
00901     WARN("Ambiguous PostScript resource type: %s", (char *) p);
00902 #endif
00903     return  1;
00904   }
00905   /* Otherwise ambiguious */
00906   return  0;
00907 }
00908 
00909 /* %!PS-Adobe-x.y Resource-CMap */
00910 static int
00911 ispscmap (FILE *fp)
00912 {
00913   char  *p;
00914   p = mfgets(_sbuf, 128, fp); p[127] = '\0';
00915   if (!p || strlen(p) < 4 || memcmp(p, "%!PS", 4))
00916     return 0;
00917   for (p += 4; *p && !isspace(*p); p++);
00918   for ( ; *p && (*p == ' ' || *p == '\t'); p++);
00919   if (*p == '\0' || strlen(p) < strlen("Resource-CMap"))
00920     return  0;
00921   else if (!memcmp(p, "Resource-CMap", strlen("Resource-CMap")))
00922     return  1;
00923   /* Otherwise ambiguious */
00924   return  0;
00925 }
00926 
00927 static int
00928 isdfont (FILE *fp)
00929 {
00930   int i, n;
00931   unsigned long pos;
00932 
00933   rewind(fp);
00934 
00935   get_unsigned_quad(fp);
00936   seek_absolute(fp, (pos = get_unsigned_quad(fp)) + 0x18);
00937   seek_absolute(fp, pos + get_unsigned_pair(fp));
00938   n = get_unsigned_pair(fp);
00939   for (i = 0; i <= n; i++) {
00940     if (get_unsigned_quad(fp) == 0x73666e74UL) /* "sfnt" */
00941       return 1;
00942     get_unsigned_quad(fp);
00943   }
00944   return 0;
00945 }
00946       
00947 /* This actually opens files. */
00948 static int
00949 qcheck_filetype (const char *fqpn, int type)
00950 {
00951   int    r = 1;
00952   FILE  *fp;
00953 
00954   if (!fqpn)
00955     return  0;
00956 
00957   fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
00958   if (!fp) {
00959     WARN("File \"%s\" found but I could not open that...", fqpn);
00960     return  0;
00961   }
00962   switch (type) {
00963   case DPX_RES_TYPE_T1FONT:
00964     r = ist1binary(fp);
00965     break;
00966   case DPX_RES_TYPE_TTFONT:
00967     r = istruetype(fp);
00968     break;
00969   case DPX_RES_TYPE_OTFONT:
00970     r = isopentype(fp);
00971     break;
00972   case DPX_RES_TYPE_CMAP:
00973     r = ispscmap(fp);
00974     break;
00975   case DPX_RES_TYPE_DFONT:
00976     r = isdfont(fp);
00977     break;
00978   }
00979   MFCLOSE(fp);
00980 
00981   return  r;
00982 }
00983