textmap.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:8k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* textmap.c - by David Blythe, SGI */
  2. /* Helper routines used by textext.c for texture mapped fonts. */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <GL/glut.h>
  6. #include "textmap.h"
  7. #include "texture.h"
  8. /* byte swap a 32-bit value */
  9. #define SWAPL(x, n) { 
  10.                  n = ((char *) (x))[0];
  11.                  ((char *) (x))[0] = ((char *) (x))[3];
  12.                  ((char *) (x))[3] = n;
  13.                  n = ((char *) (x))[1];
  14.                  ((char *) (x))[1] = ((char *) (x))[2];
  15.                  ((char *) (x))[2] = n; }
  16. /* byte swap a short */
  17. #define SWAPS(x, n) { 
  18.                  n = ((char *) (x))[0];
  19.                  ((char *) (x))[0] = ((char *) (x))[1];
  20.                  ((char *) (x))[1] = n; }
  21. static texfnt *curtfnt;
  22. static unsigned char *fb;
  23. static unsigned char *gptr;
  24. /* get metric data into image */
  25. static void
  26. initget(void)
  27. {
  28.   gptr = fb;
  29. }
  30. static void
  31. getbytes(void *pbuf, int n)
  32. {
  33.   char *buf = pbuf;
  34.   while (n--) {
  35.     *buf++ = *gptr++;
  36.   }
  37. }
  38. static void
  39. fixrow(unsigned short *sptr, int n)
  40. {
  41.   while (n--) {
  42.     /* *sptr = *sptr + (0xff<<8); */
  43.     /* *sptr = (*sptr<<8) | 0xff; */
  44.     sptr++;
  45.   }
  46. }
  47. int
  48. doSwap(void)
  49. {
  50.   int i = 0xffff0000;
  51.   char *cptr = (char*) &i;
  52.   if (cptr[0] == 0) {
  53.     return 1;  /* little endian (x86, alpha) */
  54.   } else {
  55.     return 0;  /* big endian (SGI, 68000, VAX, SPARC) */
  56.   }
  57. }
  58. texfnt *
  59. readtexfont(char *name)
  60. {
  61.   texfnt *tfnt;
  62.   unsigned *image;
  63.   unsigned char *cptr;
  64.   unsigned short *sbuf, *sptr;
  65.   short advancecell, xadvance;
  66.   short llx, lly, urx, ury, ox, oy;
  67.   int i, y, extralines;
  68.   texchardesc *cd;
  69.   int xsize, ysize, components;
  70.   int swap = doSwap();
  71.   int tmp;
  72.   tfnt = (texfnt *) malloc(sizeof(texfnt));
  73.   image = read_texture(name, &xsize, &ysize, &components);
  74.   if (!image) {
  75.     fprintf(stderr, "textmap: can't open font image %sn", name);
  76.     return 0;
  77.   }
  78.   extralines = ysize - xsize;
  79.   if (extralines < 1) {
  80.     fprintf(stderr, "textmap: bad input font!!n");
  81.     return 0;
  82.   }
  83.   fb = (unsigned char *) malloc(xsize * extralines);
  84.   sbuf = (unsigned short *) malloc(xsize * sizeof(short));
  85.   cptr = fb;
  86.   for (y = xsize; y < ysize; y++) {
  87.     int x;
  88.     for (x = 0; x < xsize; x++)
  89.       cptr[x] = image[y * xsize + x] >> 16;
  90.     cptr += xsize;
  91.   }
  92.   initget();
  93.   tfnt->rasxsize = xsize;
  94.   tfnt->rasysize = xsize;
  95.   getbytes(&tfnt->charmin, sizeof(short));
  96.   getbytes(&tfnt->charmax, sizeof(short));
  97.   getbytes(&tfnt->pixhigh, sizeof(float));
  98.   getbytes(&advancecell, sizeof(short));
  99.   if (swap) {
  100.     SWAPS(&tfnt->charmin, tmp);
  101.     SWAPS(&tfnt->charmax, tmp);
  102.     SWAPL(&tfnt->pixhigh, tmp);
  103.     SWAPS(&advancecell, tmp);
  104.   }
  105.   tfnt->nchars = tfnt->charmax - tfnt->charmin + 1;
  106.   tfnt->chars = (texchardesc *) malloc(tfnt->nchars * sizeof(texchardesc));
  107.   tfnt->rasdata = (unsigned short *) malloc(tfnt->rasxsize * tfnt->rasysize * sizeof(long));
  108.   sptr = tfnt->rasdata;
  109.   for (y = 0; y < tfnt->rasysize; y++) {
  110.     int x;
  111.     for (x = 0; x < xsize; x++)
  112.       sptr[x] = image[y * xsize + x] >> 16;
  113.     fixrow(sptr, tfnt->rasxsize);
  114.     sptr += tfnt->rasxsize;
  115.   }
  116.   cd = tfnt->chars;
  117.   for (i = 0; i < tfnt->nchars; i++) {
  118.     getbytes(&xadvance, sizeof(short));
  119.     getbytes(&llx, sizeof(short));
  120.     getbytes(&lly, sizeof(short));
  121.     getbytes(&urx, sizeof(short));
  122.     getbytes(&ury, sizeof(short));
  123.     getbytes(&ox, sizeof(short));
  124.     getbytes(&oy, sizeof(short));
  125.     if (swap) {
  126.       SWAPS(&xadvance, tmp);
  127.       SWAPS(&llx, tmp);
  128.       SWAPS(&lly, tmp);
  129.       SWAPS(&urx, tmp);
  130.       SWAPS(&ury, tmp);
  131.       SWAPS(&ox, tmp);
  132.       SWAPS(&oy, tmp);
  133.     }
  134.     cd->movex = xadvance / (float) advancecell;
  135.     if (llx >= 0) {
  136.       cd->haveimage = 1;
  137.       cd->llx = (llx - ox) / tfnt->pixhigh;
  138.       cd->lly = (lly - oy) / tfnt->pixhigh;
  139.       cd->urx = (urx - ox + 1) / tfnt->pixhigh;
  140.       cd->ury = (ury - oy + 1) / tfnt->pixhigh;
  141.       cd->tllx = llx / (float) tfnt->rasxsize;
  142.       cd->tlly = lly / (float) tfnt->rasysize;
  143.       cd->turx = (urx + 1) / (float) tfnt->rasxsize;
  144.       cd->tury = (ury + 1) / (float) tfnt->rasysize;
  145.       cd->data[0] = cd->tllx;
  146.       cd->data[1] = cd->tlly;
  147.       cd->data[2] = cd->llx;
  148.       cd->data[3] = cd->lly;
  149.       cd->data[4] = cd->turx;
  150.       cd->data[5] = cd->tlly;
  151.       cd->data[6] = cd->urx;
  152.       cd->data[7] = cd->lly;
  153.       cd->data[8] = cd->turx;
  154.       cd->data[9] = cd->tury;
  155.       cd->data[10] = cd->urx;
  156.       cd->data[11] = cd->ury;
  157.       cd->data[12] = cd->tllx;
  158.       cd->data[13] = cd->tury;
  159.       cd->data[14] = cd->llx;
  160.       cd->data[15] = cd->ury;
  161.       cd->data[16] = cd->llx;
  162.       cd->data[17] = cd->lly;
  163.       cd->data[18] = cd->urx;
  164.       cd->data[19] = cd->lly;
  165.       cd->data[20] = cd->urx;
  166.       cd->data[21] = cd->ury;
  167.       cd->data[22] = cd->llx;
  168.       cd->data[23] = cd->ury;
  169.     } else {
  170.       cd->haveimage = 0;
  171.     }
  172.     cd++;
  173.   }
  174.   free(fb);
  175.   free(sbuf);
  176.   free(image);
  177.   return tfnt;
  178. }
  179. void
  180. texfont(texfnt * tfnt)
  181. {
  182.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  183.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  184.   glTexImage2D(GL_TEXTURE_2D, 0, 2, tfnt->rasxsize, tfnt->rasysize, 0,
  185.     GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tfnt->rasdata);
  186.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  187.   curtfnt = tfnt;
  188. }
  189. float
  190. texstrwidth(char *str)
  191. {
  192.   unsigned int c;
  193.   unsigned int charmin, tnchars;
  194.   texfnt *tfnt;
  195.   texchardesc *cdbase, *cd;
  196.   float xpos;
  197.   tfnt = curtfnt;
  198.   if (!tfnt) {
  199.     fprintf(stderr, "texstrwidth: no texfont set!!n");
  200.     return 0;
  201.   }
  202.   charmin = tfnt->charmin;
  203.   tnchars = tfnt->nchars;
  204.   cdbase = tfnt->chars;
  205.   xpos = 0.0;
  206.   while (*str) {
  207.     c = *str - charmin;
  208.     if (c < tnchars) {
  209.       cd = cdbase + c;
  210.       xpos += cd->movex;
  211.     }
  212.     str++;
  213.   }
  214.   return xpos;
  215. }
  216. void
  217. texcharstr(char *str)
  218. {
  219.   unsigned int c;
  220.   unsigned int charmin, tnchars;
  221.   texfnt *tfnt;
  222.   texchardesc *cdbase, *cd;
  223.   float *fdata, xpos;
  224.   tfnt = curtfnt;
  225.   if (!tfnt) {
  226.     fprintf(stderr, "texcharstr: no texfont set!!n");
  227.     return;
  228.   }
  229.   charmin = tfnt->charmin;
  230.   tnchars = tfnt->nchars;
  231.   cdbase = tfnt->chars;
  232.   xpos = 0.0;
  233. #if 0
  234.   texbind(TX_TEXTURE_0, LETTER_INDEX);  /* bind letter texture */
  235.   tevbind(TV_ENV0, LETTER_INDEX);
  236. #endif
  237.   while (*str) {
  238.     c = *str - charmin;
  239.     if (c < tnchars) {
  240.       cd = cdbase + c;
  241.       if (cd->haveimage) {
  242.         fdata = cd->data;
  243.         fdata[16] = fdata[2] + xpos;
  244.         fdata[18] = fdata[6] + xpos;
  245.         fdata[20] = fdata[10] + xpos;
  246.         fdata[22] = fdata[14] + xpos;
  247.         glBegin(GL_POLYGON);
  248.         glTexCoord2fv(&fdata[0]);
  249.         glVertex2fv(&fdata[16]);
  250.         glTexCoord2fv(&fdata[4]);
  251.         glVertex2fv(&fdata[18]);
  252.         glTexCoord2fv(&fdata[8]);
  253.         glVertex2fv(&fdata[20]);
  254.         glTexCoord2fv(&fdata[12]);
  255.         glVertex2fv(&fdata[22]);
  256.         glEnd();
  257.       }
  258.       xpos += cd->movex;
  259.     }
  260.     str++;
  261.   }
  262. }
  263. int
  264. texfntinit(char *file)
  265. {
  266.   static int once = 0;
  267.   static texfnt *tfnt;
  268.   if (!once) {
  269.     tfnt = readtexfont(file);
  270.     if (!tfnt) {
  271.       fprintf(stderr, "texfntinit: can't open input font %sn", file);
  272.       return -1;
  273.     }
  274.     texfont(tfnt);
  275.     once = 1;
  276.   }
  277.   return 0;
  278. }
  279. float
  280. texfntwidth(char *str)
  281. {
  282.   return texstrwidth(str) * 12.5 / 6.;
  283. }
  284. void
  285. texfntstroke(char *s, float xoffset, float yoffset)
  286. {
  287.   glEnable(GL_BLEND);
  288.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  289.   glPushMatrix();
  290.   glTranslatef(xoffset, yoffset, 0.0);
  291.   glScalef(12.5, 12.5, 12.5);
  292.   texcharstr(s);
  293.   glPopMatrix();
  294.   glDisable(GL_BLEND);
  295. }