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