]> icculus.org git repositories - taylor/freespace2.git/blob - src/fonttool/fontkern.cpp
Initial revision
[taylor/freespace2.git] / src / fonttool / fontkern.cpp
1 /*
2  * $Logfile: /Freespace2/code/Fonttool/FontKern.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Tool for interactively kerning fonts
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:08  root
11  * Initial revision
12  *
13  * 
14  * 6     5/19/99 4:07p Dave
15  * Moved versioning code into a nice isolated common place. Fixed up
16  * updating code on the pxo screen. Fixed several stub problems.
17  * 
18  * 5     12/18/98 1:14a Dave
19  * Rough 1024x768 support for Direct3D. Proper detection and usage through
20  * the launcher.
21  * 
22  * 4     12/02/98 9:58a Dave
23  * Got fonttool working under glide/direct3d.
24  * 
25  * 3     11/30/98 1:09p Dave
26  * 
27  * 2     10/24/98 5:15p Dave
28  * 
29  * 1     10/24/98 4:58p Dave
30  * 
31  * 14    5/06/98 5:30p John
32  * Removed unused cfilearchiver.  Removed/replaced some unused/little used
33  * graphics functions, namely gradient_h and _v and pixel_sp.   Put in new
34  * DirectX header files and libs that fixed the Direct3D alpha blending
35  * problems.
36  * 
37  * 13    4/13/98 10:11a John
38  * Made timer functions thread safe.  Made timer_init be called in all
39  * projects.
40  * 
41  * 12    3/10/98 4:18p John
42  * Cleaned up graphics lib.  Took out most unused gr functions.   Made D3D
43  * & Glide have popups and print screen.  Took out all >8bpp software
44  * support.  Made Fred zbuffer.  Made zbuffer allocate dynamically to
45  * support Fred.  Made zbuffering key off of functions rather than one
46  * global variable.
47  * 
48  * 11    3/05/98 11:15p Hoffoss
49  * Changed non-game key checking to use game_check_key() instead of
50  * game_poll().
51  * 
52  * 10    10/30/97 4:56p John
53  * Fixed up font stuff to build.  Fixed bug where it didn't show the last
54  * 3 characters in kerning table.
55  * 
56  * 9     9/03/97 4:32p John
57  * changed bmpman to only accept ani and pcx's.  made passing .pcx or .ani
58  * to bm_load functions not needed.   Made bmpman keep track of palettes
59  * for bitmaps not mapped into game palettes.
60  * 
61  * 8     6/06/97 6:47p John
62  * Fixed bug
63  * 
64  * 7     6/06/97 4:41p John
65  * Fixed alpha colors to be smoothly integrated into gr_set_color_fast
66  * code.
67  * 
68  * 6     6/06/97 11:10a John
69  * made scrolling kern pair box.
70  * 
71  * 5     6/06/97 9:21a John
72  * added some kerning pairs
73  * 
74  * 4     6/06/97 9:18a John
75  * Added capital hamburger.    
76  * 
77  * 3     6/05/97 5:00p John
78  * used fonttool.pcx
79  * 
80  * 2     6/05/97 4:53p John
81  * First rev of new antialiased font stuff.
82  * 
83  * 1     6/02/97 4:04p John
84  *
85  * $NoKeywords: $
86  */
87
88 #include <windows.h>
89 #include <stdlib.h>
90 #include <stdlib.h>
91 #include <stdio.h>
92 #include <io.h>
93 #include <conio.h>
94
95 #include "pstypes.h"
96 #include "osapi.h"
97 #include "cfile.h"
98 #include "2d.h"
99 #include "key.h"
100 #include "mouse.h"
101 #include "palman.h"
102 #include "timer.h"
103 #include "bmpman.h"
104 #include "osregistry.h"
105
106 #include "fonttool.h"
107
108 char *SampleText = "This is some sample text that is here to\n" \
109 "Show you how the antialiasing will\n"  \
110 "look over different color backgrounds\n" \
111 "KERN PAIRS: VaWaVeWeVAV-LyT.T,TyTvTcYe\n";
112
113 static void myexit(int value)
114 {
115 //      getch();
116         exit(value);
117 }
118
119 int game_check_key()
120 {
121         return key_inkey();
122 }
123
124 int game_poll()
125 {
126         return key_inkey();
127 }
128
129 int os_done = 0;
130
131 void os_close()
132 {
133         os_done = 1;
134 }
135
136 int fonttool_get_kerning( font *fnt, int c1, int c2, int *pairnum )
137 {
138         int i;
139
140         int l1 = c1 - fnt->first_ascii;
141         int l2 = c2 - fnt->first_ascii;
142
143         for (i=0; i<fnt->num_kern_pairs; i++ )  {
144                 if ( (fnt->kern_data[i].c1 == l1) && (fnt->kern_data[i].c2 == l2) )     {
145                         if (pairnum) *pairnum = i;
146                         return fnt->kern_data[i].offset;
147                 }
148         }
149         return 0;
150 }
151
152 void fonttool_resync_kerning( font *fnt )
153 {
154         int i;
155
156         // update all the font into
157         for (i=0; i<fnt->num_chars; i++ )       {
158                 fnt->char_data[i].kerning_entry = -1;
159         }
160
161         for (i=0; i<fnt->num_kern_pairs; i++ )  {
162                 int c = fnt->kern_data[i].c1;
163                 if ( fnt->char_data[c].kerning_entry == -1 )
164                         fnt->char_data[c].kerning_entry = (short)i;
165         }
166 }
167
168 void fonttool_remove_kern_pair( font *fnt, int index )
169 {
170         // not found, add it
171         int i, n, new_num_pairs;
172
173         new_num_pairs = fnt->num_kern_pairs - 1;
174
175         if ( new_num_pairs < 1 )        {
176                 fonttool_remove_kerning(fnt);
177                 return;
178         }
179
180         font_kernpair *new_kern_data = (font_kernpair *)malloc( new_num_pairs*sizeof(font_kernpair) );
181         if (!new_kern_data)     {
182                 printf( "Out of memory!\n" );
183                 myexit(1);
184         }
185
186
187         n=0;
188         for (i=0; i<fnt->num_kern_pairs; i++ )  {
189                 if ( i != index )       {
190                         new_kern_data[n] = fnt->kern_data[i];
191                         n++;
192                 }
193         }
194
195         if ( fnt->kern_data ) free( fnt->kern_data );
196         fnt->kern_data = new_kern_data;
197         fnt->kern_data_size = sizeof(font_kernpair)*new_num_pairs;
198         fnt->num_kern_pairs = new_num_pairs;
199
200         fonttool_resync_kerning(fnt);
201
202         mprintf(( "Font has %d kern pairs\n", fnt->num_kern_pairs ));
203 }
204
205 void fonttool_set_kerning( font *fnt, int c1, int c2, int dist )
206 {
207         int i;
208
209         int l1 = c1 - fnt->first_ascii;
210         int l2 = c2 - fnt->first_ascii;
211
212         for (i=0; i<fnt->num_kern_pairs; i++ )  {
213                 if ( (fnt->kern_data[i].c1 == l1) && (fnt->kern_data[i].c2 == l2) )     {
214                         fnt->kern_data[i].offset = (signed char)dist;
215                         if ( dist == 0 )        {
216                                 fonttool_remove_kern_pair( fnt, i );                            
217                         }
218                         return;
219                 }
220         }
221         if ( dist == 0 )        return;
222
223         // not found, add it
224         int new_num_pairs;
225
226         new_num_pairs = fnt->num_kern_pairs+1;
227
228         font_kernpair *new_kern_data = (font_kernpair *)malloc( new_num_pairs*sizeof(font_kernpair) );
229         if (!new_kern_data)     {
230                 printf( "Out of memory!\n" );
231                 myexit(1);
232         }
233
234
235         int n=0;
236         uint newcode = l1*256+l2;
237
238         for (i=0; i<fnt->num_kern_pairs; i++ )  {
239                 uint code = fnt->kern_data[i].c1*256 + fnt->kern_data[i].c2;
240                 if ( code < newcode )   {
241                         new_kern_data[n] = fnt->kern_data[i];
242                         n++;
243                 } else {
244                         break;
245                 }
246         }
247
248
249         new_kern_data[n].c1 = (char)l1;
250         new_kern_data[n].c2 = (char)l2;
251         new_kern_data[n].offset = (signed char)dist;
252         n++;
253
254         
255         for (; i<fnt->num_kern_pairs; i++ )     {
256                 new_kern_data[n] = fnt->kern_data[i];
257                 n++;
258         }
259
260
261         if ( fnt->kern_data ) free( fnt->kern_data );
262         fnt->kern_data = new_kern_data;
263         fnt->kern_data_size +=  sizeof(font_kernpair);
264         fnt->num_kern_pairs++;
265
266         fonttool_resync_kerning(fnt);
267
268         mprintf(( "Font has %d kern pairs\n", fnt->num_kern_pairs ));
269
270 }
271
272
273 void fonttool_remove_kerning( font *fnt )
274 {
275         int i;
276
277         for (i=0; i<fnt->num_chars; i++ )       {
278                 fnt->char_data[i].kerning_entry = -1;
279         }
280
281         fnt->kern_data_size = 0;
282         if (fnt->kern_data)
283                 free( fnt->kern_data );
284         fnt->kern_data = NULL;
285         fnt->num_kern_pairs = 0;
286 }
287
288
289 void fonttool_edit_kerning(char *fname1)
290 {
291         int i, k,x;
292         int done;
293         int bkg;
294         font KernFont, tmpfont;
295         int alpha = 16;
296         int cr=16, cb=16, cg=16;
297         int c1 = 'b', c2 = 'u';
298         char kerntext[128];
299         int current_pair = -1;
300         int first_item = 0;
301         int current_item = 0;
302         int num_items_displayed = 1;
303         int last_good_pair = -1;
304         char *ptr;
305         color ac;
306         
307         printf( "Editing kerning data for %s\n", fname1 );
308         fonttool_read( fname1, &KernFont );
309
310         timer_init();
311
312         // setup the fred exe directory so CFILE can init properly
313         //char *c = GetCommandLine();
314         //Assert(c != NULL);
315         //char *tok = strtok(c, " ");
316         //Assert(tok != NULL);  
317         cfile_init(__argv[0]);
318
319         os_init( "FontTool", "FontTool - Kerning Table Editor" );
320         // init the registry
321         os_init_registry_stuff(Osreg_company_name, Osreg_app_name,NULL);
322         ptr = os_config_read_string(NULL, NOX("Videocard"), NULL);      
323         if((ptr == NULL) || !stricmp(ptr, "Aucune accélération 3D") || !stricmp(ptr, "Keine 3D-Beschleunigerkarte") || !stricmp(ptr, "No 3D acceleration")){
324                 MessageBox((HWND)os_get_window(), "Warning, Freespace 2 requires Glide or Direct3D hardware accleration. You will not be able to run Freespace 2 without it", "Warning", MB_OK);                
325                 exit(1);
326         }
327
328         if (!stricmp(ptr, NOX("3DFX Glide"))) {
329                 // Glide
330                 gr_init(GR_640, GR_GLIDE);
331         } else if (strstr(ptr, NOX("Direct 3D -"))){
332                 // Direct 3D
333                 gr_init(GR_640, GR_DIRECT3D);
334         } else {
335                 Int3();
336         }       
337
338         gr_set_palette("none",NULL);
339         bkg = bm_load( "code\\fonttool\\FontTool" );
340         if ( bkg < 0 )  {
341                 printf("Error loading FontTool\n" );
342                 myexit(1);
343         }
344         palette_use_bm_palette(bkg);
345
346         key_init();
347         mouse_init();
348
349         gr_init_alphacolor( &ac, cr*16,cg*16,cb*16,alpha*16 );
350         
351
352         {
353                 extern font *Current_font;
354                 Current_font = &KernFont;
355         }
356
357         done = 0;
358         while (!done)   {
359                 k = key_inkey();
360                 switch(k)       {               
361                 case KEY_F5:
362                         fonttool_read( fname1, &tmpfont );
363                         fonttool_copy_kern( &tmpfont, &KernFont );
364                         break;
365
366                 case KEY_F6:
367                         fonttool_remove_kerning( &KernFont );
368                         break;
369
370                 case KEY_F10:
371                         fonttool_dump( fname1, &KernFont );
372                         done=1;
373                         break;
374
375                 case KEY_COMMA:
376                         if ( alpha > 1 )        {
377                                 alpha--;
378                                 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16);
379                         }
380                         break;
381
382                 case KEY_PERIOD:
383                         if ( alpha < 17 )       {
384                                 alpha++;
385                                 gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16);
386                         }
387                         break;
388
389                 case KEY_R:
390                         if ( cr == 16 ) cr = 1; else cr = 16;
391                         gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16);
392                         break;
393
394                 case KEY_G:
395                         if ( cg == 16 ) cg = 1; else cg = 16;
396                         gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16);
397                         break;
398
399                 case KEY_B:
400                         if ( cb == 16 ) cb = 1; else cb = 16;
401                         gr_init_alphacolor(&ac,cr*16,cg*16,cb*16,alpha*16);
402                         break;
403
404                 case KEY_PAD6:
405                         x = fonttool_get_kerning( &KernFont, c1, c2, NULL );
406                         fonttool_set_kerning( &KernFont, c1, c2, x+1 );
407                         break;
408
409                 case KEY_PAD4:
410                         x = fonttool_get_kerning( &KernFont, c1, c2, NULL );
411                         fonttool_set_kerning( &KernFont, c1, c2, x-1 );
412                         break;
413
414                 case KEY_PAD5:
415                         fonttool_set_kerning( &KernFont, c1, c2, 0 );
416                         break;
417
418                 case KEY_PAD7:  
419                         if ( c1 < KernFont.first_ascii + KernFont.num_chars-1 ) c1++;
420                         break;
421
422                 case KEY_PAD1:  
423                         if ( c1 > KernFont.first_ascii ) c1--;
424                         break;
425
426                 case KEY_PAD9:  
427                         if ( c2 < KernFont.first_ascii + KernFont.num_chars-1 ) c2++;
428                         mprintf(( "C2 = %d\n", c2 ));
429                         break;
430
431                 case KEY_PAD3:  
432                         if ( c2 > KernFont.first_ascii ) c2--;
433                         mprintf(( "C2 = %d\n", c2 ));
434                         break;
435
436                 case KEY_PAD2:
437                         if ( current_pair < 0 ) 
438                                 current_pair = last_good_pair;
439                         else 
440                                 current_pair++;
441                         if ( current_pair >= KernFont.num_kern_pairs )  {
442                                 current_pair = KernFont.num_kern_pairs-1;
443                         }
444                         if ( (current_pair < KernFont.num_kern_pairs) && (current_pair > -1) )  {
445                                 c1 = KernFont.kern_data[current_pair].c1 + KernFont.first_ascii;
446                                 c2 = KernFont.kern_data[current_pair].c2 + KernFont.first_ascii;
447                         }
448                         break;
449
450                 case KEY_PAD8:
451                         if ( current_pair < 0 ) 
452                                 current_pair = last_good_pair;
453                         else
454                                 current_pair--;
455                         if ( current_pair < 0 ) {
456                                 current_pair = 0;
457                         }
458                         if ( (current_pair < KernFont.num_kern_pairs) && (current_pair > -1) )  {
459                                 c1 = KernFont.kern_data[current_pair].c1 + KernFont.first_ascii;
460                                 c2 = KernFont.kern_data[current_pair].c2 + KernFont.first_ascii;
461                         }
462                         break;
463
464                 case KEY_ESC:
465                         done=1;
466                         break;
467                 }
468
469                 if ( current_pair >= KernFont.num_kern_pairs )  {
470                         current_pair = -1;
471                 }
472
473                 int tmpp=-1;
474                 fonttool_get_kerning( &KernFont, c1, c2, &tmpp );
475
476                 if ( tmpp != -1 )       {
477                         current_pair = tmpp;
478                 } else  {
479                         if ( current_pair > -1 )
480                                 last_good_pair = current_pair;
481                         current_pair = -1;
482                 }
483         
484                 gr_reset_clip();
485                 gr_set_bitmap(bkg);
486                 gr_bitmap(0,0);
487                 gr_set_color_fast(&ac);
488
489                 sprintf( kerntext, "%c (%d)", c1, c1 );
490                 gr_string( 240, 210, kerntext );
491                 sprintf( kerntext, "%c (%d)", c2, c2 );
492                 gr_string( 340, 210, kerntext );
493
494                 sprintf( kerntext, "Ham%c%crger", c1, c2 );
495                 gr_string( 0x8000, 240, kerntext );
496
497                 sprintf( kerntext, "HAM%c%cRGER", c1, c2 );
498                 gr_string( 0x8000, 270, kerntext );
499
500                 sprintf( kerntext, "Offset: %d pixels", fonttool_get_kerning( &KernFont, c1, c2, NULL ) );
501                 gr_string( 0x8000, 300, kerntext );
502
503                 {
504                         int tw, th;
505                         gr_get_string_size( &tw, &th, kerntext );
506
507                         gr_string( 0x8000, 360, SampleText );
508                         gr_string( 20, 360+th+20, SampleText );
509                 }
510
511                 int x = 5, y = 200;
512                 int widest = 0;
513
514                  //= ( 330 - 200 ) / KernFont.h;
515                 int num_items = KernFont.num_kern_pairs;
516
517                 if ( current_pair > -1 )
518                         current_item = current_pair;
519
520                 if (current_item <0 )
521                         current_item = 0;
522
523                 if (current_item >= num_items )
524                         current_item = num_items-1;
525
526                 if (current_item<first_item)
527                         first_item = current_item;
528
529                 if (current_item>=(first_item+num_items_displayed))
530                         first_item = current_item-num_items_displayed+1;
531
532                 if (num_items <= num_items_displayed )  
533                         first_item = 0;
534
535                 int stop = first_item+num_items_displayed;
536                 if (stop>num_items) stop = num_items;
537
538                 int n = 0;
539                 for (i=first_item; i<stop; i++ )        {
540                         int tw, th;
541
542                         sprintf( kerntext, "%c%c", KernFont.kern_data[i].c1 + KernFont.first_ascii, KernFont.kern_data[i].c2 + KernFont.first_ascii );
543                         if ( i==current_pair )  {
544                                 gr_set_color( 255, 0, 0 );
545                                 //hud_tri( i2fl(x),i2fl(y), i2fl(x+6), i2fl(y+5), i2fl(x), i2fl(y+8) );
546                                 
547                                 int x1 = x;
548                                 int y1 = y;
549                                 int x2 = x+6;
550                                 int y2 = y+5;
551                                 int x3 = x;
552                                 int y3 = y+8;
553         
554                                 gr_line(x1,y1,x2,y2);
555                                 gr_line(x2,y2,x3,y3);
556                                 gr_line(x3,y3,x1,y1);
557
558                                 gr_set_color_fast(&ac);
559                         }
560                         gr_string( x+8, y, kerntext );
561                         n++;
562                         gr_get_string_size( &tw, &th, kerntext );
563                         tw += 8;
564                         if ( tw > widest )
565                                 widest = tw;
566                         y += KernFont.h;
567                         if ( y > 330 ) {
568                                 y = 200;
569                                 x += widest + 5;
570                                 if ( x > 150 ) {
571                                         num_items_displayed=n;
572                                         break;
573                                 }
574                                 widest = 0;
575                         }
576                 }
577                 if (i==stop)
578                         num_items_displayed++;
579
580                 if (num_items_displayed < 1 )
581                         num_items_displayed = 1;
582
583                 if (num_items_displayed > num_items )
584                         num_items_displayed = num_items;
585
586                 //mprintf(( "Num items = %d\n", num_items_displayed ));
587
588
589                 gr_flip();
590
591         }
592
593
594         exit(0);
595 }
596