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