static void input_move_left(const bool do_refresh) { if (pos > 0) { const int x_delta = get_char_width(&input_buffer[pos = prev_pos(input_buffer, pos, encoding)], encoding); assert(pos >= 0); if (x == start_x) { offset = pos; if (char_ins_del_ok) { int i, j; for(i = start_x, j = offset; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); delete_chars(get_char_width(&input_buffer[j], encoding)); } move_cursor(ne_lines - 1, start_x); insert_char(get_char(&input_buffer[pos], encoding), 0, encoding); move_cursor(ne_lines - 1, start_x); } else if (do_refresh) input_refresh(); } else x -= x_delta; } }
static void input_refresh(void) { move_cursor(ne_lines - 1, start_x); for(int i = start_x, j = offset; j < len; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)) { if (i + get_char_width(&input_buffer[j], encoding) >= ne_columns) break; output_char(get_char(&input_buffer[j], encoding), 0, encoding); } clear_to_eol(); fflush(stdout); }
/* Return a copy of source truncated to be no longer than max_len_x including the append_str on the end. */ char *truncated_string(char *dest, const char *source, size_t dest_max_len, const char *append_str, float max_len_x, float font_ratio) { float string_width = 0; size_t dest_len = 0; float append_len_x = get_string_width((unsigned char*)append_str) * font_ratio; char *dest_p = dest; while ((*source != '\0') && (dest_len < dest_max_len-1)) { float char_width = get_char_width(*source) * font_ratio; if ((string_width + char_width) > (max_len_x - append_len_x)) break; *dest_p++ = *source++; dest_len++; string_width += char_width; } while ((*append_str != '\0') && (dest_len < dest_max_len-1)) { *dest_p++ = *append_str++; dest_len++; } *dest_p = '\0'; return dest; }
void gr_get_string_size(int *w1, int *h1, const char *text, int len) { int longest_width; int width,spacing; int w, h; if (!Current_font) { if ( w1) *w1 = 16; if ( h1 ) *h1 = 16; return; } w = 0; h = 0; longest_width = 0; if (text != NULL ) { h += Current_font->h; while (*text && (len>0) ) { // Process one or more while ((*text == '\n') && (len>0) ) { text++; len--; if ( *text ) { h += Current_font->h; } w = 0; } if (*text == 0) { break; } get_char_width(text[0], text[1], &width, &spacing); w += spacing; if (w > longest_width) longest_width = w; text++; len--; } } if ( h1 ) *h1 = h; if ( w1 ) *w1 = longest_width; }
int get_centered_x_scaled(char *s, fix scale_x) { int w,w2,s2; for (w=0;*s!=0 && *s!='\n';s++) { get_char_width(s[0],s[1],&w2,&s2); w += s2; } return ((grd_curcanv->cv_bitmap.bm_w - w * f2fl(scale_x)) / 2); }
int get_string_width(char* str, int size) { size_t i = 0; int sum = 0; for(; str[i] != '0'; i++) { sum += get_char_width(str[i], size) + get_char_sep(size); } sum -= get_char_sep(size); return sum; }
// NOTE: this returns an unscaled size for non-standard resolutions int get_centered_x(const char *s) { int w,w2,s2; for (w=0;*s!=0 && *s!='\n';s++) { get_char_width(s[0],s[1],&w2,&s2); w += s2; } return ((gr_screen.clip_width_unscaled - w) / 2); }
int get_centered_x(unsigned char *s) { int w,w2,s2; for (w=0;*s!=0 && *s!='\n';s++) { get_char_width(s[0],s[1],&w2,&s2); w += s2; } return ((grd_curcanv->cv_bitmap.bm_w - w) / 2); }
static void input_move_right(const bool do_refresh) { const int prev_pos = pos; if (pos < len) { const int x_delta = get_char_width(&input_buffer[pos], encoding); pos = next_pos(input_buffer, pos, encoding); assert(pos <= len); if ((x += x_delta) >= ne_columns) { const int shift = x - (ne_columns - 1); int width = 0; do { width += get_char_width(&input_buffer[offset], encoding); offset = next_pos(input_buffer, offset, encoding); } while(width < shift && offset < len); assert(offset < len); x -= width; if (char_ins_del_ok) { int i, j; move_cursor(ne_lines - 1, start_x); delete_chars(width); move_cursor(ne_lines - 1, x - x_delta); output_char(get_char(&input_buffer[prev_pos], encoding), 0, encoding); i = x; j = pos; while(j < len && i + (width = get_char_width(&input_buffer[j], encoding)) < ne_columns) { output_char(get_char(&input_buffer[j], encoding), 0, encoding); i += width; j = next_pos(input_buffer, j, encoding); } } else if (do_refresh) input_refresh(); } } }
size_t get_utf8_overhead(const char str[]) { size_t overhead = 0; while(*str != '\0') { size_t char_width = get_char_width(str); str += char_width; overhead += char_width - 1; } return overhead; }
/* returns count of utf8 characters in string */ size_t get_utf8_string_length(const char *string) { size_t length = 0; while(*string != '\0') { size_t char_width = get_char_width(string); string += char_width; length++; } return length; }
/* returns count of bytes of whole string or of first max_len utf8 characters */ size_t get_real_string_width(char *string, size_t max_len) { size_t width = 0; while(*string != '\0' && max_len-- != 0) { size_t char_width = get_char_width(string); width += char_width; string += char_width; } return width; }
/* returns (string_width - string_length) */ size_t get_utf8_overhead(const char *string) { size_t overhead = 0; while(*string != '\0') { size_t char_width = get_char_width(string); string += char_width; overhead += char_width - 1; } return overhead; }
size_t get_screen_string_length(const char str[]) { size_t length = 0; while(*str != '\0') { const size_t char_width = get_char_width(str); const size_t char_screen_width = get_char_screen_width(str, char_width); str += char_width; length += char_screen_width; } return length; }
size_t get_screen_overhead(const char str[]) { size_t overhead = 0; while(*str != '\0') { const size_t char_width = get_char_width(str); const size_t char_screen_width = get_char_screen_width(str, char_width); str += char_width; overhead += (char_width - 1) - (char_screen_width - 1); } return overhead; }
static void search_buff(const buffer *b, char * p, const int encoding, const bool case_search, const int ext) { assert(p); const int p_len = strlen(p); const int (*cmp)(const char *, const char *, size_t) = case_search ? strncmp : strncasecmp; for(line_desc *ld = (line_desc *)b->line_desc_list.head, *next; next = (line_desc *)ld->ld_node.next; ld = next) { int64_t l = 0, r = 0; do { /* find left edge of word */ while (l < ld->line_len - p_len && !ne_isword(get_char(&ld->line[l], b->encoding), b->encoding)) l += get_char_width(&ld->line[l], b->encoding); if (l < ld->line_len - p_len ) { int ch; /* find right edge of word */ r = l + get_char_width(&ld->line[l], b->encoding); /* accept "'" as a word character if it is followed by another word character, so that words like "don't" are not broken into "don" and "t". */ while (r < ld->line_len && ( ne_isword(ch=get_char(&ld->line[r], b->encoding), b->encoding) || ( r+1 < ld->line_len && ch == '\'' && ne_isword(get_char(&ld->line[r+1], b->encoding), b->encoding)) ) ) r += get_char_width(&ld->line[r], b->encoding); if ((b != cur_buffer || ld != b->cur_line_desc || b->cur_pos < l || r < b->cur_pos) && r - l > p_len && (b->encoding == encoding || is_ascii(&ld->line[l], r - l)) && !cmp(p, &ld->line[l], p_len)) add_string(&ld->line[l], r - l, ext); l = r; count_scanned++; } assert(l <= ld->line_len); if (stop || count_scanned >= MAX_AUTOCOMPLETE_SCAN) { add_string(NULL, -1, 0); return; } } while (l < ld->line_len - p_len); } add_string(NULL, -1, 0); }
void put_char_in_buffer(unsigned char ch) { input_text_line[input_text_lenght]=ch; input_text_line[input_text_lenght+1]='_'; input_text_line[input_text_lenght+2]=0; input_text_lenght++; if(input_text_lenght==(input_text_lines*(window_width-hud_x))/(get_char_width(ch)-1)-1) { input_text_line[input_text_lenght]=0x0a; input_text_line[input_text_lenght+1]='_'; input_text_line[input_text_lenght+2]=0; input_text_lenght++; input_text_lines++; } }
int get_line_width (char *s) { int w, w2, s2; if (!s) return 0; for (w = 0; *s && (*s != '\n'); s++) { if (*s <= 0x06) { if (*s <= 0x03) s++; continue;//skip color codes. } get_char_width (s[0], s[1], &w2, &s2); w += s2; } return w; }
static void size_new_toplevel (windata_t *vwin) { int cw = get_char_width(vwin->text); int hsize, vsize; if (vwin->role == EDIT_SCRIPT) { hsize = SCRIPT_WIDTH; vsize = SCRIPT_HEIGHT; } else { hsize = 63; /* MODEL_WIDTH ? */ vsize = MODEL_HEIGHT; } hsize *= cw; hsize += 48; gtk_window_set_default_size(GTK_WINDOW(vwin->main), hsize, vsize); }
size_t get_real_string_width(const char str[], size_t max_screen_width) { size_t width = 0; while(*str != '\0' && max_screen_width != 0) { size_t char_width = get_char_width(str); size_t char_screen_width = get_char_screen_width(str, char_width); if(char_screen_width > max_screen_width) { break; } max_screen_width -= char_screen_width; width += char_width; str += char_width; } return width; }
button_t* initialize_button_t (coord_t pos,char * text, int(*action)(), int size, float trans) { button_t* out = malloc(sizeof(button_t)); out->text = text; out->pos.y = pos.y; out->action = action; out->height = get_line_space(size); size_t i = 0; out->width = 0; for(; text[i] != '\0'; i++) { out->width += get_char_width(text[i], size) + get_char_sep(size); } out->width -= get_char_sep(size); out->pos.x = get_h_res()/2 - out->width /2; out->size = size; out->trans = trans; return out; }
static GtkWidget *dlg_text_edit_new (int *hsize, gboolean s) { GtkTextBuffer *tbuf; GtkWidget *tview; tbuf = gtk_text_buffer_new(NULL); tview = gtk_text_view_new_with_buffer(tbuf); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tview), GTK_WRAP_WORD); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(tview), 4); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(tview), 4); gtk_widget_modify_font(GTK_WIDGET(tview), fixed_font); *hsize *= get_char_width(tview); *hsize += 48; gtk_text_view_set_editable(GTK_TEXT_VIEW(tview), s); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(tview), s); return tview; }
static void input_move_to_eol(void) { const int width_to_end = get_string_width(input_buffer + pos, len - pos, encoding); if (x + width_to_end < ne_columns) { x += width_to_end; pos = len; return; } x = start_x; pos = offset = len; int i = ne_columns - 1 - start_x; for(;;) { const int prev = prev_pos(input_buffer, offset, encoding); const int width = get_char_width(&input_buffer[prev], encoding); if (i - width < 0) break; offset = prev; i -= width; x += width; } input_refresh(); }
void draw_ortho_ingame_string(float x, float y,float z, const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL int font_x_size=FONT_X_SPACING; int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifndef SKY_FPV_OPTIONAL /* if(big) { displayed_font_x_size=0.17*zoom_level*name_zoom/3.0; displayed_font_y_size=0.25*zoom_level*name_zoom/3.0; } else { displayed_font_x_size=SMALL_INGAME_FONT_X_LEN*zoom_level*name_zoom/3.0; displayed_font_y_size=SMALL_INGAME_FONT_Y_LEN*zoom_level*name_zoom/3.0; } */ #endif // not SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*name_zoom*12.0; displayed_font_y_size=font_y_scale*name_zoom*12.0; glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*font_x_size+ignored_bits)/256.0f; u_end=(float)(row*font_x_size+font_x_size-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*font_y_size)/256.0f; v_end=(float)(col*font_y_size+font_y_size-1)/256.0f; #else v_start=(float)1.0f-(1+col*font_y_size)/256.0f; v_end=(float)1.0f-(col*font_y_size+font_y_size-1)/256.0f; #endif //NEW_TEXTURES //v_end=(float)1.0f-(col*font_y_size+font_y_size-2)/256.0f; glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); //cur_x+=displayed_font_x_size; cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; } else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=x; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); cur_x+=displayed_font_x_width; } else if(is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); } void draw_ingame_string(float x, float y,const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL //int font_x_size=FONT_X_SPACING; //int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifdef SKY_FPV_OPTIONAL double model[16], proj[16],hx,hy,hz; int view[4]; displayed_font_x_size=font_x_scale*name_zoom*12.0*font_scale; displayed_font_y_size=font_y_scale*name_zoom*12.0*font_scale; glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject((double)x,0.0f,(double)y,model, proj, view, &hx,&hy,&hz); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(view[0],view[2]+view[0],view[1],view[3]+view[1],0.0f,-1.0f); #endif // SKY_FPV_OPTIONAL #ifndef SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*zoom_level*name_zoom/3.0; displayed_font_y_size=font_y_scale*zoom_level*name_zoom/3.0; #endif // not SKY_FPV_OPTIONAL glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; #ifndef SKY_FPV_OPTIONAL cur_x=x; cur_y=y; #else // SKY_FPV_OPTIONAL cur_x=hx; cur_y=hy; #endif // SKY_FPV_OPTIONAL glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if(is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,0,cur_y+displayed_font_y_size); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,0,cur_y); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,0,cur_y); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,0,cur_y+displayed_font_y_size); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; }else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=hx; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif // NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,0); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,0); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,0); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,0); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); #ifdef SKY_FPV_OPTIONAL glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); #endif // SKY_FPV_OPTIONAL } #endif //!MAP_EDITOR_2 #endif //ELC // font handling int get_font_width(int cur_char) { // ignore unknown characters if (cur_char < 0) { return 0; } // return width of character + spacing between chars (supports variable width fonts) return (fonts[cur_font_num]->widths[cur_char] + fonts[cur_font_num]->spacing); } int get_char_width(unsigned char cur_char) { return get_font_width(get_font_char(cur_char)); } int get_string_width(const unsigned char *str) { return get_nstring_width(str, strlen((char*)str)); } int get_nstring_width(const unsigned char *str, int len) { int i, wdt=0; for(i=0; i<len; i++) { wdt+= get_char_width(str[i]); } // adjust to ignore the final spacing wdt-= fonts[cur_font_num]->spacing; return wdt; }
int get_nstring_width(const unsigned char *str, int len) { int i, wdt=0; for(i=0; i<len; i++) wdt+=get_char_width(str[i]); return wdt; }
/* * create variables tree view widget * arguments: * on_render_name - custom name column renderer function * on_expression_changed - callback to call on expression changed */ GtkWidget* vtree_create(watch_render_name on_render_name, watch_expression_changed on_expression_changed) { /* create tree view */ GtkTreeStore* store = gtk_tree_store_new ( W_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); GtkWidget* tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)); /* set tree view parameters */ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(tree), GTK_TREE_VIEW_GRID_LINES_VERTICAL); g_object_set(tree, "rules-hint", TRUE, NULL); /* connect signals */ g_signal_connect(G_OBJECT(tree), "row-collapsed", G_CALLBACK (on_row_collapsed), NULL); g_signal_connect(G_OBJECT(tree), "key-press-event", G_CALLBACK (on_key_pressed), NULL); /* create columns */ GtkCellRenderer *renderer; GtkTreeViewColumn *column; gchar *header; int char_width = get_char_width(tree); /* Name */ header = _("Name"); renderer = gtk_cell_renderer_text_new (); column = create_column(header, renderer, FALSE, get_header_string_width(header, MW_NAME, char_width), "text", W_NAME); if (on_render_name) gtk_tree_view_column_set_cell_data_func(column, renderer, on_render_name, NULL, NULL); if (on_expression_changed) { g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (on_expression_changed), NULL); } gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* Value */ header = _("Value"); renderer = gtk_cell_renderer_text_new (); column = create_column(header, renderer, TRUE, get_header_string_width(header, MW_VALUE, char_width), "text", W_VALUE); gtk_tree_view_column_set_cell_data_func(column, renderer, render_value, NULL, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* Type */ header = _("Type"); renderer = gtk_cell_renderer_text_new (); column = create_column(header, renderer, FALSE, get_header_string_width(header, MW_TYPE, char_width), "text", W_TYPE); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* Internal (unvisible column) */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Internal", renderer, "text", W_INTERNAL, NULL); gtk_tree_view_column_set_visible(column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* Path expression (unvisible column) */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Expression", renderer, "text", W_EXPRESSION, NULL); gtk_tree_view_column_set_visible(column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* STUB (unvisible column) */ renderer = gtk_cell_renderer_toggle_new (); column = gtk_tree_view_column_new_with_attributes ("Need Update", renderer, "active", W_STUB, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); gtk_tree_view_column_set_visible(column, FALSE); /* Changed (unvisible column) */ renderer = gtk_cell_renderer_toggle_new (); column = gtk_tree_view_column_new_with_attributes ("Changed", renderer, "active", W_CHANGED, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); gtk_tree_view_column_set_visible(column, FALSE); return tree; }
size_t utf8_get_screen_width_of_char(const char str[]) { return get_char_screen_width(str, get_char_width(str)); }
int gr_internal_string0m(int x, int y, unsigned char *s ) { unsigned char * fp; unsigned char * text_ptr, * next_row, * text_ptr1; int r, BitMask, i, bits, width, spacing, letter, underline; unsigned int VideoOffset, VideoOffset1; VideoOffset1 = y * ROWSIZE + x; next_row = s; while (next_row != NULL ) { text_ptr1 = next_row; next_row = NULL; if (x==0x8000) { //centered int xx = get_centered_x(text_ptr1); VideoOffset1 = y * ROWSIZE + xx; } for (r=0; r<FHEIGHT; r++) { text_ptr = text_ptr1; VideoOffset = VideoOffset1; while (*text_ptr) { if (*text_ptr == '\n' ) { next_row = &text_ptr[1]; break; } underline = 0; if (*text_ptr == '&' ) { if ((r==FBASELINE+2) || (r==FBASELINE+3)) underline = 1; text_ptr++; } get_char_width(text_ptr[0],text_ptr[1],&width,&spacing); letter = *text_ptr-FMINCHAR; if (!INFONT(letter)) { //not in font, draw as space VideoOffset += spacing; text_ptr++; continue; } if (FFLAGS & FT_PROPORTIONAL) fp = FCHARS[letter]; else fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT; if (underline) for (i=0; i< width; i++ ) DATA[VideoOffset++] = FG_COLOR; else { fp += BITS_TO_BYTES(width)*r; BitMask = 0; for (i=0; i< width; i++ ) { if (BitMask==0) { bits = *fp++; BitMask = 0x80; } if (bits & BitMask) DATA[VideoOffset++] = FG_COLOR; else VideoOffset++; BitMask >>= 1; } } text_ptr++; VideoOffset += spacing-width; } VideoOffset1 += ROWSIZE; y++; } } return 0; }
int gr_internal_string2(int x, int y, unsigned char *s ) { unsigned char * fp; unsigned char * text_ptr, * next_row, * text_ptr1; int r, BitMask, i, bits, width, spacing, letter, underline; int page_switched; unsigned int VideoOffset, VideoOffset1; VideoOffset1 = (unsigned long)DATA + y * ROWSIZE + x; gr_vesa_setpage(VideoOffset1 >> 16); VideoOffset1 &= 0xFFFF; next_row = s; while (next_row != NULL ) { text_ptr1 = next_row; next_row = NULL; if (x==0x8000) { //centered int xx = get_centered_x(text_ptr1); VideoOffset1 = y * ROWSIZE + xx; gr_vesa_setpage(VideoOffset1 >> 16); VideoOffset1 &= 0xFFFF; } for (r=0; r<FHEIGHT; r++) { text_ptr = text_ptr1; VideoOffset = VideoOffset1; page_switched = 0; while (*text_ptr) { if (*text_ptr == '\n' ) { next_row = &text_ptr[1]; break; } underline = 0; if (*text_ptr == '&' ) { if ((r==FBASELINE+2) || (r==FBASELINE+3)) underline = 1; text_ptr++; } get_char_width(text_ptr[0],text_ptr[1],&width,&spacing); Assert(width==spacing); //no kerning support here letter = *text_ptr-FMINCHAR; if (!INFONT(letter)) { //not in font, draw as space VideoOffset += spacing; text_ptr++; continue; } if (FFLAGS & FT_PROPORTIONAL) fp = FCHARS[letter]; else fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT; if (underline) { if ( VideoOffset+width > 0xFFFF ) { for (i=0; i< width; i++ ) { gr_video_memory[VideoOffset++] = FG_COLOR; if (VideoOffset > 0xFFFF ) { VideoOffset -= 0xFFFF + 1; page_switched = 1; gr_vesa_incpage(); } } } else { for (i=0; i< width; i++ ) gr_video_memory[VideoOffset++] = FG_COLOR; } } else { // fp -- dword // VideoOffset // width fp += BITS_TO_BYTES(width)*r; BitMask = 0; if ( VideoOffset+width > 0xFFFF ) { for (i=0; i< width; i++ ) { if (BitMask==0) { bits = *fp++; BitMask = 0x80; } if (bits & BitMask) gr_video_memory[VideoOffset++] = FG_COLOR; else gr_video_memory[VideoOffset++] = BG_COLOR; BitMask >>= 1; if (VideoOffset > 0xFFFF ) { VideoOffset -= 0xFFFF + 1; page_switched = 1; gr_vesa_incpage(); } } } else { if (width == 8 ) { bits = *fp++; if (bits & 0x80) gr_video_memory[VideoOffset+0] = FG_COLOR; else gr_video_memory[VideoOffset+0] = BG_COLOR; if (bits & 0x40) gr_video_memory[VideoOffset+1] = FG_COLOR; else gr_video_memory[VideoOffset+1] = BG_COLOR; if (bits & 0x20) gr_video_memory[VideoOffset+2] = FG_COLOR; else gr_video_memory[VideoOffset+2] = BG_COLOR; if (bits & 0x10) gr_video_memory[VideoOffset+3] = FG_COLOR; else gr_video_memory[VideoOffset+3] = BG_COLOR; if (bits & 0x08) gr_video_memory[VideoOffset+4] = FG_COLOR; else gr_video_memory[VideoOffset+4] = BG_COLOR; if (bits & 0x04) gr_video_memory[VideoOffset+5] = FG_COLOR; else gr_video_memory[VideoOffset+5] = BG_COLOR; if (bits & 0x02) gr_video_memory[VideoOffset+6] = FG_COLOR; else gr_video_memory[VideoOffset+6] = BG_COLOR; if (bits & 0x01) gr_video_memory[VideoOffset+7] = FG_COLOR; else gr_video_memory[VideoOffset+7] = BG_COLOR; VideoOffset += 8; } else { for (i=0; i< width/2 ; i++ ) { if (BitMask==0) { bits = *fp++; BitMask = 0x80; } if (bits & BitMask) gr_video_memory[VideoOffset++] = FG_COLOR; else gr_video_memory[VideoOffset++] = BG_COLOR; BitMask >>= 1; // Unroll twice if (BitMask==0) { bits = *fp++; BitMask = 0x80; } if (bits & BitMask) gr_video_memory[VideoOffset++] = FG_COLOR; else gr_video_memory[VideoOffset++] = BG_COLOR; BitMask >>= 1; } } } } text_ptr++; } VideoOffset1 += ROWSIZE; y++; if (VideoOffset1 > 0xFFFF ) { VideoOffset1 -= 0xFFFF + 1; if (!page_switched) gr_vesa_incpage(); } }
int reset_soft_breaks (char *str, int len, int size, float zoom, int width, int *cursor, float *max_line_width) { char *buf; int ibuf; int nchar; int font_bit_width; int nlines; float line_width; int isrc, idst; int lastline; int dcursor = 0; /* the generic special text window code needs to know the maximum line length in pixels. This information is used but was previously throw away in this function. Others may fine it useful for setting the winow size, so pass back to the caller if they provide somewhere to store it. */ float local_max_line_width = 0; // error checking if (str == NULL || width <= 0 || size <= 0) { return 0; } /* strip existing soft breaks before we start, to avoid complicated code later */ for (isrc=0, idst=0; isrc<len; isrc++) { if (str[isrc] == '\r') { /* move the cursor back if after this point */ if ((cursor != NULL) && (isrc < *cursor)) dcursor--; } else str[idst++] = str[isrc]; } len = idst; str[len] = 0; /* allocate the working buffer so it can hold the maximum the source string can take. Previously, the fixed length buffer was sometimes not big enough. The code looked to attempt to cope but was floored. When ever the wrap caused more characters to be in the output, some of the source would be lost. This is still possable if the source size cannot take the extra characters. For example, try #glinfo and watch as the end characters are lost. At least characters are no longer lost wrap process. If you make size large enough for no character will be lost. Twice the actual string length is probably enough */ buf = (char *)calloc(size, sizeof(char)); nlines = 1; isrc = ibuf = idst = 0; line_width = 0; lastline = 0; // fill the buffer while (isrc < len && str[isrc] != '\0') { // see if it's an explicit line break if (str[isrc] == '\n') { nlines++; if (line_width > local_max_line_width) local_max_line_width = line_width; line_width = 0; } else { font_bit_width = (int) (0.5f + get_char_width (str[isrc]) * 11.0f * zoom / 12.0f); if (line_width + font_bit_width >= width) { // search back for a space for (nchar = 0; ibuf-nchar-1 > lastline; nchar++) { if (buf[ibuf-nchar-1] == ' ') { break; } } if (ibuf-nchar-1 <= lastline) // no space found, introduce a break in // the middle of the word nchar = 0; // introduce the break, and reset the counters ibuf -= nchar; isrc -= nchar; buf[ibuf] = '\r'; nlines++; ibuf++; if (cursor && isrc < *cursor) { dcursor++; } if (ibuf >= size - 1) { break; } if (line_width > local_max_line_width) local_max_line_width = line_width; lastline = ibuf; line_width = font_bit_width; } else { line_width += font_bit_width; } } // copy the character into the buffer buf[ibuf] = str[isrc]; isrc++; ibuf++; if (ibuf >= size - 1) { break; } } safe_strncpy(str, buf, size * sizeof(char)); str[size-1] = '\0'; if (cursor) { *cursor += dcursor; if(*cursor > size-1) { /* If there's a better way to detect this, please do */ *cursor = size-1; } } free(buf); if (line_width > local_max_line_width) local_max_line_width = line_width; if (max_line_width!=NULL) *max_line_width = local_max_line_width; return nlines; }