X-Git-Url: http://nitlanguage.org diff --git a/lib/gamnit/bmfont.nit b/lib/gamnit/bmfont.nit index afdbf04..d052922 100644 --- a/lib/gamnit/bmfont.nit +++ b/lib/gamnit/bmfont.nit @@ -283,7 +283,7 @@ end # var pos: Point3d[Float] = ui_camera.top_left.offset(128.0, -128.0, 0.0) # var ui_text = new TextSprites(font, pos) # -# redef fun on_create +# redef fun create_scene # do # super # @@ -366,15 +366,28 @@ class BMFontAsset var dx = 0.0 var dy = 0.0 var text_width = 0.0 + var line_sprites = new Array[Sprite] + var height = 0.0 + + # Has the current line height been added to `height`? + var line_height_counted = false + # TextSprite customization var max_width = text_sprites.max_width var max_height = text_sprites.max_height var scale = text_sprites.scale + # Font customization var line_height = desc.line_height * scale var partial_line_skip = line_height * partial_line_mod.to_f - var line_sprites = new Array[Sprite] + # Links data + text_sprites.links.clear + var in_link = false + var link_sprites = new Array[Sprite] + var link_name = "" + + # Loop over all characters var prev_char = null var i = -1 while i < text.length - 1 do @@ -388,14 +401,21 @@ class BMFontAsset dy -= line_height if max_height != null and max_height < -dy + line_height then break dx = 0.0 + if not line_height_counted then + # Force to account for empty lines + height += line_height + end + line_height_counted = false prev_char = null continue else if c == pld then dy -= partial_line_skip + height += partial_line_skip word_break = true continue else if c == plu then dy += partial_line_skip + height -= partial_line_skip # We could keep two heights and return the max word_break = true continue else if c.is_whitespace then @@ -406,8 +426,57 @@ class BMFontAsset else 16.0 dx += space_advance * scale word_break = true + else if c == '[' then + # Open link? + if i + 1 < text.length and text[i+1] == '[' then + # Escape if duplicated + i += 1 + else + in_link = true + continue + end + else if c == ']' then + # Close link? + if i + 1 < text.length and text[i+1] == ']' then + # Escape if duplicated + i += 1 + else + # If there's a () use it as link_name + var j = i + 1 + if j < text.length and text[j] == '(' then + var new_name + new_name = "" + loop + j += 1 + if j > text.length then + # No closing ), abort + new_name = null + break + end + + var l = text[j] + if l == ')' then break + new_name += l.to_s + end + if new_name != null then + link_name = new_name + i = j + end + end + + # Register the link for the clients + text_sprites.links[link_name] = link_sprites + + # Prepare next link + in_link = false + link_sprites = new Array[Sprite] + link_name = "" + continue + end end + if in_link then link_name += c.to_s + # End of a word? if word_break then # If we care about line width, check for overflow @@ -418,25 +487,28 @@ class BMFontAsset 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 + if w == '\n' or w == pld or w == plu or w.is_whitespace or (in_link and w == ']') then break + + if not desc.chars.keys.has(w) then + var rc = replacement_char + if rc == null then continue + w = rc + end + word_len += advance(prev_w, w) * scale 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 + 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 + line_height_counted = false + + if not text_sprites.wrap then + # Cut short, skip everything until the next new line while c != '\n' and i < text.length - 1 do i += 1 c = text[i] @@ -467,11 +539,18 @@ class BMFontAsset s.scale = scale * char_info.scale text_sprites.sprites.add s line_sprites.add s + if in_link then link_sprites.add s dx += (advance + kerning) * scale prev_char = c text_width = text_width.max(dx) + + if not line_height_counted then + # Increase `height` only once per line iff there's a caracter + line_height_counted = true + height += line_height + end end justify(line_sprites, text_sprites.align, dx) @@ -483,7 +562,7 @@ class BMFontAsset end text_sprites.width = text_width.max(dx) - text_sprites.height = dy + line_height + text_sprites.height = height end # Character replacing other characters missing from the font