1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/gdi/mglyph/mglyphtool.pl Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,364 @@
1.4 +# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +# All rights reserved.
1.6 +# This component and the accompanying materials are made available
1.7 +# under the terms of "Eclipse Public License v1.0"
1.8 +# which accompanies this distribution, and is available
1.9 +# at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +#
1.11 +# Initial Contributors:
1.12 +# Nokia Corporation - initial contribution.
1.13 +#
1.14 +# Contributors:
1.15 +#
1.16 +# Description:
1.17 +#
1.18 +
1.19 +use strict;
1.20 +
1.21 +## Used as global variables, probably need to change and pass variables through as parameters.
1.22 +my %globalValues=();
1.23 +##initialise filenames
1.24 +$globalValues{'inputFile'} = 'mglyphs.txt';
1.25 +$globalValues{'outputFileName'} = 'mglyphs.inl';
1.26 +$globalValues{'htmlFileName'} = 'mglyphs.html';
1.27 +$globalValues{'lgtablesize'} = 9; # Default tablesize value is 512
1.28 +$globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
1.29 +$globalValues{'storeashex'} = 0;
1.30 +$globalValues{'stepOffset'} = 72;
1.31 +$globalValues{'stepShift'} = 0;
1.32 +
1.33 +## die if the correct number of argumements have not been entered
1.34 +&extractFlags(\@ARGV, \%globalValues);
1.35 +&printDebug("Remainder:$globalValues{'tablesize'}\n");
1.36 +&printDebug("StoreAsHex:$globalValues{'storeashex'}\n");
1.37 +
1.38 +if ($globalValues{"information"})
1.39 + {
1.40 + &dieShowingUsage();
1.41 + }
1.42 +
1.43 +&printDebug("Creating HashTable....\n");
1.44 +my %hashTable = &createHashTable($globalValues{'inputFile'});
1.45 +if (!defined(%hashTable))
1.46 + {
1.47 + die("ERROR: Hash table was not created\n");
1.48 + }
1.49 +if ($globalValues{"outputtohtml"})
1.50 + {
1.51 + my $htmlFileName = $globalValues{'htmlFileName'};
1.52 + &printDebug("Creating HTML output to file: $htmlFileName\n");
1.53 + &createHTMLOfMappings($htmlFileName, %hashTable);
1.54 + }
1.55 +my $outputFileName = $globalValues{'outputFileName'};
1.56 +&printDebug("Writing Hash table to file: $outputFileName\n");
1.57 +&writeHashTableToFile($outputFileName, %hashTable);
1.58 +&printDebug("$outputFileName created.");
1.59 +
1.60 +##################### end of main section
1.61 +sub extractFlags
1.62 + {
1.63 + my $aArgumentArray=shift;
1.64 + my $aArguments=shift;
1.65 + my $expectedArg = 'lgtablesize';
1.66 + my $expectedExtension;
1.67 + foreach my $argument (@$aArgumentArray)
1.68 + {
1.69 + if ($argument =~ m!^[-/]([a-zA-Z].*)$!)
1.70 + {
1.71 + my $switch = $1;
1.72 + $expectedArg = 'lgtablesize';
1.73 + $expectedExtension = undef;
1.74 + if ($switch=~/^(x|hexoutput)$/i)
1.75 + {
1.76 + $$aArguments{'storeashex'}=1;
1.77 + }
1.78 + elsif ($switch=~/^(\?|help)$/i)
1.79 + {
1.80 + $$aArguments{'information'}=1;
1.81 + }
1.82 + elsif ($switch=~/^(v|verbose)$/i)
1.83 + {
1.84 + $$aArguments{'verbose'}=1;
1.85 + }
1.86 + elsif ($switch=~/^(h|outputtohtml)$/i)
1.87 + {
1.88 + $$aArguments{'outputtohtml'}=1;
1.89 + $expectedArg = 'htmlFileName';
1.90 + $expectedExtension = '.html';
1.91 + }
1.92 + elsif ($switch=~/^(i|input)$/i)
1.93 + {
1.94 + $expectedArg = 'inputFile';
1.95 + }
1.96 + elsif ($switch=~/^(o|output)$/i)
1.97 + {
1.98 + $expectedArg = 'outputFileName';
1.99 + $expectedExtension = '.inl';
1.100 + }
1.101 + elsif ($switch=~/^(offset)$/i)
1.102 + {
1.103 + $expectedArg = 'stepOffset';
1.104 + }
1.105 + elsif ($switch=~/^(shift)$/i)
1.106 + {
1.107 + $expectedArg = 'stepShift';
1.108 + }
1.109 + }
1.110 + else
1.111 + {
1.112 + if (defined $expectedExtension && $argument !~ m!\.[^/\\]*$!)
1.113 + {
1.114 + $argument .= $expectedExtension;
1.115 + }
1.116 + $$aArguments{$expectedArg} = $argument;
1.117 + $expectedArg = 'lgtablesize';
1.118 + }
1.119 + }
1.120 + $globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
1.121 + $globalValues{'stepOffset'} &= 0xFFFFFE;
1.122 + }
1.123 +#####################
1.124 +sub dieShowingUsage
1.125 + {
1.126 + print <<USAGE_EOF;
1.127 +
1.128 +Usage:
1.129 +
1.130 +perl -w mglyphtool.pl [-?] [<lg-table-size>] [-x] [-i <input-file-name>]
1.131 + [-o <output-file-name>] [-h [<output-html-file-name]]
1.132 + [-offset <value-for-offset>] [-shift <value-for-shift>]
1.133 +
1.134 +<lg-table-size> the default log(base 2) table size is 9. This gives a table
1.135 +size of 512 entries (2 to the power 9). So 7 gives a size of 128, 8 gives
1.136 +256, 9 gives 512, 10 gives 1024 and so on.
1.137 +
1.138 +options: -x -o -i -h
1.139 +
1.140 + -? Shows help
1.141 +
1.142 + The -x flag stores values into the .inl file in hex format:
1.143 + hex(OriginalKeyCodeMirrorGlyphCode),
1.144 + By default the values are stored in string hex format i.e 0x220C2209
1.145 +
1.146 + The -h flag generates a html file displaying hash table information.
1.147 + This may be followed by the filename to be output.
1.148 + Default is 'mglyphs.html'
1.149 +
1.150 + The -i file specifies input file name. Default is 'mglyphs.txt'.
1.151 +
1.152 + The -o file specifies output file name. Default is 'mglyphs.inl'.
1.153 +
1.154 + -shift and -offset alter the "step" hash algorithm.
1.155 +
1.156 +USAGE_EOF
1.157 + exit 0;
1.158 + }
1.159 +#########
1.160 +#
1.161 +# Writes a hash table to file.
1.162 +# Current format:
1.163 +# Hex mode: "hex number created"
1.164 +# Hex string mode: "Original keyMapped key"
1.165 +#####################
1.166 +sub writeHashTableToFile
1.167 + {
1.168 + &printDebug("Writing to .inl file");
1.169 + my ($aOutputFileName, %aHashTable) = @_;
1.170 + open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to write to\n');
1.171 + ## Print comments at top of .inl file
1.172 + printf(OUTPUT_FILE "\/\/ mGlyphs.inl\n");
1.173 + printf(OUTPUT_FILE "\/\/\n");
1.174 + printf(OUTPUT_FILE "\/\/ Generated by mglyphtool.pl from '$globalValues{'inputFile'}'\n");
1.175 + printf(OUTPUT_FILE "\/\/\n\n");
1.176 + ## Declare array and fill in values
1.177 + printf(OUTPUT_FILE "const unsigned long mGlyphArray[] = {\n\t");
1.178 + for (my $counter = 0; $counter < $globalValues{'tablesize'}; $counter++)
1.179 + {
1.180 + my $storeValue = "00000000";
1.181 + if (defined($aHashTable{$counter}))
1.182 + {
1.183 + $storeValue = $aHashTable{$counter};
1.184 + }
1.185 + $storeValue = ($globalValues{'storeashex'}) ? hex($storeValue) : "0x$storeValue";
1.186 + print OUTPUT_FILE $storeValue;
1.187 + if (($counter+1) < $globalValues{'tablesize'})
1.188 + {
1.189 + print OUTPUT_FILE (($counter + 1) % 8 == 0? ",\n\t" : ', ');
1.190 + }
1.191 + }
1.192 + print(OUTPUT_FILE "};\n");
1.193 + print(OUTPUT_FILE "\nconst int KLgMirrorTableSize=$globalValues{'lgtablesize'};\n");
1.194 + print(OUTPUT_FILE "const int KMirrorTableSize=$globalValues{'tablesize'};\n");
1.195 + # Inline functions
1.196 + # Get a Hash value from a given key
1.197 + print(OUTPUT_FILE "\n// Returns the first index to probe for character aKey.\n");
1.198 + print(OUTPUT_FILE "inline long MirrorStart(long aKey)\n");
1.199 + print(OUTPUT_FILE "\t{ return aKey \& (KMirrorTableSize-1); }\n");
1.200 + print(OUTPUT_FILE "\n// Returns the offset for further probes for character aKey.\n");
1.201 + print(OUTPUT_FILE "inline long MirrorStep(long aKey)\n");
1.202 + my $stepShift = $globalValues{'stepShift'};
1.203 + print(OUTPUT_FILE "\t{ return (");
1.204 + if ($stepShift == 0)
1.205 + {
1.206 + print(OUTPUT_FILE "aKey");
1.207 + }
1.208 + elsif (0 < $stepShift)
1.209 + {
1.210 + print(OUTPUT_FILE "(aKey >> $stepShift)");
1.211 + }
1.212 + else
1.213 + {
1.214 + $stepShift = -$stepShift;
1.215 + print(OUTPUT_FILE "(aKey << $stepShift)");
1.216 + }
1.217 + print(OUTPUT_FILE " | 1) + $globalValues{'stepOffset'}; }\n\n");
1.218 +
1.219 + close(OUTPUT_FILE);
1.220 + }
1.221 +##################### listing of hash indexes values for original and mirrored glyphs
1.222 +sub createHTMLOfMappings
1.223 + {
1.224 + my ($aOutputFileName, %aHashTable )= @_;
1.225 + open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to create HTML output');
1.226 + printf(OUTPUT_FILE "<HTML><HEAD><TITLE>MirrorGlyph Hash Output<\/TITLE><\/HEAD><BODY>");
1.227 +## print hash table details
1.228 + printf(OUTPUT_FILE "<P>Values in hash Table - <B>(Hash Function: Key mod $globalValues{'tablesize'})<\/B><\/P><TABLE border=1>");
1.229 + printf(OUTPUT_FILE "<TR><TD><B>---<\/B><\/TD><TD BGCOLOR=\#8888FF><B>Character code:<\/B><\/TD><TD><B>Hash Index:<\/B><\/TD><TD BGCOLOR=\#8888FF><B>Mirror Glyph Value:<\/B><\/TD><TD><b>Search Jump Count<\/b>");
1.230 + my %keySet;
1.231 + foreach my $value (values %aHashTable)
1.232 + {
1.233 + $keySet{&getLower(hex $value)} = 1;
1.234 + }
1.235 + foreach my $key (32..127)
1.236 + {
1.237 + $keySet{$key} = 1;
1.238 + }
1.239 + my @keys = sort {$a <=> $b} (keys %keySet);
1.240 + foreach my $key (@keys)
1.241 + {
1.242 + my $counter = 0;
1.243 + my $HKey = &findHashTableIndex($key, \$counter, \%aHashTable);
1.244 + my $stored = $aHashTable{$HKey};
1.245 + my $storedValue = 'no change';
1.246 + my $storedKey = $key;
1.247 + if (defined $stored)
1.248 + {
1.249 + $storedValue = sprintf('%02x', &getLower(hex $stored));
1.250 + $storedKey = &getUpper(hex $stored);
1.251 + }
1.252 + if ($storedKey)
1.253 + {
1.254 + die('incorrect key found in hash table') unless ($storedKey == $key);
1.255 + printf(OUTPUT_FILE "<TR><TD>---<\/TD><TD BGCOLOR=\#8888FF><B>%02x<\/B><\/TD><TD>%02x<\/TD><TD BGCOLOR=\#8888FF><B>%s<\/B><\/TD><TD>%d<\/TD><\/TR>", $key, $HKey, $storedValue, $counter);
1.256 + }
1.257 + }
1.258 + printf(OUTPUT_FILE "<\/TABLE>");
1.259 + printf(OUTPUT_FILE "<\/BODY><\/HTML>");
1.260 + close(OUTPUT_FILE);
1.261 + }
1.262 +#####################
1.263 +# Hash Table functions
1.264 +#####################
1.265 +
1.266 +#####################
1.267 +#Returns a new Hash Table
1.268 +#####################
1.269 +sub createHashTable
1.270 + {
1.271 + my $aInputFileName = shift;
1.272 + my $lineNumber = 1;
1.273 + my %newHashTable = ();
1.274 + open(INPUT_FILE, '< ' . $aInputFileName) or die('ERROR: Could not open $aInputFileName to read from');
1.275 + while (my $line=<INPUT_FILE>)
1.276 + {
1.277 + if ($line=~/^(.*);\s(.*\w)\s\W.*$/) ## Grab Original glyph value and mirrored glyph value
1.278 + {
1.279 + &updateHashTable($1, $2, \%newHashTable);
1.280 + }
1.281 + $lineNumber++;
1.282 + }
1.283 + close(INPUT_FILE);
1.284 + return %newHashTable;
1.285 + }
1.286 +#####################
1.287 +#
1.288 +# Retrieves a HashKey which is not currently being used in a given HashTable
1.289 +#
1.290 +#####################
1.291 +sub findHashTableIndex
1.292 + {
1.293 + my ($aHashKey, $aCounter, $aHashTable) = @_;
1.294 + my $current = &hashFunction($aHashKey);
1.295 + my $step = &hashStepFunction($aHashKey);
1.296 + my $tableSize = $globalValues{'tablesize'};
1.297 + while (defined($$aHashTable{$current}) && &getUpper(hex($$aHashTable{$current})) != $aHashKey)
1.298 + {
1.299 + ++$$aCounter;
1.300 + $current += $step;
1.301 + $current &= $tableSize - 1;
1.302 + }
1.303 + if (2 < $$aCounter)
1.304 + {
1.305 + printf STDERR ("WARNING: Jumped $$aCounter times, inefficient hash for %02x ($current, $step)\n", $aHashKey);
1.306 + }
1.307 + return $current;
1.308 + }
1.309 +
1.310 +#####################
1.311 +sub updateHashTable
1.312 +{
1.313 + my ($aKey, $aValueToStore, $aHashTable) = @_;
1.314 + my $counter = 0;
1.315 + my $key = hex($aKey);
1.316 + my $hashKey = &findHashTableIndex($key, \$counter, $aHashTable);
1.317 + $$aHashTable{$hashKey} = "$aKey$aValueToStore";
1.318 + return $hashKey;
1.319 +}
1.320 +#####################
1.321 +# Returns a hash key for a given key
1.322 +# Currently using a simple hash function
1.323 +#####################
1.324 +sub hashFunction
1.325 + {
1.326 + my $aKey = shift;
1.327 + return $aKey & ($globalValues{'tablesize'}-1);
1.328 + }
1.329 +
1.330 +# Returns second hash value: used for the step size
1.331 +sub hashStepFunction
1.332 + {
1.333 + my $aKey = shift;
1.334 + my $stepShift = $globalValues{'stepShift'};
1.335 + if ($stepShift < 0)
1.336 + {
1.337 + $aKey <<= -$stepShift;
1.338 + }
1.339 + elsif (0 < $stepShift)
1.340 + {
1.341 + $aKey >>= $stepShift;
1.342 + }
1.343 + return ($aKey | 1) + $globalValues{'stepOffset'};
1.344 + }
1.345 +
1.346 +#####################
1.347 +# Utility functions
1.348 +#####################
1.349 +sub getLower
1.350 + {
1.351 + my $aValue = shift;
1.352 + return $aValue & hex("0000FFFF");
1.353 + }
1.354 +sub getUpper
1.355 + {
1.356 + my $aValue = shift;
1.357 + return ($aValue & hex("FFFF0000")) >> 16;
1.358 + }
1.359 +sub printDebug
1.360 + {
1.361 + my $string = shift;
1.362 + if ($globalValues{'verbose'})
1.363 + {
1.364 + print $string;
1.365 + }
1.366 + }
1.367 +