KSM edits to RA8875

Dependents:   Liz_Test_Code

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FontMods.h Source File

FontMods.h

00001 // This file contains a perl script used to modify the mikroe generated fonts.
00002 //
00003 // Do not "include" this file into your project - just copy everything from
00004 // the #if to the #endif and put it into a .pl file on your local PC to
00005 // run it (this script requires that you have Perl installed).
00006 #if 0
00007 
00008 # ParseMikroeFont.pl
00009 #
00010 # Parse and Modify Mikroe Font File and make a few strategic changes
00011 #
00012 # Copyright (c) 2019 by Smartware Computing, all rights reserved.
00013 #
00014 use strict;
00015 use warnings; 
00016 use POSIX;
00017 
00018 my @HelpInfo = (
00019     "                                                                           ",
00020     "This script modifies a font file which was generated with a tool by        ",
00021     "MikroElektronika - GLD Font Creator.                                       ",
00022     "                                                                           ",
00023     "That tool creates the font data set for an embedded system from a Windows  ",
00024     "True Type font. The user is encouraged to ensure that the font used is     ",
00025     "properly licensed, or drawn from a source that does not have a license     ",
00026     "restriction.                                                               ",
00027     "                                                                           ",
00028     "This script will read and then modify the file for a few specific purposes:",
00029     "  * <space>   character is redefined to set the width to 1/4 the height,   ",
00030     "              because the normal behavior sets it much too narrow.         ",
00031     "  * '0' - '9' characters are redefined to set the width equal to the width ",
00032     "              of the widest digit, or to the user override value.          ",
00033     "                                                                           ",
00034     "And just because it can, it then improves upon the documentation in the    ",
00035     "resulting data structure.                                                  ",
00036     "                                                                           ",
00037     "This script was created by Smartware Computing, and is provided 'as is'    ",
00038     "with no warranty or suitability of fitness for any purpose. Anyone may use ",
00039     "or modify it subject to the agreement that:                                ",
00040     "  * The Smartware copyright statement remains intact.                      ",
00041     "  * Modifications for derivative use are clearly stated in this header.    ",
00042     "                                                                           ",
00043     "Modifications from the original:                                           ",
00044     "  * none.                                                                  ",
00045     "                                                                           ",
00046 );
00047 
00048 
00049 my $FixFile = 1;        # Fix the file with planned changes
00050 my $Details = 1;        # Emit more detailed information
00051 my $Debug = 0;          # 0=None, 1=Some, 2=Detailed
00052 
00053 my $DigitWidth = 0;     # can be set on the command line, or it uses width('0')
00054 my $ff = "";            # FontFile
00055 my $of = "";            # Output File - otherwise stdout
00056 my $OH;                 # Handle to the output file
00057 
00058 my $prg = $0;
00059 $prg =~ s/.*[\\\/]//;
00060 $prg =~ s/\.pl//i;
00061 my $args = join(" ", @ARGV);
00062 
00063 if (!@ARGV) {
00064     ShowHelp();
00065     exit;
00066 }
00067 foreach (@ARGV) {
00068     if (/-0=(\d+)/) {
00069         $DigitWidth = $1;
00070     } elsif (/-d=(\d+)/) {
00071         $Debug = $1;
00072     } elsif ($ff eq "") {
00073         $ff = $_;
00074     } elsif ($of eq "") {
00075         $of = $_;
00076     } else {
00077         ShowHelp();
00078         exit;
00079     }
00080 }
00081 if (! -e $ff) {
00082     printf("Can't read $ff\n");
00083     ShowHelp();
00084     exit;
00085 }
00086 if (! -T $ff) {
00087     printf("File $ff isn't text.\n");
00088     ShowHelp();
00089     exit;
00090 }
00091 if ($of ne "") {
00092     open($OH, ">$of") || die("Can't write to $of");
00093     select($OH);
00094 }
00095 
00096 my @data = ();      # Raw byte stream from the source file
00097 my @FileTop;
00098 my $FontDeclaration;
00099 my @FileBot;
00100 my %charData;       # charData{$char}{width}, {$char}{data}
00101 
00102 ImportFontFile();
00103 DumpRawData() if ($Debug >= 2);
00104 
00105 my $unk_0 = GetValueAt_Size_(0,1);
00106 my $unk_1 = GetValueAt_Size_(1,1);
00107 
00108 my $firstChar = GetValueAt_Size_(2,2);
00109 my $lastChar = GetValueAt_Size_(4,2);
00110 my $fontHeight = GetValueAt_Size_(6,1);
00111 my $unk_2 = GetValueAt_Size_(7,1);
00112 
00113 printf("// Char Range [%4X - %4X]\n", $firstChar, $lastChar) if ($Debug);
00114 
00115 for (my $char = $firstChar; $char <= $lastChar; $char++) {
00116     my $offsetToChar = 8 + 4 * ($char - $firstChar);
00117     my $charWidth = GetValueAt_Size_($offsetToChar,1);
00118     my $charDataNdx = GetValueAt_Size_($offsetToChar + 1, 2);
00119     $charData{$char}{width} = $charWidth;
00120     my $count = (floor(($charWidth+7)/8));
00121     @{$charData{$char}{data}} = GetByteArrayAt_Size_($charDataNdx, $count * $fontHeight);
00122 }
00123 
00124 ShowFonts() if ($Debug >= 2);   # Before Modifications
00125 FixChars() if ($FixFile);
00126 ShowFonts() if ($Debug);        # After Modifications
00127 EmitFile();
00128 if ($of ne "") {
00129     select(STDOUT);
00130     close($OH);
00131 }
00132 exit;
00133 
00134 #########################################################################
00135 
00136 sub FixChars {
00137     my @newDat;
00138     my $char;
00139     my $charWidth;
00140     my $BytesWide;
00141 
00142     #
00143     # * <space>   character is redefined to set the width to 1/4 the height.
00144     #
00145     $char = 0x20;                           # Fix <space>
00146     $charWidth = floor($fontHeight/4);
00147     $charData{$char}{width} = $charWidth;
00148     $BytesWide = floor($charWidth/8);
00149     for (my $i=0; $i<($BytesWide*$fontHeight); $i++) {
00150         $charData{$char}{data}[$i] = 0x00;
00151     }
00152     
00153     #
00154     # * '0' - '9' characters are redefined to set the width equal to width('0')
00155     #             or to the user override value.                               
00156     #
00157     if ($DigitWidth > 0) {
00158         $charWidth = $DigitWidth;   # User override option
00159     } else {
00160         $charWidth = DigitMaxWidth();           # Set it to the width of the widest digit
00161     }
00162     $BytesWide = floor(($charWidth+7)/8);
00163     #printf("Set Width = $charWidth, BytesWide = $BytesWide, Height = $fontHeight\n");
00164     for ($char = 0x30; $char <= 0x39; $char++) {
00165         for (my $h=0; $h<$fontHeight; $h++) {
00166             for (my $w=0; $w<$BytesWide; $w++) {
00167                 my $pDst = $h * $BytesWide + $w;
00168                 if ($w < ceil($charData{$char}{width}/8)) {
00169                     my $pSrc = $h * floor(($charData{$char}{width}+7)/8) + $w;
00170                     $newDat[$pDst] = $charData{$char}{data}[$pSrc];
00171                 } else {
00172                     $newDat[$pDst] = 0x00;
00173                 }
00174             }
00175         }
00176         $charData{$char}{width} = $charWidth;
00177         for (my $i=0; $i<($fontHeight * $BytesWide); $i++) {
00178             $charData{$char}{data}[$i] = $newDat[$i];
00179         }
00180         #RenderChar($char);
00181         #<stdin>;
00182     }
00183 }
00184 
00185 sub DigitMaxWidth {
00186     my $max = 0;
00187     for (my $char=0x30; $char <= 0x39; $char++) {
00188         $max  = $charData{$char}{width} if ($max < $charData{$char}{width});
00189     }
00190     return $max;
00191 }
00192 
00193 sub ImportFontFile {
00194     # 0 = scanning
00195     # 1 = after '{'
00196     # 2 = found '}'
00197     my $state = 0;
00198 
00199     open(FH, "<$ff") || die("Can't open $ff");
00200     while (<FH>) {
00201         my $rec = $_;
00202         chomp $rec;
00203         if ($state == 0) {
00204             if ($rec =~ /^const .*{/) {
00205                 $FontDeclaration = $rec;
00206                 $state = 1;
00207             } else {
00208                 push @FileTop, $rec;
00209             }
00210         } elsif ($state == 1) {
00211             if ($rec =~ /};/) {
00212                 $rec =~ s/^ +(.*)$/$1/ if ($Details);
00213                 push @FileBot, $rec;
00214                 $state = 2;
00215             } else {
00216                 $rec =~ s/( +)/ /g;
00217                 next if ($rec =~ /^ *$/);
00218                 $rec =~ s# +//.*##;
00219                 $rec =~ s/^ +(.*)$/$1/;
00220                 $rec =~ s/^(.*),$/$1/;
00221                 $rec =~ s/0x//g;
00222                 push @data, split(",", $rec);
00223             }
00224         } elsif ($state == 2) {
00225             push @FileBot, $rec;
00226         }
00227     }
00228     close FH;
00229 }
00230 
00231 
00232 sub ShowHelp {
00233     print "\n\n$prg\n\n";
00234     foreach (@HelpInfo) {
00235         print "    $_\n";
00236     }
00237     print <<EOM;
00238 $prg <MikroeFontFile> [Options] [<OptionalNewFile>]
00239 
00240     Process the MikreFontFile, optionally generating a new file.
00241 
00242     Options:
00243      -0=xx      Set Digit '0' - '9' width to xx
00244      -d=x       Set Debug Level 0=None, 1=Some, 2=More
00245 
00246 EOM
00247 }
00248 
00249 sub ShowFonts {
00250     for (my $char = $firstChar; $char <= $lastChar; $char++) {
00251         my $charWidth = $charData{$char}{width};
00252         printf("\n// === %d (0x%2X) === w:%d, h:%d\n", $char, $char, $charWidth, $fontHeight);
00253         RenderChar($char);
00254     }
00255 }
00256 
00257 sub EmitFile {
00258     if ($Details) {
00259         foreach (@HelpInfo) {
00260             print "//    $_\n";
00261         }
00262         print "// Script Activation:\n";
00263         printf("//   %s %s\n", $prg, $args);
00264         print "\n";
00265     }
00266 
00267     print join("\n", @FileTop) . "\n";      # Mikroe header
00268     printf("%s\n", $FontDeclaration);
00269     printf("    // Font Info\n") if ($Details);
00270     printf("    0x%02X,                   // Unknown #1\n", $unk_0);
00271     printf("    0x%02X,                   // Unknown #2\n", $unk_1);
00272     printf("    %s,              // FirstChar\n", HexStream($firstChar,2));
00273     printf("    %s,              // LastChar\n", HexStream($lastChar,2));
00274     printf("    %s,                   // FontHeight\n", HexStream($fontHeight,1));
00275     printf("    0x%02X,                   // Unknown #3\n", $unk_2);
00276     
00277     printf("    // Directory of Chars  [Width] [Offset-L] [Offset-M] [Offset-H]\n") if ($Details);
00278     my $offsetToChar = 8 + 4 * ($lastChar - $firstChar + 1);
00279     for (my $char = $firstChar; $char <= $lastChar; $char++) {
00280         my $charWidth = $charData{$char}{width};
00281         my $charByteCount = floor(($charWidth+7)/8) * $fontHeight;
00282         my $asc = ($char >= 0x20 && $char < 0x7F) ? chr($char) : "<non-printable>";
00283         $asc = "\\\\" if ($char == 0x5C);
00284         my $details = ($Details) ? sprintf("    // 0x%02X '%s' ", $char, $asc) : "";
00285         printf("    0x%02X,%s,0x%02X,%s\n",
00286             $charWidth, HexStream($offsetToChar,2), 0,
00287             $details
00288         );
00289         $offsetToChar += $charByteCount;
00290     }
00291     printf("    // Chars Bitstream\n") if ($Details);
00292     for (my $char = $firstChar; $char <= $lastChar; $char++) {
00293         my $charWidth = $charData{$char}{width};
00294         my $charByteCount = floor(($charWidth+7)/8) * $fontHeight;
00295         my $asc = ($char >= 0x20 && $char < 0x7F) ? chr($char) : "<non-printable>";
00296         $asc = "\\\\" if ($char == 0x5C);
00297         my $string = GetSomeHexBytes($char, 0, 8 * $charByteCount);
00298         printf("    %s%s  // 0x%02X '%s'\n",
00299             $string, 
00300             ($char != $lastChar) ? "," : "",
00301             $char, $asc
00302         );
00303     }
00304     print join("\n", @FileBot);
00305 }
00306 
00307 sub DumpRawData {
00308     my $i;
00309     print "// ";
00310     for ($i=0; $i<=$#data; $i++) {
00311         printf("%02X ", hex($data[$i]));
00312         print "\n// " if ($i % 16 == 15);
00313     }
00314     print "\n";
00315 }
00316 
00317 
00318 sub HexStream {
00319     my ($value, $len) = @_;
00320     my @parts;
00321     while ($len--) {
00322         push @parts, sprintf("0x%02X", $value & 0xFF);
00323         $value >>= 8;
00324     }
00325     return join(",", @parts);
00326 }
00327 
00328 sub RenderChar {
00329     my ($char) = shift;
00330     my $h = $fontHeight;
00331     my $w = $charData{$char}{width};
00332     
00333     PrintChar($char,$w,$h,@{$charData{$char}{data}});
00334 }
00335 
00336 sub PrintChar {
00337     my ($char,$w,$h,@datablock) = @_;
00338     
00339     printf("//     +%s+    \n// ", '-' x $w);
00340     my $row = 0;
00341     my $boolStream = 0;
00342     while ($h--) {
00343         my $pixels = $w;
00344         my $bitmask = 0x01;
00345         my $rowStream = $boolStream;
00346         printf("%02X  |", $row++);
00347         my $tail = "";
00348         while ($pixels) {
00349             my $byte;
00350             $datablock[$rowStream] = 0 if (!defined($datablock[$rowStream]));
00351             $byte = $datablock[$rowStream];
00352             printf("%s", ($byte & $bitmask) ? "*" : " ");
00353             $bitmask <<= 1;
00354             if ($pixels > 1 && ($bitmask & 0xFF) == 0) {
00355                 $bitmask = 0x01;
00356                 $rowStream++;
00357             }
00358             $pixels--;
00359         }
00360         printf("|    %s\n// ", $tail);
00361         $boolStream += ($rowStream - $boolStream + 1);
00362     }
00363     printf("    +%s+\n", '-' x $w);
00364 }
00365 
00366 
00367 sub GetSomeHexBytes {
00368     my ($char, $offSet, $w) = @_;
00369     my @out;
00370     my $x = 0;
00371     
00372     $w = floor(($w+7)/8);
00373     while ($w--) {
00374         my $c = 0;
00375         $c = $charData{$char}{data}[$offSet + $x++] if (defined($charData{$char}{data}[$offSet + $x]));
00376         push @out, sprintf("0x%02X", $c);
00377     }
00378     return join(",", @out);
00379 }
00380 
00381 sub GetSomeBytes {
00382     my ($char, $offSet, $w) = @_;
00383     my $string = "";
00384     my $x = 0;
00385     
00386     $w = floor(($w+7)/8);
00387     while ($w--) {
00388         $string .= sprintf("%02X ", $charData{$char}{data}[$offSet + $x++]);
00389     }
00390     return $string;
00391 }
00392 
00393 sub GetValueAt_Size_ {
00394     my ($offset, $size) = @_;
00395     my $value = 0;
00396     while ($size--) {
00397         $value = ($value << 8) | hex($data[$offset + $size]);
00398     }
00399     return $value;
00400 }
00401 
00402 sub GetValueFromArray_At_Size_ {
00403     my ($offset, $size, $ary) = @_;
00404     my $value = 0;
00405     while ($size--) {
00406         $value = ($value << 8) | hex($$ary[$offset + $size]);
00407     }
00408     return $value;
00409 }
00410 
00411 sub GetByteArrayAt_Size_ {
00412     my ($offset, $size) = @_;
00413     my @bytes;
00414     while ($size--) {
00415         push @bytes, hex($data[$offset++]);
00416     }
00417     return @bytes;
00418 }
00419 
00420 sub GetByteSreamAt_Size_ {
00421     my ($offset, $size) = @_;
00422     my $value = "";
00423     while ($size--) {
00424         $value .= sprintf("%02X ", hex($data[$offset++]));
00425     }
00426     return $value;
00427 }
00428 
00429 #endif