int compute_nb_lines(int w, struct font* font) { int i, nb_lines; int cur_x, delta_x; if(logfindex == 0 && !logfwrap) return 0; if(logfwrap) i = logfindex; else i = 0; cur_x = 0; nb_lines = 0; do { if(logfbuffer[i] == '\0') { cur_x = 0; nb_lines++; } else { /* does character fit on this line ? */ delta_x = font_get_width(font, logfbuffer[i]); if(cur_x + delta_x > w) { cur_x = 0; nb_lines++; } /* update pointer */ cur_x += delta_x; } i++; if(i >= MAX_LOGF_SIZE) i = 0; } while(i != logfindex); return nb_lines; }
void menu_create_buffer(menu_t *menu){ #ifdef DEBUG if(menu->buffer != NULL){ printf("MEMORY LEAK: MENU BUFFER OVER-WRITE\n"); } #endif int32_t x = 0; int32_t w = 0; int32_t h = 0; for(uint32_t i=0; i<MENU_MAX_OPTIONS; i++){ if(menu->options[i] != NULL){ x = font_get_width(menu->font, menu->options[i]->label); if(x > w){ w = x; } h += font_get_height(menu->font); } } w += 20; h += 8; menu->buffer = create_surface(w,h); }
/* put a string at a given pixel position, skipping first ofs pixel columns */ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) { unsigned short *ucs; struct font* pf = font_get(current_vp->font); int vp_flags = current_vp->flags; int rtl_next_non_diac_width, last_non_diacritic_width; if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) { int w; LCDFN(getstringsize)(str, &w, NULL); /* center takes precedence */ if (vp_flags & VP_FLAG_ALIGN_CENTER) { x = ((current_vp->width - w)/ 2) + x; if (x < 0) x = 0; } else { x = current_vp->width - w - x; x += ofs; ofs = 0; } } rtl_next_non_diac_width = 0; last_non_diacritic_width = 0; /* Mark diacritic and rtl flags for each character */ for (ucs = bidi_l2v(str, 1); *ucs; ucs++) { bool is_rtl, is_diac; const unsigned char *bits; int width, base_width, drawmode = 0, base_ofs = 0; const unsigned short next_ch = ucs[1]; if (x >= current_vp->width) break; is_diac = is_diacritic(*ucs, &is_rtl); /* Get proportional width and glyph bits */ width = font_get_width(pf, *ucs); /* Calculate base width */ if (is_rtl) { /* Forward-seek the next non-diacritic character for base width */ if (is_diac) { if (!rtl_next_non_diac_width) { const unsigned short *u; /* Jump to next non-diacritic char, and calc its width */ for (u = &ucs[1]; *u && is_diacritic(*u, NULL); u++); rtl_next_non_diac_width = *u ? font_get_width(pf, *u) : 0; } base_width = rtl_next_non_diac_width; } else { rtl_next_non_diac_width = 0; /* Mark */ base_width = width; } } else { if (!is_diac) last_non_diacritic_width = width; base_width = last_non_diacritic_width; } if (ofs > width) { ofs -= width; continue; } if (is_diac) { /* XXX: Suggested by amiconn: * This will produce completely wrong results if the original * drawmode is DRMODE_COMPLEMENT. We need to pre-render the current * character with all its diacritics at least (in mono) and then * finally draw that. And we'll need an extra buffer that can hold * one char's bitmap. Basically we can't just change the draw mode * to something else irrespective of the original mode and expect * the result to look as intended and with DRMODE_COMPLEMENT (which * means XORing pixels), overdrawing this way will cause odd results * if the diacritics and the base char both have common pixels set. * So we need to combine the char and its diacritics in a temp * buffer using OR, and then draw the final bitmap instead of the * chars, without touching the drawmode **/ drawmode = current_vp->drawmode; current_vp->drawmode = DRMODE_FG; base_ofs = (base_width - width) / 2; } bits = font_get_bits(pf, *ucs); LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x + base_ofs, y, width - ofs, pf->height); if (is_diac) { current_vp->drawmode = drawmode; } if (next_ch) { bool next_is_rtl; bool next_is_diacritic = is_diacritic(next_ch, &next_is_rtl); /* Increment if: * LTR: Next char is not diacritic, * RTL: Current char is non-diacritic and next char is diacritic */ if ((is_rtl && !is_diac) || (!is_rtl && (!next_is_diacritic || next_is_rtl))) { x += base_width - ofs; ofs = 0; } } } }
bool dbg_hw_info_clkctrl(void) { lcd_setfont(FONT_SYSFIXED); while(1) { int button = get_action(CONTEXT_STD, HZ / 10); switch(button) { case ACTION_STD_NEXT: case ACTION_STD_PREV: case ACTION_STD_OK: case ACTION_STD_MENU: lcd_setfont(FONT_UI); return true; case ACTION_STD_CANCEL: lcd_setfont(FONT_UI); return false; } lcd_clear_display(); /* 012345678901234567890123456789 */ lcd_putsf(0, 0, "name en by idiv fdiv frequency"); for(unsigned i = 0; i < ARRAYLEN(dbg_clk); i++) { #define c dbg_clk[i] lcd_putsf(0, i + 1, "%4s", c.name); if(c.has_enable) lcd_putsf(5, i + 1, "%2d", imx233_clkctrl_is_clock_enabled(c.clk)); if(c.has_bypass) lcd_putsf(8, i + 1, "%2d", imx233_clkctrl_get_bypass_pll(c.clk)); if(c.has_idiv && imx233_clkctrl_get_clock_divisor(c.clk) != 0) lcd_putsf(10, i + 1, "%4d", imx233_clkctrl_get_clock_divisor(c.clk)); if(c.has_fdiv && imx233_clkctrl_get_fractional_divisor(c.clk) != 0) lcd_putsf(16, i + 1, "%4d", imx233_clkctrl_get_fractional_divisor(c.clk)); if(c.has_freq) lcd_putsf(21, i + 1, "%9d", imx233_clkctrl_get_clock_freq(c.clk)); #undef c } int line = ARRAYLEN(dbg_clk) + 1; lcd_putsf(0, line, "as: %d/%d emi sync: %d", imx233_clkctrl_is_auto_slow_enabled(), 1 << imx233_clkctrl_get_auto_slow_divisor(), imx233_clkctrl_is_emi_sync_enabled()); line++; lcd_putsf(0, line, "as monitor: "); int x_off = 12; bool first = true; unsigned line_w = lcd_getwidth() / font_get_width(font_get(lcd_getfont()), ' '); for(unsigned i = 0; i < ARRAYLEN(dbg_as_monitor); i++) { if(!imx233_clkctrl_is_auto_slow_monitor_enabled(dbg_as_monitor[i].monitor)) continue; if(!first) { lcd_putsf(x_off, line, ", "); x_off += 2; } first = false; if((x_off + strlen(dbg_as_monitor[i].name)) > line_w) { x_off = 1; line++; } lcd_putsf(x_off, line, "%s", dbg_as_monitor[i].name); x_off += strlen(dbg_as_monitor[i].name); } line++; lcd_update(); yield(); } }
bool logfdisplay(void) { int action; int w, h, i, index; int fontnr; int cur_x, cur_y, delta_y, delta_x; struct font* font; int user_index;/* user_index will be number of the first line to display (warning: line!=logf entry) */ char buf[2]; fontnr = lcd_getfont(); font = font_get(fontnr); /* get the horizontal size of each line */ font_getstringsize("A", NULL, &delta_y, fontnr); buf[1] = '\0'; w = LCD_WIDTH; h = LCD_HEIGHT; /* start at the end of the log */ user_index = compute_nb_lines(w, font) - h/delta_y -1; /* if negative, will be set 0 to zero later */ do { lcd_clear_display(); if(user_index < 0) user_index = 0; if(logfwrap) i = logfindex; else i = 0; index = 0; cur_x = 0; cur_y = 0; /* nothing to print ? */ if(logfindex == 0 && !logfwrap) goto end_print; do { if(logfbuffer[i] == '\0') { /* should be display a newline ? */ if(index >= user_index) cur_y += delta_y; cur_x = 0; index++; } else { /* does character fit on this line ? */ delta_x = font_get_width(font, logfbuffer[i]); if(cur_x + delta_x > w) { /* should be display a newline ? */ if(index >= user_index) cur_y += delta_y; cur_x = 0; index++; } /* should we print character ? */ if(index >= user_index) { buf[0] = logfbuffer[i]; lcd_putsxy(cur_x, cur_y, buf); } /* update pointer */ cur_x += delta_x; } /* did we fill the screen ? */ if(cur_y > h) break; i++; if(i >= MAX_LOGF_SIZE) i = 0; } while(i != logfindex); end_print: lcd_update(); action = get_action(CONTEXT_STD, HZ); switch( action ) { case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: user_index++; break; case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: user_index--; break; case ACTION_STD_OK: user_index = 0; break; #ifdef HAVE_TOUCHSCREEN case ACTION_TOUCHSCREEN: { short x, y; static int prev_y; action = action_get_touchscreen_press(&x, &y); if(action & BUTTON_REL) prev_y = 0; else { if(prev_y != 0) user_index += (prev_y - y) / delta_y; prev_y = y; } } #endif default: break; } } while(action != ACTION_STD_CANCEL); return false; }
static void displayremote(void) { /* TODO: we should have a debug option that enables/disables this! */ int w, h, i; int fontnr; int cur_x, cur_y, delta_y, delta_x; struct font* font; int nb_lines; char buf[2]; /* Memorize the pointer to the beginning of the last ... lines I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically I hope there is no font with height < 6 ! */ const int NB_ENTRIES=LCD_REMOTE_HEIGHT / 6; int line_start_ptr[NB_ENTRIES]; fontnr = lcd_getfont(); font = font_get(fontnr); /* get the horizontal size of each line */ font_getstringsize("A", NULL, &delta_y, fontnr); /* font too small ? */ if(delta_y < 6) return; /* nothing to print ? */ if(logfindex == 0 && !logfwrap) return; w = LCD_REMOTE_WIDTH; h = LCD_REMOTE_HEIGHT; nb_lines = 0; if(logfwrap) i = logfindex; else i = 0; cur_x = 0; line_start_ptr[0] = i; do { if(logfbuffer[i] == '\0') { line_start_ptr[++nb_lines % NB_ENTRIES] = i+1; cur_x = 0; } else { /* does character fit on this line ? */ delta_x = font_get_width(font, logfbuffer[i]); if(cur_x + delta_x > w) { cur_x = 0; line_start_ptr[++nb_lines % NB_ENTRIES] = i; } /* update pointer */ cur_x += delta_x; } i++; if(i >= MAX_LOGF_SIZE) i = 0; } while(i != logfindex); lcd_remote_clear_display(); i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES]; cur_x = 0; cur_y = 0; buf[1] = '\0'; do { if(logfbuffer[i] == '\0') { cur_y += delta_y; cur_x = 0; } else { /* does character fit on this line ? */ delta_x = font_get_width(font, logfbuffer[i]); if(cur_x + delta_x > w) { cur_y += delta_y; cur_x = 0; } buf[0] = logfbuffer[i]; lcd_remote_putsxy(cur_x, cur_y, buf); cur_x += delta_x; } i++; if(i >= MAX_LOGF_SIZE) i = 0; } while(i != logfindex); lcd_remote_update(); }