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 + -
显示快捷键?