Version 1.0

This commit is contained in:
Pierre-Yves Rollo 2018-01-13 12:38:55 +01:00
parent 5cf61f9e23
commit a71ae8e013
171 changed files with 254 additions and 160 deletions

@ -15,6 +15,20 @@ For more information, see the [forum topic](https://forum.minetest.net/viewtopic
## Changelog
### 2018-01-13 (Version 1.0)
- Switch to Epilepsy font by KREATIVE SOFTWARE
- Add settings "default_font"
- Add horizontal alignment
- Add tool for creating font textures from .ttf font files
- Fix UTF 8 to Unicode decoding
- Updated forum thread link in README.md
### 2017-12-19
This change is a preparation to merge Andrzej Pieńkowski fork (apienk) : new font and support of UTF chars.

@ -10,5 +10,5 @@ This library's purpose is to ease creation of nodes with one or more displays on
**API**: See [API.md](https://github.com/pyrollo/display_modpack/blob/master/display_lib/API.md) document please.
For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?f=11&t=13563) at the Minetest forums.
For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums.

@ -1,6 +1,11 @@
# Font Lib API
This document describes Font Lib API. Font Lib creates textures for font display on entities.
## 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)**
@ -8,9 +13,7 @@ This document describes Font Lib API. Font Lib creates textures for font display
Computes size for a given font and text
**font\_name**: Font name of registered font to use
**text**: Text to be rendered
**Returns**: rendered text width, height
### make\_line\_texture
@ -19,36 +22,25 @@ Computes size for a given font and text
Builds texture part for a text line
**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
### make\_multiline\_texture
**font\_lib.make\_multiline\_texture(font\_name, text, width, height, maxlines, valign, color)**
**font\_lib.make\_multiline\_texture(font\_name, text, width, height, maxlines, halign, valign, color)**
Builds texture for a multiline colored text
**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
**valign**: Vertical text align ("top", "bottom" or "center")
**color**: Color of the text
**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
### register\_font
@ -57,34 +49,62 @@ Builds texture for a multiline colored text
Registers a new font in font_lib.
**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
**height**: Height of the font in pixels (all font textures should have the same height)
**widths** : An array containing the width of each font texture, indexed by its UTF code
Font must have a char 0 which will be used to display any unknown char.
All textures corresponding to the indexes in **widths** array should be present in textures directory with a name matching the pattern :
**font\_<font\_name>_<utf\_code>.png**
<font\_name>: Name of the font as given in the first argument
<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
To ease that declaration, a shell is provided to build a <font\_name>.lua file from the texture files (see provided tools).
### set\_fallback\_font
**function font\_lib.set\_fallback\_font(font\_name)**
Defines the fallback font to be used instead of given font if not registered.
**font\_name**: Name of the font to be used as fallback font (has to be registered)
## Provided tools
Still in early stage of development, these tools are helpers to create font mods.
### make_font_texture.sh
This scripts takes a .ttf file as input and create one .png file per char, that can be used as font texture. Launch it from your future font mod directory.
__Advice__
This script works much better with pixels font, providing the correct height. There is no antialiasing at all, vector fonts and bad heights gives very ugly results.
__Syntax__
**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_lib (should be simple, with no spaces).
**<fontsize>**: Font height to be rendered.
### make_font_lua.sh
Still in early stage of development.
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.
__Syntax__
**make\_font_lua.sh <fontname>**
**<fontname>**: The font name to be used in font_lib (same as given to make\_font\_texture.sh)
### An exemple generating a font mod
mkdir font_myfont
cd font_myfont
/<path_to_font_lib>/tools/make_font_texture.sh myfont.ttf myfont 12
/<path_to_font_lib>/tools/make_font_lua.sh myfont
mv font_myfont.lua init.lua
This script analyses textures in textures directory and creates a font\_<font\_name>.lua files with a call to register_font with images information.

@ -1,12 +0,0 @@
--[[
generated by tools/make_font_lua.sh Thu Dec 21 21:45:53 CET 2017
--]]
font_lib.register_font(
'default',
12,
{ [0]=6, [32]=4, [33]=3, [34]=4, [35]=7, [36]=6, [37]=8, [38]=8, [39]=3, [40]=4, [41]=4, [42]=4, [43]=7, [44]=3, [45]=5, [46]=3, [47]=5, [48]=6, [49]=4, [50]=6, [51]=6, [52]=7, [53]=6, [54]=6, [55]=6, [56]=6, [57]=6, [58]=3, [59]=3, [60]=5, [61]=6, [62]=5, [63]=6, [64]=11, [65]=8, [66]=7, [67]=8, [68]=7, [69]=6, [70]=6, [71]=8, [72]=7, [73]=3, [74]=6, [75]=8, [76]=6, [77]=10, [78]=8, [79]=8, [80]=7, [81]=8, [82]=7, [83]=7, [84]=7, [85]=7, [86]=8, [87]=11, [88]=8, [89]=9, [90]=7, [91]=4, [92]=5, [93]=4, [94]=5, [95]=7, [96]=3, [97]=7, [98]=6, [99]=5, [100]=6, [101]=6, [102]=5, [103]=6, [104]=6, [105]=3, [106]=3, [107]=7, [108]=3, [109]=9, [110]=6, [111]=6, [112]=6, [113]=6, [114]=5, [115]=6, [116]=4, [117]=6, [118]=6, [119]=8, [120]=7, [121]=6, [122]=6, [123]=5, [124]=3, [125]=5, [126]=6, [138]=6, [141]=3, [161]=3, [177]=6, [191]=6, [192]=8, [193]=8, [194]=8, [195]=8, [196]=8, [197]=8, [198]=10, [199]=8, [200]=6, [201]=6, [202]=6, [203]=6, [204]=3, [205]=3, [206]=3, [207]=3, [208]=8, [209]=8, [210]=8, [211]=8, [212]=8, [213]=8, [214]=8, [215]=6, [216]=8, [217]=7, [218]=7, [219]=7, [220]=7, [221]=9, [224]=7, [225]=7, [226]=7, [227]=7, [228]=7, [229]=7, [230]=9, [231]=5, [232]=6, [233]=6, [234]=6, [235]=6, [236]=3, [237]=3, [238]=3, [239]=3, [242]=6, [244]=6, [245]=6, [246]=6, [247]=6, [249]=6, [250]=6, [251]=6, [252]=6, [253]=6, [255]=6 }
);

@ -18,11 +18,18 @@
--]]
-- Global variables
-------------------
font_lib = {}
font_lib.path = minetest.get_modpath("font_lib")
font_lib.name = minetest.get_current_modname()
font_lib.path = minetest.get_modpath(font_lib.name)
font_lib.registered_fonts = {}
-- Local variables
------------------
local default_font = false
-- Local functions
------------------
@ -41,38 +48,41 @@ local function split_lines(text, maxlines)
end
end
-- Returns next char, managing ascii and unicode plane 0 (0000-FFFF).
-- Gets a default (settings or fist font)
local function get_next_char(text, pos)
pos = pos + 1
local char = text:sub(pos, pos):byte()
local function get_default_font()
-- First call
if default_font == false then
default_font = nil
-- 1 byte char
if char < 0x80 then
return char, pos
-- First, try with settings
local settings_font = minetest.settings:get("default_font")
if settings_font ~= nil and settings_font ~= "" then
default_font = font_lib.registered_fonts[settings_font]
if default_font == nil then
minetest.log("warning", "Default font in settings (\""..
settings_font.."\") is not registered.")
end
end
-- 4 bytes char not managed
if char >= 0xF0 then
pos = pos + 3
return 0, pos
-- If failed, choose first font
if default_font == nil then
for _, font in pairs(font_lib.registered_fonts) do
default_font = font
break
end
end
-- 3 bytes char not managed
if char >= 0xE0 then
pos = pos + 2
return 0, pos
-- Error, no font registered
if default_font == nil then
minetest.log("error",
"No font registred, unable to choose a default font.")
end
end
-- 2 bytes char (little endian)
if char >= 0xC2 then
pos = pos + 1
return (char - 0xC2) * 0x40 + text:sub(pos, pos):byte(), pos
end
-- Not an UTF char
return 0, pos
return default_font
end
-- Returns font properties to be used according to font_name
@ -89,17 +99,49 @@ local function get_font(font_name)
message = "Font \""..font_name.."\" unregistered"
end
if font_lib.fallback_font == nil then
minetest.log("error", message.." and no other font registered.")
else
minetest.log("info", message..", using font \""..font_lib.fallback_font.."\".")
font = font_lib.registered_fonts[font_lib.fallback_font]
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
----------------
@ -111,17 +153,19 @@ end
function font_lib.get_text_size(font_name, text)
local char
local width = 0
local pos = 0
local pos = 1
local font = get_font(font_name)
if font == nil then
return 0, 0
else
while pos < #text do
while pos <= #text do
char, pos = get_next_char(text, pos)
-- Ignore chars with no texture
-- 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
@ -137,19 +181,23 @@ end
-- @param y Vertical position of the line in texture
-- @return Texture string
--> ADD ALIGN
function font_lib.make_line_texture(font_name, text, width, x, y)
local texture = ""
local char
local pos = 0
local pos = 1
local font = get_font(font_name)
if font ~= nil then
while pos < #text do
while pos <= #text do
char, pos = get_next_char(text, pos)
-- Ignore chars with no texture
if font.widths[char] ~= nil then
-- Replace chars with no texture by the NULL(0) char
if font.widths[char] == nil then
print(string.format("["..font_lib.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..
@ -157,9 +205,6 @@ function font_lib.make_line_texture(font_name, text, width, x, y)
x, y, font.name, char)
end
x = x + font.widths[char]
else
print(string.format("Missing char %d (%04x)",char,char))
end
end
end
@ -172,12 +217,13 @@ end
-- @param texturew Width of the texture (extra text will be truncated)
-- @param textureh Height of the texture
-- @param maxlines Maximum number of lines
-- @param valign Vertical text align ("top" or "center")
-- @param color Color of the text
-- @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_lib.make_multiline_texture(font_name, text, width, height,
maxlines, valign, color)
maxlines, halign, valign, color)
local texture = ""
local lines = {}
local textheight = 0
@ -200,15 +246,24 @@ function font_lib.make_multiline_texture(font_name, text, width, height,
end
for _, line in pairs(lines) do
if halign == "left" then
texture = texture..
font_lib.make_line_texture(font_name, line.text, width,
0, y)
elseif halign == "right" then
texture = texture..
font_lib.make_line_texture(font_name, line.text, width,
width - line.width, y)
else
texture = texture..
font_lib.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
@ -217,40 +272,48 @@ end
-- font_<name>_<code>.png
-- <name> : name of the font
-- <code> : 4 digit hexadecimal unicode of the char
-- If registering different sizes, add size in the font name (e.g. times_10, times_12...)
-- @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 pixel, indexed by unicode number.
-- @param widths Array of character widths in pixels, indexed by UTF codepoints
function font_lib.register_font(font_name, height, widths)
if font_lib.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_lib.registered_fonts[font_name] =
{ name = font_name, height = height, widths = widths }
-- If no fallback font, set it (so, first font registered will be the default fallback font)
if font_lib.fallback_font == nil then
font_lib.fallback_font = font_name
end
end
--- Define the fallback font
-- This font will be used instead of given font if not registered.
-- @param font_name Name of the font to be used as fallback font (has to be registered).
function font_lib.set_fallback_font(font_name)
if font_lib.registered_fonts[font_name] == nil then
minetest.log("error", "Fallback font \""..font_name.."\" not registered.")
else
font_lib.fallback_font = font_name
end
-- Force to choose again default font
-- (allows use of fonts registered after start)
default_font = false
end
--- Standard on_display_update entity callback.
-- Node should have a corresponding display_entity with size, resolution and maxlines fields and
-- optionally valign and color fields
-- Node should have a corresponding display_entity with size, resolution and
-- maxlines fields and optionally halign, valign and color fields
-- @param pos Node position
-- @param objref Object reference of entity
@ -262,15 +325,16 @@ function font_lib.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)
objref:set_properties({
textures={font_lib.make_multiline_texture(
def.font_name, text, def.size.x*def.resolution.x, def.size.y*def.resolution.y,
def.maxlines, def.valign, def.color)},
def.font_name, 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)},
visual_size = def.size
})
end
end
dofile(font_lib.path.."/font_default.lua")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Some files were not shown because too many files have changed in this diff Show More