Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Revision:
190:3132b7dfad82
Parent:
186:910fc2335c45
Child:
191:0fad2e45e196
--- a/RA8875.h	Thu Sep 19 21:45:18 2019 +0000
+++ b/RA8875.h	Sat Sep 21 17:30:00 2019 +0000
@@ -2,51 +2,51 @@
 /// @mainpage RA8875 Display Controller Driver library
 ///
 /// The RA8875 Display controller is a powerful interface for low cost displays. It
-/// can support displays up to 800 x 480 pixels x 16-bit color. 
+/// can support displays up to 800 x 480 pixels x 16-bit color.
 ///
 /// @image html Example_Program.png "Image of an Example Program"
 ///
-/// Aside from 800 x 480 pixel displays, another common implementation is 
-/// 480 x 272 x 16 with two layers. The two layers can be exchanged, or blended 
-/// in various ways (transparency, OR, AND, and more). It includes graphics 
-/// acceleration capabilities for drawing primitives, such as line, rectangle, 
+/// Aside from 800 x 480 pixel displays, another common implementation is
+/// 480 x 272 x 16 with two layers. The two layers can be exchanged, or blended
+/// in various ways (transparency, OR, AND, and more). It includes graphics
+/// acceleration capabilities for drawing primitives, such as line, rectangle,
 /// circles, and more.
 ///
-/// It is not a display for video-speed animations, and maybe could hold its own 
-/// as a slow picture frame, at least when using the SPI ports. How the performance 
+/// It is not a display for video-speed animations, and maybe could hold its own
+/// as a slow picture frame, at least when using the SPI ports. How the performance
 /// differs using I2C, 8-bit parallel or 16-bit parallel has not been evaluated.
 /// Certainly the parallel interface option would be expected to be a lot faster.
 ///
 /// What it is good at is performing as a basic display for appliance or simple
-/// home automation, and because of the built-in capability to draw lines, circles, 
-/// ellipses, rectangles, rounded rectangles, and triangles, it does a lot of the 
+/// home automation, and because of the built-in capability to draw lines, circles,
+/// ellipses, rectangles, rounded rectangles, and triangles, it does a lot of the
 /// work that your host micro would otherwise be doing, and in many cases it does
 /// it much faster.
 ///
 /// While it is good to know about Bresenham's algorithm (to draw a line) and how
-/// to implement it in software, this controller simplifies things - 
-/// You just give it (x1,y1), (x2,y2) and tell it to draw a line. 
+/// to implement it in software, this controller simplifies things -
+/// You just give it (x1,y1), (x2,y2) and tell it to draw a line.
 /// Without the hardware acceleration built into the RA8875, the host would have to
 /// compute every point, set the graphics cursor to that point, and fill in that
 /// point with the target color. A diagonal line of some length might take 100
-/// interactions instead of just a few. Other drawing primitives are similarly easy. 
+/// interactions instead of just a few. Other drawing primitives are similarly easy.
 ///
-/// It has some built-in fonts, which can be enhanced with optional font-chips, and 
+/// It has some built-in fonts, which can be enhanced with optional font-chips, and
 /// with the provided software font engine, and a few instructions, you can convert
-/// most any True Type Font into the data structures suitable for this display. 
+/// most any True Type Font into the data structures suitable for this display.
 ///
 /// To round out the features, this library offers the ability to render Bitmap (BMP),
-/// Icon (ICO), Join Photographic Experts Group (JPG), and Graphics Interchange Format 
-/// (GIF) images. These are implemented primarily in software, taking advantage of the 
-/// hardware acceleration where it can. 
+/// Icon (ICO), Join Photographic Experts Group (JPG), and Graphics Interchange Format
+/// (GIF) images. These are implemented primarily in software, taking advantage of the
+/// hardware acceleration where it can.
 ///
-/// When you are satisfied with what appears on screen, there is a PrintScreen method 
+/// When you are satisfied with what appears on screen, there is a PrintScreen method
 /// to pull that image back out and write it to a file system as a BitMap image.
 ///
 /// The controller additionally supports backlight control (via PWM), keypad scanning
 /// (for a 4 x 5 matrix) and resistive touch-panel support. Support for capacitive
 /// touch screens is also integrated, in a manner that makes the resistive and
-/// capacitive interfaces nearly API identical. The capacitive touch support is for 
+/// capacitive interfaces nearly API identical. The capacitive touch support is for
 /// either the FT5206 or the GSL1680 controller chips.
 ///
 /// Here's a few hints to get started:
@@ -66,19 +66,19 @@
 ///     was within main(), then it seemed to work as expected.
 ///
 /// @note As the author of this library, let me state that I am not affiliated with
-///     Raio (silicon provider of the RA8875), or with BuyDisplay.com (where a lot 
-///     of these displays can be purchased), I am simply a very satisfied customer 
+///     Raio (silicon provider of the RA8875), or with BuyDisplay.com (where a lot
+///     of these displays can be purchased), I am simply a very satisfied customer
 ///     of the technology of the RA8875 chip.
 ///
 /// @copyright Copyright © 2012-2019 by Smartware Computing, all rights reserved.
 ///     This library is predominantly, that of Smartware Computing, however some
-///     portions are compiled from the work of others. Where the contribution of 
-///     others was listed as copyright, that copyright is maintained, even as a 
+///     portions are compiled from the work of others. Where the contribution of
+///     others was listed as copyright, that copyright is maintained, even as a
 ///     derivative work may have been created for better integration in this library.
 ///     See @ref Copyright_References.
 ///
 /// @page Copyright_References Copyright References
-/// 
+///
 /// Following are links to the known copyright references. If I overlooked any, it was
 /// unintentional - please let me know so I can update it. Some portions of the code
 /// have been acquired from the cloud, and where any copyright information was available,
@@ -99,12 +99,12 @@
 ///
 /// During the instantiation, the display is powered on, cleared, and the backlight
 /// is energized. Additionally, the keypad and touchscreen features are activated.
-/// It is important to keep in mind that the keypad has its default mapping, 
-/// a resistive touchscreen does not yet have the calibration matrix configured, 
+/// It is important to keep in mind that the keypad has its default mapping,
+/// a resistive touchscreen does not yet have the calibration matrix configured,
 /// and the RA8875::init() function is required to configure other important options
 /// like the display resolution.
-/// 
-/// @code 
+///
+/// @code
 /// RA8875 lcd(p5, p6, p7, p12, NC, "tft");
 /// lcd.init();
 /// lcd.foreground(Blue);
@@ -119,7 +119,7 @@
 /// * 800 x 480 pixels
 ///
 /// @subsection RA8875_Layers Display Layers
-/// The RA8875 Controller, depending on the resolution and color depth, can support 
+/// The RA8875 Controller, depending on the resolution and color depth, can support
 /// multiple display layers.
 ///
 /// * 1 Layer - when the color depth is 16 bits per pixel
@@ -130,16 +130,16 @@
 /// @page Touch_Panel Touch Panel
 ///
 /// There is support for various touch panel interfaces.
-/// * @ref Resistive_Touch_Panel - native control for a resistive touch panel. 
+/// * @ref Resistive_Touch_Panel - native control for a resistive touch panel.
 ///     There are a few steps to enable this interface.
 ///
 /// For the Capacitive Touch controllers, an I2C interface is required.
 ///
 /// @image html RA8875_Touch.png "Schematic Representation of the Touch Interface"
 ///
-/// * @ref CapSense_FT5206 - FT5206 capacitive touch controller, integrated in 
+/// * @ref CapSense_FT5206 - FT5206 capacitive touch controller, integrated in
 ///     several popular RA8875-based displays. See @ref Capacitive_Touch_Panel.
-/// * @ref CapSense_GSL1680 - GSL1680 capacitive touch controller, integrated in 
+/// * @ref CapSense_GSL1680 - GSL1680 capacitive touch controller, integrated in
 ///     several popular RA8875-based displays. See @ref Capacitive_Touch_Panel.
 ///
 /// @page MicroSD_Interface Micro SD Interface
@@ -155,7 +155,7 @@
 ///
 /// The RA8875 controller supports a hardwired matrix of keys, which can be used to
 /// easily monitor for up to 20 keys (4 x 5 matrix). It is quite flexible, so these
-/// could be a set of independent functions, or they could be wired as a simple 
+/// could be a set of independent functions, or they could be wired as a simple
 /// calculator or telephone style of keypad.
 ///
 /// @image html RA8875_Keypad.png "Schematic Representation of the Keypad Interface"
@@ -167,19 +167,19 @@
 /// @page Resistive_Touch_Panel Resistive Touch Panel
 ///
 /// The RA8875 controller supports a native resistive touchscreen interface than can
-/// track a single touch-point. 
+/// track a single touch-point.
 ///
 /// If your display has this option, you can easily accept touch input, but it comes with
 /// some additional requirements - calibration being the primary concern.
 ///
 /// @section Touch_Panel_Enable Touch Panel Enable
 ///
-/// @ref RA8875::TouchPanelInit() has two forms - one fully automatic, and more controlled. 
+/// @ref RA8875::TouchPanelInit() has two forms - one fully automatic, and more controlled.
 /// See the APIs for details.
 ///
 /// @section Touch_Panel_Calibration
-/// 
-/// The touch panel is not initially calibrated on startup. The application should 
+///
+/// The touch panel is not initially calibrated on startup. The application should
 /// provide a means to activate the calibration process, and that should not require
 /// the touchscreen as it may not yet be usable. Alternately, a calibration matrix
 /// can be loaded from non-volatile and installed.
@@ -192,7 +192,7 @@
 ///
 /// * @ref CapSense_FT5206.
 /// * @ref CapSense_GSL1680.
-/// 
+///
 /// @page CapSense_FT5206 Capacitive Sense - FT5206 Controller
 ///
 /// This is the more common controller. It supports up to 5 simultaneous touch point
@@ -215,7 +215,7 @@
 /// #include "mbed.h"       // Working: v146, not fully working: v147
 /// #include "RA8875.h"     // Working: v149
 /// RA8875 lcd(p5, p6, p7, p12, NC, "tft");
-///  
+///
 /// int main()
 /// {
 ///     lcd.init(480,272,16,100);
@@ -231,7 +231,7 @@
 ///     lcd.roundrect(    410,160, 475,190, 10,8,    Yellow);
 ///     lcd.fillroundrect(415,165, 470,185,  5,3,    Orange);
 ///     lcd.line(         430,200, 460,230,          RGB(0,255,0));
-///     for (int i=0; i<=30; i+=5) 
+///     for (int i=0; i<=30; i+=5)
 ///         lcd.pixel(435+i,200+i, White);
 /// }
 /// @endcode
@@ -240,15 +240,15 @@
 
 /// @page Wiring_Diagram Example Wiring Diagram
 ///
-/// This library was crafted around the 4-Wire SPI interface. This was the chosen 
-/// interface method in order to balance the requirements of the host micro IO with 
+/// This library was crafted around the 4-Wire SPI interface. This was the chosen
+/// interface method in order to balance the requirements of the host micro IO with
 /// the capability of this display. Alternatives include: 3-Wire SPI, I2C, 8-bit and
 /// 16-bit parallel.
-/// 
-/// @section Schematic_Basic Basic Schematic 
+///
+/// @section Schematic_Basic Basic Schematic
 ///
 /// The basic schematic should be the most portable to any system that has SPI support.
-/// 
+///
 /// @image html RA8875_display_schematic.png "Basic Display support"
 ///
 /// @section Schematic_DisplayTouch Display with Capacitive Touch
@@ -260,23 +260,23 @@
 ///
 /// @section Schematic_DisplayTouchMicroSD Display with Capacitive Touch and micro SD
 ///
-/// The most advanced schematic - taking advantage of the display, the capacitive touch 
-/// controller, and the peripheral support for a micro SD card on some of the display 
+/// The most advanced schematic - taking advantage of the display, the capacitive touch
+/// controller, and the peripheral support for a micro SD card on some of the display
 /// modules.
 ///
 /// @note There are online indications that the RA8875 has a defect in its SPI interface
 ///         where it will not release the MISO pin. If this pin is shared with the micro SD
-///         port, then it could interfere with successful read/write of the files.  
+///         port, then it could interfere with successful read/write of the files.
 ///         The easiest solution is to put that interface on a separate SPI port.
 ///
 /// @image html RA8875_display_full.png "Display, Touch, and micro SD support"
 ///
 /// @page External_Resources External Resources
 ///
-/// There are many websites with information on the RA8875 Display. This partial list 
+/// There are many websites with information on the RA8875 Display. This partial list
 /// may be helpful:
 ///
-/// * <a href="https://os.mbed.com/components/RA8875-Based-Display/">RA8875 Library</a> 
+/// * <a href="https://os.mbed.com/components/RA8875-Based-Display/">RA8875 Library</a>
 ///     on the <a href="https://os.mbed.com/">mbed site</a><br/>
 ///     This page has **a lot** of detail, schematices, sample programs, instructions to
 ///     create your own fonts, and more...
@@ -326,14 +326,14 @@
 ///     - @ref RA8875::window()
 ///     - @ref RA8875::WindowMax()
 ///
-/// - Change the title-case of the functions to be consistent. Because this was adapted 
+/// - Change the title-case of the functions to be consistent. Because this was adapted
 ///     from parts of several different libraries, it isn't very consistently titled.
 ///
-/// - Change names of some of the functions to be more consistent. Why are some Set* 
+/// - Change names of some of the functions to be more consistent. Why are some Set*
 ///     and others are Select*. The layer commands SetDrawingLayer and GetDrawingLayer do
 ///     not need 'Drawing' in them.
 ///
-/// - Improve the PrintScreen method. There are two functions - one that accepts a filename, 
+/// - Improve the PrintScreen method. There are two functions - one that accepts a filename,
 ///     and a second more experimental version that could pipe the image stream back to
 ///     a calling process. This could be used, for example, to send the image over a
 ///     network interface. The intended side effect is that there is then only a single
@@ -342,14 +342,14 @@
 ///
 /// - Add support for the hardware reset pin
 ///
-/// - Figure out how to "init()" in the constructor when it is not in main(). I ran into 
-///        some issues if the display was instantiated before main(), and the code would not 
-///        run, thus the exposure and activation of the init() function. If the instantiation 
-///        is within main(), then it seemed to work as expected. 
+/// - Figure out how to "init()" in the constructor when it is not in main(). I ran into
+///        some issues if the display was instantiated before main(), and the code would not
+///        run, thus the exposure and activation of the init() function. If the instantiation
+///        is within main(), then it seemed to work as expected.
 ///
-/// - Add Scroll support for text. 
+/// - Add Scroll support for text.
 ///
-/// - Add high level objects - x-y graph, meter, buttons, ... but these will probably be 
+/// - Add high level objects - x-y graph, meter, buttons, ... but these will probably be
 ///        best served in another class, since they may not be needed for many uses.
 ///
 #ifndef RA8875_H
@@ -381,10 +381,10 @@
 /// @page PredefinedColors Predefined Colors
 ///
 /// Keep in mind that the color scheme shown here is unlikely to precisely match
-/// that on the actual display. The perceived color is additional affected by 
+/// that on the actual display. The perceived color is additional affected by
 /// other attributes, such as the backlight brightness.
 ///
-/// These are the predefined colors that are typically used where any @ref color_t 
+/// These are the predefined colors that are typically used where any @ref color_t
 /// variable is applied.
 ///
 /// <blockquote>
@@ -498,7 +498,7 @@
 ///     lcd.roundrect(    410,160, 475,190, 10,8,    Yellow);
 ///     lcd.fillroundrect(415,165, 470,185,  5,3,    Orange);
 ///     lcd.line(         430,200, 460,230,          RGB(0,255,0));
-///     for (int i=0; i<=30; i+=5) 
+///     for (int i=0; i<=30; i+=5)
 ///         lcd.pixel(435+i,200+i, White);
 /// }
 /// @endcode
@@ -508,10 +508,26 @@
 /// @todo Add high level objects - x-y graph, meter, others... but these will
 ///     probably be best served in another class, since they may not
 ///     be needed for many uses.
-/// 
+///
 class RA8875 : public GraphicsDisplay
 {
-public:   
+public:
+    /// Vertical alignment attribute. Used to align one rect against another.
+    /// @ref AlignRectInRect
+    typedef enum {
+        top,            ///< vertically align to the top
+        middle,         ///< vertically align to the middle
+        bottom          ///< vertically align to the bottom
+    } valign_t;
+
+    /// Horizontal alignment attribute. Used to align one rect against another.
+    /// @ref AlignRectInRect
+    typedef enum {
+        left,           ///< horizontally align to the left
+        center,         ///< horizontally align to the center
+        right           ///< horizontally align to the right
+    } halign_t;
+
     /// cursor type argument for @ref SetTextCursorControl()
     typedef enum
     {
@@ -529,7 +545,7 @@
         ISO8859_3,      ///< ISO8859-3 font
         ISO8859_4       ///< ISO8859-4 font
     } font_t;
-    
+
     /// display orientation argument for @ref SetOrientation()
     /// with landscape mode as the normal (0 degree) orientation.
     typedef enum
@@ -540,17 +556,17 @@
         rotate_180,     ///< rotated (clockwise) 180 degree
         rotate_270,     ///< rotated clockwise 270 degree
     } orientation_t;
-    
+
     /// alignment control argument for @ref SetTextFontControl()
     typedef enum
     {
         align_none,     ///< align - none
         align_full      ///< align - full
-    } alignment_t;    
-    
+    } alignment_t;
+
     /// Font Horizontal Scale factor - 1, 2, 3 4 for @ref SetTextFontSize(), @ref GetTextFontSize()
     typedef int HorizontalScale;
-    
+
     /// Font Vertical Scale factor - 1, 2, 3, 4 for @ref SetTextFontSize(), @ref GetTextFontSize()
     typedef int VerticalScale;
 
@@ -572,7 +588,7 @@
         BooleanAND,         ///< Boolean AND mode
         FloatingWindow      ///< Floating Window mode
     } LayerMode_T;
-    
+
     /// Touch Panel modes
     typedef enum
     {
@@ -590,7 +606,7 @@
 
     /// print screen callback
     ///
-    /// The special form of the print screen will pass one blob at a time 
+    /// The special form of the print screen will pass one blob at a time
     /// to the callback. There are basic commands declaring that the stream
     /// can be opened, a block written, and the stream closed. There is
     /// also a command to communicate the total size being delivered.
@@ -600,7 +616,7 @@
     ///
     /// @code
     /// lcd.PrintScreen(x,y,w,h,callback);
-    /// ... 
+    /// ...
     /// void callback(filecmd_t cmd, uint8_t * buffer, uint16_t size) {
     ///     switch(cmd) {
     ///         case OPEN:
@@ -626,7 +642,7 @@
     /// @returns @ref RetCode_t value.
     ///
     typedef RetCode_t (* PrintCallback_T)(filecmd_t cmd, uint8_t * buffer, uint16_t size);
-    
+
     /// Idle reason provided in the Idle Callback @ref IdleCallback_T()
     typedef enum {
         unknown,            ///< reason has not been assigned (this should not happen)
@@ -637,10 +653,10 @@
         touchcal_wait,      ///< driver is performing a touch calibration
         progress,           ///< communicates progress
     } IdleReason_T;
-    
-    /// Idle Callback 
-    ///
-    /// This defines the interface for an idle callback. That is, when the 
+
+    /// Idle Callback
+    ///
+    /// This defines the interface for an idle callback. That is, when the
     /// driver is held up, pending some event, it can call a previously registered
     /// idle function. This could be most useful for servicing a watchdog.
     ///
@@ -669,16 +685,16 @@
     ///        for 'progress' reason code, param ranges from 0 to 100 (percent)
     /// @returns @ref RetCode_t value.
     ///
-    typedef RetCode_t (* IdleCallback_T)(IdleReason_T reason, uint16_t param = 0);
-
-    /// Basic constructor for a display based on the RAiO RA8875 
+    typedef RetCode_t (* IdleCallback_T)(IdleReason_T reason, uint16_t param);
+
+    /// Basic constructor for a display based on the RAiO RA8875
     /// display controller, which can be used with no touchscreen,
     /// or the RA8875 managed resistive touchscreen.
     ///
     /// This constructor differs from the alternate by supportting
     /// either No Touch Screen, or the RA8875 built-in resistive
     /// touch screen. If the application requires the use of the
-    /// capacitive touchscreen, the alternate constructor must 
+    /// capacitive touchscreen, the alternate constructor must
     /// be used.
     ///
     /// This configures the registers and calls the @ref init method.
@@ -700,23 +716,23 @@
     /// @param[in] sclk is the SPI shift clock pin on the mbed.
     /// @param[in] csel is the DigitalOut pin on the mbed to use as the
     ///         active low chip select for the display controller.
-    /// @param[in] reset is the DigitalOut pin on the mbed to use as the 
-    ///         active low reset input on the display controller - 
+    /// @param[in] reset is the DigitalOut pin on the mbed to use as the
+    ///         active low reset input on the display controller -
     ///         but this is not currently used.
     /// @param[in] name is a text name for this object, which will permit
     ///         capturing stdout to puts() and printf() directly to it.
     ///
-    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, 
+    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
         const char * name = "lcd");
-    
-    
-    /// Constructor for a display based on the RAiO RA8875 display controller 
+
+
+    /// Constructor for a display based on the RAiO RA8875 display controller
     /// (using the FT5206 Capacitive TouchScreen Controller)
     ///
     /// @code
     /// #include "RA8875.h"
     /// RA8875 lcd(p5, p6, p7, p12, NC, p9,p10,p13, "tft");
-    /// 
+    ///
     /// int main()
     /// {
     ///     lcd.init();
@@ -733,8 +749,8 @@
     /// @param[in] sclk is the SPI shift clock pin on the mbed.
     /// @param[in] csel is the DigitalOut pin on the mbed to use as the
     ///         active low chip select for the display controller.
-    /// @param[in] reset is the DigitalOut pin on the mbed to use as the 
-    ///         active low reset input on the display controller - 
+    /// @param[in] reset is the DigitalOut pin on the mbed to use as the
+    ///         active low reset input on the display controller -
     ///         but this is not currently used.
     /// @param[in] sda is the I2C Serial Data pin you are wiring to the FT5206.
     /// @param[in] scl is the I2C Serial Clock pin you are wiring to the FT5206.
@@ -742,17 +758,17 @@
     /// @param[in] name is a text name for this object, which will permit
     ///         capturing stdout to puts() and printf() directly to it.
     ///
-    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, 
+    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
         PinName sda, PinName scl, PinName irq, const char * name = "lcd");
- 
-    
-    /// Constructor for a display based on the RAiO RA8875 display controller 
+
+
+    /// Constructor for a display based on the RAiO RA8875 display controller
     /// (using the GSL1680 Capacitive TouchScreen Controller)
     ///
     /// @code
     /// #include "RA8875.h"
     /// RA8875 lcd(p5, p6, p7, p12, NC, p9,p10,p13,p14, "tft");
-    /// 
+    ///
     /// int main()
     /// {
     ///     lcd.init();
@@ -769,8 +785,8 @@
     /// @param[in] sclk is the SPI shift clock pin on the mbed.
     /// @param[in] csel is the DigitalOut pin on the mbed to use as the
     ///         active low chip select for the display controller.
-    /// @param[in] reset is the DigitalOut pin on the mbed to use as the 
-    ///         active low reset input on the display controller - 
+    /// @param[in] reset is the DigitalOut pin on the mbed to use as the
+    ///         active low reset input on the display controller -
     ///         but this is not currently used.
     /// @param[in] sda is the I2C Serial Data pin you are wiring to the GSL1680.
     /// @param[in] scl is the I2C Serial Clock pin you are wiring to the GSL1680.
@@ -779,19 +795,19 @@
     /// @param[in] name is a text name for this object, which will permit
     ///         capturing stdout to puts() and printf() directly to it.
     ///
-    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, 
+    RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset,
         PinName sda, PinName scl, PinName wake, PinName irq, const char * name = "lcd");
- 
-    
+
+
     // Destructor doesn't have much to do as this would typically be created
     // at startup, and not at runtime.
     //~RA8875();
-    
+
     /// Initialize the driver.
     ///
-    /// The RA8875 can control typical displays from the 480x272 to 800x480, and it supports 8 or 16-bit color. 
-    /// It also supports 2 graphics layers, but it cannot support 2 layers at the maximum color depth and 
-    /// screen size. When configured under 480x400, it will support both 16-bit color depth and 2 drawing layers. 
+    /// The RA8875 can control typical displays from the 480x272 to 800x480, and it supports 8 or 16-bit color.
+    /// It also supports 2 graphics layers, but it cannot support 2 layers at the maximum color depth and
+    /// screen size. When configured under 480x400, it will support both 16-bit color depth and 2 drawing layers.
     /// Above 480x400 it support either 16-bit color, or 2 layers, but not both.
     ///
     /// Typical of the displays that are readily purchased, you will find 480x272 and 800x480 resolutions.
@@ -810,15 +826,15 @@
     ///             required for full brightness). See @ref Power.
     /// @param[in] keypadon defines if the keypad support should be enabled. This parameter is optional
     ///             and the default is true (enabled). See @ref KeypadInit.
-    /// @param[in] touchscreeenon defines if the touchscreen support should be enabled. 
+    /// @param[in] touchscreeenon defines if the touchscreen support should be enabled.
     ///             This parameter is optional and the default is true (enabled). See @ref TouchPanelInit.
-    ///             - If the constructor was called with support for the capacitive driver, this 
+    ///             - If the constructor was called with support for the capacitive driver, this
     ///             parameter causes the driver to initialize.
     ///             - If the constructor was called without support for the capacitive driver, this
     ///             parameter is used to enable and initialize the resistive touchscreen driver.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t init(int width = 480, int height = 272, int color_bpp = 16, 
+    RetCode_t init(int width = 480, int height = 272, int color_bpp = 16,
         uint8_t poweron = 40, bool keypadon = true, bool touchscreeenon = true);
 
 
@@ -832,12 +848,12 @@
     ///     is not a valid value, then it returns the text for bad_parameter;
     ///
     const char * GetErrorMessage(RetCode_t code);
-    
-    
+
+
     /// Select the drawing layer for subsequent commands.
     ///
-    /// If the screen configuration is 480 x 272, or if it is 800 x 480 
-    /// and 8-bit color, the the display supports two layers, which can 
+    /// If the screen configuration is 480 x 272, or if it is 800 x 480
+    /// and 8-bit color, the the display supports two layers, which can
     /// be independently drawn on and shown. Additionally, complex
     /// operations involving both layers are permitted.
     ///
@@ -858,7 +874,7 @@
     ///     others that reference the layers use the values 0 and 1 for
     ///     cleaner iteration in the code.
     ///
-    /// @param[in] layer is 0 or 1 to select the layer for subsequent 
+    /// @param[in] layer is 0 or 1 to select the layer for subsequent
     ///     commands.
     /// @param[out] prevLayer is an optiona pointer to where the previous layer
     ///     will be written, making it a little easer to restore layers.
@@ -866,8 +882,8 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t SelectDrawingLayer(uint16_t layer, uint16_t * prevLayer = NULL);
- 
-    
+
+
     /// Get the currently active drawing layer.
     ///
     /// This returns a value, 0 or 1, based on the screen configuration
@@ -886,10 +902,10 @@
     ///     cleaner iteration in the code.
     ///
     /// @returns the current drawing layer; 0 or 1.
-    /// 
+    ///
     virtual uint16_t GetDrawingLayer(void);
- 
-    
+
+
     /// Set the Layer presentation mode.
     ///
     /// This sets the presentation mode for layers, and permits showing
@@ -911,8 +927,8 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t SetLayerMode(LayerMode_T mode);
- 
-    
+
+
     /// Get the Layer presentation mode.
     ///
     /// This gets the current layer mode. See @ref LayerMode_T.
@@ -920,8 +936,8 @@
     /// @returns layer mode.
     ///
     LayerMode_T GetLayerMode(void);
- 
-    
+
+
     /// Set the layer transparency for each layer.
     ///
     /// Set the transparency, where the range of values is
@@ -940,22 +956,22 @@
     /// @param[in] layer1 sets the layer 1 transparency.
     /// @param[in] layer2 sets the layer 2 transparency.
     /// @returns @ref RetCode_t value.
-    /// 
+    ///
     RetCode_t SetLayerTransparency(uint8_t layer1, uint8_t layer2);
- 
-    
+
+
     /// Set the background color register used for transparency.
     ///
     /// This command sets the background color registers that are used
     /// in the transparent color operations involving the layers.
-    /// 
+    ///
     /// @param[in] color is optional and expressed in 16-bit format. If not
     ///     supplied, a default of Black is used.
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t SetBackgroundTransparencyColor(color_t color = RGB(0,0,0));
- 
- 
+
+
     /// Get the background color value used for transparency.
     ///
     /// This command reads the background color registers that define
@@ -964,9 +980,9 @@
     /// @returns the color.
     ///
     color_t GetBackgroundTransparencyColor(void);
- 
- 
-    /// Initialize theTouch Panel controller with default values 
+
+
+    /// Initialize theTouch Panel controller with default values
     ///
     /// This activates the simplified touch panel init, which may work for
     /// most uses. The alternate API is available if fine-grained control
@@ -978,8 +994,8 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t TouchPanelInit(void);
-        
- 
+
+
     /// Initialize the Touch Panel controller with detailed settings.
     ///
     /// This is the detailed touch panel init, which provides the ability
@@ -996,44 +1012,44 @@
     ///                                 - TP_MODE_MANUAL: manual capture
     /// @param[in]  bTpDebounce         Debounce circuit enable for touch panel interrupt:
     ///                                 - TP_DEBOUNCE_OFF: disable the debounce circuit
-    ///                                 - TP_DEBOUNCE_ON: enable the debounce circuit     
+    ///                                 - TP_DEBOUNCE_ON: enable the debounce circuit
     /// @param[in]  bTpManualMode       When Manual Mode is selected, this sets the mode:
-    ///                                 - TP_MANUAL_IDLE: touch panel is idle   
-    ///                                 - TP_MANUAL_WAIT: wait for touch panel event   
-    ///                                 - TP_MANUAL_LATCH_X: latch X data  
-    ///                                 - TP_MANUAL_LATCH_Y: latch Y data   
+    ///                                 - TP_MANUAL_IDLE: touch panel is idle
+    ///                                 - TP_MANUAL_WAIT: wait for touch panel event
+    ///                                 - TP_MANUAL_LATCH_X: latch X data
+    ///                                 - TP_MANUAL_LATCH_Y: latch Y data
     /// @param[in]  bTpAdcClkDiv        Sets the ADC clock as a fraction of the System CLK:
-    ///                                 - TP_ADC_CLKDIV_1: Use CLK   
-    ///                                 - TP_ADC_CLKDIV_2: Use CLK/2   
-    ///                                 - TP_ADC_CLKDIV_4: Use CLK/4   
-    ///                                 - TP_ADC_CLKDIV_8: Use CLK/8   
-    ///                                 - TP_ADC_CLKDIV_16: Use CLK/16   
-    ///                                 - TP_ADC_CLKDIV_32: Use CLK/32   
-    ///                                 - TP_ADC_CLKDIV_64: Use CLK/64   
-    ///                                 - TP_ADC_CLKDIV_128: Use CLK/128   
+    ///                                 - TP_ADC_CLKDIV_1: Use CLK
+    ///                                 - TP_ADC_CLKDIV_2: Use CLK/2
+    ///                                 - TP_ADC_CLKDIV_4: Use CLK/4
+    ///                                 - TP_ADC_CLKDIV_8: Use CLK/8
+    ///                                 - TP_ADC_CLKDIV_16: Use CLK/16
+    ///                                 - TP_ADC_CLKDIV_32: Use CLK/32
+    ///                                 - TP_ADC_CLKDIV_64: Use CLK/64
+    ///                                 - TP_ADC_CLKDIV_128: Use CLK/128
     /// @param[in]  bTpAdcSampleTime    Touch Panel sample time delay before ADC data is ready:
-    ///                                 - TP_ADC_SAMPLE_512_CLKS: Wait 512 system clocks   
-    ///                                 - TP_ADC_SAMPLE_1024_CLKS: Wait 1024 system clocks   
-    ///                                 - TP_ADC_SAMPLE_2048_CLKS: Wait 2048 system clocks   
-    ///                                 - TP_ADC_SAMPLE_4096_CLKS: Wait 4096 system clocks   
-    ///                                 - TP_ADC_SAMPLE_8192_CLKS: Wait 8192 system clocks   
-    ///                                 - TP_ADC_SAMPLE_16384_CLKS: Wait 16384 system clocks   
-    ///                                 - TP_ADC_SAMPLE_32768_CLKS: Wait 32768 system clocks   
+    ///                                 - TP_ADC_SAMPLE_512_CLKS: Wait 512 system clocks
+    ///                                 - TP_ADC_SAMPLE_1024_CLKS: Wait 1024 system clocks
+    ///                                 - TP_ADC_SAMPLE_2048_CLKS: Wait 2048 system clocks
+    ///                                 - TP_ADC_SAMPLE_4096_CLKS: Wait 4096 system clocks
+    ///                                 - TP_ADC_SAMPLE_8192_CLKS: Wait 8192 system clocks
+    ///                                 - TP_ADC_SAMPLE_16384_CLKS: Wait 16384 system clocks
+    ///                                 - TP_ADC_SAMPLE_32768_CLKS: Wait 32768 system clocks
     ///                                 - TP_ADC_SAMPLE_65536_CLKS: Wait 65536 system clocks
-    /// @returns @ref RetCode_t value.   
-    ///
-    RetCode_t TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, 
+    /// @returns @ref RetCode_t value.
+    ///
+    RetCode_t TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce,
         uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime);
-    
-    
+
+
     /// Get the screen calibrated point of touch.
     ///
     /// This method determines if there is a touch and if so it will provide
     /// the screen-relative touch coordinates. This method can be used in
-    /// a manner similar to Serial.readable(), to determine if there was a 
+    /// a manner similar to Serial.readable(), to determine if there was a
     /// touch and indicate that - but not care about the coordinates. Alternately,
     /// if a valid pointer to a point_t is provided, then if a touch is detected
-    /// the point_t will be populated with data. 
+    /// the point_t will be populated with data.
     ///
     /// @code
     ///     Timer t;
@@ -1046,7 +1062,7 @@
     ///    } while (t.read_ms() < 30000);
     /// @endcode
     ///
-    /// @param[out] TouchPoint is a pointer to a point_t, which is set as the touch point, 
+    /// @param[out] TouchPoint is a pointer to a point_t, which is set as the touch point,
     ///             if a touch is registered.
     /// @returns a value indicating the state of the touch,
     ///         - no_cal:   no calibration matrix is available, touch coordinates are not returned.
@@ -1059,7 +1075,7 @@
 
 
     /// Get the reported touch gesture, if any.
-    /// 
+    ///
     /// If it could detect a gesture, it will return a value based on
     /// the interpreted gesture.
     ///
@@ -1078,7 +1094,7 @@
     /// @returns gesture information.
     ///
     uint8_t TouchGesture(void) { return gesture; }
-    
+
 
     /// Get the count of registered touches.
     ///
@@ -1086,22 +1102,22 @@
     ///
     int TouchCount(void) { return numberOfTouchPoints; }
 
-    
+
     /// Get the count of possible touch channels.
     ///
     /// @returns count of touch channels supported by the hardware.
     ///
     int TouchChannels(void);
 
-    
+
     /// Get the Touch ID value for a specified touch channel.
     ///
     /// Touch ID is a tracking number based on the order of the touch
-    /// detections. The first touch is ID 0, the next is ID 1, and 
+    /// detections. The first touch is ID 0, the next is ID 1, and
     /// so on. If the first touch is lifted (no touch), the touch count
     /// decrements, and the remaining touch is communicated on
     /// touch channel zero, even as the Touch ID remains as originally
-    /// reported (1 in this example). In this way, it is easy to track 
+    /// reported (1 in this example). In this way, it is easy to track
     /// a specific touch.
     ///
     /// It is possible to query the data for a channel that is not
@@ -1113,7 +1129,7 @@
     /// @returns 0 if an invalid channel is queried.
     ///
     uint8_t TouchID(uint8_t channel = 0);
-    
+
     /// Get the Touch Code for a touch channel.
     ///
     /// It is possible to query the data for a channel that is not
@@ -1141,7 +1157,7 @@
     /// @returns channel 0 information if an invalid channel is queried.
     ///
     point_t TouchCoordinates(uint8_t channel = 0);
-    
+
 
     /// Poll the TouchPanel and on a touch event return the a to d filtered x, y coordinates.
     ///
@@ -1150,11 +1166,11 @@
     ///
     /// @note The returned values are not in display (pixel) units but are in analog to
     ///     digital converter units.
-    /// 
-    /// @note This API is usually not needed and is likely to be deprecated. 
-    ///     See @ref TouchPanelComputeCalibration. 
+    ///
+    /// @note This API is usually not needed and is likely to be deprecated.
+    ///     See @ref TouchPanelComputeCalibration.
     ///     See @ref TouchPanelReadable.
-    /// 
+    ///
     /// @param[out] x is the x scale a/d value.
     /// @param[out] y is the y scale a/d value.
     /// @returns a value indicating the state of the touch,
@@ -1171,15 +1187,15 @@
     ///
     /// This method reads the touch controller, which has a 10-bit range for each the
     /// x and the y axis. A number of samples of the raw data are taken, filtered,
-    /// and the results are returned. 
+    /// and the results are returned.
     ///
     /// @note The returned values are not in display (pixel) units but are in analog to
     ///     digital converter units.
-    /// 
-    /// @note This API is usually not needed and is likely to be deprecated. 
-    ///     See @ref TouchPanelComputeCalibration. 
+    ///
+    /// @note This API is usually not needed and is likely to be deprecated.
+    ///     See @ref TouchPanelComputeCalibration.
     ///     See @ref TouchPanelReadable.
-    /// 
+    ///
     /// @param[out] x is the x scale a/d value.
     /// @param[out] y is the y scale a/d value.
     /// @returns a value indicating the state of the touch,
@@ -1191,9 +1207,9 @@
     ///
     TouchCode_t TouchPanelA2DRaw(int *x, int *y);
 
-    
+
     /// Wait for a touch panel touch and return it.
-    /// 
+    ///
     /// This method is similar to Serial.getc() in that it will wait for a touch
     /// and then return. In order to extract the coordinates of the touch, a
     /// valid pointer to a point_t must be provided.
@@ -1232,10 +1248,11 @@
     /// @code
     ///     RA8875 lcd(p5, p6, p7, p12, NC);
     ///     ...
+    ///     LocalFileSystem local();
     ///     // Be sure you previously mounted the "/sd" file system to put the cal there.
     ///     lcd.ResTouchPanelCfg("/sd/tpcal.cfg", "Touch '+' to calibrate the touch panel");
     ///
-    ///     // Only if the touch panel is enabled, AND is configured as the resistive 
+    ///     // Only if the touch panel is enabled, AND is configured as the resistive
     ///     // panel will the prior command be useful.
     ///     lcd.init(LCD_W,LCD_H,LCD_C,40, false, true);
     ///
@@ -1244,7 +1261,7 @@
     /// @param[in] tpFQFN is a pointer to a fully qualified read-write accessible
     ///     filename where the calibration is held.
     /// @param[in] tpCalMessage is an optional pointer to a message shown to the
-    ///     user in the calibration process. 
+    ///     user in the calibration process.
     ///     - If this parameter is not included, a default message will be shown.
     ///     - If this parameter points to a NULL string, no message is shown.
     ///     - If this parameter points to a non-NULL string, that string will be shown.
@@ -1255,7 +1272,7 @@
     /// Calibrate the touch panel.
     ///
     /// This method accepts two lists - one list is target points in ,
-    /// display coordinates and the other is a lit of raw touch coordinate 
+    /// display coordinates and the other is a lit of raw touch coordinate
     /// values. It generates a calibration matrix for later use. This
     /// matrix is also accessible to the calling API, which may store
     /// the matrix in persistent memory and then install the calibration
@@ -1269,30 +1286,30 @@
     ///     http://www.embedded.com/design/system-integration/4023968/How-To-Calibrate-Touch-Screens
     ///
     /// @copyright Copyright &copy; 2001, Carlos E. Vidales. All rights reserved.
-    ///     This sample program was written and put in the public domain 
-    ///      by Carlos E. Vidales.  The program is provided "as is" 
+    ///     This sample program was written and put in the public domain
+    ///      by Carlos E. Vidales.  The program is provided "as is"
     ///      without warranty of any kind, either expressed or implied.
     ///     If you choose to use the program within your own products
     ///      you do so at your own risk, and assume the responsibility
     ///      for servicing, repairing or correcting the program should
     ///      it prove defective in any manner.
-    ///     You may copy and distribute the program's source code in any 
+    ///     You may copy and distribute the program's source code in any
     ///      medium, provided that you also include in each copy an
     ///      appropriate copyright notice and disclaimer of warranty.
     ///     You may also modify this program and distribute copies of
-    ///      it provided that you include prominent notices stating 
+    ///      it provided that you include prominent notices stating
     ///      that you changed the file(s) and the date of any change,
-    ///      and that you do not charge any royalties or licenses for 
+    ///      and that you do not charge any royalties or licenses for
     ///      its use.
     ///
-    /// @param[in] display is a pointer to a set of 3 points, which 
+    /// @param[in] display is a pointer to a set of 3 points, which
     ///             are in display units of measure. These are the targets
     ///             the calibration was aiming for.
     /// @param[in] screen is a pointer to a set of 3 points, which
     ///             are in touchscreen units of measure. These are the
     ///             registered touches.
-    /// @param[out] matrix is an optional parameter to hold the calibration matrix 
-    ///             as a result of the calibration. This can be saved in  
+    /// @param[out] matrix is an optional parameter to hold the calibration matrix
+    ///             as a result of the calibration. This can be saved in
     ///             non-volatile memory to recover the calibration after a power fail.
     /// @returns @ref RetCode_t value.
     ///
@@ -1307,8 +1324,8 @@
     /// matrix, and optionally provide the calibration matrix to the calling code
     /// for persistence in non-volatile memory.
     ///
-    /// @param[out] matrix is an optional parameter to hold the calibration matrix 
-    ///             as a result of the calibration. This can be saved in  
+    /// @param[out] matrix is an optional parameter to hold the calibration matrix
+    ///             as a result of the calibration. This can be saved in
     ///             non-volatile memory to recover the calibration after a power fail.
     /// @returns @ref RetCode_t value.
     ///
@@ -1325,8 +1342,8 @@
     ///
     /// @param[in] msg is a text message to present on the screen during the
     ///             calibration process.
-    /// @param[out] matrix is an optional parameter to hold the calibration matrix 
-    ///             as a result of the calibration. This can be saved in  
+    /// @param[out] matrix is an optional parameter to hold the calibration matrix
+    ///             as a result of the calibration. This can be saved in
     ///             non-volatile memory to recover the calibration after a power fail.
     /// @param[in] maxwait_s is the maximum number of seconds to wait for a touch
     ///             calibration. If no touch panel installed, it then reports
@@ -1354,10 +1371,11 @@
     ///     fclose(fh);
     /// }
     /// @endcode
-    /// 
+    ///
     /// @param[in] matrix is a pointer to the touch panel calibration matrix.
     /// @returns @ref RetCode_t value.
     ///
+    ///
     RetCode_t TouchPanelSetMatrix(tpMatrix_t * matrix);
 
     /// Get the calibration matrix for the resistive touch panel.
@@ -1367,7 +1385,7 @@
     /// process, the results are indeterminate.
     ///
     /// return const tpMatrix_t pointer
-    /// 
+    ///
     const tpMatrix_t * TouchPanelGetMatrix();
 
 #if 0
@@ -1378,7 +1396,7 @@
     ///                                - RA8875_INT_DMA: DMA interrupt
     ///                                - RA8875_INT_TP: Touch panel interrupt
     ///                                - RA8875_INT_BTE: BTE process complete interrupt
-    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)   
+    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)
     /// @param[in]    fptr is a callback function to handle the interrupt event.
     /// @returns       none
     ///
@@ -1391,7 +1409,7 @@
     ///                                - RA8875_INT_DMA: DMA interrupt
     ///                                - RA8875_INT_TP: Touch panel interrupt
     ///                                - RA8875_INT_BTE: BTE process complete interrupt
-    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)   
+    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)
     /// @return       none
     ///
     void UnAppendISR(uint8_t bISRType);
@@ -1418,8 +1436,8 @@
     ///
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t  KeypadInit(bool scanEnable = true, bool longDetect = false, 
-        uint8_t sampleTime = 0, uint8_t scanFrequency = 0, 
+    RetCode_t  KeypadInit(bool scanEnable = true, bool longDetect = false,
+        uint8_t sampleTime = 0, uint8_t scanFrequency = 0,
         uint8_t longTimeAdjustment = 0,
         bool interruptEnable = false, bool wakeupEnable = false);
 
@@ -1437,7 +1455,7 @@
     ///
     /// @code
     /// //        Return Value by Row, Column   Example reassignment
-    /// //    Column    0    1    2    3    4 
+    /// //    Column    0    1    2    3    4
     /// //          +-------------------------+  +-------------------------+
     /// // Row   0  |   1    2    3    4    5 |  | '7'  '8'  '9'  ',' '<-' |
     /// //       1  |   6    7    8    9   10 |  | '4'  '5'  '6'  '/'  '-' |
@@ -1446,17 +1464,17 @@
     /// //          +-------------------------+  +-------------------------+
     /// //     Return value  0 = No Key pressed
     /// //     Return value 21 = Error
-    /// const uint8_t CodeList[22] = 
-    ///     {0, '7', '8', '9', ',', '\h', 
+    /// const uint8_t CodeList[22] =
+    ///     {0, '7', '8', '9', ',', '\h',
     ///         '4', '5', '6', '/', '-',
     ///         '1', '2', '3', '*', '+',
-    ///         '0', '.', '(', ')', '\n', 
+    ///         '0', '.', '(', ')', '\n',
     ///         '\x1b'};
     ///     lcd.SetKeyMap(CodeList);
     /// @endcode
-    /// 
-    /// @param[in] CodeList is a pointer to an always available byte-array 
-    ///             where the first 22 bytes are used as the transformation 
+    ///
+    /// @param[in] CodeList is a pointer to an always available byte-array
+    ///             where the first 22 bytes are used as the transformation
     ///             from raw code to your reassigned value.
     ///            If CodeList is NULL, the original raw value key map is
     ///             restored.
@@ -1489,8 +1507,21 @@
     ///     keypress using 0 = no key pressed, 1 - 20 = the key pressed.
     ///
     uint8_t getc();
-    
-    
+
+
+    /// Align one rectangle against another.
+    ///
+    /// This will accept a rectangle to align and align it against another rectangle.
+    /// It would be most typical if the rectangle to align is smaller than the reference rectangle.
+    ///
+    /// @param[in] toAlign is a rectangular region to align against another.
+    /// @param[in] inRect is a rectangle to align against.
+    /// @param[in] v specifies the vertical alignment - top, middle, bottom.
+    /// @param[in] h specified the horizontal alignment - left, center, right.
+    /// @returns a new rectangle, the size of the toAlign.
+    ///
+    rect_t AlignRectInRect(rect_t toAlign, rect_t inRect, valign_t v, halign_t h);
+
     /// Determine if a point is within a rectangle.
     ///
     /// @param[in] rect is a rectangular region to use.
@@ -1506,7 +1537,7 @@
     /// @returns true if any part of rect2 intersects rect1.
     ///
     bool Intersect(rect_t rect1, rect_t rect2);
-    
+
     /// Determine if a rectangle intersects another rectangle and provides
     /// the area of intersection.
     ///
@@ -1522,7 +1553,7 @@
     ///                +------------------+
     /// @endcode
     ///
-    /// @note that the first parameter is a pointer to a rect and the 
+    /// @note that the first parameter is a pointer to a rect and the
     ///
     /// @param[inout] pRect1 is a pointer to a rectangular region, and returns
     ///             the area of intersection.
@@ -1531,8 +1562,8 @@
     ///             the rectangle describing the intersection.
     ///
     bool Intersect(rect_t * pRect1, const rect_t * pRect2);
-    
-    
+
+
     /// Write a command to the display with a word of data.
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -1555,7 +1586,7 @@
     ///
     virtual RetCode_t WriteCommand(unsigned char command, unsigned int data = 0xFFFF);
 
-    
+
     /// Write a data word to the display
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -1565,7 +1596,7 @@
     ///
     RetCode_t WriteDataW(uint16_t data);
 
-    
+
     /// Write a data byte to the display
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -1575,7 +1606,7 @@
     ///
     virtual RetCode_t WriteData(unsigned char data);
 
-    
+
     /// Read a command register
     ///
     /// @param[in] command is the command register to read.
@@ -1590,8 +1621,8 @@
     /// @returns the value read from the register.
     ///
     uint16_t ReadCommandW(unsigned char command);
-    
-    
+
+
     /// Read a data byte from the display
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -1600,7 +1631,7 @@
     ///
     unsigned char ReadData(void);
 
-    
+
     /// Read a word from the display
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -1622,28 +1653,28 @@
     /// get the width in pixels of the currently active font
     ///
     /// @returns font width in pixels.
-    ///    
+    ///
     dim_t fontwidth(void);
-    
+
 
     /// get the height in pixels of the currently active font
     ///
     /// @returns font height in pixels.
-    ///    
+    ///
     dim_t fontheight(void);
 
-    
+
     /// get the number of colums based on the currently active font
     ///
     /// @returns number of columns.
-    ///    
+    ///
     virtual int columns(void);
 
 
     /// get the number of rows based on the currently active font
     ///
     /// @returns number of rows.
-    ///    
+    ///
     virtual int rows(void);
 
 
@@ -1668,13 +1699,24 @@
     virtual dim_t color_bpp(void);
 
     /// Set cursor position based on the current font size.
-    /// 
+    ///
     /// @param[in] column is the horizontal position in character positions
     /// @param[in] row is the vertical position in character positions
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t locate(textloc_t column, textloc_t row);
 
+    /// Enable word-wrap in _puts()
+    ///
+    /// @todo Consider adding a method to define the word-delimiters, which could then
+    ///         include user-selection of characters (e.g. ' ', '-', ';', and so on).
+    ///
+    /// @param[in] _wordwrap when true controls _puts() to wrap on word-boundary, which
+    ///         is delimited by 'space' character or 'cr' 'lf' sequences.
+    /// @returns previous wordwrap setting to permit an easy restore.
+    ///
+    bool SetWordWrap(bool _wordwrap);
+
 
     /// Prepare the controller to write text to the screen by positioning
     /// the cursor.
@@ -1717,7 +1759,7 @@
     /// @returns cursor position.
     ///
     point_t GetTextCursor(void);
-    
+
 
     /// Get the current cursor horizontal position in pixels.
     ///
@@ -1735,8 +1777,8 @@
 
     /// Configure additional Cursor Control settings.
     ///
-    /// This API lets you modify other cursor control settings; 
-    /// Cursor visible/hidden, Cursor blink/normal, 
+    /// This API lets you modify other cursor control settings;
+    /// Cursor visible/hidden, Cursor blink/normal,
     /// Cursor I-Beam/underscore/box.
     ///
     /// @param[in] cursor can be set to NOCURSOR (default), IBEAM,
@@ -1746,7 +1788,7 @@
     ///
     RetCode_t SetTextCursorControl(cursor_t cursor = NOCURSOR, bool blink = false);
 
-    
+
     /// Select the built-in ISO 8859-X font to use next.
     ///
     /// Supported fonts: ISO 8859-1, -2, -3, -4
@@ -1761,7 +1803,7 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t SetTextFont(font_t font = ISO8859_1);
-    
+
 
     /// Sets the display orientation.
     ///
@@ -1778,17 +1820,17 @@
     ///     lcd.SetOrientation(RA8875::normal);
     ///     lcd.puts(30,30, "Normal Landscape");
     ///     wait_ms(2500);
-    ///     
+    ///
     ///     lcd.cls();
     ///     lcd.SetOrientation(RA8875::rotate_90);
     ///     lcd.puts(30,30, "Rotated 90 Text\r\n");
     ///     wait_ms(2500);
-    ///     
+    ///
     ///     lcd.cls();
     ///     lcd.SetOrientation(RA8875::rotate_180);
     ///     lcd.puts(30,30, "Rotated 180 Text\r\n");
     ///     wait_ms(2500);
-    /// 
+    ///
     ///     lcd.cls();
     ///     lcd.SetOrientation(RA8875::rotate_270);
     ///     lcd.puts(30,30, "Rotated 270 Text\r\n");
@@ -1803,7 +1845,7 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t SetOrientation(orientation_t angle = normal);
-    
+
 
     /// Control the font behavior.
     ///
@@ -1814,8 +1856,8 @@
     ///
     /// Options can be combined:
     /// Default:
-    /// @li Full alignment disabled, 
-    /// @li Font with Background color, 
+    /// @li Full alignment disabled,
+    /// @li Font with Background color,
     /// @li Font in normal orientiation, or rotated 90, 180, or 270 clockwise,
     /// @li Horizontal scale x 1, 2, 3, or 4
     /// @li Vertical scale x 1, 2, 3, or 4
@@ -1824,7 +1866,7 @@
     ///     full fonts on one presentation. 'align_full' starts each full
     ///     character on an even alignment. See section 7-4-7 of the RA8875
     ///     specification.
-    /// 
+    ///
     /// @param[in] fillit defaults to FILL, but can be NOFILL
     /// @param[in] hScale defaults to 1, but can be 1, 2, 3, or 4,
     ///     and scales the font size by this amount.
@@ -1832,21 +1874,41 @@
     ///     and scales the font size by this amount.
     /// @param[in] alignment defaults to align_none, but can be
     ///     align_full.
-    /// 
+    ///
     /// @note if either hScale or vScale is outside of its permitted range,
     ///     the command is not executed.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t SetTextFontControl(fill_t fillit = FILL, 
-        HorizontalScale hScale = 1, 
-        VerticalScale vScale = 1, 
+    RetCode_t SetTextFontControl(fill_t fillit = FILL,
+        HorizontalScale hScale = 1,
+        VerticalScale vScale = 1,
         alignment_t alignment = align_none);
-    
+
+
+    /// Control the font - to background fill or "ink-only"
+    ///
+    /// This command configures the font presentation to write
+    /// only the font "ink", or to write the ink and also overwrite
+    /// the background with the background color.
+    ///
+    /// @note This command applies only to the internal fonts not to user fonts
+    ///         e.g. SelectUserFont(...) out of concerns for performance.
+    ///         User fonts always write the character block as a continuous
+    ///         stream (for efficiency). This precludes first reading the
+    ///         character block before writing it. Alternately, addressing
+    ///         individual pixels would also be a significant performance
+    ///         impact.
+    ///
+    /// @param[in] fillit set to FILL will also write the background,
+    ///                 and set to NOFILL will write only the ink.
+    /// @returns the previous fill setting permitting easy restore.
+    ///
+    fill_t SetTextFontFill(fill_t fillit);
 
     /// Control the font size of the RA8875 rendered fonts.
     ///
     /// This command lets you set the font enlargement for both horizontal
-    /// and vertical, independent of the rotation, background, and 
+    /// and vertical, independent of the rotation, background, and
     /// alignment. See @ref SetTextFontControl.
     ///
     /// @note This command operates on the RA8875 internal fonts.
@@ -1854,7 +1916,7 @@
     ///
     /// @param[in] hScale defaults to 1, but can be 1, 2, 3, or 4,
     ///     and scales the font size by this amount.
-    /// @param[in] vScale is an optional parameter that defaults to the hScale value, 
+    /// @param[in] vScale is an optional parameter that defaults to the hScale value,
     ///     but can be 1, 2, 3, or 4, and scales the font size by this amount.
     ///
     /// @code
@@ -1880,7 +1942,7 @@
     /// Get the text font size of the RA8875 internal fonts.
     ///
     /// This command lets you retrieve the current settings for the font
-    /// horizontal and vertical scale factors. The return value is 
+    /// horizontal and vertical scale factors. The return value is
     /// one of the scale factors 1, 2, 3, or 4.
     ///
     /// @param[out] hScale is a pointer to memory where the horizontal scale factor
@@ -1893,6 +1955,15 @@
 
     /// put a character on the screen.
     ///
+    /// @param[in] text is a pointer to a text string to evaluate.
+    /// @param[in] charOnly defaults to false, which computes over the whole string.
+    /// @returns width in pixels, given the selected font and scale.
+    ///
+    dim_t GetTextWidth(const char * text, bool charOnly = false);
+
+
+    /// put a character on the screen.
+    ///
     /// @param[in] c is the character.
     /// @returns the character, or EOF if there is an error.
     ///
@@ -1909,7 +1980,7 @@
     ///
     void puts(const char * string);
 
-    
+
     /// Write string of text to the display at the specified location.
     ///
     /// @code
@@ -1921,7 +1992,7 @@
     /// @param[in] string is the null terminated string to send to the display.
     ///
     void puts(loc_t x, loc_t y, const char * string);
-    
+
 
     /// Prepare the controller to write binary data to the screen by positioning
     /// the memory cursor.
@@ -1939,14 +2010,14 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t SetGraphicsCursor(point_t p);
-    
+
     /// Read the current graphics cursor position as a point.
     ///
     /// @returns the graphics cursor as a point.
     ///
     virtual point_t GetGraphicsCursor(void);
 
-    
+
     /// Prepare the controller to read binary data from the screen by positioning
     /// the memory read cursor.
     ///
@@ -1955,7 +2026,7 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t SetGraphicsCursorRead(loc_t x, loc_t y);
-    
+
 
     /// Set the window, constraining where items are written to the screen.
     ///
@@ -1982,7 +2053,7 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t window(rect_t r);
-    
+
 
     /// Set the window, constraining where items are written to the screen.
     ///
@@ -2013,7 +2084,7 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t window(loc_t x = 0, loc_t y = 0, dim_t width = (dim_t)-1, dim_t height = (dim_t)-1);
-    
+
 
     /// Clear either the specified layer, or the active layer.
     ///
@@ -2030,15 +2101,15 @@
     ///     is cleared. If bit 0 is set, layer 0 is cleared, if bit
     ///     1 is set, layer 1 is cleared. If both are set, both layers
     ///     are cleared. Any other value does not cause an action.
-    ///     
+    ///
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t cls(uint16_t layers = 0);
 
-    
+
     /// Clear the screen, or clear only the active window.
     ///
-    /// The default behavior is to clear the whole screen. With the optional 
+    /// The default behavior is to clear the whole screen. With the optional
     /// parameter, the action can be restricted to the active window, which
     /// can be set with the See @ref window method.
     ///
@@ -2061,7 +2132,7 @@
     ///
     virtual RetCode_t background(color_t color);
 
-    
+
     /// Set the background color.
     ///
     /// @param[in] r is the red element of the color.
@@ -2070,7 +2141,7 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t background(unsigned char r, unsigned char g, unsigned char b);
-    
+
 
     /// Set the foreground color.
     ///
@@ -2078,7 +2149,7 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t foreground(color_t color);
-    
+
 
     /// Set the foreground color.
     ///
@@ -2088,15 +2159,15 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t foreground(unsigned char r, unsigned char g, unsigned char b);
-    
-    
+
+
     /// Get the current foreground color value.
     ///
     /// @returns the current foreground color as @ref color_t.
     ///
     color_t GetForeColor(void);
-    
-    
+
+
     /// Draw a pixel in the specified color.
     ///
     /// @note Unlike many other operations, this does not
@@ -2107,16 +2178,16 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t pixel(point_t p, color_t color);
-    
-    
+
+
     /// Draw a pixel in the current foreground color.
     ///
     /// @param[in] p is the point_t defining the location.
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t pixel(point_t p);
-    
-        
+
+
     /// Draw a pixel in the specified color.
     ///
     /// @note Unlike many other operations, this does not
@@ -2128,8 +2199,8 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t pixel(loc_t x, loc_t y, color_t color);
-    
-    
+
+
     /// Draw a pixel in the current foreground color.
     ///
     /// @param[in] x is the horizontal offset to this pixel.
@@ -2137,8 +2208,8 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t pixel(loc_t x, loc_t y);
-    
-    
+
+
     /// Get a pixel from the display.
     ///
     /// @param[in] x is the horizontal offset to this pixel.
@@ -2146,8 +2217,8 @@
     /// @returns the pixel. See @ref color_t
     ///
     virtual color_t getPixel(loc_t x, loc_t y);
-    
-    
+
+
     /// Write an RGB565 stream of pixels to the display.
     ///
     /// @param[in] p is a pointer to a color_t array to write.
@@ -2157,8 +2228,8 @@
     /// @returns @ref RetCode_t value.
     ///
     virtual RetCode_t pixelStream(color_t * p, uint32_t count, loc_t x, loc_t y);
-    
-    
+
+
     /// Get a stream of pixels from the display.
     ///
     /// @param[in] p is a pointer to a color_t array to accept the stream.
@@ -2177,14 +2248,14 @@
     /// to either the foreground or background color value and then that pixel
     /// is pushed onward.
     ///
-    /// This is similar, but different, to the @ref pixelStream API, which is 
+    /// This is similar, but different, to the @ref pixelStream API, which is
     /// given a stream of color values.
-    /// 
+    ///
     /// This is most often used for Soft Fonts, and for that reason, this method
-    /// will scale the presentation based on the selected font size. 
+    /// will scale the presentation based on the selected font size.
     /// See @ref SetTextFontSize, So, users may want to SetTextFontSize(1) for
     /// 1:1 scaling.
-    /// 
+    ///
     /// @param[in] x is the horizontal position on the display.
     /// @param[in] y is the vertical position on the display.
     /// @param[in] w is the width of the rectangular region to fill.
@@ -2195,7 +2266,6 @@
     ///
     virtual RetCode_t booleanStream(loc_t x, loc_t y, dim_t w, dim_t h, const uint8_t * boolStream);
 
-    
     /// Draw a line in the specified color
     ///
     /// @note As a side effect, this changes the current
@@ -2219,7 +2289,7 @@
     ///
     RetCode_t line(point_t p1, point_t p2);
 
-    
+
     /// Draw a line in the specified color
     ///
     /// @note As a side effect, this changes the current
@@ -2252,10 +2322,14 @@
     ///
     /// Draw a line of a specified thickness and color.
     ///
-    /// In order to draw a thick line, this draws filled circles using 
-    /// bresenham's algorithm to move the center point of the circle.
-    /// As a result, this is much slower than drawing a 1-pixel line which
-    /// uses the hardware line drawing algorithm.
+    /// In order to draw a thick line, this draws filled circles using
+    /// and then draws the 'body' of the thick line using filled triangles. This
+    /// method makes it significantly faster than in prior versions.
+    ///
+    /// An older version of this library used Bresenham's algorithm to move the
+    /// center point of the circle along the line. As a result, this was much
+    /// slower than drawing a 1-pixel line which uses the hardware line drawing
+    /// algorithm.
     ///
     /// Drawing multiple parallel lines to create a thick line is faster,
     /// however the line drawing was not guaranteed to fill every pixel
@@ -2266,10 +2340,18 @@
     /// @param[in] thickness is the line thickness.
     /// @param[in] color defines the foreground color.
     /// @returns @ref RetCode_t value.
-    /// 
+    ///
     RetCode_t ThickLine(point_t p1, point_t p2, dim_t thickness, color_t color);
 
 
+    /// Set the end-cap for ThickLines - square (default) or rounded.
+    ///
+    /// @param[in] roundCap when true causes the end-cap to be drawn as a filled circle.
+    /// @returns the previous end-cap setting, permitting easy restore.
+    ///
+    bool SetEndCap(bool roundCap);
+
+
     /// Draw a rectangle in the specified color
     ///
     /// @note As a side effect, this changes the current
@@ -2281,7 +2363,7 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t rect(rect_t rect, color_t color, fill_t fillit = NOFILL);
-    
+
 
     /// Draw a filled rectangle in the specified color
     ///
@@ -2309,7 +2391,7 @@
     /// @param[in] fillit is optional to FILL the rectangle. default is FILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         color_t color, fill_t fillit = NOFILL);
 
 
@@ -2326,7 +2408,7 @@
     /// @param[in] fillit is optional to NOFILL the rectangle. default is FILL.
     /// @returns @ref RetCode_t value.
     ///
-    virtual RetCode_t fillrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    virtual RetCode_t fillrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         color_t color, fill_t fillit = FILL);
 
 
@@ -2341,7 +2423,7 @@
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         fill_t fillit = NOFILL);
 
 
@@ -2360,16 +2442,16 @@
     /// @param[in] x2 is the horizontal end of the line and must be >= x1.
     /// @param[in] y2 is the vertical end of the line and must be >= y1.
     /// @param[in] radius1 defines the horizontal radius of the curved corner. Take care
-    ///         that this value < 1/2 the width of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the width of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] radius2 defines the vertical radius of the curved corner. Take care
-    ///         that this value < 1/2 the height of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the height of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] color defines the foreground color.
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t fillroundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t fillroundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         dim_t radius1, dim_t radius2, color_t color, fill_t fillit = FILL);
 
 
@@ -2385,16 +2467,16 @@
     ///
     /// @param[in] r is the rectangle to draw.
     /// @param[in] radius1 defines the horizontal radius of the curved corner. Take care
-    ///         that this value < 1/2 the width of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the width of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] radius2 defines the vertical radius of the curved corner. Take care
-    ///         that this value < 1/2 the height of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the height of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] color defines the foreground color.
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t fillroundrect(rect_t r, 
+    RetCode_t fillroundrect(rect_t r,
         dim_t radius1, dim_t radius2, color_t color, fill_t fillit = FILL);
 
 
@@ -2410,16 +2492,16 @@
     ///
     /// @param[in] r is the rectangle to draw.
     /// @param[in] radius1 defines the horizontal radius of the curved corner. Take care
-    ///         that this value < 1/2 the width of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the width of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] radius2 defines the vertical radius of the curved corner. Take care
-    ///         that this value < 1/2 the height of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the height of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] color defines the foreground color.
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t roundrect(rect_t r, 
+    RetCode_t roundrect(rect_t r,
         dim_t radius1, dim_t radius2, color_t color, fill_t fillit = NOFILL);
 
 
@@ -2438,16 +2520,16 @@
     /// @param[in] x2 is the horizontal end of the line and must be >= x1.
     /// @param[in] y2 is the vertical end of the line and must be >= y1.
     /// @param[in] radius1 defines the horizontal radius of the curved corner. Take care
-    ///         that this value < 1/2 the width of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the width of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] radius2 defines the vertical radius of the curved corner. Take care
-    ///         that this value < 1/2 the height of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the height of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] color defines the foreground color.
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         dim_t radius1, dim_t radius2, color_t color, fill_t fillit = NOFILL);
 
 
@@ -2463,15 +2545,15 @@
     /// @param[in] x2 is the horizontal end of the line and must be >= x1.
     /// @param[in] y2 is the vertical end of the line and must be >= y1.
     /// @param[in] radius1 defines the horizontal radius of the curved corner. Take care
-    ///         that this value < 1/2 the width of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the width of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] radius2 defines the vertical radius of the curved corner. Take care
-    ///         that this value < 1/2 the height of the rectangle, or bad_parameter 
+    ///         that this value < 1/2 the height of the rectangle, or bad_parameter
     ///         is returned.
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         dim_t radius1, dim_t radius2, fill_t fillit = NOFILL);
 
 
@@ -2502,14 +2584,14 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t triangle(point_t p1, point_t p2, point_t p3, color_t color, fill_t fillit = NOFILL);
-    
+
     /// Draw a triangle in the specified color.
     ///
     /// @note As a side effect, this changes the current
     ///     foreground color for subsequent operations.
     ///
     /// @param[in] x1 is the horizontal for point 1.
-    /// @param[in] y1 is the vertical for point 1. 
+    /// @param[in] y1 is the vertical for point 1.
     /// @param[in] x2 is the horizontal for point 2.
     /// @param[in] y2 is the vertical for point 2.
     /// @param[in] x3 is the horizontal for point 3.
@@ -2518,9 +2600,9 @@
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t triangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t triangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         loc_t x3, loc_t y3, color_t color, fill_t fillit = NOFILL);
-    
+
 
     /// Draw a filled triangle in the specified color.
     ///
@@ -2537,7 +2619,7 @@
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t filltriangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t filltriangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         loc_t x3, loc_t y3, color_t color, fill_t fillit = FILL);
 
 
@@ -2554,9 +2636,9 @@
     /// @param[in] fillit is optional to FILL the rectangle. default is NOFILL.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t triangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
+    RetCode_t triangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2,
         loc_t x3, loc_t y3, fill_t fillit = NOFILL);
-    
+
 
     /// Draw a circle using the specified color.
     ///
@@ -2653,7 +2735,7 @@
     /// @param[in] fillit defines whether the circle is filled or not.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, 
+    RetCode_t ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2,
         color_t color, fill_t fillit = NOFILL);
 
 
@@ -2670,7 +2752,7 @@
     /// @param[in] fillit defines whether the circle is filled or not.
     /// @returns @ref RetCode_t value.
     ///
-    RetCode_t fillellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, 
+    RetCode_t fillellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2,
         color_t color, fill_t fillit = FILL);
 
 
@@ -2686,7 +2768,7 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, fill_t fillit = NOFILL);
-    
+
 
 
     /// Block Move
@@ -2701,7 +2783,7 @@
     ///
     /// @code
     /// // Block Move Demo
-    /// 
+    ///
     /// // Calibrate the resistive touch screen, and store the data on the
     /// // local file system.
     /// //
@@ -2711,7 +2793,7 @@
     ///    tpMatrix_t matrix;
     ///    RetCode_t r;
     ///    Timer testperiod;
-    /// 
+    ///
     ///    r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix);
     ///    if (r == noerror) {
     ///        fh = fopen("/local/tpcal.cfg", "wb");
@@ -2728,7 +2810,7 @@
     ///     }
     ///     lcd.cls();
     /// }
-    /// 
+    ///
     /// // Try to load a previous resistive touch screen calibration from storage. If it
     /// // doesn't exist, activate the touch screen calibration process.
     /// //
@@ -2736,7 +2818,7 @@
     /// {
     ///     FILE * fh;
     ///     tpMatrix_t matrix;
-    /// 
+    ///
     ///     fh = fopen("/local/tpcal.cfg", "rb");
     ///     if (fh) {
     ///         fread(&matrix, sizeof(tpMatrix_t), 1, fh);
@@ -2755,7 +2837,7 @@
     ///     TouchCode_t touch;
     ///     const dim_t RECT_W = 100;
     ///     const dim_t RECT_H = 100;
-    ///     
+    ///
     ///     pc.baud(460800);    //I like a snappy terminal, so crank it up!
     ///     pc.printf("\r\nRA8875 BTE Move Test - Build " __DATE__ " " __TIME__ "\r\n");
     ///     lcd.init(LCD_W,LCD_H,LCD_C, BL_NORM);
@@ -2763,7 +2845,7 @@
     ///     #ifndef CAP_TOUCH
     ///     InitTS();   // Calibration for resistive touch panel
     ///     #endif
-    ///     
+    ///
     ///     RetCode_t r = lcd.RenderImageFile(0,0,"/local/fullscrn.jpg");
     ///     if (r) pc.printf("  Error: %d; %s\r\n", r, lcd.GetErrorMessage(r));
     ///     while (1) {
@@ -2771,7 +2853,7 @@
     ///         if (touch) {
     ///             point_t xy = lcd.TouchCoordinates();
     ///             TouchCode_t t = lcd.TouchCode();
-    /// 
+    ///
     ///             if (t == touch) {
     ///                 src = ComputeTopLeftOfRect(xy, RECT_W/2, RECT_H/2, LCD_W, LCD_H);
     ///             } else if (t == release) {
@@ -2791,7 +2873,7 @@
     /// @param[in] srcPoint [54-57] is a point_t defining the source coordinate.
     /// @param[in] bte_width [5C-5D]. operation width.
     /// @param[in] bte_height [5E-5F]. operation height.
-    /// @param[in] bte_op_code [51.3-0] defines the raster operation function 
+    /// @param[in] bte_op_code [51.3-0] defines the raster operation function
     ///             (write/read/move/...)
     /// @param[in] bte_rop_code [51.7-4] defines what type of BTE operation to perform
     ///             (what is placed at the destination)
@@ -2816,30 +2898,30 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t Reset(void);
-    
+
 
     /// Set backlight brightness.
     ///
-    /// When the built-in PWM is used to control the backlight, this 
+    /// When the built-in PWM is used to control the backlight, this
     /// API can be used to set the brightness.
-    /// 
+    ///
     /// @param[in] brightness ranges from 0 (off) to 255 (full on)
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t Backlight_u8(uint8_t brightness);
 
-    
+
     /// Get backlight brightness.
     ///
     /// @returns backlight setting from 0 (off) to 255 (full on).
-    /// 
+    ///
     uint8_t GetBacklight_u8(void);
 
     /// Set backlight brightness.
     ///
-    /// When the built-in PWM is used to control the backlight, this 
+    /// When the built-in PWM is used to control the backlight, this
     /// API can be used to set the brightness.
-    /// 
+    ///
     /// @param[in] brightness ranges from 0.0 (off) to 1.0 (full on)
     /// @returns @ref RetCode_t value.
     ///
@@ -2849,14 +2931,14 @@
     /// Get backlight brightness.
     ///
     /// @returns backlight setting from 0 (off) to 1.0 (full on).
-    /// 
+    ///
     float GetBacklight(void);
 
 
     /// Select a User Font for all subsequent text.
     ///
     /// @note Tool to create the fonts is accessible from its creator
-    ///     available at http://www.mikroe.com. 
+    ///     available at http://www.mikroe.com.
     ///     For version 1.2.0.0, choose the "Export for TFT and new GLCD"
     ///     format.
     ///
@@ -2874,13 +2956,13 @@
     /// Get the @ref color_t value from a DOS color index.
     ///
     /// See @ref PredefinedColors, @ref color_t.
-    /// 
+    ///
     /// @code
     ///     color_t color = DOSColor(12);
     /// @endcode
     ///
     /// @param[in] i is the color index, in the range 0 to 15;
-    /// @returns the @ref color_t value of the selected index, 
+    /// @returns the @ref color_t value of the selected index,
     ///     or 0 (@ref Black) if the index is out of bounds.
     ///
     color_t DOSColor(int i);
@@ -2889,7 +2971,7 @@
     /// Get the color name (string) from a DOS color index.
     ///
     /// See @ref PredefinedColors, @ref color_t.
-    /// 
+    ///
     /// @code
     ///     printf("color is %s\n", DOSColorNames(12));
     /// @endcode
@@ -2897,7 +2979,7 @@
     /// @param[in] i is the color index, in the range 0 to 15;
     /// @returns a pointer to a string with the color name,
     ///     or NULL if the index is out of bounds.
-    /// 
+    ///
     const char * DOSColorNames(int i);
 
 
@@ -2918,11 +3000,11 @@
     ///
     virtual RetCode_t _StartGraphicsStream(void);
 
-    
+
     /// Advanced method to put a single color pixel to the screen.
     ///
-    /// This method may be called as many times as necessary after 
-    /// See @ref _StartGraphicsStream() is called, and it should be followed 
+    /// This method may be called as many times as necessary after
+    /// See @ref _StartGraphicsStream() is called, and it should be followed
     /// by _EndGraphicsStream.
     ///
     /// @code
@@ -2934,7 +3016,7 @@
     ///
     virtual RetCode_t _putp(color_t pixel);
 
-    
+
     /// Advanced method indicating the end of a graphics stream.
     ///
     /// This is called to conclude a stream of pixel data that was sent.
@@ -2953,7 +3035,7 @@
     /// its capabilities. The RA8875 can accept writes via SPI faster
     /// than a read can be performed. The frequency set by this API
     /// is for the SPI writes. It will automatically reduce the SPI
-    /// clock rate when a read is performed, and restore it for the 
+    /// clock rate when a read is performed, and restore it for the
     /// next write. Alternately, the 2nd parameters permits setting
     /// the read speed rather than letting it compute it automatically.
     ///
@@ -2983,7 +3065,7 @@
     /// 24-bit format.
     ///
     /// This method will interrogate the current display setting and
-    /// create a bitmap based on those settings. For instance, if 
+    /// create a bitmap based on those settings. For instance, if
     /// only layer 1 is visible, then the bitmap is only layer 1. However,
     /// if there is some other operation in effect (transparent mode).
     ///
@@ -2995,7 +3077,7 @@
     /// @param[in] w is the width of the region to capture
     /// @param[in] h is the height of the region to capture.
     /// @param[in] Name_BMP is the filename to write the image to.
-    /// @param[in] bitsPerPixel is optional, defaults to 24, and only 
+    /// @param[in] bitsPerPixel is optional, defaults to 24, and only
     ///             accepts the values 24, 8
     ///             NOTE: The downscaling is CPU intensive, and the operation
     ///             takes longer.
@@ -3003,7 +3085,7 @@
     ///
     RetCode_t PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP, uint8_t bitsPerPixel = 24);
 
-    
+
     /// This method captures the specified area as a 24-bit bitmap file
     /// and delivers it to the previously attached callback.
     ///
@@ -3011,7 +3093,7 @@
     /// 24-bit format.
     ///
     /// This method will interrogate the current display setting and
-    /// create a bitmap based on those settings. For instance, if 
+    /// create a bitmap based on those settings. For instance, if
     /// only layer 1 is visible, then the bitmap is only layer 1. However,
     /// if there is some other operation in effect (transparent mode), it
     /// will return the blended image.
@@ -3023,7 +3105,7 @@
     /// @param[in] y is the top edge of the region to capture
     /// @param[in] w is the width of the region to capture
     /// @param[in] h is the height of the region to capture.
-    /// @param[in] bitsPerPixel is optional, defaults to 24, and only 
+    /// @param[in] bitsPerPixel is optional, defaults to 24, and only
     ///             accepts the values 24, 8
     ///             NOTE: The downscaling is CPU intensive, and the operation
     ///             takes longer.
@@ -3031,13 +3113,13 @@
     ///
     RetCode_t PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, uint8_t bitsPerPixel = 24);
 
-    
+
     /// PrintScreen callback registration.
     ///
     /// This method attaches a simple c-compatible callback of type PrintCallback_T.
     /// Then, the PrintScreen(x,y,w,h) method is called. Each chunk of data in the
     /// BMP file to be created is passed to this callback.
-    /// 
+    ///
     /// @param callback is the optional callback function. Without a callback function
     ///     it will unregister the handler.
     ///
@@ -3049,13 +3131,13 @@
     /// This method attaches a c++ class method as a callback of type PrintCallback_T.
     /// Then, the PrintScreen(x,y,w,h) method is called. Each chunk of data in the
     /// BMP file to be created is passed to this callback.
-    /// 
+    ///
     /// @param object is the class hosting the callback function.
     /// @param method is the callback method in the object to activate.
     ///
     template <class T>
-    void AttachPrintHandler(T *object, RetCode_t (T::*method)(void)) { 
-        obj_callback    = (FPointerDummy *)object; 
+    void AttachPrintHandler(T *object, RetCode_t (T::*method)(void)) {
+        obj_callback    = (FPointerDummy *)object;
         method_callback = (uint32_t (FPointerDummy::*)(uint32_t, uint8_t *, uint16_t))method;
     }
 
@@ -3081,7 +3163,7 @@
     ///
     RetCode_t PrintScreen(uint16_t layer, loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP);
 
-    
+
     /// idle callback registration.
     ///
     /// This method attaches a simple c-compatible callback of type IdleCallback_T.
@@ -3119,13 +3201,13 @@
 #ifdef PERF_METRICS
     /// Clear the performance metrics to zero.
     void ClearPerformance();
-    
+
     /// Count idle time.
     ///
     /// @param[in] t is the amount of idle time to accumulate.
     ///
     void CountIdleTime(uint32_t t);
-    
+
     /// Report the performance metrics for drawing functions using
     /// the available serial channel.
     ///
@@ -3139,7 +3221,7 @@
     void InitAllMemberVars();
 
     /// Touch panel parameters - common to both resistive and capacitive
-    
+
     /// Data type to indicate which TP, if any, is in use.
     typedef enum {
         TP_NONE,            ///< no touch panel in use
@@ -3148,16 +3230,16 @@
         TP_CAP=TP_FT5206,   ///< DEPRECATED: used TP_CAP5206 for that chip-set
         TP_GSL1680,         ///< Capacitive touch panel using GSL1680 chip
     } WhichTP_T;
-    
+
     /// boolean flag set true when using Capacitive touch panel, and false
     /// for resistive.
     WhichTP_T useTouchPanel;    ///< Indicates which TP is selected for use.
-        
+
     /// Touch State used by TouchPanelReadable. See @ref TouchCode_t.
     TouchCode_t touchState;
 
     ////////////////// Start of Capacitive Touch Panel parameters
-    
+
     int RoundUp(int value, int roundTo);
     uint8_t FT5206_TouchPositions(void);
     uint8_t FT5206_ReadRegU8(uint8_t reg);
@@ -3169,7 +3251,7 @@
     void TouchPanelISR(void);
     uint16_t numberOfTouchPoints;
     uint8_t gesture;            ///< Holds the reported gesture information (which doesn't work well for the FT5206)
-    
+
     /// Touch Information data structure
     typedef struct {
         uint8_t touchID;        ///< Contains the touch ID, which is the "order" of touch, from 0 to n-1
@@ -3189,9 +3271,9 @@
     //uint8_t data[2];            /// Transfer data for the I2C interface
 
     bool panelTouched;
-    
+
     ////////////////// Start of Resistive Touch Panel parameters
-    
+
     /// Resistive Touch Panel register name definitions
     #define TPCR0   0x70
     #define TPCR1   0x71
@@ -3216,29 +3298,29 @@
     // the ticker monitors the timer to see if it has been a long time since
     // a touch, and if so, it then clears the sample counter so it doesn't get partial old
     // and partial new.
-    
+
     /// Touch Panel ticker
     /// This it bound to a timer to call the _TouchTicker() function periodically.
     ///
     Ticker touchTicker;
-    
+
     /// Touch Panel timer
     /// Reset on a touch, to expire on a non-touch
     ///
     Timer timeSinceTouch;
-    
+
     /// keeps track of which sample we're collecting to filter out the noise.
     int touchSample;
-    
+
     /// Private function for touch ticker callback.
     void _TouchTicker(void);
-    
+
     /// Touch Panel calibration matrix.
     tpMatrix_t tpMatrix;
 
     /// RESISTIVE TP: The fully qualified filename for the RESISTIVE touch panel configuration settings.
     const char * tpFQFN;
-    
+
     /// RESISTIVE TP: The text message shown to the user during the calibration process.
     const char * tpCalMessage;
 
@@ -3255,21 +3337,21 @@
     /// @returns the character put.
     ///
     int _internal_putc(int c);
-    
+
     /// Internal function to put a character using the external font engine
     ///
     /// @param[in] c is the character to put to the screen.
     /// @returns the character put.
     ///
     int _external_putc(int c);
-    
+
     /// Internal function to get the actual width of a character when using the external font engine
     ///
     /// @param[in] c is the character to get the width.
     /// @returns the width in pixels of the character. zero if not found.
     ///
     int _external_getCharWidth(int c);
-    
+
     /// Write color to an RGB register set
     ///
     /// This API takes a color value, and writes it into the specified
@@ -3282,7 +3364,7 @@
     /// @returns @ref RetCode_t value.
     ///
     RetCode_t _writeColorTrio(uint8_t regAddr, color_t color);
-    
+
     /// Read color from an RGB register set
     ///
     /// This API reads a color value from a trio of registers. The actual
@@ -3293,8 +3375,8 @@
     /// @returns color_t value
     ///
     color_t _readColorTrio(uint8_t regAddr);
-    
-    
+
+
     /// Convert a 16-bit color value to an 8-bit value
     ///
     /// @param[in] c16 is the 16-bit color value to convert.
@@ -3308,7 +3390,7 @@
     /// @returns 16-bit color value.
     ///
     color_t _cvt8to16(uint8_t c8);
-    
+
     /// Select the peripheral to use it.
     ///
     /// @param[in] chipsel when true will select the peripheral, and when false
@@ -3353,7 +3435,7 @@
     ///     in while shifting out.
     ///
     unsigned char _spiwrite(unsigned char data);
-    
+
     /// The most primitive - to read a data value to the SPI interface.
     ///
     /// This is really just a specialcase of the write command, where
@@ -3363,9 +3445,9 @@
     ///     in while shifting out.
     ///
     unsigned char _spiread();
-    
+
     const uint8_t * pKeyMap;
-    
+
     SPI spi;                        ///< spi port
     bool spiWriteSpeed;             ///< indicates if the current mode is write or read
     unsigned long spiwritefreq;     ///< saved write freq
@@ -3373,20 +3455,20 @@
     DigitalOut cs;                  ///< RA8875 chip select pin, assumed active low
     DigitalOut res;                 ///< RA8875 reset pin, assumed active low
     DigitalOut * m_wake;            ///< GSL1680 wake pin
-    
+
     // display metrics to avoid lengthy spi read queries
     uint8_t screenbpp;              ///< configured bits per pixel
     dim_t screenwidth;              ///< configured screen width
     dim_t screenheight;             ///< configured screen height
-    rect_t windowrect;              ///< window commands are held here for speed of access 
+    rect_t windowrect;              ///< window commands are held here for speed of access
     bool portraitmode;              ///< set true when in portrait mode (w,h are reversed)
-    
+    bool wordwrap;                  ///< set true when wordwrap is in effect for _puts()
     const unsigned char * font;     ///< reference to an external font somewhere in memory
     uint8_t extFontHeight;          ///< computed from the font table when the user sets the font
     uint8_t extFontWidth;           ///< computed from the font table when the user sets the font
-    
+    bool roundCap;                  ///< draw round end cap on thick lines when set.
     loc_t cursor_x, cursor_y;       ///< used for external fonts only
-    
+
     #ifdef PERF_METRICS
     typedef enum
     {
@@ -3410,11 +3492,11 @@
     void RegisterPerformance(method_e method);
     Timer performance;
     #endif
-    
+
     RetCode_t _printCallback(RA8875::filecmd_t cmd, uint8_t * buffer, uint16_t size);
-    
+
     FILE * _printFH;             ///< PrintScreen file handle
-    
+
     RetCode_t privateCallback(filecmd_t cmd, uint8_t * buffer, uint16_t size) {
         if (c_callback != NULL) {
             return (*c_callback)(cmd, buffer, size);
@@ -3426,12 +3508,12 @@
         }
         return noerror;
     }
-    
+
     RetCode_t (* c_callback)(filecmd_t cmd, uint8_t * buffer, uint16_t size);
     FPointerDummy  *obj_callback;
     RetCode_t (FPointerDummy::*method_callback)(filecmd_t cmd, uint8_t * buffer, uint16_t size);
     RetCode_t (* idle_callback)(IdleReason_T reason, uint16_t param);
-    
+
     orientation_t screen_orientation;
     point_t TranslateOrientation(point_t rawPoint);
 };
@@ -3457,7 +3539,7 @@
 
 extern "C" void mbed_reset();
 
-/// This activates a small set of tests for the graphics library. 
+/// This activates a small set of tests for the graphics library.
 ///
 /// Call this API and pass it the reference to the display class.
 /// It will then run a series of tests. It accepts interaction via
@@ -3482,7 +3564,7 @@
 // {
 //     pc.baud(460800);    // I like a snappy terminal, so crank it up!
 //     pc.printf("\r\nRA8875 Test - Build " __DATE__ " " __TIME__ "\r\n");
-// 
+//
 //     pc.printf("Turning on display\r\n");
 //     lcd.init();
 //     lcd.Reset();