|
Blender
V2.59
|
00001 /* 00002 * bmfont.c 00003 * 00004 * 04-10-2000 frank 00005 * 00006 * $Id: bmfont.cpp 35170 2011-02-25 13:35:11Z jesterking $ 00007 * 00008 * ***** BEGIN GPL LICENSE BLOCK ***** 00009 * 00010 * This program is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU General Public License 00012 * as published by the Free Software Foundation; either version 2 00013 * of the License, or (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software Foundation, 00022 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00023 * 00024 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00025 * All rights reserved. 00026 * 00027 * The Original Code is: all of this file. 00028 * 00029 * Contributor(s): none yet. 00030 * 00031 * ***** END GPL LICENSE BLOCK ***** 00032 * 00033 */ 00034 00056 #include <stdio.h> 00057 00058 #include "MEM_guardedalloc.h" 00059 #include "BLI_blenlib.h" 00060 #include "BKE_global.h" 00061 #include "IMB_imbuf_types.h" 00062 00063 #include "BKE_bmfont.h" 00064 #include "BKE_bmfont_types.h" 00065 00066 /*MAART: 00067 void printfGlyph(bmGlyph * glyph) 00068 { 00069 printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode); 00070 printf(" locx: %4d locy: %4d\n", glyph->locx, glyph->locy); 00071 printf(" sizex: %3d sizey: %3d\n", glyph->sizex, glyph->sizey); 00072 printf(" ofsx: %3d ofsy: %3d\n", glyph->ofsx, glyph->ofsy); 00073 printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved); 00074 } 00075 */ 00076 00077 #define MAX2(x,y) ( (x)>(y) ? (x) : (y) ) 00078 #define MAX3(x,y,z) MAX2( MAX2((x),(y)) , (z) ) 00079 00080 void calcAlpha(ImBuf * ibuf) 00081 { 00082 int i; 00083 char * rect; 00084 00085 if (ibuf) { 00086 rect = (char *) ibuf->rect; 00087 for (i = ibuf->x * ibuf->y ; i > 0 ; i--) { 00088 rect[3] = MAX3(rect[0], rect[1], rect[2]); 00089 rect += 4; 00090 } 00091 } 00092 } 00093 00094 void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step) 00095 { 00096 int glyphcount, bytes, i, index, linelength, ysize; 00097 unsigned char * buffer; 00098 bmFont * bmfont; 00099 00100 linelength = ibuf->x * step; 00101 00102 glyphcount = (rect[6 * step] << 8) | rect[7 * step]; 00103 bytes = ((glyphcount - 1) * sizeof(bmGlyph)) + sizeof(bmFont); 00104 00105 ysize = (bytes + (ibuf->x - 1)) / ibuf->x; 00106 00107 if (ysize < ibuf->y) { 00108 // we're first going to copy all data into a liniar buffer. 00109 // step can be 4 or 1 bytes, and the data is not sequential because 00110 // the bitmap was flipped vertically. 00111 00112 buffer = (unsigned char*)MEM_mallocN(bytes, "readBitmapFontVersion0:buffer"); 00113 00114 index = 0; 00115 for (i = 0; i < bytes; i++) { 00116 buffer[i] = rect[index]; 00117 index += step; 00118 if (index >= linelength) { 00119 // we've read one line, no skip to the line *before* that 00120 rect -= linelength; 00121 index -= linelength; 00122 } 00123 } 00124 00125 // we're now going to endian convert the data 00126 00127 bmfont = (bmFont*)MEM_mallocN(bytes, "readBitmapFontVersion0:bmfont"); 00128 index = 0; 00129 00130 // first read the header 00131 bmfont->magic[0] = buffer[index++]; 00132 bmfont->magic[1] = buffer[index++]; 00133 bmfont->magic[2] = buffer[index++]; 00134 bmfont->magic[3] = buffer[index++]; 00135 bmfont->version = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00136 bmfont->glyphcount = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00137 bmfont->xsize = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00138 bmfont->ysize = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00139 00140 for (i = 0; i < bmfont->glyphcount; i++) { 00141 bmfont->glyphs[i].unicode = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00142 bmfont->glyphs[i].locx = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00143 bmfont->glyphs[i].locy = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00144 bmfont->glyphs[i].ofsx = buffer[index++]; 00145 bmfont->glyphs[i].ofsy = buffer[index++]; 00146 bmfont->glyphs[i].sizex = buffer[index++]; 00147 bmfont->glyphs[i].sizey = buffer[index++]; 00148 bmfont->glyphs[i].advance = buffer[index++]; 00149 bmfont->glyphs[i].reserved = buffer[index++]; 00150 /* MAART: 00151 if (G.f & G_DEBUG) { 00152 printfGlyph(&bmfont->glyphs[i]); 00153 } 00154 */ 00155 } 00156 00157 MEM_freeN(buffer); 00158 00159 /* MAART: 00160 if (G.f & G_DEBUG) { 00161 printf("Oldy = %d Newy = %d\n", ibuf->y, ibuf->y - ysize); 00162 printf("glyphcount = %d\n", glyphcount); 00163 printf("bytes = %d\n", bytes); 00164 } 00165 */ 00166 00167 // we've read the data from the image. Now we're going 00168 // to crop the image vertically so only the bitmap data 00169 // remains visible 00170 00171 ibuf->y -= ysize; 00172 ibuf->userdata = bmfont; 00173 ibuf->userflags |= IB_BITMAPFONT; 00174 00175 if (ibuf->depth < 32) { 00176 // we're going to fake alpha here: 00177 calcAlpha(ibuf); 00178 } 00179 } else { 00180 /* MAART: 00181 printf("readBitmapFontVersion0: corrupted bitmapfont\n"); 00182 */ 00183 } 00184 } 00185 00186 void detectBitmapFont(ImBuf *ibuf) 00187 { 00188 unsigned char * rect; 00189 unsigned short version; 00190 long i; 00191 00192 if (ibuf != NULL) { 00193 // bitmap must have an x size that is a power of two 00194 if (is_power_of_two(ibuf->x)) { 00195 rect = (unsigned char *) (ibuf->rect + (ibuf->x * (ibuf->y - 1))); 00196 // printf ("starts with: %s %c %c %c %c\n", rect, rect[0], rect[1], rect[2], rect[3]); 00197 if (rect[0] == 'B' && rect[1] == 'F' && rect[2] == 'N' && rect[3] == 'T') { 00198 // printf("found 8bit font !\n"); 00199 // round y size down 00200 // do the 8 bit font stuff. (not yet) 00201 } else { 00202 // we try all 4 possible combinations 00203 for (i = 0; i < 4; i++) { 00204 if (rect[0] == 'B' && rect[4] == 'F' && rect[8] == 'N' && rect[12] == 'T') { 00205 // printf("found 24bit font !\n"); 00206 // We're going to parse the file: 00207 00208 version = (rect[16] << 8) | rect[20]; 00209 00210 if (version == 0) { 00211 readBitmapFontVersion0(ibuf, rect, 4); 00212 } else { 00213 //printf("detectBitmapFont :Unsupported version %d\n", version); 00214 } 00215 00216 // on succes ibuf->userdata points to the bitmapfont 00217 if (ibuf->userdata) { 00218 break; 00219 } 00220 } 00221 rect++; 00222 } 00223 } 00224 } 00225 } 00226 } 00227 00228 int locateGlyph(bmFont *bmfont, unsigned short unicode) 00229 { 00230 int min, max, current = 0; 00231 00232 if (bmfont) { 00233 min = 0; 00234 max = bmfont->glyphcount; 00235 while (1) { 00236 // look halfway for glyph 00237 current = (min + max) >> 1; 00238 00239 if (bmfont->glyphs[current].unicode == unicode) { 00240 break; 00241 } else if (bmfont->glyphs[current].unicode < unicode) { 00242 // have to move up 00243 min = current; 00244 } else { 00245 // have to move down 00246 max = current; 00247 } 00248 00249 if (max - min <= 1) { 00250 // unable to locate glyph 00251 current = 0; 00252 break; 00253 } 00254 } 00255 } 00256 00257 return(current); 00258 } 00259 00260 void matrixGlyph(ImBuf * ibuf, unsigned short unicode, 00261 float *centerx, float *centery, 00262 float *sizex, float *sizey, 00263 float *transx, float *transy, 00264 float *movex, float *movey, 00265 float *advance) 00266 { 00267 int index; 00268 bmFont *bmfont; 00269 00270 *centerx = *centery = 0.0; 00271 *sizex = *sizey = 1.0; 00272 *transx = *transy = 0.0; 00273 *movex = *movey = 0.0; 00274 *advance = 1.0; 00275 00276 if (ibuf) { 00277 bmfont = (bmFont*)ibuf->userdata; 00278 if (bmfont && (ibuf->userflags & IB_BITMAPFONT)) { 00279 index = locateGlyph(bmfont, unicode); 00280 if (index) { 00281 00282 *sizex = (bmfont->glyphs[index].sizex) / (float) (bmfont->glyphs[0].sizex); 00283 *sizey = (bmfont->glyphs[index].sizey) / (float) (bmfont->glyphs[0].sizey); 00284 00285 *transx = bmfont->glyphs[index].locx / (float) ibuf->x; 00286 *transy = (ibuf->y - bmfont->glyphs[index].locy) / (float) ibuf->y; 00287 00288 *centerx = bmfont->glyphs[0].locx / (float) ibuf->x; 00289 *centery = (ibuf->y - bmfont->glyphs[0].locy) / (float) ibuf->y; 00290 00291 // 2.0 units is the default size of an object 00292 00293 *movey = (float)(1.0 - *sizey + 2.0 * (bmfont->glyphs[index].ofsy - bmfont->glyphs[0].ofsy) / (float) bmfont->glyphs[0].sizey); 00294 *movex = (float)(*sizex - 1.0 + 2.0 * (bmfont->glyphs[index].ofsx - bmfont->glyphs[0].ofsx) / (float) bmfont->glyphs[0].sizex); 00295 00296 *advance = (float)(2.0 * bmfont->glyphs[index].advance / (float) bmfont->glyphs[0].advance); 00297 00298 // printfGlyph(&bmfont->glyphs[index]); 00299 // printf("%c %d %0.5f %0.5f %0.5f %0.5f %0.5f \n", unicode, index, *sizex, *sizey, *transx, *transy, *advance); 00300 } 00301 } 00302 } 00303 }