figlet.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,077 行 · 第 1/4 页
C
2,077 行
****************************************************************************/void clearline(){ int i; for (i=0;i<charheight;i++) { outputline[i][0] = '\0'; } outlinelen = 0; inchrlinelen = 0;}/**************************************************************************** readfontchar Reads a font character from the font file, and places it in a newly-allocated entry in the list.****************************************************************************/void readfontchar(file,theord,line,maxlen)ZFILE *file;inchr theord;char *line;int maxlen;{ int row,k; char endchar; fcharnode *fclsave; fclsave = fcharlist; fcharlist = (fcharnode*)myalloc(sizeof(fcharnode)); fcharlist->ord = theord; fcharlist->thechar = (char**)myalloc(sizeof(char*)*charheight); fcharlist->next = fclsave; for (row=0;row<charheight;row++) { if (myfgets(line,maxlen+1,file)==NULL) { line[0] = '\0'; } k = MYSTRLEN(line)-1; while (k>=0 && isspace(line[k])) { k--; } if (k>=0) { endchar = line[k]; while (k>=0 ? line[k]==endchar : 0) { k--; } } line[k+1] = '\0'; fcharlist->thechar[row] = (char*)myalloc(sizeof(char)*(k+2)); strcpy(fcharlist->thechar[row],line); }}/**************************************************************************** readfont Allocates memory, initializes variables, and reads in the font. Called near beginning of main().****************************************************************************/void readfont(){#define MAXFIRSTLINELEN 1000 int i,row,numsread; inchr theord; int maxlen,cmtlines,ffright2left; int smush,smush2; char *fontpath,*fileline,magicnum[5]; ZFILE *fontfile; int namelen; namelen = MYSTRLEN(fontdirname); fontpath = (char*)myalloc(sizeof(char) *(namelen+MYSTRLEN(fontname)+FSUFFIXLEN+2)); fontfile = NULL; if (!hasdirsep(fontname)) { strcpy(fontpath,fontdirname); fontpath[namelen] = DIRSEP; fontpath[namelen+1] = '\0'; strcat(fontpath,fontname); strcat(fontpath,FONTFILESUFFIX); fontfile = Zopen(fontpath,"rb"); } if (fontfile==NULL) { strcpy(fontpath,fontname); strcat(fontpath,FONTFILESUFFIX); fontfile = Zopen(fontpath,"rb"); if (fontfile==NULL) { fprintf(stderr,"%s: %s: Unable to open font file\n",myname,fontpath); exit(1); } } readmagic(fontfile,magicnum); fileline = (char*)myalloc(sizeof(char)*(MAXFIRSTLINELEN+1)); if (myfgets(fileline,MAXFIRSTLINELEN+1,fontfile)==NULL) { fileline[0] = '\0'; } if (MYSTRLEN(fileline)>0 ? fileline[MYSTRLEN(fileline)-1]!='\n' : 0) { skiptoeol(fontfile); } numsread = sscanf(fileline,"%*c%c %d %*d %d %d %d %d %d", &hardblank,&charheight,&maxlen,&smush,&cmtlines, &ffright2left,&smush2); free(fileline); if (strcmp(magicnum,FONTFILEMAGICNUMBER) || numsread<5) { fprintf(stderr,"%s: %s: Not a FIGlet 2 font file\n",myname,fontpath); exit(1); } for (i=1;i<=cmtlines;i++) { skiptoeol(fontfile); } free(fontpath); if (numsread<6) { ffright2left = 0; } if (numsread<7) { /* if no smush2, decode smush into smush2 */ if (smush == 0) smush2 = SM_KERN; else if (smush < 0) smush2 = 0; else smush2 = (smush & 31) | SM_SMUSH; } if (charheight<1) { charheight = 1; } if (maxlen<1) { maxlen = 1; } maxlen += 100; /* Give ourselves some extra room */ if (smushoverride == SMO_NO) smushmode = smush2; else if (smushoverride == SMO_FORCE) smushmode |= smush2; if (right2left<0) { right2left = ffright2left; } if (justification<0) { justification = 2*right2left; } fileline = (char*)myalloc(sizeof(char)*(maxlen+1)); /* Allocate "missing" character */ fcharlist = (fcharnode*)myalloc(sizeof(fcharnode)); fcharlist->ord = 0; fcharlist->thechar = (char**)myalloc(sizeof(char*)*charheight); fcharlist->next = NULL; for (row=0;row<charheight;row++) { fcharlist->thechar[row] = (char*)myalloc(sizeof(char)); fcharlist->thechar[row][0] = '\0'; } for (theord=' ';theord<='~';theord++) { readfontchar(fontfile,theord,fileline,maxlen); } for (theord=0;theord<=6;theord++) { readfontchar(fontfile,deutsch[theord],fileline,maxlen); } while (myfgets(fileline,maxlen+1,fontfile)==NULL?0: sscanf(fileline,"%li",&theord)==1) { readfontchar(fontfile,theord,fileline,maxlen); } Zclose(fontfile); free(fileline);}/**************************************************************************** linealloc Allocates & clears outputline, inchrline. Sets inchrlinelenlimit. Called near beginning of main().****************************************************************************/void linealloc(){ int row; outputline = (char**)myalloc(sizeof(char*)*charheight); for (row=0;row<charheight;row++) { outputline[row] = (char*)myalloc(sizeof(char)*(outlinelenlimit+1)); } inchrlinelenlimit = outputwidth*4+100; inchrline = (inchr*)myalloc(sizeof(inchr)*(inchrlinelenlimit+1)); clearline();}/**************************************************************************** getletter Sets currchar to point to the font entry for the given character. Sets currcharwidth to the width of this character.****************************************************************************/void getletter(c)inchr c;{ fcharnode *charptr; for (charptr=fcharlist;charptr==NULL?0:charptr->ord!=c; charptr=charptr->next) ; if (charptr!=NULL) { currchar = charptr->thechar; } else { for (charptr=fcharlist;charptr==NULL?0:charptr->ord!=0; charptr=charptr->next) ; currchar = charptr->thechar; } previouscharwidth = currcharwidth; currcharwidth = MYSTRLEN(currchar[0]);}/**************************************************************************** smushem Given 2 characters, attempts to smush them into 1, according to smushmode. Returns smushed character or '\0' if no smushing can be done. smushmode values are sum of following (all values smush blanks): 1: Smush equal chars (not hardblanks) 2: Smush '_' with any char in hierarchy below 4: hierarchy: "|", "/\", "[]", "{}", "()", "<>" Each class in hier. can be replaced by later class. 8: [ + ] -> |, { + } -> |, ( + ) -> | 16: / + \ -> X, > + < -> X (only in that order) 32: hardblank + hardblank -> hardblank****************************************************************************/char smushem(lch,rch)char lch,rch;{ if (lch==' ') return rch; if (rch==' ') return lch; if (previouscharwidth<2 || currcharwidth<2) return '\0'; /* Disallows overlapping if the previous character */ /* or the current character has a width of 1 or zero. */ if ((smushmode & SM_SMUSH) == 0) return '\0'; /* kerning */ if ((smushmode & 63) == 0) { /* This is smushing by universal overlapping. */ if (lch==' ') return rch; if (rch==' ') return lch; if (lch==hardblank) return rch; if (rch==hardblank) return lch; /* Above four lines ensure overlapping preference to */ /* visible characters. */ if (right2left==1) return lch; /* Above line ensures that the dominant (foreground) */ /* fig-character for overlapping is the latter in the */ /* user's text, not necessarily the rightmost character. */ return rch; /* Occurs in the absence of above exceptions. */ } if (smushmode & SM_HARDBLANK) { if (lch==hardblank && rch==hardblank) return lch; } if (lch==hardblank || rch==hardblank) return '\0'; if (smushmode & SM_EQUAL) { if (lch==rch) return lch; } if (smushmode & SM_LOWLINE) { if (lch=='_' && strchr("|/\\[]{}()<>",rch)) return rch; if (rch=='_' && strchr("|/\\[]{}()<>",lch)) return lch; } if (smushmode & SM_HIERARCHY) { if (lch=='|' && strchr("/\\[]{}()<>",rch)) return rch; if (rch=='|' && strchr("/\\[]{}()<>",lch)) return lch; if (strchr("/\\",lch) && strchr("[]{}()<>",rch)) return rch; if (strchr("/\\",rch) && strchr("[]{}()<>",lch)) return lch; if (strchr("[]",lch) && strchr("{}()<>",rch)) return rch; if (strchr("[]",rch) && strchr("{}()<>",lch)) return lch; if (strchr("{}",lch) && strchr("()<>",rch)) return rch; if (strchr("{}",rch) && strchr("()<>",lch)) return lch; if (strchr("()",lch) && strchr("<>",rch)) return rch; if (strchr("()",rch) && strchr("<>",lch)) return lch; } if (smushmode & SM_PAIR) { if (lch=='[' && rch==']') return '|'; if (rch=='[' && lch==']') return '|'; if (lch=='{' && rch=='}') return '|'; if (rch=='{' && lch=='}') return '|'; if (lch=='(' && rch==')') return '|'; if (rch=='(' && lch==')') return '|'; } if (smushmode & SM_BIGX) { if (lch=='/' && rch=='\\') return '|'; if (rch=='/' && lch=='\\') return 'Y'; if (lch=='>' && rch=='<') return 'X'; /* Don't want the reverse of above to give 'X'. */ } return '\0';}/**************************************************************************** smushamt Returns the maximum amount that the current character can be smushed into the current line.****************************************************************************/int smushamt(){ int maxsmush,amt; int row,linebd,charbd; char ch1,ch2; if ((smushmode & (SM_SMUSH | SM_KERN)) == 0) { return 0; } maxsmush = currcharwidth; for (row=0;row<charheight;row++) { if (right2left) { for (charbd=MYSTRLEN(currchar[row]); ch1=currchar[row][charbd],(charbd>0&&(!ch1||ch1==' '));charbd--) ; for (linebd=0;ch2=outputline[row][linebd],ch2==' ';linebd++) ; amt = linebd+currcharwidth-1-charbd; } else { for (linebd=MYSTRLEN(outputline[row]); ch1 = outputline[row][linebd],(linebd>0&&(!ch1||ch1==' '));linebd--) ; for (charbd=0;ch2=currchar[row][charbd],ch2==' ';charbd++) ; amt = charbd+outlinelen-1-linebd; } if (!ch1||ch1==' ') { amt++; } else if (ch2) { if (smushem(ch1,ch2)!='\0') { amt++; } } if (amt<maxsmush) { maxsmush = amt; } } return maxsmush;}/**************************************************************************** addchar Attempts to add the given character onto the end of the current line. Returns 1 if this can be done, 0 otherwise.****************************************************************************/int addchar(c)inchr c;{ int smushamount,row,k; char *templine; getletter(c); smushamount = smushamt(); if (outlinelen+currcharwidth-smushamount>outlinelenlimit ||inchrlinelen+1>inchrlinelenlimit) { return 0; } templine = (char*)myalloc(sizeof(char)*(outlinelenlimit+1)); for (row=0;row<charheight;row++) { if (right2left) { strcpy(templine,currchar[row]); for (k=0;k<smushamount;k++) { templine[currcharwidth-smushamount+k] = smushem(templine[currcharwidth-smushamount+k],outputline[row][k]); } strcat(templine,outputline[row]+smushamount); strcpy(outputline[row],templine); } else { for (k=0;k<smushamount;k++) { if (outlinelen-smushamount+k >= 0) outputline[row][outlinelen-smushamount+k] = smushem(outputline[row][outlinelen-smushamount+k],currchar[row][k]); } strcat(outputline[row],currchar[row]+smushamount); } } free(templine); outlinelen = MYSTRLEN(outputline[0]); inchrline[inchrlinelen++] = c; return 1;}/**************************************************************************** putstring Prints out the given null-terminated string, substituting blanks for hardblanks. If outputwidth is 1, prints the entire string; otherwise prints at most outputwidth-1 characters. Prints a newline at the end of the string. The string is left-justified, centered or right-justified (taking outputwidth as the screen width) if justification is 0, 1 or 2, respectively.****************************************************************************/static int nr_chars=0;static void myputchar(unsigned char c){ static int startline = 1; if ( startline ) { startline = 0; myputchar(' '); } putc(c, stderr); if ( nr_chars == 18 ) { nr_chars = 0; putchar('"'); putchar(' '); putchar('\\'); putchar('\n'); } if ( nr_chars++ == 0 ) putchar('"'); putchar('\\'); putchar('0' + ((c>>6)&7)); putchar('0' + ((c>>3)&7)); putchar('0' + ((c>>0)&7)); if ( c == '\n' ) startline = 1;}void putstring(string)char *string;{ int i,len; len = MYSTRLEN(string); if (outputwidth>1) { if (len>outputwidth-1) { len = outputwidth-1; } if (justification>0) { for (i=1;(3-justification)*i+len+justification-2<outputwidth;i++) { myputchar(' '); } } } for (i=0;i<len;i++) { myputchar(string[i]==hardblank?' ':string[i]); } myputchar('\n');}/**************************************************************************** printline Prints outputline using putstring, then clears the current line.****************************************************************************/void printline(){ int i; for (i=0;i<charheight;i++) { putstring(outputline[i]); } clearline();}/**************************************************************************** splitline Splits inchrline at the last word break (bunch of consecutive blanks). Makes a new line out of the first part and prints it using printline. Makes a new line out of the second part and returns.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?