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_PAPER: int = 18
|
||||||
RT_MASK_LOWPAPER: int = 30
|
RT_MASK_LOWPAPER: int = 30
|
||||||
RT_MASK_NOPAPER: int = 114
|
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_NORMAL,
|
||||||
TXT_SIZE,
|
TXT_SIZE,
|
||||||
TXT_STYLE,
|
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 (
|
from .exceptions import (
|
||||||
BarcodeCodeError,
|
BarcodeCodeError,
|
||||||
@ -134,6 +146,7 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
self.profile = get_profile(profile)
|
self.profile = get_profile(profile)
|
||||||
self.magic = MagicEncode(self, **(magic_encode_args or {}))
|
self.magic = MagicEncode(self, **(magic_encode_args or {}))
|
||||||
|
self.kanji_encoding: Optional[str] = None
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
"""Call self.close upon deletion."""
|
"""Call self.close upon deletion."""
|
||||||
@ -1494,6 +1507,198 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
|
|
||||||
self._raw(BUZZER + six.int2byte(times) + six.int2byte(duration))
|
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:
|
class EscposIO:
|
||||||
r"""ESC/POS Printer IO object.
|
r"""ESC/POS Printer IO object.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user