1
0
mirror of https://git.familie-radermacher.ch/linux/ptouch-print.git synced 2025-09-16 11:55:44 +00:00

Compare commits

..

17 Commits
v1.6 ... master

Author SHA1 Message Date
Dominic Radermacher
e730c3b480 better help text for newline arg, rename build script 2025-08-11 15:09:36 +02:00
Dominic Radermacher
d293e9427d coding style cosmetics 2025-08-11 09:57:02 +02:00
Michael Schulz
92c1e43f0c improved argv parser, enable printing of text starting with a dash 2025-08-11 09:49:18 +02:00
Dominic Radermacher
3bcde60eea update po files 2025-08-10 08:28:40 +02:00
Frost
f1c34dd0d4 Send chain magic after precut
This lets you do chain mode with a precut first.
2025-08-10 08:23:56 +02:00
Frost
f59e19349b Print without the default length margins
Brother's software may default to 0x0e, but that probably assumes you're making text labels and not printing images. For printing images you might want borderless (we certainly do), and for text labels you can always add the margins to the label before printing.

This commit uses 1px length margins instead of 0 to prevent some leftover black on the edges of the next print.
2025-08-10 08:22:39 +02:00
Dominic Radermacher
ab80c721f6 fix compile warning 2025-08-10 07:23:11 +02:00
Dominic Radermacher
d7d97eede8 fix gettext.cmake 2025-08-03 14:21:56 +02:00
Dominic Radermacher
d1eeacbdd8 Added USB IDs for PT-E550W, but doesn't work yet (only prints empty tape) 2025-08-03 10:11:15 +02:00
Dominic Radermacher
efa48162a8 better gettext support (thanks to Michael Schulz) 2025-08-03 09:42:30 +02:00
Dominic Radermacher
1f450d9124 Add support for PT-E310BT (thanks to Christian Radin) 2025-06-22 08:13:08 +02:00
Marcus Müller
1a39fe1284 udev uaccess rules must have lower order than 73-seat-late.rules
see, for example, https://github.com/bigbigmdm/IMSProg/issues/98 . If the rule granting uaccess tag to a device is loaded after the seat-late rule, seat-late can't grant the user access to the device.

Signed-off-by: Marcus Müller <mueller@baseband.digital>
2025-06-01 20:15:29 +02:00
Dominic Radermacher
2c9828af87 add support for PT-9200DX, thanks Ralf Lieb for reporting 2025-06-01 20:12:20 +02:00
Dominic Radermacher
2f18522602 fix segfault for last commit 2025-05-19 13:33:55 +02:00
Dominic Radermacher
140bf0a6cc for printers with less than 128px printhead, make sure we dont print too much pixels 2025-05-12 18:29:56 +02:00
Dominic Radermacher
a6c67df2c9 cosmetics 2025-05-12 17:59:45 +02:00
Dominic Radermacher
ec923ed579 Add support for PT-2300 and fix 112px width centering (thanks to Bradley Erickson) 2025-05-12 17:47:00 +02:00
11 changed files with 838 additions and 730 deletions

View File

@ -37,7 +37,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
target_sources(${PROJECT_NAME} PRIVATE target_sources(${PROJECT_NAME} PRIVATE
include/ptouch.h include/ptouch.h
include/gettext.h
src/libptouch.c src/libptouch.c
src/ptouch-print.c src/ptouch-print.c
) )
@ -66,11 +65,13 @@ add_custom_target(git-version ALL
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/gitversion.cmake ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/gitversion.cmake
) )
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/gettext.cmake)
install(TARGETS ${PROJECT_NAME} DESTINATION bin) install(TARGETS ${PROJECT_NAME} DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ptouch-print.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ptouch-print.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
if(EXISTS /etc/udev/rules.d) if(EXISTS /etc/udev/rules.d)
install(FILES udev/90-usb-ptouch-permissions.rules DESTINATION /etc/udev/rules.d) install(FILES udev/20-usb-ptouch-permissions.rules DESTINATION /etc/udev/rules.d)
install(CODE "execute_process(COMMAND udevadm control --reload-rules)") install(CODE "execute_process(COMMAND udevadm control --reload-rules)")
endif() endif()

2
README
View File

@ -16,7 +16,7 @@ https://dominic.familie-radermacher.ch/projekte/ptouch-print/
Compile instructions: Compile instructions:
./build.sh ./compile.sh
Note: Note:

72
cmake/gettext.cmake Normal file
View File

@ -0,0 +1,72 @@
# Utilize gettext multilingual internationalization services
if(Gettext_FOUND)
# generate pot files using xgettext
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
if(GETTEXT_XGETTEXT_EXECUTABLE)
add_custom_target(
pot-update
ALL
DEPENDS ${CMAKE_SOURCE_DIR}/po/ptouch.pot
)
file(GLOB_RECURSE C_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/*.c)
add_custom_command(
TARGET pot-update
PRE_BUILD
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE}
--keyword=_
--keyword=N_
--force-po
--package-name=${PROJECT_NAME}
--copyright-holder="Dominic Radermacher <dominic@familie-radermacher.ch>"
--msgid-bugs-address="dominic@familie-radermacher.ch"
--output ${CMAKE_SOURCE_DIR}/po/ptouch.pot
${C_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# read available languages from LINGUAS file while ignoring comments
file(STRINGS po/LINGUAS LINGUAS REGEX "^[^#]")
# merge po files
find_program(GETTEXT_MSGMERGE_EXECUTABLE msgmerge)
if(GETTEXT_MSGMERGE_EXECUTABLE)
add_custom_target(
po-merge
ALL
DEPENDS ${CMAKE_SOURCE_DIR}/po/ptouch.pot
)
add_dependencies(po-merge pot-update)
foreach(LINGUA IN LISTS LINGUAS)
add_custom_command(
TARGET po-merge
PRE_BUILD
COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE}
--update
--quiet
${CMAKE_SOURCE_DIR}/po/${LINGUA}.po
${CMAKE_SOURCE_DIR}/po/ptouch.pot
)
endforeach()
endif()
endif()
# compile po files
foreach(LINGUA IN LISTS LINGUAS)
gettext_process_po_files(
${LINGUA}
ALL
PO_FILES ${CMAKE_SOURCE_DIR}/po/${LINGUA}.po
)
endforeach()
# install mo files
foreach(LINGUA IN LISTS LINGUAS)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${LINGUA}.gmo"
DESTINATION "${CMAKE_INSTALL_LOCALEDIR}/${LINGUA}/LC_MESSAGES"
RENAME "${PROJECT_NAME}.mo"
)
endforeach()
endif()

View File

@ -1,288 +0,0 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2011, 2015 Free
Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# undef gettext
# define gettext(Msgid) ((const char *) (Msgid))
# undef dgettext
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# undef dcgettext
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
# undef dngettext
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# undef dcngettext
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
# undef textdomain
# define textdomain(Domainname) ((const char *) (Domainname))
# undef bindtextdomain
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
# undef bind_textdomain_codeset
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
#endif
/* Prefer gnulib's setlocale override over libintl's setlocale override. */
#ifdef GNULIB_defined_setlocale
# undef setlocale
# define setlocale rpl_setlocale
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
#else
# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
#endif
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

171
po/de.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: ptouch-print 1.3.1\n" "Project-Id-Version: ptouch-print 1.3.1\n"
"Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n"
"POT-Creation-Date: 2024-05-23 22:20-0400\n" "POT-Creation-Date: 2025-08-11 09:57+0200\n"
"PO-Revision-Date: 2024-05-23 22:27-0400\n" "PO-Revision-Date: 2024-05-23 22:27-0400\n"
"Last-Translator: dominic@familie-radermacher.ch\n" "Last-Translator: dominic@familie-radermacher.ch\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n" "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@ -19,218 +19,293 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.2\n" "X-Generator: Poedit 2.4.2\n"
#: src/libptouch.c:95 src/libptouch.c:99 src/libptouch.c:103 #: src/libptouch.c:105 src/libptouch.c:109 src/libptouch.c:113
#, c-format #, c-format
msgid "out of memory\n" msgid "out of memory\n"
msgstr "Nicht genug Speicher\n" msgstr "Nicht genug Speicher\n"
#: src/libptouch.c:107 #: src/libptouch.c:117
#, c-format #, c-format
msgid "libusb_init() failed\n" msgid "libusb_init() failed\n"
msgstr "ptouch_init() fehlgeschlagen\n" msgstr "ptouch_init() fehlgeschlagen\n"
#: src/libptouch.c:116 #: src/libptouch.c:126
#, c-format #, c-format
msgid "failed to get device descriptor" msgid "failed to get device descriptor"
msgstr "" msgstr ""
#: src/libptouch.c:122 #: src/libptouch.c:132
#, c-format #, c-format
msgid "%s found on USB bus %d, device %d\n" msgid "%s found on USB bus %d, device %d\n"
msgstr "Drucker %s am USB Bus %d, Gerät %d gefunden\n" msgstr "Drucker %s am USB Bus %d, Gerät %d gefunden\n"
#: src/libptouch.c:137 #: src/libptouch.c:147
#, c-format #, c-format
msgid "libusb_open error :%s\n" msgid "libusb_open error :%s\n"
msgstr "" msgstr ""
#: src/libptouch.c:143 #: src/libptouch.c:153
#, c-format #, c-format
msgid "error while detaching kernel driver: %s\n" msgid "error while detaching kernel driver: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:147 #: src/libptouch.c:157
#, c-format #, c-format
msgid "interface claim error: %s\n" msgid "interface claim error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:158 #: src/libptouch.c:168
#, c-format #, c-format
msgid "No P-Touch printer found on USB (remember to put switch to position E)\n" msgid ""
"No P-Touch printer found on USB (remember to put switch to position E)\n"
msgstr "Kein P-Ptouch Drucker am USB gefunden (Schalter muss auf E stehen)\n" msgstr "Kein P-Ptouch Drucker am USB gefunden (Schalter muss auf E stehen)\n"
#: src/libptouch.c:178 #: src/libptouch.c:188
#, c-format
msgid "debug: called ptouch_send() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:195
#, c-format #, c-format
msgid "write error: %s\n" msgid "write error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:182 #: src/libptouch.c:199
#, fuzzy, c-format #, fuzzy, c-format
#| msgid "read error: got %i instead of 32 bytes\n"
msgid "write error: could send only %i of %ld bytes\n" msgid "write error: could send only %i of %ld bytes\n"
msgstr "Lesefehler: %i anstatt 32 bytes empfangen\n" msgstr "Lesefehler: %i anstatt 32 bytes empfangen\n"
#: src/libptouch.c:302 #: src/libptouch.c:249
#, c-format
msgid "debug: called ptouch_info_cmd() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:291
#, fuzzy, c-format
msgid "debug: called ptouch_rasterstart() with NULL ptdev\n"
msgstr "ptouch_rasterstart() fehlgeschlagen\n"
#: src/libptouch.c:322
#, c-format
msgid "debug: called ptouch_finalize() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:337
#, c-format #, c-format
msgid "debug: dumping raw status bytes\n" msgid "debug: dumping raw status bytes\n"
msgstr "" msgstr ""
#: src/libptouch.c:326 src/libptouch.c:362 #: src/libptouch.c:356
#, c-format
msgid "debug: called ptouch_getstatus() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:366 src/libptouch.c:402
#, c-format #, c-format
msgid "read error: %s\n" msgid "read error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:331 #: src/libptouch.c:371
#, c-format #, c-format
msgid "timeout while waiting for status response\n" msgid "timeout while waiting for status response\n"
msgstr "" msgstr ""
#: src/libptouch.c:345 #: src/libptouch.c:385
#, c-format #, c-format
msgid "unknown tape width of %imm, please report this.\n" msgid "unknown tape width of %imm, please report this.\n"
msgstr "Unbekannte Schriftband breite (%i mm), bitte melden\n" msgstr "Unbekannte Schriftband breite (%i mm), bitte melden\n"
#: src/libptouch.c:351 #: src/libptouch.c:391
#, c-format #, c-format
msgid "got only 16 bytes... wondering what they are:\n" msgid "got only 16 bytes... wondering what they are:\n"
msgstr "nur 16 bytes empfangen... mal gucken was die sind:\n" msgstr "nur 16 bytes empfangen... mal gucken was die sind:\n"
#: src/libptouch.c:355 #: src/libptouch.c:395
#, c-format #, c-format
msgid "read error: got %i instead of 32 bytes\n" msgid "read error: got %i instead of 32 bytes\n"
msgstr "Lesefehler: %i anstatt 32 bytes empfangen\n" msgstr "Lesefehler: %i anstatt 32 bytes empfangen\n"
#: src/libptouch.c:358 #: src/libptouch.c:398
#, c-format #, c-format
msgid "strange status:\n" msgid "strange status:\n"
msgstr "Seltsamer Status:\n" msgstr "Seltsamer Status:\n"
#: src/libptouch.c:360 #: src/libptouch.c:400
#, c-format #, c-format
msgid "trying to flush junk\n" msgid "trying to flush junk\n"
msgstr "" msgstr ""
#: src/libptouch.c:365 #: src/libptouch.c:405
#, c-format #, c-format
msgid "got another %i bytes. now try again\n" msgid "got another %i bytes. now try again\n"
msgstr "weitere %i bytes empfangen. probiere es nochmal.\n" msgstr "weitere %i bytes empfangen. probiere es nochmal.\n"
#: src/ptouch-print.c:82 #: src/libptouch.c:412
#, c-format
msgid "debug: called ptouch_get_tape_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:421
#, c-format
msgid "debug: called ptouch_get_max_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:433
#, c-format
msgid "debug: called ptouch_sendraster() with NULL ptdev\n"
msgstr ""
#: src/ptouch-print.c:143
#, c-format #, c-format
msgid "nothing to print\n" msgid "nothing to print\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:89 #: src/ptouch-print.c:151
#, c-format #, c-format
msgid "image is too large (%ipx x %ipx)\n" msgid "image is too large (%ipx x %ipx)\n"
msgstr "Bild ist zu gross (%ipx x %ipx)\n" msgstr "Bild ist zu gross (%ipx x %ipx)\n"
#: src/ptouch-print.c:90 src/ptouch-print.c:556 #: src/ptouch-print.c:152
#, c-format #, c-format
msgid "maximum printing width for this tape is %ipx\n" msgid "maximum printing width for this tape is %ipx\n"
msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n" msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n"
#: src/ptouch-print.c:104 #: src/ptouch-print.c:155
#, fuzzy, c-format
msgid "image size (%ipx x %ipx)\n"
msgstr "Bild ist zu gross (%ipx x %ipx)\n"
#: src/ptouch-print.c:165
#, c-format #, c-format
msgid "ptouch_rasterstart() failed\n" msgid "ptouch_rasterstart() failed\n"
msgstr "ptouch_rasterstart() fehlgeschlagen\n" msgstr "ptouch_rasterstart() fehlgeschlagen\n"
#: src/ptouch-print.c:110 #: src/ptouch-print.c:171
#, c-format #, c-format
msgid "send print information command\n" msgid "send print information command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:116 #: src/ptouch-print.c:177
#, c-format #, c-format
msgid "send PT-D460BT magic commands\n" msgid "send PT-D460BT magic commands\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:122 #: src/ptouch-print.c:183
#, c-format #, c-format
msgid "send precut command\n" msgid "send precut command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:133 #: src/ptouch-print.c:191
#, c-format
msgid "send PT-D460BT chain commands\n"
msgstr ""
#: src/ptouch-print.c:203
#, fuzzy, c-format #, fuzzy, c-format
#| msgid "ptouch_send() failed\n"
msgid "ptouch_sendraster() failed\n" msgid "ptouch_sendraster() failed\n"
msgstr "ptouch_send() fehlgeschlagen\n" msgstr "ptouch_send() fehlgeschlagen\n"
#: src/ptouch-print.c:182 #: src/ptouch-print.c:252
#, c-format #, c-format
msgid "writing image '%s' failed\n" msgid "writing image '%s' failed\n"
msgstr "Schreiben der Bilddatei '%s' fehlgeschlagen\n" msgstr "Schreiben der Bilddatei '%s' fehlgeschlagen\n"
#: src/ptouch-print.c:206 #: src/ptouch-print.c:274
#, c-format #, c-format
msgid "debug: o baseline offset - %d\n" msgid "debug: o baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:207 #: src/ptouch-print.c:275
#, c-format #, c-format
msgid "debug: text baseline offset - %d\n" msgid "debug: text baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:266 #: src/ptouch-print.c:334
#, c-format #, c-format
msgid "render_text(): %i lines, font = '%s'\n" msgid "render_text(): %i lines, font = '%s'\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:269 #: src/ptouch-print.c:337
#, c-format #, c-format
msgid "warning: font config not available\n" msgid "warning: font config not available\n"
msgstr "Warnung: fontconfig ist nicht verfügbar\n" msgstr "Warnung: fontconfig ist nicht verfügbar\n"
#: src/ptouch-print.c:273 #: src/ptouch-print.c:341
#, c-format #, c-format
msgid "setting font size=%i\n" msgid "setting font size=%i\n"
msgstr "setze Zeichensatzgrösse=%i\n" msgstr "setze Zeichensatzgrösse=%i\n"
#: src/ptouch-print.c:277 #: src/ptouch-print.c:345
#, c-format #, c-format
msgid "could not estimate needed font size\n" msgid "could not estimate needed font size\n"
msgstr "Konnte die notwendige Zeichensatzgrösse nicht bestimmen\n" msgstr "Konnte die notwendige Zeichensatzgrösse nicht bestimmen\n"
#: src/ptouch-print.c:284 #: src/ptouch-print.c:352
#, c-format #, c-format
msgid "choosing font size=%i\n" msgid "choosing font size=%i\n"
msgstr "Wähle Zeichensatzgrösse %i\n" msgstr "Wähle Zeichensatzgrösse %i\n"
#: src/ptouch-print.c:300 src/ptouch-print.c:328 #: src/ptouch-print.c:368 src/ptouch-print.c:396
#, c-format #, c-format
msgid "error in gdImageStringFT: %s\n" msgid "error in gdImageStringFT: %s\n"
msgstr "Fehler in Funktion gdImageStringFT(): %s\n" msgstr "Fehler in Funktion gdImageStringFT(): %s\n"
#: src/ptouch-print.c:495 #: src/ptouch-print.c:557
#, c-format #, c-format
msgid "ptouch-print version %s by Dominic Radermacher\n" msgid "Only up to %d lines are supported"
msgstr "ptouch-print Version %s von Dominic Radermacher\n" msgstr ""
#: src/ptouch-print.c:526 #: src/ptouch-print.c:570
msgid "No arguments supported"
msgstr ""
#: src/ptouch-print.c:575
msgid "Option --writepng missing"
msgstr ""
#: src/ptouch-print.c:578
msgid "Options --force_tape_width and --info can't be used together"
msgstr ""
#: src/ptouch-print.c:609
#, c-format #, c-format
msgid "ptouch_init() failed\n" msgid "ptouch_init() failed\n"
msgstr "ptouch_init() fehlgeschlagen\n" msgstr "ptouch_init() fehlgeschlagen\n"
#: src/ptouch-print.c:529 #: src/ptouch-print.c:612
#, c-format #, c-format
msgid "ptouch_getstatus() failed\n" msgid "ptouch_getstatus() failed\n"
msgstr "ptouch_getstatus() fehlgeschlagen\n" msgstr "ptouch_getstatus() fehlgeschlagen\n"
#: src/ptouch-print.c:568 #: src/ptouch-print.c:626
#, fuzzy, c-format
msgid "maximum printing width for this printer is %ldpx\n"
msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n"
#: src/ptouch-print.c:627
#, fuzzy, c-format
msgid "maximum printing width for this tape is %ldpx\n"
msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n"
#: src/ptouch-print.c:652
#, c-format #, c-format
msgid "failed to load image file\n" msgid "failed to load image file\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:584 #: src/ptouch-print.c:661
#, c-format #, c-format
msgid "could not render text\n" msgid "could not render text\n"
msgstr "Konnte Text nicht rendern\n" msgstr "Konnte Text nicht rendern\n"
#: src/ptouch-print.c:616 #: src/ptouch-print.c:700
#, c-format #, c-format
msgid "ptouch_finalize(%d) failed\n" msgid "ptouch_finalize(%d) failed\n"
msgstr "ptouch_finalize(%d) fehlgeschlagen\n" msgstr "ptouch_finalize(%d) fehlgeschlagen\n"
#, c-format
#~ msgid "ptouch-print version %s by Dominic Radermacher\n"
#~ msgstr "ptouch-print Version %s von Dominic Radermacher\n"
#, c-format #, c-format
#~ msgid "Error 1 = %02x\n" #~ msgid "Error 1 = %02x\n"
#~ msgstr "Fehlerbyte1 = %02x\n" #~ msgstr "Fehlerbyte1 = %02x\n"

173
po/en.po
View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: ptouch-print 1.3.1\n" "Project-Id-Version: ptouch-print 1.3.1\n"
"Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n"
"POT-Creation-Date: 2024-05-23 22:20-0400\n" "POT-Creation-Date: 2025-08-11 09:57+0200\n"
"PO-Revision-Date: 2024-05-23 22:26-0400\n" "PO-Revision-Date: 2024-05-23 22:26-0400\n"
"Last-Translator: dominic@familie-radermacher.ch\n" "Last-Translator: dominic@familie-radermacher.ch\n"
"Language-Team: English <en@translate.freefriends.org>\n" "Language-Team: English <en@translate.freefriends.org>\n"
@ -18,217 +18,294 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.2\n" "X-Generator: Poedit 2.4.2\n"
#: src/libptouch.c:95 src/libptouch.c:99 src/libptouch.c:103 #: src/libptouch.c:105 src/libptouch.c:109 src/libptouch.c:113
#, c-format #, c-format
msgid "out of memory\n" msgid "out of memory\n"
msgstr "out of memory\n" msgstr "out of memory\n"
#: src/libptouch.c:107 #: src/libptouch.c:117
#, c-format #, c-format
msgid "libusb_init() failed\n" msgid "libusb_init() failed\n"
msgstr "libusb_init() failed\n" msgstr "libusb_init() failed\n"
#: src/libptouch.c:116 #: src/libptouch.c:126
#, c-format #, c-format
msgid "failed to get device descriptor" msgid "failed to get device descriptor"
msgstr "failed to get device descriptor" msgstr "failed to get device descriptor"
#: src/libptouch.c:122 #: src/libptouch.c:132
#, c-format #, c-format
msgid "%s found on USB bus %d, device %d\n" msgid "%s found on USB bus %d, device %d\n"
msgstr "%s found on USB bus %d, device %d\n" msgstr "%s found on USB bus %d, device %d\n"
#: src/libptouch.c:137 #: src/libptouch.c:147
#, c-format #, c-format
msgid "libusb_open error :%s\n" msgid "libusb_open error :%s\n"
msgstr "libusb_open error :%s\n" msgstr "libusb_open error :%s\n"
#: src/libptouch.c:143 #: src/libptouch.c:153
#, c-format #, c-format
msgid "error while detaching kernel driver: %s\n" msgid "error while detaching kernel driver: %s\n"
msgstr "error while detaching kernel driver: %s\n" msgstr "error while detaching kernel driver: %s\n"
#: src/libptouch.c:147 #: src/libptouch.c:157
#, c-format #, c-format
msgid "interface claim error: %s\n" msgid "interface claim error: %s\n"
msgstr "interface claim error: %s\n" msgstr "interface claim error: %s\n"
#: src/libptouch.c:158 #: src/libptouch.c:168
#, c-format #, c-format
msgid "No P-Touch printer found on USB (remember to put switch to position E)\n" msgid ""
msgstr "No P-Touch printer found on USB (remember to put switch to position E)\n" "No P-Touch printer found on USB (remember to put switch to position E)\n"
msgstr ""
"No P-Touch printer found on USB (remember to put switch to position E)\n"
#: src/libptouch.c:178 #: src/libptouch.c:188
#, c-format
msgid "debug: called ptouch_send() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:195
#, c-format #, c-format
msgid "write error: %s\n" msgid "write error: %s\n"
msgstr "write error: %s\n" msgstr "write error: %s\n"
#: src/libptouch.c:182 #: src/libptouch.c:199
#, fuzzy, c-format #, fuzzy, c-format
#| msgid "write error: could send only %i of %i bytes\n"
msgid "write error: could send only %i of %ld bytes\n" msgid "write error: could send only %i of %ld bytes\n"
msgstr "write error: could send only %i of %i bytes\n" msgstr "write error: could send only %i of %i bytes\n"
#: src/libptouch.c:302 #: src/libptouch.c:249
#, c-format
msgid "debug: called ptouch_info_cmd() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:291
#, fuzzy, c-format
msgid "debug: called ptouch_rasterstart() with NULL ptdev\n"
msgstr "ptouch_rasterstart() failed\n"
#: src/libptouch.c:322
#, c-format
msgid "debug: called ptouch_finalize() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:337
#, c-format #, c-format
msgid "debug: dumping raw status bytes\n" msgid "debug: dumping raw status bytes\n"
msgstr "debug: dumping raw status bytes\n" msgstr "debug: dumping raw status bytes\n"
#: src/libptouch.c:326 src/libptouch.c:362 #: src/libptouch.c:356
#, c-format
msgid "debug: called ptouch_getstatus() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:366 src/libptouch.c:402
#, c-format #, c-format
msgid "read error: %s\n" msgid "read error: %s\n"
msgstr "read error: %s\n" msgstr "read error: %s\n"
#: src/libptouch.c:331 #: src/libptouch.c:371
#, c-format #, c-format
msgid "timeout while waiting for status response\n" msgid "timeout while waiting for status response\n"
msgstr "timeout while waiting for status response\n" msgstr "timeout while waiting for status response\n"
#: src/libptouch.c:345 #: src/libptouch.c:385
#, c-format #, c-format
msgid "unknown tape width of %imm, please report this.\n" msgid "unknown tape width of %imm, please report this.\n"
msgstr "unknown tape width of %imm, please report this.\n" msgstr "unknown tape width of %imm, please report this.\n"
#: src/libptouch.c:351 #: src/libptouch.c:391
#, c-format #, c-format
msgid "got only 16 bytes... wondering what they are:\n" msgid "got only 16 bytes... wondering what they are:\n"
msgstr "got only 16 bytes... wondering what they are:\n" msgstr "got only 16 bytes... wondering what they are:\n"
#: src/libptouch.c:355 #: src/libptouch.c:395
#, c-format #, c-format
msgid "read error: got %i instead of 32 bytes\n" msgid "read error: got %i instead of 32 bytes\n"
msgstr "read error: got %i instead of 32 bytes\n" msgstr "read error: got %i instead of 32 bytes\n"
#: src/libptouch.c:358 #: src/libptouch.c:398
#, c-format #, c-format
msgid "strange status:\n" msgid "strange status:\n"
msgstr "strange status:\n" msgstr "strange status:\n"
#: src/libptouch.c:360 #: src/libptouch.c:400
#, c-format #, c-format
msgid "trying to flush junk\n" msgid "trying to flush junk\n"
msgstr "trying to flush junk\n" msgstr "trying to flush junk\n"
#: src/libptouch.c:365 #: src/libptouch.c:405
#, c-format #, c-format
msgid "got another %i bytes. now try again\n" msgid "got another %i bytes. now try again\n"
msgstr "got another %i bytes. now try again\n" msgstr "got another %i bytes. now try again\n"
#: src/ptouch-print.c:82 #: src/libptouch.c:412
#, c-format
msgid "debug: called ptouch_get_tape_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:421
#, c-format
msgid "debug: called ptouch_get_max_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:433
#, c-format
msgid "debug: called ptouch_sendraster() with NULL ptdev\n"
msgstr ""
#: src/ptouch-print.c:143
#, c-format #, c-format
msgid "nothing to print\n" msgid "nothing to print\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:89 #: src/ptouch-print.c:151
#, c-format #, c-format
msgid "image is too large (%ipx x %ipx)\n" msgid "image is too large (%ipx x %ipx)\n"
msgstr "image is too large (%ipx x %ipx)\n" msgstr "image is too large (%ipx x %ipx)\n"
#: src/ptouch-print.c:90 src/ptouch-print.c:556 #: src/ptouch-print.c:152
#, c-format #, c-format
msgid "maximum printing width for this tape is %ipx\n" msgid "maximum printing width for this tape is %ipx\n"
msgstr "maximum printing width for this tape is %ipx\n" msgstr "maximum printing width for this tape is %ipx\n"
#: src/ptouch-print.c:104 #: src/ptouch-print.c:155
#, fuzzy, c-format
msgid "image size (%ipx x %ipx)\n"
msgstr "image is too large (%ipx x %ipx)\n"
#: src/ptouch-print.c:165
#, c-format #, c-format
msgid "ptouch_rasterstart() failed\n" msgid "ptouch_rasterstart() failed\n"
msgstr "ptouch_rasterstart() failed\n" msgstr "ptouch_rasterstart() failed\n"
#: src/ptouch-print.c:110 #: src/ptouch-print.c:171
#, c-format #, c-format
msgid "send print information command\n" msgid "send print information command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:116 #: src/ptouch-print.c:177
#, c-format #, c-format
msgid "send PT-D460BT magic commands\n" msgid "send PT-D460BT magic commands\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:122 #: src/ptouch-print.c:183
#, c-format #, c-format
msgid "send precut command\n" msgid "send precut command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:133 #: src/ptouch-print.c:191
#, c-format
msgid "send PT-D460BT chain commands\n"
msgstr ""
#: src/ptouch-print.c:203
#, c-format #, c-format
msgid "ptouch_sendraster() failed\n" msgid "ptouch_sendraster() failed\n"
msgstr "ptouch_sendraster() failed\n" msgstr "ptouch_sendraster() failed\n"
#: src/ptouch-print.c:182 #: src/ptouch-print.c:252
#, c-format #, c-format
msgid "writing image '%s' failed\n" msgid "writing image '%s' failed\n"
msgstr "writing image '%s' failed\n" msgstr "writing image '%s' failed\n"
#: src/ptouch-print.c:206 #: src/ptouch-print.c:274
#, c-format #, c-format
msgid "debug: o baseline offset - %d\n" msgid "debug: o baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:207 #: src/ptouch-print.c:275
#, c-format #, c-format
msgid "debug: text baseline offset - %d\n" msgid "debug: text baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:266 #: src/ptouch-print.c:334
#, c-format #, c-format
msgid "render_text(): %i lines, font = '%s'\n" msgid "render_text(): %i lines, font = '%s'\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:269 #: src/ptouch-print.c:337
#, c-format #, c-format
msgid "warning: font config not available\n" msgid "warning: font config not available\n"
msgstr "warning: font config not available\n" msgstr "warning: font config not available\n"
#: src/ptouch-print.c:273 #: src/ptouch-print.c:341
#, c-format #, c-format
msgid "setting font size=%i\n" msgid "setting font size=%i\n"
msgstr "setting font size=%i\n" msgstr "setting font size=%i\n"
#: src/ptouch-print.c:277 #: src/ptouch-print.c:345
#, c-format #, c-format
msgid "could not estimate needed font size\n" msgid "could not estimate needed font size\n"
msgstr "could not estimate needed font size\n" msgstr "could not estimate needed font size\n"
#: src/ptouch-print.c:284 #: src/ptouch-print.c:352
#, c-format #, c-format
msgid "choosing font size=%i\n" msgid "choosing font size=%i\n"
msgstr "choosing font size=%i\n" msgstr "choosing font size=%i\n"
#: src/ptouch-print.c:300 src/ptouch-print.c:328 #: src/ptouch-print.c:368 src/ptouch-print.c:396
#, c-format #, c-format
msgid "error in gdImageStringFT: %s\n" msgid "error in gdImageStringFT: %s\n"
msgstr "error in gdImageStringFT: %s\n" msgstr "error in gdImageStringFT: %s\n"
#: src/ptouch-print.c:495 #: src/ptouch-print.c:557
#, c-format #, c-format
msgid "ptouch-print version %s by Dominic Radermacher\n" msgid "Only up to %d lines are supported"
msgstr "ptouch-print version %s by Dominic Radermacher\n" msgstr ""
#: src/ptouch-print.c:526 #: src/ptouch-print.c:570
msgid "No arguments supported"
msgstr ""
#: src/ptouch-print.c:575
msgid "Option --writepng missing"
msgstr ""
#: src/ptouch-print.c:578
msgid "Options --force_tape_width and --info can't be used together"
msgstr ""
#: src/ptouch-print.c:609
#, c-format #, c-format
msgid "ptouch_init() failed\n" msgid "ptouch_init() failed\n"
msgstr "ptouch_init() failed\n" msgstr "ptouch_init() failed\n"
#: src/ptouch-print.c:529 #: src/ptouch-print.c:612
#, c-format #, c-format
msgid "ptouch_getstatus() failed\n" msgid "ptouch_getstatus() failed\n"
msgstr "ptouch_getstatus() failed\n" msgstr "ptouch_getstatus() failed\n"
#: src/ptouch-print.c:568 #: src/ptouch-print.c:626
#, fuzzy, c-format
msgid "maximum printing width for this printer is %ldpx\n"
msgstr "maximum printing width for this tape is %ipx\n"
#: src/ptouch-print.c:627
#, fuzzy, c-format
msgid "maximum printing width for this tape is %ldpx\n"
msgstr "maximum printing width for this tape is %ipx\n"
#: src/ptouch-print.c:652
#, c-format #, c-format
msgid "failed to load image file\n" msgid "failed to load image file\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:584 #: src/ptouch-print.c:661
#, c-format #, c-format
msgid "could not render text\n" msgid "could not render text\n"
msgstr "could not render text\n" msgstr "could not render text\n"
#: src/ptouch-print.c:616 #: src/ptouch-print.c:700
#, c-format #, c-format
msgid "ptouch_finalize(%d) failed\n" msgid "ptouch_finalize(%d) failed\n"
msgstr "ptouch_finalize(%d) failed\n" msgstr "ptouch_finalize(%d) failed\n"
#, c-format
#~ msgid "ptouch-print version %s by Dominic Radermacher\n"
#~ msgstr "ptouch-print version %s by Dominic Radermacher\n"
#, c-format #, c-format
#~ msgid "Error 1 = %02x\n" #~ msgid "Error 1 = %02x\n"
#~ msgstr "Error 1 = %02x\n" #~ msgstr "Error 1 = %02x\n"

View File

@ -1,14 +1,14 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc. # Copyright (C) YEAR Dominic\ Radermacher\ <dominic@familie-radermacher.ch>
# This file is distributed under the same license as the ptouch package. # This file is distributed under the same license as the ptouch-print package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: ptouch 1.3.3\n" "Project-Id-Version: ptouch-print\n"
"Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n"
"POT-Creation-Date: 2024-05-23 22:20-0400\n" "POT-Creation-Date: 2025-08-11 10:05+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,213 +17,285 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: src/libptouch.c:95 src/libptouch.c:99 src/libptouch.c:103 #: src/libptouch.c:105 src/libptouch.c:109 src/libptouch.c:113
#, c-format #, c-format
msgid "out of memory\n" msgid "out of memory\n"
msgstr "" msgstr ""
#: src/libptouch.c:107 #: src/libptouch.c:117
#, c-format #, c-format
msgid "libusb_init() failed\n" msgid "libusb_init() failed\n"
msgstr "" msgstr ""
#: src/libptouch.c:116 #: src/libptouch.c:126
#, c-format #, c-format
msgid "failed to get device descriptor" msgid "failed to get device descriptor"
msgstr "" msgstr ""
#: src/libptouch.c:122 #: src/libptouch.c:132
#, c-format #, c-format
msgid "%s found on USB bus %d, device %d\n" msgid "%s found on USB bus %d, device %d\n"
msgstr "" msgstr ""
#: src/libptouch.c:137 #: src/libptouch.c:147
#, c-format #, c-format
msgid "libusb_open error :%s\n" msgid "libusb_open error :%s\n"
msgstr "" msgstr ""
#: src/libptouch.c:143 #: src/libptouch.c:153
#, c-format #, c-format
msgid "error while detaching kernel driver: %s\n" msgid "error while detaching kernel driver: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:147 #: src/libptouch.c:157
#, c-format #, c-format
msgid "interface claim error: %s\n" msgid "interface claim error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:158 #: src/libptouch.c:168
#, c-format #, c-format
msgid "" msgid ""
"No P-Touch printer found on USB (remember to put switch to position E)\n" "No P-Touch printer found on USB (remember to put switch to position E)\n"
msgstr "" msgstr ""
#: src/libptouch.c:178 #: src/libptouch.c:188
#, c-format
msgid "debug: called ptouch_send() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:195
#, c-format #, c-format
msgid "write error: %s\n" msgid "write error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:182 #: src/libptouch.c:199
#, c-format #, c-format
msgid "write error: could send only %i of %ld bytes\n" msgid "write error: could send only %i of %ld bytes\n"
msgstr "" msgstr ""
#: src/libptouch.c:302 #: src/libptouch.c:249
#, c-format
msgid "debug: called ptouch_info_cmd() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:291
#, c-format
msgid "debug: called ptouch_rasterstart() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:322
#, c-format
msgid "debug: called ptouch_finalize() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:337
#, c-format #, c-format
msgid "debug: dumping raw status bytes\n" msgid "debug: dumping raw status bytes\n"
msgstr "" msgstr ""
#: src/libptouch.c:326 src/libptouch.c:362 #: src/libptouch.c:356
#, c-format
msgid "debug: called ptouch_getstatus() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:366 src/libptouch.c:402
#, c-format #, c-format
msgid "read error: %s\n" msgid "read error: %s\n"
msgstr "" msgstr ""
#: src/libptouch.c:331 #: src/libptouch.c:371
#, c-format #, c-format
msgid "timeout while waiting for status response\n" msgid "timeout while waiting for status response\n"
msgstr "" msgstr ""
#: src/libptouch.c:345 #: src/libptouch.c:385
#, c-format #, c-format
msgid "unknown tape width of %imm, please report this.\n" msgid "unknown tape width of %imm, please report this.\n"
msgstr "" msgstr ""
#: src/libptouch.c:351 #: src/libptouch.c:391
#, c-format #, c-format
msgid "got only 16 bytes... wondering what they are:\n" msgid "got only 16 bytes... wondering what they are:\n"
msgstr "" msgstr ""
#: src/libptouch.c:355 #: src/libptouch.c:395
#, c-format #, c-format
msgid "read error: got %i instead of 32 bytes\n" msgid "read error: got %i instead of 32 bytes\n"
msgstr "" msgstr ""
#: src/libptouch.c:358 #: src/libptouch.c:398
#, c-format #, c-format
msgid "strange status:\n" msgid "strange status:\n"
msgstr "" msgstr ""
#: src/libptouch.c:360 #: src/libptouch.c:400
#, c-format #, c-format
msgid "trying to flush junk\n" msgid "trying to flush junk\n"
msgstr "" msgstr ""
#: src/libptouch.c:365 #: src/libptouch.c:405
#, c-format #, c-format
msgid "got another %i bytes. now try again\n" msgid "got another %i bytes. now try again\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:82 #: src/libptouch.c:412
#, c-format
msgid "debug: called ptouch_get_tape_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:421
#, c-format
msgid "debug: called ptouch_get_max_width() with NULL ptdev\n"
msgstr ""
#: src/libptouch.c:433
#, c-format
msgid "debug: called ptouch_sendraster() with NULL ptdev\n"
msgstr ""
#: src/ptouch-print.c:143
#, c-format #, c-format
msgid "nothing to print\n" msgid "nothing to print\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:89 #: src/ptouch-print.c:151
#, c-format #, c-format
msgid "image is too large (%ipx x %ipx)\n" msgid "image is too large (%ipx x %ipx)\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:90 src/ptouch-print.c:556 #: src/ptouch-print.c:152
#, c-format #, c-format
msgid "maximum printing width for this tape is %ipx\n" msgid "maximum printing width for this tape is %ipx\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:104 #: src/ptouch-print.c:155
#, c-format
msgid "image size (%ipx x %ipx)\n"
msgstr ""
#: src/ptouch-print.c:165
#, c-format #, c-format
msgid "ptouch_rasterstart() failed\n" msgid "ptouch_rasterstart() failed\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:110 #: src/ptouch-print.c:171
#, c-format #, c-format
msgid "send print information command\n" msgid "send print information command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:116 #: src/ptouch-print.c:177
#, c-format #, c-format
msgid "send PT-D460BT magic commands\n" msgid "send PT-D460BT magic commands\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:122 #: src/ptouch-print.c:183
#, c-format #, c-format
msgid "send precut command\n" msgid "send precut command\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:133 #: src/ptouch-print.c:191
#, c-format
msgid "send PT-D460BT chain commands\n"
msgstr ""
#: src/ptouch-print.c:203
#, c-format #, c-format
msgid "ptouch_sendraster() failed\n" msgid "ptouch_sendraster() failed\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:182 #: src/ptouch-print.c:252
#, c-format #, c-format
msgid "writing image '%s' failed\n" msgid "writing image '%s' failed\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:206 #: src/ptouch-print.c:274
#, c-format #, c-format
msgid "debug: o baseline offset - %d\n" msgid "debug: o baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:207 #: src/ptouch-print.c:275
#, c-format #, c-format
msgid "debug: text baseline offset - %d\n" msgid "debug: text baseline offset - %d\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:266 #: src/ptouch-print.c:334
#, c-format #, c-format
msgid "render_text(): %i lines, font = '%s'\n" msgid "render_text(): %i lines, font = '%s'\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:269 #: src/ptouch-print.c:337
#, c-format #, c-format
msgid "warning: font config not available\n" msgid "warning: font config not available\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:273 #: src/ptouch-print.c:341
#, c-format #, c-format
msgid "setting font size=%i\n" msgid "setting font size=%i\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:277 #: src/ptouch-print.c:345
#, c-format #, c-format
msgid "could not estimate needed font size\n" msgid "could not estimate needed font size\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:284 #: src/ptouch-print.c:352
#, c-format #, c-format
msgid "choosing font size=%i\n" msgid "choosing font size=%i\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:300 src/ptouch-print.c:328 #: src/ptouch-print.c:368 src/ptouch-print.c:396
#, c-format #, c-format
msgid "error in gdImageStringFT: %s\n" msgid "error in gdImageStringFT: %s\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:495 #: src/ptouch-print.c:557
#, c-format #, c-format
msgid "ptouch-print version %s by Dominic Radermacher\n" msgid "Only up to %d lines are supported"
msgstr "" msgstr ""
#: src/ptouch-print.c:526 #: src/ptouch-print.c:570
msgid "No arguments supported"
msgstr ""
#: src/ptouch-print.c:575
msgid "Option --writepng missing"
msgstr ""
#: src/ptouch-print.c:578
msgid "Options --force_tape_width and --info can't be used together"
msgstr ""
#: src/ptouch-print.c:609
#, c-format #, c-format
msgid "ptouch_init() failed\n" msgid "ptouch_init() failed\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:529 #: src/ptouch-print.c:612
#, c-format #, c-format
msgid "ptouch_getstatus() failed\n" msgid "ptouch_getstatus() failed\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:568 #: src/ptouch-print.c:626
#, c-format
msgid "maximum printing width for this printer is %ldpx\n"
msgstr ""
#: src/ptouch-print.c:627
#, c-format
msgid "maximum printing width for this tape is %ldpx\n"
msgstr ""
#: src/ptouch-print.c:652
#, c-format #, c-format
msgid "failed to load image file\n" msgid "failed to load image file\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:584 #: src/ptouch-print.c:661
#, c-format #, c-format
msgid "could not render text\n" msgid "could not render text\n"
msgstr "" msgstr ""
#: src/ptouch-print.c:616 #: src/ptouch-print.c:700
#, c-format #, c-format
msgid "ptouch_finalize(%d) failed\n" msgid "ptouch_finalize(%d) failed\n"
msgstr "" msgstr ""

View File

@ -1,7 +1,7 @@
/* /*
libptouch - functions to help accessing a brother ptouch libptouch - functions to help accessing a brother ptouch
Copyright (C) 2013-2023 Dominic Radermacher <dominic@familie-radermacher.ch> Copyright (C) 2013-2025 Dominic Radermacher <dominic@familie-radermacher.ch>
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 3 as under the terms of the GNU General Public License version 3 as
@ -26,8 +26,8 @@
#include <sys/stat.h> /* open() */ #include <sys/stat.h> /* open() */
#include <fcntl.h> /* open() */ #include <fcntl.h> /* open() */
#include <time.h> /* nanosleep(), struct timespec */ #include <time.h> /* nanosleep(), struct timespec */
#include <libintl.h> /* gettext() */
#include "gettext.h" /* gettext(), ngettext() */
#include "ptouch.h" #include "ptouch.h"
#define _(s) gettext(s) #define _(s) gettext(s)
@ -45,9 +45,11 @@ struct _pt_tape_info tape_info[]= {
}; };
struct _pt_dev_info ptdevs[] = { struct _pt_dev_info ptdevs[] = {
{0x04f9, 0x2001, "PT-9200DX", 384, 360, FLAG_RASTER_PACKBITS|FLAG_HAS_PRECUT}, /* 360dpi, maximum 128px, max tape width 36mm */
{0x04f9, 0x2004, "PT-2300", 112, 180, FLAG_RASTER_PACKBITS|FLAG_HAS_PRECUT}, /* 180dpi, 112px printhead */
{0x04f9, 0x2007, "PT-2420PC", 128, 180, FLAG_RASTER_PACKBITS}, /* 180dpi, 128px, maximum tape width 24mm, must send TIFF compressed pixel data */ {0x04f9, 0x2007, "PT-2420PC", 128, 180, FLAG_RASTER_PACKBITS}, /* 180dpi, 128px, maximum tape width 24mm, must send TIFF compressed pixel data */
{0x04f9, 0x2011, "PT-2450PC", 128, 180, FLAG_RASTER_PACKBITS}, {0x04f9, 0x2011, "PT-2450PC", 128, 180, FLAG_RASTER_PACKBITS},
{0x04f9, 0x2019, "PT-1950", 128, 180, FLAG_RASTER_PACKBITS}, /* 180dpi, apparently 112px printhead ?, maximum tape width 18mm - unconfirmed if it works */ {0x04f9, 0x2019, "PT-1950", 112, 180, FLAG_RASTER_PACKBITS}, /* 180dpi, apparently 112px printhead ?, maximum tape width 18mm - unconfirmed if it works */
{0x04f9, 0x201f, "PT-2700", 128, 180, FLAG_HAS_PRECUT}, {0x04f9, 0x201f, "PT-2700", 128, 180, FLAG_HAS_PRECUT},
{0x04f9, 0x202c, "PT-1230PC", 128, 180, FLAG_NONE}, /* 180dpi, supports tapes up to 12mm - I don't know how much pixels it can print! */ {0x04f9, 0x202c, "PT-1230PC", 128, 180, FLAG_NONE}, /* 180dpi, supports tapes up to 12mm - I don't know how much pixels it can print! */
/* Notes about the PT-1230PC: While it is true that this printer supports /* Notes about the PT-1230PC: While it is true that this printer supports
@ -65,6 +67,9 @@ struct _pt_dev_info ptdevs[] = {
{0x04f9, 0x205f, "PT-E500", 128, 180, FLAG_RASTER_PACKBITS}, {0x04f9, 0x205f, "PT-E500", 128, 180, FLAG_RASTER_PACKBITS},
/* Note about the PT-E500: was reported by Jesse Becker with the /* Note about the PT-E500: was reported by Jesse Becker with the
remark that it also needs some padding (white pixels) */ remark that it also needs some padding (white pixels) */
{0x04f9, 0x2060, "PT-E550W", 128, 180, FLAG_UNSUP_RASTER},
/* Note about the PT-E550W: was reported by Tim Biermann but does not
work yet (only prints empty tape with FLAG_RASTER_PACKBITS|FLAG_HAS_PRECUT) */
{0x04f9, 0x2061, "PT-P700", 128, 180, FLAG_RASTER_PACKBITS|FLAG_P700_INIT|FLAG_HAS_PRECUT}, {0x04f9, 0x2061, "PT-P700", 128, 180, FLAG_RASTER_PACKBITS|FLAG_P700_INIT|FLAG_HAS_PRECUT},
{0x04f9, 0x2062, "PT-P750W", 128, 180, FLAG_RASTER_PACKBITS|FLAG_P700_INIT}, {0x04f9, 0x2062, "PT-P750W", 128, 180, FLAG_RASTER_PACKBITS|FLAG_P700_INIT},
{0x04f9, 0x2064, "PT-P700 (PLite Mode)", 128, 180, FLAG_PLITE}, {0x04f9, 0x2064, "PT-P700 (PLite Mode)", 128, 180, FLAG_PLITE},
@ -79,6 +84,11 @@ struct _pt_dev_info ptdevs[] = {
{0x04f9, 0x20e1, "PT-D610BT", 128, 180, FLAG_P700_INIT|FLAG_USE_INFO_CMD|FLAG_HAS_PRECUT|FLAG_D460BT_MAGIC}, {0x04f9, 0x20e1, "PT-D610BT", 128, 180, FLAG_P700_INIT|FLAG_USE_INFO_CMD|FLAG_HAS_PRECUT|FLAG_D460BT_MAGIC},
//{0x04f9, 0x200d, "PT-3600", 384, 360, FLAG_RASTER_PACKBITS}, //{0x04f9, 0x200d, "PT-3600", 384, 360, FLAG_RASTER_PACKBITS},
{0x04f9, 0x20af, "PT-P710BT", 128, 180, FLAG_RASTER_PACKBITS|FLAG_HAS_PRECUT}, {0x04f9, 0x20af, "PT-P710BT", 128, 180, FLAG_RASTER_PACKBITS|FLAG_HAS_PRECUT},
/* added by Christian, PT-E310BT (aka PT-E310BTVP) requires these flags, otherwise not returning from libusb_bulk_transfer-call */
/* printhead 128px, 180 dpi resolution */
/* 3,5/6/9/12/18 mm TZe Tapes, 12mm and 18mm tested */
/* 5,2/9/11,2 mm HSe heat shrink tubes not tested, probably requiring extension of struct _pt_tape_info */
{0x04f9, 0x2201, "PT-E310BT", 128, 180, FLAG_P700_INIT|FLAG_USE_INFO_CMD|FLAG_D460BT_MAGIC},
{0,0,"",0,0,0} {0,0,"",0,0,0}
}; };
@ -162,6 +172,9 @@ int ptouch_open(ptouch_dev *ptdev)
int ptouch_close(ptouch_dev ptdev) int ptouch_close(ptouch_dev ptdev)
{ {
if (!ptdev) {
return -1;
}
libusb_release_interface(ptdev->h, 0); libusb_release_interface(ptdev->h, 0);
libusb_close(ptdev->h); libusb_close(ptdev->h);
return 0; return 0;
@ -171,7 +184,11 @@ int ptouch_send(ptouch_dev ptdev, uint8_t *data, size_t len)
{ {
int r, tx; int r, tx;
if ((ptdev == NULL) || (len > 128)) { if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_send() with NULL ptdev\n"));
return -1;
}
if (len > 128) {
return -1; return -1;
} }
if ((r=libusb_bulk_transfer(ptdev->h, 0x02, data, (int)len, &tx, 0)) != 0) { if ((r=libusb_bulk_transfer(ptdev->h, 0x02, data, (int)len, &tx, 0)) != 0) {
@ -211,10 +228,11 @@ int ptouch_send_d460bt_magic(ptouch_dev ptdev)
uint8_t cmd[7]; uint8_t cmd[7];
/* n1 and n2 are the length margin/spacing, in px? (uint16_t value, little endian) */ /* n1 and n2 are the length margin/spacing, in px? (uint16_t value, little endian) */
/* A value of 0x06 is equivalent to the width margin on 6mm tape */ /* A value of 0x06 is equivalent to the width margin on 6mm tape */
/* A value of 0x01 adds barely any margin, suitable for image printing */
/* The default for P-Touch software is 0x0e */ /* The default for P-Touch software is 0x0e */
/* n3 must be 0x4D or the print gets corrupted! */ /* n3 must be 0x4D or the print gets corrupted! */
/* n4 seems to be ignored or reserved. */ /* n4 seems to be ignored or reserved. */
memcpy(cmd, "\x1b\x69\x64\x0e\x00\x4d\x00", 7); memcpy(cmd, "\x1b\x69\x64\x01\x00\x4d\x00", 7);
return ptouch_send(ptdev, (uint8_t *)cmd, sizeof(cmd)); return ptouch_send(ptdev, (uint8_t *)cmd, sizeof(cmd));
} }
@ -227,6 +245,11 @@ int ptouch_enable_packbits(ptouch_dev ptdev)
/* print information command */ /* print information command */
int ptouch_info_cmd(ptouch_dev ptdev, int size_x) int ptouch_info_cmd(ptouch_dev ptdev, int size_x)
{ {
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_info_cmd() with NULL ptdev\n"));
return -1;
}
/* 1B 69 7A {n1} {n2} {n3} {n4} {n5} {n6} {n7} {n8} {n9} {n10} */ /* 1B 69 7A {n1} {n2} {n3} {n4} {n5} {n6} {n7} {n8} {n9} {n10} */
uint8_t cmd[] = "\x1b\x69\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; uint8_t cmd[] = "\x1b\x69\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
@ -264,6 +287,10 @@ int ptouch_send_precut_cmd(ptouch_dev ptdev, int precut)
int ptouch_rasterstart(ptouch_dev ptdev) int ptouch_rasterstart(ptouch_dev ptdev)
{ {
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_rasterstart() with NULL ptdev\n"));
return -1;
}
/* 1B 69 52 01 = Select graphics transfer mode = Raster */ /* 1B 69 52 01 = Select graphics transfer mode = Raster */
char cmd[] = "\x1b\x69\x52\x01"; char cmd[] = "\x1b\x69\x52\x01";
/* 1B 69 61 01 = switch mode (0=esc/p, 1=raster mode) */ /* 1B 69 61 01 = switch mode (0=esc/p, 1=raster mode) */
@ -291,6 +318,11 @@ int ptouch_ff(ptouch_dev ptdev)
/* finish print and either cut or leave tape in machine */ /* finish print and either cut or leave tape in machine */
int ptouch_finalize(ptouch_dev ptdev, int chain) int ptouch_finalize(ptouch_dev ptdev, int chain)
{ {
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_finalize() with NULL ptdev\n"));
return -1;
}
char cmd_eject[]="\x1a"; /* Print command with feeding */ char cmd_eject[]="\x1a"; /* Print command with feeding */
char cmd_chain[]="\x0c"; /* Print command (no cut) */ char cmd_chain[]="\x0c"; /* Print command (no cut) */
@ -320,6 +352,11 @@ int ptouch_getstatus(ptouch_dev ptdev)
int i, r, tx=0, tries=0; int i, r, tx=0, tries=0;
struct timespec w; struct timespec w;
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_getstatus() with NULL ptdev\n"));
return -1;
}
ptouch_send(ptdev, (uint8_t *)cmd, strlen(cmd)); ptouch_send(ptdev, (uint8_t *)cmd, strlen(cmd));
while (tx == 0) { while (tx == 0) {
w.tv_sec=0; w.tv_sec=0;
@ -371,11 +408,19 @@ int ptouch_getstatus(ptouch_dev ptdev)
size_t ptouch_get_tape_width(ptouch_dev ptdev) size_t ptouch_get_tape_width(ptouch_dev ptdev)
{ {
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_get_tape_width() with NULL ptdev\n"));
return 0;
}
return ptdev->tape_width_px; return ptdev->tape_width_px;
} }
size_t ptouch_get_max_width(ptouch_dev ptdev) size_t ptouch_get_max_width(ptouch_dev ptdev)
{ {
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_get_max_width() with NULL ptdev\n"));
return 0;
}
return ptdev->devinfo->max_px; return ptdev->devinfo->max_px;
} }
@ -384,6 +429,10 @@ int ptouch_sendraster(ptouch_dev ptdev, uint8_t *data, size_t len)
uint8_t buf[64]; uint8_t buf[64];
int rc; int rc;
if (!ptdev) {
fprintf(stderr, _("debug: called ptouch_sendraster() with NULL ptdev\n"));
return -1;
}
if (len > (size_t)(ptdev->devinfo->max_px / 8)) { if (len > (size_t)(ptdev->devinfo->max_px / 8)) {
return -1; return -1;
} }

View File

@ -1,7 +1,7 @@
/* /*
ptouch-print - Print labels with images or text on a Brother P-Touch ptouch-print - Print labels with images or text on a Brother P-Touch
Copyright (C) 2015-2024 Dominic Radermacher <dominic@familie-radermacher.ch> Copyright (C) 2015-2025 Dominic Radermacher <dominic@familie-radermacher.ch>
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 3 as under the terms of the GNU General Public License version 3 as
@ -17,6 +17,7 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <argp.h>
#include <stdio.h> /* printf() */ #include <stdio.h> /* printf() */
#include <stdlib.h> /* exit(), malloc() */ #include <stdlib.h> /* exit(), malloc() */
#include <stdbool.h> #include <stdbool.h>
@ -29,13 +30,35 @@
#include <locale.h> /* LC_ALL */ #include <locale.h> /* LC_ALL */
#include "version.h" #include "version.h"
#include "gettext.h" /* gettext(), ngettext() */
#include "ptouch.h" #include "ptouch.h"
#define _(s) gettext(s) #define _(s) gettext(s)
#define MAX_LINES 4 /* maybe this should depend on tape size */ #define MAX_LINES 4 /* maybe this should depend on tape size */
#define P_NAME "ptouch-print"
struct arguments {
bool chain;
int copies;
bool debug;
bool info;
char *font_file;
int font_size;
int forced_tape_width;
char *save_png;
int verbose;
};
typedef enum { JOB_CUTMARK, JOB_IMAGE, JOB_PAD, JOB_TEXT, JOB_UNDEFINED } job_type_t;
typedef struct job {
job_type_t type;
int n;
char *lines[MAX_LINES];
struct job *next;
} job_t;
gdImage *image_load(const char *file); gdImage *image_load(const char *file);
void rasterline_setpixel(uint8_t* rasterline, size_t size, int pixel); void rasterline_setpixel(uint8_t* rasterline, size_t size, int pixel);
int get_baselineoffset(char *text, char *font, int fsz); int get_baselineoffset(char *text, char *font, int fsz);
@ -44,21 +67,59 @@ int needed_width(char *text, char *font, int fsz);
int print_img(ptouch_dev ptdev, gdImage *im, int chain); int print_img(ptouch_dev ptdev, gdImage *im, int chain);
int write_png(gdImage *im, const char *file); int write_png(gdImage *im, const char *file);
gdImage *img_append(gdImage *in_1, gdImage *in_2); gdImage *img_append(gdImage *in_1, gdImage *in_2);
gdImage *img_cutmark(int tape_width); gdImage *img_cutmark(int print_width);
gdImage *render_text(char *font, char *line[], int lines, int tape_width); gdImage *render_text(char *font, char *line[], int lines, int print_width);
void unsupported_printer(ptouch_dev ptdev); void unsupported_printer(ptouch_dev ptdev);
void usage(char *progname); void add_job(job_type_t type, int n, char *line);
int parse_args(int argc, char **argv); static error_t parse_opt(int key, char *arg, struct argp_state *state);
// char *font_file = "/usr/share/fonts/TTF/Ubuntu-M.ttf"; const char *argp_program_version = P_NAME " " VERSION;
// char *font_file = "Ubuntu:medium"; const char *argp_program_bug_address = "Dominic Radermacher <dominic@familie-radermacher.ch>";
char *font_file = "DejaVuSans"; static char doc[] = "ptouch-print is a command line tool to print labels on Brother P-Touch printers on Linux.";
char *save_png = NULL; static char args_doc[] = "";
int verbose = 0;
int fontsize = 0; static struct argp_option options[] = {
bool debug = false; // name, key, arg, flags, doc, group
bool chain = false; { 0, 0, 0, 0, "options:", 1},
int forced_tape_width = 0; { "debug", 1, 0, 0, "Enable debug output", 1},
{ "font", 2, "<file>", 0, "Use font <file> or <name>", 1},
{ "fontsize", 3, "<size>", 0, "Manually set font size", 1},
{ "writepng", 4, "<file>", 0, "Instead of printing, write output to png <file>", 1},
{ "force-tape-width", 5, "<px>", 0, "Set tape width in pixels, use together with --writepng without a printer connected", 1},
{ "copies", 6, "<number>", 0, "Sets the number of identical prints", 1},
{ 0, 0, 0, 0, "print commands:", 2},
{ "image", 'i', "<file>", 0, "Print the given image which must be a 2 color (black/white) png", 2},
{ "text", 't', "<text>", 0, "Print line of <text>. If the text contains spaces, use quotation marks taround it", 2},
{ "cutmark", 'c', 0, 0, "Print a mark where the tape should be cut", 2},
{ "pad", 'p', "<n>", 0, "Add n pixels padding (blank tape)", 2},
{ "chain", 10, 0, 0, "Skip final feed of label and any automatic cut", 2},
{ "newline", 'n', "<text>", 0, "Add text in a new line (up to 4 lines)", 2},
{ 0, 0, 0, 0, "other commands:", 3},
{ "info", 20, 0, 0, "Show info about detected tape", 3},
{ "list-supported", 21, 0, 0, "Show printers supported by this version", 3},
{ 0 }
};
static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };
struct arguments arguments = {
.chain = false,
.copies = 1,
.debug = false,
.info = false,
//.font_file = "/usr/share/fonts/TTF/Ubuntu-M.ttf",
//.font_file = "Ubuntu:medium",
.font_file = "DejaVuSans",
.font_size = 0,
.forced_tape_width = 0,
.save_png = NULL,
.verbose = 0
};
job_t *jobs = NULL;
job_t *last_added_job = NULL;
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
-------------------------------------------------------------------- */ -------------------------------------------------------------------- */
@ -67,7 +128,7 @@ void rasterline_setpixel(uint8_t* rasterline, size_t size, int pixel)
{ {
// TODO: pixel should be unsigned, since we can't have negative // TODO: pixel should be unsigned, since we can't have negative
// if (pixel > ptdev->devinfo->device_max_px) { // if (pixel > ptdev->devinfo->device_max_px) {
if (pixel > (int)(size*8)) { if ((pixel < 0) || (pixel >= (int)(size*8))) {
return; return;
} }
rasterline[(size-1)-(pixel/8)] |= (uint8_t)(1<<(pixel%8)); rasterline[(size-1)-(pixel/8)] |= (uint8_t)(1<<(pixel%8));
@ -76,27 +137,26 @@ void rasterline_setpixel(uint8_t* rasterline, size_t size, int pixel)
int print_img(ptouch_dev ptdev, gdImage *im, int chain) int print_img(ptouch_dev ptdev, gdImage *im, int chain)
{ {
int d,i,k,offset,tape_width;
uint8_t rasterline[(ptdev->devinfo->max_px)/8]; uint8_t rasterline[(ptdev->devinfo->max_px)/8];
if (!im) { if (!im) {
printf(_("nothing to print\n")); printf(_("nothing to print\n"));
return -1; return -1;
} }
tape_width=ptouch_get_tape_width(ptdev); int tape_width = ptouch_get_tape_width(ptdev);
size_t max_pixels = ptouch_get_max_width(ptdev);
/* find out whether color 0 or color 1 is darker */ /* find out whether color 0 or color 1 is darker */
d=(gdImageRed(im,1)+gdImageGreen(im,1)+gdImageBlue(im,1) < gdImageRed(im,0)+gdImageGreen(im,0)+gdImageBlue(im,0))?1:0; int d = (gdImageRed(im,1) + gdImageGreen(im,1) + gdImageBlue(im,1) < gdImageRed(im,0) + gdImageGreen(im,0) + gdImageBlue(im,0))?1:0;
if (gdImageSY(im) > tape_width) { if (gdImageSY(im) > tape_width) {
printf(_("image is too large (%ipx x %ipx)\n"), gdImageSX(im), gdImageSY(im)); printf(_("image is too large (%ipx x %ipx)\n"), gdImageSX(im), gdImageSY(im));
printf(_("maximum printing width for this tape is %ipx\n"), tape_width); printf(_("maximum printing width for this tape is %ipx\n"), tape_width);
return -1; return -1;
} }
//offset=64-(gdImageSY(im)/2); /* always print centered */ printf(_("image size (%ipx x %ipx)\n"), gdImageSX(im), gdImageSY(im));
size_t max_pixels=ptouch_get_max_width(ptdev); int offset = ((int)max_pixels / 2) - (gdImageSY(im)/2); /* always print centered */
offset=((int)max_pixels / 2)-(gdImageSY(im)/2); /* always print centered */
printf("max_pixels=%ld, offset=%d\n", max_pixels, offset); printf("max_pixels=%ld, offset=%d\n", max_pixels, offset);
if ((ptdev->devinfo->flags & FLAG_RASTER_PACKBITS) == FLAG_RASTER_PACKBITS) { if ((ptdev->devinfo->flags & FLAG_RASTER_PACKBITS) == FLAG_RASTER_PACKBITS) {
if (debug) { if (arguments.debug) {
printf("enable PackBits mode\n"); printf("enable PackBits mode\n");
} }
ptouch_enable_packbits(ptdev); ptouch_enable_packbits(ptdev);
@ -107,36 +167,39 @@ int print_img(ptouch_dev ptdev, gdImage *im, int chain)
} }
if ((ptdev->devinfo->flags & FLAG_USE_INFO_CMD) == FLAG_USE_INFO_CMD) { if ((ptdev->devinfo->flags & FLAG_USE_INFO_CMD) == FLAG_USE_INFO_CMD) {
ptouch_info_cmd(ptdev, gdImageSX(im)); ptouch_info_cmd(ptdev, gdImageSX(im));
if (debug) { if (arguments.debug) {
printf(_("send print information command\n")); printf(_("send print information command\n"));
} }
} }
if ((ptdev->devinfo->flags & FLAG_D460BT_MAGIC) == FLAG_D460BT_MAGIC) { if ((ptdev->devinfo->flags & FLAG_D460BT_MAGIC) == FLAG_D460BT_MAGIC) {
if (chain) {
ptouch_send_d460bt_chain(ptdev);
if (debug) {
printf(_("send PT-D460BT chain commands\n"));
}
}
ptouch_send_d460bt_magic(ptdev); ptouch_send_d460bt_magic(ptdev);
if (debug) { if (arguments.debug) {
printf(_("send PT-D460BT magic commands\n")); printf(_("send PT-D460BT magic commands\n"));
} }
} }
if ((ptdev->devinfo->flags & FLAG_HAS_PRECUT) == FLAG_HAS_PRECUT) { if ((ptdev->devinfo->flags & FLAG_HAS_PRECUT) == FLAG_HAS_PRECUT) {
ptouch_send_precut_cmd(ptdev, 1); ptouch_send_precut_cmd(ptdev, 1);
if (debug) { if (arguments.debug) {
printf(_("send precut command\n")); printf(_("send precut command\n"));
} }
} }
for (k=0; k<gdImageSX(im); k+=1) { /* send chain command after precut, to allow precutting before chain */
if ((ptdev->devinfo->flags & FLAG_D460BT_MAGIC) == FLAG_D460BT_MAGIC) {
if (chain) {
ptouch_send_d460bt_chain(ptdev);
if (arguments.debug) {
printf(_("send PT-D460BT chain commands\n"));
}
}
}
for (int k = 0; k < gdImageSX(im); ++k) {
memset(rasterline, 0, sizeof(rasterline)); memset(rasterline, 0, sizeof(rasterline));
for (i=0; i<gdImageSY(im); i+=1) { for (int i = 0; i < gdImageSY(im); ++i) {
if (gdImageGetPixel(im, k, gdImageSY(im)-1-i) == d) { if (gdImageGetPixel(im, k, gdImageSY(im) - 1 - i) == d) {
rasterline_setpixel(rasterline, sizeof(rasterline), offset+i); rasterline_setpixel(rasterline, sizeof(rasterline), offset+i);
} }
} }
if (ptouch_sendraster(ptdev, rasterline, 16) != 0) { if (ptouch_sendraster(ptdev, rasterline, (ptdev->devinfo->max_px / 8)) != 0) {
printf(_("ptouch_sendraster() failed\n")); printf(_("ptouch_sendraster() failed\n"));
return -1; return -1;
} }
@ -153,10 +216,10 @@ int print_img(ptouch_dev ptdev, gdImage *im, int chain)
gdImage *image_load(const char *file) gdImage *image_load(const char *file)
{ {
const uint8_t png[8]={0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a}; const uint8_t png[8] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
char d[10]; char d[10];
FILE *f; FILE *f;
gdImage *img=NULL; gdImage *img = NULL;
if (!strcmp(file, "-")) { if (!strcmp(file, "-")) {
f = stdin; f = stdin;
@ -167,14 +230,14 @@ gdImage *image_load(const char *file)
return NULL; return NULL;
} }
if (fseek(f, 0L, SEEK_SET)) { /* file is not seekable. eg 'stdin' */ if (fseek(f, 0L, SEEK_SET)) { /* file is not seekable. eg 'stdin' */
img=gdImageCreateFromPng(f); img = gdImageCreateFromPng(f);
} else { } else {
if (fread(d, sizeof(d), 1, f) != 1) { if (fread(d, sizeof(d), 1, f) != 1) {
return NULL; return NULL;
} }
rewind(f); rewind(f);
if (memcmp(d, png, 8) == 0) { if (memcmp(d, png, 8) == 0) {
img=gdImageCreateFromPng(f); img = gdImageCreateFromPng(f);
} }
} }
fclose(f); fclose(f);
@ -201,15 +264,13 @@ int write_png(gdImage *im, const char *file)
int get_baselineoffset(char *text, char *font, int fsz) int get_baselineoffset(char *text, char *font, int fsz)
{ {
int brect[8]; int brect[8];
int o_offset;
int text_offset;
/* NOTE: This assumes that 'o' is always on the baseline */ /* NOTE: This assumes that 'o' is always on the baseline */
gdImageStringFT(NULL, &brect[0], -1, font, fsz, 0.0, 0, 0, "o"); gdImageStringFT(NULL, &brect[0], -1, font, fsz, 0.0, 0, 0, "o");
o_offset=brect[1]; int o_offset = brect[1];
gdImageStringFT(NULL, &brect[0], -1, font, fsz, 0.0, 0, 0, text); gdImageStringFT(NULL, &brect[0], -1, font, fsz, 0.0, 0, 0, text);
text_offset=brect[1]; int text_offset = brect[1];
if (debug) { if (arguments.debug) {
printf(_("debug: o baseline offset - %d\n"), o_offset); printf(_("debug: o baseline offset - %d\n"), o_offset);
printf(_("debug: text baseline offset - %d\n"), text_offset); printf(_("debug: text baseline offset - %d\n"), text_offset);
} }
@ -223,7 +284,7 @@ int get_baselineoffset(char *text, char *font, int fsz)
-------------------------------------------------------------------- */ -------------------------------------------------------------------- */
int find_fontsize(int want_px, char *font, char *text) int find_fontsize(int want_px, char *font, char *text)
{ {
int save=0; int save = 0;
int brect[8]; int brect[8];
for (int i=4; ; ++i) { for (int i=4; ; ++i) {
@ -231,7 +292,7 @@ int find_fontsize(int want_px, char *font, char *text)
break; break;
} }
if (brect[1]-brect[5] <= want_px) { if (brect[1]-brect[5] <= want_px) {
save=i; save = i;
} else { } else {
break; break;
} }
@ -262,25 +323,25 @@ int offset_x(char *text, char *font, int fsz)
return -brect[0]; return -brect[0];
} }
gdImage *render_text(char *font, char *line[], int lines, int tape_width) gdImage *render_text(char *font, char *line[], int lines, int print_width)
{ {
int brect[8]; int brect[8];
int i, black, x=0, tmp=0, fsz=0; int i, black, x = 0, tmp = 0, fsz = 0;
char *p; char *p;
gdImage *im=NULL; gdImage *im = NULL;
if (debug) { if (arguments.debug) {
printf(_("render_text(): %i lines, font = '%s'\n"), lines, font); printf(_("render_text(): %i lines, font = '%s'\n"), lines, font);
} }
if (gdFTUseFontConfig(1) != GD_TRUE) { if (gdFTUseFontConfig(1) != GD_TRUE) {
printf(_("warning: font config not available\n")); printf(_("warning: font config not available\n"));
} }
if (fontsize > 0) { if (arguments.font_size > 0) {
fsz=fontsize; fsz = arguments.font_size;
printf(_("setting font size=%i\n"), fsz); printf(_("setting font size=%i\n"), fsz);
} else { } else {
for (i=0; i<lines; ++i) { for (i = 0; i < lines; ++i) {
if ((tmp=find_fontsize(tape_width/lines, font, line[i])) < 0) { if ((tmp = find_fontsize(print_width/lines, font, line[i])) < 0) {
printf(_("could not estimate needed font size\n")); printf(_("could not estimate needed font size\n"));
return NULL; return NULL;
} }
@ -290,48 +351,48 @@ gdImage *render_text(char *font, char *line[], int lines, int tape_width)
} }
printf(_("choosing font size=%i\n"), fsz); printf(_("choosing font size=%i\n"), fsz);
} }
for(i=0; i<lines; ++i) { for (i = 0; i < lines; ++i) {
tmp=needed_width(line[i], font_file, fsz); tmp = needed_width(line[i], arguments.font_file, fsz);
if (tmp > x) { if (tmp > x) {
x=tmp; x = tmp;
} }
} }
im=gdImageCreatePalette(x, tape_width); im = gdImageCreatePalette(x, print_width);
gdImageColorAllocate(im, 255, 255, 255); gdImageColorAllocate(im, 255, 255, 255);
black=gdImageColorAllocate(im, 0, 0, 0); black = gdImageColorAllocate(im, 0, 0, 0);
/* gdImageStringFT(im,brect,fg,fontlist,size,angle,x,y,string) */ /* gdImageStringFT(im,brect,fg,fontlist,size,angle,x,y,string) */
/* find max needed line height for ALL lines */ /* find max needed line height for ALL lines */
int max_height=0; int max_height=0;
for (i=0; i<lines; ++i) { for (i = 0; i < lines; ++i) {
if ((p=gdImageStringFT(NULL, &brect[0], -black, font, fsz, 0.0, 0, 0, line[i])) != NULL) { if ((p = gdImageStringFT(NULL, &brect[0], -black, font, fsz, 0.0, 0, 0, line[i])) != NULL) {
printf(_("error in gdImageStringFT: %s\n"), p); printf(_("error in gdImageStringFT: %s\n"), p);
} }
//int ofs=get_baselineoffset(line[i], font_file, fsz); //int ofs = get_baselineoffset(line[i], font_file, fsz);
int lineheight=brect[1]-brect[5]; int lineheight = brect[1]-brect[5];
if (lineheight > max_height) { if (lineheight > max_height) {
max_height=lineheight; max_height = lineheight;
} }
} }
if (debug) { if (arguments.debug) {
printf("debug: needed (max) height is %ipx\n", max_height); printf("debug: needed (max) height is %ipx\n", max_height);
} }
if ((max_height * lines) > tape_width) { if ((max_height * lines) > print_width) {
printf("Font size %d too large for %d lines\n", fsz, lines); printf("Font size %d too large for %d lines\n", fsz, lines);
return NULL; return NULL;
} }
/* calculate unused pixels */ /* calculate unused pixels */
int unused_px = tape_width - (max_height * lines); int unused_px = print_width - (max_height * lines);
/* now render lines */ /* now render lines */
for (i=0; i<lines; ++i) { for (i = 0; i < lines; ++i) {
int ofs=get_baselineoffset(line[i], font_file, fsz); int ofs = get_baselineoffset(line[i], arguments.font_file, fsz);
//int pos=((i)*(tape_width/(lines)))+(max_height)-ofs-1; //int pos = ((i)*(print_width/(lines)))+(max_height)-ofs-1;
int pos=((i)*(tape_width/(lines)))+(max_height)-ofs; int pos = ((i)*(print_width/(lines)))+(max_height)-ofs;
pos += (unused_px/lines) / 2; pos += (unused_px/lines) / 2;
if (debug) { if (arguments.debug) {
printf("debug: line %i pos=%i ofs=%i\n", i+1, pos, ofs); printf("debug: line %i pos=%i ofs=%i\n", i+1, pos, ofs);
} }
int off_x = offset_x(line[i], font_file, fsz); int off_x = offset_x(line[i], arguments.font_file, fsz);
if ((p=gdImageStringFT(im, &brect[0], -black, font, fsz, 0.0, off_x, pos, line[i])) != NULL) { if ((p = gdImageStringFT(im, &brect[0], -black, font, fsz, 0.0, off_x, pos, line[i])) != NULL) {
printf(_("error in gdImageStringFT: %s\n"), p); printf(_("error in gdImageStringFT: %s\n"), p);
} }
} }
@ -340,80 +401,80 @@ gdImage *render_text(char *font, char *line[], int lines, int tape_width)
gdImage *img_append(gdImage *in_1, gdImage *in_2) gdImage *img_append(gdImage *in_1, gdImage *in_2)
{ {
gdImage *out=NULL; gdImage *out = NULL;
int width=0; int width = 0;
int i_1_x=0; int i_1_x = 0;
int length=0; int length = 0;
if (in_1 != NULL) { if (in_1 != NULL) {
width=gdImageSY(in_1); width = gdImageSY(in_1);
length=gdImageSX(in_1); length = gdImageSX(in_1);
i_1_x=gdImageSX(in_1); i_1_x = gdImageSX(in_1);
} }
if (in_2 != NULL) { if (in_2 != NULL) {
length += gdImageSX(in_2); length += gdImageSX(in_2);
/* width should be the same, but let's be sure */ /* width should be the same, but let's be sure */
if (gdImageSY(in_2) > width) { if (gdImageSY(in_2) > width) {
width=gdImageSY(in_2); width = gdImageSY(in_2);
} }
} }
if ((width == 0) || (length == 0)) { if ((width == 0) || (length == 0)) {
return NULL; return NULL;
} }
out=gdImageCreatePalette(length, width); out = gdImageCreatePalette(length, width);
if (out == NULL) { if (out == NULL) {
return NULL; return NULL;
} }
gdImageColorAllocate(out, 255, 255, 255); gdImageColorAllocate(out, 255, 255, 255);
gdImageColorAllocate(out, 0, 0, 0); gdImageColorAllocate(out, 0, 0, 0);
if (debug) { if (arguments.debug) {
printf("debug: created new img with size %d * %d\n", length, width); printf("debug: created new img with size %d * %d\n", length, width);
} }
if (in_1 != NULL) { if (in_1 != NULL) {
gdImageCopy(out, in_1, 0, 0, 0, 0, gdImageSX(in_1), gdImageSY(in_1)); gdImageCopy(out, in_1, 0, 0, 0, 0, gdImageSX(in_1), gdImageSY(in_1));
if (debug) { if (arguments.debug) {
printf("debug: copied part 1\n"); printf("debug: copied part 1\n");
} }
} }
if (in_2 != NULL) { if (in_2 != NULL) {
gdImageCopy(out, in_2, i_1_x, 0, 0, 0, gdImageSX(in_2), gdImageSY(in_2)); gdImageCopy(out, in_2, i_1_x, 0, 0, 0, gdImageSX(in_2), gdImageSY(in_2));
if (debug) { if (arguments.debug) {
printf("copied part 2\n"); printf("copied part 2\n");
} }
} }
return out; return out;
} }
gdImage *img_cutmark(int tape_width) gdImage *img_cutmark(int print_width)
{ {
gdImage *out=NULL; gdImage *out = NULL;
int style_dashed[6]; int style_dashed[6];
out=gdImageCreatePalette(9, tape_width); out = gdImageCreatePalette(9, print_width);
if (out == NULL) { if (out == NULL) {
return NULL; return NULL;
} }
gdImageColorAllocate(out, 255, 255, 255); gdImageColorAllocate(out, 255, 255, 255);
int black=gdImageColorAllocate(out, 0, 0, 0); int black = gdImageColorAllocate(out, 0, 0, 0);
style_dashed[0]=gdTransparent; style_dashed[0] = gdTransparent;
style_dashed[1]=gdTransparent; style_dashed[1] = gdTransparent;
style_dashed[2]=gdTransparent; style_dashed[2] = gdTransparent;
style_dashed[3]=black; style_dashed[3] = black;
style_dashed[4]=black; style_dashed[4] = black;
style_dashed[5]=black; style_dashed[5] = black;
gdImageSetStyle(out, style_dashed, 6); gdImageSetStyle(out, style_dashed, 6);
gdImageLine(out, 5, 0, 5, tape_width-1, gdStyled); gdImageLine(out, 5, 0, 5, print_width - 1, gdStyled);
return out; return out;
} }
gdImage *img_padding(int tape_width, int length) gdImage *img_padding(int print_width, int length)
{ {
gdImage *out=NULL; gdImage *out = NULL;
if ((length < 1) || (length > 256)) { if ((length < 1) || (length > 256)) {
length=1; length=1;
} }
out=gdImageCreatePalette(length, tape_width); out = gdImageCreatePalette(length, print_width);
if (out == NULL) { if (out == NULL) {
return NULL; return NULL;
} }
@ -421,130 +482,126 @@ gdImage *img_padding(int tape_width, int length)
return out; return out;
} }
void usage(char *progname) void add_job(job_type_t type, int n, char *line)
{ {
printf("usage: %s [options] <print-command(s)>\n", progname); job_t *new_job = (job_t*)malloc(sizeof(job_t));
printf("options:\n"); if (!new_job) {
printf("\t--debug\t\t\tenable debug output\n"); fprintf(stderr, "Memory allocation failed\n");
printf("\t--font <file>\t\tuse font <file> or <name>\n"); return;
printf("\t--fontsize <size>\tManually set fontsize\n"); }
printf("\t--writepng <file>\tinstead of printing, write output to png file\n"); new_job->type = type;
printf("\t--force-tape-width <px>\tSet tape width in pixels, use together with\n"); if (type == JOB_TEXT && n > MAX_LINES) {
printf("\t\t\t\t--writepng without a printer connected.\n"); n = MAX_LINES;
printf("\t--copies <number>\tSets the number of identical prints\n"); }
printf("print commands:\n"); new_job->n = n;
printf("\t--image <file>\t\tprint the given image which must be a 2 color\n"); new_job->lines[0] = line;
printf("\t\t\t\t(black/white) png\n"); for (int i=1; i<MAX_LINES; ++i) {
printf("\t--text <text>\t\tPrint 1-4 lines of text.\n"); new_job->lines[i] = NULL;
printf("\t\t\t\tIf the text contains spaces, use quotation marks\n\t\t\t\taround it.\n"); }
printf("\t--cutmark\t\tPrint a mark where the tape should be cut\n"); new_job->next = NULL;
printf("\t--pad <n>\t\tAdd n pixels padding (blank tape)\n");
printf("\t--chain\t\t\tSkip final feed of label and any automatic cut\n"); if (!last_added_job) { // just created the first job
printf("other commands:\n"); jobs = last_added_job = new_job;
printf("\t--version\t\tshow version info (required for bug report)\n"); return;
printf("\t--info\t\t\tshow info about detected tape\n"); }
printf("\t--list-supported\tshow printers supported by this version\n");
exit(1); last_added_job->next = new_job;
last_added_job = new_job;
} }
/* here we don't print anything, but just try to catch syntax errors */ static error_t parse_opt(int key, char *arg, struct argp_state *state)
int parse_args(int argc, char **argv)
{ {
int lines, i; struct arguments *arguments = (struct arguments *)state->input;
for (i=1; i<argc; ++i) { switch (key) {
if (*argv[i] != '-') { case 1: // debug
arguments->debug = true;
break; break;
} case 2: // font
if (strcmp(&argv[i][1], "-font") == 0) { arguments->font_file = arg;
if (i+1<argc) { break;
font_file=argv[++i]; case 3: // fontsize
} else { arguments->font_size = strtol(arg, NULL, 10);
usage(argv[0]); break;
case 4: // writepng
arguments->save_png = arg;
break;
case 5: // force-tape-width
arguments->forced_tape_width = strtol(arg, NULL, 10);
break;
case 6: // copies
arguments->copies = strtol(arg, NULL, 10);
break;
case 'i': // image
add_job(JOB_IMAGE, 1, arg);
break;
case 't': // text
add_job(JOB_TEXT, 1, arg);
break;
case 'c': // cutmark
add_job(JOB_CUTMARK, 0, NULL);
break;
case 'p': // pad
add_job(JOB_PAD, atoi(arg), NULL);
break;
case 10: // chain
arguments->chain = true;
break;
case 'n': // newline
if (!last_added_job || last_added_job->type != JOB_TEXT) {
add_job(JOB_TEXT, 1, arg);
break;
} }
} else if (strcmp(&argv[i][1], "-fontsize") == 0) {
if (i+1<argc) { if (last_added_job->n >= MAX_LINES) { // max number of lines reached
++i; argp_failure(state, 1, EINVAL, _("Only up to %d lines are supported"), MAX_LINES);
} else { break;
usage(argv[0]);
} }
} else if (strcmp(&argv[i][1], "-writepng") == 0) {
if (i+1<argc) { last_added_job->lines[last_added_job->n++] = arg;
save_png=argv[++i]; break;
} else { case 20: // info
usage(argv[0]); arguments->info = true;
} break;
} else if (strcmp(&argv[i][1], "-force-tape-width") == 0) { case 21: // list-supported
if (i+1<argc) {
forced_tape_width=strtol(argv[++i], NULL, 10);
} else {
usage(argv[0]);
}
} else if (strcmp(&argv[i][1], "-cutmark") == 0) {
continue; /* not done here */
} else if (strcmp(&argv[i][1], "-chain") == 0) {
chain=true;
} else if (strcmp(&argv[i][1], "-debug") == 0) {
debug=true;
} else if (strcmp(&argv[i][1], "-info") == 0) {
continue; /* not done here */
} else if (strcmp(&argv[i][1], "-copies") == 0) {
if (i+1<argc) {
++i;
} else {
usage(argv[0]);
}
} else if (strcmp(&argv[i][1], "-image") == 0) {
if (i+1<argc) {
++i;
} else {
usage(argv[0]);
}
} else if (strcmp(&argv[i][1], "-pad") == 0) {
if (i+1<argc) {
++i;
} else {
usage(argv[0]);
}
} else if (strcmp(&argv[i][1], "-text") == 0) {
for (lines=0; (lines < MAX_LINES) && (i < argc); ++lines) {
if ((i+1 >= argc) || (argv[i+1][0] == '-')) {
break;
}
++i;
}
} else if (strcmp(&argv[i][1], "-version") == 0) {
printf(_("ptouch-print version %s by Dominic Radermacher\n"), VERSION);
exit(0);
} else if (strcmp(&argv[i][1], "-list-supported") == 0) {
ptouch_list_supported(); ptouch_list_supported();
exit(0); exit(0);
} else { case ARGP_KEY_ARG:
usage(argv[0]); argp_failure(state, 1, E2BIG, _("No arguments supported"));
} break;
case ARGP_KEY_END:
// final argument validation
if (arguments->forced_tape_width && !arguments->save_png) {
argp_failure(state, 1, ENOTSUP, _("Option --writepng missing"));
}
if (arguments->forced_tape_width && arguments->info) {
argp_failure(state, 1, ENOTSUP, _("Options --force_tape_width and --info can't be used together"));
}
break;
default:
return ARGP_ERR_UNKNOWN;
} }
if (forced_tape_width && !save_png) { return 0;
forced_tape_width = 0;
}
return i;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, lines = 0, tape_width, copies=1; int print_width = 0;
char *line[MAX_LINES]; gdImage *im = NULL;
gdImage *im=NULL; gdImage *out = NULL;
gdImage *out=NULL; ptouch_dev ptdev = NULL;
ptouch_dev ptdev=NULL;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain("ptouch-print", "/usr/share/locale/"); const char *textdomain_dir = getenv("TEXTDOMAINDIR");
textdomain("ptouch-print"); if (!textdomain_dir) {
i=parse_args(argc, argv); textdomain_dir = "/usr/share/locale/";
if (i != argc) {
usage(argv[0]);
} }
if (!forced_tape_width) { bindtextdomain(P_NAME, "/usr/share/locale/");
textdomain(P_NAME);
argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (!arguments.forced_tape_width) {
if ((ptouch_open(&ptdev)) < 0) { if ((ptouch_open(&ptdev)) < 0) {
return 5; return 5;
} }
@ -555,101 +612,92 @@ int main(int argc, char *argv[])
printf(_("ptouch_getstatus() failed\n")); printf(_("ptouch_getstatus() failed\n"));
return 1; return 1;
} }
tape_width=ptouch_get_tape_width(ptdev); print_width = ptouch_get_tape_width(ptdev);
} else { int max_print_width = ptouch_get_max_width(ptdev);
tape_width = forced_tape_width; // do not try to print more pixels than printhead has
} if (print_width > max_print_width) {
for (i=1; i<argc; ++i) { print_width = max_print_width;
if (*argv[i] != '-') {
break;
} }
if (strcmp(&argv[i][1], "-font") == 0) { } else { // --forced_tape_width together with --writepng
if (i+1<argc) { print_width = arguments.forced_tape_width;
font_file=argv[++i]; }
} else {
usage(argv[0]); if (arguments.info) {
printf(_("maximum printing width for this printer is %ldpx\n"), ptouch_get_max_width(ptdev));
printf(_("maximum printing width for this tape is %ldpx\n"), ptouch_get_tape_width(ptdev));
printf("media type = %02x (%s)\n", ptdev->status->media_type, pt_mediatype(ptdev->status->media_type));
printf("media width = %d mm\n", ptdev->status->media_width);
printf("tape color = %02x (%s)\n", ptdev->status->tape_color, pt_tapecolor(ptdev->status->tape_color));
printf("text color = %02x (%s)\n", ptdev->status->text_color, pt_textcolor(ptdev->status->text_color));
printf("error = %04x\n", ptdev->status->error);
if (arguments.debug) {
ptouch_rawstatus((uint8_t *)ptdev->status);
}
exit(0);
}
// iterate through all print jobs
for (job_t *job = jobs; job != NULL; job = job->next) {
if (arguments.debug) {
printf("job %p: type=%d | n=%d", job, job->type, job->n);
for (int i=0; i<MAX_LINES; ++i) {
printf(" | %s", job->lines[i]);
} }
} else if (strcmp(&argv[i][1], "-fontsize") == 0) { printf(" | next=%p\n", job->next);
if (i+1<argc) { }
fontsize=strtol(argv[++i], NULL, 10);
} else { switch (job->type) {
usage(argv[0]); case JOB_IMAGE:
} if ((im = image_load(job->lines[0])) == NULL) {
} else if (strcmp(&argv[i][1], "-force-tape-width") == 0) { printf(_("failed to load image file\n"));
if (forced_tape_width && save_png) { return 1;
++i;
continue;
} else {
usage(argv[0]);
}
} else if (strcmp(&argv[i][1], "-writepng") == 0) {
i++;
continue;
} else if (strcmp(&argv[i][1], "-info") == 0) {
printf(_("maximum printing width for this tape is %ipx\n"), tape_width);
printf("media type = %02x (%s)\n", ptdev->status->media_type, pt_mediatype(ptdev->status->media_type));
printf("media width = %d mm\n", ptdev->status->media_width);
printf("tape color = %02x (%s)\n", ptdev->status->tape_color, pt_tapecolor(ptdev->status->tape_color));
printf("text color = %02x (%s)\n", ptdev->status->text_color, pt_textcolor(ptdev->status->text_color));
printf("error = %04x\n", ptdev->status->error);
if (debug) {
ptouch_rawstatus((uint8_t *)ptdev->status);
}
exit(0);
} else if (strcmp(&argv[i][1], "-image") == 0) {
if ((im=image_load(argv[++i])) == NULL) {
printf(_("failed to load image file\n"));
return 1;
}
out=img_append(out, im);
gdImageDestroy(im);
im = NULL;
} else if (strcmp(&argv[i][1], "-text") == 0) {
for (lines=0; (lines < MAX_LINES) && (i < argc); ++lines) {
if ((i+1 >= argc) || (argv[i+1][0] == '-')) {
break;
} }
++i; out = img_append(out, im);
line[lines]=argv[i]; gdImageDestroy(im);
} im = NULL;
if (lines) { break;
if ((im=render_text(font_file, line, lines, tape_width)) == NULL) { case JOB_TEXT:
if ((im = render_text(arguments.font_file, job->lines, job->n, print_width)) == NULL) {
printf(_("could not render text\n")); printf(_("could not render text\n"));
return 1; return 1;
} }
out=img_append(out, im); out = img_append(out, im);
gdImageDestroy(im); gdImageDestroy(im);
im = NULL; im = NULL;
} break;
} else if (strcmp(&argv[i][1], "-cutmark") == 0) { case JOB_CUTMARK:
im=img_cutmark(tape_width); im = img_cutmark(print_width);
out=img_append(out, im); out = img_append(out, im);
gdImageDestroy(im); gdImageDestroy(im);
im = NULL; im = NULL;
} else if (strcmp(&argv[i][1], "-pad") == 0) { break;
int length=strtol(argv[++i], NULL, 10); case JOB_PAD:
im=img_padding(tape_width, length); im = img_padding(print_width, job->n);
out=img_append(out, im); out = img_append(out, im);
gdImageDestroy(im); gdImageDestroy(im);
im = NULL; im = NULL;
} else if (strcmp(&argv[i][1], "-chain") == 0) { break;
chain = true; default:
} else if (strcmp(&argv[i][1], "-debug") == 0) { break;
debug = true;
} else if (strcmp(&argv[i][1], "-copies") == 0) {
copies = strtol(argv[++i], NULL, 10);
} else {
usage(argv[0]);
} }
} }
// clean up job list
for (job_t *job = jobs; job != NULL; ) {
job_t *next = job->next;
free(job);
job = next;
}
jobs = last_added_job = NULL;
if (out) { if (out) {
if (save_png) { if (arguments.save_png) {
write_png(out, save_png); write_png(out, arguments.save_png);
} else { } else {
for (i=0; i<copies; ++i) { for (int i = 0; i < arguments.copies; ++i) {
print_img(ptdev, out, chain); print_img(ptdev, out, arguments.chain);
if (ptouch_finalize(ptdev, ( chain || (i < copies-1) ) ) != 0) { if (ptouch_finalize(ptdev, ( arguments.chain || (i < arguments.copies-1) ) ) != 0) {
printf(_("ptouch_finalize(%d) failed\n"), chain); printf(_("ptouch_finalize(%d) failed\n"), arguments.chain);
return 2; return 2;
} }
} }
@ -659,7 +707,7 @@ int main(int argc, char *argv[])
if (im != NULL) { if (im != NULL) {
gdImageDestroy(im); gdImageDestroy(im);
} }
if (!forced_tape_width) { if (!arguments.forced_tape_width) {
ptouch_close(ptdev); ptouch_close(ptdev);
} }
libusb_exit(NULL); libusb_exit(NULL);

View File

@ -1,4 +1,5 @@
# Enable non-root access for known ptouch printers # Enable non-root access for known ptouch printers
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2004", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2007", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2007", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2011", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2011", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2019", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2019", MODE="0660", TAG+="uaccess"
@ -16,3 +17,4 @@ SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20af", MODE=
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20df", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20df", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20e0", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20e0", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20e1", MODE="0660", TAG+="uaccess" SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "20e1", MODE="0660", TAG+="uaccess"
SUBSYSTEM == "usb", ATTRS{idVendor} == "04f9", ATTRS{idProduct} == "2201", MODE="0660", TAG+="uaccess"