Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) const { ERR_FAIL_COND_V(p_width <= 0, Vector2(0, get_height())); int l = p_string.length(); if (l == 0) return Size2(p_width, get_height()); float line_w = 0; float h = 0; float space_w = get_char_size(' ').width; Vector<String> lines = p_string.split("\n"); for (int i = 0; i < lines.size(); i++) { h += get_height(); String t = lines[i]; line_w = 0; Vector<String> words = t.split(" "); for (int j = 0; j < words.size(); j++) { line_w += get_string_size(words[j]).x; if (line_w > p_width) { h += get_height(); line_w = get_string_size(words[j]).x; } else { line_w += space_w; } } } return Size2(p_width, h); }
void Font::draw(RID p_canvas_item, const Point2& p_pos, const String& p_text, const Color& p_modulate,int p_clip_w) const { Point2 pos=p_pos; float ofs=0; VisualServer *vs = VisualServer::get_singleton(); for (int i=0;i<p_text.length();i++) { const Character * c = char_map.getptr(p_text[i]); if (!c) continue; // if (p_clip_w>=0 && (ofs+c->rect.size.width)>(p_clip_w)) // break; //width exceeded if (p_clip_w>=0 && (ofs+c->rect.size.width)>p_clip_w) break; //clip Point2 cpos=pos; cpos.x+=ofs+c->h_align; cpos.y-=ascent; cpos.y+=c->v_align; ERR_CONTINUE( c->texture_idx<-1 || c->texture_idx>=textures.size()); if (c->texture_idx!=-1) textures[c->texture_idx]->draw_rect_region( p_canvas_item, Rect2( cpos, c->rect.size ), c->rect, p_modulate ); ofs+=get_char_size(p_text[i],p_text[i+1]).width; } }
void Font::draw(RID p_canvas_item, const Point2& p_pos, const String& p_text, const Color& p_modulate,int p_clip_w) const { Vector2 ofs; for (int i=0;i<p_text.length();i++) { int width = get_char_size(p_text[i]).width; if (p_clip_w>=0 && (ofs.x+width)>p_clip_w) break; //clip ofs.x+=draw_char(p_canvas_item,p_pos+ofs,p_text[i],p_text[i+1],p_modulate); } }
Size2 Font::get_string_size(const String& p_string) const { float w=0; int l = p_string.length(); if (l==0) return Size2(0,height); const CharType *sptr = &p_string[0]; for (int i=0;i<l;i++) { w+=get_char_size(sptr[i],sptr[i+1]).width; } return Size2(w,height); }
float Font::draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_char,const CharType& p_next,const Color& p_modulate) const { const Character * c = char_map.getptr(p_char); if (!c) return 0; Point2 cpos=p_pos; cpos.x+=c->h_align; cpos.y-=ascent; cpos.y+=c->v_align; ERR_FAIL_COND_V( c->texture_idx<-1 || c->texture_idx>=textures.size(),0); if (c->texture_idx!=-1) VisualServer::get_singleton()->canvas_item_add_texture_rect_region( p_canvas_item, Rect2( cpos, c->rect.size ), textures[c->texture_idx]->get_rid(),c->rect, p_modulate ); return get_char_size(p_char,p_next).width; }
float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { const Character *c = char_map.getptr(p_char); if (!c) { if (fallback.is_valid()) return fallback->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline); return 0; } ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), 0); if (!p_outline && c->texture_idx != -1) { Point2 cpos = p_pos; cpos.x += c->h_align; cpos.y -= ascent; cpos.y += c->v_align; VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), false); } return get_char_size(p_char, p_next).width; }
void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w, const Color &p_outline_modulate) const { Vector2 ofs; int chars_drawn = 0; bool with_outline = has_outline(); for (int i = 0; i < p_text.length(); i++) { int width = get_char_size(p_text[i]).width; if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w) break; //clip ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], with_outline ? p_outline_modulate : p_modulate, with_outline); ++chars_drawn; } if (has_outline()) { ofs = Vector2(0, 0); for (int i = 0; i < chars_drawn; i++) { ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], p_modulate, false); } } }
void label_contour( double **data, long nx, long ny, double value, char *string, double xmin, double dx, double ymin, double dy, double error_limit, long label_mode ) { /* long label_mode 0 -> on contours, 1 -> around border */ register double distance, best_distance, nbest_distance; register long iy; long ix, ix_best, iy_best, ix_nbest=0, iy_nbest=0, n_data; double x, y, xmax, ymax, i_int; double xd, yd; double hoff, voff; xmax = xmin + dx*(nx-1); ymax = ymin + dy*(ny-1); if (label_mode==0) { distance = best_distance = 1.0E37; ix_best = iy_best = -1; n_data = nx*ny; for (ix=1; ix<nx-2; ix++) { for (iy=1; iy<ny-2; iy++) { distance = fabs(value - data[ix][iy])/error_limit; if (distance<1) { distance += sqr((ix-nx/2.)/nx)+sqr((iy-ny/2.)/ny); if (distance<best_distance) { ix_nbest = ix_best; iy_nbest = iy_best; nbest_distance = best_distance; ix_best = ix; iy_best = iy; best_distance = distance; } } } } ix = ix_best; iy = iy_best; if (ix==-1) { ix = 0; for (iy=1; iy<ny-2; iy++) { distance = fabs(value - data[ix][iy])/error_limit; if (distance<1) { distance += sqr((ix-nx/2.)/nx)+sqr((iy-ny/2.)/ny); if (distance<best_distance) { ix_nbest = ix_best; iy_nbest = iy_best; nbest_distance = best_distance; ix_best = ix; iy_best = iy; best_distance = distance; } } } if (ix_best==-1) { printf("note: failed to find acceptable contour to label for value %e\n", value); return; } ix = ix_best; iy = iy_best; } if (fabs(value-data[ix][iy])>error_limit) bomb("algorithmic error (1) in label_contour()", NULL); x = dx*ix + xmin; y = dy*iy + ymin; if (ix<nx-1 && data[ix][iy]!=data[ix+1][iy]) x += dx*(value-data[ix][iy])/(data[ix+1][iy]-data[ix][iy]); else if (iy<ny-1 && data[ix][iy]!=data[ix][iy+1]) y += dy*(value-data[ix][iy])/(data[ix][iy+1]-data[ix][iy]); if (x>=xmax-dx/2 || y>=ymax-dy/2 || x<xmin+dx/4 || y<ymin+dy/4) { ix = ix_nbest; iy = iy_nbest; if (ix!=-1) { x = dx*ix + xmin; y = dy*iy + ymin; if (ix<nx-1 && data[ix][iy]!=data[ix+1][iy]) x += dx*(value-data[ix][iy])/(data[ix+1][iy]-data[ix][iy]); else if (iy<ny-1 && data[ix][iy]!=data[ix][iy+1]) y += dy*(value-data[ix][iy])/(data[ix][iy+1]-data[ix][iy]); if (x>=xmax-dx/2 || y>=ymax-dy/2 || x<xmin+dx/4 || y<ymin+dy/4) { printf("note: label algorithm went outside plot region for value %e\n", value); return; } } else { printf("note: label algorithm went outside plot region for value %e\n", value); return; } } xd = x; yd = y; plot_string(&xd, &yd, string); } else { distance = best_distance = 1.0E37; vertical_print(1); /* search for end of contour along top edge */ iy = ny-1; get_char_size(&hoff, &voff, 1); for (ix=nx-1; ix>0; ix--) { if ((data[ix][iy]<value && data[(ix-1)][iy]>=value) || (data[ix][iy]>value && data[(ix-1)][iy]<=value) ) { xd = xmin + hoff/3 + dx*(i_int=INTERPOLATE(ix-1, ix, data[ix-1][iy], data[ix][iy], value)); if (i_int>=ix-1 && i_int<=ix) { yd = ymin + (ny-1)*dy + (value>0?voff:voff/2); plot_string(&xd, &yd, string); } } } /* search for end of contour along right edge */ ix = nx-1; vertical_print(0); get_char_size(&hoff, &voff, 1); for (iy=1; iy<ny; iy++) { if ((data[ix][iy]<value && value<=data[ix][iy-1]) || (data[ix][iy]>value && value>=data[ix][iy-1]) ) { yd = ymin - 2*voff/3 + dy*(i_int=INTERPOLATE(iy-1, iy, data[ix][iy-1], data[ix][iy], value)); if (!(i_int<iy-1 || i_int>iy)) { xd = xmin + (nx-1)*dx + hoff/2; plot_string(&xd, &yd, string); } } } } }
SchObj read_sharp_sequence( SchPort* port ) { unsigned int c = SCH_GETC(port); char *s, *format; char msg[256]; /* TODO hard code */ int size; switch(c) { case 't': s = token(port); if ( STRLEN(s) != 0 ) { format="#t followed by garbage \"%s\""; sprintf(msg,format,s); EXCEPTION(msg); break; } else { return SCH_TRUE; } case 'f': s = token(port); if ( STRLEN(s) != 0 ) { format="#f followed by garbage \"%s\""; sprintf(msg,format,s); EXCEPTION(msg); break; } else { return SCH_FALSE; } case '\\': c = SCH_GETC(port); size = get_char_size(c); if ( size > 1 ) { unsigned int c4 = (unsigned char)c; while ( --size > 0 && (c = SCH_GETC(port)) ) { c4 = ((c4 << 8) | (unsigned char)c); } return make_char(c4); } else { s = token(port); if ( strlen(s) == 0 ) { return make_char(c); } else if (c == 's') { if ( strcmp(s,"pace") == 0 ) { return make_char(' '); } } else if (c == 'n') { if ( strcmp(s,"ewline") == 0 ) { return make_char('\n'); } } else if (c == 't') { if ( strcmp(s,"ab") == 0 ) { return make_char('\t'); } } else if (c == 'f') { if ( strcmp(s,"ormfeed") == 0 ) { return make_char('\f'); } } else if (c == 'r') { if ( strcmp(s,"eturn") == 0 ) { return make_char('\r'); } } else { char msg[256]; char* format="unknown character #\\%c%s"; sprintf(msg,format,c,s); EXCEPTION(msg); } } break; case '(': { SchObj x, vec; size = 0; SchVecLList* lst = make_vec_llist(); while ( (x = read_obj(port)) != SCH_KOKKA ) { vec_push(lst,x); size++; } vec = (SchObj)make_vec_from_list(lst,size); return vec; } case 'b': s = token(port); return read_number(s, 2); case 'o': s = token(port); return read_number(s, 8); case 'd': s = token(port); return read_number(s, 10); case 'x': s = token(port); return read_number(s, 16); default: format = "unknown syntax #%c"; sprintf(msg,format,c); EXCEPTION(msg); } return SCH_UNDEFINE; }