From 73ef8c4c0a6d36a9c38263a80a152e1248c1ca49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Elsd=C3=B6rfer?= Date: Tue, 30 Aug 2016 17:39:26 +0200 Subject: [PATCH] Write as many characters as possible at once. --- src/escpos/magicencode.py | 50 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/escpos/magicencode.py b/src/escpos/magicencode.py index 3d62dab..23fa9e1 100644 --- a/src/escpos/magicencode.py +++ b/src/escpos/magicencode.py @@ -85,7 +85,6 @@ class Encoder(object): index ) - def find_suitable_encoding(self, char): """The order of our search is a specific one: @@ -113,6 +112,21 @@ class Encoder(object): return encoding +def split_writable_text(encoder, text, encoding): + """Splits off as many characters from the begnning of text as + are writable with "encoding". Returns a 2-tuple (writable, rest). + """ + if not encoding: + return None, text + + for idx, char in enumerate(text): + if encoder.can_encode(encoding, char): + continue + return text[:idx], text[idx:] + + return text, None + + class MagicEncode(object): """A helper that helps us to automatically switch to the right code page to encode any given Unicode character. @@ -161,30 +175,24 @@ class MagicEncode(object): self.write_with_encoding(self.encoding, text) return - # TODO: Currently this very simple loop means we send every - # character individually to the printer. We can probably - # improve performace by searching the text for the first - # character that cannot be rendered using the current code - # page, and then sending all of those characters at once. - # Or, should a lower-level buffer be responsible for that? + # See how far we can go into the text with the current encoding + to_write, text = split_writable_text(self.encoder, text, self.encoding) + if to_write: + self.write_with_encoding(self.encoding, to_write) - for char in text: - # See if the current code page works for this character. - # The encoder object will use a cache to be able to answer - # this question fairly easily. - if self.encoding and self.encoder.can_encode(self.encoding, char): - self.write_with_encoding(self.encoding, char) - continue - - # We have to find another way to print this character. - # See if any of the code pages that the printer profile supports - # can encode this character. - encoding = self.encoder.find_suitable_encoding(char) + while text: + # See if any of the code pages that the printer profile + # supports can encode this character. + encoding = self.encoder.find_suitable_encoding(text[0]) if not encoding: - self._handle_character_failed(char) + self._handle_character_failed(text[0]) + text = text[1:] continue - self.write_with_encoding(encoding, char) + # Write as much text as possible with the encoding found. + to_write, text = split_writable_text(self.encoder, text, encoding) + if to_write: + self.write_with_encoding(encoding, to_write) def _handle_character_failed(self, char): """Called when no codepage was found to render a character.