1.1 diff -r a933b13e087f -r 088286f9e1e4 src/ptouch.c 1.2 --- a/src/ptouch.c Wed Aug 05 15:02:31 2009 +0100 1.3 +++ b/src/ptouch.c Wed Aug 05 15:04:55 2009 +0100 1.4 @@ -11,6 +11,10 @@ 1.5 // TODO: disable 1.6 #define DEBUG 1.7 1.8 +// This debug option forces Request Status to always "see" a good status 1.9 +// block. Mostly useful for testing using write-to-file mode. 1.10 +#define DEBUG_SKIP_STATUS_READ 1.11 + 1.12 #include <stdio.h> 1.13 #include <stdlib.h> 1.14 #include <stdbool.h> 1.15 @@ -56,6 +60,18 @@ 1.16 1.17 int pt_GetStatus(pt_Device *dev) 1.18 { 1.19 +#ifdef DEBUG_SKIP_STATUS_READ 1.20 + unsigned char buf[32]; 1.21 + memset(buf, 0x00, 32); 1.22 + buf[0] = 0x80; 1.23 + buf[1] = 0x20; 1.24 + buf[2] = 0x42; 1.25 + buf[3] = 0x30; 1.26 + buf[4] = 0x4b; 1.27 + buf[5] = 0x30; 1.28 + buf[10] = 0x0c; 1.29 + buf[11] = 0x01; 1.30 +#else 1.31 // REQUEST STATUS 1.32 fprintf(dev->fp, "%c%c%c", ESC, 'i', 'S'); 1.33 1.34 @@ -71,6 +87,7 @@ 1.35 // Timeout 1.36 return PT_ERR_TIMEOUT; 1.37 } 1.38 +#endif 1.39 1.40 #ifdef DEBUG 1.41 printf("DEBUG: Printer status buffer = \n"); 1.42 @@ -104,16 +121,60 @@ 1.43 dev->pixelWidth = ((dev->mediaWidth * 180 * 10) / 254) - 2; 1.44 } 1.45 1.46 + // Set printing parameters to defaults -- 1.47 + // Mirror off 1.48 + // Autocut on 1.49 + dev->mirror = false; 1.50 + dev->autocut = false; 1.51 + 1.52 // Operation succeeded 1.53 return PT_ERR_SUCCESS; 1.54 } 1.55 1.56 -// TODO: print options struct parameter (e.g. fullcut, halfcut, print res, ...) 1.57 -// 1.58 -// 1.59 +int pt_SetOption(pt_Device *dev, PT_E_OPTION option, int value) 1.60 +{ 1.61 + // trap dev == NULL 1.62 + if (dev == NULL) { 1.63 + return PT_ERR_BAD_PARAMETER; 1.64 + } 1.65 + 1.66 + // set option 1.67 + switch(option) { 1.68 + case PT_OPTION_MIRROR: // Mirror 1.69 + dev->mirror = (value ? 1 : 0); 1.70 + return PT_ERR_SUCCESS; 1.71 + 1.72 + case PT_OPTION_AUTOCUT: // Auto-cutter enable/disable 1.73 + dev->autocut = (value ? 1 : 0); 1.74 + return PT_ERR_SUCCESS; 1.75 + 1.76 + default: 1.77 + return PT_ERR_BAD_PARAMETER; 1.78 + } 1.79 +} 1.80 1.81 -// labels: 1 or more labels 1.82 -// count: number of labels, 0<count<MAXINT 1.83 +int pt_GetOption(pt_Device *dev, PT_E_OPTION option, int *value) 1.84 +{ 1.85 + // trap dev == NULL or value == NULL 1.86 + if ((dev == NULL) || (value == NULL)) { 1.87 + return PT_ERR_BAD_PARAMETER; 1.88 + } 1.89 + 1.90 + // get option value 1.91 + switch(option) { 1.92 + case PT_OPTION_MIRROR: // Mirror 1.93 + *value = dev->mirror; 1.94 + return PT_ERR_SUCCESS; 1.95 + 1.96 + case PT_OPTION_AUTOCUT: // Auto-cutter enable/disable 1.97 + *value = dev->autocut; 1.98 + return PT_ERR_SUCCESS; 1.99 + 1.100 + default: 1.101 + return PT_ERR_BAD_PARAMETER; 1.102 + } 1.103 +} 1.104 + 1.105 int pt_Print(pt_Device *dev, gdImagePtr *labels, int count) 1.106 { 1.107 int err; 1.108 @@ -159,9 +220,11 @@ 1.109 1.110 // M {n1} -- Set Compression Mode 1.111 // {n1} = 0x00 ==> no compression 1.112 + // Doesn't seem to work on the PT-2450DX... 1.113 // {n1} = 0x01 ==> reserved 1.114 // {n1} = 0x02 ==> TIFF/Packbits 1.115 - fprintf(dev->fp, "M%c", 0x00); 1.116 + // But this works fine on the PT-2450DX... 1.117 + fprintf(dev->fp, "M%c", 0x02); 1.118 1.119 // Loop over the images that were passed in 1.120 for (int imnum=0; imnum < count; imnum++) { 1.121 @@ -170,10 +233,15 @@ 1.122 return PT_ERR_LABEL_TOO_WIDE; 1.123 } 1.124 1.125 - // 1.126 - // TODO: trap image height / width == 0? 1.127 - // will libgd allow an image with a zero dimension? 1.128 - // 1.129 + // Trap a label with a width of zero 1.130 + // I'm not sure if this can happen, but it's a single if statement, so 1.131 + // probably worth checking anyway... 1.132 + if (gdImageSX(*curLabel) == 0) { 1.133 + return PT_ERR_LABEL_ZERO_LENGTH; 1.134 + } 1.135 + 1.136 + // Get the index of the colour "white" (RGB:255,255,255) in the Gd image 1.137 + int col_white = gdImageColorResolve(*curLabel, 255, 255, 255); 1.138 1.139 // Iterate left-to-right over the source image 1.140 for (int xpos = 0; xpos < gdImageSX(*curLabel); xpos++) { 1.141 @@ -185,12 +253,12 @@ 1.142 1.143 // Calculate left-side margin for this label size 1.144 // Again, 128-dot printhead. 1.145 - int margin = (128 + dev->pixelWidth) / 2; 1.146 + int margin = (128 / 2) - (dev->pixelWidth / 2); 1.147 1.148 // Copy data from the image to the bit-buffer 1.149 for (int ypos = 0; ypos < gdImageSY(*curLabel); ypos++) { 1.150 - // Get pixel from gd, is it white (palette entry 0)? 1.151 - if (gdImageGetPixel(*curLabel, xpos, ypos) != 0) { 1.152 + // Get pixel from gd, is it white? 1.153 + if (gdImageGetPixel(*curLabel, xpos, ypos) != col_white) { 1.154 // No. Set the bit. 1.155 int bit = 1 << (7 - ((margin+ypos) % 8)); 1.156 bitbuf[(margin+ypos) / 8] |= bit; 1.157 @@ -211,7 +279,15 @@ 1.158 // Row is not clear -- send the pixel data 1.159 // 1.160 // TODO: the printer supports Packbits compression. Implement! 1.161 - fprintf(dev->fp, "G"); 1.162 + // TODO: After Packbits is implemented, ((128/8)+1) must be 1.163 + // changed to the length of the Packbits compressed data. 1.164 + // (note: 128/8 is the printhead size in bytes, the +1 is for 1.165 + // the control byte we add below...) 1.166 + fprintf(dev->fp, "G%c%c", ((128/8)+1) & 0xff, ((128/8)+1) >> 8); 1.167 + 1.168 + // This printer asks for Packbits compressed data. In this 1.169 + // case, we send a "run of N" control byte and fake it... 1.170 + fputc(sizeof(bitbuf) - 1, dev->fp); 1.171 for (int i=0; i<sizeof(bitbuf); i++) { 1.172 fputc(bitbuf[i], dev->fp); 1.173 }