📄 text.cpp
字号:
/** * This code was originally written by Mark Kilgard (mjk@nvidia.com) (c) 1997 * see: http://www.opengl.org/developers/code/mjktips/TexFont/TexFont.html *//*************************************************************************** text.cpp - description ------------------- begin : Mon Jul 7 2003 copyright : (C) 2003 by Gabor Torok email : cctorok@yahoo.com ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <assert.h>#include <ctype.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "text.h"TexturedText::TexturedText() { useLuminanceAlpha = 0; strcpy(filename, rootDir); strcat(filename, "/fonts/default.txf"); txf = txfLoadFont(filename); if(txf == NULL) { fprintf(stderr, "Problem loading %s\n", filename); exit(1); } }TexturedText::~TexturedText() {}TexFont *TexturedText::txfLoadFont(char *filename) { TexFont *txf; FILE *file; GLfloat w, h, xstep, ystep; char fileid[4], tmp; unsigned char *texbitmap; int min_glyph, max_glyph; int endianness, swap, format, stride, width, height; int i, j, got; txf = NULL; file = fopen(filename, "rb"); if (file == NULL) { lastError = "file open failed."; goto error; } txf = (TexFont *) malloc(sizeof(TexFont)); if (txf == NULL) { lastError = "out of memory."; goto error; } /* For easy cleanup in error case. */ txf->tgi = NULL; txf->tgvi = NULL; txf->lut = NULL; txf->teximage = NULL; got = fread(fileid, 1, 4, file); if (got != 4 || strncmp(fileid, "\377txf", 4)) { lastError = "not a texture font file."; goto error; } assert(sizeof(int) == 4); /* Ensure external file format size. */ got = fread(&endianness, sizeof(int), 1, file); if (got == 1 && endianness == 0x12345678) { swap = 0; } else if (got == 1 && endianness == 0x78563412) { swap = 1; } else { lastError = "not a texture font file."; goto error; }#define EXPECT(n) if (got != n) { lastError = "premature end of file."; goto error; } got = fread(&format, sizeof(int), 1, file); EXPECT(1); got = fread(&txf->tex_width, sizeof(int), 1, file); EXPECT(1); got = fread(&txf->tex_height, sizeof(int), 1, file); EXPECT(1); got = fread(&txf->max_ascent, sizeof(int), 1, file); EXPECT(1); got = fread(&txf->max_descent, sizeof(int), 1, file); EXPECT(1); got = fread(&txf->num_glyphs, sizeof(int), 1, file); EXPECT(1); if (swap) { SWAPL(&format, tmp); SWAPL(&txf->tex_width, tmp); SWAPL(&txf->tex_height, tmp); SWAPL(&txf->max_ascent, tmp); SWAPL(&txf->max_descent, tmp); SWAPL(&txf->num_glyphs, tmp); } txf->tgi = (TexGlyphInfo *) malloc(txf->num_glyphs * sizeof(TexGlyphInfo)); if (txf->tgi == NULL) { lastError = "out of memory."; goto error; } assert(sizeof(TexGlyphInfo) == 12); /* Ensure external file format size. */ got = fread(txf->tgi, sizeof(TexGlyphInfo), txf->num_glyphs, file); EXPECT(txf->num_glyphs); if (swap) { for (i = 0; i < txf->num_glyphs; i++) { SWAPS(&txf->tgi[i].c, tmp); SWAPS(&txf->tgi[i].x, tmp); SWAPS(&txf->tgi[i].y, tmp); } } txf->tgvi = (TexGlyphVertexInfo *) malloc(txf->num_glyphs * sizeof(TexGlyphVertexInfo)); if (txf->tgvi == NULL) { lastError = "out of memory."; goto error; } w = txf->tex_width; h = txf->tex_height; xstep = 0.5 / w; ystep = 0.5 / h; for (i = 0; i < txf->num_glyphs; i++) { TexGlyphInfo *tgi; tgi = &txf->tgi[i]; txf->tgvi[i].t0[0] = tgi->x / w + xstep; txf->tgvi[i].t0[1] = tgi->y / h + ystep; txf->tgvi[i].v0[0] = tgi->xoffset; txf->tgvi[i].v0[1] = tgi->yoffset; txf->tgvi[i].t1[0] = (tgi->x + tgi->width) / w + xstep; txf->tgvi[i].t1[1] = tgi->y / h + ystep; txf->tgvi[i].v1[0] = tgi->xoffset + tgi->width; txf->tgvi[i].v1[1] = tgi->yoffset; txf->tgvi[i].t2[0] = (tgi->x + tgi->width) / w + xstep; txf->tgvi[i].t2[1] = (tgi->y + tgi->height) / h + ystep; txf->tgvi[i].v2[0] = tgi->xoffset + tgi->width; txf->tgvi[i].v2[1] = tgi->yoffset + tgi->height; txf->tgvi[i].t3[0] = tgi->x / w + xstep; txf->tgvi[i].t3[1] = (tgi->y + tgi->height) / h + ystep; txf->tgvi[i].v3[0] = tgi->xoffset; txf->tgvi[i].v3[1] = tgi->yoffset + tgi->height; txf->tgvi[i].advance = tgi->advance; } min_glyph = txf->tgi[0].c; max_glyph = txf->tgi[0].c; for (i = 1; i < txf->num_glyphs; i++) { if (txf->tgi[i].c < min_glyph) { min_glyph = txf->tgi[i].c; } if (txf->tgi[i].c > max_glyph) { max_glyph = txf->tgi[i].c; } } txf->min_glyph = min_glyph; txf->range = max_glyph - min_glyph + 1; txf->lut = (TexGlyphVertexInfo **) calloc(txf->range, sizeof(TexGlyphVertexInfo *)); if (txf->lut == NULL) { lastError = "out of memory."; goto error; } for (i = 0; i < txf->num_glyphs; i++) { txf->lut[txf->tgi[i].c - txf->min_glyph] = &txf->tgvi[i]; } switch (format) { case TXF_FORMAT_BYTE: if (useLuminanceAlpha) { unsigned char *orig; orig = (unsigned char *) malloc(txf->tex_width * txf->tex_height); if (orig == NULL) { lastError = "out of memory."; goto error; } got = fread(orig, 1, txf->tex_width * txf->tex_height, file); EXPECT(txf->tex_width * txf->tex_height); txf->teximage = (unsigned char *) malloc(2 * txf->tex_width * txf->tex_height); if (txf->teximage == NULL) { lastError = "out of memory."; goto error; } for (i = 0; i < txf->tex_width * txf->tex_height; i++) { txf->teximage[i * 2] = orig[i]; txf->teximage[i * 2 + 1] = orig[i]; } free(orig); } else { txf->teximage = (unsigned char *) malloc(txf->tex_width * txf->tex_height); if (txf->teximage == NULL) { lastError = "out of memory."; goto error; } got = fread(txf->teximage, 1, txf->tex_width * txf->tex_height, file); EXPECT(txf->tex_width * txf->tex_height); } break; case TXF_FORMAT_BITMAP: width = txf->tex_width; height = txf->tex_height; stride = (width + 7) >> 3; texbitmap = (unsigned char *) malloc(stride * height); if (texbitmap == NULL) { lastError = "out of memory."; goto error; } got = fread(texbitmap, 1, stride * height, file); EXPECT(stride * height); if (useLuminanceAlpha) { txf->teximage = (unsigned char *) calloc(width * height * 2, 1); if (txf->teximage == NULL) { lastError = "out of memory."; goto error; } for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7))) { txf->teximage[(i * width + j) * 2] = 255; txf->teximage[(i * width + j) * 2 + 1] = 255; } } } } else { txf->teximage = (unsigned char *) calloc(width * height, 1); if (txf->teximage == NULL) { lastError = "out of memory."; goto error; } for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7))) { txf->teximage[i * width + j] = 255; } } } } free(texbitmap); break; } fclose(file); return txf;error: if (txf) { if (txf->tgi) free(txf->tgi); if (txf->tgvi) free(txf->tgvi); if (txf->lut) free(txf->lut); if (txf->teximage) free(txf->teximage); free(txf); } if (file) fclose(file); return NULL;}GLuint TexturedText::txfEstablishTexture(GLuint texobj, GLboolean setupMipmaps) { if (txf->texobj == 0) { if (texobj == 0) {#if !defined(USE_DISPLAY_LISTS) glGenTextures(1, &txf->texobj);#else txf->texobj = glGenLists(1);#endif } else { txf->texobj = texobj; } }#if !defined(USE_DISPLAY_LISTS) glBindTexture(GL_TEXTURE_2D, txf->texobj);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -