Add Epson test page: text sizes, EAN-13, QR, and a raster image
deploy / deploy (push) Successful in 9s
deploy / deploy (push) Successful in 9s
ReceiptBuilder#image implements GS v 0 raster printing (no image library needed for the demo -- a procedural 8px checkerboard proves it end to end). Skipped attempting the printer's real-time clock: unsure the TM-T20II actually has a battery-backed RTC (that's usually an option on higher-end models), not worth guessing at an undocumented command.
This commit is contained in:
1 parent
790d716d57
commit
d2900361b3
3 files changed
+78
No files matched your search
@@ -107,6 +107,60 @@ helpers do
|
|||||||
receipt.print!(PRINTER_DEVICE_EPSON)
|
receipt.print!(PRINTER_DEVICE_EPSON)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Procedural 64x64 checkerboard (8px squares) -- no image library needed,
|
||||||
|
# just to prove GS v 0 raster printing works end to end.
|
||||||
|
def checkerboard_bitmap(size_px = 64, block_px = 8)
|
||||||
|
width_bytes = size_px / 8
|
||||||
|
bytes = "".b
|
||||||
|
size_px.times do |y|
|
||||||
|
row_block = y / block_px
|
||||||
|
width_bytes.times do |xb|
|
||||||
|
byte = 0
|
||||||
|
8.times do |bit|
|
||||||
|
x = xb * 8 + bit
|
||||||
|
col_block = x / block_px
|
||||||
|
byte |= (1 << (7 - bit)) if (row_block + col_block).even?
|
||||||
|
end
|
||||||
|
bytes << byte.chr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
bytes
|
||||||
|
end
|
||||||
|
|
||||||
|
# Demonstrates most of what the printer can do: text sizes/styles, EAN-13,
|
||||||
|
# QR code, and a raster image -- mirrors /test-print's role for the Datamax.
|
||||||
|
def print_epson_test_page
|
||||||
|
receipt = ReceiptBuilder.new
|
||||||
|
receipt.align(:center).bold.size(:big).text("TM-T20II TEST\n").size(:normal).bold(false)
|
||||||
|
receipt.align(:left).text(('-' * 48) + "\n")
|
||||||
|
|
||||||
|
receipt.text("Normal text\n")
|
||||||
|
receipt.bold.text("Bold text\n").bold(false)
|
||||||
|
receipt.underline.text("Underlined text\n").underline(false)
|
||||||
|
receipt.size(:wide).text("Double width\n").size(:normal)
|
||||||
|
receipt.size(:high).text("Double height\n").size(:normal)
|
||||||
|
receipt.size(:big).text("Double both\n").size(:normal)
|
||||||
|
receipt.text(('-' * 48) + "\n")
|
||||||
|
|
||||||
|
receipt.align(:center)
|
||||||
|
receipt.text("EAN-13 barcode:\n")
|
||||||
|
receipt.ean13('2012345678902')
|
||||||
|
receipt.feed(1)
|
||||||
|
|
||||||
|
receipt.text("QR code:\n")
|
||||||
|
receipt.qr('https://git.priesol.net/randy/home-gitops')
|
||||||
|
receipt.feed(1)
|
||||||
|
|
||||||
|
receipt.text("Raster image:\n")
|
||||||
|
receipt.image(64, 64, checkerboard_bitmap)
|
||||||
|
receipt.feed(1)
|
||||||
|
|
||||||
|
receipt.align(:left).text(('-' * 48) + "\n")
|
||||||
|
receipt.text("Printed: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||||
|
receipt.feed(3).cut
|
||||||
|
receipt.print!(PRINTER_DEVICE_EPSON)
|
||||||
|
end
|
||||||
|
|
||||||
ESCPOS_MNEMONICS = {
|
ESCPOS_MNEMONICS = {
|
||||||
'ESC' => "\x1B", 'GS' => "\x1D", 'FS' => "\x1C", 'DLE' => "\x10",
|
'ESC' => "\x1B", 'GS' => "\x1D", 'FS' => "\x1C", 'DLE' => "\x10",
|
||||||
'LF' => "\x0A", 'CR' => "\x0D", 'HT' => "\x09", 'NUL' => "\x00"
|
'LF' => "\x0A", 'CR' => "\x0D", 'HT' => "\x09", 'NUL' => "\x00"
|
||||||
@@ -313,6 +367,16 @@ get '/epson' do
|
|||||||
erb :epson
|
erb :epson
|
||||||
end
|
end
|
||||||
|
|
||||||
|
post '/epson/test-print' do
|
||||||
|
begin
|
||||||
|
print_epson_test_page
|
||||||
|
flash 'Test page sent to Epson printer', 'success'
|
||||||
|
rescue => e
|
||||||
|
flash "Epson test print failed (#{e.message})", 'danger'
|
||||||
|
end
|
||||||
|
redirect '/epson'
|
||||||
|
end
|
||||||
|
|
||||||
post '/epson/print' do
|
post '/epson/print' do
|
||||||
begin
|
begin
|
||||||
print_receipt(title: params[:title].to_s, body: params[:body].to_s, qr: params[:qr].to_s)
|
print_receipt(title: params[:title].to_s, body: params[:body].to_s, qr: params[:qr].to_s)
|
||||||
|
|||||||
@@ -93,6 +93,16 @@ class ReceiptBuilder
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Raster bit image (GS v 0) -- bytes must already be packed 1bpp,
|
||||||
|
# row-major, (width_px/8 rounded up) bytes per row, MSB-first, 1=black.
|
||||||
|
def image(width_px, height_px, bytes)
|
||||||
|
width_bytes = (width_px + 7) / 8
|
||||||
|
@buffer << "\x1D\x76\x30\x00"
|
||||||
|
@buffer << [width_bytes % 256, width_bytes / 256, height_px % 256, height_px / 256].pack('C4')
|
||||||
|
@buffer << bytes
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def feed(lines = 3)
|
def feed(lines = 3)
|
||||||
@buffer << ("\n" * lines)
|
@buffer << ("\n" * lines)
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
<button class="btn btn-secondary" type="submit">Print</button>
|
<button class="btn btn-secondary" type="submit">Print</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form action="/epson/test-print" method="POST" class="mt-3">
|
||||||
|
<button class="btn btn-outline-secondary" type="submit">Print test page (sizes, barcode, QR, image)</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<hr class="mt-4">
|
<hr class="mt-4">
|
||||||
|
|
||||||
<h5>Free text (ESC/POS mnemonic notation)</h5>
|
<h5>Free text (ESC/POS mnemonic notation)</h5>
|
||||||
|
|||||||
Reference in new issue
Block a user