This is a port of Henning Kralsen's UTFT library for Arduino/chipKIT to mbed, refactored to make full use of C++ inheritance and access control, in order to reduce work when implementing new drivers and at the same time make the code more readable and easier to maintain. As of now supported are SSD1289 (16-bit interface), HX8340-B (serial interface) and ST7735 (serial interface). Drivers for other controllers will be added as time and resources to acquire the displays to test the code permit.

Dependents:   test SDCard capstone_display capstone_display_2 ... more

TFTLCD Library

NOTE (2013-03-25) Tested with both mbed LPC1768 and Freedom KL25Z. -todor

A TFT LCD driver library, which at the moment provides support for the following display controllers: HX8340-B (serial interface), SSD1289 (16-bit interface), ST7735-R (serial interface), ILI9325/ILI9328 (16-bit interface).

As I am acquiring and testing out new displays, I decided to combine all ported drivers into one library as with the original work done by Henning. However I also had as a goal to make the code maintenance and readability easier/better, so the code has been heavily refactored to make full use of C++ facilities as inheritance and access control. I extracted the common pieces of code into a base class, which every driver inherits and only the controller-specific side is provided in the actual driver - things like initialization, addressing, data transfer, etc.

Another nice extension is that the display's backlight can now be controlled through the driver. Either a simple on/off method of control could be selected, or the brightness can be set through use of PWM (the latter placing some restrictions on which pins can be used for this, as mbed offers hardware PWM on only 6 pins).

I also plan to add support for touch screens as part of the library. The goal is to grow this piece of software into a lightweight graphics widgets library, which can be used to construct control screens with buttons or menus in a speedy and intuitive way.

Changes

2013-07-21

  • Fixed the sleep/wake-up functions of the ILI9328 driver.

2013-06-15

  • Added driver for ILI9328 (works with ILI9325) controller, 16-bit data bus. Screen rotation works as usual with the TFTLCD library, but for now only RGB565 color depth is working and you can use both 65K and 262K color space with this driver. But for some reason the sleep function is not behaving as expected; I am working on this.
  • This is only on my to-do list for now - haven't really had the time yet - but I am going to refactor the library a bit to allow use of GPIO ports for data transfers instead of DigitalOut: faster and cleaner that way. For those who are using it already in a working design and cannot repurpose the pins anymore, the current way it's working will still be available; I am hoping not to tear up the public interfaces of the library (... too much). Anyway, since I am at it, I will also try to add support for multiple bus interfaces to drivers that support it (i.e. both 8bit and 16bit use of ILI932x or SSD1289). Thought this might be a good place to give you guys the heads-up.

2013-01-25

  • Replaced all existing fonts from the UTFT library with the free Terminus font. Two different sizes are provided: 8x12 pixels and 16x28 pixels. I found the old fonts not so good looking and then they supported only the ASCII codes in the range 30 (space) to 126 (the tilde ). The 7segment font didn't even implement anything else than the numbers from 0 to 9 - so it was unusable for anything (one couldn't even display the time or date as it lacked the colon [:] or the period [.] or the slash [/] or the space [ ] characters). So I completely revamped the fonts and added Terminus as the new default with its 2 sizes. Further more I added in both sizes most of the characters up to ASCII code 255. For any code not in there, the space character is substituted. In the case, when you already have provided your own fonts, please have a look at the API changes in the files <terminus.h> and <terminus.cpp>: I promise you whatever time you spent designing your own font, it is not wasted; you merely need to add a second array, which describes which ASCII codes are available in your font, and their byte offset in the original character bitmap array; and a struct to tie all parts together and describe the character size. I am sorry for breaking the old API, but you will like the change and new options it brings you. Now you can insert any char above 127 up to code 255 (if available, of course) with its hex representation, e.g displaying the current temperature would look something like 85\xB0 F or 26\xB0 C (the space in between degree and F or C is needed because both F and C are used in hex numbers, so \xB0F is interpreted as ASCII code 2831 instead of ASCII code 176, followed by the temperature scale denomination; if you insist on avoiding the space, you could write 85\xB0\x46 which will be displayed correctly as 85°F). You can either look up the ASCII code you need on Google or Bing, or just look at what's available - how it looks and its hex value - in the comments in <terminus.cpp>.
  • Added PWM backlight control. If you intend to use this, please make sure that control pin is either one of p21, p22, p23, p24, p25, or p26, as only they support hardware PWM. Please be aware that the mbed pins do not have much juice behind them, so if your display's backlight requires a lot of current, you are better off interfacing through as small signal transistor or a MOSFET. For the rest please consult the updated Doxygen documentation. NOTE The addition of PWM-controlled backlight will not break your existing code, the new options have default values, which initialize the used driver to behave as prior to PWM. Only if you want to use the new feature, some changes need to be made. The PWM is configured to be 120Hz (period of 8.33 milliseconds), in order to avoid noticeable flicker in the backlight. If in your opinion this value is too fine, then you can reduce the frequency in the LCD constructor in <lcd_base.cpp> by increasing the period value. My recommendation is to avoid frequencies lower than 60Hz.

2012-12-21

  • Internal-only changes in the way drivers transmit colors - done to simplify the bitmap drawing routines; client API remains unchanged.

2012-12-12

  • Added the driver for the ST7735 display controller.
  • Added the RGB18 color mode: choose between 16-bit (65K distinct colors) and 18-bit (262K distinct colors) color space [supported by all drivers]. NOTE This feature requires the image drawing functions to be changed, in order to account for differences between configured display color depth and the color depth of the image. Please review the API docs, in particular the new type bitmap_t and the DrawBitmap functions.
  • Changed display rotation to be achieved through the correspondent settings in the respective controller registers: no more software translation between width and height in different display orientations.
  • Extended the orientation options: PORTRAIT (top line to 12 o'clock/upright) and LANDSCAPE (top line to 9 o'clock) positions are the old options, PORTRAIT_REV (top line to 6 o'clock/upside-down) and LANDSCAPE_REV (top line to 3 o'clock) are the new orientations.
  • Added more pre-defined colors: available now are COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_CYAN, COLOR_MAGENTA and COLOR_YELLOW.

TODO

  • Finish implementing PWM-controlled backlight (current-sink configuration).
  • Add a driver for the HX8352-A controller (ITDB02-3.2WD 16:9 240x400 pixel resolution display).

How to Use

The code is documented, so please review the API docs. There is a simple example to get you started...

Committer:
ttodorov
Date:
Mon Jul 22 01:48:06 2013 +0000
Revision:
27:26491d710e72
Parent:
22:4c169297f374
- fix sleep/wakeup of ILI9328 driver

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ttodorov 0:881ff0b71102 1 /*
ttodorov 0:881ff0b71102 2 * Copyright (C)2010-2012 Henning Karlsen. All right reserved.
ttodorov 0:881ff0b71102 3 * Copyright (C)2012 Todor Todorov.
ttodorov 0:881ff0b71102 4 *
ttodorov 0:881ff0b71102 5 * This library is free software; you can redistribute it and/or
ttodorov 0:881ff0b71102 6 * modify it under the terms of the GNU Lesser General Public
ttodorov 0:881ff0b71102 7 * License as published by the Free Software Foundation; either
ttodorov 0:881ff0b71102 8 * version 2.1 of the License, or (at your option) any later version.
ttodorov 0:881ff0b71102 9 *
ttodorov 0:881ff0b71102 10 * This library is distributed in the hope that it will be useful,
ttodorov 0:881ff0b71102 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ttodorov 0:881ff0b71102 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ttodorov 0:881ff0b71102 13 * Lesser General Public License for more details.
ttodorov 0:881ff0b71102 14 *
ttodorov 0:881ff0b71102 15 * You should have received a copy of the GNU Lesser General Public
ttodorov 0:881ff0b71102 16 * License along with this library; if not, write to:
ttodorov 0:881ff0b71102 17 *
ttodorov 0:881ff0b71102 18 * Free Software Foundation, Inc.
ttodorov 0:881ff0b71102 19 * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
ttodorov 0:881ff0b71102 20 *
ttodorov 0:881ff0b71102 21 *********************************************************************/
ttodorov 0:881ff0b71102 22 #include "lcd_base.h"
ttodorov 3:64a5b67d5b51 23 #include "helpers.h"
ttodorov 0:881ff0b71102 24
ttodorov 22:4c169297f374 25 LCD::LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS, PinName RESET, PinName BL, backlight_t blType, float defaultBacklight )
ttodorov 22:4c169297f374 26 : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ), _lcd_pin_reset( RESET ), _bl_type( blType )
ttodorov 4:3ac4239f6c9c 27 {
ttodorov 4:3ac4239f6c9c 28 SetForeground();
ttodorov 4:3ac4239f6c9c 29 SetBackground();
ttodorov 21:e5c1e8ffada1 30 _font = &TerminusFont;
ttodorov 22:4c169297f374 31 if ( defaultBacklight < 0 ) _bl_pwm_default = 0;
ttodorov 22:4c169297f374 32 else if ( defaultBacklight > 1.0 ) _bl_pwm_default = 1.0;
ttodorov 22:4c169297f374 33 else _bl_pwm_default = defaultBacklight;
ttodorov 22:4c169297f374 34 if ( BL != NC )
ttodorov 22:4c169297f374 35 {
ttodorov 22:4c169297f374 36 if ( blType == Constant )
ttodorov 22:4c169297f374 37 {
ttodorov 22:4c169297f374 38 _bl_pwm = 0;
ttodorov 22:4c169297f374 39 _lcd_pin_bl = new DigitalOut( BL );
ttodorov 22:4c169297f374 40 }
ttodorov 22:4c169297f374 41 else
ttodorov 22:4c169297f374 42 {
ttodorov 22:4c169297f374 43 _lcd_pin_bl = 0;
ttodorov 22:4c169297f374 44 _bl_pwm = new PwmOut( BL );
ttodorov 22:4c169297f374 45 _bl_pwm->period_ms( 8.33 ); // 120 Hz
ttodorov 22:4c169297f374 46 _bl_pwm_current = _bl_pwm_default;
ttodorov 22:4c169297f374 47 // initially off
ttodorov 22:4c169297f374 48 *_bl_pwm = 0;
ttodorov 22:4c169297f374 49 }
ttodorov 22:4c169297f374 50
ttodorov 22:4c169297f374 51 }
ttodorov 22:4c169297f374 52 else
ttodorov 22:4c169297f374 53 {
ttodorov 22:4c169297f374 54 _lcd_pin_bl = 0;
ttodorov 22:4c169297f374 55 _bl_pwm = 0;
ttodorov 22:4c169297f374 56 }
ttodorov 22:4c169297f374 57 }
ttodorov 22:4c169297f374 58
ttodorov 22:4c169297f374 59 void LCD::Sleep( void )
ttodorov 22:4c169297f374 60 {
ttodorov 22:4c169297f374 61 if ( _lcd_pin_bl != 0 )
ttodorov 22:4c169297f374 62 *_lcd_pin_bl = LOW;
ttodorov 22:4c169297f374 63 else if ( _bl_pwm != 0 )
ttodorov 22:4c169297f374 64 *_bl_pwm = 0;
ttodorov 22:4c169297f374 65 }
ttodorov 22:4c169297f374 66
ttodorov 22:4c169297f374 67 void LCD::WakeUp( void )
ttodorov 22:4c169297f374 68 {
ttodorov 22:4c169297f374 69 if ( _lcd_pin_bl != 0 )
ttodorov 22:4c169297f374 70 *_lcd_pin_bl = HIGH;
ttodorov 22:4c169297f374 71 else if ( _bl_pwm != 0 )
ttodorov 22:4c169297f374 72 *_bl_pwm = _bl_pwm_current;
ttodorov 4:3ac4239f6c9c 73 }
ttodorov 0:881ff0b71102 74
ttodorov 0:881ff0b71102 75 inline
ttodorov 12:d0978272a340 76 void LCD::SetForeground( unsigned int color )
ttodorov 0:881ff0b71102 77 {
ttodorov 0:881ff0b71102 78 _foreground = color;
ttodorov 0:881ff0b71102 79 }
ttodorov 0:881ff0b71102 80
ttodorov 0:881ff0b71102 81 inline
ttodorov 12:d0978272a340 82 void LCD::SetBackground( unsigned int color )
ttodorov 0:881ff0b71102 83 {
ttodorov 0:881ff0b71102 84 _background = color;
ttodorov 0:881ff0b71102 85 }
ttodorov 0:881ff0b71102 86
ttodorov 21:e5c1e8ffada1 87 void LCD::SetFont( const font_t *font )
ttodorov 0:881ff0b71102 88 {
ttodorov 21:e5c1e8ffada1 89 _font = font;
ttodorov 0:881ff0b71102 90 }
ttodorov 0:881ff0b71102 91
ttodorov 0:881ff0b71102 92 inline
ttodorov 0:881ff0b71102 93 unsigned short LCD::GetWidth( void )
ttodorov 0:881ff0b71102 94 {
ttodorov 12:d0978272a340 95 if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_height;
ttodorov 0:881ff0b71102 96 return _disp_width;
ttodorov 0:881ff0b71102 97 }
ttodorov 0:881ff0b71102 98
ttodorov 0:881ff0b71102 99 inline
ttodorov 0:881ff0b71102 100 unsigned short LCD::GetHeight( void )
ttodorov 0:881ff0b71102 101 {
ttodorov 12:d0978272a340 102 if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_width;
ttodorov 0:881ff0b71102 103 return _disp_height;
ttodorov 0:881ff0b71102 104 }
ttodorov 0:881ff0b71102 105
ttodorov 21:e5c1e8ffada1 106 inline
ttodorov 21:e5c1e8ffada1 107 uint8_t LCD::GetFontWidth( void )
ttodorov 21:e5c1e8ffada1 108 {
ttodorov 21:e5c1e8ffada1 109 if ( _font != 0 ) return _font->Width;
ttodorov 21:e5c1e8ffada1 110 return 0;
ttodorov 21:e5c1e8ffada1 111 }
ttodorov 21:e5c1e8ffada1 112
ttodorov 21:e5c1e8ffada1 113 inline
ttodorov 21:e5c1e8ffada1 114 uint8_t LCD::GetFontHeight( void )
ttodorov 21:e5c1e8ffada1 115 {
ttodorov 21:e5c1e8ffada1 116 if ( _font != 0 ) return _font->Height;
ttodorov 21:e5c1e8ffada1 117 return 0;
ttodorov 21:e5c1e8ffada1 118 }
ttodorov 21:e5c1e8ffada1 119
ttodorov 22:4c169297f374 120 void LCD::SetBacklightLevel( float level )
ttodorov 22:4c169297f374 121 {
ttodorov 22:4c169297f374 122 switch ( _bl_type )
ttodorov 22:4c169297f374 123 {
ttodorov 22:4c169297f374 124 case Direct:
ttodorov 22:4c169297f374 125 if ( _bl_pwm != 0 )
ttodorov 22:4c169297f374 126 {
ttodorov 22:4c169297f374 127 *_bl_pwm = level;
ttodorov 22:4c169297f374 128 _bl_pwm_current = level;
ttodorov 22:4c169297f374 129 }
ttodorov 22:4c169297f374 130 break;
ttodorov 22:4c169297f374 131
ttodorov 22:4c169297f374 132 case Indirect:
ttodorov 22:4c169297f374 133 break;
ttodorov 22:4c169297f374 134 case Constant:
ttodorov 22:4c169297f374 135 default:
ttodorov 22:4c169297f374 136 break;
ttodorov 22:4c169297f374 137 }
ttodorov 22:4c169297f374 138 }
ttodorov 22:4c169297f374 139
ttodorov 0:881ff0b71102 140 void LCD::FillScreen( int color )
ttodorov 0:881ff0b71102 141 {
ttodorov 12:d0978272a340 142 unsigned int rgb = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 4:3ac4239f6c9c 143 Activate();
ttodorov 2:81ed304b7e9b 144 ClearXY();
ttodorov 1:14bef43daf6f 145 for ( int i = 0; i < ( ( _disp_width ) * ( _disp_height ) ); i++ )
ttodorov 10:69571adcfad5 146 SetPixelColor( rgb );
ttodorov 4:3ac4239f6c9c 147 Deactivate();
ttodorov 0:881ff0b71102 148 }
ttodorov 0:881ff0b71102 149
ttodorov 0:881ff0b71102 150 inline
ttodorov 0:881ff0b71102 151 void LCD::ClearScreen( void )
ttodorov 0:881ff0b71102 152 {
ttodorov 0:881ff0b71102 153 FillScreen( -1 );
ttodorov 0:881ff0b71102 154 }
ttodorov 0:881ff0b71102 155
ttodorov 0:881ff0b71102 156 void LCD::DrawPixel( unsigned short x, unsigned short y, int color )
ttodorov 0:881ff0b71102 157 {
ttodorov 4:3ac4239f6c9c 158 Activate();
ttodorov 2:81ed304b7e9b 159 SetXY( x, y, x, y );
ttodorov 10:69571adcfad5 160 SetPixelColor( color == -1 ? _background :
ttodorov 0:881ff0b71102 161 color == -2 ? _foreground : color );
ttodorov 4:3ac4239f6c9c 162 Deactivate();
ttodorov 0:881ff0b71102 163 }
ttodorov 0:881ff0b71102 164
ttodorov 0:881ff0b71102 165 void LCD::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
ttodorov 0:881ff0b71102 166 {
ttodorov 0:881ff0b71102 167
ttodorov 0:881ff0b71102 168 double delta, tx, ty;
ttodorov 0:881ff0b71102 169
ttodorov 0:881ff0b71102 170 if ( ( ( x2 - x1 ) < 0 ) )
ttodorov 0:881ff0b71102 171 {
ttodorov 0:881ff0b71102 172 swap( ushort, x1, x2 )
ttodorov 0:881ff0b71102 173 swap( ushort, y1, y2 )
ttodorov 0:881ff0b71102 174 }
ttodorov 0:881ff0b71102 175 if ( ( ( y2 - y1 ) < 0 ) )
ttodorov 0:881ff0b71102 176 {
ttodorov 0:881ff0b71102 177 swap( ushort, x1, x2 )
ttodorov 0:881ff0b71102 178 swap( ushort, y1, y2 )
ttodorov 0:881ff0b71102 179 }
ttodorov 0:881ff0b71102 180
ttodorov 0:881ff0b71102 181 if ( y1 == y2 )
ttodorov 0:881ff0b71102 182 {
ttodorov 0:881ff0b71102 183 if ( x1 > x2 )
ttodorov 0:881ff0b71102 184 swap( ushort, x1, x2 )
ttodorov 2:81ed304b7e9b 185 DrawHLine( x1, y1, x2 - x1, color );
ttodorov 0:881ff0b71102 186 }
ttodorov 0:881ff0b71102 187 else if ( x1 == x2 )
ttodorov 0:881ff0b71102 188 {
ttodorov 0:881ff0b71102 189 if ( y1 > y2 )
ttodorov 0:881ff0b71102 190 swap( ushort, y1, y2 )
ttodorov 2:81ed304b7e9b 191 DrawVLine( x1, y1, y2 - y1, color );
ttodorov 0:881ff0b71102 192 }
ttodorov 4:3ac4239f6c9c 193 else
ttodorov 0:881ff0b71102 194 {
ttodorov 12:d0978272a340 195 unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 4:3ac4239f6c9c 196 Activate();
ttodorov 4:3ac4239f6c9c 197 if ( abs( x2 - x1 ) > abs( y2 - y1 ) )
ttodorov 0:881ff0b71102 198 {
ttodorov 4:3ac4239f6c9c 199 delta = ( double( y2 - y1 ) / double( x2 - x1 ) );
ttodorov 4:3ac4239f6c9c 200 ty = double( y1 );
ttodorov 4:3ac4239f6c9c 201 if ( x1 > x2 )
ttodorov 0:881ff0b71102 202 {
ttodorov 4:3ac4239f6c9c 203 for ( int i = x1; i >= x2; i-- )
ttodorov 4:3ac4239f6c9c 204 {
ttodorov 4:3ac4239f6c9c 205 SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
ttodorov 10:69571adcfad5 206 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 207 ty = ty - delta;
ttodorov 4:3ac4239f6c9c 208 }
ttodorov 4:3ac4239f6c9c 209 }
ttodorov 4:3ac4239f6c9c 210 else
ttodorov 4:3ac4239f6c9c 211 {
ttodorov 4:3ac4239f6c9c 212 for ( int i = x1; i <= x2; i++ )
ttodorov 4:3ac4239f6c9c 213 {
ttodorov 4:3ac4239f6c9c 214 SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
ttodorov 10:69571adcfad5 215 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 216 ty = ty + delta;
ttodorov 4:3ac4239f6c9c 217 }
ttodorov 0:881ff0b71102 218 }
ttodorov 0:881ff0b71102 219 }
ttodorov 0:881ff0b71102 220 else
ttodorov 0:881ff0b71102 221 {
ttodorov 4:3ac4239f6c9c 222 delta = ( float( x2 - x1 ) / float( y2 - y1 ) );
ttodorov 4:3ac4239f6c9c 223 tx = float( x1 );
ttodorov 4:3ac4239f6c9c 224 if ( y1 > y2 )
ttodorov 0:881ff0b71102 225 {
ttodorov 4:3ac4239f6c9c 226 for ( int i = y2 + 1; i > y1; i-- )
ttodorov 4:3ac4239f6c9c 227 {
ttodorov 4:3ac4239f6c9c 228 SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
ttodorov 10:69571adcfad5 229 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 230 tx = tx + delta;
ttodorov 4:3ac4239f6c9c 231 }
ttodorov 4:3ac4239f6c9c 232 }
ttodorov 4:3ac4239f6c9c 233 else
ttodorov 4:3ac4239f6c9c 234 {
ttodorov 4:3ac4239f6c9c 235 for ( int i = y1; i < y2 + 1; i++ )
ttodorov 4:3ac4239f6c9c 236 {
ttodorov 4:3ac4239f6c9c 237 SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
ttodorov 10:69571adcfad5 238 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 239 tx = tx + delta;
ttodorov 4:3ac4239f6c9c 240 }
ttodorov 0:881ff0b71102 241 }
ttodorov 0:881ff0b71102 242 }
ttodorov 4:3ac4239f6c9c 243 Deactivate();
ttodorov 0:881ff0b71102 244 }
ttodorov 0:881ff0b71102 245 }
ttodorov 0:881ff0b71102 246
ttodorov 0:881ff0b71102 247 void LCD::DrawRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
ttodorov 0:881ff0b71102 248 {
ttodorov 0:881ff0b71102 249 if ( x1 > x2 ) swap( ushort, x1, x2 )
ttodorov 0:881ff0b71102 250 if ( y1 > y2 ) swap( ushort, y1, y2 )
ttodorov 0:881ff0b71102 251
ttodorov 2:81ed304b7e9b 252 DrawHLine( x1, y1, x2 - x1, color );
ttodorov 2:81ed304b7e9b 253 DrawHLine( x1, y2, x2 - x1, color );
ttodorov 2:81ed304b7e9b 254 DrawVLine( x1, y1, y2 - y1, color );
ttodorov 2:81ed304b7e9b 255 DrawVLine( x2, y1, y2 - y1, color );
ttodorov 0:881ff0b71102 256 }
ttodorov 0:881ff0b71102 257
ttodorov 0:881ff0b71102 258 void LCD::DrawRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
ttodorov 0:881ff0b71102 259 {
ttodorov 0:881ff0b71102 260 if ( x1 > x2 ) swap( ushort, x1, x2 )
ttodorov 0:881ff0b71102 261 if ( y1 > y2 ) swap( ushort, y1, y2 )
ttodorov 0:881ff0b71102 262
ttodorov 0:881ff0b71102 263 if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
ttodorov 0:881ff0b71102 264 {
ttodorov 0:881ff0b71102 265 DrawPixel( x1 + 1, y1 + 1, color );
ttodorov 0:881ff0b71102 266 DrawPixel( x2 - 1, y1 + 1, color );
ttodorov 0:881ff0b71102 267 DrawPixel( x1 + 1, y2 - 1, color );
ttodorov 0:881ff0b71102 268 DrawPixel( x2 - 1, y2 - 1, color );
ttodorov 2:81ed304b7e9b 269 DrawHLine( x1 + 2, y1, x2 - x1 - 4, color );
ttodorov 2:81ed304b7e9b 270 DrawHLine( x1 + 2, y2, x2 - x1 - 4, color );
ttodorov 2:81ed304b7e9b 271 DrawVLine( x1, y1 + 2, y2 - y1 - 4, color );
ttodorov 2:81ed304b7e9b 272 DrawVLine( x2, y1 + 2, y2 - y1 - 4, color );
ttodorov 0:881ff0b71102 273 }
ttodorov 0:881ff0b71102 274 }
ttodorov 0:881ff0b71102 275
ttodorov 0:881ff0b71102 276 void LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
ttodorov 0:881ff0b71102 277 {
ttodorov 0:881ff0b71102 278 if ( x1 > x2 ) swap( ushort, x1, x2 );
ttodorov 0:881ff0b71102 279 if ( y1 > y2 ) swap( ushort, y1, y2 );
ttodorov 0:881ff0b71102 280
ttodorov 12:d0978272a340 281 for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
ttodorov 0:881ff0b71102 282 {
ttodorov 12:d0978272a340 283 DrawHLine( x1, y1 + i, x2 - x1, color );
ttodorov 12:d0978272a340 284 DrawHLine( x1, y2 - i, x2 - x1, color );
ttodorov 0:881ff0b71102 285 }
ttodorov 0:881ff0b71102 286 }
ttodorov 0:881ff0b71102 287
ttodorov 0:881ff0b71102 288 void LCD::FillRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
ttodorov 0:881ff0b71102 289 {
ttodorov 0:881ff0b71102 290 if ( x1 > x2 ) swap( ushort, x1, x2 )
ttodorov 0:881ff0b71102 291 if ( y1 > y2 ) swap( ushort, y1, y2 )
ttodorov 0:881ff0b71102 292
ttodorov 0:881ff0b71102 293 if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
ttodorov 0:881ff0b71102 294 {
ttodorov 0:881ff0b71102 295 for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
ttodorov 0:881ff0b71102 296 {
ttodorov 0:881ff0b71102 297 switch ( i )
ttodorov 0:881ff0b71102 298 {
ttodorov 0:881ff0b71102 299 case 0:
ttodorov 2:81ed304b7e9b 300 DrawHLine( x1 + 2, y1 + i, x2 - x1 - 4, color );
ttodorov 2:81ed304b7e9b 301 DrawHLine( x1 + 2, y2 - i, x2 - x1 - 4, color );
ttodorov 0:881ff0b71102 302 break;
ttodorov 0:881ff0b71102 303
ttodorov 0:881ff0b71102 304 case 1:
ttodorov 2:81ed304b7e9b 305 DrawHLine( x1 + 1, y1 + i, x2 - x1 - 2, color );
ttodorov 2:81ed304b7e9b 306 DrawHLine( x1 + 1, y2 - i, x2 - x1 - 2, color );
ttodorov 0:881ff0b71102 307 break;
ttodorov 0:881ff0b71102 308
ttodorov 0:881ff0b71102 309 default:
ttodorov 2:81ed304b7e9b 310 DrawHLine( x1, y1 + i, x2 - x1, color );
ttodorov 2:81ed304b7e9b 311 DrawHLine( x1, y2 - i, x2 - x1, color );
ttodorov 0:881ff0b71102 312 break;
ttodorov 0:881ff0b71102 313 }
ttodorov 0:881ff0b71102 314 }
ttodorov 0:881ff0b71102 315 }
ttodorov 0:881ff0b71102 316 }
ttodorov 0:881ff0b71102 317
ttodorov 0:881ff0b71102 318 void LCD::DrawCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
ttodorov 0:881ff0b71102 319 {
ttodorov 0:881ff0b71102 320 int f = 1 - radius;
ttodorov 0:881ff0b71102 321 int ddF_x = 1;
ttodorov 0:881ff0b71102 322 int ddF_y = -2 * radius;
ttodorov 0:881ff0b71102 323 int x1 = 0;
ttodorov 0:881ff0b71102 324 int y1 = radius;
ttodorov 12:d0978272a340 325 unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 0:881ff0b71102 326
ttodorov 4:3ac4239f6c9c 327 Activate();
ttodorov 2:81ed304b7e9b 328 SetXY( x, y + radius, x, y + radius );
ttodorov 10:69571adcfad5 329 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 330 SetXY( x, y - radius, x, y - radius );
ttodorov 10:69571adcfad5 331 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 332 SetXY( x + radius, y, x + radius, y );
ttodorov 10:69571adcfad5 333 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 334 SetXY( x - radius, y, x - radius, y );
ttodorov 10:69571adcfad5 335 SetPixelColor( usedColor );
ttodorov 0:881ff0b71102 336
ttodorov 0:881ff0b71102 337 while ( x1 < y1 )
ttodorov 0:881ff0b71102 338 {
ttodorov 0:881ff0b71102 339 if ( f >= 0 )
ttodorov 0:881ff0b71102 340 {
ttodorov 0:881ff0b71102 341 y1--;
ttodorov 0:881ff0b71102 342 ddF_y += 2;
ttodorov 0:881ff0b71102 343 f += ddF_y;
ttodorov 0:881ff0b71102 344 }
ttodorov 0:881ff0b71102 345 x1++;
ttodorov 0:881ff0b71102 346 ddF_x += 2;
ttodorov 0:881ff0b71102 347 f += ddF_x;
ttodorov 2:81ed304b7e9b 348 SetXY( x + x1, y + y1, x + x1, y + y1 );
ttodorov 10:69571adcfad5 349 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 350 SetXY( x - x1, y + y1, x - x1, y + y1 );
ttodorov 10:69571adcfad5 351 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 352 SetXY( x + x1, y - y1, x + x1, y - y1 );
ttodorov 10:69571adcfad5 353 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 354 SetXY( x - x1, y - y1, x - x1, y - y1 );
ttodorov 10:69571adcfad5 355 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 356 SetXY( x + y1, y + x1, x + y1, y + x1 );
ttodorov 10:69571adcfad5 357 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 358 SetXY( x - y1, y + x1, x - y1, y + x1 );
ttodorov 10:69571adcfad5 359 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 360 SetXY( x + y1, y - x1, x + y1, y - x1 );
ttodorov 10:69571adcfad5 361 SetPixelColor( usedColor );
ttodorov 2:81ed304b7e9b 362 SetXY( x - y1, y - x1, x - y1, y - x1 );
ttodorov 10:69571adcfad5 363 SetPixelColor( usedColor );
ttodorov 0:881ff0b71102 364 }
ttodorov 4:3ac4239f6c9c 365 Deactivate();
ttodorov 0:881ff0b71102 366 }
ttodorov 0:881ff0b71102 367
ttodorov 0:881ff0b71102 368 void LCD::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
ttodorov 0:881ff0b71102 369 {
ttodorov 12:d0978272a340 370 unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 4:3ac4239f6c9c 371 Activate();
ttodorov 0:881ff0b71102 372 for ( int y1 = -radius; y1 <= radius; y1++ )
ttodorov 0:881ff0b71102 373 for ( int x1 = -radius; x1 <= radius; x1++ )
ttodorov 0:881ff0b71102 374 if ( x1 * x1 + y1 * y1 <= radius * radius )
ttodorov 0:881ff0b71102 375 {
ttodorov 2:81ed304b7e9b 376 SetXY( x + x1, y + y1, x + x1, y + y1 );
ttodorov 10:69571adcfad5 377 SetPixelColor( usedColor );
ttodorov 0:881ff0b71102 378 }
ttodorov 4:3ac4239f6c9c 379 Deactivate();
ttodorov 0:881ff0b71102 380 }
ttodorov 0:881ff0b71102 381
ttodorov 0:881ff0b71102 382 void LCD::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg )
ttodorov 0:881ff0b71102 383 {
ttodorov 0:881ff0b71102 384 int stl, i;
ttodorov 0:881ff0b71102 385
ttodorov 0:881ff0b71102 386 stl = strlen( str );
ttodorov 0:881ff0b71102 387
ttodorov 12:d0978272a340 388 if ( x == RIGHT )
ttodorov 21:e5c1e8ffada1 389 x = GetWidth() - ( stl * _font->Width );
ttodorov 12:d0978272a340 390 if ( x == CENTER )
ttodorov 21:e5c1e8ffada1 391 x = ( GetWidth() - ( stl * _font->Width ) ) / 2;
ttodorov 0:881ff0b71102 392
ttodorov 0:881ff0b71102 393 for ( i = 0; i < stl; i++ )
ttodorov 0:881ff0b71102 394 if ( deg == 0 )
ttodorov 21:e5c1e8ffada1 395 PrintChar( *str++, x + ( i * ( _font->Width ) ), y, fgColor, bgColor );
ttodorov 0:881ff0b71102 396 else
ttodorov 2:81ed304b7e9b 397 RotateChar( *str++, x, y, i, fgColor, bgColor, deg );
ttodorov 0:881ff0b71102 398 }
ttodorov 0:881ff0b71102 399
ttodorov 12:d0978272a340 400 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned char scale )
ttodorov 0:881ff0b71102 401 {
ttodorov 0:881ff0b71102 402 int tx, ty, tc, tsx, tsy;
ttodorov 0:881ff0b71102 403
ttodorov 4:3ac4239f6c9c 404 Activate();
ttodorov 0:881ff0b71102 405 if ( scale == 1 )
ttodorov 0:881ff0b71102 406 {
ttodorov 12:d0978272a340 407 SetXY( x, y, x + img->Width - 1, y + img->Height - 1 );
ttodorov 20:4bdca8d8dadc 408
ttodorov 13:5ceeba86bbe4 409 if ( img->Format == RGB16 )
ttodorov 0:881ff0b71102 410 {
ttodorov 13:5ceeba86bbe4 411 const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
ttodorov 20:4bdca8d8dadc 412 for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
ttodorov 20:4bdca8d8dadc 413 SetPixelColor( *pixel++, img->Format );
ttodorov 13:5ceeba86bbe4 414 }
ttodorov 13:5ceeba86bbe4 415 else if ( img->Format == RGB18 )
ttodorov 13:5ceeba86bbe4 416 {
ttodorov 13:5ceeba86bbe4 417 const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
ttodorov 20:4bdca8d8dadc 418 for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
ttodorov 20:4bdca8d8dadc 419 SetPixelColor( *pixel++, img->Format );
ttodorov 0:881ff0b71102 420 }
ttodorov 0:881ff0b71102 421 }
ttodorov 0:881ff0b71102 422 else
ttodorov 0:881ff0b71102 423 {
ttodorov 13:5ceeba86bbe4 424 if ( img->Format == RGB16 )
ttodorov 0:881ff0b71102 425 {
ttodorov 13:5ceeba86bbe4 426 const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
ttodorov 13:5ceeba86bbe4 427
ttodorov 13:5ceeba86bbe4 428 for ( ty = 0; ty < img->Height; ty++ )
ttodorov 13:5ceeba86bbe4 429 {
ttodorov 13:5ceeba86bbe4 430 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
ttodorov 13:5ceeba86bbe4 431 for ( tsy = 0; tsy < scale; tsy++ )
ttodorov 13:5ceeba86bbe4 432 {
ttodorov 13:5ceeba86bbe4 433 for ( tx = 0; tx < img->Width; tx++ )
ttodorov 13:5ceeba86bbe4 434 {
ttodorov 13:5ceeba86bbe4 435 for ( tsx = 0; tsx < scale; tsx++ )
ttodorov 20:4bdca8d8dadc 436 SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
ttodorov 20:4bdca8d8dadc 437 }
ttodorov 20:4bdca8d8dadc 438 }
ttodorov 20:4bdca8d8dadc 439 }
ttodorov 20:4bdca8d8dadc 440 }
ttodorov 20:4bdca8d8dadc 441 else if ( img->Format == RGB18 )
ttodorov 20:4bdca8d8dadc 442 {
ttodorov 20:4bdca8d8dadc 443 const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
ttodorov 20:4bdca8d8dadc 444
ttodorov 20:4bdca8d8dadc 445 for ( ty = 0; ty < img->Height; ty++ )
ttodorov 20:4bdca8d8dadc 446 {
ttodorov 20:4bdca8d8dadc 447 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
ttodorov 20:4bdca8d8dadc 448 for ( tsy = 0; tsy < scale; tsy++ )
ttodorov 20:4bdca8d8dadc 449 {
ttodorov 20:4bdca8d8dadc 450 for ( tx = 0; tx < img->Width; tx++ )
ttodorov 20:4bdca8d8dadc 451 {
ttodorov 20:4bdca8d8dadc 452 for ( tsx = 0; tsx < scale; tsx++ )
ttodorov 20:4bdca8d8dadc 453 SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
ttodorov 13:5ceeba86bbe4 454 }
ttodorov 13:5ceeba86bbe4 455 }
ttodorov 13:5ceeba86bbe4 456 }
ttodorov 13:5ceeba86bbe4 457 }
ttodorov 0:881ff0b71102 458 }
ttodorov 4:3ac4239f6c9c 459 Deactivate();
ttodorov 0:881ff0b71102 460 }
ttodorov 0:881ff0b71102 461
ttodorov 12:d0978272a340 462 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned short deg, unsigned short rox, unsigned short roy )
ttodorov 0:881ff0b71102 463 {
ttodorov 0:881ff0b71102 464 int tx, ty, newx, newy;
ttodorov 0:881ff0b71102 465 double radian;
ttodorov 0:881ff0b71102 466 radian = deg * 0.0175;
ttodorov 0:881ff0b71102 467
ttodorov 0:881ff0b71102 468 if ( deg == 0 )
ttodorov 12:d0978272a340 469 DrawBitmap( x, y, img );
ttodorov 0:881ff0b71102 470 else
ttodorov 0:881ff0b71102 471 {
ttodorov 4:3ac4239f6c9c 472 Activate();
ttodorov 13:5ceeba86bbe4 473
ttodorov 13:5ceeba86bbe4 474 if ( img->Format == RGB16 )
ttodorov 13:5ceeba86bbe4 475 {
ttodorov 13:5ceeba86bbe4 476 const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
ttodorov 13:5ceeba86bbe4 477
ttodorov 13:5ceeba86bbe4 478 for ( ty = 0; ty < img->Height; ty++ )
ttodorov 13:5ceeba86bbe4 479 for ( tx = 0; tx < img->Width; tx++ )
ttodorov 13:5ceeba86bbe4 480 {
ttodorov 13:5ceeba86bbe4 481 newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
ttodorov 13:5ceeba86bbe4 482 newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
ttodorov 13:5ceeba86bbe4 483
ttodorov 13:5ceeba86bbe4 484 SetXY( newx, newy, newx, newy );
ttodorov 20:4bdca8d8dadc 485 SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
ttodorov 13:5ceeba86bbe4 486 }
ttodorov 13:5ceeba86bbe4 487 }
ttodorov 13:5ceeba86bbe4 488 else if ( img->Format == RGB18 )
ttodorov 13:5ceeba86bbe4 489 {
ttodorov 13:5ceeba86bbe4 490 const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
ttodorov 13:5ceeba86bbe4 491
ttodorov 13:5ceeba86bbe4 492 for ( ty = 0; ty < img->Height; ty++ )
ttodorov 13:5ceeba86bbe4 493 for ( tx = 0; tx < img->Width; tx++ )
ttodorov 13:5ceeba86bbe4 494 {
ttodorov 13:5ceeba86bbe4 495 newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
ttodorov 13:5ceeba86bbe4 496 newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
ttodorov 13:5ceeba86bbe4 497
ttodorov 13:5ceeba86bbe4 498 SetXY( newx, newy, newx, newy );
ttodorov 20:4bdca8d8dadc 499 SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
ttodorov 13:5ceeba86bbe4 500 }
ttodorov 13:5ceeba86bbe4 501 }
ttodorov 4:3ac4239f6c9c 502 Deactivate();
ttodorov 0:881ff0b71102 503 }
ttodorov 4:3ac4239f6c9c 504 }
ttodorov 4:3ac4239f6c9c 505
ttodorov 4:3ac4239f6c9c 506 inline
ttodorov 4:3ac4239f6c9c 507 void LCD::Activate( void )
ttodorov 4:3ac4239f6c9c 508 {
ttodorov 4:3ac4239f6c9c 509 _lcd_pin_cs = LOW;
ttodorov 4:3ac4239f6c9c 510 }
ttodorov 4:3ac4239f6c9c 511
ttodorov 4:3ac4239f6c9c 512 inline
ttodorov 4:3ac4239f6c9c 513 void LCD::Deactivate( void )
ttodorov 4:3ac4239f6c9c 514 {
ttodorov 4:3ac4239f6c9c 515 _lcd_pin_cs = HIGH;
ttodorov 0:881ff0b71102 516 }
ttodorov 0:881ff0b71102 517
ttodorov 0:881ff0b71102 518 inline
ttodorov 2:81ed304b7e9b 519 void LCD::WriteCmdData( unsigned short cmd, unsigned short data )
ttodorov 0:881ff0b71102 520 {
ttodorov 2:81ed304b7e9b 521 WriteCmd( cmd );
ttodorov 2:81ed304b7e9b 522 WriteData( data );
ttodorov 0:881ff0b71102 523 }
ttodorov 0:881ff0b71102 524
ttodorov 12:d0978272a340 525 inline
ttodorov 12:d0978272a340 526 void LCD::ClearXY( void )
ttodorov 0:881ff0b71102 527 {
ttodorov 12:d0978272a340 528 SetXY( 0, 0, GetWidth() - 1, GetHeight() - 1 );
ttodorov 0:881ff0b71102 529 }
ttodorov 0:881ff0b71102 530
ttodorov 2:81ed304b7e9b 531 void LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
ttodorov 0:881ff0b71102 532 {
ttodorov 12:d0978272a340 533 unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 0:881ff0b71102 534
ttodorov 4:3ac4239f6c9c 535 Activate();
ttodorov 2:81ed304b7e9b 536 SetXY( x, y, x + len, y );
ttodorov 0:881ff0b71102 537 for ( int i = 0; i < len + 1; i++ )
ttodorov 10:69571adcfad5 538 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 539 Deactivate();
ttodorov 0:881ff0b71102 540 }
ttodorov 0:881ff0b71102 541
ttodorov 2:81ed304b7e9b 542 void LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
ttodorov 0:881ff0b71102 543 {
ttodorov 12:d0978272a340 544 unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
ttodorov 0:881ff0b71102 545
ttodorov 4:3ac4239f6c9c 546 Activate();
ttodorov 2:81ed304b7e9b 547 SetXY( x, y, x, y + len );
ttodorov 0:881ff0b71102 548 for ( int i = 0; i < len; i++ )
ttodorov 10:69571adcfad5 549 SetPixelColor( usedColor );
ttodorov 4:3ac4239f6c9c 550 Deactivate();
ttodorov 0:881ff0b71102 551 }
ttodorov 0:881ff0b71102 552
ttodorov 2:81ed304b7e9b 553 void LCD::PrintChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor )
ttodorov 0:881ff0b71102 554 {
ttodorov 0:881ff0b71102 555 uint8_t i, ch;
ttodorov 0:881ff0b71102 556 uint16_t j;
ttodorov 12:d0978272a340 557 unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
ttodorov 12:d0978272a340 558 unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
ttodorov 21:e5c1e8ffada1 559
ttodorov 21:e5c1e8ffada1 560 uint16_t totalCharBytes = ( _font->Width * _font->Height ) / 8;
ttodorov 21:e5c1e8ffada1 561 int16_t position = _font->Position[ c - _font->Offset ];
ttodorov 21:e5c1e8ffada1 562 if ( position == -1 ) position = 0; // will print space character
ttodorov 21:e5c1e8ffada1 563
ttodorov 4:3ac4239f6c9c 564 Activate();
ttodorov 0:881ff0b71102 565
ttodorov 21:e5c1e8ffada1 566 SetXY( x, y, x + _font->Width - 1, y + _font->Height - 1 );
ttodorov 21:e5c1e8ffada1 567
ttodorov 21:e5c1e8ffada1 568 for ( j = 0; j < totalCharBytes; j++ )
ttodorov 0:881ff0b71102 569 {
ttodorov 21:e5c1e8ffada1 570 ch = _font->Data[ position ];
ttodorov 12:d0978272a340 571 for ( i = 0; i < 8; i++ )
ttodorov 0:881ff0b71102 572 {
ttodorov 21:e5c1e8ffada1 573 if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
ttodorov 21:e5c1e8ffada1 574 else SetPixelColor( usedColorBG );
ttodorov 0:881ff0b71102 575 }
ttodorov 21:e5c1e8ffada1 576 position++;
ttodorov 0:881ff0b71102 577 }
ttodorov 4:3ac4239f6c9c 578 Deactivate();
ttodorov 0:881ff0b71102 579 }
ttodorov 0:881ff0b71102 580
ttodorov 2:81ed304b7e9b 581 void LCD::RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg )
ttodorov 0:881ff0b71102 582 {
ttodorov 0:881ff0b71102 583 uint8_t i, j, ch;
ttodorov 0:881ff0b71102 584 int newx, newy;
ttodorov 0:881ff0b71102 585 double radian;
ttodorov 0:881ff0b71102 586 radian = deg * 0.0175;
ttodorov 0:881ff0b71102 587
ttodorov 12:d0978272a340 588 unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
ttodorov 12:d0978272a340 589 unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
ttodorov 0:881ff0b71102 590
ttodorov 21:e5c1e8ffada1 591 int16_t position = _font->Position[ c - _font->Offset ];
ttodorov 21:e5c1e8ffada1 592 if ( position == -1 ) position = 0; // will print space character
ttodorov 21:e5c1e8ffada1 593
ttodorov 4:3ac4239f6c9c 594 Activate();
ttodorov 21:e5c1e8ffada1 595
ttodorov 21:e5c1e8ffada1 596 for ( j = 0; j < _font->Height; j++ )
ttodorov 0:881ff0b71102 597 {
ttodorov 21:e5c1e8ffada1 598 for ( uint16_t zz = 0; zz < ( ( double ) _font->Width / 8 ); zz++ )
ttodorov 0:881ff0b71102 599 {
ttodorov 21:e5c1e8ffada1 600 ch = _font->Data[ position + zz ];
ttodorov 0:881ff0b71102 601 for ( i = 0; i < 8; i++ )
ttodorov 0:881ff0b71102 602 {
ttodorov 21:e5c1e8ffada1 603 newx = x + ( ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * cos( radian ) ) - ( ( j ) * sin( radian ) ) );
ttodorov 21:e5c1e8ffada1 604 newy = y + ( ( ( j ) * cos( radian ) ) + ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * sin( radian ) ) );
ttodorov 0:881ff0b71102 605
ttodorov 2:81ed304b7e9b 606 SetXY( newx, newy, newx + 1, newy + 1 );
ttodorov 0:881ff0b71102 607
ttodorov 21:e5c1e8ffada1 608 if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
ttodorov 21:e5c1e8ffada1 609 else SetPixelColor( usedColorBG );
ttodorov 0:881ff0b71102 610 }
ttodorov 0:881ff0b71102 611 }
ttodorov 21:e5c1e8ffada1 612 position += ( _font->Width / 8 );
ttodorov 0:881ff0b71102 613 }
ttodorov 21:e5c1e8ffada1 614
ttodorov 4:3ac4239f6c9c 615 Deactivate();
ttodorov 0:881ff0b71102 616 }