]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/lcd_draw.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / libboard_sama5d3x-ek / source / lcd_draw.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /** \addtogroup lcdd_draw\r
31  *\r
32  * Implementation of draw function on LCD, Include draw text, image\r
33  * and basic shapes (line, rectangle, circle).\r
34  *\r
35  */\r
36  \r
37 /** \file */\r
38 \r
39 /*----------------------------------------------------------------------------\r
40  *        Headers\r
41  *----------------------------------------------------------------------------*/\r
42 \r
43 #include "board.h"\r
44 \r
45 #include <stdint.h>\r
46 #include <string.h>\r
47 #include <assert.h>\r
48 \r
49 /*----------------------------------------------------------------------------\r
50  *        Local variable\r
51  *----------------------------------------------------------------------------*/\r
52 \r
53 /** Front color cache */\r
54 static uint32_t dwFrontColor;\r
55 \r
56 /*----------------------------------------------------------------------------\r
57  *        Local functions\r
58  *----------------------------------------------------------------------------*/\r
59 \r
60 /**\r
61  * Hide canvas layer\r
62  */\r
63 static void _HideCanvas(void)\r
64 {\r
65     //LCDD_EnableLayer(LCDD_GetCanvas()->bLayer, 0);\r
66 }\r
67 \r
68 /**\r
69  * Update canvas\r
70  */\r
71 static void _ShowCanvas(void)\r
72 {\r
73     //LCDD_EnableLayer(LCDD_GetCanvas()->bLayer, 1);\r
74 }\r
75 \r
76 /**\r
77  * Set front color\r
78  * \param dwColor Pixel color.\r
79  */\r
80 static void _SetFrontColor(uint32_t dwColor)\r
81 {\r
82     dwFrontColor = dwColor;\r
83 }\r
84 \r
85 /**\r
86  * \brief Draw a pixel on LCD of front color.\r
87  *\r
88  * \param dwX       X-coordinate of pixel.\r
89  * \param dwY       Y-coordinate of pixel.\r
90  */\r
91 static void _DrawPixel( uint32_t dwX, uint32_t dwY )\r
92 {\r
93     sLCDDLayer *pDisp = LCDD_GetCanvas();\r
94     uint8_t* buffer = pDisp->pBuffer;\r
95     uint16_t w = pDisp->wImgW;\r
96     //uint16_t h = pDisp->wImgH;\r
97     uint16_t cw = pDisp->bMode/8; /* color width */\r
98     uint32_t rw = w * cw;         /* row width in bytes */\r
99     //uint8_t  r, g, b;\r
100     uint8_t  *pPix;\r
101 \r
102     if (buffer == NULL)\r
103         return;\r
104 \r
105     if (rw & 0x3) rw = (rw | 0x3) + 1; /* 4-byte aligned rows */\r
106     pPix = &buffer[dwY * rw + cw * dwX];\r
107 \r
108     switch (pDisp->bMode)\r
109     {\r
110         case 16: /* TRGB 1555 */\r
111             pPix[0] = (dwFrontColor      ) & 0xFF;\r
112             pPix[1] = (dwFrontColor >>  8) & 0xFF;\r
113             break;\r
114         case 24: /*  RGB  888 */\r
115             pPix[0] = (dwFrontColor      ) & 0xFF;\r
116             pPix[1] = (dwFrontColor >>  8) & 0xFF;\r
117             pPix[2] = (dwFrontColor >> 16) & 0xFF;\r
118             break;\r
119         case 32: /* ARGB 8888 */\r
120             pPix[0] = (dwFrontColor      ) & 0xFF;\r
121             pPix[1] = (dwFrontColor >>  8) & 0xFF;\r
122             pPix[2] = (dwFrontColor >> 16) & 0xFF;\r
123             pPix[3] = (dwFrontColor >> 24) & 0xFF;\r
124             break;\r
125     }\r
126 }\r
127 \r
128 /**\r
129  * \brief Fill rectangle with front color.\r
130  * \param dwX1  X-coordinate of top left.\r
131  * \param dwY1  Y-coordinate of top left.\r
132  * \param dwX2  X-coordinate of bottom right.\r
133  * \param dwY1  Y-coordinate of bottom right.\r
134  */\r
135 static void _FillRect( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )\r
136 {\r
137     sLCDDLayer *pDisp = LCDD_GetCanvas();\r
138     uint16_t w = pDisp->wImgW;\r
139     uint16_t cw = pDisp->bMode/8; /* color width */\r
140     uint32_t rw = w * cw;         /* row width in bytes */\r
141     uint8_t *base = pDisp->pBuffer;\r
142     uint8_t *buffer = pDisp->pBuffer;\r
143     uint32_t fillStart, fillEnd;\r
144     uint32_t i;\r
145     if (buffer == NULL) return;\r
146 \r
147     /* 4-byte aligned rows */\r
148     if (rw & 0x3) rw = (rw | 0x3) + 1;\r
149     /* Buffer address for the starting row */\r
150     base = &buffer[dwY1*rw];\r
151 \r
152     fillStart = dwX1 * cw;\r
153     fillEnd   = dwX2 * cw;\r
154 \r
155     #if 1 /* Memcopy pixel */\r
156     buffer = base;\r
157     for (; dwY1 <= dwY2; dwY1 ++)\r
158     {\r
159         for (i = fillStart; i <= fillEnd; i += cw)\r
160         {\r
161             memcpy(&buffer[i], &dwFrontColor, cw);\r
162         }\r
163         buffer = &buffer[rw]; \r
164     }\r
165     #endif\r
166 \r
167     #if 0 /* Pixel by pixel */\r
168     for (; dwY1 <= dwY2; dwY1 ++)\r
169     {\r
170         for (i = dwX1; i <= dwX2; i ++)\r
171         {\r
172             _DrawPixel(i, dwY1);\r
173         }\r
174     }\r
175     #endif\r
176 \r
177     #if 0 /* Optimized */\r
178     /* First row */\r
179     for (i = fillStart; i <= fillEnd; i += cw)\r
180     {\r
181         memcpy(&base[i], &dwFrontColor, cw);\r
182     }\r
183     /* Next rows, copy first */\r
184     buffer = &base[rw + fillStart];\r
185     for (i = dwY1 + 1; i <= dwY2; i ++)\r
186     {\r
187         memcpy(buffer, &base[fillStart], fillEnd - fillStart + cw);\r
188         buffer = &buffer[rw];\r
189     }\r
190     #endif\r
191 }\r
192 \r
193 /**\r
194  * \brief Draw a line on LCD, which is not horizontal or vertical.\r
195  *\r
196  * \param dwX1       X-coordinate of line start.\r
197  * \param dwY1       Y-coordinate of line start.\r
198  * \param dwX2       X-coordinate of line end.\r
199  * \param dwY2       Y-coordinate of line end.\r
200  */\r
201 static uint32_t _DrawLineBresenham( uint32_t dwX1, uint32_t dwY1,\r
202                                     uint32_t dwX2, uint32_t dwY2 )\r
203 {\r
204     int dx, dy ;\r
205     int i ;\r
206     int xinc, yinc, cumul ;\r
207     int x, y ;\r
208 \r
209     x = dwX1 ;\r
210     y = dwY1 ;\r
211     dx = dwX2 - dwX1 ;\r
212     dy = dwY2 - dwY1 ;\r
213 \r
214     xinc = ( dx > 0 ) ? 1 : -1 ;\r
215     yinc = ( dy > 0 ) ? 1 : -1 ;\r
216     dx = ( dx > 0 ) ? dx : -dx ;\r
217     dy = ( dy > 0 ) ? dy : -dy ;\r
218 \r
219     _DrawPixel( x, y ) ;\r
220 \r
221     if ( dx > dy )\r
222     {\r
223       cumul = dx / 2 ;\r
224       for ( i = 1 ; i <= dx ; i++ )\r
225       {\r
226         x += xinc ;\r
227         cumul += dy ;\r
228 \r
229         if ( cumul >= dx )\r
230         {\r
231           cumul -= dx ;\r
232           y += yinc ;\r
233         }\r
234         _DrawPixel( x, y ) ;\r
235       }\r
236     }\r
237     else\r
238     {\r
239         cumul = dy / 2 ;\r
240         for ( i = 1 ; i <= dy ; i++ )\r
241         {\r
242             y += yinc ;\r
243             cumul += dx ;\r
244 \r
245             if ( cumul >= dy )\r
246             {\r
247                 cumul -= dy ;\r
248                 x += xinc ;\r
249             }\r
250 \r
251             _DrawPixel( x, y ) ;\r
252         }\r
253     }\r
254 \r
255     return 0 ;\r
256 }\r
257 \r
258 \r
259 \r
260 /*----------------------------------------------------------------------------\r
261  *        Exported functions\r
262  *----------------------------------------------------------------------------*/\r
263 \r
264 /**\r
265  * \brief Fills the given LCD buffer with a particular color.\r
266  *\r
267  * \param color  Fill color.\r
268  */\r
269 void LCDD_Fill( uint32_t dwColor )\r
270 {\r
271     sLCDDLayer *pDisp = LCDD_GetCanvas();\r
272     _SetFrontColor(dwColor);\r
273     _HideCanvas();\r
274     _FillRect( 0, 0, pDisp->wImgW, pDisp->wImgH );\r
275     _ShowCanvas();\r
276 }\r
277 \r
278 void LCDD_Fill0(void)\r
279 {\r
280     sLCDDLayer *pDisp = LCDD_GetCanvas();    \r
281     _HideCanvas();\r
282     _SetFrontColor(0xFF0000);\r
283     _FillRect( 0, 0, pDisp->wImgW/3, pDisp->wImgH );\r
284     _SetFrontColor(0x00FF00);\r
285     _FillRect( pDisp->wImgW/3, 0, pDisp->wImgW/3+pDisp->wImgW/3, pDisp->wImgH );\r
286     _SetFrontColor(0x0000FF);\r
287     _FillRect( pDisp->wImgW/3+pDisp->wImgW/3, 0, pDisp->wImgW, pDisp->wImgH );\r
288     _ShowCanvas();\r
289 }\r
290 /**\r
291  * \brief Draw a pixel on LCD of given color.\r
292  *\r
293  * \param x  X-coordinate of pixel.\r
294  * \param y  Y-coordinate of pixel.\r
295  * \param color  Pixel color.\r
296  */\r
297 extern void LCDD_DrawPixel( uint32_t x, uint32_t y, uint32_t color )\r
298 {\r
299     _SetFrontColor(color);\r
300     _HideCanvas();\r
301     _DrawPixel(x, y);\r
302     _ShowCanvas();\r
303 }\r
304 \r
305 /**\r
306  * \brief Read a pixel from LCD.\r
307  *\r
308  * \param x  X-coordinate of pixel.\r
309  * \param y  Y-coordinate of pixel.\r
310  *\r
311  * \return color  Readed pixel color.\r
312  */\r
313 extern uint32_t LCDD_ReadPixel( uint32_t x, uint32_t y )\r
314 {\r
315     sLCDDLayer *pDisp = LCDD_GetCanvas();\r
316     uint8_t* buffer = pDisp->pBuffer;\r
317     uint16_t w = pDisp->wImgW;\r
318     //uint16_t h = pDisp->wImgH;\r
319     uint16_t cw = pDisp->bMode/8; /* color width */\r
320     uint32_t rw = w * cw;         /* row width in bytes */\r
321     uint8_t  *pPix;\r
322     uint32_t color = 0;\r
323 \r
324     if (buffer == NULL) return 0;\r
325 \r
326     if (rw & 0x3) rw = (rw | 0x3) + 1; /* 4-byte aligned rows */\r
327     pPix = &buffer[x * rw + cw * y];\r
328 \r
329     switch (pDisp->bMode)\r
330     {\r
331         case 16: /* TRGB 1555 */\r
332             color = pPix[0] | (pPix[1] << 8);\r
333             break;\r
334         case 24: /*  RGB  888 */\r
335             color = pPix[0] | (pPix[1] << 8) | (pPix[2] << 16);\r
336             break;\r
337         case 32: /* ARGB 8888 */\r
338             color = pPix[0] | (pPix[1] << 8) | (pPix[2] << 16) | (pPix[3] << 24);\r
339             break;\r
340     }\r
341     return color;\r
342 }\r
343 \r
344 /**\r
345  * \brief Draw a line on LCD, horizontal and vertical line are supported.\r
346  *\r
347  * \param x1        X-coordinate of line start.\r
348  * \param y1        Y-coordinate of line start.\r
349  * \param x2        X-coordinate of line end.\r
350  * \param y2        Y-coordinate of line end.\r
351  * \param color     Pixel color.\r
352  */\r
353 extern void LCDD_DrawLine( uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t color )\r
354 {\r
355     _SetFrontColor(color);\r
356     if ( (x1 == x2) || (y1 == y2) )\r
357     {\r
358         LCDD_DrawFilledRectangle(x1, y1, x2, y2, color);\r
359     }\r
360     else\r
361     {\r
362         _HideCanvas();\r
363         _DrawLineBresenham(x1, y1, x2, y2);\r
364         _ShowCanvas();\r
365     }\r
366 }\r
367 \r
368 /**\r
369  * \brief Draws a rectangle on LCD, at the given coordinates.\r
370  *\r
371  * \param x      X-coordinate of upper-left rectangle corner.\r
372  * \param y      Y-coordinate of upper-left rectangle corner.\r
373  * \param width  Rectangle width in pixels.\r
374  * \param height  Rectangle height in pixels.\r
375  * \param color  Rectangle color.\r
376  */\r
377 extern void LCDD_DrawRectangle( uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color )\r
378 {\r
379     uint32_t x1 = x + width - 1;\r
380     uint32_t y1 = y + height - 1;\r
381 \r
382     _SetFrontColor(color);\r
383     _HideCanvas();\r
384     _FillRect(x , y , x1, y );\r
385     _FillRect(x1, y , x1, y1);\r
386     _FillRect(x , y , x , y1);\r
387     _FillRect(x , y1, x1, y1);\r
388     _ShowCanvas();\r
389 }\r
390 \r
391 /**\r
392  * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.\r
393  *\r
394  * \param dwX1   X-coordinate of upper-left rectangle corner.\r
395  * \param dwY1   Y-coordinate of upper-left rectangle corner.\r
396  * \param dwX2   X-coordinate of down-right rectangle corner.\r
397  * \param dwY2   Y-coordinate of down-right rectangle corner.\r
398  * \param color  Rectangle color.\r
399  */\r
400 extern void LCDD_DrawFilledRectangle( uint32_t dwX1, uint32_t dwY1,\r
401                                       uint32_t dwX2, uint32_t dwY2,\r
402                                       uint32_t dwColor )\r
403 {\r
404     _SetFrontColor(dwColor);\r
405     _HideCanvas();\r
406     _FillRect(dwX1, dwY1, dwX2, dwY2);\r
407     _ShowCanvas();\r
408 }\r
409 \r
410 /**\r
411  * \brief Draws a circle on LCD, at the given coordinates.\r
412  *\r
413  * \param dwX     X-coordinate of circle center.\r
414  * \param dwY     Y-coordinate of circle center.\r
415  * \param dwR     circle radius.\r
416  * \param dwColor circle color.\r
417  */\r
418 extern void LCDD_DrawCircle( uint32_t dwX, uint32_t dwY, uint32_t dwR, uint32_t dwColor )\r
419 {\r
420     int32_t   d;    /* Decision Variable */\r
421     uint32_t  curX; /* Current X Value */\r
422     uint32_t  curY; /* Current Y Value */\r
423 \r
424    if (dwR == 0) return;\r
425    _SetFrontColor(dwColor);\r
426 \r
427    d = 3 - (dwR << 1);\r
428    curX = 0;\r
429    curY = dwR;\r
430 \r
431    _HideCanvas();\r
432    while (curX <= curY)\r
433    {\r
434        _DrawPixel(dwX + curX, dwY + curY);\r
435        _DrawPixel(dwX + curX, dwY - curY);\r
436        _DrawPixel(dwX - curX, dwY + curY);\r
437        _DrawPixel(dwX - curX, dwY - curY);\r
438        _DrawPixel(dwX + curY, dwY + curX);\r
439        _DrawPixel(dwX + curY, dwY - curX);\r
440        _DrawPixel(dwX - curY, dwY + curX);\r
441        _DrawPixel(dwX - curY, dwY - curX);\r
442    \r
443        if (d < 0) {\r
444            d += (curX << 2) + 6;\r
445        }\r
446        else {\r
447            d += ((curX - curY) << 2) + 10;\r
448            curY--;\r
449        }\r
450        curX++;\r
451    }\r
452    _ShowCanvas();\r
453 }\r
454 \r
455 \r
456 /**\r
457  * \brief Draws a filled circle on LCD, at the given coordinates.\r
458  *\r
459  * \param dwX     X-coordinate of circle center.\r
460  * \param dwY     Y-coordinate of circle center.\r
461  * \param dwR     circle radius.\r
462  * \param dwColor circle color.\r
463  */\r
464 void LCDD_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwR, uint32_t dwColor )\r
465 {\r
466     signed int d ; // Decision Variable\r
467     uint32_t dwCurX ; // Current X Value\r
468     uint32_t dwCurY ; // Current Y Value\r
469     uint32_t dwXmin, dwYmin;\r
470 \r
471     if (dwR == 0)        return;\r
472     _SetFrontColor(dwColor);\r
473 \r
474     d = 3 - (dwR << 1) ;\r
475     dwCurX = 0 ;\r
476     dwCurY = dwR ;\r
477 \r
478     _HideCanvas();\r
479     while ( dwCurX <= dwCurY )\r
480     {\r
481         dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;\r
482         dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;\r
483         _FillRect( dwXmin, dwYmin, dwX+dwCurX, dwYmin ) ;\r
484         _FillRect( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY ) ;\r
485         dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;\r
486         dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;\r
487         _FillRect( dwXmin, dwYmin, dwX+dwCurY, dwYmin ) ;\r
488         _FillRect( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX ) ;\r
489 \r
490         if ( d < 0 )\r
491         {\r
492             d += (dwCurX << 2) + 6 ;\r
493         }\r
494         else\r
495         {\r
496             d += ((dwCurX - dwCurY) << 2) + 10;\r
497             dwCurY-- ;\r
498         }\r
499 \r
500         dwCurX++ ;\r
501     }\r
502     _ShowCanvas();\r
503 }\r
504 \r
505 /**\r
506  * \brief Draws a string inside a LCD buffer, at the given coordinates. Line breaks\r
507  * will be honored.\r
508  *\r
509  * \param x        X-coordinate of string top-left corner.\r
510  * \param y        Y-coordinate of string top-left corner.\r
511  * \param pString  String to display.\r
512  * \param color    String color.\r
513  */\r
514 extern void LCDD_DrawString( uint32_t x, uint32_t y, const char *pString, uint32_t color )\r
515 {\r
516     uint32_t xorg = x;\r
517     while (*pString)\r
518     {\r
519         if (*pString == '\n')\r
520         {\r
521             y += gFont.height + 2; x = xorg;\r
522         }\r
523         else\r
524         {\r
525             LCDD_DrawChar(x, y, *pString, color);\r
526             x += gFont.width + 2;\r
527         }\r
528         pString ++;\r
529     }\r
530 }\r
531 \r
532 /**\r
533  * \brief Draws a string inside a LCD buffer, at the given coordinates\r
534  * with given background color. Line breaks will be honored.\r
535  *\r
536  * \param x         X-coordinate of string top-left corner.\r
537  * \param y         Y-coordinate of string top-left corner.\r
538  * \param pString   String to display.\r
539  * \param fontColor String color.\r
540  * \param bgColor   Background color.\r
541  */\r
542 extern void LCDD_DrawStringWithBGColor( uint32_t x, uint32_t y, const char *pString, uint32_t fontColor, uint32_t bgColor )\r
543 {\r
544     uint32_t xorg = x;\r
545     while (*pString)\r
546     {\r
547         if (*pString == '\n')\r
548         {\r
549             y += gFont.height + 2; x = xorg;\r
550         }\r
551         else\r
552         {\r
553             LCDD_DrawCharWithBGColor(x, y, *pString, fontColor, bgColor);\r
554             x += gFont.width + 2;\r
555         }\r
556         pString ++;\r
557     }\r
558 }\r
559 \r
560 /**\r
561  * \brief Returns the width & height in pixels that a string will occupy on the screen\r
562  * if drawn using LCDD_DrawString.\r
563  *\r
564  * \param pString  String.\r
565  * \param pWidth   Pointer for storing the string width (optional).\r
566  * \param pHeight  Pointer for storing the string height (optional).\r
567  *\r
568  * \return String width in pixels.\r
569  */\r
570 extern void LCDD_GetStringSize( const char *pString, uint32_t *pWidth, uint32_t *pHeight )\r
571 {\r
572     uint32_t width = 0;\r
573     uint32_t height = gFont.height;\r
574     while (*pString)\r
575     {\r
576         if (*pString == '\n') height += gFont.height + 2;\r
577         else                  width  += gFont.height + 2;\r
578         pString ++;\r
579     }\r
580     if (width > 0) width -= 2;\r
581 \r
582     if (pWidth) *pWidth  = width;\r
583     if (pHeight)*pHeight = height;\r
584 }\r
585 \r
586 /**\r
587  * \brief Draw a raw image at given position on LCD.\r
588  *\r
589  * \param x         X-coordinate of image start.\r
590  * \param y         Y-coordinate of image start.\r
591  * \param pImage    Image buffer.\r
592  * \param width     Image width.\r
593  * \param height    Image height.\r
594  */\r
595 void LCDD_DrawImage( uint32_t dwX, uint32_t dwY, const uint8_t *pImage, uint32_t dwWidth, uint32_t dwHeight )\r
596 {\r
597     sLCDDLayer *pDisp = LCDD_GetCanvas();\r
598     uint16_t cw  = pDisp->bMode/8;      /* color width */\r
599     uint32_t rw  = pDisp->wImgW * cw;   /* Row width in bytes */\r
600     uint32_t rws = dwWidth * cw;        /* Source Row Width */\r
601     uint32_t rl  = (rw  & 0x3) ? ((rw  | 0x3) + 1) :  rw; /* Aligned length*/\r
602     uint32_t rls = (rws & 0x3) ? ((rws | 0x3) + 1) : rws; /* Aligned length */\r
603     uint8_t *pSrc, *pDst;\r
604     uint32_t i;\r
605 \r
606     pSrc = (uint8_t*)pImage;\r
607     pDst = pDisp->pBuffer;\r
608     pDst = &pDst[dwX*cw + dwY*rl];\r
609 \r
610     for (i = 0; i < dwHeight; i ++)\r
611     {\r
612         memcpy(pDst, pSrc, rws);\r
613         pSrc = &pSrc[rls];\r
614         pDst = &pDst[rl];\r
615     }\r
616 }\r
617 \r
618 \r
619 /**\r
620  * \brief Clear a window with an color.\r
621  *\r
622  * \param dwX         X-coordinate of the window.\r
623  * \param dwY         Y-coordinate of the window.\r
624  * \param dwWidth     window width.\r
625  * \param dwHeight    window height.\r
626  * \param dwColor     background color\r
627  */\r
628 extern void LCDD_ClearWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )\r
629 {\r
630     _SetFrontColor(dwColor);\r
631     _HideCanvas();\r
632     _FillRect(0, 0, dwX + dwWidth - 1, dwY + dwHeight - 1);\r
633     _ShowCanvas();\r
634 }\r
635 \r