home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / driver / util / amiga / fast_cp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-10  |  12.1 KB  |  485 lines

  1. #ifndef SLOW
  2.  
  3. #include "defines.h"
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7.  
  8. #ifdef AMIGA
  9. # ifdef DISPLAY
  10. #  include <intuition/intuition.h>
  11.    extern struct RastPort      myRastPort;
  12. # endif
  13. #endif
  14.  
  15. #ifdef AZTEC_C
  16. #  include "functions.h"
  17. #endif
  18.  
  19.  
  20. #include "globals.h"
  21. #include "bitmap.h"
  22. #include "commands.h"
  23. #include "flmt.h"
  24. #include "new_font.h"
  25.  
  26. #include "globals.i"
  27. #include "fast_cp.i"
  28. #include "dvihand.i"
  29. #include "unpack.i"
  30. #include "new_font.i"        /* fuer Load_really() */
  31. #include "search.i"
  32.  
  33. #ifdef DISPLAY
  34. #  include <clib/graphics_protos.h>
  35. #endif
  36.  
  37. #ifdef MYDEBUG
  38. extern struct Library * DOSBase;
  39. #endif
  40.  
  41.  
  42. #define PixRound(x,conv)    (long)(((x) + ((conv) >> 1)) / (conv))
  43.  
  44. #define BITSPERLONG    32
  45. #define BITSPERWORD    16
  46. #define WORD_WIDTH    16
  47.  
  48. extern long  hconv, vconv;            /* converts DVI units to pixels       */
  49. extern long  h;                       /* current horizontal position        */
  50. extern long  hh;                      /* current h on device                */
  51. extern long  v;                       /* current vertical position          */
  52. extern long  vv;                      /* current v on device                */
  53.  
  54.  
  55.  
  56. extern int        DeBug;
  57. extern struct bitmap    map;
  58. extern long        upper_limit;
  59. extern long        lower_limit;
  60.  
  61. extern int   hmaxdrift;                 /* max pixels away from true rounded position */
  62. extern int   vmaxdrift;                 /* max pixels away from true rounded position */
  63.  
  64.  
  65. /* extern struct font_entry *cfontptr; */
  66.  
  67. extern struct Font *cfontptr;
  68.  
  69.  
  70. static void __inline setmotion(void);
  71.  
  72.  
  73. static void __inline setmotion(void)
  74. {
  75.   long roundpos;
  76.  
  77.   roundpos = PixRound(h, hconv);
  78.   if (roundpos - hh > hmaxdrift) {
  79.     hh = roundpos - hmaxdrift;
  80.   }
  81.   else if (hh - roundpos > hmaxdrift) { 
  82.     hh = roundpos + hmaxdrift;
  83.   }
  84. }
  85.  
  86.  
  87.  
  88. /*-->SetChar*/
  89. /**********************************************************************/
  90. /*****************************  SetChar  ******************************/
  91. /**********************************************************************/
  92.  
  93. #if !defined(USE_ASM_SETCHAR) || !defined(DISPLAY)
  94.  
  95. void SetChar(long pc, int command)
  96. {
  97.   struct Char            *ptr;
  98.  
  99.   register unsigned long     reg;
  100.   unsigned short        *char_adr;
  101.   unsigned short        *start_adr, *adr;
  102.   long                nr_sh, length_row;
  103.   long                c, l;
  104.  
  105.   long            x, y;        /* upper left corner (pixels)           */
  106.   long            cp_h, w;     /* height / width of character (pixels) */
  107.   /* long        *p; */          /* pointer to bitmap */
  108.   unsigned short    *p;          /* pointer to bitmap */
  109.   struct Chars        *cd;
  110.  
  111.   long            words, lmin, lmax;
  112.  
  113.  
  114.   cd = &(cfontptr->common->ch[pc]);
  115.  
  116.   if (cd->packed_data == -1) {
  117.     /* character not in font:
  118.      * add tfm width to h and set hh = PixRound(h)
  119.      */
  120.     if (command <= SET4) {        /* SET command (or PUT command) ? */
  121.     if (!cfontptr->ctfmw_valid ) {
  122.        h += scalewidth(cfontptr->common->fnt_group->tfmw[(int)pc&255],
  123.                    cfontptr->space_faktor);
  124.         }
  125.     else {
  126.       h += cfontptr->ctfmw[(int)pc&255];
  127.     }
  128.     hh = PixRound(h, hconv);
  129.     }
  130.     return ;  /* kein Shift */
  131.   }
  132.  
  133.   if ((ptr = cd->unpacked) == NULL) {
  134.     if (cfontptr->common->fnt_status == FNT_DEFINED ||
  135.         cfontptr->common->fnt_status == FNT_FOUND) {
  136.       /* Font noch nicht geladen?? */
  137.       /* Die Abfrage kommt nur, wenn der Buchstabe nicht eh schon gefunden    */
  138.       /* wird, also wenn der Char sicher noch nie ausgepackt wurde!        */
  139.  
  140.       Load_really(cfontptr);        /* nun wird er geladen... */
  141.     }
  142.     unpack_char(cfontptr, pc);
  143.     if ((ptr = cd->unpacked) == NULL) {
  144.       /* auspacken hat nicht geklappt, aber die Breite des Chars ist bekannt */
  145.  
  146.       D(bug("Font %s, Num: %ld, Status: %ld, Zeichen: %ld (Zeichen auspacken)\n", 
  147.         cfontptr->common->fnt_group->fnt_name, cfontptr->fnt_number, cfontptr->common->fnt_status, pc));
  148.  
  149.       goto sh_return;
  150.     }
  151.   }
  152.  
  153. #if 0
  154.   x = (long)(PixRound(h, hconv)-ptr->xOffset) + hoffset;
  155.   y = (long)(PixRound(v, vconv)-ptr->yOffset) + voffset; 
  156. #endif
  157.  
  158.  
  159. #ifdef OLD_NO_OFFSET_VARS
  160.  
  161. #ifdef DISPLAY
  162.   x = hh - ptr->xOffset + hoffset;
  163.   y = vv - ptr->yOffset + voffset; 
  164. #else
  165.   if (landscape) {
  166.     // wird spaeter noch gedreht, also jetzt etwas seltsame Offsets
  167.     x = hh - ptr->xOffset + hconvresolution;    // plus 1 inch
  168.     y = vv - ptr->yOffset + hoffset; 
  169.   }
  170.   else {
  171.     x = hh - ptr->xOffset + hoffset;
  172.     y = vv - ptr->yOffset + voffset; 
  173.   }
  174.  
  175.   // die rechte Seite wird direkt neben die linke gesetzt.
  176.   // Dazu wird der hoffset der rechten abgezogen, da dort kein Offset mehr benoetigt wird.
  177.   // hoffset gibt es wirklich nur am linken Rand. Ansonsten hat man ja den moffset.
  178.   if (twopage && !leftpage) x += paper_width + moffset - hoffset;
  179. #endif
  180.  
  181. #else
  182.  
  183.   x = hh - ptr->xOffset + OffsetBitmap_X;
  184.   y = vv - ptr->yOffset + OffsetBitmap_Y; 
  185.  
  186. #endif
  187.  
  188.  
  189.   w = (long)ptr->width;                    /* char width */
  190.   cp_h = (long)ptr->height;                /* char height */
  191.  
  192.  
  193. #ifdef DISPLAY
  194.   // Such-Modus?
  195.   if (InSearchMode) {
  196.     BMSearch(pc, x, y, w, cp_h);
  197.     goto sh_return;
  198.   }
  199. #endif
  200.  
  201.  
  202.   p = (unsigned short *)(ptr+1);
  203.  
  204.   /* Buchstaben am Rand werden vollstaendig weggelassen */
  205.   if (x < 0L || x+w >= map.width) {
  206.       goto sh_return;
  207.   }
  208. #ifdef BERND
  209.   if (y >= lower_limit || y-cp_h < upper_limit) {
  210.                 ^^^^^^ falsche Richtung!
  211.       goto sh_return;
  212.   }
  213. #else
  214.   /* Buchstaben die ganz unten oder oben heraus sind werden weggelassen */
  215.   if (y >= lower_limit || y+cp_h < upper_limit) {
  216.       goto sh_return;
  217.   }
  218. #endif
  219.  
  220.   lmin = 0; lmax = cp_h;
  221.  
  222.   /* Buchstaben die nach unten herausragt wird abgeschnitten */
  223.   if (y+cp_h >= lower_limit) {
  224.     lmax = lower_limit - y /*- 1*/;    /* -1 wird nicht benoetigt, da <lmax! */
  225.   }
  226.   /* Buchstaben die nach oben herausragen werden ebenfalls abgeschnitten */
  227.   if (y < upper_limit) {
  228.     lmin = upper_limit - y;
  229.   }
  230.  
  231.   length_row = map.width >> 4;        /* Laenge einer Zeile in Woerter */
  232.  
  233.   start_adr = ((unsigned short *)map.pixptr) 
  234.                 + ((y - upper_limit + lmin) * length_row)
  235.                 + (x >> 4);
  236.   /* Adresse des ersten Wortes */
  237.  
  238.   nr_sh = x & 15;            /* Anzahl benoetigter Shifte */
  239.   words = (w + 15) / 16;        /* Anzahl Words des Chars pro Zeile */
  240.  
  241.   char_adr = (unsigned short *) ((unsigned short *)p + (lmin * words));
  242.  
  243.    //reg = 0L;
  244.  
  245. #if 0
  246.   // Zeichen 98....'b' hatte Probleme gemacht
  247.   if (!strcmp(cfontptr->common->fnt_group->fnt_name, "cmsl12")) {
  248.     D(bug("Font %s, Num: %ld, Status: %ld, Zeichen: %ld\n", 
  249.       cfontptr->common->fnt_group->fnt_name, cfontptr->fnt_number, cfontptr->common->fnt_status, pc));
  250.   }
  251. #endif
  252.  
  253.  
  254.    if (words == 1) {                /* width char <= width word */
  255.      for (l=lmax-lmin; l>0; l--) {
  256.         reg = ((long)(*char_adr++)) << 16;
  257.         reg >>= nr_sh;
  258.         *(unsigned long *)start_adr |= reg;
  259.         start_adr += length_row;
  260.     }                        /* end for l        */
  261.    }
  262.    else {
  263.     adr = start_adr;
  264.     for (l=lmax-lmin; l>0; l--) {
  265.       for (c=words; c>0; c--) {
  266.         reg = ((long)(*char_adr++)) << 16;
  267.         reg >>= nr_sh;
  268.         *(unsigned long *)(adr++) |= reg;
  269.       }                        /* end for c        */
  270.       start_adr += length_row;
  271.       adr = start_adr;
  272.     }                        /* end for l        */
  273.   }                        /* end else w<16    */
  274.  
  275.  
  276. sh_return:
  277.  
  278.     if (command <= SET4) {    /* SET command, not a PUT command */
  279.        /* ... but {\tt DVItype} will allow character codes greater 255,
  280.         * assuming that they all have the same width as the character
  281.         * whose code is  c mod 256.
  282.         */
  283.       if (!cfontptr->ctfmw_valid ) {
  284.         /* Diese Abfrage ist eigentlich ueberfluessig!!         */
  285.         /* Wenn das Programm korrekt funktioniert, sollte dieser */
  286.         /* Fall nie auftreten!                     */
  287.         WarningStr("Internal error: 'ctfmw_valid' (%s, #%d, St:%d)",
  288.         cfontptr->common->fnt_group->fnt_name, cfontptr->fnt_number, cfontptr->common->fnt_status);
  289.     setup_ctfmw(cfontptr);
  290.         h  += cfontptr->ctfmw[(int)pc&255];
  291.     /* h += scalewidth(cfontptr->common->fnt_group->tfmw[(int)pc&255], cfontptr->space_faktor); */
  292.       }
  293.       else {
  294.         h  += cfontptr->ctfmw[(int)pc&255];
  295.       }
  296.       hh += cd->pixelwidth;
  297.       setmotion();     /* Immer wenn was geaendert wird, wird auch setmotion() gemacht! */
  298.     }
  299. #if 0
  300.     setmotion();     /* seltsam, warum wird das immer gemacht? */
  301. #endif
  302.  
  303.   /* Antwort: Wird nicht immer gemacht, sondern nur nach einer Bewegung,
  304.    * deshalb sollte der Aufruf von setmotion eigentlich in's if.
  305.    * Wird nach jeder Aenderung von h gemacht, damit hh nicht mehr als
  306.    * maxdrift von PixRound(h) abweicht. (br)
  307.    */
  308.  
  309. }
  310.  
  311. #endif // !USE_ASM_SETCHAR || !DISPLAY
  312.  
  313.  
  314.  
  315. /*-->SetRule*/
  316. /**********************************************************************/
  317. /*****************************  SetRule  ******************************/
  318. /**********************************************************************/
  319.  
  320. void SetRule(long y, long x, BOOLEAN Set)    /* this routine will draw a rule */
  321. {
  322. #ifndef WEGDISPLAY
  323.   unsigned short    *start_adr, *adr;
  324.   unsigned short    start_mask, end_mask;
  325.   long            l, c;
  326.   long            length_row;
  327.   long            words;
  328. #endif
  329.   long            lmin, lmax;
  330.  
  331.   long            cp_x, cp_y;        /* upper left corner (pixels)           */
  332.   long            cp_h, cp_w;        /* height / width of character (pixels) */
  333.  
  334.   long rxx, ryy;
  335.  
  336.  
  337.     /* Hoehe und Breite immer aufrunden */
  338.     rxx = (x + (hconv - 1)) / hconv;
  339.     ryy = (y + (vconv - 1)) / vconv;
  340.  
  341.  
  342. #ifdef DISPLAY
  343.     if (InSearchMode) goto shift;
  344. #endif
  345.  
  346.  
  347.     if (x > 0 && y > 0) {
  348.  
  349.  
  350. #ifdef OLD_NO_OFFSET_VARS
  351.  
  352. #ifdef DISPLAY
  353.        cp_x = hh + hoffset;
  354.        cp_y = vv + voffset;
  355. #else
  356.        if (landscape) {
  357.          // wird spaeter noch gedreht, also jetzt etwas seltsame Offsets
  358.          cp_x = hh + hconvresolution;    // plus 1 inch
  359.          cp_y = vv + hoffset; 
  360.        }
  361.        else {
  362.          cp_x = hh + hoffset;
  363.          cp_y = vv + voffset;
  364.        }
  365.  
  366.        if (twopage && !leftpage) cp_x += paper_width + moffset - hoffset;
  367. #endif
  368.  
  369. #else
  370.  
  371.        cp_x = hh + OffsetBitmap_X;
  372.        cp_y = vv + OffsetBitmap_Y;
  373.  
  374. #endif
  375.  
  376.  
  377.        cp_w = rxx;
  378.        cp_h = ryy;
  379.  
  380.        /* mache linken unteren zum linken oberen ... */
  381.        cp_y -= (cp_h - 1);
  382.  
  383.       /*---- Schneide Rule links und rechts an den Seitengrenzen ab ----*/
  384.       if( cp_x < 0L ) {
  385.     cp_w += cp_x;    cp_x = 0L;
  386.       }
  387.       if( cp_x + cp_w >= map.width )    /* oder ist -1 notwendig ? */
  388.          cp_w = map.width - cp_x;
  389.  
  390.       if( cp_w <= 0L )    /* Rule liegt nicht mehr auf der Seite */
  391.     goto shift;
  392.  
  393.       /*---- Schneide Rule oben und unten an den Seitengrenzen ab ----*/
  394.       if( cp_y < upper_limit ) {
  395.     cp_h = cp_h - (upper_limit - cp_y);
  396.     cp_y = upper_limit;
  397.       }
  398.       if( cp_y + cp_h >= lower_limit )    /* oder ist -1 notwendig ? */
  399.     cp_h = lower_limit - cp_y;
  400.  
  401.       if( cp_h <= 0L )    /* Rule liegt nicht mehr auf der Seite */
  402.     goto shift;
  403.  
  404.  
  405.        lmin = 0; lmax = cp_h;
  406.  
  407. #if 0
  408.        if (cp_x+cp_w < 0L || cp_x >= map.width-1) {
  409.          goto shift;
  410.        }
  411.        if (cp_x+cp_w >= map.width) {    /* Abfrage, dass die Linie nicht rechts raus geht */
  412.          cp_w = map.width - cp_x - 1;
  413.        }
  414.  
  415.        if (cp_y >= lower_limit || cp_y+cp_h < upper_limit) {
  416.          goto shift;
  417.        }
  418.        if (cp_y+cp_h >= lower_limit) {
  419.          lmax = lower_limit - cp_y - 1;
  420.        }
  421.        if (cp_y - upper_limit < 0) {
  422.          lmin = upper_limit - cp_y;
  423.        }
  424. #endif
  425.  
  426. #ifdef WEGDISPLAY
  427.        RectFill(&myRastPort, cp_x, cp_y+lmin, cp_x+cp_w-1, cp_y+lmax-1);
  428. #else
  429.  
  430.   length_row = map.width >> 4;        /* Laenge einer Zeile in Woerter */
  431.   start_adr = ((unsigned short *)map.pixptr) + ((cp_y - upper_limit + lmin) * length_row)
  432.                     + (cp_x >> 4);
  433.   start_mask = (1 << (16-(cp_x & 15)))-1;
  434.   end_mask   = ~((1 << (16-((cp_x+cp_w) & 15)))-1);
  435.  
  436.   adr = start_adr;
  437.   c = (cp_x & 15) + cp_w;    /* Hilfe fuer unten */
  438.  
  439.   if (c < 16 ) {
  440.     start_mask &= end_mask;
  441.     for (l=lmin; l<lmax; l++) {
  442.       *adr |= start_mask;
  443.       adr += length_row;
  444.     }
  445.   }
  446.   else {
  447.     if (c < 32) {
  448.       length_row--;
  449.       for (l=lmin; l<lmax; l++) {
  450.         *adr |= start_mask;
  451.     adr++;
  452.     *adr |= end_mask;
  453.         adr += length_row;
  454.       }
  455.     }
  456.     else {
  457.       words = (cp_w + 15 - (16-(cp_x&15)) - ((cp_x+cp_w)&15) ) >> 4;
  458.     /* Anzahl der Woerter */
  459.       for (l=lmin; l<lmax; l++) {
  460.         *adr |= start_mask;
  461.     adr++;
  462.     for (c=0; c<words; c++) {
  463.       *adr = 0xFFFF;
  464.       adr++;
  465.     }
  466.     *adr |= end_mask;
  467.         start_adr += length_row;
  468.         adr = start_adr;
  469.       }
  470.     }
  471.   }
  472. #endif        /* WEGDISPLAY */
  473.      }
  474.  
  475. shift:
  476.     if (Set) {
  477.       h  += x;
  478.       hh += rxx ;
  479.       setmotion();    /* muss nach jeder Aenderung gemacht werden! */
  480.     }
  481. }
  482.  
  483.  
  484. #endif        /* SLOW */
  485.