rtoss - Blame information for rev 320

Subversion Repositories:
Rev:
Rev Author Line No. Line
317 roytam 1 /* vim:set ts=8 sts=4 sw=4 tw=0: */
2 /*
3  * bdf.c -
4  *
5  * Written By:  MURAOKA Taro <koron@tka.att.ne.jp>
6  * Last Change: 09-Oct-2003.
7  */
8  
9 //#define USE_FLEXIBLE_GLYPHWIDTH
10  
11 #ifndef UCS_TABLEDIR
12 # define UCS_TABLEDIR "ucstable.d"
13 #endif
14 #define USE_PIXELSIZE
15  
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <ctype.h>
20  
21 #include "bdf.h"
22 #include "ucsconv.h"
23 #include "debug.h"
24  
25 #define RAS_BYTE(nbit) (((nbit) + 7) >> 3)
26  
27 /* Count up entries in the array */
28 #ifndef elementof
29 # define elementof(a) (sizeof(a) / sizeof(a[0]))
30 #endif
31  
32 /* Define _MAX_PATH if wasn't defined. */
33 #ifndef _MAX_PATH
34 # if defined(FILENAME_MAX)
35 #  define _MAX_PATH FILENAME_MAX
36 # endif
37 #endif
38  
39 #ifdef _WIN32
40 # define QSORT_CALLBACK __cdecl
41 #else
42 # define QSORT_CALLBACK
43 #endif
44  
45 typedef struct
46 {
320 roytam 47         char*   name;
48         unsigned char width;
317 roytam 49 } width_table_t;
50  
51 static width_table_t cell_width_table[] = {
320 roytam 52         { "JISX0208",   2 },
53         { "JISX0212",   2 },
54         { "JISX0213",   2 },
55         { "KSX1001",    2 },
56         { NULL,         0 },
317 roytam 57 };
58  
59 static int      bdf_load_fh(bdf_t* font, FILE* fp);
60 static void     count_validglyph(bdf_t* font);
61 static bdf_glyph_t*     glyph_open();
62 static void             glyph_close(bdf_glyph_t *glyph);
63 static char*    iscmd(char* target, char* keyword);
64 static int      atoi_next(char** str);
65 static int      hex2n(char ch);
66 static int      hex2byte(char *str);
67 static void     chomp(char* str);
68 static int      check_bdfsize(char* filename);
69  
320 roytam 70         bdf_t*
317 roytam 71 bdf_open()
72 {
320 roytam 73         bdf_t *font;
317 roytam 74  
320 roytam 75         font = (bdf_t*)calloc(1, sizeof(*font));
76         font->indexFirst = -1;
77         font->indexLast  = -1;
78         memset(font->cell_width, 1, sizeof(font->cell_width));
79         return font;
317 roytam 80 }
81  
320 roytam 82         void
317 roytam 83 bdf_close(bdf_t *font)
84 {
320 roytam 85         if (font)
86         {
87                 int i;
317 roytam 88  
320 roytam 89                 for (i = 0; i < BDF_MAX_GLYPH; ++i)
90                 {
91                         if (font->glyph[i])
92                         glyph_close(font->glyph[i]);
93                 }
94                 free(font);
317 roytam 95         }
96 }
97  
320 roytam 98         bdf_glyph_t*
317 roytam 99 bdf_get_glyph(bdf_t* font, int id)
100 {
320 roytam 101         return font ? font->glyph[id] : NULL;
317 roytam 102 }
103  
320 roytam 104         int
317 roytam 105 bdf_get_pixel_glyph(bdf_glyph_t* glyph, int x, int y)
106 {
320 roytam 107         if (glyph && x >= 0 && y >= 0
108                 && x < glyph->bbx.width
109                 && y < glyph->bbx.height
110                 && glyph->bitmap
111            )
112         {
113                 int base = RAS_BYTE(glyph->bbx.width) * y;
114                 return glyph->bitmap[base + (x / 8)] & (0x80 >> (x % 8))
115                         ? 1 : 0;
116         }
117         return -1;
317 roytam 118 }
119  
320 roytam 120         int
317 roytam 121 bdf_get_pixel(bdf_t * font, int id, int x, int y)
122 {
320 roytam 123         if (font)
124         {
125                 bdf_glyph_t* glyph = bdf_get_glyph(font, id);
126                 return bdf_get_pixel_glyph(glyph, x, y);
127         }
128         return -1;
317 roytam 129 }
130  
320 roytam 131         static bdf_glyph_t *
317 roytam 132 glyph_open(int width, int height)
133 {
320 roytam 134         bdf_glyph_t * glyph;
135         size_t size;
317 roytam 136  
320 roytam 137         glyph = (bdf_glyph_t*)calloc(1, sizeof(*glyph));
138         size = RAS_BYTE(width) * height;
139         glyph->bitmap = (bdf_byte_t*)calloc(size, sizeof(bdf_byte_t));
140         return glyph;
317 roytam 141 }
142  
320 roytam 143         static void
317 roytam 144 glyph_close(bdf_glyph_t *glyph)
145 {
320 roytam 146         if (glyph)
147         {
148                 if (glyph->bitmap)
149                         free(glyph->bitmap);
150                 free(glyph);
151         }
317 roytam 152 }
153  
320 roytam 154         static char*
317 roytam 155 skipspace(char* str)
156 {
320 roytam 157         while (isspace(*str))
158                 ++str;
159         return str;
317 roytam 160 }
161  
320 roytam 162         static char*
317 roytam 163 iscmd(char* target, char* keyword)
164 {
320 roytam 165         size_t len = strlen(keyword);
166         return strncmp(target, keyword, len) == 0 && !isgraph(target[len])
317 roytam 167         ? skipspace(target + len) : NULL;
168 }
169  
320 roytam 170         void
317 roytam 171 chomp(char* str)
172 {
320 roytam 173         int len = strlen(str) - 1;
174         for (; len >= 0 && isspace(str[len]); --len)
175                 str[len] = '\0';
317 roytam 176 }
177  
320 roytam 178         int
317 roytam 179 atoi_next(char** str)
180 {
320 roytam 181         int retval = atoi(*str);
182         while (isdigit(**str))
183                 ++*str;
184         *str = skipspace(*str);
185         return retval;
317 roytam 186 }
187  
320 roytam 188         int
317 roytam 189 hex2n(char ch)
190 {
320 roytam 191         if (ch >= '0' && ch <= '9')
192                 return (int)(ch - '0');
193         else if (ch >= 'a' && ch <= 'f')
194                 return (int)(ch - 'a' + 10);
195         else if (ch >= 'A' && ch <= 'F')
196                 return (int)(ch - 'A' + 10);
197         else
198                 return 0;
317 roytam 199 }
200  
320 roytam 201         int
317 roytam 202 hex2byte(char *str)
203 {
320 roytam 204         return (hex2n(str[0]) << 4) + hex2n(str[1]);
317 roytam 205 }
206  
320 roytam 207         void
317 roytam 208 count_validglyph(bdf_t* font)
209 {
320 roytam 210         int i;
317 roytam 211  
320 roytam 212         font->numGlyph = 0;
213         for (i = 0; i < BDF_MAX_GLYPH; ++i)
214                 if (font->glyph[i])
215                 {
216                         font->glyph[i]->id = font->numGlyph;
217                         ++font->numGlyph;
317 roytam 218  
320 roytam 219                         if (font->indexFirst < 0)
220                                 font->indexFirst = i;
221                         font->indexLast = i;
222                 }
317 roytam 223 }
224  
320 roytam 225         static char*
319 roytam 226 parse_FONT_backend(char* cmd, int c)
317 roytam 227 {
320 roytam 228         /* int c = 13; */
229         int len;
317 roytam 230  
320 roytam 231         while (c && *cmd)
317 roytam 232         if (*cmd++ == '-')
320 roytam 233                 --c;
234         len = strlen(cmd);
235         if (len > 0)
317 roytam 236         {
320 roytam 237                 int i;
317 roytam 238  
320 roytam 239                 for (i = 0; i < len; ++i)
317 roytam 240                 {
320 roytam 241                         if (cmd[i] == '.')
242                         {
243                                 /* Remove year notification, and plane 0 */
244                                 int j, n;
245  
246                                 for (j = i + 1; cmd[j] != '\0' && cmd[j] != '-'; ++j)
247                                         ;
248                                 if (cmd[j] == '-' && (n = atoi(&cmd[j + 1])) > 0)
249                                 {
250                                         while (cmd[j] != '\0')
251                                                 cmd[i++] = cmd[j++];
252                                 }
253                                 cmd[i] = '\0';
254                                 break;
255                         }
256                         cmd[i] = toupper(cmd[i]);
317 roytam 257                 }
320 roytam 258                 /* Remove prefix "ISO", if exists. */
259                 if (strncmp(cmd, "ISO", 3) == 0)
260                         cmd += 3;
317 roytam 261         }
320 roytam 262         return cmd;
317 roytam 263 }
264  
320 roytam 265         static char*
319 roytam 266 parse_FONT(char* cmd)
267 {
320 roytam 268         return parse_FONT_backend(cmd, 13);
319 roytam 269 }
270  
320 roytam 271         static char*
319 roytam 272 removeQuote(char* str)
273 {
320 roytam 274         size_t len;
275         char *noQuotes;
276         size_t i, j;
277         len = strlen(str);
278         j = 0;
279         noQuotes = (char*)malloc(str);
280         if(str[0] != '"') {
281                 noQuotes[j++] = str[0];
282         }
283         for(i = 1; i < len; i++){
284                 if(str[i] == '"' && str[i-1] != '\\')
285                         continue;
286                 noQuotes[j++] = str[i];
287         }
288         return noQuotes;
319 roytam 289 }
290  
320 roytam 291         static ucsconv_t*
317 roytam 292 init_conv(char* encname, ucsconv_t** pconv)
293 {
320 roytam 294         ucsconv_t *conv;
317 roytam 295  
320 roytam 296         if (conv = ucsconv_open())
297         {
298                 int i;
299                 char *postfix[] = { ".TXT", ".WIN.TXT" };
300                 int loaded = 0;
317 roytam 301  
320 roytam 302                 /* Generate encode table filename */
303                 for (i = 0; i < elementof(postfix); ++i)
304                 {
305                         int n;
306                         char encfile[_MAX_PATH];
307                         char *env = getenv("UCSTABLEDIR");
308                         sprintf(encfile, "%s/%s%s", env ? env : UCS_TABLEDIR,
309                                 encname, postfix[i]);
310                         n = ucsconv_load(conv, encfile);
311                         loaded += n;
317 roytam 312 #if 0
320 roytam 313                         printf ("  [%d] %s (%d)\n", i, encfile, n);
317 roytam 314 #endif
320 roytam 315                 }
316                 if (loaded == 0)
317                 {
318                         ucsconv_close(conv);
319                         conv = NULL;
320                 }
317 roytam 321         }
320 roytam 322  
323         if (pconv)
317 roytam 324         {
320 roytam 325                 if (*pconv)
326                         ucsconv_close(*pconv);
327                 *pconv = conv;
317 roytam 328         }
320 roytam 329         return conv;
317 roytam 330 }
331  
332 /*
333  * Return 1 if succeeded.
334  * Return -SIZE if failed.
335  */
320 roytam 336         int
317 roytam 337 bdf_load_fh(bdf_t * font, FILE* fp)
338 {
320 roytam 339         bdf_glyph_t tmp, *ptmp = NULL;
340         int predat = 1;
341         int encnum = 0;
342         int ras = 0, line = 0;
343         char buf[8192], *cmd;
344         ucsconv_t* conv = NULL;
345         unsigned char cell_width = 1;
317 roytam 346  
320 roytam 347         memset(&tmp, 0, sizeof(tmp));
348         while (fgets(buf, sizeof(buf), fp))
317 roytam 349         {
320 roytam 350                 chomp(buf);
351                 if (predat)
317 roytam 352                 {
320 roytam 353                         /* Pre data section parser */
354                         if (cmd = iscmd(buf, "CHARS"))
355                                 predat = 0;
356                         else if (cmd = iscmd(buf, "SIZE"))
357                         {
358                                 int size = atoi_next(&cmd);
359                                 if (font->size != size)
360                                 {
361                                         if (font->verbose > 0)
362                                                 fprintf(stderr,
363                                                         "WARNING: SIZE was changed (%d -> %d)\n",
364                                                         font->size, size);
365                                         if (font->size < size)
366                                                 font->size = size;
367                                 }
368                         }
369                         else if (cmd = iscmd(buf, "PIXEL_SIZE"))
370                         {
371                                 int pixel_size = atoi_next(&cmd);
372                                 font->pixel_size = pixel_size;
373                         }
374                         else if (cmd = iscmd(buf, "FONTBOUNDINGBOX"))
375                         {
376                                 font->bbx.width = atoi_next(&cmd);
377                                 font->bbx.height = atoi_next(&cmd);
378                                 font->bbx.offset.x = atoi_next(&cmd);
379                                 font->bbx.offset.y = atoi_next(&cmd);
380                         }
381                         else if (cmd = iscmd(buf, "FONT"))
382                         {
383                                 if (cmd = parse_FONT(cmd))
384                                 {
385                                         width_table_t *p;
317 roytam 386  
320 roytam 387                                         TRACE("bdf_load: [#F] encoding is %s\n", cmd);
388                                         init_conv(cmd, &conv);
389                                         for (p = cell_width_table; p->name != NULL; ++p)
390                                                 if (strcmp(p->name, cmd) == 0)
391                                                         break;
392                                         if (p->name != NULL)
393                                                 cell_width = p->width;
394                                 }
395                                 else if (conv)
396                                 {
397                                         TRACE("bdf_load: disable usc #F\n");
398                                         ucsconv_close(conv);
399                                         conv = NULL;
400                                 }
401                         }
402                         else if (cmd = iscmd(buf, "CHARSET_REGISTRY"))
403                         {
404                                 char* charset_name = removeQuote(cmd);
405                                 TRACE("bdf_load: get CHARSET_REGISTRY = %s\n", charset_name);
406                                 if ((cmd = parse_FONT_backend(charset_name, 0)) && !conv)
407                                 {
408                                         width_table_t *p;
409  
410                                         TRACE("bdf_load: [#CR] encoding is %s\n", cmd);
411                                         init_conv(cmd, &conv);
412                                         for (p = cell_width_table; p->name != NULL; ++p)
413                                                 if (strcmp(p->name, cmd) == 0)
414                                                         break;
415                                         if (p->name != NULL)
416                                                 cell_width = p->width;
417                                 }
418                                 /*else if (conv)
419                                 {
420                                         TRACE("bdf_load: disable usc #CR\n");
421                                         ucsconv_close(conv);
422                                         conv = NULL;
423                                 }*/
424                                 free(charset_name);
425                         }
426                         else if (cmd = iscmd(buf, "FONT_ASCENT"))
427                                 font->ascent = atoi(cmd);
428                         else if (cmd = iscmd(buf, "FONT_DESCENT"))
429                                 font->descent = atoi(cmd);
317 roytam 430                 }
320 roytam 431                 else if (ptmp)
317 roytam 432                 {
320 roytam 433                         /* Parse bitmap */
434                         if (cmd = iscmd(buf, "ENDCHAR"))
435                         {
436                                 if (encnum >= 0)
437                                 {
438                                         if (font->glyph[encnum])
439                                                 glyph_close(font->glyph[encnum]);
440                                         font->glyph[encnum] = ptmp;
441                                         //font->cell_width[encnum] = cell_width;
442                                         font->glyph_dwidth[encnum] = ptmp->dwidth.x;
443                                         font->cell_width[encnum] = ptmp->dwidth.x > (font->size / 2)
444                                         ? 2 : 1;
445                                 }
446                                 else
447                                         glyph_close(ptmp);
448                                 ptmp = NULL;
449                         }
450                         else
451                         {
452                                 int i;
453                                 bdf_byte_t *p = ptmp->bitmap + ras * line;
454 #if 0
455                                 if (line == 5)
456                                 {
457                                         fprintf(stderr, "(%s)", buf);
458                                         for (i = 0; i < ras; ++i)
459                                         fprintf(stderr, " %02X", hex2byte(buf + i * 2));
460                                         fprintf(stderr, "\n");
461                                 }
462 #endif
463                                 for (i = 0; i < ras; ++i)
464                                         p[i] = hex2byte(buf + i * 2);
465                                 ++line;
466                         }
317 roytam 467                 }
320 roytam 468                 /* Parse font glyph headers */
469                 else if (cmd = iscmd(buf, "ENCODING"))
319 roytam 470                 {
320 roytam 471                         /* Convert encondig in UCS.  When encondig wasn't converted, use
472                          * original value */
473                         encnum = atoi(cmd);
474                         if (conv)
475                         {
476                                 int convnum = (int)ucsconv_toUCS(conv, (ucschar_t)encnum);
477 #if 0
478                                 TRACE("bdf_load: ucs %04x => %04x\n", encnum, convnum);
479 #endif
319 roytam 480  
320 roytam 481                                 if (convnum)
482                                         encnum = convnum;
483                                 else
484                                 {
485                                         char *filename = "STREAM";
486                                         if (font->loadingFilename)
487                                                 filename = font->loadingFilename;
488                                         if (font->verbose > 0)
489                                         {
490                                                 fprintf(stderr, "%04x can't convert to UCS (%s)\n",
491                                                         encnum, filename);
492                                         }
493                                         encnum = -1;
494                                 }
495                         }
319 roytam 496                 }
320 roytam 497                 else if (cmd = iscmd(buf, "SWIDTH"))
319 roytam 498                 {
320 roytam 499                         tmp.swidth.x = atoi_next(&cmd);
500                         tmp.swidth.y = atoi_next(&cmd);
501                 }
502                 else if (cmd = iscmd(buf, "DWIDTH"))
317 roytam 503                 {
320 roytam 504                         tmp.dwidth.x = atoi_next(&cmd);
505                         tmp.dwidth.y = atoi_next(&cmd);
317 roytam 506                 }
320 roytam 507                 else if (cmd = iscmd(buf, "BBX"))
317 roytam 508                 {
320 roytam 509                         tmp.bbx.width = atoi_next(&cmd);
510                         tmp.bbx.height = atoi_next(&cmd);
511                         tmp.bbx.offset.x = atoi_next(&cmd);
512                         tmp.bbx.offset.y = atoi_next(&cmd);
317 roytam 513                 }
320 roytam 514                 else if (cmd = iscmd(buf, "BITMAP"))
515                 {
516                         ptmp = glyph_open(tmp.bbx.width, tmp.bbx.height);
517                         tmp.bitmap = ptmp->bitmap;
518                         *ptmp = tmp;
319 roytam 519  
320 roytam 520                         ras = RAS_BYTE(ptmp->bbx.width);
521                         line = 0;
317 roytam 522                 }
523         }
320 roytam 524         if (font->pixel_size == 0)
317 roytam 525         {
320 roytam 526                 font->pixel_size = font->size;
527                 fprintf(stderr, "bdf_load: PIXEL_SIZE was not found, use %d\n", font->size);
317 roytam 528         }
320 roytam 529         /* Remove a glyph for charcode 0 */
530         if (font->glyph[0])
317 roytam 531         {
320 roytam 532                 glyph_close(font->glyph[0]);
533                 font->glyph[0] = NULL;
317 roytam 534         }
320 roytam 535         /* Caliculate glyph statistics information */
536         count_validglyph(font);
537         return 1;
317 roytam 538 }
539  
320 roytam 540         int
317 roytam 541 bdf_load(bdf_t* font, char* filename)
542 {
320 roytam 543         FILE *fp;
544         int retval = 0;
317 roytam 545  
320 roytam 546         if (!font)
547                 return retval;
548         fp = fopen(filename, "rb");
549         if (fp)
550         {
551                 font->loadingFilename = filename;
552                 retval = bdf_load_fh(font, fp);
553                 font->loadingFilename = NULL;
554                 fclose(fp);
555         }
317 roytam 556         return retval;
557 }
558  
559 /*****************************************************************************
560  * BDF2
561  *****************************************************************************/
562  
320 roytam 563         bdf2_t*
317 roytam 564 bdf2_open()
565 {
320 roytam 566         bdf2_t *font;
567         int i;
317 roytam 568  
320 roytam 569         font = (bdf2_t*)calloc(1, sizeof(*font));
570         for (i = 0; i < BDF_MAX_GLYPH; ++i)
571         {
572                 font->glyph_id[i] = -1;
573                 font->glyph_width[i] = 1;
574         }
317 roytam 575  
320 roytam 576         return font;
317 roytam 577 }
578  
320 roytam 579         void
317 roytam 580 bdf2_close(bdf2_t* font)
581 {
320 roytam 582         if (!font)
583                 return;
584         while (font->list)
585         {
586                 bdf_list_t *next = font->list->next;
587  
588                 bdf_close(font->list->bdf);
589                 free(font->list);
590                 font->list = next;
591         }
592         if (font->sizelist)
593         {
594                 free(font->sizelist);
595                 font->sizelist = NULL;
596         }
597         free(font);
317 roytam 598         return;
599 }
600  
320 roytam 601         int
317 roytam 602 check_bdfsize(char* filename)
603 {
320 roytam 604         FILE *fp;
317 roytam 605  
320 roytam 606         fp = fopen(filename, "rb");
607         if (!fp)
608                 return 0;
609         else
610         {
611                 int     pixel_size = 0;
612                 int     size = 0;
613                 char    buf[8192], *cmd;
317 roytam 614  
320 roytam 615                 while (fgets(buf, sizeof(buf), fp))
616                 {
617                         chomp(buf);
618                         if (cmd = iscmd(buf, "SIZE"))
619                                 size = atoi_next(&cmd);
317 roytam 620 #ifdef USE_PIXELSIZE
320 roytam 621                         else if (cmd = iscmd(buf, "PIXEL_SIZE"))
622                         {
623                                 pixel_size = atoi_next(&cmd);
624                                 break;
625                         }
317 roytam 626 #endif
320 roytam 627                 }
628                 fclose(fp);
317 roytam 629 #ifdef USE_PIXELSIZE
320 roytam 630                 return pixel_size > 0 ? pixel_size : size;
317 roytam 631 #else
320 roytam 632                 return size;
317 roytam 633 #endif
320 roytam 634         }
317 roytam 635 }
636  
320 roytam 637         int QSORT_CALLBACK
317 roytam 638 numsort(const void* a, const void* b)
639 {
320 roytam 640         int *pa = (int*)a;
641         int *pb = (int*)b;
317 roytam 642  
320 roytam 643         return *pa - *pb;
317 roytam 644 }
645  
320 roytam 646         int
317 roytam 647 bdf2_load(bdf2_t* font, char* filename)
648 {
320 roytam 649         int size;
650         bdf_t *bdf;
651         int newsize = 0;
652         int retval;
653         int i;
317 roytam 654  
320 roytam 655         size = check_bdfsize(filename);
656         TRACE("bdf2_load: size=%d\n", size);
657         if (size <= 0)
658         {
659                 fprintf(stderr, "check_bdfsize(%s) returns %d\n", filename, size);
660                 return 0;
661         }
662         bdf = bdf2_get_bdf1(font, size);
663         /*
664          * If not exists BDF in that size, create new and set no zero value for
665          * newsize
666          */
667         if (!bdf)
668         {
669                 bdf_list_t *list;
317 roytam 670  
320 roytam 671                 list = (bdf_list_t*)malloc(sizeof(*list));
672                 list->bdf = bdf = bdf_open();
673                 bdf->verbose = font->verbose;
674                 list->next = font->list;
675                 font->list = list;
676                 ++font->count;
677                 newsize = size;
678                 TRACE("bdf2_load: create a font size %d\n", newsize);
679         }
680         retval = bdf_load(bdf, filename);
681         if (retval != 1)
682         {
683                 /* Unexpected error!  This'll not be caused */
684                 fprintf(stderr, "bdf2_load: bdf_load(%p, %s) return %d\n",
685                         bdf, filename, retval);
686                 return retval;
687         }
317 roytam 688  
320 roytam 689         /* Check glyph existance */
690         font->numGlyph  = 0;
691         font->indexFirst        = -1;
692         font->indexLast = -1;
693         for (i = 0; i < BDF_MAX_GLYPH; ++i)
317 roytam 694         {
320 roytam 695                 bdf_glyph_t *g = bdf_get_glyph(bdf, i);
696                 if (g)
697                 {
698                         font->glyph_flag[i] |= BDF2GF_AVAILABLE;
317 roytam 699 #ifdef USE_FLEXIBLE_GLYPHWIDTH
320 roytam 700                         if (font->glyph_width[i] != 2 && g->bbx.width > (size / 2))
701                         {
702                                 /* Multi cell glyph has always 2 cell */
703                                 font->glyph_width[i] = 2;
704                                 font->has_multicell = 1;
705                                 //TRACE("i=%d s=%d w=%d\n", i, size, g->bbx.width);
706                         }
317 roytam 707 #else
320 roytam 708                         font->glyph_width[i] = 1;
317 roytam 709 #endif
320 roytam 710                 }
711                 if (font->glyph_flag[i] & BDF2GF_AVAILABLE)
712                 {
713                         font->glyph_id[i] = font->numGlyph;
714                         ++font->numGlyph;
715                         if (font->indexFirst < 0)
716                                 font->indexFirst = i;
717                         font->indexLast = i;
718                 }
719                 else
720                         font->glyph_id[i] = -1;
317 roytam 721         }
320 roytam 722         TRACE("bdf2_load: numGlyph=%d\n", font->numGlyph);
723         /* Add size in the sizelist */
724         if (newsize > 0)
317 roytam 725         {
320 roytam 726                 font->sizelist = (int*)realloc(font->sizelist,
727                         sizeof(int) * font->count);
728                 font->sizelist[font->count - 1] = newsize;
729                 qsort((void*)font->sizelist, font->count, sizeof(int), numsort);
317 roytam 730         }
731  
320 roytam 732         bdf = bdf2_get_bdf1(font, font->sizelist[0]);
733         font->bboxX = bdf->bbx.width;
734         for (i = 0; i < BDF_MAX_GLYPH; ++i)
735                 font->glyph_dwidth[i] = bdf->glyph_dwidth[i];
319 roytam 736  
317 roytam 737 #ifndef USE_FLEXIBLE_GLYPHWIDTH
320 roytam 738         /* Chech cell width */
739         for (i = 0; i < font->count; ++i)
740         {
741                 int j;
317 roytam 742  
320 roytam 743                 bdf = bdf2_get_bdf1(font, font->sizelist[i]);
744                 for (j = 0; j < BDF_MAX_GLYPH; ++j)
745                         if (font->glyph_width[j] < bdf->cell_width[j])
746                                 font->glyph_width[j] = bdf->cell_width[j];
747         }
317 roytam 748 #endif
749  
320 roytam 750         return 1;
317 roytam 751 }
752  
320 roytam 753         bdf_glyph_t*
317 roytam 754 bdf2_get_glyph(bdf2_t* font, int size, int id)
755 {
320 roytam 756         bdf_t *bdf;
317 roytam 757  
320 roytam 758         bdf = bdf2_get_bdf1(font, size);
759         return bdf ? bdf_get_glyph(bdf, id) : NULL;
317 roytam 760 }
761  
320 roytam 762         int
317 roytam 763 bdf2_get_pixel(bdf2_t* font, int size, int id, int x, int y)
764 {
320 roytam 765         bdf_t *bdf;
317 roytam 766  
320 roytam 767         bdf = bdf2_get_bdf1(font, size);
768         return bdf ? bdf_get_pixel(bdf, id, x, y) : -1;
317 roytam 769 }
770  
771 /*
772  * Search bdf_t by size.
773  */
320 roytam 774         bdf_t*
317 roytam 775 bdf2_get_bdf1(bdf2_t* font, int size)
776 {
320 roytam 777         bdf_list_t **list = &font->list;
778         bdf_list_t *tmp;
779         while (1)
780         {
781                 tmp = *list;
782                 if (!tmp)
783                         return NULL; /* not found */
317 roytam 784 #ifdef USE_PIXELSIZE
320 roytam 785                 else if (tmp->bdf->pixel_size == size)
786                         break; /* found */
317 roytam 787 #else
320 roytam 788                 else if (tmp->bdf->size == size)
789                         break; /* found */
317 roytam 790 #endif
320 roytam 791                 list = &tmp->next;
792         }
793         /* Put found bdf_t top in the list */
794         if (tmp != font->list)
795         {
796                 *list = tmp->next;
797                 tmp->next = font->list;
798                 font->list = tmp;
799         }
800         return font->list->bdf;
317 roytam 801 }
802  
320 roytam 803         int
317 roytam 804 bdf2_get_count(bdf2_t* font)
805 {
320 roytam 806         return font->count;
317 roytam 807 }
808  
320 roytam 809         int*
317 roytam 810 bdf2_get_sizelist(bdf2_t* font)
811 {
320 roytam 812         return font->sizelist;
317 roytam 813 }
814  
320 roytam 815         int
317 roytam 816 bdf2_get_glyph_id(bdf2_t* font, int id)
817 {
320 roytam 818         if (id < 0 || id >= BDF_MAX_GLYPH)
819                 return -1;
820         else
821                 return font->glyph_id[id];
317 roytam 822 }
823  
320 roytam 824         unsigned char
317 roytam 825 bdf2_get_glyph_flag(bdf2_t* font, int id)
826 {
320 roytam 827         if (id < 0 || id >= BDF_MAX_GLYPH)
828                 return 0;
829         else
830                 return font->glyph_flag[id];
317 roytam 831 }
832  
320 roytam 833         unsigned char
317 roytam 834 bdf2_get_glyph_width(bdf2_t* font, int id)
835 {
320 roytam 836         if (id < 0 || id >= BDF_MAX_GLYPH)
837                 return 0;
838         else
839                 return font->glyph_width[id];
317 roytam 840 }
841  
320 roytam 842         unsigned char
319 roytam 843 bdf2_get_glyph_dwidth(bdf2_t* font, int id)
844 {
320 roytam 845         if (id < 0 || id >= BDF_MAX_GLYPH)
846                 return 0;
847         else
848                 return font->glyph_dwidth[id];
319 roytam 849 }
850  
320 roytam 851         int
317 roytam 852 bdf2_is_glyph_available(bdf2_t* font, int id)
853 {
320 roytam 854         return bdf2_get_glyph_flag(font, id) & BDF2GF_AVAILABLE ? 1 : 0;
317 roytam 855 }
856  
857 /*****************************************************************************
858  * TEST
859  *****************************************************************************/
860  
861 #ifdef BDF_TEST
320 roytam 862         void
317 roytam 863 out_bitmap(bdf_t* font)
864 {
320 roytam 865         int i;
317 roytam 866  
320 roytam 867         printf("size=%d\n", font->size);
868         printf("bbx=%d %d %d %d\n", font->bbx.width, font->bbx.height,
869                 font->bbx.offset.x, font->bbx.offset.y);
870         printf("numGlyph=%d\n", font->numGlyph);
871         for (i = 0; i < BDF_MAX_GLYPH; ++i)
317 roytam 872         {
320 roytam 873                 int y;
874                 bdf_glyph_t *glyph;
317 roytam 875  
320 roytam 876                 glyph = bdf_get_glyph(font, i);
877                 if (!glyph)
878                         continue;
879                 printf("\n[%04x] %d %d %d %d\n", i,
880                         glyph->bbx.width, glyph->bbx.height,
881                         glyph->bbx.offset.x, glyph->bbx.offset.y);
882                 for (y = 0; bdf_get_pixel(font, i, 0, y) >= 0; ++y)
883                 {
884                         int x;
885  
886                         printf("  ");
887                         for (x = 0; ; ++x)
888                         {
889                                 int pixel = bdf_get_pixel(font, i, x, y);
890                                 if (pixel < 0)
891                                         break;
892                                 printf("%c", pixel ? '1' : '0');
893                         }
894                         printf("\n");
895                 }
317 roytam 896         }
897 }
898  
320 roytam 899         void
317 roytam 900 out_bdf(bdf_t* font)
901 {
320 roytam 902         int i;
317 roytam 903  
320 roytam 904         printf("SIZE %d %d %d\n", font->size, 72, 72);
905         printf("FONTBOUNDINGBOX %d %d %d %d\n",
906                 font->bbx.width, font->bbx.height,
907                 font->bbx.offset.x, font->bbx.offset.y);
908         printf("CHARS %d\n", font->numGlyph);
909         for (i = 0; i < BDF_MAX_GLYPH; ++i)
910         {
911                 int x, y, X, Y;
912                 bdf_glyph_t *glyph;
317 roytam 913  
320 roytam 914                 glyph = bdf_get_glyph(font, i);
915                 if (!glyph)
916                         continue;
917                 printf("STARTCHAR .%04x.%04x\n", i, glyph->id);
918                 printf("ENCODING %d\n", i);
919                 printf("SWIDTH %d %d\n", glyph->swidth.x, glyph->swidth.y);
920                 printf("DWIDTH %d %d\n", glyph->dwidth.x, glyph->dwidth.y);
921                 printf("BBX %d %d %d %d\n",
922                         glyph->bbx.width, glyph->bbx.height,
923                         glyph->bbx.offset.x, glyph->bbx.offset.y);
924                 printf("BITMAP\n");
925                 X = RAS_BYTE(glyph->bbx.width);
926                 Y = glyph->bbx.height;
927                 for (y = 0; y < Y; ++y)
928                 {
929                         for (x = 0; x < X; ++x)
930                                 printf("%02x", glyph->bitmap[x + y * X]);
931                         printf("\n");
932                 }
933                 printf("ENDCHAR\n");
317 roytam 934         }
935 }
936  
320 roytam 937         int
317 roytam 938 main(int argc, char** argv)
939 {
320 roytam 940         int i;
941         bdf_t* font;
317 roytam 942  
320 roytam 943         if (argc < 2)
944         {
945                 printf("Usage: %s {bdffile} [{bdffile} ...]\n", argv[0]);
946                 return -1;
947         }
317 roytam 948  
320 roytam 949         font = bdf_open();
950         for (i = 1; argv[i]; ++i)
317 roytam 951         bdf_load(font, argv[i]);
952  
320 roytam 953         //out_bitmap(font);
954         out_bdf(font);
317 roytam 955  
320 roytam 956         bdf_close(font);
957         return 0;
317 roytam 958 }
959 #endif