This is the David Smart RA8875 Library with mods for working with FRDM-K64F

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();