libptouch の更新に追従

This commit is contained in:
knb
2026-04-13 11:39:31 +09:00
parent ae67a8b288
commit f26a1186a3
17 changed files with 399 additions and 140 deletions

View File

@@ -22,6 +22,8 @@ module Libptouch
USB_VID_BROTHER = 0x04f9
USB_PID_PTP900W = 0x2085
USB_PID_PTP750W = 0x2062
USB_PID_PTP710BT = 0x20af
STATUS_LENGTH = 32
PNG_DEFAULT_THRESHOLD = 128

View File

@@ -20,7 +20,7 @@ module Libptouch
if opts[:status]
warn_unused_file_options(opts)
return run_status
return run_status(opts)
end
return usage_error("-f is required (or use --status)") if opts[:file].to_s.empty?
@@ -44,35 +44,78 @@ module Libptouch
end
def parse(argv)
o = {
opts_hash = default_cli_opts
build_cli_parser(opts_hash).parse!(argv)
return nil unless threshold_option_ok?(opts_hash)
return nil unless usb_pid_option_ok?(opts_hash)
opts_hash.delete(:usb_pid_invalid)
opts_hash
end
def default_cli_opts
{
file: nil,
threshold: nil,
usb_pid: nil,
usb_pid_invalid: false,
dry_run: false,
status: false,
version: false,
help: false
}
parser = OptionParser.new do |p|
end
def pid_option_description
p900 = Libptouch::USB_PID_PTP900W
p750 = Libptouch::USB_PID_PTP750W
p710 = Libptouch::USB_PID_PTP710BT
"USB 製品 ID16 進可)。既定 P900W 0x#{p900.to_s(16)}; " \
"P750W 0x#{p750.to_s(16)}; P710BT 0x#{p710.to_s(16)}"
end
def apply_usb_pid_option(opts_hash, pid_str)
opts_hash[:usb_pid] = Integer(pid_str, 0)
rescue ArgumentError
warn "invalid --pid: #{pid_str.inspect}"
opts_hash[:usb_pid_invalid] = true
end
def threshold_option_ok?(opts_hash)
return true if opts_hash[:threshold].nil? || (0..255).cover?(opts_hash[:threshold])
warn "-t must be 0..255"
false
end
def usb_pid_option_ok?(opts_hash)
return false if opts_hash[:usb_pid_invalid]
return true if opts_hash[:usb_pid].nil?
return true if opts_hash[:usb_pid].between?(1, 0xFFFF)
warn "-p/--pid must be 1..0xFFFF"
false
end
def build_cli_parser(opts_hash)
OptionParser.new do |p|
p.banner = usage_banner
p.separator ""
p.on("-f", "--file PATH", "入力 PNG ファイル") { |v| o[:file] = v }
p.on("-f", "--file PATH", "入力 PNG ファイル") { |v| opts_hash[:file] = v }
p.on("-t", "--threshold N", Integer,
"二値化しきい値 0255既定 #{Libptouch::PNG_DEFAULT_THRESHOLD}") do |v|
o[:threshold] = v
opts_hash[:threshold] = v
end
p.on("-n", "--dry-run", "読み込みと検証のみUSB なし)") { o[:dry_run] = true }
p.on("-S", "--status", "USB プリンタのステータスを JSON で表示して終了") { o[:status] = true }
p.on("-V", "--version", "バージョンを表示して終了") { o[:version] = true }
p.on("-h", "--help", "このヘルプ") { o[:help] = true }
p.on("-p", "--pid PID", pid_option_description) do |v|
apply_usb_pid_option(opts_hash, v)
end
p.on("-n", "--dry-run", "読み込みと検証のみUSB なし)") { opts_hash[:dry_run] = true }
p.on("-S", "--status", "USB プリンタのステータスを JSON で表示して終了") do
opts_hash[:status] = true
end
p.on("-V", "--version", "バージョンを表示して終了") { opts_hash[:version] = true }
p.on("-h", "--help", "このヘルプ") { opts_hash[:help] = true }
end
parser.parse!(argv)
unless o[:threshold].nil? || (0..255).cover?(o[:threshold])
warn "-t must be 0..255"
return nil
end
o
end
def usage_banner
@@ -103,34 +146,40 @@ module Libptouch
end
def parser_help_text
o = {
file: nil,
threshold: nil,
dry_run: false,
status: false,
version: false,
help: false
}
opts_hash = default_cli_opts
p = OptionParser.new do |parser|
parser.banner = "ptouch-print-png [options]"
parser.on("-f", "--file PATH", "入力 PNG ファイル") { |v| o[:file] = v }
parser.on("-f", "--file PATH", "入力 PNG ファイル") { |v| opts_hash[:file] = v }
parser.on("-t", "--threshold N", Integer,
"二値化しきい値 0255既定 #{Libptouch::PNG_DEFAULT_THRESHOLD}") do |v|
o[:threshold] = v
opts_hash[:threshold] = v
end
parser.on("-n", "--dry-run", "読み込みと検証のみUSB なし)") { o[:dry_run] = true }
parser.on("-S", "--status", "USB プリンタのステータスを JSON で表示して終了") { o[:status] = true }
parser.on("-V", "--version", "バージョンを表示して終了") { o[:version] = true }
parser.on("-h", "--help", "このヘルプ") { o[:help] = true }
parser.on("-p", "--pid PID", pid_option_description) do |v|
apply_usb_pid_option(opts_hash, v)
end
parser.on("-n", "--dry-run", "読み込みと検証のみUSB なし)") { opts_hash[:dry_run] = true }
parser.on("-S", "--status", "USB プリンタのステータスを JSON で表示して終了") do
opts_hash[:status] = true
end
parser.on("-V", "--version", "バージョンを表示して終了") { opts_hash[:version] = true }
parser.on("-h", "--help", "このヘルプ") { opts_hash[:help] = true }
end
p.help
end
def run_status
def open_usb_for_opts(ctx, opts)
if opts[:usb_pid]
ctx.open_usb_vid_pid(Libptouch::USB_VID_BROTHER, opts[:usb_pid])
else
ctx.open_usb
end
end
def run_status(opts)
ctx = nil
begin
ctx = Libptouch::Context.new
ctx.open_usb
open_usb_for_opts(ctx, opts)
h = Libptouch.parse_status(ctx.status_bytes)
h.delete(:raw_bytes)
puts JSON.pretty_generate(h)
@@ -161,7 +210,7 @@ module Libptouch
return 0
end
ctx.open_usb
open_usb_for_opts(ctx, opts)
ctx.print_raster(data, width_dots: width, height_dots: height)
0
rescue Libptouch::Error => e

View File

@@ -87,7 +87,7 @@ module Libptouch
raw = out_pp.read_pointer
raise Libptouch::Error.new(OK, "null raster from PNG") if raw.null?
len = out_len.read_size_t
len = out_len.get(:size_t, 0)
bytes = raw.read_bytes(len)
Binding.libptouch_free_raster(raw)
[bytes, out_params[:width_dots], out_params[:height_dots]]

View File

@@ -104,7 +104,9 @@ module Libptouch
0x6F => "PT-P900W",
0x70 => "PT-P950NW",
0x71 => "PT-P900",
0x78 => "PT-P910BT"
0x78 => "PT-P910BT",
0x68 => "PT-P750W",
0x76 => "PT-P710BT"
}.freeze
MEDIA_WIDTH = {