textmap.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:8k
- /* textmap.c - by David Blythe, SGI */
- /* Helper routines used by textext.c for texture mapped fonts. */
- #include <stdio.h>
- #include <stdlib.h>
- #include <GL/glut.h>
- #include "textmap.h"
- #include "texture.h"
- /* byte swap a 32-bit value */
- #define SWAPL(x, n) {
- n = ((char *) (x))[0];
- ((char *) (x))[0] = ((char *) (x))[3];
- ((char *) (x))[3] = n;
- n = ((char *) (x))[1];
- ((char *) (x))[1] = ((char *) (x))[2];
- ((char *) (x))[2] = n; }
- /* byte swap a short */
- #define SWAPS(x, n) {
- n = ((char *) (x))[0];
- ((char *) (x))[0] = ((char *) (x))[1];
- ((char *) (x))[1] = n; }
- static texfnt *curtfnt;
- static unsigned char *fb;
- static unsigned char *gptr;
- /* get metric data into image */
- static void
- initget(void)
- {
- gptr = fb;
- }
- static void
- getbytes(void *pbuf, int n)
- {
- char *buf = pbuf;
- while (n--) {
- *buf++ = *gptr++;
- }
- }
- static void
- fixrow(unsigned short *sptr, int n)
- {
- while (n--) {
- /* *sptr = *sptr + (0xff<<8); */
- /* *sptr = (*sptr<<8) | 0xff; */
- sptr++;
- }
- }
- int
- doSwap(void)
- {
- int i = 0xffff0000;
- char *cptr = (char*) &i;
- if (cptr[0] == 0) {
- return 1; /* little endian (x86, alpha) */
- } else {
- return 0; /* big endian (SGI, 68000, VAX, SPARC) */
- }
- }
- texfnt *
- readtexfont(char *name)
- {
- texfnt *tfnt;
- unsigned *image;
- unsigned char *cptr;
- unsigned short *sbuf, *sptr;
- short advancecell, xadvance;
- short llx, lly, urx, ury, ox, oy;
- int i, y, extralines;
- texchardesc *cd;
- int xsize, ysize, components;
- int swap = doSwap();
- int tmp;
- tfnt = (texfnt *) malloc(sizeof(texfnt));
- image = read_texture(name, &xsize, &ysize, &components);
- if (!image) {
- fprintf(stderr, "textmap: can't open font image %sn", name);
- return 0;
- }
- extralines = ysize - xsize;
- if (extralines < 1) {
- fprintf(stderr, "textmap: bad input font!!n");
- return 0;
- }
- fb = (unsigned char *) malloc(xsize * extralines);
- sbuf = (unsigned short *) malloc(xsize * sizeof(short));
- cptr = fb;
- for (y = xsize; y < ysize; y++) {
- int x;
- for (x = 0; x < xsize; x++)
- cptr[x] = image[y * xsize + x] >> 16;
- cptr += xsize;
- }
- initget();
- tfnt->rasxsize = xsize;
- tfnt->rasysize = xsize;
- getbytes(&tfnt->charmin, sizeof(short));
- getbytes(&tfnt->charmax, sizeof(short));
- getbytes(&tfnt->pixhigh, sizeof(float));
- getbytes(&advancecell, sizeof(short));
- if (swap) {
- SWAPS(&tfnt->charmin, tmp);
- SWAPS(&tfnt->charmax, tmp);
- SWAPL(&tfnt->pixhigh, tmp);
- SWAPS(&advancecell, tmp);
- }
- tfnt->nchars = tfnt->charmax - tfnt->charmin + 1;
- tfnt->chars = (texchardesc *) malloc(tfnt->nchars * sizeof(texchardesc));
- tfnt->rasdata = (unsigned short *) malloc(tfnt->rasxsize * tfnt->rasysize * sizeof(long));
- sptr = tfnt->rasdata;
- for (y = 0; y < tfnt->rasysize; y++) {
- int x;
- for (x = 0; x < xsize; x++)
- sptr[x] = image[y * xsize + x] >> 16;
- fixrow(sptr, tfnt->rasxsize);
- sptr += tfnt->rasxsize;
- }
- cd = tfnt->chars;
- for (i = 0; i < tfnt->nchars; i++) {
- getbytes(&xadvance, sizeof(short));
- getbytes(&llx, sizeof(short));
- getbytes(&lly, sizeof(short));
- getbytes(&urx, sizeof(short));
- getbytes(&ury, sizeof(short));
- getbytes(&ox, sizeof(short));
- getbytes(&oy, sizeof(short));
- if (swap) {
- SWAPS(&xadvance, tmp);
- SWAPS(&llx, tmp);
- SWAPS(&lly, tmp);
- SWAPS(&urx, tmp);
- SWAPS(&ury, tmp);
- SWAPS(&ox, tmp);
- SWAPS(&oy, tmp);
- }
- cd->movex = xadvance / (float) advancecell;
- if (llx >= 0) {
- cd->haveimage = 1;
- cd->llx = (llx - ox) / tfnt->pixhigh;
- cd->lly = (lly - oy) / tfnt->pixhigh;
- cd->urx = (urx - ox + 1) / tfnt->pixhigh;
- cd->ury = (ury - oy + 1) / tfnt->pixhigh;
- cd->tllx = llx / (float) tfnt->rasxsize;
- cd->tlly = lly / (float) tfnt->rasysize;
- cd->turx = (urx + 1) / (float) tfnt->rasxsize;
- cd->tury = (ury + 1) / (float) tfnt->rasysize;
- cd->data[0] = cd->tllx;
- cd->data[1] = cd->tlly;
- cd->data[2] = cd->llx;
- cd->data[3] = cd->lly;
- cd->data[4] = cd->turx;
- cd->data[5] = cd->tlly;
- cd->data[6] = cd->urx;
- cd->data[7] = cd->lly;
- cd->data[8] = cd->turx;
- cd->data[9] = cd->tury;
- cd->data[10] = cd->urx;
- cd->data[11] = cd->ury;
- cd->data[12] = cd->tllx;
- cd->data[13] = cd->tury;
- cd->data[14] = cd->llx;
- cd->data[15] = cd->ury;
- cd->data[16] = cd->llx;
- cd->data[17] = cd->lly;
- cd->data[18] = cd->urx;
- cd->data[19] = cd->lly;
- cd->data[20] = cd->urx;
- cd->data[21] = cd->ury;
- cd->data[22] = cd->llx;
- cd->data[23] = cd->ury;
- } else {
- cd->haveimage = 0;
- }
- cd++;
- }
- free(fb);
- free(sbuf);
- free(image);
- return tfnt;
- }
- void
- texfont(texfnt * tfnt)
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, 2, tfnt->rasxsize, tfnt->rasysize, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tfnt->rasdata);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- curtfnt = tfnt;
- }
- float
- texstrwidth(char *str)
- {
- unsigned int c;
- unsigned int charmin, tnchars;
- texfnt *tfnt;
- texchardesc *cdbase, *cd;
- float xpos;
- tfnt = curtfnt;
- if (!tfnt) {
- fprintf(stderr, "texstrwidth: no texfont set!!n");
- return 0;
- }
- charmin = tfnt->charmin;
- tnchars = tfnt->nchars;
- cdbase = tfnt->chars;
- xpos = 0.0;
- while (*str) {
- c = *str - charmin;
- if (c < tnchars) {
- cd = cdbase + c;
- xpos += cd->movex;
- }
- str++;
- }
- return xpos;
- }
- void
- texcharstr(char *str)
- {
- unsigned int c;
- unsigned int charmin, tnchars;
- texfnt *tfnt;
- texchardesc *cdbase, *cd;
- float *fdata, xpos;
- tfnt = curtfnt;
- if (!tfnt) {
- fprintf(stderr, "texcharstr: no texfont set!!n");
- return;
- }
- charmin = tfnt->charmin;
- tnchars = tfnt->nchars;
- cdbase = tfnt->chars;
- xpos = 0.0;
- #if 0
- texbind(TX_TEXTURE_0, LETTER_INDEX); /* bind letter texture */
- tevbind(TV_ENV0, LETTER_INDEX);
- #endif
- while (*str) {
- c = *str - charmin;
- if (c < tnchars) {
- cd = cdbase + c;
- if (cd->haveimage) {
- fdata = cd->data;
- fdata[16] = fdata[2] + xpos;
- fdata[18] = fdata[6] + xpos;
- fdata[20] = fdata[10] + xpos;
- fdata[22] = fdata[14] + xpos;
- glBegin(GL_POLYGON);
- glTexCoord2fv(&fdata[0]);
- glVertex2fv(&fdata[16]);
- glTexCoord2fv(&fdata[4]);
- glVertex2fv(&fdata[18]);
- glTexCoord2fv(&fdata[8]);
- glVertex2fv(&fdata[20]);
- glTexCoord2fv(&fdata[12]);
- glVertex2fv(&fdata[22]);
- glEnd();
- }
- xpos += cd->movex;
- }
- str++;
- }
- }
- int
- texfntinit(char *file)
- {
- static int once = 0;
- static texfnt *tfnt;
- if (!once) {
- tfnt = readtexfont(file);
- if (!tfnt) {
- fprintf(stderr, "texfntinit: can't open input font %sn", file);
- return -1;
- }
- texfont(tfnt);
- once = 1;
- }
- return 0;
- }
- float
- texfntwidth(char *str)
- {
- return texstrwidth(str) * 12.5 / 6.;
- }
- void
- texfntstroke(char *s, float xoffset, float yoffset)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushMatrix();
- glTranslatef(xoffset, yoffset, 0.0);
- glScalef(12.5, 12.5, 12.5);
- texcharstr(s);
- glPopMatrix();
- glDisable(GL_BLEND);
- }