libptouch の更新に追従
This commit is contained in:
@@ -22,6 +22,7 @@ struct libptouch_ctx {
|
||||
int claimed_interface; /* -1 if none */
|
||||
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 */
|
||||
};
|
||||
|
||||
void ptouch_set_error(libptouch_ctx *ctx, libptouch_err_t code, const char *msg);
|
||||
|
||||
159
src/lib/libptouch_layout.c
Normal file
159
src/lib/libptouch_layout.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* libptouch — layout tables and profile resolution (Brother raster PDFs)
|
||||
*
|
||||
* Author: knb
|
||||
* Email: knb@artif.org
|
||||
*/
|
||||
|
||||
#include "libptouch_layout.h"
|
||||
|
||||
/* --- cv_ptp900_jpn_raster_102.pdf: TZe / その他(HS 以外で共通レイアウトを使う帯) --- */
|
||||
static const ptouch_layout_row_t layout_tze_560[] = {
|
||||
{ 0x04, 248, 48, 264 },
|
||||
{ 0x06, 240, 64, 256 },
|
||||
{ 0x09, 219, 106, 235 },
|
||||
{ 0x0C, 197, 150, 213 },
|
||||
{ 0x12, 155, 234, 171 },
|
||||
{ 0x18, 112, 320, 128 },
|
||||
{ 0x24, 45, 454, 61 },
|
||||
};
|
||||
|
||||
static const ptouch_layout_row_t layout_hs_560[] = {
|
||||
{ 0x06, 244, 56, 260 },
|
||||
{ 0x09, 224, 96, 240 },
|
||||
{ 0x0C, 206, 132, 222 },
|
||||
{ 0x12, 166, 212, 182 },
|
||||
{ 0x18, 144, 256, 160 },
|
||||
};
|
||||
|
||||
/* --- cv_ptp750w_710bt_jpn_raster_102.pdf --- */
|
||||
static const ptouch_layout_row_t layout_tze_128[] = {
|
||||
{ 0x04, 52, 24, 52 },
|
||||
{ 0x06, 48, 32, 48 },
|
||||
{ 0x09, 39, 50, 39 },
|
||||
{ 0x0C, 29, 70, 29 },
|
||||
{ 0x12, 8, 112, 8 },
|
||||
{ 0x18, 0, 128, 0 },
|
||||
};
|
||||
|
||||
static const ptouch_layout_row_t layout_hs_128[] = {
|
||||
{ 0x06, 50, 28, 50 },
|
||||
{ 0x09, 40, 48, 40 },
|
||||
{ 0x0C, 31, 66, 31 },
|
||||
{ 0x12, 11, 106, 11 },
|
||||
{ 0x18, 0, 128, 0 },
|
||||
};
|
||||
|
||||
static const uint16_t pids_128pin[] = {
|
||||
LIBPTOUCH_USB_PID_PTP750W,
|
||||
LIBPTOUCH_USB_PID_PTP710BT,
|
||||
0,
|
||||
};
|
||||
|
||||
static const uint8_t models_128pin[] = {
|
||||
0x68, /* PT-P750W */
|
||||
0x76, /* PT-P710BT */
|
||||
0,
|
||||
};
|
||||
|
||||
static const ptouch_printer_profile_t ptouch_layout_profiles[] = {
|
||||
{
|
||||
.usb_pids = pids_128pin,
|
||||
.model_codes = models_128pin,
|
||||
.is_default = 0,
|
||||
.head_width_dots = 128u,
|
||||
.margin_feed_dpi = 180.0,
|
||||
.margin_feed_max_dots = 900u,
|
||||
.tze = layout_tze_128,
|
||||
.tze_count = sizeof(layout_tze_128) / sizeof(layout_tze_128[0]),
|
||||
.hs = layout_hs_128,
|
||||
.hs_count = sizeof(layout_hs_128) / sizeof(layout_hs_128[0]),
|
||||
.doc_ref = "cv_ptp750w_710bt_jpn_raster_102.pdf",
|
||||
},
|
||||
{
|
||||
.usb_pids = NULL,
|
||||
.model_codes = NULL,
|
||||
.is_default = 1,
|
||||
.head_width_dots = 560u,
|
||||
.margin_feed_dpi = 360.0,
|
||||
.margin_feed_max_dots = 1800u,
|
||||
.tze = layout_tze_560,
|
||||
.tze_count = sizeof(layout_tze_560) / sizeof(layout_tze_560[0]),
|
||||
.hs = layout_hs_560,
|
||||
.hs_count = sizeof(layout_hs_560) / sizeof(layout_hs_560[0]),
|
||||
.doc_ref = "cv_ptp900_jpn_raster_102.pdf (560-dot family)",
|
||||
},
|
||||
};
|
||||
|
||||
static int pid_in_list(const uint16_t *list, uint16_t pid)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
for (; *list; list++) {
|
||||
if (*list == pid)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int model_in_list(const uint8_t *list, uint8_t code)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
for (; *list; list++) {
|
||||
if (*list == code)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ptouch_printer_profile_t *ptouch_layout_resolve_profile(uint16_t usb_pid,
|
||||
uint8_t status_model_byte)
|
||||
{
|
||||
const ptouch_printer_profile_t *fallback = NULL;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < sizeof(ptouch_layout_profiles) / sizeof(ptouch_layout_profiles[0]);
|
||||
i++) {
|
||||
const ptouch_printer_profile_t *p = &ptouch_layout_profiles[i];
|
||||
if (p->is_default) {
|
||||
fallback = p;
|
||||
continue;
|
||||
}
|
||||
if (pid_in_list(p->usb_pids, usb_pid) ||
|
||||
model_in_list(p->model_codes, status_model_byte))
|
||||
return p;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
static libptouch_err_t layout_lookup_table(const ptouch_layout_row_t *table, size_t n,
|
||||
uint8_t media_wbyte, uint16_t *left,
|
||||
uint16_t *print_dots, uint16_t *right)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (table[i].media_wbyte != media_wbyte)
|
||||
continue;
|
||||
*left = table[i].left_dots;
|
||||
*print_dots = table[i].print_dots;
|
||||
*right = table[i].right_dots;
|
||||
return LIBPTOUCH_OK;
|
||||
}
|
||||
return LIBPTOUCH_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
libptouch_err_t ptouch_layout_from_status(const ptouch_printer_profile_t *prof,
|
||||
uint8_t media_kind, uint8_t media_wbyte,
|
||||
uint16_t *left_dots, uint16_t *print_dots,
|
||||
uint16_t *right_dots)
|
||||
{
|
||||
if (!prof || !left_dots || !print_dots || !right_dots)
|
||||
return LIBPTOUCH_ERR_ARG;
|
||||
|
||||
int is_hs = (media_kind == 0x11u || media_kind == 0x17u);
|
||||
const ptouch_layout_row_t *table = is_hs ? prof->hs : prof->tze;
|
||||
size_t n = is_hs ? prof->hs_count : prof->tze_count;
|
||||
|
||||
return layout_lookup_table(table, n, media_wbyte, left_dots, print_dots,
|
||||
right_dots);
|
||||
}
|
||||
50
src/lib/libptouch_layout.h
Normal file
50
src/lib/libptouch_layout.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* libptouch — tape width → printable dots (data tables per printer family)
|
||||
*
|
||||
* Author: knb
|
||||
* Email: knb@artif.org
|
||||
*/
|
||||
|
||||
#ifndef LIBPTOUCH_LAYOUT_H
|
||||
#define LIBPTOUCH_LAYOUT_H
|
||||
|
||||
#include "libptouch.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** One row: status byte st[10] (media width code) when it matches this tape width slot */
|
||||
typedef struct ptouch_layout_row {
|
||||
uint8_t media_wbyte;
|
||||
uint16_t left_dots;
|
||||
uint16_t print_dots;
|
||||
uint16_t right_dots;
|
||||
} ptouch_layout_row_t;
|
||||
|
||||
/**
|
||||
* Printer family: USB PID / status model byte select a profile; tables supply layouts.
|
||||
* New models: add a row to @ref ptouch_layout_profiles or add TZe/HS rows to existing tables.
|
||||
*/
|
||||
typedef struct ptouch_printer_profile {
|
||||
const uint16_t *usb_pids; /* 0-terminated; NULL = do not match on PID */
|
||||
const uint8_t *model_codes; /* 0-terminated; NULL = do not match on status[4] */
|
||||
int is_default; /* 1 = fallback when no other profile matches */
|
||||
unsigned head_width_dots; /* 128 or 560; full raster width for pack/GF payload */
|
||||
double margin_feed_dpi; /* ESC i d feed dots per inch (PDF) */
|
||||
unsigned margin_feed_max_dots;
|
||||
const ptouch_layout_row_t *tze;
|
||||
size_t tze_count;
|
||||
const ptouch_layout_row_t *hs;
|
||||
size_t hs_count;
|
||||
const char *doc_ref;
|
||||
} ptouch_printer_profile_t;
|
||||
|
||||
const ptouch_printer_profile_t *ptouch_layout_resolve_profile(uint16_t usb_pid,
|
||||
uint8_t status_model_byte);
|
||||
|
||||
libptouch_err_t ptouch_layout_from_status(const ptouch_printer_profile_t *prof,
|
||||
uint8_t media_kind, uint8_t media_wbyte,
|
||||
uint16_t *left_dots, uint16_t *print_dots,
|
||||
uint16_t *right_dots);
|
||||
|
||||
#endif /* LIBPTOUCH_LAYOUT_H */
|
||||
@@ -6,96 +6,18 @@
|
||||
*/
|
||||
|
||||
#include "libptouch_internal.h"
|
||||
#include "libptouch_layout.h"
|
||||
|
||||
#include <libusb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* cv_ptp900_jpn_raster_102.pdf: テープ幅から印刷可能ドット */
|
||||
static libptouch_err_t layout_from_status(uint8_t media_kind, uint8_t media_wbyte,
|
||||
uint16_t *left, uint16_t *print_dots,
|
||||
uint16_t *right)
|
||||
static void pack_line(uint8_t *line, size_t line_bytes, unsigned head_dots,
|
||||
const uint8_t *row, uint32_t width_dots, uint16_t left_dots,
|
||||
uint16_t print_dots)
|
||||
{
|
||||
if (media_kind == 0x11u || media_kind == 0x17u) {
|
||||
switch (media_wbyte) {
|
||||
case 0x06:
|
||||
*left = 244;
|
||||
*print_dots = 56;
|
||||
*right = 260;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x09:
|
||||
*left = 224;
|
||||
*print_dots = 96;
|
||||
*right = 240;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x0C:
|
||||
*left = 206;
|
||||
*print_dots = 132;
|
||||
*right = 222;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x12:
|
||||
*left = 166;
|
||||
*print_dots = 212;
|
||||
*right = 182;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x18:
|
||||
*left = 144;
|
||||
*print_dots = 256;
|
||||
*right = 160;
|
||||
return LIBPTOUCH_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (media_wbyte) {
|
||||
case 0x04:
|
||||
*left = 248;
|
||||
*print_dots = 48;
|
||||
*right = 264;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x06:
|
||||
*left = 240;
|
||||
*print_dots = 64;
|
||||
*right = 256;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x09:
|
||||
*left = 219;
|
||||
*print_dots = 106;
|
||||
*right = 235;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x0C:
|
||||
*left = 197;
|
||||
*print_dots = 150;
|
||||
*right = 213;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x12:
|
||||
*left = 155;
|
||||
*print_dots = 234;
|
||||
*right = 171;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x18:
|
||||
*left = 112;
|
||||
*print_dots = 320;
|
||||
*right = 128;
|
||||
return LIBPTOUCH_OK;
|
||||
case 0x24:
|
||||
*left = 45;
|
||||
*print_dots = 454;
|
||||
*right = 61;
|
||||
return LIBPTOUCH_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
(void)media_kind;
|
||||
return LIBPTOUCH_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* cv_ptp900_jpn_raster_102.pdf: 2.3.5 ラスターライン(全 560 ドット = 70 バイト) */
|
||||
static void pack_line_560(uint8_t line[70], const uint8_t *row, uint32_t width_dots,
|
||||
uint16_t left_dots, uint16_t print_dots)
|
||||
{
|
||||
memset(line, 0, 70u);
|
||||
memset(line, 0, line_bytes);
|
||||
if (width_dots > (uint32_t)print_dots)
|
||||
return;
|
||||
uint32_t start = (uint32_t)left_dots +
|
||||
@@ -106,7 +28,7 @@ static void pack_line_560(uint8_t line[70], const uint8_t *row, uint32_t width_d
|
||||
if (((row[ubyte] >> ubit) & 1u) == 0)
|
||||
continue;
|
||||
uint32_t dot = start + x;
|
||||
if (dot >= 560u)
|
||||
if (dot >= (uint32_t)head_dots)
|
||||
break;
|
||||
uint32_t b = dot / 8u;
|
||||
uint32_t bi = 7u - (dot % 8u);
|
||||
@@ -158,11 +80,19 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
if (v != LIBPTOUCH_OK)
|
||||
return v;
|
||||
|
||||
const ptouch_printer_profile_t *prof =
|
||||
ptouch_layout_resolve_profile(ctx->usb_pid, st[4]);
|
||||
if (!prof) {
|
||||
ptouch_set_error(ctx, LIBPTOUCH_ERR_UNSUPPORTED,
|
||||
"no layout profile for this printer");
|
||||
return LIBPTOUCH_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
uint8_t media_kind = st[11];
|
||||
uint8_t media_w = st[10];
|
||||
uint16_t left_dots, print_dots, right_dots;
|
||||
v = layout_from_status(media_kind, media_w, &left_dots, &print_dots,
|
||||
&right_dots);
|
||||
v = ptouch_layout_from_status(prof, media_kind, media_w, &left_dots,
|
||||
&print_dots, &right_dots);
|
||||
if (v != LIBPTOUCH_OK) {
|
||||
ptouch_set_error(ctx, LIBPTOUCH_ERR_UNSUPPORTED,
|
||||
"tape width/layout not supported for this media "
|
||||
@@ -171,6 +101,10 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
}
|
||||
(void)right_dots;
|
||||
|
||||
unsigned head_dots = prof->head_width_dots;
|
||||
size_t line_payload = (size_t)((head_dots + 7u) / 8u);
|
||||
size_t gf_packet = 3u + line_payload;
|
||||
|
||||
uint32_t wd = params->width_dots;
|
||||
uint32_t ht = params->height_dots;
|
||||
uint8_t *transposed = transpose_raster_alloc(data, wd, ht, &wd, &ht);
|
||||
@@ -191,15 +125,17 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
return LIBPTOUCH_ERR_ARG;
|
||||
}
|
||||
|
||||
double margin_dpi = prof->margin_feed_dpi;
|
||||
unsigned margin_max = prof->margin_feed_max_dots;
|
||||
unsigned margin_dots = 14u;
|
||||
if (params->margin_mm > 0) {
|
||||
margin_dots = (unsigned)((double)params->margin_mm * 360.0 /
|
||||
margin_dots = (unsigned)((double)params->margin_mm * margin_dpi /
|
||||
25.4 +
|
||||
0.5);
|
||||
if (margin_dots < 14u)
|
||||
margin_dots = 14u;
|
||||
if (margin_dots > 1800u)
|
||||
margin_dots = 1800u;
|
||||
if (margin_dots > margin_max)
|
||||
margin_dots = margin_max;
|
||||
}
|
||||
|
||||
uint32_t lines = ht;
|
||||
@@ -263,19 +199,29 @@ libptouch_err_t libptouch_print_raster(libptouch_ctx *ctx,
|
||||
}
|
||||
|
||||
size_t row_b = ((size_t)wd + 7u) / 8u;
|
||||
uint8_t gbuf[73];
|
||||
static const uint8_t g_hdr[] = { 0x47, 0x46, 0x00 };
|
||||
|
||||
uint8_t *gbuf = (uint8_t *)malloc(gf_packet);
|
||||
if (!gbuf) {
|
||||
ptouch_set_error(ctx, LIBPTOUCH_ERR_NOMEM,
|
||||
"raster line buffer");
|
||||
free(transposed);
|
||||
return LIBPTOUCH_ERR_NOMEM;
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < lines; y++) {
|
||||
const uint8_t *row = src + (size_t)y * row_b;
|
||||
pack_line_560(gbuf + 3, row, wd, left_dots, print_dots);
|
||||
pack_line(gbuf + 3, line_payload, head_dots, row, wd, left_dots,
|
||||
print_dots);
|
||||
memcpy(gbuf, g_hdr, sizeof(g_hdr));
|
||||
v = ptouch_bulk_send_job(ctx, gbuf, sizeof(gbuf), "raster line");
|
||||
v = ptouch_bulk_send_job(ctx, gbuf, gf_packet, "raster line");
|
||||
if (v != LIBPTOUCH_OK) {
|
||||
free(gbuf);
|
||||
free(transposed);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
free(gbuf);
|
||||
|
||||
static const uint8_t print_end[] = { 0x1A };
|
||||
v = ptouch_bulk_send_job(ctx, print_end, sizeof(print_end), "print end");
|
||||
|
||||
@@ -75,6 +75,12 @@ static void fprint_model(FILE *fp, uint8_t code)
|
||||
case 0x78:
|
||||
name = "PT-P910BT";
|
||||
break;
|
||||
case 0x68:
|
||||
name = "PT-P750W";
|
||||
break;
|
||||
case 0x76:
|
||||
name = "PT-P710BT";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ libptouch_err_t libptouch_open_usb_vid_pid(libptouch_ctx *ctx, uint16_t vid,
|
||||
(void)libusb_clear_halt(h, ctx->bulk_out_ep);
|
||||
(void)libusb_clear_halt(h, ctx->bulk_in_ep);
|
||||
|
||||
ctx->usb_pid = pid;
|
||||
ctx->usb_open = 1;
|
||||
ptouch_set_error(ctx, LIBPTOUCH_OK, "");
|
||||
return LIBPTOUCH_OK;
|
||||
@@ -141,6 +142,7 @@ void libptouch_close(libptouch_ctx *ctx)
|
||||
}
|
||||
ctx->bulk_out_ep = 0;
|
||||
ctx->bulk_in_ep = 0;
|
||||
ctx->usb_pid = 0;
|
||||
ctx->usb_open = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user