add cut bitmask option and debug dump support
Replace auto-cut toggle with --cut bit flags (default 011), wire flags through C/Ruby APIs, and document the new cut/debug-dump behavior in both READMEs. Made-with: Cursor
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
build/
|
||||
tmp/
|
||||
|
||||
ruby/*.gem
|
||||
ruby/.rubocop_cache/
|
||||
|
||||
@@ -47,6 +47,8 @@ ctest --test-dir build --output-on-failure
|
||||
**SVG**(拡張子 `.svg`)の場合は現在装着中テープの印字可能ドット幅に合わせて自動拡大・縮小します(USB 接続が必要)。
|
||||
`--trim-right[=DOTS]` で右側空白列を削減できます(DOTS 省略時は左余白ドット、取得失敗時は 0)。
|
||||
任意で `-t`(0–255)で二値化しきい値を指定できます。
|
||||
`--cut BITS` でカット系フラグを指定できます(`[auto-cut][half-cut][chain-print]`、例 `010`)。
|
||||
指定なしの既定は `011`(オートカットしない / ハーフカットする / つなげて印刷する)です。
|
||||
|
||||
**1bit packed ラスター**(行優先、行あたり `ceil(width/8)` バイト × 行数)の場合は `-f` に加え `-w` / `-H` が必須です。
|
||||
|
||||
@@ -64,6 +66,12 @@ ctest --test-dir build --output-on-failure
|
||||
# PNG — しきい値を指定
|
||||
./build/ptouch-print -n -f label.png -t 160
|
||||
|
||||
# カットフラグを指定(auto=0, half=1, chain=0)
|
||||
./build/ptouch-print -n -f label.png --cut 010
|
||||
|
||||
# デバッグ: USB に送る印字データをファイル保存
|
||||
./build/ptouch-print -f label.png --debug-dump print_job.bin
|
||||
|
||||
# 1bit ラスター — 検証のみ
|
||||
./build/ptouch-print -n -f sample.raster -w 128 -H 64
|
||||
|
||||
@@ -90,6 +98,7 @@ ctest --test-dir build --output-on-failure
|
||||
- `libptouch_get_status` / `libptouch_status_fprint` — ステータス情報リクエスト(ESC i S)の応答
|
||||
- `libptouch_get_current_media_info` — 現在テープ幅(mm)・印字可能幅(dots)・DPI・最小余白(mm)を取得
|
||||
- `libptouch_check_raster` — ラスターバッファの検証のみ
|
||||
- `libptouch_set_debug_dump_path` — USB bulk OUT へ送った印字データをファイル保存(デバッグ用)
|
||||
- `libptouch_png_file_to_raster` / `libptouch_free_raster` — PNG を 1bit ラスターに変換(libpng)
|
||||
- `libptouch_svg_file_to_raster_fit_current_tape` — SVG を現在テープ幅に合わせて 1bit ラスターへ変換(librsvg + cairo、USB 必須)
|
||||
- `libptouch_print_raster` — ラスター印刷(USB・PDF のコマンド列、内部で転置)
|
||||
|
||||
@@ -84,10 +84,33 @@ libptouch_err_t libptouch_open_usb(libptouch_ctx *ctx);
|
||||
|
||||
void libptouch_close(libptouch_ctx *ctx);
|
||||
|
||||
/**
|
||||
* デバッグ用: USB bulk OUT へ実際に送ったバイト列を path に保存する。
|
||||
* 各 @ref libptouch_print_raster ごとにファイルを上書きし直す(ジョブ先頭のチャンクで wb)。
|
||||
* path が NULL または空文字で無効化。転送が成功したチャンクのみ追記する。
|
||||
*/
|
||||
void libptouch_set_debug_dump_path(libptouch_ctx *ctx, const char *path);
|
||||
|
||||
/** @ref libptouch_raster_params_t.flags 用: ESC i M bit6 でオートカット ON */
|
||||
#define LIBPTOUCH_RASTER_FLAG_AUTO_CUT 0x01u
|
||||
/** @ref libptouch_raster_params_t.flags 用: ESC i K bit2 でハーフカット ON */
|
||||
#define LIBPTOUCH_RASTER_FLAG_HALF_CUT 0x02u
|
||||
/** @ref libptouch_raster_params_t.flags 用: ChainPrint する(ESC i K bit3=0) */
|
||||
#define LIBPTOUCH_RASTER_FLAG_CHAIN_PRINT 0x04u
|
||||
/** 既定: 011(オートカットしない・ハーフカットする・つなげて印刷する) */
|
||||
#define LIBPTOUCH_RASTER_FLAGS_DEFAULT \
|
||||
(LIBPTOUCH_RASTER_FLAG_HALF_CUT | LIBPTOUCH_RASTER_FLAG_CHAIN_PRINT)
|
||||
|
||||
typedef struct {
|
||||
uint32_t width_dots; /**< ラスター幅(ドット) */
|
||||
uint32_t height_dots; /**< ラスター高さ(ドット・走査方向は実装と機種に依存) */
|
||||
uint8_t margin_mm; /**< 余白など(機種・仕様に合わせて使用) */
|
||||
/**
|
||||
* LIBPTOUCH_RASTER_FLAG_*。未使用ビットは 0。
|
||||
* 既定は @ref LIBPTOUCH_RASTER_FLAGS_DEFAULT(011: オートカットしない・ハーフカットする・つなげて印刷する)。
|
||||
*/
|
||||
uint8_t flags;
|
||||
uint8_t _reserved[2]; /**< 将来用。0 にすること */
|
||||
} libptouch_raster_params_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -135,6 +158,8 @@ libptouch_err_t libptouch_trim_right_blank_columns(
|
||||
* width_dots は装着テープの印刷可能幅以下であること。系統は @ref libptouch_get_current_media_info
|
||||
* の printer_family で判別できる(P900 系は主に 360dpi 相当ドット列、P700 系は 180dpi 相当)。
|
||||
* @param margin_mm 余白(フィード)量。0 のとき PDF の最小 1mm(14 ドット)相当を送る。
|
||||
* @param params->flags bit0=オートカット、bit1=ハーフカット、bit2=チェーンプリントする。
|
||||
* 指定なしは @ref LIBPTOUCH_RASTER_FLAGS_DEFAULT(011)。
|
||||
* 印刷時は内部でドット列を転置する(テープ幅方向とバッファの縦横の対応)。
|
||||
* @param data 1 行あたり width_dots ビットを ceil(width_dots/8) バイトで並べた連続領域
|
||||
* @param data_len 期待値: height * row_bytes, row_bytes = (width_dots + 7) / 8
|
||||
|
||||
@@ -39,6 +39,8 @@ SVG は現在装着テープの印字可能幅に合わせて自動拡大・縮
|
||||
また、`--template`(SVG)と `--data`(JSON/YAML)を使うと `data-field` 属性をキーにした差込印刷が可能です。
|
||||
`data-kb-placeholder="qr"` / `data-kb-placeholder="barcode"` を付けた SVG 要素(`x/y/width/height` 必須)には、対応する `data-field` 値から QR / Code128 バーコードを生成して差し込みできます。
|
||||
`--trim-right[=DOTS]` を付けると、libptouch 側の共通処理でラベル右側の空白ドット列を削減します。`DOTS` 省略時は左余白ドット数を使い、取得失敗時は `0` にフォールバックします。
|
||||
`--cut BITS` は 3bit(`[auto-cut][half-cut][chain-print]`)で、例 `010` のように指定します。既定は `011` です。
|
||||
`--debug-dump PATH` を付けると USB へ送る印字データをファイル保存します(1 印刷ごとに上書き)。
|
||||
|
||||
開発ツリーからそのまま試す例:
|
||||
|
||||
@@ -48,6 +50,8 @@ bundle exec ruby -I lib exe/ptouch-label -n -f ../samples/your.png
|
||||
bundle exec ruby -I lib exe/ptouch-label -n -f ../samples/your.svg
|
||||
bundle exec ruby -I lib exe/ptouch-label -n -f ../samples/your.svg --trim-right
|
||||
bundle exec ruby -I lib exe/ptouch-label -n -f ../samples/your.svg --trim-right=20
|
||||
bundle exec ruby -I lib exe/ptouch-label -n -f ../samples/your.png --cut 010
|
||||
bundle exec ruby -I lib exe/ptouch-label -f ../samples/your.png --debug-dump print_job.bin
|
||||
bundle exec ruby -I lib exe/ptouch-label -n --template ../samples/your_template.svg --data ../samples/your_data.yml
|
||||
bundle exec ruby -I lib exe/ptouch-label --media-info
|
||||
bundle exec ruby -I lib exe/ptouch-label --status -p 0x2062
|
||||
@@ -98,7 +102,7 @@ ctx.dispose
|
||||
|
||||
## API の範囲
|
||||
|
||||
- 実行ファイル `ptouch-label`(互換: `ptouch-print-png`)… PNG/SVG(`-f`, `-t`, `-p`, `-n`, `-M`, `-S`, `-V`, `-h`, `--template`, `--data`, `--trim-right[=DOTS]`)。`-M` は現在テープ情報(幅 mm・DPI 等)を JSON 出力、`-S` はステータス JSON 出力、`--trim-right` は右側空白列を削減
|
||||
- 実行ファイル `ptouch-label`(互換: `ptouch-print-png`)… PNG/SVG(`-f`, `-t`, `-p`, `-n`, `-M`, `-S`, `-V`, `-h`, `--template`, `--data`, `--trim-right[=DOTS]`, `--cut BITS`, `--debug-dump PATH`)。`-M` は現在テープ情報(幅 mm・DPI 等)を JSON 出力、`-S` はステータス JSON 出力、`--trim-right` は右側空白列を削減
|
||||
- `Libptouch::Context` … `open_usb` / `open_usb_vid_pid` / `close` / `dispose`
|
||||
- `check_raster` / `print_raster` / `png_file_to_raster` / `svg_file_to_raster_fit_current_tape` / `status_bytes` / `status_hash` / `current_media_info`
|
||||
- `current_media_info` には `print_dpi` / `feed_dpi` / `tape_width_mm` / `printable_height_dots` / `min_feed_mm` などを含む(テープ幅方向は `printable_height_dots`)
|
||||
|
||||
@@ -32,4 +32,9 @@ module Libptouch
|
||||
FAMILY_UNKNOWN = 0
|
||||
FAMILY_P700 = 1
|
||||
FAMILY_P900 = 2
|
||||
|
||||
RASTER_FLAG_AUTO_CUT = 0x01
|
||||
RASTER_FLAG_HALF_CUT = 0x02
|
||||
RASTER_FLAG_CHAIN_PRINT = 0x04
|
||||
RASTER_FLAGS_DEFAULT = RASTER_FLAG_HALF_CUT | RASTER_FLAG_CHAIN_PRINT
|
||||
end
|
||||
|
||||
@@ -25,7 +25,9 @@ module Libptouch
|
||||
layout :width_dots, :uint32,
|
||||
:height_dots, :uint32,
|
||||
:margin_mm, :uint8,
|
||||
:_pad, [:uint8, 3]
|
||||
:flags, :uint8,
|
||||
:reserved0, :uint8,
|
||||
:reserved1, :uint8
|
||||
end
|
||||
|
||||
class MediaInfo < FFI::Struct
|
||||
@@ -52,6 +54,7 @@ module Libptouch
|
||||
end
|
||||
|
||||
attach_function :libptouch_create, [], :pointer
|
||||
attach_function :libptouch_set_debug_dump_path, %i[pointer string], :void
|
||||
attach_function :libptouch_printer_family_label, [:uint32], :string
|
||||
attach_function :libptouch_destroy, [:pointer], :void
|
||||
attach_function :libptouch_strerror, [:pointer], :string
|
||||
|
||||
@@ -76,8 +76,10 @@ module Libptouch
|
||||
return nil unless threshold_option_ok?(opts_hash)
|
||||
return nil unless trim_right_option_ok?(opts_hash)
|
||||
return nil unless usb_pid_option_ok?(opts_hash)
|
||||
return nil if opts_hash[:cut_invalid]
|
||||
|
||||
opts_hash.delete(:usb_pid_invalid)
|
||||
opts_hash.delete(:cut_invalid)
|
||||
opts_hash
|
||||
end
|
||||
|
||||
@@ -94,7 +96,9 @@ module Libptouch
|
||||
media_info: false,
|
||||
status: false,
|
||||
version: false,
|
||||
help: false
|
||||
help: false,
|
||||
cut_flags: Libptouch::RASTER_FLAGS_DEFAULT,
|
||||
debug_dump: nil
|
||||
}
|
||||
end
|
||||
|
||||
@@ -138,6 +142,19 @@ module Libptouch
|
||||
false
|
||||
end
|
||||
|
||||
def apply_cut_option(opts_hash, bits)
|
||||
unless bits.is_a?(String) && bits.match?(/\A[01]{3}\z/)
|
||||
warn "--cut must be 3 bits (e.g. 010: auto/half/chain)"
|
||||
opts_hash[:cut_invalid] = true
|
||||
return
|
||||
end
|
||||
flags = 0
|
||||
flags |= Libptouch::RASTER_FLAG_AUTO_CUT if bits[0] == "1"
|
||||
flags |= Libptouch::RASTER_FLAG_HALF_CUT if bits[1] == "1"
|
||||
flags |= Libptouch::RASTER_FLAG_CHAIN_PRINT if bits[2] == "1"
|
||||
opts_hash[:cut_flags] = flags
|
||||
end
|
||||
|
||||
def build_cli_parser(opts_hash)
|
||||
OptionParser.new do |p|
|
||||
p.banner = usage_banner
|
||||
@@ -152,6 +169,12 @@ module Libptouch
|
||||
p.on("-p", "--pid PID", pid_option_description) do |v|
|
||||
apply_usb_pid_option(opts_hash, v)
|
||||
end
|
||||
p.on("--cut BITS", "3bit: [auto][half][chain]。既定 011") do |v|
|
||||
apply_cut_option(opts_hash, v)
|
||||
end
|
||||
p.on("--debug-dump PATH", "デバッグ: 印字バイト列を PATH に保存(1 印刷ごとに上書き)") do |v|
|
||||
opts_hash[:debug_dump] = v
|
||||
end
|
||||
p.on("-n", "--dry-run", "読み込みと検証のみ(USB なし)") { opts_hash[:dry_run] = true }
|
||||
p.on("--trim-right[=DOTS]", Integer,
|
||||
"右側空白を削減。DOTS省略時は左余白(失敗時 0)") do |v|
|
||||
@@ -212,6 +235,12 @@ module Libptouch
|
||||
parser.on("-p", "--pid PID", pid_option_description) do |v|
|
||||
apply_usb_pid_option(opts_hash, v)
|
||||
end
|
||||
parser.on("--cut BITS", "3bit: [auto][half][chain]。既定 011") do |v|
|
||||
apply_cut_option(opts_hash, v)
|
||||
end
|
||||
parser.on("--debug-dump PATH", "印字バイト列を PATH に保存") do |v|
|
||||
opts_hash[:debug_dump] = v
|
||||
end
|
||||
parser.on("-n", "--dry-run", "読み込みと検証のみ(USB なし)") { opts_hash[:dry_run] = true }
|
||||
parser.on("--trim-right[=DOTS]", Integer,
|
||||
"右側空白を削減。DOTS省略時は左余白(失敗時 0)") do |v|
|
||||
@@ -486,6 +515,7 @@ module Libptouch
|
||||
ctx = nil
|
||||
begin
|
||||
ctx = Libptouch::Context.new
|
||||
ctx.debug_dump_path = opts[:debug_dump] if opts[:debug_dump]
|
||||
usb_opened = false
|
||||
threshold = opts[:threshold]
|
||||
data, width, height = if kind == :svg
|
||||
@@ -508,11 +538,13 @@ module Libptouch
|
||||
data,
|
||||
width_dots: width,
|
||||
height_dots: height,
|
||||
right_padding_dots: trim_pad
|
||||
right_padding_dots: trim_pad,
|
||||
cut_flags: opts[:cut_flags]
|
||||
)
|
||||
end
|
||||
|
||||
ctx.check_raster(data, width_dots: width, height_dots: height)
|
||||
ctx.check_raster(data, width_dots: width, height_dots: height,
|
||||
cut_flags: opts[:cut_flags])
|
||||
|
||||
if opts[:dry_run]
|
||||
puts "dry-run OK: #{data.bytesize} bytes, src #{width}x#{height} dots (print lengthxwidth #{width}x#{height})"
|
||||
@@ -520,7 +552,8 @@ module Libptouch
|
||||
end
|
||||
|
||||
open_usb_for_opts(ctx, opts) if kind == :png && !usb_opened
|
||||
ctx.print_raster(data, width_dots: width, height_dots: height)
|
||||
ctx.print_raster(data, width_dots: width, height_dots: height,
|
||||
cut_flags: opts[:cut_flags])
|
||||
0
|
||||
rescue Libptouch::Error => e
|
||||
warn e.message
|
||||
|
||||
@@ -36,6 +36,11 @@ module Libptouch
|
||||
self
|
||||
end
|
||||
|
||||
def debug_dump_path=(path)
|
||||
Binding.libptouch_set_debug_dump_path(@native, path.nil? || path.to_s.empty? ? nil : path.to_s)
|
||||
self
|
||||
end
|
||||
|
||||
def close
|
||||
Binding.libptouch_close(@native) if @native && !@native.null?
|
||||
self
|
||||
@@ -47,11 +52,14 @@ module Libptouch
|
||||
@native = nil
|
||||
end
|
||||
|
||||
def check_raster(data, width_dots:, height_dots:, margin_mm: 0)
|
||||
def check_raster(data, width_dots:, height_dots:, margin_mm: 0, cut_flags: RASTER_FLAGS_DEFAULT)
|
||||
params = Binding::RasterParams.new
|
||||
params[:width_dots] = width_dots
|
||||
params[:height_dots] = height_dots
|
||||
params[:margin_mm] = margin_mm
|
||||
params[:flags] = cut_flags
|
||||
params[:reserved0] = 0
|
||||
params[:reserved1] = 0
|
||||
buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
||||
buf.put_bytes(0, data)
|
||||
raise_on_error(Binding.libptouch_check_raster(@native, buf, data.bytesize,
|
||||
@@ -59,11 +67,14 @@ module Libptouch
|
||||
self
|
||||
end
|
||||
|
||||
def print_raster(data, width_dots:, height_dots:, margin_mm: 0)
|
||||
def print_raster(data, width_dots:, height_dots:, margin_mm: 0, cut_flags: RASTER_FLAGS_DEFAULT)
|
||||
params = Binding::RasterParams.new
|
||||
params[:width_dots] = width_dots
|
||||
params[:height_dots] = height_dots
|
||||
params[:margin_mm] = margin_mm
|
||||
params[:flags] = cut_flags
|
||||
params[:reserved0] = 0
|
||||
params[:reserved1] = 0
|
||||
buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
||||
buf.put_bytes(0, data)
|
||||
raise_on_error(Binding.libptouch_print_raster(@native, buf, data.bytesize,
|
||||
@@ -115,11 +126,15 @@ module Libptouch
|
||||
[bytes, out_params[:width_dots], out_params[:height_dots]]
|
||||
end
|
||||
|
||||
def trim_right_blank_columns(data, width_dots:, height_dots:, margin_mm: 0, right_padding_dots: 0)
|
||||
def trim_right_blank_columns(data, width_dots:, height_dots:, margin_mm: 0,
|
||||
right_padding_dots: 0, cut_flags: RASTER_FLAGS_DEFAULT)
|
||||
in_params = Binding::RasterParams.new
|
||||
in_params[:width_dots] = width_dots
|
||||
in_params[:height_dots] = height_dots
|
||||
in_params[:margin_mm] = margin_mm
|
||||
in_params[:flags] = cut_flags
|
||||
in_params[:reserved0] = 0
|
||||
in_params[:reserved1] = 0
|
||||
in_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
||||
in_buf.put_bytes(0, data)
|
||||
out_pp = FFI::MemoryPointer.new(:pointer)
|
||||
|
||||
@@ -27,6 +27,9 @@ static void usage(const char *argv0)
|
||||
" -n, --dry-run 読み込みと check_raster のみ(USB なし)\n"
|
||||
" -v, --verbose 印刷前情報と印刷後ステータスを標準出力\n"
|
||||
" -p, --pid HEX USB 製品 ID(既定: P900W の 0x2085)。例: P750W 0x2062、P710BT 0x20af\n"
|
||||
" --cut BITS 3bit 指定: [auto-cut][half-cut][chain-print] (例: 010)\n"
|
||||
" 既定: 011(オートカットしない、ハーフカットする、つなげて印刷する)\n"
|
||||
" --debug-dump PATH デバッグ: USB に送った印字データをファイルへ保存(1 印刷ごとに上書き)\n"
|
||||
" -S, --status ステータスを表示して終了\n"
|
||||
" -V, --version バージョンを表示して終了\n"
|
||||
" -h, --help このヘルプ\n"
|
||||
@@ -103,6 +106,25 @@ static int read_file(const char *path, uint8_t **out, size_t *out_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_cut_bits(const char *s, uint8_t *out_flags)
|
||||
{
|
||||
if (!s || strlen(s) != 3u)
|
||||
return -1;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (s[i] != '0' && s[i] != '1')
|
||||
return -1;
|
||||
}
|
||||
uint8_t flags = 0u;
|
||||
if (s[0] == '1')
|
||||
flags |= LIBPTOUCH_RASTER_FLAG_AUTO_CUT;
|
||||
if (s[1] == '1')
|
||||
flags |= LIBPTOUCH_RASTER_FLAG_HALF_CUT;
|
||||
if (s[2] == '1')
|
||||
flags |= LIBPTOUCH_RASTER_FLAG_CHAIN_PRINT;
|
||||
*out_flags = flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void verbose_print_pre_print_info(libptouch_ctx *ctx,
|
||||
const libptouch_raster_params_t *params,
|
||||
size_t data_len)
|
||||
@@ -115,6 +137,11 @@ static void verbose_print_pre_print_info(libptouch_ctx *ctx,
|
||||
printf("raster size: %ux%u dots (length x width)\n",
|
||||
(unsigned)params->width_dots, (unsigned)params->height_dots);
|
||||
printf("margin_mm: %u\n", (unsigned)params->margin_mm);
|
||||
printf("raster flags: 0x%02X (auto-cut %s, half-cut %s, chain-print %s)\n",
|
||||
(unsigned)params->flags,
|
||||
(params->flags & LIBPTOUCH_RASTER_FLAG_AUTO_CUT) ? "on" : "off",
|
||||
(params->flags & LIBPTOUCH_RASTER_FLAG_HALF_CUT) ? "on" : "off",
|
||||
(params->flags & LIBPTOUCH_RASTER_FLAG_CHAIN_PRINT) ? "on" : "off");
|
||||
|
||||
libptouch_media_info_t mi;
|
||||
if (libptouch_get_current_media_info(ctx, &mi) == LIBPTOUCH_OK) {
|
||||
@@ -183,6 +210,8 @@ int main(int argc, char **argv)
|
||||
unsigned trim_right_dots = 0;
|
||||
int has_threshold = 0;
|
||||
int want_status = 0;
|
||||
uint8_t cut_flags = LIBPTOUCH_RASTER_FLAGS_DEFAULT;
|
||||
const char *debug_dump_path = NULL;
|
||||
static struct option longopts[] = {
|
||||
{ "width", required_argument, NULL, 'w' },
|
||||
{ "height", required_argument, NULL, 'H' },
|
||||
@@ -195,6 +224,8 @@ int main(int argc, char **argv)
|
||||
{ "status", no_argument, NULL, 'S' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "cut", required_argument, NULL, 1000 },
|
||||
{ "debug-dump", required_argument, NULL, 1001 },
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
||||
@@ -246,6 +277,16 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case 1000:
|
||||
if (parse_cut_bits(optarg, &cut_flags) != 0) {
|
||||
fprintf(stderr,
|
||||
"--cut must be 3 bits (e.g. 010: auto/half/chain)\n");
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case 1001:
|
||||
debug_dump_path = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
want_status = 1;
|
||||
break;
|
||||
@@ -329,10 +370,12 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "libptouch_create failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (debug_dump_path)
|
||||
libptouch_set_debug_dump_path(ctx, debug_dump_path);
|
||||
|
||||
uint8_t *data = NULL;
|
||||
size_t data_len = 0;
|
||||
libptouch_raster_params_t params = { 0, 0, 0 };
|
||||
libptouch_raster_params_t params = { 0 };
|
||||
libptouch_err_t e;
|
||||
int usb_opened = 0;
|
||||
int data_from_lib = 0;
|
||||
@@ -406,7 +449,7 @@ int main(int argc, char **argv)
|
||||
|
||||
uint8_t *trimmed = NULL;
|
||||
size_t trimmed_len = 0;
|
||||
libptouch_raster_params_t trimmed_params = { 0, 0, 0 };
|
||||
libptouch_raster_params_t trimmed_params = { 0 };
|
||||
e = libptouch_trim_right_blank_columns(
|
||||
ctx, data, data_len, ¶ms, pad, &trimmed, &trimmed_len,
|
||||
&trimmed_params);
|
||||
@@ -430,6 +473,10 @@ int main(int argc, char **argv)
|
||||
data_from_lib = 1;
|
||||
}
|
||||
|
||||
params.flags = cut_flags;
|
||||
params._reserved[0] = 0u;
|
||||
params._reserved[1] = 0u;
|
||||
|
||||
e = libptouch_check_raster(ctx, data, data_len, ¶ms);
|
||||
if (e != LIBPTOUCH_OK) {
|
||||
fprintf(stderr, "check_raster: %s\n",
|
||||
|
||||
@@ -55,9 +55,29 @@ void libptouch_destroy(libptouch_ctx *ctx)
|
||||
if (!ctx)
|
||||
return;
|
||||
libptouch_close(ctx);
|
||||
free(ctx->debug_dump_path);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void libptouch_set_debug_dump_path(libptouch_ctx *ctx, const char *path)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
free(ctx->debug_dump_path);
|
||||
ctx->debug_dump_path = NULL;
|
||||
ctx->debug_dump_truncate_next = 0;
|
||||
if (!path || !path[0])
|
||||
return;
|
||||
ctx->debug_dump_path = strdup(path);
|
||||
}
|
||||
|
||||
void ptouch_debug_dump_begin_print_job(libptouch_ctx *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
ctx->debug_dump_truncate_next = 1;
|
||||
}
|
||||
|
||||
const char *libptouch_strerror(const libptouch_ctx *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
|
||||
@@ -23,8 +23,13 @@ struct libptouch_ctx {
|
||||
uint8_t bulk_out_ep;
|
||||
uint8_t bulk_in_ep;
|
||||
uint16_t usb_pid; /* 0 if USB not open; used to pick 128- vs 560-dot raster */
|
||||
char *debug_dump_path; /* strdup; NULL = 印字データのファイル保存なし */
|
||||
int debug_dump_truncate_next; /* 次の bulk 書き込みでファイルを切り詰め(ジョブ先頭) */
|
||||
};
|
||||
|
||||
/** 1 回の libptouch_print_raster ジョブの先頭で呼ぶ(最初の bulk 前) */
|
||||
void ptouch_debug_dump_begin_print_job(libptouch_ctx *ctx);
|
||||
|
||||
/* ctx に最終エラー(コードとメッセージ)を記録する。公開 API のエラー返却前に使う。 */
|
||||
void ptouch_set_error(libptouch_ctx *ctx, libptouch_err_t code, const char *msg);
|
||||
/* libusb のエラー番号を人が読めるメッセージにして ptouch_set_error に渡す。 */
|
||||
|
||||
@@ -36,9 +36,8 @@ libptouch_err_t libptouch_png_file_to_raster(libptouch_ctx *ctx, const char *pat
|
||||
|
||||
*out_raster = NULL;
|
||||
*out_raster_bytes = 0;
|
||||
out_params->width_dots = 0;
|
||||
out_params->height_dots = 0;
|
||||
out_params->margin_mm = 0;
|
||||
memset(out_params, 0, sizeof(*out_params));
|
||||
out_params->flags = LIBPTOUCH_RASTER_FLAGS_DEFAULT;
|
||||
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
@@ -157,6 +156,7 @@ libptouch_err_t libptouch_png_file_to_raster(libptouch_ctx *ctx, const char *pat
|
||||
out_params->width_dots = (uint32_t)width;
|
||||
out_params->height_dots = (uint32_t)height;
|
||||
out_params->margin_mm = 0;
|
||||
out_params->flags = LIBPTOUCH_RASTER_FLAGS_DEFAULT;
|
||||
*out_raster = out;
|
||||
*out_raster_bytes = total;
|
||||
ptouch_set_error(ctx, LIBPTOUCH_OK, "");
|
||||
|
||||
@@ -156,11 +156,14 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
pos += sizeof(raster_mode);
|
||||
|
||||
uint8_t esc_iz[13];
|
||||
ptouch_fill_esc_iz(esc_iz, prof, media_kind, media_w, lines);
|
||||
ptouch_fill_esc_iz(esc_iz, prof, media_w, lines);
|
||||
memcpy(head + pos, esc_iz, sizeof(esc_iz));
|
||||
pos += sizeof(esc_iz);
|
||||
|
||||
static const uint8_t esc_im[] = { 0x1B, 0x69, 0x4D, 0x40 };
|
||||
/* ESC i M: bit6 オートカット(reference/印字データ.md)。既定オフ。 */
|
||||
uint8_t esc_im_n1 =
|
||||
(params->flags & LIBPTOUCH_RASTER_FLAG_AUTO_CUT) ? 0x40u : 0x00u;
|
||||
uint8_t esc_im[] = { 0x1B, 0x69, 0x4D, esc_im_n1 };
|
||||
memcpy(head + pos, esc_im, sizeof(esc_im));
|
||||
pos += sizeof(esc_im);
|
||||
|
||||
@@ -174,7 +177,9 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
pos += sizeof(esc_ia);
|
||||
}
|
||||
|
||||
uint8_t esc_ik[] = { 0x1B, 0x69, 0x4B, ptouch_esc_ik_value(head_dots) };
|
||||
uint8_t esc_ik_n1 =
|
||||
ptouch_esc_ik_extended_mode(ctx->usb_pid, params->flags);
|
||||
uint8_t esc_ik[] = { 0x1B, 0x69, 0x4B, esc_ik_n1 };
|
||||
memcpy(head + pos, esc_ik, sizeof(esc_ik));
|
||||
pos += sizeof(esc_ik);
|
||||
|
||||
@@ -190,6 +195,7 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
memcpy(head + pos, mode_m, sizeof(mode_m));
|
||||
pos += sizeof(mode_m);
|
||||
|
||||
ptouch_debug_dump_begin_print_job(ctx);
|
||||
v = ptouch_bulk_send_job(ctx, head, pos, "print preamble");
|
||||
if (v != LIBPTOUCH_OK) {
|
||||
free(transposed);
|
||||
|
||||
@@ -13,7 +13,7 @@ void ptouch_fill_gf_header(uint8_t out[3], size_t line_payload_bytes)
|
||||
}
|
||||
|
||||
void ptouch_fill_esc_iz(uint8_t out[13], const ptouch_printer_profile_t *prof,
|
||||
uint8_t media_kind, uint8_t media_width, uint32_t raster_lines)
|
||||
uint8_t media_width, uint32_t raster_lines)
|
||||
{
|
||||
uint8_t page_byte = 0x00u;
|
||||
if (prof && prof->family == LIBPTOUCH_FAMILY_P900)
|
||||
@@ -23,9 +23,9 @@ void ptouch_fill_esc_iz(uint8_t out[13], const ptouch_printer_profile_t *prof,
|
||||
out[1] = 0x69u;
|
||||
out[2] = 0x7Au;
|
||||
/* PI flags: enable media/width/length with quality bit for broad compatibility. */
|
||||
out[3] = 0x8Eu;
|
||||
out[3] = 0x84u;
|
||||
/* Use status media-kind byte directly (e.g., 0x01 laminated, 0x03 non-laminate). */
|
||||
out[4] = media_kind;
|
||||
out[4] = 0x00u;
|
||||
out[5] = media_width;
|
||||
out[6] = 0x00u;
|
||||
out[7] = (uint8_t)(raster_lines & 0xFFu);
|
||||
@@ -36,8 +36,22 @@ void ptouch_fill_esc_iz(uint8_t out[13], const ptouch_printer_profile_t *prof,
|
||||
out[12] = 0x00u; /* fixed */
|
||||
}
|
||||
|
||||
uint8_t ptouch_esc_ik_value(unsigned head_dots)
|
||||
uint8_t ptouch_esc_ik_extended_mode(uint16_t usb_pid, uint8_t raster_flags)
|
||||
{
|
||||
/* Preserve legacy 560-dot behaviour (0x0C), 128-dot uses 0x08. */
|
||||
return head_dots > 128u ? 0x0Cu : 0x08u;
|
||||
uint8_t n1 = 0x00u;
|
||||
int want_half = (raster_flags & LIBPTOUCH_RASTER_FLAG_HALF_CUT) != 0;
|
||||
int want_chain = (raster_flags & LIBPTOUCH_RASTER_FLAG_CHAIN_PRINT) != 0;
|
||||
|
||||
/*
|
||||
* reference/印字データ.md:
|
||||
* - bit2: ハーフカット
|
||||
* - bit3: ChainPrint しない
|
||||
*/
|
||||
if (usb_pid == LIBPTOUCH_USB_PID_PTP710BT)
|
||||
want_half = 0; /* PT-P710BT はハーフカット非対応 */
|
||||
if (want_half)
|
||||
n1 |= 0x04u;
|
||||
if (!want_chain)
|
||||
n1 |= 0x08u;
|
||||
return n1;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ void ptouch_fill_gf_header(uint8_t out[3], size_t line_payload_bytes);
|
||||
* P700 は 00h)。prof が NULL のときは 00h。
|
||||
*/
|
||||
void ptouch_fill_esc_iz(uint8_t out[13], const ptouch_printer_profile_t *prof,
|
||||
uint8_t media_kind, uint8_t media_width,
|
||||
uint32_t raster_lines);
|
||||
uint8_t ptouch_esc_ik_value(unsigned head_dots);
|
||||
uint8_t media_width, uint32_t raster_lines);
|
||||
/** ESC i K の n1: flags(オート/ハーフ/チェーン)と機種制約から算出。 */
|
||||
uint8_t ptouch_esc_ik_extended_mode(uint16_t usb_pid, uint8_t raster_flags);
|
||||
|
||||
#endif /* LIBPTOUCH_PROTOCOL_H */
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
libptouch_err_t libptouch_svg_file_to_raster_fit_current_tape(
|
||||
libptouch_ctx *ctx, const char *path,
|
||||
@@ -51,9 +52,8 @@ libptouch_err_t libptouch_svg_file_to_raster_fit_current_tape(
|
||||
|
||||
*out_raster = NULL;
|
||||
*out_raster_bytes = 0;
|
||||
out_params->width_dots = 0;
|
||||
out_params->height_dots = 0;
|
||||
out_params->margin_mm = 0;
|
||||
memset(out_params, 0, sizeof(*out_params));
|
||||
out_params->flags = LIBPTOUCH_RASTER_FLAGS_DEFAULT;
|
||||
|
||||
uint8_t st[LIBPTOUCH_STATUS_LENGTH];
|
||||
libptouch_err_t v = libptouch_get_status(ctx, st);
|
||||
@@ -203,6 +203,7 @@ libptouch_err_t libptouch_svg_file_to_raster_fit_current_tape(
|
||||
out_params->width_dots = out_w;
|
||||
out_params->height_dots = out_h;
|
||||
out_params->margin_mm = 0;
|
||||
out_params->flags = LIBPTOUCH_RASTER_FLAGS_DEFAULT;
|
||||
*out_raster = out;
|
||||
*out_raster_bytes = total;
|
||||
ptouch_set_error(ctx, LIBPTOUCH_OK, "");
|
||||
|
||||
@@ -79,6 +79,9 @@ libptouch_err_t libptouch_trim_right_blank_columns(
|
||||
out_params->width_dots = new_width;
|
||||
out_params->height_dots = height;
|
||||
out_params->margin_mm = in_params->margin_mm;
|
||||
out_params->flags = in_params->flags;
|
||||
out_params->_reserved[0] = in_params->_reserved[0];
|
||||
out_params->_reserved[1] = in_params->_reserved[1];
|
||||
ptouch_set_error(ctx, LIBPTOUCH_OK, "");
|
||||
return LIBPTOUCH_OK;
|
||||
}
|
||||
|
||||
@@ -194,5 +194,14 @@ libptouch_err_t ptouch_bulk_send_job(libptouch_ctx *ctx, const uint8_t *buf,
|
||||
ptouch_set_error(ctx, LIBPTOUCH_ERR_USB, msg);
|
||||
return LIBPTOUCH_ERR_USB;
|
||||
}
|
||||
if (ctx->debug_dump_path && ctx->debug_dump_path[0]) {
|
||||
FILE *fp = fopen(ctx->debug_dump_path,
|
||||
ctx->debug_dump_truncate_next ? "wb" : "ab");
|
||||
if (fp) {
|
||||
(void)fwrite(buf, 1, len, fp);
|
||||
(void)fclose(fp);
|
||||
}
|
||||
ctx->debug_dump_truncate_next = 0;
|
||||
}
|
||||
return LIBPTOUCH_OK;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "libptouch_protocol.h"
|
||||
|
||||
#include "libptouch.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -38,23 +40,38 @@ int main(void)
|
||||
fail |= expect_int("gf70_n2", gf[2], 0x00);
|
||||
|
||||
uint8_t iz[13];
|
||||
ptouch_fill_esc_iz(iz, &prof_fixture_p700, 0x01u, 0x0Cu, 70u);
|
||||
ptouch_fill_esc_iz(iz, &prof_fixture_p700, 0x0Cu, 70u);
|
||||
fail |= expect_int("iz_cmd_0", iz[0], 0x1B);
|
||||
fail |= expect_int("iz_cmd_1", iz[1], 0x69);
|
||||
fail |= expect_int("iz_cmd_2", iz[2], 0x7A);
|
||||
fail |= expect_int("iz_n1_flags", iz[3], 0x8E);
|
||||
fail |= expect_int("iz_media_kind_passthrough", iz[4], 0x01);
|
||||
fail |= expect_int("iz_n1_flags", iz[3], 0x84);
|
||||
fail |= expect_int("iz_media_kind_fixed", iz[4], 0x00);
|
||||
fail |= expect_int("iz_media_width", iz[5], 0x0C);
|
||||
fail |= expect_int("iz_lines_lsb", iz[7], 70);
|
||||
fail |= expect_int("iz_page_control_p700", iz[11], 0x00);
|
||||
fail |= expect_int("iz_last_fixed", iz[12], 0x00);
|
||||
|
||||
ptouch_fill_esc_iz(iz, &prof_fixture_p900, 0x01u, 0x0Cu, 70u);
|
||||
ptouch_fill_esc_iz(iz, &prof_fixture_p900, 0x0Cu, 70u);
|
||||
fail |= expect_int("iz_page_control_p900_single", iz[11], 0x02);
|
||||
|
||||
/* ESC i K mode byte: 128-dot vs 560-dot families */
|
||||
fail |= expect_int("esc_ik_128", ptouch_esc_ik_value(128u), 0x08);
|
||||
fail |= expect_int("esc_ik_560", ptouch_esc_ik_value(560u), 0x0C);
|
||||
/* ESC i K: bit2=ハーフカット、bit3=ChainPrintしない */
|
||||
fail |= expect_int(
|
||||
"esc_ik_p750w_half_chain",
|
||||
(int)ptouch_esc_ik_extended_mode(
|
||||
LIBPTOUCH_USB_PID_PTP750W, LIBPTOUCH_RASTER_FLAGS_DEFAULT),
|
||||
0x04);
|
||||
fail |= expect_int(
|
||||
"esc_ik_p710bt_no_half",
|
||||
(int)ptouch_esc_ik_extended_mode(
|
||||
LIBPTOUCH_USB_PID_PTP710BT, LIBPTOUCH_RASTER_FLAGS_DEFAULT),
|
||||
0x00);
|
||||
fail |= expect_int(
|
||||
"esc_ik_p900w_auto_half_no_chain",
|
||||
(int)ptouch_esc_ik_extended_mode(
|
||||
LIBPTOUCH_USB_PID_PTP900W,
|
||||
LIBPTOUCH_RASTER_FLAG_AUTO_CUT |
|
||||
LIBPTOUCH_RASTER_FLAG_HALF_CUT),
|
||||
0x0C);
|
||||
|
||||
return fail ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user