/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine 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. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.io.device.printer; import totalcross.io.*; import totalcross.io.device.*; import totalcross.ui.gfx.*; import totalcross.ui.image.*; /** Used as interface to printers that uses Bluetooth to communicate with the device. * See the CitizenPrinter javadocs if you plan to use one. * <p> * Note: during tests, we found that some printers require to fill their buffer to start printing. * So, if you have problems printing, try the following code after you instantiate this class: * <pre> * cp = new CitizenPrinter(); // or new BluetoothPrinter(); * cp.write(new byte[2048]); // fill the buffer * cp.newLine(); * ... * </pre> */ public class BluetoothPrinter { static final byte ESC = 27; private static final byte[] ENTER = {(byte)'\n'}; PortConnector con; public static final byte IMAGE_MODE_8_SINGLE = (byte)0; public static final byte IMAGE_MODE_8_DOUBLE = (byte)1; public static final byte IMAGE_MODE_24_SINGLE = (byte)0x20; public static final byte IMAGE_MODE_24_DOUBLE = (byte)0x21; /** Creates a new BluetoothPrinter instance, using PortConnector.BLUETOOTH port at 57600 baud rate. */ public BluetoothPrinter() throws IOException { this(new PortConnector(PortConnector.BLUETOOTH, 57600)); } /** Creates a new BluetoothPrinter instance, using the given PortConnector as bridge to the printer. * Note that PortConnector can use any port (including infrared), however, it is not guaranteed * that it will work with that port. For example, IR does not work on Palm OS devices. */ public BluetoothPrinter(PortConnector con) throws IOException { this.con = con; } /** Sends the given raw data to the printer. */ public void write(byte[] data) throws IOException { con.writeBytes(data, 0, data.length); } /** Sends an escape command to the printer. */ public void escape(int command) throws IOException { write(new byte[]{ESC, (byte)command}); } /** Sends an escape command to the printer. */ public void escape(int command, int value1) throws IOException { write(new byte[]{ESC, (byte)command, (byte)value1}); } /** Sends an escape command to the printer. */ public void escape(int command, int value1, int value2) throws IOException { write(new byte[]{ESC, (byte)command, (byte)value1, (byte)value2}); } /** Prints the given String. */ public void print(String str) throws IOException { write(str.getBytes()); } private static int getVerticalDensity(byte mode) { return mode >= IMAGE_MODE_24_SINGLE ? 24 : 8; } /** Prints the given MonoImage. See IMAGE_xxx for possible modes. * <b> IMPORTANT: the image height must be a multiple of the vertical density! </b> * If it's not, a new image will be created, forcing the correct behavior. * <br><br> * In the image, only black pixels are written. The maximum width * for single density is 192, and for double density is 384; the image is trimmed * to fit these values. */ public void print(MonoImage img, byte imageMode) throws ImageException, IOException { int vd = getVerticalDensity(imageMode); int remains = img.getHeight() % vd; if (remains != 0) // if the number of vertical dots is not a multiple of the vertical density, fill the remaining with white { MonoImage img2 = new MonoImage(img.getWidth(), img.getHeight()+vd-remains); Graphics g = img2.getGraphics(); g.backColor = Color.WHITE; g.fillRect(0,0,img2.getWidth(),img2.getHeight()); g.drawImage(img, 0,0); img = img2; } img.printTo(this, imageMode); } /** Sends a new line to the printer. */ public void newLine() throws IOException { write(ENTER); } public void close() throws IOException { con.close(); } }