void ParseLtfFlags(LexStruct *l,U8 *flags,U4 *type) { I8 i; BoolU4 turn_on; while (l->token=='+' || l->token=='-') { turn_on=(l->token=='+'); if (Lex(l)==TK_IDENT) { i=MatchSysTextEntry(l->ident,"ST_LTF_FLAGS",MLE_EXACT); if (i<0) *type=LTFT_ERROR; else { AssignBit(flags,i,turn_on); if (i==LTFLf_SELECTED) AssignBit(type,30,turn_on); else if (i==LTFLf_UNDERLINED) AssignBit(type,31,turn_on); else if (i==LTFLf_INVERTED) AssignBit(type,29,turn_on); else if (i==LTFLf_BLINK) AssignBit(type,28,turn_on); } Lex(l); //skip flag } } } void LtfDefaultFlags(U4 *type,U8 *f1) { switch (*type & 255) {$AN,"default_flags","default_flags"$ case LTFT_TREE: *f1=LTFLF_COLLAPSED|LTFLF_TREE; *type|=LTFLT_UNDERLINE; break; case LTFT_DATA: *f1=LTFLF_DATA_IS_PTR | LTFLF_HAS_TERMINATOR | LTFLF_AUX_STR; break; case LTFT_CURSOR_MOVEMENT: *f1=LTFLF_LEFT_EXP | LTFLF_RIGHT_EXP; break; case LTFT_LINK: *f1=LTFLF_LINK|LTFLF_AUX_STR; *type|=LTFLT_UNDERLINE; break; case LTFT_ANCHOR: *f1=LTFLF_AUX_STR; break; case LTFT_BUTTON: *f1=LTFLF_ESC | LTFLF_LEFT_EXP | LTFLF_HAS_BORDER; break; case LTFT_CHECK_BOX: *f1=LTFLF_DATA_IS_PTR; break; case LTFT_MACRO: *f1=LTFLF_ESC | LTFLF_LEFT_MACRO; *type|=LTFLT_UNDERLINE; break; case LTFT_MENU_VALUE: *f1=LTFLF_ESC | LTFLF_LEFT_EXP; *type|=LTFLT_UNDERLINE; break; case LTFT_HEX_EDIT: *f1=LTFLF_DATA_IS_PTR | LTFLF_ZERO_BASED; break; case LTFT_PICWORD: *f1=LTFLF_HAS_BIN|LTFLF_AUX_STR|LTFLF_FROM_START|LTFLF_WIDTH|LTFLF_HEIGHT; break; case LTFT_PICTURE: *f1=LTFLF_HAS_BIN; break; case LTFT_TOP_LEFT_TOOLBAR: *f1=LTFLF_HAS_BIN|LTFLF_TOP_LEFT_MENU|LTFLF_WIDTH|LTFLF_HEIGHT; break; case LTFT_TOP_RIGHT_TOOLBAR: *f1=LTFLF_HAS_BIN|LTFLF_TOP_RIGHT_MENU|LTFLF_WIDTH|LTFLF_HEIGHT; break; case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: *f1=LTFLF_HAS_BIN; break; case LTFT_HIDE_START: *f1=LTFLF_COLLAPSED; *type|=LTFLT_UNDERLINE; break; case LTFT_SONG: *f1=LTFLF_SONG; break; } } I1 *LtfToPlainText(Ltf *l,LtfEntry *ll) { //TODO: break strs I8 i,j; U8 type=ll->btype,f1=0,flags; I1 *buf,*buf2; buf=NewStr(SysTextSub(ll->btype,"ST_LTF_CMDS")); if (ll->btype!=LTFT_ERROR) { LtfDefaultFlags(&type,&f1); flags=ll->flags & ~(LTFLF_WORD_WRAP |LTFLF_UNDERLINED | LTFLF_INVERTED | LTFLF_BLINK | LTFLF_SKIP); for (i=0;i<64;i++) if (Bt(&f1,i)!=Bt(&flags,i)) { if (Bt(&flags,i)) buf=Add2Str(buf,"+"); else buf=Add2Str(buf,"-"); buf=Add2Str(buf,SysTextSub(i,"ST_LTF_FLAGS")); } for (i=28;i<32;i++) if (Bt(&type,i)!=Bt(&ll->type,i)) { if (Bt(&ll->type,i)) buf=Add2Str(buf,"+"); else buf=Add2Str(buf,"-"); switch (i) { case 28: j=LTFLf_BLINK; break; case 29: j=LTFLf_INVERTED; break; case 30: j=LTFLf_SELECTED; break; case 31: j=LTFLf_UNDERLINED; break; } buf=Add2Str(buf,SysTextSub(j,"ST_LTF_FLAGS")); } buf=Add2Str(buf,","); switch (ll->btype) { case LTFT_TEXT: case LTFT_LINK: case LTFT_ANCHOR: case LTFT_MENU_VALUE: case LTFT_BUTTON: case LTFT_CHECK_BOX: case LTFT_TREE: case LTFT_PICTURE: case LTFT_PICWORD: case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: case LTFT_SONG: buf=Add2Str(buf,"\""); if (i==LTFT_CHECK_BOX) { buf=Add2Str(buf,ll->display+4); } else { if (ll->flags & LTFLF_TREE) buf=Add2Str(buf,ll->display+3); else buf=Add2Str(buf,ll->display); } buf=Add2Str(buf,"\","); break; case LTFT_DATA: buf2=MSPrintF("%s%d,",buf,ll->len); Free(buf); buf=buf2; break; case LTFT_HEX_EDIT: buf2=MSPrintF("%s%d,",buf,ll->len); Free(buf); buf=buf2; buf2=MSPrintF("%s%d,",buf,ll->hex_edit_width); Free(buf); buf=buf2; break; case LTFT_PAGE_LENGTH: case LTFT_LEFT_MARGIN: case LTFT_RIGHT_MARGIN: case LTFT_HEADER: case LTFT_FOOTER: case LTFT_INDENT: case LTFT_FOREGROUND_COLOR: case LTFT_BACKGROUND_COLOR: case LTFT_DEFAULT_FOREGROUND_COLOR: case LTFT_DEFAULT_BACKGROUND_COLOR: case LTFT_LINK_FOREGROUND: case LTFT_LINK_BACKGROUND: case LTFT_MACRO_FOREGROUND: case LTFT_MACRO_BACKGROUND: case LTFT_ANCHOR_FOREGROUND: case LTFT_ANCHOR_BACKGROUND: case LTFT_HIDDEN_FOREGROUND: case LTFT_HIDDEN_BACKGROUND: case LTFT_TREE_FOREGROUND: case LTFT_TREE_BACKGROUND: case LTFT_USER_FOREGROUND: case LTFT_USER_BACKGROUND: case LTFT_WORD_WRAP: case LTFT_UNDERLINED: case LTFT_INVERTED: case LTFT_BLINK: case LTFT_SHIFTED_X: case LTFT_SHIFTED_Y: if (ll->attr!=LTF_DEFAULT) { buf2=MSPrintF("%s%d,",buf,ll->attr); Free(buf); buf=buf2; } break; } flags=ll->flags& (LTFLF_SCROLLING_X|LTFLF_SHIFTED_X|LTFLF_SCROLLING_Y| LTFLF_AUX_STR|LTFLF_LEFT_EXP|LTFLF_LEFT_MACRO| LTFLF_HAS_BIN|LTFLF_RIGHT_EXP|LTFLF_RIGHT_MACRO| LTFLF_WIDTH|LTFLF_HEIGHT); while (flags) { j=Bsf(flags); Btr(&flags,j); switch (j) { case LTFLf_SCROLLING_X: buf2=MSPrintF("%s%d",buf,ll->scroll_len); Free(buf); buf=buf2; break; case LTFLf_SHIFTED_X: j=(ll->type.u2[1])&0x1F; if (j&0x10) j|=0xFFFFFFF0; buf2=MSPrintF("%s%d",buf,j); Free(buf); buf=buf2; break; case LTFLf_SHIFTED_Y: j=(ll->type>>21)&0x1F; if (j&0x10) j|=0xFFFFFFF0; buf2=MSPrintF("%s%d",buf,j); Free(buf); buf=buf2; break; case LTFLf_AUX_STR: buf2=MSPrintF("%s\"%Q\"",buf,ll->aux_str); Free(buf); buf=buf2; break; case LTFLf_LEFT_EXP: buf2=MSPrintF("%s%d",buf,ll->left_exp); Free(buf); buf=buf2; break; case LTFLf_LEFT_MACRO: buf2=MSPrintF("%s\"%Q\"",buf,ll->left_macro); Free(buf); buf=buf2; break; case LTFLf_RIGHT_EXP: buf2=MSPrintF("%s%d",buf,ll->right_exp); Free(buf); buf=buf2; break; case LTFLf_RIGHT_MACRO: buf2=MSPrintF("%s\"%Q\"",buf,ll->right_macro); Free(buf); buf=buf2; break; case LTFLf_HAS_BIN: buf2=MSPrintF("%s%d",buf,ll->bin_num); Free(buf); buf=buf2; break; case LTFLf_WIDTH: buf2=MSPrintF("%s%d",buf,ll->width); Free(buf); buf=buf2; break; case LTFLf_HEIGHT: buf2=MSPrintF("%s%d",buf,ll->height); Free(buf); buf=buf2; break; } buf=Add2Str(buf,","); } buf[StrLen(buf)-1]=0; //Kill last comma } buf2=NewStr(buf,l->mem_tss); //exact allocation Free(buf); return buf2; } LtfEntry *ParseDollarCmd(Ltf *l,I1 *st) { I8 i,j,size,flags; I1 *ptr,*st2; LtfEntry *ll=NULL; LexStruct *lx=LexNew(st,LF_DONT_FREE_BUFFER,NULL); Lex(lx); if (lx->token==TK_IDENT) { i=MatchSysTextEntry(lx->ident,"ST_LTF_CMDS",MLE_IGNORE_CASE); if (i<0) i=LTFT_ERROR; Lex(lx); //skip cmd code ll=MAllocZ(sizeof(LtfEntry),l->mem_tss); ll->type=i; LtfDefaultFlags(&ll->type,&ll->flags); ParseLtfFlags(lx,&ll->flags,&ll->type); if (lx->token==',') Lex(lx); switch (i) { case LTFT_TEXT: case LTFT_LINK: case LTFT_ANCHOR: case LTFT_MENU_VALUE: case LTFT_BUTTON: case LTFT_CHECK_BOX: case LTFT_TREE: case LTFT_PICTURE: case LTFT_PICWORD: case LTFT_INSERT_BINARY: case LTFT_INSERT_BINARY_TYPE: case LTFT_INSERT_BINARY_SIZE: case LTFT_SONG: if (lx->token==TK_STR) { st2=LexExtendStr(lx,&size); if (i==LTFT_CHECK_BOX) { st=MSPrintF("[X] %s",st2); Free(st2); ll->min_col=1; } else if (ll->flags & LTFLF_TREE) { st=MSPrintF("+] %s",st2); Free(st2); ll->min_col=1; } else st=st2; ll->display=NewStr(st,l->mem_tss); Free(st); } else { if (i>=LTFT_PICTURE && i<=LTFT_INSERT_BINARY_SIZE || i==LTFT_SONG) ll->display=NewStr("",l->mem_tss); else { ll->display=NULL; ll->type=LTFT_ERROR; } } break; case LTFT_HIDE_START: ll->display=NewStr("<-",l->mem_tss); ll->min_col=1; break; case LTFT_HIDE_END: ll->display=NewStr(">",l->mem_tss); break; case LTFT_DATA: ll->flags|=LTFLF_AUX_STR; //don't allow switched off ll->len=Expression(lx); break; case LTFT_HEX_EDIT: ll->len=Expression(lx); if (lx->token==',') Lex(lx); ll->hex_edit_width=Expression(lx); break; case LTFT_PAGE_LENGTH: case LTFT_LEFT_MARGIN: case LTFT_RIGHT_MARGIN: case LTFT_HEADER: case LTFT_FOOTER: case LTFT_INDENT: case LTFT_FOREGROUND_COLOR: case LTFT_BACKGROUND_COLOR: case LTFT_DEFAULT_FOREGROUND_COLOR: case LTFT_DEFAULT_BACKGROUND_COLOR: case LTFT_LINK_FOREGROUND: case LTFT_LINK_BACKGROUND: case LTFT_MACRO_FOREGROUND: case LTFT_MACRO_BACKGROUND: case LTFT_ANCHOR_FOREGROUND: case LTFT_ANCHOR_BACKGROUND: case LTFT_HIDDEN_FOREGROUND: case LTFT_HIDDEN_BACKGROUND: case LTFT_TREE_FOREGROUND: case LTFT_TREE_BACKGROUND: case LTFT_USER_FOREGROUND: case LTFT_USER_BACKGROUND: case LTFT_WORD_WRAP: case LTFT_UNDERLINED: case LTFT_INVERTED: case LTFT_BLINK: case LTFT_SHIFTED_X: case LTFT_SHIFTED_Y: if (!lx->token) ll->attr=LTF_DEFAULT; else ll->attr=Expression(lx); break; case LTFT_ERROR: ll->flags=0; ll->type=LTFT_ERROR; break; } flags=ll->flags& (LTFLF_SCROLLING_X|LTFLF_SHIFTED_X|LTFLF_SCROLLING_Y| LTFLF_AUX_STR|LTFLF_LEFT_EXP|LTFLF_LEFT_MACRO| LTFLF_HAS_BIN|LTFLF_RIGHT_EXP|LTFLF_RIGHT_MACRO| LTFLF_WIDTH|LTFLF_HEIGHT); while (flags) { j=Bsf(flags); Btr(&flags,j); while (lx->token==',') Lex(lx); switch (j) { //TODO: Might check for expression errors case LTFLf_SCROLLING_X: ll->scroll_len=Expression(lx); break; case LTFLf_SHIFTED_X: ll->type|=((Expression(lx) & 0x1F)<<16); break; case LTFLf_SHIFTED_Y: ll->type|=((Expression(lx) & 0x1F)<<21); break; case LTFLf_AUX_STR: if (lx->token==TK_STR) { st2=LexExtendStr(lx,&size); ll->aux_str=NewStr(st2,l->mem_tss); Free(st2); if (i==LTFT_MACRO && !ll->display) ll->display=NewStr(ll->aux_str,l->mem_tss); if (i==LTFT_DATA) { if (ptr=StrStr(ll->aux_str,":")) ll->min_col=ptr-ll->aux_str+1; ll->display=MAlloc(ll->len+ll->min_col+2,l->mem_tss); } } else ll->type=LTFT_ERROR; break; case LTFLf_LEFT_EXP: ll->left_exp=Expression(lx); break; case LTFLf_LEFT_MACRO: if (lx->token==TK_STR) { st2=LexExtendStr(lx,&size); ll->left_macro=NewStr(st2,l->mem_tss); Free(st2); if (i==LTFT_MACRO && !ll->display) ll->display=NewStr(ll->left_macro,l->mem_tss); } else ll->type=LTFT_ERROR; break; case LTFLf_RIGHT_EXP: ll->right_exp=Expression(lx); break; case LTFLf_RIGHT_MACRO: if (lx->token==TK_STR) { st2=LexExtendStr(lx,&size); ll->right_macro=NewStr(st2,l->mem_tss); Free(st2); if (i==LTFT_MACRO && !ll->display) ll->display=NewStr(ll->right_macro,l->mem_tss); } else ll->type=LTFT_ERROR; break; case LTFLf_HAS_BIN: if (!lx->token) ll->bin_num=0; else ll->bin_num=Expression(lx); break; case LTFLf_WIDTH: ll->width=Expression(lx); break; case LTFLf_HEIGHT: ll->height=Expression(lx); break; } } } else if (!ll) { ll=MAllocZ(sizeof(LtfEntry),l->mem_tss); ll->type=LTFT_ERROR; } LexDel(lx); return ll; } void LtfInsert(Ltf *l,LtfEntry *ll) { I1 *dst; LtfEntry *cl=l->cur_entry,*nl; ll->x=cl->x; ll->y=cl->y; ll->indent=cl->indent; ll->page_line_num=cl->page_line_num; ll->left_margin=cl->left_margin; ll->right_margin=cl->right_margin; if (l->cur_data_col>0 && cl->btype==LTFT_TEXT && l->cur_data_colmax_col) { nl=MAllocZ(sizeof(LtfEntryBase)+sizeof(void *),l->mem_tss); nl->type=LTFT_TEXT|cl->type&-0x100; nl->x=cl->x; nl->y=cl->y; nl->indent=cl->indent; nl->page_line_num=cl->page_line_num; nl->left_margin=cl->left_margin; nl->right_margin=cl->right_margin; nl->flags=cl->flags; dst=cl->display+l->cur_data_col; nl->display=NewStr(dst,l->mem_tss); *dst=0; cl->max_col=l->cur_data_col; InsQue(nl,cl); l->cur_data_col=0; cl=nl; cl->max_col=StrLen(cl->display); } if (cl->btype==LTFT_TEXT && l->cur_data_col>=cl->max_col) { InsQue(ll,cl); l->cur_entry=ll->next; } else { InsQue(ll,cl->last); l->cur_entry=cl; } l->cur_data_col=l->cur_entry->min_col; LtfRemoveSoftCRs(l,l->cur_entry); } #help_index "Ltf/Output" public LtfEntry *LtfPutSExt(Ltf *l,I1 *st) { I1 ch,*ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src; BoolU4 old_preempt=Preempt(OFF); LtfEntry *ll=NULL,*result=NULL,*cl=l->cur_entry; l->recalc_start=l; //TODO:This might be optimized if (!st) { Preempt(old_preempt); return NULL; } while (*ptr) { ptr2=ptr; ch=*ptr++; while (TRUE) { if (l->flags & LTFF_PLAIN_TEXT_WITH_TABS) while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_CURSOR) ch=*ptr++; else if (l->flags & LTFF_PLAIN_TEXT) while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_TAB && ch!=CH_CURSOR && ch!=CH_FORM_FEED) ch=*ptr++; else while (ch && ch!=CH_CR && ch!=CH_LINE_FEED && ch!=CH_TAB && ch!=CH_CURSOR && ch!=CH_FORM_FEED && ch!='$$') ch=*ptr++; if (ch==CH_CURSOR) { if (l->flags & LTFF_NO_CURSOR) ch=*ptr++; else break; } else break; } ptr--; if (!ch) { if (ptr!=ptr2) { ll=MAllocZ(sizeof(LtfEntryBase)+sizeof(void *),l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; if (l->flags & LTFF_NO_CURSOR) { src=NewStr(ptr2); StrUtil(src,SU_REMOVE_CTRL_CHARS); } else src=ptr2; ll->display=NewStr(src,l->mem_tss); ll->max_col=StrLen(src); LtfInsert(l,ll); if (l->flags & LTFF_NO_CURSOR) Free(src); } } else { if (ptr!=ptr2) { *ptr=0; ll=MAllocZ(sizeof(LtfEntryBase)+sizeof(void *),l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; if (l->flags & LTFF_NO_CURSOR) { src=NewStr(ptr2); StrUtil(src,SU_REMOVE_CTRL_CHARS); } else src=ptr2; ll->display=NewStr(src,l->mem_tss); ll->max_col=StrLen(src); LtfInsert(l,ll); if (l->flags & LTFF_NO_CURSOR) Free(src); *ptr=ch; } if (ch==CH_CURSOR) { //cursor ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CURSOR | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch==CH_FORM_FEED) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_PAGE_BREAK | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch==CH_TAB) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_TAB | l->text_attribute << 8; LtfInsert(l,ll); ptr++; } else if (ch=='$$') { ptr++; //skip first dollar ptr2=ptr; while (*ptr && *ptr!='$$') ptr++; if (*ptr) { *ptr=0; //zero second dollar if (ptr==ptr2) { ll=MAllocZ(sizeof(LtfEntryBase)+sizeof(void *),l->mem_tss); ll->type=LTFT_TEXT | l->text_attribute << 8; ll->max_col=1; if (l->flags & LTFF_DOUBLE_DOLLARS) ll->display=NewStr("$$$$",l->mem_tss); else ll->display=NewStr("$$",l->mem_tss); LtfInsert(l,ll); } else { st2=MAlloc(ptr-ptr2+1); ptr3=ptr2; ptr4=st2; while (*ptr3) { ch=*ptr3++; if (ch==CH_CURSOR) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CURSOR | l->text_attribute << 8; LtfInsert(l,ll); } else if (ch==CH_FORM_FEED) { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_PAGE_BREAK | l->text_attribute << 8; LtfInsert(l,ll); } else *ptr4++=ch; } *ptr4=0; if (ll=ParseDollarCmd(l,st2)) { result=ll; LtfInsert(l,ll); } Free(st2); } *ptr++='$$'; } } else { ll=MAllocZ(sizeof(LtfEntryBase),l->mem_tss); ll->type=LTFT_CR | l->text_attribute << 8; LtfInsert(l,ll); if (ch==CH_CR) while (*ptr==CH_CR) ptr++; if (*ptr==CH_LINE_FEED) ptr++; while (*ptr==CH_CR) ptr++; } } } Preempt(old_preempt); return result; } public LtfEntry *LtfPrintF(Ltf *l,I1 *src,...) { LtfEntry *result; I1 *buf=SPrintFJoin(NULL,src,argc,argv); result=LtfPutSExt(l,buf); Free(buf); return result; } #help_index "PicWords" #help_file "::/LT/Doc/PicWords.TXZ" #help_index "PicWords;Ltf/Output" public PicWordEntry *AddPicWord(I1 *st,GrElem *tempe,U8 size,I8 width=0,I8 height=0,I1 *txt=NULL) { //If you set $FG,4$txt$FG$, then include dollar signs //$FG,4$$$PW,"padspaces","Word",%d,width,height$$$FG$ // //If you want a macro picword //$FG,4$$$PW+LM,"padspaces","Word","Macro",%d,width,height$$$FG$ //See $LK,"LtfWordsToPics","MN:LtfWordsToPics"$ I1 *st2; I8 l; PicWordEntry *temppw=MAllocZ(sizeof(PicWordEntry)); temppw->type=HTT_PIC_WORD; temppw->use_cnt=0; temppw->grelem=tempe; temppw->size=size; temppw->width=width; temppw->height=height; if (txt) { l=StrLen(txt); if (l>2) { st2=MAlloc(l-2+1); MemCpy(st2,txt+1,l-2); st2[l-2]=0; temppw->txt=st2; } } temppw->source_link=NULL; temppw->str=NewStr(st); AddSysHashEntry(temppw,Fs->hash_table); return temppw; } #help_index "Ltf"