Skip to content

Commit

Permalink
Added support for assigning layers on generated nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
britzl committed Mar 5, 2018
1 parent 179a379 commit 85b26a5
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 2 deletions.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,46 @@ The `settings` table can contain the following values:
* `width` (number) - Maximum width of a line of text. Omit this value to present the entire text on a single line
* `position` (vector3) - The position that the text aligns to (refer to the `align` setting for details). Defaults to 0,0 if not specified.
* `parent` (node) - GUI nodes will be attached to this node if specified.
* `fonts` (table) - Table with fonts, keyed on font name. Each entry should be a table with mappings to fonts for different font styles. Accepted keys are `regular`, `italic`, `bold`, `bold_italic`. If no `fonts` table is provided the font used will be the one passed to `richtext.create()`.
* `fonts` (table) - Table with fonts, keyed on font name. See separate section below. If no `fonts` table is provided the font used will be the one passed to `richtext.create()`.
* `layers` (table) - Table with font, texture and spine scene mappings to layer names. See separate section below.
* `color` (vector4) - The default color of text. Will be white if not specified.
* `align` (hash) - One of `richtext.ALIGN_LEFT`, `richtext.ALIGN_CENTER` and `richtext.ALIGN_RIGHT`. Defaults to `richtext.ALIGN_LEFT`. Defines how the words of a line of text are positioned in relation the provided `position`.
* `line_spacing` (number) - Value to multiply line height with. Set to a value lower than 1.0 to reduce space between lines and a value higher than 1.0 to increase space between lines. Defaults to 1.0.

The `fonts` table should have the following format:

name (string) = {
regular (string) = font (hash),
italic (string) = font (hash),
bold (string) = font (hash),
bold_italic (string) = font (hash),
},
name (string) = {
...
},

Where `name` is the name specified in a `<font>` tag and the `font` for each of `regular`, `italic`, `bold` and `bold_italic` should correspond to the name of a font added to a .gui scene.

The `layers` table should map fonts, textures and spine scenes to layer names. It should have the following format:

fonts = {
font (hash) = layer (hash),
...
font (hash) = layer (hash),
},
images = {
texture (hash) = layer (hash),
...
texture (hash) = layer (hash),
},
spinescenes = {
spinescene (hash) = layer (hash),
...
spinescene (hash) = layer (hash),
}

Where `layer` is the name of a layer in the .gui scene, `font` is the value returned from a call to `gui.get_font(node)`, `texture` is the value returned from a call to `gui.get_texture(node)` and finally `spinescene` is the value returned from a call to `gui.get_spine_scene(node)`.

**RETURNS**
* `words` (table) - A table with all the words that the text has been broken up into. Each word is represented by a table with keys such as `node`, `tags`, `text` etc
* `metrics` (table) - A table with text metrics.
Expand Down
21 changes: 21 additions & 0 deletions example/example.gui
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,27 @@ nodes {
template_node_child: false
size_mode: SIZE_MODE_MANUAL
}
layers {
name: "roboto-regular"
}
layers {
name: "roboto-bold"
}
layers {
name: "roboto-italic"
}
layers {
name: "roboto-bold_italic"
}
layers {
name: "nanum-regular"
}
layers {
name: "image-smileys"
}
layers {
name: "spine-spineboy"
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512
Expand Down
15 changes: 15 additions & 0 deletions example/example.gui_script
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ local function create_complex_example()
regular = hash("Nanum-Regular"),
},
},
layers = {
fonts = {
[hash("Roboto-Regular")] = hash("roboto-regular"),
[hash("Roboto-Italic")] = hash("roboto-italic"),
[hash("Roboto-Bold")] = hash("roboto-bold"),
[hash("Roboto-BoldItalic")] = hash("roboto-bold_italic"),
[hash("Nanum-Regular")] = hash("nanum-regular"),
},
images = {
[hash("smileys")] = hash("image-smileys"),
},
spinemodels = {
[hash("spineboy")] = hash("spine-spineboy"),
},
},
width = 400,
position = vmath.vector3(0, 0, 0),
parent = gui.get_node("bg"),
Expand Down
25 changes: 24 additions & 1 deletion richtext/richtext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ local function get_font(word, fonts)
end


local function get_layer(word, layers)
local node = word.node
if word.image then
return layers.images[gui.get_texture(node)]
elseif word.spine then
return layers.spinescenes[gui.get_spine_scene(node)]
end
return layers.fonts[gui.get_font(node)]
end


-- position all words according to the line alignment and line width
-- the list of words will be empty after this function is called
local function position_words(words, line_width, line_height, position, settings)
Expand Down Expand Up @@ -188,6 +199,10 @@ function M.create(text, font, settings)
settings.align = settings.align or M.ALIGN_LEFT
settings.fonts = settings.fonts or {}
settings.fonts[font] = settings.fonts[font] or { regular = hash(font) }
settings.layers = settings.layers or {}
settings.layers.fonts = settings.layers.fonts or {}
settings.layers.images = settings.layers.images or {}
settings.layers.spinescenes = settings.layers.spinescenes or {}
settings.color = settings.color or V3_ONE
settings.position = settings.position or V3_ZERO
settings.line_spacing = settings.line_spacing or 1
Expand Down Expand Up @@ -215,10 +230,16 @@ function M.create(text, font, settings)

-- get font to use based on word tags
local font = get_font(word, settings.fonts)

-- create node and get metrics
word.node, word.metrics = create_node(word, settings.parent, font)

-- assign layer
local layer = get_layer(word, settings.layers)
if layer then
gui.set_layer(word.node, layer)
end

-- does the word fit on the line or does it overflow?
local overflow = (settings.width and (line_width + word.metrics.width) > settings.width)
if overflow then
Expand Down Expand Up @@ -333,13 +354,15 @@ function M.characters(word)
-- split word into characters
local parent = gui.get_parent(word.node)
local font = gui.get_font(word.node)
local layer = gui.get_layer(word.node)
local chars = {}
local chars_width = 0
for i=1,#word.text do
local char = deepcopy(word)
chars[#chars + 1] = char
char.text = word.text:sub(i,i)
char.node, char.metrics = create_node(char, parent, font)
gui.set_layer(char.node, layer)
chars_width = chars_width + char.metrics.width
end

Expand Down

0 comments on commit 85b26a5

Please sign in to comment.