mcufriend 2.4 TFT LCD Shield Lib

Dependents:   Nucleo_LCD_mcufriend_test

Fork of 24_TFT_STMNUCLEO by Carlos Silva

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lcd_base.cpp Source File

lcd_base.cpp

00001 /*
00002  * Copyright (C)2010-2012 Henning Karlsen. All right reserved.
00003  * Copyright (C)2012 Todor Todorov.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to:
00017  *
00018  * Free Software Foundation, Inc.
00019  * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
00020  *
00021  *********************************************************************/
00022 #include "lcd_base.h"
00023 #include "helpers.h"
00024  
00025 LCD::LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS, PinName RESET, PinName BL, backlight_t blType, float defaultBacklight )
00026     : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ), _lcd_pin_reset( RESET ), _bl_type( blType )
00027 {
00028     SetForeground();
00029     SetBackground();
00030 //    _font = &TerminusFont;
00031     _font = &TerminusBigFont;
00032     if ( defaultBacklight < 0 ) _bl_pwm_default = 0;
00033     else if ( defaultBacklight > 1.0 ) _bl_pwm_default = 1.0;
00034     else _bl_pwm_default = defaultBacklight;
00035     if ( BL != NC )
00036     {
00037         if ( blType == Constant )
00038         {
00039             _bl_pwm = 0;
00040             _lcd_pin_bl = new DigitalOut( BL );
00041         }
00042         else
00043         {
00044             _lcd_pin_bl = 0;
00045             _bl_pwm = new PwmOut( BL );
00046             _bl_pwm->period_ms( 8.33 ); // 120 Hz
00047             _bl_pwm_current = _bl_pwm_default;
00048             // initially off
00049             *_bl_pwm = 0;
00050         }
00051         
00052     }
00053     else
00054     {
00055         _lcd_pin_bl = 0;
00056         _bl_pwm = 0;
00057     }
00058 }
00059  
00060 void LCD::Sleep( void )
00061 {
00062     if ( _lcd_pin_bl != 0 )
00063         *_lcd_pin_bl = LOW;
00064     else if ( _bl_pwm != 0 )
00065         *_bl_pwm = 0;
00066 }
00067  
00068 void LCD::WakeUp( void )
00069 {
00070     if ( _lcd_pin_bl != 0 )
00071         *_lcd_pin_bl = HIGH;
00072     else if ( _bl_pwm != 0 )
00073         *_bl_pwm = _bl_pwm_current;
00074 }
00075  
00076 inline
00077 void LCD::SetForeground( unsigned int color )
00078 {
00079     _foreground = color;
00080 }
00081  
00082 inline
00083 void LCD::SetBackground( unsigned int color )
00084 {
00085     _background = color;
00086 }
00087  
00088 void LCD::SetFont( const font_t *font )
00089 {
00090     _font = font;
00091 }
00092  
00093 //inline
00094 unsigned short LCD::GetHeight( void )
00095 {
00096     if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_width;
00097     return _disp_height;
00098 }
00099  
00100  
00101 //inline
00102 unsigned short LCD::GetWidth( void )
00103 {
00104     if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_height;
00105     return _disp_width;
00106 }
00107  
00108  
00109 //inline
00110 uint8_t LCD::GetFontWidth( void )
00111 {
00112     if ( _font != 0 ) return _font->Width;
00113     return 0;
00114 }
00115  
00116 inline
00117 uint8_t LCD::GetFontHeight( void )
00118 {
00119     if ( _font != 0 ) return _font->Height;
00120     return 0;
00121 }
00122  
00123 void LCD::SetBacklightLevel( float level )
00124 {
00125     switch ( _bl_type )
00126     {
00127         case Direct:
00128             if ( _bl_pwm != 0 )
00129             {
00130                 *_bl_pwm = level;
00131                 _bl_pwm_current = level;
00132             }
00133             break;
00134             
00135         case Indirect:
00136             break;
00137         case Constant:
00138         default:
00139             break;
00140     }
00141 }
00142  
00143 void LCD::FillScreen( int color )
00144 {
00145     unsigned int rgb = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00146     Activate();
00147     ClearXY();
00148     for ( int i = 0; i < ( ( _disp_width ) * ( _disp_height ) ); i++ )
00149         SetPixelColor( rgb );
00150     Deactivate();
00151 }
00152  
00153 inline
00154 void LCD::ClearScreen( void )
00155 {
00156     FillScreen( -1 );
00157 }
00158  
00159 void LCD::DrawPixel( unsigned short x, unsigned short y, int color )
00160 {
00161     Activate();
00162     SetXY( x, y, x, y );
00163     SetPixelColor( color == -1 ? _background :
00164                     color == -2 ? _foreground : color );
00165     Deactivate();
00166 }
00167  
00168 void LCD::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00169 {
00170     
00171     double delta, tx, ty;
00172  
00173     if ( ( ( x2 - x1 ) < 0 ) )
00174     {
00175         swap( ushort, x1, x2 )
00176         swap( ushort, y1, y2 )
00177     }
00178     if ( ( ( y2 - y1 ) < 0 ) )
00179     {
00180         swap( ushort, x1, x2 )
00181         swap( ushort, y1, y2 )
00182     }
00183  
00184     if ( y1 == y2 )
00185     {
00186         if ( x1 > x2 )
00187             swap( ushort, x1, x2 )
00188         DrawHLine( x1, y1, x2 - x1, color );
00189     }
00190     else if ( x1 == x2 )
00191     {
00192         if ( y1 > y2 )
00193             swap( ushort, y1, y2 )
00194         DrawVLine( x1, y1, y2 - y1, color );
00195     }
00196     else
00197     {
00198         unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00199         Activate();
00200         if ( abs( x2 - x1 ) > abs( y2 - y1 ) )
00201         {
00202             delta = ( double( y2 - y1 ) / double( x2 - x1 ) );
00203             ty = double( y1 );
00204             if ( x1 > x2 )
00205             {
00206                 for ( int i = x1; i >= x2; i-- )
00207                 {
00208                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00209                     SetPixelColor( usedColor );
00210                     ty = ty - delta;
00211                 }
00212             }
00213             else
00214             {
00215                 for ( int i = x1; i <= x2; i++ )
00216                 {
00217                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00218                     SetPixelColor( usedColor );
00219                     ty = ty + delta;
00220                 }
00221             }
00222         }
00223         else
00224         {
00225             delta = ( float( x2 - x1 ) / float( y2 - y1 ) );
00226             tx = float( x1 );
00227             if ( y1 > y2 )
00228             {
00229                 for ( int i = y2 + 1; i > y1; i-- )
00230                 {
00231                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00232                     SetPixelColor( usedColor );
00233                     tx = tx + delta;
00234                 }
00235             }
00236             else
00237             {
00238                 for ( int i = y1; i < y2 + 1; i++ )
00239                 {
00240                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00241                     SetPixelColor( usedColor );
00242                     tx = tx + delta;
00243                 }
00244             }
00245         }
00246         Deactivate();
00247     }
00248 }
00249 void LCD::DrawTriangle( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short x3, unsigned short y3,  int color )
00250 {
00251 //    if ( x1 > x2 ) swap( ushort, x1, x2 )
00252 //    if ( y1 > y2 ) swap( ushort, y1, y2 )
00253  
00254     DrawLine( x1, y1, x2, y2, color );
00255     DrawLine( x2, y2, x3, y3, color );
00256     DrawLine( x3, y3, x1, y1, color );
00257 }
00258  
00259 void LCD::FillTriangle( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short x3, unsigned short y3,  int color )
00260 {
00261     int dx1, dx2, dx3;
00262     int sx1, sx2, sy;
00263     
00264  
00265     if ( y1 > y2 ) { swap( ushort, y1, y2 ); swap( ushort, x1, x2 ); }
00266     if ( y2 > y3 ) { swap( ushort, y3, y2 ); swap( ushort, x3, x2 ); }
00267     if ( y1 > y2 ) { swap( ushort, y1, y2 ); swap( ushort, x1, x2 ); }
00268  
00269     sx2= x1 * 1000; // Use fixed point math for x axis values
00270     sx1 = sx2;
00271     sy=y1;
00272  
00273   // Calculate interpolation deltas
00274     if (y2-y1 > 0) dx1=((x2-x1)*1000)/(y2-y1);
00275       else dx1=0;
00276     if (y3-y1 > 0) dx2=((x3-x1)*1000)/(y3-y1);
00277       else dx2=0;
00278     if (y3-y2 > 0) dx3=((x3-x2)*1000)/(y3-y2);
00279       else dx3=0;
00280  
00281   // Render scanlines (horizontal lines are the fastest rendering method)
00282   if (dx1 > dx2)
00283   {
00284     for(; sy<=y2; sy++, sx1+=dx2, sx2+=dx1)
00285     {
00286       DrawHLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00287     }
00288     sx2 = x2*1000;
00289     sy = y2;
00290     for(; sy<=y3; sy++, sx1+=dx2, sx2+=dx3)
00291     {
00292       DrawHLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00293     }
00294   }
00295   else
00296   {
00297     for(; sy<=y2; sy++, sx1+=dx1, sx2+=dx2)
00298     {
00299       DrawHLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00300     }
00301     sx1 = x2*1000;
00302     sy = y2;
00303     for(; sy<=y3; sy++, sx1+=dx3, sx2+=dx2)
00304     {
00305       DrawHLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00306     }
00307   }
00308  
00309 }
00310  
00311 void LCD::DrawRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00312 {
00313     if ( x1 > x2 ) swap( ushort, x1, x2 )
00314     if ( y1 > y2 ) swap( ushort, y1, y2 )
00315  
00316     DrawHLine( x1, y1, x2 - x1, color );
00317     DrawHLine( x1, y2, x2 - x1, color );
00318     DrawVLine( x1, y1, y2 - y1, color );
00319     DrawVLine( x2, y1, y2 - y1, color );
00320 }
00321  
00322 void LCD::DrawRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00323 {
00324     if ( x1 > x2 ) swap( ushort, x1, x2 )
00325     if ( y1 > y2 ) swap( ushort, y1, y2 )
00326  
00327     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00328     {
00329         DrawPixel( x1 + 1, y1 + 1, color );
00330         DrawPixel( x2 - 1, y1 + 1, color );
00331         DrawPixel( x1 + 1, y2 - 1, color );
00332         DrawPixel( x2 - 1, y2 - 1, color );
00333         DrawHLine( x1 + 2, y1, x2 - x1 - 4, color );
00334         DrawHLine( x1 + 2, y2, x2 - x1 - 4, color );
00335         DrawVLine( x1, y1 + 2, y2 - y1 - 4, color );
00336         DrawVLine( x2, y1 + 2, y2 - y1 - 4, color );
00337     }
00338 }
00339  
00340 void LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00341 {
00342     if ( x1 > x2 ) swap( ushort, x1, x2 );
00343     if ( y1 > y2 ) swap( ushort, y1, y2 );
00344  
00345     for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00346     {
00347         DrawHLine( x1, y1 + i, x2 - x1, color );
00348         DrawHLine( x1, y2 - i, x2 - x1, color );
00349     }
00350 }
00351  
00352 void LCD::FillRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00353 {
00354     if ( x1 > x2 ) swap( ushort, x1, x2 )
00355     if ( y1 > y2 ) swap( ushort, y1, y2 )
00356  
00357     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00358     {
00359         for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00360         {
00361             switch ( i )
00362             {
00363                 case 0:
00364                     DrawHLine( x1 + 2, y1 + i, x2 - x1 - 4, color );
00365                     DrawHLine( x1 + 2, y2 - i, x2 - x1 - 4, color );
00366                     break;
00367  
00368                 case 1:
00369                     DrawHLine( x1 + 1, y1 + i, x2 - x1 - 2, color );
00370                     DrawHLine( x1 + 1, y2 - i, x2 - x1 - 2, color );
00371                     break;
00372  
00373                 default:
00374                     DrawHLine( x1, y1 + i, x2 - x1, color );
00375                     DrawHLine( x1, y2 - i, x2 - x1, color );
00376                     break;
00377             }
00378         }
00379     }
00380 }
00381  
00382 void LCD::DrawCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00383 {
00384     int f = 1 - radius;
00385     int ddF_x = 1;
00386     int ddF_y = -2 * radius;
00387     int x1 = 0;
00388     int y1 = radius;
00389     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00390  
00391     Activate();
00392     SetXY( x, y + radius, x, y + radius );
00393     SetPixelColor( usedColor );
00394     SetXY( x, y - radius, x, y - radius );
00395     SetPixelColor( usedColor );
00396     SetXY( x + radius, y, x + radius, y );
00397     SetPixelColor( usedColor );
00398     SetXY( x - radius, y, x - radius, y );
00399     SetPixelColor( usedColor );
00400  
00401     while ( x1 < y1 )
00402     {
00403         if ( f >= 0 )
00404         {
00405             y1--;
00406             ddF_y += 2;
00407             f += ddF_y;
00408         }
00409         x1++;
00410         ddF_x += 2;
00411         f += ddF_x;
00412         SetXY( x + x1, y + y1, x + x1, y + y1 );
00413         SetPixelColor( usedColor );
00414         SetXY( x - x1, y + y1, x - x1, y + y1 );
00415         SetPixelColor( usedColor );
00416         SetXY( x + x1, y - y1, x + x1, y - y1 );
00417         SetPixelColor( usedColor );
00418         SetXY( x - x1, y - y1, x - x1, y - y1 );
00419         SetPixelColor( usedColor );
00420         SetXY( x + y1, y + x1, x + y1, y + x1 );
00421         SetPixelColor( usedColor );
00422         SetXY( x - y1, y + x1, x - y1, y + x1 );
00423         SetPixelColor( usedColor );
00424         SetXY( x + y1, y - x1, x + y1, y - x1 );
00425         SetPixelColor( usedColor );
00426         SetXY( x - y1, y - x1, x - y1, y - x1 );
00427         SetPixelColor( usedColor );
00428     }
00429     Deactivate();
00430 }
00431  
00432 void LCD::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00433 {
00434     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00435     Activate();
00436     for ( int y1 = -radius; y1 <= radius; y1++ )
00437         for ( int x1 = -radius; x1 <= radius; x1++ )
00438             if ( x1 * x1 + y1 * y1 <= radius * radius )
00439             {
00440                 SetXY( x + x1, y + y1, x + x1, y + y1 );
00441                 SetPixelColor( usedColor );
00442             }
00443     Deactivate();
00444 }
00445  
00446 void LCD::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg )
00447 {
00448     int stl, i;
00449  
00450     stl = strlen( str );
00451  
00452     if ( x == RIGHT )
00453         x = GetWidth() - ( stl * _font->Width );
00454     if ( x == CENTER )
00455         x = ( GetWidth() - ( stl * _font->Width ) ) / 2;
00456  
00457     for ( i = 0; i < stl; i++ )
00458         if ( deg == 0 )
00459             PrintChar( *str++, x + ( i * ( _font->Width ) ), y, fgColor, bgColor );
00460         else
00461             RotateChar( *str++, x, y, i, fgColor, bgColor, deg );
00462 }
00463  
00464 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned char scale )
00465 {
00466     int tx, ty, tc, tsx, tsy;
00467  
00468     Activate();
00469     if ( scale == 1 )
00470     {
00471         SetXY( x, y, x + img->Width - 1, y + img->Height - 1 );
00472  
00473         if ( img->Format == RGB16 )
00474         {
00475             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00476             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00477                 SetPixelColor( *pixel++, img->Format );
00478         }
00479         else if ( img->Format == RGB18 )
00480         {
00481             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00482             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00483                 SetPixelColor( *pixel++, img->Format );
00484         }
00485     }
00486     else
00487     {
00488         if ( img->Format == RGB16 )
00489         {
00490             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00491             
00492             for ( ty = 0; ty < img->Height; ty++ )
00493             {
00494                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00495                 for ( tsy = 0; tsy < scale; tsy++ )
00496                 {
00497                     for ( tx = 0; tx < img->Width; tx++ )
00498                     {
00499                         for ( tsx = 0; tsx < scale; tsx++ )
00500                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00501                     }
00502                 }
00503             }
00504         }
00505         else if ( img->Format == RGB18 )
00506         {
00507             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00508             
00509             for ( ty = 0; ty < img->Height; ty++ )
00510             {
00511                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00512                 for ( tsy = 0; tsy < scale; tsy++ )
00513                 {
00514                     for ( tx = 0; tx < img->Width; tx++ )
00515                     {
00516                         for ( tsx = 0; tsx < scale; tsx++ )
00517                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00518                     }
00519                 }
00520             }
00521         }
00522     }
00523     Deactivate();
00524 }
00525  
00526 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned short deg, unsigned short rox, unsigned short roy )
00527 {
00528     int tx, ty, newx, newy;
00529     double radian;
00530     radian = deg * 0.0175;
00531  
00532     if ( deg == 0 )
00533         DrawBitmap( x, y, img );
00534     else
00535     {
00536         Activate();
00537         
00538         if ( img->Format == RGB16 )
00539         {
00540             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00541             
00542             for ( ty = 0; ty < img->Height; ty++ )
00543                 for ( tx = 0; tx < img->Width; tx++ )
00544                 {
00545                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00546                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00547     
00548                     SetXY( newx, newy, newx, newy );
00549                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00550                 }
00551         }
00552         else if ( img->Format == RGB18 )
00553         {
00554             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00555             
00556             for ( ty = 0; ty < img->Height; ty++ )
00557                 for ( tx = 0; tx < img->Width; tx++ )
00558                 {
00559                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00560                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00561     
00562                     SetXY( newx, newy, newx, newy );
00563                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00564                 }
00565         }
00566         Deactivate();
00567     }
00568 }
00569  
00570 inline
00571 void LCD::Activate( void )
00572 {
00573     _lcd_pin_cs = LOW;
00574 }
00575  
00576 inline
00577 void LCD::Deactivate( void )
00578 {
00579     _lcd_pin_cs = HIGH;
00580 }
00581  
00582 inline
00583 void LCD::WriteCmdData( unsigned short cmd, unsigned short data )
00584 {
00585     WriteCmd( cmd );
00586     WriteData( data );
00587 }
00588  
00589 inline
00590 void LCD::ClearXY( void )
00591 {
00592     SetXY( 0, 0, GetWidth() - 1, GetHeight() - 1 );
00593 }
00594  
00595 void LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
00596 {
00597     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00598     
00599     Activate();
00600     SetXY( x, y, x + len, y );
00601     for ( int i = 0; i < len + 1; i++ )
00602         SetPixelColor( usedColor );
00603     Deactivate();
00604 }
00605  
00606 void LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
00607 {
00608     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00609     
00610     Activate();
00611     SetXY( x, y, x, y + len );
00612     for ( int i = 0; i < len; i++ )
00613         SetPixelColor( usedColor );
00614     Deactivate();
00615 }
00616  
00617 void LCD::PrintChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor )
00618 {
00619     uint8_t i, ch;
00620     uint16_t j;
00621     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00622     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00623     
00624     uint16_t totalCharBytes = ( _font->Width * _font->Height ) / 8;
00625     int16_t position = _font->Position[ c - _font->Offset ];
00626     if ( position == -1 ) position = 0; // will print space character
00627     
00628     Activate();
00629  
00630     SetXY( x, y, x + _font->Width - 1, y + _font->Height - 1 );
00631     
00632     for ( j = 0; j < totalCharBytes; j++ )
00633     {
00634         ch = _font->Data[ position ];
00635         for ( i = 0; i < 8; i++ )
00636         {
00637             if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00638             else SetPixelColor( usedColorBG );
00639         }
00640         position++;
00641     }
00642     Deactivate();
00643 }
00644  
00645 void LCD::RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg )
00646 {
00647     uint8_t i, j, ch;
00648     int newx, newy;
00649     double radian;
00650     radian = deg * 0.0175;
00651     
00652     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00653     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00654  
00655     int16_t position = _font->Position[ c - _font->Offset ];
00656     if ( position == -1 ) position = 0; // will print space character
00657     
00658     Activate();
00659     
00660     for ( j = 0; j < _font->Height; j++ )
00661     {
00662         for ( uint16_t zz = 0; zz < ( ( double ) _font->Width / 8 ); zz++ )
00663         {
00664             ch = _font->Data[ position + zz ];
00665             for ( i = 0; i < 8; i++ )
00666             {
00667                 newx = x + ( ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * cos( radian ) ) - ( ( j ) * sin( radian ) ) );
00668                 newy = y + ( ( ( j ) * cos( radian ) ) + ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * sin( radian ) ) );
00669  
00670                 SetXY( newx, newy, newx + 1, newy + 1 );
00671  
00672                 if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00673                 else SetPixelColor( usedColorBG );
00674             }
00675         }
00676         position += ( _font->Width / 8 );
00677     }
00678  
00679     Deactivate();
00680 }