2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Fonttool/FontKern.cpp $
15 * Tool for interactively kerning fonts
18 * Revision 1.4 2006/04/26 19:38:36 taylor
19 * fix some minor fonttool compile errors
21 * Revision 1.3 2003/01/30 20:03:48 relnev
22 * various files ported needed for fonttool. There is a bug where on exit it segfaults in SDL_GL_SwapBuffers, I'm probably missing something (don't know what) but it works fine otherwise (Taylor Richards)
24 * Revision 1.2 2002/06/09 04:41:16 relnev
25 * added copyright header
27 * Revision 1.1.1.1 2002/05/03 03:28:08 root
31 * 6 5/19/99 4:07p Dave
32 * Moved versioning code into a nice isolated common place. Fixed up
33 * updating code on the pxo screen. Fixed several stub problems.
35 * 5 12/18/98 1:14a Dave
36 * Rough 1024x768 support for Direct3D. Proper detection and usage through
39 * 4 12/02/98 9:58a Dave
40 * Got fonttool working under glide/direct3d.
42 * 3 11/30/98 1:09p Dave
44 * 2 10/24/98 5:15p Dave
46 * 1 10/24/98 4:58p Dave
48 * 14 5/06/98 5:30p John
49 * Removed unused cfilearchiver. Removed/replaced some unused/little used
50 * graphics functions, namely gradient_h and _v and pixel_sp. Put in new
51 * DirectX header files and libs that fixed the Direct3D alpha blending
54 * 13 4/13/98 10:11a John
55 * Made timer functions thread safe. Made timer_init be called in all
58 * 12 3/10/98 4:18p John
59 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
60 * & Glide have popups and print screen. Took out all >8bpp software
61 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
62 * support Fred. Made zbuffering key off of functions rather than one
65 * 11 3/05/98 11:15p Hoffoss
66 * Changed non-game key checking to use game_check_key() instead of
69 * 10 10/30/97 4:56p John
70 * Fixed up font stuff to build. Fixed bug where it didn't show the last
71 * 3 characters in kerning table.
73 * 9 9/03/97 4:32p John
74 * changed bmpman to only accept ani and pcx's. made passing .pcx or .ani
75 * to bm_load functions not needed. Made bmpman keep track of palettes
76 * for bitmaps not mapped into game palettes.
78 * 8 6/06/97 6:47p John
81 * 7 6/06/97 4:41p John
82 * Fixed alpha colors to be smoothly integrated into gr_set_color_fast
85 * 6 6/06/97 11:10a John
86 * made scrolling kern pair box.
88 * 5 6/06/97 9:21a John
89 * added some kerning pairs
91 * 4 6/06/97 9:18a John
92 * Added capital hamburger.
94 * 3 6/05/97 5:00p John
97 * 2 6/05/97 4:53p John
98 * First rev of new antialiased font stuff.
100 * 1 6/02/97 4:04p John
125 #include "osregistry.h"
128 #include "fonttool.h"
130 const char *SampleText = "This is some sample text that is here to\n" \
131 "Show you how the antialiasing will\n" \
132 "look over different color backgrounds\n" \
133 "KERN PAIRS: VaWaVeWeVAV-LyT.T,TyTvTcYe\n";
135 static void myexit(int value)
160 int fonttool_get_kerning( font *fnt, int c1, int c2, int *pairnum )
164 int l1 = c1 - fnt->first_ascii;
165 int l2 = c2 - fnt->first_ascii;
167 for (i=0; i<fnt->num_kern_pairs; i++ ) {
168 if ( (fnt->kern_data[i].c1 == l1) && (fnt->kern_data[i].c2 == l2) ) {
169 if (pairnum) *pairnum = i;
170 return fnt->kern_data[i].offset;
176 void fonttool_resync_kerning( font *fnt )
180 // update all the font into
181 for (i=0; i<fnt->num_chars; i++ ) {
182 fnt->char_data[i].kerning_entry = -1;
185 for (i=0; i<fnt->num_kern_pairs; i++ ) {
186 int c = fnt->kern_data[i].c1;
187 if ( fnt->char_data[c].kerning_entry == -1 )
188 fnt->char_data[c].kerning_entry = (short)i;
192 void fonttool_remove_kern_pair( font *fnt, int index )
195 int i, n, new_num_pairs;
197 new_num_pairs = fnt->num_kern_pairs - 1;
199 if ( new_num_pairs < 1 ) {
200 fonttool_remove_kerning(fnt);
204 font_kernpair *new_kern_data = (font_kernpair *)malloc( new_num_pairs*sizeof(font_kernpair) );
205 if (!new_kern_data) {
206 printf( "Out of memory!\n" );
212 for (i=0; i<fnt->num_kern_pairs; i++ ) {
214 new_kern_data[n] = fnt->kern_data[i];
219 if ( fnt->kern_data ) free( fnt->kern_data );
220 fnt->kern_data = new_kern_data;
221 fnt->kern_data_size = sizeof(font_kernpair)*new_num_pairs;
222 fnt->num_kern_pairs = new_num_pairs;
224 fonttool_resync_kerning(fnt);
226 mprintf(( "Font has %d kern pairs\n", fnt->num_kern_pairs ));
229 void fonttool_set_kerning( font *fnt, int c1, int c2, int dist )
233 int l1 = c1 - fnt->first_ascii;
234 int l2 = c2 - fnt->first_ascii;
236 for (i=0; i<fnt->num_kern_pairs; i++ ) {
237 if ( (fnt->kern_data[i].c1 == l1) && (fnt->kern_data[i].c2 == l2) ) {
238 fnt->kern_data[i].offset = (signed char)dist;
240 fonttool_remove_kern_pair( fnt, i );
245 if ( dist == 0 ) return;
250 new_num_pairs = fnt->num_kern_pairs+1;
252 font_kernpair *new_kern_data = (font_kernpair *)malloc( new_num_pairs*sizeof(font_kernpair) );
253 if (!new_kern_data) {
254 printf( "Out of memory!\n" );
260 uint newcode = l1*256+l2;
262 for (i=0; i<fnt->num_kern_pairs; i++ ) {
263 uint code = fnt->kern_data[i].c1*256 + fnt->kern_data[i].c2;
264 if ( code < newcode ) {
265 new_kern_data[n] = fnt->kern_data[i];
273 new_kern_data[n].c1 = (char)l1;
274 new_kern_data[n].c2 = (char)l2;
275 new_kern_data[n].offset = (signed char)dist;
279 for (; i<fnt->num_kern_pairs; i++ ) {
280 new_kern_data[n] = fnt->kern_data[i];
285 if ( fnt->kern_data ) free( fnt->kern_data );
286 fnt->kern_data = new_kern_data;
287 fnt->kern_data_size += sizeof(font_kernpair);
288 fnt->num_kern_pairs++;
290 fonttool_resync_kerning(fnt);
292 mprintf(( "Font has %d kern pairs\n", fnt->num_kern_pairs ));
297 void fonttool_remove_kerning( font *fnt )
301 for (i=0; i<fnt->num_chars; i++ ) {
302 fnt->char_data[i].kerning_entry = -1;
305 fnt->kern_data_size = 0;
307 free( fnt->kern_data );
308 fnt->kern_data = NULL;
309 fnt->num_kern_pairs = 0;
313 void fonttool_edit_kerning(char *fname1, char *extras_dir)
318 font KernFont, tmpfont;
320 int cr=16, cb=16, cg=16;
321 int c1 = 'b', c2 = 'u';
323 int current_pair = -1;
325 int current_item = 0;
326 int num_items_displayed = 1;
327 int last_good_pair = -1;
330 printf( "Editing kerning data for %s\n", fname1 );
331 fonttool_read( fname1, &KernFont );
335 // setup the fred exe directory so CFILE can init properly
336 //char *c = GetCommandLine();
337 //SDL_assert(c != NULL);
338 //char *tok = strtok(c, " ");
339 //SDL_assert(tok != NULL);
341 cfile_init(extras_dir);
343 os_init( "FontTool", "FontTool - Kerning Table Editor" );
345 // always run this thing in a window
346 Cmdline_fullscreen = 0;
349 gr_init(GR_640, GR_OPENGL);
351 gr_set_palette("none",NULL);
353 char fonttool_pcx[128];
354 sprintf(fonttool_pcx, "src%sfonttool%sfonttool", DIR_SEPARATOR_STR, DIR_SEPARATOR_STR);
356 bkg = bm_load( fonttool_pcx );
359 printf("Error loading FontTool\n" );
362 palette_use_bm_palette(bkg);
367 gr_init_alphacolor( &ac, cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD );
371 extern font *Current_font;
372 Current_font = &KernFont;
382 fonttool_read( fname1, &tmpfont );
383 fonttool_copy_kern( &tmpfont, &KernFont );
387 fonttool_remove_kerning( &KernFont );
391 fonttool_dump( fname1, &KernFont );
398 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD);
405 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD);
410 if ( cr == 16 ) cr = 1; else cr = 16;
411 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD);
415 if ( cg == 16 ) cg = 1; else cg = 16;
416 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD);
420 if ( cb == 16 ) cb = 1; else cb = 16;
421 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16,AC_TYPE_HUD);
425 x = fonttool_get_kerning( &KernFont, c1, c2, NULL );
426 fonttool_set_kerning( &KernFont, c1, c2, x+1 );
430 x = fonttool_get_kerning( &KernFont, c1, c2, NULL );
431 fonttool_set_kerning( &KernFont, c1, c2, x-1 );
435 fonttool_set_kerning( &KernFont, c1, c2, 0 );
439 if ( c1 < KernFont.first_ascii + KernFont.num_chars-1 ) c1++;
443 if ( c1 > KernFont.first_ascii ) c1--;
447 if ( c2 < KernFont.first_ascii + KernFont.num_chars-1 ) c2++;
448 mprintf(( "C2 = %d\n", c2 ));
452 if ( c2 > KernFont.first_ascii ) c2--;
453 mprintf(( "C2 = %d\n", c2 ));
457 if ( current_pair < 0 )
458 current_pair = last_good_pair;
461 if ( current_pair >= KernFont.num_kern_pairs ) {
462 current_pair = KernFont.num_kern_pairs-1;
464 if ( (current_pair < KernFont.num_kern_pairs) && (current_pair > -1) ) {
465 c1 = KernFont.kern_data[current_pair].c1 + KernFont.first_ascii;
466 c2 = KernFont.kern_data[current_pair].c2 + KernFont.first_ascii;
471 if ( current_pair < 0 )
472 current_pair = last_good_pair;
475 if ( current_pair < 0 ) {
478 if ( (current_pair < KernFont.num_kern_pairs) && (current_pair > -1) ) {
479 c1 = KernFont.kern_data[current_pair].c1 + KernFont.first_ascii;
480 c2 = KernFont.kern_data[current_pair].c2 + KernFont.first_ascii;
489 if ( current_pair >= KernFont.num_kern_pairs ) {
494 fonttool_get_kerning( &KernFont, c1, c2, &tmpp );
499 if ( current_pair > -1 )
500 last_good_pair = current_pair;
507 gr_set_color_fast(&ac);
509 sprintf( kerntext, "%c (%d)", c1, c1 );
510 gr_string( 240, 210, kerntext );
511 sprintf( kerntext, "%c (%d)", c2, c2 );
512 gr_string( 340, 210, kerntext );
514 sprintf( kerntext, "Ham%c%crger", c1, c2 );
515 gr_string( 0x8000, 240, kerntext );
517 sprintf( kerntext, "HAM%c%cRGER", c1, c2 );
518 gr_string( 0x8000, 270, kerntext );
520 sprintf( kerntext, "Offset: %d pixels", fonttool_get_kerning( &KernFont, c1, c2, NULL ) );
521 gr_string( 0x8000, 300, kerntext );
525 gr_get_string_size( &tw, &th, kerntext );
527 gr_string( 0x8000, 360, SampleText );
528 gr_string( 20, 360+th+20, SampleText );
534 //= ( 330 - 200 ) / KernFont.h;
535 int num_items = KernFont.num_kern_pairs;
537 if ( current_pair > -1 )
538 current_item = current_pair;
540 if (current_item <0 )
543 if (current_item >= num_items )
544 current_item = num_items-1;
546 if (current_item<first_item)
547 first_item = current_item;
549 if (current_item>=(first_item+num_items_displayed))
550 first_item = current_item-num_items_displayed+1;
552 if (num_items <= num_items_displayed )
555 int stop = first_item+num_items_displayed;
556 if (stop>num_items) stop = num_items;
559 for (i=first_item; i<stop; i++ ) {
562 sprintf( kerntext, "%c%c", KernFont.kern_data[i].c1 + KernFont.first_ascii, KernFont.kern_data[i].c2 + KernFont.first_ascii );
563 if ( i==current_pair ) {
564 gr_set_color( 255, 0, 0 );
565 //hud_tri( i2fl(x),i2fl(y), i2fl(x+6), i2fl(y+5), i2fl(x), i2fl(y+8) );
574 gr_line(x1,y1,x2,y2);
575 gr_line(x2,y2,x3,y3);
576 gr_line(x3,y3,x1,y1);
578 gr_set_color_fast(&ac);
580 gr_string( x+8, y, kerntext );
582 gr_get_string_size( &tw, &th, kerntext );
591 num_items_displayed=n;
598 num_items_displayed++;
600 if (num_items_displayed < 1 )
601 num_items_displayed = 1;
603 if (num_items_displayed > num_items )
604 num_items_displayed = num_items;
606 //mprintf(( "Num items = %d\n", num_items_displayed ));
611 // sleep a little bit, don't need high framerate here