Merge: subset: Add grammar and kind
authorJean Privat <jean@pryen.org>
Sat, 17 Jun 2017 00:24:44 +0000 (20:24 -0400)
committerJean Privat <jean@pryen.org>
Sat, 17 Jun 2017 00:24:44 +0000 (20:24 -0400)
Implement the syntactic, inheritance and instantiation rules.

Obsoletes: #2469

Pull-Request: #2483
Reviewed-by: Jean Privat <jean@pryen.org>

28 files changed:
bin/nit-makepackage
contrib/oot.sh
contrib/oot.txt
lib/core/file.nit
lib/gamnit/README.md
lib/gamnit/bmfont.nit
lib/gamnit/examples/fonts_showcase/Makefile [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/README.md [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.fnt [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.png [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/assets/anchor.png [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/package.ini [new file with mode: 0644]
lib/gamnit/examples/fonts_showcase/src/fonts_showcase.nit [new file with mode: 0644]
lib/gamnit/font.nit
lib/gamnit/textures.nit
lib/gamnit/tileset.nit
lib/neo4j/neo4j.nit
misc/docker/Dockerfile
misc/jenkins/unitrun.sh
share/man/nit-makepackage.md [new file with mode: 0644]
src/compiler/abstract_compiler.nit
src/modelize/modelize_class.nit
src/modelize/modelize_property.nit
tests/error_formal_super.nit [new file with mode: 0644]
tests/sav/error_formal_super.res [new file with mode: 0644]
tests/test_neo4j.nit
tests/test_neo4j_batch.nit
tests/tests.sh

index 3ee3090..a03af86 100755 (executable)
 #
 # Default values are guessed from git and the file system.
 
+while true; do
+       case "$1" in
+               "")
+                       break
+                       ;;
+               -h|--help)
+                       echo "nit-makepackage: creates a package.ini in the current directory"
+                       echo "There is no option (yet)"
+                       exit
+                       ;;
+               *)
+                       echo >&2 "nit-makepackage does not accept options yet"
+                       exit 1
+                       ;;
+       esac
+done
+
+
 name=`basename $PWD`
 maintainer=`git shortlog -esn . | head -n 1 | sed 's/\s*[0-9]*\s*//'`
 dir=`git rev-parse --show-prefix`
index ff29ba2..351e69d 100755 (executable)
@@ -21,6 +21,7 @@
 update_oot() {
        if test -d "$dir"; then
                echo "$name: git pull"
+               ../misc/jenkins/unitrun.sh "cmd-$name-remote" git --work-tree="$PWD/$dir" --git-dir="$PWD/$dir/.git" remote set-url origin "$repo"
                ../misc/jenkins/unitrun.sh "cmd-$name-pull" git --work-tree="$PWD/$dir" --git-dir="$PWD/$dir/.git" pull -f
        else
                echo "$name: git clone"
index 4ceea39..46e720b 100644 (file)
@@ -2,6 +2,8 @@
 # Format: repo name
 https://github.com/R4PaSs/brewnit.git brewnit
 https://gitlab.com/xymus/darpg.git darpg
+https://gitlab.com/jeremlvt/dawn_arrival.git dawn_arrival
 https://github.com/Morriar/Missions.git missions
+https://gitlab.com/Heavyshield/NitGains.git nitgains
 https://github.com/ppepos/pep8-dbg.git pep8dbg
 https://gitlab.com/xymus/sputnit.git sputnit
index 09b20d9..643fe08 100644 (file)
@@ -898,9 +898,7 @@ redef class Text
 
        # return true if a file with this names exists
        fun file_exists: Bool do return to_cstring.file_exists
-end
 
-redef class String
        # The status of a file. see POSIX stat(2).
        fun file_stat: nullable FileStat
        do
@@ -943,14 +941,14 @@ redef class String
                if extension == null then
                        extension = file_extension
                        if extension == null then
-                               return self
+                               return self.to_s
                        else extension = ".{extension}"
                end
 
                if has_suffix(extension) then
-                       return substring(0, length - extension.length)
+                       return substring(0, length - extension.length).to_s
                end
-               return self
+               return self.to_s
        end
 
        # Extract the basename of a path and strip the `extension`
@@ -989,7 +987,7 @@ redef class String
 
                if extension != null then
                        return n.strip_extension(extension)
-               else return n
+               else return n.to_s
        end
 
        # Extract the dirname of a path
@@ -1018,7 +1016,7 @@ redef class String
                while l > 0 and s.chars[l] == '/' do l -= 1 # remove all trailing `/`
                var pos = s.chars.last_index_of_from('/', l)
                if pos > 0 then
-                       return s.substring(0, pos)
+                       return s.substring(0, pos).to_s
                else if pos == 0 then
                        return "/"
                else
@@ -1115,11 +1113,11 @@ redef class String
        # Note: You may want to use `simplify_path` on the result.
        #
        # Note: This method works only with POSIX paths.
-       fun join_path(path: String): String
+       fun join_path(path: Text): String
        do
-               if path.is_empty then return self
-               if self.is_empty then return path
-               if path.chars[0] == '/' then return path
+               if path.is_empty then return self.to_s
+               if self.is_empty then return path.to_s
+               if path.chars[0] == '/' then return path.to_s
                if self.last == '/' then return "{self}{path}"
                return "{self}/{path}"
        end
@@ -1134,7 +1132,7 @@ redef class String
        #     assert "".to_program_name == "./" # At least, your shell will detect the error.
        fun to_program_name: String do
                if self.has_prefix("/") then
-                       return self
+                       return self.to_s
                else
                        return "./{self}"
                end
@@ -1154,7 +1152,7 @@ redef class String
        #     var b = "/bar"
        #     var c = "baz/foobar"
        #     assert a/b/c == "/bar/baz/foobar"
-       fun /(path: String): String do return join_path(path)
+       fun /(path: Text): String do return join_path(path)
 
        # Returns the relative path needed to go from `self` to `dest`.
        #
@@ -1318,7 +1316,7 @@ redef class String
        do
                var last_slash = chars.last_index_of('.')
                if last_slash > 0 then
-                       return substring( last_slash+1, length )
+                       return substring( last_slash+1, length ).to_s
                else
                        return null
                end
index 8dd9b7e..dba4c4e 100644 (file)
@@ -5,7 +5,7 @@ It is based on the portability framework _app.nit_ and the OpenGL ES 2.0 standar
 
 # System configuration
 
-To compile the _gamnit_ apps packaged with the Nit repositoy on GNU/Linux you need to install the dev version of a few libraries and some tools.
+To compile the _gamnit_ apps packaged with the Nit repository on GNU/Linux you need to install the dev version of a few libraries and some tools.
 Under Debian 8.2, this command should install everything needed:
 
 ~~~
index 2cd69d7..fa3a197 100644 (file)
@@ -24,7 +24,7 @@ module bmfont
 
 private import dom
 
-import font
+intrude import font
 
 # BMFont description, parsed with `Text::parse_bmfont` or loaded as a `BMFontAsset`
 #
@@ -40,7 +40,7 @@ class BMFont
        var face: Text
 
        # Size of the source true type font
-       var size: Int
+       var size: Float
 
        # Is the font bold?
        var bold: Bool
@@ -67,16 +67,16 @@ class BMFont
        # Information common to all characters
 
        # Distance in pixels between each line of text
-       var line_height: Int
+       var line_height: Float
 
        # Pixels from the top of the line to the base of the characters
-       var base: Int
+       var base: Float
 
        # Width of the texture
-       var scale_w: Int
+       var scale_w: Float
 
        # Height of the texture
-       var scale_h: Int
+       var scale_h: Float
 
        # Textures
        var pages = new Map[String, TextureAsset]
@@ -85,7 +85,14 @@ class BMFont
        var chars = new Map[Char, BMFontChar]
 
        # Distance between certain characters
-       var kernings = new HashMap2[Char, Char, Int]
+       var kernings = new HashMap2[Char, Char, Float]
+
+       # Additional distance between `prev_char` and `char`
+       fun kerning(prev_char: nullable Char, char: Char): Float
+       do
+               if prev_char == null then return 0.0
+               return kernings[prev_char, char] or else 0.0
+       end
 
        redef fun to_s do return "<{class_name} {face} at {size} pt, "+
                                 "{pages.length} pages, {chars.length} chars>"
@@ -111,25 +118,25 @@ end
 class BMFontChar
 
        # Subtexture left coordinate
-       var x: Int
+       var x: Float
 
        # Subtexture top coordinate
-       var y: Int
+       var y: Float
 
        # Subtexture width
-       var width: Int
+       var width: Float
 
        # Subtexture height
-       var height: Int
+       var height: Float
 
        # Drawing offset on X
-       var xoffset: Int
+       var xoffset: Float
 
        # Drawing offset on Y
-       var yoffset: Int
+       var yoffset: Float
 
        # Cursor advance after drawing this character
-       var xadvance: Int
+       var xadvance: Float
 
        # Full texture contaning this character and others
        var page: TextureAsset
@@ -174,9 +181,9 @@ redef class Text
        # """
        #
        # var fnt = desc.parse_bmfont("dir_in_assets").value
-       # assert fnt.to_s == "<BMFont arial at 72 pt, 1 pages, 3 chars>"
-       # assert fnt.line_height == 80
-       # assert fnt.kernings['A', 'C'] == -1
+       # assert fnt.to_s == "<BMFont arial at 72.0 pt, 1 pages, 3 chars>"
+       # assert fnt.line_height == 80.0
+       # assert fnt.kernings['A', 'C'] == -1.0
        # assert fnt.chars['A'].page.path == "dir_in_assets/arial.png"
        # ~~~
        fun parse_bmfont(dir: String): MaybeError[BMFont, Error]
@@ -208,16 +215,16 @@ redef class Text
 
                var fnt = new BMFont(
                        info_map["face"],
-                       info_map["size"].to_i,
+                       info_map["size"].to_f,
                        info_map["bold"] == "1",
                        info_map["italic"] == "1",
                        info_map["unicode"] == "1",
                        info_map["padding"],
                        info_map["spacing"],
-                       common_map["lineHeight"].to_i,
-                       common_map["base"].to_i,
-                       common_map["scaleW"].to_i,
-                       common_map["scaleH"].to_i
+                       common_map["lineHeight"].to_f,
+                       common_map["base"].to_f,
+                       common_map["scaleW"].to_f,
+                       common_map["scaleH"].to_f
                )
 
                # Pages / pixel data files
@@ -238,10 +245,10 @@ redef class Text
                        var id = attributes["id"].to_i.code_point
 
                        var c = new BMFontChar(
-                               attributes["x"].to_i, attributes["y"].to_i,
-                               attributes["width"].to_i, attributes["height"].to_i,
-                               attributes["xoffset"].to_i, attributes["yoffset"].to_i,
-                               attributes["xadvance"].to_i,
+                               attributes["x"].to_f, attributes["y"].to_f,
+                               attributes["width"].to_f, attributes["height"].to_f,
+                               attributes["xoffset"].to_f, attributes["yoffset"].to_f,
+                               attributes["xadvance"].to_f,
                                fnt.pages[attributes["page"]])
 
                        fnt.chars[id] = c
@@ -256,7 +263,7 @@ redef class Text
                                var attributes = item.attributes_to_map
                                var first = attributes["first"].to_i.code_point
                                var second = attributes["second"].to_i.code_point
-                               var amount = attributes["amount"].to_i
+                               var amount = attributes["amount"].to_f
                                fnt.kernings[first, second] = amount
                        end
                end
@@ -355,35 +362,85 @@ class BMFontAsset
        do
                var dx = 0.0
                var dy = 0.0
+               var text_width = 0.0
 
-               var line_height = desc.line_height.to_f
+               var max_width = text_sprites.max_width
+               var max_height = text_sprites.max_height
 
-               var prev_char = null
-               for c in text do
+               var line_height = desc.line_height
+               var partial_line_skip = line_height * partial_line_mod.to_f
+               var line_sprites = new Array[Sprite]
 
-                       var partial_line_mod = 0.4
+               var prev_char = null
+               var i = -1
+               while i < text.length - 1 do
+                       i += 1
+                       var c = text[i]
 
                        # Special characters
+                       var word_break = false
                        if c == '\n' then
-                               dy -= line_height.to_f
-                               dx = 0.0 #advance/2.0
+                               justify(line_sprites, text_sprites.align, dx)
+                               dy -= line_height
+                               if max_height != null and max_height < -dy + line_height then break
+                               dx = 0.0
                                prev_char = null
                                continue
                        else if c == pld then
-                               dy -= line_height * partial_line_mod.to_f
-                               prev_char = null
+                               dy -= partial_line_skip
+                               word_break = true
                                continue
                        else if c == plu then
-                               dy += line_height * partial_line_mod.to_f
-                               prev_char = null
+                               dy += partial_line_skip
+                               word_break = true
                                continue
                        else if c.is_whitespace then
-                               var advance = if desc.chars.keys.has(' ') then
-                                               desc.chars[' '].xadvance.to_f
+                               var space_advance = if desc.chars.keys.has(' ') then
+                                               desc.chars[' '].xadvance
                                        else if desc.chars.keys.has('f') then
-                                               desc.chars['f'].xadvance.to_f
+                                               desc.chars['f'].xadvance
                                        else 16.0
-                               dx += advance
+                               dx += space_advance
+                               word_break = true
+                       end
+
+                       # End of a word?
+                       if word_break then
+                               # If we care about line width, check for overflow
+                               if max_width != null then
+                                       # Calculate the length of the next word
+                                       var prev_w = null
+                                       var word_len = 0.0
+                                       for wi in [i+1..text.length[ do
+                                               var w = text[wi]
+
+                                               if w == '\n' or w == pld or w == plu or w.is_whitespace then break
+                                               word_len += advance(prev_w, w)
+                                               prev_w = w
+                                       end
+
+                                       # Would the line be too long?
+                                       if dx + word_len > max_width then
+                                               if text_sprites.wrap then
+                                                       # Wrap
+                                                       justify(line_sprites, text_sprites.align, dx)
+                                                       dy -= line_height
+                                                       if max_height != null and max_height < -dy + line_height then break
+                                                       dx = 0.0
+                                               else
+                                                       # Cut short
+                                                       justify(line_sprites, text_sprites.align, dx)
+                                                       dy -= line_height
+                                                       if max_height != null and max_height < -dy + line_height then break
+                                                       dx = 0.0
+                                                       while c != '\n' and i < text.length - 1 do
+                                                               i += 1
+                                                               c = text[i]
+                                                       end
+                                               end
+                                       end
+                               end
+
                                prev_char = null
                                continue
                        end
@@ -396,28 +453,53 @@ class BMFontAsset
                        end
 
                        var char_info = desc.chars[c]
-                       var advance = char_info.xadvance.to_f
-
-                       var kerning = 0.0
-                       if prev_char != null then
-                               kerning = (desc.kernings[prev_char, c] or else 0).to_f
-                       end
+                       var advance = char_info.xadvance
+                       var kerning = desc.kerning(prev_char, c)
 
-                       var x = dx + char_info.width.to_f/2.0  + char_info.xoffset.to_f + kerning
-                       var y = dy - char_info.height.to_f/2.0 - char_info.yoffset.to_f
+                       var x = dx + char_info.width/2.0  + char_info.xoffset + kerning
+                       var y = dy - char_info.height/2.0 - char_info.yoffset
                        var pos = text_sprites.anchor.offset(x, y, 0.0)
-                       text_sprites.sprites.add new Sprite(char_info.subtexture, pos)
+                       var s = new Sprite(char_info.subtexture, pos)
+                       text_sprites.sprites.add s
+                       line_sprites.add s
 
                        dx += advance + kerning
                        prev_char = c
+
+                       text_width = text_width.max(dx)
+               end
+
+               justify(line_sprites, text_sprites.align, dx)
+
+               # valign
+               if text_sprites.valign != 0.0 then
+                       var d = (-dy+line_height) * text_sprites.valign
+                       for s in text_sprites.sprites do s.center.y += d
                end
+
+               text_sprites.width = text_width.max(dx)
+               text_sprites.height = dy + line_height
        end
 
-       # Character replacing other charactesr missing from the font
+       # Character replacing other characters missing from the font
        private var replacement_char: nullable Char is lazy do
                for c in  "ďż˝?".chars do
                        if desc.chars.keys.has(c) then return c
                end
                return null
        end
+
+       private fun advance(prev_char: nullable Char, char: Char): Float
+       do
+               var char_info = desc.chars[char]
+               var kerning = desc.kerning(prev_char, char)
+               return char_info.xadvance + kerning
+       end
+
+       private fun justify(line_sprites: Array[Sprite], align: Float, line_width: Float)
+       do
+               var dx = -line_width*align
+               for s in line_sprites do s.center.x += dx
+               line_sprites.clear
+       end
 end
diff --git a/lib/gamnit/examples/fonts_showcase/Makefile b/lib/gamnit/examples/fonts_showcase/Makefile
new file mode 100644 (file)
index 0000000..0c6b3b5
--- /dev/null
@@ -0,0 +1,14 @@
+bin/fonts_showcase: $(shell nitls -M src/fonts_showcase.nit -m linux)
+       mkdir -p bin/
+       nitc src/fonts_showcase.nit -m linux -o $@
+
+android: bin/fonts_showcase.apk
+bin/fonts_showcase.apk: $(shell nitls -M src/fonts_showcase.nit -m android)
+       mkdir -p bin/
+       nitc src/fonts_showcase.nit -m android -o $@
+
+check:
+       nitunit .
+
+clean:
+       rm -rf bin/
diff --git a/lib/gamnit/examples/fonts_showcase/README.md b/lib/gamnit/examples/fonts_showcase/README.md
new file mode 100644 (file)
index 0000000..039d3e0
--- /dev/null
@@ -0,0 +1,5 @@
+Simple application to display and test the behavior the different `TextSprites` settings.
+
+# Artwork
+
+The font Josefin_Sans is published under SIL Open Font License 1.1 by Santiago Orozco
diff --git a/lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.fnt b/lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.fnt
new file mode 100644 (file)
index 0000000..397d2f6
--- /dev/null
@@ -0,0 +1,1177 @@
+<font>
+  <info face="font" size="34" bold="0" italic="0" charset="" unicode="" stretchH="100" smooth="1" aa="1" padding="2,2,2,2" spacing="0,0" outline="0"/>
+  <common lineHeight="34" base="27" scaleW="134" scaleH="506" pages="1" packed="0"/>
+  <pages>
+    <page id="0" file="font.png"/>
+  </pages>
+  <chars count="90">
+    <char id="97" x="2" y="2" width="17" height="17" xoffset="1.05" yoffset="12.34" xadvance="18.29" page="0" chnl="15"/>
+    <char id="98" x="2" y="21" width="18" height="29" xoffset="2.04" yoffset="0.51" xadvance="18.36" page="0" chnl="15"/>
+    <char id="99" x="21" y="2" width="15" height="17" xoffset="1.05" yoffset="12.34" xadvance="14.14" page="0" chnl="15"/>
+    <char id="100" x="2" y="52" width="17" height="29" xoffset="1.09" yoffset="0.51" xadvance="18.33" page="0" chnl="15"/>
+    <char id="101" x="2" y="83" width="17" height="17" xoffset="1.05" yoffset="12.34" xadvance="15.74" page="0" chnl="15"/>
+    <char id="102" x="2" y="102" width="13" height="29" xoffset="0.82" yoffset="0.51" xadvance="10.95" page="0" chnl="15"/>
+    <char id="103" x="2" y="133" width="18" height="24" xoffset="1.09" yoffset="12.34" xadvance="18.33" page="0" chnl="15"/>
+    <char id="104" x="17" y="102" width="16" height="29" xoffset="2.04" yoffset="0.51" xadvance="17.31" page="0" chnl="15"/>
+    <char id="105" x="21" y="52" width="6" height="24" xoffset="1.67" yoffset="5.37" xadvance="6.97" page="0" chnl="15"/>
+    <char id="106" x="29" y="21" width="8" height="31" xoffset="-0.03" yoffset="5.37" xadvance="6.97" page="0" chnl="15"/>
+    <char id="107" x="29" y="54" width="15" height="29" xoffset="2.04" yoffset="0.51" xadvance="15.03" page="0" chnl="15"/>
+    <char id="108" x="22" y="21" width="5" height="29" xoffset="2.07" yoffset="0.51" xadvance="7.04" page="0" chnl="15"/>
+    <char id="109" x="38" y="2" width="26" height="17" xoffset="2.04" yoffset="12.34" xadvance="27.27" page="0" chnl="15"/>
+    <char id="110" x="39" y="21" width="16" height="17" xoffset="2.04" yoffset="12.34" xadvance="17.31" page="0" chnl="15"/>
+    <char id="111" x="2" y="159" width="17" height="17" xoffset="1.05" yoffset="12.34" xadvance="17.17" page="0" chnl="15"/>
+    <char id="112" x="2" y="178" width="18" height="24" xoffset="2.04" yoffset="12.34" xadvance="18.36" page="0" chnl="15"/>
+    <char id="113" x="2" y="204" width="17" height="24" xoffset="1.09" yoffset="12.34" xadvance="18.33" page="0" chnl="15"/>
+    <char id="114" x="21" y="159" width="11" height="17" xoffset="2.04" yoffset="12.34" xadvance="10.57" page="0" chnl="15"/>
+    <char id="115" x="22" y="133" width="12" height="17" xoffset="0.95" yoffset="12.38" xadvance="11.56" page="0" chnl="15"/>
+    <char id="116" x="35" y="85" width="12" height="23" xoffset="0.71" yoffset="6.46" xadvance="10.34" page="0" chnl="15"/>
+    <char id="117" x="35" y="110" width="16" height="17" xoffset="1.9" yoffset="12.72" xadvance="17.31" page="0" chnl="15"/>
+    <char id="118" x="46" y="40" width="18" height="18" xoffset="0.14" yoffset="12.72" xadvance="15.13" page="0" chnl="15"/>
+    <char id="119" x="57" y="21" width="25" height="17" xoffset="-0.69" yoffset="12.72" xadvance="22.24" page="0" chnl="15"/>
+    <char id="120" x="66" y="2" width="17" height="16" xoffset="0.37" yoffset="12.72" xadvance="14.76" page="0" chnl="15"/>
+    <char id="121" x="46" y="60" width="19" height="23" xoffset="0.2" yoffset="12.72" xadvance="16.29" page="0" chnl="15"/>
+    <char id="122" x="66" y="40" width="16" height="18" xoffset="0.51" yoffset="11.36" xadvance="14.93" page="0" chnl="15"/>
+    <char id="65" x="2" y="230" width="25" height="28" xoffset="-0.97" yoffset="1.12" xadvance="22" page="0" chnl="15"/>
+    <char id="66" x="22" y="178" width="18" height="27" xoffset="3.03" yoffset="2.28" xadvance="20.2" page="0" chnl="15"/>
+    <char id="67" x="36" y="129" width="22" height="28" xoffset="1.33" yoffset="2.01" xadvance="21.69" page="0" chnl="15"/>
+    <char id="68" x="53" y="85" width="22" height="27" xoffset="3.03" yoffset="2.28" xadvance="24.17" page="0" chnl="15"/>
+    <char id="69" x="2" y="260" width="19" height="27" xoffset="3.03" yoffset="2.28" xadvance="20.98" page="0" chnl="15"/>
+    <char id="70" x="2" y="289" width="17" height="27" xoffset="3.03" yoffset="2.28" xadvance="18.87" page="0" chnl="15"/>
+    <char id="71" x="2" y="318" width="22" height="28" xoffset="1.33" yoffset="2.01" xadvance="23.29" page="0" chnl="15"/>
+    <char id="72" x="21" y="289" width="22" height="27" xoffset="3.03" yoffset="2.28" xadvance="25.84" page="0" chnl="15"/>
+    <char id="73" x="23" y="260" width="6" height="27" xoffset="3.03" yoffset="2.28" xadvance="9.76" page="0" chnl="15"/>
+    <char id="74" x="29" y="207" width="11" height="32" xoffset="-0.95" yoffset="2.28" xadvance="11.12" page="0" chnl="15"/>
+    <char id="75" x="31" y="241" width="22" height="27" xoffset="3.03" yoffset="2.28" xadvance="22" page="0" chnl="15"/>
+    <char id="76" x="42" y="159" width="18" height="27" xoffset="3.03" yoffset="2.28" xadvance="19.41" page="0" chnl="15"/>
+    <char id="77" x="60" y="114" width="27" height="28" xoffset="3.03" yoffset="1.19" xadvance="30.74" page="0" chnl="15"/>
+    <char id="78" x="42" y="188" width="24" height="29" xoffset="3.03" yoffset="1.12" xadvance="27.68" page="0" chnl="15"/>
+    <char id="79" x="62" y="144" width="28" height="28" xoffset="1.29" yoffset="2.01" xadvance="27.78" page="0" chnl="15"/>
+    <char id="80" x="77" y="60" width="18" height="27" xoffset="3.03" yoffset="2.28" xadvance="19.62" page="0" chnl="15"/>
+    <char id="81" x="84" y="20" width="28" height="28" xoffset="1.29" yoffset="2.01" xadvance="27.95" page="0" chnl="15"/>
+    <char id="82" x="89" y="89" width="20" height="27" xoffset="3.03" yoffset="2.28" xadvance="21.35" page="0" chnl="15"/>
+    <char id="83" x="97" y="50" width="20" height="27" xoffset="0.82" yoffset="2.14" xadvance="19.21" page="0" chnl="15"/>
+    <char id="84" x="114" y="2" width="18" height="27" xoffset="1.36" yoffset="2.28" xadvance="18.73" page="0" chnl="15"/>
+    <char id="85" x="2" y="348" width="21" height="27" xoffset="2.75" yoffset="2.28" xadvance="24.31" page="0" chnl="15"/>
+    <char id="86" x="2" y="377" width="25" height="28" xoffset="-0.93" yoffset="2.28" xadvance="22.07" page="0" chnl="15"/>
+    <char id="87" x="26" y="318" width="34" height="28" xoffset="0.24" yoffset="2.38" xadvance="32.23" page="0" chnl="15"/>
+    <char id="88" x="25" y="348" width="24" height="27" xoffset="0.24" yoffset="2.28" xadvance="21.45" page="0" chnl="15"/>
+    <char id="89" x="45" y="270" width="25" height="27" xoffset="0.14" yoffset="2.28" xadvance="22.3" page="0" chnl="15"/>
+    <char id="90" x="55" y="219" width="24" height="28" xoffset="-0.97" yoffset="1.02" xadvance="21.59" page="0" chnl="15"/>
+    <char id="33" x="68" y="174" width="6" height="28" xoffset="2.62" yoffset="1.09" xadvance="9.04" page="0" chnl="15"/>
+    <char id="8470" x="60" y="144" width="0" height="0" xoffset="0" yoffset="26.93" xadvance="10.2" page="0" chnl="15"/>
+    <char id="59" x="55" y="249" width="9" height="19" xoffset="0.1" yoffset="14.45" xadvance="8.6" page="0" chnl="15"/>
+    <char id="37" x="89" y="118" width="24" height="21" xoffset="1.33" yoffset="9.11" xadvance="24.41" page="0" chnl="15"/>
+    <char id="58" x="34" y="159" width="6" height="16" xoffset="1.87" yoffset="13.74" xadvance="7.51" page="0" chnl="15"/>
+    <char id="63" x="111" y="79" width="16" height="28" xoffset="1.12" yoffset="1.7" xadvance="16.12" page="0" chnl="15"/>
+    <char id="42" x="21" y="85" width="12" height="12" xoffset="1.67" yoffset="2.45" xadvance="12.82" page="0" chnl="15"/>
+    <char id="40" x="76" y="174" width="11" height="34" xoffset="1.22" yoffset="1.22" xadvance="10.06" page="0" chnl="15"/>
+    <char id="41" x="119" y="31" width="11" height="34" xoffset="0.37" yoffset="1.33" xadvance="10.06" page="0" chnl="15"/>
+    <char id="95" x="111" y="109" width="16" height="5" xoffset="1.87" yoffset="23.9" xadvance="17.54" page="0" chnl="15"/>
+    <char id="43" x="85" y="2" width="15" height="15" xoffset="1.39" yoffset="12.75" xadvance="15.2" page="0" chnl="15"/>
+    <char id="45" x="22" y="152" width="9" height="5" xoffset="1.87" yoffset="18.02" xadvance="10.06" page="0" chnl="15"/>
+    <char id="61" x="45" y="299" width="20" height="12" xoffset="2.04" yoffset="13.46" xadvance="21.52" page="0" chnl="15"/>
+    <char id="46" x="68" y="204" width="6" height="6" xoffset="1.84" yoffset="23.09" xadvance="7.48" page="0" chnl="15"/>
+    <char id="44" x="102" y="2" width="9" height="9" xoffset="0.17" yoffset="23.97" xadvance="8.19" page="0" chnl="15"/>
+    <char id="47" x="2" y="407" width="16" height="28" xoffset="1.05" yoffset="1.56" xadvance="14.86" page="0" chnl="15"/>
+    <char id="124" x="2" y="437" width="5" height="34" xoffset="2.89" yoffset="2.79" xadvance="8.94" page="0" chnl="15"/>
+    <char id="34" x="77" y="89" width="10" height="11" xoffset="2.18" yoffset="2.11" xadvance="11.97" page="0" chnl="15"/>
+    <char id="39" x="39" y="40" width="5" height="11" xoffset="2.18" yoffset="2.11" xadvance="7.41" page="0" chnl="15"/>
+    <char id="64" x="2" y="473" width="31" height="31" xoffset="1.33" yoffset="5.44" xadvance="32.13" page="0" chnl="15"/>
+    <char id="35" x="9" y="437" width="19" height="25" xoffset="1.36" yoffset="4.76" xadvance="19.75" page="0" chnl="15"/>
+    <char id="36" x="29" y="377" width="20" height="32" xoffset="1.19" yoffset="0" xadvance="19.79" page="0" chnl="15"/>
+    <char id="94" x="42" y="219" width="11" height="9" xoffset="2.07" yoffset="4.18" xadvance="12.44" page="0" chnl="15"/>
+    <char id="38" x="30" y="411" width="23" height="29" xoffset="1.19" yoffset="1.09" xadvance="22.24" page="0" chnl="15"/>
+    <char id="123" x="51" y="348" width="12" height="33" xoffset="0.92" yoffset="1.22" xadvance="11.12" page="0" chnl="15"/>
+    <char id="125" x="62" y="313" width="12" height="33" xoffset="1.05" yoffset="1.22" xadvance="11.15" page="0" chnl="15"/>
+    <char id="91" x="72" y="249" width="9" height="33" xoffset="2.92" yoffset="1.22" xadvance="10.68" page="0" chnl="15"/>
+    <char id="93" x="81" y="210" width="9" height="33" xoffset="1.02" yoffset="1.22" xadvance="10.68" page="0" chnl="15"/>
+    <char id="48" x="51" y="383" width="21" height="25" xoffset="1.6" yoffset="4.25" xadvance="21.69" page="0" chnl="15"/>
+    <char id="49" x="20" y="407" width="7" height="25" xoffset="1.6" yoffset="4.52" xadvance="10.34" page="0" chnl="15"/>
+    <char id="50" x="72" y="284" width="18" height="25" xoffset="1.43" yoffset="4.25" xadvance="18.46" page="0" chnl="15"/>
+    <char id="51" x="30" y="442" width="16" height="25" xoffset="0.95" yoffset="4.52" xadvance="15.84" page="0" chnl="15"/>
+    <char id="52" x="65" y="348" width="19" height="25" xoffset="0" yoffset="4.25" xadvance="17.92" page="0" chnl="15"/>
+    <char id="53" x="89" y="174" width="15" height="25" xoffset="1.26" yoffset="4.52" xadvance="15.5" page="0" chnl="15"/>
+    <char id="54" x="92" y="141" width="17" height="25" xoffset="1.43" yoffset="4.96" xadvance="18.02" page="0" chnl="15"/>
+    <char id="55" x="76" y="311" width="17" height="25" xoffset="1.02" yoffset="4.52" xadvance="15.54" page="0" chnl="15"/>
+    <char id="56" x="83" y="245" width="17" height="25" xoffset="1.43" yoffset="4.25" xadvance="17.99" page="0" chnl="15"/>
+    <char id="57" x="92" y="272" width="17" height="24" xoffset="1.46" yoffset="4.96" xadvance="18.05" page="0" chnl="15"/>
+    <char id="32" x="0" y="0" width="0" height="0" xoffset="1.46" yoffset="4.96" xadvance="7.82" page="0" chnl="15"/>
+  </chars>
+  <kernings count="1075">
+    <kerning first="32" second="118" amount="-0.78"/>
+    <kerning first="32" second="121" amount="-0.78"/>
+    <kerning first="32" second="119" amount="-0.75"/>
+    <kerning first="32" second="65" amount="-1.02"/>
+    <kerning first="32" second="74" amount="-1.33"/>
+    <kerning first="32" second="89" amount="-1.39"/>
+    <kerning first="32" second="84" amount="-0.95"/>
+    <kerning first="32" second="86" amount="-1.29"/>
+    <kerning first="32" second="87" amount="-1.22"/>
+    <kerning first="32" second="39" amount="-0.44"/>
+    <kerning first="116" second="32" amount="-0.61"/>
+    <kerning first="116" second="46" amount="-0.71"/>
+    <kerning first="116" second="111" amount="-0.31"/>
+    <kerning first="116" second="65" amount="-1.12"/>
+    <kerning first="116" second="73" amount="-0.65"/>
+    <kerning first="116" second="74" amount="-1.43"/>
+    <kerning first="116" second="85" amount="-0.54"/>
+    <kerning first="116" second="89" amount="-2.96"/>
+    <kerning first="116" second="84" amount="-2.35"/>
+    <kerning first="116" second="41" amount="-1.16"/>
+    <kerning first="116" second="125" amount="-0.88"/>
+    <kerning first="116" second="47" amount="-0.34"/>
+    <kerning first="116" second="86" amount="-2.07"/>
+    <kerning first="116" second="83" amount="-0.99"/>
+    <kerning first="116" second="90" amount="-1.56"/>
+    <kerning first="116" second="87" amount="-1.87"/>
+    <kerning first="116" second="88" amount="-1.77"/>
+    <kerning first="116" second="93" amount="-0.85"/>
+    <kerning first="108" second="73" amount="-0.31"/>
+    <kerning first="108" second="74" amount="-0.99"/>
+    <kerning first="108" second="85" amount="-0.51"/>
+    <kerning first="108" second="89" amount="-0.37"/>
+    <kerning first="108" second="84" amount="-0.61"/>
+    <kerning first="108" second="86" amount="-0.24"/>
+    <kerning first="108" second="83" amount="-0.34"/>
+    <kerning first="108" second="90" amount="-0.31"/>
+    <kerning first="108" second="87" amount="-0.2"/>
+    <kerning first="108" second="88" amount="-0.44"/>
+    <kerning first="108" second="79" amount="-0.41"/>
+    <kerning first="105" second="73" amount="-0.31"/>
+    <kerning first="105" second="74" amount="-0.99"/>
+    <kerning first="105" second="85" amount="-0.65"/>
+    <kerning first="105" second="89" amount="-1.7"/>
+    <kerning first="105" second="84" amount="-1.6"/>
+    <kerning first="105" second="41" amount="-0.41"/>
+    <kerning first="105" second="86" amount="-1.16"/>
+    <kerning first="105" second="83" amount="-0.34"/>
+    <kerning first="105" second="90" amount="-0.31"/>
+    <kerning first="105" second="87" amount="-1.05"/>
+    <kerning first="105" second="88" amount="-0.51"/>
+    <kerning first="105" second="79" amount="-0.44"/>
+    <kerning first="99" second="111" amount="-0.51"/>
+    <kerning first="99" second="73" amount="-0.65"/>
+    <kerning first="99" second="74" amount="-1.16"/>
+    <kerning first="99" second="85" amount="-1.02"/>
+    <kerning first="99" second="89" amount="-4.11"/>
+    <kerning first="99" second="84" amount="-3.26"/>
+    <kerning first="99" second="63" amount="-0.58"/>
+    <kerning first="99" second="41" amount="-1.16"/>
+    <kerning first="99" second="42" amount="-0.51"/>
+    <kerning first="99" second="125" amount="-1.02"/>
+    <kerning first="99" second="45" amount="-0.44"/>
+    <kerning first="99" second="86" amount="-3.13"/>
+    <kerning first="99" second="83" amount="-0.27"/>
+    <kerning first="99" second="87" amount="-2.79"/>
+    <kerning first="99" second="88" amount="-0.2"/>
+    <kerning first="99" second="39" amount="-0.31"/>
+    <kerning first="99" second="93" amount="-1.09"/>
+    <kerning first="99" second="79" amount="-0.34"/>
+    <kerning first="114" second="32" amount="-0.71"/>
+    <kerning first="114" second="46" amount="-1.26"/>
+    <kerning first="114" second="111" amount="-0.27"/>
+    <kerning first="114" second="65" amount="-1.29"/>
+    <kerning first="114" second="73" amount="-0.54"/>
+    <kerning first="114" second="74" amount="-1.46"/>
+    <kerning first="114" second="85" amount="-0.37"/>
+    <kerning first="114" second="89" amount="-3.16"/>
+    <kerning first="114" second="84" amount="-2.65"/>
+    <kerning first="114" second="41" amount="-1.43"/>
+    <kerning first="114" second="125" amount="-1.02"/>
+    <kerning first="114" second="47" amount="-0.51"/>
+    <kerning first="114" second="86" amount="-2.07"/>
+    <kerning first="114" second="83" amount="-0.92"/>
+    <kerning first="114" second="90" amount="-1.9"/>
+    <kerning first="114" second="87" amount="-1.9"/>
+    <kerning first="114" second="88" amount="-1.9"/>
+    <kerning first="114" second="93" amount="-1.09"/>
+    <kerning first="101" second="118" amount="-0.2"/>
+    <kerning first="101" second="121" amount="-0.2"/>
+    <kerning first="101" second="119" amount="-0.17"/>
+    <kerning first="101" second="65" amount="-0.24"/>
+    <kerning first="101" second="73" amount="-0.75"/>
+    <kerning first="101" second="74" amount="-1.36"/>
+    <kerning first="101" second="85" amount="-0.82"/>
+    <kerning first="101" second="89" amount="-4.15"/>
+    <kerning first="101" second="84" amount="-3.33"/>
+    <kerning first="101" second="63" amount="-0.88"/>
+    <kerning first="101" second="41" amount="-1.46"/>
+    <kerning first="101" second="42" amount="-0.71"/>
+    <kerning first="101" second="125" amount="-1.29"/>
+    <kerning first="101" second="86" amount="-3.67"/>
+    <kerning first="101" second="83" amount="-0.65"/>
+    <kerning first="101" second="90" amount="-0.48"/>
+    <kerning first="101" second="87" amount="-3.33"/>
+    <kerning first="101" second="88" amount="-0.75"/>
+    <kerning first="101" second="39" amount="-0.54"/>
+    <kerning first="101" second="93" amount="-1.22"/>
+    <kerning first="101" second="79" amount="-0.27"/>
+    <kerning first="46" second="116" amount="-0.37"/>
+    <kerning first="46" second="102" amount="-0.37"/>
+    <kerning first="46" second="118" amount="-1.33"/>
+    <kerning first="46" second="121" amount="-1.29"/>
+    <kerning first="46" second="119" amount="-1.12"/>
+    <kerning first="46" second="73" amount="-0.27"/>
+    <kerning first="46" second="85" amount="-0.75"/>
+    <kerning first="46" second="89" amount="-2.99"/>
+    <kerning first="46" second="84" amount="-2.07"/>
+    <kerning first="46" second="49" amount="-0.51"/>
+    <kerning first="46" second="55" amount="-0.51"/>
+    <kerning first="46" second="57" amount="-0.54"/>
+    <kerning first="46" second="48" amount="-0.61"/>
+    <kerning first="46" second="86" amount="-2.79"/>
+    <kerning first="46" second="87" amount="-2.58"/>
+    <kerning first="46" second="39" amount="-3.71"/>
+    <kerning first="46" second="79" amount="-1.02"/>
+    <kerning first="102" second="32" amount="-0.68"/>
+    <kerning first="102" second="46" amount="-0.95"/>
+    <kerning first="102" second="111" amount="-0.31"/>
+    <kerning first="102" second="65" amount="-1.26"/>
+    <kerning first="102" second="73" amount="-0.2"/>
+    <kerning first="102" second="74" amount="-1.26"/>
+    <kerning first="102" second="89" amount="1.02"/>
+    <kerning first="102" second="41" amount="1.36"/>
+    <kerning first="102" second="125" amount="0.71"/>
+    <kerning first="102" second="45" amount="-0.31"/>
+    <kerning first="102" second="47" amount="-0.41"/>
+    <kerning first="102" second="86" amount="1.12"/>
+    <kerning first="102" second="83" amount="-0.54"/>
+    <kerning first="102" second="87" amount="0.92"/>
+    <kerning first="102" second="88" amount="0.61"/>
+    <kerning first="102" second="93" amount="0.78"/>
+    <kerning first="118" second="32" amount="-0.82"/>
+    <kerning first="118" second="46" amount="-1.33"/>
+    <kerning first="118" second="115" amount="-0.27"/>
+    <kerning first="118" second="111" amount="-0.51"/>
+    <kerning first="118" second="65" amount="-0.99"/>
+    <kerning first="118" second="73" amount="-0.61"/>
+    <kerning first="118" second="74" amount="-1.7"/>
+    <kerning first="118" second="85" amount="-0.51"/>
+    <kerning first="118" second="89" amount="-3.43"/>
+    <kerning first="118" second="84" amount="-3.4"/>
+    <kerning first="118" second="63" amount="-0.34"/>
+    <kerning first="118" second="41" amount="-1.53"/>
+    <kerning first="118" second="125" amount="-1.09"/>
+    <kerning first="118" second="45" amount="-0.34"/>
+    <kerning first="118" second="47" amount="-0.54"/>
+    <kerning first="118" second="86" amount="-2.31"/>
+    <kerning first="118" second="83" amount="-0.95"/>
+    <kerning first="118" second="90" amount="-1.94"/>
+    <kerning first="118" second="87" amount="-2.04"/>
+    <kerning first="118" second="88" amount="-2.07"/>
+    <kerning first="118" second="93" amount="-1.16"/>
+    <kerning first="106" second="73" amount="-0.31"/>
+    <kerning first="106" second="74" amount="-0.51"/>
+    <kerning first="106" second="85" amount="-0.65"/>
+    <kerning first="106" second="89" amount="-1.63"/>
+    <kerning first="106" second="84" amount="-1.53"/>
+    <kerning first="106" second="86" amount="-1.12"/>
+    <kerning first="106" second="83" amount="-0.31"/>
+    <kerning first="106" second="90" amount="-0.31"/>
+    <kerning first="106" second="87" amount="-1.02"/>
+    <kerning first="106" second="88" amount="-0.51"/>
+    <kerning first="106" second="79" amount="-0.44"/>
+    <kerning first="115" second="118" amount="-0.24"/>
+    <kerning first="115" second="121" amount="-0.24"/>
+    <kerning first="115" second="119" amount="-0.2"/>
+    <kerning first="115" second="73" amount="-0.78"/>
+    <kerning first="115" second="74" amount="-1.39"/>
+    <kerning first="115" second="85" amount="-1.12"/>
+    <kerning first="115" second="89" amount="-3.98"/>
+    <kerning first="115" second="84" amount="-3.4"/>
+    <kerning first="115" second="63" amount="-0.71"/>
+    <kerning first="115" second="41" amount="-1.29"/>
+    <kerning first="115" second="42" amount="-0.58"/>
+    <kerning first="115" second="125" amount="-1.02"/>
+    <kerning first="115" second="86" amount="-3.3"/>
+    <kerning first="115" second="83" amount="-0.27"/>
+    <kerning first="115" second="90" amount="-0.24"/>
+    <kerning first="115" second="87" amount="-2.99"/>
+    <kerning first="115" second="88" amount="-0.44"/>
+    <kerning first="115" second="39" amount="-0.37"/>
+    <kerning first="115" second="93" amount="-1.12"/>
+    <kerning first="115" second="79" amount="-0.54"/>
+    <kerning first="107" second="118" amount="-0.14"/>
+    <kerning first="107" second="121" amount="-0.14"/>
+    <kerning first="107" second="111" amount="-0.61"/>
+    <kerning first="107" second="73" amount="-0.71"/>
+    <kerning first="107" second="74" amount="-0.44"/>
+    <kerning first="107" second="85" amount="-1.09"/>
+    <kerning first="107" second="89" amount="-3.71"/>
+    <kerning first="107" second="84" amount="-3.33"/>
+    <kerning first="107" second="63" amount="-0.71"/>
+    <kerning first="107" second="41" amount="-0.71"/>
+    <kerning first="107" second="42" amount="-0.61"/>
+    <kerning first="107" second="125" amount="-0.82"/>
+    <kerning first="107" second="45" amount="-0.34"/>
+    <kerning first="107" second="86" amount="-3.37"/>
+    <kerning first="107" second="83" amount="-0.2"/>
+    <kerning first="107" second="87" amount="-3.06"/>
+    <kerning first="107" second="39" amount="-0.75"/>
+    <kerning first="107" second="93" amount="-0.92"/>
+    <kerning first="107" second="79" amount="-0.65"/>
+    <kerning first="121" second="32" amount="-0.78"/>
+    <kerning first="121" second="46" amount="-1.29"/>
+    <kerning first="121" second="115" amount="-0.24"/>
+    <kerning first="121" second="111" amount="-0.51"/>
+    <kerning first="121" second="65" amount="-0.99"/>
+    <kerning first="121" second="73" amount="-0.68"/>
+    <kerning first="121" second="74" amount="-1.67"/>
+    <kerning first="121" second="85" amount="-0.51"/>
+    <kerning first="121" second="89" amount="-3.47"/>
+    <kerning first="121" second="84" amount="-3.43"/>
+    <kerning first="121" second="41" amount="-1.43"/>
+    <kerning first="121" second="125" amount="-1.05"/>
+    <kerning first="121" second="45" amount="-0.27"/>
+    <kerning first="121" second="47" amount="-0.51"/>
+    <kerning first="121" second="86" amount="-2.35"/>
+    <kerning first="121" second="83" amount="-0.95"/>
+    <kerning first="121" second="90" amount="-1.97"/>
+    <kerning first="121" second="87" amount="-2.04"/>
+    <kerning first="121" second="88" amount="-2.07"/>
+    <kerning first="121" second="93" amount="-1.09"/>
+    <kerning first="119" second="32" amount="-0.78"/>
+    <kerning first="119" second="46" amount="-1.16"/>
+    <kerning first="119" second="115" amount="-0.2"/>
+    <kerning first="119" second="111" amount="-0.44"/>
+    <kerning first="119" second="65" amount="-0.85"/>
+    <kerning first="119" second="73" amount="-0.58"/>
+    <kerning first="119" second="74" amount="-1.53"/>
+    <kerning first="119" second="85" amount="-0.44"/>
+    <kerning first="119" second="89" amount="-3.43"/>
+    <kerning first="119" second="84" amount="-3.33"/>
+    <kerning first="119" second="41" amount="-1.5"/>
+    <kerning first="119" second="125" amount="-1.05"/>
+    <kerning first="119" second="45" amount="-0.27"/>
+    <kerning first="119" second="47" amount="-0.44"/>
+    <kerning first="119" second="86" amount="-2.31"/>
+    <kerning first="119" second="83" amount="-0.88"/>
+    <kerning first="119" second="90" amount="-1.77"/>
+    <kerning first="119" second="87" amount="-2.01"/>
+    <kerning first="119" second="88" amount="-1.94"/>
+    <kerning first="119" second="93" amount="-1.09"/>
+    <kerning first="120" second="111" amount="-0.51"/>
+    <kerning first="120" second="73" amount="-0.61"/>
+    <kerning first="120" second="74" amount="-0.51"/>
+    <kerning first="120" second="85" amount="-1.02"/>
+    <kerning first="120" second="89" amount="-3.71"/>
+    <kerning first="120" second="84" amount="-3.2"/>
+    <kerning first="120" second="63" amount="-0.34"/>
+    <kerning first="120" second="41" amount="-0.71"/>
+    <kerning first="120" second="125" amount="-0.75"/>
+    <kerning first="120" second="45" amount="-0.31"/>
+    <kerning first="120" second="86" amount="-2.82"/>
+    <kerning first="120" second="83" amount="-0.17"/>
+    <kerning first="120" second="87" amount="-2.52"/>
+    <kerning first="120" second="93" amount="-0.88"/>
+    <kerning first="120" second="79" amount="-0.37"/>
+    <kerning first="122" second="111" amount="-0.24"/>
+    <kerning first="122" second="73" amount="-0.65"/>
+    <kerning first="122" second="74" amount="-1.16"/>
+    <kerning first="122" second="85" amount="-1.02"/>
+    <kerning first="122" second="89" amount="-3.88"/>
+    <kerning first="122" second="84" amount="-3.26"/>
+    <kerning first="122" second="63" amount="-0.37"/>
+    <kerning first="122" second="41" amount="-0.88"/>
+    <kerning first="122" second="125" amount="-0.85"/>
+    <kerning first="122" second="86" amount="-2.89"/>
+    <kerning first="122" second="83" amount="-0.17"/>
+    <kerning first="122" second="87" amount="-2.58"/>
+    <kerning first="122" second="93" amount="-0.95"/>
+    <kerning first="122" second="79" amount="-0.37"/>
+    <kerning first="111" second="116" amount="-0.24"/>
+    <kerning first="111" second="102" amount="-0.27"/>
+    <kerning first="111" second="118" amount="-0.51"/>
+    <kerning first="111" second="121" amount="-0.51"/>
+    <kerning first="111" second="119" amount="-0.41"/>
+    <kerning first="111" second="120" amount="-0.51"/>
+    <kerning first="111" second="122" amount="-0.48"/>
+    <kerning first="111" second="65" amount="-0.41"/>
+    <kerning first="111" second="73" amount="-0.68"/>
+    <kerning first="111" second="74" amount="-1.36"/>
+    <kerning first="111" second="85" amount="-0.99"/>
+    <kerning first="111" second="89" amount="-4.76"/>
+    <kerning first="111" second="84" amount="-3.57"/>
+    <kerning first="111" second="63" amount="-0.99"/>
+    <kerning first="111" second="41" amount="-1.67"/>
+    <kerning first="111" second="42" amount="-0.85"/>
+    <kerning first="111" second="125" amount="-1.29"/>
+    <kerning first="111" second="86" amount="-3.47"/>
+    <kerning first="111" second="83" amount="-0.71"/>
+    <kerning first="111" second="90" amount="-0.82"/>
+    <kerning first="111" second="87" amount="-3.06"/>
+    <kerning first="111" second="88" amount="-1.19"/>
+    <kerning first="111" second="39" amount="-0.68"/>
+    <kerning first="111" second="93" amount="-1.33"/>
+    <kerning first="111" second="79" amount="-0.48"/>
+    <kerning first="65" second="32" amount="-1.02"/>
+    <kerning first="65" second="116" amount="-0.75"/>
+    <kerning first="65" second="117" amount="-0.24"/>
+    <kerning first="65" second="102" amount="-0.75"/>
+    <kerning first="65" second="118" amount="-0.99"/>
+    <kerning first="65" second="121" amount="-0.95"/>
+    <kerning first="65" second="119" amount="-0.82"/>
+    <kerning first="65" second="111" amount="-0.37"/>
+    <kerning first="65" second="85" amount="-0.68"/>
+    <kerning first="65" second="89" amount="-2.41"/>
+    <kerning first="65" second="84" amount="-2.21"/>
+    <kerning first="65" second="63" amount="-0.71"/>
+    <kerning first="65" second="50" amount="-0.37"/>
+    <kerning first="65" second="49" amount="-0.51"/>
+    <kerning first="65" second="54" amount="-0.44"/>
+    <kerning first="65" second="55" amount="-0.41"/>
+    <kerning first="65" second="56" amount="-0.44"/>
+    <kerning first="65" second="41" amount="-0.44"/>
+    <kerning first="65" second="42" amount="-2.04"/>
+    <kerning first="65" second="57" amount="-0.58"/>
+    <kerning first="65" second="125" amount="-0.48"/>
+    <kerning first="65" second="48" amount="-0.58"/>
+    <kerning first="65" second="86" amount="-2.01"/>
+    <kerning first="65" second="87" amount="-1.8"/>
+    <kerning first="65" second="39" amount="-2.11"/>
+    <kerning first="65" second="93" amount="-0.61"/>
+    <kerning first="65" second="38" amount="-0.44"/>
+    <kerning first="65" second="79" amount="-0.92"/>
+    <kerning first="66" second="116" amount="-0.95"/>
+    <kerning first="66" second="108" amount="-0.54"/>
+    <kerning first="66" second="105" amount="-0.51"/>
+    <kerning first="66" second="104" amount="-0.54"/>
+    <kerning first="66" second="117" amount="-0.51"/>
+    <kerning first="66" second="102" amount="-0.99"/>
+    <kerning first="66" second="118" amount="-1.02"/>
+    <kerning first="66" second="106" amount="-0.51"/>
+    <kerning first="66" second="115" amount="-0.65"/>
+    <kerning first="66" second="121" amount="-0.95"/>
+    <kerning first="66" second="119" amount="-0.92"/>
+    <kerning first="66" second="120" amount="-1.05"/>
+    <kerning first="66" second="122" amount="-1.12"/>
+    <kerning first="66" second="111" amount="-0.31"/>
+    <kerning first="66" second="65" amount="-0.17"/>
+    <kerning first="66" second="74" amount="-0.51"/>
+    <kerning first="66" second="89" amount="-0.92"/>
+    <kerning first="66" second="84" amount="-0.24"/>
+    <kerning first="66" second="41" amount="-0.65"/>
+    <kerning first="66" second="125" amount="-0.44"/>
+    <kerning first="66" second="86" amount="-0.61"/>
+    <kerning first="66" second="90" amount="-0.24"/>
+    <kerning first="66" second="87" amount="-0.48"/>
+    <kerning first="66" second="88" amount="-0.2"/>
+    <kerning first="66" second="93" amount="-0.51"/>
+    <kerning first="66" second="110" amount="-0.51"/>
+    <kerning first="68" second="116" amount="-0.17"/>
+    <kerning first="68" second="108" amount="-0.41"/>
+    <kerning first="68" second="105" amount="-0.44"/>
+    <kerning first="68" second="104" amount="-0.41"/>
+    <kerning first="68" second="117" amount="-0.41"/>
+    <kerning first="68" second="46" amount="-0.95"/>
+    <kerning first="68" second="102" amount="-0.2"/>
+    <kerning first="68" second="106" amount="-0.44"/>
+    <kerning first="68" second="115" amount="-0.41"/>
+    <kerning first="68" second="120" amount="-0.34"/>
+    <kerning first="68" second="122" amount="-0.37"/>
+    <kerning first="68" second="111" amount="-0.48"/>
+    <kerning first="68" second="65" amount="-0.88"/>
+    <kerning first="68" second="74" amount="-0.82"/>
+    <kerning first="68" second="89" amount="-1.46"/>
+    <kerning first="68" second="84" amount="-0.61"/>
+    <kerning first="68" second="41" amount="-1.02"/>
+    <kerning first="68" second="125" amount="-0.75"/>
+    <kerning first="68" second="86" amount="-0.95"/>
+    <kerning first="68" second="83" amount="-0.2"/>
+    <kerning first="68" second="90" amount="-0.85"/>
+    <kerning first="68" second="87" amount="-0.82"/>
+    <kerning first="68" second="88" amount="-0.75"/>
+    <kerning first="68" second="93" amount="-0.78"/>
+    <kerning first="68" second="110" amount="-0.48"/>
+    <kerning first="69" second="116" amount="-0.75"/>
+    <kerning first="69" second="108" amount="-0.27"/>
+    <kerning first="69" second="105" amount="-0.31"/>
+    <kerning first="69" second="104" amount="-0.27"/>
+    <kerning first="69" second="117" amount="-0.51"/>
+    <kerning first="69" second="102" amount="-0.78"/>
+    <kerning first="69" second="118" amount="-0.95"/>
+    <kerning first="69" second="106" amount="-0.34"/>
+    <kerning first="69" second="115" amount="-0.24"/>
+    <kerning first="69" second="121" amount="-0.95"/>
+    <kerning first="69" second="119" amount="-0.92"/>
+    <kerning first="69" second="122" amount="-0.17"/>
+    <kerning first="69" second="111" amount="-0.58"/>
+    <kerning first="69" second="79" amount="-0.44"/>
+    <kerning first="69" second="110" amount="-0.41"/>
+    <kerning first="73" second="116" amount="-0.78"/>
+    <kerning first="73" second="108" amount="-0.31"/>
+    <kerning first="73" second="105" amount="-0.31"/>
+    <kerning first="73" second="104" amount="-0.31"/>
+    <kerning first="73" second="117" amount="-0.31"/>
+    <kerning first="73" second="46" amount="-0.27"/>
+    <kerning first="73" second="102" amount="-0.75"/>
+    <kerning first="73" second="118" amount="-0.65"/>
+    <kerning first="73" second="106" amount="-0.31"/>
+    <kerning first="73" second="115" amount="-0.78"/>
+    <kerning first="73" second="121" amount="-0.68"/>
+    <kerning first="73" second="119" amount="-0.71"/>
+    <kerning first="73" second="120" amount="-0.58"/>
+    <kerning first="73" second="122" amount="-0.68"/>
+    <kerning first="73" second="111" amount="-0.68"/>
+    <kerning first="73" second="110" amount="-0.27"/>
+    <kerning first="74" second="116" amount="-0.71"/>
+    <kerning first="74" second="108" amount="-0.31"/>
+    <kerning first="74" second="105" amount="-0.31"/>
+    <kerning first="74" second="104" amount="-0.31"/>
+    <kerning first="74" second="117" amount="-0.34"/>
+    <kerning first="74" second="46" amount="-0.34"/>
+    <kerning first="74" second="102" amount="-0.78"/>
+    <kerning first="74" second="118" amount="-0.61"/>
+    <kerning first="74" second="106" amount="-0.31"/>
+    <kerning first="74" second="115" amount="-0.78"/>
+    <kerning first="74" second="121" amount="-0.61"/>
+    <kerning first="74" second="119" amount="-0.65"/>
+    <kerning first="74" second="120" amount="-0.65"/>
+    <kerning first="74" second="122" amount="-0.75"/>
+    <kerning first="74" second="111" amount="-0.71"/>
+    <kerning first="74" second="110" amount="-0.31"/>
+    <kerning first="75" second="32" amount="-0.44"/>
+    <kerning first="75" second="116" amount="-1.12"/>
+    <kerning first="75" second="105" amount="-0.17"/>
+    <kerning first="75" second="117" amount="-0.65"/>
+    <kerning first="75" second="102" amount="-1.16"/>
+    <kerning first="75" second="118" amount="-2.21"/>
+    <kerning first="75" second="106" amount="-0.17"/>
+    <kerning first="75" second="121" amount="-2.18"/>
+    <kerning first="75" second="119" amount="-2.04"/>
+    <kerning first="75" second="111" amount="-0.95"/>
+    <kerning first="75" second="41" amount="0.54"/>
+    <kerning first="75" second="48" amount="-0.44"/>
+    <kerning first="75" second="45" amount="-0.34"/>
+    <kerning first="75" second="47" amount="0.31"/>
+    <kerning first="75" second="90" amount="0.24"/>
+    <kerning first="75" second="79" amount="-1.53"/>
+    <kerning first="75" second="110" amount="-0.17"/>
+    <kerning first="80" second="32" amount="-0.99"/>
+    <kerning first="80" second="116" amount="-0.17"/>
+    <kerning first="80" second="108" amount="-0.27"/>
+    <kerning first="80" second="105" amount="-0.2"/>
+    <kerning first="80" second="104" amount="-0.27"/>
+    <kerning first="80" second="117" amount="-0.71"/>
+    <kerning first="80" second="46" amount="-3.5"/>
+    <kerning first="80" second="102" amount="-0.17"/>
+    <kerning first="80" second="106" amount="-0.24"/>
+    <kerning first="80" second="115" amount="-1.22"/>
+    <kerning first="80" second="120" amount="-0.17"/>
+    <kerning first="80" second="111" amount="-1.84"/>
+    <kerning first="80" second="65" amount="-1.97"/>
+    <kerning first="80" second="74" amount="-0.71"/>
+    <kerning first="80" second="89" amount="-0.44"/>
+    <kerning first="80" second="52" amount="-1.12"/>
+    <kerning first="80" second="58" amount="-0.31"/>
+    <kerning first="80" second="45" amount="-1.36"/>
+    <kerning first="80" second="47" amount="-1.05"/>
+    <kerning first="80" second="86" amount="-0.2"/>
+    <kerning first="80" second="90" amount="-0.17"/>
+    <kerning first="80" second="110" amount="-0.88"/>
+    <kerning first="82" second="116" amount="-0.99"/>
+    <kerning first="82" second="108" amount="-0.51"/>
+    <kerning first="82" second="105" amount="-0.51"/>
+    <kerning first="82" second="104" amount="-0.51"/>
+    <kerning first="82" second="117" amount="-0.92"/>
+    <kerning first="82" second="102" amount="-1.02"/>
+    <kerning first="82" second="118" amount="-1.22"/>
+    <kerning first="82" second="106" amount="-0.51"/>
+    <kerning first="82" second="115" amount="-0.37"/>
+    <kerning first="82" second="121" amount="-1.22"/>
+    <kerning first="82" second="119" amount="-1.19"/>
+    <kerning first="82" second="111" amount="-1.29"/>
+    <kerning first="82" second="85" amount="-0.27"/>
+    <kerning first="82" second="89" amount="-1.36"/>
+    <kerning first="82" second="84" amount="-0.54"/>
+    <kerning first="82" second="86" amount="-1.02"/>
+    <kerning first="82" second="87" amount="-0.92"/>
+    <kerning first="82" second="79" amount="-0.37"/>
+    <kerning first="82" second="110" amount="-0.51"/>
+    <kerning first="85" second="116" amount="-0.71"/>
+    <kerning first="85" second="108" amount="-0.51"/>
+    <kerning first="85" second="105" amount="-0.65"/>
+    <kerning first="85" second="104" amount="-0.51"/>
+    <kerning first="85" second="117" amount="-0.78"/>
+    <kerning first="85" second="46" amount="-0.75"/>
+    <kerning first="85" second="102" amount="-0.75"/>
+    <kerning first="85" second="118" amount="-0.48"/>
+    <kerning first="85" second="106" amount="-0.65"/>
+    <kerning first="85" second="115" amount="-1.12"/>
+    <kerning first="85" second="121" amount="-0.51"/>
+    <kerning first="85" second="119" amount="-0.54"/>
+    <kerning first="85" second="120" amount="-0.88"/>
+    <kerning first="85" second="122" amount="-0.95"/>
+    <kerning first="85" second="111" amount="-1.02"/>
+    <kerning first="85" second="65" amount="-0.68"/>
+    <kerning first="85" second="74" amount="-0.44"/>
+    <kerning first="85" second="110" amount="-0.65"/>
+    <kerning first="89" second="32" amount="-1.36"/>
+    <kerning first="89" second="116" amount="-2.58"/>
+    <kerning first="89" second="108" amount="-0.41"/>
+    <kerning first="89" second="105" amount="-1.73"/>
+    <kerning first="89" second="104" amount="-0.41"/>
+    <kerning first="89" second="117" amount="-3.71"/>
+    <kerning first="89" second="46" amount="-2.96"/>
+    <kerning first="89" second="102" amount="-2.21"/>
+    <kerning first="89" second="118" amount="-3.5"/>
+    <kerning first="89" second="106" amount="-1.8"/>
+    <kerning first="89" second="115" amount="-4.11"/>
+    <kerning first="89" second="121" amount="-3.5"/>
+    <kerning first="89" second="119" amount="-3.57"/>
+    <kerning first="89" second="120" amount="-3.71"/>
+    <kerning first="89" second="122" amount="-3.37"/>
+    <kerning first="89" second="111" amount="-4.79"/>
+    <kerning first="89" second="65" amount="-2.38"/>
+    <kerning first="89" second="74" amount="-0.82"/>
+    <kerning first="89" second="64" amount="-2.28"/>
+    <kerning first="89" second="50" amount="-0.85"/>
+    <kerning first="89" second="52" amount="-2.72"/>
+    <kerning first="89" second="53" amount="-0.58"/>
+    <kerning first="89" second="54" amount="-2.48"/>
+    <kerning first="89" second="56" amount="-1.53"/>
+    <kerning first="89" second="58" amount="-2.11"/>
+    <kerning first="89" second="41" amount="0.61"/>
+    <kerning first="89" second="57" amount="-1.09"/>
+    <kerning first="89" second="124" amount="-0.44"/>
+    <kerning first="89" second="48" amount="-1.39"/>
+    <kerning first="89" second="45" amount="-2.58"/>
+    <kerning first="89" second="47" amount="-2.31"/>
+    <kerning first="89" second="83" amount="-0.85"/>
+    <kerning first="89" second="38" amount="-1.16"/>
+    <kerning first="89" second="79" amount="-1.46"/>
+    <kerning first="89" second="110" amount="-3.81"/>
+    <kerning first="70" second="32" amount="-0.82"/>
+    <kerning first="70" second="116" amount="-0.85"/>
+    <kerning first="70" second="108" amount="-0.44"/>
+    <kerning first="70" second="105" amount="-0.68"/>
+    <kerning first="70" second="104" amount="-0.44"/>
+    <kerning first="70" second="117" amount="-1.63"/>
+    <kerning first="70" second="46" amount="-3.16"/>
+    <kerning first="70" second="102" amount="-0.95"/>
+    <kerning first="70" second="118" amount="-0.85"/>
+    <kerning first="70" second="106" amount="-0.75"/>
+    <kerning first="70" second="115" amount="-1.67"/>
+    <kerning first="70" second="121" amount="-0.85"/>
+    <kerning first="70" second="119" amount="-0.92"/>
+    <kerning first="70" second="120" amount="-1.46"/>
+    <kerning first="70" second="122" amount="-1.43"/>
+    <kerning first="70" second="111" amount="-1.87"/>
+    <kerning first="70" second="65" amount="-1.94"/>
+    <kerning first="70" second="74" amount="-0.61"/>
+    <kerning first="70" second="64" amount="-0.37"/>
+    <kerning first="70" second="52" amount="-1.12"/>
+    <kerning first="70" second="54" amount="-0.41"/>
+    <kerning first="70" second="58" amount="-0.48"/>
+    <kerning first="70" second="45" amount="-0.68"/>
+    <kerning first="70" second="47" amount="-1.16"/>
+    <kerning first="70" second="83" amount="-0.2"/>
+    <kerning first="70" second="110" amount="-1.6"/>
+    <kerning first="76" second="32" amount="-1.09"/>
+    <kerning first="76" second="116" amount="-1.09"/>
+    <kerning first="76" second="117" amount="-0.2"/>
+    <kerning first="76" second="102" amount="-1.12"/>
+    <kerning first="76" second="118" amount="-2.79"/>
+    <kerning first="76" second="121" amount="-2.72"/>
+    <kerning first="76" second="119" amount="-2.31"/>
+    <kerning first="76" second="111" amount="-0.37"/>
+    <kerning first="76" second="85" amount="-0.31"/>
+    <kerning first="76" second="89" amount="-3.37"/>
+    <kerning first="76" second="84" amount="-3.03"/>
+    <kerning first="76" second="63" amount="-0.44"/>
+    <kerning first="76" second="42" amount="-3.77"/>
+    <kerning first="76" second="57" amount="-0.34"/>
+    <kerning first="76" second="45" amount="-1.05"/>
+    <kerning first="76" second="86" amount="-3.16"/>
+    <kerning first="76" second="87" amount="-2.99"/>
+    <kerning first="76" second="39" amount="-3.71"/>
+    <kerning first="76" second="79" amount="-0.71"/>
+    <kerning first="67" second="116" amount="-1.09"/>
+    <kerning first="67" second="105" amount="-0.17"/>
+    <kerning first="67" second="117" amount="-0.31"/>
+    <kerning first="67" second="102" amount="-1.09"/>
+    <kerning first="67" second="118" amount="-2.01"/>
+    <kerning first="67" second="106" amount="-0.17"/>
+    <kerning first="67" second="121" amount="-2.01"/>
+    <kerning first="67" second="119" amount="-1.8"/>
+    <kerning first="67" second="111" amount="-0.37"/>
+    <kerning first="67" second="79" amount="-0.68"/>
+    <kerning first="67" second="110" amount="-0.17"/>
+    <kerning first="81" second="65" amount="0.14"/>
+    <kerning first="81" second="90" amount="-0.03"/>
+    <kerning first="81" second="88" amount="-0.2"/>
+    <kerning first="84" second="32" amount="-0.95"/>
+    <kerning first="84" second="116" amount="-2.62"/>
+    <kerning first="84" second="108" amount="-0.61"/>
+    <kerning first="84" second="105" amount="-1.77"/>
+    <kerning first="84" second="104" amount="-0.61"/>
+    <kerning first="84" second="117" amount="-3.67"/>
+    <kerning first="84" second="46" amount="-2.11"/>
+    <kerning first="84" second="102" amount="-2.62"/>
+    <kerning first="84" second="118" amount="-3.57"/>
+    <kerning first="84" second="106" amount="-1.73"/>
+    <kerning first="84" second="115" amount="-3.54"/>
+    <kerning first="84" second="121" amount="-3.57"/>
+    <kerning first="84" second="119" amount="-3.57"/>
+    <kerning first="84" second="120" amount="-3.3"/>
+    <kerning first="84" second="122" amount="-3.4"/>
+    <kerning first="84" second="111" amount="-3.67"/>
+    <kerning first="84" second="65" amount="-2.21"/>
+    <kerning first="84" second="74" amount="-0.58"/>
+    <kerning first="84" second="64" amount="-1.94"/>
+    <kerning first="84" second="52" amount="-1.97"/>
+    <kerning first="84" second="54" amount="-2.11"/>
+    <kerning first="84" second="56" amount="-0.58"/>
+    <kerning first="84" second="58" amount="-1.77"/>
+    <kerning first="84" second="57" amount="-0.34"/>
+    <kerning first="84" second="48" amount="-0.61"/>
+    <kerning first="84" second="45" amount="-1.77"/>
+    <kerning first="84" second="47" amount="-1.7"/>
+    <kerning first="84" second="38" amount="-0.48"/>
+    <kerning first="84" second="79" amount="-0.58"/>
+    <kerning first="84" second="110" amount="-3.67"/>
+    <kerning first="64" second="65" amount="-0.48"/>
+    <kerning first="64" second="74" amount="-0.68"/>
+    <kerning first="64" second="89" amount="-2.18"/>
+    <kerning first="64" second="84" amount="-1.77"/>
+    <kerning first="64" second="86" amount="-1.56"/>
+    <kerning first="64" second="87" amount="-1.39"/>
+    <kerning first="64" second="39" amount="-0.37"/>
+    <kerning first="50" second="89" amount="-1.39"/>
+    <kerning first="50" second="84" amount="-0.58"/>
+    <kerning first="50" second="86" amount="-1.02"/>
+    <kerning first="50" second="87" amount="-0.88"/>
+    <kerning first="49" second="65" amount="-0.37"/>
+    <kerning first="49" second="89" amount="-0.75"/>
+    <kerning first="49" second="41" amount="-0.41"/>
+    <kerning first="49" second="86" amount="-0.54"/>
+    <kerning first="49" second="87" amount="-0.48"/>
+    <kerning first="51" second="65" amount="-0.48"/>
+    <kerning first="51" second="74" amount="-0.71"/>
+    <kerning first="51" second="86" amount="-0.44"/>
+    <kerning first="52" second="65" amount="-0.48"/>
+    <kerning first="52" second="74" amount="-0.54"/>
+    <kerning first="52" second="89" amount="-1.36"/>
+    <kerning first="52" second="84" amount="-0.65"/>
+    <kerning first="52" second="41" amount="-0.95"/>
+    <kerning first="52" second="125" amount="-0.58"/>
+    <kerning first="52" second="86" amount="-1.09"/>
+    <kerning first="52" second="87" amount="-1.02"/>
+    <kerning first="52" second="39" amount="-0.37"/>
+    <kerning first="52" second="93" amount="-0.61"/>
+    <kerning first="53" second="65" amount="-0.44"/>
+    <kerning first="53" second="74" amount="-0.65"/>
+    <kerning first="53" second="89" amount="-0.71"/>
+    <kerning first="53" second="41" amount="-0.44"/>
+    <kerning first="53" second="86" amount="-0.54"/>
+    <kerning first="53" second="87" amount="-0.48"/>
+    <kerning first="54" second="65" amount="-0.48"/>
+    <kerning first="54" second="74" amount="-0.68"/>
+    <kerning first="54" second="89" amount="-1.39"/>
+    <kerning first="54" second="84" amount="-0.61"/>
+    <kerning first="54" second="41" amount="-1.02"/>
+    <kerning first="54" second="125" amount="-0.71"/>
+    <kerning first="54" second="86" amount="-1.09"/>
+    <kerning first="54" second="87" amount="-0.99"/>
+    <kerning first="54" second="93" amount="-0.78"/>
+    <kerning first="55" second="46" amount="-2.04"/>
+    <kerning first="55" second="65" amount="-1.8"/>
+    <kerning first="55" second="74" amount="-0.75"/>
+    <kerning first="55" second="89" amount="0.27"/>
+    <kerning first="55" second="61" amount="-0.41"/>
+    <kerning first="55" second="52" amount="-1.26"/>
+    <kerning first="55" second="54" amount="-1.05"/>
+    <kerning first="55" second="56" amount="-0.37"/>
+    <kerning first="55" second="35" amount="-0.44"/>
+    <kerning first="55" second="43" amount="-1.39"/>
+    <kerning first="55" second="45" amount="-0.88"/>
+    <kerning first="55" second="47" amount="-1.26"/>
+    <kerning first="55" second="86" amount="0.58"/>
+    <kerning first="55" second="87" amount="0.27"/>
+    <kerning first="56" second="65" amount="-0.44"/>
+    <kerning first="56" second="74" amount="-0.65"/>
+    <kerning first="56" second="89" amount="-1.53"/>
+    <kerning first="56" second="84" amount="-0.71"/>
+    <kerning first="56" second="41" amount="-1.05"/>
+    <kerning first="56" second="125" amount="-0.75"/>
+    <kerning first="56" second="86" amount="-1.19"/>
+    <kerning first="56" second="87" amount="-1.05"/>
+    <kerning first="56" second="93" amount="-0.82"/>
+    <kerning first="58" second="89" amount="-2.07"/>
+    <kerning first="58" second="84" amount="-1.7"/>
+    <kerning first="58" second="86" amount="-1.53"/>
+    <kerning first="58" second="87" amount="-1.33"/>
+    <kerning first="58" second="39" amount="-0.68"/>
+    <kerning first="40" second="116" amount="-0.99"/>
+    <kerning first="40" second="105" amount="-0.44"/>
+    <kerning first="40" second="117" amount="-1.33"/>
+    <kerning first="40" second="102" amount="-0.85"/>
+    <kerning first="40" second="118" amount="-1.56"/>
+    <kerning first="40" second="106" amount="0.51"/>
+    <kerning first="40" second="115" amount="-1.22"/>
+    <kerning first="40" second="121" amount="-0.85"/>
+    <kerning first="40" second="119" amount="-1.53"/>
+    <kerning first="40" second="120" amount="-0.71"/>
+    <kerning first="40" second="122" amount="-0.71"/>
+    <kerning first="40" second="111" amount="-1.63"/>
+    <kerning first="40" second="65" amount="-0.51"/>
+    <kerning first="40" second="74" amount="1.8"/>
+    <kerning first="40" second="89" amount="0.48"/>
+    <kerning first="40" second="52" amount="-1.16"/>
+    <kerning first="40" second="54" amount="-1.29"/>
+    <kerning first="40" second="56" amount="-1.02"/>
+    <kerning first="40" second="40" amount="-0.58"/>
+    <kerning first="40" second="57" amount="-0.99"/>
+    <kerning first="40" second="123" amount="-0.37"/>
+    <kerning first="40" second="48" amount="-1.12"/>
+    <kerning first="40" second="86" amount="0.54"/>
+    <kerning first="40" second="83" amount="-0.37"/>
+    <kerning first="40" second="87" amount="0.41"/>
+    <kerning first="40" second="79" amount="-1.05"/>
+    <kerning first="40" second="110" amount="-1.09"/>
+    <kerning first="41" second="41" amount="-0.58"/>
+    <kerning first="41" second="125" amount="-0.34"/>
+    <kerning first="41" second="93" amount="-0.37"/>
+    <kerning first="42" second="117" amount="-0.27"/>
+    <kerning first="42" second="115" amount="-0.61"/>
+    <kerning first="42" second="111" amount="-0.88"/>
+    <kerning first="42" second="65" amount="-2.04"/>
+    <kerning first="42" second="74" amount="-0.65"/>
+    <kerning first="42" second="110" amount="-0.31"/>
+    <kerning first="43" second="50" amount="-0.41"/>
+    <kerning first="43" second="49" amount="-0.44"/>
+    <kerning first="43" second="55" amount="-1.19"/>
+    <kerning first="57" second="46" amount="-1.67"/>
+    <kerning first="57" second="65" amount="-1.26"/>
+    <kerning first="57" second="74" amount="-0.95"/>
+    <kerning first="57" second="89" amount="-1.22"/>
+    <kerning first="57" second="84" amount="-0.37"/>
+    <kerning first="57" second="51" amount="-0.41"/>
+    <kerning first="57" second="41" amount="-1.12"/>
+    <kerning first="57" second="125" amount="-0.95"/>
+    <kerning first="57" second="47" amount="-0.61"/>
+    <kerning first="57" second="86" amount="-0.75"/>
+    <kerning first="57" second="90" amount="-1.05"/>
+    <kerning first="57" second="87" amount="-0.65"/>
+    <kerning first="57" second="88" amount="-0.85"/>
+    <kerning first="57" second="93" amount="-0.99"/>
+    <kerning first="124" second="89" amount="-0.58"/>
+    <kerning first="124" second="86" amount="-0.44"/>
+    <kerning first="124" second="87" amount="-0.37"/>
+    <kerning first="123" second="116" amount="-0.71"/>
+    <kerning first="123" second="117" amount="-1.05"/>
+    <kerning first="123" second="102" amount="-0.65"/>
+    <kerning first="123" second="118" amount="-1.12"/>
+    <kerning first="123" second="115" amount="-1.09"/>
+    <kerning first="123" second="121" amount="-0.78"/>
+    <kerning first="123" second="119" amount="-1.09"/>
+    <kerning first="123" second="120" amount="-0.78"/>
+    <kerning first="123" second="122" amount="-0.78"/>
+    <kerning first="123" second="111" amount="-1.29"/>
+    <kerning first="123" second="65" amount="-0.54"/>
+    <kerning first="123" second="74" amount="1.22"/>
+    <kerning first="123" second="52" amount="-0.71"/>
+    <kerning first="123" second="54" amount="-0.99"/>
+    <kerning first="123" second="56" amount="-0.71"/>
+    <kerning first="123" second="40" amount="-0.34"/>
+    <kerning first="123" second="57" amount="-0.71"/>
+    <kerning first="123" second="48" amount="-0.85"/>
+    <kerning first="123" second="86" amount="0.17"/>
+    <kerning first="123" second="79" amount="-0.78"/>
+    <kerning first="123" second="110" amount="-0.95"/>
+    <kerning first="125" second="41" amount="-0.37"/>
+    <kerning first="48" second="46" amount="-0.61"/>
+    <kerning first="48" second="65" amount="-0.61"/>
+    <kerning first="48" second="74" amount="-0.85"/>
+    <kerning first="48" second="89" amount="-1.43"/>
+    <kerning first="48" second="84" amount="-0.75"/>
+    <kerning first="48" second="41" amount="-1.12"/>
+    <kerning first="48" second="125" amount="-0.85"/>
+    <kerning first="48" second="86" amount="-1.02"/>
+    <kerning first="48" second="90" amount="-0.58"/>
+    <kerning first="48" second="87" amount="-0.88"/>
+    <kerning first="48" second="88" amount="-0.48"/>
+    <kerning first="48" second="93" amount="-0.88"/>
+    <kerning first="45" second="118" amount="-0.34"/>
+    <kerning first="45" second="121" amount="-0.27"/>
+    <kerning first="45" second="119" amount="-0.27"/>
+    <kerning first="45" second="120" amount="-0.27"/>
+    <kerning first="45" second="122" amount="-0.51"/>
+    <kerning first="45" second="74" amount="-0.68"/>
+    <kerning first="45" second="89" amount="-2.55"/>
+    <kerning first="45" second="84" amount="-1.7"/>
+    <kerning first="45" second="55" amount="-0.68"/>
+    <kerning first="45" second="86" amount="-1.84"/>
+    <kerning first="45" second="87" amount="-1.56"/>
+    <kerning first="45" second="88" amount="-0.31"/>
+    <kerning first="45" second="39" amount="-2.89"/>
+    <kerning first="47" second="116" amount="-0.51"/>
+    <kerning first="47" second="117" amount="-1.22"/>
+    <kerning first="47" second="102" amount="-0.41"/>
+    <kerning first="47" second="118" amount="-0.95"/>
+    <kerning first="47" second="115" amount="-1.5"/>
+    <kerning first="47" second="121" amount="-0.95"/>
+    <kerning first="47" second="119" amount="-0.99"/>
+    <kerning first="47" second="120" amount="-1.02"/>
+    <kerning first="47" second="122" amount="-0.85"/>
+    <kerning first="47" second="111" amount="-1.8"/>
+    <kerning first="47" second="65" amount="-1.94"/>
+    <kerning first="47" second="74" amount="-0.78"/>
+    <kerning first="47" second="52" amount="-1.43"/>
+    <kerning first="47" second="54" amount="-1.26"/>
+    <kerning first="47" second="56" amount="-0.58"/>
+    <kerning first="47" second="48" amount="-0.41"/>
+    <kerning first="47" second="47" amount="-1.39"/>
+    <kerning first="47" second="79" amount="-0.34"/>
+    <kerning first="47" second="110" amount="-1.29"/>
+    <kerning first="71" second="116" amount="-0.41"/>
+    <kerning first="71" second="108" amount="-0.37"/>
+    <kerning first="71" second="105" amount="-0.37"/>
+    <kerning first="71" second="104" amount="-0.37"/>
+    <kerning first="71" second="117" amount="-0.37"/>
+    <kerning first="71" second="102" amount="-0.44"/>
+    <kerning first="71" second="118" amount="-0.51"/>
+    <kerning first="71" second="106" amount="-0.37"/>
+    <kerning first="71" second="115" amount="-0.27"/>
+    <kerning first="71" second="121" amount="-0.51"/>
+    <kerning first="71" second="119" amount="-0.48"/>
+    <kerning first="71" second="120" amount="-0.37"/>
+    <kerning first="71" second="122" amount="-0.41"/>
+    <kerning first="71" second="111" amount="-0.34"/>
+    <kerning first="71" second="89" amount="-0.54"/>
+    <kerning first="71" second="86" amount="-0.44"/>
+    <kerning first="71" second="87" amount="-0.37"/>
+    <kerning first="71" second="110" amount="-0.37"/>
+    <kerning first="86" second="32" amount="-1.29"/>
+    <kerning first="86" second="116" amount="-1.94"/>
+    <kerning first="86" second="108" amount="-0.24"/>
+    <kerning first="86" second="105" amount="-1.22"/>
+    <kerning first="86" second="104" amount="-0.24"/>
+    <kerning first="86" second="117" amount="-2.89"/>
+    <kerning first="86" second="46" amount="-2.79"/>
+    <kerning first="86" second="102" amount="-1.94"/>
+    <kerning first="86" second="118" amount="-2.38"/>
+    <kerning first="86" second="106" amount="-1.29"/>
+    <kerning first="86" second="115" amount="-3.33"/>
+    <kerning first="86" second="121" amount="-2.38"/>
+    <kerning first="86" second="119" amount="-2.45"/>
+    <kerning first="86" second="120" amount="-2.69"/>
+    <kerning first="86" second="122" amount="-2.38"/>
+    <kerning first="86" second="111" amount="-3.54"/>
+    <kerning first="86" second="65" amount="-2.01"/>
+    <kerning first="86" second="74" amount="-0.71"/>
+    <kerning first="86" second="64" amount="-1.73"/>
+    <kerning first="86" second="50" amount="-0.54"/>
+    <kerning first="86" second="52" amount="-2.07"/>
+    <kerning first="86" second="53" amount="-0.34"/>
+    <kerning first="86" second="54" amount="-1.84"/>
+    <kerning first="86" second="56" amount="-1.05"/>
+    <kerning first="86" second="58" amount="-1.56"/>
+    <kerning first="86" second="41" amount="0.78"/>
+    <kerning first="86" second="57" amount="-0.68"/>
+    <kerning first="86" second="125" amount="0.17"/>
+    <kerning first="86" second="48" amount="-0.88"/>
+    <kerning first="86" second="45" amount="-1.84"/>
+    <kerning first="86" second="47" amount="-1.94"/>
+    <kerning first="86" second="83" amount="-0.61"/>
+    <kerning first="86" second="93" amount="0.17"/>
+    <kerning first="86" second="38" amount="-0.88"/>
+    <kerning first="86" second="79" amount="-0.95"/>
+    <kerning first="86" second="110" amount="-2.79"/>
+    <kerning first="83" second="116" amount="-0.58"/>
+    <kerning first="83" second="108" amount="-0.31"/>
+    <kerning first="83" second="105" amount="-0.31"/>
+    <kerning first="83" second="104" amount="-0.31"/>
+    <kerning first="83" second="117" amount="-0.27"/>
+    <kerning first="83" second="102" amount="-0.65"/>
+    <kerning first="83" second="118" amount="-0.71"/>
+    <kerning first="83" second="106" amount="-0.31"/>
+    <kerning first="83" second="115" amount="-0.31"/>
+    <kerning first="83" second="121" amount="-0.71"/>
+    <kerning first="83" second="119" amount="-0.68"/>
+    <kerning first="83" second="120" amount="-0.71"/>
+    <kerning first="83" second="122" amount="-0.78"/>
+    <kerning first="83" second="111" amount="-0.17"/>
+    <kerning first="83" second="65" amount="-0.44"/>
+    <kerning first="83" second="74" amount="-0.34"/>
+    <kerning first="83" second="89" amount="-0.37"/>
+    <kerning first="83" second="86" amount="-0.44"/>
+    <kerning first="83" second="87" amount="-0.37"/>
+    <kerning first="83" second="110" amount="-0.31"/>
+    <kerning first="90" second="116" amount="-1.02"/>
+    <kerning first="90" second="108" amount="-0.27"/>
+    <kerning first="90" second="105" amount="-0.27"/>
+    <kerning first="90" second="104" amount="-0.27"/>
+    <kerning first="90" second="117" amount="-0.37"/>
+    <kerning first="90" second="102" amount="-1.02"/>
+    <kerning first="90" second="118" amount="-1.97"/>
+    <kerning first="90" second="106" amount="-0.27"/>
+    <kerning first="90" second="115" amount="-0.17"/>
+    <kerning first="90" second="121" amount="-1.97"/>
+    <kerning first="90" second="119" amount="-1.8"/>
+    <kerning first="90" second="111" amount="-0.34"/>
+    <kerning first="90" second="79" amount="-0.61"/>
+    <kerning first="90" second="110" amount="-0.27"/>
+    <kerning first="87" second="32" amount="-1.22"/>
+    <kerning first="87" second="116" amount="-1.87"/>
+    <kerning first="87" second="105" amount="-1.12"/>
+    <kerning first="87" second="117" amount="-2.58"/>
+    <kerning first="87" second="46" amount="-2.58"/>
+    <kerning first="87" second="102" amount="-1.87"/>
+    <kerning first="87" second="118" amount="-2.07"/>
+    <kerning first="87" second="106" amount="-1.19"/>
+    <kerning first="87" second="115" amount="-3.03"/>
+    <kerning first="87" second="121" amount="-2.04"/>
+    <kerning first="87" second="119" amount="-2.18"/>
+    <kerning first="87" second="120" amount="-2.38"/>
+    <kerning first="87" second="122" amount="-2.14"/>
+    <kerning first="87" second="111" amount="-3.13"/>
+    <kerning first="87" second="65" amount="-1.84"/>
+    <kerning first="87" second="74" amount="-0.61"/>
+    <kerning first="87" second="64" amount="-1.53"/>
+    <kerning first="87" second="50" amount="-0.48"/>
+    <kerning first="87" second="52" amount="-1.84"/>
+    <kerning first="87" second="54" amount="-1.63"/>
+    <kerning first="87" second="56" amount="-0.92"/>
+    <kerning first="87" second="58" amount="-1.36"/>
+    <kerning first="87" second="41" amount="0.68"/>
+    <kerning first="87" second="57" amount="-0.58"/>
+    <kerning first="87" second="48" amount="-0.71"/>
+    <kerning first="87" second="45" amount="-1.6"/>
+    <kerning first="87" second="47" amount="-1.77"/>
+    <kerning first="87" second="83" amount="-0.54"/>
+    <kerning first="87" second="38" amount="-0.78"/>
+    <kerning first="87" second="79" amount="-0.82"/>
+    <kerning first="87" second="110" amount="-2.48"/>
+    <kerning first="88" second="116" amount="-1.53"/>
+    <kerning first="88" second="108" amount="-0.44"/>
+    <kerning first="88" second="105" amount="-0.54"/>
+    <kerning first="88" second="104" amount="-0.44"/>
+    <kerning first="88" second="117" amount="-0.99"/>
+    <kerning first="88" second="102" amount="-1.53"/>
+    <kerning first="88" second="118" amount="-2.11"/>
+    <kerning first="88" second="106" amount="-0.54"/>
+    <kerning first="88" second="115" amount="-0.31"/>
+    <kerning first="88" second="121" amount="-2.07"/>
+    <kerning first="88" second="119" amount="-1.94"/>
+    <kerning first="88" second="111" amount="-1.19"/>
+    <kerning first="88" second="41" amount="0.2"/>
+    <kerning first="88" second="48" amount="-0.34"/>
+    <kerning first="88" second="45" amount="-0.34"/>
+    <kerning first="88" second="79" amount="-0.78"/>
+    <kerning first="88" second="110" amount="-0.51"/>
+    <kerning first="39" second="32" amount="-0.44"/>
+    <kerning first="39" second="46" amount="-3.71"/>
+    <kerning first="39" second="115" amount="-0.41"/>
+    <kerning first="39" second="111" amount="-0.71"/>
+    <kerning first="39" second="65" amount="-2.11"/>
+    <kerning first="39" second="74" amount="-0.68"/>
+    <kerning first="39" second="64" amount="-0.85"/>
+    <kerning first="39" second="52" amount="-1.84"/>
+    <kerning first="39" second="54" amount="-0.82"/>
+    <kerning first="39" second="58" amount="-0.71"/>
+    <kerning first="39" second="45" amount="-2.89"/>
+    <kerning first="39" second="47" amount="-1.22"/>
+    <kerning first="39" second="38" amount="-0.51"/>
+    <kerning first="91" second="116" amount="-0.75"/>
+    <kerning first="91" second="117" amount="-1.09"/>
+    <kerning first="91" second="102" amount="-0.65"/>
+    <kerning first="91" second="118" amount="-1.16"/>
+    <kerning first="91" second="115" amount="-1.12"/>
+    <kerning first="91" second="121" amount="-0.78"/>
+    <kerning first="91" second="119" amount="-1.12"/>
+    <kerning first="91" second="120" amount="-0.88"/>
+    <kerning first="91" second="122" amount="-0.88"/>
+    <kerning first="91" second="111" amount="-1.33"/>
+    <kerning first="91" second="65" amount="-0.65"/>
+    <kerning first="91" second="74" amount="1.22"/>
+    <kerning first="91" second="52" amount="-0.85"/>
+    <kerning first="91" second="54" amount="-1.02"/>
+    <kerning first="91" second="56" amount="-0.75"/>
+    <kerning first="91" second="40" amount="-0.34"/>
+    <kerning first="91" second="57" amount="-0.75"/>
+    <kerning first="91" second="48" amount="-0.85"/>
+    <kerning first="91" second="86" amount="0.17"/>
+    <kerning first="91" second="83" amount="-0.34"/>
+    <kerning first="91" second="79" amount="-0.82"/>
+    <kerning first="91" second="110" amount="-1.02"/>
+    <kerning first="38" second="65" amount="0.78"/>
+    <kerning first="38" second="89" amount="-1.5"/>
+    <kerning first="38" second="84" amount="-1.56"/>
+    <kerning first="38" second="86" amount="-1.09"/>
+    <kerning first="38" second="90" amount="0.78"/>
+    <kerning first="38" second="87" amount="-0.95"/>
+    <kerning first="38" second="88" amount="0.58"/>
+    <kerning first="79" second="108" amount="-0.41"/>
+    <kerning first="79" second="105" amount="-0.44"/>
+    <kerning first="79" second="104" amount="-0.41"/>
+    <kerning first="79" second="117" amount="-0.41"/>
+    <kerning first="79" second="46" amount="-1.02"/>
+    <kerning first="79" second="102" amount="-0.17"/>
+    <kerning first="79" second="106" amount="-0.44"/>
+    <kerning first="79" second="115" amount="-0.41"/>
+    <kerning first="79" second="120" amount="-0.31"/>
+    <kerning first="79" second="122" amount="-0.34"/>
+    <kerning first="79" second="111" amount="-0.51"/>
+    <kerning first="79" second="65" amount="-0.92"/>
+    <kerning first="79" second="74" amount="-0.85"/>
+    <kerning first="79" second="89" amount="-1.46"/>
+    <kerning first="79" second="84" amount="-0.58"/>
+    <kerning first="79" second="41" amount="-1.02"/>
+    <kerning first="79" second="125" amount="-0.78"/>
+    <kerning first="79" second="86" amount="-0.95"/>
+    <kerning first="79" second="83" amount="-0.24"/>
+    <kerning first="79" second="90" amount="-0.92"/>
+    <kerning first="79" second="87" amount="-0.82"/>
+    <kerning first="79" second="88" amount="-0.78"/>
+    <kerning first="79" second="93" amount="-0.78"/>
+    <kerning first="79" second="110" amount="-0.48"/>
+    <kerning first="100" second="73" amount="-0.31"/>
+    <kerning first="100" second="74" amount="-0.95"/>
+    <kerning first="100" second="85" amount="-0.51"/>
+    <kerning first="100" second="89" amount="-0.37"/>
+    <kerning first="100" second="84" amount="-0.61"/>
+    <kerning first="100" second="86" amount="-0.24"/>
+    <kerning first="100" second="83" amount="-0.34"/>
+    <kerning first="100" second="90" amount="-0.31"/>
+    <kerning first="100" second="87" amount="-0.17"/>
+    <kerning first="100" second="88" amount="-0.44"/>
+    <kerning first="100" second="79" amount="-0.41"/>
+    <kerning first="97" second="73" amount="-0.27"/>
+    <kerning first="97" second="74" amount="-0.95"/>
+    <kerning first="97" second="85" amount="-0.61"/>
+    <kerning first="97" second="89" amount="-3.88"/>
+    <kerning first="97" second="84" amount="-3.57"/>
+    <kerning first="97" second="63" amount="-0.61"/>
+    <kerning first="97" second="41" amount="-1.16"/>
+    <kerning first="97" second="42" amount="-0.31"/>
+    <kerning first="97" second="125" amount="-0.99"/>
+    <kerning first="97" second="86" amount="-2.75"/>
+    <kerning first="97" second="83" amount="-0.48"/>
+    <kerning first="97" second="90" amount="-0.31"/>
+    <kerning first="97" second="87" amount="-2.45"/>
+    <kerning first="97" second="88" amount="-0.51"/>
+    <kerning first="97" second="93" amount="-1.05"/>
+    <kerning first="97" second="79" amount="-0.44"/>
+    <kerning first="110" second="118" amount="-0.24"/>
+    <kerning first="110" second="121" amount="-0.24"/>
+    <kerning first="110" second="119" amount="-0.17"/>
+    <kerning first="110" second="73" amount="-0.34"/>
+    <kerning first="110" second="74" amount="-1.05"/>
+    <kerning first="110" second="85" amount="-0.71"/>
+    <kerning first="110" second="89" amount="-4.52"/>
+    <kerning first="110" second="84" amount="-3.6"/>
+    <kerning first="110" second="63" amount="-0.82"/>
+    <kerning first="110" second="41" amount="-1.16"/>
+    <kerning first="110" second="42" amount="-0.61"/>
+    <kerning first="110" second="125" amount="-1.05"/>
+    <kerning first="110" second="86" amount="-3.33"/>
+    <kerning first="110" second="83" amount="-0.44"/>
+    <kerning first="110" second="90" amount="-0.24"/>
+    <kerning first="110" second="87" amount="-2.96"/>
+    <kerning first="110" second="88" amount="-0.44"/>
+    <kerning first="110" second="39" amount="-0.44"/>
+    <kerning first="110" second="93" amount="-1.12"/>
+    <kerning first="110" second="79" amount="-0.61"/>
+  </kernings>
+</font>
\ No newline at end of file
diff --git a/lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.png b/lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.png
new file mode 100644 (file)
index 0000000..3e8bd23
Binary files /dev/null and b/lib/gamnit/examples/fonts_showcase/assets/Josefin_Sans/font.png differ
diff --git a/lib/gamnit/examples/fonts_showcase/assets/anchor.png b/lib/gamnit/examples/fonts_showcase/assets/anchor.png
new file mode 100644 (file)
index 0000000..2aef81f
Binary files /dev/null and b/lib/gamnit/examples/fonts_showcase/assets/anchor.png differ
diff --git a/lib/gamnit/examples/fonts_showcase/package.ini b/lib/gamnit/examples/fonts_showcase/package.ini
new file mode 100644 (file)
index 0000000..4503def
--- /dev/null
@@ -0,0 +1,11 @@
+[package]
+name=fonts_showcase
+tags=game,example
+maintainer=Alexis Laferrière <alexis.laf@xymus.net>
+license=WTFPL
+[upstream]
+browse=https://github.com/nitlang/nit/tree/master/lib/gamnit/examples/fonts_showcase/
+git=https://github.com/nitlang/nit.git
+git.directory=lib/gamnit/examples/fonts_showcase/
+homepage=http://gamnit.org
+issues=https://github.com/nitlang/nit/issues
diff --git a/lib/gamnit/examples/fonts_showcase/src/fonts_showcase.nit b/lib/gamnit/examples/fonts_showcase/src/fonts_showcase.nit
new file mode 100644 (file)
index 0000000..0fae76d
--- /dev/null
@@ -0,0 +1,177 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the Do What The Fuck You Want To
+# Public License, Version 2, as published by Sam Hocevar. See
+# http://sam.zoy.org/projects/COPYING.WTFPL for more details.
+
+# Font support showcase
+module fonts_showcase is
+       app_name "gamnit fonts"
+       app_namespace "org.gamnit.fonts_showcase"
+       app_version(1, 0, git_revision)
+       android_api_target 10
+       android_manifest_activity """android:screenOrientation="sensorLandscape" """
+end
+
+import gamnit::flat
+import gamnit::bmfont
+
+redef class App
+
+       # Asset font used to display text
+       var font = new BMFontAsset("Josefin_Sans/font.fnt")
+
+       # Anchor texture used to identify the anchor coordinate of each `TextSprites`
+       var anchor = new Texture("anchor.png")
+
+       redef fun on_create
+       do
+               super
+
+               for tex in all_root_textures do
+                       var error = tex.error
+                       if error != null then print_error "Texture '{tex}' failed to load: {error}"
+               end
+
+               update_text
+       end
+
+       # Draw or redraw all the `TextSprites`
+       fun update_text
+       do
+               # Remove existing text and sprites
+               ui_sprites.clear
+               var texts = new Array[TextSprites]
+
+               # Shared content
+               var description = "The anchor icon identifies the coordinate of TextSprites::anchor."
+               var lorem_ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
+               var color = [0.0, 0.25, 0.5]
+
+               # ---
+               # TextSprites (the interesting part)
+
+               # Aligned text (no max_width)
+               texts.add new TextSprites(font,
+                       ui_camera.top.offset(-400.0, 0.0, 0.0),
+                       "Left, align=0.0:\n"+description)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top.offset(-400.0, -100.0, 0.0),
+                       "Right, align=1.0:\n"+description, align=1.0)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top.offset(-400.0, -200.0, 0.0),
+                       "Center, align=0.5:\n"+description, align=0.5)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top.offset(-400.0, -300.0, 0.0),
+                       "Weird, align=0.2:\n"+description, align=0.2)
+
+               # Aligned with max width
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(100.0, -400.0, 0.0),
+                       "Left, max_width=400.0:\n"+lorem_ipsum,
+                       align=0.0, max_width=400.0)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1000.0, -400.0, 0.0),
+                       "Right, max_width=400.0:\n"+lorem_ipsum,
+                       align=1.0, max_width=400.0)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(300.0, -700.0, 0.0),
+                       "Center, max_width=400.0:\n"+lorem_ipsum,
+                       align=0.5, max_width=400.0)
+
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(680.0, -700.0, 0.0),
+                       "Weird, max_width=400.0:\n"+lorem_ipsum,
+                       align=0.2, max_width=400.0)
+
+               # Max width & height
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1100.0, -400.0, 0.0),
+                       "max_width & max_height:\n"+lorem_ipsum,
+                       max_width=600.0, max_height=150.0)
+
+               # Thin max_width with overflows
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1100.0, -600.0, 0.0),
+                       "The 1{plu}st{pld} word of a line can always overflow:\n"+lorem_ipsum,
+                        max_width=100.0, max_height=400.0)
+
+               # No wrap
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1300.0, -600.0, 0.0),
+                       "wrap=false:\nLong lines are cut short blah blah blah\n"+lorem_ipsum,
+                       max_width=400.0, wrap=false)
+
+               # Bottom align
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1300.0, -1000.0, 0.0),
+                       "valign=1.0:\n"+lorem_ipsum,
+                       max_width=400.0, valign=1.0)
+
+               # Center valign
+               texts.add new TextSprites(font,
+                       ui_camera.top_left.offset(1500.0, -220.0, 0.0),
+                       "align=0.5, valign=0.5:\n"+lorem_ipsum,
+                       max_width=400.0, align=0.5, valign=0.5)
+
+               # ---
+               # Anchors and background boxes
+
+               # Gradient background for the max_width texts
+               var box = new CustomTexture(400.0, 200.0)
+               for x in 400.times do for y in 150.times do
+                       var p = 1.0-1.0*y.to_f/150.0
+                       p = p.sqrt
+                       box[x, y] = color + [p]
+               end
+               box.load
+               for i in [4..8[ do
+                       var t = texts[i]
+                       ui_sprites.add new Sprite(box,
+                               t.anchor.offset((-t.align+0.5)*t.max_width.as(not null),
+                               -100.0, -1.0))
+               end
+
+               # Plain boxes for max_width and max_height boxes
+               var large_box = new CustomTexture(600.0, 150.0)
+               large_box.fill color
+               large_box.load
+               ui_sprites.add new Sprite(large_box, texts[8].anchor.offset(300.0, -75.0, -1.0))
+
+               var thin_box = new CustomTexture(100.0, 400.0)
+               thin_box.fill color
+               thin_box.load
+               ui_sprites.add new Sprite(thin_box, ui_camera.top_left.offset(1150.0, -800.0, -1.0))
+
+               # Other TextSprites
+               ui_sprites.add new Sprite(box, texts[10].anchor.offset(200.0, -100.0, -1.0))
+
+               var s = new Sprite(box, texts[11].anchor.offset(200.0, 100.0, -1.0))
+               s.rotation = pi
+               ui_sprites.add s
+
+               ui_sprites.add new Sprite(box, texts[12].anchor.offset(0.0, 0.0, -1.0))
+
+               # Add the anchor effects to all TextSprites
+               for t in texts do ui_sprites.add new Sprite(anchor, t.anchor)
+       end
+
+       redef fun accept_event(event)
+       do
+               if event isa QuitEvent or
+                 (event isa KeyEvent and event.name == "escape" and event.is_up) then
+                       # Quit abruptly
+                       exit 0
+               else if event isa KeyEvent and event.is_up then
+                       update_text
+               end
+
+               return false
+       end
+end
index 8a5defe..df46590 100644 (file)
@@ -36,7 +36,17 @@ class TextSprites
        # Font used to draw text
        var font: Font
 
-       # Top left of the first character in UI coordinates
+       # Reference coordinates of this block of text
+       #
+       # When left aligned, the default at `align == 0.0`, the anchor is the
+       # left coordinate of the first character of the first line.
+       # When right aligned, at `align == 1.0`, the anchor is the right
+       # coordinate of the last character.
+       # When centered, at `align == 0.5`, the anchor is at the center.
+       #
+       # When top aligned, the default at `valign == 0.0`, the anchor is at the
+       # top of this block of text.
+       # When bottom aligned, at `valign == 1.0`, the anchor is at the bottom.
        var anchor: Point3d[Float]
 
        # Last set of sprites generated to display `text=`
@@ -48,7 +58,9 @@ class TextSprites
        # `app::sprites` or a custom collection.
        var target_sprite_set: Set[Sprite] = app.ui_sprites is lazy, writable
 
-       private var cached_text: nullable Text = ""
+       private var cached_text: nullable Text = null
+
+       private var init_complete = false
 
        # Last text drawn
        fun text: nullable Text do return cached_text
@@ -62,6 +74,8 @@ class TextSprites
                if text == cached_text then return
                cached_text = text
 
+               if not init_complete then return
+
                # Clean up last used sprites
                for s in sprites do if target_sprite_set.has(s) then target_sprite_set.remove s
                sprites.clear
@@ -73,6 +87,65 @@ class TextSprites
                # Register sprites to be drawn by `app.ui_camera`
                target_sprite_set.add_all sprites
        end
+
+       # Horizontal text alignment
+       #
+       # Use 0.0 to align left (the default), 0.5 to align in the center or
+       # 1.0 to align on the right.
+       #
+       # See: `valign`
+       var align = 0.0 is optional, writable
+
+       # Vertical text alignment
+       #
+       # Use 0.0 for top alignment (the default) where the text is under the `anchor`,
+       # 0.5 to vertically center the text on the `anchor` or
+       # or 1.0 to bottom align the text above the `anchor`.
+       #
+       # See: `align`
+       var valign = 0.0 is optional, writable
+
+       # Maximum width of each line of text
+       #
+       # The first word of each line is exempt and may overflow.
+       #
+       # The behavior when a line overflow depends on `wrap`.
+       var max_width: nullable Float is writable
+
+       # Maximum height of this block of text
+       #
+       # The first line is exempt and may overflow.
+       # Overflowing lines are cut.
+       var max_height: nullable Float is writable
+
+       # Should overflowing lines wrap to the next line?
+       #
+       # If `true`, the default, overflowing lines continue on the next line.
+       # Otherwise, lines are cut before overflowing.
+       var wrap = true is optional, writable
+
+       # Width of the currently displayed text
+       var width = 0.0
+
+       # Height of the currently displayed text
+       var height = 0.0
+
+       # Force drawing of the text sprites
+       #
+       # This method may be called after changing a setting (`align`, `wrap`, etc.)
+       # to update the displayed text.
+       fun force_redraw
+       do
+               var t = cached_text
+               cached_text = null
+               text = t
+       end
+
+       init
+       do
+               init_complete = true
+               force_redraw
+       end
 end
 
 # Partial line forward (U+008B)
index 6b47788..4bc95cb 100644 (file)
@@ -96,26 +96,117 @@ abstract class Texture
 
        # Offset of the bottom border on `root` from 0.0 to 1.0
        fun offset_bottom: Float do return 1.0
+
+       # Should this texture be drawn pixelated when magnified? otherwise it is interpolated
+       #
+       # This setting affects all the textures based on the same pixel data, or `root`.
+       #
+       # Must be set after a successful call to `load`.
+       fun pixelated=(pixelated: Bool)
+       do
+               if root.gl_texture == -1 then return
+
+               # TODO do not modify `root` by using *sampler objects* in glesv3
+               glBindTexture(gl_TEXTURE_2D, root.gl_texture)
+
+               var param = if pixelated then gl_NEAREST else gl_LINEAR
+               glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, param)
+       end
 end
 
-# Colorful small texture of 2x2 pixels
+# Colorful small texture of 32x32 pixels by default
 class CheckerTexture
        super RootTexture
 
+       # Width and height in pixels, defaults to 32
+       var size = 32 is optional
+
        redef fun load(force)
        do
-               var pixels = [0xFFu8, 0x00u8, 0x00u8,
-                             0x00u8, 0xFFu8, 0x00u8,
-                             0x00u8, 0x00u8, 0xFFu8,
-                             0xFFu8, 0xFFu8, 0xFFu8]
+               if gl_texture != -1 then return
+               load_checker size
+               loaded = true
+       end
+end
 
-               var cpixels = new CByteArray.from(pixels)
+# Custom texture with pixel values filled programmatically
+#
+# At creation, the texture is composed of `width` by `height` (rounded down)
+# transparent pixels. The pixels value can be set using `[]=`.
+#
+# ~~~
+# # Build a texture with 4 colors
+# var tex = new CustomTexture(2.0, 2.0)
+# tex[0, 0] = [1.0, 0.0, 0.0] # Red
+# tex[0, 1] = [0.0, 1.0, 0.0] # Green
+# tex[1, 0] = [0.0, 0.0, 1.0] # Blue
+# tex[1, 1] = [1.0, 1.0, 1.0, 0.5] # Transparent white
+# tex.load
+# ~~~
+class CustomTexture
+       super RootTexture
+
+       redef var width
+       redef var height
 
-               width = 2.0
-               height = 2.0
-               load_from_pixels(cpixels.native_array, 2, 2, gl_RGB)
+       private var cpixels = new CByteArray(4*width.to_i*height.to_i) is lazy
+
+       # Set the `color` of the pixel at `x`, `y` (from the top-left corner)
+       #
+       # The argument `color` should be an array of up to 4 floats (RGBA).
+       # If `color` has less than 4 items, the missing items are replaced by 1.0.
+       #
+       # Require: `not loaded and x < width.to_i and y < height.to_i`
+       fun []=(x, y: Int, color: Array[Float])
+       do
+               assert not loaded else print_error "{class_name}::[]= already loaded"
+               assert x < width.to_i and y < height.to_i else print_error "{class_name}::[] out of bounds"
+
+               # Simple conversion from [0.0..1.0] to [0..255]
+               var bytes = [for c in color do (c*255.0).round.to_i.clamp(0, 255).to_bytes.last]
+               while bytes.length < 4 do bytes.add 255u8
+
+               var offset = 4*(x + y*width.to_i)
+               for i in [0..4[ do cpixels[offset+i] = bytes[i]
+       end
+
+       # Overwrite all pixels with `color`
+       #
+       # The argument `color` should be an array of up to 4 floats (RGBA).
+       # If `color` has less than 4 items, the missing items are replaced by 1.0.
+       #
+       # Require: `not loaded`
+       fun fill(color: Array[Float])
+       do
+               assert not loaded else print_error "{class_name}::fill already loaded"
+
+               # Simple conversion from [0.0..1.0] to [0..255]
+               var bytes = [for c in color do (c*255.0).round.to_i.clamp(0, 255).to_bytes.last]
+               while bytes.length < 4 do bytes.add 255u8
+
+               var i = 0
+               for x in [0..width.to_i[ do
+                       for y in [0..height.to_i[ do
+                               for j in [0..4[ do cpixels[i+j] = bytes[j]
+                               i += 4
+                       end
+               end
+       end
+
+       redef fun load(force)
+       do
+               if loaded then return
+
+               # Round down the desired dimension
+               var width = width.to_i
+               var height = height.to_i
+               self.width = width.to_f
+               self.height = height.to_f
+
+               load_from_pixels(cpixels.native_array, width, height, gl_RGBA)
 
                cpixels.destroy
+               loaded = true
        end
 end
 
@@ -151,16 +242,29 @@ class RootTexture
                glGenerateMipmap(gl_TEXTURE_2D)
        end
 
-       # Set whether this texture should be pixelated when drawn, otherwise it is interpolated
-       fun pixelated=(pixelated: Bool)
+       private fun load_checker(size: Int)
        do
-               # TODO this service could be made available in `Texture` when using
-               # the kind of texture wrapper of gles v2 or maybe 3
+               var cpixels = new CByteArray(3*size*size)
+
+               var i = 0
+               for x in [0..size[ do
+                       var quadrant_x = if x < size/2 then 0 else 1
+                       for y in [0..size[ do
+                               var quadrant_y = if y < size/2 then 0 else 1
+                               var color = if quadrant_x == quadrant_y then
+                                       [0u8, 0u8, 0u8, 255u8]
+                               else [255u8, 255u8, 255u8, 255u8]
+
+                               for j in [0..3[ do cpixels[i+j] = color[j]
+                               i += 3
+                       end
+               end
 
-               glBindTexture(gl_TEXTURE_2D, gl_texture)
+               width = size.to_f
+               height = size.to_f
+               load_from_pixels(cpixels.native_array, size, size, gl_RGB)
 
-               var param = if pixelated then gl_NEAREST else gl_LINEAR
-               glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, param)
+               cpixels.destroy
        end
 
        # Has this resource been deleted?
@@ -190,6 +294,9 @@ class TextureAsset
 
                load_from_platform
 
+               # If no pixel data was loaded, load the pixel default texture
+               if gl_texture == -1 then load_checker 32
+
                loaded = true
        end
 
index 1a784ae..ce610e2 100644 (file)
@@ -58,6 +58,8 @@ class TileSet
 end
 
 # A monospace bitmap font where glyphs are stored in a tileset
+#
+# This `Font` does not implement all settings of `TextSprites`.
 class TileSetFont
        super TileSet
        super Font
index f054423..2489f9c 100644 (file)
@@ -415,6 +415,13 @@ class CypherQuery
                self.params = params
        end
 
+       # Pass the argument `value` as the parameter `key`.
+       #
+       # SEE: `set`
+       fun []=(key: String, value: nullable Serializable) do
+               params[key] = value
+       end
+
        # Add a `CREATE` statement to the query
        fun ncreate(query: String): CypherQuery do
                self.query = "{self.query}CREATE {query} "
@@ -451,6 +458,23 @@ class CypherQuery
                return self
        end
 
+       # Pass the argument `value` as the parameter `key`.
+       #
+       # Return `self`.
+       #
+       # ```
+       # var query = (new CypherQuery).nmatch("(n)").nwhere(
+       #               "n.key = key").set("key", "foo")
+       #
+       # assert query.params["key"] == "foo"
+       # ```
+       #
+       # SEE: `[]=`
+       fun set(key: String, value: nullable Serializable): SELF do
+               self[key] = value
+               return self
+       end
+
        # Translate the query to the body of a corresponding Neo4j REST request.
        fun to_rest: JsonObject do
                var obj = new JsonObject
index a1d602c..ee34149 100644 (file)
@@ -26,7 +26,7 @@ RUN git clone https://github.com/nitlang/nit.git /nit \
        && make \
        && . misc/nit_env.sh install \
        # Clean and reduce size
-       && strip c_src/nitc bin/nit* \
+       && { strip c_src/nitc bin/nit* || true; } \
        && ccache -C \
        && rm -rf .git
 
index dce0047..c1430da 100755 (executable)
@@ -25,12 +25,12 @@ name=$1
 shift
 
 # Detect a working time command
-if env time --quiet -f%U true 2>/dev/null; then
-       TIME="env time --quiet -f%U -o ${name}.t.out"
-elif env time -f%U true 2>/dev/null; then
-       TIME="env time -f%U -o ${name}.t.out"
-elif env gtime -f%U true 2>/dev/null; then
-       TIME="env gtime -f%U -o ${name}.t.out"
+if command time --quiet -f%e true 2>/dev/null; then
+       TIME="command time --quiet -f%e -o ${name}.t.out"
+elif command time -f%e true 2>/dev/null; then
+       TIME="command time -f%e -o ${name}.t.out"
+elif command gtime -f%e true 2>/dev/null; then
+       TIME="command gtime -f%e -o ${name}.t.out"
 else
        TIME=
 fi
diff --git a/share/man/nit-makepackage.md b/share/man/nit-makepackage.md
new file mode 100644 (file)
index 0000000..7569395
--- /dev/null
@@ -0,0 +1,18 @@
+# NAME
+
+nit-makepackage - helper script to setup package metadata
+
+# SYNOPSIS
+
+nit-makepackage
+
+# DESCRIPTION
+
+`nit-makepackage` creates (or overrides) a package.ini template file in the current directory.
+The result must be examined and adapted.
+
+Default values are guessed from git and the file system.
+
+# SEE ALSO
+
+The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>
index 31795fc..a3a0bc8 100644 (file)
@@ -360,8 +360,12 @@ class MakefileToolchain
                var debug = toolcontext.opt_debug.value
 
                makefile.write """
-CC ?= ccache cc
-CXX ?= ccache c++
+ifeq ($(origin CC), default)
+        CC = ccache cc
+endif
+ifeq ($(origin CXX), default)
+        CXX = ccache c++
+endif
 CFLAGS ?= -g {{{if not debug then "-O2" else ""}}} -Wno-unused-value -Wno-switch -Wno-attributes -Wno-trigraphs
 CINCL =
 LDFLAGS ?=
index 553263b..853d8ff 100644 (file)
@@ -149,7 +149,6 @@ redef class ModelBuilder
        private fun build_a_mclassdef(nmodule: AModule, nclassdef: AClassdef)
        do
                var mmodule = nmodule.mmodule.as(not null)
-               var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
                var mclass = nclassdef.mclass
                if mclass == null then return # Skip error
 
@@ -161,8 +160,45 @@ redef class ModelBuilder
                        return
                end
 
+               var bound_mtype = build_a_bound_mtype(nmodule, nclassdef)
+               if bound_mtype == null then return
+               var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location)
+               nclassdef.mclassdef = mclassdef
+               self.mclassdef2nclassdef[mclassdef] = nclassdef
+
+               if nclassdef isa AStdClassdef then
+                       var ndoc = nclassdef.n_doc
+                       if ndoc != null then
+                               var mdoc = ndoc.to_mdoc
+                               mclassdef.mdoc = mdoc
+                               mdoc.original_mentity = mclassdef
+                       else if mclassdef.is_intro and mclass.visibility >= public_visibility then
+                               advice(nclassdef, "missing-doc", "Documentation warning: Undocumented public class `{mclass}`")
+                       end
+               end
+
+               if mclassdef.is_intro then
+                       self.toolcontext.info("{mclassdef} introduces new {mclass.kind} {mclass.full_name}", 3)
+               else
+                       self.toolcontext.info("{mclassdef} refines {mclass.kind} {mclass.full_name}", 3)
+               end
+       end
+
+       # Determine the type parameter bounds for `nclassdef`.
+       #
+       # In case of error, return `null`.
+       #
+       # REQUIRE: `nmodule.mmodule != null`
+       # REQUIRE: `nclassdef.mclass != null`
+       private fun build_a_bound_mtype(nmodule: AModule, nclassdef: AClassdef): nullable MClassType
+       do
+               var mmodule = nmodule.mmodule.as(not null)
+               var mclass = nclassdef.mclass.as(not null)
+
                var bounds = new Array[MType]
                if nclassdef isa AStdClassdef and mclass.arity > 0 then
+                       var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
+
                        # Revolve bound for formal parameters
                        for i in [0..mclass.arity[ do
                                if nclassdef.n_formaldefs.is_empty then
@@ -180,7 +216,7 @@ redef class ModelBuilder
                                var nfdt = nfd.n_type
                                if nfdt != null then
                                        var bound = resolve_mtype3_unchecked(mmodule, null, null, nfdt, false)
-                                       if bound == null then return # Forward error
+                                       if bound == null then return null # Forward error
                                        if bound.need_anchor then
                                                # No F-bounds!
                                                error(nfd, "Error: formal parameter type `{pname}` bounded with a formal parameter type.")
@@ -191,7 +227,7 @@ redef class ModelBuilder
                                else if mclass.mclassdefs.is_empty then
                                        if objectclass == null then
                                                error(nfd, "Error: formal parameter type `{pname}` unbounded but no `Object` class exists.")
-                                               return
+                                               return null
                                        end
                                        # No bound, then implicitely bound by nullable Object
                                        var bound = objectclass.mclass_type.as_nullable
@@ -206,41 +242,39 @@ redef class ModelBuilder
                        end
                end
 
-               var bound_mtype = mclass.get_mtype(bounds)
-               var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location)
-               nclassdef.mclassdef = mclassdef
-               self.mclassdef2nclassdef[mclassdef] = nclassdef
-
-               if nclassdef isa AStdClassdef then
-                       var ndoc = nclassdef.n_doc
-                       if ndoc != null then
-                               var mdoc = ndoc.to_mdoc
-                               mclassdef.mdoc = mdoc
-                               mdoc.original_mentity = mclassdef
-                       else if mclassdef.is_intro and mclass.visibility >= public_visibility then
-                               advice(nclassdef, "missing-doc", "Documentation warning: Undocumented public class `{mclass}`")
-                       end
-               end
-
-               if mclassdef.is_intro then
-                       self.toolcontext.info("{mclassdef} introduces new {mclass.kind} {mclass.full_name}", 3)
-               else
-                       self.toolcontext.info("{mclassdef} refines {mclass.kind} {mclass.full_name}", 3)
-               end
+               return mclass.get_mtype(bounds)
        end
 
        # Visit the AST and set the super-types of the `MClassDef` objects
-       private fun collect_a_mclassdef_inheritance(nmodule: AModule, nclassdef: AClassdef)
+       private fun build_a_mclassdef_inheritance(nmodule: AModule, nclassdef: AClassdef)
        do
                var mmodule = nmodule.mmodule
                if mmodule == null then return
-               var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
-               var pointerclass = try_get_mclass_by_name(nmodule, mmodule, "Pointer")
                var mclass = nclassdef.mclass
                if mclass == null then return
                var mclassdef = nclassdef.mclassdef
                if mclassdef == null then return
 
+               var supertypes = collect_supertypes(nmodule, nclassdef, mclassdef.is_intro)
+               mclassdef.set_supertypes(supertypes)
+               if not supertypes.is_empty then self.toolcontext.info("{mclassdef} new super-types: {supertypes.join(", ")}", 3)
+       end
+
+       # List the supertypes specified or implied by `nclassdef`.
+       #
+       # REQUIRE: `nmodule.mmodule != null`
+       # REQUIRE: `nclassdef.mclass != null`
+       private fun collect_supertypes(nmodule: AModule, nclassdef: AClassdef,
+                       is_intro: Bool): Array[MClassType]
+       do
+               var mmodule = nmodule.mmodule.as(not null)
+               var mclass = nclassdef.mclass.as(not null)
+               var name = mclass.name
+               var kind = mclass.kind
+
+               var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
+               var pointerclass = try_get_mclass_by_name(nmodule, mmodule, "Pointer")
+
                # Do we need to specify Object as a super class?
                var specobject = true
 
@@ -253,42 +287,43 @@ redef class ModelBuilder
                        for nsc in nclassdef.n_superclasses do
                                specobject = false
                                var ntype = nsc.n_type
-                               var mtype = resolve_mtype_unchecked(mclassdef, ntype, false)
+                               var mtype = resolve_mtype3_unchecked(mmodule, mclass, null,
+                                               ntype, false)
                                if mtype == null then continue # Skip because of error
                                if not mtype isa MClassType then
-                                       error(ntype, "Error: supertypes cannot be a formal type.")
-                                       return
+                                       error(ntype, "Error: a supertype cannot be a formal type.")
+                                       continue
                                end
-                               if not mclass.kind.can_specialize(mtype.mclass.kind) then
-                                       error(ntype, "Error: {mclass.kind} `{mclass}` cannot specialize {mtype.mclass.kind} `{mtype.mclass}`.")
+                               var superclass = mtype.mclass
+                               var super_kind = superclass.kind
+                               if not kind.can_specialize(super_kind) then
+                                       error(ntype, "Error: {kind} `{mclass}` cannot specialize {super_kind} `{superclass}`.")
                                end
                                supertypes.add mtype
                                #print "new super : {mclass} < {mtype}"
-                               if mtype.mclass.kind == extern_kind then specpointer = false
+                               if super_kind == extern_kind then specpointer = false
                        end
                end
 
-               if mclassdef.is_intro and objectclass != null then
-                       if mclass.kind == extern_kind and mclass.name != "Pointer" then
+               if is_intro and objectclass != null then
+                       if kind == extern_kind and name != "Pointer" then
                                # it is an extern class, but not a Pointer
                                if pointerclass == null then
                                        error(nclassdef, "Error: `Pointer` must be defined first.")
-                                       return
+                                       return supertypes
                                end
                                if specpointer then supertypes.add pointerclass.mclass_type
                        else if specobject then
-                               if mclass.name != "Object" then
+                               if name != "Object" then
                                        # it is a standard class without super class (but is not Object)
                                        supertypes.add objectclass.mclass_type
-                               else if mclass.kind != interface_kind then
+                               else if kind != interface_kind then
                                        error(nclassdef, "Error: `Object` must be an {interface_kind}.")
-                                       return
                                end
                        end
                end
 
-               mclassdef.set_supertypes(supertypes)
-               if not supertypes.is_empty then self.toolcontext.info("{mclassdef} new super-types: {supertypes.join(", ")}", 3)
+               return supertypes
        end
 
        # Check the validity of the specialization heirarchy
@@ -344,7 +379,7 @@ redef class ModelBuilder
 
                # Create inheritance on all classdefs
                for nclassdef in nmodule.n_classdefs do
-                       self.collect_a_mclassdef_inheritance(nmodule, nclassdef)
+                       self.build_a_mclassdef_inheritance(nmodule, nclassdef)
                end
 
                # Create the mclassdef hierarchy
@@ -435,8 +470,11 @@ redef class ModelBuilder
                        for nsc in nclassdef.n_superclasses do
                                var ntype = nsc.n_type
                                var mtype = ntype.mtype
-                               if mtype == null then continue
-                               assert mtype isa MClassType
+
+                               # If the supertype is `null` or don’t refer to a class, we
+                               # already raised an error.
+                               if not mtype isa MClassType then continue
+
                                var sc = mtype.mclass
                                if not parents.has(sc) or sc == objectclass then
                                        # Skip the warning on generated code
index a7f75ff..8880ef7 100644 (file)
@@ -769,22 +769,21 @@ redef class AMethPropdef
        do
                var n_kwinit = n_kwinit
                var n_kwnew = n_kwnew
-               var is_init = n_kwinit != null or n_kwnew != null
+               var is_new = n_kwnew != null
+               var is_init = n_kwinit != null or is_new
                var name: String
                var amethodid = self.n_methid
                var name_node: ANode
                if amethodid == null then
-                       if not is_init then
-                               name = "main"
-                               name_node = self
-                       else if n_kwinit != null then
+                       if n_kwinit != null then
                                name = "init"
                                name_node = n_kwinit
                        else if n_kwnew != null then
                                name = "new"
                                name_node = n_kwnew
                        else
-                               abort
+                               name = "main"
+                               name_node = self
                        end
                else if amethodid isa AIdMethid then
                        name = amethodid.n_id.text
@@ -828,8 +827,8 @@ redef class AMethPropdef
                                mprop.is_root_init = true
                        end
                        mprop.is_init = is_init
-                       mprop.is_new = n_kwnew != null
-                       if mprop.is_new then mclassdef.mclass.has_new_factory = true
+                       mprop.is_new = is_new
+                       if is_new then mclassdef.mclass.has_new_factory = true
                        if name == "sys" then mprop.is_toplevel = true # special case for sys allowed in `new` factories
                        if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then
                                mprop.is_broken = true
@@ -873,11 +872,12 @@ redef class AMethPropdef
        do
                var mpropdef = self.mpropdef
                if mpropdef == null then return # Error thus skiped
+               var mproperty = mpropdef.mproperty
                var mclassdef = mpropdef.mclassdef
                var mmodule = mclassdef.mmodule
                var nsig = self.n_signature
 
-               if mpropdef.mproperty.is_root_init and not mclassdef.is_intro then
+               if mproperty.is_root_init and not mclassdef.is_intro then
                        var root_init = mclassdef.mclass.root_init
                        if root_init != null then
                                # Inherit the initializers by refinement
@@ -907,7 +907,7 @@ redef class AMethPropdef
                # FIXME: do not inherit from the intro, but from the most specific
                var msignature: nullable MSignature = null
                if not mpropdef.is_intro then
-                       msignature = mpropdef.mproperty.intro.msignature
+                       msignature = mproperty.intro.msignature
                        if msignature == null then return # Skip error
 
                        # The local signature is adapted to use the local formal types, if any.
@@ -917,14 +917,14 @@ redef class AMethPropdef
                        if param_names.length != msignature.arity then
                                var node: ANode
                                if nsig != null then node = nsig else node = self
-                               modelbuilder.error(node, "Redef Error: expected {msignature.arity} parameter(s) for `{mpropdef.mproperty.name}{msignature}`; got {param_names.length}. See introduction at `{mpropdef.mproperty.full_name}`.")
+                               modelbuilder.error(node, "Redef Error: expected {msignature.arity} parameter(s) for `{mproperty.name}{msignature}`; got {param_names.length}. See introduction at `{mproperty.full_name}`.")
                                return
                        end
-               else if mpropdef.mproperty.is_init and not mpropdef.mproperty.is_new then
+               else if mproperty.is_init and not mproperty.is_new then
                        # FIXME UGLY: inherit signature from a super-constructor
                        for msupertype in mclassdef.supertypes do
                                msupertype = msupertype.anchor_to(mmodule, mclassdef.bound_mtype)
-                               var candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, mpropdef.mproperty.name)
+                               var candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, mproperty.name)
                                if candidate != null then
                                        if msignature == null then
                                                msignature = candidate.intro.as(MMethodDef).msignature
@@ -961,14 +961,14 @@ redef class AMethPropdef
                end
 
                # In `new`-factories, the return type is by default the classtype.
-               if ret_type == null and mpropdef.mproperty.is_new then ret_type = mclassdef.mclass.mclass_type
+               if ret_type == null and mproperty.is_new then ret_type = mclassdef.mclass.mclass_type
 
                # Special checks for operator methods
                if not accept_special_last_parameter and mparameters.not_empty and mparameters.last.is_vararg then
-                       modelbuilder.error(self.n_signature.n_params.last, "Error: illegal variadic parameter `{mparameters.last}` for `{mpropdef.mproperty.name}`.")
+                       modelbuilder.error(self.n_signature.n_params.last, "Error: illegal variadic parameter `{mparameters.last}` for `{mproperty.name}`.")
                end
                if ret_type == null and return_is_mandatory then
-                       modelbuilder.error(self.n_methid, "Error: mandatory return type for `{mpropdef.mproperty.name}`.")
+                       modelbuilder.error(self.n_methid, "Error: mandatory return type for `{mproperty.name}`.")
                end
 
                msignature = new MSignature(mparameters, ret_type)
diff --git a/tests/error_formal_super.nit b/tests/error_formal_super.nit
new file mode 100644 (file)
index 0000000..216dac8
--- /dev/null
@@ -0,0 +1,21 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Test of formal types as supertypes.
+
+import core::kernel
+
+class Foo[E]
+       super E
+end
diff --git a/tests/sav/error_formal_super.res b/tests/sav/error_formal_super.res
new file mode 100644 (file)
index 0000000..b63cceb
--- /dev/null
@@ -0,0 +1 @@
+error_formal_super.nit:20,8: Error: a supertype cannot be a formal type.
index e556349..5da93bb 100644 (file)
@@ -14,6 +14,7 @@
 
 import neo4j
 
+# key used to loosely assume unicity and prevent conflicting db accesses
 var key = "NIT_TESTING_ID".environ.to_i
 
 var srv = new Neo4jServer
@@ -24,6 +25,9 @@ print "# Test local\n"
 var client = new Neo4jClient("http://localhost:7474")
 assert client.is_ok
 
+# Clear the previous objects, if any
+client.cypher(new CypherQuery.from_string("MATCH (n) WHERE n.key = {key} OPTIONAL MATCH n-[r]-() DELETE r, n"))
+
 var andres = new NeoNode
 andres.labels.add_all(["PERSON", "MALE"])
 andres["name"] = "Andres"
@@ -122,5 +126,5 @@ var query = (new CypherQuery).
        nand("n.key = {key}").
        nreturn("n, r, m")
 var res7 = client.cypher(query)
-assert not res7.as(JsonObject)["data"].as(JsonArray).is_empty
+assert res7.as(JsonObject)["data"].as(JsonArray).length == 1
 
index 35f550c..e098357 100644 (file)
@@ -17,6 +17,7 @@ import neo4j
 var srv = new Neo4jServer
 srv.start_quiet
 
+# key used to loosely assume unicity and prevent conflicting db accesses
 var key = "NIT_TESTING_ID".environ.to_i
 
 var andres = new NeoNode
@@ -39,6 +40,9 @@ loves["since"] = 1999
 var client = new Neo4jClient("http://localhost:7474")
 assert client.is_ok
 
+# Clear the previous objects, if any
+client.cypher(new CypherQuery.from_string("MATCH (n) WHERE n.key = {key} OPTIONAL MATCH n-[r]-() DELETE r, n"))
+
 print "# Save batch\n"
 
 var batch = new NeoBatch(client)
index e413069..a402eb2 100755 (executable)
@@ -130,12 +130,12 @@ else
 fi
 
 # Detect a working time command
-if env time --quiet -f%U true 2>/dev/null; then
-       TIME="env time --quiet -f%U"
-elif env time -f%U true 2>/dev/null; then
-       TIME="env time -f%U"
-elif env gtime -f%U true 2>/dev/null; then
-       TIME="env gtime -f%U"
+if command time --quiet -f%e true 2>/dev/null; then
+       TIME="command time --quiet -f%e"
+elif command time -f%e true 2>/dev/null; then
+       TIME="command time -f%e"
+elif command gtime -f%e true 2>/dev/null; then
+       TIME="command gtime -f%e"
 else
        TIME=
 fi