home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / libtex / rotate.c < prev    next >
C/C++ Source or Header  |  1990-07-10  |  4KB  |  155 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/rotate.c,v 2.4 89/08/22 21:56:05 chris Exp $";
  10. #endif
  11.  
  12. /*
  13.  * Routines to generate rotated bitmaps given unrotated inputs.
  14.  *
  15.  * The rotated bitmap is indistinguishable from the unrotated one (aside
  16.  * from being rotated of course!).
  17.  */
  18.  
  19. #include "types.h"
  20. #include "error.h"
  21. #include "font.h"
  22.  
  23. static void RotateClockwise();
  24.  
  25. extern    int errno;
  26. char    *malloc();
  27.  
  28. /*
  29.  * Rounding, but by powers of two only.
  30.  */
  31. #define ROUND(n,r) (((n) + ((r) - 1)) & ~((r) - 1))
  32.  
  33. /*
  34.  * Set the rotation of glyph g to r.
  35.  */
  36. SetRotation(g, r)
  37.     register struct glyph *g;
  38.     int r;
  39. {
  40.  
  41.     if (r < ROT_NORM || r > ROT_RIGHT)
  42.         error(1, 0, "bad rotation value %d", r);
  43.  
  44.     /*
  45.      * The null glyph is trivial to rotate by any amount.
  46.      *
  47.      * Note that this assumes that any raster has been obtained
  48.      * BEFORE calling SetRotation()!
  49.      */
  50.     if (g->g_raster == NULL) {
  51.         g->g_rotation = r;
  52.         return;
  53.     }
  54.  
  55.     /*
  56.      * This is hardly efficient, but it *is* expedient....
  57.      */
  58.     while (g->g_rotation != r) {
  59.         RotateClockwise(g);
  60.         g->g_rotation = (g->g_rotation - 1) & 3;
  61.     }
  62. }
  63.  
  64. /*
  65.  * Rotation by 1/4 turn clockwise (from ROT_NORM to ROT_RIGHT, e.g.).
  66.  */
  67. static void
  68. RotateClockwise(glyph)
  69.     struct glyph *glyph;
  70. {
  71.     register char *nrast;    /* new raster */
  72.     register char *orast;    /* old raster */
  73.     register int oheight;    /* old raster height, new raster width */
  74.     register int owidth;    /* old raster width, new raster height */
  75.     unsigned int size;    /* size of new raster (in bytes) */
  76.     int nplus;        /* offset between rows in nrast */
  77.  
  78.     /*
  79.      * First, get a new raster.
  80.      */
  81.     {
  82.         register struct glyph *g = glyph;
  83.         register int t;
  84.  
  85.         oheight = g->g_height;
  86.         owidth = g->g_width;
  87.  
  88.         /*
  89.          * Offset is (new width) rounded to bytes.
  90.          */
  91.         nplus = ROUND(oheight, 8) >> 3;
  92.  
  93.         /*
  94.          * Size of new raster is (new height) * (new rounded width,
  95.          * in bytes).
  96.          */
  97.         size = nplus * owidth;
  98.         if ((nrast = malloc(size)) == NULL)
  99.             error(1, errno, "out of memory");
  100.         bzero(nrast, size);
  101.  
  102.         /*
  103.          * New y origin is old x origin; new x origin is old height
  104.          * minus old y origin - 1.
  105.          */
  106.         t = g->g_yorigin;
  107.         g->g_yorigin = g->g_xorigin;
  108.         g->g_xorigin = oheight - t - 1;
  109.  
  110.         /* While we are at it, exchange height & width... */
  111.         g->g_height = owidth;
  112.         g->g_width = oheight;
  113.  
  114.         /* and grab a pointer to the old raster. */
  115.         orast = g->g_raster;
  116.     }
  117.  
  118.     /*
  119.      * Now copy bits from the old raster to the new one.  The mapping
  120.      * function is
  121.      *
  122.      *    for i in [0..height)
  123.      *        for j in [0..width)
  124.      *            new[j, height-i-1] = old[i, j] 
  125.      *
  126.      * Thus i maps to height-i-1 and (since we have to do our own 2
  127.      * dimensional array indexing) j to nplus*j.  We call the mapped
  128.      * variables mapi and mapj, and, since we scan sequentially through
  129.      * the old raster, can discard the original i and j.
  130.      */
  131.     {
  132.         register int mapj, c, k, mapi;
  133.  
  134.         mapi = oheight;
  135.         owidth *= nplus;
  136.         while (--mapi >= 0) {
  137.             k = 7;
  138.             for (mapj = 0; mapj < owidth; mapj += nplus) {
  139.                 if (++k == 8)    /* get another byte */
  140.                     c = *orast++, k = 0;
  141.                 if (c & 0x80)    /* old[i,j] was set */
  142.                     nrast[mapj + (mapi >> 3)] |=
  143.                         1 << (7 - (mapi & 7));
  144.                 c <<= 1;
  145.             }
  146.         }
  147.     }
  148.  
  149.     /*
  150.      * Finally, free the storage associated with the original raster.
  151.      */
  152.     free(glyph->g_raster);
  153.     glyph->g_raster = nrast;
  154. }
  155.