?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /******************************************************************************
2 PostScript Printer Language Support
3  
4 Summary:
5 This file provides support for the PostScript printer language when using the
6 USB Embedded Host Printer Client Driver.
7  
8 Description:
9 This file provides support for the PostScript printer language when using the
10 USB Embedded Host Printer Client Driver.
11  
12 In general, PostScript is recommended for use with the USB Embedded Host
13 printer class when printing to a full sheet printer. Implementation of the
14 PostScript language across various printers is standard, ensuring uniform
15 output from printers produced by different manufacturers.
16  
17 Notes:
18 The PostScript coordinate origin is located at the bottom left corner of the
19 paper. For consistency for the user, the coordinates are adjusted so the
20 origin is located at the top left corner. This matches the coordinate
21 system use by the Microchip Graphics library.
22  
23 *******************************************************************************/
24 //DOM-IGNORE-BEGIN
25 /******************************************************************************
26  
27 FileName: usb_host_printer_postscript.c
28 Dependencies: None
29 Processor: PIC24F/PIC32MX
30 Compiler: C30/C32
31 Company: Microchip Technology, Inc.
32  
33 Software License Agreement
34  
35 The software supplied herewith by Microchip Technology Incorporated
36 (the “Company”) for its PICmicro® Microcontroller is intended and
37 supplied to you, the Company’s customer, for use solely and
38 exclusively on Microchip PICmicro Microcontroller products. The
39 software is owned by the Company and/or its supplier, and is
40 protected under applicable copyright laws. All rights are reserved.
41 Any use in violation of the foregoing restrictions may subject the
42 user to criminal sanctions under applicable laws, as well as to
43 civil liability for the breach of the terms and conditions of this
44 license.
45  
46 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
47 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
48 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
49 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
50 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
51 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
52  
53 Change History:
54 Rev Description
55 ---------- ----------------------------------------------------------
56 2.6 - 2.6a No change
57  
58 2.7 Changed the interface to _SetCurrentPosition to be able to
59 take in the printer number as a parameter.
60  
61 2.7a Provided macro wrapped versions of malloc() and free()
62 so that a user can override these functions easily.
63 *******************************************************************************/
64 //DOM-IGNORE-END
65  
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include "GenericTypedefs.h"
70 #include "USB\usb.h"
71 #include "USB\usb_host_printer.h"
72 #include "USB\usb_host_printer_postscript.h"
73  
74 //#define DEBUG_MODE
75 #ifdef DEBUG_MODE
76 #include "uart2.h"
77 #endif
78  
79  
80 #ifdef USB_PRINTER_LANGUAGE_POSTSCRIPT
81  
82  
83 // *****************************************************************************
84 // *****************************************************************************
85 // Section: Configuration
86 // *****************************************************************************
87 // *****************************************************************************
88  
89 #if !defined(USB_ENABLE_TRANSFER_EVENT)
90 #error The USB Host Printer Client Driver requires transfer events.
91 #endif
92  
93  
94 // *****************************************************************************
95 // *****************************************************************************
96 // Section: Constants
97 // *****************************************************************************
98 // *****************************************************************************
99  
100 #define ESCAPE "\033"
101  
102 #define COMMAND_EJECT_PAGE "showpage "
103  
104 #define COMMAND_GRAPHICS_COLOR_BLACK "0 setgray "
105 #define COMMAND_GRAPHICS_COLOR_WHITE "1 setgray "
106 #define COMMAND_GRAPHICS_LINE_TYPE_DASHED "[3] 0 setdash "
107 #define COMMAND_GRAPHICS_LINE_TYPE_DOTTED "[1 5] 0 setdash"
108 #define COMMAND_GRAPHICS_LINE_TYPE_SOLID "[] 0 setdash "
109 #define COMMAND_GRAPHICS_LINE_WIDTH_NORMAL "1 setlinewidth "
110 #define COMMAND_GRAPHICS_LINE_WIDTH_THICK "3 setlinewidth "
111 #define COMMAND_GRAPHICS_LINE_END_BUTT "0 setlinecap "
112 #define COMMAND_GRAPHICS_LINE_END_ROUND "1 setlinecap "
113 #define COMMAND_GRAPHICS_LINE_END_SQUARE "2 setlinecap "
114 #define COMMAND_GRAPHICS_LINE_JOIN_BEVEL "2 setlinejoin "
115 #define COMMAND_GRAPHICS_LINE_JOIN_MITER "0 setlinejoin "
116 #define COMMAND_GRAPHICS_LINE_JOIN_ROUND "1 setlinejoin "
117 #define COMMAND_GRAPHICS_MOVE_TO "%d %d moveto "
118 #define COMMAND_GRAPHICS_MOVE_RELATIVE "%d %d rmoveto "
119 #define COMMAND_GRAPHICS_LINE_TO "%d %d lineto "
120 #define COMMAND_GRAPHICS_LINE_TO_RELATIVE "%d %d rlineto "
121 #define COMMAND_GRAPHICS_ARC "%d %d %d %d %d arc "
122 #define COMMAND_GRAPHICS_ARC_TO "%d %d %d %d %d arcto clear "
123 #define COMMAND_GRAPHICS_CIRCLE "%d %d %d 0 360 arc "
124 #define COMMAND_GRAPHICS_CLOSEPATH "closepath "
125  
126 #define COMMAND_IMAGE_STOP ">} image grestore "
127 #define COMMAND_JOB_START ESCAPE "%-12345X"
128 #define COMMAND_LANDSCAPE "612 0 translate 90 rotate "
129 #define COMMAND_JOB_STOP "showpage " ESCAPE "%-12345X"
130 #define COMMAND_SET_POSITION "%d %d moveto "
131 #define COMMAND_TEXT_START "("
132 #define COMMAND_TEXT_STOP ") show "
133 #define COMMAND_FILL "fill "
134 #define COMMAND_STROKE "stroke "
135  
136 #define X_COORDINATE_IN_RANGE(x) ((0 <= (x)) && ((x) <= printerListPostScript[printer].currentWidth))
137 #define Y_COORDINATE_IN_RANGE(y) ((0 <= (y)) && ((y) <= printerListPostScript[printer].currentHeight))
138  
139 // *****************************************************************************
140 // *****************************************************************************
141 // Section: Data Structures
142 // *****************************************************************************
143 // *****************************************************************************
144  
145 //-----------------------------------------------------------------------------
146 /* Printer Status Structure
147  
148 This structure holds the information about an attached printer. One instance
149 of this structure is needed for each attached printer.
150 */
151  
152 typedef struct _PRINTER_STATUS_POSTSCRIPT
153 {
154 USB_PRINTER_FUNCTION_SUPPORT support; // The functions supported by this printer.
155  
156 WORD currentHeight; // The current height of the page in points.
157 WORD currentWidth; // The current width of the page in points.
158  
159 WORD currentX; // Current X-axis position.
160 WORD currentY; // Current Y-axis position.
161  
162 BYTE deviceAddress; // Address of the attached printer
163 BYTE fontName; // Currently selected font
164 BYTE fontSize; // Size of the current font
165  
166 union
167 {
168 BYTE value;
169  
170 struct
171 {
172 BYTE isLandscape : 1; // Landscape(1) or portrait(0)
173 BYTE isBold : 1; // If the font is bold
174 BYTE isItalic : 1; // If the font is italic
175 BYTE penIsWhite : 1; // Current selected pen is white.
176 };
177 } printerFlags;
178  
179 } PRINTER_STATUS_POSTSCRIPT;
180  
181  
182 // *****************************************************************************
183 // *****************************************************************************
184 // Section: Global Variables
185 // *****************************************************************************
186 // *****************************************************************************
187  
188 const unsigned char _psCharacterArray[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
189 const char _psFontNames[USB_PRINTER_FONT_MAX_FONT][4][30] = {
190 { "AvantGarde-Book", "AvantGarde-Demi", "AvantGarde-Oblique", "AvantGarde-DemiOblique" },
191 { "Bookman-Light", "Bookman-Demi", "Bookman-LightOblique", "Bookman-DemiOblique" },
192 { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" },
193 { "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique" },
194 { "Helvetica-Narrow", "Helvetica-Narrow-Bold", "Helvetica-Narrow-Oblique", "Helvetica-Narrow-BoldOblique" },
195 { "NewCenturySchlbk-Roman", "NewCenturySchlbk-Bold", "NewCenturySchlbk-Italic", "NewCenturySchlbk-BoldItalic" },
196 { "Palatino-Roman", "Palatino-Bold", "Palatino-Italic", "Palatino-BoldItalic" },
197 { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic" } };
198  
199 PRINTER_STATUS_POSTSCRIPT printerListPostScript[USB_MAX_PRINTER_DEVICES];
200  
201  
202 // *****************************************************************************
203 // *****************************************************************************
204 // Section: Macros
205 // *****************************************************************************
206 // *****************************************************************************
207  
208 #define PAGE_IS_LANDSCAPE(x) ((x & 0x01) == 0x01)
209 #define PAGE_IS_PORTRAIT(x) ((x & 0x01) == 0x00)
210 #define FONT_IS_BOLD(x) ((x & 0x02) == 0x02)
211 #define FONT_IS_ITALIC(x) ((x & 0x04) == 0x04)
212  
213 #define _SetCurrentPosition(p,x,y) \
214 { \
215 printerListPostScript[(p)].currentX = (x); \
216 printerListPostScript[(p)].currentY = (y); \
217 }
218  
219 #ifndef USB_MALLOC
220 #define USB_MALLOC(size) malloc(size)
221 #endif
222  
223 #ifndef USB_FREE
224 #define USB_FREE(ptr) free(ptr)
225 #endif
226  
227 #define USB_FREE_AND_CLEAR(ptr) {USB_FREE(ptr); ptr = NULL;}
228  
229 // *****************************************************************************
230 // *****************************************************************************
231 // Section: Local Prototypes
232 // *****************************************************************************
233 // *****************************************************************************
234  
235 static BYTE _PrintFontCommand( BYTE printer, BYTE transferFlags );
236 static BYTE _PrintStaticCommand( BYTE address, char *command, BYTE transferFlags );
237 static void _SetFontString( BYTE font, BYTE printerFlags, char *ptr );
238  
239  
240 // *****************************************************************************
241 // *****************************************************************************
242 // Section: Interface Functions
243 // *****************************************************************************
244 // *****************************************************************************
245  
246 /****************************************************************************
247 Function:
248 BYTE USBHostPrinterLanguagePostScript( BYTE address,
249 USB_PRINTER_COMMAND command, USB_DATA_POINTER data, DWORD size, BYTE transferFlags )
250  
251 Summary:
252 This function executes printer commands for a PostScript printer.
253  
254 Description:
255 This function executes printer commands for a PostScript printer. When
256 the application issues a printer command, the printer client driver
257 determines what language to use to communicate with the printer, and
258 transfers the command to that language support routine. As much as
259 possible, commands are designed to produce the same output regardless
260 of what printer language is used.
261  
262 Not all printer commands support data from both RAM and ROM. Unless
263 otherwise noted, the data pointer is assumed to point to RAM, regardless of
264 the value of transferFlags. Refer to the specific command to see if ROM
265 data is supported.
266  
267 Preconditions:
268 None
269  
270 Parameters:
271 BYTE address - Device's address on the bus
272 USB_PRINTER_COMMAND command - Command to execute. See the enumeration
273 USB_PRINTER_COMMAND for the list of
274 valid commands and their requirements.
275 USB_DATA_POINTER data - Pointer to the required data. Note that
276 the caller must set transferFlags
277 appropriately to indicate if the pointer is
278 a RAM pointer or a ROM pointer.
279 DWORD size - Size of the data. For some commands, this
280 parameter is used to hold the data itself.
281 BYTE transferFlags - Flags that indicate details about the
282 transfer operation. Refer to these flags
283 * USB_PRINTER_TRANSFER_COPY_DATA
284 * USB_PRINTER_TRANSFER_STATIC_DATA
285 * USB_PRINTER_TRANSFER_NOTIFY
286 * USB_PRINTER_TRANSFER_FROM_ROM
287 * USB_PRINTER_TRANSFER_FROM_RAM
288  
289 Return Values:
290 USB_PRINTER_SUCCESS - The command was executed successfully.
291 USB_PRINTER_UNKNOWN_DEVICE - A printer with the indicated address is not
292 attached
293 USB_PRINTER_TOO_MANY_DEVICES - The printer status array does not have
294 space for another printer.
295 USB_PRINTER_OUT_OF_MEMORY - Not enough available heap space to
296 execute the command.
297 other - See possible return codes from the
298 function USBHostPrinterWrite().
299  
300 Remarks:
301 When developing new commands, keep in mind that the function
302 USBHostPrinterCommandReady() will be used before calling this function to
303 see if there is space available in the output transfer queue.
304 USBHostPrinterCommandReady() will routine TRUE if a single space is
305 available in the output queue. Therefore, each command can generate only
306 one output transfer.
307  
308 Multiple printer languages may be used in a single application. The USB
309 Embedded Host Printer Client Driver will call the routine required for the
310 attached device.
311 ***************************************************************************/
312  
313 BYTE USBHostPrinterLanguagePostScript( BYTE address,
314 USB_PRINTER_COMMAND command, USB_DATA_POINTER data, DWORD size, BYTE transferFlags )
315 {
316 char *buffer;
317 BYTE printer = 0;
318  
319 if (command != USB_PRINTER_ATTACHED)
320 {
321 // Try to find the current printer. If we can't find the printer in the list,
322 // put it in the list at the first available location.
323 for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListPostScript[printer].deviceAddress != address); printer++ );
324 if (printer == USB_MAX_PRINTER_DEVICES)
325 {
326 return USB_PRINTER_UNKNOWN_DEVICE;
327 }
328 }
329  
330 switch( command )
331 {
332 //---------------------------------------------------------------------
333 case USB_PRINTER_ATTACHED:
334 for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListPostScript[printer].deviceAddress != 0); printer++ );
335 if (printer != USB_MAX_PRINTER_DEVICES)
336 {
337 printerListPostScript[printer].deviceAddress = address;
338 printerListPostScript[printer].support = *((USB_PRINTER_FUNCTION_SUPPORT *)(data.pointerRAM));
339 return USB_PRINTER_SUCCESS;
340 }
341 return USB_PRINTER_TOO_MANY_DEVICES;
342 break;
343  
344 //---------------------------------------------------------------------
345 case USB_PRINTER_DETACHED:
346 for (printer=0; (printer<USB_MAX_PRINTER_DEVICES) && (printerListPostScript[printer].deviceAddress != address); printer++ );
347 if (printer != USB_MAX_PRINTER_DEVICES)
348 {
349 printerListPostScript[printer].deviceAddress = 0;
350 }
351 return USB_PRINTER_SUCCESS;
352 break;
353  
354 //---------------------------------------------------------------------
355 case USB_PRINTER_JOB_START:
356 // Initialize page information.
357 printerListPostScript[printer].fontName = USB_PRINTER_FONT_HELVETICA;
358 printerListPostScript[printer].fontSize = 12;
359 printerListPostScript[printer].printerFlags.value = 0;
360 printerListPostScript[printer].currentHeight = PRINTER_PAGE_PORTRAIT_HEIGHT;
361 printerListPostScript[printer].currentWidth = PRINTER_PAGE_PORTRAIT_WIDTH;
362 _SetCurrentPosition( printer, 0, 0 );
363 return _PrintStaticCommand( address, COMMAND_JOB_START, transferFlags );
364 break;
365  
366 //---------------------------------------------------------------------
367 case USB_PRINTER_JOB_STOP:
368 return _PrintStaticCommand( address, COMMAND_JOB_STOP, transferFlags | USB_PRINTER_TRANSFER_NOTIFY );
369 break;
370  
371 //---------------------------------------------------------------------
372 case USB_PRINTER_ORIENTATION_PORTRAIT:
373 // PostScript resets all settings at the beginning of a page. Portrait
374 // is the default orientation, so we don't have to do anything. This
375 // command should be the first command sent after USB_PRINTER_JOB_START
376 // or USB_PRINTER_EJECT_PAGE.
377 printerListPostScript[printer].printerFlags.isLandscape = 0;
378 printerListPostScript[printer].currentHeight = PRINTER_PAGE_PORTRAIT_HEIGHT;
379 printerListPostScript[printer].currentWidth = PRINTER_PAGE_PORTRAIT_WIDTH;
380 return USB_PRINTER_SUCCESS;
381 break;
382  
383 //---------------------------------------------------------------------
384 case USB_PRINTER_ORIENTATION_LANDSCAPE:
385 // PostScript resets all settings at the beginning of a page. This
386 // command should be the first command sent after USB_PRINTER_JOB_START
387 // or USB_PRINTER_EJECT_PAGE. It must be called only once, or the
388 // paper will be rotated again.
389 printerListPostScript[printer].printerFlags.isLandscape = 1;
390 printerListPostScript[printer].currentHeight = PRINTER_PAGE_LANDSCAPE_HEIGHT;
391 printerListPostScript[printer].currentWidth = PRINTER_PAGE_LANDSCAPE_WIDTH;
392 return _PrintStaticCommand( address, COMMAND_LANDSCAPE, transferFlags );
393 break;
394  
395 //---------------------------------------------------------------------
396 case USB_PRINTER_FONT_NAME:
397 // Font name is passed in the size parameter.
398 printerListPostScript[printer].fontName = (BYTE)size;
399 return _PrintFontCommand( printer, transferFlags );
400 break;
401  
402 //---------------------------------------------------------------------
403 case USB_PRINTER_FONT_SIZE:
404 // Font size is passed in the size parameter.
405 printerListPostScript[printer].fontSize = (BYTE)size;
406 return _PrintFontCommand( printer, transferFlags );
407 break;
408  
409 //---------------------------------------------------------------------
410 case USB_PRINTER_FONT_ITALIC:
411 printerListPostScript[printer].printerFlags.isItalic = 1;
412 return _PrintFontCommand( printer, transferFlags );
413 break;
414  
415 //---------------------------------------------------------------------
416 case USB_PRINTER_FONT_UPRIGHT:
417 printerListPostScript[printer].printerFlags.isItalic = 0;
418 return _PrintFontCommand( printer, transferFlags );
419 break;
420  
421 //---------------------------------------------------------------------
422 case USB_PRINTER_FONT_BOLD:
423 printerListPostScript[printer].printerFlags.isBold = 1;
424 return _PrintFontCommand( printer, transferFlags );
425 break;
426  
427 //---------------------------------------------------------------------
428 case USB_PRINTER_FONT_MEDIUM:
429 printerListPostScript[printer].printerFlags.isBold = 0;
430 return _PrintFontCommand( printer, transferFlags );
431 break;
432  
433 //---------------------------------------------------------------------
434 case USB_PRINTER_EJECT_PAGE:
435 // When we eject a page, all of our settings are cleared.
436 return _PrintStaticCommand( address, COMMAND_EJECT_PAGE, transferFlags );
437 break;
438  
439 //---------------------------------------------------------------------
440 case USB_PRINTER_TEXT_START:
441 return _PrintStaticCommand( address, COMMAND_TEXT_START, transferFlags );
442 break;
443  
444 //---------------------------------------------------------------------
445 case USB_PRINTER_TEXT:
446 case USB_PRINTER_TRANSPARENT:
447 // If the user's data is in ROM, we have to copy it to RAM first,
448 // so the USB Host routines can read it.
449 if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
450 {
451 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
452 }
453 if (transferFlags & USB_PRINTER_TRANSFER_COPY_DATA)
454 {
455 buffer = (char *)USB_MALLOC( size );
456 if (buffer == NULL)
457 {
458 return USB_PRINTER_OUT_OF_MEMORY;
459 }
460  
461 if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
462 {
463 #if defined( __C30__ )
464 char __prog__ *ptr;
465 #elif defined( __PIC32MX__ )
466 const char *ptr;
467 #endif
468 DWORD i;
469  
470 ptr = ((USB_DATA_POINTER)data).pointerROM;
471 for (i=0; i<size; i++)
472 {
473 buffer[i] = *ptr++;
474 }
475 }
476 else
477 {
478 char *ptr;
479 DWORD i;
480  
481 ptr = ((USB_DATA_POINTER)data).pointerRAM;
482 for (i=0; i<size; i++)
483 {
484 buffer[i] = *ptr++;
485 }
486 }
487 }
488 else
489 {
490 buffer = ((USB_DATA_POINTER)data).pointerRAM;
491 }
492  
493 return USBHostPrinterWrite( address, buffer, size, transferFlags );
494 break;
495  
496 //---------------------------------------------------------------------
497 case USB_PRINTER_TEXT_STOP:
498 return _PrintStaticCommand( address, COMMAND_TEXT_STOP, transferFlags );
499 break;
500  
501 //---------------------------------------------------------------------
502 case USB_PRINTER_GRAPHICS_MOVE_TO:
503 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
504 if (!X_COORDINATE_IN_RANGE((WORD)(size >> 16)) || !Y_COORDINATE_IN_RANGE((WORD)size ))
505 {
506 return USB_PRINTER_BAD_PARAMETER;
507 }
508 #endif
509 case USB_PRINTER_SET_POSITION:
510 // This command sets the cursor to the specified position. Note
511 // that we must convert the specification to use PostScript's
512 // orientation of the Y-axis.
513 buffer = (char *)USB_MALLOC( 16 );
514 if (buffer == NULL)
515 {
516 return USB_PRINTER_OUT_OF_MEMORY;
517 }
518  
519 sprintf( buffer, COMMAND_SET_POSITION, (WORD)(size >> 16), printerListPostScript[printer].currentHeight - (WORD)size );
520 _SetCurrentPosition( printer, (WORD)(size >> 16), (WORD)size );
521 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
522 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
523 break;
524  
525 //---------------------------------------------------------------------
526 case USB_PRINTER_IMAGE_START:
527 buffer = (char *)USB_MALLOC( 146 );
528 if (buffer == NULL)
529 {
530 return USB_PRINTER_OUT_OF_MEMORY;
531 }
532  
533 {
534 USB_PRINTER_IMAGE_INFO *info;
535  
536 info = (USB_PRINTER_IMAGE_INFO *)(data.pointerRAM);
537  
538 sprintf( buffer, "gsave %d %d %d %7.2f mul sub translate %d %7.2f mul %d %7.2f mul scale %d %d 1 [%d 0 0 -%d 0 %d] {<",
539 info->positionX, printerListPostScript[printer].currentHeight - info->positionY, info->height, (double)info->scale,
540 info->width, (double)info->scale, info->height, (double)info->scale,
541 info->width, info->height,
542 info->width, info->height, info->height );
543 #ifdef DEBUG_MODE
544 UART2PrintString( buffer );
545 UART2PrintString( "\r\n" );
546 #endif
547 }
548 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
549 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
550 break;
551  
552 //---------------------------------------------------------------------
553 case USB_PRINTER_IMAGE_DATA_HEADER:
554 return USB_PRINTER_SUCCESS;
555 break;
556  
557 //---------------------------------------------------------------------
558 case USB_PRINTER_IMAGE_DATA:
559 // We have to translate the data here from binary to an ASCII representation
560 // of the binary. For each four bits, we need one byte for the ASCII, plus one
561 // for a NULL at the end. We cannot do this in terms of bytes - PostScript will
562 // ignore extra bits at the end of a single character only, not at the end of
563 // a byte.
564  
565 // Determine the number of data nibbles. We might have a size that is
566 // not an even multiple of 4 bits. To account for this, add 3 to the
567 // size, and then divide by 4.
568 size += 3;
569 size /= 4;
570  
571 buffer = (char *)USB_MALLOC( size + 1 ); // Add one for possible truncation error.
572 if (buffer == NULL)
573 {
574 return USB_PRINTER_OUT_OF_MEMORY;
575 }
576 else
577 {
578 WORD i;
579 BYTE printVar;
580 char *tempNew;
581  
582 // If the data is being read from ROM, then we have to
583 // use a different pointer type to get the data.
584 if (transferFlags & USB_PRINTER_TRANSFER_FROM_ROM)
585 {
586 #if defined( __C30__ )
587 BYTE __prog__ *tempOld;
588 #elif defined( __PIC32MX__ )
589 const BYTE *tempOld;
590 #endif
591  
592 tempNew = (char *)buffer;
593 tempOld = ((USB_DATA_POINTER)data).pointerROM;
594  
595 // PostScript will ignore extra bits at the end of a nibble, but
596 // not at the end of a byte. Therefore, we have to print one
597 // nibble at a time.
598 for (i=0; i<size; i++)
599 {
600 if (!(i & 0x01))
601 {
602 // Most significant nibble. Don't advance the byte pointer.
603 printVar = (*tempOld>>4) & 0x0F;
604 }
605 else
606 {
607 // Least significant nibble. Advance the byte pointer.
608 printVar = *tempOld++ & 0x0F;
609 }
610 *tempNew++ = _psCharacterArray[printVar];
611 }
612 }
613 else
614 {
615 BYTE *tempOld;
616  
617 tempNew = (char *)buffer;
618 tempOld = ((USB_DATA_POINTER)data).pointerRAM;
619  
620 // PostScript will ignore extra bits at the end of a nibble, but
621 // not at the end of a byte. Therefore, we have to print one
622 // nibble at a time.
623 for (i=0; i<size; i++)
624 {
625 if (!(i & 0x01))
626 {
627 // Most significant nibble. Don't advance the byte pointer.
628 printVar = (*tempOld>>4) & 0x0F;
629 }
630 else
631 {
632 // Least significant nibble. Advance the byte pointer.
633 printVar = *tempOld++ & 0x0F;
634 }
635 *tempNew++ = _psCharacterArray[printVar];
636 }
637 }
638  
639 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
640 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, size, transferFlags );
641 }
642 break;
643  
644 //---------------------------------------------------------------------
645 case USB_PRINTER_IMAGE_STOP:
646 return _PrintStaticCommand( address, COMMAND_IMAGE_STOP, transferFlags );
647 break;
648  
649  
650 //---------------------------------------------------------------------
651 case USB_PRINTER_GRAPHICS_LINE_TYPE:
652 if (size == PRINTER_LINE_TYPE_SOLID)
653 {
654 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_TYPE_SOLID, transferFlags );
655 }
656 else if (size == PRINTER_LINE_TYPE_DASHED)
657 {
658 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_TYPE_DASHED, transferFlags );
659 }
660 else // PRINTER_LINE_TYPE_DOTTED
661 {
662 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_TYPE_DOTTED, transferFlags );
663 }
664 break;
665  
666 break;
667  
668 //---------------------------------------------------------------------
669 case USB_PRINTER_GRAPHICS_LINE_WIDTH:
670 if (size == PRINTER_LINE_WIDTH_NORMAL)
671 {
672 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_WIDTH_NORMAL, transferFlags );
673 }
674 else //PRINTER_LINE_WIDTH_THICK
675 {
676 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_WIDTH_THICK, transferFlags );
677 }
678 break;
679  
680 //---------------------------------------------------------------------
681 case USB_PRINTER_GRAPHICS_LINE_END:
682 if (size == PRINTER_LINE_END_BUTT)
683 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_END_BUTT, transferFlags );
684 else if (size == PRINTER_LINE_END_ROUND)
685 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_END_ROUND, transferFlags );
686 else //PRINTER_LINE_END_SQUARE
687 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_END_SQUARE, transferFlags );
688 break;
689  
690 //---------------------------------------------------------------------
691 case USB_PRINTER_GRAPHICS_LINE_JOIN:
692 if (size == PRINTER_LINE_JOIN_BEVEL)
693 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_JOIN_BEVEL, transferFlags );
694 if (size == PRINTER_LINE_JOIN_MITER)
695 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_JOIN_MITER, transferFlags );
696 else // PRINTER_LINE_JOIN_ROUND
697 return _PrintStaticCommand( address, COMMAND_GRAPHICS_LINE_JOIN_ROUND, transferFlags );
698 break;
699  
700 //---------------------------------------------------------------------
701 case USB_PRINTER_GRAPHICS_FILL_TYPE:
702 // This command is not supported yet. It's a bit complicated.
703 break;
704  
705 //---------------------------------------------------------------------
706 case USB_PRINTER_GRAPHICS_COLOR:
707 if (size == PRINTER_COLOR_BLACK)
708 {
709 printerListPostScript[printer].printerFlags.penIsWhite = 0;
710 return _PrintStaticCommand( address, COMMAND_GRAPHICS_COLOR_BLACK, transferFlags );
711 }
712 else //PRINTER_COLOR_WHITE
713 {
714 printerListPostScript[printer].printerFlags.penIsWhite = 1;
715 return _PrintStaticCommand( address, COMMAND_GRAPHICS_COLOR_WHITE, transferFlags );
716 }
717 break;
718  
719 //---------------------------------------------------------------------
720 case USB_PRINTER_GRAPHICS_MOVE_RELATIVE:
721 // Note that we must convert the specification to use PostScript's
722 // orientation of the Y-axis.
723 {
724 int x;
725 int y;
726  
727 x = printerListPostScript[printer].currentX + (int)(size >> 16);
728 y = printerListPostScript[printer].currentY + (int)(size & 0xFFFF);
729  
730 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
731 if (!X_COORDINATE_IN_RANGE( x ) || !Y_COORDINATE_IN_RANGE( y ))
732 {
733 return USB_PRINTER_BAD_PARAMETER;
734 }
735 #endif
736  
737 buffer = (char *)USB_MALLOC( 16 );
738 if (buffer == NULL)
739 {
740 return USB_PRINTER_OUT_OF_MEMORY;
741 }
742  
743 sprintf( buffer, COMMAND_GRAPHICS_MOVE_TO, x, printerListPostScript[printer].currentHeight - y ) ;
744 _SetCurrentPosition( printer, x, y );
745 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
746 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
747 }
748 break;
749  
750 //---------------------------------------------------------------------
751 case USB_PRINTER_GRAPHICS_LINE:
752 // Note that we must convert the specification to use PostScript's
753 // orientation of the Y-axis.
754  
755 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
756 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.x1) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.y1) ||
757 !X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.x2) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.y2))
758 {
759 return USB_PRINTER_BAD_PARAMETER;
760 }
761 #endif
762  
763 buffer = (char *)USB_MALLOC( 73 );
764 if (buffer == NULL)
765 {
766 return USB_PRINTER_OUT_OF_MEMORY;
767 }
768  
769 sprintf( buffer, COMMAND_SET_POSITION COMMAND_GRAPHICS_LINE_TO COMMAND_STROKE,
770 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.x1, printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.y1),
771 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.x2, printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.y2) );
772 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.x2, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sLine.y2 );
773 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
774 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
775 break;
776  
777 //---------------------------------------------------------------------
778 case USB_PRINTER_GRAPHICS_LINE_TO:
779 // Note that we must convert the specification to use PostScript's
780 // orientation of the Y-axis.
781  
782 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
783 if (!X_COORDINATE_IN_RANGE( (int)(size >> 16) ) || !Y_COORDINATE_IN_RANGE( (int)(size & 0xFFFF) ))
784 {
785 return USB_PRINTER_BAD_PARAMETER;
786 }
787 #endif
788  
789 buffer = (char *)USB_MALLOC( 46 );
790 if (buffer == NULL)
791 {
792 return USB_PRINTER_OUT_OF_MEMORY;
793 }
794  
795 sprintf( buffer, COMMAND_GRAPHICS_MOVE_TO COMMAND_GRAPHICS_LINE_TO COMMAND_STROKE,
796 printerListPostScript[printer].currentX, printerListPostScript[printer].currentHeight - printerListPostScript[printer].currentY,
797 (int)(size >> 16), printerListPostScript[printer].currentHeight - (int)(size & 0xFFFF) );
798 _SetCurrentPosition( printer, (int)(size >> 16), (int)(size & 0xFFFF) );
799 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
800 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
801 break;
802  
803 //---------------------------------------------------------------------
804 case USB_PRINTER_GRAPHICS_LINE_TO_RELATIVE:
805 // Note that we must convert the specification to use PostScript's
806 // orientation of the Y-axis.
807  
808 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
809 if (!X_COORDINATE_IN_RANGE( printerListPostScript[printer].currentX + (int)(size >> 16) ) || !Y_COORDINATE_IN_RANGE( printerListPostScript[printer].currentY + (int)(size & 0xFFFF) ))
810 {
811 return USB_PRINTER_BAD_PARAMETER;
812 }
813 #endif
814  
815 buffer = (char *)USB_MALLOC( 46 );
816 if (buffer == NULL)
817 {
818 return USB_PRINTER_OUT_OF_MEMORY;
819 }
820  
821 sprintf( buffer, COMMAND_GRAPHICS_MOVE_TO COMMAND_GRAPHICS_LINE_TO_RELATIVE COMMAND_STROKE,
822 printerListPostScript[printer].currentX, printerListPostScript[printer].currentHeight - printerListPostScript[printer].currentY,
823 (int)(size >> 16), (int)(size & 0xFFFF) * -1 ) ;
824 _SetCurrentPosition( printer, printerListPostScript[printer].currentX + (int)(size >> 16), printerListPostScript[printer].currentY + (int)(size & 0xFFFF) );
825 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
826 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
827 break;
828  
829 //---------------------------------------------------------------------
830 case USB_PRINTER_GRAPHICS_ARC:
831 // Note that we must convert the specification to use PostScript's
832 // orientation of the Y-axis. Also, the coordinate parameters do
833 // not match the command parameters (x,y).
834 // x y ro a1 a2 arc fill 1 setgray x y ri a1 a2 arc fill 0 setgray
835  
836 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
837 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.xL) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.yT) ||
838 !X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.xR) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.yB))
839 {
840 return USB_PRINTER_BAD_PARAMETER;
841 }
842 #endif
843  
844 buffer = (char *)USB_MALLOC( 15 + (56 + 11)* 2 );
845 if (buffer == NULL)
846 {
847 return USB_PRINTER_OUT_OF_MEMORY;
848 }
849  
850 {
851 int a1;
852 int a2;
853 int x;
854 int y;
855 BYTE mask;
856 BYTE maskPrevious;
857  
858 // Find the angles that define the arc.
859  
860 if (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.octant == 0)
861 {
862 a1 = 0;
863 a2 = 0;
864 }
865 else if (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.octant == 0xFF)
866 {
867 a1 = 0;
868 a2 = 360;
869 }
870 else
871 {
872 // Look for the first edge of the arc.
873 a1 = 0;
874 mask = 0x02;
875 maskPrevious = 0x04;
876 while (!((mask & ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.octant) && !(maskPrevious & ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.octant)))
877 {
878 a1 += 45;
879 maskPrevious = mask;
880 mask >>= 1;
881 if (mask == 0)
882 {
883 mask = 0x80;
884 }
885 }
886  
887 // Look for the second edge of the arc
888 a2 = a1;
889 while (mask & ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.octant)
890 {
891 a2 += 45;
892 mask >>= 1;
893 if (mask == 0)
894 {
895 mask = 0x80;
896 }
897 }
898 }
899  
900 // Draw the outer circle of the arc.
901  
902 x = (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.xR + ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.xL) / 2;
903 y = (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.yT + ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.yB) / 2;
904  
905 sprintf( buffer, COMMAND_GRAPHICS_MOVE_TO COMMAND_GRAPHICS_ARC COMMAND_FILL,
906 x, printerListPostScript[printer].currentHeight - y,
907 x, printerListPostScript[printer].currentHeight - y,
908 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.r2, a1, a2 );
909  
910 if (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.r1 != 0)
911 {
912 // Change pens
913  
914 if (printerListPostScript[printer].printerFlags.penIsWhite)
915 {
916 strcat( buffer, COMMAND_GRAPHICS_COLOR_BLACK );
917 }
918 else
919 {
920 strcat( buffer, COMMAND_GRAPHICS_COLOR_WHITE );
921 }
922  
923 // Draw the inner circle to erase the interior.
924  
925 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_ARC COMMAND_FILL,
926 x, printerListPostScript[printer].currentHeight - y,
927 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.r1, a1, a2 );
928  
929 // Put the original pen back.
930  
931 if (printerListPostScript[printer].printerFlags.penIsWhite)
932 {
933 strcat( buffer, COMMAND_GRAPHICS_COLOR_WHITE );
934 }
935 else
936 {
937 strcat( buffer, COMMAND_GRAPHICS_COLOR_BLACK );
938 }
939 }
940 }
941 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.xL, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sArc.yT );
942 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
943 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
944 break;
945  
946 //---------------------------------------------------------------------
947 case USB_PRINTER_GRAPHICS_CIRCLE:
948 case USB_PRINTER_GRAPHICS_CIRCLE_FILLED:
949 // Note that we must convert the specification to use PostScript's
950 // orientation of the Y-axis.
951  
952 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
953 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.x + ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.r) ||
954 !X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.x - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.r) ||
955 !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.y + ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.r) ||
956 !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.y - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.r))
957 {
958 return USB_PRINTER_BAD_PARAMETER;
959 }
960 #endif
961  
962 buffer = (char *)USB_MALLOC( 50 );
963 if (buffer == NULL)
964 {
965 return USB_PRINTER_OUT_OF_MEMORY;
966 }
967  
968 sprintf( buffer, COMMAND_GRAPHICS_CIRCLE,
969 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.x,
970 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.y),
971 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.r );
972  
973 if (command == USB_PRINTER_GRAPHICS_CIRCLE)
974 {
975 strcat( buffer, COMMAND_STROKE );
976 }
977 else // USB_PRINTER_GRAPHICS_CIRCLE_FILLED
978 {
979 strcat( buffer, COMMAND_FILL );
980 }
981  
982 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.x, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sCircle.y );
983 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
984 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
985 break;
986  
987 //---------------------------------------------------------------------
988 case USB_PRINTER_GRAPHICS_BEVEL:
989 case USB_PRINTER_GRAPHICS_BEVEL_FILLED:
990 // Note that we must convert the specification to use PostScript's
991 // orientation of the Y-axis.
992 // xL yB-r moveto xL yT xR yT r arcto clear xR yT xR yB r arcto clear xR yB xL yT r arcto clear xL yB xL yT r arcto clear stroke
993  
994 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
995 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yT) ||
996 !X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xR) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB))
997 {
998 return USB_PRINTER_BAD_PARAMETER;
999 }
1000 #endif
1001  
1002 buffer = (char *)USB_MALLOC( 155 );
1003 if (buffer == NULL)
1004 {
1005 return USB_PRINTER_OUT_OF_MEMORY;
1006 }
1007  
1008 // xL yB+r moveto
1009 sprintf( buffer, COMMAND_SET_POSITION,
1010 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL,
1011 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.r ));
1012  
1013 // xL yT xR yT r arcto clear
1014 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_ARC_TO,
1015 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL,
1016 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yT),
1017 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xR,
1018 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yT),
1019 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.r );
1020  
1021 // xR yT xR yB r arcto clear
1022 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_ARC_TO,
1023 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xR,
1024 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yT),
1025 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xR,
1026 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB),
1027 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.r );
1028  
1029 // xR yB xL yB r arcto clear
1030 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_ARC_TO,
1031 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xR,
1032 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB),
1033 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL,
1034 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB),
1035 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.r );
1036  
1037 // xL yB xL yT r arcto clear
1038 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_ARC_TO,
1039 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL,
1040 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB),
1041 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL,
1042 printerListPostScript[printer].currentHeight - (((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yT),
1043 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.r );
1044  
1045 if (command == USB_PRINTER_GRAPHICS_BEVEL)
1046 {
1047 strcat( buffer, COMMAND_STROKE );
1048 }
1049 else // USB_PRINTER_GRAPHICS_BEVEL_FILLED
1050 {
1051 strcat( buffer, COMMAND_FILL );
1052 }
1053  
1054 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.xL, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sBevel.yB );
1055 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
1056 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
1057 break;
1058  
1059 //---------------------------------------------------------------------
1060 case USB_PRINTER_GRAPHICS_RECTANGLE:
1061 case USB_PRINTER_GRAPHICS_RECTANGLE_FILLED:
1062 // Note that we must convert the specification to use PostScript's
1063 // orientation of the Y-axis.
1064 // xL yB moveto xL yT lineto xR yT lineto xR yB lineto closepath stroke
1065  
1066 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
1067 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xL) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yT) ||
1068 !X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xR) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yB))
1069 {
1070 return USB_PRINTER_BAD_PARAMETER;
1071 }
1072 #endif
1073  
1074 buffer = (char *)USB_MALLOC( 80 );
1075 if (buffer == NULL)
1076 {
1077 return USB_PRINTER_OUT_OF_MEMORY;
1078 }
1079  
1080 // xL yB moveto
1081 sprintf( buffer, COMMAND_SET_POSITION,
1082 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xL,
1083 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yB );
1084  
1085 // xL yT lineto
1086 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_LINE_TO,
1087 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xL,
1088 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yT );
1089  
1090 // xR yT lineto
1091 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_LINE_TO,
1092 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xR,
1093 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yT );
1094  
1095 // xR yB lineto
1096 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_LINE_TO,
1097 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xR,
1098 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yB );
1099  
1100 strcat( buffer, COMMAND_GRAPHICS_CLOSEPATH );
1101 if (command == USB_PRINTER_GRAPHICS_RECTANGLE)
1102 {
1103 strcat( buffer, COMMAND_STROKE );
1104 }
1105 else // USB_PRINTER_GRAPHICS_RECTANGLE_FILLED
1106 {
1107 strcat( buffer, COMMAND_FILL );
1108 }
1109  
1110 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.xL, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sRectangle.yB );
1111 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
1112 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
1113 break;
1114  
1115 //---------------------------------------------------------------------
1116 case USB_PRINTER_GRAPHICS_POLYGON:
1117 // Note that we must convert the specification to use PostScript's
1118 // orientation of the Y-axis.
1119  
1120 #ifdef PRINTER_GRAPHICS_COORDINATE_CHECKING
1121 {
1122 WORD i;
1123  
1124 for (i = 0; i < ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.numPoints * 2; i+=2)
1125 {
1126 if (!X_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i]) || !Y_COORDINATE_IN_RANGE(((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i+1]))
1127 {
1128 return USB_PRINTER_BAD_PARAMETER;
1129 }
1130 }
1131 }
1132 #endif
1133  
1134 buffer = (char *)USB_MALLOC( 15 + ( 15 * ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.numPoints) + 18 );
1135 if (buffer == NULL)
1136 {
1137 return USB_PRINTER_OUT_OF_MEMORY;
1138 }
1139  
1140 {
1141 WORD i = 0;
1142  
1143 // x0 y0 moveto
1144 sprintf( buffer, COMMAND_SET_POSITION,
1145 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i],
1146 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i+1] );
1147 i += 2;
1148  
1149 // xn yn lineto
1150 while (i < ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.numPoints * 2)
1151 {
1152 sprintf( &(buffer[strlen(buffer)]), COMMAND_GRAPHICS_LINE_TO,
1153 ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i],
1154 printerListPostScript[printer].currentHeight - ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[i+1] );
1155 i += 2;
1156 }
1157  
1158 strcat( buffer, COMMAND_GRAPHICS_CLOSEPATH COMMAND_STROKE );
1159 }
1160  
1161 _SetCurrentPosition( printer, ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[0], ((USB_PRINTER_GRAPHICS_PARAMETERS *)(data.pointerRAM))->sPolygon.points[1] );
1162 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
1163 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
1164 break;
1165  
1166 //---------------------------------------------------------------------
1167 default:
1168 return USB_PRINTER_UNKNOWN_COMMAND;
1169 break;
1170 }
1171 return USB_PRINTER_UNKNOWN_COMMAND;
1172 }
1173  
1174  
1175 /****************************************************************************
1176 Function:
1177 BOOL USBHostPrinterLanguagePostScriptIsSupported( char *deviceID,
1178 USB_PRINTER_FUNCTION_SUPPORT *support )
1179  
1180 Description:
1181 This function determines if the printer with the given device ID string
1182 supports the PostScript printer language.
1183  
1184 Preconditions:
1185 None
1186  
1187 Parameters:
1188 char *deviceID - Pointer to the "COMMAND SET:" portion of the device ID
1189 string of the attached printer.
1190 USB_PRINTER_FUNCTION_SUPPORT *support - Pointer to returned information
1191 about what types of functions this printer supports.
1192  
1193 Return Values:
1194 TRUE - The printer supports PostScript.
1195 FALSE - The printer does not support PostScript.
1196  
1197 Remarks:
1198 The caller must first locate the "COMMAND SET:" section of the device ID
1199 string. To ensure that only the "COMMAND SET:" section of the device ID
1200 string is checked, the ";" at the end of the section should be temporarily
1201 replaced with a NULL. Otherwise, this function may find the printer
1202 language string in the comments or other section, and incorrectly indicate
1203 that the printer supports the language.
1204  
1205 Device ID strings are case sensitive.
1206 ***************************************************************************/
1207  
1208 BOOL USBHostPrinterLanguagePostScriptIsSupported( char *deviceID,
1209 USB_PRINTER_FUNCTION_SUPPORT *support )
1210 {
1211 if (strstr( deviceID, LANGUAGE_ID_STRING_POSTSCRIPT ))
1212 {
1213 support->val = LANGUAGE_SUPPORT_FLAGS_POSTSCRIPT;
1214 return TRUE;
1215 }
1216 return FALSE;
1217 }
1218  
1219 // *****************************************************************************
1220 // *****************************************************************************
1221 // Section: Local Functions
1222 // *****************************************************************************
1223 // *****************************************************************************
1224  
1225 /****************************************************************************
1226 Function:
1227 static BYTE _PrintFontCommand( BYTE printer, BYTE transferFlags )
1228  
1229 Description:
1230 This function generates the command needed to select the desired font
1231 and sends it to the printer. The font specification includes typeface,
1232 size, and bold and italic indications.
1233  
1234 Preconditions:
1235 None
1236  
1237 Parameters:
1238 BYTE printer - Index of the desired printer in the printer support array.
1239 BYTE transferFlags - Transfer control flags.
1240  
1241 Return Values:
1242 USB_PRINTER_SUCCESS - Command completed successfully.
1243 USB_PRINTER_OUT_OF_MEMORY - Not enough dynamic memory to perform the
1244 command.
1245 others - See the return values for the function
1246 USBHostPrinterWrite().
1247  
1248 Remarks:
1249 None
1250 ***************************************************************************/
1251  
1252 static BYTE _PrintFontCommand( BYTE printer, BYTE transferFlags )
1253 {
1254 char *buffer;
1255 // char temp[6];
1256  
1257 buffer = (char *)USB_MALLOC( 1 + 30 + 10 + 5 + 20 );
1258 if (buffer == NULL)
1259 {
1260 return USB_PRINTER_OUT_OF_MEMORY;
1261 }
1262  
1263 buffer[0] = '/';
1264 _SetFontString( printerListPostScript[printer].fontName, printerListPostScript[printer].printerFlags.value, &(buffer[1]) );
1265 sprintf( &(buffer[strlen(buffer)]), " findfont %d scalefont setfont ", printerListPostScript[printer].fontSize );
1266 // strcat( buffer, " findfont " );
1267 // sprintf( temp, "%d", printerListPostScript[printer].fontSize );
1268 // strcat( buffer, temp );
1269 // strcat( buffer, " scalefont setfont " );
1270  
1271 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
1272  
1273 return USBHostPrinterWrite( printerListPostScript[printer].deviceAddress, buffer, strlen(buffer), transferFlags );
1274 }
1275  
1276  
1277 /****************************************************************************
1278 Function:
1279 static BYTE _PrintStaticCommand( BYTE address, char *command, BYTE transferFlags )
1280  
1281 Description:
1282 This function sends a hard-coded command to the printer. Many printer
1283 commands are constant text strings that require no parameters. This
1284 routine allocates dynamic memory for a copy of the command, copies the
1285 command into the string, and sends the command to the printer.
1286  
1287 Preconditions:
1288 None
1289  
1290 Parameters:
1291 BYTE address - Address of the attached printer.
1292 char *command - Printer command string.
1293 BYTE transferFlags - Transfer control string.
1294  
1295 Return Values:
1296 USB_PRINTER_SUCCESS - Command completed successfully.
1297 USB_PRINTER_OUT_OF_MEMORY - Not enough dynamic memory to perform the
1298 command.
1299 others - See the return values for the function
1300 USBHostPrinterWrite().
1301  
1302 Remarks:
1303 None
1304 ***************************************************************************/
1305  
1306 static BYTE _PrintStaticCommand( BYTE address, char *command, BYTE transferFlags )
1307 {
1308 char *buffer;
1309  
1310 USBHOSTPRINTER_SETFLAG_COPY_DATA( transferFlags );
1311  
1312 buffer = (char *)USB_MALLOC( strlen(command) + 1 );
1313 if (buffer == NULL)
1314 {
1315 return USB_PRINTER_OUT_OF_MEMORY;
1316 }
1317 strcpy( buffer, command );
1318 return USBHostPrinterWrite( address, buffer, strlen(buffer), transferFlags );
1319 }
1320  
1321  
1322 /****************************************************************************
1323 Function:
1324 static void _SetFontString( BYTE font, BYTE printerFlags, char *ptr )
1325  
1326 Description:
1327 This function puts the string that designates the selected font into
1328 the indicated character buffer.
1329  
1330 Preconditions:
1331 None
1332  
1333 Parameters:
1334 BYTE font - Font indication. See the enumeration
1335 USB_PRINTER_FONTS for the list of valid values.
1336 BYTE printerFlags - Flags that indicate the bold and italic condition
1337 of the font. These must match the structure of
1338 printerFlags in the PRINTER_STATUS_POSTSCRIPT
1339 structure
1340 char *ptr - Buffer to store the font string.
1341  
1342 Returns:
1343 None
1344  
1345 Remarks:
1346 None
1347 ***************************************************************************/
1348  
1349 static void _SetFontString( BYTE font, BYTE printerFlags, char *ptr )
1350 {
1351 BYTE i;
1352  
1353 if (font > USB_PRINTER_FONT_MAX_FONT)
1354 {
1355 font = USB_PRINTER_FONT_COURIER;
1356 }
1357  
1358 i = 0;
1359 if (FONT_IS_BOLD( printerFlags )) i |= 0x01;
1360 if (FONT_IS_ITALIC( printerFlags)) i |= 0x02;
1361  
1362 strcpy( ptr, &(_psFontNames[font][i][0]) );
1363 }
1364  
1365  
1366  
1367 #endif
1368  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3