mirror of
https://github.com/python-escpos/python-escpos
synced 2025-06-25 08:38:43 +00:00
Add Kanji-related feature code
This commit is contained in:
parent
a394826d69
commit
42db405bf9
@ -303,3 +303,23 @@ RT_MASK_ONLINE: int = 8
|
||||
RT_MASK_PAPER: int = 18
|
||||
RT_MASK_LOWPAPER: int = 30
|
||||
RT_MASK_NOPAPER: int = 114
|
||||
|
||||
# Kanji mode
|
||||
KANJI_PRINT_MODE: bytes = FS + b"\x21" # Select Kanji print mode (FS !)
|
||||
KANJI_ENTER_KANJI_MODE: bytes = FS + b"\x26" # Set Kanji mode (FS &)
|
||||
KANJI_UNDERLINE: bytes = FS + b"\x2d" # Underline Kanji mode (FS -)
|
||||
KANJI_EXIT_KANJI_MODE: bytes = FS + b"\x2e" # Cancel Kanji mode (FS .)
|
||||
KANJI_DEFINE_USER_DEFINED: bytes = (
|
||||
FS + b"\x32"
|
||||
) # Define user-defined Kanji characters (FS 2)
|
||||
KANJI_DELETE_USER_DEFINED: bytes = (
|
||||
FS + b"\x3f"
|
||||
) # Cancel user-defined Kanji characters (FS ?)
|
||||
KANJI_SET_ENCODING: bytes = FS + b"\x43" # Set Kanji code system (FS C)
|
||||
KANJI_SET_SPACING: bytes = FS + b"\x53" # Select Kanji character spacing (FS S)
|
||||
KANJI_SET_QUADRUPLE_SIZE: bytes = FS + b"\x57" # Select Kanji quadruple size (FS W)
|
||||
KANJI_SET_CHAR_STYLE: bytes = FS + b"\x28\x41" # Select Kanji character style (FS ( A)
|
||||
|
||||
# ISO-2022-JP Escape Sequences (partially implemented)
|
||||
ISO2022_JP_ASCII: bytes = b"\x1b\x28\x42"
|
||||
ISO2022_JP_JIS_X_0208_1983: bytes = b"\x1b\x24\x42" # So-called "New JIS"
|
||||
|
@ -84,6 +84,18 @@ from .constants import (
|
||||
TXT_NORMAL,
|
||||
TXT_SIZE,
|
||||
TXT_STYLE,
|
||||
KANJI_PRINT_MODE,
|
||||
KANJI_ENTER_KANJI_MODE,
|
||||
KANJI_UNDERLINE,
|
||||
KANJI_EXIT_KANJI_MODE,
|
||||
KANJI_DEFINE_USER_DEFINED,
|
||||
KANJI_DELETE_USER_DEFINED,
|
||||
KANJI_SET_ENCODING,
|
||||
KANJI_SET_SPACING,
|
||||
KANJI_SET_QUADRUPLE_SIZE,
|
||||
KANJI_SET_CHAR_STYLE,
|
||||
ISO2022_JP_JIS_X_0208_1983,
|
||||
ISO2022_JP_ASCII,
|
||||
)
|
||||
from .exceptions import (
|
||||
BarcodeCodeError,
|
||||
@ -134,6 +146,7 @@ class Escpos(object, metaclass=ABCMeta):
|
||||
"""
|
||||
self.profile = get_profile(profile)
|
||||
self.magic = MagicEncode(self, **(magic_encode_args or {}))
|
||||
self.kanji_encoding: Optional[str] = None
|
||||
|
||||
def __del__(self):
|
||||
"""Call self.close upon deletion."""
|
||||
@ -1494,6 +1507,198 @@ class Escpos(object, metaclass=ABCMeta):
|
||||
|
||||
self._raw(BUZZER + six.int2byte(times) + six.int2byte(duration))
|
||||
|
||||
def _enter_kanji_mode(self):
|
||||
"""Enters Kanji mode."""
|
||||
self._raw(KANJI_ENTER_KANJI_MODE)
|
||||
|
||||
def _exit_kanji_mode(self):
|
||||
"""Exits Kanji mode."""
|
||||
self._raw(KANJI_EXIT_KANJI_MODE)
|
||||
|
||||
def kanji_text(self, text: str) -> None:
|
||||
"""Prints Kanji text.
|
||||
|
||||
:param text: The Kanji text.
|
||||
:param encoding: The encoding of the text.
|
||||
:raises ValueError: If the Kanji encoding is not set.
|
||||
"""
|
||||
|
||||
if self.kanji_encoding is None:
|
||||
raise ValueError("Kanji encoding not set")
|
||||
elif self.kanji_encoding == "iso2022_jp":
|
||||
# ISO-2022-JP encoding is a stateful encoding.
|
||||
# We need to enter and exit Kanji mode.
|
||||
self._iso2022jp_text(text)
|
||||
else:
|
||||
encoded_text = text.encode(self.kanji_encoding, "ignore")
|
||||
self._enter_kanji_mode()
|
||||
self._raw(encoded_text)
|
||||
self._exit_kanji_mode()
|
||||
|
||||
def _iso2022jp_text(self, text: str) -> None:
|
||||
"""Prints ISO-2022-JP text."""
|
||||
encoded = text.encode("iso2022_jp", "ignore")
|
||||
while len(encoded) > 0:
|
||||
# find the next escape sequence
|
||||
escape_pos = encoded.find(b"\x1b", 1)
|
||||
if escape_pos == -1:
|
||||
current_chunk = encoded
|
||||
encoded = ""
|
||||
else:
|
||||
current_chunk = encoded[:escape_pos]
|
||||
encoded = encoded[escape_pos:]
|
||||
|
||||
# find encoding
|
||||
if not current_chunk.startswith(ESC):
|
||||
# ASCII
|
||||
self._raw(current_chunk)
|
||||
elif current_chunk.startswith(ISO2022_JP_ASCII):
|
||||
# ASCII
|
||||
stripped = current_chunk[len(ISO2022_JP_ASCII) :]
|
||||
self._raw(stripped)
|
||||
elif current_chunk.startswith(ISO2022_JP_JIS_X_0208_1983):
|
||||
# JIS X 0208-1983
|
||||
stripped = current_chunk[len(ISO2022_JP_JIS_X_0208_1983) :]
|
||||
self._enter_kanji_mode()
|
||||
self._raw(stripped)
|
||||
self._exit_kanji_mode()
|
||||
else:
|
||||
# unknown encoding
|
||||
pretty_sequence = " ".join([hex(b) for b in current_chunk])
|
||||
raise ValueError(
|
||||
"Unimplemented ISO-2022-JP escape sequence: " + pretty_sequence
|
||||
)
|
||||
|
||||
def set_kanji_decoration(
|
||||
self,
|
||||
*,
|
||||
double_width: bool = False,
|
||||
double_height: bool = False,
|
||||
underline: Literal[0, 1, 2] = 0,
|
||||
):
|
||||
"""Sets the Kanji print mode.
|
||||
|
||||
:param double_width: Doubles the width of the text.
|
||||
:param double_height: Doubles the height of the text.
|
||||
:param underline: Underlines the text.
|
||||
"""
|
||||
n: int = 0x00
|
||||
if double_width:
|
||||
n |= 0x04
|
||||
if double_height:
|
||||
n |= 0x08
|
||||
self._raw(KANJI_PRINT_MODE + six.int2byte(n))
|
||||
self.set_kanji_underline(underline)
|
||||
|
||||
def set_kanji_underline(
|
||||
self,
|
||||
underline: Literal[0, 1, 2] = 0,
|
||||
):
|
||||
"""Sets the Kanji underline mode.
|
||||
|
||||
Some printers may only support 1 dot width underline.
|
||||
|
||||
:param underline: The underline mode.
|
||||
0 Unset underline.
|
||||
1 Set underline with 1 dot width.
|
||||
2 Set underline with 2 dot width.
|
||||
"""
|
||||
self._raw(KANJI_UNDERLINE + six.int2byte(underline))
|
||||
|
||||
def define_user_defined_kanji(
|
||||
self,
|
||||
code: bytes,
|
||||
data: bytes,
|
||||
):
|
||||
"""Sets a user defined Kanji character.
|
||||
|
||||
:param code: The Kanji code.
|
||||
:param data: The Kanji data.
|
||||
"""
|
||||
self._raw(KANJI_DEFINE_USER_DEFINED + code + data)
|
||||
|
||||
def delete_user_defined_kanji(
|
||||
self,
|
||||
code: bytes,
|
||||
):
|
||||
"""Deletes a user defined Kanji character.
|
||||
:param code: The Kanji code.
|
||||
"""
|
||||
self._raw(KANJI_DELETE_USER_DEFINED + code)
|
||||
|
||||
def set_kanji_encoding(
|
||||
self,
|
||||
encoding: Literal[
|
||||
"iso2022_jp",
|
||||
"shift_jis",
|
||||
"shift_jis_2004",
|
||||
"euc_kr", # FIXME test with real device,
|
||||
"big5", # FIXME test with real device,
|
||||
"gb2312", # FIXME test with real device,
|
||||
"gb18030", # FIXME test with real device,
|
||||
],
|
||||
):
|
||||
"""Selects the Kanji encoding.
|
||||
This command is available only for Japanese model printers.
|
||||
|
||||
:param code: Encoding.
|
||||
:raises ValueError: If the encoding is invalid.
|
||||
"""
|
||||
# Japanese model printer have several Kanji encoding modes.
|
||||
if (
|
||||
encoding == "iso2022_jp"
|
||||
or encoding == "euc_kr"
|
||||
or encoding == "big5"
|
||||
or encoding == "gb2312"
|
||||
or encoding == "gb18030"
|
||||
):
|
||||
self._raw(KANJI_SET_ENCODING + b"\x00")
|
||||
self.kanji_encoding = encoding
|
||||
elif encoding == "shift_jis":
|
||||
self._raw(KANJI_SET_ENCODING + b"\x01")
|
||||
self.kanji_encoding = encoding
|
||||
elif encoding == "shift_jis_2004":
|
||||
self._raw(KANJI_SET_ENCODING + b"\x02")
|
||||
self.kanji_encoding = encoding
|
||||
else:
|
||||
raise ValueError("Invalid encoding")
|
||||
|
||||
def set_kanji_spacing(
|
||||
self,
|
||||
left_spacing: int,
|
||||
right_spacing: int,
|
||||
):
|
||||
"""Sets the Kanji spacing.
|
||||
Spacing is either 0-255 or 0-32 according to the printer model.
|
||||
:param left_spacing: The left spacing.
|
||||
:param right_spacing: The right spacing.
|
||||
"""
|
||||
self._raw(
|
||||
KANJI_SET_SPACING + six.int2byte(left_spacing) + six.int2byte(right_spacing)
|
||||
)
|
||||
|
||||
def set_kanji_quadruple_size(
|
||||
self,
|
||||
enable: bool,
|
||||
):
|
||||
"""Sets the Kanji quadruple size.
|
||||
:param enable: Enable quadruple size.
|
||||
"""
|
||||
self._raw(KANJI_SET_QUADRUPLE_SIZE + six.int2byte(int(enable)))
|
||||
|
||||
def set_kanji_font(
|
||||
self,
|
||||
font: Literal[0, 1, 2],
|
||||
):
|
||||
"""Sets the Kanji font.
|
||||
:param font: The Kanji font.
|
||||
0 font A
|
||||
1 font B
|
||||
2 font C
|
||||
Some fonts may not be available on all printers.
|
||||
"""
|
||||
self._raw(KANJI_SET_CHAR_STYLE + b"\x02\x00\x30" + six.int2byte(font))
|
||||
|
||||
|
||||
class EscposIO:
|
||||
r"""ESC/POS Printer IO object.
|
||||
|
Loading…
x
Reference in New Issue
Block a user