|
Blender
V2.59
|
00001 /* 00002 * bmfont.c 00003 * 00004 * 04-10-2000 frank 00005 * 00006 * $Id: bmfont.c 35247 2011-02-27 20:40:57Z 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 "BKE_global.h" 00060 #include "IMB_imbuf_types.h" 00061 00062 #include "BKE_bmfont.h" 00063 #include "BKE_bmfont_types.h" 00064 00065 void printfGlyph(bmGlyph * glyph) 00066 { 00067 printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode); 00068 printf(" locx: %4d locy: %4d\n", glyph->locx, glyph->locy); 00069 printf(" sizex: %3d sizey: %3d\n", glyph->sizex, glyph->sizey); 00070 printf(" ofsx: %3d ofsy: %3d\n", glyph->ofsx, glyph->ofsy); 00071 printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved); 00072 } 00073 00074 #define MAX2(x,y) ( (x)>(y) ? (x) : (y) ) 00075 #define MAX3(x,y,z) MAX2( MAX2((x),(y)) , (z) ) 00076 00077 void calcAlpha(ImBuf * ibuf) 00078 { 00079 int i; 00080 char * rect; 00081 00082 if (ibuf) { 00083 rect = (char *) ibuf->rect; 00084 for (i = ibuf->x * ibuf->y ; i > 0 ; i--) { 00085 rect[3] = MAX3(rect[0], rect[1], rect[2]); 00086 rect += 4; 00087 } 00088 } 00089 } 00090 00091 void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step) 00092 { 00093 int glyphcount, bytes, i, index, linelength, ysize; 00094 unsigned char * buffer; 00095 bmFont * bmfont; 00096 00097 linelength = ibuf->x * step; 00098 00099 glyphcount = (rect[6 * step] << 8) | rect[7 * step]; 00100 bytes = ((glyphcount - 1) * sizeof(bmGlyph)) + sizeof(bmFont); 00101 00102 ysize = (bytes + (ibuf->x - 1)) / ibuf->x; 00103 00104 if (ysize < ibuf->y) { 00105 // we're first going to copy all data into a liniar buffer. 00106 // step can be 4 or 1 bytes, and the data is not sequential because 00107 // the bitmap was flipped vertically. 00108 00109 buffer = MEM_mallocN(bytes, "readBitmapFontVersion0:buffer"); 00110 00111 index = 0; 00112 for (i = 0; i < bytes; i++) { 00113 buffer[i] = rect[index]; 00114 index += step; 00115 if (index >= linelength) { 00116 // we've read one line, no skip to the line *before* that 00117 rect -= linelength; 00118 index -= linelength; 00119 } 00120 } 00121 00122 // we're now going to endian convert the data 00123 00124 bmfont = MEM_mallocN(bytes, "readBitmapFontVersion0:bmfont"); 00125 index = 0; 00126 00127 // first read the header 00128 bmfont->magic[0] = buffer[index++]; 00129 bmfont->magic[1] = buffer[index++]; 00130 bmfont->magic[2] = buffer[index++]; 00131 bmfont->magic[3] = buffer[index++]; 00132 bmfont->version = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00133 bmfont->glyphcount = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00134 bmfont->xsize = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00135 bmfont->ysize = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00136 00137 for (i = 0; i < bmfont->glyphcount; i++) { 00138 bmfont->glyphs[i].unicode = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00139 bmfont->glyphs[i].locx = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00140 bmfont->glyphs[i].locy = (buffer[index] << 8) | buffer[index + 1]; index += 2; 00141 bmfont->glyphs[i].ofsx = buffer[index++]; 00142 bmfont->glyphs[i].ofsy = buffer[index++]; 00143 bmfont->glyphs[i].sizex = buffer[index++]; 00144 bmfont->glyphs[i].sizey = buffer[index++]; 00145 bmfont->glyphs[i].advance = buffer[index++]; 00146 bmfont->glyphs[i].reserved = buffer[index++]; 00147 if (G.f & G_DEBUG) { 00148 printfGlyph(&bmfont->glyphs[i]); 00149 } 00150 } 00151 00152 MEM_freeN(buffer); 00153 00154 if (G.f & G_DEBUG) { 00155 printf("Oldy = %d Newy = %d\n", ibuf->y, ibuf->y - ysize); 00156 printf("glyphcount = %d\n", glyphcount); 00157 printf("bytes = %d\n", bytes); 00158 } 00159 00160 // we've read the data from the image. Now we're going 00161 // to crop the image vertically so only the bitmap data 00162 // remains visible 00163 00164 ibuf->y -= ysize; 00165 ibuf->userdata = bmfont; 00166 ibuf->userflags |= IB_BITMAPFONT; 00167 00168 if (ibuf->depth < 32) { 00169 // we're going to fake alpha here: 00170 calcAlpha(ibuf); 00171 } 00172 } else { 00173 printf("readBitmapFontVersion0: corrupted bitmapfont\n"); 00174 } 00175 } 00176 00177 void detectBitmapFont(ImBuf *ibuf) 00178 { 00179 unsigned char * rect; 00180 unsigned short version; 00181 int i; 00182 00183 if (ibuf != NULL && ibuf->rect != NULL) { 00184 // bitmap must have an x size that is a power of two 00185 if (is_power_of_two(ibuf->x)) { 00186 rect = (unsigned char *) (ibuf->rect + (ibuf->x * (ibuf->y - 1))); 00187 // printf ("starts with: %s %c %c %c %c\n", rect, rect[0], rect[1], rect[2], rect[3]); 00188 if (rect[0] == 'B' && rect[1] == 'F' && rect[2] == 'N' && rect[3] == 'T') { 00189 // printf("found 8bit font !\n"); 00190 // round y size down 00191 // do the 8 bit font stuff. (not yet) 00192 } else { 00193 // we try all 4 possible combinations 00194 for (i = 0; i < 4; i++) { 00195 if (rect[0] == 'B' && rect[4] == 'F' && rect[8] == 'N' && rect[12] == 'T') { 00196 // printf("found 24bit font !\n"); 00197 // We're going to parse the file: 00198 00199 version = (rect[16] << 8) | rect[20]; 00200 00201 if (version == 0) { 00202 readBitmapFontVersion0(ibuf, rect, 4); 00203 } else { 00204 printf("detectBitmapFont :Unsupported version %d\n", version); 00205 } 00206 00207 // on succes ibuf->userdata points to the bitmapfont 00208 if (ibuf->userdata) { 00209 break; 00210 } 00211 } 00212 rect++; 00213 } 00214 } 00215 } 00216 } 00217 } 00218 00219 int locateGlyph(bmFont *bmfont, unsigned short unicode) 00220 { 00221 int min, max, current = 0; 00222 00223 if (bmfont) { 00224 min = 0; 00225 max = bmfont->glyphcount; 00226 while (1) { 00227 // look halfway for glyph 00228 current = (min + max) >> 1; 00229 00230 if (bmfont->glyphs[current].unicode == unicode) { 00231 break; 00232 } else if (bmfont->glyphs[current].unicode < unicode) { 00233 // have to move up 00234 min = current; 00235 } else { 00236 // have to move down 00237 max = current; 00238 } 00239 00240 if (max - min <= 1) { 00241 // unable to locate glyph 00242 current = 0; 00243 break; 00244 } 00245 } 00246 } 00247 00248 return(current); 00249 } 00250 00251 void matrixGlyph(ImBuf * ibuf, unsigned short unicode, 00252 float *centerx, float *centery, 00253 float *sizex, float *sizey, 00254 float *transx, float *transy, 00255 float *movex, float *movey, 00256 float *advance) 00257 { 00258 int index; 00259 bmFont *bmfont; 00260 00261 *centerx = *centery = 0.0; 00262 *sizex = *sizey = 1.0; 00263 *transx = *transy = 0.0; 00264 *movex = *movey = 0.0; 00265 *advance = 1.0; 00266 00267 if (ibuf) { 00268 bmfont = ibuf->userdata; 00269 if (bmfont && (ibuf->userflags & IB_BITMAPFONT)) { 00270 index = locateGlyph(bmfont, unicode); 00271 if (index) { 00272 00273 *sizex = (bmfont->glyphs[index].sizex) / (float) (bmfont->glyphs[0].sizex); 00274 *sizey = (bmfont->glyphs[index].sizey) / (float) (bmfont->glyphs[0].sizey); 00275 00276 *transx = bmfont->glyphs[index].locx / (float) ibuf->x; 00277 *transy = (ibuf->y - bmfont->glyphs[index].locy) / (float) ibuf->y; 00278 00279 *centerx = bmfont->glyphs[0].locx / (float) ibuf->x; 00280 *centery = (ibuf->y - bmfont->glyphs[0].locy) / (float) ibuf->y; 00281 00282 // 2.0 units is the default size of an object 00283 00284 *movey = 1.0f - *sizey + 2.0f * (bmfont->glyphs[index].ofsy - bmfont->glyphs[0].ofsy) / (float) bmfont->glyphs[0].sizey; 00285 *movex = *sizex - 1.0f + 2.0f * (bmfont->glyphs[index].ofsx - bmfont->glyphs[0].ofsx) / (float) bmfont->glyphs[0].sizex; 00286 00287 *advance = 2.0f * bmfont->glyphs[index].advance / (float) bmfont->glyphs[0].advance; 00288 00289 // printfGlyph(&bmfont->glyphs[index]); 00290 // printf("%c %d %0.5f %0.5f %0.5f %0.5f %0.5f \n", unicode, index, *sizex, *sizey, *transx, *transy, *advance); 00291 } 00292 } 00293 } 00294 }