os/graphics/graphicsdeviceinterface/gdi/mglyph/mglyphtool.pl
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 # All rights reserved.
     3 # This component and the accompanying materials are made available
     4 # under the terms of "Eclipse Public License v1.0"
     5 # which accompanies this distribution, and is available
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 #
     8 # Initial Contributors:
     9 # Nokia Corporation - initial contribution.
    10 #
    11 # Contributors:
    12 #
    13 # Description:
    14 #
    15 
    16 use strict;
    17 
    18 ## Used as global variables, probably need to change and pass variables through as parameters.
    19 my %globalValues=();
    20 ##initialise filenames
    21 $globalValues{'inputFile'} = 'mglyphs.txt';
    22 $globalValues{'outputFileName'} = 'mglyphs.inl';
    23 $globalValues{'htmlFileName'} = 'mglyphs.html';
    24 $globalValues{'lgtablesize'} = 9; # Default tablesize value is 512
    25 $globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
    26 $globalValues{'storeashex'} = 0;
    27 $globalValues{'stepOffset'} = 72;
    28 $globalValues{'stepShift'} = 0;
    29 
    30 ## die if the correct number of argumements have not been entered
    31 &extractFlags(\@ARGV, \%globalValues);
    32 &printDebug("Remainder:$globalValues{'tablesize'}\n");
    33 &printDebug("StoreAsHex:$globalValues{'storeashex'}\n");
    34 
    35 if ($globalValues{"information"})
    36 	{
    37 	&dieShowingUsage();
    38 	}
    39 
    40 &printDebug("Creating HashTable....\n");
    41 my %hashTable = &createHashTable($globalValues{'inputFile'});
    42 if (!defined(%hashTable))
    43 	{
    44 	die("ERROR: Hash table was not created\n");
    45 	}
    46 if ($globalValues{"outputtohtml"})
    47 	{
    48 	my $htmlFileName = $globalValues{'htmlFileName'};
    49 	&printDebug("Creating HTML output to file: $htmlFileName\n");	
    50 	&createHTMLOfMappings($htmlFileName, %hashTable);
    51 	}
    52 my $outputFileName = $globalValues{'outputFileName'};
    53 &printDebug("Writing Hash table to file: $outputFileName\n");
    54 &writeHashTableToFile($outputFileName, %hashTable);
    55 &printDebug("$outputFileName created.");
    56 
    57 ##################### end of main section 
    58 sub extractFlags
    59 	{
    60 	my $aArgumentArray=shift;
    61 	my $aArguments=shift;
    62 	my $expectedArg = 'lgtablesize';
    63 	my $expectedExtension;
    64 	foreach my $argument (@$aArgumentArray)
    65 		{
    66 		if ($argument =~ m!^[-/]([a-zA-Z].*)$!)
    67 			{
    68 			my $switch = $1;
    69 			$expectedArg = 'lgtablesize';
    70 			$expectedExtension = undef;
    71 			if ($switch=~/^(x|hexoutput)$/i)
    72 				{
    73 				$$aArguments{'storeashex'}=1;
    74 				}
    75 			elsif ($switch=~/^(\?|help)$/i)
    76 				{
    77 				$$aArguments{'information'}=1;
    78 				}
    79 			elsif ($switch=~/^(v|verbose)$/i)
    80 				{
    81 				$$aArguments{'verbose'}=1;
    82 				}
    83 			elsif ($switch=~/^(h|outputtohtml)$/i)
    84 				{
    85 				$$aArguments{'outputtohtml'}=1;
    86 				$expectedArg = 'htmlFileName';
    87 				$expectedExtension = '.html';
    88 				}
    89 			elsif ($switch=~/^(i|input)$/i)
    90 				{
    91 				$expectedArg = 'inputFile';
    92 				}
    93 			elsif ($switch=~/^(o|output)$/i)
    94 				{
    95 				$expectedArg = 'outputFileName';
    96 				$expectedExtension = '.inl';
    97 				}
    98 			elsif ($switch=~/^(offset)$/i)
    99 				{
   100 				$expectedArg = 'stepOffset';
   101 				}
   102 			elsif ($switch=~/^(shift)$/i)
   103 				{
   104 				$expectedArg = 'stepShift';
   105 				}
   106 			}
   107 		else
   108 			{
   109 			if (defined $expectedExtension && $argument !~ m!\.[^/\\]*$!)
   110 				{
   111 				$argument .= $expectedExtension;
   112 				}
   113 			$$aArguments{$expectedArg} = $argument;
   114 			$expectedArg = 'lgtablesize';
   115 			}
   116 		}
   117 	$globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
   118 	$globalValues{'stepOffset'} &= 0xFFFFFE;
   119 	}
   120 #####################
   121 sub dieShowingUsage
   122 	{
   123 	print <<USAGE_EOF;
   124 
   125 Usage:
   126 
   127 perl -w mglyphtool.pl [-?] [<lg-table-size>] [-x] [-i <input-file-name>]
   128 		[-o <output-file-name>] [-h [<output-html-file-name]]
   129 		[-offset <value-for-offset>] [-shift <value-for-shift>]
   130 
   131 <lg-table-size> the default log(base 2) table size is 9. This gives a table
   132 size of 512 entries (2 to the power 9). So 7 gives a size of 128, 8 gives
   133 256, 9 gives 512, 10 gives 1024 and so on.
   134 
   135 options: -x -o -i -h
   136 
   137 	-? Shows help
   138 
   139 	The -x flag stores values into the .inl file in hex format: 
   140 		hex(OriginalKeyCodeMirrorGlyphCode), 
   141 	By default the values are stored in string hex format i.e 0x220C2209
   142 
   143 	The -h flag generates a html file displaying hash table information.
   144 	This may be followed by the filename to be output.
   145 	Default is 'mglyphs.html'
   146 
   147 	The -i file specifies input file name. Default is 'mglyphs.txt'.
   148 
   149 	The -o file specifies output file name. Default is 'mglyphs.inl'.
   150 
   151 	-shift and -offset alter the "step" hash algorithm.
   152 	
   153 USAGE_EOF
   154 	exit 0;
   155 	}
   156 ######### 
   157 #
   158 # Writes a hash table to file.
   159 # Current format:
   160 # 	Hex mode: 		"hex number created"
   161 #	Hex string mode:	"Original keyMapped key"
   162 #####################
   163 sub writeHashTableToFile
   164 	{
   165 	&printDebug("Writing to .inl file");
   166 	my ($aOutputFileName, %aHashTable) = @_;
   167 	open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to write to\n');
   168 	## Print comments at top of .inl file
   169 	printf(OUTPUT_FILE "\/\/ mGlyphs.inl\n");
   170 	printf(OUTPUT_FILE "\/\/\n");
   171 	printf(OUTPUT_FILE "\/\/ Generated by mglyphtool.pl from '$globalValues{'inputFile'}'\n");
   172 	printf(OUTPUT_FILE "\/\/\n\n");
   173 	## Declare array and fill in values
   174 	printf(OUTPUT_FILE "const unsigned long mGlyphArray[] = {\n\t");
   175 	for (my $counter = 0; $counter < $globalValues{'tablesize'}; $counter++)
   176 		{
   177 		my $storeValue = "00000000";
   178 		if (defined($aHashTable{$counter}))
   179 			{
   180 			$storeValue = $aHashTable{$counter};
   181 			}
   182 		$storeValue = ($globalValues{'storeashex'}) ? hex($storeValue) : "0x$storeValue";
   183 		print OUTPUT_FILE $storeValue;
   184 		if (($counter+1) < $globalValues{'tablesize'})
   185 			{
   186 			print OUTPUT_FILE (($counter + 1) % 8 == 0? ",\n\t" : ', ');
   187 			}
   188 		}
   189 	print(OUTPUT_FILE "};\n");
   190 	print(OUTPUT_FILE "\nconst int KLgMirrorTableSize=$globalValues{'lgtablesize'};\n");
   191 	print(OUTPUT_FILE "const int KMirrorTableSize=$globalValues{'tablesize'};\n");
   192 	# Inline functions
   193 	# Get a Hash value from a given key	
   194 	print(OUTPUT_FILE "\n// Returns the first index to probe for character aKey.\n");
   195 	print(OUTPUT_FILE "inline long MirrorStart(long aKey)\n");
   196 	print(OUTPUT_FILE "\t{ return aKey \& (KMirrorTableSize-1); }\n");
   197 	print(OUTPUT_FILE "\n// Returns the offset for further probes for character aKey.\n");
   198 	print(OUTPUT_FILE "inline long MirrorStep(long aKey)\n");
   199 	my $stepShift = $globalValues{'stepShift'};
   200 	print(OUTPUT_FILE "\t{ return (");
   201 	if ($stepShift == 0)
   202 		{
   203 		print(OUTPUT_FILE "aKey");
   204 		}
   205 	elsif (0 < $stepShift)
   206 		{
   207 		print(OUTPUT_FILE "(aKey >> $stepShift)");
   208 		}
   209 	else
   210 		{
   211 		$stepShift = -$stepShift;
   212 		print(OUTPUT_FILE "(aKey << $stepShift)");
   213 		}
   214 	print(OUTPUT_FILE " | 1) + $globalValues{'stepOffset'}; }\n\n");
   215 
   216 	close(OUTPUT_FILE);
   217 	}	
   218 ##################### listing of hash indexes values for original and mirrored glyphs
   219 sub createHTMLOfMappings
   220 	{
   221 	my ($aOutputFileName, %aHashTable )= @_;
   222 	open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to create HTML output');
   223 	printf(OUTPUT_FILE "<HTML><HEAD><TITLE>MirrorGlyph Hash Output<\/TITLE><\/HEAD><BODY>");
   224 ## print hash table details
   225 	printf(OUTPUT_FILE "<P>Values in hash Table - <B>(Hash Function: Key mod $globalValues{'tablesize'})<\/B><\/P><TABLE border=1>");
   226 	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>");	
   227 	my %keySet;
   228 	foreach my $value (values %aHashTable)
   229 		{
   230 		$keySet{&getLower(hex $value)} = 1;
   231 		}
   232 	foreach my $key (32..127)
   233 		{
   234 		$keySet{$key} = 1;
   235 		}
   236 	my @keys = sort {$a <=> $b} (keys %keySet);
   237 	foreach my $key (@keys)
   238 		{
   239 		my $counter = 0;
   240 		my $HKey = &findHashTableIndex($key, \$counter, \%aHashTable);
   241 		my $stored = $aHashTable{$HKey};
   242 		my $storedValue = 'no change';
   243 		my $storedKey = $key;
   244 		if (defined $stored)
   245 			{
   246 			$storedValue = sprintf('%02x', &getLower(hex $stored));
   247 			$storedKey = &getUpper(hex $stored);
   248 			}
   249 		if ($storedKey)
   250 			{
   251 			die('incorrect key found in hash table') unless ($storedKey == $key);
   252 			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);
   253 			}
   254 		}
   255 	printf(OUTPUT_FILE "<\/TABLE>");
   256 	printf(OUTPUT_FILE "<\/BODY><\/HTML>");
   257 	close(OUTPUT_FILE);
   258 	}
   259 #####################
   260 # Hash Table functions	
   261 ##################### 
   262 
   263 #####################
   264 #Returns a new Hash Table 
   265 #####################
   266 sub createHashTable
   267 	{	
   268 	my $aInputFileName = shift;	
   269 	my $lineNumber = 1;
   270 	my %newHashTable = ();
   271 	open(INPUT_FILE, '< ' . $aInputFileName) or die('ERROR: Could not open $aInputFileName to read from');
   272 	while (my $line=<INPUT_FILE>)
   273 		{
   274 		if ($line=~/^(.*);\s(.*\w)\s\W.*$/) ## Grab Original glyph value and mirrored glyph value
   275 			{		
   276 			&updateHashTable($1, $2, \%newHashTable);
   277 			}
   278 		$lineNumber++;
   279 		}		
   280 	close(INPUT_FILE);
   281 	return %newHashTable;
   282 	}
   283 ##################### 
   284 #
   285 # Retrieves a HashKey which is not currently being used in a given HashTable
   286 #
   287 #####################
   288 sub findHashTableIndex
   289 	{
   290 	my ($aHashKey, $aCounter, $aHashTable) = @_;	
   291 	my $current = &hashFunction($aHashKey);
   292 	my $step = &hashStepFunction($aHashKey);
   293 	my $tableSize = $globalValues{'tablesize'};
   294 	while (defined($$aHashTable{$current}) && &getUpper(hex($$aHashTable{$current})) != $aHashKey)
   295 		{
   296 		++$$aCounter;
   297 		$current += $step;
   298 		$current &= $tableSize - 1;
   299 		}
   300 	if (2 < $$aCounter)
   301 		{
   302 		printf STDERR ("WARNING: Jumped $$aCounter times, inefficient hash for %02x ($current, $step)\n", $aHashKey);
   303 		}
   304 	return $current;
   305 	}
   306 
   307 #####################
   308 sub updateHashTable
   309 {
   310 	my ($aKey, $aValueToStore, $aHashTable) = @_;
   311 	my $counter = 0;
   312 	my $key = hex($aKey);
   313 	my $hashKey = &findHashTableIndex($key, \$counter, $aHashTable);
   314 	$$aHashTable{$hashKey} = "$aKey$aValueToStore";
   315 	return $hashKey;
   316 }
   317 ##################### 
   318 # Returns a hash key for a given key
   319 # Currently using a simple hash function 
   320 #####################
   321 sub hashFunction
   322 	{
   323 	my $aKey = shift;
   324 	return $aKey & ($globalValues{'tablesize'}-1);
   325 	}
   326 
   327 # Returns second hash value: used for the step size
   328 sub hashStepFunction
   329 	{
   330 	my $aKey = shift;
   331 	my $stepShift = $globalValues{'stepShift'};
   332 	if ($stepShift < 0)
   333 		{
   334 		$aKey <<= -$stepShift;
   335 		}
   336 	elsif (0 < $stepShift)
   337 		{
   338 		$aKey >>= $stepShift;
   339 		}
   340 	return ($aKey | 1) + $globalValues{'stepOffset'};
   341 	}
   342 	
   343 #####################
   344 # Utility functions 
   345 #####################
   346 sub getLower
   347 	{
   348 	my $aValue = shift;
   349 	return $aValue & hex("0000FFFF");
   350 	}
   351 sub getUpper
   352 	{
   353 	my $aValue = shift;
   354 	return ($aValue & hex("FFFF0000")) >> 16;				
   355 	}
   356 sub printDebug
   357 	{
   358 	my $string = shift;
   359 	if ($globalValues{'verbose'})
   360 		{
   361 		print $string;
   362 		}
   363 	}
   364