diff -r -u rockboxmuliscroll/apps/gui/gwps-common.c rockbox/apps/gui/gwps-common.c --- rockboxmuliscroll/apps/gui/gwps-common.c 2007-07-28 13:02:02.551214400 +0100 +++ rockbox/apps/gui/gwps-common.c 2007-07-28 14:01:51.201440000 +0100 @@ -1341,7 +1341,55 @@ case WPS_TOKEN_ALIGN_SCROLLMARGIN_RIGHT: gwps->display->setmargins( gwps->display->getleftmargin(), token->value.i, gwps->display->getymargin() ); return NULL; - + + case WPS_TOKEN_CUSTOMLINE_XPOS: + gwps->data->line_xpos=token->value.i; + return NULL; + case WPS_TOKEN_CUSTOMLINE_YPOS: + gwps->data->line_ypos=token->value.i; + return NULL; + case WPS_TOKEN_CUSTOMLINE_WIDTH: + gwps->data->line_width=token->value.i; + return NULL; + case WPS_TOKEN_CUSTOMLINE_FONT: + gwps->data->line_font=token->value.i; + return NULL; + case WPS_TOKEN_CUSTOMLINE_COLOR: + gwps->data->line_fgcolor=token->value.i; + gwps->data->customline = true; +#ifdef HAVE_LCD_COLOR + if(gwps->display->depth>2){ + gwps->display->set_foreground(gwps->data->line_fgcolor); + } +#endif + + gwps->display->setmargins( gwps->data->line_xpos, gwps->data->line_xpos+gwps->data->line_width, gwps->data->line_ypos ); + + switch (gwps->data->line_font) { + case 1: + gwps->display->setfont(FONT_USER1); + break; + case 2: + gwps->display->setfont(FONT_USER2); + break; + case 3: + gwps->display->setfont(FONT_USER3); + break; + case 4: + gwps->display->setfont(FONT_USER4); + break; + case 5: + gwps->display->setfont(FONT_USER5); + break; + case 6: + gwps->display->setfont(FONT_USER6); + break; + case 7: + gwps->display->setfont(FONT_USER7); + break; + } + return NULL; + default: return NULL; } @@ -1656,7 +1704,8 @@ line is the index of the line on the screen. scroll indicates whether the line is a scrolling one or not. */ -static void write_line(struct screen *display, +static void write_line(struct wps_data *data, + struct screen *display, struct align_pos *format_align, int line, bool scroll) @@ -1669,7 +1718,8 @@ int space_width; int string_height; const int scroll_width = display->getrightmargin()-display->getleftmargin(); - + bool customline=data->customline; + /* calculate different string sizes and positions */ display->getstringsize((unsigned char *)" ", &space_width, &string_height); if (format_align->left != 0) { @@ -1679,7 +1729,12 @@ else { left_width = 0; } - left_xpos = display->getleftmargin(); + if(customline){ + left_xpos = data->line_xpos; + } + else { + left_xpos = display->getleftmargin(); + } if (format_align->center != 0) { display->getstringsize((unsigned char *)format_align->center, @@ -1688,8 +1743,13 @@ else { center_width = 0; } - center_xpos=(display->getrightmargin() + display->getleftmargin() - center_width)/2; - + if(customline){ + center_xpos=(data->line_width - center_width) / 2 + data->line_xpos; + } + else { + center_xpos=(display->getrightmargin() + display->getleftmargin() - center_width)/2; + } + if (format_align->right != 0) { display->getstringsize((unsigned char *)format_align->right, &right_width, &string_height); @@ -1697,7 +1757,12 @@ else { right_width = 0; } - right_xpos = (display->getrightmargin() - right_width); + if(customline){ + 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 @@ -1783,42 +1848,106 @@ } ypos = (line * string_height) + display->getymargin(); - - - if (scroll && ( left_width > scroll_width || center_width > scroll_width || right_width > scroll_width ) ) - { - display->puts_scroll(0, line, - (unsigned char *)format_align->left); - } - else - { + #ifdef HAVE_LCD_BITMAP - /* clear the line first */ - display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); - display->fillrect(0, ypos, display->width, string_height); - display->set_drawmode(DRMODE_SOLID); + /* 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(data->line_xpos, data->line_ypos, data->line_width, string_height); + display->set_drawmode(DRMODE_SOLID); + } #endif - /* Nasty hack: we output an empty scrolling string, - which will reset the scroller for that line */ - display->puts_scroll(0, line, (unsigned char *)""); + if(customline){ + if (scroll && ( left_width > scroll_width || center_width > scroll_width || right_width > scroll_width ) ) + { + display->puts_customline_scroll(line, + (unsigned char *)format_align->left); + } + else + { + 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; + } + /* Nasty hack: we output an empty scrolling string, + which will reset the scroller for that line */ + display->puts_customline_scroll(line, (unsigned char *)""); + + /* print aligned strings */ + if (left_width != 0) + { + display->putsxy(left_xpos, data->line_ypos, + (unsigned char *)format_align->left); + } + if (center_width != 0) + { + display->putsxy(center_xpos, data->line_ypos, + (unsigned char *)format_align->center); + } + if (right_width != 0) + { + display->putsxy(right_xpos, data->line_ypos, + (unsigned char *)format_align->right); + } + } + } else { + if (scroll && ( left_width > scroll_width || center_width > scroll_width || right_width > scroll_width ) ) + { + display->puts_scroll(0, line, + (unsigned char *)format_align->left); + } + else + { +#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(0, ypos, display->width, string_height); + display->set_drawmode(DRMODE_SOLID); + } +#endif - /* print aligned strings */ - if (left_width != 0) - { - display->putsxy(left_xpos, ypos, - (unsigned char *)format_align->left); - } - if (center_width != 0) - { - display->putsxy(center_xpos, ypos, - (unsigned char *)format_align->center); - } - if (right_width != 0) - { - display->putsxy(right_xpos, ypos, - (unsigned char *)format_align->right); - } + /* Nasty hack: we output an empty scrolling string, + which will reset the scroller for that line */ + display->puts_scroll(0, line, (unsigned char *)""); + + /* print aligned strings */ + if (left_width != 0) + { + display->putsxy(left_xpos, ypos, + (unsigned char *)format_align->left); + } + if (center_width != 0) + { + display->putsxy(center_xpos, ypos, + (unsigned char *)format_align->center); + } + if (right_width != 0) + { + display->putsxy(right_xpos, ypos, + (unsigned char *)format_align->right); + } + } } } @@ -1845,6 +1974,16 @@ bool update_line, new_subline_refresh; +#ifdef HAVE_LCD_COLOR + int fgcolor_save; + if(display->depth>2){ + fgcolor_save=display->get_foreground(); + } +#endif + int leftmargin_save=display->getleftmargin(); + int rightmargin_save=display->getrightmargin(); + int ymargin_save=display->getymargin(); + #ifdef HAVE_LCD_BITMAP gui_wps_statusbar_draw(gwps, true); @@ -1959,10 +2098,10 @@ /* if the line is a scrolling one we don't want to update too often, so that it has the time to scroll */ if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) - write_line(display, &align, line, true); + write_line(data, display, &align, line, true); } else - write_line(display, &align, line, false); + write_line(data, display, &align, line, false); } } @@ -2009,6 +2148,12 @@ } #endif +#ifdef HAVE_LCD_COLOR + if(display->depth>2){ + display->set_foreground(fgcolor_save); + } +#endif + display->setmargins( leftmargin_save, rightmargin_save, ymargin_save ); return true; } diff -r -u rockboxmuliscroll/apps/gui/gwps.h rockbox/apps/gui/gwps.h --- rockboxmuliscroll/apps/gui/gwps.h 2007-07-28 12:54:17.472464000 +0100 +++ rockbox/apps/gui/gwps.h 2007-07-28 14:01:51.381699200 +0100 @@ -187,6 +187,13 @@ WPS_TOKEN_IMAGE_PRELOAD, WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, WPS_TOKEN_IMAGE_DISPLAY, + + /* customline */ + WPS_TOKEN_CUSTOMLINE_XPOS, + WPS_TOKEN_CUSTOMLINE_YPOS, + WPS_TOKEN_CUSTOMLINE_WIDTH, + WPS_TOKEN_CUSTOMLINE_FONT, + WPS_TOKEN_CUSTOMLINE_COLOR, #endif /* Metadata */ @@ -338,6 +345,12 @@ int num_strings; bool wps_loaded; + + /* customline */ + int line_xpos, line_ypos, line_width; + int line_font; + int line_fgcolor; + bool customline; }; /* initial setup of wps_data */ diff -r -u rockboxmuliscroll/apps/gui/wps_parser.c rockbox/apps/gui/wps_parser.c --- rockboxmuliscroll/apps/gui/wps_parser.c 2007-07-28 12:54:17.522536000 +0100 +++ rockbox/apps/gui/wps_parser.c 2007-07-28 14:01:51.431771200 +0100 @@ -126,6 +126,8 @@ struct wps_token *token, struct wps_data *wps_data); static int parse_image_load(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); +static int parse_customline(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); #endif /*HAVE_LCD_BITMAP */ #ifdef CONFIG_RTC @@ -281,6 +283,7 @@ { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, { WPS_NO_TOKEN, "m", 0, parse_scrollmargins }, + { WPS_NO_TOKEN, "e", 0, parse_customline }, { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) @@ -629,10 +632,72 @@ } } } - + return(0); } +static int parse_customline(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) +{ + /* format: %e|x|y|w|font|color */ + const char* _pos; + + if(*wps_bufptr!='|') + return(0); /* malformed token: */ + + _pos=wps_bufptr+1; + if(!isdigit(*_pos)) + return(0); /* malformed token: */ + + wps_data->num_tokens +=5; + token->type = WPS_TOKEN_CUSTOMLINE_XPOS; + token->value.i = atoi(_pos); + token++; + + _pos=strchr(_pos,'|'); + if(!_pos || !isdigit(*(++_pos))) + return(0); /* malformed token: */ + + token->type = WPS_TOKEN_CUSTOMLINE_YPOS; + token->value.i = atoi(_pos); + token++; + + _pos=strchr(_pos,'|'); + if(!_pos || !isdigit(*(++_pos))) + return(0); /* malformed token: */ + + token->type = WPS_TOKEN_CUSTOMLINE_WIDTH; + token->value.i = atoi(_pos); + token++; + + _pos=strchr(_pos,'|'); + if(!_pos || !isdigit(*(++_pos))) + return(0); /* malformed token: */ + + token->type = WPS_TOKEN_CUSTOMLINE_FONT; + token->value.i = atoi(_pos); + token++; + + _pos=strchr(_pos,'|'); + if(!_pos) + return(0); /* malformed token: */ + + ++_pos; + char fg_color[7]; + snprintf(fg_color, 7, "%s", _pos); + + token->type = WPS_TOKEN_CUSTOMLINE_COLOR; +#ifdef HAVE_LCD_COLOR + token->value.i = hex_to_rgb(fg_color); +#else + token->value.i=0; +#endif + + _pos+=6; + return( _pos - wps_bufptr + 1 ); +} + /* Parse a generic token from the given string. Return the length read */ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) { @@ -934,6 +999,13 @@ wps_data->full_line_progressbar = false; #endif wps_data->wps_loaded = false; + + wps_data->customline = false; + wps_data->line_xpos = -1; + wps_data->line_ypos = 1; + wps_data->line_width = -1; + wps_data->line_fgcolor = -1; + wps_data->line_font = -1; } static void wps_reset(struct wps_data *data) diff -r -u rockboxmuliscroll/apps/screen_access.c rockbox/apps/screen_access.c --- rockboxmuliscroll/apps/screen_access.c 2007-07-28 13:02:05.715764800 +0100 +++ rockbox/apps/screen_access.c 2007-07-28 14:01:51.551944000 +0100 @@ -48,6 +48,7 @@ screen->getymargin=&lcd_remote_getymargin; screen->getleftmargin=&lcd_remote_getleftmargin; screen->getrightmargin=&lcd_remote_getrightmargin; + screen->getmarginwidth=&lcd_remote_getmarginwidth; screen->getstringsize=&lcd_remote_getstringsize; #if 1 /* all remote LCDs are bitmapped so far */ screen->setfont=&lcd_remote_setfont; @@ -99,7 +100,9 @@ screen->puts=&lcd_remote_puts; screen->puts_offset=&lcd_remote_puts_offset; screen->puts_scroll=&lcd_remote_puts_scroll; + screen->puts_customline_scroll=&lcd_remote_puts_customline_scroll; screen->puts_scroll_offset=&lcd_remote_puts_scroll_offset; + screen->puts_customline_scroll_offset=&lcd_remote_puts_customline_scroll_offset; screen->scroll_speed=&lcd_remote_scroll_speed; screen->lcd_scroll_info.delay=&lcd_remote_lcd_scroll_info.delay; screen->stop_scroll=&lcd_remote_stop_scroll; @@ -131,6 +134,7 @@ screen->getymargin=&lcd_getymargin; screen->getleftmargin=&lcd_getleftmargin; screen->getrightmargin=&lcd_getrightmargin; + screen->getmarginwidth=&lcd_getmarginwidth; screen->getstringsize=&lcd_getstringsize; #ifdef HAVE_LCD_BITMAP screen->setfont=&lcd_setfont; @@ -185,7 +189,9 @@ screen->puts=&lcd_puts; screen->puts_offset=&lcd_puts_offset; screen->puts_scroll=&lcd_puts_scroll; + screen->puts_customline_scroll=&lcd_puts_customline_scroll; screen->puts_scroll_offset=&lcd_puts_scroll_offset; + screen->puts_customline_scroll_offset=&lcd_puts_customline_scroll_offset; screen->scroll_speed=&lcd_scroll_speed; screen->lcd_scroll_info.delay=&lcd_lcd_scroll_info.delay; screen->stop_scroll=&lcd_stop_scroll; diff -r -u rockboxmuliscroll/apps/screen_access.h rockbox/apps/screen_access.h --- rockboxmuliscroll/apps/screen_access.h 2007-07-28 13:02:05.735793600 +0100 +++ rockbox/apps/screen_access.h 2007-07-28 14:01:51.571972800 +0100 @@ -70,7 +70,7 @@ int (*getleftmargin)(void); int (*getrightmargin)(void); int (*getymargin)(void); - + int (*getmarginwidth)(void); int (*getstringsize)(const unsigned char *str, int *w, int *h); #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) /* always bitmap */ void (*setfont)(int newfont); @@ -130,6 +130,10 @@ void (*puts_scroll)(int x, int y, const unsigned char *string); void (*puts_scroll_offset)(int x, int y, const unsigned char *string, int offset); + void (*puts_customline_scroll)(int i, const unsigned char *string); + void (*puts_customline_scroll_offset)(int i, const unsigned char *string, + int offset); + void (*scroll_speed)(int speed); void (*lcd_scroll_info.delay)(int ms); void (*stop_scroll)(void); diff -r -u rockboxmuliscroll/firmware/drivers/lcd-16bit.c rockbox/firmware/drivers/lcd-16bit.c --- rockboxmuliscroll/firmware/drivers/lcd-16bit.c 2007-07-28 13:02:06.306614400 +0100 +++ rockbox/firmware/drivers/lcd-16bit.c 2007-07-28 14:01:51.592001600 +0100 @@ -133,6 +133,11 @@ return ymargin; } +int lcd_getmarginwidth(void) +{ + return lcd_getrightmargin()-lcd_getleftmargin(); +} + void lcd_setfont(int newfont) { curfont = newfont; @@ -837,7 +843,154 @@ bg_pattern = oldbgcolor; } +/* put a string at a given pixel position, skipping first ofs pixel columns + if rmargin==0 the global rightmargin is used */ +static void lcd_putsxyofs_custom(int x, int y, int ofs, const unsigned char *str, int rmargin) +{ + unsigned short ch; + unsigned short *ucs; + struct font* pf = font_get(curfont); + int used_rightmargin=rmargin?rmargin:rightmargin; + + ucs = bidi_l2v(str, 1); + + while ((ch = *ucs++) != 0 && x < used_rightmargin) + { + int width; + const unsigned char *bits; + + /* get proportional width and glyph bits */ + width = font_get_width(pf,ch,curfont); + + if (ofs > width) + { + ofs -= width; + continue; + } + + bits = font_get_bits(pf, ch, curfont); + + lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, (x+width > used_rightmargin?used_rightmargin-x:width) - ofs, pf->height); + + x += width - ofs; + ofs = 0; + } +} + +void lcd_puts_customline_style_offset(int i, const unsigned char *str, int style, + int offset) +{ + int xpos,ypos,w,h,xrect; + int lastmode = drawmode; + + /* make sure scrolling is turned off on the line we are updating */ + lcd_scroll_info.lines &= ~(1 << i); + + if(!str || !str[0]) + return; + + lcd_getstringsize(str, &w, &h); + xpos = leftmargin; + ypos = ymargin; + drawmode = (style & STYLE_INVERT) ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs_custom(xpos, ypos, offset, str, 0); + drawmode ^= DRMODE_INVERSEVID; + xrect = xpos + MAX(w - offset, 0); + lcd_fillrect(xpos + w, ypos, rightmargin - (xpos + w), h); + drawmode = lastmode; +} + +void lcd_puts_customline_offset(int i, const unsigned char *str, int offset) +{ + lcd_puts_customline_style_offset(i, str, STYLE_DEFAULT, offset); +} + /*** scrolling ***/ +void lcd_puts_customline_scroll_style(int i, const unsigned char *string, int style) +{ + lcd_puts_customline_scroll_style_offset(i, string, style, 0); +} + +void lcd_puts_customline_scroll_offset(int i, const unsigned char *string, int offset) +{ + lcd_puts_customline_scroll_style_offset(i, string, STYLE_DEFAULT, offset); +} + +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 = &lcd_scroll_info.scroll[i]; + + s->customline = true; + s->line_font = curfont; + s->line_xpos = lcd_getleftmargin(); + s->line_ypos = lcd_getymargin(); + s->fgcolor = lcd_get_foreground(); + s->line_width = lcd_getrightmargin()-lcd_getleftmargin(); + + s->start_tick = current_tick + lcd_scroll_info.delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_puts_customline_style_offset(i,string,STYLE_INVERT,offset); + } + else + lcd_puts_customline_offset(i,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 ( lcd_scroll_info.bidir_limit ) { + s->bidir = s->width < (s->line_width) * + (100 + lcd_scroll_info.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, s->line_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; + s->y_margin=ymargin; + lcd_scroll_info.lines |= (1<customline = false; + s->line_font = curfont; + s->line_xpos = 0; + s->line_ypos = 0; + s->line_width=0; + s->fgcolor = lcd_get_foreground(); s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { @@ -945,5 +1086,6 @@ unsigned old_fgcolor = fg_pattern; unsigned old_bgcolor = bg_pattern; + int fgcolor_save; for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { /* really scroll? */ @@ -952,9 +1112,18 @@ else s->offset += lcd_scroll_info.step; + if (s->customline) { + lcd_setfont(s->line_font); + } + pf = font_get(curfont); - xpos = s->startx; - ypos = s->y_margin + index * pf->height; + if (s->customline) { + xpos = s->line_xpos; + ypos = s->line_ypos; + } else { + xpos = s->startx; + ypos = s->y_margin + index * pf->height; + } if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { @@ -976,16 +1145,20 @@ s->offset %= s->width; } + fgcolor_save = lcd_get_foreground(); + lcd_set_foreground(s->fgcolor); + lastmode = drawmode; drawmode = s->invert ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); + lcd_putsxyofs_custom(xpos, ypos, s->offset, s->line, s->right_margin); if (LCD_WIDTH>s->right_margin) { drawmode ^= DRMODE_INVERSEVID; lcd_fillrect(s->right_margin, ypos, LCD_WIDTH - s->right_margin, pf->height); } drawmode = lastmode; lcd_update_rect(xpos, ypos, s->right_margin - xpos, pf->height); + lcd_set_foreground(fgcolor_save); } fg_pattern = old_fgcolor; diff -r -u rockboxmuliscroll/firmware/drivers/lcd-2bit-vert.c rockbox/firmware/drivers/lcd-2bit-vert.c --- rockboxmuliscroll/firmware/drivers/lcd-2bit-vert.c 2007-07-28 13:02:06.476859200 +0100 +++ rockbox/firmware/drivers/lcd-2bit-vert.c 2007-07-28 14:01:51.692145600 +0100 @@ -128,6 +128,11 @@ return ymargin; } +int lcd_getmarginwidth(void) +{ + return lcd_getrightmargin()-lcd_getleftmargin(); +} + void lcd_setfont(int newfont) { curfont = newfont; @@ -1011,4 +1011,66 @@ drawmode = lastmode; } +/* put a string at a given pixel position, skipping first ofs pixel columns + if rmargin==0 the global rightmargin is used */ +static void lcd_putsxyofs_custom(int x, int y, int ofs, const unsigned char *str, int rmargin) +{ + unsigned short ch; + unsigned short *ucs; + struct font* pf = font_get(curfont); + int used_rightmargin=rmargin?rmargin:rightmargin; + + ucs = bidi_l2v(str, 1); + + while ((ch = *ucs++) != 0 && x < used_rightmargin) + { + int width; + const unsigned char *bits; + + /* get proportional width and glyph bits */ + width = font_get_width(pf,ch,curfont); + + if (ofs > width) + { + ofs -= width; + continue; + } + + bits = font_get_bits(pf, ch, curfont); + + lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, (x+width > used_rightmargin?used_rightmargin-x:width) - ofs, pf->height); + + x += width - ofs; + ofs = 0; + } +} + +void lcd_puts_customline_style_offset(int i, const unsigned char *str, int style, + int offset) +{ + int xpos,ypos,w,h,xrect; + int lastmode = drawmode; + + /* make sure scrolling is turned off on the line we are updating */ + lcd_scroll_info.lines &= ~(1 << i); + + if(!str || !str[0]) + return; + + lcd_getstringsize(str, &w, &h); + xpos = leftmargin; + ypos = ymargin; + drawmode = (style & STYLE_INVERT) ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs_custom(xpos, ypos, offset, str, 0); + drawmode ^= DRMODE_INVERSEVID; + xrect = xpos + MAX(w - offset, 0); + lcd_fillrect(xpos + w, ypos, rightmargin - (xpos + w), h); + drawmode = lastmode; +} + +void lcd_puts_customline_offset(int i, const unsigned char *str, int offset) +{ + lcd_puts_customline_style_offset(i, str, STYLE_DEFAULT, offset); +} /*** scrolling ***/ @@ -1038,14 +1105,22 @@ s = &lcd_scroll_info.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->fgcolor = lcd_get_foreground(); + s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; - lcd_puts_style_offset(x,y,string,STYLE_INVERT,offset); + lcd_puts_style_offset(0,0,string,STYLE_INVERT,offset); } else - lcd_puts_offset(x,y,string,offset); + lcd_puts_offset(0,0,string,offset); lcd_getstringsize(string, &w, &h); @@ -1109,14 +1184,23 @@ if (TIME_BEFORE(current_tick, s->start_tick)) continue; + if (s->customline) { + lcd_setfont(s->line_font); + } + if (s->backward) s->offset -= lcd_scroll_info.step; else s->offset += lcd_scroll_info.step; pf = font_get(curfont); - xpos = s->startx; - ypos = s->y_margin + index * pf->height; + if (s->customline) { + xpos = s->line_xpos; + ypos = s->line_ypos; + } else { + xpos = s->startx; + ypos = s->y_margin + index * pf->height; + } if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { @@ -1141,12 +1225,91 @@ lastmode = drawmode; drawmode = s->invert ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - if (LCD_WIDTH>s->right_margin) { - drawmode ^= DRMODE_INVERSEVID; - lcd_fillrect(s->right_margin, ypos, LCD_WIDTH - s->right_margin, pf->height); - } + lcd_putsxyofs_custom(xpos, ypos, s->offset, s->line, s->right_margin); drawmode = lastmode; lcd_update_rect(xpos, ypos, s->right_margin - xpos, pf->height); } } + +void lcd_puts_customline_scroll_style(int i, const unsigned char *string, int style) +{ + lcd_puts_customline_scroll_style_offset(i, string, style, 0); +} + +void lcd_puts_customline_scroll_offset(int i, const unsigned char *string, int offset) +{ + lcd_puts_customline_scroll_style_offset(i, string, STYLE_DEFAULT, offset); +} + +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 = &lcd_scroll_info.scroll[i]; + + s->customline = true; + s->line_font = curfont; + s->line_xpos = lcd_getleftmargin(); + s->line_ypos = lcd_getymargin(); + s->line_width = lcd_getrightmargin()-lcd_getleftmargin(); + + s->start_tick = current_tick + lcd_scroll_info.delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_puts_customline_style_offset(i,string,STYLE_INVERT,offset); + } + else + lcd_puts_customline_offset(i,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 ( lcd_scroll_info.bidir_limit ) { + s->bidir = s->width < (s->line_width) * + (100 + lcd_scroll_info.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, s->line_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; + s->y_margin=ymargin; + lcd_scroll_info.lines |= (1< width) + { + ofs -= width; + continue; + } + + bits = font_get_bits(pf, ch, curfont); + + lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, (x+width > used_rightmargin?used_rightmargin-x:width) - ofs, + pf->height); + + x += width - ofs; + ofs = 0; + } +} + +void lcd_remote_puts_customline_style_offset(int i, const unsigned char *str, int style, + int offset) +{ + int xpos,ypos,w,h,xrect; + int lastmode = drawmode; + + /* make sure scrolling is turned off on the line we are updating */ + lcd_scroll_info.lines &= ~(1 << i); + + if(!str || !str[0]) + return; + + lcd_remote_getstringsize(str, &w, &h); + xpos = leftmargin; + ypos = ymargin; + drawmode = (style & STYLE_INVERT) ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_remote_putsxyofs_custom(xpos, ypos, offset, str, 0); + drawmode ^= DRMODE_INVERSEVID; + xrect = xpos + MAX(w - offset, 0); + lcd_remote_fillrect(xpos + w, ypos, rightmargin - (xpos + w), h); + drawmode = lastmode; +} + +void lcd_remote_puts_customline_offset(int i, const unsigned char *str, int offset) +{ + lcd_remote_puts_customline_style_offset(i, str, STYLE_DEFAULT, offset); +} + /*** scrolling ***/ void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) @@ -769,14 +769,23 @@ if (TIME_BEFORE(current_tick, s->start_tick)) continue; + if (s->customline) { + lcd_remote_setfont(s->line_font); + } + if (s->backward) s->offset -= lcd_remote_scroll_info.step; else s->offset += lcd_remote_scroll_info.step; pf = font_get(curfont); - xpos = s->startx; - ypos = s->y_margin + index * pf->height; + if (s->customline) { + xpos = s->line_xpos; + ypos = s->line_ypos; + } else { + xpos = s->startx; + ypos = s->y_margin + index * pf->height; + } if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { @@ -801,11 +879,7 @@ lastmode = drawmode; drawmode = s->invert ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); - if (LCD_REMOTE_WIDTH > s->right_margin) { - drawmode ^= DRMODE_INVERSEVID; - lcd_remote_fillrect(s->right_margin, ypos, LCD_WIDTH - s->right_margin, pf->height); - } + lcd_remote_putsxyofs_custom(xpos, ypos, s->offset, s->line, s->right_margin); drawmode = lastmode; lcd_remote_update_rect(xpos, ypos, s->right_margin - xpos, pf->height); } @@ -819,3 +893,86 @@ lcd_remote_init_device(); #endif } + +void lcd_remote_puts_customline_scroll_style(int i, const unsigned char *string, int style) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, style, 0); +} + +void lcd_remote_puts_customline_scroll_offset(int i, const unsigned char *string, int offset) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, STYLE_DEFAULT, offset); +} + +void lcd_remote_puts_customline_scroll(int i, const unsigned char *string) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, + STYLE_DEFAULT, 0); +} + +void lcd_remote_puts_customline_scroll_style_offset(int i, const unsigned char *string, + int style, int offset) +{ + struct scrollinfo* s; + int w, h; + + s = &lcd_scroll_info.scroll[i]; + + s->customline = true; + s->line_font = curfont; + s->line_xpos = lcd_remote_getleftmargin(); + s->line_ypos = lcd_remote_getymargin(); + s->line_width = lcd_remote_getrightmargin()-lcd_remote_getleftmargin(); + + s->start_tick = current_tick + lcd_scroll_info.delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_remote_puts_customline_style_offset(i,string,STYLE_INVERT,offset); + } + else + lcd_remote_puts_customline_offset(i,string,offset); + + lcd_remote_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_remote_getstringsize(s->line, &w, &h); + + /* scroll bidirectional or forward only depending on the string + width */ + if ( lcd_scroll_info.bidir_limit ) { + s->bidir = s->width < (s->line_width) * + (100 + lcd_scroll_info.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_remote_getstringsize(s->line, &w, &h); + } + + end = strchr(s->line, '\0'); + strncpy(end, string, s->line_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; + s->y_margin=ymargin; + lcd_scroll_info.lines |= (1< width) + { + ofs -= width; + continue; + } + + bits = font_get_bits(pf, ch, curfont); + + lcd_remote_mono_bitmap_part(bits, ofs, 0, width, x, y, (x+width > used_rightmargin?used_rightmargin-x:width) - ofs, + pf->height); + + x += width - ofs; + ofs = 0; + } +} + /* put a string at a given char position, style, and pixel position, * skipping first offset pixel columns */ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, @@ -1000,13 +1040,42 @@ ypos = s->y_margin + y*h; drawmode = (style & STYLE_INVERT) ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_remote_putsxyofs(xpos, ypos, offset, str); + lcd_remote_putsxyofs_custom(xpos, ypos, offset, str, 0); drawmode ^= DRMODE_INVERSEVID; xrect = xpos + MAX(w - offset, 0); lcd_remote_fillrect(xrect, ypos, LCD_REMOTE_WIDTH - xrect, h); drawmode = lastmode; } +void lcd_remote_puts_customline_style_offset(int i, const unsigned char *str, int style, + int offset) +{ + int xpos,ypos,w,h,xrect; + int lastmode = drawmode; + + /* make sure scrolling is turned off on the line we are updating */ + lcd_scroll_info.lines &= ~(1 << i); + + if(!str || !str[0]) + return; + + lcd_remote_getstringsize(str, &w, &h); + xpos = leftmargin; + ypos = ymargin; + drawmode = (style & STYLE_INVERT) ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_remote_putsxyofs(xpos, ypos, offset, str, 0); + drawmode ^= DRMODE_INVERSEVID; + xrect = xpos + MAX(w - offset, 0); + lcd_remote_fillrect(xpos + w, ypos, rightmargin - (xpos + w), h); + drawmode = lastmode; +} + +void lcd_remote_puts_customline_offset(int i, const unsigned char *str, int offset) +{ + lcd_remote_puts_customline_style_offset(i, str, STYLE_DEFAULT, offset); +} + /*** scrolling ***/ void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) { @@ -1033,6 +1102,13 @@ s = &lcd_remote_scroll_info.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 + lcd_remote_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { @@ -1102,14 +1178,23 @@ if (TIME_BEFORE(current_tick, s->start_tick)) continue; + if (s->customline) { + lcd_remote_setfont(s->line_font); + } + if (s->backward) s->offset -= lcd_remote_scroll_info.step; else s->offset += lcd_remote_scroll_info.step; pf = font_get(curfont); - xpos = s->startx; - ypos = s->y_margin + index * pf->height; + if (s->customline) { + xpos = s->line_xpos; + ypos = s->line_ypos; + } else { + xpos = s->startx; + ypos = s->y_margin + index * pf->height; + } if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { @@ -1134,9 +1219,9 @@ lastmode = drawmode; drawmode = s->invert ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); + lcd_remote_putsxyofs_custom(xpos, ypos, s->offset, s->line, s->right_margin); drawmode = lastmode; - lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + lcd_remote_update_rect(xpos, ypos, s->right_margin - xpos, pf->height); } } @@ -1148,3 +1233,87 @@ lcd_remote_init_device(); #endif } + +void lcd_remote_puts_customline_scroll_style(int i, const unsigned char *string, int style) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, style, 0); +} + +void lcd_remote_puts_customline_scroll_offset(int i, const unsigned char *string, int offset) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, STYLE_DEFAULT, offset); +} + +void lcd_remote_puts_customline_scroll(int i, const unsigned char *string) +{ + lcd_remote_puts_customline_scroll_style_offset(i, string, + STYLE_DEFAULT, 0); +} + +void lcd_remote_puts_customline_scroll_style_offset(int i, const unsigned char *string, + int style, int offset) +{ + struct scrollinfo* s; + int w, h; + + s = &lcd_scroll_info.scroll[i]; + + s->customline = true; + s->line_font = curfont; + s->line_xpos = lcd_remote_getleftmargin(); + s->line_ypos = lcd_remote_getymargin(); + s->line_width = lcd_remote_getrightmargin()-lcd_remote_getleftmargin(); + + s->start_tick = current_tick + lcd_scroll_info.delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_remote_puts_customline_style_offset(i,string,STYLE_INVERT,offset); + } + else + lcd_remote_puts_customline_offset(i,string,offset); + + lcd_remote_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_remote_getstringsize(s->line, &w, &h); + + /* scroll bidirectional or forward only depending on the string + width */ + if ( lcd_scroll_info.bidir_limit ) { + s->bidir = s->width < (s->line_width) * + (100 + lcd_scroll_info.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_remote_getstringsize(s->line, &w, &h); + } + + end = strchr(s->line, '\0'); + strncpy(end, string, s->line_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; + s->y_margin=ymargin; + lcd_scroll_info.lines |= (1<= 8 extern lcd_fastpixelfunc_type* const *lcd_fastpixelfuncs; diff -r -u rockboxmuliscroll/firmware/export/scroll_engine.h rockbox/firmware/export/scroll_engine.h --- rockboxmuliscroll/firmware/export/scroll_engine.h 2007-07-28 12:42:26.129603200 +0100 +++ rockbox/firmware/export/scroll_engine.h 2007-07-28 14:01:29.650451200 +0100 @@ -50,6 +50,13 @@ long start_tick; int left_margin; int right_margin; + /* Customline arguments */ + bool customline; + int line_font; + int line_xpos; + int line_ypos; + int line_width; + int fgcolor; #ifdef HAVE_LCD_COLOR int line_color; #endif