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

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

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

Offline Help Manual (Windows chm)

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

Revision:
202:a22cbc04f332
Parent:
200:ae29b60d087c
Child:
203:704df2dbd3e6
--- a/RA8875.cpp	Sun Mar 29 18:12:24 2020 +0000
+++ b/RA8875.cpp	Thu Apr 30 13:51:32 2020 +0000
@@ -736,8 +736,8 @@
 
 bool RA8875::Intersect(rect_t rect, point_t p)
 {
-    if (p.x >= min(rect.p1.x, rect.p2.x) && p.x <= max(rect.p1.x, rect.p2.x)
-    && p.y >= min(rect.p1.y, rect.p2.y) && p.y <= max(rect.p1.y, rect.p2.y))
+    if (p.x >= RAmin(rect.p1.x, rect.p2.x) && p.x <= RAmax(rect.p1.x, rect.p2.x)
+    && p.y >= RAmin(rect.p1.y, rect.p2.y) && p.y <= RAmax(rect.p1.y, rect.p2.y))
         return true;
     else
         return false;
@@ -748,12 +748,12 @@
 {
 #if 1
     // If one rectangle is on left side of other
-    if (max(rect1.p1.x,rect1.p2.x) < min(rect2.p1.x,rect2.p2.x)
-        || min(rect1.p1.x, rect1.p2.x) > max(rect2.p1.x, rect2.p2.x))
+    if (RAmax(rect1.p1.x,rect1.p2.x) < RAmin(rect2.p1.x,rect2.p2.x)
+        || RAmin(rect1.p1.x, rect1.p2.x) > RAmax(rect2.p1.x, rect2.p2.x))
         return false;
     // If one rectangle is above other
-    if (max(rect1.p1.y, rect1.p2.y) < min(rect2.p1.y, rect2.p2.y)
-        || min(rect1.p1.y, rect1.p2.y) > max(rect2.p1.y, rect2.p2.y))
+    if (RAmax(rect1.p1.y, rect1.p2.y) < RAmin(rect2.p1.y, rect2.p2.y)
+        || RAmin(rect1.p1.y, rect1.p2.y) > RAmax(rect2.p1.y, rect2.p2.y))
         return false;
     return true;            // all that's left is they overlap
 #else
@@ -776,10 +776,10 @@
     if (Intersect(*pRect1, *pRect2)) {
         rect_t iSect;
 
-        iSect.p1.x = max(min(pRect1->p1.x,pRect1->p2.x),min(pRect2->p1.x,pRect2->p2.x));
-        iSect.p1.y = max(min(pRect1->p1.y,pRect1->p2.y),min(pRect2->p1.y,pRect2->p2.y));
-        iSect.p2.x = min(max(pRect1->p1.x,pRect1->p2.x),max(pRect2->p1.x,pRect2->p2.x));
-        iSect.p2.y = min(max(pRect1->p1.y,pRect1->p2.y),max(pRect2->p1.y,pRect2->p2.y));
+        iSect.p1.x = RAmax(RAmin(pRect1->p1.x,pRect1->p2.x),RAmin(pRect2->p1.x,pRect2->p2.x));
+        iSect.p1.y = RAmax(RAmin(pRect1->p1.y,pRect1->p2.y),RAmin(pRect2->p1.y,pRect2->p2.y));
+        iSect.p2.x = RAmin(RAmax(pRect1->p1.x,pRect1->p2.x),RAmax(pRect2->p1.x,pRect2->p2.x));
+        iSect.p2.y = RAmin(RAmax(pRect1->p1.y,pRect1->p2.y),RAmax(pRect2->p1.y,pRect2->p2.y));
         *pRect1 = iSect;
         return true;
     } else {
@@ -1073,20 +1073,23 @@
 point_t RA8875::SetTextCursor(loc_t x, loc_t y)
 {
     point_t oldCursor = GetTextCursor();
-    cursor_x = x;     // set these values for non-internal fonts
-    cursor_y = y;
-    switch (screen_orientation) {
-    default:
-    case rotate_0:
-    case rotate_180:
-        WriteCommandW(RA8875_FCURXL, x);
-        WriteCommandW(RA8875_FCURYL, y);
-        break;
-    case rotate_90:
-    case rotate_270:
-        WriteCommandW(RA8875_FCURXL, y);
-        WriteCommandW(RA8875_FCURYL, x);
-        break;
+    if (x >= 0 && x <= virt_screenwidth
+        && y >= 0 && y <= virt_screenheight) {
+        cursor_x = x;     // set these values for non-internal fonts
+        cursor_y = y;
+        switch (screen_orientation) {
+            default:
+            case rotate_0:
+            case rotate_180:
+                WriteCommandW(RA8875_FCURXL, x);
+                WriteCommandW(RA8875_FCURYL, y);
+                break;
+            case rotate_90:
+            case rotate_270:
+                WriteCommandW(RA8875_FCURXL, y);
+                WriteCommandW(RA8875_FCURYL, x);
+                break;
+        }
     }
     return oldCursor;
 }
@@ -1186,6 +1189,32 @@
     }
 }
 
+point_t RA8875::TranslateOrientation(loc_t x, loc_t y) {
+    point_t pt;
+
+    switch (screen_orientation) {
+        default:
+        case rotate_0:
+            pt.x = x;
+            pt.y = y;
+            break;
+        case rotate_90:
+            pt.x = y;
+            pt.y = x;
+            break;
+        case rotate_180:
+            pt.x = virt_screenwidth - 1 - x;
+            pt.y = virt_screenheight - 1 - y;
+            break;
+        case rotate_270:
+            pt.x = virt_screenheight - 1 - y;
+            pt.y = virt_screenwidth - 1 - x;
+            break;
+    }
+    return pt;
+}
+
+
 orientation_t RA8875::GetGraphicsOrientation()
 {
     return screen_orientation;
@@ -1205,29 +1234,29 @@
     switch (angle) {
         case normal:
             //dpcrVal |= 0x00;
-            tempWidth = max(virt_screenwidth, virt_screenheight);
-            tempHeight = min(virt_screenwidth, virt_screenheight);
+            tempWidth = RAmax(virt_screenwidth, virt_screenheight);
+            tempHeight = RAmin(virt_screenwidth, virt_screenheight);
             break;
         case rotate_90:
             dpcrVal |= 0x08;
             mwcr0 |= 0x08;
             mrcd |= 0x02;
-            tempWidth = min(virt_screenwidth, virt_screenheight);
-            tempHeight = max(virt_screenwidth, virt_screenheight);
+            tempWidth = RAmin(virt_screenwidth, virt_screenheight);
+            tempHeight = RAmax(virt_screenwidth, virt_screenheight);
             break;
         case rotate_180:
             dpcrVal |= 0x0C;
             //mwcr0 |= 0x00;
             //mrcd |= 0x00;
-            tempWidth = max(virt_screenwidth, virt_screenheight);
-            tempHeight = min(virt_screenwidth, virt_screenheight);
+            tempWidth = RAmax(virt_screenwidth, virt_screenheight);
+            tempHeight = RAmin(virt_screenwidth, virt_screenheight);
             break;
         case rotate_270:
             dpcrVal |= 0x04;
             mwcr0 |= 0x08;
             mrcd |= 0x02;
-            tempWidth = min(virt_screenwidth, virt_screenheight);
-            tempHeight = max(virt_screenwidth, virt_screenheight);
+            tempWidth = RAmin(virt_screenwidth, virt_screenheight);
+            tempHeight = RAmax(virt_screenwidth, virt_screenheight);
             break;
         default:
             return invalid;
@@ -1264,6 +1293,7 @@
         return invalid;
     }
     WriteCommand(RA8875_FNCR1, fncr1Val);
+    text_orientation = angle;
     return oldAngle;
 }
 
@@ -1355,6 +1385,58 @@
     }
 }
 
+rect_t RA8875::GetTextRect(const char* text, bool charOnly) {
+    rect_t rect = { 0, 0, 0, 0 };
+
+    if (charOnly) {
+        if (font == NULL) {
+            rect.p2.x = fontwidth();
+            rect.p2.y = fontheight();
+        } else {
+            dim_t cWidth, cHeight;
+            if (getCharMetrics(*text, &cWidth, &cHeight)) {
+                rect.p2.x = cWidth;
+                rect.p2.y = cHeight;
+            }
+        }
+    } else {
+        rect.p2.y = fontheight();
+        const char* p = text;
+        dim_t curX = 0;
+        while (*p) {
+            rect_t cRect = GetTextRect(p, true);
+            switch (*p) {
+                case '\r':
+                    curX = 0;
+                    break;
+                case '\n':
+                    rect.p2.y += cRect.p2.y;
+                    break;
+                default:
+                    if ((curX + cRect.p2.x) >= virt_screenwidth) {
+                        rect.p2.x = virt_screenwidth - 1;
+                        curX = cRect.p2.x;
+                        if ((rect.p2.y + cRect.p2.y) > virt_screenheight) {
+                            rect.p2.y = virt_screenheight - 1;
+                        } else {
+                            rect.p2.y += cRect.p2.y;
+                        }
+                    } else {
+                        curX += cRect.p2.x;
+                        if (curX > rect.p2.x)
+                            rect.p2.x = curX;
+                    }
+                    break;
+            }
+            if (rect.p2.y >= virt_screenheight - 1)
+                break;
+            p++;
+        }
+    }
+    return rect;
+}
+
+
 int RA8875::_putc(int c)
 {
     if (font == NULL) {
@@ -1649,8 +1731,8 @@
     switch (screen_orientation) {
     case rotate_0:
     case rotate_180:
-        tempWidth = max(virt_screenwidth, virt_screenheight);
-        tempHeight = min(virt_screenwidth, virt_screenheight);
+        tempWidth = RAmax(virt_screenwidth, virt_screenheight);
+        tempHeight = RAmin(virt_screenwidth, virt_screenheight);
         virt_screenwidth = tempWidth;
         virt_screenheight = tempHeight;
         //GraphicsDisplay::SetWindow(x1, y1, x2, y2);
@@ -1661,8 +1743,8 @@
         break;
     case rotate_90:
     case rotate_270:
-        tempWidth = min(virt_screenwidth, virt_screenheight);
-        tempHeight = max(virt_screenwidth, virt_screenheight);
+        tempWidth = RAmin(virt_screenwidth, virt_screenheight);
+        tempHeight = RAmax(virt_screenwidth, virt_screenheight);
         virt_screenwidth = tempWidth;
         virt_screenheight = tempHeight;
         //GraphicsDisplay::SetWindow(x1, y1, x2, y2);
@@ -3569,7 +3651,7 @@
     for (i=0; i<16; i++) {
         x1 = 300 + rand() % 100;
         y1 = 70 + rand() % 200;
-        r1 = rand() % min(y1 - 20, 100);
+        r1 = rand() % RAmin(y1 - 20, 100);
         display.circle(x1,y1,r1, display.DOSColor(i));
         if (!SuppressSlowStuff)
             wait_us(20000);
@@ -3703,13 +3785,13 @@
     for (i=0; i<16; i++) {
         x = 100 + rand() % 100;
         y = 70 + rand() % 200;
-        r1 = rand() % min(y - 20, 100);
+        r1 = rand() % RAmin(y - 20, 100);
         //pc.printf("  (%d,%d) - %d\r\n", x,y,r1);
         display.circle(x,y,r1, display.DOSColor(i));
 
         x = 300 + rand() % 100;
         y = 70 + rand() % 200;
-        r1 = rand() % min(y - 20, 100);
+        r1 = rand() % RAmin(y - 20, 100);
         //pc.printf("  (%d,%d) - %d FILL\r\n", x,y,r1);
         display.circle(x,y,r1, display.DOSColor(i), FILL);
     }
@@ -3729,14 +3811,14 @@
     for (i=0; i<16; i++) {
         x = 100 + rand() % 100;
         y = 70 + rand() % 200;
-        r1 = rand() % min(y - 20, 100);
-        r2 = rand() % min(y - 20, 100);
+        r1 = rand() % RAmin(y - 20, 100);
+        r2 = rand() % RAmin(y - 20, 100);
         display.ellipse(x,y,r1,r2, display.DOSColor(i));
 
         x = 300 + rand() % 100;
         y = 70 + rand() % 200;
-        r1 = rand() % min(y - 20, 100);
-        r2 = rand() % min(y - 20, 100);
+        r1 = rand() % RAmin(y - 20, 100);
+        r2 = rand() % RAmin(y - 20, 100);
         display.ellipse(x,y,r1,r2, FILL);
     }
 }