Changeset 512
- Timestamp:
- 02/16/08 17:53:55 (8 months ago)
- Location:
- trunk/thune
- Files:
-
- 1 added
- 20 modified
-
boot.c (modified) (1 diff)
-
doc/FindThune.cmake (modified) (1 diff)
-
doc/FindThuneGL.cmake (added)
-
doc/UserManual (modified) (1 diff)
-
eval.c (modified) (1 diff)
-
files.c (modified) (1 diff)
-
gl/TexFont.c (modified) (14 diffs)
-
gl/TexFont.h (modified) (5 diffs)
-
gl/gx_atoms.h (modified) (1 diff)
-
gl/gx_dt.c (modified) (6 diffs)
-
gl/joystick.c (modified) (2 diffs)
-
gl/png_load.c (modified) (4 diffs)
-
gl/rfont.c (modified) (4 diffs)
-
gl/rfont.h (modified) (1 diff)
-
gl/scripts/view.t (modified) (1 diff)
-
make.c (modified) (3 diffs)
-
mkboot.t (modified) (1 diff)
-
tests/working/series.good (modified) (1 diff)
-
tests/working/series.t (modified) (1 diff)
-
thune.c (modified) (3 diffs)
-
urlan.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/thune/boot.c
r510 r512 89 89 "[reduce [first to-text console.out] iter] proc :prin.pack ;(val -- )\n" 90 90 "[reduce to-text console.out eol console.out] proc :print ;(val -- )\n" 91 "[dup .] proc :.t\n" 91 92 "[error! swap make throw] proc :error\n" 92 93 "[swap context bind proc] proc :proc.env ;(env body -- proc)\n" -
trunk/thune/doc/FindThune.cmake
r478 r512 1 1 FIND_PATH(THUNE_INCLUDE_DIR urlan.h /usr/include /usr/local/include) 2 2 3 FIND_LIBRARY(THUNE_LIBRARY NAMES thune PATH /usr/lib /usr/local/lib)3 FIND_LIBRARY(THUNE_LIBRARY NAMES thune PATH /usr/lib64 /usr/local/lib64 /usr/lib /usr/local/lib) 4 4 5 5 IF (THUNE_INCLUDE_DIR AND THUNE_LIBRARY) -
trunk/thune/doc/UserManual
r510 r512 349 349 stack.level ( -- level) Returns depth of data stack. 350 350 =========== ================= ============================ 351 352 353 Data Stack Helpers 354 ~~~~~~~~~~~~~~~~~~ 355 356 =========== ====================== ============================ 357 Word Stack Usage Function 358 =========== ====================== ============================ 359 .t (val -- val) Show value on top of stack. 360 =========== ====================== ============================ 351 361 352 362 -
trunk/thune/eval.c
r511 r512 1320 1320 } 1321 1321 break; 1322 } 1323 1324 if( ur_type(val) >= UT_BI_COUNT ) 1325 { 1326 UCall func = ut->env->customDT[ ur_type(val) - UT_BI_COUNT ].toType; 1327 func( ut, tos ); 1328 return; 1322 1329 } 1323 1330 -
trunk/thune/files.c
r510 r512 753 753 char* cpB; 754 754 755 if( ! ur_binarySlice( ut, tos, &cpA, &cpB ) || (cpA == 0) ) 755 if( ! ur_binarySlice( ut, tos, &cpA, &cpB ) ) 756 { 757 ur_throwErr( UR_ERR_DATATYPE, "decompress expected binary!" ); 758 return; 759 } 760 if( cpA == 0 ) 756 761 return; 757 762 -
trunk/thune/gl/TexFont.c
r352 r512 21 21 22 22 23 #define KERN 124 23 //#define DUMP 1 25 24 26 #define FT_PIXELS(x) (x >> 6) 27 28 29 #ifdef KERN 30 typedef struct 31 { 32 uint32_t avail; 33 uint32_t used; 34 char* ptr; 35 } 36 Array; 37 38 39 static void arrayReserve( Array* arr, size_t nsize ) 40 { 41 if( nsize > arr->avail ) 42 { 43 size_t count; 44 45 count = arr->avail * 2; 46 if( count < nsize ) 47 count = (nsize < 8) ? 8 : nsize; 48 49 arr->ptr = (char*) realloc( arr->ptr, count ); 50 assert( arr->ptr ); 51 } 52 } 53 #endif 25 #define FT_PIXELS(x) (x >> 6) 26 27 #define GLYPHS(tf) ((TexGlyphInfo*) (tf + 1)) 28 #define TABLE(tf) (((uint16_t*) tf) + tf->table_offset) 29 #define KERN(tf) (((int16_t*) tf) + tf->kern_offset) 54 30 55 31 56 32 //---------------------------------------------------------------------------- 57 58 59 void txf_init( TexFont* txf, int w, int h )60 {61 txf->tex_width = w;62 txf->tex_height = h;63 txf->tgi = 0;64 txf->table = 0;65 txf->kerning = 0;66 }67 68 69 void txf_free( TexFont* txf )70 {71 #define FREE(n) if(n) { free(n); n=0; }72 73 FREE( txf->tgi )74 FREE( txf->table )75 FREE( txf->kerning )76 }77 78 79 void txf_setGlyphCount( TexFont* txf, int n )80 {81 if( txf->tgi )82 free( txf->tgi );83 txf->tgi = (TexGlyphInfo*) malloc( sizeof(TexGlyphInfo) * n );84 txf->num_glyphs = n;85 }86 87 88 /**89 Build glyph lookup table.90 */91 static void _buildGlyphTable( TexFont* txf )92 {93 int min_glyph;94 int max_glyph;95 TexGlyphInfo* it;96 TexGlyphInfo* end;97 98 //assert( txf->num_glyphs );99 100 // Find high & low glyph.101 min_glyph = txf->tgi[0].c;102 max_glyph = txf->tgi[0].c;103 104 it = txf->tgi;105 end = it + txf->num_glyphs;106 107 while( it != end )108 {109 if( it->c < min_glyph )110 min_glyph = it->c;111 if( it->c > max_glyph )112 max_glyph = it->c;113 ++it;114 }115 116 txf->min_glyph = min_glyph;117 txf->table_size = max_glyph - min_glyph + 1;118 119 // Allocate table.120 if( txf->table )121 free( txf->table );122 txf->table = (TexGlyphInfo**)123 malloc( sizeof(TexGlyphInfo*) * txf->table_size );124 125 // Fill table.126 memset( txf->table, 0, sizeof(TexGlyphInfo*) * txf->table_size );127 128 it = txf->tgi;129 while( it != end )130 {131 txf->table[ it->c - txf->min_glyph ] = it;132 ++it;133 }134 }135 33 136 34 … … 140 38 uppercase not available (and vice versa). 141 39 */ 142 TexGlyphInfo* txf_glyph( const TexFont* txf, int c ) 143 { 144 TexGlyphInfo* tgi; 145 int max_glyph = txf->min_glyph + txf->table_size; 146 147 if( (c >= txf->min_glyph) && (c < max_glyph) ) 148 { 149 tgi = txf->table[c - txf->min_glyph]; 150 if( tgi ) 151 return tgi; 40 TexGlyphInfo* txf_glyph( const TexFont* tf, int c ) 41 { 42 uint16_t n; 43 uint16_t* table = TABLE(tf); 44 int min_glyph = tf->min_glyph; 45 int max_glyph = min_glyph + tf->table_size; 46 47 if( (c >= min_glyph) && (c < max_glyph) ) 48 { 49 n = table[ c - min_glyph ]; 50 if( n < 0xffff ) 51 return GLYPHS(tf) + n; 152 52 153 53 if( (c >= 'a') && (c <= 'z') ) 154 54 { 155 55 c -= 'a' - 'A'; // toupper 156 157 if( (c >= txf->min_glyph) && (c < max_glyph) ) 158 { 159 return txf->table[c - txf->min_glyph]; 160 } 56 if( (c >= min_glyph) && (c < max_glyph) ) 57 return GLYPHS(tf) + table[ c - min_glyph ]; 161 58 } 162 59 else if( (c >= 'A') && (c <= 'Z') ) 163 60 { 164 61 c += 'a' - 'A'; // tolower 165 166 if( (c >= txf->min_glyph) && (c < max_glyph) ) 167 { 168 return txf->table[c - txf->min_glyph]; 169 } 170 } 171 } 172 62 if( (c >= min_glyph) && (c < max_glyph) ) 63 return GLYPHS(tf) + table[ c - min_glyph ]; 64 } 65 } 173 66 return 0; 174 67 } 175 68 176 69 177 int txf_kerning( const TexFont* txf, const TexGlyphInfo* left, 178 const TexGlyphInfo* right ) 179 { 180 #ifdef KERN 181 unsigned char* table; 70 int txf_kerning( const TexFont* tf, const TexGlyphInfo* left, 71 const TexGlyphInfo* right ) 72 { 73 const int16_t* table; 182 74 if( left->kern_index > -1 ) 183 75 { 184 table = txf->kerning+ left->kern_index;76 table = KERN(tf) + left->kern_index; 185 77 while( *table ) 186 78 { … … 191 83 */ 192 84 if( right->c == *table ) 193 return ((char*) table)[1]; 194 ++table; 195 } 196 } 197 #else 198 (void) txf; 199 (void) left; 200 (void) right; 201 #endif 85 return table[1]; 86 table += 2; 87 } 88 } 202 89 return 0; 203 90 } 204 91 205 92 93 static void swap16( uint16_t* it, uint16_t* end ) 94 { 95 uint8_t* bp; 96 while( it != end ) 97 { 98 bp = (uint8_t*) it; 99 *it++ = (bp[0] << 8) | bp[1]; 100 } 101 } 102 103 104 /** 105 Swap endianess of TexFont data if not native. 106 */ 107 void txf_swap( TexFont* tf ) 108 { 109 if( tf && (tf->glyph_offset == (sizeof(TexFont) << 8)) ) 110 { 111 TexGlyphInfo* tgi; 112 TexGlyphInfo* end; 113 uint16_t* it; 114 115 it = &tf->glyph_offset; 116 swap16( it, it + (sizeof(TexFont) / sizeof(uint16_t)) ); 117 118 tgi = GLYPHS(tf); 119 end = tgi + tf->glyph_count; 120 while( tgi != end ) 121 { 122 it = &tgi->c; 123 swap16( it, it + 4 ); 124 ++tgi; 125 } 126 127 it = TABLE(tf); 128 swap16( it, it + tf->table_size ); 129 130 it = (uint16_t*) KERN(tf); 131 swap16( it, it + tf->kern_size ); 132 } 133 } 134 135 206 136 //---------------------------------------------------------------------------- 207 137 208 138 209 139 #if DUMP 210 void dumpCharMaps( FT_Face face )140 static void dumpCharMaps( FT_Face face ) 211 141 { 212 142 FT_CharMap charmap; … … 230 160 231 161 232 void blitGlyphToBitmap( FT_Bitmap* src, FT_Bitmap* dst, int x, int y )162 static void blitGlyphToBitmap( FT_Bitmap* src, FT_Bitmap* dst, int x, int y ) 233 163 { 234 164 unsigned char* s; … … 285 215 286 216 287 #ifdef KERN288 217 /* 289 218 Returns index into table or -1 if there is no kerning for left_glyph. 290 219 */ 291 static int _loadKerning( Array* table, FT_Face face, FT_UInt left_glyph, 220 static int _loadKerning( TexFont* tf, int space, 221 FT_Face face, FT_UInt left_glyph, 292 222 const char* codes ) 293 223 { … … 295 225 FT_UInt right_glyph; 296 226 const char* ci; 297 char* entry;298 uint32_t start = table->used;299 300 ci = codes; 227 int16_t* ktable = KERN(tf); 228 int16_t* entry; 229 uint32_t start = tf->kern_size; 230 301 231 for( ci = codes; *ci != '\0'; ++ci ) 302 232 { … … 309 239 //FT_KERNING_UNFITTED, FT_KERNING_UNSCALED 310 240 &kern ); 311 if( kern.x || kern.y ) 312 { 313 //printf(" %c %ld %ld\n", *ci, FT_PIXELS(kern.x), FT_PIXELS(kern.y)); 314 315 arrayReserve( table, table->used + 3 ); 316 entry = table->ptr + table->used; 317 table->used += 2; 318 319 // NOTE: kern.y is ignored since is it almost always zero. 241 242 // NOTE: kern.y is ignored since is it almost always zero. 243 if( kern.x /*|| kern.y*/ ) 244 { 245 #ifdef DUMP 246 printf(" %c %ld %ld\n", *ci, FT_PIXELS(kern.x), FT_PIXELS(kern.y)); 247 #endif 248 if( space < 3 ) 249 { 250 ktable[ tf->kern_size ] = 0; 251 fprintf( stderr, "txf_build: Kerning table full\n" ); 252 return -1; 253 } 254 255 entry = ktable + tf->kern_size; 256 tf->kern_size += 2; 257 space -= 2; 258 320 259 entry[0] = *ci; 321 260 entry[1] = FT_PIXELS(kern.x); … … 323 262 } 324 263 325 if( t able->used> start )264 if( tf->kern_size > start ) 326 265 { 327 266 // Terminate entries. 328 table->ptr[ table->used ] = 0; 329 ++table->used; 330 267 ktable[ tf->kern_size ] = 0; 268 ++tf->kern_size; 331 269 return start; 332 270 } … … 334 272 return -1; 335 273 } 336 #endif337 274 338 275 339 276 /** 340 Returns number of glyphs addedor zero if fails.277 Returns TexFont pointer or zero if fails. 341 278 */ 342 int txf_build( TexFont* txf, const char* file, 343 const char* codes, FT_Bitmap* img, int psize, int gap, 344 int asBitmap ) 279 TexFont* txf_build( const char* file, const char* codes, 280 FT_Bitmap* img, int psize, int gap, int antialias ) 345 281 { 346 282 FT_Library library; … … 351 287 FT_F26Dot6 start_x; 352 288 FT_F26Dot6 step_y; 353 FT_F26Dot6 x, y; 354 #ifdef KERN 355 Array kern; 356 #endif 289 int x, y; 290 int nextX; 291 int glyph_index; 292 int gmin, gmax; 293 int ch; 294 int kern_space; 357 295 const char* ci; 358 int count = 0; 296 uint16_t* table; 297 TexGlyphInfo* tgi; 298 TexFont* txf = 0; 299 int count; 359 300 int loadFailed = 0; 360 301 … … 362 303 error = FT_Init_FreeType( &library ); 363 304 if( error ) 364 {365 305 return 0; 366 }367 306 368 307 error = FT_New_Face( library, file, 0, &face ); 369 308 if( error ) 370 { 371 return 0; 372 } 309 goto cleanup_lib; 373 310 374 311 375 312 #if DUMP 376 313 #define EM_PIX(n) n,FT_PIXELS(n) 377 printf( "FT_Face [\n" );378 printf( " family_name: \"%s\"\n", face->family_name );379 printf( " style_name: \"%s\"\n", face->style_name );380 printf( " num_glyphs: %ld\n", face->num_glyphs );381 printf( " units_per_EM: %d (%d)\n", EM_PIX(face->units_per_EM) );382 printf( " ascender: %d (%d)\n", EM_PIX(face->ascender) );383 printf( " descender: %d (%d)\n", EM_PIX(face->descender) );384 printf( " height: %d (%d)\n", EM_PIX(face->height) );385 dumpCharMaps( face );386 printf( "]\n" );314 printf( "FT_Face [\n" ); 315 printf( " family_name: \"%s\"\n", face->family_name ); 316 printf( " style_name: \"%s\"\n", face->style_name ); 317 printf( " num_glyphs: %ld\n", face->num_glyphs ); 318 printf( " units_per_EM: %d (%d)\n", EM_PIX(face->units_per_EM) ); 319 printf( " ascender: %d (%d)\n", EM_PIX(face->ascender) ); 320 printf( " descender: %d (%d)\n", EM_PIX(face->descender) ); 321 printf( " height: %d (%d)\n", EM_PIX(face->height) ); 322 dumpCharMaps( face ); 323 printf( "]\n" ); 387 324 #endif 388 325 … … 390 327 error = FT_Set_Pixel_Sizes( face, psize, psize ); 391 328 if( error ) 392 { 393 return 0; 394 } 395 396 #ifdef KERN 397 kern.ptr = 0; 398 kern.avail = 0; 399 kern.used = 0; 400 #endif 329 goto cleanup; 401 330 402 331 glyph = face->glyph; … … 404 333 405 334 406 txf_setGlyphCount( txf, face->num_glyphs ); 335 // Count glyphs and find the high & low. 336 gmin = 0xffff; 337 gmax = 0; 338 ci = codes; 339 while( *ci ) 340 { 341 ch = *ci++; 342 if( ch < gmin ) 343 gmin = ch; 344 if( ch > gmax ) 345 gmax = ch; 346 } 347 count = ci - codes; 348 349 350 // Most glyphs have no kerning adjustment, and those with it have only 351 // a handful (at least at small font sizes). 352 kern_space = count * 5; // 5 = 2 glyphs + terminator 353 354 txf = (TexFont*) malloc( sizeof(TexFont) + 355 (sizeof(TexGlyphInfo) * count) + 356 (sizeof(uint16_t) * (gmax - gmin + 1)) + 357 (sizeof(int16_t) * kern_space) ); 358 359 txf->glyph_offset = sizeof(TexFont); 360 txf->glyph_count = count; 361 txf->table_offset = (txf->glyph_offset + (sizeof(TexGlyphInfo) * count)) 362 / sizeof(uint16_t); 363 txf->table_size = gmax - gmin + 1; 364 txf->kern_offset = txf->table_offset + txf->table_size; 365 txf->kern_size = 0; 366 407 367 //txf.max_ascent = size->metrics.y_ppem; 408 368 txf->max_ascent = face->ascender * psize / face->units_per_EM; 409 369 txf->max_descent = -face->descender * psize / face->units_per_EM; 410 370 411 412 /* Clear bitmap */ 371 txf->min_glyph = gmin; 372 txf->tex_width = img->pitch; 373 txf->tex_height = img->rows; 374 375 table = TABLE(txf); 376 memset( table, 0xff, sizeof(uint16_t) * txf->table_size ); 377 378 379 // Clear bitmap. 413 380 memset( img->buffer, 0, img->rows * img->pitch ); 414 381 … … 420 387 y = step_y; 421 388 389 count = 0; 390 tgi = GLYPHS(txf); 422 391 ci = codes; 423 for( ci = codes; *ci != '\0'; ++ci ) 424 { 425 int glyph_index = FT_Get_Char_Index( face, *ci ); 392 while( *ci ) 393 { 394 ch = *ci++; 395 396 glyph_index = FT_Get_Char_Index( face, ch ); 426 397 if( glyph_index == 0 ) 427 398 { 428 printf( "Code 0x%x (%c) is undefined\n", (int) *ci, (char) *ci ); 399 fprintf( stderr, "txf_build: Code 0x%x (%c) is undefined\n", 400 ch, (char) ch ); 429 401 continue; 430 402 } 431 403 432 404 error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); 433 if( ! error ) 434 { 435 TexGlyphInfo* tgi; 436 int nextX = x + FT_PIXELS(glyph->metrics.width) + gap; 437 438 if( nextX > img->width ) 405 if( error ) 406 { 407 ++loadFailed; 408 continue; 409 } 410 411 nextX = x + FT_PIXELS(glyph->metrics.width) + gap; 412 413 if( nextX > img->width ) 414 { 415 x = start_x; 416 y += step_y; 417 418 //if( (y + step_y) >= img->rows ) 419 if( y >= img->rows ) 439 420 { 440 x = start_x; 441 y += step_y; 442 443 //if( (y + step_y) >= img->rows ) 444 if( y >= img->rows ) 445 { 446 fprintf(stderr, "** Texture too small\n"); 447 break; 448 } 449 450 nextX = x + FT_PIXELS(glyph->metrics.width) + gap; 421 fprintf( stderr, "txf_build: Texture too small\n" ); 422 break; 451 423 } 452 424 453 _renderGlyph( img, glyph, x, y, ! asBitmap ); 454 455 tgi = txf->tgi + count; 456 count++; 457 458 tgi->c = *ci; 459 tgi->width = FT_PIXELS(glyph->metrics.width); 460 tgi->height = FT_PIXELS(glyph->metrics.height); 461 tgi->xoffset = FT_PIXELS(glyph->metrics.horiBearingX); 462 tgi->yoffset = FT_PIXELS(glyph->metrics.horiBearingY) - tgi->height; 463 tgi->advance = FT_PIXELS(glyph->metrics.horiAdvance); 464 tgi->x = x /*+ tgi->xoffset*/; 465 tgi->y = img->rows - y + tgi->yoffset; 425 nextX = x + FT_PIXELS(glyph->metrics.width) + gap; 426 } 427 428 _renderGlyph( img, glyph, x, y, antialias ); 429 430 tgi->c = ch; 431 tgi->width = FT_PIXELS(glyph->metrics.width); 432 tgi->height = FT_PIXELS(glyph->metrics.height); 433 tgi->xoffset = FT_PIXELS(glyph->metrics.horiBearingX); 434 tgi->yoffset = FT_PIXELS(glyph->metrics.horiBearingY) - tgi->height; 435 tgi->advance = FT_PIXELS(glyph->metrics.horiAdvance); 436 tgi->x = x /*+ tgi->xoffset*/; 437 tgi->y = img->rows - y + tgi->yoffset; 438 439 #ifdef DUMP 440 printf( "Glyph %c %d,%d %d,%d %d %d,%d\n", ch, 441 tgi->width, tgi->height, 442 tgi->xoffset, tgi->yoffset, 443 tgi->advance, tgi->x, tgi->y ); 444 #endif 445 446 table[ ch - txf->min_glyph ] = count++; 447 448 if( FT_HAS_KERNING( face ) ) 449 { 450 #ifdef DUMP 451 printf( "Kern %c\n", ch ); 452 #endif 453 tgi->kern_index = _loadKerning( txf, 454 kern_space - txf->kern_size, 455 face, glyph_index, codes ); 456 } 457 else 458 { 466 459 tgi->kern_index = -1; 467 468 #ifdef KERN 469 if( FT_HAS_KERNING( face ) ) 470 { 471 //printf( "KR Kern %c\n", *ci ); 472 tgi->kern_index = _loadKerning(&kern, face, glyph_index, codes); 473 } 474 #endif 475 476 x = nextX; 477 }
