termfont

Log

Files

Refs

termfont.c (19706B)

     1 #! /usr/bin/env sheepy
     2 /* or direct path to sheepy: #! /usr/local/bin/sheepy */
     3 
     4 // ANSI Regular.flf ANSI Shadow.flf DOS Rebel.flf
     5 // https://www.fontspace.com/withheld-data-font-f29245
     6 // https://www.fontspace.com/computer-pixel-7-font-f15539
     7 // https://www.fontspace.com/pxlvetica-font-f16197
     8 // https://www.fontspace.com/trs-80-coconut-font-f29856
     9 // https://www.fontspace.com/shylock-nbp-font-f15144
    10 // https://www.fontspace.com/guru-meditation-nbp-font-f15920
    11 // https://www.fontspace.com/bittypix-monospace-font-f29160
    12 // https://www.fontspace.com/g7-star-force-font-f5955
    13 // https://www.fontspace.com/inky-thin-pixels-font-f28123
    14 // https://www.fontspace.com/public-pixel-font-f72305
    15 // https://www.fontspace.com/hachicro-undertale-font-f83280
    16 // https://www.fontspace.com/pixgamer-font-f85447
    17 // https://www.fontspace.com/pixeloid-font-f69232
    18 // https://www.fontspace.com/minecraft-font-f28180
    19 // https://www.fontspace.com/press-start-2p-font-f11591
    20 // https://www.fontspace.com/jogan-soft-font-f80664
    21 // https://www.fontspace.com/pixel-emulator-font-f21507
    22 // https://www.fontspace.com/determination-mono-web-font-f23209
    23 // https://www.fontspace.com/lcd-solid-font-f11346
    24 // https://www.fontspace.com/nineteen-ninety-seven-font-f29655
    25 // https://www.fontspace.com/old-school-adventures-font-f26494
    26 // https://www.fontspace.com/edit-undo-brk-font-f19980
    27 // https://www.fontspace.com/mozart-nbp-font-f18977
    28 // https://www.fontspace.com/mecha-font-f13151
    29 // https://www.fontspace.com/gamegirl-classic-font-f3331
    30 // https://www.fontspace.com/thin-pixel-7-font-f16064
    31 // https://www.fontspace.com/connection-serif-font-f26406
    32 // https://www.fontspace.com/warioland4tt-font-f30199
    33 // https://www.fontspace.com/teeny-tiny-pixls-font-f30095
    34 // convert -background none -fill black -font font.ttf -pointsize 300 label:"Z" z.png
    35 // convert file txt:-
    36 
    37 /* Libsheepy documentation: https://spartatek.se/libsheepy/ */
    38 #include "libsheepyObject.h"
    39 
    40 #define FONT_DIR "~/.termfont/"
    41 
    42 int argc; char **argv;
    43 
    44 /* enable/disable logging */
    45 /* #undef pLog */
    46 /* #define pLog(...) */
    47 
    48 typ struct {
    49   u32 width;
    50   u8  *pixels;
    51 } symbol;
    52 
    53 typ struct {
    54   bool   pixel;
    55   u32    height;
    56   symbol chars[127];
    57   u8     *pixels;
    58 } twidfont;
    59 
    60 bool parseTwidFont(smallArrayt *fontFile, twidfont *font) {
    61 
    62   // scan symbol sizes
    63   // create pixel buffer
    64   // copy font to pixel buffer
    65 
    66   // scan symbol sizes
    67   u32 totalWidth  = 0;
    68   u8 index        = 0;
    69   bool scanHeight = yes;
    70   char *status    = "pixel";
    71   iter(fontFile, L) {
    72     castS(l, L);
    73     if (eqG(status, "in char")) {
    74       if (font->chars[index].width == 0) {
    75         font->chars[index].width = indexOfG(l, "@");
    76         totalWidth += font->chars[index].width;
    77       }
    78       if (scanHeight) inc font->height;
    79       if (endsWithG(l, "@@")) {
    80         // char is finished
    81         scanHeight = no;
    82         status     = "define char";
    83         continue;
    84       }
    85     }
    86     if (eqG(status, "define char")) {
    87       defineChar:
    88       index = ssGet(l)[0];
    89       status = "in char";
    90     }
    91     if (eqG(status, "pixel")) {
    92       if (ssGet(l)[0] == '#') continue; // comment at the begining
    93       font->pixel = eqG(l, "pixel");
    94       if (not font->pixel) goto defineChar; // already define char
    95       status      = "define char";
    96     }
    97   }
    98   //logVarG(totalWidth);
    99 
   100   // create pixel buffer
   101   font->pixels = malloc(font->height * totalWidth);
   102 
   103   // copy font to pixel buffer
   104   u8 *symbolStart = font->pixels;
   105   u8 *p; // pointer for copying symbol pixel data
   106   status          = "pixel";
   107   iter(fontFile, L) {
   108     castS(l, L);
   109     if (eqG(status, "in char")) {
   110       if (!font->chars[index].pixels) {
   111         // set pointer in pixel buffer for symbol
   112         font->chars[index].pixels = symbolStart;
   113         p                         = symbolStart;
   114         symbolStart              += font->height * font->chars[index].width;
   115       }
   116       memcpy(p, ssGet(l), font->chars[index].width);
   117       p += font->chars[index].width;
   118       if (endsWithG(l, "@@")) {
   119         // char is finished
   120         scanHeight = no;
   121         status     = "define char";
   122         continue;
   123       }
   124     }
   125     if (eqG(status, "define char")) {
   126       defineChar2:
   127       index = ssGet(l)[0];
   128       status = "in char";
   129     }
   130     if (eqG(status, "pixel")) {
   131       if (ssGet(l)[0] == '#') continue; // comment at the begining
   132       font->pixel = eqG(l, "pixel");
   133       if (not font->pixel) goto defineChar2; // already define char
   134       status      = "define char";
   135     }
   136   }
   137 
   138   ret yes;
   139 }
   140 
   141 void freeTwidFont(twidfont *font) {
   142   if (font) freen(font->pixels);
   143 }
   144 
   145 void showRawSymbol(twidfont *font, u32 index) {
   146   if (!font) ret;
   147   u8 line[font->chars[index].width +1];
   148   line[font->chars[index].width] = 0;
   149 
   150   u8 *p = font->chars[index].pixels;
   151   range(i, font->height) {
   152     memcpy(line, p, font->chars[index].width);
   153     p += font->chars[index].width;
   154     puts(line);
   155   }
   156 }
   157 
   158 // bit 0 is the lower line
   159 // bit 1 is the upper line
   160 // ▄ 0x2584 ▀ 0x2580 █ 0x2588
   161 char *halfBlocks[] = {" ", "▄", "▀", "█"};
   162 
   163 void showSymbolHalfBlock(twidfont *font, u32 index) {
   164   if (!font or !font->pixel) ret;
   165 
   166   u8 *p = font->chars[index].pixels;
   167   rangeFromStep(j, 1, font->height, 2) {
   168     u8 block = 0;
   169     range(i, font->chars[index].width) {
   170       block = (*(p + i)== ' ' ? 0 : 2) | (*(p + i + font->chars[index].width)== ' ' ? 0 : 1);
   171       printf(halfBlocks[block]);
   172     }
   173     put;
   174     p += font->chars[index].width * 2;
   175   }
   176   if (font->height & 1) {
   177     u8 block = 0;
   178     range(i, font->chars[index].width) {
   179       block = (*(p + i)== ' ' ? 0 : 2);
   180       printf(halfBlocks[block]);
   181     }
   182     put;
   183   }
   184 }
   185 
   186 // bits 3|2
   187 //      ---
   188 //      1|0
   189 // ▗ 0x2597 ▖ 0x2596 ▄ 0x2584 ▝ 0x259D ▐ 0x2590 ▞ 0x259E ▟ 0x259F ▘ 0x2598
   190 // ▚ 0x259A ▌ 0x258C ▙ 0x2599 ▀ 0x2580 ▜ 0x259C ▛ 0x259B █ 0x2588
   191 char *quadrants[] = {" ", "▗", "▖", "▄", "▝", "▐", "▞", "▟", "▘", "▚", "▌", "▙", "▀", "▜", "▛", "█"};
   192 
   193 void showSymbolQuadrant(twidfont *font, u32 index) {
   194   if (!font or !font->pixel) ret;
   195 
   196   u8 *p = font->chars[index].pixels;
   197   rangeFromStep(j, 1, font->height, 2) {
   198     u8 block = 0;
   199     rangeFromStep(i, 1, font->chars[index].width, 2) {
   200       block =   (*(p + i-1)                            == ' ' ? 0 : 8)
   201               | (*(p + i)                              == ' ' ? 0 : 4)
   202               | (*(p + i-1 + font->chars[index].width) == ' ' ? 0 : 2)
   203               | (*(p + i + font->chars[index].width)   == ' ' ? 0 : 1);
   204       printf(quadrants[block]);
   205     }
   206     if (font->chars[index].width & 1) {
   207       block =   (*(p + font->chars[index].width-1)                            == ' ' ? 0 : 8)
   208               | (*(p + font->chars[index].width-1 + font->chars[index].width) == ' ' ? 0 : 2);
   209       printf(quadrants[block]);
   210     }
   211     put;
   212     p += font->chars[index].width * 2;
   213   }
   214   if (font->height & 1) {
   215     u8 block = 0;
   216     range(i, font->chars[index].width) {
   217       block = (*(p + i)== ' ' ? 0 : 2);
   218       printf(halfBlocks[block]);
   219     }
   220     put;
   221   }
   222 }
   223 
   224 void showStringRaw(twidfont *font, char *string) {
   225   if (!font or font->pixel) ret;
   226   size_t len = lenG(string);
   227   if (!len) ret;
   228 
   229   u32 totalWidth = 0; // in blocks
   230   range(i, len) {
   231     totalWidth += font->chars[string[i]].width;
   232   }
   233 
   234   totalWidth += 1; // for line returns and end of string
   235 
   236   u8 *pixels  = malloc(font->height * totalWidth);
   237   u32 x       = 0; // start of next character in pixels
   238 
   239   range(i, len) {
   240     if (!font->chars[string[i]].width) continue; // font symbol unavailable
   241     // copy symbol to buffer
   242     u8 *p = font->chars[string[i]].pixels;
   243     range(ii, font->height) {
   244       memcpy(pixels + x + ii * totalWidth, p, font->chars[string[i]].width);
   245       p += font->chars[string[i]].width;
   246     }
   247 
   248     x+= font->chars[string[i]].width;
   249   }
   250   range(i, font->height-1) {
   251     *(pixels + totalWidth -1 + i * totalWidth) = '\n';
   252   }
   253   *(pixels + totalWidth -1 + (font->height-1) * totalWidth) = 0;
   254 
   255   printf(pixels);
   256   put
   257 
   258   free(pixels);
   259 }
   260 
   261 void showStringHalfblock(twidfont *font, char *string) {
   262   if (!font or !font->pixel) ret;
   263   size_t len = lenG(string);
   264   if (!len) ret;
   265 
   266   u32 totalWidth = 0; // in blocks
   267   range(i, len) {
   268     totalWidth += font->chars[string[i]].width;
   269   }
   270 
   271   u8 *pixels  = malloc(font->height * totalWidth);
   272   u32 x       = 0; // start of next character in pixels
   273 
   274   range(i, len) {
   275     if (!font->chars[string[i]].width) continue; // font symbol unavailable
   276     // copy symbol to buffer
   277     u8 *p = font->chars[string[i]].pixels;
   278     range(ii, font->height) {
   279       memcpy(pixels + x + ii * totalWidth, p, font->chars[string[i]].width);
   280       p += font->chars[string[i]].width;
   281     }
   282 
   283     x+= font->chars[string[i]].width;
   284   }
   285 
   286   u8 *p = pixels;
   287   rangeFromStep(j, 1, font->height, 2) {
   288     u8 block = 0;
   289     range(i, totalWidth) {
   290       block = (*(p + i)== ' ' ? 0 : 2) | (*(p + i + totalWidth)== ' ' ? 0 : 1);
   291       printf(halfBlocks[block]);
   292     }
   293     put;
   294     p += totalWidth * 2;
   295   }
   296   if (font->height & 1) {
   297     u8 block = 0;
   298     range(i, totalWidth) {
   299       block = (*(p + i)== ' ' ? 0 : 2);
   300       printf(halfBlocks[block]);
   301     }
   302     put;
   303   }
   304 
   305   /* u32 *buffer = malloc(  (font->height/2 + font->height&1) */
   306   /*                      * (  totalWidth) */
   307   /*                      * sizeof(u32)); */
   308   /* free(buffer); */
   309   free(pixels);
   310 }
   311 
   312 void showStringHalfblockNoFullBlock(twidfont *font, char *string) {
   313   if (!font or !font->pixel) ret;
   314   size_t len = lenG(string);
   315   if (!len) ret;
   316 
   317   u32 totalWidth = 0; // in blocks
   318   range(i, len) {
   319     totalWidth += font->chars[string[i]].width;
   320   }
   321 
   322   u8 *pixels  = malloc(font->height * totalWidth);
   323   u32 x       = 0; // start of next character in pixels
   324 
   325   range(i, len) {
   326     if (!font->chars[string[i]].width) continue; // font symbol unavailable
   327     // copy symbol to buffer
   328     u8 *p = font->chars[string[i]].pixels;
   329     range(ii, font->height) {
   330       memcpy(pixels + x + ii * totalWidth, p, font->chars[string[i]].width);
   331       p += font->chars[string[i]].width;
   332     }
   333 
   334     x+= font->chars[string[i]].width;
   335   }
   336 
   337   u32 colors[] = {0x4495cc, 0x6baddb, 0xcceafe, 0xd4eefd, 0x896215, 0xd49b33, 0xe3b248, 0xfee2a4};
   338 
   339   u8 *p = pixels;
   340   rangeFromStep(j, 1, font->height, 2) {
   341     range(i, totalWidth) {
   342       if (*(p + i)== ' ')
   343         printf("%k",0);
   344       else
   345         printf("%k", colors[j-1]);
   346       if (*(p + i + totalWidth)== ' ')
   347         printf("%K", 0);
   348       else
   349         printf("%K", colors[j]);
   350       printf(halfBlocks[2]);
   351     }
   352     printf(RST);
   353     put;
   354     p += totalWidth * 2;
   355   }
   356   if (font->height & 1) {
   357     range(i, totalWidth) {
   358       if (*(p + i)== ' ')
   359         printf("%k",0);
   360       else
   361         printf("%k", colors[j-1]);
   362       printf(halfBlocks[2]);
   363       printf(RST);
   364     }
   365     put;
   366   }
   367 
   368   /* u32 *buffer = malloc(  (font->height/2 + font->height&1) */
   369   /*                      * (  totalWidth) */
   370   /*                      * sizeof(u32)); */
   371   /* free(buffer); */
   372   free(pixels);
   373 }
   374 
   375 void showStringQuadrant(twidfont *font, char *string) {
   376   if (!font or !font->pixel) ret;
   377   size_t len = lenG(string);
   378   if (!len) ret;
   379 
   380   u32 totalWidth = 0; // in blocks
   381   range(i, len) {
   382     totalWidth += font->chars[string[i]].width;
   383   }
   384 
   385   u8 *pixels  = malloc(font->height * totalWidth);
   386   u32 x       = 0; // start of next character in pixels
   387 
   388   range(i, len) {
   389     if (!font->chars[string[i]].width) continue; // font symbol unavailable
   390     // copy symbol to buffer
   391     u8 *p = font->chars[string[i]].pixels;
   392     range(ii, font->height) {
   393       memcpy(pixels + x + ii * totalWidth, p, font->chars[string[i]].width);
   394       p += font->chars[string[i]].width;
   395     }
   396 
   397     x+= font->chars[string[i]].width;
   398   }
   399 
   400   u8 *p = pixels;
   401   rangeFromStep(j, 1, font->height, 2) {
   402     u8 block = 0;
   403     rangeFromStep(i, 1, totalWidth, 2) {
   404       block =   (*(p + i-1)              == ' ' ? 0 : 8)
   405               | (*(p + i)                == ' ' ? 0 : 4)
   406               | (*(p + i-1 + totalWidth) == ' ' ? 0 : 2)
   407               | (*(p + i + totalWidth)   == ' ' ? 0 : 1);
   408       printf(quadrants[block]);
   409     }
   410     if (totalWidth & 1) {
   411       block =   (*(p + totalWidth-1)              == ' ' ? 0 : 8)
   412               | (*(p + totalWidth-1 + totalWidth) == ' ' ? 0 : 2);
   413       printf(quadrants[block]);
   414     }
   415     put;
   416     p += totalWidth * 2;
   417   }
   418   if (font->height & 1) {
   419     u8 block = 0;
   420     rangeFromStep(i, 1, totalWidth, 2) {
   421       block =   (*(p + i-1) == ' ' ? 0 : 8)
   422               | (*(p + i)   == ' ' ? 0 : 4);
   423       printf(quadrants[block]);
   424     }
   425     if (totalWidth & 1) {
   426       block =   (*(p + totalWidth-1)              == ' ' ? 0 : 8);
   427       printf(quadrants[block]);
   428     }
   429     put;
   430   }
   431 
   432   /* u32 *buffer = malloc(  (font->height/2 + font->height&1) */
   433   /*                      * (  totalWidth/2 + totalWidth&1) */
   434   /*                      * sizeof(u32)); */
   435   /* free(buffer); */
   436   free(pixels);
   437 }
   438 
   439 void showStringQuadrantColors(twidfont *font, char *string) {
   440   if (!font or !font->pixel) ret;
   441   size_t len = lenG(string);
   442   if (!len) ret;
   443 
   444   u32 totalWidth = 0; // in blocks
   445   range(i, len) {
   446     totalWidth += font->chars[string[i]].width;
   447   }
   448 
   449   u8 *pixels  = malloc(font->height * totalWidth);
   450   u32 x       = 0; // start of next character in pixels
   451 
   452   range(i, len) {
   453     if (!font->chars[string[i]].width) continue; // font symbol unavailable
   454     // copy symbol to buffer
   455     u8 *p = font->chars[string[i]].pixels;
   456     range(ii, font->height) {
   457       memcpy(pixels + x + ii * totalWidth, p, font->chars[string[i]].width);
   458       p += font->chars[string[i]].width;
   459     }
   460 
   461     x+= font->chars[string[i]].width;
   462   }
   463 
   464   u32 colors[] = {0x4495cc, 0xd4eefd, 0xd49b33, 0xecc778};
   465 
   466   u8 *p = pixels;
   467   rangeFromStep(j, 1, font->height, 2) {
   468     u8 block = 0;
   469     printf("%k", colors[j/2]);
   470     rangeFromStep(i, 1, totalWidth, 2) {
   471       block =   (*(p + i-1)              == ' ' ? 0 : 8)
   472               | (*(p + i)                == ' ' ? 0 : 4)
   473               | (*(p + i-1 + totalWidth) == ' ' ? 0 : 2)
   474               | (*(p + i + totalWidth)   == ' ' ? 0 : 1);
   475       printf(quadrants[block]);
   476     }
   477     if (totalWidth & 1) {
   478       block =   (*(p + totalWidth-1)              == ' ' ? 0 : 8)
   479               | (*(p + totalWidth-1 + totalWidth) == ' ' ? 0 : 2);
   480       printf(quadrants[block]);
   481     }
   482     printf(RST);
   483     put;
   484     p += totalWidth * 2;
   485   }
   486   if (font->height & 1) {
   487     u8 block = 0;
   488     printf("%k", colors[font->height/2]);
   489     rangeFromStep(i, 1, totalWidth, 2) {
   490       block =   (*(p + i-1) == ' ' ? 0 : 8)
   491               | (*(p + i)   == ' ' ? 0 : 4);
   492       printf(quadrants[block]);
   493     }
   494     if (totalWidth & 1) {
   495       block =   (*(p + totalWidth-1)              == ' ' ? 0 : 8);
   496       printf(quadrants[block]);
   497     }
   498     printf(RST);
   499     put;
   500   }
   501 
   502   /* u32 *buffer = malloc(  (font->height/2 + font->height&1) */
   503   /*                      * (  totalWidth/2 + totalWidth&1) */
   504   /*                      * sizeof(u32)); */
   505   /* free(buffer); */
   506   free(pixels);
   507 }
   508 
   509 void list(void) {
   510   cleanCharP(p)         = expandHome(FONT_DIR);
   511   cleanSmallArrayP(dir) = readDirG(rtSmallArrayt, p);
   512 
   513   iter(dir, L) {
   514     castS(l,L);
   515     if (endsWithG(l, ".twidf")) {
   516       setG(l, -6, 0);
   517       logI("%m", l);
   518     }
   519   }
   520 }
   521 void demo(void) {
   522   cleanCharP(p)         = expandHome(FONT_DIR);
   523   cleanSmallArrayP(dir) = readDirG(rtSmallArrayt, p);
   524 
   525   iter(dir, L) {
   526     castS(l,L);
   527     if (endsWithG(l, ".twidf")) {
   528       cleanAllocateSmallArray(fontFile);
   529       readFileG(fontFile, l);
   530       setG(l, -6, 0);
   531       logI("%m", l);
   532       twidfont font = init0Var;
   533       parseTwidFont(fontFile, &font);
   534       if (not font.pixel)
   535         showStringRaw(&font,  "0123 abcd ABCD");
   536       else {
   537         showStringQuadrant(&font, "0123 abcd ABCD");
   538         showStringHalfblock(&font, "0123 abcd ABCD");
   539       }
   540       freeTwidFont(&font);
   541     }
   542   }
   543 }
   544 
   545 int main(int ARGC, char** ARGV) {
   546 
   547   argc = ARGC; argv = ARGV;
   548 
   549   initLibsheepy(ARGV[0]);
   550   setLogMode(LOG_VOID);
   551   //openProgLogFile();
   552   //setLogSymbols(LOG_UTF8);
   553   //disableLibsheepyErrorLogs;
   554 
   555   if ((argc == 1) or
   556       (argc == 4 and not eqG(argv[1], "-f") and not eqG(argv[1], "-F"))) {
   557     help:
   558     logI("Help\n"
   559          "Commands:\n"
   560          BLD CYN"list"RST"                                    to list available fonts in "FONT_DIR"\n"
   561          BLD CYN"demo"RST"                                    to print a short string with all available fonts\n"
   562          BLD CYN"-f font name (without .twidf) 'Message'"RST" to show message with the selected font rendered with quadrants\n"
   563          BLD CYN"-F font name (without .twidf) 'Message'"RST" to show message with the selected font rendered with halfblocks\n"
   564          BLD CYN"color 'Message'"RST"                         to show message with the PressStart2P halfblock with colors\n"
   565          BLD CYN"help, -h or --help"RST"                      for help");
   566     ret 0;
   567   }
   568   if (argc == 2) {
   569     if (eqG(argv[1], "help") or eqG(argv[1], "--help") or eqG(argv[1], "-h")) goto help;
   570     elif (eqG(argv[1], "list")) {
   571       list();
   572       ret 0;
   573     }
   574     elif (eqG(argv[1], "demo")) {
   575       demo();
   576       ret 0;
   577     }
   578     goto help;
   579   }
   580 
   581   if (argc == 3) {
   582     if (eqG(argv[1], "color")) {
   583       cleanAllocateSmallArray(fontFile);
   584       cleanCharP(p) = expandHome(FONT_DIR"PressStart2P.twidf");
   585       readFileG(fontFile, p);
   586 
   587       twidfont font = init0Var;
   588 
   589       parseTwidFont(fontFile, &font);
   590 
   591       showStringHalfblockNoFullBlock(&font, argv[2]);
   592 
   593       freeTwidFont(&font);
   594       ret 0;
   595     }
   596     goto help;
   597   }
   598 
   599   cleanCharP(fontname) = catS(argv[2], ".twidf");
   600   if (not isPath(fontname)) {
   601     freen(fontname);
   602     cleanCharP(p) = catS(FONT_DIR, argv[2], ".twidf");
   603     fontname      = expandHome(p);
   604     if (not isPath(fontname)) {
   605       logE("Font file not found: %s", argv[2]);
   606       ret 1;
   607     }
   608   }
   609 
   610   cleanAllocateSmallArray(fontFile);
   611   readFileG(fontFile, fontname);
   612 
   613   twidfont font = init0Var;
   614 
   615   parseTwidFont(fontFile, &font);
   616 
   617   if   (not font.pixel)
   618     showStringRaw(&font,  argv[3]);
   619   elif (eqG(argv[1], "-f"))
   620     showStringQuadrant(&font, argv[3]);
   621   elif (eqG(argv[1], "-F"))
   622     showStringHalfblock(&font, argv[3]);
   623 
   624   freeTwidFont(&font);
   625   ret 0;
   626 
   627   {
   628     cleanAllocateSmallArray(fontFile);
   629     //readFileG(fontFile, "WithheldData.twidf");
   630     //readFileG(fontFile, "Warioland.twidf");
   631     readFileG(fontFile, "PressStart2P.twidf");
   632     // TODO readFileG(fontFile, "hazeltine.twidf");
   633 
   634     twidfont font = init0Var;
   635 
   636     parseTwidFont(fontFile, &font);
   637 
   638     logI("Font height %d", font.height);
   639 
   640     arange(i, font.chars) {
   641       if (font.chars[i].width) {
   642         //showSymbolQuadrant(&font, i);
   643         showRawSymbol(&font, i);
   644       }
   645     }
   646 
   647     /* showRawSymbol(&font, '#'); */
   648     /* showRawSymbol(&font, '


); */
   649     /* showSymbolHalfBlock(&font, '#'); */
   650     /* showSymbolHalfBlock(&font, '


); */
   651     /* showSymbolQuadrant(&font, '#'); */
   652     /* showSymbolQuadrant(&font, '


); */
   653     //showStringQuadrant(&font, "0123456789 abcdefghijklmnopqrstuvwxz ABCDEFGHIJKLMNOPQRSTUVWXZ");
   654     showStringHalfblock(&font, "0123 abcd ABCD");
   655     showStringHalfblockNoFullBlock(&font, "0123 abcd ABCD");
   656     showStringQuadrant(&font, "Press Start");
   657     showStringQuadrant(&font, "> <");
   658 
   659     showStringRaw(&font, "12");
   660 
   661     // demo
   662     cleanSmallArrayP(dir) = readDirG(rtSmallArrayt, ".");
   663 
   664     iter(dir, L) {
   665       castS(l,L);
   666       if (endsWithG(l, ".twidf")) {
   667         logI("%m", l);
   668         cleanAllocateSmallArray(fontFile);
   669         readFileG(fontFile, l);
   670         twidfont font = init0Var;
   671         parseTwidFont(fontFile, &font);
   672         showStringQuadrant(&font, "0123 abcd ABCD");
   673         showStringHalfblock(&font, "0123 abcd ABCD");
   674         freeTwidFont(&font);
   675       }
   676     }
   677 
   678     freeTwidFont(&font);
   679   }
   680 }
   681 // vim: set expandtab ts=2 sw=2: