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