# 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
#
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
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
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
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]
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)
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