aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/card.lua32
1 files changed, 18 insertions, 14 deletions
diff --git a/lib/card.lua b/lib/card.lua
index d1f37f7..6729b31 100644
--- a/lib/card.lua
+++ b/lib/card.lua
@@ -122,12 +122,15 @@ end
local extents = cairo_text_extents_t:create()
-- Ink size of a string: how much space the glyphs actually cover.
+-- Returns width, height and a third value: the ink's left offset from the pen
+-- (x_bearing), which right/centre alignment must subtract or a glyph with a
+-- large bearing overruns the edge.
-- Use this to CENTRE or RIGHT-ALIGN text, never to advance a cursor.
function M.measure(cr, s)
local list = runs(s)
if not list then
cairo_text_extents(cr, s, extents)
- return extents.width, extents.height
+ return extents.width, extents.height, extents.x_bearing
end
-- Union of each run's ink box, offset by the advances before it. A run
-- with no ink (spaces) moves the pen but adds nothing to the box.
@@ -143,8 +146,8 @@ function M.measure(cr, s)
end
pen = pen + extents.x_advance
end)
- if not x0 then return 0, 0 end
- return x1 - x0, y1 - y0
+ if not x0 then return 0, 0, 0 end
+ return x1 - x0, y1 - y0, x0
end
-- How far the cursor moves after drawing a string. Use this to lay out runs of
@@ -171,14 +174,14 @@ end
-- Right-aligned text: x is the RIGHT edge.
function M.text_right(cr, x, y, s)
- local w = M.measure(cr, s)
- M.text(cr, x - w, y, s)
+ local w, _, xb = M.measure(cr, s)
+ M.text(cr, x - w - xb, y, s)
end
-- Centred text: x is the CENTRE.
function M.text_centre(cr, x, y, s)
- local w = M.measure(cr, s)
- M.text(cr, x - w / 2, y, s)
+ local w, _, xb = M.measure(cr, s)
+ M.text(cr, x - w / 2 - xb, y, s)
end
-- A rounded-rectangle path. Does not paint; the caller fills or strokes, so one
@@ -330,25 +333,26 @@ end
function M.standard(cr, inner, colors, spec)
local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.32
local rows = spec.rows or {}
+ local big = spec.big and tostring(spec.big)
local big_font = spec.big_font or M.FONT_HEAVY
local head = { { M.title_str(spec.icon, spec.title), M.FONT_MONO, LABEL_F } }
- if spec.big then head[2] = { spec.big, big_font, BIG_F } end
+ if big then head[2] = { big, big_font, BIG_F } end
local groups = { head }
for _, r in ipairs(rows) do
groups[#groups + 1] = { { r[1], M.FONT_MONO, ROW_F },
- { tostring(r[2]), M.FONT_MONO, ROW_F } }
+ { r[2] == nil and '--' or tostring(r[2]), M.FONT_MONO, ROW_F } }
end
-- Height in units of S: the header line, the gap under it, a step per row.
- local head_f = spec.big and BIG_F or LABEL_F * 1.2
+ local head_f = big and BIG_F or LABEL_F * 1.2
local budget = inner.h * (spec.share or 1)
local S = clamp(math.min(budget * 0.94 / (head_f + 0.5 + #rows * 0.66),
M.fit_unit(cr, inner.w * 0.96, groups, 100)), 10, 72)
local label_size, row_size = S * LABEL_F, S * ROW_F
- if spec.big then
+ if big then
M.font(cr, big_font, S * BIG_F, false)
M.rgba(cr, spec.big_color or colors.body)
- M.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, spec.big)
+ M.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, big)
end
M.font(cr, M.FONT_MONO, label_size, false)
M.title(cr, inner.x, inner.y + label_size, spec.icon, spec.title, colors)
@@ -362,11 +366,11 @@ function M.standard(cr, inner, colors, spec)
M.rgba(cr, colors.label)
M.text(cr, inner.x, y, r[1])
M.rgba(cr, r[3] or colors.value)
- M.text_right(cr, inner.x + inner.w, y, tostring(r[2]))
+ M.text_right(cr, inner.x + inner.w, y, r[2] == nil and '--' or tostring(r[2]))
last = y
y = y + step
end
- return last + row_size * 0.8, S
+ return math.min(last + row_size * 0.8, inner.y + inner.h), S
end
-- Shorten a string to `limit` characters, appending an ellipsis when it cuts.