handle TABs in draw_string() (also ps and svg draw_string()), tcl var tabstop (default = 8) sets the tab positions.

This commit is contained in:
stefan schippers 2024-05-23 00:57:45 +02:00
parent 747652ffe1
commit 17bf6f3efb
8 changed files with 111 additions and 22 deletions

View File

@ -261,6 +261,7 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
char c;
int lineno=0;
double size;
char *estr = NULL; /* expanded str: tabs replaced with spaces */
cairo_font_extents_t fext;
int llength=0, no_of_lines;
double longest_line;
@ -271,8 +272,8 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
/*fprintf(errfp, "size=%.16g\n", size*xctx->mooz); */
if(size*xctx->mooz<3.0) return; /* too small */
if(size*xctx->mooz>1600) return; /* too big */
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
estr = my_expand(str, tclgetintvar("tabstop"));
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
&textx1,&texty1,&textx2,&texty2, &no_of_lines, &longest_line);
if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,
xctx->areay2,textx1,texty1,textx2,texty2)) {
@ -307,7 +308,7 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
dbg(1, "draw_string(): size * mooz=%g height=%g ascent=%g descent=%g\n",
size * xctx->mooz, fext.height, fext.ascent, fext.descent);
llength=0;
my_strdup2(_ALLOC_ID_, &sss, str);
my_strdup2(_ALLOC_ID_, &sss, estr);
tt=ss=sss;
for(;;) {
c=*ss;
@ -329,6 +330,7 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
++ss;
}
my_free(_ALLOC_ID_, &sss);
my_free(_ALLOC_ID_, &estr);
}
#else /* !HAS_CAIRO */
@ -355,9 +357,10 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
return;
}
else {
char *estr = my_expand(str, tclgetintvar("tabstop"));
xscale*=tclgetdoublevar("nocairo_font_xscale") * cairo_font_scale;
yscale*=tclgetdoublevar("nocairo_font_yscale") * cairo_font_scale;
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x1,y1,
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter, x1,y1,
&textx1,&texty1,&textx2,&texty2, &no_of_lines, &longest_line);
if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,
textx1,texty1,textx2,texty2)) return;
@ -366,8 +369,8 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
else rot=0;
flip = 0; yy=y1;
invxscale=1/xscale;
while(str[pos2]) {
cc = (unsigned char)str[pos2++];
while(estr[pos2]) {
cc = (unsigned char)estr[pos2++];
if(cc>127) cc= '?';
if(cc=='\n') {
yy+=(FONTHEIGHT+FONTDESCENT+FONTWHITESPACE)* yscale;
@ -394,6 +397,7 @@ void draw_string(int layer, int what, const char *str, short rot, short flip, in
++pos;
a += FONTWIDTH+FONTWHITESPACE;
}
my_free(_ALLOC_ID_, &estr);
}
}
@ -405,12 +409,15 @@ void draw_temp_string(GC gctext, int what, const char *str, short rot, short fli
double textx1,textx2,texty1,texty2;
int tmp;
double dtmp;
char *estr = NULL;
if(!has_x) return;
dbg(2, "draw_string(): string=%s\n",str);
if(!text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x1,y1,
estr = my_expand(str, tclgetintvar("tabstop"));
dbg(2, "draw_string(): string=%s\n",estr);
if(!text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter, x1,y1,
&textx1,&texty1,&textx2,&texty2, &tmp, &dtmp)) return;
drawtemprect(gctext,what, textx1,texty1,textx2,texty2);
my_free(_ALLOC_ID_, &estr);
}

View File

@ -224,6 +224,38 @@ void my_strndup(int id, char **dest, const char *src, size_t n) /* empty source
}
}
/* replace TABs with required number of spaces
* User must free returned string */
char *my_expand(const char *s, int tabstop)
{
char pad[200];
size_t spos = 0;
char *t = NULL;
const char *sptr = s;
if(!s) {
return NULL;
}
my_strcat2(_ALLOC_ID_, &t, "");
while(*sptr) {
if(*sptr == '\t') {
int i;
size_t npad = tabstop - spos % tabstop;
for(i = 0; i < npad; i++) pad[i] = ' ';
pad[i] = '\0';
spos += npad;
} else {
pad[0] = *sptr;
pad[1] = '\0';
spos++;
}
my_strcat2(_ALLOC_ID_, &t, pad);
if(*sptr == '\n') spos = 0;
sptr++;
}
return t;
}
void dbg(int level, char *fmt, ...)
{
if(debug_var>=level) {
@ -590,6 +622,31 @@ size_t my_strcat(int id, char **str, const char *append_str)
}
}
/* same as my_strcat, but appending "" to NULL returns "" instead of NULL */
size_t my_strcat2(int id, char **str, const char *append_str)
{
size_t s, a;
dbg(3,"my_strcat(%d,): str=%s append_str=%s\n", id, *str, append_str);
if( *str != NULL)
{
s = strlen(*str);
if(append_str == NULL || append_str[0]=='\0') return s;
a = strlen(append_str) + 1;
my_realloc(id, str, s + a );
memcpy(*str + s, append_str, a);
dbg(3,"my_strcat(%d,): reallocated string %s\n", id, *str);
return s + a - 1;
} else { /* str == NULL */
if(append_str == NULL ) return 0;
a = strlen(append_str) + 1;
*str = my_malloc(id, a );
memcpy(*str, append_str, a);
dbg(3,"my_strcat(%d,): allocated string %s\n", id, *str);
return a - 1;
}
}
size_t my_strncat(int id, char **str, size_t n, const char *append_str)
{
size_t s, a;

View File

@ -194,6 +194,7 @@ Hilight_hashentry *bus_hilight_hash_lookup(const char *token, int value, int wha
return ptr2;
}
/* highlight an arbitrary hierarchic net */
Hilight_hashentry *hier_hilight_hash_lookup(const char *token, int value, const char *path, int what)
{
Hilight_hashentry *entry;

View File

@ -668,6 +668,7 @@ static void ps_draw_string(int layer, const char *str, short rot, short flip, in
char *tt, *ss, *sss=NULL;
double textx1,textx2,texty1,texty2;
char c;
char *estr = NULL; /* expanded string: TABs replaced with spaces */
int lineno=0;
double size, height, ascent, descent;
int llength=0, no_of_lines;
@ -679,7 +680,8 @@ static void ps_draw_string(int layer, const char *str, short rot, short flip, in
ascent = size*xctx->mooz * 0.808; /* was 0.908 */
descent = size*xctx->mooz * 0.219; /* was 0.219 */
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter,
estr = my_expand(str, tclgetintvar("tabstop"));
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter,
x,y, &textx1,&texty1,&textx2,&texty2, &no_of_lines, &longest_line);
if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,
@ -707,7 +709,7 @@ static void ps_draw_string(int layer, const char *str, short rot, short flip, in
if(rot == 3 && flip == 1 ) { x=textx1;}
}
llength=0;
my_strdup2(_ALLOC_ID_, &sss, str);
my_strdup2(_ALLOC_ID_, &sss, estr);
tt=ss=sss;
for(;;) {
c=*ss;
@ -726,6 +728,7 @@ static void ps_draw_string(int layer, const char *str, short rot, short flip, in
++ss;
}
my_free(_ALLOC_ID_, &sss);
my_free(_ALLOC_ID_, &estr);
}
static void old_ps_draw_string(int gctext, const char *str,
@ -738,15 +741,17 @@ static void old_ps_draw_string(int gctext, const char *str,
int pos=0,cc,pos2=0;
int i, no_of_lines;
double longest_line;
char *estr = NULL;
if(str==NULL) return;
estr = my_expand(str, tclgetintvar("tabstop"));
xscale*=tclgetdoublevar("nocairo_font_xscale") * cairo_font_scale;
yscale*=tclgetdoublevar("nocairo_font_yscale") * cairo_font_scale;
#if HAS_CAIRO==1
text_bbox_nocairo(str, xscale, yscale, rot, flip, hcenter, vcenter,
text_bbox_nocairo(estr, xscale, yscale, rot, flip, hcenter, vcenter,
x1,y1, &rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line);
#else
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter,
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter,
x1,y1, &rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line);
#endif
@ -756,9 +761,9 @@ static void old_ps_draw_string(int gctext, const char *str,
if(rot&1) {y1=ry2;rot=3;}
else rot=0;
flip = 0; yy=y1;
while(str[pos2])
while(estr[pos2])
{
cc = (unsigned char)str[pos2++];
cc = (unsigned char)estr[pos2++];
if(cc>127) cc= '?';
if(cc=='\n')
{
@ -781,6 +786,7 @@ static void old_ps_draw_string(int gctext, const char *str,
}
++pos;
}
my_free(_ALLOC_ID_, &estr);
}
static void ps_drawgrid()

View File

@ -5524,7 +5524,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
else if(argc > 2 && atoi(argv[2]) == 3) {
Tcl_ResetResult(interp);
char *s = "aa bb cc dd\n"
"eee fff ggg hhh";
char *t = my_expand(s, 8);
dbg(0, "%s\n----\n", s);
Tcl_SetResult(interp, t, TCL_VOLATILE);
my_free(_ALLOC_ID_, &t);
}
}

View File

@ -323,13 +323,15 @@ static void svg_draw_string(int layer, const char *str, short rot, short flip, i
double size, height, ascent, descent;
int llength=0, no_of_lines;
double longest_line;
char *estr = NULL; /* expanded string: TABs replaced with spaces */
if(str==NULL) return;
estr = my_expand(str, tclgetintvar("tabstop"));
size = xscale*52. * cairo_font_scale;
height = size*xctx->mooz * 1.147;
ascent = size*xctx->mooz * 0.908;
descent = size*xctx->mooz * 0.219;
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
&textx1,&texty1,&textx2,&texty2, &no_of_lines, &longest_line);
if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,textx1,texty1,textx2,texty2)) {
return;
@ -355,7 +357,7 @@ static void svg_draw_string(int layer, const char *str, short rot, short flip, i
if(rot == 3 && flip == 1 ) { x=textx1;}
}
llength=0;
my_strdup2(_ALLOC_ID_, &sss, str);
my_strdup2(_ALLOC_ID_, &sss, estr);
tt=ss=sss;
for(;;) {
c=*ss;
@ -374,6 +376,7 @@ static void svg_draw_string(int layer, const char *str, short rot, short flip, i
++ss;
}
my_free(_ALLOC_ID_, &sss);
my_free(_ALLOC_ID_, &estr);
}
@ -387,15 +390,17 @@ static void old_svg_draw_string(int layer, const char *str,
int pos=0,cc,pos2=0;
int i, no_of_lines;
double longest_line;
char *estr = NULL;
if(str==NULL) return;
estr = my_expand(str, tclgetintvar("tabstop"));
xscale*=tclgetdoublevar("nocairo_font_xscale") * cairo_font_scale;
yscale*=tclgetdoublevar("nocairo_font_yscale") * cairo_font_scale;
#if HAS_CAIRO==1
text_bbox_nocairo(str, xscale, yscale, rot, flip, hcenter, vcenter,
text_bbox_nocairo(estr, xscale, yscale, rot, flip, hcenter, vcenter,
x,y, &rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line);
#else
text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
text_bbox(estr, xscale, yscale, rot, flip, hcenter, vcenter, x,y,
&rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line);
#endif
if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,rx1,ry1,rx2,ry2)) return;
@ -403,9 +408,9 @@ static void old_svg_draw_string(int layer, const char *str,
if(rot&1) {y=ry2;rot=3;}
else rot=0;
flip = 0; yy=y;
while(str[pos2])
while(estr[pos2])
{
cc = (unsigned char)str[pos2++];
cc = (unsigned char)estr[pos2++];
if(cc>127) cc= '?';
if(cc=='\n')
{
@ -427,6 +432,7 @@ static void old_svg_draw_string(int layer, const char *str,
}
++pos;
}
my_free(_ALLOC_ID_, &estr);
}

View File

@ -1285,6 +1285,7 @@ extern void set_grid(double);
extern void create_plot_cmd(void);
extern int set_modify(int mod); /* return number of floaters */
extern int there_are_floaters(void);
extern char *my_expand(const char *s, int tabstop) ;
extern void dbg(int level, char *fmt, ...);
extern unsigned int hash_file(const char *f, int skip_path_lines);
extern void here(double i);
@ -1624,6 +1625,7 @@ extern void my_realloc(int id, void *ptr,size_t size);
extern void *my_calloc(int id, size_t nmemb, size_t size);
extern char *my_free(int id, void *ptr);
extern size_t my_strcat(int id, char **, const char *);
extern size_t my_strcat2(int id, char **, const char *);
extern size_t my_mstrcat(int id, char **str, const char *append_str, ...);
extern char *my_itoa(int i);
extern double atof_spice(const char *s);

View File

@ -6935,7 +6935,7 @@ set tctx::global_list {
search_select search_value selected_tok show_hidden_texts show_infowindow
show_infowindow_after_netlist
simconf_default_geometry simconf_vpos simulate_bg spiceprefix split_files svg_colors
svg_font_name sym_txt symbol symbol_width tclcmd_txt tclstop text_line_default_geometry
svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop text_line_default_geometry
text_replace_selection textwindow_fileid textwindow_filename textwindow_w
toolbar_horiz toolbar_list
toolbar_visible transparent_svg undo_type use_lab_wire unselect_partial_sel_wires
@ -8398,6 +8398,8 @@ set_ne en_hilight_conn_inst 0
set_ne to_png {gm convert}
## ps to pdf conversion
set_ne to_pdf {ps2pdf}
## tab stop position
set_ne tabstop 8
# selected graph user is editing attributes with graph GUI
set_ne graph_bus 0