ESP8266 ILI9341 display support code with printf sources, wire-frame viewer and custom fonts  1.0
ESP8266ILI9341DisplayProject
bdffontutil.c
Go to the documentation of this file.
1 
2 
3 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <limits.h>
43 #include <errno.h>
44 #include <stdint.h>
45 #include <ctype.h>
46 
47 #include "font.h"
48 #include "bdffontutil.h"
49 
50 // Maximum number of fonts we can convert
52 // File names to convert
54 
55 char *EMPTY = "";
56 
62 void *db_calloc(size_t size)
63 {
64  void *ptr = calloc( size + 2, 1);
65  if( ptr == NULL )
66  {
67  fprintf(stderr,"Can not allocate memory\n");
68  exit(1);
69  }
70  return(ptr);
71 }
72 
78 void *db_free(void *p)
79 {
80  if( p == NULL || p == EMPTY)
81  {
82  return EMPTY;
83  }
84  free(p);
85 }
86 
87 
93 char *stralloc(char *str)
94 {
95  char *ptr;
96  int len = strlen(str);
97 
98  ptr = db_calloc(len+1);
99  strcpy(ptr,str);
100  return(ptr);
101 }
102 
103 
109 char *remove_quotes(char *str)
110 {
111  if(!str)
112  return(NULL);
113 
114  char *base;
115  while(*str)
116  {
117  if(*str == '\"' || *str == ' ' || *str == '\t')
118  ++str;
119  else
120  break;
121  }
122  base = str;
123  while(*str)
124  {
125  if(*str == '\"')
126  *str = ' ';
127  ++str;
128  }
129  trim_tail(base);
130  return(base);
131 }
132 
133 
141 void line_wrap(char *str, int max)
142 {
143  int len = 0;
144  int lastsp = 0;
145  char *sp = NULL;
146  while(*str)
147  {
148  if(*str == '\n')
149  {
150  sp = NULL;
151  len = 0;
152  }
153  if(len >= max)
154  {
155  if(sp)
156  {
157  *sp = '\n';
158  sp = NULL;
159  }
160  len = 0;
161  }
162  if(*str == ' ' || *str == '\t')
163  {
164  sp = str;
165  }
166  ++str;
167  ++len;
168  }
169 }
170 
171 
177 void trim_tail(char *str)
178 {
179  int len = strlen(str);
180  while(len--)
181  {
182  if(str[len] > ' ')
183  break;
184  str[len] = 0;
185  }
186 }
187 
193 char *skip_spaces(char *str)
194 {
195  // Skip not displayable characters first
196  while(*str && ( *str <= ' ' || *str >= 0x7f) )
197  ++str;
198  return(str);
199 }
200 
209 char *get_token(char *str, char *token, int max)
210 {
211  int len;
212  char *save;
213 
214  *token = 0;
215 
216  // NULL ?
217  if(!str)
218  return(NULL);
219 
220  str = skip_spaces(str);
221  save = str;
222 
223  // Find size of token
224  len = 0;
225  while(*str > ' ' && *str <= 0x7e && len < max)
226  {
227  // clip token to max length
228  if(len < max)
229  {
230  *token++ = *str++;
231  ++len;
232  }
233  }
234  *token = 0;
235  // str points past the token
236  if(!len)
237  return(NULL);
238  return(str);
239 }
240 
241 
247 int ishex(int c)
248 {
249  if( (c >= '0' && c <= '9') )
250  return( c - '0');
251  else if (c >= 'A' && c <= 'F')
252  return( c - 'A' + 10);
253  else if (c >= 'a' || c <= 'f')
254  return(c - 'a'+ 10);
255  return(-1);
256 }
257 
262 int ishexstr(char *str)
263 {
264  while(*str && ishex(*str) >= 0)
265  ++str;
266  if(!*str)
267  return(1);
268  return(0);
269 }
270 
279 char *match_token(char *str, char *pat)
280 {
281  int patlen;
282  int len;
283  char *ptr;
284  char *save = str;
285 
286  // Skip not displayable characters
287  while(*str <= ' ' || *str >= 0x7f)
288  ++str;
289 
290  // Find size of token
291  ptr = str;
292  len = 0;
293  while(*ptr > ' ' && *ptr <= 0x7e )
294  {
295  ++len;
296  ++ptr;
297  }
298  // ptr now points past the token in str
299 
300  // Empty string
301  if(!len)
302  return(NULL);
303 
304  patlen = strlen(pat);
305 
306  // Size mismatch ?
307  if(len != patlen)
308  return(NULL);
309 
310  if(strncmp(str,pat,patlen) == 0)
311  return(ptr);
312  return(NULL);
313 }
323 void FontHeaderInfo(FILE *out, _font *font, char *prog, char *target)
324 {
325  if(target == NULL)
326  {
327  if(font->info)
328  target = basename(font->info->FILE_NAME);
329  else
330  target = "";
331  }
332  fprintf(out,"/**\n");
333  fprintf(out," @file %s\n", target);
334  fprintf(out," Created using %s (c) 2015 by Mike Gore\n"
335  " License GPL3\n"
336  "\n", basename(prog));
337  if(font->info)
338  {
339  fprintf(out," BDF File: [%s]\n", font->info->FILE_NAME);
340  fprintf(out," C structure:[%s]\n", font->info->STRUCT_NAME);
341  fprintf(out,"\n");
342  fprintf(out," FONT COPYRIGHT: %s\n", font->info->COPYRIGHT);
343  fprintf(out," FONT NAME: %s\n", font->info->FONT_NAME);
344  fprintf(out," FAMILY_NAME: %s\n", font->info->FAMILY_NAME);
345  fprintf(out," WEIGHT_NAME: %s\n", font->info->WEIGHT_NAME);
346  fprintf(out," SLANT: %s\n", font->info->SLANT);
347  fprintf(out,"\n");
348  }
349  else
350  {
351  fprintf(out,"Font info empty\n");
352 
353  }
354  fprintf(out,"*/\n");
355 }
356 
357 
366 {
367  fprintf(out,"\n");
368  fprintf(out,"#ifndef MEMSPACE_FONT\n");
369  fprintf(out, " #define MEMSPACE_FONT /* */\n");
370  fprintf(out, "#endif\n");
371  fprintf(out, "\n");
372 
373  if(font->info != NULL)
374  {
375  /* Forware Reference to Font table and Font BIT data */
376  fprintf(out,"extern unsigned char %s_bitmap[];\n",
377  font->info->STRUCT_NAME);
378  fprintf(out, "\n");
379 
380  fprintf(out,"#ifdef FONTSPECS\n");
381  fprintf(out," extern _fontspecs %s_specs[];\n",
382  font->info->STRUCT_NAME);
383  fprintf(out,"#endif\n");
384  fprintf(out, "\n");
385 
386  fprintf(out,"#ifdef FONTINFO\n");
387  fprintf(out," extern _fontinfo %s_info[];\n",
388  font->info->STRUCT_NAME);
389  fprintf(out,"#endif\n");
390  fprintf(out, "\n");
391 
392  fprintf(out,"/* Font %s */\n\n",
393  font->info->STRUCT_NAME);
394  fprintf(out,"_font %s = {\n",
395  font->info->STRUCT_NAME);
396  fprintf(out, "\n");
397  }
398 
399  /* Write Font Structure */
400  emit_number(out,"Glyphs", font->Glyphs);
401  emit_number(out,"Fixed Width Flag", font->Fixed);
402  emit_number(out,"First Glyph", font->First);
403  emit_number(out,"Font Bounding Box Width", font->Width);
404  emit_number(out,"Font Bounding Box Height", font->Height);
405  emit_number(out,"Font Orgin X", font->X);
406  emit_number(out,"Font Orgin Y", font->Y);
407  emit_number(out,"Font Ascent", font->Ascent);
408  emit_number(out,"Font Decent", font->Decent);
409  emit_number(out,"Font Gap", font->gap);
410  emit_number(out,"Font Bytes for entire Bitmap", font->Bytes);
411 
412 
413  if(font->info != NULL)
414  {
415  fprintf(out,"\t%s_bitmap,\n", font->info->STRUCT_NAME);
416  fprintf(out,"#ifdef FONTSPECS\n");
417  fprintf(out,"\t%s_specs,\n", font->info->STRUCT_NAME);
418  fprintf(out,"#else\n");
419  fprintf(out,"\tNULL, /* font->specs */\n");
420  fprintf(out,"#endif\n");
421  fprintf(out,"#ifdef FONTINFO\n");
422  fprintf(out,"\t%s_info\n", font->info->STRUCT_NAME);
423  fprintf(out,"#else\n");
424  fprintf(out,"\tNULL /* font->info */\n");
425  fprintf(out,"#endif\n");
426  }
427 
428  fprintf(out,"};\n\n");
429 
430  WriteFontInfo( out , font);
431  WriteFontTable ( out , font);
432  WriteFontBits ( out , font);
433 }
434 
442 void emit_number(FILE *out, char *name, int num)
443 {
444  fprintf(out,"\t/* %s = %d */\n", name, num);
445  fprintf(out,"\t\t\%d,\n", num);
446 }
447 
448 
457 void emit_data(FILE *out, char *name, unsigned char *data, int size)
458 {
459 
460 
461  fprintf(out,"\t/* %s */\n", name);
462  fprintf(out,"\t\t{\n");
463  while(size--)
464  {
465  fprintf(out,"0x%02x,", *data);
466  data++;
467  }
468  fprintf(out,"\t\t},\n");
469 }
470 
478 void emit_str(FILE *out, char *name, unsigned char *data)
479 {
480  fprintf(out,"\t/* %s */\n", name);
481  if(!data)
482  fprintf(out,"\t\tNULL,\n");
483  else
484  fprintf(out,"\t\t\"%s\",\n", data);
485 }
486 
491 void InitNames()
492 {
493  int i;
494 
495  for(i=0;i<MAXFONTS;++i)
496  {
497  fnames[i] = NULL;
498  }
499 
500  for(i=0;i<MAXFONTS;++i)
501  {
502  BDFnames[i].filename = NULL;
503  BDFnames[i].structname = NULL;
504  }
505 }
506 
513 {
514  int i;
515 
516  _fontinfo *info = db_calloc(sizeof(_fontinfo));
517  info->FILE_NAME = EMPTY;
518  info->STRUCT_NAME = EMPTY;
519  info->COPYRIGHT = EMPTY;
520  info->FONT_NAME = EMPTY;
521  info->FAMILY_NAME = EMPTY;
522  info->WEIGHT_NAME = EMPTY;
523  info->SLANT = EMPTY;
524  info->SPACING = EMPTY;
525 
526  font->info = info;
527  font->First = 0;
528  font->Fixed = 0;
529  font->Width = 0;
530  font->Height = 0;
531  font->X = 0;
532  font->Y = 0;
533  font->Ascent = 0;
534  font->Decent = 0;
535  font->gap = 0;
536  font->Bytes = 0;
537  font->bitmap = NULL;
538  font->specs = db_calloc(sizeof(_fontspecs) * MAXGLYPHS);
539  for(i=0;i<MAXGLYPHS;++i)
540  {
541  font->specs[i].Offset = -1;
542  font->specs[i].Width = 0;
543  font->specs[i].Height = 0;
544  font->specs[i].X = 0;
545  font->specs[i].Y = 0;
546  }
547 }
548 
555 {
556  _fontinfo *info = font->info;
557  if(info != NULL)
558  {
559  db_free(info->FILE_NAME);
560  db_free(info->STRUCT_NAME);
561  db_free(info->COPYRIGHT);
562  db_free(info->FONT_NAME);
563  db_free(info->FAMILY_NAME);
564  db_free(info->WEIGHT_NAME);
565  db_free(info->SLANT);
566  db_free(info->SPACING);
567  db_free(info);
568  font->info = NULL;
569  }
570 
571  db_free(font->bitmap);
572  db_free(font->specs);
573 }
574 
575 
583 {
584  char name[MAXLINE];
585  char *save = name;
586  /* We define the font by its size - not its bounding box */
587  snprintf(name,MAXLINE-1, "%s_%s_%s_X%d_Y%d",
588  font->info->FAMILY_NAME,
589  font->info->WEIGHT_NAME,
590  font->info->SLANT,
591  font->Width,
592  font->Height
593  );
594  char *ptr = name;
595  while(*ptr)
596  {
597  if(!isalnum(*ptr))
598  {
599  *ptr = '_';
600  }
601  ++ptr;
602  }
603  font->info->STRUCT_NAME = stralloc(save);
604 
605 }
606 
611 int FindFontName(char *str)
612 {
613  int i;
614 
615  for(i=0;BDFnames[i].structname != NULL;++i)
616  {
617  if(strcmp( BDFnames[i].structname, str) == 0)
618  {
619  return(i);
620  }
621  }
622  return(-1);
623 }
624 
632 {
633  int i;
634  int c;
635  fprintf(out, "/* Font BIT DATA , MSB Left to Right (padded to byte alignment), Top Down */\n");
636 
637  if(font->info)
638  {
639  fprintf(out,"MEMSPACE_FONT unsigned char %s_bitmap[%d]= { /* %s_bitmap */\n", font->info->STRUCT_NAME, font->Bytes, font->info->STRUCT_NAME);
640  }
641  for(i=0;i<font->Glyphs;++i)
642  {
643  WriteCharacterBits(out, font, i);
644  }
645  fprintf(out, "};\n");
646 }
647 
655 {
656  int i;
657  int c;
658 
659  if(!font->info)
660  return;
661 
662  fprintf(out, "#ifdef FONTINFO\n");
663  fprintf(out, "MEMSPACE_FONT _fontinfo %s_info[%d] = /* %s_info */\n",
664  font->info->STRUCT_NAME, font->Glyphs, font->info->STRUCT_NAME);
665  fprintf(out, "\t{\n");
666  emit_str(out,"FILE_NAME", font->info->FILE_NAME);
667  emit_str(out,"STRUCT_NAME", font->info->STRUCT_NAME);
668  emit_str(out,"COPYRIGHT", font->info->COPYRIGHT);
669  emit_str(out,"FONT", font->info->FONT_NAME);
670  emit_str(out,"FAMILY_NAME", font->info->FAMILY_NAME);
671  emit_str(out,"WEIGHT_NAME", font->info->WEIGHT_NAME);
672  emit_str(out,"SLANT", font->info->SLANT);
673  emit_str(out,"SPACING", font->info->SPACING);
674  fprintf(out, "};\n");
675  fprintf(out, "#endif\n");
676 }
677 
685 {
686  int i;
687  int c;
688 
689  if(!font->specs || !font->info)
690  return;
691 
692  fprintf(out, "#ifdef FONTSPECS\n");
693  fprintf(out, "MEMSPACE_FONT _fontspecs %s_specs[%d] = /* %s_specs */\n",
694  font->info->STRUCT_NAME, font->Glyphs, font->info->STRUCT_NAME);
695  fprintf(out, "\t{\n");
696 
697  fprintf(out, "\t\t/* Offset, Width, Height, X, Y*/\n");
698  for(i=0;i<font->Glyphs;++i)
699  {
700  c = i + font->First;
701  fprintf(out, "\t\t{ % 5d, % 5d, % 5d, % 5d, %5d }, /* [%c]*/\n",
702  font->specs[i].Offset,
703  font->specs[i].Width,
704  font->specs[i].Height,
705  font->specs[i].X,
706  font->specs[i].Y,
707  c);
708  if(font->specs[i].Offset == -1)
709  break;
710  }
711  fprintf(out, "};\n");
712  fprintf(out, "\n#endif\n");
713 }
721 void WriteCharacterBits(FILE * out, _font *font, int num)
722 {
723  int c;
724  int x,y;
725  int xoff,yoff;
726  int w,h;
727  int bytes;
728  int offset;
729  int i, mask;
730  unsigned char *ptr = font->bitmap;
731 
732  if(num < 0 || num >= font->Glyphs)
733  return;
734 
735  if(font->specs)
736  {
737 
738  offset = font->specs[num].Offset;
739  w = font->specs[num].Width;
740  h = font->specs[num].Height;
741  xoff = font->specs[num].X;
742  yoff = font->specs[num].Y;
743  bytes = ((w * h) + 7)/8;
744  ptr += offset;
745  }
746  else
747  {
748  w = font->Width;
749  h = font->Height;
750  xoff = 0;
751  yoff = 0;
752  bytes = ((w * h) + 7)/8;
753  offset = (bytes * num);
754  ptr += offset;
755  }
756 
757  c = num + font->First;
758 
759  fprintf(out, "/* index:%d, [%c] 0x%02x, W:% 3d, H:% 3d, X:% 3d, Y:% 3d */\n",
760  num, c, c,
761  w,
762  h,
763  xoff,
764  yoff
765  );
766 
767  for(i=0;i<bytes;++i)
768  {
769  if((i & 15) == 0)
770  fprintf(out,"\t");
771  fprintf(out,"0x%02x,", ptr[i]);
772  if((i & 15) == 15)
773  fprintf(out,"\n");
774  }
775  if((i & 15) != 0)
776  fprintf(out,"\n");
777 }
778 
779 
790 int ReadBdf(char *name, _font *font, int lower, int upper)
791 {
792  FILE *bdf;
793 
794  // Our output font byte array offset
795  int offset = 0;
796  // Current Character value
797  int character;
798  // HEX data decoding vars
799  int num,digit,mask;
800  // BITMAP X an Y for decoding data bitmap data
801  int x, addr, hexline;
802  // Current Glyph table index
803  int ind;
804  // Font DWIDTH var - horizontal distance to next font
805  int Next;
806  // Font bitmap size in bytes
807  int bytes;
808  // Font bounding box for the currennt working font
809  int BitBox_X = 0;
810  int BitBox_Y = 0;
811  int BitBox_Width = 0;
812  int BitBox_Height = 0;
813  // Total number of Glyps defined in this BDF file
814  int Glyphs = 0;
815  int BBXF = 0;
816  int max = 0;
817 
818  unsigned char *ptr, *save, *bp;
819 
820  int len;
821 
822  // File line buffer
823  char line[MAXLINE];
824  // Working token
825  char token[MAXLINE];
826 
827  // Font STructure Name
828  char bdfname[MAXLINE];
829  line[0]=0;
830  token[0]=0;
831  bdfname[0] = 0;
832 
833  InitFonts(font);
834 
835  bdf = fopen(name,"r");
836  if(!bdf )
837  {
838  fprintf(stderr,"Can't open: %s\n", name);
839  return(0);
840  }
841 
842  font->info->FILE_NAME = stralloc(name);
843 
844  // Number glyphs defined in this BDF file
845  Glyphs = -1;
846 
847  font->First = lower;
848 
849  // SCAN start of BDF file until the CHARS token
850  while( fgets(line, sizeof(line), bdf) != NULL)
851  {
852  trim_tail(line);
853 
854  len = strlen(line);
855  if(!len)
856  continue;
857 
858  ptr = get_token(line,token,sizeof(token)-1);
859  if(MATCH(token, "FONTBOUNDINGBOX"))
860  {
861  // We do not have to check ptr == NULL, get_token() does that - token will be empty on NULL
862 
863  ptr = get_token(ptr,token,sizeof(token)-1);
864  /* Width and Height of the Bounding box - one greater in X,Y of the largest Glyph in all fonts */
865  font->Width = atoi(token);
866  ptr = get_token(ptr,token,sizeof(token)-1);
867  font->Height = atoi(token);
868 
869  /* Lower left-hand corner starting at X, Y */
870  ptr = get_token(ptr,token,sizeof(token)-1);
871  font->X = atoi(token);
872  ptr = get_token(ptr,token,sizeof(token)-1);
873  font->Y = atoi(token);
874 
875  BBXF = 1;
876  continue;
877 
878  }
879  if(MATCH(token, "FONT_ASCENT"))
880  {
881  // We do not have to check ptr == NULL, get_token() does that - token will be empty on NULL
882  ptr = get_token(ptr,token,sizeof(token)-1);
883  font->Ascent = atoi(token);
884  continue;
885  }
886  if(MATCH(token, "FONT_DESCENT"))
887  {
888  // We do not have to check ptr == NULL, get_token() does that - token will be empty on NULL
889  ptr = get_token(ptr,token,sizeof(token)-1);
890  font->Decent = atoi(token);
891  continue;
892  }
893 
894  if(MATCH(token, "FONT"))
895  {
896  ptr = remove_quotes(ptr);
897  if(ptr) font->info->FONT_NAME = stralloc(ptr);
898  //line_wrap(font->FONT_NAME, 72);
899  continue;
900  }
901  if(MATCH(token, "FAMILY_NAME"))
902  {
903  ptr = remove_quotes(ptr);
904  if(ptr) font->info->FAMILY_NAME = stralloc( ptr);
905  continue;
906  }
907  if(MATCH(token, "WEIGHT_NAME"))
908  {
909  ptr = remove_quotes(ptr);
910  if(ptr) font->info->WEIGHT_NAME = stralloc(ptr);
911  continue;
912  }
913  if(MATCH(token, "SLANT"))
914  {
915  ptr = remove_quotes(ptr);
916  if(ptr) font->info->SLANT = stralloc(ptr);
917  continue;
918  }
919  if(MATCH(token, "SPACING"))
920  {
921  int c;
922  ptr = remove_quotes(ptr);
923  if(ptr)
924  {
925  font->info->SPACING = stralloc(ptr);
926  c = toupper( font->info->SPACING[0] );
927  if(c == 'P')
928  font->Fixed = 0;
929  if(c == 'C' || c == 'M')
930  font->Fixed = 1;
931  continue;
932  }
933  }
934  if(MATCH(token, "COPYRIGHT"))
935  {
936  ptr = remove_quotes(ptr);
937  if(ptr) font->info->COPYRIGHT = stralloc(ptr);
938  continue;
939  }
940  // Character data follows after this
941  // Number of Glyphs in the BDF file
942  if(MATCH(token, "CHARS"))
943  {
944  ptr = get_token(ptr,token,sizeof(token)-1);
945  Glyphs = atoi(token);
946  break;
947  }
948  }
949 
950  // We must have a Font bounding box for these fonts
951  if (!BBXF)
952  {
953  fprintf(stderr, "FONTBOUNDINGBOX missing!\n");
954  fprintf(stderr, "%s\n",font->info->FONT_NAME);
955  fclose(bdf);
956  return(0);
957  }
958  if (Glyphs <= 0)
959  {
960  fprintf(stderr, "CHARS token is missing\n");
961  fprintf(stderr, "%s\n",font->info->FONT_NAME);
962  fclose(bdf);
963  return(0);
964  }
965 
966 
967  // Calloc space for ALL Glyph bitmap arrays
968  // Each character is a stream of bits W * H rounded to a byte boundry
969  // So if we round the width up to a byte boundry we will have a safe margin
970  // bp = db_calloc(( Glyphs * ((font->Width) + 7) / 8) * font->Height);
971  bp = db_calloc(( Glyphs * ((MAXWIDTH+1) + 7) / 8) * (MAXHEIGHT+1));
972  font->bitmap = bp;
973  // Save start of glyph array
974 
975  // Save Font Size in font entry
976  ind = 0;
977  // Initialize
978 
979  // Font Variables
980  hexline = 0;
981  BitBox_X = 0;
982  BitBox_Y = 0;
983  BitBox_Width = 0;
984  BitBox_Height = 0;
985  character = -1;
986  Next = font->Width-1; // Default horizontal distance to next Glyph
987 
988  // SCAN remander of BDF file until end of fie
989  while( fgets(line, sizeof(line), bdf) != NULL)
990  {
991  trim_tail(line);
992  len = strlen(line);
993  if(!len)
994  continue;
995 
996  ptr = get_token(line,token,sizeof(token)-1);
997  if(MATCH(token, "STARTCHAR"))
998  {
999  ptr = get_token(ptr,token,sizeof(token)-1);
1000  if(ishexstr(token))
1001  {
1002  sscanf(token,"%x", &character);
1003  /* Reset Font Variables */
1004  hexline = 0;
1005  BitBox_X = 0;
1006  BitBox_Y = 0;
1007  BitBox_Width = 0;
1008  BitBox_Height = 0;
1009  }
1010  continue;
1011  }
1012 
1013  if(MATCH(token, "ENCODING"))
1014  {
1015  ptr = get_token(ptr,token,sizeof(token)-1);
1016 
1017  character = atoi(token);
1018 
1019  /* Reset Font Variables */
1020  hexline = 0;
1021  BitBox_X = 0;
1022  BitBox_Y = 0;
1023  BitBox_Width = 0;
1024  BitBox_Height = 0;
1025  continue;
1026  }
1027 
1028  /* Horizontal offset to next Glyph */
1029  if(MATCH(token, "DWIDTH"))
1030  {
1031  ptr = get_token(ptr,token,sizeof(token)-1);
1032  Next = atoi(token);
1033  continue;
1034  }
1035 
1036  /* Font bit box size and offset */
1037  if(MATCH(token, "BBX"))
1038  {
1039  // Font Width and height
1040  ptr = get_token(ptr,token,sizeof(token)-1);
1041  BitBox_Width = atoi(token);
1042  ptr = get_token(ptr,token,sizeof(token)-1);
1043  BitBox_Height = atoi(token);
1044 
1045  // Font offset required to render font
1046  ptr = get_token(ptr,token,sizeof(token)-1);
1047  BitBox_X = atoi(token);
1048  ptr = get_token(ptr,token,sizeof(token)-1);
1049  BitBox_Y = atoi(token);
1050 
1051  // Bounds checking
1052  if(BitBox_Width > MAXWIDTH)
1053  {
1054  fprintf(stderr,"Font:%d, Bit Width(%d) > MAXWIDTH(%d)!\n", ind, BitBox_Width,MAXWIDTH);
1055  fprintf(stderr, "%s\n",font->info->FONT_NAME);
1056  fclose(bdf);
1057  return(0);
1058  }
1059  // Bounds checking
1060  if(BitBox_Height > MAXHEIGHT)
1061  {
1062  fprintf(stderr,"Font:%d, Bit Height(%d) > MAXHEIGHT(%d)!\n", ind, BitBox_Height,MAXHEIGHT);
1063  fprintf(stderr, "%s\n",font->info->FONT_NAME);
1064  fclose(bdf);
1065  return(0);
1066  }
1067 
1068  // Bounds checking warnings
1069  if(BitBox_Width > font->Width)
1070  {
1071  fprintf(stderr,"Font:%d, Bit Width(%d) > Font bounding Box Bit Width(%d)!\n", ind, BitBox_Width,font->Width);
1072  fprintf(stderr, "%s\n",font->info->FONT_NAME);
1073  }
1074  // Bounds checking
1075  if(BitBox_Height > font->Height)
1076  {
1077  fprintf(stderr,"Font:%d, Bit Height(%d) > Font bounding Box Bit Height(%d)!\n", ind, BitBox_Height,font->Height);
1078  fprintf(stderr, "%s\n",font->info->FONT_NAME);
1079  }
1080  continue;
1081  }
1082 
1083  x = 0;
1084  if(MATCH(token, "BITMAP"))
1085  {
1086  if(character < lower || character > upper)
1087  continue;
1088 
1089  // Process BITMAP
1090  font->specs[ind].Offset = offset;
1091  font->specs[ind].Width = BitBox_Width;
1092  font->specs[ind].Height = BitBox_Height;
1093  font->specs[ind].X = BitBox_X;
1094  font->specs[ind].Y = BitBox_Y;
1095  font->Bytes = offset;
1096  max = 0;
1097 
1098  // Read HEX data until ENDCHAR
1099  hexline = 0;
1100  addr = 0;
1101  // SCAN for HEX BITMAP data or end of file
1102  while( fgets(line, sizeof(line), bdf) != NULL)
1103  {
1104  trim_tail(line);
1105  len = strlen(line);
1106  if(!len)
1107  continue;
1108 
1109  ptr = get_token(line,token,sizeof(token)-1);
1110  // Finished this character ?
1111  if(MATCH(token, "ENDCHAR"))
1112  {
1113  ptr = get_token(ptr,token,sizeof(token)-1);
1114  break;
1115  }
1116 
1117  // Make sure we have only HEX data!
1118  if(!ishexstr(token))
1119  break;
1120  // Parse one BITMAP HEX data line
1121  ptr = token;
1122  x = 0;
1123  // Process data a byte at a time
1124  while (*ptr) {
1125  // We already verified the whole string as HEX
1126  digit = ishex(*ptr);
1127  mask = 0x08;
1128  while(mask && x < BitBox_Width)
1129  {
1130  addr = x + BitBox_Width * hexline;
1131  if(mask & digit)
1132  bitsetxy(bp, x,hexline, BitBox_Width, BitBox_Height);
1133  else
1134  bitclrxy(bp, x,hexline, BitBox_Width, BitBox_Height);
1135  ++x;
1136  mask >>= 1;
1137  }
1138  ++ptr;
1139  } // while ( HEX string ... )
1140  // Advance to next line
1141  ++hexline;
1142  } // while( reading HEX data ...)
1143  bytes = ((BitBox_Width * BitBox_Height) + 7) / 8;
1144 
1145  offset += bytes;
1146  // advance bitmap pointer
1147  bp += bytes;
1148 
1149  // Out of font memory ???
1150  if (++ind >= Glyphs )
1151  {
1152  fprintf(stderr, "Too many characters\n");
1153  fprintf(stderr, "%s\n",font->info->FONT_NAME);
1154  fclose(bdf);
1155  return(0);
1156  }
1157 
1158  // Reset Font Variables
1159  hexline = 0;
1160  BitBox_X = 0;
1161  BitBox_Y = 0;
1162  BitBox_Width = 0;
1163  BitBox_Height = 0;
1164  character = -1;
1165  Next = font->Width-1;
1166 
1167  } // if ( BITMAP token ... )
1168  } // for( reading BDF file ... )
1169 
1170 
1171  font->Bytes = offset;
1172  font->Glyphs = ind;
1173 
1174  AdjustFontTable(font);
1175 
1176 
1177  AddFontName(font);
1178  fclose(bdf);
1179 
1180  ComputeGapSize(font);
1181  return(font->Glyphs);
1182 }
1183 
1192 {
1193  int i;
1194  int W= 0;
1195  int H= 0;
1196  int X = 0;
1197  int Y = 0;
1198 
1199 // Adjust Font offset, normalize X and Y to 0
1200  for(i=0;i<font->Glyphs;++i)
1201  {
1202  if(font->specs[i].X < X)
1203  X = font->specs[i].X;
1204  if(font->specs[i].Y < Y)
1205  Y = font->specs[i].Y;
1206  }
1207 
1208 //Apply X and Y offset
1209  for(i=0;i<font->Glyphs;++i)
1210  {
1211  font->specs[i].X -= X;
1212  font->specs[i].Y -= Y;
1213  }
1214 
1215  font->X = 0;
1216  font->Y = 0;
1217 //printf("X:[%d], Y:[%d]\n", X, Y);
1218 
1219 // Adjust Font bounding box Width and Height
1220  for(i=0;i<font->Glyphs;++i)
1221  {
1222  if((font->specs[i].Width + font->specs[i].X) > W)
1223  W = font->specs[i].Width + font->specs[i].X;
1224  if((font->specs[i].Height + font->specs[i].Y) > H)
1225  H = font->specs[i].Height + font->specs[i].Y;
1226  }
1227 // Update W and H bounding box
1228  font->Width = W;
1229  font->Height = H;
1230 
1231 //printf("W:[%d], H:[%d]\n", W, H);
1232 }
1233 
1234 
1241 {
1242  int x,y;
1243  int w,h;
1244  int xoff,yoff;
1245  int bytes;
1246  int skip;
1247  int i;
1248  int offset = 0;
1249 
1250  unsigned char *ptr = font->bitmap;
1251  unsigned char *save = db_calloc(( font->Glyphs * ((MAXWIDTH+1) + 7) / 8) * (MAXHEIGHT+1));
1252  unsigned char *bp = save;
1253 
1254 
1255  for(i=0;i<font->Glyphs;++i)
1256  {
1257  if(font->specs[i].Offset == -1)
1258  break;
1259 
1260  w = font->specs[i].Width;
1261  h = font->specs[i].Height;
1262  xoff = font->specs[i].X;
1263  yoff = font->specs[i].Y;
1264  ptr = font->bitmap + font->specs[i].Offset;
1265 
1266  font->specs[i].Offset = offset;
1267 
1268  // Font DATA MSB first
1269  skip = font->Height-(yoff+h);
1270  for (y = 0; y < skip; ++y)
1271  {
1272  for (x = 0; x < font->Width; ++x)
1273  bitclrxy(bp,x,y, font->Width, font->Height);
1274  }
1275 
1276  for (y=0;y < h; ++y) {
1277  for (x = 0; x < xoff; ++x)
1278  bitclrxy(bp,x,y+skip, font->Width, font->Height);
1279  for (x=0;x < w; ++x) {
1280  if(bittestxy(ptr, x,y, w,h))
1281  bitsetxy(bp,x+xoff,y+skip, font->Width, font->Height);
1282  else
1283  bitclrxy(bp,x+xoff,y+skip, font->Width, font->Height);
1284  }
1285  for (x=xoff+w;x < font->Width; ++x)
1286  bitclrxy(bp,x+xoff+w,y+skip, font->Width, font->Height);
1287  }
1288 
1289  // Font DATA MSB first
1290  for (y = 0; y < yoff; ++y)
1291  {
1292  for (x = 0; x < font->Width; ++x)
1293  bitclrxy(bp,x,y+skip+h, font->Width, font->Height);
1294  }
1295 
1296  bytes = ((font->Width * font->Height) + 7) / 8;
1297 
1298  font->specs[i].Width = font->Width;
1299  font->specs[i].Height = font->Height;
1300  font->specs[i].X = 0;
1301  font->specs[i].Y = 0;
1302 
1303  offset += bytes;
1304  bp += bytes;
1305  }
1306  font->X = 0;
1307  font->Y = 0;
1308  font->Bytes = offset;
1309  db_free(font->bitmap);
1310  font->bitmap = save;
1311 //fprintf(stderr,"Adjusted Bytes:%d\n", font->Bytes);
1312 
1313 }
1314 
1326 {
1327  int X,Y;
1328  int x,y;
1329  int w,h;
1330  int xdelta,ydelta;
1331  int bytes;
1332  int skip;
1333  int i;
1334  int offset = 0; // oldbitmap Glyph offset
1335  int newoffset = 0; // new bitmap Glyph offset
1336  int specf;
1337 
1338  int minx,maxx;
1339  int width,height;
1340  int miny,maxy;
1341 
1342  unsigned char *ptr = font->bitmap;
1343  unsigned char *tmp;
1344 
1345  // compute bitmap that can hold worst case size
1346  unsigned char *new = db_calloc(( font->Glyphs * ((MAXWIDTH+1) + 7) / 8) * (MAXHEIGHT+1));
1347 
1348  // Do we need to create font-specs
1349  // This defines each font bounding box and offsets
1350  if(font->specs)
1351  {
1352  specf = 1;
1353  }
1354  else
1355  {
1356  specf = 0;
1357  font->specs = db_calloc(sizeof(_fontspecs) * MAXGLYPHS);
1358  }
1359 
1360  // Scan old font looking for smallest font bounding box
1361 
1362  for(i=0;i<font->Glyphs;++i)
1363  {
1364  // Does font->specs exist ?
1365  if(specf)
1366  {
1367  w = font->specs[i].Width;
1368  h = font->specs[i].Height;
1369  X = font->specs[i].X;
1370  Y = font->specs[i].Y;
1371  offset = font->specs[i].Offset;
1372  }
1373  else /* We must create fixed specs entry it */
1374  {
1375  // fixed fonts without specs rely on main font bounding box
1376  w = font->Width;
1377  h = font->Height;
1378  font->specs[i].Width = w;
1379  font->specs[i].Height = h;
1380  X = 0;
1381  Y = 0;
1382  X = font->specs[i].X;
1383  Y = font->specs[i].Y;
1384  offset = i * ((w*h)+7)/8;
1385 
1386  // update specs entry
1387  // fixed fonts without specs have 0,0 offsets
1388  font->specs[i].Offset = offset;
1389  }
1390 
1391  minx = MAXWIDTH+1;
1392  maxx = 0;
1393  miny = MAXHEIGHT+1;
1394  maxy = 0;
1395 
1396  // Compute the smallest font bounding box for this Glyph
1397  // scan font maxy to miny
1398  for (y=0;y <h; ++y) {
1399  for (x=0;x < w; ++x)
1400  {
1401  if(bittestxy(font->bitmap+offset, x,y, w,h))
1402  {
1403  if(x < minx)
1404  minx = x;
1405  if(x > maxx)
1406  maxx = x;
1407  if(y < miny)
1408  miny = y;
1409  if(y > maxy)
1410  maxy = y;
1411  }
1412 
1413  }
1414  }
1415 
1416  // maxy has highest Y (near base of Glyph)
1417  // minx has lowest X (near left of font)
1418  if(minx > h)
1419  {
1420  minx = 0;
1421  maxx = 0;
1422  width = 0;
1423  }
1424  else
1425  {
1426  width = maxx - minx + 1;
1427  }
1428  if(miny > h)
1429  {
1430  miny = 0;
1431  maxy = 0;
1432  height = 0;
1433  }
1434  else
1435  {
1436  height = maxy - miny + 1;
1437  }
1438 
1439  // Update new font bounding box
1440  font->specs[i].Width = width;
1441  font->specs[i].Height = height;
1442 
1443  // Compute X and Y shift update to render font correctly
1444  // With its new bit array
1445  if(h && height)
1446  {
1447  ydelta = (h-1-maxy);
1448  }
1449  else
1450  {
1451  ydelta = 0;
1452  }
1453  xdelta = minx;
1454 
1455  // if new minx is > 0 , bit array can shift minx
1456  font->specs[i].X += xdelta;
1457 
1458  // if new maxy is < h-1, bit array can shift down
1459  font->specs[i].Y += ydelta;
1460 
1461 
1462  // miny has lowest Y
1463  // minx has lowest X
1464 
1465  // Write new font using updated bonding box
1466  // minx,miny are the offsets from old bitmap to new
1467  // Recall the fonts are *rendered* top down, left right
1468  // FIXME maybe we should re-render bdf fonts bottom up ???
1469  // (this would make these computations easy )
1470  // X offsets are measured from the left
1471  // Y offsets are measured from the *bottom* of Glyph
1472  // - where bottom is maxy here.
1473  // minx and miny is the first bit set scanning the
1474  // old font from top of glyph to bottom (min to max y)
1475  // So the new bitmap offset is just miny
1476 
1477  for (y=0;y < h; ++y) {
1478  for (x=0;x < w ; ++x)
1479  {
1480  if(bittestxy(ptr+offset, x,y, w,h))
1481  {
1482  bitsetxy(new+newoffset,x-minx,y-miny, width, height);
1483  }
1484  else
1485  {
1486  }
1487  }
1488  }
1489 
1490  // update to new offset
1491  font->specs[i].Offset = newoffset;
1492  // Size of this Glyph
1493  bytes = ((width * height) + 7) / 8;
1494  // Offset to next Glyph
1495  newoffset += bytes;
1496  } // for()
1497 
1498  // We do not use main font offsets anymore
1499  font->X = 0;
1500  font->Y = 0;
1501 
1502  // Total number of bytes is newoffset
1503  font->Bytes = newoffset;
1504 
1505  // free old bitmap
1506  db_free(font->bitmap);
1507 
1508  // replace bitmap
1509  font->bitmap = new;
1510 
1511  // renormalize if needed - should not matter
1512  AdjustFontTable(font);
1513 }
1514 // ======================================================
1515 
1525 {
1526  int x,y;
1527  int w,h;
1528  int Width;
1529  int Span;
1530  int i;
1531  int offset = 0;
1532 
1533  int minx,maxx;
1534  int flag = 0;
1535 
1536 
1537  // Compute the gap between fonts
1538  // Most fixed fonts have a built in gap
1539  // Most proportional fonts do not have a gap built in
1540  //
1541  // Find smallest non blank horizonal feature in all glyphs
1542 
1543  // FIXME - perhaps we want to scan just the center ?
1544 
1545  Span = MAXWIDTH;
1546  for(i=0;i<font->Glyphs;++i)
1547  {
1548  // Does font->specs exist ?
1549  if(font->specs)
1550  {
1551  w = font->specs[i].Width;
1552  h = font->specs[i].Height;
1553  offset = font->specs[i].Offset;
1554  }
1555  else /* We must create fixed specs entry it */
1556  {
1557  // fixed fonts without specs rely on main font bounding box
1558  w = font->Width;
1559  h = font->Height;
1560  offset = i * ((w*h)+7)/8;
1561  }
1562 
1563  // Scan a Character "Glyph"
1564  // Compute width of smallest non-blank feature
1565  for (y=0;y <h; ++y) {
1566  // We find the largest span on a line by line basis
1567  flag = 0;
1568  minx = MAXWIDTH ;
1569  maxx = 0;
1570  for (x=0;x < w; ++x)
1571  {
1572  if(bittestxy(font->bitmap+offset, x,y, w,h))
1573  {
1574  flag = 1; // a bit is set
1575  if(x <= minx)
1576  minx = x;
1577  if(x > maxx)
1578  maxx = x;
1579  }
1580  }
1581  // Compute width of character in this column
1582  if(flag)
1583  {
1584  // minimum span
1585  Width = (maxx - minx + 1);
1586  if(Span < Width)
1587  Span = Width;
1588  }
1589  }
1590  }
1591 
1592  // should never happen!
1593  // implies font data without any pixels turned on!
1594  if(Span == MAXWIDTH)
1595  {
1596  Span = 0;
1597  }
1598 
1599  // Some fixed width fonts may not have built in gaps
1600  // So if not then we add one by scanning all the glyphs
1601  // and find the narrowest on-blank glyph we find.
1602 
1603  // FIXME check font rendering code to verify we are
1604  // not adjusting this gap size assumption
1605  if(Span > 0)
1606  {
1607  // font->gap = (Width+3)/4;
1608  font->gap = Span;
1609  }
1610  else
1611  {
1612  font->gap = 1;
1613  }
1614 }
1615 
1616 
1617 // ======================================================
1618 
1625 void bsetv(unsigned char *ptr, int addr)
1626 {
1627  int byte, bit;
1628  byte = addr >> 3;
1629  bit = (addr & 7);
1630  ptr[byte] |= (0x80 >> bit);
1631 }
1632 
1639 void bclrv(unsigned char *ptr, int addr)
1640 {
1641  int byte, bit;
1642  byte = addr >> 3;
1643  bit = (addr & 7);
1644  ptr[byte] &= ~(0x80 >> bit);
1645 }
1646 
1653 int btestv(unsigned char *ptr, int addr)
1654 {
1655  int byte, bit;
1656  byte = addr >> 3;
1657  bit = (addr & 7);
1658  return ( ptr[byte] & (0x80 >> bit) );
1659 }
1660 
1670 int bittestxy(unsigned char *ptr, int x, int y, int w, int h)
1671 {
1672  int byte, bit;
1673  int addr;
1674 
1675  if(y < 0 || y > h)
1676  {
1677  return 0;
1678  }
1679  if(x < 0 || x > w)
1680  {
1681  return 0;
1682  }
1683  addr = y * w + x;
1684  byte = addr >> 3;
1685  bit = (addr & 7);
1686  return( (ptr[byte] & (0x80 >> bit)) );
1687 }
1688 
1698 void bitsetxy(unsigned char *ptr, int x, int y, int w, int h)
1699 {
1700  int byte, bit;
1701  int addr;
1702 
1703  if(y < 0 || y > h)
1704  {
1705  return;
1706  }
1707  if(x < 0 || x > w)
1708  {
1709  return;
1710  }
1711  addr = y * w + x;
1712  byte = addr >> 3;
1713  bit = (addr & 7);
1714  ptr[byte] |= (0x80 >> bit);
1715 }
1716 
1726 void bitclrxy(unsigned char *ptr, int x, int y, int width, int height)
1727 {
1728  int byte, bit;
1729  int addr;
1730 
1731  if(y < 0 || y > height)
1732  {
1733  return;
1734  }
1735  if(x < 0 || x > width)
1736  {
1737  return;
1738  }
1739  addr = y * width + x;
1740  byte = addr >> 3;
1741  bit = (addr & 7);
1742  ptr[byte] &= ~(0x80 >> bit);
1743 }
1744 
1745 
1753 void FontPreview(FILE * out, _font *font, int num)
1754 {
1755  int c;
1756  int x,y;
1757  int xoff, yoff;
1758  int w,h;
1759  int bytes;
1760  int offset;
1761  int i, mask;
1762  unsigned char *ptr = font->bitmap;
1763 
1764  if(num < 0 || num >= font->Glyphs)
1765  return;
1766 
1767  c = num + font->First;
1768 
1769  if(font->specs)
1770  {
1771 
1772  offset = font->specs[num].Offset;
1773  w = font->specs[num].Width;
1774  h = font->specs[num].Height;
1775  xoff = font->specs[num].X;
1776  yoff = font->specs[num].Y;
1777  bytes = ((w * h) + 7)/8;
1778  ptr += offset;
1779  }
1780  else
1781  {
1782  w = font->Width;
1783  h = font->Height;
1784  xoff = 0;
1785  yoff = 0;
1786  bytes = ((w * h) + 7)/8;
1787  offset = (bytes * num);
1788  ptr += offset;
1789  }
1790 
1791 
1792  fprintf(out, "/* index:%d, [%c] 0x%02x, W:% 3d, H:% 3d, X:% 3d, Y:% 3d */\n",
1793  num, c, c,
1794  w,
1795  h,
1796  xoff,
1797  yoff
1798  );
1799 
1800  // Top border
1801  fprintf(out,"/* |");
1802  for (x = 0; x < w; ++x)
1803  {
1804  fprintf(out,"-");
1805  }
1806  fprintf(out,"| */\n");
1807 
1808  // Font DATA MSB first
1809  for (y = 0; y < h; ++y) {
1810  fprintf(out,"/* |");
1811  for (x = 0; x < w; ++x) {
1812  if(bittestxy(ptr, x,y, w,h))
1813  fprintf(out,"*");
1814  else
1815  fprintf(out," ");
1816  }
1817  fprintf(out,"| */\n");
1818  }
1819 
1820  // Bottom border
1821  fprintf(out,"/* |");
1822  for (x = 0; x < w; ++x)
1823  {
1824  fprintf(out,"-");
1825  }
1826  fprintf(out,"| */\n");
1827 }
1828 
1836 void FontPreviewFull(FILE * out, _font *font, int num)
1837 {
1838  int c;
1839  int x,y;
1840  int w,h;
1841  int xoff,yoff;
1842  int bytes;
1843  int offset;
1844  int i, mask;
1845  unsigned char *ptr = font->bitmap;
1846 
1847  if(num < 0 || num >= font->Glyphs)
1848  return;
1849 
1850  c = num + font->First;
1851 
1852  if(font->specs)
1853  {
1854 
1855  offset = font->specs[num].Offset;
1856  w = font->specs[num].Width;
1857  h = font->specs[num].Height;
1858  xoff = font->specs[num].X;
1859  yoff = font->specs[num].Y;
1860  ptr += offset;
1861  }
1862  else
1863  {
1864  w = font->Width;
1865  h = font->Height;
1866  xoff = 0;
1867  yoff = 0;
1868  offset = ((w * h) + 7)/8;
1869  ptr += (offset * num);
1870  }
1871 
1872  fprintf(out, "/* index:%d, [%c] 0x%02x, W:% 3d, H:% 3d, X:% 3d, Y:% 3d */\n",
1873  num, c, c,
1874  w,
1875  h,
1876  xoff,
1877  yoff
1878  );
1879 
1880  // Top border
1881  fprintf(out,"/* |");
1882  for (x = 0; x < font->Width; ++x)
1883  {
1884  fprintf(out,"-");
1885  }
1886  fprintf(out,"| */\n");
1887 
1888  // Font DATA MSB first
1889  //for (y = yoff+h; y < font->Height; ++y)
1890  for (y = 0; y < font->Height-(yoff+h); ++y)
1891  {
1892  fprintf(out,"/* |");
1893  for (x = 0; x < font->Width; ++x)
1894  fprintf(out," ");
1895  fprintf(out,"| */\n");
1896  }
1897 
1898  for (y=0;y< h; ++y) {
1899  fprintf(out,"/* |");
1900  for (x = 0; x < xoff; ++x)
1901  fprintf(out," ");
1902  for (x=0;x < w; ++x) {
1903  if(bittestxy(ptr, x,y, w,h))
1904  fprintf(out,"*");
1905  else
1906  fprintf(out," ");
1907  }
1908  for (x=xoff+w;x < font->Width; ++x)
1909  fprintf(out," ");
1910  fprintf(out,"| */\n");
1911  }
1912 
1913  // Font DATA MSB first
1914  for (y = 0; y < yoff; ++y)
1915  {
1916  fprintf(out,"/* |");
1917  for (x = 0; x < font->Width; ++x)
1918  fprintf(out," ");
1919  fprintf(out,"| */\n");
1920  }
1921 
1922  // Bottom border
1923  fprintf(out,"/* |");
1924  for (x = 0; x < font->Width; ++x)
1925  {
1926  fprintf(out,"-");
1927  }
1928  fprintf(out,"| */\n");
1929 }
1930 
1938 void FontPreviewProportional(FILE * out, _font *font, int num)
1939 {
1940  int c;
1941  int x,y;
1942  int w,h;
1943  int xoff,yoff;
1944  int bytes;
1945  int offset;
1946  int i, mask;
1947  unsigned char *ptr = font->bitmap;
1948 
1949  if(num < 0 || num >= font->Glyphs)
1950  return;
1951 
1952  c = num + font->First;
1953 
1954  if(font->specs)
1955  {
1956 
1957  offset = font->specs[num].Offset;
1958  w = font->specs[num].Width;
1959  h = font->specs[num].Height;
1960  xoff = font->specs[num].X;
1961  yoff = font->specs[num].Y;
1962  bytes = ((w * h) + 7)/8;
1963  ptr += offset;
1964  }
1965  else
1966  {
1967  w = font->Width;
1968  h = font->Height;
1969  xoff = 0;
1970  yoff = 0;
1971  bytes = ((w * h) + 7)/8;
1972  offset = (bytes * num);
1973  ptr += offset;
1974  }
1975 
1976 
1977  fprintf(out, "/* index:%d, [%c] 0x%02x, W:% 3d, H:% 3d, X:% 3d, Y:% 3d */\n",
1978  num, c, c,
1979  w,
1980  h,
1981  xoff,
1982  yoff
1983  );
1984 
1985 
1986  // Top border
1987  fprintf(out,"/* |");
1988  for (x = 0; x < w; ++x)
1989  {
1990  fprintf(out,"-");
1991  }
1992  fprintf(out,"| */\n");
1993 
1994  // Font DATA MSB first
1995  //for (y = yoff+h; y < font->Height; ++y)
1996  for (y = 0; y < font->Height-(yoff+h); ++y)
1997  {
1998  fprintf(out,"/* |");
1999  for (x = 0; x < w; ++x)
2000  fprintf(out," ");
2001  fprintf(out,"| */\n");
2002  }
2003 
2004  for (y=0;y< h; ++y) {
2005  fprintf(out,"/* |");
2006  for (x=0;x < w; ++x) {
2007  if(bittestxy(ptr, x,y, w,h))
2008  fprintf(out,"*");
2009  else
2010  fprintf(out," ");
2011  }
2012  fprintf(out,"| */\n");
2013  }
2014 
2015  // Font DATA MSB first
2016  for (y = 0; y < yoff+1; ++y)
2017  {
2018  fprintf(out,"/* |");
2019  for (x = 0; x < w; ++x)
2020  fprintf(out," ");
2021  fprintf(out,"| */\n");
2022  }
2023 
2024  // Bottom border
2025  fprintf(out,"/* |");
2026  for (x = 0; x < w; ++x)
2027  {
2028  fprintf(out,"-");
2029  }
2030  fprintf(out,"| */\n");
2031 }
2032 
2040 void WriteFontBitsPreview(FILE * out, _font *font, int preview)
2041 {
2042  int i;
2043  int c;
2044 
2045  fprintf(out, "/* Font BIT DATA , MSB Left to Right (padded to byte alignment), Top Down */\n");
2046 
2047  for(i=0;i<font->Glyphs;++i)
2048  {
2049  if(preview == 1)
2050  FontPreview(out, font, i);
2051  if(preview == 2)
2052  FontPreviewFull(out, font, i);
2053  if(preview == 3)
2054  FontPreviewProportional(out, font, i);
2055  }
2056 }
2057 
void WriteFontTable(FILE *out, _font *font)
Write Specification Font Table.
Definition: bdffontutil.c:684
int8_t Decent
Definition: font.h:80
char * COPYRIGHT
Definition: font.h:62
MEMSPACE int WEAK_ATR strcmp(const char *str, const char *pat)
Compare two strings.
Definition: stringsup.c:362
int ReadBdf(char *name, _font *font, int lower, int upper)
Read and parse a BDF file for specified font and character set range Fills fonts structures.
Definition: bdffontutil.c:790
MEMSPACE size_t WEAK_ATR strlen(const char *str)
String Length.
Definition: stringsup.c:146
char * fnames[MAXFONTS]
Definition: bdffontutil.c:53
char * remove_quotes(char *str)
STrip quotes from string and leading spaces.
Definition: bdffontutil.c:109
int skip
Definition: user_main.c:304
Definition: font.h:43
#define MAXGLYPHS
Definition: font.h:39
int8_t Ascent
Definition: font.h:79
#define MATCH(a, b)
Definition: bdffontutil.h:39
Cordic_T X
Main Cordic routine - used for basic trig and vector rotations We use fixed point numbers...
Definition: cordic.c:102
void FreeFont(_font *font)
Free font data.
Definition: bdffontutil.c:554
par BDF font utils for BDF to C code converter Displays fonts generated by bdffont2c BDF to C code co...
int ishexstr(char *str)
Does a string only contain hex characters ?
Definition: bdffontutil.c:262
int16_t y[XYSTACK+2]
Definition: ili9341.c:372
MEMSPACE char * fgets(char *str, int size, FILE *stream)
get a string from stdin See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:420
MEMSPACE FILE * fopen(const char *path, const char *mode)
POSIX Open a file with path name and ascii file mode string.
Definition: posix.c:782
void FontHeaderInfo(FILE *out, _font *font, char *prog, char *target)
Write Font Header Information Copyright, font family, etc.
Definition: bdffontutil.c:323
static struct ip_info info
Definition: network.c:55
uint8_t * bitmap
Definition: font.h:84
MEMSPACE int WEAK_ATR strncmp(const char *str, const char *pat, size_t len)
Compare two strings maximum len bytes in size.
Definition: stringsup.c:386
#define MAXLINE
Definition: bdffontutil.h:40
void emit_data(FILE *out, char *name, unsigned char *data, int size)
Write Font Structure element as a uint8_t value.
Definition: bdffontutil.c:457
char * match_token(char *str, char *pat)
Match next token against pattern.
Definition: bdffontutil.c:279
FILE type structure.
Definition: posix.h:156
Cordic_T Y
Definition: cordic.c:102
MEMSPACE int fprintf(FILE *fp, const char *format,...)
fprintf function Example user defined printf function using fputc for I/O This method allows I/O to d...
Definition: posix.c:2484
uint8_t Width
Definition: font.h:52
void bitsetxy(unsigned char *ptr, int x, int y, int w, int h)
Set bit in width * height size bit array usng x and y offsets.
Definition: bdffontutil.c:1698
void FontPreview(FILE *out, _font *font, int num)
Write Font Preview bit bounding box in ASCII character comments.
Definition: bdffontutil.c:1753
#define snprintf(s, size, format, args...)
Definition: cpu.h:81
Definition: font.h:58
void * db_calloc(size_t size)
calloc memory or error exit
Definition: bdffontutil.c:62
void emit_number(FILE *out, char *name, int num)
Write Font Structure element as a number.
Definition: bdffontutil.c:442
void WriteFontBits(FILE *out, _font *font)
Write Font bitmap data for all characters in a font.
Definition: bdffontutil.c:631
void trim_tail(char *str)
Remove characters less then or equal to space from end of string.
Definition: bdffontutil.c:177
char * skip_spaces(char *str)
Skip spaces at start of string.
Definition: bdffontutil.c:193
MEMSPACE void * calloc(size_t nmemb, size_t size)
calloc buffer POSIX function
Definition: system.c:69
char * stralloc(char *str)
Allocate memory and copy string into it.
Definition: bdffontutil.c:93
uint8_t Height
Definition: font.h:76
char * FAMILY_NAME
Definition: font.h:64
MEMSPACE WEAK_ATR char * strcpy(char *dest, const char *src)
copy a string
Definition: stringsup.c:161
int16_t x[XYSTACK+2]
Definition: ili9341.c:371
int Offset
Definition: font.h:51
char * FILE_NAME
Definition: font.h:60
int8_t Y
Definition: font.h:55
#define NULL
Definition: cpu.h:55
_fontspecs * specs
Definition: font.h:85
void WriteFontBitsPreview(FILE *out, _font *font, int preview)
Write all Font characters in a font as ASCII character comments.
Definition: bdffontutil.c:2040
char * SLANT
Definition: font.h:66
int FindFontName(char *str)
Search for a font name.
Definition: bdffontutil.c:611
#define MAXHEIGHT
Definition: font.h:41
MEMSPACE void free(void *p)
Free buffer POSIX function We only call os_free() is pointer is not null.
Definition: system.c:87
MEMSPACE int token(char *str, char *pat)
Search for token in a string matching user pattern.
Definition: stringsup.c:671
void InitFonts(_font *font)
Initialize all font structures to reset states.
Definition: bdffontutil.c:512
_fontinfo * info
Definition: font.h:86
void AddFontName(_font *font)
Generate the font name for this font This is based on the BDF FAMILY_NAME,WEIGHT_NAME,SLANT keywords.
Definition: bdffontutil.c:582
int8_t Y
Definition: font.h:78
void ComputeGapSize(_font *font)
Find a good gap size (inter-character spacing) for any font Currently we searching for the smallest w...
Definition: bdffontutil.c:1524
int ind
Definition: ili9341.c:373
MEMSPACE int WEAK_ATR toupper(int c)
Convert character to upper case, only if it is lower case.
Definition: stringsup.c:112
MEMSPACE int fclose(FILE *stream)
POSIX close a file stream.
Definition: posix.c:1239
void bsetv(unsigned char *ptr, int addr)
bit set in byte array
Definition: bdffontutil.c:1625
int sscanf(const char *strp, const char *fmt,...)
int8_t X
Definition: font.h:54
int ishex(int c)
is a character hex ASCII character
Definition: bdffontutil.c:247
char * get_token(char *str, char *token, int max)
get first non space containing string Skip spaces at start of string
Definition: bdffontutil.c:209
_font font
uint8_t Height
Definition: font.h:53
void FontAdjustSmall(_font *font)
Ajust font to use smallest font bounding box for each font Can be used to converting large fixed font...
Definition: bdffontutil.c:1325
void bitclrxy(unsigned char *ptr, int x, int y, int width, int height)
Clear bit in width * height size bit array usng x and y offsets.
Definition: bdffontutil.c:1726
void FontPreviewProportional(FILE *out, _font *font, int num)
Write Font Preview as proportional format in ASCII character comments.
Definition: bdffontutil.c:1938
#define MAXFONTS
Definition: font.h:38
void bclrv(unsigned char *ptr, int addr)
bit clear in byte array
Definition: bdffontutil.c:1639
int16_t First
Definition: font.h:74
uint8_t Width
Definition: font.h:75
void FontPreviewFull(FILE *out, _font *font, int num)
Write Font Preview as full format in ASCII character comments.
Definition: bdffontutil.c:1836
void * db_free(void *p)
free memory
Definition: bdffontutil.c:78
#define stderr
Definition: posix.h:271
MEMSPACE char * basename(char *str)
POSIX Basename of filename.
Definition: posix.c:1446
char * EMPTY
Definition: bdffontutil.c:55
uint8_t Fixed
Definition: font.h:73
#define MAXWIDTH
Definition: font.h:40
char * WEIGHT_NAME
Definition: font.h:65
char * SPACING
Definition: font.h:67
int Bytes
Definition: font.h:83
char * FONT_NAME
Definition: font.h:63
void Convert_Font2c(FILE *out, _font *font)
Convert font to C structure Writes header information, font specification, font bitmap.
Definition: bdffontutil.c:365
int16_t Glyphs
Definition: font.h:72
int8_t gap
Definition: font.h:81
_bdffile BDFnames[MAXFONTS]
Definition: bdffontutil.c:51
char * filename
Definition: font.h:45
void InitNames()
Reset File and Structure names.
Definition: bdffontutil.c:491
void FontAdjustFull(_font *font)
Adjust font to full size with no offset.
Definition: bdffontutil.c:1240
int btestv(unsigned char *ptr, int addr)
Test bit in byte array.
Definition: bdffontutil.c:1653
MEMSPACE int atoi(const char *str)
Convert ASCII string to number in base 10.
Definition: mathio.c:281
int8_t X
Definition: font.h:77
int bittestxy(unsigned char *ptr, int x, int y, int w, int h)
Test bit in width * height size bit array usng x and y offsets.
Definition: bdffontutil.c:1670
void emit_str(FILE *out, char *name, unsigned char *data)
Write Font Structure string.
Definition: bdffontutil.c:478
char * STRUCT_NAME
Definition: font.h:61
void AdjustFontTable(_font *font)
Adjust Font X Y offset, renormalize X Y to 0 0 Also readjust font bounding box.
Definition: bdffontutil.c:1191
void WriteFontInfo(FILE *out, _font *font)
Write C Header: Font Information Summary.
Definition: bdffontutil.c:654
Definition: font.h:70
void line_wrap(char *str, int max)
Line wrap function ASSUMES we write back into the string (replace space or tab with newlines...
Definition: bdffontutil.c:141
void WriteCharacterBits(FILE *out, _font *font, int num)
Write Font bitmap data for one charactre.
Definition: bdffontutil.c:721
char * structname
Definition: font.h:46