diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/gdi/mglyph/mglyphtool.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/gdi/mglyph/mglyphtool.pl Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,364 @@ +# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +use strict; + +## Used as global variables, probably need to change and pass variables through as parameters. +my %globalValues=(); +##initialise filenames +$globalValues{'inputFile'} = 'mglyphs.txt'; +$globalValues{'outputFileName'} = 'mglyphs.inl'; +$globalValues{'htmlFileName'} = 'mglyphs.html'; +$globalValues{'lgtablesize'} = 9; # Default tablesize value is 512 +$globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'}; +$globalValues{'storeashex'} = 0; +$globalValues{'stepOffset'} = 72; +$globalValues{'stepShift'} = 0; + +## die if the correct number of argumements have not been entered +&extractFlags(\@ARGV, \%globalValues); +&printDebug("Remainder:$globalValues{'tablesize'}\n"); +&printDebug("StoreAsHex:$globalValues{'storeashex'}\n"); + +if ($globalValues{"information"}) + { + &dieShowingUsage(); + } + +&printDebug("Creating HashTable....\n"); +my %hashTable = &createHashTable($globalValues{'inputFile'}); +if (!defined(%hashTable)) + { + die("ERROR: Hash table was not created\n"); + } +if ($globalValues{"outputtohtml"}) + { + my $htmlFileName = $globalValues{'htmlFileName'}; + &printDebug("Creating HTML output to file: $htmlFileName\n"); + &createHTMLOfMappings($htmlFileName, %hashTable); + } +my $outputFileName = $globalValues{'outputFileName'}; +&printDebug("Writing Hash table to file: $outputFileName\n"); +&writeHashTableToFile($outputFileName, %hashTable); +&printDebug("$outputFileName created."); + +##################### end of main section +sub extractFlags + { + my $aArgumentArray=shift; + my $aArguments=shift; + my $expectedArg = 'lgtablesize'; + my $expectedExtension; + foreach my $argument (@$aArgumentArray) + { + if ($argument =~ m!^[-/]([a-zA-Z].*)$!) + { + my $switch = $1; + $expectedArg = 'lgtablesize'; + $expectedExtension = undef; + if ($switch=~/^(x|hexoutput)$/i) + { + $$aArguments{'storeashex'}=1; + } + elsif ($switch=~/^(\?|help)$/i) + { + $$aArguments{'information'}=1; + } + elsif ($switch=~/^(v|verbose)$/i) + { + $$aArguments{'verbose'}=1; + } + elsif ($switch=~/^(h|outputtohtml)$/i) + { + $$aArguments{'outputtohtml'}=1; + $expectedArg = 'htmlFileName'; + $expectedExtension = '.html'; + } + elsif ($switch=~/^(i|input)$/i) + { + $expectedArg = 'inputFile'; + } + elsif ($switch=~/^(o|output)$/i) + { + $expectedArg = 'outputFileName'; + $expectedExtension = '.inl'; + } + elsif ($switch=~/^(offset)$/i) + { + $expectedArg = 'stepOffset'; + } + elsif ($switch=~/^(shift)$/i) + { + $expectedArg = 'stepShift'; + } + } + else + { + if (defined $expectedExtension && $argument !~ m!\.[^/\\]*$!) + { + $argument .= $expectedExtension; + } + $$aArguments{$expectedArg} = $argument; + $expectedArg = 'lgtablesize'; + } + } + $globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'}; + $globalValues{'stepOffset'} &= 0xFFFFFE; + } +##################### +sub dieShowingUsage + { + print <] [-x] [-i ] + [-o ] [-h [] [-shift ] + + the default log(base 2) table size is 9. This gives a table +size of 512 entries (2 to the power 9). So 7 gives a size of 128, 8 gives +256, 9 gives 512, 10 gives 1024 and so on. + +options: -x -o -i -h + + -? Shows help + + The -x flag stores values into the .inl file in hex format: + hex(OriginalKeyCodeMirrorGlyphCode), + By default the values are stored in string hex format i.e 0x220C2209 + + The -h flag generates a html file displaying hash table information. + This may be followed by the filename to be output. + Default is 'mglyphs.html' + + The -i file specifies input file name. Default is 'mglyphs.txt'. + + The -o file specifies output file name. Default is 'mglyphs.inl'. + + -shift and -offset alter the "step" hash algorithm. + +USAGE_EOF + exit 0; + } +######### +# +# Writes a hash table to file. +# Current format: +# Hex mode: "hex number created" +# Hex string mode: "Original keyMapped key" +##################### +sub writeHashTableToFile + { + &printDebug("Writing to .inl file"); + my ($aOutputFileName, %aHashTable) = @_; + open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to write to\n'); + ## Print comments at top of .inl file + printf(OUTPUT_FILE "\/\/ mGlyphs.inl\n"); + printf(OUTPUT_FILE "\/\/\n"); + printf(OUTPUT_FILE "\/\/ Generated by mglyphtool.pl from '$globalValues{'inputFile'}'\n"); + printf(OUTPUT_FILE "\/\/\n\n"); + ## Declare array and fill in values + printf(OUTPUT_FILE "const unsigned long mGlyphArray[] = {\n\t"); + for (my $counter = 0; $counter < $globalValues{'tablesize'}; $counter++) + { + my $storeValue = "00000000"; + if (defined($aHashTable{$counter})) + { + $storeValue = $aHashTable{$counter}; + } + $storeValue = ($globalValues{'storeashex'}) ? hex($storeValue) : "0x$storeValue"; + print OUTPUT_FILE $storeValue; + if (($counter+1) < $globalValues{'tablesize'}) + { + print OUTPUT_FILE (($counter + 1) % 8 == 0? ",\n\t" : ', '); + } + } + print(OUTPUT_FILE "};\n"); + print(OUTPUT_FILE "\nconst int KLgMirrorTableSize=$globalValues{'lgtablesize'};\n"); + print(OUTPUT_FILE "const int KMirrorTableSize=$globalValues{'tablesize'};\n"); + # Inline functions + # Get a Hash value from a given key + print(OUTPUT_FILE "\n// Returns the first index to probe for character aKey.\n"); + print(OUTPUT_FILE "inline long MirrorStart(long aKey)\n"); + print(OUTPUT_FILE "\t{ return aKey \& (KMirrorTableSize-1); }\n"); + print(OUTPUT_FILE "\n// Returns the offset for further probes for character aKey.\n"); + print(OUTPUT_FILE "inline long MirrorStep(long aKey)\n"); + my $stepShift = $globalValues{'stepShift'}; + print(OUTPUT_FILE "\t{ return ("); + if ($stepShift == 0) + { + print(OUTPUT_FILE "aKey"); + } + elsif (0 < $stepShift) + { + print(OUTPUT_FILE "(aKey >> $stepShift)"); + } + else + { + $stepShift = -$stepShift; + print(OUTPUT_FILE "(aKey << $stepShift)"); + } + print(OUTPUT_FILE " | 1) + $globalValues{'stepOffset'}; }\n\n"); + + close(OUTPUT_FILE); + } +##################### listing of hash indexes values for original and mirrored glyphs +sub createHTMLOfMappings + { + my ($aOutputFileName, %aHashTable )= @_; + open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to create HTML output'); + printf(OUTPUT_FILE "MirrorGlyph Hash Output<\/TITLE><\/HEAD><BODY>"); +## print hash table details + printf(OUTPUT_FILE "<P>Values in hash Table - <B>(Hash Function: Key mod $globalValues{'tablesize'})<\/B><\/P><TABLE border=1>"); + 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>"); + my %keySet; + foreach my $value (values %aHashTable) + { + $keySet{&getLower(hex $value)} = 1; + } + foreach my $key (32..127) + { + $keySet{$key} = 1; + } + my @keys = sort {$a <=> $b} (keys %keySet); + foreach my $key (@keys) + { + my $counter = 0; + my $HKey = &findHashTableIndex($key, \$counter, \%aHashTable); + my $stored = $aHashTable{$HKey}; + my $storedValue = 'no change'; + my $storedKey = $key; + if (defined $stored) + { + $storedValue = sprintf('%02x', &getLower(hex $stored)); + $storedKey = &getUpper(hex $stored); + } + if ($storedKey) + { + die('incorrect key found in hash table') unless ($storedKey == $key); + 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); + } + } + printf(OUTPUT_FILE "<\/TABLE>"); + printf(OUTPUT_FILE "<\/BODY><\/HTML>"); + close(OUTPUT_FILE); + } +##################### +# Hash Table functions +##################### + +##################### +#Returns a new Hash Table +##################### +sub createHashTable + { + my $aInputFileName = shift; + my $lineNumber = 1; + my %newHashTable = (); + open(INPUT_FILE, '< ' . $aInputFileName) or die('ERROR: Could not open $aInputFileName to read from'); + while (my $line=<INPUT_FILE>) + { + if ($line=~/^(.*);\s(.*\w)\s\W.*$/) ## Grab Original glyph value and mirrored glyph value + { + &updateHashTable($1, $2, \%newHashTable); + } + $lineNumber++; + } + close(INPUT_FILE); + return %newHashTable; + } +##################### +# +# Retrieves a HashKey which is not currently being used in a given HashTable +# +##################### +sub findHashTableIndex + { + my ($aHashKey, $aCounter, $aHashTable) = @_; + my $current = &hashFunction($aHashKey); + my $step = &hashStepFunction($aHashKey); + my $tableSize = $globalValues{'tablesize'}; + while (defined($$aHashTable{$current}) && &getUpper(hex($$aHashTable{$current})) != $aHashKey) + { + ++$$aCounter; + $current += $step; + $current &= $tableSize - 1; + } + if (2 < $$aCounter) + { + printf STDERR ("WARNING: Jumped $$aCounter times, inefficient hash for %02x ($current, $step)\n", $aHashKey); + } + return $current; + } + +##################### +sub updateHashTable +{ + my ($aKey, $aValueToStore, $aHashTable) = @_; + my $counter = 0; + my $key = hex($aKey); + my $hashKey = &findHashTableIndex($key, \$counter, $aHashTable); + $$aHashTable{$hashKey} = "$aKey$aValueToStore"; + return $hashKey; +} +##################### +# Returns a hash key for a given key +# Currently using a simple hash function +##################### +sub hashFunction + { + my $aKey = shift; + return $aKey & ($globalValues{'tablesize'}-1); + } + +# Returns second hash value: used for the step size +sub hashStepFunction + { + my $aKey = shift; + my $stepShift = $globalValues{'stepShift'}; + if ($stepShift < 0) + { + $aKey <<= -$stepShift; + } + elsif (0 < $stepShift) + { + $aKey >>= $stepShift; + } + return ($aKey | 1) + $globalValues{'stepOffset'}; + } + +##################### +# Utility functions +##################### +sub getLower + { + my $aValue = shift; + return $aValue & hex("0000FFFF"); + } +sub getUpper + { + my $aValue = shift; + return ($aValue & hex("FFFF0000")) >> 16; + } +sub printDebug + { + my $string = shift; + if ($globalValues{'verbose'}) + { + print $string; + } + } +