"Fossies" - the Fresh Open Source Software Archive

Member "epstool-3.08/src/capp.c" (10 Jun 2005, 17924 Bytes) of package /linux/misc/old/ghost/ghostgum/epstool-3.08-os2.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Copyright (C) 2001-2005 Ghostgum Software Pty Ltd.  All rights reserved.
    2 
    3   This software is provided AS-IS with no warranty, either express or
    4   implied.
    5 
    6   This software is distributed under licence and may not be copied,
    7   modified or distributed except as expressly authorised under the terms
    8   of the licence contained in the file LICENCE in this distribution.
    9 
   10   For more information about licensing, please refer to
   11   http://www.ghostgum.com.au/ or contact Ghostsgum Software Pty Ltd, 
   12   218 Gallaghers Rd, Glen Waverley VIC 3150, AUSTRALIA, 
   13   Fax +61 3 9886 6616.
   14 */
   15 
   16 /* $Id: capp.c,v 1.20 2005/06/10 09:39:24 ghostgum Exp $ */
   17 /* Application */
   18 
   19 #include "common.h"
   20 #include "dscparse.h"
   21 #define DEFINE_COPT
   22 #include "copt.h"
   23 #define DEFINE_CAPP
   24 #include "capp.h"
   25 #include "cargs.h"
   26 #include "cdll.h"
   27 #include "cgssrv.h"
   28 #include "cimg.h"
   29 #include "cpagec.h"
   30 #include "cprofile.h"
   31 #include "cres.h"
   32 
   33 /* GLOBAL WARNING */
   34 int debug = DEBUG_GENERAL;
   35 const char szAppName[] = "GSview";
   36 /* GLOBAL WARNING */
   37 
   38 static void rotate_last_files(GSview *a, int count);
   39 
   40 GSDLL **
   41 app_dll(GSview *a)
   42 {
   43     /* Because Ghostscript only supports one instance, we store
   44      * the DLL in the app.
   45      */
   46     return &a->gsdll;
   47 }
   48 
   49 PLDLL **
   50 app_pldll(GSview *a)
   51 {
   52     /* Because GhostPCL only supports one instance, we store
   53      * the DLL in the app.
   54      */
   55     return &a->pldll;
   56 }
   57 
   58 Doc **
   59 app_docs(GSview *a)
   60 {
   61     return &a->doclist;
   62 }
   63 
   64 OPTION *
   65 app_option(GSview *a)
   66 {
   67     return &a->option;
   68 }
   69 
   70 PAGECACHE **
   71 app_pagecache(GSview *a)
   72 {
   73     return &a->pagecache;
   74 }
   75 
   76 BOOL
   77 app_multithread(GSview *a)
   78 {
   79     return a->multithread;
   80 }
   81 
   82 int 
   83 app_gssrv_request(GSview *a, GSREQ *reqnew)
   84 {
   85     if (a->gssrv)
   86         return gssrv_request(a->gssrv, reqnew);
   87     return -1;
   88 }
   89 
   90 int 
   91 app_plsrv_request(GSview *a, GSREQ *reqnew)
   92 {
   93     if (a->plsrv)
   94         return gssrv_request(a->plsrv, reqnew);
   95     return -1;
   96 }
   97 
   98 /* we call this when we know that the app mutex is already locked by us */
   99 int
  100 app_msg_len_nolock(GSview *a, const char *str, int len)
  101 {
  102     char *p;
  103     const char *s;
  104     int i, lfcount;
  105 
  106     /* if debugging, write to a log file */
  107     if (debug & DEBUG_LOG)
  108     app_log(str, len);
  109 
  110     /* we need to add \r after each \n, so count the \n's */
  111     lfcount = 0;
  112     s = str;
  113     for (i=0; i<len; i++) {
  114     if (*s == '\n')
  115         lfcount++;
  116     s++;
  117     }
  118     if (len + lfcount >= TWSCROLL)
  119     return 0;   /* too large */
  120     if (len + lfcount + a->twend >= TWLENGTH-1) {
  121     /* scroll buffer */
  122     a->twend -= TWSCROLL;
  123     memmove(a->twbuf, a->twbuf+TWSCROLL, a->twend);
  124     }
  125     p = a->twbuf+a->twend;
  126     for (i=0; i<len; i++) {
  127     if (*str == '\n') {
  128         *p++ = '\r';
  129     }
  130     if (*str == '\0') {
  131         *p++ = ' '; /* ignore null characters */
  132         str++;
  133     }
  134     else
  135         *p++ = *str++;
  136     }
  137     a->twend += (len + lfcount);
  138     *(a->twbuf+a->twend) = '\0';
  139     return len;
  140 }
  141 
  142 /* Add string for Ghostscript message window */
  143 int
  144 app_msg_len(GSview *a, const char *str, int len)
  145 {
  146     int n;
  147     app_lock(a);
  148     n = app_msg_len_nolock(a, str, len);
  149     app_unlock(a);
  150     return n;
  151 }
  152 
  153 int
  154 app_msg(GSview *a, const char *str)
  155 {
  156     return app_msg_len(a, str, (int)strlen(str));
  157 }
  158 
  159 int
  160 app_msgf(GSview *a, const char *fmt, ...)
  161 {
  162 va_list args;
  163 int count;
  164 char buf[2048];
  165     va_start(args,fmt);
  166     count = vsnprintf(buf,sizeof(buf),fmt,args);
  167     buf[sizeof(buf)-1]='\0';
  168     if (count >= (int)sizeof(buf)-1) {
  169     debug |= DEBUG_LOG;
  170     app_msg(a, "PANIC: internal buffer overflow.  Stack is corrupted\n");
  171     }
  172     app_msg(a, buf);
  173     va_end(args);
  174     return count;
  175 }
  176 
  177 int
  178 app_csmsg_len_nolock(GSview *a, LPCTSTR wstr, int wlen)
  179 {
  180     char buf[MAXSTR];
  181     char *nstr = NULL;
  182     int nlen = cs_to_narrow(NULL, 0, wstr, wlen);
  183     if (nlen < (int)sizeof(buf))
  184     nstr = buf;
  185     else
  186     nstr = (char *)malloc(nlen); 
  187     if (nstr) {
  188     cs_to_narrow(nstr, nlen, wstr, wlen);
  189     app_msg_len_nolock(a, nstr, nlen);
  190     if (nstr != buf)
  191         free(nstr);
  192     }
  193     return wlen;
  194 }
  195 
  196 int
  197 app_csmsg_len(GSview *a, LPCTSTR wstr, int wlen)
  198 {
  199     int n;
  200     app_lock(a);
  201     n = app_csmsg_len_nolock(a, wstr, wlen);
  202     app_unlock(a);
  203     return n;
  204 }
  205 
  206 
  207 int
  208 app_csmsg(GSview *a, LPCTSTR wstr)
  209 {
  210     return app_csmsg_len(a, wstr, (int)cslen(wstr));
  211 }
  212 
  213 int
  214 app_csmsgf(GSview *a, LPCTSTR fmt, ...)
  215 {
  216 va_list args;
  217 int count;
  218 TCHAR buf[2048];
  219     va_start(args,fmt);
  220     count = csvnprintf(buf,sizeof(buf)/sizeof(TCHAR),fmt,args);
  221     if (count >= (int)sizeof(buf)/(int)sizeof(TCHAR)-1) {
  222     debug |= DEBUG_LOG;
  223     app_msg(a, "PANIC: internal buffer overflow.  Stack is corrupted\n");
  224     }
  225     app_csmsg(a, buf);
  226     va_end(args);
  227     return count;
  228 }
  229 
  230 #ifdef NO_SNPRINTF
  231 /* Dangerous code here - no length checking */
  232 int
  233 snprintf(char *buffer, size_t count, const char *fmt, ...)
  234 {
  235 va_list args;
  236 int len;
  237     va_start(args,fmt);
  238     len = vsprintf(buffer,fmt,args);
  239     buffer[count-1]='\0';
  240     if (len >= (int)count) {
  241     debug |= DEBUG_LOG;
  242     printf("PANIC: internal buffer overflow.  Stack is corrupted\n");
  243     }
  244     va_end(args);
  245     return len;
  246 }
  247 
  248 int
  249 vsnprintf(char *buffer, size_t count, const char *fmt, va_list argptr)
  250 {
  251     int len = vsprintf(buffer, fmt, argptr);
  252     if (len >= (int)count) {
  253     debug |= DEBUG_LOG;
  254     printf("PANIC: internal buffer overflow.  Stack is corrupted\n");
  255     }
  256     return len;
  257 }
  258 #endif
  259 
  260 static void
  261 rotate_last_files(GSview *a, int count)
  262 {
  263 int i;
  264 TCHAR buf[MAXSTR];
  265     if (count >= MAX_LAST_FILES)
  266     return;
  267     csncpy(buf, a->last_files[count], MAXSTR-1);
  268     for (i=count; i>0; i--)
  269     csncpy(a->last_files[i], a->last_files[i-1], MAXSTR-1);
  270     csncpy(a->last_files[0], buf, MAXSTR-1);
  271 }
  272 
  273 void
  274 app_update_last_files(GSview *a, LPCTSTR filename)
  275 {
  276 int i;
  277     for (i=0; i<a->last_files_count; i++) {
  278     if (cscmp(filename, a->last_files[i]) == 0)
  279         break;
  280     }
  281     if (i < a->last_files_count) {
  282     /* already in list */
  283     rotate_last_files(a, i);
  284     return;
  285     }
  286     if (a->last_files_count < MAX_LAST_FILES)
  287         a->last_files_count++;
  288     rotate_last_files(a, a->last_files_count-1);
  289     csncpy(a->last_files[0], filename, MAXSTR-1);
  290 }
  291 
  292 LPCTSTR
  293 app_last_files(GSview *a, int i)
  294 {
  295     if (i < a->last_files_count)
  296     return a->last_files[i];
  297     return NULL;
  298 }
  299 
  300 /* Read last files from INI file */
  301 int
  302 app_read_last_files(GSview *a, LPCTSTR filename)
  303 {
  304     int i;
  305     char buf[MAXSTR];
  306     char lastfile[MAXSTR];
  307     const char *section = INISECTION;
  308     PROFILE *prf;
  309     prf = profile_open(filename);
  310     if (prf == NULL)
  311     return_error(-1);
  312 
  313     a->last_files_count = 0;
  314     memset(lastfile, 0, sizeof(lastfile));
  315     for (i=0; i<MAX_LAST_FILES; i++) {
  316     snprintf(buf, sizeof(buf), "LastFile%d", i);
  317     buf[sizeof(buf)-1]='\0';
  318     profile_read_string(prf, section, buf, "", 
  319         lastfile, sizeof(lastfile));
  320     narrow_to_cs(a->last_files[i], sizeof(a->last_files[i])/sizeof(TCHAR)-1,
  321         lastfile, (int)strlen(lastfile)+1);
  322     if (a->last_files[i][0])
  323         a->last_files_count++;
  324     }
  325     profile_close(prf);
  326     return 0;
  327 }
  328 
  329 int
  330 app_write_last_files(GSview *a, LPCTSTR filename)
  331 {
  332     int i;
  333     char buf[MAXSTR];
  334     char lastfile[MAXSTR];
  335     const char *section = INISECTION;
  336     PROFILE *prf;
  337     prf = profile_open(filename);
  338     if (prf == NULL)
  339     return_error(-1);
  340 
  341     a->last_files_count = 0;
  342     memset(lastfile, 0, sizeof(lastfile));
  343     for (i=0; i<MAX_LAST_FILES; i++) {
  344     snprintf(buf, sizeof(buf), "LastFile%d", i);
  345         buf[sizeof(buf)-1]='\0';
  346     cs_to_narrow(lastfile, sizeof(lastfile)-1,
  347         a->last_files[i], (int)cslen(a->last_files[i])+1);
  348     profile_write_string(prf, section, buf, lastfile);
  349     }
  350     profile_close(prf);
  351     return 0;
  352 }
  353 
  354 /* Platform independent processing of arguments, before window creation */
  355 void
  356 app_use_args(GSview *app, GSVIEW_ARGS *args)
  357 {
  358     OPTION *opt = app_option(app);
  359     if (args->geometry) {
  360     if (args->geometry == 4) {
  361         opt->img_origin.x = args->geometry_xoffset;
  362         opt->img_origin.y = args->geometry_yoffset;
  363     }
  364     if (args->geometry >= 2) {
  365         opt->img_size.x = args->geometry_width;
  366         opt->img_size.y = args->geometry_height;
  367     }
  368     }
  369 }
  370 
  371 
  372 static int
  373 app_init(GSview *a)
  374 {
  375     app_platform_init(a);
  376     return 0;
  377 }
  378 
  379 static int
  380 app_finish(GSview *a)
  381 {
  382     pagecache_unref_all(a);
  383     zlib_free(a);
  384     bzip2_free(a);
  385     app_platform_finish(a);
  386     return 0;
  387 }
  388 
  389 
  390 GSview *
  391 app_new(void *handle, BOOL multithread)
  392 {
  393     GSview *a = (GSview *)malloc(sizeof(GSview));
  394     if (a) {
  395     memset(a, 0, sizeof(GSview));
  396     a->handle = handle;
  397     a->multithread = multithread;
  398     app_init(a);
  399     app_ref(a); /* caller has reference to app */
  400     }
  401     return a;
  402 }
  403 
  404 /* Increment reference count of App */
  405 /* A Document will increment refcount when it attaches to App */
  406 /* Assumes we own the lock */
  407 int
  408 app_ref(GSview *a)
  409 {
  410     int refcount = ++(a->refcount);
  411     if (debug & DEBUG_DEV) {
  412     char buf[MAXSTR];
  413     snprintf(buf, sizeof(buf), "app refcount=%d\n", refcount);
  414     app_msg_len_nolock(a, buf, (int)strlen(buf));
  415     }
  416     return refcount;
  417 }
  418 
  419 /* Release reference to App. */
  420 /* When reference count reaches zero, App is freed. */
  421 /* Assumes we own the lock */
  422 int
  423 app_unref(GSview *a)
  424 {
  425     int refcount;
  426     if (a->refcount > 0)
  427     a->refcount--;
  428     refcount = a->refcount;
  429     if (debug & DEBUG_DEV) {
  430     char buf[MAXSTR];
  431     snprintf(buf, sizeof(buf), "app refcount=%d\n", refcount);
  432     buf[sizeof(buf)-1]='\0';
  433     app_msg_len_nolock(a, buf, (int)strlen(buf));
  434     }
  435     if (refcount == 0) {
  436     app_finish(a);
  437     memset(a, 0, sizeof(GSview));
  438     free(a);
  439     }
  440 
  441     return refcount;
  442 }
  443 
  444 
  445 
  446 int 
  447 zlib_load(GSview *a)
  448 {
  449     int code = 0;
  450     TCHAR buf[1024];
  451     ZLIB *zlib = &a->zlib;
  452     if (zlib->loaded)
  453     return 0;
  454 
  455     memset(buf, 0, sizeof(buf));
  456     code = dll_open(&zlib->hmodule, TEXT(ZLIBNAME), 
  457     buf, sizeof(buf)/sizeof(TCHAR)-1);
  458     if (code != 0) {
  459     app_csmsg(a, buf);
  460     }
  461     else {
  462     if (code == 0)
  463         zlib->gzopen = (PFN_gzopen)dll_sym(&zlib->hmodule, "gzopen");
  464     if (zlib->gzopen == NULL) {
  465         app_msg(a, "Can't find gzopen\n");
  466         code = -1;
  467     }
  468     if (code == 0)
  469         zlib->gzread = (PFN_gzread)dll_sym(&zlib->hmodule, "gzread");
  470     if (zlib->gzread == NULL) {
  471         app_msg(a, "Can't find gzread\n");
  472         code = -1;
  473     }
  474     if (code == 0)
  475         zlib->gzclose = (PFN_gzclose)dll_sym(&zlib->hmodule, "gzclose");
  476     if (zlib->gzclose == NULL) {
  477         app_msg(a, "Can't find gzclose\n");
  478         code = -1;
  479     }
  480     if (code == 0)
  481         zlib->loaded = TRUE;
  482     else {
  483         dll_close(&zlib->hmodule);
  484         memset(zlib, 0, sizeof(ZLIB));
  485         zlib->loaded = FALSE;
  486     }
  487     }
  488     return code;
  489 }
  490 
  491 void
  492 zlib_free(GSview *a)
  493 {
  494     if (a->zlib.loaded == FALSE)
  495     return;
  496     dll_close(&a->zlib.hmodule);
  497     a->zlib.hmodule = (GGMODULE)0;
  498     a->zlib.gzopen = NULL;
  499     a->zlib.gzread = NULL;
  500     a->zlib.gzclose = NULL;
  501     a->zlib.loaded = FALSE;
  502 }
  503 
  504 int
  505 zlib_uncompress(GSview *app, GFile *outfile, const char *filename)
  506 {
  507     gzFile infile;
  508     char *buffer;
  509     int count;
  510 
  511     if (zlib_load(app))
  512     return_error(-1);
  513 
  514     /* create buffer for file copy */
  515     buffer = (char *)malloc(COPY_BUF_SIZE);
  516     if (buffer == (char *)NULL)
  517     return_error(-1);
  518 
  519     if ((infile = app->zlib.gzopen(filename, "rb")) == (gzFile)NULL) {
  520     free(buffer);
  521     return_error(-1);
  522     }
  523     
  524     while ( (count = app->zlib.gzread(infile, buffer, COPY_BUF_SIZE)) > 0 ) {
  525     gfile_write(outfile, buffer, count);
  526     }
  527     free(buffer);
  528     app->zlib.gzclose(infile);
  529     if (count < 0)
  530     return_error(-1);
  531     return 0;
  532 }
  533 
  534 int 
  535 bzip2_load(GSview *a)
  536 {
  537     int code = 0;
  538     TCHAR buf[1024];
  539     BZIP2 *bzip2 = &a->bzip2;
  540     if (bzip2->loaded)
  541     return 0;
  542 
  543     memset(buf, 0, sizeof(buf));
  544     code = dll_open(&bzip2->hmodule, TEXT(BZIP2NAME), 
  545     buf, sizeof(buf)/sizeof(TCHAR)-1);
  546     if (code != 0) {
  547     app_csmsg(a, buf);
  548     }
  549     else {
  550     if (code == 0)
  551         bzip2->bzopen = (PFN_bzopen)dll_sym(&bzip2->hmodule, "BZ2_bzopen");
  552     if (bzip2->bzopen == NULL) {
  553         app_msg(a, "Can't find bzopen\n");
  554         code = -1;
  555     }
  556     if (code == 0)
  557         bzip2->bzread = (PFN_bzread)dll_sym(&bzip2->hmodule, "BZ2_bzread");
  558     if (bzip2->bzread == NULL) {
  559         app_msg(a, "Can't find bzread\n");
  560         code = -1;
  561     }
  562     if (code == 0)
  563         bzip2->bzclose = (PFN_bzclose)dll_sym(&bzip2->hmodule, "BZ2_bzclose");
  564     if (bzip2->bzclose == NULL) {
  565         app_msg(a, "Can't find bzclose\n");
  566         code = -1;
  567     }
  568     if (code == 0)
  569         bzip2->loaded = TRUE;
  570     else {
  571         dll_close(&bzip2->hmodule);
  572         memset(bzip2, 0, sizeof(ZLIB));
  573         bzip2->loaded = FALSE;
  574     }
  575     }
  576     return code;
  577 }
  578 
  579 void 
  580 bzip2_free(GSview *a)
  581 {
  582     if (a->bzip2.loaded == FALSE)
  583     return;
  584     dll_close(&a->bzip2.hmodule);
  585     a->bzip2.hmodule = (GGMODULE)0;
  586     a->bzip2.bzopen = NULL;
  587     a->bzip2.bzread = NULL;
  588     a->bzip2.bzclose = NULL;
  589     a->bzip2.loaded = FALSE;
  590 }
  591 
  592 int
  593 bzip2_uncompress(GSview *app, GFile *outfile, const char *filename)
  594 {
  595     bzFile infile;
  596     char *buffer;
  597     int count;
  598 
  599     if (bzip2_load(app))
  600     return_error(-1);
  601 
  602     /* create buffer for file copy */
  603     buffer = (char *)malloc(COPY_BUF_SIZE);
  604     if (buffer == (char *)NULL)
  605     return_error(-1);
  606 
  607     if ((infile = app->bzip2.bzopen(filename, "rb")) == (gzFile)NULL) {
  608     free(buffer);
  609     return_error(-1);
  610     }
  611     
  612     while ( (count = app->bzip2.bzread(infile, buffer, COPY_BUF_SIZE)) > 0 ) {
  613     gfile_write(outfile, buffer, count);
  614     }
  615     free(buffer);
  616     app->bzip2.bzclose(infile);
  617     if (count < 0)
  618     return_error(-1);
  619     return 0;
  620 }
  621 
  622 GFile *
  623 app_temp_gfile(GSview *app, TCHAR *fname, int len)
  624 {
  625     TCHAR *temp;    
  626 #if defined(UNIX) || defined(OS2)
  627     long fd;
  628 #endif
  629     memset(fname, 0, len*sizeof(TCHAR));
  630     if ( (temp = csgetenv(TEXT("TEMP"))) == NULL )
  631 #ifdef UNIX
  632     csncpy(fname, "/tmp", len-1);
  633 #else
  634     csgetcwd(fname, len-1);
  635 #endif
  636     else
  637     csncpy(fname, temp, len-1);
  638     /* Prevent X's in path from being converted by mktemp. */
  639 #if defined(_Windows) || defined(OS2)
  640     temp = fname;
  641     while (*temp) {
  642     if (*temp == '/')
  643         *temp = '\\';
  644     if (*temp < 'a')
  645         *temp = (char)tolower(*temp);
  646     temp = CHARNEXT(temp);
  647     }
  648 #endif
  649     if ( cslen(fname) && (fname[cslen(fname)-1] != PATHSEP[0]) )
  650     csncat(fname, TEXT(PATHSEP), len-1-cslen(fname));
  651 
  652     csncat(fname, TEXT("gsview"), len-1-cslen(fname));
  653     csncat(fname, TEXT("XXXXXX"), len-1-cslen(fname));
  654 #if defined(UNIX) || defined(OS2)
  655     fd = mkstemp(fname);
  656     if (debug & DEBUG_GENERAL)
  657     app_csmsgf(app, TEXT("Creating temporary file \042%s\042\n"), fname); 
  658     return gfile_open_handle((void *)fd, gfile_modeWrite | gfile_modeCreate);
  659 #else
  660     csmktemp(fname);
  661     if (debug & DEBUG_GENERAL)
  662     app_csmsgf(app, TEXT("Creating temporary file \042%s\042\n"), fname); 
  663     return gfile_open(fname, gfile_modeWrite | gfile_modeCreate);
  664 #endif
  665 }
  666 
  667 FILE *
  668 app_temp_file(GSview *app, TCHAR *fname, int len)
  669 {
  670     TCHAR *temp;    
  671 #if defined(UNIX) || defined(OS2)
  672     long fd;
  673 #endif
  674     memset(fname, 0, len*sizeof(TCHAR));
  675     if ( (temp = csgetenv(TEXT("TEMP"))) == NULL )
  676 #ifdef UNIX
  677     csncpy(fname, "/tmp", len-1);
  678 #else
  679     csgetcwd(fname, len-1);
  680 #endif
  681     else
  682     csncpy(fname, temp, len-1);
  683     /* Prevent X's in path from being converted by mktemp. */
  684 #if defined(_Windows) || defined(OS2)
  685     temp = fname;
  686     while (*temp) {
  687     if (*temp == '/')
  688         *temp = '\\';
  689     if (*temp < 'a')
  690         *temp = (char)tolower(*temp);
  691     temp = CHARNEXT(temp);
  692     }
  693 #endif
  694     if ( cslen(fname) && (fname[cslen(fname)-1] != PATHSEP[0]) )
  695     csncat(fname, TEXT(PATHSEP), len-1-cslen(fname));
  696 
  697     csncat(fname, TEXT("gsview"), len-1-cslen(fname));
  698     csncat(fname, TEXT("XXXXXX"), len-1-cslen(fname));
  699 #if defined(UNIX) || defined(OS2)
  700     fd = mkstemp(fname);
  701     if (debug & DEBUG_GENERAL)
  702     app_csmsgf(app, TEXT("Creating temporary file \042%s\042\n"), fname); 
  703     return fdopen(fd, "wb");
  704 #else
  705     csmktemp(fname);
  706     if (debug & DEBUG_GENERAL)
  707     app_csmsgf(app, TEXT("Creating temporary file \042%s\042\n"), fname); 
  708     return csfopen(fname, TEXT("wb"));
  709 #endif
  710 }
  711 
  712 
  713 float 
  714 app_get_points(GSview *a, const TCHAR *str)
  715 {
  716     float val;
  717     TCHAR ptbuf[16];
  718     TCHAR inchbuf[16];
  719     TCHAR mmbuf[16];
  720     TCHAR unitbuf[MAXSTR];
  721     TCHAR *p = unitbuf;
  722     TCHAR *q;
  723     char fbuf[64];
  724     int i;
  725     memset(unitbuf, 0, sizeof(unitbuf));
  726     csncpy(unitbuf, str, sizeof(unitbuf)/sizeof(TCHAR)-1);
  727     ptbuf[0] = inchbuf[0] = mmbuf[0] = '\0';
  728     load_string(a, IDS_UNITNAME + UNIT_PT, 
  729     ptbuf, sizeof(ptbuf));
  730     load_string(a, IDS_UNITNAME + UNIT_IN, 
  731     inchbuf, sizeof(inchbuf));
  732     load_string(a, IDS_UNITNAME + UNIT_MM, 
  733     mmbuf, sizeof(mmbuf));
  734     while (*p && (*p == ' '))
  735     p = CHARNEXT(p);
  736     cs_to_narrow(fbuf, (int)sizeof(fbuf)-1, p, (int)cslen(p)+1);
  737     fbuf[sizeof(fbuf)-1] = '\0';
  738     val = (float)atof(fbuf);
  739     while (*p && ( ((*p >= '0') && (*p <= '9')) || (*p == '.')))
  740     p = CHARNEXT(p);
  741     while (*p && (*p == ' '))
  742     p = CHARNEXT(p);
  743     q = p;
  744     while (*q && (*q >= 'A'))
  745     q = CHARNEXT(q);
  746     if (*q)
  747     q = CHARNEXT(q);
  748     i = (int)(q - p);
  749     if ((csncmp(p, ptbuf, max(i, (int)cslen(ptbuf))) == 0) ||
  750          (csncmp(p, TEXT("pt"), 2) == 0)) {
  751     /* do nothing */
  752     }
  753     else if ((csncmp(p, inchbuf, max(i, (int)cslen(inchbuf))) == 0) || 
  754          (csncmp(p, TEXT("in"), 2) == 0))
  755     val *= 72.0;
  756     else if ((csncmp(p, mmbuf, max(i, (int)cslen(mmbuf))) == 0) || 
  757          (csncmp(p, TEXT("mm"), 2) == 0))
  758     val *= (float)(72.0 / 25.4);
  759     else if (csncmp(p, TEXT("cm"), 2) == 0)
  760     val *= (float)(72.0 / 2.54);
  761     else if (csncmp(p, TEXT("m"), 1) == 0)
  762     val *= (float)(72.0 / 0.0254);
  763     else if (csncmp(p, TEXT("ft"), 2) == 0)
  764     val *= (float)(72.0 * 12.0);
  765     return val;
  766 }
  767 
  768 void 
  769 app_put_points(GSview *a, UNIT unit, TCHAR *buf, int len, float n)
  770 {
  771     TCHAR ubuf[16];
  772     float factor = 1.0;
  773     if (len < 1)
  774     return;
  775     buf[0] = '\0';
  776     ubuf[0] = '\0';
  777     load_string(a, IDS_UNITNAME + unit, ubuf, sizeof(ubuf));
  778     if (len < 32 + (int)cslen(ubuf))
  779     return;
  780     switch (unit) {
  781     case UNIT_MM:
  782         factor = (float)(25.4 / 72.0);
  783         break;
  784     case UNIT_IN:
  785         factor = (float)(1.0 / 72.0);
  786         break;
  787     case UNIT_PT:
  788     default:
  789        factor = 1.0;
  790     }
  791     csnprintf(buf, len, TEXT("%g %s"), n*factor, ubuf);
  792     buf[len-1] = '0';
  793 }