Index: apps/gui/gwps-common.c
===================================================================
--- apps/gui/gwps-common.c.orig
+++ apps/gui/gwps-common.c
@@ -1599,6 +1599,42 @@ static void format_display(struct gui_wp
                 }
                 fmt += 8;
                 break;
+            case 'e': /* Line settings (x/y/width and font face */
+        	fmt++;
+        	if (*fmt == '|') {
+        	    char *p=strchr(fmt, '|');
+        	    if (p) {
+        		fmt = ++p;
+        		gwps->data->line_xpos = atoi(p);
+        		p = strchr(p, '|');
+        		if (p) {
+        		    fmt = ++p;
+        		    gwps->data->line_ypos = atoi(p);
+        		    p = strchr(p, '|');
+        		    if (p) {
+        			fmt = ++p;
+        			gwps->data->line_width = atoi(p);
+        			p = strchr(p, '|');
+        			if (p) {
+        			    fmt = ++p;
+        			    gwps->data->line_font = atoi(p);
+        			    p = strchr(p, '|');
+        			    if (p) {
+        				fmt = ++p;
+        				char fg_color[7];
+        				snprintf(fg_color, 7, "%s", p);
+        				gwps->data->line_fgcolor = hex_to_rgb(fg_color);
+        				p = strchr(p, '|');
+        				if (p) {
+        				    fmt = ++p;
+        				}
+        			    }
+        			}
+        		    }
+        		}
+        	    }
+        	}
+        	break;
             case 'a':
                 ++fmt;
                 /* remember where the current aligned text started */
@@ -2256,6 +2292,46 @@ bool gui_wps_refresh(struct gui_wps *gwp
             }
 #endif
 #ifdef HAVE_LCD_BITMAP
+	    /* If need to refresh a line and we have a custom font we
+	       should set the font face prior getting the font size */
+            if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC | WPS_REFRESH_SCROLL))
+            {
+	        	if (((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC|WPS_REFRESH_SCROLL)) ||
+    	    	    new_subline_refresh) && 
+        		    ((int)data->line_xpos || (int)data->line_ypos ||
+        		     (int)data->line_width || (int)data->line_font))
+	        	{
+    	    	    if (data->line_font_prev != data->line_font) {
+        				switch (data->line_font) 
+        				{
+        			    	case 1:
+	        				display->setfont(FONT_USER1);
+    	    				break;
+        				    case 2:
+		        			display->setfont(FONT_USER2);
+        					break;
+        				    case 3:
+		        			display->setfont(FONT_USER3);
+        					break;
+        				    case 4:
+		        			display->setfont(FONT_USER4);
+        					break;
+        				    case 5:
+		        			display->setfont(FONT_USER5);
+        					break;
+        				    case 6:
+		        			display->setfont(FONT_USER6);
+        					break;
+        				    case 7:
+		        			display->setfont(FONT_USER7);
+        					break;
+        				}
+        		
+		        		data->line_font_prev = data->line_font;
+    	    	    }
+    	    	}
+    	    }
+        	    
             /* calculate different string sizes and positions */
             display->getstringsize((unsigned char *)" ", &space_width, &string_height);
             if (data->format_align[i][data->curr_subline[i]].left != 0) {
@@ -2266,9 +2342,15 @@ bool gui_wps_refresh(struct gui_wps *gwp
             else {
                 left_width = 0;
             }
-            left_xpos = display->getleftmargin();
-
-            if (data->format_align[i][data->curr_subline[i]].center != 0) {
+			
+			if(data->line_xpos){
+				left_xpos=data->line_xpos;
+			}
+			else {
+				left_xpos = display->getleftmargin();
+			}
+            
+			if (data->format_align[i][data->curr_subline[i]].center != 0) {
                 display->getstringsize((unsigned char *)data->format_align[i]
                                        [data->curr_subline[i]].center,
                                        &center_width, &string_height);
@@ -2276,8 +2358,13 @@ bool gui_wps_refresh(struct gui_wps *gwp
             else {
                 center_width = 0;
             }
-            center_xpos=(display->getrightmargin()-display->getleftmargin() - center_width) / 2 + display->getleftmargin();
-
+			if(data->line_xpos){
+				center_xpos=(data->line_width - center_width) / 2 + data->line_xpos;
+			}
+			else {
+				center_xpos=(display->getrightmargin()-display->getleftmargin() - center_width) / 2 + display->getleftmargin();
+			}
+			
             if (data->format_align[i][data->curr_subline[i]].right != 0) {
                 display->getstringsize((unsigned char *)data->format_align[i]
                                        [data->curr_subline[i]].right,
@@ -2286,7 +2373,12 @@ bool gui_wps_refresh(struct gui_wps *gwp
             else {
                 right_width = 0;
             }
-            right_xpos = (display->getrightmargin() - right_width);
+			if(data->line_xpos){
+				right_xpos = (data->line_xpos+data->line_width - right_width);
+			}
+			else {
+				right_xpos = (display->getrightmargin() - right_width);
+			}
 
             /* Checks for overlapping strings.
                If needed the overlapping strings will be merged, separated by a
@@ -2378,6 +2470,85 @@ bool gui_wps_refresh(struct gui_wps *gwp
 #endif
 
             if (flags & WPS_REFRESH_SCROLL) {
+                /* Custom line with scroll capabilities */
+                if (((refresh_mode & WPS_REFRESH_SCROLL) ||
+                    new_subline_refresh) && 
+	        	    ((int)data->line_xpos || (int)data->line_ypos ||
+    	    	     (int)data->line_width || (int)data->line_font))
+    	    	{
+#ifdef HAVE_LCD_BITMAP
+					/* Clear the area first if there is something to display */
+					if (left_width || center_width || right_width) {
+						display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+						display->fillrect((int)data->line_xpos,
+							  (int)data->line_ypos,
+							  (int)data->line_width,
+							  string_height);
+						display->set_drawmode(DRMODE_SOLID);
+					}
+					
+					if (data->line_fgcolor_prev != data->line_fgcolor) {
+						lcd_set_foreground(data->line_fgcolor);
+						data->line_fgcolor_prev = data->line_fgcolor;
+					}
+					
+					display->setmargins(data->line_xpos, data->line_xpos+data->line_width,  data->line_ypos);
+					display->set_custom_width(data->line_width);
+					
+					if((left_width > display->width) || 
+						(display->get_custom_width()-display->getleftmargin() < left_width) ||
+						(display->get_custom_width()-display->getleftmargin() < center_width) ||
+						(display->get_custom_width()-display->getleftmargin() < right_width)){
+						display->puts_customline_scroll(i,
+										   (unsigned char *)data->format_align[i]
+										   [data->curr_subline[i]].left);
+
+					} else {
+						/* Nasty hack: we output an empty scrolling string,
+						   which will reset the scroller for that line */
+						display->puts_customline_scroll(i, (unsigned char *)"");
+						// MWE
+						/* Print aligned strings */
+						if (left_width != 0) 
+						{
+							DEBUGF("left line:  %s %d\n", (unsigned char *)data->format_align[i]
+									[data->curr_subline[i]].left, (int)data->line_xpos);
+									
+							display->putsxy((int)data->line_xpos,
+								(int)data->line_ypos,
+								(unsigned char *)data->format_align[i]
+								[data->curr_subline[i]].left);
+						}
+						if (center_width != 0) 
+						{
+							DEBUGF("centered line:  %s %d\n", (unsigned char *)data->format_align[i]
+									[data->curr_subline[i]].center, (int)data->line_xpos+
+									(int)((data->line_width-center_width)/2));
+
+							display->putsxy((int)data->line_xpos+
+									(int)((data->line_width-center_width)/2),
+								(int)data->line_ypos,
+								(unsigned char *)data->format_align[i]
+								[data->curr_subline[i]].center);
+						}
+						if (right_width != 0) 
+						{
+							DEBUGF("right line:  %s %d\n", (unsigned char *)data->format_align[i]
+									[data->curr_subline[i]].right, (int)data->line_xpos+
+									((int)data->line_width-right_width));
+									
+							display->putsxy((int)data->line_xpos+
+									((int)data->line_width-right_width),
+								(int)data->line_ypos,
+								(unsigned char *)data->format_align[i]
+								[data->curr_subline[i]].right);
+						}
+					}
+#else
+					display->puts_scroll(0, i, buf);
+					update_line = true;
+#endif
+    	    	} else
 
                 /* scroll line */
                 if ((refresh_mode & WPS_REFRESH_SCROLL) ||
@@ -2430,8 +2601,68 @@ bool gui_wps_refresh(struct gui_wps *gwp
 #endif
                 }
             }
+            /* Custom lines with x/y/width coordinates and font face/color */
             else if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC))
             {
+        	if (((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) ||
+        	    new_subline_refresh) && 
+        	    ((int)data->line_xpos || (int)data->line_ypos ||
+        	     (int)data->line_width || (int)data->line_font))
+        	{
+#ifdef HAVE_LCD_BITMAP
+        	    update_line = true;
+        	    
+        	    /* Clear the area first if there is something to display */
+        	    if (left_width || center_width || right_width) {
+	        	    display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+    	    	    display->fillrect((int)data->line_xpos,
+        			      (int)data->line_ypos,
+        			      (int)data->line_width,
+        			      string_height);
+        		    display->set_drawmode(DRMODE_SOLID);
+        	    }
+        	    
+				/* Nasty hack: we output an empty scrolling string,
+					which will reset the scroller for that line */
+				display->puts_scroll(0, i, (unsigned char *)"");
+								
+	       	    if (data->line_fgcolor_prev != data->line_fgcolor) {
+					lcd_set_foreground(data->line_fgcolor);
+    	    		data->line_fgcolor_prev = data->line_fgcolor;
+        	    }
+        	    
+        	    display->setmargins(data->line_xpos, data->line_xpos+data->line_width, data->line_ypos);
+        	    display->set_custom_width(data->line_width);
+        	    
+        	    /* Print aligned strings */
+        	    if (left_width != 0) 
+        	    {
+        			display->putsxy((int)data->line_xpos,
+        				(int)data->line_ypos,
+        				(unsigned char *)data->format_align[i]
+        				[data->curr_subline[i]].left);
+        	    }
+        	    if (center_width != 0) 
+        	    {
+        			display->putsxy((int)data->line_xpos+
+        					(int)((data->line_width-center_width)/2),
+        				(int)data->line_ypos,
+        				(unsigned char *)data->format_align[i]
+        				[data->curr_subline[i]].center);
+        	    }
+        	    if (right_width != 0) 
+        	    {
+        			display->putsxy((int)data->line_xpos+
+        				    ((int)data->line_width-right_width),
+        				(int)data->line_ypos,
+        				(unsigned char *)data->format_align[i]
+        				[data->curr_subline[i]].right);
+        	    }
+#else
+				update_line = true;
+				display->puts(0, i, buf);
+#endif
+        	} else
                 /* dynamic / static line */
                 if ((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) ||
                     new_subline_refresh)
@@ -2441,9 +2672,11 @@ bool gui_wps_refresh(struct gui_wps *gwp
                     update_line = true;
 
                     /* clear the line first */
-                    display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
-                    display->fillrect(0, ypos, display->width, string_height);
-                    display->set_drawmode(DRMODE_SOLID);
+                    if (left_width || center_width || right_width) { 
+	                    display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+    	                display->fillrect(0, ypos, display->width, string_height);
+        	            display->set_drawmode(DRMODE_SOLID);
+                    }
 
                     /* Nasty hack: we output an empty scrolling string,
                        which will reset the scroller for that line */
@@ -2496,6 +2729,17 @@ bool gui_wps_refresh(struct gui_wps *gwp
     /* Now we know wether the peak meter is used.
        So we can enable / disable the peak meter thread */
     data->peak_meter_enabled = enable_pm;
+    /* Reset margins */
+    data->line_xpos=0;
+    data->line_ypos=0;
+    data->line_width=0;
+    data->line_font=0;
+    /* Reset display color */
+    data->line_fgcolor_prev = 0;
+    data->line_fgcolor = global_settings.fg_color;
+	lcd_set_foreground(global_settings.fg_color);
+	// MWE reset custom width
+	display->set_custom_width(display->width);
 #endif
 
 #ifdef CONFIG_BACKLIGHT
Index: apps/gui/gwps.h
===================================================================
--- apps/gui/gwps.h.orig
+++ apps/gui/gwps.h
@@ -403,6 +403,9 @@ struct wps_data
     int progress_y; /* if 0, progress bars use up a line as before */
     bool wps_loaded;
     bool peak_meter_enabled;
+    int line_xpos, line_ypos, line_width;
+    int line_font, line_font_prev;
+    int line_fgcolor, line_fgcolor_prev;
 };
 
 /* initial setup of wps_data */
Index: apps/screen_access.h
===================================================================
--- apps/screen_access.h.orig
+++ apps/screen_access.h
@@ -124,6 +124,7 @@ struct screen
 #endif
     void (*init)(void);
     void (*puts_scroll)(int x, int y, const unsigned char *string);
+    void (*puts_customline_scroll)(int i, const unsigned char *string);
     void (*scroll_speed)(int speed);
     void (*scroll_delay)(int ms);
     void (*stop_scroll)(void);
Index: apps/screen_access.c
===================================================================
--- apps/screen_access.c.orig
+++ apps/screen_access.c
@@ -100,6 +100,7 @@ void screen_init(struct screen * screen,
 
             screen->init=&lcd_remote_init;
             screen->puts_scroll=&lcd_remote_puts_scroll;
+			screen->puts_customline_scroll=&lcd_remote_puts_customline_scroll;
             screen->stop_scroll=&lcd_remote_stop_scroll;
             screen->clear_display=&lcd_remote_clear_display;
             screen->update=&lcd_remote_update;
@@ -188,6 +189,7 @@ void screen_init(struct screen * screen,
 
             screen->init=&lcd_init;
             screen->puts_scroll=&lcd_puts_scroll;
+            screen->puts_customline_scroll=&lcd_puts_customline_scroll;
             screen->stop_scroll=&lcd_stop_scroll;
             screen->clear_display=&lcd_clear_display;
 #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
Index: firmware/export/lcd.h
===================================================================
--- firmware/export/lcd.h.orig
+++ firmware/export/lcd.h
@@ -66,6 +66,9 @@ extern void lcd_putc(int x, int y, unsig
 extern void lcd_stop_scroll(void);
 extern void lcd_scroll_speed(int speed);
 extern void lcd_scroll_delay(int ms);
+extern void lcd_puts_customline_scroll(int i, const unsigned char *string);
+extern void lcd_puts_customline_scroll_style_offset(int i, const unsigned char *string,
+											        int style, int offset);
 extern void lcd_puts_scroll(int x, int y, const unsigned char* string);
 extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string,
                                   int style);
@@ -388,6 +391,13 @@ struct scrollinfo {
     int right_margin;
     int fgcolor;
     int bgcolor;
+	/* Custome line arguments */
+	bool customline;
+	int line_font;
+	int line_xpos;
+	int line_ypos;
+	int line_width;
+	//int line_fgcolor;
 };
 #else /* !HAVE_LCD_BITMAP */
 
Index: firmware/drivers/lcd-16bit.c
===================================================================
--- firmware/drivers/lcd-16bit.c.orig
+++ firmware/drivers/lcd-16bit.c
@@ -864,6 +864,82 @@ void lcd_bidir_scroll(int percent)
     bidir_limit = percent;
 }
 
+void lcd_puts_customline_scroll(int i, const unsigned char *string)
+{
+    lcd_puts_customline_scroll_style_offset(i, string, 
+    		STYLE_DEFAULT, 0);
+}
+
+void lcd_puts_customline_scroll_style_offset(int i, 
+		const unsigned char *string, int style, int offset)
+{
+    struct scrollinfo* s;
+    int w, h;
+
+    s = &scroll[i];
+    
+    s->customline = true;
+    s->line_font = curfont;
+    s->line_xpos = lcd_getleftmargin();
+    s->line_ypos = lcd_getymargin();
+#if LCD_DEPTH > 1	
+	s->fgcolor = lcd_get_foreground();
+	s->bgcolor = lcd_get_background();
+#endif
+    s->line_width = lcd_get_custom_width()-lcd_getleftmargin();
+
+    s->start_tick = current_tick + scroll_delay;
+    s->invert = false;
+    if (style & STYLE_INVERT) {
+        s->invert = true;
+        lcd_puts_style_offset(0,0,string,STYLE_INVERT,offset);
+    }
+    else
+        lcd_puts_offset(0,0,string,offset);
+
+    lcd_getstringsize(string, &w, &h);
+
+    if (s->line_width < w) {
+        /* prepare scroll line */
+        char *end;
+
+        memset(s->line, 0, sizeof s->line);
+        strcpy(s->line, string);
+
+        /* get width */
+        s->width = lcd_getstringsize(s->line, &w, &h);
+
+        /* scroll bidirectional or forward only depending on the string
+           width */
+        if ( bidir_limit ) {
+            s->bidir = s->width < (lcd_get_custom_width() - leftmargin) *
+                (100 + bidir_limit) / 100;
+        }
+        else
+            s->bidir = false;
+
+        if (!s->bidir) { /* add spaces if scrolling in the round */
+            strcat(s->line, "   ");
+            /* get new width incl. spaces */
+            s->width = lcd_getstringsize(s->line, &w, &h);
+        }
+
+        end = strchr(s->line, '\0');
+        strncpy(end, string, lcd_get_custom_width()/2);
+
+        s->len = utf8length(string);
+        s->offset = offset;
+        s->startx = leftmargin + leftmargin * s->width / s->len;
+        s->backward = false;
+		s->left_margin=s->line_xpos;
+		s->right_margin=s->line_xpos+s->line_width;
+        scrolling_lines |= (1<<i);
+    }
+    else 
+        /* force a bit switch-off since it doesn't scroll */
+        scrolling_lines &= ~(1<<i);
+}
+
 void lcd_puts_scroll(int x, int y, const unsigned char *string)
 {
     lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT);
@@ -887,6 +963,13 @@ void lcd_puts_scroll_style_offset(int x,
 
     s = &scroll[y];
 
+	// MWE reset customline attributes
+	s->customline = false;
+	s->line_font = curfont;
+	s->line_xpos = 0;
+	s->line_ypos = 0;
+	s->line_width=0;
+	
     s->start_tick = current_tick + scroll_delay;
     s->invert = false;
 #if LCD_DEPTH > 1
@@ -951,7 +1034,7 @@ static void scroll_thread(void)
     int xpos, ypos;
     int lastmode;
     int fgcolor_save, bgcolor_save;
-    
+	
     /* initialize scroll struct array */
     scrolling_lines = 0;
 
@@ -966,7 +1049,21 @@ static void scroll_thread(void)
             /* check pause */
             if (TIME_BEFORE(current_tick, s->start_tick))
                 continue;
-
+            
+#if LCD_DEPTH > 1
+			fgcolor_save = lcd_get_foreground();
+			bgcolor_save = lcd_get_background();
+				
+			lcd_set_foreground(s->fgcolor);
+			lcd_set_background(s->bgcolor);		
+#endif
+		
+           if (s->customline) {
+             	lcd_setfont(s->line_font);
+            	lcd_setmargins(s->line_xpos, s->line_xpos+s->line_width, s->line_ypos);
+            	lcd_set_custom_width(s->line_width);
+            }
+            	
             if (s->backward)
                 s->offset -= scroll_step;
             else
@@ -975,6 +1072,11 @@ static void scroll_thread(void)
             pf = font_get(curfont);
             xpos = s->startx;
             ypos = ymargin + index * pf->height;
+            
+            if (s->customline) {
+            	xpos = s->line_xpos;
+            	ypos = s->line_ypos;
+            }
 
             if (s->bidir) { /* scroll bidirectional */
                 if (s->offset <= 0) {
@@ -996,14 +1098,6 @@ static void scroll_thread(void)
                     s->offset %= s->width;
             }
 
-#if LCD_DEPTH > 1
-            fgcolor_save = lcd_get_foreground();
-            bgcolor_save = lcd_get_background();
-
-            lcd_set_foreground(s->fgcolor);
-            lcd_set_background(s->bgcolor);
-#endif
-
             lastmode = drawmode;
             drawmode = s->invert ? 
                        (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
Index: firmware/drivers/lcd-remote-2bit-vi.c
===================================================================
--- firmware/drivers/lcd-remote-2bit-vi.c.orig
+++ firmware/drivers/lcd-remote-2bit-vi.c
@@ -1196,6 +1196,7 @@ static void scroll_thread(void)
     }
 }
 
+
 /* LCD init */
 #ifdef SIMULATOR
 void lcd_remote_init(void)
@@ -1217,3 +1218,12 @@ void lcd_remote_init(void)
                   sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE));
 }
 #endif
+
+void lcd_remote_puts_customline_scroll(int i, const unsigned char *string)
+{
+}
+
+void lcd_remote puts_customline_scroll_style_offset(int i, const unsigned char *string,
+														int style, int offset)
+{
+}
Index: firmware/export/lcd-remote.h
===================================================================
--- firmware/export/lcd-remote.h.orig
+++ firmware/export/lcd-remote.h
@@ -107,6 +107,7 @@ extern void lcd_remote_putc(int x, int y
 extern void lcd_remote_stop_scroll(void);
 extern void lcd_remote_scroll_speed(int speed);
 extern void lcd_remote_scroll_delay(int ms);
+
 extern void lcd_remote_puts_scroll(int x, int y, const unsigned char *str);
 extern void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *str,
                                          int style);
@@ -115,7 +116,9 @@ extern void lcd_remote_puts_scroll_offse
 extern void lcd_remote_puts_scroll_style_offset(int x, int y,
                                                 const unsigned char *string,
                                                 int style, int offset);
-
+extern void lcd_remote_puts_customline_scroll(int i, const unsigned char *string);
+extern void lcd_remote_puts_customline_scroll_style_offset(int i, const unsigned char *string,
+														int style, int offset);
 extern void lcd_remote_update(void);
 extern void lcd_remote_update_rect(int x, int y, int width, int height);
 
