add glyph blit operatin to gcld
authorJim Morris <morris@wolfman.com>
Fri, 2 Aug 2013 07:23:40 +0000 (00:23 -0700)
committerJim Morris <morris@wolfman.com>
Fri, 2 Aug 2013 07:25:40 +0000 (00:25 -0700)
add hotend, bed and fan icons to watch screen for graphical controllers

src/modules/utils/panel/Panel.cpp
src/modules/utils/panel/panels/LcdBase.h
src/modules/utils/panel/panels/ReprapDiscountGLCD.cpp
src/modules/utils/panel/panels/ReprapDiscountGLCD.h
src/modules/utils/panel/panels/rrdglcd/RrdGlcd.cpp
src/modules/utils/panel/panels/rrdglcd/RrdGlcd.h
src/modules/utils/panel/screens/WatchScreen.cpp

index b24f328..64d0586 100644 (file)
@@ -167,17 +167,17 @@ void Panel::on_idle(void* argument){
         if(this->lcd->hasGraphics()) {
             // TODO display nifty graphics startup screen
 
-        }else{
-            Version v;
-            string build(v.get_build());
-            string date(v.get_build_date());
-            this->lcd->clear();
-            this->lcd->setCursor(0,0); this->lcd->printf("Welcome to Smoothie");
-            this->lcd->setCursor(0,1); this->lcd->printf("%s", build.substr(0, 20).c_str());
-            this->lcd->setCursor(0,2); this->lcd->printf("%s", date.substr(0, 20).c_str());
-            this->lcd->setCursor(0,3); this->lcd->printf("Please wait....");
         }
 
+        Version v;
+        string build(v.get_build());
+        string date(v.get_build_date());
+        this->lcd->clear();
+        this->lcd->setCursor(0,0); this->lcd->printf("Welcome to Smoothie");
+        this->lcd->setCursor(0,1); this->lcd->printf("%s", build.substr(0, 20).c_str());
+        this->lcd->setCursor(0,2); this->lcd->printf("%s", date.substr(0, 20).c_str());
+        this->lcd->setCursor(0,3); this->lcd->printf("Please wait....");
+
         this->lcd->on_refresh(true); // tell lcd to display now
 
         // Default top screen
index 30dd778..402cd5f 100644 (file)
@@ -106,8 +106,7 @@ class LcdBase {
         virtual void setLedBrightness(int led, int val){};
         virtual void buzz(long,uint16_t){};
         virtual bool hasGraphics() { return false; }
-        virtual void bltGlyph(int x, int y, const uint8_t *glyph, int size){};
-
+        virtual void bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span= 0, int x_offset=0, int y_offset=0){}
         // only used on certain panels
         virtual void on_refresh(bool now= false){};
         virtual void on_main_loop(){};
index d01a841..ac2fc7b 100644 (file)
@@ -100,8 +100,24 @@ void ReprapDiscountGLCD::init(){
     this->glcd->initDisplay();
 }
 
-void ReprapDiscountGLCD::bltGlyph(int x, int y, int w, int h, const uint8_t *glyph) {
-    // TODO
+// displays a selectable rectangle from the glyph
+void ReprapDiscountGLCD::bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span, int x_offset, int y_offset) {
+    if(x_offset == 0 && y_offset == 0 && span == 0) {
+        // blt the whole thing
+        this->glcd->renderGlyph(x, y, glyph, w, h);
+
+    }else{
+        // copy portion of glyph into g where x_offset is left byte aligned
+        // Note currently thw x_offset must be byte aligned
+        int n= w/8; // bytes per line to copy
+        if(w%8 != 0) n++; // round up to next byte
+        uint8_t g[n*h];
+
+        for (int i = 0; i < h; ++i) {
+            memcpy(&g[i*n], &glyph[(i+y_offset)*span+x_offset/8], n);
+        }
+        this->glcd->renderGlyph(x, y, g, w, h);
+    }
 }
 
 void ReprapDiscountGLCD::on_refresh(bool now){
index 12c6c2c..83e1e46 100644 (file)
@@ -29,7 +29,7 @@ class ReprapDiscountGLCD : public LcdBase {
         virtual ~ReprapDiscountGLCD();
 
         int getEncoderResolution() { return 2; }
-        bool hasGraphics() { return false; }
+        bool hasGraphics() { return true; }
         uint16_t get_screen_lines() { return 8; }
 
         uint8_t readButtons();
@@ -41,8 +41,10 @@ class ReprapDiscountGLCD : public LcdBase {
         void setCursor(uint8_t col, uint8_t row);
         void init();
         void buzz(long,uint16_t);
-        // blit a glyph of w pixels wide and h pixels high to x,y. The glyph will be zero left padded bytes from top left to bottom right
-        void bltGlyph(int x, int y, int w, int h, const uint8_t *glyph);
+        // blit a glyph of w pixels wide and h pixels high to x, y. offset pixel position in glyph by x_offset, y_offset.
+        // span is the width in bytes of the src bitmap
+        // The glyph bytes will be 8 bits of X pixels, msbit->lsbit from top left to bottom right
+        void bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span= 0, int x_offset=0, int y_offset=0);
         void on_refresh(bool now=false);
 
     private:
index f26f0a9..fb3c95e 100644 (file)
@@ -325,14 +325,15 @@ void RrdGlcd::displayString(int row, int col, const char *ptr, int length) {
 }
 
 void RrdGlcd::renderChar(uint8_t *fb, char c, int ox, int oy) {
+    // using the specific font data where y is in consecutive bytes and x is each bit position lsbit->msbit
     int i= c*5;
     for(int y=0;y<8;y++) {
       for(int x=0;x<5;x++) {
         int b= font5x7[i+x];
         if((b & (1<<(y))) != 0){
-            fb[(y+oy)*16 + (x+ox)/8] |= (1<<(8-(x+ox)%8-1));
+            fb[(y+oy)*16 + (x+ox)/8] |= (1<<(7-(x+ox)%8));
         }else{
-            fb[(y+oy)*16 + (x+ox)/8] &= ~(1<<(8-(x+ox)%8-1));
+            fb[(y+oy)*16 + (x+ox)/8] &= ~(1<<(7-(x+ox)%8));
         }
       }
     }
@@ -342,7 +343,26 @@ void RrdGlcd::displayChar(int row, int col, char c) {
     // convert row/column into y and x pixel positions based on font size
     renderChar(this->fb, c, col*6, row*8);
 }
-   
+
+void RrdGlcd::renderGlyph(int xp, int yp, const uint8_t *g, int pixelWidth, int pixelHeight) {
+    for(int y=0;y<pixelHeight;y++) {
+        int m= 0x80;
+        int b= *g++;
+        for(int x=0;x<pixelWidth;x++) {
+            if((b & m) != 0){
+                fb[(y+yp)*16 + (x+xp)/8] |= (1<<(7-(x+xp)%8));
+            }else{
+                fb[(y+yp)*16 + (x+xp)/8] &= ~(1<<(7-(x+xp)%8));
+            }
+            m= m>>1;
+            if(m == 0){
+                m= 0x80;
+                b= *g++;
+            } 
+        }
+    }
+}
+
 // copy frame buffer to graphic buffer on display
 void RrdGlcd::fillGDRAM(const uint8_t *bitmap) {
     unsigned char i, y;
index 907e2cd..d3dc32e 100644 (file)
@@ -36,7 +36,7 @@ public:
 
     void initDisplay(void);
     void clearScreen(void);
-    void displayString(int Row, int Column, const char *ptr, int length);
+    void displayString(int row, int column, const char *ptr, int length);
     void refresh();
 
      /**
@@ -47,12 +47,15 @@ public:
     *
     */
     void fillGDRAM(const uint8_t *bitmap);
-    
+
+    // copy the bits in g, of X line size pixels, to x, y in frame buffer
+    void renderGlyph(int x, int y, const uint8_t *g, int pixelWidth, int pixelHeight);
+
 private:
     Pin cs;
     mbed::SPI* spi;
     void renderChar(uint8_t *fb, char c, int ox, int oy);
-    void displayChar(int Row, int Column,char inpChr);
+    void displayChar(int row, int column,char inpChr);
 
     uint8_t fb[1024];
     bool inited;
index 667f22a..82ab10a 100644 (file)
 
 #include <string>
 using namespace std;
+static const uint8_t icons[] = { // 115x19 - 3 bytes each: he1, he2, he3, bed, fan
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xE0,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0xE0,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x0C,0x60,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x0E,0x20,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4F,0x0F,0x20,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x0F,0xA0,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x07,0xA0,
+0x7F,0x80,0x00,0x3F,0xC0,0x00,0x3F,0xC0,0x00,0x41,0x04,0x00,0x40,0x60,0x20,
+0xFB,0xC0,0x00,0x79,0xE0,0x00,0x79,0xE0,0x00,0x20,0x82,0x00,0x40,0xF0,0x20,
+0xF3,0xC0,0x00,0x76,0xE0,0x00,0x76,0xE0,0x00,0x20,0x82,0x00,0x40,0xF0,0x20,
+0xEB,0xC0,0x00,0x7E,0xE0,0x00,0x7E,0xE0,0x00,0x41,0x04,0x00,0x40,0x60,0x20,
+0x7B,0x80,0x00,0x3D,0xC0,0x00,0x39,0xC0,0x00,0x82,0x08,0x00,0x5E,0x07,0xA0,
+0x7B,0x80,0x00,0x3B,0xC0,0x00,0x3E,0xC0,0x01,0x04,0x10,0x00,0x5F,0x0F,0xA0,
+0xFB,0xC0,0x00,0x77,0xE0,0x00,0x76,0xE0,0x01,0x04,0x10,0x00,0x4F,0x0F,0x20,
+0xFB,0xC0,0x00,0x70,0xE0,0x00,0x79,0xE0,0x00,0x82,0x08,0x00,0x47,0x0E,0x20,
+0xFF,0xC0,0x00,0x7F,0xE0,0x00,0x7F,0xE0,0x00,0x41,0x04,0x00,0x63,0x0C,0x60,
+0x3F,0x00,0x00,0x1F,0x80,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,0x70,0x00,0xE0,
+0x1E,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x01,0xFF,0xFF,0x80,0x7F,0xFF,0xE0,
+0x0C,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x01,0xFF,0xFF,0x80,0x00,0x00,0x00
+};
 
 WatchScreen::WatchScreen(){
     speed_changed= false;
@@ -51,7 +72,7 @@ void WatchScreen::on_refresh(){
             this->panel->reset_counter();
         }else{
             // change actual speed
-            this->speed_changed= true; // flag main loop to isseu g code
+            this->speed_changed= true; // flag main loop to issue g code
             this->refresh_screen(false);
         }
     }
@@ -74,6 +95,22 @@ void WatchScreen::on_refresh(){
         this->panel->lcd->setLed(LED_BED_ON, this->bedtarget > 0);
         this->panel->lcd->setLed(LED_HOTEND_ON, this->hotendtarget > 0);
         //this->panel->lcd->setLed(LED_FAN_ON, this->fanon);
+
+        if(this->panel->lcd->hasGraphics()) {
+            // display the graphical icons below the status are
+            //this->panel->lcd->bltGlyph(0, 34, 115, 19, icons);
+            // for (int i = 0; i < 5; ++i) {
+            //     this->panel->lcd->bltGlyph(i*24, 38, 23, 19, icons, 15, i*24, 0);
+            // }
+            if(this->hotendtarget > 0)
+                this->panel->lcd->bltGlyph(8, 38, 20, 19, icons, 15, 0, 0);
+
+            if(this->bedtarget > 0)
+                this->panel->lcd->bltGlyph(32, 38, 23, 19, icons, 15, 64, 0);
+            
+            // fan always on for now
+            this->panel->lcd->bltGlyph(96, 38, 23, 19, icons, 15, 96, 0);
+        }
     }
 }