KSM edits to RA8875
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 26 2022 07:46:24 by 1.7.2