Current section
Files
Jump to
Current section
Files
src/escpos/protocol.gleam
//// Low-level ESC/POS command encoding.
////
//// Each function returns a `BitArray` containing the raw bytes for a single
//// ESC/POS command. These are used internally by the `escpos` module to
//// build command buffers.
import gleam/bit_array
import gleam/int
/// Text justification mode.
pub type Justify {
Left
Center
Right
}
/// Paper cut mode.
pub type Cut {
Partial
Full
}
/// Built-in printer font. Available fonts vary by printer model;
/// FontA and FontB are the most widely supported.
pub type Font {
FontA
FontB
FontC
FontD
FontE
SpecialFontA
SpecialFontB
}
/// Image tone mode. Most printers only support `Monochrome`.
pub type ImageTone {
Monochrome
MultipleTone
}
/// Image scaling factor for the graphics buffer.
pub type ImageScale {
Scale1x
Scale2x
}
/// Print color selection. Most printers only support `Color1` (black).
pub type PrintColor {
Color1
Color2
Color3
Color4
}
const esc = 27
const gs = 29
/// Initialize printer command (`ESC @`).
pub const init = <<esc, "@">>
/// Line feed byte (`LF`).
pub const lf = <<10>>
/// Paper cut command (`GS V`).
pub fn cut(cut: Cut) -> BitArray {
case cut {
Full -> <<gs, "V", 0>>
Partial -> <<gs, "V", 1>>
}
}
/// Feeds the given number of lines, clamped to 1–255 (`ESC d`).
pub fn line_feed(lines: Int) -> BitArray {
case lines {
l if l < 2 -> <<esc, "d", 1>>
l if l > 254 -> <<esc, "d", 255>>
_ -> <<esc, "d", lines>>
}
}
/// Sets text justification (`ESC a`). Must be at the start of a line
/// to take effect.
pub fn justify(justify: Justify) -> BitArray {
case justify {
Left -> <<esc, "a", 0>>
Center -> <<esc, "a", 1>>
Right -> <<esc, "a", 2>>
}
}
/// Enables or disables bold text (`ESC E`).
pub fn bold(on: Bool) -> BitArray {
case on {
True -> <<esc, "E", 1>>
False -> <<esc, "E", 0>>
}
}
/// Enables or disables underlined text (`ESC -`).
pub fn underline(on: Bool) -> BitArray {
case on {
True -> <<esc, "-", 1>>
False -> <<esc, "-", 0>>
}
}
/// Enables or disables double-strike text (`ESC G`).
pub fn double_strike(on: Bool) -> BitArray {
case on {
True -> <<esc, "G", 1>>
False -> <<esc, "G", 0>>
}
}
/// Enables or disables reverse (white on black) printing (`GS B`).
pub fn reverse(on: Bool) -> BitArray {
case on {
True -> <<gs, "B", 1>>
False -> <<gs, "B", 0>>
}
}
/// Enables or disables upside-down printing (`ESC {`).
pub fn upside_down(on: Bool) -> BitArray {
case on {
True -> <<esc, "{", 1>>
False -> <<esc, "{", 0>>
}
}
/// Enables or disables character smoothing (`GS b`).
pub fn smooth(on: Bool) -> BitArray {
case on {
True -> <<gs, "b", 1>>
False -> <<gs, "b", 0>>
}
}
/// Enables or disables 180-degree rotation (`ESC V`).
pub fn flip(on: Bool) -> BitArray {
case on {
True -> <<esc, "V", 1>>
False -> <<esc, "V", 0>>
}
}
/// Selects a built-in printer font (`ESC M`).
pub fn font(font: Font) -> BitArray {
case font {
FontA -> <<esc, "M", 0>>
FontB -> <<esc, "M", 1>>
FontC -> <<esc, "M", 2>>
FontD -> <<esc, "M", 3>>
FontE -> <<esc, "M", 4>>
SpecialFontA -> <<esc, "M", 97>>
SpecialFontB -> <<esc, "M", 98>>
}
}
/// Sets character width and height 1–8 (`GS !`).
pub fn character_size(width: Int, height: Int) -> BitArray {
let w = int.clamp(width, min: 1, max: 8) |> int.subtract(1)
let h = int.clamp(height, min: 1, max: 8) |> int.subtract(1)
<<gs, "!", 0:1, w:3, 0:1, h:3>>
}
/// Stores raster image data into the printer's graphics buffer
/// (`GS ( L`, fn=112).
pub fn image_to_graphics_buffer(
data: BitArray,
width: Int,
height: Int,
tone: ImageTone,
scale_x: ImageScale,
scale_y: ImageScale,
color: PrintColor,
) -> BitArray {
let data_size = bit_array.byte_size(data)
let data_length = 10 + data_size
let pl = data_length % 256
let ph = data_length / 256
let xl = width % 256
let xh = width / 256
let yl = height % 256
let yh = height / 256
let a = case tone {
Monochrome -> 48
MultipleTone -> 52
}
let bx = case scale_x {
Scale1x -> 1
Scale2x -> 2
}
let by = case scale_y {
Scale1x -> 1
Scale2x -> 2
}
let c = case color {
Color1 -> 49
Color2 -> 50
Color3 -> 51
Color4 -> 52
}
<<
gs,
"(",
"L",
pl,
ph,
48,
// m (fixed)
112,
// fn = 112
a,
// tone
bx,
// x scaling
by,
// y scaling
c,
// color
xl,
xh,
// width in dots
yl,
yh,
// height in dots
data:bits,
>>
}
/// Prints the contents of the graphics buffer (`GS ( L`, fn=50).
pub fn print_graphics_buffer() -> BitArray {
<<gs, "(", "L", 2, 0, 48, 50>>
}