aboutsummaryrefslogtreecommitdiff
path: root/font_api
diff options
context:
space:
mode:
authorPierre-Yves Rollo <dev@pyrollo.com>2018-07-08 20:36:34 +0200
committerPierre-Yves Rollo <dev@pyrollo.com>2018-07-08 20:36:34 +0200
commitc6cad702bcea7f7836153b9b7f6ad847e3bd605e (patch)
tree3c571f40c56ad1bd97f306c02a25eee1bc0c2d33 /font_api
parent23bcd7019986c5a943baad30cd73034f88079394 (diff)
downloaddisplay_modpack-c6cad702bcea7f7836153b9b7f6ad847e3bd605e.tar.gz
display_modpack-c6cad702bcea7f7836153b9b7f6ad847e3bd605e.tar.bz2
display_modpack-c6cad702bcea7f7836153b9b7f6ad847e3bd605e.zip
Creation of Font class and code update accordingly
Diffstat (limited to 'font_api')
-rw-r--r--font_api/API.md131
-rw-r--r--font_api/font.lua270
-rw-r--r--font_api/init.lua295
-rw-r--r--font_api/registry.lua151
-rwxr-xr-xfont_api/tools/make_font_lua.sh19
-rwxr-xr-xfont_api/tools/make_font_textures.sh2
6 files changed, 528 insertions, 340 deletions
diff --git a/font_api/API.md b/font_api/API.md
index a4aee6d..4c711be 100644
--- a/font_api/API.md
+++ b/font_api/API.md
@@ -4,65 +4,52 @@ This document describes Font Lib API. Font Lib creates textures for font display
## Settings
### default_font
Name of the font to be used when no font is given. The font should be registered.
+
If no default\_font given or if default\_font given but not registered, the first registered font will be used as default.
## Provided methods
-### get\_text\_size
-**font\_lib.get\_text\_size(font\_name, text)**
-Computes size for a given font and text
+### font_api.get_default_font_name()
+Returns de default font name.
-**font\_name**: Font name of registered font to use
-**text**: Text to be rendered
-**Returns**: rendered text width, height
+###font_api.register_font(font_name, font_def)
+Register a new font.
+**font_name**: Name of the font to register. If registering different sizes of the same font, add size in the font name (e.g. times_10, times_12...).
+**font_def**: Font definition table (see **Font definition table** below).
-### make\_line\_texture
-**font\_lib.make\_line\_texture(font\_name, text, width, x, y)**
+###font_api.on_display_update(pos, objref)
+Standard on_display_update entity callback.
-Builds texture part for a text line
+**pos**: Node position
-**font\_name**: Font name of registered font to use
-**text**: Text to be rendered
-**texturew**: Width of the texture (extra text is not rendered)
-**x**: Starting x position in texture
-**y**: Vertical position of the line in texture
-**Returns**: Texture string
+**objref**: Object reference of entity
-### make\_multiline\_texture
-**font\_lib.make\_multiline\_texture(font\_name, text, width, height, maxlines, halign, valign, color)**
+Node should have a corresponding display_entity with size, resolution and maxlines fields and optionally halign, valign and color fields.
-Builds texture for a multiline colored text
+###Font definition table
+Font definition table used by **font_api.register_font** and **font\_api.Font:new** may/can contain following elements:
-**font\_name**: Font name of registered font to use
-**text**: Text to be rendered
-**texturew**: Width of the texture (extra text will be truncated)
-**textureh**: Height of the texture
-**maxlines**: Maximum number of lines
-**halign**: Horizontal text align ("left", "right" or "center") (optional)
-**valign**: Vertical text align ("top", "bottom" or "center") (optional)
-**color**: Color of the text (optional)
-**Returns**: Texture string
+* **height** (required): Font height in pixels (all font textures should have the same height) .
+* **widths** (required): Array of character widths in pixels, indexed by UTF codepoints.
+* **margintop** (optional): Margin (in texture pixels) added on top of each char texture.
+* **marginbottom** (optional): Margin (in texture pixels) added at bottom of each char texture.
+* **linespacing** (optional): Spacing (in texture pixels) between each lines.
-### register\_font
-**font\_lib.register_font(font\_name, height, widths)**
+**margintop**, **marginbottom** and **linespacing** can be negative numbers (default 0) and are to be used to adjust various font styles to each other.
-Registers a new font in font_api.
+Font must have a char 0 which will be used to display any unknown char.
-**font\_name**: Name of the font to register (this name will be used to address the font later)
-If registering different sizes of the same font, add size in the font name (e.g. times\_10, times\_12...).
-**height**: Font height in pixels (all font textures should have the same height)
-**widths** : Array of character widths in pixels, indexed by UTF codepoints
+All textures corresponding to the indexes in widths array should be present in textures directory with a name matching the pattern :
-Font must have a char 0 which will be used to display any unknown char.
+> font\_**{font_name}**_**{utf_code}**.png
-All textures corresponding to the indexes in **widths** array should be present in textures directory with a name matching the pattern :
+**{font\_name}**: Name of the font as given in the first argument
-**font\_<font\_name>_<utf\_code>.png**
+**{utf\_code}**: UTF code of the char in 4 hexadecimal digits
-**<font\_name>**: Name of the font as given in the first argument
-**<utf\_code>**: UTF code of the char in 4 hexadecimal digits
+Example : font_courrier_0041.png is for the "A" char in the "courrier" font.
-To ease that declaration, a shell is provided to build a <font\_name>.lua file from the texture files (see provided tools).
+To ease that declaration (specially to build the **widths** array), a shell is provided to build a {font\_name}.lua file from the texture files (see provided tools).
## Provided tools
@@ -78,23 +65,23 @@ This script works much better with pixels font, providing the correct height. Th
__Syntax__
-**make\_font\_texture.sh <fontfile> <fontname> <fontsize>**
+**make\_font\_texture.sh {fontfile} {fontname} {fontsize}**
-**<fontfile>**: A TTF font file to use to create textures.
-**<fontname>**: The font name to be used in font_api (should be simple, with no spaces).
-**<fontsize>**: Font height to be rendered.
+**{fontfile}**: A TTF font file to use to create textures.
+**{fontname}**: The font name to be used in font_api (should be simple, with no spaces).
+**{fontsize}**: Font height to be rendered.
### make_font_lua.sh
-This script analyses textures in textures directory and creates a font\_<font\_name>.lua files with a call to register_font with images information. Launch it from your future font mod directory.
+This script analyses textures in textures directory and creates a font\_{font\_name}.lua files with a call to register_font with images information. Launch it from your future font mod directory.
-Once the font\_<font\_name>.lua created, it can be included by a init.lua file or directly renamed to init.lua if you are creating a simple font mod.
+Once the font\_{font\_name}.lua created, it can be included by a init.lua file or directly renamed to init.lua if you are creating a simple font mod.
__Syntax__
-**make\_font_lua.sh <fontname>**
+**make\_font_lua.sh {fontname}**
-**<fontname>**: The font name to be used in font_api (same as given to make\_font\_texture.sh)
+**{fontname}**: The font name to be used in font_api (same as given to make\_font\_texture.sh)
### An exemple generating a font mod
@@ -104,7 +91,55 @@ __Syntax__
/<path_to_font_api>/tools/make_font_lua.sh myfont
mv font_myfont.lua init.lua
+## Font class
+A font usable with font API. This class is supposed to be for internal use but who knows.
+
+### font\_api.Font:new(def)
+Create a new font object.
+
+**def** is a table containing font definition. See **Font definition table** above.
+
+### font:get_char_width(char)
+Returns the width of char **char** in texture pixels.
+
+**char**: Unicode codepoint of char.
+
+### font:get_height(nb_of_lines)
+Returns line(s) height. Takes care of top and bottom margins and line spacing.
+
+**nb_of_lines**: Number of lines in the text.
+
+### font:get_width(line)
+
+Returns the width of a text line. Beware, if line contains any new line char, they are ignored.
+
+**line**: Line of text which the width will be computed.
+
+### font:make_line_texture(line, texturew, x, y)
+Create a texture for a text line.
+
+**line**: Line of text to be rendered in texture.
+
+**texturew**: Width of the texture (extra text is not rendered).
+
+**x**: Starting x position in texture.
+
+**y**: Vertical position of the line in texture.
+
+### font:make_text_texture(text, texturew, textureh, maxlines, halign, valign, color)
+Builds texture for a multiline colored text.
+
+**text**: Text to be rendered.
+
+**texturew**: Width of the texture (extra text will be truncated).
+
+**textureh**: Height of the texture.
+
+**maxlines**: Maximum number of lines.
+**halign**: Horizontal text align ("left"/"center"/"right") (optional).
+**valign**: Vertical text align ("top"/"center"/"bottom") (optional).
+**color**: Color of the text (optional).
diff --git a/font_api/font.lua b/font_api/font.lua
new file mode 100644
index 0000000..60563d8
--- /dev/null
+++ b/font_api/font.lua
@@ -0,0 +1,270 @@
+--[[
+ font_api mod for Minetest - Library to add font display capability
+ to display_api mod.
+ (c) Pierre-Yves Rollo
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+--]]
+
+
+--[[
+ Margins, spacings, can be negative numbers
+]]--
+
+-- Local functions
+------------------
+
+-- Table deep copy
+
+local function deep_copy(input)
+ local output = {}
+ local key, value
+ for key, value in pairs(input) do
+ if type(value) == 'table' then
+ output[key] = deep_copy(value)
+ else
+ output[key] = value
+ end
+ end
+ return output
+end
+
+-- Returns next char, managing ascii and unicode plane 0 (0000-FFFF).
+
+local function get_next_char(text, pos)
+
+ local msb = text:byte(pos)
+ -- 1 byte char, ascii equivalent codepoints
+ if msb < 0x80 then
+ return msb, pos + 1
+ end
+
+ -- 4 bytes char not managed (Only 16 bits codepoints are managed)
+ if msb >= 0xF0 then
+ return 0, pos + 4
+ end
+
+ -- 3 bytes char
+ if msb >= 0xE0 then
+ return (msb - 0xE0) * 0x1000
+ + text:byte(pos + 1) % 0x40 * 0x40
+ + text:byte(pos + 2) % 0x40,
+ pos + 3
+ end
+
+ -- 2 bytes char (little endian)
+ if msb >= 0xC2 then
+ return (msb - 0xC2) * 0x40 + text:byte(pos + 1),
+ pos + 2
+ end
+
+ -- Not an UTF char
+ return 0, pos + 1
+end
+
+-- Split multiline text into array of lines, with <maxlines> maximum lines.
+
+local function split_lines(text, maxlines)
+ local splits = text:split("\n")
+ if maxlines then
+ local lines = {}
+ for num = 1,maxlines do
+ lines[num] = splits[num]
+ end
+ return lines
+ else
+ return splits
+ end
+end
+
+--------------------------------------------------------------------------------
+--- Font class
+
+font_api.Font = {}
+
+function font_api.Font:new(def)
+
+ if type(def) ~= "table" then
+ minetest.log("error", "Font definition must be a table.")
+ return nil
+ end
+
+ if def.height == nil or def.height <= 0 then
+ minetest.log("error", "Font definition must have a positive height.")
+ return nil
+ end
+
+ if type(def.widths) ~= "table" then
+ minetest.log("error", "Font definition must have a widths array.")
+ return nil
+ end
+
+ if def.widths[0] == nil then
+ minetest.log("error",
+ "Font must have a char with codepoint 0 (=unknown char).")
+ return nil
+ end
+
+ local font = deep_copy(def)
+ setmetatable(font, self)
+ self.__index = self
+ return font
+end
+
+--- Returns the width of a given char
+-- @param char : codepoint of the char
+-- @return Char width
+
+function font_api.Font:get_char_width(char)
+ -- Replace chars with no texture by the NULL(0) char
+ if self.widths[char] ~= nil then
+ return self.widths[char]
+ else
+ return self.widths[0]
+ end
+end
+
+--- Text height for multiline text including margins and line spacing
+-- @param nb_of_lines : number of text lines (default 1)
+-- @return Text height
+
+function font_api.Font:get_height(nb_of_lines)
+ if nb_of_lines == nil then nb_of_lines = 1 end
+
+ if nb_of_lines > 0 then
+ return
+ (
+ (self.height or 0) +
+ (self.margin_top or 0) +
+ (self.margin_bottom or 0)
+ ) * nb_of_lines +
+ (self.line_spacing or 0) * (nb_of_lines -1)
+ else
+ return nb_of_lines == 0 and 0 or nil
+ end
+end
+
+--- Computes text width for a given text (ignores new lines)
+-- @param line Line of text which the width will be computed.
+-- @return Text width
+
+function font_api.Font:get_width(line)
+
+ local char
+ local width = 0
+ local pos = 1
+
+ -- TODO: Use iterator
+ while pos <= #line do
+ char, pos = get_next_char(line, pos)
+ width = width + self:get_char_width(char)
+ end
+
+ return width
+end
+
+--- Builds texture part for a text line
+-- @param line Text line to be rendered
+-- @param texturew Width of the texture (extra text is not rendered)
+-- @param x Starting x position in texture
+-- @param y Vertical position of the line in texture
+-- @return Texture string
+
+function font_api.Font:make_line_texture(line, texturew, x, y)
+ local texture = ""
+ local char
+ local pos = 1
+
+ -- TODO: Use iterator
+ while pos <= #text do
+ char, pos = get_next_char(line, pos)
+
+ -- Replace chars with no texture by the NULL(0) char
+ if self.widths[char] == nil
+or char == 88 --DEBUG
+ then
+ print(string.format("["..font_api.name
+ .."] Missing char %d (%04x)",char,char))
+ char = 0
+ end
+
+ -- Add image only if it is visible (at least partly)
+ if x + self.widths[char] >= 0 and x <= texturew then
+ texture = texture..
+ string.format(":%d,%d=font_%s_%04x.png",
+ x, y, self.name, char)
+ end
+ x = x + self.widths[char]
+ end
+
+ return texture
+end
+
+--- Builds texture for a multiline colored text
+-- @param text Text to be rendered
+-- @param texturew Width of the texture (extra text will be truncated)
+-- @param textureh Height of the texture
+-- @param maxlines Maximum number of lines
+-- @param halign Horizontal text align ("left"/"center"/"right") (optional)
+-- @param valign Vertical text align ("top"/"center"/"bottom") (optional)
+-- @param color Color of the text (optional)
+-- @return Texture string
+
+function font_api.Font:make_text_texture(text, texturew, textureh, maxlines,
+ halign, valign, color)
+ local texture = ""
+ local lines = {}
+ local textheight = 0
+ local y
+
+ -- Split text into lines (limited to maxlines fist lines)
+ for num, line in pairs(split_lines(text, maxlines)) do
+ lines[num] = { text = line, width = self:get_width(line) }
+ end
+
+ textheight = self:get_height(#lines)
+
+ if #lines then
+ if valign == "top" then
+ y = 0
+ elseif valign == "bottom" then
+ y = textureh - textheight
+ else
+ y = (textureh - textheight) / 2
+ end
+ end
+
+ for _, line in pairs(lines) do
+ if halign == "left" then
+ texture = texture..
+ self:make_line_texture(line.text, texturew,
+ 0, y)
+ elseif halign == "right" then
+ texture = texture..
+ self:make_line_texture(line.text, texturew,
+ texturew - line.width, y)
+ else
+ texture = texture..
+ self:make_line_texture(line.text, texturew,
+ (texturew - line.width) / 2, y)
+ end
+
+ y = y + self:get_height() + (self.line_spacing or 0)
+ end
+
+ texture = string.format("[combine:%dx%d", texturew, textureh)..texture
+ if color then texture = texture.."^[colorize:"..color end
+ return texture
+end
+
diff --git a/font_api/init.lua b/font_api/init.lua
index f407f8b..2dc38ec 100644
--- a/font_api/init.lua
+++ b/font_api/init.lua
@@ -23,293 +23,12 @@
font_api = {}
font_api.name = minetest.get_current_modname()
font_api.path = minetest.get_modpath(font_api.name)
-font_api.registered_fonts = {}
--- Local variables
-------------------
+-- Inclusions
+-------------
-local default_font = false
-
--- Local functions
-------------------
-
--- Split multiline text into array of lines, with <maxlines> maximum lines.
-
-local function split_lines(text, maxlines)
- local splits = text:split("\n")
- if maxlines then
- local lines = {}
- for num = 1,maxlines do
- lines[num] = splits[num]
- end
- return lines
- else
- return splits
- end
-end
-
--- Gets a default (settings or fist font)
-
-local function get_default_font()
- -- First call
- if default_font == false then
- default_font = nil
-
- -- First, try with settings
- local settings_font = minetest.settings:get("default_font")
-
- if settings_font ~= nil and settings_font ~= "" then
- default_font = font_api.registered_fonts[settings_font]
-
- if default_font == nil then
- minetest.log("warning", "Default font in settings (\""..
- settings_font.."\") is not registered.")
- end
- end
-
- -- If failed, choose first font
- if default_font == nil then
- for _, font in pairs(font_api.registered_fonts) do
- default_font = font
- break
- end
- end
-
- -- Error, no font registered
- if default_font == nil then
- minetest.log("error",
- "No font registred, unable to choose a default font.")
- end
- end
-
- return default_font
-end
-
--- Returns font properties to be used according to font_name
-
-local function get_font(font_name)
- local font = font_api.registered_fonts[font_name]
-
- if font == nil then
- local message
-
- if font_name == nil then
- message = "No font given"
- else
- message = "Font \""..font_name.."\" unregistered"
- end
-
- font = get_default_font()
-
- if font ~= nil then
- minetest.log("info", message..", using font \""..font.name.."\".")
- end
- end
-
- return font
-end
-
--- Returns next char, managing ascii and unicode plane 0 (0000-FFFF).
-
-local function get_next_char(text, pos)
-
- local msb = text:byte(pos)
- -- 1 byte char, ascii equivalent codepoints
- if msb < 0x80 then
- return msb, pos + 1
- end
-
- -- 4 bytes char not managed (Only 16 bits codepoints are managed)
- if msb >= 0xF0 then
- return 0, pos + 4
- end
-
- -- 3 bytes char
- if msb >= 0xE0 then
- return (msb - 0xE0) * 0x1000
- + text:byte(pos + 1) % 0x40 * 0x40
- + text:byte(pos + 2) % 0x40,
- pos + 3
- end
-
- -- 2 bytes char (little endian)
- if msb >= 0xC2 then
- return (msb - 0xC2) * 0x40 + text:byte(pos + 1),
- pos + 2
- end
-
- -- Not an UTF char
- return 0, pos + 1
-end
-
--- API functions
-----------------
-
--- Computes text size for a given font and text (ignores new lines)
--- @param font_name Font to be used
--- @param text Text to be rendered
--- @return Rendered text (width, height)
-
-function font_api.get_text_size(font_name, text)
- local char
- local width = 0
- local pos = 1
- local font = get_font(font_name)
-
- if font == nil then
- return 0, 0
- else
- while pos <= #text do
- char, pos = get_next_char(text, pos)
- -- Replace chars with no texture by the NULL(0) char
- if font.widths[char] ~= nil then
- width = width + font.widths[char]
- else
- width = width + font.widths[0]
- end
- end
- end
-
- return width, font.height
-end
-
---- Builds texture part for a text line
--- @param font_name Font to be used
--- @param text Text to be rendered
--- @param width Width of the texture (extra text is not rendered)
--- @param x Starting x position in texture
--- @param y Vertical position of the line in texture
--- @return Texture string
-
-function font_api.make_line_texture(font_name, text, width, x, y)
- local texture = ""
- local char
- local pos = 1
- local font = get_font(font_name)
-
- if font ~= nil then
- while pos <= #text do
- char, pos = get_next_char(text, pos)
-
- -- Replace chars with no texture by the NULL(0) char
- if font.widths[char] == nil then
- print(string.format("["..font_api.name
- .."] Missing char %d (%04x)",char,char))
- char = 0
- end
-
- -- Add image only if it is visible (at least partly)
- if x + font.widths[char] >= 0 and x <= width then
- texture = texture..
- string.format(":%d,%d=font_%s_%04x.png",
- x, y, font.name, char)
- end
- x = x + font.widths[char]
- end
- end
-
- return texture
-end
-
---- Builds texture for a multiline colored text
--- @param font_name Font to be used
--- @param text Text to be rendered
--- @param texturew Width of the texture (extra text will be truncated)
--- @param textureh Height of the texture
--- @param maxlines Maximum number of lines
--- @param halign Horizontal text align ("left"/"center"/"right") (optional)
--- @param valign Vertical text align ("top"/"center"/"bottom") (optional)
--- @param color Color of the text (optional)
--- @return Texture string
-
-function font_api.make_multiline_texture(font_name, text, width, height,
- maxlines, halign, valign, color)
- local texture = ""
- local lines = {}
- local textheight = 0
- local y, w, h
-
- for num, line in pairs(split_lines(text, maxlines)) do
- w, h = font_api.get_text_size(font_name, line)
- lines[num] = { text = line, width = w, height = h, }
- textheight = textheight + h
- end
-
- if #lines then
- if valign == "top" then
- y = 0
- elseif valign == "bottom" then
- y = height - textheight
- else
- y = (height - textheight) / 2
- end
- end
-
- for _, line in pairs(lines) do
- if halign == "left" then
- texture = texture..
- font_api.make_line_texture(font_name, line.text, width,
- 0, y)
- elseif halign == "right" then
- texture = texture..
- font_api.make_line_texture(font_name, line.text, width,
- width - line.width, y)
- else
- texture = texture..
- font_api.make_line_texture(font_name, line.text, width,
- (width - line.width) / 2, y)
- end
- y = y + line.height
- end
-
- texture = string.format("[combine:%dx%d", width, height)..texture
- if color then texture = texture.."^[colorize:"..color end
- return texture
-end
-
---- Register a new font
--- Textures corresponding to the font should be named after following patern :
--- font_<name>_<code>.png
--- <name> : name of the font
--- <code> : 4 digit hexadecimal unicode of the char
--- @param font_name Name of the font to register
--- If registering different sizes of the same font, add size in the font name
--- (e.g. times_10, times_12...).
--- @param height Font height in pixels
--- @param widths Array of character widths in pixels, indexed by UTF codepoints
-
-function font_api.register_font(font_name, height, widths)
-
- if font_api.registered_fonts[font_name] ~= nil then
- minetest.log("error", "Font \""..font_name.."\" already registered.")
- return
- end
-
- if height == nil or height <= 0 then
- minetest.log("error", "Font \""..font_name..
- "\" must have a positive height.")
- return
- end
-
- if type(widths) ~= "table" then
- minetest.log("error", "Font \""..font_name..
- "\" must have a widths array.")
- return
- end
-
- if widths[0] == nil then
- minetest.log("error", "Font \""..font_name..
- "\" must have a char with codepoint 0 (=unknown char).")
- return
- end
-
- font_api.registered_fonts[font_name] =
- { name = font_name, height = height, widths = widths }
-
- -- Force to choose again default font
- -- (allows use of fonts registered after start)
- default_font = false
-end
+dofile(font_api.path.."/font.lua")
+dofile(font_api.path.."/registry.lua")
--- Standard on_display_update entity callback.
-- Node should have a corresponding display_entity with size, resolution and
@@ -325,11 +44,9 @@ function font_api.on_display_update(pos, objref)
if entity and ndef.display_entities[entity.name] then
local def = ndef.display_entities[entity.name]
- local font = get_font(def.font_name)
-
+ local font = font_api.get_font(meta:get_string("font") or def.font_name)
objref:set_properties({
- textures={font_api.make_multiline_texture(
- def.font_name, text,
+ textures={font:make_text_texture(text,
def.size.x * def.resolution.x * font.height,
def.size.y * def.resolution.y * font.height,
def.maxlines, def.halign, def.valign, def.color)},
diff --git a/font_api/registry.lua b/font_api/registry.lua
new file mode 100644
index 0000000..62fbb52
--- /dev/null
+++ b/font_api/registry.lua
@@ -0,0 +1,151 @@
+--[[
+ font_api mod for Minetest - Library to add font display capability
+ to display_api mod.
+ (c) Pierre-Yves Rollo
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+--]]
+
+-- Global variables
+-------------------
+
+font_api.registered_fonts = {}
+font_api.registered_fonts_number = 0
+
+-- Local variables
+------------------
+
+local default_font = false
+
+-- Local functions
+------------------
+
+-- Gets a default (settings or fist font)
+local function get_default_font()
+ -- First call
+ if default_font == false then
+ default_font = nil
+
+ -- First, try with settings
+ local settings_font = minetest.settings:get("default_font")
+
+ if settings_font ~= nil and settings_font ~= "" then
+ default_font = font_api.registered_fonts[settings_font]
+
+ if default_font == nil then
+ minetest.log("warning", "Default font in settings (\""..
+ settings_font.."\") is not registered.")
+ end
+ end
+
+ -- If failed, choose first font
+ if default_font == nil then
+ for _, font in pairs(font_api.registered_fonts) do
+ default_font = font
+ break
+ end
+ end
+
+ -- Error, no font registered
+ if default_font == nil then
+ minetest.log("error",
+ "No font registred, unable to choose a default font.")
+ end
+ end
+
+ return default_font
+end
+
+--- Returns font object to be used according to font_name
+-- @param font_name: Name of the font
+-- @return Font object if font found (or default font)
+
+function font_api.get_font(font_name)
+ local font = font_api.registered_fonts[font_name]
+
+ if font == nil then
+ local message
+
+ if font_name == nil then
+ message = "No font given"
+ else
+ message = "Font \""..font_name.."\" unregistered"
+ end
+
+ font = get_default_font()
+
+ if font ~= nil then
+ minetest.log("info", message..", using font \""..font.name.."\".")
+ end
+ end
+
+ return font
+end
+
+-- API functions
+----------------
+
+--- Returns de default font name
+-- @return Default font name
+
+function font_api.get_default_font_name()
+ return get_default_font().name
+end
+
+--- Register a new font
+-- Textures corresponding to the font should be named after following patern :
+-- font_<name>_<code>.png
+-- <name> : name of the font
+-- <code> : 4 digit hexadecimal unicode of the char
+-- @param font_name Name of the font to register
+-- If registering different sizes of the same font, add size in the font name
+-- (e.g. times_10, times_12...).
+-- @param def font definition. A associative array with following keys :
+-- @key height (mandatory) Height in pixels of all font textures
+-- @key widths (mandatory) Array of character widths in pixels, indexed by
+-- UTF codepoints
+-- @key margintop (optional) Margin (in texture pixels) added on top of each
+-- char texture.
+-- @key marginbottom (optional) dded at bottom of each char texture.
+-- @key linespacing (optional) Spacing (in texture pixels) between each lines.
+-- margintop, marginbottom and linespacing can be negative numbers (default 0)
+-- and are to be used to adjust various font styles to each other.
+
+-- TODO: Add something to remove common accent if not defined in font
+
+function font_api.register_font(font_name, font_def)
+
+ if font_api.registered_fonts[font_name] ~= nil then
+ minetest.log("error", "Font \""..font_name.."\" already registered.")
+ return
+ end
+
+ local font = font_api.Font:new(font_def)
+
+ if font == nil then
+ minetest.log("error", "Unable to register font \""..font_name.."\".")
+ return
+ end
+
+ font.name = font_name
+ font_api.registered_fonts[font_name] = font
+ font_api.registered_fonts_number = font_api.registered_fonts_number + 1
+
+ -- Force to choose again default font
+ -- (allows use of fonts registered after start)
+ default_font = false
+
+ minetest.log("action", "New font registered in font_api: "..font_name..".")
+end
+
diff --git a/font_api/tools/make_font_lua.sh b/font_api/tools/make_font_lua.sh
index ae24001..e858360 100755
--- a/font_api/tools/make_font_lua.sh
+++ b/font_api/tools/make_font_lua.sh
@@ -3,6 +3,17 @@
scriptname=$(basename $0)
identify="identify"
+usage() {
+ echo "Usage: $0 fontname"
+ echo "fontname: The name of the font. Must correspond to existing texture/font_<fontname>_????.png files"
+}
+
+if [ $# -ne 1 ]
+then
+ usage
+ exit 1
+fi
+
font_name=$1
for f in textures/font_${font_name}_????.png
@@ -41,8 +52,12 @@ $luafile generated by $scriptname $(LANG=en_US date)
font_api.register_font(
'$font_name',
- $font_height,
- { $font_widths }
+ {
+ height = $font_height,
+ widths = {
+ $font_widths
+ },
+ }
);
" > font_$font_name.lua
diff --git a/font_api/tools/make_font_textures.sh b/font_api/tools/make_font_textures.sh
index 6f4959d..4a3191c 100755
--- a/font_api/tools/make_font_textures.sh
+++ b/font_api/tools/make_font_textures.sh
@@ -67,7 +67,7 @@ generate() {
mkdir textures
# Reads all available code points in the font.
-codepoints=$(ttx -o - $fontfile | grep "<map code=" | cut -d \" -f 2)
+codepoints=$(ttx -o - "$fontfile" | grep "<map code=" | cut -d \" -f 2)
# Mandatory chars
generate 0020 007f