?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 * Module for Microchip Graphics Library
3 * Graphic Primitives Layer
4 *****************************************************************************
5 * FileName: Primitive.c
6 * Dependencies: Graphics.h
7 * Processor: PIC24F, PIC24H, dsPIC, PIC32
8 * Compiler: MPLAB C30 V3.00, MPLAB C32
9 * Linker: MPLAB LINK30, MPLAB LINK32
10 * Company: Microchip Technology Incorporated
11 *
12 * Software License Agreement
13 *
14 * Copyright © 2008 Microchip Technology Inc. All rights reserved.
15 * Microchip licenses to you the right to use, modify, copy and distribute
16 * Software only when embedded on a Microchip microcontroller or digital
17 * signal controller, which is integrated into your product or third party
18 * product (pursuant to the sublicense terms in the accompanying license
19 * agreement).
20 *
21 * You should refer to the license agreement accompanying this Software
22 * for additional information regarding your rights and obligations.
23 *
24 * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
25 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
26 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
27 * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
28 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
29 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
30 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
31 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
32 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
33 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
34 * OR OTHER SIMILAR COSTS.
35 *
36 * Author Date Comment
37 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38 * Anton Alkhimenok and
39 * Paolo A. Tomayo 11/12/07 Version 1.0 release
40 *****************************************************************************/
41 #include "Graphics\Graphics.h"
42  
43 #define USE_PRIMITIVE_BEVEL
44  
45 /////////////////////// LOCAL FUNCTIONS PROTOTYPES ////////////////////////////
46 void PutImage1BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch);
47 void PutImage4BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch);
48 void PutImage8BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch);
49 void PutImage16BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch);
50  
51 void PutImage1BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch);
52 void PutImage4BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch);
53 void PutImage8BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch);
54 void PutImage16BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch);
55  
56 // Current line type
57 SHORT _lineType;
58  
59 // Current line thickness
60 BYTE _lineThickness;
61  
62 // Font orientation
63 BYTE _fontOrientation;
64  
65 // Current cursor x-coordinates
66 SHORT _cursorX;
67  
68 // Current cursor y-coordinates
69 SHORT _cursorY;
70  
71 // Pointer to the current font
72 void *_font;
73  
74 #ifdef USE_PALETTE
75 void *_palette;
76 #endif
77  
78 // First and last characters in the font
79 WORD _fontFirstChar; // First character in the font table.
80 WORD _fontLastChar; // Last character in the font table.
81  
82 // Installed font height
83 SHORT _fontHeight;
84  
85 // bevel drawing type (0 = full bevel, 0xF0 - top bevel only, 0x0F - bottom bevel only
86 BYTE _bevelDrawType;
87  
88  
89 /*********************************************************************
90 * Function: void InitGraph(void)
91 *
92 * PreCondition: none
93 *
94 * Input: none
95 *
96 * Output: none
97 *
98 * Side Effects: none
99 *
100 * Overview: initializes LCD controller,
101 * sets cursor position to upper left corner,
102 * sets active and visual pages to page 0,
103 * clears active page with BLACK,
104 * sets color to WHITE,
105 * disables clipping
106 *
107 * Note: none
108 *
109 ********************************************************************/
110 void InitGraph(void)
111 {
112  
113 // Current line type
114 SetLineType(SOLID_LINE);
115  
116 // Current line thickness
117 SetLineThickness(NORMAL_LINE);
118  
119 // Current cursor coordinates to 0,0
120 MoveTo(0, 0);
121  
122 // Reset device
123 ResetDevice();
124  
125 // Set active and visual pages
126 SetActivePage(0);
127 SetVisualPage(0);
128  
129 // Set color to BLACK
130 SetColor(BLACK);
131  
132 // Clear screen
133 ClearDevice();
134  
135 // Set color to WHITE
136 SetColor(WHITE);
137  
138 // Disable clipping
139 SetClip(CLIP_DISABLE);
140  
141 // Set font orientation
142 SetFontOrientation(ORIENT_HOR);
143  
144 // set Bevel drawing
145 SetBevelDrawType(DRAWFULLBEVEL);
146 }
147  
148 /*********************************************************************
149 * Function: WORD Arc(SHORT xL, SHORT yT, SHORT xR, SHORT yB, SHORT r1, SHORT r2, BYTE octant);
150 *
151 * PreCondition: none
152 *
153 * Input: xL, yT - location of the upper left center in the x,y coordinate
154 * xR, yB - location of the lower right left center in the x,y coordinate
155 * r1, r2 - the two concentric circle radii, r1 as the radius
156 * of the smaller circle and and r2 as the radius of the
157 * larger circle.
158 * octant - bitmask of the octant that will be drawn.
159 * Moving in a clockwise direction from x = 0, y = +radius
160 * bit0 : first octant bit4 : fifth octant
161 * bit1 : second octant bit5 : sixth octant
162 * bit2 : third octant bit6 : seventh octant
163 * bit3 : fourth octant bit7 : eigth octant
164 *
165 * Output: For NON-Blocking configuration:
166 * - Returns 0 when device is busy and the shape is not yet completely drawn.
167 * - Returns 1 when the shape is completely drawn.
168 * For Blocking configuration:
169 * - Always return 1.
170 *
171 * Side Effects: none
172 *
173 * Overview: Draws the octant arc of a beveled figure with given centers, radii
174 * and octant mask. When r1 is zero and r2 has some value, a filled
175 * circle is drawn; when the radii have values, an arc of
176 * thickness (r2-r1) is drawn; when octant = 0xFF, a full ring
177 * is drawn. When r1 and r2 are zero, a rectangular object is drawn, where
178 * xL, yT specifies the left top corner; xR, yB specifies the right bottom
179 * corner.
180 *
181 * Note: none
182 *
183 ********************************************************************/
184 WORD Arc(SHORT xL, SHORT yT, SHORT xR, SHORT yB, SHORT r1, SHORT r2, BYTE octant)
185 {
186  
187 // this is using a variant of the Midpoint (Bresenham's) Algorithm
188 #ifndef USE_NONBLOCKING_CONFIG
189  
190 SHORT y1Limit, y2Limit;
191 SHORT x1, x2, y1, y2;
192 SHORT err1, err2;
193 SHORT x1Cur, y1Cur, y1New;
194 SHORT x2Cur, y2Cur, y2New;
195 DWORD_VAL temp;
196  
197 temp.Val = SIN45 * r1;
198 y1Limit = temp.w[1];
199 temp.Val = SIN45 * r2;
200 y2Limit = temp.w[1];
201  
202 temp.Val = (DWORD) (ONEP25 - ((LONG) r1 << 16));
203 err1 = (SHORT) (temp.w[1]);
204  
205 temp.Val = (DWORD) (ONEP25 - ((LONG) r2 << 16));
206 err2 = (SHORT) (temp.w[1]);
207  
208 x1 = r1;
209 x2 = r2;
210 y1 = 0;
211 y2 = 0;
212  
213 x1Cur = x1;
214 y1Cur = y1;
215 y1New = y1;
216 x2Cur = x2;
217 y2Cur = y2;
218 y2New = y2;
219  
220 while(y2 <= y2Limit)
221 { // just watch for y2 limit since outer circle
222 // will have greater value.
223 // Drawing of the rounded panel is done only when there is a change in the
224 // x direction. Bars are drawn to be efficient.
225 // detect changes in the x position. Every change will mean a bar will be drawn
226 // to cover the previous area. y1New records the last position of y before the
227 // change in x position.
228 // y1New & y2New records the last y positions, must remember this to
229 // draw the correct bars (non-overlapping).
230 y1New = y1;
231 y2New = y2;
232  
233 if(y1 <= y1Limit)
234 {
235 if(err1 > 0)
236 {
237 x1--;
238 err1 += 5;
239 err1 += (y1 - x1) << 1;
240 }
241 else
242 {
243 err1 += 3;
244 err1 += y1 << 1;
245 }
246  
247 y1++;
248 }
249 else
250 {
251 y1++;
252 if(x1 < y1)
253 x1 = y1;
254 }
255  
256 if(err2 > 0)
257 {
258 x2--;
259 err2 += 5;
260 err2 += (y2 - x2) << 1;
261 }
262 else
263 {
264 err2 += 3;
265 err2 += y2 << 1;
266 }
267  
268 y2++;
269  
270 if((x1Cur != x1) || (x2Cur != x2))
271 {
272 if(octant & 0x01)
273 {
274 Bar(xR + y2Cur, yT - x2Cur, xR + y1New, yT - x1Cur); // 1st octant
275 }
276  
277 if(octant & 0x02)
278 {
279 Bar(xR + x1Cur, yT - y1New, xR + x2Cur, yT - y2Cur); // 2nd octant
280 }
281  
282 if(octant & 0x04)
283 {
284 Bar(xR + x1Cur, yB + y1Cur, xR + x2Cur, yB + y2New); // 3rd octant
285 }
286  
287 if(octant & 0x08)
288 {
289 Bar(xR + y1Cur, yB + x1Cur, xR + y2New, yB + x2Cur); // 4th octant
290 }
291  
292 if(octant & 0x10)
293 {
294 Bar(xL - y1New, yB + x1Cur, xL - y2Cur, yB + x2Cur); // 5th octant
295 }
296  
297 if(octant & 0x20)
298 {
299 Bar(xL - x2Cur, yB + y2Cur, xL - x1Cur, yB + y1New); // 6th octant
300 }
301  
302 if(octant & 0x40)
303 {
304 Bar(xL - x2Cur, yT - y2New, xL - x1Cur, yT - y1Cur); // 7th octant
305 }
306  
307 if(octant & 0x80)
308 {
309 Bar(xL - y2New, yT - x2Cur, xL - y1Cur, yT - x1Cur); // 8th octant
310 }
311  
312 // update current values
313 x1Cur = x1;
314 y1Cur = y1;
315 x2Cur = x2;
316 y2Cur = y2;
317 }
318 } // end of while loop
319  
320 // draw the width and height
321 if((xR - xL) || (yB - yT))
322 {
323  
324 // draw right
325 if(octant & 0x02)
326 {
327 Bar(xR + r1, yT, xR + r2, (yB + yT) >> 1);
328 }
329  
330 if(octant & 0x04)
331 {
332 Bar(xR + r1, ((yB + yT) >> 1), xR + r2, yB);
333 }
334  
335 // draw bottom
336 if(octant & 0x10)
337 {
338 Bar(xL, yB + r1, ((xR + xL) >> 1), yB + r2);
339 }
340  
341 if(octant & 0x08)
342 {
343 Bar(((xR + xL) >> 1), yB + r1, xR, yB + r2);
344 }
345  
346 if(xR - xL)
347 {
348  
349 // draw top
350 if(octant & 0x80)
351 {
352 Bar(xL, yT - r2, ((xR + xL) >> 1), yT - r1);
353 }
354  
355 if(octant & 0x01)
356 {
357 Bar(((xR + xL) >> 1), yT - r2, xR, yT - r1);
358 }
359 }
360  
361 if(yT - yB)
362 {
363  
364 // draw left
365 if(octant & 0x40)
366 {
367 Bar(xL - r2, yT, xL - r1, ((yB + yT) >> 1));
368 }
369  
370 if(octant & 0x20)
371 {
372 Bar(xL - r2, ((yB + yT) >> 1), xL - r1, yB);
373 }
374 }
375 }
376  
377 return (1);
378 #else
379  
380 typedef enum
381 {
382 BEGIN,
383 QUAD11,
384 BARRIGHT1,
385 QUAD12,
386 BARRIGHT2,
387 QUAD21,
388 BARLEFT1,
389 QUAD22,
390 BARLEFT2,
391 QUAD31,
392 BARTOP1,
393 QUAD32,
394 BARTOP2,
395 QUAD41,
396 BARBOTTOM1,
397 QUAD42,
398 BARBOTTOM2,
399 CHECK,
400 } OCTANTARC_STATES;
401  
402 DWORD_VAL temp;
403  
404 // LONG temp1;
405 static SHORT y1Limit, y2Limit;
406 static SHORT x1, x2, y1, y2;
407 static SHORT err1, err2;
408 static SHORT x1Cur, y1Cur, y1New;
409 static SHORT x2Cur, y2Cur, y2New;
410 static OCTANTARC_STATES state = BEGIN;
411  
412 while(1)
413 {
414 if(IsDeviceBusy())
415 return (0);
416 switch(state)
417 {
418 case BEGIN:
419 temp.Val = SIN45 * r1;
420 y1Limit = temp.w[1];
421 temp.Val = SIN45 * r2;
422 y2Limit = temp.w[1];
423  
424 temp.Val = (DWORD) (ONEP25 - ((LONG) r1 << 16));
425 err1 = (SHORT) (temp.w[1]);
426  
427 temp.Val = (DWORD) (ONEP25 - ((LONG) r2 << 16));
428 err2 = (SHORT) (temp.w[1]);
429  
430 x1 = r1;
431 x2 = r2;
432 y1 = 0;
433 y2 = 0;
434  
435 x1Cur = x1;
436 y1Cur = y1;
437 y1New = y1;
438 x2Cur = x2;
439 y2Cur = y2;
440 y2New = y2;
441 state = CHECK;
442  
443 case CHECK:
444 arc_check_state : if(y2 > y2Limit)
445 {
446 state = BARRIGHT1;
447 goto arc_draw_width_height_state;
448 }
449  
450 // y1New & y2New records the last y positions
451 y1New = y1;
452 y2New = y2;
453  
454 if(y1 <= y1Limit)
455 {
456 if(err1 > 0)
457 {
458 x1--;
459 err1 += 5;
460 err1 += (y1 - x1) << 1;
461 }
462 else
463 {
464 err1 += 3;
465 err1 += y1 << 1;
466 }
467  
468 y1++;
469 }
470 else
471 {
472 y1++;
473 if(x1 < y1)
474 x1 = y1;
475 }
476  
477 if(err2 > 0)
478 {
479 x2--;
480 err2 += 5;
481 err2 += (y2 - x2) << 1;
482 }
483 else
484 {
485 err2 += 3;
486 err2 += y2 << 1;
487 }
488  
489 y2++;
490  
491 state = QUAD11;
492 break;
493  
494 case QUAD11:
495 if((x1Cur != x1) || (x2Cur != x2))
496 {
497  
498 // 1st octant
499 if(octant & 0x01)
500 {
501 if(Bar(xR + y2Cur, yT - x2Cur, xR + y1New, yT - x1Cur) == 0)
502 return (0);
503 }
504 }
505 else
506 {
507 state = CHECK;
508 goto arc_check_state;
509 }
510  
511 state = QUAD12;
512 break;
513  
514 case QUAD12:
515  
516 // 2nd octant
517 if(octant & 0x02)
518 {
519 if(Bar(xR + x1Cur, yT - y1New, xR + x2Cur, yT - y2Cur) == 0)
520 return (0);
521 }
522  
523 state = QUAD21;
524 break;
525  
526 case QUAD21:
527  
528 // 3rd octant
529 if(octant & 0x04)
530 {
531 if(Bar(xR + x1Cur, yB + y1Cur, xR + x2Cur, yB + y2New) == 0)
532 return (0);
533 }
534  
535 state = QUAD22;
536 break;
537  
538 case QUAD22:
539  
540 // 4th octant
541 if(octant & 0x08)
542 {
543 if(Bar(xR + y1Cur, yB + x1Cur, xR + y2New, yB + x2Cur) == 0)
544 return (0);
545 }
546  
547 state = QUAD31;
548 break;
549  
550 case QUAD31:
551  
552 // 5th octant
553 if(octant & 0x10)
554 {
555 if(Bar(xL - y1New, yB + x1Cur, xL - y2Cur, yB + x2Cur) == 0)
556 return (0);
557 }
558  
559 state = QUAD32;
560 break;
561  
562 case QUAD32:
563  
564 // 6th octant
565 if(octant & 0x20)
566 {
567 if(Bar(xL - x2Cur, yB + y2Cur, xL - x1Cur, yB + y1New) == 0)
568 return (0);
569 }
570  
571 state = QUAD41;
572 break;
573  
574 case QUAD41:
575  
576 // 7th octant
577 if(octant & 0x40)
578 {
579 if(Bar(xL - x2Cur, yT - y2New, xL - x1Cur, yT - y1Cur) == 0)
580 return (0);
581 }
582  
583 state = QUAD42;
584 break;
585  
586 case QUAD42:
587  
588 // 8th octant
589 if(octant & 0x80)
590 {
591 if(Bar(xL - y2New, yT - x2Cur, xL - y1Cur, yT - x1Cur) == 0)
592 return (0);
593 }
594  
595 // update current values
596 x1Cur = x1;
597 y1Cur = y1;
598 x2Cur = x2;
599 y2Cur = y2;
600 state = CHECK;
601 break;
602  
603 case BARRIGHT1: // draw upper right
604 arc_draw_width_height_state : if((xR - xL) || (yB - yT))
605 {
606  
607 // draw right
608 if(octant & 0x02)
609 {
610 if(Bar(xR + r1, yT, xR + r2, (yB + yT) >> 1) == 0)
611 return (0);
612 }
613 }
614 else
615 {
616 state = BEGIN;
617 return (1);
618 }
619  
620 state = BARRIGHT2;
621 break;
622  
623 case BARRIGHT2: // draw lower right
624 if(octant & 0x04)
625 {
626 if(Bar(xR + r1, ((yB + yT) >> 1), xR + r2, yB) == 0)
627 return (0);
628 }
629  
630 state = BARBOTTOM1;
631 break;
632  
633 case BARBOTTOM1: // draw left bottom
634 // draw bottom
635 if(octant & 0x10)
636 {
637 if(Bar(xL, yB + r1, ((xR + xL) >> 1), yB + r2) == 0)
638 return (0);
639 }
640  
641 state = BARBOTTOM2;
642 break;
643  
644 case BARBOTTOM2: // draw right bottom
645 if(octant & 0x08)
646 {
647 if(Bar(((xR + xL) >> 1), yB + r1, xR, yB + r2) == 0)
648 return (0);
649 }
650  
651 state = BARTOP1;
652 break;
653  
654 case BARTOP1: // draw left top
655 if(xR - xL)
656 {
657  
658 // draw top
659 if(octant & 0x80)
660 {
661 if(Bar(xL, yT - r2, ((xR + xL) >> 1), yT - r1) == 0)
662 return (0);
663 }
664  
665 state = BARTOP2;
666 }
667 else
668 state = BARLEFT1; // no width go directly to height bar
669 break;
670  
671 case BARTOP2: // draw right top
672 if(octant & 0x01)
673 {
674 if(Bar(((xR + xL) >> 1), yT - r2, xR, yT - r1) == 0)
675 return (0);
676 }
677  
678 state = BARLEFT1;
679 break;
680  
681 case BARLEFT1: // draw upper left
682 if(yT - yB)
683 {
684  
685 // draw left
686 if(octant & 0x40)
687 {
688 if(Bar(xL - r2, yT, xL - r1, ((yB + yT) >> 1)) == 0)
689 return (0);
690 }
691  
692 state = BARLEFT2;
693 }
694 else
695 {
696 state = BEGIN; // no height go back to BEGIN
697 return (1);
698 }
699  
700 break;
701  
702 case BARLEFT2: // draw lower left
703 if(octant & 0x20)
704 {
705 if(Bar(xL - r2, ((yB + yT) >> 1), xL - r1, yB) == 0)
706 return (0);
707 }
708  
709 state = BEGIN;
710 return (1);
711 } // end of switch
712 } // end of while
713 #endif // USE_NONBLOCKING_CONFIG
714 }
715  
716 /*********************************************************************
717 * Function: WORD Line(SHORT x1, SHORT y1, SHORT x2, SHORT y2)
718 *
719 * PreCondition: none
720 *
721 * Input: x1,y1 - starting coordinates, x2,y2 - ending coordinates
722 *
723 * Output: For NON-Blocking configuration:
724 * - Returns 0 when device is busy and the shape is not yet completely drawn.
725 * - Returns 1 when the shape is completely drawn.
726 * For Blocking configuration:
727 * - Always return 1.
728 *
729 * Side Effects: none
730 *
731 * Overview: draws line
732 *
733 * Note: none
734 *
735 ********************************************************************/
736 #ifndef USE_DRV_LINE
737  
738 /* */
739 WORD Line(SHORT x1, SHORT y1, SHORT x2, SHORT y2)
740 {
741 SHORT deltaX, deltaY;
742 SHORT error, stepErrorLT, stepErrorGE;
743 SHORT stepX, stepY;
744 SHORT steep;
745 SHORT temp;
746 SHORT style, type;
747  
748 #ifndef USE_NONBLOCKING_CONFIG
749 while(IsDeviceBusy() != 0) Nop();
750  
751 /* Ready */
752 #else
753 if(IsDeviceBusy() != 0)
754 return (0);
755 #endif
756  
757 // Move cursor
758 MoveTo(x2, y2);
759  
760 if(x1 == x2)
761 {
762 if(y1 > y2)
763 {
764 temp = y1;
765 y1 = y2;
766 y2 = temp;
767 }
768  
769 style = 0;
770 type = 1;
771 for(temp = y1; temp < y2 + 1; temp++)
772 {
773 if((++style) == _lineType)
774 {
775 type ^= 1;
776 style = 0;
777 }
778  
779 if(type)
780 {
781 PutPixel(x1, temp);
782 if(_lineThickness)
783 {
784 PutPixel(x1 + 1, temp);
785 PutPixel(x1 - 1, temp);
786 }
787 }
788 }
789  
790 return (1);
791 }
792  
793 if(y1 == y2)
794 {
795 if(x1 > x2)
796 {
797 temp = x1;
798 x1 = x2;
799 x2 = temp;
800 }
801  
802 style = 0;
803 type = 1;
804 for(temp = x1; temp < x2 + 1; temp++)
805 {
806 if((++style) == _lineType)
807 {
808 type ^= 1;
809 style = 0;
810 }
811  
812 if(type)
813 {
814 PutPixel(temp, y1);
815 if(_lineThickness)
816 {
817 PutPixel(temp, y1 + 1);
818 PutPixel(temp, y1 - 1);
819 }
820 }
821 }
822  
823 return (1);
824 }
825  
826 stepX = 0;
827 deltaX = x2 - x1;
828 if(deltaX < 0)
829 {
830 deltaX = -deltaX;
831 --stepX;
832 }
833 else
834 {
835 ++stepX;
836 }
837  
838 stepY = 0;
839 deltaY = y2 - y1;
840 if(deltaY < 0)
841 {
842 deltaY = -deltaY;
843 --stepY;
844 }
845 else
846 {
847 ++stepY;
848 }
849  
850 steep = 0;
851 if(deltaX < deltaY)
852 {
853 ++steep;
854 temp = deltaX;
855 deltaX = deltaY;
856 deltaY = temp;
857 temp = x1;
858 x1 = y1;
859 y1 = temp;
860 temp = stepX;
861 stepX = stepY;
862 stepY = temp;
863 PutPixel(y1, x1);
864 }
865 else
866 {
867 PutPixel(x1, y1);
868 }
869  
870 // If the current error greater or equal zero
871 stepErrorGE = deltaX << 1;
872  
873 // If the current error less than zero
874 stepErrorLT = deltaY << 1;
875  
876 // Error for the first pixel
877 error = stepErrorLT - deltaX;
878  
879 style = 0;
880 type = 1;
881  
882 while(--deltaX >= 0)
883 {
884 if(error >= 0)
885 {
886 y1 += stepY;
887 error -= stepErrorGE;
888 }
889  
890 x1 += stepX;
891 error += stepErrorLT;
892  
893 if((++style) == _lineType)
894 {
895 type ^= 1;
896 style = 0;
897 }
898  
899 if(type)
900 {
901 if(steep)
902 {
903 PutPixel(y1, x1);
904 if(_lineThickness)
905 {
906 PutPixel(y1 + 1, x1);
907 PutPixel(y1 - 1, x1);
908 }
909 }
910 else
911 {
912 PutPixel(x1, y1);
913 if(_lineThickness)
914 {
915 PutPixel(x1, y1 + 1);
916 PutPixel(x1, y1 - 1);
917 }
918 }
919 }
920 } // end of while
921  
922 return (1);
923 }
924  
925 #endif
926  
927 /*********************************************************************
928 * Function: WORD Bevel(SHORT x1, SHORT y1, SHORT x2, SHORT y2, SHORT rad)
929 *
930 * PreCondition: None
931 *
932 * Input: x1, y1 - coordinate position of the upper left center of the
933 * circle that draws the rounded corners,
934 * x2, y2 - coordinate position of the lower right center of the
935 * circle that draws the rounded corners,
936 * rad - defines the redius of the circle,
937 *
938 * Output: For NON-Blocking configuration:
939 * - Returns 0 when device is busy and the shape is not yet completely drawn.
940 * - Returns 1 when the shape is completely drawn.
941 * For Blocking configuration:
942 * - Always return 1.
943 *
944 * Overview: Draws a beveled figure on the screen.
945 * For a pure circular object x1 = x2 and y1 = y2.
946 * For a rectangular object radius = 0.
947 *
948 * Note: none
949 *
950 ********************************************************************/
951 WORD Bevel(SHORT x1, SHORT y1, SHORT x2, SHORT y2, SHORT rad)
952 {
953 SHORT style, type, xLimit, xPos, yPos, error;
954 DWORD_VAL temp;
955  
956 #ifndef USE_NONBLOCKING_CONFIG
957 while(IsDeviceBusy() != 0) Nop();
958  
959 /* Ready */
960 #else
961 if(IsDeviceBusy() != 0)
962 return (0);
963 #endif
964 temp.Val = SIN45 * rad;
965 xLimit = temp.w[1] + 1;
966 temp.Val = (DWORD) (ONEP25 - ((LONG) rad << 16));
967 error = (SHORT) (temp.w[1]);
968 yPos = rad;
969  
970 style = 0;
971 type = 1;
972  
973 if(rad)
974 {
975 for(xPos = 0; xPos <= xLimit; xPos++)
976 {
977 if((++style) == _lineType)
978 {
979 type ^= 1;
980 style = 0;
981 }
982  
983 if(type)
984 {
985 PutPixel(x2 + xPos, y1 - yPos); // 1st quadrant
986 PutPixel(x2 + yPos, y1 - xPos);
987 PutPixel(x2 + xPos, y2 + yPos); // 2nd quadrant
988 PutPixel(x2 + yPos, y2 + xPos);
989 PutPixel(x1 - xPos, y2 + yPos); // 3rd quadrant
990 PutPixel(x1 - yPos, y2 + xPos);
991 PutPixel(x1 - yPos, y1 - xPos); // 4th quadrant
992 PutPixel(x1 - xPos, y1 - yPos);
993  
994 if(_lineThickness)
995 {
996 PutPixel(x2 + xPos, y1 - yPos - 1); // 1st quadrant
997 PutPixel(x2 + xPos, y1 - yPos + 1);
998 PutPixel(x2 + yPos + 1, y1 - xPos);
999 PutPixel(x2 + yPos - 1, y1 - xPos);
1000 PutPixel(x2 + xPos, y2 + yPos - 1); // 2nd quadrant
1001 PutPixel(x2 + xPos, y2 + yPos + 1);
1002 PutPixel(x2 + yPos + 1, y2 + xPos);
1003 PutPixel(x2 + yPos - 1, y2 + xPos);
1004 PutPixel(x1 - xPos, y2 + yPos - 1); // 3rd quadrant
1005 PutPixel(x1 - xPos, y2 + yPos + 1);
1006 PutPixel(x1 - yPos + 1, y2 + xPos);
1007 PutPixel(x1 - yPos - 1, y2 + xPos);
1008 PutPixel(x1 - yPos + 1, y1 - xPos); // 4th quadrant
1009 PutPixel(x1 - yPos - 1, y1 - xPos);
1010 PutPixel(x1 - xPos, y1 - yPos + 1);
1011 PutPixel(x1 - xPos, y1 - yPos - 1);
1012 }
1013 }
1014  
1015 if(error > 0)
1016 {
1017 yPos--;
1018 error += 5 + ((xPos - yPos) << 1);
1019 }
1020 else
1021 error += 3 + (xPos << 1);
1022 }
1023 }
1024 // Must use lines here since this can also be used to draw focus of round buttons
1025 if(x2 - x1)
1026 {
1027 while(!Line(x1, y1 - rad, x2, y1 - rad));
1028  
1029 // draw top
1030 }
1031  
1032 if(y2 - y1)
1033 {
1034 while(!Line(x1 - rad, y1, x1 - rad, y2));
1035  
1036 // draw left
1037 }
1038  
1039 if((x2 - x1) || (y2 - y1))
1040 {
1041 while(!Line(x2 + rad, y1, x2 + rad, y2));
1042  
1043 // draw right
1044 while(!Line(x1, y2 + rad, x2, y2 + rad));
1045  
1046 // draw bottom
1047 }
1048  
1049 return (1);
1050 }
1051  
1052 /*********************************************************************
1053 * Function: WORD FillBevel(SHORT x1, SHORT y1, SHORT x2, SHORT y2, SHORT rad)
1054 *
1055 * PreCondition: None
1056 *
1057 * Input: x1, y1 - coordinate position of the upper left center of the
1058 * circle that draws the rounded corners,
1059 * x2, y2 - coordinate position of the lower right center of the
1060 * circle that draws the rounded corners,
1061 * rad - defines the redius of the circle,
1062 *
1063 * Output: For NON-Blocking configuration:
1064 * - Returns 0 when device is busy and the shape is not yet completely drawn.
1065 * - Returns 1 when the shape is completely drawn.
1066 * For Blocking configuration:
1067 * - Always return 1.
1068 *
1069 * Overview: Draws a filled beveled figure on the screen.
1070 * For a filled circular object x1 = x2 and y1 = y2.
1071 * For a filled rectangular object radius = 0.
1072 *
1073 * Note: none
1074 *
1075 ********************************************************************/
1076 WORD FillBevel(SHORT x1, SHORT y1, SHORT x2, SHORT y2, SHORT rad)
1077 {
1078 #ifndef USE_NONBLOCKING_CONFIG
1079  
1080 SHORT yLimit, xPos, yPos, err;
1081 SHORT xCur, yCur, yNew;
1082 DWORD_VAL temp;
1083  
1084 // note that octants here is defined as:
1085 // from yPos=-radius, xPos=0 in the clockwise direction octant 1 to 8 are labeled
1086 // assumes an origin at 0,0. Quadrants are defined in the same manner
1087 if(rad)
1088 {
1089 temp.Val = SIN45 * rad;
1090 yLimit = temp.w[1];
1091 temp.Val = (DWORD) (ONEP25 - ((LONG) rad << 16));
1092 err = (SHORT) (temp.w[1]);
1093 xPos = rad;
1094 yPos = 0;
1095  
1096 xCur = xPos;
1097 yCur = yPos;
1098 yNew = yPos;
1099  
1100 while(yPos <= yLimit)
1101 {
1102  
1103 // Drawing of the rounded panel is done only when there is a change in the
1104 // x direction. Bars are drawn to be efficient.
1105 // detect changes in the x position. Every change will mean a bar will be drawn
1106 // to cover the previous area. y1New records the last position of y before the
1107 // change in x position.
1108 // y1New records the last y position
1109 yNew = yPos;
1110  
1111 if(err > 0)
1112 {
1113 xPos--;
1114 err += 5 + ((yPos - xPos) << 1);
1115 }
1116 else
1117 err += 3 + (yPos << 1);
1118 yPos++;
1119  
1120 if(xCur != xPos)
1121 {
1122 if (_bevelDrawType & DRAWBOTTOMBEVEL)
1123 {
1124 // 6th octant to 3rd octant
1125 Bar(x1 - xCur, y2 + yCur, x2 + xCur, y2 + yNew);
1126  
1127 // 5th octant to 4th octant
1128 Bar(x1 - yNew, y2 + xPos, x2 + yNew, y2 + xCur);
1129 }
1130  
1131 if (_bevelDrawType & DRAWTOPBEVEL)
1132 {
1133 // 8th octant to 1st octant
1134 Bar(x1 - yNew, y1 - xCur, x2 + yNew, y1 - xPos);
1135  
1136 // 7th octant to 2nd octant
1137 Bar(x1 - xCur, y1 - yNew, x2 + xCur, y1 - yCur);
1138 }
1139 // update current values
1140 xCur = xPos;
1141 yCur = yPos;
1142 }
1143 }
1144 }
1145  
1146 // this covers both filled rounded object and filled rectangle.
1147 if((x2 - x1) || (y2 - y1))
1148 {
1149 if (_bevelDrawType == DRAWFULLBEVEL)
1150 Bar(x1 - rad, y1, x2 + rad, y2);
1151 else if (_bevelDrawType == DRAWTOPBEVEL)
1152 Bar(x1 - rad, y1, x2 + rad, y1+((y2-y1)>>1));
1153 else
1154 Bar(x1 - rad, y1+((y2-y1)>>1), x2 + rad, y2);
1155 }
1156  
1157 return (1);
1158 #else
1159  
1160 typedef enum
1161 {
1162 BEGIN,
1163 CHECK,
1164 Q8TOQ1,
1165 Q7TOQ2,
1166 Q6TOQ3,
1167 Q5TOQ4,
1168 WAITFORDONE,
1169 FACE
1170 } FILLCIRCLE_STATES;
1171  
1172 DWORD_VAL temp;
1173 static LONG err;
1174 static SHORT yLimit, xPos, yPos;
1175 static SHORT xCur, yCur, yNew;
1176  
1177 static FILLCIRCLE_STATES state = BEGIN;
1178  
1179 while(1)
1180 {
1181 if(IsDeviceBusy())
1182 return (0);
1183 switch(state)
1184 {
1185 case BEGIN:
1186 if(!rad)
1187 { // no radius object is a filled rectangle
1188 state = FACE;
1189 break;
1190 }
1191  
1192 // compute variables
1193 temp.Val = SIN45 * rad;
1194 yLimit = temp.w[1];
1195 temp.Val = (DWORD) (ONEP25 - ((LONG) rad << 16));
1196 err = (SHORT) (temp.w[1]);
1197 xPos = rad;
1198 yPos = 0;
1199 xCur = xPos;
1200 yCur = yPos;
1201 yNew = yPos;
1202 state = CHECK;
1203  
1204 case CHECK:
1205 bevel_fill_check : if(yPos > yLimit)
1206 {
1207 state = FACE;
1208 break;
1209 }
1210  
1211 // y1New records the last y position
1212 yNew = yPos;
1213  
1214 // calculate the next value of x and y
1215 if(err > 0)
1216 {
1217 xPos--;
1218 err += 5 + ((yPos - xPos) << 1);
1219 }
1220 else
1221 err += 3 + (yPos << 1);
1222 yPos++;
1223 state = Q6TOQ3;
1224  
1225 case Q6TOQ3:
1226 if(xCur != xPos)
1227 {
1228  
1229 // 6th octant to 3rd octant
1230 if (_bevelDrawType & DRAWBOTTOMBEVEL)
1231 {
1232 if(Bar(x1 - xCur, y2 + yCur, x2 + xCur, y2 + yNew) == 0)
1233 return (0);
1234 }
1235 state = Q5TOQ4;
1236 break;
1237 }
1238  
1239 state = CHECK;
1240 goto bevel_fill_check;
1241  
1242 case Q5TOQ4:
1243  
1244 if (_bevelDrawType & DRAWBOTTOMBEVEL)
1245 {
1246 // 5th octant to 4th octant
1247 if(Bar(x1 - yNew, y2 + xPos, x2 + yNew, y2 + xCur) == 0)
1248 return (0);
1249 }
1250 state = Q8TOQ1;
1251 break;
1252  
1253 case Q8TOQ1:
1254  
1255 // 8th octant to 1st octant
1256 if (_bevelDrawType & DRAWTOPBEVEL)
1257 {
1258 if(Bar(x1 - yNew, y1 - xCur, x2 + yNew, y1 - xPos) == 0)
1259 return (0);
1260 }
1261 state = Q7TOQ2;
1262 break;
1263  
1264 case Q7TOQ2:
1265  
1266 // 7th octant to 2nd octant
1267 if (_bevelDrawType & DRAWTOPBEVEL)
1268 {
1269 if(Bar(x1 - xCur, y1 - yNew, x2 + xCur, y1 - yCur) == 0)
1270 return (0);
1271 }
1272 // update current values
1273 xCur = xPos;
1274 yCur = yPos;
1275 state = CHECK;
1276 break;
1277  
1278  
1279  
1280 case FACE:
1281 if((x2 - x1) || (y2 - y1))
1282 {
1283 if (_bevelDrawType == DRAWFULLBEVEL)
1284 {
1285 if(Bar(x1 - rad, y1, x2 + rad, y2) == 0)
1286 return (0);
1287 }
1288 else if (_bevelDrawType == DRAWTOPBEVEL)
1289 {
1290 if(Bar(x1 - rad, y1, x2 + rad, y1+((y2-y1)>>1)) == 0)
1291 return (0);
1292 }
1293 else
1294 {
1295 if(Bar(x1 - rad, y1+((y2-y1)>>1), x2 + rad, y2) == 0)
1296 return (0);
1297 }
1298  
1299 state = WAITFORDONE;
1300 }
1301 else
1302 {
1303 state = BEGIN;
1304 return (1);
1305 }
1306  
1307 case WAITFORDONE:
1308 if(IsDeviceBusy())
1309 return (0);
1310 state = BEGIN;
1311 return (1);
1312 } // end of switch
1313 } // end of while
1314 #endif // end of USE_NONBLOCKING_CONFIG
1315 }
1316  
1317 /*********************************************************************
1318 * Function: WORD DrawPoly(SHORT numPoints, SHORT* polyPoints)
1319 *
1320 * PreCondition: none
1321 *
1322 * Input: numPoints - points number, polyPoints - pointer to points array
1323 *
1324 * Output: For NON-Blocking configuration:
1325 * - Returns 0 when device is busy and the shape is not yet completely drawn.
1326 * - Returns 1 when the shape is completely drawn.
1327 * For Blocking configuration:
1328 * - Always return 1.
1329 *
1330 * Side Effects: none
1331 *
1332 * Overview: draws line polygon
1333 *
1334 * Note: none
1335 *
1336 ********************************************************************/
1337 WORD DrawPoly(SHORT numPoints, SHORT *polyPoints)
1338 {
1339 #ifndef USE_NONBLOCKING_CONFIG
1340  
1341 SHORT counter;
1342 SHORT sx, sy, ex, ey;
1343  
1344 #ifndef USE_NONBLOCKING_CONFIG
1345 while(IsDeviceBusy() != 0) Nop();
1346  
1347 /* Ready */
1348 #else
1349 if(IsDeviceBusy() != 0)
1350 return (0);
1351 #endif
1352 sx = *polyPoints++;
1353 sy = *polyPoints++;
1354 for(counter = 0; counter < numPoints - 1; counter++)
1355 {
1356 ex = *polyPoints++;
1357 ey = *polyPoints++;
1358 while(Line(sx, sy, ex, ey) == 0);
1359 sx = ex;
1360 sy = ey;
1361 }
1362  
1363 #else
1364  
1365 typedef enum
1366 {
1367 POLY_BEGIN,
1368 POLY_DRAWING,
1369 } DRAWPOLY_STATES;
1370  
1371 static DRAWPOLY_STATES state = POLY_BEGIN;
1372 static SHORT counter;
1373 SHORT sx, sy, ex, ey;
1374 while(1)
1375 {
1376 if(IsDeviceBusy())
1377 return (0);
1378 switch(state)
1379 {
1380 case POLY_BEGIN:
1381 counter = 1;
1382 state = POLY_DRAWING;
1383  
1384 case POLY_DRAWING:
1385 if(counter == 0 || counter >= numPoints)
1386 {
1387 state = POLY_BEGIN;
1388 break;
1389 }
1390  
1391 while(counter < numPoints)
1392 {
1393 sx = polyPoints[(counter - 1) * 2];
1394 sy = polyPoints[(counter * 2) - 1];
1395 ex = polyPoints[counter * 2];
1396 ey = polyPoints[counter * 2 + 1];
1397 if(Line(sx, sy, ex, ey) == 0)
1398 {
1399 return (0);
1400 }
1401  
1402 counter++;
1403 }
1404  
1405 state = POLY_BEGIN;
1406 return (1);
1407 }
1408 }
1409  
1410 #endif
1411 return (1);
1412 }
1413  
1414 /*********************************************************************
1415 * Function: WORD Bar(SHORT left, SHORT top, SHORT right, SHORT bottom)
1416 *
1417 * PreCondition: none
1418 *
1419 * Input: left,top - top left corner coordinates,
1420 * right,bottom - bottom right corner coordinates
1421 *
1422 * Output: For NON-Blocking configuration:
1423 * - Returns 0 when device is busy and the shape is not yet completely drawn.
1424 * - Returns 1 when the shape is completely drawn.
1425 * For Blocking configuration:
1426 * - Always return 1.
1427 *
1428 * Side Effects: none
1429 *
1430 * Overview: draws rectangle filled with current color
1431 *
1432 * Note: none
1433 *
1434 ********************************************************************/
1435 #ifndef USE_DRV_BAR
1436  
1437 /* */
1438 WORD Bar(SHORT left, SHORT top, SHORT right, SHORT bottom)
1439 {
1440 SHORT x, y;
1441  
1442 #ifndef USE_NONBLOCKING_CONFIG
1443 while(IsDeviceBusy() != 0) Nop();
1444  
1445 /* Ready */
1446 #else
1447 if(IsDeviceBusy() != 0)
1448 return (0);
1449 #endif
1450 for(y = top; y < bottom + 1; y++)
1451 for(x = left; x < right + 1; x++)
1452 PutPixel(x, y);
1453  
1454 return (1);
1455 }
1456  
1457 #endif
1458  
1459 /*********************************************************************
1460 * Function: void ClearDevice(void)
1461 *
1462 * PreCondition: none
1463 *
1464 * Input: none
1465 *
1466 * Output: none
1467 *
1468 * Side Effects: none
1469 *
1470 * Overview: clears screen with current color and sets cursor to 0,0
1471 *
1472 * Note: none
1473 *
1474 ********************************************************************/
1475 #ifndef USE_DRV_CLEARDEVICE
1476  
1477 /* */
1478 void ClearDevice(void)
1479 {
1480 while(Bar(0, 0, GetMaxX(), GetMaxY()) == 0);
1481 MoveTo(0, 0);
1482 }
1483  
1484 #endif
1485  
1486 #ifndef USE_DRV_FONT
1487 /*********************************************************************
1488 * Function: void SetFont(void* font)
1489 *
1490 * PreCondition: none
1491 *
1492 * Input: pointer to the font image
1493 *
1494 * Output: none
1495 *
1496 * Side Effects: none
1497 *
1498 * Overview: defines current font
1499 *
1500 * Note: none
1501 *
1502 ********************************************************************/
1503 void SetFont(void *font)
1504 {
1505 FONT_HEADER *pHeader;
1506  
1507 #ifdef USE_FONT_EXTERNAL
1508 FONT_HEADER header;
1509 #endif
1510 _font = font;
1511 switch(*((SHORT *)font))
1512 {
1513 #ifdef USE_FONT_FLASH
1514  
1515 case FLASH:
1516 pHeader = (FONT_HEADER *) ((FONT_FLASH *)font)->address;
1517 break;
1518 #endif
1519 #ifdef USE_FONT_EXTERNAL
1520  
1521 case EXTERNAL:
1522 pHeader = &header;
1523 ExternalMemoryCallback(font, 0, sizeof(FONT_HEADER), pHeader);
1524 break;
1525 #endif
1526  
1527 default:
1528 return;
1529 }
1530  
1531 _fontFirstChar = pHeader->firstChar;
1532 _fontLastChar = pHeader->lastChar;
1533 _fontHeight = pHeader->height;
1534 }
1535  
1536 #endif
1537  
1538 /*********************************************************************
1539 * Function: WORD OutText(XCHAR* textString)
1540 *
1541 * PreCondition: none
1542 *
1543 * Input: textString - pointer to text string
1544 *
1545 * Output: non-zero if drawing done (used for NON-BLOCKING configuration)
1546 *
1547 * Side Effects: none
1548 *
1549 * Overview: outputs text from current position
1550 *
1551 * Note: none
1552 *
1553 ********************************************************************/
1554 WORD OutText(XCHAR *textString)
1555 {
1556 #ifndef USE_NONBLOCKING_CONFIG
1557  
1558 XCHAR ch;
1559 while((XCHAR)15 < (XCHAR)(ch = *textString++))
1560 while(OutChar(ch) == 0);
1561 return (1);
1562  
1563 #else
1564  
1565 XCHAR ch;
1566 static WORD counter = 0;
1567  
1568 while((XCHAR)(ch = *(textString + counter)) > (XCHAR)15)
1569 {
1570 if(OutChar(ch) == 0)
1571 return (0);
1572 counter++;
1573 }
1574  
1575 counter = 0;
1576 return (1);
1577 #endif
1578 }
1579  
1580 /*********************************************************************
1581 * Function: WORD OutTextXY(SHORT x, SHORT y, XCHAR* textString)
1582 *
1583 * PreCondition: none
1584 *
1585 * Input: x,y - starting coordinates, textString - pointer to text string
1586 *
1587 * Output: non-zero if drawing done (used for NON-BLOCKING configuration)
1588 *
1589 * Side Effects: none
1590 *
1591 * Overview: outputs text from x,y position
1592 *
1593 * Note: none
1594 *
1595 ********************************************************************/
1596 WORD OutTextXY(SHORT x, SHORT y, XCHAR *textString)
1597 {
1598 #ifndef USE_NONBLOCKING_CONFIG
1599 MoveTo(x, y);
1600 OutText(textString);
1601 return (1);
1602  
1603 #else
1604  
1605 static BYTE start = 1;
1606  
1607 if(start)
1608 {
1609 MoveTo(x, y);
1610 start = 0;
1611 }
1612  
1613 if(OutText(textString) == 0)
1614 {
1615 return (0);
1616 }
1617 else
1618 {
1619 start = 1;
1620 return (1);
1621 }
1622  
1623 #endif
1624 }
1625  
1626 #ifndef USE_DRV_FONT
1627 /*********************************************************************
1628 * Function: WORD OutChar(XCHAR ch)
1629 *
1630 * PreCondition: none
1631 *
1632 * Input: character code
1633 *
1634 * Output: For NON-Blocking configuration:
1635 * - Returns 0 when device is busy and the character is not yet completely drawn.
1636 * - Returns 1 when the character is completely drawn.
1637 * For Blocking configuration:
1638 * - Always return 1.
1639 *
1640 * Side Effects: none
1641 *
1642 * Overview: outputs a character
1643 *
1644 * Note: none
1645 *
1646 ********************************************************************/
1647 WORD OutChar(XCHAR ch)
1648 {
1649 #ifdef USE_FONT_FLASH
1650 GLYPH_ENTRY *pChTable = NULL;
1651 #endif
1652 BYTE *pChImage = NULL;
1653  
1654 #ifdef USE_FONT_EXTERNAL
1655 GLYPH_ENTRY chTable;
1656 BYTE chImage[EXTERNAL_FONT_BUFFER_SIZE];
1657 WORD imageSize;
1658 DWORD_VAL glyphOffset;
1659 #endif
1660 SHORT chWidth = 0;
1661 SHORT xCnt, yCnt, x = 0, y;
1662 BYTE temp = 0, mask;
1663  
1664 #ifndef USE_NONBLOCKING_CONFIG
1665 while(IsDeviceBusy() != 0) Nop();
1666  
1667 /* Ready */
1668 #else
1669 if(IsDeviceBusy() != 0)
1670 return (0);
1671 #endif
1672 if((XCHAR)ch < (XCHAR)_fontFirstChar)
1673 return (-1);
1674 if((XCHAR)ch > (XCHAR)_fontLastChar)
1675 return (-1);
1676  
1677 switch(*((SHORT *)_font))
1678 {
1679 #ifdef USE_FONT_FLASH
1680  
1681 case FLASH:
1682 pChTable = (GLYPH_ENTRY *) (((FONT_FLASH *)_font)->address + sizeof(FONT_HEADER)) + ((XCHAR)ch - (XCHAR)_fontFirstChar);
1683  
1684 pChImage = (BYTE *) (((FONT_FLASH *)_font)->address + ((DWORD)(pChTable->offsetMSB) << 8) + pChTable->offsetLSB);
1685  
1686 chWidth = pChTable->width;
1687  
1688 break;
1689 #endif
1690 #ifdef USE_FONT_EXTERNAL
1691  
1692 case EXTERNAL:
1693  
1694 // get glyph entry
1695 ExternalMemoryCallback
1696 (
1697 _font,
1698 sizeof(FONT_HEADER) + ((XCHAR)ch - (XCHAR)_fontFirstChar) * sizeof(GLYPH_ENTRY),
1699 sizeof(GLYPH_ENTRY),
1700 &chTable
1701 );
1702  
1703 chWidth = chTable.width;
1704  
1705 // width of glyph in bytes
1706 imageSize = 0;
1707 if(chWidth & 0x0007)
1708 imageSize = 1;
1709 imageSize += (chWidth >> 3);
1710  
1711 // glyph image size
1712 imageSize *= _fontHeight;
1713  
1714 // get glyph image
1715 glyphOffset.w[1] = (chTable.offsetMSB >> 8);
1716 glyphOffset.w[0] = (chTable.offsetMSB << 8) + (chTable.offsetLSB);
1717  
1718 ExternalMemoryCallback(_font, glyphOffset.Val, imageSize, &chImage);
1719 pChImage = (BYTE *) &chImage;
1720  
1721 break;
1722 #endif
1723  
1724 default:
1725 break;
1726 }
1727  
1728 if(_fontOrientation == ORIENT_HOR)
1729 {
1730 y = GetY();
1731 for(yCnt = 0; yCnt < _fontHeight; yCnt++)
1732 {
1733 x = GetX();
1734 mask = 0;
1735 for(xCnt = 0; xCnt < chWidth; xCnt++)
1736 {
1737 if(mask == 0)
1738 {
1739 temp = *pChImage++;
1740 mask = 0x01;
1741 }
1742  
1743 if(temp & mask)
1744 {
1745 PutPixel(x, y);
1746 }
1747  
1748 x++;
1749 mask <<= 1;
1750 }
1751  
1752 y++;
1753 }
1754  
1755 // move cursor
1756 _cursorX = x;
1757 }
1758 else
1759 {
1760 y = GetX();
1761 for(yCnt = 0; yCnt < _fontHeight; yCnt++)
1762 {
1763 x = GetY();
1764 mask = 0;
1765 for(xCnt = 0; xCnt < chWidth; xCnt++)
1766 {
1767 if(mask == 0)
1768 {
1769 temp = *pChImage++;
1770 mask = 0x01;
1771 }
1772  
1773 if(temp & mask)
1774 {
1775 PutPixel(y, x);
1776 }
1777  
1778 x--;
1779 mask <<= 1;
1780 }
1781  
1782 y++;
1783 }
1784  
1785 // move cursor
1786 _cursorY = x;
1787 }
1788  
1789 return (1);
1790 }
1791  
1792 #endif
1793  
1794 /*********************************************************************
1795 * Function: SHORT GetTextWidth(XCHAR* textString, void* font)
1796 *
1797 * PreCondition: none
1798 *
1799 * Input: textString - pointer to the text string,
1800 * font - pointer to the font
1801 *
1802 * Output: text width in pixels
1803 *
1804 * Side Effects: none
1805 *
1806 * Overview: returns text width for the font
1807 *
1808 * Note: none
1809 *
1810 ********************************************************************/
1811 SHORT GetTextWidth(XCHAR *textString, void *font)
1812 {
1813 #if defined (USE_FONT_RAM) || defined (USE_FONT_FLASH)
1814 GLYPH_ENTRY *pChTable;
1815 FONT_HEADER *pHeader;
1816 #endif
1817 #ifdef USE_FONT_EXTERNAL
1818 GLYPH_ENTRY chTable;
1819 FONT_HEADER header;
1820 #endif
1821  
1822 #if defined (USE_FONT_RAM) || defined (USE_FONT_FLASH) || defined (USE_FONT_EXTERNAL)
1823 SHORT textWidth;
1824 XCHAR ch;
1825 XCHAR fontFirstChar;
1826 XCHAR fontLastChar;
1827 #endif
1828  
1829 switch(*((SHORT *)font))
1830 {
1831 #ifdef USE_FONT_RAM
1832  
1833 case RAM:
1834 pHeader = (FONT_HEADER *) ((FONT_RAM *)font)->address;
1835 fontFirstChar = pHeader->firstChar;
1836 fontLastChar = pHeader->lastChar;
1837 pChTable = (GLYPH_ENTRY *) (pHeader + 1);
1838 textWidth = 0;
1839 while((unsigned XCHAR)15 < (unsigned XCHAR)(ch = *textString++))
1840 {
1841 if((unsigned XCHAR)ch < (unsigned XCHAR)fontFirstChar)
1842 continue;
1843 if((unsigned XCHAR)ch > (unsigned XCHAR)fontLastChar)
1844 continue;
1845 textWidth += (pChTable + ((unsigned XCHAR)ch - (unsigned XCHAR)fontFirstChar))->width;
1846 }
1847  
1848 return (textWidth);
1849 #endif
1850  
1851 #ifdef USE_FONT_FLASH
1852  
1853 case FLASH:
1854 pHeader = (FONT_HEADER *) ((FONT_FLASH *)font)->address;
1855 fontFirstChar = pHeader->firstChar;
1856 fontLastChar = pHeader->lastChar;
1857 pChTable = (GLYPH_ENTRY *) (pHeader + 1);
1858 textWidth = 0;
1859 while((XCHAR)15 < (XCHAR)(ch = *textString++))
1860 {
1861 if((XCHAR)ch < (XCHAR)fontFirstChar)
1862 continue;
1863 if((XCHAR)ch > (XCHAR)fontLastChar)
1864 continue;
1865 textWidth += (pChTable + ((XCHAR)ch - (XCHAR)fontFirstChar))->width;
1866 }
1867  
1868 return (textWidth);
1869 #endif
1870 #ifdef USE_FONT_EXTERNAL
1871  
1872 case EXTERNAL:
1873 ExternalMemoryCallback(font, 0, sizeof(FONT_HEADER), &header);
1874 fontFirstChar = header.firstChar;
1875 fontLastChar = header.lastChar;
1876 textWidth = 0;
1877 while((XCHAR)15 < (XCHAR)(ch = *textString++))
1878 {
1879 if((XCHAR)ch < (XCHAR)fontFirstChar)
1880 continue;
1881 if((XCHAR)ch > (XCHAR)fontLastChar)
1882 continue;
1883 ExternalMemoryCallback
1884 (
1885 font,
1886 sizeof(FONT_HEADER) + sizeof(GLYPH_ENTRY) * ((XCHAR)ch - (XCHAR)fontFirstChar),
1887 sizeof(GLYPH_ENTRY),
1888 &chTable
1889 );
1890 textWidth += chTable.width;
1891 }
1892  
1893 return (textWidth);
1894 #endif
1895  
1896 default:
1897 return (0);
1898 }
1899 }
1900  
1901 /*********************************************************************
1902 * Function: SHORT GetTextHeight(void* font)
1903 *
1904 * PreCondition: none
1905 *
1906 * Input: pointer to the font
1907 *
1908 * Output: character height in pixels
1909 *
1910 * Side Effects: none
1911 *
1912 * Overview: returns characters height for the font
1913 *
1914 * Note: none
1915 *
1916 ********************************************************************/
1917 SHORT GetTextHeight(void *font)
1918 {
1919 #ifdef USE_FONT_EXTERNAL
1920  
1921 char height;
1922 #endif
1923 switch(*((SHORT *)font))
1924 {
1925 #ifdef USE_FONT_RAM
1926 case RAM:
1927 return ((FONT_HEADER *) ((FONT_RAM *)font)->address)->height;
1928 #endif
1929  
1930 #ifdef USE_FONT_FLASH
1931 case FLASH:
1932 return ((FONT_HEADER *) ((FONT_FLASH *)font)->address)->height;
1933 #endif
1934  
1935 #ifdef USE_FONT_EXTERNAL
1936 case EXTERNAL:
1937 ExternalMemoryCallback(font, sizeof(FONT_HEADER) - 2, 1, &height);
1938 return (height);
1939 #endif
1940  
1941 default:
1942 return (0);
1943 }
1944 }
1945  
1946 /*********************************************************************
1947 * Function: SHORT GetImageWidth(void* bitmap)
1948 *
1949 * PreCondition: none
1950 *
1951 * Input: bitmap - image pointer
1952 *
1953 * Output: none
1954 *
1955 * Side Effects: none
1956 *
1957 * Overview: returns image width
1958 *
1959 * Note: none
1960 *
1961 ********************************************************************/
1962 SHORT GetImageWidth(void *bitmap)
1963 {
1964 #ifdef USE_BITMAP_EXTERNAL
1965  
1966 SHORT width;
1967 #endif
1968 switch(*((SHORT *)bitmap))
1969 {
1970 #ifdef USE_BITMAP_FLASH
1971  
1972 case FLASH:
1973 return (*((FLASH_WORD *) ((BITMAP_FLASH *)bitmap)->address + 2));
1974 #endif
1975 #ifdef USE_BITMAP_EXTERNAL
1976  
1977 case EXTERNAL:
1978 ExternalMemoryCallback(bitmap, 4, 2, &width);
1979 return (width);
1980 #endif
1981  
1982 default:
1983 return (0);
1984 }
1985 }
1986  
1987 /*********************************************************************
1988 * Function: SHORT GetImageHeight(void* bitmap)
1989 *
1990 * PreCondition: none
1991 *
1992 * Input: bitmap - image pointer
1993 *
1994 * Output: none
1995 *
1996 * Side Effects: none
1997 *
1998 * Overview: returns image height
1999 *
2000 * Note: none
2001 *
2002 ********************************************************************/
2003 SHORT GetImageHeight(void *bitmap)
2004 {
2005 #ifdef USE_BITMAP_EXTERNAL
2006  
2007 SHORT height;
2008 #endif
2009 switch(*((SHORT *)bitmap))
2010 {
2011 #ifdef USE_BITMAP_FLASH
2012  
2013 case FLASH:
2014 return (*((FLASH_WORD *) ((BITMAP_FLASH *)bitmap)->address + 1));
2015 #endif
2016 #ifdef USE_BITMAP_EXTERNAL
2017  
2018 case EXTERNAL:
2019 ExternalMemoryCallback(bitmap, 2, 2, &height);
2020 return (height);
2021 #endif
2022  
2023 default:
2024 return (0);
2025 }
2026 }
2027  
2028 #ifndef USE_DRV_PUTIMAGE
2029  
2030 /*********************************************************************
2031 * Function: WORD PutImage(SHORT left, SHORT top, void* bitmap, BYTE stretch)
2032 *
2033 * PreCondition: none
2034 *
2035 * Input: left,top - left top image corner,
2036 * bitmap - image pointer,
2037 * stretch - image stretch factor
2038 *
2039 * Output: For NON-Blocking configuration:
2040 * - Returns 0 when device is busy and the image is not yet completely drawn.
2041 * - Returns 1 when the image is completely drawn.
2042 * For Blocking configuration:
2043 * - Always return 1.
2044 *
2045 * Side Effects: none
2046 *
2047 * Overview: outputs image starting from left,top coordinates
2048 *
2049 * Note: image must be located in flash
2050 *
2051 ********************************************************************/
2052 WORD PutImage(SHORT left, SHORT top, void *bitmap, BYTE stretch)
2053 {
2054 FLASH_BYTE *flashAddress;
2055 BYTE colorDepth;
2056 WORD colorTemp;
2057  
2058 #ifndef USE_NONBLOCKING_CONFIG
2059 while(IsDeviceBusy() != 0) Nop();
2060  
2061 /* Ready */
2062 #else
2063 if(IsDeviceBusy() != 0)
2064 return (0);
2065 #endif
2066  
2067 // Save current color
2068 colorTemp = GetColor();
2069  
2070 switch(*((SHORT *)bitmap))
2071 {
2072 #ifdef USE_BITMAP_FLASH
2073  
2074 case FLASH:
2075  
2076 // Image address
2077 flashAddress = ((BITMAP_FLASH *)bitmap)->address;
2078  
2079 // Read color depth
2080 colorDepth = *(flashAddress + 1);
2081  
2082 // Draw picture
2083 switch(colorDepth)
2084 {
2085 case 1: PutImage1BPP(left, top, flashAddress, stretch); break;
2086  
2087 #if (COLOR_DEPTH >= 4)
2088 case 4: PutImage4BPP(left, top, flashAddress, stretch); break;
2089 #endif
2090  
2091 #if (COLOR_DEPTH >= 8)
2092 case 8: PutImage8BPP(left, top, flashAddress, stretch); break;
2093 #endif
2094  
2095 #if (COLOR_DEPTH == 16)
2096 case 16: PutImage16BPP(left, top, flashAddress, stretch); break;
2097 #endif
2098  
2099 default: break;
2100 }
2101  
2102 break;
2103 #endif
2104  
2105 #ifdef USE_BITMAP_EXTERNAL
2106  
2107 case EXTERNAL:
2108  
2109 // Get color depth
2110 ExternalMemoryCallback(bitmap, 1, 1, &colorDepth);
2111  
2112 // Draw picture
2113 switch(colorDepth)
2114 {
2115 case 1: PutImage1BPPExt(left, top, bitmap, stretch); break;
2116  
2117 #if (COLOR_DEPTH >= 4)
2118 case 4: PutImage4BPPExt(left, top, bitmap, stretch); break;
2119 #endif
2120  
2121 #if (COLOR_DEPTH >= 8)
2122 case 8: PutImage8BPPExt(left, top, bitmap, stretch); break;
2123 #endif
2124  
2125 #if (COLOR_DEPTH == 16)
2126 case 16: PutImage16BPPExt(left, top, bitmap, stretch); break;
2127 #endif
2128  
2129 default: break;
2130 }
2131  
2132 break;
2133 #endif
2134  
2135 default:
2136 break;
2137 }
2138  
2139 // Restore current color
2140 SetColor(colorTemp);
2141 return (1);
2142 }
2143  
2144 #ifdef USE_BITMAP_FLASH
2145  
2146 /*********************************************************************
2147 * Function: void PutImage1BPP(SHORT left, SHORT top, FLASH_BYTE* bitmap, BYTE stretch)
2148 *
2149 * PreCondition: none
2150 *
2151 * Input: left,top - left top image corner,
2152 * bitmap - image pointer,
2153 * stretch - image stretch factor
2154 *
2155 * Output: none
2156 *
2157 * Side Effects: none
2158 *
2159 * Overview: outputs monochrome image starting from left,top coordinates
2160 *
2161 * Note: image must be located in flash
2162 *
2163 ********************************************************************/
2164 void PutImage1BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch)
2165 {
2166 register FLASH_BYTE *flashAddress;
2167 register FLASH_BYTE *tempFlashAddress;
2168 BYTE temp = 0;
2169 WORD sizeX, sizeY;
2170 WORD x, y;
2171 WORD xc, yc;
2172 BYTE stretchX, stretchY;
2173 WORD pallete[2];
2174 BYTE mask;
2175  
2176 // Move pointer to size information
2177 flashAddress = bitmap + 2;
2178  
2179 // Read image size
2180 sizeY = *((FLASH_WORD *)flashAddress);
2181 flashAddress += 2;
2182 sizeX = *((FLASH_WORD *)flashAddress);
2183 flashAddress += 2;
2184 pallete[0] = *((FLASH_WORD *)flashAddress);
2185 flashAddress += 2;
2186 pallete[1] = *((FLASH_WORD *)flashAddress);
2187 flashAddress += 2;
2188  
2189 yc = top;
2190 for(y = 0; y < sizeY; y++)
2191 {
2192 tempFlashAddress = flashAddress;
2193 for(stretchY = 0; stretchY < stretch; stretchY++)
2194 {
2195 flashAddress = tempFlashAddress;
2196 mask = 0;
2197 xc = left;
2198 for(x = 0; x < sizeX; x++)
2199 {
2200  
2201 // Read 8 pixels from flash
2202 if(mask == 0)
2203 {
2204 temp = *flashAddress;
2205 flashAddress++;
2206 mask = 0x80;
2207 }
2208  
2209 // Set color
2210 if(mask & temp)
2211 {
2212 // Set color
2213 #ifdef USE_PALETTE
2214 SetColor(1);
2215 #else
2216 SetColor(pallete[1]);
2217 #endif
2218 }
2219 else
2220 {
2221 // Set color
2222 #ifdef USE_PALETTE
2223 SetColor(0);
2224 #else
2225 SetColor(pallete[0]);
2226 #endif
2227 }
2228  
2229 // Write pixel to screen
2230 for(stretchX = 0; stretchX < stretch; stretchX++)
2231 {
2232 PutPixel(xc++, yc);
2233 }
2234  
2235 // Shift to the next pixel
2236 mask >>= 1;
2237 }
2238  
2239 yc++;
2240 }
2241 }
2242 }
2243  
2244 /*********************************************************************
2245 * Function: void PutImage4BPP(SHORT left, SHORT top, FLASH_BYTE* bitmap, BYTE stretch)
2246 *
2247 * PreCondition: none
2248 *
2249 * Input: left,top - left top image corner, bitmap - image pointer,
2250 * stretch - image stretch factor
2251 *
2252 * Output: none
2253 *
2254 * Side Effects: none
2255 *
2256 * Overview: outputs 16 color image starting from left,top coordinates
2257 *
2258 * Note: image must be located in flash
2259 *
2260 ********************************************************************/
2261 #if (COLOR_DEPTH >= 4)
2262  
2263 /* */
2264 void PutImage4BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch)
2265 {
2266 register FLASH_BYTE *flashAddress;
2267 register FLASH_BYTE *tempFlashAddress;
2268 WORD sizeX, sizeY;
2269 register WORD x, y;
2270 WORD xc, yc;
2271 BYTE temp = 0;
2272 register BYTE stretchX, stretchY;
2273 WORD pallete[16];
2274 WORD counter;
2275  
2276 // Move pointer to size information
2277 flashAddress = bitmap + 2;
2278  
2279 // Read image size
2280 sizeY = *((FLASH_WORD *)flashAddress);
2281 flashAddress += 2;
2282 sizeX = *((FLASH_WORD *)flashAddress);
2283 flashAddress += 2;
2284  
2285 // Read pallete
2286 for(counter = 0; counter < 16; counter++)
2287 {
2288 pallete[counter] = *((FLASH_WORD *)flashAddress);
2289 flashAddress += 2;
2290 }
2291  
2292 yc = top;
2293 for(y = 0; y < sizeY; y++)
2294 {
2295 tempFlashAddress = flashAddress;
2296 for(stretchY = 0; stretchY < stretch; stretchY++)
2297 {
2298 flashAddress = tempFlashAddress;
2299 xc = left;
2300 for(x = 0; x < sizeX; x++)
2301 {
2302  
2303 // Read 2 pixels from flash
2304 if(x & 0x0001)
2305 {
2306  
2307 // second pixel in byte
2308 // Set color
2309 #ifdef USE_PALETTE
2310 SetColor(temp >> 4);
2311 #else
2312 SetColor(pallete[temp >> 4]);
2313 #endif
2314 }
2315 else
2316 {
2317 temp = *flashAddress;
2318 flashAddress++;
2319  
2320 // first pixel in byte
2321 // Set color
2322 #ifdef USE_PALETTE
2323 SetColor(temp & 0x0f);
2324 #else
2325 SetColor(pallete[temp & 0x0f]);
2326 #endif
2327 }
2328  
2329 // Write pixel to screen
2330 for(stretchX = 0; stretchX < stretch; stretchX++)
2331 {
2332 PutPixel(xc++, yc);
2333 }
2334 }
2335  
2336 yc++;
2337 }
2338 }
2339 }
2340  
2341 #endif
2342  
2343 /*********************************************************************
2344 * Function: void PutImage8BPP(SHORT left, SHORT top, FLASH_BYTE* bitmap, BYTE stretch)
2345 *
2346 * PreCondition: none
2347 *
2348 * Input: left,top - left top image corner, bitmap - image pointer,
2349 * stretch - image stretch factor
2350 *
2351 * Output: none
2352 *
2353 * Side Effects: none
2354 *
2355 * Overview: outputs 256 color image starting from left,top coordinates
2356 *
2357 * Note: image must be located in flash
2358 *
2359 ********************************************************************/
2360 #if (COLOR_DEPTH >= 8)
2361  
2362 /* */
2363 void PutImage8BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch)
2364 {
2365 register FLASH_BYTE *flashAddress;
2366 register FLASH_BYTE *tempFlashAddress;
2367 WORD sizeX, sizeY;
2368 WORD x, y;
2369 WORD xc, yc;
2370 BYTE temp;
2371 BYTE stretchX, stretchY;
2372 WORD pallete[256];
2373 WORD counter;
2374  
2375 // Move pointer to size information
2376 flashAddress = bitmap + 2;
2377  
2378 // Read image size
2379 sizeY = *((FLASH_WORD *)flashAddress);
2380 flashAddress += 2;
2381 sizeX = *((FLASH_WORD *)flashAddress);
2382 flashAddress += 2;
2383  
2384 // Read pallete
2385 for(counter = 0; counter < 256; counter++)
2386 {
2387 pallete[counter] = *((FLASH_WORD *)flashAddress);
2388 flashAddress += 2;
2389 }
2390  
2391 yc = top;
2392 for(y = 0; y < sizeY; y++)
2393 {
2394 tempFlashAddress = flashAddress;
2395 for(stretchY = 0; stretchY < stretch; stretchY++)
2396 {
2397 flashAddress = tempFlashAddress;
2398 xc = left;
2399 for(x = 0; x < sizeX; x++)
2400 {
2401  
2402 // Read pixels from flash
2403 temp = *flashAddress;
2404 flashAddress++;
2405  
2406 // Set color
2407 #ifdef USE_PALETTE
2408 SetColor(temp);
2409 #else
2410 SetColor(pallete[temp]);
2411 #endif
2412  
2413 // Write pixel to screen
2414 for(stretchX = 0; stretchX < stretch; stretchX++)
2415 {
2416 PutPixel(xc++, yc);
2417 }
2418 }
2419  
2420 yc++;
2421 }
2422 }
2423 }
2424  
2425 #endif
2426  
2427 /*********************************************************************
2428 * Function: void PutImage16BPP(SHORT left, SHORT top, FLASH_BYTE* bitmap, BYTE stretch)
2429 *
2430 * PreCondition: none
2431 *
2432 * Input: left,top - left top image corner, bitmap - image pointer,
2433 * stretch - image stretch factor
2434 *
2435 * Output: none
2436 *
2437 * Side Effects: none
2438 *
2439 * Overview: outputs hicolor image starting from left,top coordinates
2440 *
2441 * Note: image must be located in flash
2442 *
2443 ********************************************************************/
2444 #if (COLOR_DEPTH == 16)
2445  
2446 /* */
2447 void PutImage16BPP(SHORT left, SHORT top, FLASH_BYTE *bitmap, BYTE stretch)
2448 {
2449 register FLASH_WORD *flashAddress;
2450 register FLASH_WORD *tempFlashAddress;
2451 WORD sizeX, sizeY;
2452 register WORD x, y;
2453 WORD xc, yc;
2454 WORD temp;
2455 register BYTE stretchX, stretchY;
2456  
2457 // Move pointer to size information
2458 flashAddress = (FLASH_WORD *)bitmap + 1;
2459  
2460 // Read image size
2461 sizeY = *flashAddress;
2462 flashAddress++;
2463 sizeX = *flashAddress;
2464 flashAddress++;
2465  
2466 yc = top;
2467 for(y = 0; y < sizeY; y++)
2468 {
2469 tempFlashAddress = flashAddress;
2470 for(stretchY = 0; stretchY < stretch; stretchY++)
2471 {
2472 flashAddress = tempFlashAddress;
2473 xc = left;
2474 for(x = 0; x < sizeX; x++)
2475 {
2476  
2477 // Read pixels from flash
2478 temp = *flashAddress;
2479 flashAddress++;
2480  
2481 // Set color
2482 SetColor(temp);
2483  
2484 // Write pixel to screen
2485 for(stretchX = 0; stretchX < stretch; stretchX++)
2486 {
2487 PutPixel(xc++, yc);
2488 }
2489 }
2490  
2491 yc++;
2492 }
2493 }
2494 }
2495  
2496 #endif
2497 #endif
2498 #ifdef USE_BITMAP_EXTERNAL
2499  
2500 /*********************************************************************
2501 * Function: void PutImage1BPPExt(SHORT left, SHORT top, void* bitmap, BYTE stretch)
2502 *
2503 * PreCondition: none
2504 *
2505 * Input: left,top - left top image corner, bitmap - image pointer,
2506 * stretch - image stretch factor
2507 *
2508 * Output: none
2509 *
2510 * Side Effects: none
2511 *
2512 * Overview: outputs monochrome image starting from left,top coordinates
2513 *
2514 * Note: image must be located in external memory
2515 *
2516 ********************************************************************/
2517 void PutImage1BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch)
2518 {
2519 register DWORD memOffset;
2520 BITMAP_HEADER bmp;
2521 WORD pallete[2];
2522 BYTE lineBuffer[((GetMaxX() + 1) / 8) + 1];
2523 BYTE *pData;
2524 SHORT byteWidth;
2525  
2526 BYTE temp;
2527 BYTE mask;
2528 WORD sizeX, sizeY;
2529 WORD x, y;
2530 WORD xc, yc;
2531 BYTE stretchX, stretchY;
2532  
2533 // Get bitmap header
2534 ExternalMemoryCallback(bitmap, 0, sizeof(BITMAP_HEADER), &bmp);
2535  
2536 // Get pallete (2 entries)
2537 ExternalMemoryCallback(bitmap, sizeof(BITMAP_HEADER), 2 * sizeof(WORD), pallete);
2538  
2539 // Set offset to the image data
2540 memOffset = sizeof(BITMAP_HEADER) + 2 * sizeof(WORD);
2541  
2542 // Line width in bytes
2543 byteWidth = bmp.width >> 3;
2544 if(bmp.width & 0x0007)
2545 byteWidth++;
2546  
2547 // Get size
2548 sizeX = bmp.width;
2549 sizeY = bmp.height;
2550  
2551 yc = top;
2552 for(y = 0; y < sizeY; y++)
2553 {
2554  
2555 // Get line
2556 ExternalMemoryCallback(bitmap, memOffset, byteWidth, lineBuffer);
2557 memOffset += byteWidth;
2558 for(stretchY = 0; stretchY < stretch; stretchY++)
2559 {
2560 pData = lineBuffer;
2561 mask = 0;
2562 xc = left;
2563 for(x = 0; x < sizeX; x++)
2564 {
2565  
2566 // Read 8 pixels from flash
2567 if(mask == 0)
2568 {
2569 temp = *pData++;
2570 mask = 0x80;
2571 }
2572  
2573 // Set color
2574 if(mask & temp)
2575 {
2576 // Set color
2577 #ifdef USE_PALETTE
2578 SetColor(1);
2579 #else
2580 SetColor(pallete[1]);
2581 #endif
2582 }
2583 else
2584 {
2585 // Set color
2586 #ifdef USE_PALETTE
2587 SetColor(0);
2588 #else
2589 SetColor(pallete[0]);
2590 #endif
2591 }
2592  
2593 // Write pixel to screen
2594 for(stretchX = 0; stretchX < stretch; stretchX++)
2595 {
2596 PutPixel(xc++, yc);
2597 }
2598  
2599 // Shift to the next pixel
2600 mask >>= 1;
2601 }
2602  
2603 yc++;
2604 }
2605 }
2606 }
2607  
2608 /*********************************************************************
2609 * Function: void PutImage4BPPExt(SHORT left, SHORT top, void* bitmap, BYTE stretch)
2610 *
2611 * PreCondition: none
2612 *
2613 * Input: left,top - left top image corner, bitmap - image pointer,
2614 * stretch - image stretch factor
2615 *
2616 * Output: none
2617 *
2618 * Side Effects: none
2619 *
2620 * Overview: outputs monochrome image starting from left,top coordinates
2621 *
2622 * Note: image must be located in external memory
2623 *
2624 ********************************************************************/
2625 #if (COLOR_DEPTH >= 4)
2626  
2627 /* */
2628 void PutImage4BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch)
2629 {
2630 register DWORD memOffset;
2631 BITMAP_HEADER bmp;
2632 WORD pallete[16];
2633 BYTE lineBuffer[((GetMaxX() + 1) / 2) + 1];
2634 BYTE *pData;
2635 SHORT byteWidth;
2636  
2637 BYTE temp = 0;
2638 WORD sizeX, sizeY;
2639 WORD x, y;
2640 WORD xc, yc;
2641 BYTE stretchX, stretchY;
2642  
2643 // Get bitmap header
2644 ExternalMemoryCallback(bitmap, 0, sizeof(BITMAP_HEADER), &bmp);
2645  
2646 // Get pallete (16 entries)
2647 ExternalMemoryCallback(bitmap, sizeof(BITMAP_HEADER), 16 * sizeof(WORD), pallete);
2648  
2649 // Set offset to the image data
2650 memOffset = sizeof(BITMAP_HEADER) + 16 * sizeof(WORD);
2651  
2652 // Line width in bytes
2653 byteWidth = bmp.width >> 1;
2654 if(bmp.width & 0x0001)
2655 byteWidth++;
2656  
2657 // Get size
2658 sizeX = bmp.width;
2659 sizeY = bmp.height;
2660  
2661 yc = top;
2662 for(y = 0; y < sizeY; y++)
2663 {
2664  
2665 // Get line
2666 ExternalMemoryCallback(bitmap, memOffset, byteWidth, lineBuffer);
2667 memOffset += byteWidth;
2668 for(stretchY = 0; stretchY < stretch; stretchY++)
2669 {
2670 pData = lineBuffer;
2671 xc = left;
2672 for(x = 0; x < sizeX; x++)
2673 {
2674  
2675 // Read 2 pixels from flash
2676 if(x & 0x0001)
2677 {
2678  
2679 // second pixel in byte
2680 // Set color
2681 #ifdef USE_PALETTE
2682 SetColor(temp >> 4);
2683 #else
2684 SetColor(pallete[temp >> 4]);
2685 #endif
2686 }
2687 else
2688 {
2689 temp = *pData++;
2690  
2691 // first pixel in byte
2692 // Set color
2693 #ifdef USE_PALETTE
2694 SetColor(temp & 0x0f);
2695 #else
2696 SetColor(pallete[temp & 0x0f]);
2697 #endif
2698 }
2699  
2700 // Write pixel to screen
2701 for(stretchX = 0; stretchX < stretch; stretchX++)
2702 {
2703 PutPixel(xc++, yc);
2704 }
2705 }
2706  
2707 yc++;
2708 }
2709 }
2710 }
2711  
2712 #endif
2713  
2714 /*********************************************************************
2715 * Function: void PutImage8BPPExt(SHORT left, SHORT top, void* bitmap, BYTE stretch)
2716 *
2717 * PreCondition: none
2718 *
2719 * Input: left,top - left top image corner, bitmap - image pointer,
2720 * stretch - image stretch factor
2721 *
2722 * Output: none
2723 *
2724 * Side Effects: none
2725 *
2726 * Overview: outputs monochrome image starting from left,top coordinates
2727 *
2728 * Note: image must be located in external memory
2729 *
2730 ********************************************************************/
2731 #if (COLOR_DEPTH >= 8)
2732  
2733 /* */
2734 void PutImage8BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch)
2735 {
2736 register DWORD memOffset;
2737 BITMAP_HEADER bmp;
2738 WORD pallete[256];
2739 BYTE lineBuffer[(GetMaxX() + 1)];
2740 BYTE *pData;
2741  
2742 BYTE temp;
2743 WORD sizeX, sizeY;
2744 WORD x, y;
2745 WORD xc, yc;
2746 BYTE stretchX, stretchY;
2747  
2748 // Get bitmap header
2749 ExternalMemoryCallback(bitmap, 0, sizeof(BITMAP_HEADER), &bmp);
2750  
2751 // Get pallete (256 entries)
2752 ExternalMemoryCallback(bitmap, sizeof(BITMAP_HEADER), 256 * sizeof(WORD), pallete);
2753  
2754 // Set offset to the image data
2755 memOffset = sizeof(BITMAP_HEADER) + 256 * sizeof(WORD);
2756  
2757 // Get size
2758 sizeX = bmp.width;
2759 sizeY = bmp.height;
2760  
2761 yc = top;
2762 for(y = 0; y < sizeY; y++)
2763 {
2764  
2765 // Get line
2766 ExternalMemoryCallback(bitmap, memOffset, sizeX, lineBuffer);
2767 memOffset += sizeX;
2768 for(stretchY = 0; stretchY < stretch; stretchY++)
2769 {
2770 pData = lineBuffer;
2771 xc = left;
2772 for(x = 0; x < sizeX; x++)
2773 {
2774 temp = *pData++;
2775 // Set color
2776 #ifdef USE_PALETTE
2777 SetColor(temp);
2778 #else
2779 SetColor(pallete[temp]);
2780 #endif
2781  
2782 // Write pixel to screen
2783 for(stretchX = 0; stretchX < stretch; stretchX++)
2784 {
2785 PutPixel(xc++, yc);
2786 }
2787 }
2788  
2789 yc++;
2790 }
2791 }
2792 }
2793  
2794 #endif
2795  
2796 /*********************************************************************
2797 * Function: void PutImage16BPPExt(SHORT left, SHORT top, void* bitmap, BYTE stretch)
2798 *
2799 * PreCondition: none
2800 *
2801 * Input: left,top - left top image corner, bitmap - image pointer,
2802 * stretch - image stretch factor
2803 *
2804 * Output: none
2805 *
2806 * Side Effects: none
2807 *
2808 * Overview: outputs monochrome image starting from left,top coordinates
2809 *
2810 * Note: image must be located in external memory
2811 *
2812 ********************************************************************/
2813 #if (COLOR_DEPTH == 16)
2814  
2815 /* */
2816 void PutImage16BPPExt(SHORT left, SHORT top, void *bitmap, BYTE stretch)
2817 {
2818 register DWORD memOffset;
2819 BITMAP_HEADER bmp;
2820 WORD lineBuffer[(GetMaxX() + 1)];
2821 WORD *pData;
2822 WORD byteWidth;
2823  
2824 WORD temp;
2825 WORD sizeX, sizeY;
2826 WORD x, y;
2827 WORD xc, yc;
2828 BYTE stretchX, stretchY;
2829  
2830 // Get bitmap header
2831 ExternalMemoryCallback(bitmap, 0, sizeof(BITMAP_HEADER), &bmp);
2832  
2833 // Set offset to the image data
2834 memOffset = sizeof(BITMAP_HEADER);
2835  
2836 // Get size
2837 sizeX = bmp.width;
2838 sizeY = bmp.height;
2839  
2840 byteWidth = sizeX << 1;
2841  
2842 yc = top;
2843 for(y = 0; y < sizeY; y++)
2844 {
2845  
2846 // Get line
2847 ExternalMemoryCallback(bitmap, memOffset, byteWidth, lineBuffer);
2848 memOffset += byteWidth;
2849 for(stretchY = 0; stretchY < stretch; stretchY++)
2850 {
2851 pData = lineBuffer;
2852  
2853 xc = left;
2854 for(x = 0; x < sizeX; x++)
2855 {
2856 temp = *pData++;
2857 SetColor(temp);
2858  
2859 // Write pixel to screen
2860 for(stretchX = 0; stretchX < stretch; stretchX++)
2861 {
2862 PutPixel(xc++, yc);
2863 }
2864 }
2865  
2866 yc++;
2867 }
2868 }
2869 }
2870  
2871 #endif
2872 #endif
2873 #endif // USE_DRV_PUTIMAGE
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3