Merge: gamnit: customize writing with BMFont
authorJean Privat <jean@pryen.org>
Sat, 17 Jun 2017 00:24:33 +0000 (20:24 -0400)
committerJean Privat <jean@pryen.org>
Sat, 17 Jun 2017 00:24:33 +0000 (20:24 -0400)
Add format services to `TestSprites` implemented (only) by `BMFont`: `align, valign, wrap, max_width` and `max_height`. You can see the result in the screenshot of the new showcase/test program:

![screenshot from 2017-06-15 15 53 28](https://user-images.githubusercontent.com/208057/27199185-1b9a36dc-51e3-11e7-9700-8dde5724e98a.png)

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

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/tileset.nit

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 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