Class: ZplRender::Canvas
- Inherits:
-
Object
- Object
- ZplRender::Canvas
- Defined in:
- lib/zpl_render/canvas.rb
Overview
A 1-bit monochrome dot canvas at printer resolution. Pixel value 1 = black dot (ink), 0 = white. Stored one byte per pixel for fast random access via String#getbyte/#setbyte.
Constant Summary collapse
- ROTATIONS =
%i[n r i b].freeze
Instance Attribute Summary collapse
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Class Method Summary collapse
-
.rotated_size(w, h, rotation) ⇒ Object
Dimensions of
srcafter rotation, as [w, h].
Instance Method Summary collapse
-
#blit(src, x, y, rotation: :n, mode: :paint) ⇒ Object
Blit
srconto self with its (rotated) top-left corner at (x, y). - #fill_rect(x, y, w, h, color: :black, xor: false) ⇒ Object
- #get(x, y) ⇒ Object
-
#initialize(width, height) ⇒ Canvas
constructor
A new instance of Canvas.
-
#packed_rows ⇒ Object
Packed rows, 8 pixels per byte, MSB first (for PNG/PDF encoders).
- #set(x, y, on = true) ⇒ Object
- #to_ascii(on: "#", off: ".") ⇒ Object
- #toggle(x, y) ⇒ Object
Constructor Details
#initialize(width, height) ⇒ Canvas
Returns a new instance of Canvas.
12 13 14 15 16 17 18 |
# File 'lib/zpl_render/canvas.rb', line 12 def initialize(width, height) raise ArgumentError, "canvas size must be positive (#{width}x#{height})" if width < 1 || height < 1 @width = width @height = height @bits = ("\x00" * (width * height)).b end |
Instance Attribute Details
#height ⇒ Object (readonly)
Returns the value of attribute height.
8 9 10 |
# File 'lib/zpl_render/canvas.rb', line 8 def height @height end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
8 9 10 |
# File 'lib/zpl_render/canvas.rb', line 8 def width @width end |
Class Method Details
.rotated_size(w, h, rotation) ⇒ Object
Dimensions of src after rotation, as [w, h].
88 89 90 |
# File 'lib/zpl_render/canvas.rb', line 88 def self.rotated_size(w, h, rotation) %i[r b].include?(rotation) ? [h, w] : [w, h] end |
Instance Method Details
#blit(src, x, y, rotation: :n, mode: :paint) ⇒ Object
Blit src onto self with its (rotated) top-left corner at (x, y).
Rotation is one of :n (0), :r (90 CW), :i (180), :b (270 CW).
mode :paint -> src ink paints black, src background is transparent
mode :erase -> src ink paints white (used for ^GB/^GC color W)
mode :xor -> src ink inverts the canvas (ZPL ^FR field reverse)
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/zpl_render/canvas.rb', line 64 def blit(src, x, y, rotation: :n, mode: :paint) sw = src.width sh = src.height (0...sh).each do |sy| (0...sw).each do |sx| next unless src.get(sx, sy) tx, ty = case rotation when :n then [x + sx, y + sy] when :r then [x + (sh - 1 - sy), y + sx] when :i then [x + (sw - 1 - sx), y + (sh - 1 - sy)] when :b then [x + sy, y + (sw - 1 - sx)] else [x + sx, y + sy] end case mode when :xor then toggle(tx, ty) when :erase then set(tx, ty, false) else set(tx, ty, true) end end end end |
#fill_rect(x, y, w, h, color: :black, xor: false) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/zpl_render/canvas.rb', line 39 def fill_rect(x, y, w, h, color: :black, xor: false) x0 = [x, 0].max y0 = [y, 0].max x1 = [x + w, @width].min y1 = [y + h, @height].min return if x0 >= x1 || y0 >= y1 value = color == :black ? 1 : 0 (y0...y1).each do |yy| row = yy * @width (x0...x1).each do |xx| if xor @bits.setbyte(row + xx, @bits.getbyte(row + xx) ^ 1) else @bits.setbyte(row + xx, value) end end end end |
#get(x, y) ⇒ Object
33 34 35 36 37 |
# File 'lib/zpl_render/canvas.rb', line 33 def get(x, y) return false if x.negative? || y.negative? || x >= @width || y >= @height @bits.getbyte(y * @width + x) == 1 end |
#packed_rows ⇒ Object
Packed rows, 8 pixels per byte, MSB first (for PNG/PDF encoders).
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zpl_render/canvas.rb', line 93 def packed_rows Array.new(@height) do |y| row_offset = y * @width bytes = ("\x00" * ((@width + 7) / 8)).b (0...@width).each do |x| next unless @bits.getbyte(row_offset + x) == 1 bytes.setbyte(x >> 3, bytes.getbyte(x >> 3) | (0x80 >> (x & 7))) end bytes end end |
#set(x, y, on = true) ⇒ Object
20 21 22 23 24 |
# File 'lib/zpl_render/canvas.rb', line 20 def set(x, y, on = true) return if x.negative? || y.negative? || x >= @width || y >= @height @bits.setbyte(y * @width + x, on ? 1 : 0) end |
#to_ascii(on: "#", off: ".") ⇒ Object
106 107 108 109 110 |
# File 'lib/zpl_render/canvas.rb', line 106 def to_ascii(on: "#", off: ".") Array.new(@height) do |y| Array.new(@width) { |x| get(x, y) ? on : off }.join end.join("\n") end |
#toggle(x, y) ⇒ Object
26 27 28 29 30 31 |
# File 'lib/zpl_render/canvas.rb', line 26 def toggle(x, y) return if x.negative? || y.negative? || x >= @width || y >= @height idx = y * @width + x @bits.setbyte(idx, @bits.getbyte(idx) ^ 1) end |