LCD LIB

Dependents:   HagridOS5

Fork of RA8875 by David Smart

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Sun Jan 17 22:16:37 2016 +0000
Parent:
100:0b084475d5a9
Child:
102:fc60bfa0199f
Commit message:
External fonts now wrap correctly at the edge of the screen (right edge by moving down one line and to the left margin, and last row by wrapping to the top row.
; Altered the soft font <space> character; auto-generated fonts computed zero width.

Changed in this revision

Fonts/BPG_Arial10x10.h Show annotated file Show diff for this revision Revisions of this file
Fonts/BPG_Arial20x20.h Show annotated file Show diff for this revision Revisions of this file
Fonts/BPG_Arial31x32.h Show annotated file Show diff for this revision Revisions of this file
Fonts/BPG_Arial63x63.h Show annotated file Show diff for this revision Revisions of this file
GraphicsDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
GraphicsDisplay.h Show annotated file Show diff for this revision Revisions of this file
RA8875.cpp Show annotated file Show diff for this revision Revisions of this file
RA8875.h Show annotated file Show diff for this revision Revisions of this file
--- a/Fonts/BPG_Arial10x10.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/Fonts/BPG_Arial10x10.h	Sun Jan 17 22:16:37 2016 +0000
@@ -1,4 +1,4 @@
-
+//Manually adjusted the ' ' (space) to be 4-pix wide
 
 //Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
 //MikroElektrnika 2011 
@@ -14,7 +14,7 @@
    0x7F,0x00,
    0x0A,
    0x00,
-   0x02,0x88,0x01,0x00,
+   0x04,0x88,0x01,0x00,
    0x02,0x92,0x01,0x00,
    0x03,0x9C,0x01,0x00,
    0x06,0xA6,0x01,0x00,
--- a/Fonts/BPG_Arial20x20.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/Fonts/BPG_Arial20x20.h	Sun Jan 17 22:16:37 2016 +0000
@@ -1,3 +1,4 @@
+//Manually adjusted the ' ' (space) to be 4-pix wide
 
 //Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
 //MikroElektrnika 2011 
@@ -13,7 +14,7 @@
    0x7F,0x00,
    0x14,
    0x00,
-   0x01,0x88,0x01,0x00,
+   0x04,0x88,0x01,0x00,
    0x04,0x9C,0x01,0x00,
    0x06,0xB0,0x01,0x00,
    0x0B,0xC4,0x01,0x00,
--- a/Fonts/BPG_Arial31x32.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/Fonts/BPG_Arial31x32.h	Sun Jan 17 22:16:37 2016 +0000
@@ -1,3 +1,4 @@
+//Manually adjusted the ' ' (space) to be 8-pix wide
 
 //Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
 //MikroElektrnika 2011 
@@ -13,7 +14,7 @@
    0x7F,0x00,
    0x20,
    0x00,
-   0x01,0x88,0x01,0x00,
+   0x08,0x88,0x01,0x00,
    0x06,0xA8,0x01,0x00,
    0x0A,0xC8,0x01,0x00,
    0x11,0x08,0x02,0x00,
--- a/Fonts/BPG_Arial63x63.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/Fonts/BPG_Arial63x63.h	Sun Jan 17 22:16:37 2016 +0000
@@ -1,3 +1,4 @@
+//Manually adjusted the ' ' (space) to be 8-pix wide
 
 //Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
 //MikroElektrnika 2011 
@@ -13,7 +14,7 @@
    0x7F,0x00,
    0x3F,
    0x00,
-   0x01,0x88,0x01,0x00,
+   0x08,0x88,0x01,0x00,
    0x0C,0xC7,0x01,0x00,
    0x14,0x45,0x02,0x00,
    0x23,0x02,0x03,0x00,
--- a/GraphicsDisplay.cpp	Sat Dec 19 15:55:09 2015 +0000
+++ b/GraphicsDisplay.cpp	Sun Jan 17 22:16:37 2016 +0000
@@ -93,7 +93,7 @@
 
 int GraphicsDisplay::character(int x, int y, int c)
 {
-    return fontblit(x, y, font, c);
+    return fontblit(x, y, c);
 }
 
 RetCode_t GraphicsDisplay::window(loc_t x, loc_t y, dim_t w, dim_t h)
@@ -165,7 +165,9 @@
 //0x00,...             // ' ' data stream.
 //0x00,0x06,0x00,0x07,0x80,0x07,0xC0,0x07,0xC0,0x07,0xC0 // '!'
 //...
-int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char c)
+
+
+const uint8_t * GraphicsDisplay::getCharMetrics(const unsigned char c, uint8_t * width, uint8_t * height)
 {
     uint16_t offsetToCharLookup;
     uint16_t firstChar = font[3] * 256 + font[2];
@@ -175,42 +177,74 @@
     
     INFO("first:%d, last:%d, c:%d", firstChar, lastChar, c);
     if (c < firstChar || c > lastChar)
+        return NULL;       // advance zero pixels since it was unprintable...
+    
+    // 8 bytes of preamble to the first level lookup table
+    offsetToCharLookup = 8 + 4 * (c - firstChar);    // 4-bytes: width(pixels), 16-bit offset from table start, 0
+    uint8_t charWidth = font[offsetToCharLookup];
+    charRecord = font + font[offsetToCharLookup + 2] * 256 + font[offsetToCharLookup + 1];
+    //INFO("hgt:%d, wdt:%d", charHeight, charWidth);
+    if (width)
+        *width = charWidth;
+    if (height)
+        *height = charHeight;
+    return charRecord;
+}
+
+int GraphicsDisplay::fontblit(int x, int y, const unsigned char c)
+{
+    #if 0
+    uint16_t offsetToCharLookup;
+    uint16_t firstChar = font[3] * 256 + font[2];
+    uint16_t lastChar  = font[5] * 256 + font[4];
+    uint8_t charHeight = font[6];
+    const unsigned char * charRecord;   // width, data, data, data, ...
+    
+    INFO("first:%d, last:%d, c:%d", firstChar, lastChar, c);
+    if (c < firstChar || c > lastChar)
         return 0;       // advance zero pixels since it was unprintable...
     
     // 8 bytes of preamble to the first level lookup table
     offsetToCharLookup = 8 + 4 * (c - firstChar);    // 4-bytes: width(pixels), 16-bit offset from table start, 0
     uint8_t charWidth = font[offsetToCharLookup];
     charRecord = font + font[offsetToCharLookup + 2] * 256 + font[offsetToCharLookup + 1];
-
-    INFO("hgt:%d, wdt:%d", charHeight, charWidth);
-    // clip to the edge of the screen
-    //if (x + charWidth >= width())
-    //    charWidth = width() - x;
-    //if (y + charHeight >= height())
-    //    charHeight = height() - y;
-    window(x, y, charWidth, charHeight);
-    _StartGraphicsStream();
-    while (charHeight--) {
-        uint8_t pixels = charWidth;
-        uint8_t bitmask = 0x01;
-        
-        while (pixels) {
-            uint8_t byte = *charRecord;
-            INFO("byte, mask: %02X, %02X", byte, bitmask);
-            color_t c = (byte & bitmask) ? _foreground : _background;
-            _putp(c);
-            bitmask <<= 1;
-            if (pixels > 1 && bitmask == 0) {
-                bitmask = 0x01;
-                charRecord++;
+#endif
+    const unsigned char * charRecord;   // width, data, data, data, ...
+    uint8_t charWidth, charHeight;
+    charRecord = getCharMetrics(c, &charWidth, &charHeight);
+    if (charRecord) {
+        INFO("hgt:%d, wdt:%d", charHeight, charWidth);
+        // clip to the edge of the screen
+        //if (x + charWidth >= width())
+        //    charWidth = width() - x;
+        //if (y + charHeight >= height())
+        //    charHeight = height() - y;
+        window(x, y, charWidth, charHeight);
+        _StartGraphicsStream();
+        while (charHeight--) {
+            uint8_t pixels = charWidth;
+            uint8_t bitmask = 0x01;
+            
+            while (pixels) {
+                uint8_t byte = *charRecord;
+                INFO("byte, mask: %02X, %02X", byte, bitmask);
+                color_t c = (byte & bitmask) ? _foreground : _background;
+                _putp(c);
+                bitmask <<= 1;
+                if (pixels > 1 && bitmask == 0) {
+                    bitmask = 0x01;
+                    charRecord++;
+                }
+                pixels--;
             }
-            pixels--;
+            charRecord++;
         }
-        charRecord++;
+        _EndGraphicsStream();
+        WindowMax();
+        return charWidth;
+    } else {
+        return 0;
     }
-    _EndGraphicsStream();
-    WindowMax();
-    return charWidth;
 }
 
 // BMP Color Palette is BGRx
--- a/GraphicsDisplay.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/GraphicsDisplay.h	Sun Jan 17 22:16:37 2016 +0000
@@ -192,21 +192,37 @@
     
     virtual RetCode_t blit(int x, int y, int w, int h, const int * color);    
     
+    /// This method returns the width in pixels of the chosen character
+    /// from the previously selected external font.
+    ///
+    /// @param[in] c is the character of interest.
+    /// @param[inout] width is a pointer to where the width will be stored.
+    ///     This parameter is NULL tested and will only be written if not null
+    ///     which is convenient if you only want the height.
+    /// @param[inout] height is a pointer to where the height will be stored.
+    ///     This parameter is NULL tested and will only be written if not null
+    ///     which is convenient if you only want the width.
+    /// @returns a pointer to the raw character data or NULL if not found.
+    ///
+    virtual const uint8_t * getCharMetrics(const unsigned char c, uint8_t * width, uint8_t * height);
+    
     /// This method transfers one character from the external font data
     /// to the screen.
     ///
+    /// The font being used has already been set with the SelectUserFont
+    /// API.
+    ///
     /// @note the font data is in a special format as generate by
     ///         the mikroe font creator.
     ///         See http://www.mikroe.com/glcd-font-creator/
     ///
     /// @param[in] x is the horizontal pixel coordinate
     /// @param[in] y is the vertical pixel coordinate
-    /// @param[in] fontTable is the base of the table which has the metrics
     /// @param[in] c is the character to render
     /// @returns how far the cursor should advance to the right in pixels.
     /// @returns zero if the character could not be rendered.
     ///
-    virtual int fontblit(int x, int y, const unsigned char * fontTable, const unsigned char c);
+    virtual int fontblit(int x, int y, const unsigned char c);
     
     /// This method returns the color value from a palette.
     ///
--- a/RA8875.cpp	Sat Dec 19 15:55:09 2015 +0000
+++ b/RA8875.cpp	Sun Jan 17 22:16:37 2016 +0000
@@ -803,6 +803,13 @@
 }
 
 
+
+// Questions to ponder -
+// - if we choose to wrap to the next line, because the character won't fit on the current line,
+//      should it erase the space to the width of the screen (in case there is leftover junk there)?
+// - it currently wraps from the bottom of the screen back to the top. I have pondered what
+//      it might take to scroll the screen - but haven't thought hard enough about it.
+//
 int RA8875::_external_putc(int c)
 {
     if (c) {
@@ -811,17 +818,23 @@
         } else if (c == '\n') {
             cursor_y += extFontHeight;
         } else {
-            int advance = character(cursor_x, cursor_y, c);     // advance tells us how many pixels we advanced
-            INFO("x,y,advance %d,%d,%d '%c", cursor_x, cursor_y, advance, c);
-            if (advance) {
-                cursor_x += advance;
-                if (cursor_x >= width()) {
+            uint8_t charWidth, charHeight;
+            const uint8_t * charRecord;
+            
+            charRecord = getCharMetrics(c, &charWidth, &charHeight);
+            //int advance = charwidth(c);
+            INFO("(%d,%d) ,charWidth: %d '%c", cursor_x, cursor_y, charWidth, c);
+            if (charRecord) {
+                //cursor_x += advance;
+                if (cursor_x + charWidth >= width()) {
                     cursor_x = 0;
-                    cursor_y += extFontHeight;
-                    if (cursor_y >= height()) {
-                        cursor_y = 0;               // @todo Should it scroll?
-                    }
+                    cursor_y += charHeight;
                 }
+                if (cursor_y + charHeight >= height()) {
+                    cursor_y = 0;               // @todo Should it scroll?
+                }
+                (void)character(cursor_x, cursor_y, c);
+                cursor_x += charWidth;
             }
         }
     }
--- a/RA8875.h	Sat Dec 19 15:55:09 2015 +0000
+++ b/RA8875.h	Sun Jan 17 22:16:37 2016 +0000
@@ -8,8 +8,13 @@
 /// It includes graphics acceleration capabilities for drawing primitives, 
 /// such as line, rectangle, circles, and more.
 ///
+/// It is not a display for super-fast animations, video, picture frames and so forth,
+/// at least when using the SPI ports. Performance has not been evaluated with one
+/// of the parallel port options.
+///
 /// The controller additionally supports backlight control (via PWM), keypad scanning
-/// (for a 4 x 5 matrix) and resistive touch-panel support. 
+/// (for a 4 x 5 matrix) and resistive touch-panel support. Others have provides
+/// support for a capacitive touch screen.
 ///
 /// @section Display_Config Display Configuration
 ///
@@ -53,6 +58,13 @@
 /// The keypad has a default keypad mapping, but there is an API that permits
 /// installing a custom keymap.
 ///
+/// @todo Add APIs for the 2nd PWM channel, which might be quite useful as a simple
+///     beeper.
+/// @todo Figure out how to "init()" in the constructor. 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 constructor
+///     was within main(), then it seemed to work as expected.
+///
 #ifndef RA8875_H
 #define RA8875_H
 #include <mbed.h>
@@ -1994,18 +2006,25 @@
 
     /// Internal function to put a character using the built-in (internal) font engine
     ///
-    /// @param[in] is the character to put to the screen.
+    /// @param[in] c is the character to put to the screen.
     /// @returns the character put.
     ///
     int _internal_putc(int c);
     
     /// Internal function to put a character using the external font engine
     ///
-    /// @param[in] is the character to put to the screen.
+    /// @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);
+    
     /// Select the peripheral to use it.
     ///
     /// @param[in] chipsel when true will select the peripheral, and when false
@@ -2171,6 +2190,7 @@
 //     pc.printf("\r\nRA8875 Test - Build " __DATE__ " " __TIME__ "\r\n");
 // 
 //     pc.printf("Turning on display\r\n");
+//     lcd.init();
 //     lcd.Reset();
 //     lcd.Power(true);  // display power is on, but the backlight is independent
 //     lcd.Backlight(0.5);