Module:ItemBox: Difference between revisions

Jump to navigation Jump to search
Vergir (talk | contribs)
m Use Module:TextFit instead of own implementation
Vergir (talk | contribs)
Emit the name size in cqw against the name area, dropping the em conversion and grid snapping (with help from vergir-bot LLM)
 
Line 10: Line 10:
--    .itembox-name      line-height: 1.2; font-size: 1.5em (overridden inline)
--    .itembox-name      line-height: 1.2; font-size: 1.5em (overridden inline)
--  so the name's content box is 8 - 2*0.4 = 7.2em wide and 4.5 - 2*0.5 = 3.5em
--  so the name's content box is 8 - 2*0.4 = 7.2em wide and 4.5 - 2*0.5 = 3.5em
--  tall. Keep these in step with that stylesheet.
--  tall. Only the ratio and the size limits are read from those figures: the
--  Glyph widths live in [[Module:TextFit]].
--  size is emitted in cqw against .itembox-name-area, so the browser supplies
--  the actual width. Glyph widths live in [[Module:TextFit]].
-- ============================================================================
-- ============================================================================
local NAME_W = 7.2
local NAME_W = 7.2
local NAME_H = 3.5
local NAME_H = 3.5
local LINE_H = 1.2
local LINE_H = 1.2
local MAX_EM = 1.5
local MAX_EM = 1.5
local MIN_EM = 0.8
local MIN_EM = 0.8
local SNAP_EM = 0.05  -- keep emitted sizes on a tidy grid


-- Returns the name font size as an em string (scales with the card).
-- Returns the name font size as a cqw string, measured against
-- .itembox-name-area, which [[Template:ItemBox]] makes a query container.
function p.getFontSize(frame)
function p.getFontSize(frame)
     local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1")
     local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1")
     if name == "" then return string.format("%.2f", MAX_EM) end
    local max = MAX_EM / NAME_W * 100          -- 20.83cqw
     if name == "" then return string.format("%.2fcqw", max) end


     local pct = textfit.fit(name, {
     return string.format("%.2fcqw", textfit.fit(name, {
         aspect    = NAME_H / NAME_W,
         aspect    = NAME_H / NAME_W,
         lineHeight = LINE_H,
         lineHeight = LINE_H,
         max        = MAX_EM / NAME_W * 100,
         max        = max,
         min        = MIN_EM / NAME_W * 100,
         min        = MIN_EM / NAME_W * 100,   -- 11.11cqw
        bold      = true,  -- .itembox-name is font-weight: bold
     }))
     })
 
    -- fit() returns a percentage of the usable width. Convert back to em and
    -- coarsen downward, so a snapped value still fits. The epsilon guards
    -- against binary representation: 1.45 / 0.05 is 28.999999999999996, which
    -- would otherwise floor a whole grid step too low.
    local em = math.floor(pct / 100 * NAME_W / SNAP_EM + 1e-9) * SNAP_EM
    return string.format("%.2f", math.max(em, MIN_EM))
end
end