diff options
author | marha <marha@users.sourceforge.net> | 2014-06-26 09:53:21 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-06-26 09:53:21 +0200 |
commit | 90137f4c5e30b1c6f9a262e8c853494540dad2d7 (patch) | |
tree | 7da9d06a291a853f0d17b2ee49a2d31d86a5d757 /freetype/src/tools | |
parent | d47db8d4713de42ccca071c9e8401fc7a213ed49 (diff) | |
parent | fba3b6d1979c1d1ad0d56d46fc2d787f111c07fb (diff) | |
download | vcxsrv-90137f4c5e30b1c6f9a262e8c853494540dad2d7.tar.gz vcxsrv-90137f4c5e30b1c6f9a262e8c853494540dad2d7.tar.bz2 vcxsrv-90137f4c5e30b1c6f9a262e8c853494540dad2d7.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
Updated to freetype 2.5.3
Diffstat (limited to 'freetype/src/tools')
-rw-r--r-- | freetype/src/tools/afblue.pl | 545 | ||||
-rw-r--r-- | freetype/src/tools/chktrcmp.py | 4 | ||||
-rw-r--r-- | freetype/src/tools/docmaker/content.py | 19 | ||||
-rw-r--r-- | freetype/src/tools/docmaker/docmaker.py | 4 | ||||
-rw-r--r-- | freetype/src/tools/docmaker/sources.py | 40 | ||||
-rw-r--r-- | freetype/src/tools/docmaker/tohtml.py | 35 |
6 files changed, 592 insertions, 55 deletions
diff --git a/freetype/src/tools/afblue.pl b/freetype/src/tools/afblue.pl new file mode 100644 index 000000000..58aa2a055 --- /dev/null +++ b/freetype/src/tools/afblue.pl @@ -0,0 +1,545 @@ +#! /usr/bin/perl -w +# -*- Perl -*- +# +# afblue.pl +# +# Process a blue zone character data file. +# +# Copyright 2013, 2014 by +# David Turner, Robert Wilhelm, and Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, +# modified, and distributed under the terms of the FreeType project +# license, LICENSE.TXT. By continuing to use, modify, or distribute +# this file you indicate that you have read the license and +# understand and accept it fully. + +use strict; +use warnings; +use English '-no_match_vars'; +use open ':std', ':encoding(UTF-8)'; + + +my $prog = $PROGRAM_NAME; +$prog =~ s| .* / ||x; # Remove path. + +die "usage: $prog datafile < infile > outfile\n" if $#ARGV != 0; + + +my $datafile = $ARGV[0]; + +my %diversions; # The extracted and massaged data from `datafile'. +my @else_stack; # Booleans to track else-clauses. +my @name_stack; # Stack of integers used for names of aux. variables. + +my $curr_enum; # Name of the current enumeration. +my $curr_array; # Name of the current array. +my $curr_max; # Name of the current maximum value. + +my $curr_enum_element; # Name of the current enumeration element. +my $curr_offset; # The offset relative to current aux. variable. +my $curr_elem_size; # The size of the current string or block. + +my $have_sections = 0; # Boolean; set if start of a section has been seen. +my $have_strings; # Boolean; set if current section contains strings. +my $have_blocks; # Boolean; set if current section contains blocks. + +my $have_enum_element; # Boolean; set if we have an enumeration element. +my $in_string; # Boolean; set if a string has been parsed. + +my $num_sections = 0; # Number of sections seen so far. + +my $last_aux; # Name of last auxiliary variable. + + +# Regular expressions. + +# [<ws>] <enum_name> <ws> <array_name> <ws> <max_name> [<ws>] ':' [<ws>] '\n' +my $section_re = qr/ ^ \s* (\S+) \s+ (\S+) \s+ (\S+) \s* : \s* $ /x; + +# [<ws>] <enum_element_name> [<ws>] '\n' +my $enum_element_re = qr/ ^ \s* ( [A-Za-z0-9_]+ ) \s* $ /x; + +# '#' <preprocessor directive> '\n' +my $preprocessor_re = qr/ ^ \# /x; + +# '/' '/' <comment> '\n' +my $comment_re = qr| ^ // |x; + +# empty line +my $whitespace_only_re = qr/ ^ \s* $ /x; + +# [<ws>] '"' <string> '"' [<ws>] '\n' (<string> doesn't contain newlines) +my $string_re = qr/ ^ \s* + " ( (?> (?: (?> [^"\\]+ ) | \\. )* ) ) " + \s* $ /x; + +# [<ws>] '{' <block> '}' [<ws>] '\n' (<block> can contain newlines) +my $block_start_re = qr/ ^ \s* \{ /x; + +# We need the capturing group for `split' to make it return the separator +# tokens (i.e., the opening and closing brace) also. +my $brace_re = qr/ ( [{}] ) /x; + + +sub Warn +{ + my $message = shift; + warn "$datafile:$INPUT_LINE_NUMBER: warning: $message\n"; +} + + +sub Die +{ + my $message = shift; + die "$datafile:$INPUT_LINE_NUMBER: error: $message\n"; +} + + +my $warned_before = 0; + +sub warn_before +{ + Warn("data before first section gets ignored") unless $warned_before; + $warned_before = 1; +} + + +sub strip_newline +{ + chomp; + s/ \x0D $ //x; +} + + +sub end_curr_string +{ + # Append final null byte to string. + if ($have_strings) + { + push @{$diversions{$curr_array}}, " '\\0',\n" if $in_string; + + $curr_offset++; + $in_string = 0; + } +} + + +sub update_max_elem_size +{ + if ($curr_elem_size) + { + my $max = pop @{$diversions{$curr_max}}; + $max = $curr_elem_size if $curr_elem_size > $max; + push @{$diversions{$curr_max}}, $max; + } +} + + +sub convert_non_ascii_char +{ + # A UTF-8 character outside of the printable ASCII range, with possibly a + # leading backslash character. + my $s = shift; + + # Here we count characters, not bytes. + $curr_elem_size += length $s; + + utf8::encode($s); + $s = uc unpack 'H*', $s; + + $curr_offset += $s =~ s/\G(..)/'\\x$1', /sg; + + return $s; +} + + +sub convert_ascii_chars +{ + # A series of ASCII characters in the printable range. + my $s = shift; + + my $count = $s =~ s/\G(.)/'$1', /g; + $curr_offset += $count; + $curr_elem_size += $count; + + return $s; +} + + +sub convert_literal +{ + my $s = shift; + my $orig = $s; + + # ASCII printables and space + my $safe_re = '\x20-\x7E'; + # ASCII printables and space, no backslash + my $safe_no_backslash_re = '\x20-\x5B\x5D-\x7E'; + + $s =~ s{ + (?: \\? ( [^$safe_re] ) + | ( (?: [$safe_no_backslash_re] + | \\ [$safe_re] )+ ) ) + } + { + defined($1) ? convert_non_ascii_char($1) + : convert_ascii_chars($2) + }egx; + + # We assume that `$orig' doesn't contain `*/' + return $s . " /* $orig */"; +} + + +sub aux_name +{ + return "af_blue_" . $num_sections. "_" . join('_', @name_stack); +} + + +sub aux_name_next +{ + $name_stack[$#name_stack]++; + my $name = aux_name(); + $name_stack[$#name_stack]--; + + return $name; +} + + +sub enum_val_string +{ + # Build string that holds code to save the current offset in an + # enumeration element. + my $aux = shift; + + my $add = ($last_aux eq "af_blue_" . $num_sections . "_0" ) + ? "" + : "$last_aux + "; + + return " $aux = $add$curr_offset,\n"; +} + + + +# Process data file. + +open(DATA, $datafile) || die "$prog: can't open \`$datafile': $OS_ERROR\n"; + +while (<DATA>) +{ + strip_newline(); + + next if /$comment_re/; + next if /$whitespace_only_re/; + + if (/$section_re/) + { + Warn("previous section is empty") if ($have_sections + && !$have_strings + && !$have_blocks); + + end_curr_string(); + update_max_elem_size(); + + # Save captured groups from `section_re'. + $curr_enum = $1; + $curr_array = $2; + $curr_max = $3; + + $curr_enum_element = ""; + $curr_offset = 0; + + Warn("overwriting already defined enumeration \`$curr_enum'") + if exists($diversions{$curr_enum}); + Warn("overwriting already defined array \`$curr_array'") + if exists($diversions{$curr_array}); + Warn("overwriting already defined maximum value \`$curr_max'") + if exists($diversions{$curr_max}); + + $diversions{$curr_enum} = []; + $diversions{$curr_array} = []; + $diversions{$curr_max} = []; + + push @{$diversions{$curr_max}}, 0; + + @name_stack = (); + push @name_stack, 0; + + $have_sections = 1; + $have_strings = 0; + $have_blocks = 0; + + $have_enum_element = 0; + $in_string = 0; + + $num_sections++; + $curr_elem_size = 0; + + $last_aux = aux_name(); + + next; + } + + if (/$preprocessor_re/) + { + if ($have_sections) + { + # Having preprocessor conditionals complicates the computation of + # correct offset values. We have to introduce auxiliary enumeration + # elements with the name `af_blue_<s>_<n1>_<n2>_...' that store + # offsets to be used in conditional clauses. `<s>' is the number of + # sections seen so far, `<n1>' is the number of `#if' and `#endif' + # conditionals seen so far in the topmost level, `<n2>' the number of + # `#if' and `#endif' conditionals seen so far one level deeper, etc. + # As a consequence, uneven values are used within a clause, and even + # values after a clause, since the C standard doesn't allow the + # redefinition of an enumeration value. For example, the name + # `af_blue_5_1_6' is used to construct enumeration values in the fifth + # section after the third (second-level) if-clause within the first + # (top-level) if-clause. After the first top-level clause has + # finished, `af_blue_5_2' is used. The current offset is then + # relative to the value stored in the current auxiliary element. + + if (/ ^ \# \s* if /x) + { + push @else_stack, 0; + + $name_stack[$#name_stack]++; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ \# \s* elif /x) + { + Die("unbalanced #elif") unless @else_stack; + + pop @name_stack; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ \# \s* else /x) + { + my $prev_else = pop @else_stack; + Die("unbalanced #else") unless defined($prev_else); + Die("#else already seen") if $prev_else; + push @else_stack, 1; + + pop @name_stack; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ (\# \s*) endif /x) + { + my $prev_else = pop @else_stack; + Die("unbalanced #endif") unless defined($prev_else); + + pop @name_stack; + + # If there is no else-clause for an if-clause, we add one. This is + # necessary to have correct offsets. + if (!$prev_else) + { + # Use amount of whitespace from `endif'. + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()) + . $1 . "else\n"; + $last_aux = aux_name(); + + $curr_offset = 0; + } + + $name_stack[$#name_stack]++; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); + $last_aux = aux_name(); + + $curr_offset = 0; + } + + # Handle (probably continued) preprocessor lines. + CONTINUED_LOOP: + { + do + { + strip_newline(); + + push @{$diversions{$curr_enum}}, $ARG . "\n"; + push @{$diversions{$curr_array}}, $ARG . "\n"; + + last CONTINUED_LOOP unless / \\ $ /x; + + } while (<DATA>); + } + } + else + { + warn_before(); + } + + next; + } + + if (/$enum_element_re/) + { + end_curr_string(); + update_max_elem_size(); + + $curr_enum_element = $1; + $have_enum_element = 1; + $curr_elem_size = 0; + + next; + } + + if (/$string_re/) + { + if ($have_sections) + { + Die("strings and blocks can't be mixed in a section") if $have_blocks; + + # Save captured group from `string_re'. + my $string = $1; + + if ($have_enum_element) + { + push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); + $have_enum_element = 0; + } + + $string = convert_literal($string); + + push @{$diversions{$curr_array}}, " $string\n"; + + $have_strings = 1; + $in_string = 1; + } + else + { + warn_before(); + } + + next; + } + + if (/$block_start_re/) + { + if ($have_sections) + { + Die("strings and blocks can't be mixed in a section") if $have_strings; + + my $depth = 0; + my $block = ""; + my $block_end = 0; + + # Count braces while getting the block. + BRACE_LOOP: + { + do + { + strip_newline(); + + foreach my $substring (split(/$brace_re/)) + { + if ($block_end) + { + Die("invalid data after last matching closing brace") + if $substring !~ /$whitespace_only_re/; + } + + $block .= $substring; + + if ($substring eq '{') + { + $depth++; + } + elsif ($substring eq '}') + { + $depth--; + + $block_end = 1 if $depth == 0; + } + } + + # If we are here, we have run out of substrings, so get next line + # or exit. + last BRACE_LOOP if $block_end; + + $block .= "\n"; + + } while (<DATA>); + } + + if ($have_enum_element) + { + push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); + $have_enum_element = 0; + } + + push @{$diversions{$curr_array}}, $block . ",\n"; + + $curr_offset++; + $curr_elem_size++; + + $have_blocks = 1; + } + else + { + warn_before(); + } + + next; + } + + # Garbage. We weren't able to parse the data. + Die("syntax error"); +} + +# Finalize data. +end_curr_string(); +update_max_elem_size(); + + +# Filter stdin to stdout, replacing `@...@' templates. + +sub emit_diversion +{ + my $diversion_name = shift; + return (exists($diversions{$1})) ? "@{$diversions{$1}}" + : "@" . $diversion_name . "@"; +} + + +$LIST_SEPARATOR = ''; + +my $s1 = "This file has been generated by the Perl script \`$prog',"; +my $s1len = length $s1; +my $s2 = "using data from file \`$datafile'."; +my $s2len = length $s2; +my $slen = ($s1len > $s2len) ? $s1len : $s2len; + +print "/* " . $s1 . " " x ($slen - $s1len) . " */\n" + . "/* " . $s2 . " " x ($slen - $s2len) . " */\n" + . "\n"; + +while (<STDIN>) +{ + s/ @ ( [A-Za-z0-9_]+? ) @ / emit_diversion($1) /egx; + print; +} + +# EOF diff --git a/freetype/src/tools/chktrcmp.py b/freetype/src/tools/chktrcmp.py index d0f342e6b..ce6500c7e 100644 --- a/freetype/src/tools/chktrcmp.py +++ b/freetype/src/tools/chktrcmp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Check trace components in FreeType 2 source. -# Author: suzuki toshiya, 2009 +# Author: suzuki toshiya, 2009, 2013 # # This code is explicitly into the public domain. @@ -15,7 +15,7 @@ USED_COMPONENT = {} KNOWN_COMPONENT = {} SRC_FILE_DIRS = [ "src" ] -TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ] +TRACE_DEF_FILES = [ "include/internal/fttrace.h" ] # -------------------------------------------------------------- diff --git a/freetype/src/tools/docmaker/content.py b/freetype/src/tools/docmaker/content.py index 26087f7b8..98025e67e 100644 --- a/freetype/src/tools/docmaker/content.py +++ b/freetype/src/tools/docmaker/content.py @@ -1,4 +1,4 @@ -# Content (c) 2002, 2004, 2006-2009, 2012 +# Content (c) 2002, 2004, 2006-2009, 2012, 2013 # David Turner <david@freetype.org> # # This file contains routines used to parse the content of documentation @@ -268,15 +268,6 @@ class DocMarkup: except: return None - def get_start( self ): - try: - result = "" - for word in self.fields[0].items[0].words: - result = result + " " + word - return result[1:] - except: - return "ERROR" - def dump( self, margin ): print " " * margin + "<" + self.tag + ">" for f in self.fields: @@ -555,14 +546,6 @@ class DocBlock: return m return None - def get_markup_name( self, tag_name ): - """return the name of a given primary markup in a block""" - try: - m = self.get_markup( tag_name ) - return m.get_name() - except: - return None - def get_markup_words( self, tag_name ): try: m = self.get_markup( tag_name ) diff --git a/freetype/src/tools/docmaker/docmaker.py b/freetype/src/tools/docmaker/docmaker.py index 1d9de9fbf..bf75c5d5f 100644 --- a/freetype/src/tools/docmaker/docmaker.py +++ b/freetype/src/tools/docmaker/docmaker.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -# DocMaker (c) 2002, 2004, 2008 David Turner <david@freetype.org> +# DocMaker (c) 2002, 2004, 2008, 2013 David Turner <david@freetype.org> # -# This program is a re-write of the original DocMaker took used +# This program is a re-write of the original DocMaker tool used # to generate the API Reference of the FreeType font engine # by converting in-source comments into structured HTML. # diff --git a/freetype/src/tools/docmaker/sources.py b/freetype/src/tools/docmaker/sources.py index 490ba2506..dab834978 100644 --- a/freetype/src/tools/docmaker/sources.py +++ b/freetype/src/tools/docmaker/sources.py @@ -1,4 +1,4 @@ -# Sources (c) 2002-2004, 2006-2009, 2012 +# Sources (c) 2002-2004, 2006-2009, 2012, 2013 # David Turner <david@freetype.org> # # @@ -132,7 +132,7 @@ re_markup_tags = [re_markup_tag1, re_markup_tag2] # # used to detect a cross-reference, after markup tags have been stripped # -re_crossref = re.compile( r'@((?:\w|-)*)(.*)' ) +re_crossref = re.compile( r'@((?:\w|-)*)(.*)' ) # @foo # # used to detect italic and bold styles in paragraph text @@ -141,6 +141,42 @@ re_italic = re.compile( r"_(\w(\w|')*)_(.*)" ) # _italic_ re_bold = re.compile( r"\*(\w(\w|')*)\*(.*)" ) # *bold* # +# this regular expression code to identify an URL has been taken from +# +# http://mail.python.org/pipermail/tutor/2002-September/017228.html +# +# (with slight modifications) +# + +urls = r'(?:https?|telnet|gopher|file|wais|ftp)' +ltrs = r'\w' +gunk = r'/#~:.?+=&%@!\-' +punc = r'.:?\-' +any = "%(ltrs)s%(gunk)s%(punc)s" % { 'ltrs' : ltrs, + 'gunk' : gunk, + 'punc' : punc } +url = r""" + ( + \b # start at word boundary + %(urls)s : # need resource and a colon + [%(any)s] +? # followed by one or more of any valid + # character, but be conservative and + # take only what you need to... + (?= # [look-ahead non-consumptive assertion] + [%(punc)s]* # either 0 or more punctuation + (?: # [non-grouping parentheses] + [^%(any)s] | $ # followed by a non-url char + # or end of the string + ) + ) + ) + """ % {'urls' : urls, + 'any' : any, + 'punc' : punc } + +re_url = re.compile( url, re.VERBOSE | re.MULTILINE ) + +# # used to detect the end of commented source lines # re_source_sep = re.compile( r'\s*/\*\s*\*/' ) diff --git a/freetype/src/tools/docmaker/tohtml.py b/freetype/src/tools/docmaker/tohtml.py index fffa12097..7944f1c99 100644 --- a/freetype/src/tools/docmaker/tohtml.py +++ b/freetype/src/tools/docmaker/tohtml.py @@ -1,4 +1,4 @@ -# ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008 +# ToHTML (c) 2002, 2003, 2005-2008, 2013 # David Turner <david@freetype.org> from sources import * @@ -175,25 +175,6 @@ def html_quote( line ): return result -# same as 'html_quote', but ignores left and right brackets -def html_quote0( line ): - return string.replace( line, "&", "&" ) - - -def dump_html_code( lines, prefix = "" ): - # clean the last empty lines - l = len( self.lines ) - while l > 0 and string.strip( self.lines[l - 1] ) == "": - l = l - 1 - - # The code footer should be directly appended to the last code - # line to avoid an additional blank line. - print prefix + code_header, - for line in self.lines[0 : l + 1]: - print '\n' + prefix + html_quote( line ), - print prefix + code_footer, - - class HtmlFormatter( Formatter ): @@ -242,16 +223,6 @@ class HtmlFormatter( Formatter ): def make_block_url( self, block ): return self.make_section_url( block.section ) + "#" + block.name - def make_html_words( self, words ): - """ convert a series of simple words into some HTML text """ - line = "" - if words: - line = html_quote( words[0] ) - for w in words[1:]: - line = line + " " + html_quote( w ) - - return line - def make_html_word( self, word ): """analyze a simple word to detect cross-references and styling""" # look for cross-references @@ -291,6 +262,8 @@ class HtmlFormatter( Formatter ): line = self.make_html_word( words[0] ) for word in words[1:]: line = line + " " + self.make_html_word( word ) + # handle hyperlinks + line = re_url.sub( r'<a href="\1">\1</a>', line ) # convert `...' quotations into real left and right single quotes line = re.sub( r"(^|\W)`(.*?)'(\W|$)", \ r'\1‘\2’\3', \ @@ -549,7 +522,7 @@ class HtmlFormatter( Formatter ): if block.source.filename.find( f ) >= 0: header = self.headers[f] + ' (' + f + ')' break; - + # if not header: # sys.stderr.write( \ # 'WARNING: No header macro for ' + block.source.filename + '.\n' ) |