diff --git a/glyphs.py b/glyphs.py index 20407fd..fc1b438 100644 --- a/glyphs.py +++ b/glyphs.py @@ -1,14 +1,18 @@ """Custom fraction glyphs for the TM-T88V receipt printer. -Each glyph is a 12-wide x 24-tall pixel bitmap defined as a list of 24 strings. -'#' = pixel on, '.' = pixel off. +Fractions are composed from small digit patterns stacked vertically: +numerator on top, denominator on bottom — matching the old ticker tape style. -To customize a glyph, edit its pattern below. Each row must be exactly 12 -characters wide and there must be exactly 24 rows per glyph. +To customize: + - Edit DIGIT_PATTERNS to change how a digit looks in ALL fractions using it. + - Or override a specific fraction in GLYPH_OVERRIDES with a full 12x24 grid. + - '#' = pixel on, '.' = pixel off + - Each digit pattern is 12 wide x 11 tall. + - Each full glyph is 12 wide x 24 tall (11 + 2 gap + 11). """ -# Map each fraction to a character code on the printer. -# Must be in 0x20-0x7E range and not conflict with output chars (A-Z, 0-9, '.', 's', ' ') +# Character codes used on the printer for each fraction. +# Must be 0x20-0x7E and not conflict with output chars (A-Z, 0-9, '.', 's', ' ') CHAR_MAP = { "1/8": "a", "1/4": "b", @@ -30,194 +34,149 @@ EIGHTHS_TO_NAME = { 7: "7/8", } +# ── Digit patterns (12 wide x 11 tall) ─────────────────────────────────────── +# These are composed into the fraction glyphs below. # fmt: off -GLYPHS = { - "1/8": [ - "............", # 0 - ".........#..", # 1 ── numerator "1" - "........##..", # 2 - ".........#..", # 3 - ".........#..", # 4 - ".........#..", # 5 - ".........#..", # 6 - ".........#..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "..##........", # 16 ── denominator "8" - ".#..#.......", # 17 - ".#..#.......", # 18 - "..##........", # 19 - ".#..#.......", # 20 - ".#..#.......", # 21 - "..##........", # 22 - "............", # 23 +DIGIT_PATTERNS = { + 1: [ + ".....##.....", + "....###.....", + "...####.....", + ".....##.....", + ".....##.....", + ".....##.....", + ".....##.....", + ".....##.....", + ".....##.....", + ".....##.....", + "...######...", ], - "1/4": [ - "............", # 0 - ".........#..", # 1 ── "1" - "........##..", # 2 - ".........#..", # 3 - ".........#..", # 4 - ".........#..", # 5 - ".........#..", # 6 - ".........#..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "....#.......", # 16 ── "4" - "...##.......", # 17 - "..#.#.......", # 18 - ".#..#.......", # 19 - ".####.......", # 20 - "....#.......", # 21 - "....#.......", # 22 - "............", # 23 + 2: [ + "..########..", + ".##......##.", + "..........##", + "..........##", + "........##..", + "......##....", + "....##......", + "..##........", + ".##.........", + ".##.........", + "############", ], - "3/8": [ - "............", # 0 - "........##..", # 1 ── "3" - ".......#..#.", # 2 - "..........#.", # 3 - "........##..", # 4 - "..........#.", # 5 - ".......#..#.", # 6 - "........##..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "..##........", # 16 ── "8" - ".#..#.......", # 17 - ".#..#.......", # 18 - "..##........", # 19 - ".#..#.......", # 20 - ".#..#.......", # 21 - "..##........", # 22 - "............", # 23 + 3: [ + "..########..", + ".##......##.", + "..........##", + "..........##", + ".....####...", + "..........##", + "..........##", + "..........##", + ".##......##.", + ".##......##.", + "..########..", ], - "1/2": [ - "............", # 0 - ".........#..", # 1 ── "1" - "........##..", # 2 - ".........#..", # 3 - ".........#..", # 4 - ".........#..", # 5 - ".........#..", # 6 - ".........#..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "..##........", # 16 ── "2" - ".#..#.......", # 17 - "....#.......", # 18 - "...#........", # 19 - "..#.........", # 20 - ".#..........", # 21 - ".####.......", # 22 - "............", # 23 + 4: [ + ".......##...", + "......###...", + ".....####...", + "....##.##...", + "...##..##...", + "..##...##...", + ".##....##...", + "############", + ".......##...", + ".......##...", + ".......##...", ], - "5/8": [ - "............", # 0 - ".......####.", # 1 ── "5" - ".......#....", # 2 - ".......###..", # 3 - "..........#.", # 4 - "..........#.", # 5 - ".......#..#.", # 6 - "........##..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "..##........", # 16 ── "8" - ".#..#.......", # 17 - ".#..#.......", # 18 - "..##........", # 19 - ".#..#.......", # 20 - ".#..#.......", # 21 - "..##........", # 22 - "............", # 23 + 5: [ + "############", + "##..........", + "##..........", + "##..........", + "##########..", + "..........##", + "..........##", + "..........##", + "..........##", + ".##......##.", + "..########..", ], - "3/4": [ - "............", # 0 - "........##..", # 1 ── "3" - ".......#..#.", # 2 - "..........#.", # 3 - "........##..", # 4 - "..........#.", # 5 - ".......#..#.", # 6 - "........##..", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "....#.......", # 16 ── "4" - "...##.......", # 17 - "..#.#.......", # 18 - ".#..#.......", # 19 - ".####.......", # 20 - "....#.......", # 21 - "....#.......", # 22 - "............", # 23 + 7: [ + "############", + "##........##", + "..........##", + ".........##.", + "........##..", + ".......##...", + "......##....", + ".....##.....", + "....##......", + "....##......", + "....##......", ], - "7/8": [ - "............", # 0 - ".......####.", # 1 ── "7" - "..........#.", # 2 - ".........#..", # 3 - ".........#..", # 4 - "........#...", # 5 - "........#...", # 6 - "........#...", # 7 - "........#...", # 8 ── slash - ".......#....", # 9 - "......#.....", # 10 - ".....#......", # 11 - "....#.......", # 12 - "...#........", # 13 - "..#.........", # 14 - ".#..........", # 15 - "..##........", # 16 ── "8" - ".#..#.......", # 17 - ".#..#.......", # 18 - "..##........", # 19 - ".#..#.......", # 20 - ".#..#.......", # 21 - "..##........", # 22 - "............", # 23 + 8: [ + "..########..", + ".##......##.", + ".##......##.", + ".##......##.", + "..########..", + ".##......##.", + ".##......##.", + ".##......##.", + ".##......##.", + ".##......##.", + "..########..", ], } # fmt: on +def _compose_fraction(num, den): + """Build a 12x24 glyph: numerator digit stacked over denominator digit. + + Layout (24 rows): + rows 0-10: numerator digit (11 rows) + rows 11-12: gap (2 rows) + rows 13-23: denominator digit (11 rows) + """ + blank = "." * 12 + rows = list(DIGIT_PATTERNS[num]) + rows.extend([blank] * 2) + rows.extend(DIGIT_PATTERNS[den]) + return rows + + +# ── Composed glyphs (auto-generated from digit patterns) ──────────────────── +GLYPHS = { + "1/8": _compose_fraction(1, 8), + "1/4": _compose_fraction(1, 4), + "3/8": _compose_fraction(3, 8), + "1/2": _compose_fraction(1, 2), + "5/8": _compose_fraction(5, 8), + "3/4": _compose_fraction(3, 4), + "7/8": _compose_fraction(7, 8), +} + +# ── Per-fraction overrides ────────────────────────────────────────────────── +# To hand-craft a specific fraction, add it here as a 24-row list of 12-char +# strings. It will replace the auto-composed version above. +# +# GLYPH_OVERRIDES = { +# "1/2": [ +# "............", +# ... # 24 rows total +# ], +# } +GLYPH_OVERRIDES = {} + +# Apply overrides +GLYPHS.update(GLYPH_OVERRIDES) + + +# ── ESC/POS conversion & upload ───────────────────────────────────────────── + def glyph_to_escpos(rows): """Convert a visual glyph (24 rows of 12-char strings) to ESC/POS column data. @@ -254,7 +213,7 @@ def price_to_fraction(price): """Convert a decimal price to dollar amount + fraction character. Rounds to the nearest eighth of a dollar, like old ticker tapes. - Returns e.g. "246" or "57a" where 'a' is the custom ⅛ glyph. + Returns e.g. "246" or "57d" where 'd' is the custom ½ glyph. """ dollars = int(price) eighths = round((price - dollars) * 8)