void LCDFN(set_viewport)(struct viewport* vp) { if (vp == NULL) current_vp = &default_vp; else current_vp = vp; #if defined(SIMULATOR) /* Force the viewport to be within bounds. If this happens it should * be considered an error - the viewport will not draw as it might be * expected. */ if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH) || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT) || current_vp->x + current_vp->width > LCDM(WIDTH) || current_vp->y + current_vp->height > LCDM(HEIGHT)) { #if !defined(HAVE_VIEWPORT_CLIP) DEBUGF("ERROR: " #else DEBUGF("NOTE: " #endif "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", current_vp->x, current_vp->y, current_vp->width, current_vp->height); }
void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string, int style, int x_offset, int y_offset) { struct scrollinfo* s; char *end; int w, h; int len; if ((unsigned)y >= (unsigned)current_vp->height) return; /* remove any previously scrolling line at the same location */ LCDFN(scroll_stop_line)(current_vp, y); if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) return; if (!string) return; LCDFN(puts_style_xyoffset)(x, y, string, style, x_offset, y_offset); LCDFN(getstringsize)(string, &w, &h); if (current_vp->width - x * 8 >= w) return; /* prepare scroll line */ s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines]; s->start_tick = current_tick + LCDFN(scroll_info).delay; s->style = style; strlcpy(s->line, string, sizeof s->line); /* get width */ s->width = LCDFN(getstringsize)(s->line, &w, &h); /* scroll bidirectional or forward only depending on the string width */ if ( LCDFN(scroll_info).bidir_limit ) { s->bidir = s->width < (current_vp->width) * (100 + LCDFN(scroll_info).bidir_limit) / 100; } else s->bidir = false; if (!s->bidir) { /* add spaces if scrolling in the round */ strlcat(s->line, " ", sizeof s->line); /* get new width incl. spaces */ s->width = LCDFN(getstringsize)(s->line, &w, &h); } end = strchr(s->line, '\0'); len = sizeof s->line - (end - s->line); strlcpy(end, string, MIN(current_vp->width/2, len)); s->vp = current_vp; s->y = y; s->offset = x_offset; s->startx = x * LCDFN(getstringsize)(" ", NULL, NULL); s->y_offset = y_offset; s->backward = false; LCDFN(scroll_info).lines++; }
#define LCDFN(fn) lcd_ ## fn #define FBFN(fn) fb_ ## fn #define LCDM(ma) LCD_ ## ma #define LCDNAME "lcd_" #define MAIN_LCD #endif /*** globals ***/ FBFN(data) LCDFN(framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; static struct viewport default_vp = { .x = 0, .y = 0, .width = LCDM(WIDTH), .height = LCDM(HEIGHT), .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, }; static struct viewport* current_vp = &default_vp; /*** Viewports ***/ void LCDFN(set_viewport)(struct viewport* vp) { if (vp == NULL) current_vp = &default_vp; else current_vp = vp;
/*** globals ***/ FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0]; static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; static FBFN(data) *backdrop = NULL; static long backdrop_offset IDATA_ATTR = 0; static struct viewport default_vp = { .x = 0, .y = 0, .width = LCDM(WIDTH), .height = LCDM(HEIGHT), .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, .fg_pattern = LCDM(DEFAULT_FG), .bg_pattern = LCDM(DEFAULT_BG) }; static struct viewport * current_vp IBSS_ATTR; static unsigned fg_pattern IBSS_ATTR; static unsigned bg_pattern IBSS_ATTR; /*** Viewports ***/ void LCDFN(set_viewport)(struct viewport* vp)