summaryrefslogtreecommitdiff
path: root/Build/source/texk/seetexk/rotate.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/seetexk/rotate.c
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff)
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/seetexk/rotate.c')
-rw-r--r--Build/source/texk/seetexk/rotate.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/Build/source/texk/seetexk/rotate.c b/Build/source/texk/seetexk/rotate.c
new file mode 100644
index 00000000000..757a479f291
--- /dev/null
+++ b/Build/source/texk/seetexk/rotate.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1987, 1989 University of Maryland
+ * Department of Computer Science. All rights reserved.
+ * Permission to copy for any purpose is hereby granted
+ * so long as this copyright notice remains intact.
+ */
+
+#ifndef lint
+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 $";
+#endif
+
+/*
+ * Routines to generate rotated bitmaps given unrotated inputs.
+ *
+ * The rotated bitmap is indistinguishable from the unrotated one (aside
+ * from being rotated of course!).
+ */
+
+#include "types.h"
+#include "error.h"
+#include "font.h"
+
+static void RotateClockwise();
+
+#if !defined( WIN32 ) && !defined( _AMIGA )
+extern int errno;
+char *malloc();
+#endif
+
+/*
+ * Rounding, but by powers of two only.
+ */
+#define ROUND(n,r) (((n) + ((r) - 1)) & ~((r) - 1))
+
+/*
+ * Set the rotation of glyph g to r.
+ */
+void SetRotation(g, r)
+ register struct glyph *g;
+ int r;
+{
+
+ if (r < ROT_NORM || r > ROT_RIGHT)
+ error(1, 0, "bad rotation value %d", r);
+
+ /*
+ * The null glyph is trivial to rotate by any amount.
+ *
+ * Note that this assumes that any raster has been obtained
+ * BEFORE calling SetRotation()!
+ */
+ if (g->g_raster == NULL) {
+ g->g_rotation = r;
+ return;
+ }
+
+ /*
+ * This is hardly efficient, but it *is* expedient....
+ */
+ while (g->g_rotation != r) {
+ RotateClockwise(g);
+ g->g_rotation = (g->g_rotation - 1) & 3;
+ }
+}
+
+/*
+ * Rotation by 1/4 turn clockwise (from ROT_NORM to ROT_RIGHT, e.g.).
+ */
+static void
+RotateClockwise(glyph)
+ struct glyph *glyph;
+{
+ register char *nrast; /* new raster */
+ register char *orast; /* old raster */
+ register int oheight; /* old raster height, new raster width */
+ register int owidth; /* old raster width, new raster height */
+ unsigned int size; /* size of new raster (in bytes) */
+ int nplus; /* offset between rows in nrast */
+
+ /*
+ * First, get a new raster.
+ */
+ {
+ register struct glyph *g = glyph;
+ register int t;
+
+ oheight = g->g_height;
+ owidth = g->g_width;
+
+ /*
+ * Offset is (new width) rounded to bytes.
+ */
+ nplus = ROUND(oheight, 8) >> 3;
+
+ /*
+ * Size of new raster is (new height) * (new rounded width,
+ * in bytes).
+ */
+ size = nplus * owidth;
+ if ((nrast = malloc(size)) == NULL)
+ error(1, errno, "out of memory");
+ bzero(nrast, size);
+
+ /*
+ * New y origin is old x origin; new x origin is old height
+ * minus old y origin - 1.
+ */
+ t = g->g_yorigin;
+ g->g_yorigin = g->g_xorigin;
+ g->g_xorigin = oheight - t - 1;
+
+ /* While we are at it, exchange height & width... */
+ g->g_height = owidth;
+ g->g_width = oheight;
+
+ /* and grab a pointer to the old raster. */
+ orast = g->g_raster;
+ }
+
+ /*
+ * Now copy bits from the old raster to the new one. The mapping
+ * function is
+ *
+ * for i in [0..height)
+ * for j in [0..width)
+ * new[j, height-i-1] = old[i, j]
+ *
+ * Thus i maps to height-i-1 and (since we have to do our own 2
+ * dimensional array indexing) j to nplus*j. We call the mapped
+ * variables mapi and mapj, and, since we scan sequentially through
+ * the old raster, can discard the original i and j.
+ */
+ {
+ register int mapj, c, k, mapi;
+
+ mapi = oheight;
+ owidth *= nplus;
+ while (--mapi >= 0) {
+ k = 7;
+ for (mapj = 0; mapj < owidth; mapj += nplus) {
+ if (++k == 8) /* get another byte */
+ c = *orast++, k = 0;
+ if (c & 0x80) /* old[i,j] was set */
+ nrast[mapj + (mapi >> 3)] |=
+ 1 << (7 - (mapi & 7));
+ c <<= 1;
+ }
+ }
+ }
+
+ /*
+ * Finally, free the storage associated with the original raster.
+ */
+ free(glyph->g_raster);
+ glyph->g_raster = nrast;
+}