Colored text
Colour belongs to the draw, not to the string: each run is natiny.render.set_color
followed by natiny.render.text, with natiny.font.measure_text moving the pen
to the next one. The same runs are drawn twice, once dark and offset, for the shadow.
local natiny = require("natiny")
natiny.backend.init()
local win = natiny.window.create("Colored text", 900, 600)
natiny.window.set_scale_mode(win, natiny.window.SCALE_MODE_STRETCH)
local res = natiny.resource.load("data/common/fonts/roboto.ttf")
local font = natiny.font.create(res, 26)
local small = natiny.font.create(res, 18)
local BG = { 21 / 255, 30 / 255, 44 / 255 } -- #151E2C
local PANEL = { 15 / 255, 22 / 255, 33 / 255 } -- #0F1621
local OBJECT = { 169 / 255, 179 / 255, 197 / 255 } -- #A9B3C5
local LIGHT_TEXT = { 243 / 255, 245 / 255, 250 / 255 } -- #F3F5FA
-- One colour to a kind of token. There is no rich text: a run is a colour and
-- a string, and the pen keeps its place between them.
local INK = {
keyword = { 198 / 255, 146 / 255, 233 / 255 },
call = { 122 / 255, 190 / 255, 255 / 255 },
string = { 168 / 255, 194 / 255, 56 / 255 },
number = { 244 / 255, 178 / 255, 102 / 255 },
comment = { 110 / 255, 122 / 255, 140 / 255 },
plain = LIGHT_TEXT,
}
local LINES = {
{ { "-- one colour, one draw, one pen", "comment" } },
{ { "local ", "keyword" }, { "message ", "plain" }, { "= ", "plain" },
{ "\"hello\"", "string" } },
{ { "for ", "keyword" }, { "i ", "plain" }, { "= ", "plain" },
{ "1", "number" }, { ", ", "plain" }, { "8 ", "number" },
{ "do", "keyword" } },
{ { " print", "call" }, { "(message, i * ", "plain" },
{ "1.5", "number" }, { ")", "plain" } },
{ { "end", "keyword" } },
}
local X, Y = 90, 220
local SHADOW = 3
-- Draws one line of runs and answers how wide it turned out. Every run is an
-- ordinary text draw; measure_text is what moves the pen past the last one.
local function draw_line(y, runs, color)
local pen = X
for _, run in ipairs(runs) do
local ink = color or INK[run[2]]
natiny.render.set_color(ink[1], ink[2], ink[3], color and 0.5 or 1)
natiny.render.text(font, pen, y, run[1])
pen = pen + natiny.font.measure_text(font, run[1])
end
return pen - X
end
natiny.backend.loop(function()
natiny.window.bind(win, function()
local line_height = natiny.font.get_line_height(font)
local height = line_height * #LINES
natiny.render.clear(BG[1], BG[2], BG[3], 1)
natiny.render.set_color(PANEL[1], PANEL[2], PANEL[3], 1)
natiny.render.rounded_rectangle(X - 30, Y - 26, 720, height + 52, 10)
natiny.render.set_color(OBJECT[1], OBJECT[2], OBJECT[3], 0.25)
natiny.render.rounded_rectangle_outline(X - 30, Y - 26, 720, height + 52, 10, 10, 10, 10, 2)
for i, runs in ipairs(LINES) do
local y = Y + (i - 1) * line_height
-- The same runs twice: a dark pass offset behind, then the colours.
draw_line(y + SHADOW, runs, { 0, 0, 0 })
draw_line(y, runs)
end
natiny.render.set_color(LIGHT_TEXT[1], LIGHT_TEXT[2], LIGHT_TEXT[3], 1)
natiny.render.text(small, X - 30, 70,
"set_color, text, set_color, text - the colour belongs to the draw")
local legend, pen = { "keyword", "call", "string", "number", "comment" }, X - 30
for _, kind in ipairs(legend) do
local ink = INK[kind]
natiny.render.set_color(ink[1], ink[2], ink[3], 1)
natiny.render.rectangle(pen, Y + height + 78, 12, 12)
natiny.render.text(small, pen + 20, Y + height + 72, kind)
pen = pen + 40 + natiny.font.measure_text(small, kind)
end
end)
end)
natiny.backend.shutdown()