static void calc_entry_dimens(WMenu *menu) { int i, n=extl_table_get_n(menu->tab); GrFontExtents fnte; GrBorderWidths bdw; int maxw=0; char *str; #if 0 if(extl_table_gets_s(menu->tab, title, &str)){ maxw=grbrush_get_text_width(title_brush, str, strlen(str)); free(str); } #endif for(i=1; i<=n; i++){ if(extl_table_getis(menu->tab, i, "name", 's', &str)){ int w=grbrush_get_text_width(menu->entry_brush, str, strlen(str)); if(w>maxw) maxw=w; free(str); } } grbrush_get_border_widths(menu->entry_brush, &bdw); grbrush_get_font_extents(menu->entry_brush, &fnte); menu->max_entry_w=maxw+bdw.left+bdw.right; menu->entry_h=fnte.max_height+bdw.top+bdw.bottom; menu->entry_spacing=bdw.spacing; }
static void frame_shaped_recalc_bar_size(WFrame *frame, bool complete) { int bar_w=0, textw=0, tmaxw=frame->tab_min_w, tmp=0; WLListIterTmp itmp; WRegion *sub; const char *p; GrBorderWidths bdw; char *title; uint bdtotal; int i, m; if(frame->bar_brush==NULL) return; m=FRAME_MCOUNT(frame); if(m>0){ grbrush_get_border_widths(frame->bar_brush, &bdw); bdtotal=((m-1)*(bdw.tb_ileft+bdw.tb_iright+bdw.spacing) +bdw.right+bdw.left); FRAME_MX_FOR_ALL(sub, frame, itmp){ p=region_displayname(sub); if(p==NULL) continue; textw=grbrush_get_text_width(frame->bar_brush, p, strlen(p)); if(textw>tmaxw) tmaxw=textw; }
static int max_width(GrBrush *brush, const char *str) { int maxw=0, w; while(str && *str!='\0'){ w=grbrush_get_text_width(brush, str, 1); if(w>maxw) maxw=w; str++; } return maxw; }
/* * Temporarily store actual title widths (without truncation) in * frame->titles[*].iw, when calculating tabs widths and bar width. After the * algorithm returns it has to set frame->titles[*].iw to the proper values. * * This function is generic for all algorithms. */ static void get_titles_text_width(WFrame *frame) { int i=0; WLListIterTmp itmp; WRegion *sub; const char *displayname; /* Assume frame->bar_brush != NULL. Assume FRAME_MCOUNT(frame) > 0 */ FRAME_MX_FOR_ALL(sub, frame, itmp){ displayname=region_displayname(sub); if(displayname==NULL) frame->titles[i].iw=0; else frame->titles[i].iw=grbrush_get_text_width(frame->bar_brush, displayname, strlen(displayname)); i++; }
static void frame_shaped_recalc_bar_size(WFrame *frame, bool complete) { int bar_w=0, textw, w, tmaxw, tminw, tmp=0; WLListIterTmp itmp; WRegion *sub; const char *p; GrBorderWidths bdw; char *title; uint bdtotal; int i, m; if(frame->bar_brush==NULL) return; m=FRAME_MCOUNT(frame); bar_w=frame->bar_max_width_q*REGION_GEOM(frame).w; if(m>0){ frame_get_max_width_and_elastic(frame, bar_w, &tmaxw, &tmp, &tminw); //fprintf(stderr," * WID total:%i maxw:%i minw:%i elastic:%i m:%i\n",bar_w,tmaxw,tminw,tmp,m); if ((tmaxw < 0) && (tminw == frame->float_tab_min_w)) { /* No label truncation needed, good. See how much can be padded. */ w=bar_w-tmp; FRAME_MX_FOR_ALL(sub, frame, itmp){ p=region_displayname(sub); if(p==NULL) continue; textw=2*CF_TAB_MAX_TEXT_X_OFF+ grbrush_get_text_width(frame->bar_brush, p, strlen(p))- frame->float_tab_min_w; //fprintf(stderr," * WID addtextw:%i\n",textw); if (textw>=2*CF_TAB_MAX_TEXT_X_OFF) w+=2*CF_TAB_MAX_TEXT_X_OFF; else if (textw >=0) w+=textw; }
static void infowin_resize(WInfoWin *p) { WRQGeomParams rq=RQGEOMPARAMS_INIT; const char *str=INFOWIN_BUFFER(p); GrBorderWidths bdw; GrFontExtents fnte; rq.flags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y; rq.geom.x=REGION_GEOM(p).x; rq.geom.y=REGION_GEOM(p).y; grbrush_get_border_widths(p->brush, &bdw); grbrush_get_font_extents(p->brush, &fnte); rq.geom.w=bdw.left+bdw.right; rq.geom.w+=grbrush_get_text_width(p->brush, str, strlen(str)); rq.geom.h=fnte.max_height+bdw.top+bdw.bottom; if(rectangle_compare(&rq.geom, ®ION_GEOM(p))!=RECTANGLE_SAME) region_rqgeom((WRegion*)p, &rq, NULL); }
char *grbrush_make_label(GrBrush *brush, const char *str, uint maxw) { size_t nmatch=10; regmatch_t pmatch[10]; SR *rule; int ret; char *retstr; bool fits=FALSE; if(grbrush_get_text_width(brush, str, strlen(str))<=maxw) fits=TRUE; /*return scopy(str);*/ for(rule=shortenrules; rule!=NULL; rule=rule->next){ if(fits && !rule->always) continue; ret=regexec(&(rule->re), str, nmatch, pmatch, 0); if(ret!=0) continue; retstr=shorten(brush, str, maxw, rule->rule, nmatch, pmatch); goto rettest; } if(fits){ retstr=scopy(str); }else{ pmatch[0].rm_so=0; pmatch[0].rm_eo=strlen(str)-1; retstr=shorten(brush, str, maxw, "$1$<...", 1, pmatch); } rettest: if(retstr!=NULL) return retstr; return scopy(""); }
static char *shorten(GrBrush *brush, const char *str, uint maxw, const char *rule, int nmatch, regmatch_t *pmatch) { char *s; int rulelen, slen, i, j, k, ll; int strippt=0; int stripdir=-1; bool more=FALSE; /* Ensure matches are at character boundaries */ if(!ioncore_g.enc_sb){ int pos=0, len, strl; mbstate_t ps; memset(&ps, 0, sizeof(ps)); strl=strlen(str); while(pos<strl){ len=mbrtowc(NULL, str+pos, strl-pos, &ps); if(len<0){ /* Invalid multibyte string */ return scopy("???"); } if(len==0) break; for(i=0; i<nmatch; i++){ if(pmatch[i].rm_so>pos && pmatch[i].rm_so<pos+len) pmatch[i].rm_so=pos+len; if(pmatch[i].rm_eo>pos && pmatch[i].rm_eo<pos+len) pmatch[i].rm_eo=pos; } pos+=len; } } /* Stupid alloc rule that wastes space */ rulelen=strlen(rule); slen=rulelen; for(i=0; i<nmatch; i++){ if(pmatch[i].rm_so==-1) continue; slen+=(pmatch[i].rm_eo-pmatch[i].rm_so); } s=ALLOC_N(char, slen); if(s==NULL) return NULL; do{ more=FALSE; j=0; strippt=0; stripdir=-1; for(i=0; i<rulelen; i++){ if(rule[i]!='$'){ s[j++]=rule[i]; continue; } i++; if(rule[i]=='|'){ rule=rule+i+1; rulelen=rulelen-i-1; more=TRUE; break; } if(rule[i]=='$'){ s[j++]='$'; continue; } if(rule[i]=='<'){ strippt=j; stripdir=-1; continue; } if(rule[i]=='>'){ strippt=j; stripdir=1; continue; } if(rule[i]>='0' && rule[i]<='9'){ k=(int)(rule[i]-'0'); if(k>=nmatch) continue; if(pmatch[k].rm_so==-1) continue; ll=(pmatch[k].rm_eo-pmatch[k].rm_so); strncpy(s+j, str+pmatch[k].rm_so, ll); j+=ll; } } slen=j; s[slen]='\0'; i=strippt; j=strippt; /* shorten */ { uint bl=grbrush_get_text_width(brush, s, i); uint el=grbrush_get_text_width(brush, s+j, slen-j); while(1){ /* el+bl may not be the actual length, but close enough. */ if(el+bl<=maxw){ memmove(s+i, s+j, slen-j+1); return s; } if(stripdir==-1){ ll=str_prevoff(s, i); if(ll==0) break; i-=ll; bl=grbrush_get_text_width(brush, s, i); }else{ ll=str_nextoff(s, j); if(ll==0) break; j+=ll; el=grbrush_get_text_width(brush, s+j, slen-j); } } } }while(more); free(s); return NULL; }