home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / driver / util / dvihand.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  40KB  |  1,636 lines

  1. /*
  2. **    This file generated by localize 2.9 (AmigaDOS 2.1) from util/dvihand.c
  3. */
  4. /** dvihand.c **/
  5.  
  6. #include "defines.h"
  7. #include <stdio.h>
  8. #include <ctype.h>
  9.  
  10. #include "globals.h"
  11.  
  12. #include <stddef.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <math.h>
  16.  
  17. #include "bitmap.h"
  18. #include "commands.h"
  19. #include "dvihand.h"
  20. #include "flmt.h"
  21. #include "new_font.h"
  22.  
  23. #include "dvihand.i"
  24. #include "globals.i"
  25. #include "new_font.i"
  26. #include "bitmap.i"
  27.  
  28. #ifndef AZTEC_C
  29. #  define fgetc(fp)    getc(fp)    /* Effizienz ? */
  30. #endif
  31.  
  32. #ifdef AMIGA
  33. #  include <exec/types.h>
  34. #  include <exec/exec.h>
  35. #  include <exec/ports.h>
  36. #  include <dos/dos.h>
  37.    extern struct ExecBase    * SysBase;
  38.    extern struct DosLibrary    * DOSBase;
  39. #  include <clib/dos_protos.h>
  40. #  include <pragmas/dos_pragmas.h>
  41. #  include <clib/exec_protos.h>
  42. #  include <pragmas/exec_pragmas.h>
  43. #  include "fast_cp.i"
  44. #endif
  45.  
  46. #ifdef ATARI
  47. extern int access(char *, int);
  48. # include "atscreen.h"
  49. #endif
  50.  
  51. #ifndef ANSI
  52. char *strcpy(); 
  53. #endif
  54. /** char *logname(); **/
  55.  
  56.  
  57.  
  58. /*
  59.  * Fuer die locale-Library:
  60.  *
  61.  * Hier duerfen *nur* die MSG_#? Nummern eingebunden werden!
  62.  * Achtung:
  63.  * Es muss/sollte 'multiple-include' erlaubt sein!
  64.  */
  65. #include "local.i"
  66.  
  67. #undef  CATCOMP_ARRAY
  68. #undef  CATCOMP_BLOCK
  69. #undef  CATCOMP_STRINGS
  70. #define CATCOMP_NUMBERS
  71. #include "localstr.h"
  72.  
  73.  
  74.  
  75.  
  76. extern long  hconv, vconv;              /* converts DVI units to pixels       */
  77. extern long  den;                       /* denominator specified in preamble  */
  78. extern DVIFILE *dvifp;                     /* DVI file pointer                   */
  79. extern long  h;                         /* current horizontal position        */
  80. extern long  hh;                        /* current h on device                */
  81. extern long  v;                         /* current vertical position          */
  82. extern long  vv;                        /* current v on device                */
  83. extern long  mag;                       /* magnification specified in preamble*/
  84. extern long  num;                       /* numerator specified in preamble    */
  85. extern long  postambleptr;              /* Pointer to the postamble           */
  86. extern long  ppagep;                    /* previous page pointer              */
  87. extern long  paper_height, paper_width; /* real height and width of page      */
  88. extern int   pheight_pt;            /* real height in pt              */
  89. extern int   pwidth_pt;                /* real width in pt              */
  90. extern int   hmaxdrift;                 /* max pixels away from true rounded position */
  91. extern int   vmaxdrift;                 /* max pixels away from true rounded position */
  92. extern int   thinspace;            /* needet in dvihand.c for rounding   */
  93. extern int   backspace;
  94. extern int   vertsmallspace;        /* also ^^                  */
  95. extern double alpha;                    /* conversion ratio, DVI unit per TFM unit */
  96.  
  97. extern struct bitmap    map;
  98. extern long        upper_limit;
  99. extern long        lower_limit;
  100.  
  101.  
  102. #define EVPATH
  103.  
  104. #ifdef EVPATH
  105.  
  106. #include "EVPaths.h"
  107. static struct EnvVarPath * evpath_config = NULL;
  108.  
  109. void _STD_5555_FreeEVpath(void)
  110. {
  111.   if (evpath_config) {
  112.     Free_EnvVarPath(evpath_config);
  113.     evpath_config = NULL;
  114.   }
  115. }
  116. #endif
  117.  
  118. #ifdef AMIGA
  119. FILE *OpenConfigFile(char *name, int modus)
  120. {
  121.   register char *ptr;
  122.   char path[120], env[120];
  123.   FILE *fp;
  124.   
  125.   ptr = getenv(ENV_DEFAULT_PATH);
  126.   if (ptr == NULL) ptr = DEFAULT_PATH;
  127.   strcpy(env, ptr);
  128.  
  129. #ifdef EVPATH
  130.  
  131.   if (!evpath_config) {
  132.     evpath_config = Alloc_EnvVarPath(ENV_DEFAULT_PATH, 1024);
  133.     Init_EnvVarPath(evpath_config, DEFAULT_PATH, ENVPATH_DEFSTR);
  134.     
  135. #undef EVPATH_DEBUG
  136. #ifdef EVPATH_DEBUG
  137.     { int i = 0;
  138.  
  139.       printf("The environment variable `%s' has length %ld\n", ENV_DEFAULT_PATH, GetVarLength(ENV_DEFAULT_PATH));
  140.       while (evpath_config->storage.strings[i])
  141.         printf("%ld -> `%s'\n", i, evpath_config->storage.strings[i++]);
  142.     }
  143. #endif
  144.   }
  145.   
  146.   if (!evpath_config) return NULL;
  147.  
  148.   switch(modus) {
  149.     case MODE_READ:   ptr = "r"; break;
  150.     case MODE_WRITE:  ptr = "w"; break;
  151.     default:          ptr = "a"; break;
  152.   }
  153.   
  154.   if (EVP_FileSearch(name, evpath_config, path, sizeof(path)-1)) {
  155.     fp = fopen(path, ptr);
  156.   }
  157. #else
  158.   
  159.   ptr = strtok(env, ",;");
  160.   do {
  161.     strcpy(path, ptr);
  162.     mk_correct_path(path);
  163.     if (strcmp(path, "./") == 0) path[0] = '\0';    /* ./ is actual directory */
  164.     strcat(path, name);
  165.     fp = fopen(path, "r");
  166.   } while (fp == NULL && (ptr = strtok(NULL, ",;")) != NULL);
  167.  
  168.   /* bei WRITE/APPEND ueberschreibe existierendes File */
  169.   if (fp != NULL && modus != MODE_READ) {
  170.     fclose(fp);
  171.     if (modus == MODE_WRITE) {
  172.       fp = fopen(path, "w");
  173.     }
  174.     else {
  175.       fp = fopen(path, "a");
  176.     }
  177.   }
  178. #endif
  179.  
  180.   /* falls noch kein existierendes File gefunden wurde dann nun ein neues oeffnen */
  181.   if (fp == NULL && modus != MODE_READ) {
  182.     ptr = strtok(env, ",;");
  183.     do {
  184.       strcpy(path, ptr);
  185.       mk_correct_path(path);
  186.       if (strcmp(path, "./") == 0) path[0] = '\0';    /* ./ is actual directory */
  187.       strcat(path, name);
  188.       fp = fopen(path, (modus == MODE_WRITE) ? "w" : "a");
  189.     } while (fp == NULL && (ptr = strtok(NULL, ",;")) != NULL);
  190.   }
  191.   
  192.   return fp;
  193. }
  194. #endif
  195.  
  196.  
  197. /*
  198.  * Oeffne ein DVI-File und kopiere ins RAM, wenns denn sein muss
  199.  */
  200. DVIFILE * OpenDVI(char * name, int maxbuf)
  201. {
  202.   DVIFILE * df;
  203.   FILE    * fp;
  204.   __aligned struct FileInfoBlock fib;
  205.   BPTR lck;
  206.   
  207.   dvidatestamp.ds_Days   = 0;
  208.   dvidatestamp.ds_Minute = 0;
  209.   dvidatestamp.ds_Tick   = 0;
  210.   
  211.   df = xmalloc(sizeof(DVIFILE));
  212.  
  213.   fp = fopen(name, "r");
  214.   if (fp) {
  215.     lck = Lock(name, ACCESS_READ);
  216.     if (lck) {
  217.       strncpy(df->name, name, sizeof(df->name));
  218.       df->pointer = 0;
  219.  
  220.       if (Examine(lck, &fib)) {
  221.         df->size = fib.fib_Size;
  222.         dvidatestamp = fib.fib_Date;
  223.  
  224.         if (df->size <= maxbuf) {
  225.           // soll es kopiert werden? Ja.
  226.           df->rambuf = malloc(df->size);
  227.           if (df->rambuf) {
  228.             fseek(fp, 0, SEEK_SET);        // an den Anfang
  229.             if (fread(df->rambuf, 1, df->size, fp) != df->size) {
  230.               free(df->rambuf);
  231.               df->rambuf = NULL;
  232.             }
  233.             fseek(fp, 0, SEEK_SET);        // und wieder an den Anfang
  234.             if (df->rambuf) df->flags |= InRam;
  235.           }
  236.         }
  237.  
  238.       }
  239.       
  240.       UnLock(lck);
  241.     }
  242.  
  243.     // und wie ist das File nun angelegt?
  244.     if (df->flags & InRam) {
  245.       // ist in RAM, fp wird also nicht mehr gebraucht
  246.       fclose(fp);
  247.       if (df->size == 0) df->flags |= Eof;
  248.     }
  249.     else {
  250.       df->fp = fp;
  251.     }
  252.   }
  253.   
  254.   if (!(df->flags & InRam) && !df->fp) {
  255.     // dann sind wir gescheitert
  256.     free(df);
  257.     df = NULL;
  258.   }
  259.   
  260.   return df;
  261. }
  262.  
  263.  
  264. /*
  265.  * CloseDVI: schliesse ein DVI-File
  266.  */
  267. void CloseDVI(DVIFILE * dvifp)
  268. {
  269.   if (dvifp) {
  270.     if (dvifp->fp)     fclose(dvifp->fp);
  271.     if (dvifp->rambuf) free(dvifp->rambuf);
  272.     free(dvifp);
  273.   }
  274. }
  275.  
  276.  
  277. /*
  278.  * TempCloseDVI: schliesse bei einem DVI-File nur temporaer das fp
  279.  *               damit virtex darauf schreiben kann
  280.  */
  281. void TempCloseDVI(DVIFILE * dvifp)
  282. {
  283.   if (dvifp) {
  284.     if (!(dvifp->flags & InRam) && dvifp->fp) {
  285.       dvifp->tmpftell = ftell(dvifp->fp);
  286.       fclose(dvifp->fp);
  287.       dvifp->fp = NULL;
  288.       dvifp->flags |= TmpClosed;
  289.     }
  290.   }
  291. }
  292.  
  293. /*
  294.  * TempOpenDVI: Oeffne ein DVI-File, das vorher Temp geschlossen wurde
  295.  */
  296. void TempOpenDVI(DVIFILE ** dvifp)
  297. {
  298.   DVIFILE * fp = *dvifp;
  299.  
  300.   if (fp && (fp->flags & TmpClosed) && !fp->fp) {
  301.     fp->flags &= ~TmpClosed;
  302.     fp->fp = fopen(fp->name, "r");
  303.     if (fp->fp) {
  304.       fseek(fp->fp, fp->tmpftell, SEEK_SET);
  305.     }
  306.     else {
  307.       CloseDVI(fp);
  308.       *dvifp = NULL;
  309.     }
  310.   }
  311. }
  312.  
  313. /* 
  314.  * DVIftell: Wie ftell
  315.  */
  316. long DVIftell(DVIFILE * dvifp)
  317. {
  318.   if (dvifp->flags & InRam) {
  319.     return dvifp->pointer;
  320.   }
  321.   else {
  322.     return ftell(dvifp->fp);
  323.   }
  324. }
  325.  
  326. /*
  327.  * DVIfseekSet: Wie fseek mit SEEK_SET
  328.  */
  329. int DVIfseekSet(DVIFILE * dvifp, long pos)
  330. {
  331.   if (dvifp) {
  332.     if (dvifp->flags & InRam) {
  333.       if (pos > dvifp->size || pos < 0) {
  334.         return -1;
  335.       }
  336.       else {
  337.         dvifp->pointer = pos;
  338.         return 0;
  339.       }
  340.     }
  341.     else {
  342.       return fseek(dvifp->fp, pos, SEEK_SET);
  343.     }
  344.   }
  345. }
  346.  
  347.  
  348. /*
  349.  * DVIrewind: wie rewind
  350.  */
  351. void DVIrewind(DVIFILE * dvifp)
  352. {
  353.   if (dvifp) {
  354.     if (dvifp->flags & InRam) {
  355.       dvifp->pointer = 0;
  356.     }
  357.     else {
  358.       rewind(dvifp->fp);
  359.     }
  360.   }
  361. }
  362.  
  363.  
  364.  
  365. /*
  366.  * DVIseekEnd: setze Filepointer auf das Ende des Files
  367.  */
  368. void DVIseekEnd(DVIFILE * dvifp)
  369. {
  370.   if (dvifp) {
  371.     if (dvifp->flags & InRam) {
  372.       dvifp->pointer = dvifp->size;
  373.     }
  374.     else {
  375.       fseek(dvifp->fp, 0, SEEK_END);
  376. #ifdef SEEK_FUNKT_NICHT
  377.       if (ftell(dvifp->fp) == 0) {
  378.         WarningStr("ACHTUNG: fseek(fp, 0, SEEK_END) funktioniert nicht!");
  379.         while (!feof(dvifp->fp)) (void)fgetc(dvifp->fp);
  380.       }
  381. #endif
  382.     }
  383.   }
  384. }
  385.  
  386.  
  387.  
  388. /*
  389.  * DVIfread: Wie fread
  390.  */
  391. int DVIfread(char * buf, int bsize, int nr, DVIFILE * dvifp)
  392. {
  393.   if (dvifp->flags & InRam) {
  394.     int cnr = bsize*nr;
  395.     if (dvifp->pointer+cnr < dvifp->size) {
  396.       /* CopyMem(dvifp->rambuf+dvifp->pointer, buf, cnr); */
  397.       memcpy(buf, dvifp->rambuf+dvifp->pointer, cnr);    // das ist builtin
  398.       dvifp->pointer += cnr;
  399.     }
  400.     else {
  401.       Fatal(5,MSG_DVI_FILE_ERROR);
  402.     }
  403.   }
  404.   else {
  405.     if (fread(buf, bsize, nr, dvifp->fp) != nr) Fatal(5,MSG_DVI_FILE_ERROR);
  406.   }
  407.  
  408.   return nr;
  409. }
  410.  
  411.  
  412. /*
  413.  * DVIfeof: wie feof
  414.  */
  415. int DVIfeof(DVIFILE * dvifp)
  416. {
  417.   if (dvifp) {
  418.     if (dvifp->flags & InRam) {
  419.       return dvifp->size == dvifp->pointer;
  420.     }
  421.     else {
  422.       return feof(dvifp->fp);
  423.     }
  424.   }
  425. }
  426.  
  427.  
  428.  
  429.  
  430. /*
  431.  *   Code to scale dimensions.  Takes two thirty-two bit integers, multiplies
  432.  *   them, divides them by 2^20, and returns the thirty-two bit result.
  433.  *   The first integer, the width in FIXes, can lie between -2^24 and 2^24-1.
  434.  *   The second integer, the scale factor, can lie between 0 and 2^27-1.  The
  435.  *   arithmetic must be exact.  The answer is truncated to an integer.
  436.  *
  437.  */
  438.  
  439. long scalewidth(long a, long b)
  440. {
  441.   register long al, bl ;
  442.  
  443.   al = a & 32767 ;
  444.   bl = b & 32767 ;
  445.   a >>= 15 ;
  446.   b >>= 15 ;
  447.   return ( ((al*bl/32768) + a*bl+al*b)/32 + a*b*1024) ;
  448. }
  449.  
  450.  
  451.  
  452. /*-->ActualFactor*/
  453. /**********************************************************************/
  454. /**************************  ActualFactor  ****************************/
  455. /**********************************************************************/
  456.  
  457. double           /* compute the actual size factor given the approximation */
  458. ActualFactor(long unmodsize)        /* actually factor * 1000 */
  459. {
  460.     double realsize;     /* the actual magnification factor */
  461.  
  462.     realsize = (double)unmodsize / 1000.0;
  463.     /* a real hack to correct for rounding in some cases--rkf */
  464.     if(unmodsize==1095) realsize = 1.095445;    /*stephalf*/
  465.     else if(unmodsize==1315) realsize=1.314534; /*stepihalf*/
  466.     else if(unmodsize==1577) realsize=1.577441; /*stepiihalf*/
  467.     else if(unmodsize==1893) realsize=1.892929; /*stepiiihalf*/
  468.     else if(unmodsize==2074) realsize=2.0736;   /*stepiv*/
  469.     else if(unmodsize==2488) realsize=2.48832;  /*stepv*/
  470.     else if(unmodsize==2986) realsize=2.985984; /*stepvi*/
  471.     /* the remaining magnification steps are represented with sufficient
  472.            accuracy already */
  473.     return(realsize);
  474. }
  475.  
  476.  
  477. /*-->DoConv*/
  478. /*********************************************************************/
  479. /********************************  DoConv  ***************************/
  480. /*********************************************************************/
  481.  
  482. long DoConv(long num, long den, int convResolution)
  483. {
  484.     double conv;
  485.  
  486.     conv = ((double)num/(double)den) * 
  487.         ((double) mag/(double)1000.0) *
  488.         ((double)convResolution/(double)254000.0);
  489.  
  490.     return (long)floor((double)1.0 / conv + 0.5);
  491. }
  492.  
  493.  
  494. /*-->FindPostAmblePtr*/
  495. /**********************************************************************/
  496. /************************  FindPostAmblePtr  **************************/
  497. /**********************************************************************/
  498.  
  499. int FindPostAmblePtr(long *postambleptr)
  500.  
  501. /* this routine will move to the end of the file and find the start
  502.     of the postamble */
  503.  
  504. {
  505.     int     i;
  506.  
  507.     DVIseekEnd(dvifp);               /* goto end of file */
  508.     *postambleptr = DVIftell(dvifp) - 4;
  509.     DVIfseekSet(dvifp, (long) *postambleptr);
  510.  
  511.     while (TRUE)
  512.      {
  513.       DVIfseekSet(dvifp,(long) --(*postambleptr));
  514.       if (((i = Read1Byte(dvifp)) != 223) && (i != DVIFORMAT))
  515.        {
  516. /*
  517.         Fatal (5, "Bad end of DVI file");
  518. */
  519.     Warning(MSG_BAD_DVI_FILE_END);
  520.     return(1);
  521.        } 
  522.       if (i == DVIFORMAT)
  523.        break;
  524.      }
  525.     DVIfseekSet(dvifp, (long) ((*postambleptr) - 4));
  526.     (*postambleptr) = Read4Byte(dvifp);
  527.     DVIfseekSet(dvifp,(long) *postambleptr);
  528.     return(0);
  529. }
  530.  
  531.  
  532. /*-->GetBytes*/
  533. /**********************************************************************/
  534. /*****************************  GetBytes  *****************************/
  535. /**********************************************************************/
  536.  
  537. void GetBytes(DVIFILE *fp, char *cp, long n)    /* get n bytes from file fp */
  538.                         /* fp file pointer  */
  539.                         /* cp character pointer */
  540.                         /* n  number of bytes  */
  541.  
  542. {
  543.   (void)DVIfread(cp, 1, n, fp);
  544. }
  545.  
  546.  
  547. /*-->GetFontDef*/
  548. /**********************************************************************/
  549. /**************************** GetFontDef  *****************************/
  550. /**********************************************************************/
  551.  
  552. void GetFontDef(int load)
  553.  
  554. /***********************************************************************
  555.    Read the font  definitions as they  are in the  postamble of the  DVI
  556.    file.
  557. ***********************************************************************/
  558.  
  559. {
  560.     unsigned char   byte;
  561.  
  562.     while (((byte = (unsigned char) Read1Byte(dvifp)) >= FNT_DEF1) &&
  563.            (byte <= FNT_DEF4))
  564.      {
  565.       switch (byte)
  566.        {
  567.         case FNT_DEF1:
  568.                       ReadFontDef (Read1Byte(dvifp),load);
  569.                       break;
  570.         case FNT_DEF2:
  571.                       ReadFontDef (Read2Byte(dvifp),load);
  572.                       break;
  573.         case FNT_DEF3:
  574.                       ReadFontDef (Read3Byte(dvifp),load);
  575.                       break;
  576.         case FNT_DEF4:
  577.                       ReadFontDef (Read4Byte(dvifp),load);
  578.                       break;
  579.         default:
  580.                       Fatal (5, MSG_BAD_FONT_DEFS);
  581.                       break;
  582.        }
  583.      }
  584.     if (byte != POST_POST)
  585.      {
  586.       Fatal (5, MSG_MISS_POST_POST);
  587.      }
  588. }
  589.  
  590.  
  591.  
  592. /*-->MoveDown*/
  593. /**********************************************************************/
  594. /****************************  MoveDown  ******************************/
  595. /**********************************************************************/
  596.  
  597. void MoveDown(long p)
  598. {
  599.   long roundpos;
  600.  
  601. /*
  602.  *   The calculations here are crucial to the appearance of the document.
  603.  *   If the motion is small, we round the amount of relative motion; otherwise,
  604.  *   we update the position and round the new position.  Then we check to
  605.  *   insure that the rounded position didn't accumulate an error that was
  606.  *   greater than maxdrift.
  607.  */
  608.  
  609.   /* naechste Zeile nur fuer virtuelle Fonts */
  610.   /* if (curpos) p = scalewidth(p, (frp-1)->curf->scaledsize) ; */
  611.  
  612.   v += p;
  613.  
  614.   if (p >= vertsmallspace || p <= -vertsmallspace) {
  615.     vv = PixRound(v, vconv);    /* hier ist schon alles exact */
  616.   }
  617.   else {
  618.     vv += PixRound(p, vconv);
  619.  
  620.     roundpos = PixRound(v, vconv);
  621.     if (roundpos - vv > vmaxdrift) {
  622.       vv = roundpos - vmaxdrift;
  623.     }
  624.     else if (vv - roundpos > vmaxdrift) {
  625.       vv = roundpos + vmaxdrift;
  626.     }
  627.   }
  628. }
  629.  
  630.  
  631. /*-->MoveOver*/
  632. /**********************************************************************/
  633. /****************************  MoveOver  ******************************/
  634. /**********************************************************************/
  635.  
  636. void MoveOver(long p)
  637. {
  638. /*
  639.  *   Horizontal motion is analogous. We know the exact width of each
  640.  *   character in pixels. Kerning is distinguished from space between
  641.  *   words if it's less than a thinspace and not more negative than would
  642.  *   occur when an accent is being positioned by backspacing.
  643.  */
  644.  
  645.   long roundpos;
  646.  
  647.   /* naechste Zeile nur fuer virtuelle Fonts */
  648.   /* if (curpos) p = scalewidth(p, (frp-1)->curf->scaledsize); */
  649.  
  650.   h += p;
  651.  
  652.   if (p >= thinspace || p <= backspace) {
  653.     hh = PixRound(h, hconv);
  654.   }
  655.   else {
  656.     hh += PixRound(p, hconv);
  657.  
  658. #if 1        /* bringt etwas Geschwindigkeit.... (hoff) (hes) */
  659.     roundpos = PixRound(h, hconv);
  660.     if (roundpos - hh > hmaxdrift) {
  661.       hh = roundpos - hmaxdrift;
  662.     }
  663.     else if (hh - roundpos > hmaxdrift) { 
  664.       hh = roundpos + hmaxdrift;
  665.     }
  666. #else
  667.     setmotion(); /** das oben ist setmotion() (hes) **/
  668. #endif
  669.   }
  670. }
  671.  
  672.  
  673.  
  674. #if 0    /* wird in SetChar/SetRule gebraucht (??!) */
  675. // ist nach fast_cp ausgelagert!! (hes) 10.07.94
  676. /*-->setmotion*/
  677. /**********************************************************************/
  678. /***************************  setmotion  ******************************/
  679. /**********************************************************************/
  680.  
  681. void setmotion(void)
  682. {
  683.   long roundpos;
  684.  
  685.   roundpos = PixRound(h, hconv);
  686.   if (roundpos - hh > hmaxdrift) {
  687.     hh = roundpos - hmaxdrift;
  688.   }
  689.   else if (hh - roundpos > hmaxdrift) { 
  690.     hh = roundpos + hmaxdrift;
  691.   }
  692. }
  693. #endif
  694.  
  695.  
  696.  
  697.  
  698. /*-->NoSignExtend*/
  699. /**********************************************************************/
  700. /***************************  NoSignExtend  ***************************/
  701. /**********************************************************************/
  702.  
  703. #ifdef oldie
  704. long OldNoSignExtend(FILE *fp, int n)    /* return n byte quantity from file fd */
  705.                     /* fp file pointer    */
  706.                     /* n  number of bytes */
  707.  
  708. {
  709.     register long x = 0L;     /* number being constructed */
  710.     int n1;
  711.  
  712.     x = fgetc(fp);   /* get first (high-order) byte */
  713.     n1 = n--;
  714.     while (n--)
  715.      {
  716.       x <<= 8;
  717.       x |= fgetc(fp);
  718.      }
  719.  
  720.     return(x);
  721. }
  722. #endif
  723.  
  724.  
  725. long NoSignExtend(DVIFILE *fp, int n)    /* return n byte quantity from file fd */
  726.                     /* fp file pointer    */
  727.                     /* n  number of bytes */
  728. {
  729.   if (n==1) return Read1Byte(fp);
  730.   else if (n==2) return Read2Byte(fp);
  731.   else if (n==3) return Read3Byte(fp);
  732.   else return Read4Byte(fp);
  733. }
  734.  
  735. #if 0    // die 4 Funktionen sind nach dvihand.h ausgelagert worden (INLINE!!)
  736.  
  737. long __inline Read1Byte(DVIFILE *fp)     /* return n byte quantity from file fd */
  738. {
  739.   unsigned char buf[2];
  740.  
  741.   DVIfread(buf, 1, 1, fp);
  742.  
  743.   return (long)buf[0];
  744. }
  745.  
  746. long __inline Read2Byte(DVIFILE *fp)
  747. {
  748.   unsigned short x;
  749.  
  750.   DVIfread((char *)&x,2,1,fp);
  751.   return (long)((unsigned long)x);
  752. }
  753.  
  754. long __inline Read3Byte(DVIFILE *fp)
  755. {
  756.   unsigned char x[4];
  757.  
  758.   DVIfread(&(x[0]),3,1,fp);
  759.   return (long)((*(unsigned long *)(&(x[0]))) >> 8);
  760. }
  761.  
  762. long __inline Read4Byte(DVIFILE *fp)
  763. {
  764.   long x;
  765.  
  766.   DVIfread((char *)&x,1,4,fp);
  767.   return x;
  768. }
  769.  
  770. #endif
  771.  
  772.  
  773. /*-->PixRound*/
  774. /**********************************************************************/
  775. /*****************************  PixRound  *****************************/
  776. /**********************************************************************/
  777.  
  778. /*
  779. #define PixRound(x,conv)    (long)(((x) + ((conv) >> 1)) / (conv))
  780. long
  781. PixRound(x, conv)       / * return rounded number of pixels * /
  782. register long x;        / * in DVI units     * /
  783. long conv;              / * conversion factor * /
  784. {
  785.     return((long)((x + (conv >> 1)) / conv));
  786. }
  787. */
  788.  
  789.  
  790.  
  791.  
  792. /*-->ReadFontDef*/
  793. /**********************************************************************/
  794. /****************************  ReadFontDef  ***************************/
  795. /**********************************************************************/
  796.  
  797.  
  798. void ReadFontDef(long k, int load)
  799. {
  800.     char nname[STRSIZE];
  801.     long font_mag, font_mag_5, c, s, d;
  802.     int a, l;
  803.     double z;
  804.  
  805.     c = Read4Byte(dvifp); /* checksum */
  806.     s = Read4Byte(dvifp); /* space size */
  807.     d = Read4Byte(dvifp); /* design size */
  808.     a = Read1Byte(dvifp); /* area length for font name */
  809.     l = Read1Byte(dvifp); /* device length */
  810.  
  811.     GetBytes(dvifp, nname, (long) (a+l));
  812.     nname[a+l] = '\0';
  813.  
  814.  
  815. #ifdef AMIGA
  816.     z = ActualFactor((long)floor( ((double)s/(double)d) * (double)1000.0 +0.5)) * 
  817.            ActualFactor(mag) * (double)resolution;
  818.     font_mag   = (long)floor(z+0.5);
  819.     font_mag_5 = (long)floor(z*(double)5.0+0.5);
  820. #else
  821.   {
  822.     register long par;
  823.  
  824.     z = ((double) s/(double) d)*1000.0 + 0.5;
  825.     par = (long)floor(z);
  826.     z = ActualFactor(par) * ActualFactor(mag) * (double)resolution;
  827.     font_mag_5 = floor((z * (double)5.0) + (double)0.5);
  828.     font_mag = (long)floor(z + (double)0.5);
  829.   }
  830. #endif
  831.  
  832.     LoadFont ((load)? 2 : 0, k, nname, c, d, s, font_mag, font_mag_5 ); 
  833. }
  834.  
  835.  
  836. /*-->ReadPostAmble*/
  837. /**********************************************************************/
  838. /**************************  ReadPostAmble  ***************************/
  839. /**********************************************************************/
  840.  
  841. int ReadPostAmble(int load)
  842. /***********************************************************************
  843.     This  routine  is  used  to  read  in  the  postamble  values.    It
  844.     initializes the magnification and checks  the stack height prior  to
  845.     starting printing the document.
  846. ***********************************************************************/
  847. {  long ph, pw;
  848.    int pages;
  849.    
  850.    NumOfPages = 0;
  851.  
  852.     if (FindPostAmblePtr (&postambleptr))
  853.      {
  854.       ppagep = -1L;
  855.       return(1);
  856.      }
  857.  
  858.     if (Read1Byte(dvifp) != POST)
  859.      {
  860.       Warning (MSG_MISS_POST);
  861.       ppagep = -1L;
  862.       if (hconv == 0) {
  863.         hconv = 50000;
  864.       }
  865.       if (vconv == 0) {
  866.         vconv = 50000;
  867.       }
  868.       return (1);
  869.      }
  870. #ifdef DEBUG
  871.     if (DeBug) {
  872.       Message("got POST command");
  873.     }
  874. #endif
  875.     
  876.     ppagep = Read4Byte(dvifp);
  877.     num    = Read4Byte(dvifp);
  878.     den    = Read4Byte(dvifp);
  879.     mag    = Read4Byte(dvifp);
  880.  
  881.     /* man muss beim h-v offset die Magnification beruecksichtigen! */       
  882.     if (hoffset_is_true) {
  883.       hoffset_in = hoffset_in_fix;
  884.     }
  885.     else {
  886.       hoffset_in = (hoffset_in_fix * mag) / 1000.0;
  887.     }
  888.     if (voffset_is_true) {
  889.       voffset_in = voffset_in_fix;
  890.     }
  891.     else {
  892.       voffset_in = (voffset_in_fix * mag) / 1000.0;
  893.     }
  894.     if (moffset_is_true) {
  895.       moffset_in = moffset_in_fix;
  896.     }
  897.     else {
  898.       moffset_in = (moffset_in_fix * mag) / 1000.0;
  899.     }
  900.  
  901.     hoffset = (int)((float)hconvresolution * hoffset_in);
  902.     voffset = (int)((float)vconvresolution * voffset_in);
  903.     moffset = (int)((float)hconvresolution * moffset_in);
  904.  
  905.     hconv = DoConv(num, den, hconvresolution);
  906.     vconv = DoConv(num, den, vconvresolution);
  907.  
  908.     alpha = (((double)den / 7227.0) / 0x100000) * (25400000.0 / (double) num) ;
  909.     /** fsizetol = 1 + (long)(resolution/(72270.0 * hconv)) ; **/
  910.  
  911.  
  912.     ph = Read4Byte (dvifp);
  913.     pw = Read4Byte (dvifp);
  914.  
  915.  
  916.     if (abs(user_paper_height_in+13.13) > 0.01) {
  917.       // hier kommt kein Offset dazu oder weg. Die Höhe ist inklusive Offset!
  918.       pheight_pt   = (int)(user_paper_height_in * 72.27 + 0.5);
  919.       paper_height = (int)(user_paper_height_in * vconvresolution);
  920.       ph = pheight_pt << 16;
  921.     }
  922.     else {
  923.       pheight_pt  = (int)((unsigned long)((ph+voffset*vconv)>>16));
  924.       paper_height = (int) (PixRound(ph,vconv) + (long)voffset);   /* height-plus-depth of tallest page */
  925.     }
  926.  
  927.     if (abs(user_paper_width_in+13.13) > 0.01) {
  928.       // hier kommt kein Offset dazu oder weg. Die Breite ist inklusive Offset!
  929.       pwidth_pt   = (int)(user_paper_width_in * 72.27 + 0.5);
  930.       paper_width = (int)(user_paper_width_in * hconvresolution);
  931.       pw = pwidth_pt << 16;
  932.     }
  933.     else {
  934.       pwidth_pt  = (int)((unsigned long)((pw+hoffset*hconv)>>16));
  935.       paper_width  = (int) (PixRound(pw,hconv) + (long)hoffset);   /* width of widest page */
  936.     }
  937.  
  938.  
  939.     /** pheight_inch = (pheight_inch * 1000) / mag;  **/
  940.     /** pwidth_inch  = (pwidth_inch * 1000) /mag;    **/
  941.     /* pheight_inch = ((pheight_inch + 50) / 100 ) * 100; */    /* eine Kommastelle reicht */
  942.     /* pwidth_inch  = ((pwidth_inch + 50) / 100 ) * 100; */
  943.  
  944.     if (Stats) {
  945.       Logging(MSG_LOG_PAGE_DIM);
  946.       Logging(MSG_LOG_HORIZ, (float)(((unsigned long)pw)>>16) / 72.27, paper_width  - hoffset,
  947.         ((unsigned long)pw)>>16, pw);
  948.       Logging(MSG_LOG_VERT, (float)(((unsigned long)ph)>>16) / 72.27, paper_height - voffset,
  949.         ((unsigned long)ph)>>16, ph);
  950.       Logging(MSG_LOG_MAG,mag, hconv);
  951.       Logging(MSG_LOG_OFFSET);
  952.  
  953.       Logging(MSG_LOG_HOFF, hoffset_in, hoffset_in_fix, hoffset);
  954.       Logging(MSG_LOG_VOFF, voffset_in, voffset_in_fix, voffset);
  955.  
  956.       Logging(MSG_LOG_RESO,hconvresolution, vconvresolution);
  957.     }
  958.  
  959.     if (Read2Byte(dvifp) >= STACKSIZE) {
  960.       Fatal (10, MSG_DVI_STACK_TOO_SMALL,STACKSIZE);
  961.     }
  962.  
  963.     pages=Read2Byte(dvifp);     /* this reads the number of pages in */
  964.     NumOfPages = pages;         /* the DVI file */
  965.                        
  966.     if (Stats)
  967.      {
  968.       Logging(MSG_LOG_NUM_PAGES, pages);
  969.      }
  970.  
  971. #ifdef oldie
  972.     if (load) {
  973.       GetFontDef (1);        /* (hes) */
  974.     }
  975. #endif
  976.  
  977.     return(0);        /* DVI file is complete */
  978. }
  979.  
  980. #if 0
  981. #ifdef SLOW
  982. /*-->SetChar*/
  983. /**********************************************************************/
  984. /*****************************  SetChar  ******************************/
  985. /**********************************************************************/
  986.  
  987. void SetChar(long c, int command)
  988. {
  989.     long shift;
  990.  
  991.     hh = PixRound(h, hconv);
  992.     vv = PixRound(v, vconv);
  993.     shift = PrintChar(hh,vv,c);
  994.     if (command <= SET4) h += shift;
  995. }
  996. #endif
  997. #endif
  998.  
  999. #if 0
  1000. #ifdef SLOW
  1001.  
  1002. /*-->SetRule*/
  1003. /**********************************************************************/
  1004. /*****************************  SetRule  ******************************/
  1005. /**********************************************************************/
  1006.  
  1007. void SetRule(long a, long b, BOOLEAN Set)
  1008. {           /*   this routine will draw a rule */
  1009.     long ehh, evv;
  1010.     hh = PixRound(h, hconv);
  1011.     vv = PixRound(v-a, vconv);
  1012.     ehh = PixRound(h + b, hconv);
  1013.     evv = PixRound(v, vconv);
  1014.     if (hh == ehh) 
  1015.      {
  1016.       ehh++;
  1017.      }
  1018.     if (vv == evv) 
  1019.      {
  1020.       vv--;
  1021.      }
  1022.     if ((a > 0) && (b > 0))
  1023.      {
  1024.       CopyBitArray ((long)hh, (long)vv, (long)(ehh-hh), (long)(evv-vv),
  1025.         (long *)NULL);
  1026.      }
  1027.     if (Set) 
  1028.      {
  1029.       h += b;
  1030.      }
  1031.  
  1032. }
  1033. #endif
  1034. #endif
  1035.  
  1036. /*-->SignExtend*/
  1037. /**********************************************************************/
  1038. /****************************  SignExtend  ****************************/
  1039. /**********************************************************************/
  1040.  
  1041. #ifdef oldie
  1042. long OldSignExtend(FILE *fp, int n)   /* return n byte quantity from file fd */
  1043. {
  1044.     int n1;         /* number of bytes      */
  1045.     register long x=0; /* number being constructed */
  1046.  
  1047.     x = fgetc(fp);   /* get first (high-order) byte */
  1048.     n1 = n--;
  1049.     while (n--)
  1050.      {
  1051.       x <<= 8;
  1052.       x |= fgetc(fp);
  1053.      }
  1054.  
  1055.     /* NOTE: This code assumes that the right-shift is an arithmetic, rather
  1056.     than logical, shift which will propagate the sign bit right.   According
  1057.     to Kernighan and Ritchie, this is compiler dependent! */
  1058.  
  1059.     x<<=32-8*n1;
  1060.     x>>=32-8*n1;  /* sign extend */
  1061.     return(x);
  1062. }
  1063. #endif
  1064.  
  1065. long SignExtend(DVIFILE *fp, int n)     /* return n byte quantity from file fd */
  1066. {
  1067.   if (n==1) return SRead1Byte(fp);
  1068.   else if (n==2) return SRead2Byte(fp);
  1069.   else if (n==3) return SRead3Byte(fp);
  1070.   else return SRead4Byte(fp);
  1071. }
  1072.  
  1073.  
  1074.  
  1075. long SRead1Byte(DVIFILE *fp)     /* return n byte quantity from file fd */
  1076. {
  1077.   signed char x;
  1078.  
  1079.   DVIfread((char *)&x,1,1,fp);
  1080.   return (long)x;
  1081. }
  1082.  
  1083. long SRead2Byte(DVIFILE *fp)
  1084. {
  1085.   short x;
  1086.  
  1087.   DVIfread((char *)&x,2,1,fp);
  1088.   return (long)x;
  1089. }
  1090.  
  1091. long SRead3Byte(DVIFILE *fp)
  1092. {
  1093.   char x[4];
  1094.  
  1095.   DVIfread(&(x[0]),3,1,fp);
  1096.   return (long)((*(long *)(&(x[0]))) >> 8);
  1097. }
  1098.  
  1099. long SRead4Byte(DVIFILE *fp)
  1100. {
  1101.   long x;
  1102.  
  1103.   DVIfread((char *)&x,1,4,fp);
  1104.   return x;
  1105. }
  1106.  
  1107.  
  1108.  
  1109. /*-->SkipFontDef*/
  1110. /**********************************************************************/
  1111. /****************************  SkipFontDef  ***************************/
  1112. /**********************************************************************/
  1113.  
  1114. void SkipFontDef(void)
  1115. {
  1116.     int a, l;
  1117.     char n[STRSIZE];
  1118.  
  1119.     Read4Byte(dvifp);
  1120.     Read4Byte(dvifp);
  1121.     Read4Byte(dvifp);
  1122.     a = Read1Byte(dvifp);
  1123.     l = Read1Byte(dvifp);
  1124.     GetBytes(dvifp, n,(long)(a+l));
  1125. }
  1126.  
  1127.  
  1128. /*-->DoSpecial*/
  1129. /*********************************************************************/
  1130. /*****************************  DoSpecial  ***************************/
  1131. /*********************************************************************/
  1132.  
  1133.  
  1134. #ifdef KEIN_DOSPECIAL_FILE
  1135.  
  1136. /* die Funktionen sind nun nach dospecia verlagert worden. */
  1137.  
  1138.  
  1139.  
  1140. #ifdef ATARI
  1141.  
  1142. typedef enum {None, String, Integer, Number, Dimension} ValTyp;
  1143.  
  1144. typedef struct 
  1145.  {
  1146.   char    *Key;        /* the keyword string */
  1147.   char    *Val;        /* the value string */
  1148.   ValTyp  vt;        /* the value type */
  1149.   union                /* the decoded value */
  1150.    {
  1151.     int  i;
  1152.     float n;
  1153.    } v;
  1154.  } KeyWord;
  1155.  
  1156. typedef struct
  1157.  {
  1158.   char        *Entry;
  1159.   ValTyp    Type;
  1160.  } KeyDesc;
  1161.  
  1162. # define IMGFILE 0
  1163. # define MAXIMGWIDTH 1
  1164. # define MAXIMGHEIGHT 2
  1165.  
  1166. KeyDesc KeyTab[] = 
  1167.  {{"imgfile", String},
  1168.   {"hsize", Dimension},
  1169.   {"vsize", Dimension},
  1170.   {"hoffset", Dimension},
  1171.   {"voffset", Dimension},
  1172.   {"hscale", Number},
  1173.   {"vscale", Number}};
  1174.  
  1175. # define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
  1176.  
  1177. /*-->GetKeyStr*/
  1178. /**********************************************************************/
  1179. /*****************************  GetKeyStr  ****************************/
  1180. /**********************************************************************/
  1181.  
  1182. /* extract first keyword-value pair from string (value part may be null)
  1183.  * return pointer to remainder of string
  1184.  * return NULL if none found
  1185.  */
  1186.  
  1187. char    KeyStr[STRSIZE];
  1188. char    ValStr[STRSIZE];
  1189.  
  1190. char *GetKeyStr( char *str, KeyWord *kw )
  1191. {
  1192.  char *s, *k, *v, t;
  1193.  
  1194.  if( str== NULL )
  1195.   {
  1196.    return( NULL );
  1197.   }
  1198.  
  1199.  for( s=str; *s == ' '; s++ )
  1200.   ; /* skip over blanks */
  1201.  if ( *s == '\0' )
  1202.   {
  1203.    return( NULL );
  1204.   }
  1205.  
  1206.  for( k=KeyStr;                    /* extract keyword portion */
  1207.       (*s != ' ') && (*s != '\0') && (*s != '='); 
  1208.       *k++ = *s++ )
  1209.   ;
  1210.  *k = '\0';
  1211.  kw->Key = KeyStr;
  1212.  kw->Val = v = NULL;
  1213.  kw->vt = None;
  1214.  
  1215.  for( ; *s == ' '; s++ )
  1216.   ;                    /* skip over blanks */
  1217.  
  1218.  if( *s != '=' )    /* look for "=" */
  1219.   {
  1220.    return( s );
  1221.   }
  1222.  
  1223.  for( s++ ; *s == ' '; s++ )
  1224.   ;                    /* skip over blanks */
  1225.  if( *s == '\'' || *s == '\"' )     /* get string delimiter */
  1226.   {
  1227.    t = *s++;
  1228.   }
  1229.  else
  1230.   {
  1231.    t = ' ';
  1232.   }
  1233.  for( v=ValStr;            /* copy value portion up to delim */
  1234.       *s != t && *s != '\0';
  1235.       *v++ = *s++ )
  1236.   ;
  1237.  if ( t != ' ' && *s == t )
  1238.   {
  1239.    s++;
  1240.   }
  1241.  *v = '\0';
  1242.  kw->Val = ValStr;
  1243.  kw->vt = String;
  1244.  
  1245.  return( s );
  1246. }
  1247.  
  1248.  
  1249. /*-->GetKeyVal*/
  1250. /**********************************************************************/
  1251. /*****************************  GetKeyVal  ****************************/
  1252. /**********************************************************************/
  1253.  
  1254. /* get next keyword-value pair
  1255.  * decode value according to table entry
  1256.  */
  1257.  
  1258. int GetKeyVal( KeyWord *kw, KeyDesc tab[], int nt, int *tno)
  1259. {
  1260.  int i;
  1261.  
  1262.  *tno = -1;
  1263.  
  1264.  for(i=0; i<nt; i++)
  1265.   {
  1266.    if ( !strcmp(kw->Key, tab[i].Entry) )
  1267.     {
  1268.      *tno = i;
  1269.      switch ( tab[i].Type )
  1270.       {
  1271.        case None: 
  1272.         if ( kw->vt != None )
  1273.          {
  1274.           return( FALSE );
  1275.          }
  1276.         break;
  1277.        case String:
  1278.         if ( kw->vt != String )
  1279.          {
  1280.           return( FALSE );
  1281.          }
  1282.         break;
  1283.        case Integer:
  1284.         if ( kw->vt != String )
  1285.          {
  1286.           return( FALSE );
  1287.          }
  1288. # if 0
  1289.         if ( sscanf(kw->Val,"%d%c", &(kw->v.i), &c) != 1
  1290.              || c != '\0' )
  1291. # endif
  1292.         if ( sscanf(kw->Val,"%d", &(kw->v.i)) != 1)
  1293.          {
  1294.           return( FALSE );
  1295.          }
  1296.         break;
  1297.        case Number:
  1298.        case Dimension:
  1299.         if ( kw->vt != String )
  1300.          {
  1301.           return( FALSE );
  1302.          }
  1303. # if 0
  1304.         if( sscanf(kw->Val,"%f%c", &(kw->v.n), &c) != 2
  1305.             /* || c != '\0' */) 
  1306. # endif
  1307.         if( sscanf(kw->Val,"%f", &(kw->v.n)) != 1) 
  1308.          {
  1309.           return( FALSE );
  1310.          }
  1311.         break;
  1312.       }
  1313.      kw->vt = tab[i].Type;
  1314.      return( TRUE );
  1315.     }
  1316.   }
  1317.  return( TRUE );
  1318. }
  1319.  
  1320. void DoSpecial( char *str, long n )
  1321.   /* interpret a \special command, made up of keyword=value pairs */
  1322.  char spbuf[STRSIZE]; 
  1323.  char *sf = NULL;
  1324.  KeyWord k;
  1325.  int i;
  1326.  int maxwidth, maxheight;
  1327.  double hsz, vsz;
  1328.  long ihh, ivv;
  1329.   
  1330.  str[n] = '\0';
  1331.  spbuf[0] = '\0';
  1332.  
  1333.  while( (str=GetKeyStr(str,&k)) != NULL ) /* get all keyword-value pairs */
  1334.   {
  1335.       /* for compatibility, single words are taken as file names */
  1336.    if( k.vt == None /* && access(k.Key,0) == 0 */)
  1337.     {
  1338.      if (sf != NULL)
  1339.       {
  1340.        Warning("More than one \\special file name given. %s ignored", sf );
  1341.       }
  1342.      strcpy(spbuf, k.Key);
  1343.      sf = spbuf;
  1344.     }
  1345.    else if( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
  1346.     {
  1347.      switch (i)
  1348.       {
  1349.        case IMGFILE:
  1350.         if (sf != NULL)
  1351.          {
  1352.           Warning("More than one \\special file name given. %s ignored", sf );
  1353.          }
  1354.         strcpy(spbuf, k.Val);
  1355.         sf = spbuf;
  1356.         break;
  1357.        case MAXIMGWIDTH:
  1358.         hsz = k.v.n;
  1359.         break;
  1360.        case MAXIMGHEIGHT:
  1361.         vsz = k.v.n;
  1362.         break;
  1363.        default:
  1364.         Logging( "%f @%s\n", k.v.n, KeyTab[i].Entry);
  1365.         break;
  1366.       }
  1367.     }
  1368.    else
  1369.     {
  1370.      Warning("Invalid keyword or value in \\special - \"%s\" ignored", k.Key );
  1371.     }
  1372.   }
  1373.  
  1374.  if (sf != NULL)
  1375.   {
  1376.    ihh = (long)PixRound(h, hconv) + (long)hoffset;
  1377.    ivv = (long)PixRound(v, vconv) + (long)voffset;
  1378.    maxwidth = (int)((hsz * hconvresolution)/2.54);
  1379.    maxwidth = (maxwidth+7)/8;
  1380.    maxheight = (int)((vsz * vconvresolution)/2.54);
  1381. # ifdef ATARI
  1382.    PaintImage (sf, ihh, ivv, maxwidth, maxheight);
  1383. # endif
  1384.   }
  1385.  else
  1386.   {
  1387.    Warning("No special file name provided.");
  1388.   }
  1389. }
  1390.  
  1391. #endif   /* ATARI */
  1392.  
  1393.  
  1394. #ifdef AMIGA
  1395.  
  1396. static void draw_border(struct special_map *bmap);
  1397.  
  1398. static void draw_border(struct special_map *bmap)
  1399. {
  1400.   long width,height;
  1401.   long svv = vv, shh = hh;
  1402.  
  1403.   width = bmap->width;        /* width in Bits */
  1404.   height = bmap->height;
  1405.   width = ((long)(((double)width/(double)hconvresolution)*72.27+0.5))<<16;
  1406.   height = ((long)(((double)height/(double)vconvresolution)*72.27+0.5))<<16;
  1407.  
  1408.   vv += bmap->voffset;
  1409.   hh += bmap->hoffset;
  1410.  
  1411.   SetRule(height, 1<<15, FALSE);    /* 1<<15 == 0.5 pt */
  1412.   SetRule(1<<15, width, FALSE);
  1413.  
  1414.   vv -= bmap->height /*-vthickness*/;
  1415.   SetRule(1<<15, width, FALSE);
  1416.  
  1417.   vv += bmap->height /*-vthickness*/;
  1418.   hh += bmap->width /*-hthickness*/;
  1419.   SetRule(height, 1<<15, FALSE);
  1420.  
  1421.   vv = svv;
  1422.   hh = shh;
  1423. }
  1424.  
  1425. void DoSpecial( char *str, long n )
  1426. {
  1427.   struct special_map *bmap;
  1428.   long x,y,width,height, xpos, ypos, pagewidth, xoff, shift, ystart;
  1429.   long xstart, xend;
  1430.   unsigned short *page, *image, it;
  1431.   unsigned long copy, *insert;
  1432.   FILE *iffile;
  1433.   long buffer;
  1434.   unsigned short *line;
  1435.   long width_bit;
  1436.  
  1437.  
  1438.   str[n] = '\0';
  1439.   bmap = send_special(str);
  1440.   xstart = 0;
  1441.   xend = 0;
  1442.  
  1443.   if (bmap != NULL) {
  1444.  
  1445. #ifdef OLD_VERSION
  1446.     x = PixRound(h, hconv) + (long)hoffset + bmap->hoffset;
  1447.     y = PixRound(v, vconv) + (long)voffset + bmap->voffset;
  1448. #endif
  1449.  
  1450.     if (landscape) {
  1451.       // wird spaeter noch gedreht, also jetzt etwas seltsame Offsets
  1452.       x = hh + hconvresolution + bmap->hoffset;    // plus 1 inch
  1453.       y = vv + hoffset + bmap->voffset; 
  1454.     }
  1455.     else {
  1456.       x = hh + hoffset + bmap->hoffset;
  1457.       y = vv + voffset + bmap->voffset; 
  1458.     }
  1459.  
  1460.     // die rechte Seite wird direkt neben die linke gesetzt.
  1461.     // Dazu wird der hoffset der rechten abgezogen, da dort kein Offset mehr benoetigt wird.
  1462.     // hoffset gibt es wirklich nur am linken Rand. Ansonsten hat man ja den moffset.
  1463.  
  1464.     if (twopage && !leftpage) x += paper_width + moffset - hoffset;
  1465.  
  1466.  
  1467.     if (x < 0) {
  1468.       Warning("Picture out of left border! (x=%ld)",x);
  1469.       xstart = (15-x)/16;    /* weglassen von Vielfachen von 16Bit (Word) */
  1470.       x += xstart*16;
  1471.     }
  1472.  
  1473.     switch (bmap->where_is) {
  1474.       case LOC_BITMAP:
  1475.       case LOC_BITMAP_BORDER:
  1476.         copy = 0;
  1477.         width = (bmap->width + 15) / 16;    /* width in Words */
  1478.         height = bmap->height;
  1479.         y -= height;
  1480.         xend = width;
  1481.  
  1482.         if (x+width*16 > map.width) {
  1483.           Warning("Picture out of right border!");
  1484.           xend = width - (((x+width*16-map.width)+15)/16);
  1485.         }
  1486.  
  1487.         xoff  = x >> 4;
  1488.         shift = x - (xoff << 4);
  1489.  
  1490.         pagewidth = map.width >> 4;
  1491.  
  1492.     /* Test ob Bild im sichtbaren Bereich */
  1493.     if (y >= lower_limit || y + height < upper_limit) {
  1494.       break;
  1495.     }
  1496.  
  1497.     /* Test oberer Rand */
  1498.     if (y < upper_limit) {
  1499.       ystart = upper_limit - y;
  1500.           page  = ((unsigned short *)map.pixptr) + xoff;
  1501.           image = (unsigned short *)bmap->loc.map + xstart + (width*ystart);
  1502.     }
  1503.     else {
  1504.       ystart = 0;
  1505.           page  = ((unsigned short *)map.pixptr) + (y-upper_limit) * pagewidth + xoff;
  1506.           image = (unsigned short *)bmap->loc.map + xstart;
  1507.     }
  1508.  
  1509.  
  1510.     /* Test unterer Rand */
  1511.         if (y + height >= lower_limit) {
  1512.           height = lower_limit - y - 1;
  1513.           /* height -= (lower_limit - y); that's a bug !! */
  1514.         }
  1515.         
  1516.         for (ypos = ystart; ypos < height; ypos++) {
  1517.           for (xpos = xstart; xpos < xend; xpos++) {
  1518.             it = *((unsigned short *)image+xpos);
  1519.             copy = ((unsigned long)it) << 16;
  1520.             insert = (unsigned long *)(page + xpos);
  1521.             *insert |= (copy >> shift); 
  1522.           }
  1523.           image += width;
  1524.           page += pagewidth;
  1525.         }
  1526.         if (bmap->where_is == LOC_BITMAP_BORDER) {
  1527.           draw_border(bmap);
  1528.         }
  1529.         break;
  1530.  
  1531.       case LOC_FILE:
  1532.       case LOC_FILE_BORDER:
  1533.         if ((iffile = fopen(bmap->loc.filename,"r")) != NULL) {
  1534.       if (fread((char *)&buffer,4,1,iffile) == 1 && buffer == MAGIC_WORD) {
  1535.         (void)fread((char *)&buffer,4,1,iffile);
  1536.         if (fread((char *)&buffer,4,1,iffile) == 1) {
  1537.               width = (buffer+15) / 16;            /* in words */
  1538.               width_bit = buffer;
  1539.           xend = width;
  1540.           if (x+width*16 > map.width) {
  1541.             Warning("Picture out of right border!");
  1542.             xend = width - (((x+width*16-map.width)+15)/16);
  1543.           }
  1544.  
  1545.           if (fread((char *)&buffer,4,1,iffile) == 1) {
  1546.                 height = buffer;
  1547.             y -= height;
  1548.                 if ((line = xmalloc(width*2)) == NULL) {
  1549.                   Warning("No memory for special-bitmap copy!");
  1550.                 }
  1551.                 else {
  1552.           xoff  = x >> 4;
  1553.           shift = x - (xoff << 4);
  1554.                 pagewidth = map.width >> 4;
  1555.  
  1556.           /* Test on Bild im sichtbaren Bereich */
  1557.           if (y > lower_limit || y + height < upper_limit) {
  1558.             fclose(iffile);
  1559.             break;
  1560.           }
  1561.  
  1562.           /* Test oberer Rand */
  1563.           if (y < upper_limit) {
  1564.             ystart = upper_limit - y;
  1565.             page  = ((unsigned short *)map.pixptr) + xoff;
  1566.             fseek(iffile,width * 2 * ystart, 1);    /* seek from actuall pos */
  1567.           }
  1568.           else {
  1569.             page  = ((unsigned short *)map.pixptr) + (y-upper_limit) * pagewidth + xoff;
  1570.             ystart = 0;
  1571.           }
  1572.  
  1573.           /* Test unterer Rand */
  1574.               if (y + height > lower_limit) {
  1575.                 height = lower_limit - y;
  1576.               }
  1577.  
  1578.           for (ypos = ystart; ypos < height; ypos++) {
  1579.             if (fread((char *)line,2,width,iffile) == width) {
  1580.               image = (unsigned short *)line+xstart;
  1581.               for (xpos = xstart; xpos < xend; xpos++) {
  1582.                 it = *((unsigned short *)image+xpos);
  1583.                 copy = ((unsigned long)it) << 16;
  1584.                 insert = (unsigned long *)(page + xpos);
  1585.                 *insert |= (copy >> shift); 
  1586.               }
  1587.               page += pagewidth;
  1588.             }
  1589.           }
  1590.           xfree(line);
  1591.                 }
  1592.             if (bmap->where_is == LOC_FILE_BORDER) {
  1593.               bmap->width = width_bit;
  1594.               bmap->height = height;
  1595.               draw_border(bmap);
  1596.             }
  1597.               }
  1598.         }
  1599.       }
  1600.           fclose(iffile);
  1601.         }
  1602.         break;
  1603.  
  1604.       case LOC_BORDER:
  1605.         draw_border(bmap);
  1606.         break;
  1607.  
  1608.       case LOC_RECTANGLE:
  1609.         width = bmap->width;        /* width in Bits */
  1610.         height = bmap->height;
  1611.         width = ((long)(((double)width/(double)hconvresolution)*72.27+0.5))<<16;
  1612.         height = ((long)(((double)height/(double)vconvresolution)*72.27+0.5))<<16;
  1613.     vv += bmap->voffset;
  1614.     hh += bmap->hoffset;
  1615.     SetRule(height, width, FALSE);
  1616.     vv -= bmap->voffset;
  1617.     hh -= bmap->hoffset;
  1618.         break;
  1619.  
  1620.       case LOC_NONE:
  1621.         break;
  1622.  
  1623.       default:
  1624.           Warning("Unknown picture locating!?");
  1625.           break;
  1626.     }
  1627.   }
  1628.  
  1629.   special_ok();
  1630. }
  1631.  
  1632. #endif
  1633.  
  1634. #endif /* KEIN_DOSPECIAL_FILE */
  1635.