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