OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [engine/] [selfont.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
3
 * Copyright (c) 2000 Morten Rolland
4
 *
5
 * Device-independent font selection routines
6
 */
7
/*#define NDEBUG*/
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <string.h>
11
#include <assert.h>
12
#include <ctype.h>              /* toupper*/
13
#include <string.h>
14
 
15
#include "device.h"
16
#if (UNIX | DOS_DJGPP)
17
#define strcmpi strcasecmp
18
#endif
19
 
20
#if FONTMAPPER
21
 
22
/* entry points*/
23
int select_font(const PMWLOGFONT plogfont, char *physname);
24
 
25
/*
26
 * The following structure, defines and variables are used to administrate
27
 * a set of fonts that are scanned when a font is requested.  The set of
28
 * fonts can be configured with the GdClearFontList and GdAddFont functions.
29
 */
30
 
31
struct available_font {
32
        MWLOGFONT       lf;
33
        char *foundry;
34
        char *family;
35
        char *fontname;
36
        int fontclass, alias;
37
        struct available_font *next;
38
};
39
 
40
static struct available_font *all_fonts = 0;
41
 
42
/*
43
 * Stupid little function to perform a comparison of two strings,
44
 * returning one of STREQ_EXACT, STREQ_CASE or STREQ_NOMATCH.
45
 */
46
#define STREQ_EXACT     0
47
#define STREQ_CASE      1
48
#define STREQ_NOMATCH   2
49
 
50
static int streq(const char *a, const char *b)
51
{
52
        int rc;
53
 
54
        for ( rc = STREQ_EXACT;  *a != 0; a++, b++ ) {
55
                if ( *a == *b )
56
                        continue;
57
                if ( toupper((unsigned char)*a) != toupper((unsigned char)*b) )
58
                        return STREQ_NOMATCH;
59
                rc = STREQ_CASE;
60
        }
61
        if ( *b != 0 )
62
                return STREQ_NOMATCH;
63
        return rc;
64
}
65
 
66
/*
67
 * Decode the "foundry" information into a MWLF_CLASS_ value denoting
68
 * which rendering system should be used to render the font.
69
 */
70
static int decode_font_class(const char *class)
71
{
72
        if ( class == NULL )
73
                return 0;
74
        if ( !strcmp("T1",class) )
75
                return MWLF_CLASS_T1LIB;
76
        if ( !strcmp("FT",class) )
77
                return MWLF_CLASS_FREETYPE;
78
        if ( !strcmp("MWF",class) )
79
                return MWLF_CLASS_BUILTIN;
80
        return 0;
81
}
82
 
83
/*
84
 * Try to find a font that matches the foundry and font name
85
 * requested.
86
 */
87
void test_font_naming(const char *foundry, const char *fontname,
88
                      struct available_font *af,
89
                      struct available_font **best, int *goodness)
90
{
91
        int penalty = 0;
92
 
93
        if ( foundry != 0 ) {
94
                if ( af->foundry != 0 ) {
95
                        switch ( streq(foundry,af->foundry) ) {
96
                                case STREQ_EXACT:
97
                                        break;
98
                                case STREQ_CASE:
99
                                        penalty += 2;
100
                                        break;
101
                                default:
102
                                        penalty += 8;
103
                                        break;
104
                        }
105
                } else {
106
                        penalty += 4;
107
                }
108
        }
109
 
110
        switch ( streq(fontname,af->fontname) ) {
111
                case STREQ_EXACT:
112
                        break;
113
                case STREQ_CASE:
114
                        penalty += 1;
115
                        break;
116
                default:
117
                        penalty += 16;
118
                        break;
119
        }
120
 
121
        if ( *goodness < 0 || penalty < *goodness ) {
122
                *best = af;
123
                *goodness = penalty;
124
        }
125
}
126
 
127
 
128
/*
129
 * The 'test_font_goodness' function attempts to find how suitable a font is
130
 * compared to a desired one.  The desired font is specified by:
131
 *
132
 *   foundry (can be NULL), family and the MWLOGFONT
133
 *   structure (can be NULL).
134
 *
135
 * If any fonts are configured, one will always be returned from here,
136
 * but the goodness may be very bad.  The goodness (or similarity)
137
 * factor is computed by adding up:
138
 */
139
 
140
#define GOODNESS_NO_FONTNAME            1000    /* No matching font-name found*/
141
#define GOODNESS_WEIGHT_DIFF            1       /* 0-900 for weight difference*/
142
 
143
#define GOODNESS_NO_FOUNDRY             100     /* No foundry */
144
 
145
#define GOODNESS_FOUNDRY_UNKNOWN        16      /* Foundry unknown */
146
#define GOODNESS_CASE_FAMILY            8
147
#define GOODNESS_CASE_FONTNAME          4
148
#define GOODNESS_CASE_FOUNDRY           2
149
#define GOODNESS_EXACT_FAMILY           1       /* Matched font family */
150
 
151
#define GOODNESS_EXACT_FOUNDRY          0        /* Clean match */
152
#define GOODNESS_EXACT_FONTNAME         0        /* Clean match */
153
 
154
#define GOODNESS_FAMILY_UNKNOWN         3000
155
#define GOODNESS_NOMATCH_FAMILY         10000
156
 
157
#define GOODNESS_EXACT_FONTFAMILY       0
158
#define GOODNESS_CASE_FONTFAMILY        32
159
#define GOODNESS_CLOSE_SLANT            128
160
#define GOODNESS_BAD_SLANT              256
161
#define GOODNESS_WRONG_SPACING          2048
162
 
163
#define GOODNESS_WRONG_SERIFSTYLE       1024
164
 
165
#define GOODNESS_WANTED_SMALLCAPS_NOT_AVAILABLE         4096
166
#define GOODNESS_ONLY_SMALLCAPS_AVAILABLE               8192
167
 
168
 
169
static int find_foundry_penalty(const struct available_font *have,
170
                         const char *foundry)
171
{
172
        if ( foundry == 0 )
173
                return 0;
174
 
175
        if ( have->foundry == 0 )
176
                return GOODNESS_FOUNDRY_UNKNOWN;
177
 
178
        switch ( streq(foundry,have->foundry) ) {
179
                case STREQ_EXACT:
180
                        return GOODNESS_EXACT_FOUNDRY;
181
                        break;
182
                case STREQ_CASE:
183
                        return GOODNESS_CASE_FOUNDRY;
184
                        break;
185
                default:
186
                        return GOODNESS_NO_FOUNDRY;
187
                        break;
188
        }
189
}
190
 
191
static int find_family_penalty(const struct available_font *have,
192
                               const char *family)
193
{
194
        if ( family == 0 )
195
                return 0;
196
 
197
        if ( have->family == 0 )
198
                return GOODNESS_FAMILY_UNKNOWN;
199
 
200
        switch ( streq(family,have->family) ) {
201
                case STREQ_EXACT:
202
                        return GOODNESS_EXACT_FAMILY;
203
                        break;
204
                case STREQ_CASE:
205
                        return GOODNESS_CASE_FAMILY;
206
                        break;
207
                default:
208
                        return GOODNESS_NOMATCH_FAMILY;
209
                        break;
210
        }
211
}
212
 
213
static int find_fontname_penalty(const struct available_font *have,
214
                                 const char *fontname)
215
{
216
        switch ( streq(have->fontname,fontname) ) {
217
                case STREQ_EXACT:
218
                        return GOODNESS_EXACT_FONTNAME;
219
                        break;
220
                case STREQ_CASE:
221
                        return GOODNESS_CASE_FONTNAME;
222
                        break;
223
                default:
224
                        break;
225
        }
226
 
227
        /* Test Fontname against font family name */
228
        if ( have->family != 0 ) {
229
                switch ( streq(have->family,fontname) ) {
230
                        case STREQ_EXACT:
231
                                return GOODNESS_EXACT_FONTFAMILY;
232
                                break;
233
                        case STREQ_CASE:
234
                                return GOODNESS_CASE_FONTFAMILY;
235
                                break;
236
                        default:
237
                                /* No suitable fontname found */
238
                                break;
239
                }
240
        }
241
        return GOODNESS_NO_FONTNAME;
242
}
243
 
244
static int find_weight_penalty(PMWLOGFONT want, PMWLOGFONT have)
245
{
246
        int weight_diff;
247
 
248
        weight_diff = want->lfWeight - have->lfWeight;
249
        if ( weight_diff < 0 )
250
                weight_diff = -weight_diff;
251
        return weight_diff * GOODNESS_WEIGHT_DIFF;
252
}
253
 
254
static int find_slant_penalty(PMWLOGFONT want, PMWLOGFONT have)
255
{
256
        /* See if slant is acceptable */
257
 
258
        if ( !want->lfItalic && !want->lfRoman && !want->lfOblique ) {
259
                /* Try to default to Romans if not specified */
260
                if ( have->lfItalic || have->lfOblique )
261
                        return GOODNESS_CLOSE_SLANT;
262
                return 0;
263
        }
264
 
265
        if ( want->lfItalic && have->lfItalic )
266
                return 0;
267
 
268
        if ( want->lfRoman && have->lfRoman )
269
                return 0;
270
 
271
        if ( want->lfOblique && have->lfOblique )
272
                return 0;
273
 
274
        /* No perfect match for the slant, try "closest" one */
275
 
276
        if ( want->lfItalic && have->lfOblique )
277
                return GOODNESS_CLOSE_SLANT;
278
 
279
        if ( want->lfOblique && have->lfItalic )
280
                return GOODNESS_CLOSE_SLANT;
281
 
282
        return GOODNESS_BAD_SLANT;
283
}
284
 
285
static int find_spacing_penalty(PMWLOGFONT want, PMWLOGFONT have)
286
{
287
        if ( want->lfProportional && have->lfProportional )
288
                return 0;
289
        if ( want->lfMonospace && have->lfMonospace )
290
                return 0;
291
        if ( want->lfMonospace || want->lfProportional )
292
                return GOODNESS_WRONG_SPACING;
293
 
294
        return 0;        /* No special desires */
295
}
296
 
297
static int find_serif_penalty(PMWLOGFONT want, PMWLOGFONT have)
298
{
299
        if ( !want->lfSerif && !want->lfSansSerif )
300
                return 0;
301
        if ( want->lfSerif && have->lfSerif )
302
                return 0;
303
        if ( want->lfSansSerif && have->lfSansSerif )
304
                return 0;
305
 
306
        return GOODNESS_WRONG_SERIFSTYLE;
307
}
308
 
309
static int find_smallcaps_penalty(PMWLOGFONT want, PMWLOGFONT have)
310
{
311
        if ( !want->lfSmallCaps && !have->lfSmallCaps )
312
                return 0;
313
        if ( want->lfSmallCaps && have->lfSmallCaps )
314
                return 0;
315
        if ( want->lfSmallCaps )
316
                return GOODNESS_WANTED_SMALLCAPS_NOT_AVAILABLE;
317
        return GOODNESS_ONLY_SMALLCAPS_AVAILABLE;
318
}
319
 
320
 
321
static void test_font_goodness(const char *foundry, const char *family,
322
                               const char *fontname, const PMWLOGFONT lf,
323
                               struct available_font *af,
324
                               struct available_font **best, int *goodness)
325
{
326
        int penalty = 0;
327
 
328
        penalty += find_foundry_penalty(af,foundry);
329
        penalty += find_family_penalty(af,family);
330
 
331
        /* Test Fontname, but only if there is no family */
332
        if ( family == 0 )
333
                penalty += find_fontname_penalty(af,fontname);
334
 
335
        if ( lf != 0 ) {
336
                /* Check logical font attributes */
337
                penalty += find_weight_penalty(lf,&af->lf);
338
                penalty += find_slant_penalty(lf,&af->lf);
339
                penalty += find_spacing_penalty(lf,&af->lf);
340
                penalty += find_serif_penalty(lf,&af->lf);
341
                penalty += find_smallcaps_penalty(lf,&af->lf);
342
        }
343
 
344
        /* See if this font is better than the previous one */
345
        if ( *goodness < 0 || penalty < *goodness ) {
346
                /* Yes, this font is better; change to it */
347
                *best = af;
348
                *goodness = penalty;
349
        }
350
}
351
 
352
static struct available_font *find_suitable_font(const char *foundry,
353
                                               const char *fontname,
354
                                               const PMWLOGFONT plogfont)
355
{
356
        struct available_font *af, *best;
357
        char *family;
358
        int goodness;
359
 
360
        /*
361
         * Try to find a font that matches the name specified as the
362
         * desired font (and foundry if possible).  If we find a
363
         * suitable font, we will use the family name when trying to
364
         * find a font that matches the MWLOGFONT attributes.  This
365
         * makes it possible to ask for an Italic version of
366
         * "Times Roman" and the expected thing will happen (get the
367
         * font "Times Italic").
368
         */
369
        goodness = -1;
370
        for ( af = best = all_fonts; af != 0; af = af->next ) {
371
                test_font_naming(foundry,fontname,af,&best,&goodness);
372
        }
373
        family = 0;
374
        if ( goodness != -1 ) {
375
                /* A font with a name that kind of matched was found,
376
                 * make a note of its family.  If it has no family, we
377
                 * can't make any use of the
378
                 */
379
                family = best->family;
380
        }
381
 
382
        /*
383
         * Try to find the closest font that matches the font family
384
         * we have established.  If no family was found above, all
385
         * fonts will be considered.
386
         */
387
        goodness = -1;
388
        for ( af = best = all_fonts; af != 0; af = af->next ) {
389
                test_font_goodness(foundry,family,fontname,plogfont,af,
390
                                   &best,&goodness);
391
        }
392
 
393
        return best;
394
}
395
 
396
 
397
int select_font(const PMWLOGFONT plogfont, char *physname)
398
{
399
        struct available_font *font;
400
        char fndry[128], *foundry;
401
        const char *fontname;
402
        char *tmp;
403
        int t, comma;
404
        int fontclass = 0;
405
        int found_font = 0;
406
 
407
        fontname = plogfont->lfFaceName;
408
 
409
        for ( t=0; t < 20; t++ ) {
410
                /* Only follow 20 aliases deep, assume failure if more ... */
411
 
412
                /* Find foundry for the current font */
413
                foundry = NULL;
414
                if ( (tmp = index(fontname,',')) != NULL ) {
415
                        /*
416
                         * We have a font name like T1,c0934345 or
417
                         * Adobe,Times (e.g. it includes foundry or
418
                         * rendering method).  Separate them here.
419
                         */
420
                        comma = tmp - fontname;
421
                        tmp++;
422
                        strncpy(fndry,fontname,comma);
423
                        fndry[comma] = '\0';
424
                        foundry = fndry;
425
                        fontname = tmp;
426
                }
427
 
428
                fontclass = decode_font_class(foundry);
429
 
430
                if ( plogfont == NULL && fontclass == 0 )
431
                        fontclass = MWLF_CLASS_BUILTIN;
432
 
433
                if ( fontclass ) {
434
                        /* The font is a "physical" font, use it directly */
435
                        strcpy(physname,fontname);
436
                        return fontclass;
437
                }
438
 
439
                if ( found_font ) {
440
                        /* Oops, should not get here, unless a font definition
441
                         * resulted in a non-existent font, e.g. the fontclass
442
                         * is unknown.
443
                         */
444
                        goto default_font;
445
                }
446
 
447
                font = find_suitable_font(foundry,fontname,plogfont);
448
 
449
                if ( font == NULL ) {
450
                        goto default_font;
451
                }
452
 
453
                if ( !font->alias )
454
                        found_font = 1;
455
 
456
                fontname = font->lf.lfFaceName;
457
        }
458
 
459
 default_font:
460
 
461
        strcpy(physname, MWFONT_SYSTEM_VAR);
462
        return MWLF_CLASS_BUILTIN;
463
}
464
 
465
/* This function can be used to clear the existing, possibly default list
466
 * of fonts on the system.  This is typically done before reading a
467
 * configuration file that defines the available fonts.
468
 */
469
void
470
GdClearFontList(void)
471
{
472
        struct available_font *font, *next_font;
473
 
474
        font = all_fonts;
475
        while ( font != 0 ) {
476
                next_font = font->next;
477
                if ( font->foundry != 0 )
478
                        free(font->foundry);
479
                if ( font->family != 0 )
480
                        free(font->family);
481
                free(font->fontname);
482
                free(font);
483
                font = next_font;
484
        }
485
 
486
        all_fonts = 0;
487
}
488
 
489
/* This function will add a font to the list of available fonts.
490
 * The physical name is the name as used by the underlying font
491
 * rendering engine.
492
 */
493
int
494
GdAddFont(char *fndry, char *fmly, char *fontname, PMWLOGFONT lf,
495
        unsigned int flags)
496
{
497
        struct available_font *font, *walk;
498
        int fontclass = 0;
499
        char *physname = lf->lfFaceName;
500
 
501
        if ( !strncmp(physname,"T1,",3) ) {
502
#ifdef HAVE_T1LIB_SUPPORT
503
                /* Can handle Type 1 fonts */
504
                physname += 3;
505
                fontclass = MWLF_CLASS_T1LIB;
506
                goto do_font;
507
#else
508
                /* Can't handle Type 1 fonts */
509
                return -1;
510
#endif
511
        }
512
 
513
        if ( !strncmp(physname,"FT,",3) ) {
514
#if HAVE_FREETYPE_SUPPORT
515
                /* Can handle FreeType fonts */
516
                physname += 3;
517
                fontclass = MWLF_CLASS_FREETYPE;
518
                goto do_font;
519
#else
520
                /* Can't handle Type 1 fonts */
521
                return -1;
522
#endif
523
        }
524
 
525
        if ( !strncmp(physname,"MWF,",4) ) {
526
                /* This is a Microwindows built in font */
527
                physname += 4;
528
                fontclass = MWLF_CLASS_BUILTIN;
529
                goto do_font;
530
        }
531
 
532
        /* Only aliases does not need to use T1, FT or MWF description */
533
        if ( !(flags & MWLF_FLAGS_ALIAS) )
534
                return -1;
535
 
536
 do_font:
537
 
538
        font = malloc(sizeof(*font));
539
        if ( font == 0 )
540
                return -1;
541
 
542
        font->foundry = 0;
543
        if ( strcmp("-",fndry) ) {
544
                font->foundry = strdup(fndry);
545
                if ( font->foundry == 0 ) {
546
                        free(font);
547
                        return -1;
548
                }
549
        }
550
 
551
        font->family = 0;
552
        if ( strcmp("-",fmly) ) {
553
                font->family = strdup(fmly);
554
                if ( font->family == 0 ) {
555
                        free(font->foundry);
556
                        free(font);
557
                        return -1;
558
                }
559
        }
560
 
561
        font->fontname = strdup(fontname);
562
        if ( font->fontname == 0 ) {
563
                free(font->foundry);
564
                free(font->family);
565
                free(font);
566
                return -1;
567
        }
568
 
569
        memcpy(&font->lf,lf,sizeof(*lf));
570
 
571
        printf("Adding font: '%s' '%s' '%s' '%s'\n",font->foundry,
572
               font->family,font->fontname,font->lf.lfFaceName);
573
 
574
        font->next = 0;
575
        font->alias = (flags & MWLF_FLAGS_ALIAS) ? 1 : 0;
576
        font->fontclass = fontclass;
577
 
578
        /* Stupid append at end of list code */
579
        if ( all_fonts == 0 ) {
580
                all_fonts = font;
581
        } else {
582
                for ( walk = all_fonts; walk->next != 0; walk = walk->next )
583
                        ;
584
                walk->next = font;
585
        }
586
 
587
        return 0;
588
}
589
 
590
/*
591
 * These functions are used to set attributes in a logical font
592
 * structure, called through a table of function pointers.
593
 */
594
static void font_set_light(PMWLOGFONT lf)
595
        { lf->lfWeight = MWLF_WEIGHT_LIGHT; }
596
static void font_set_regular(PMWLOGFONT lf)
597
        { lf->lfWeight = MWLF_WEIGHT_REGULAR; }
598
static void font_set_medium(PMWLOGFONT lf)
599
        { lf->lfWeight = MWLF_WEIGHT_MEDIUM; }
600
static void font_set_demibold(PMWLOGFONT lf)
601
        { lf->lfWeight = MWLF_WEIGHT_DEMIBOLD; }
602
static void font_set_bold(PMWLOGFONT lf)
603
        { lf->lfWeight = MWLF_WEIGHT_BOLD; }
604
static void font_set_black(PMWLOGFONT lf)
605
        { lf->lfWeight = MWLF_WEIGHT_BLACK; }
606
 
607
static void font_set_italic(PMWLOGFONT lf) { lf->lfItalic = 1; }
608
static void font_set_roman(PMWLOGFONT lf) { lf->lfRoman = 1; }
609
static void font_set_oblique(PMWLOGFONT lf) { lf->lfOblique = 1; }
610
 
611
static void font_set_normal(PMWLOGFONT lf)
612
        { lf->lfPitch = MWLF_PITCH_NORMAL; }
613
static void font_set_semicondensed(PMWLOGFONT lf)
614
        { lf->lfPitch = MWLF_PITCH_SEMICONDENSED; }
615
static void font_set_condensed(PMWLOGFONT lf)
616
        { lf->lfPitch = MWLF_PITCH_CONDENSED; }
617
 
618
static void font_set_serif(PMWLOGFONT lf) { lf->lfSerif = 1; }
619
static void font_set_sansserif(PMWLOGFONT lf) { lf->lfSansSerif = 1; }
620
static void font_set_monospace(PMWLOGFONT lf) { lf->lfMonospace = 1; }
621
static void font_set_proportional(PMWLOGFONT lf) { lf->lfProportional = 1; }
622
 
623
int config_font(char *file, int line, int argc, char *argv[])
624
{
625
        unsigned int flags = 0;
626
        MWLOGFONT lf;
627
        char tmp[512];
628
        char *p, *q, *fndry, *family, *fontname;
629
        int size, t;
630
 
631
        static struct {
632
                char *name;
633
                void (*function)(PMWLOGFONT lf);
634
        } attrs[] = {
635
                /* Weight */
636
                { "Light",              font_set_light },
637
                { "Regular",            font_set_regular },
638
                { "Medium",             font_set_medium },
639
                { "DemiBold",           font_set_demibold },
640
                { "Demibold",           font_set_demibold },
641
                { "Bold",               font_set_bold },
642
                { "Black",              font_set_black },
643
 
644
                /* Slant */
645
                { "Italic",             font_set_italic },
646
                { "Italics",            font_set_italic },
647
                { "Roman",              font_set_roman },
648
                { "Oblique",            font_set_oblique },
649
 
650
                /* Width */
651
                { "Normal",             font_set_normal },
652
                { "Semicondensed",      font_set_semicondensed },
653
                { "Condensed",          font_set_condensed },
654
 
655
                /* Class */
656
                { "Serif",              font_set_serif },
657
                { "Sans-serif",         font_set_sansserif },
658
                { "Monospace",          font_set_monospace },
659
                { "Proportional",       font_set_proportional },
660
 
661
                { 0, 0 }
662
        };
663
 
664
        MWLF_Clear(&lf);
665
 
666
        if ( argc != 6 ) {
667
                fprintf(stderr,"Bad font description %s:%d\n",file,line);
668
                return 1;
669
        }
670
 
671
        if ( !strcmp("alias",argv[1]) ) {
672
                flags |= MWLF_FLAGS_ALIAS;
673
                fndry = "-";
674
        } else {
675
                fndry = argv[1];
676
        }
677
 
678
        family = argv[2];
679
        fontname = argv[3];
680
        strcpy(lf.lfFaceName,argv[5]);
681
        p = argv[4];
682
 
683
        while ( *p != '\0' ) {
684
                /* Parse attributes */
685
                q = strchr(p,',');
686
                if ( q != 0 ) {
687
                        size = q - p;
688
                        strncpy(tmp,p,size);
689
                        tmp[size] = '\0';
690
                        p = q + 1;
691
                } else {
692
                        strcpy(tmp,p);
693
                        p += strlen(tmp);
694
                }
695
 
696
                for ( t = 0; attrs[t].name != 0; t++ ) {
697
                        if ( !strcmp(attrs[t].name,tmp) ) {
698
                                attrs[t].function(&lf);
699
                                goto next;
700
                        }
701
                }
702
 
703
                fprintf(stderr,"No such font attribute '%s' in %s:%d\n",
704
                        tmp,file,line);
705
                return 1;
706
 
707
        next: ;
708
        }
709
 
710
        GdAddFont(fndry,family,fontname,&lf,flags);
711
 
712
        return 0;
713
}
714
 
715
/*
716
 * Handle a single configuration line entery.  Arguments as for
717
 * function 'main(int argc, char **argv)' -- argv[0] is name of
718
 * original configuration file.  Return negative value for error,
719
 * zero for OK.
720
 */
721
 
722
int config_line(char *file, int line, int argc, char *argv[])
723
{
724
        if ( !argc )
725
                return 0;        /* Empty line */
726
 
727
        if ( argv[0][0] == '#' )
728
                return 0;        /* Comment line */
729
 
730
        if ( !strcmp("font", argv[0]) )
731
                return config_font(file,line,argc,argv);
732
 
733
        if ( !strcmp("clear-fonts", argv[0]) ) {
734
                GdClearFontList();
735
                return 0;
736
        }
737
 
738
        return -1;
739
}
740
 
741
 
742
/*
743
 * Read (one of) the configuration files.
744
 */
745
#define MAXCONFIGLINESIZE       1024
746
#define MAXCONFIGELEMENTS         64
747
 
748
int read_configfile(char *file)
749
{
750
        FILE *cf;
751
        char buffer[MAXCONFIGLINESIZE+1];
752
        char *args[MAXCONFIGELEMENTS+1];
753
        unsigned char *p;
754
        int argc, s, rc, t, line;
755
 
756
        if ( (cf = fopen(file,"r")) == 0 ) {
757
                fprintf(stderr,"Unable to read config file '%s'\n",file);
758
                return -1;
759
        }
760
 
761
        line = 0;
762
        while ( !feof(cf) ) {
763
                if ( fgets(buffer,1000,cf) == 0 )
764
                        break;
765
                line++;
766
                s = strlen(buffer) - 1;
767
                while ( s >= 0 && buffer[s] == '\n' )
768
                        buffer[s--] = '\0';
769
                p = (unsigned char *)buffer;
770
                argc = 0;
771
                for ( t=0; t < MAXCONFIGELEMENTS; t++ ) {
772
                        while ( *p != '\0' && isspace(*p) )
773
                                p++;
774
                        if ( *p == '\"' ) {
775
                                /* Quoted string */
776
                                p++;
777
                                args[t] = p;
778
                                argc++;
779
                                while ( *p != '\0' && *p != '\"' )
780
                                        p++;
781
                                if ( *p == '\0' ) {
782
                                        fprintf(stderr,"Unbalanced quotes in %s:%d\n",
783
                                                file,line);
784
                                        break;
785
                                }
786
                                *p++ = '\0';
787
                        } else {
788
                                if ( *p == '\0' )
789
                                        break;
790
                                args[t] = p;
791
                                argc++;
792
                                while ( *p != '\0' && !isspace(*p) )
793
                                        p++;
794
                                *p++ = '\0';
795
                        }
796
                }
797
#if 0
798
                {
799
                        int t;
800
                        for ( t=0; t < argc; t++ )
801
                                printf("#%d: '%s'\n",t,args[t]);
802
                }
803
#endif
804
                rc = config_line(file, line, argc, args);
805
                if ( rc < 0 )
806
                        return rc;
807
        }
808
 
809
        fclose(cf);
810
 
811
        return 0;
812
}
813
#endif /* FONTMAPPER*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.