diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c005071..0ff3ed2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,21 @@ ********* Changelog ********* +2016-08-26 - Version 2.2.0 - "Fate Amenable To Change" +------------------------------------------------------ + +changes +^^^^^^^ +- fix improper API-use in qrcode() +- change setup.py shebang to make it compatible with virtualenvs. +- add constants for sheet mode and colors +- support changing the linespacing + +contributors +^^^^^^^^^^^^ +- Michael Elsdörfer +- Patrick Kanzler + 2016-08-10 - Version 2.1.3 - "Ethics Gradient" ---------------------------------------------- diff --git a/README.rst b/README.rst index 72e21bd..e79b279 100644 --- a/README.rst +++ b/README.rst @@ -54,14 +54,14 @@ The basic usage is: .. code:: python - from escpos import * + from escpos.printer import Usb """ Seiko Epson Corp. Receipt Printer M129 Definitions (EPSON TM-T88IV) """ - Epson = escpos.Escpos(0x04b8,0x0202,0) - Epson.text("Hello World\n") - Epson.image("logo.gif") - Epson.barcode('1324354657687','EAN13',64,2,'','') - Epson.cut() + p = Usb(0x04b8,0x0202,0) + p.text("Hello World\n") + p.image("logo.gif") + p.barcode('1324354657687','EAN13',64,2,'','') + p.cut() The full project-documentation is available on `Read the Docs `_. diff --git a/setup.py b/setup.py index 6a95e63..219ee2c 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python import os import sys diff --git a/src/escpos/constants.py b/src/escpos/constants.py index 6087c80..d606ecc 100644 --- a/src/escpos/constants.py +++ b/src/escpos/constants.py @@ -55,11 +55,18 @@ _CUT_PAPER = lambda m: GS + b'V' + m PAPER_FULL_CUT = _CUT_PAPER(b'\x00') # Full cut paper PAPER_PART_CUT = _CUT_PAPER(b'\x01') # Partial cut paper +# Beep +BEEP = b'\x07' + # Panel buttons (e.g. the FEED button) _PANEL_BUTTON = lambda n: ESC + b'c5' + six.int2byte(n) PANEL_BUTTON_ON = _PANEL_BUTTON(0) # enable all panel buttons PANEL_BUTTON_OFF = _PANEL_BUTTON(1) # disable all panel buttons +# Sheet modes +SHEET_SLIP_MODE = ESC + b'\x63\x30\x04' # slip paper +SHEET_ROLL_MODE = ESC + b'\x63\x30\x01' # paper roll + # Text format # TODO: Acquire the "ESC/POS Application Programming Guide for Paper Roll # Printers" and tidy up this stuff too. @@ -104,6 +111,18 @@ SET_FONT = lambda n: ESC + b'\x4d' + n TXT_FONT_A = SET_FONT(b'\x00') # Font type A TXT_FONT_B = SET_FONT(b'\x01') # Font type B +# Text colors +TXT_COLOR_BLACK = ESC + b'\x72\x00' # Default Color +TXT_COLOR_RED = ESC + b'\x72\x01' # Alternative Color (Usually Red) + +# Spacing +LINESPACING_RESET = ESC + b'2' +LINESPACING_FUNCS = { + 60: ESC + b'A', # line_spacing/60 of an inch, 0 <= line_spacing <= 85 + 360: ESC + b'+', # line_spacing/360 of an inch, 0 <= line_spacing <= 255 + 180: ESC + b'3', # line_spacing/180 of an inch, 0 <= line_spacing <= 255 +} + # Char code table CHARCODE_PC437 = ESC + b'\x74\x00' # USA: Standard Europe CHARCODE_JIS = ESC + b'\x74\x01' # Japanese Katakana @@ -189,7 +208,7 @@ QR_ECLEVEL_L = 0 QR_ECLEVEL_M = 1 QR_ECLEVEL_Q = 2 QR_ECLEVEL_H = 3 - + # QRcode models QR_MODEL_1 = 1 QR_MODEL_2 = 2 diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 50e59f8..9a18fec 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -585,6 +585,35 @@ class Escpos(object): else: self._raw(TXT_INVERT_OFF) + def line_spacing(self, spacing=None, divisor=180): + """ Set line character spacing. + + If no spacing is given, we reset it to the default. + + There are different commands for setting the line spacing, using + a different denominator: + + '+'' line_spacing/360 of an inch, 0 <= line_spacing <= 255 + '3' line_spacing/180 of an inch, 0 <= line_spacing <= 255 + 'A' line_spacing/60 of an inch, 0 <= line_spacing <= 85 + + Some printers may not support all of them. The most commonly + available command (using a divisor of 180) is chosen. + """ + if spacing is None: + self._raw(LINESPACING_RESET) + return + + if divisor not in LINESPACING_FUNCS: + raise ValueError("divisor must be either 360, 180 or 60") + if (divisor in [360, 180] \ + and (not(0 <= spacing <= 255))): + raise ValueError("spacing must be a int between 0 and 255 when divisor is 360 or 180") + if divisor == 60 and (not(0 <= spacing <= 85)): + raise ValueError("spacing must be a int between 0 and 85 when divisor is 60") + + self._raw(LINESPACING_FUNCS[divisor] + six.int2byte(spacing)) + def cut(self, mode=''): """ Cut paper. diff --git a/test/test_functions.py b/test/test_functions.py new file mode 100644 index 0000000..22ee737 --- /dev/null +++ b/test/test_functions.py @@ -0,0 +1,26 @@ +from nose.tools import assert_raises +from escpos.printer import Dummy + + +def test_line_spacing_code_gen(): + printer = Dummy() + printer.line_spacing(10) + assert printer.output == b'\x1b3\n' + + +def test_line_spacing_rest(): + printer = Dummy() + printer.line_spacing() + assert printer.output == b'\x1b2' + + +def test_line_spacing_error_handling(): + printer = Dummy() + with assert_raises(ValueError): + printer.line_spacing(99, divisor=44) + with assert_raises(ValueError): + printer.line_spacing(divisor=80, spacing=86) + with assert_raises(ValueError): + printer.line_spacing(divisor=360, spacing=256) + with assert_raises(ValueError): + printer.line_spacing(divisor=180, spacing=256) \ No newline at end of file