Fri, 25 Sep 2009 10:51:24 +0100
test app now a little more interesting -- prints component box labels
philpem@3 | 1 | /************************** |
philpem@3 | 2 | * P-Touch PT-2450DX printer driver |
philpem@3 | 3 | * |
philpem@3 | 4 | * P. Pemberton, 2009 |
philpem@3 | 5 | * |
philpem@3 | 6 | * Specs: |
philpem@3 | 7 | * Printer head is 128 dots, 180dpi, for a total print area of ~18mm vertical |
philpem@3 | 8 | * by however long your TZ label tape is. |
philpem@3 | 9 | * Printhead size is (128/180)=0.711[.] inches, or 18.0622[.] mm |
philpem@3 | 10 | * Each dot is (18.062/128) = 0.1411[.] mm |
philpem@3 | 11 | * Printable area is (numdots * 0.1411) mm |
philpem@3 | 12 | * |
philpem@3 | 13 | * Tape width Margins Printable area |
philpem@3 | 14 | * mm dots mm dots mm dots |
philpem@3 | 15 | * 6mm 42 1.0mm 7 4mm 28 |
philpem@3 | 16 | * 9mm 63 1.0mm 7 7mm 49 |
philpem@3 | 17 | * 12mm 85 2.0mm 14 8mm 57 |
philpem@3 | 18 | * 18mm 127 3.0mm 21 12mm 85 |
philpem@3 | 19 | * 24mm 170 3.0mm 128 18mm 128 *** |
philpem@3 | 20 | * |
philpem@3 | 21 | * 24mm is slightly odd. Because the printhead is only 128 dots (18mm), the |
philpem@3 | 22 | * margins are enforced by this, and not the driver software. It is impossible |
philpem@3 | 23 | * to print right to the edge of a 24mm label in a PT-2450DX. |
philpem@3 | 24 | * |
philpem@3 | 25 | **************************/ |
philpem@3 | 26 | |
philpem@0 | 27 | #include <stdio.h> |
philpem@0 | 28 | #include <stdlib.h> |
philpem@10 | 29 | #include <gd.h> |
philpem@10 | 30 | #include <gdfonts.h> |
philpem@10 | 31 | #include <gdfontl.h> |
philpem@3 | 32 | #include "ptouch.h" |
philpem@0 | 33 | |
philpem@3 | 34 | /****************************************************************************/ |
philpem@0 | 35 | |
philpem@0 | 36 | int main(int argc, char **argv) |
philpem@0 | 37 | { |
philpem@3 | 38 | pt_Device *dev; |
philpem@3 | 39 | |
philpem@0 | 40 | // check command line args |
philpem@0 | 41 | if (argc < 2) { |
philpem@0 | 42 | printf("ERROR: must specify device name\n"); |
philpem@0 | 43 | return -1; |
philpem@0 | 44 | } |
philpem@0 | 45 | |
philpem@3 | 46 | // Open and initialise the printer |
philpem@3 | 47 | dev = pt_Initialise(argv[1]); |
philpem@3 | 48 | |
philpem@3 | 49 | if (dev == NULL) { |
philpem@3 | 50 | printf("Error opening printer device.\n"); |
philpem@0 | 51 | return -1; |
philpem@0 | 52 | } |
philpem@0 | 53 | |
philpem@10 | 54 | // Get printer status |
philpem@10 | 55 | int err; |
philpem@10 | 56 | if ((err = pt_GetStatus(dev)) != PT_ERR_SUCCESS) { |
philpem@10 | 57 | printf("getstatus error %d\n", err); |
philpem@10 | 58 | return -1; |
philpem@10 | 59 | } |
philpem@10 | 60 | |
philpem@22 | 61 | // Figure out image width from DPI |
philpem@22 | 62 | // Multiply by 10, that way we can use integer math instead if floating |
philpem@22 | 63 | // point for the DPI/width calculations. |
philpem@22 | 64 | unsigned long labelLength = ((20.0 * dev->dpiLabel * 10) / 254) - 2; |
philpem@22 | 65 | |
philpem@22 | 66 | // quick test |
philpem@22 | 67 | printf("label of 256 dots = %lf in\n", (256.0 / dev->dpiLabel)); |
philpem@22 | 68 | printf("label of 256 dots = %lf mm\n", (256.0 / dev->dpiLabel) * 25.4); |
philpem@22 | 69 | printf("label of %ld dots = %lf mm\n", labelLength, (((double)labelLength) / dev->dpiLabel) * 25.4); |
philpem@22 | 70 | |
philpem@10 | 71 | // Create a label |
philpem@10 | 72 | gdImagePtr im; |
philpem@10 | 73 | int white, black; |
philpem@22 | 74 | im = gdImageCreate(labelLength, dev->pixelWidth); |
philpem@10 | 75 | white = gdImageColorAllocate(im, 255, 255, 255); |
philpem@10 | 76 | black = gdImageColorAllocate(im, 0, 0, 0); |
philpem@22 | 77 | /* gdImageString(im, gdFontGetLarge(), 0, 0, "!!123!! Test label !!ABC!!", black); |
philpem@10 | 78 | gdImageString(im, gdFontGetLarge(), 10, 10, "!!123!! Test label !!ABC!!", black); |
philpem@10 | 79 | gdImageString(im, gdFontGetLarge(), 20, 20, "!!123!! Test label !!ABC!!", black); |
philpem@10 | 80 | gdImageString(im, gdFontGetLarge(), 30, 30, "!!123!! Test label !!ABC!!", black); |
philpem@10 | 81 | gdImageString(im, gdFontGetLarge(), 40, 40, "!!123!! Test label !!ABC!!", black); |
philpem@22 | 82 | */ |
philpem@22 | 83 | |
philpem@22 | 84 | //#define FONT_BLUEHIGHWAY |
philpem@22 | 85 | |
philpem@22 | 86 | #if defined(FONT_BLUEHIGHWAY) |
philpem@22 | 87 | char *font_normal = "./bluehighway/bluehigh.ttf"; |
philpem@22 | 88 | char *font_bold = "./bluehighway/bluebold.ttf"; |
philpem@22 | 89 | #else |
philpem@22 | 90 | char *font_normal = "./Arial.ttf"; |
philpem@22 | 91 | char *font_bold = "./Arial_Bold.ttf"; |
philpem@22 | 92 | #endif |
philpem@22 | 93 | |
philpem@22 | 94 | char *pn = "SMD-001/01"; |
philpem@22 | 95 | char *strings[] = { |
philpem@22 | 96 | "Surface mount resistor", |
philpem@22 | 97 | "0805, \u00BCW (SMD-001/01)", |
philpem@22 | 98 | "$33\u03A9", |
philpem@22 | 99 | }; |
philpem@22 | 100 | |
philpem@22 | 101 | int curtop = 3; |
philpem@22 | 102 | int brect[8]; |
philpem@22 | 103 | char *fte; |
philpem@22 | 104 | |
philpem@22 | 105 | gdFTStringExtra extra; |
philpem@22 | 106 | extra.flags = gdFTEX_RESOLUTION | gdFTEX_DISABLE_KERNING; |
philpem@22 | 107 | extra.hdpi = dev->dpiLabel; |
philpem@22 | 108 | extra.vdpi = dev->dpiPrinthead; |
philpem@22 | 109 | |
philpem@22 | 110 | //// PART NUMBER |
philpem@22 | 111 | // calc bounding box |
philpem@22 | 112 | fte = gdImageStringFTEx(NULL, &brect[0], 0, font_bold, 9.0, 0.0, 0, 0, pn, &extra); |
philpem@22 | 113 | if (fte != NULL) printf("freetype error: %s\n", fte); |
philpem@22 | 114 | |
philpem@22 | 115 | // draw P/N |
philpem@22 | 116 | fte = gdImageStringFTEx(im, NULL, 0-black, font_bold, 9.0, 0.0, 3+abs(brect[6]), curtop+abs(brect[7]), pn, &extra); |
philpem@22 | 117 | if (fte != NULL) printf("freetype error: %s\n", fte); |
philpem@22 | 118 | |
philpem@22 | 119 | // update Y position |
philpem@22 | 120 | curtop += abs(brect[7]) + 2; |
philpem@22 | 121 | |
philpem@22 | 122 | //// draw description |
philpem@22 | 123 | for (int i=0; i<(sizeof(strings)/sizeof(strings[0])); i++) { |
philpem@22 | 124 | char *str = strings[i]; |
philpem@22 | 125 | char *font = font_normal; |
philpem@22 | 126 | float fontsize = 7.0; |
philpem@22 | 127 | |
philpem@22 | 128 | if (*str == '$') { font = font_bold; fontsize = 8.0; str++; } |
philpem@22 | 129 | |
philpem@22 | 130 | fte = gdImageStringFTEx(NULL, &brect[0], 0, font, fontsize, 0.0, 0, 0, str, &extra); |
philpem@22 | 131 | if (fte != NULL) printf("freetype error: %s\n", fte); |
philpem@22 | 132 | |
philpem@22 | 133 | fte = gdImageStringFTEx(im, NULL, 0-black, font, fontsize, 0.0, 3+abs(brect[6]), curtop+abs(brect[7]), str, &extra); |
philpem@22 | 134 | if (fte != NULL) printf("freetype error: %s\n", fte); |
philpem@22 | 135 | |
philpem@22 | 136 | curtop += abs(brect[7]) + 1; |
philpem@22 | 137 | } |
philpem@10 | 138 | |
philpem@10 | 139 | // dump the image (for testing purposes) |
philpem@10 | 140 | FILE *fp = fopen("labeldump.png", "wb"); |
philpem@10 | 141 | gdImagePng(im, fp); |
philpem@10 | 142 | fclose(fp); |
philpem@10 | 143 | |
philpem@16 | 144 | // Set job options |
philpem@16 | 145 | pt_SetOption(dev, PT_OPTION_AUTOCUT, 1); |
philpem@16 | 146 | pt_SetOption(dev, PT_OPTION_MIRROR, 1); |
philpem@19 | 147 | pt_SetOption(dev, PT_OPTION_SEPARATOR, 1); |
philpem@16 | 148 | |
philpem@10 | 149 | // Print the label |
philpem@10 | 150 | printf("Print state code: %d\n", pt_Print(dev, &im, 1)); |
philpem@10 | 151 | |
philpem@10 | 152 | gdImageDestroy(im); |
philpem@10 | 153 | |
philpem@3 | 154 | // Close the printer device |
philpem@3 | 155 | pt_Close(dev); |
philpem@0 | 156 | |
philpem@0 | 157 | return 0; |
philpem@0 | 158 | } |