/* *The abbreviation name phk & phj are alike and I like drinking cola too, *So I modify the BEER-WARE LICENSE into the COLA-WARE LICENSE. * :-) *--------------------------------------------------------------------------- *"THE COLA-WARE LICENSE" (Revision 1): * wrote this file.As long as you retain this notice you *can do whatever you want with this stuff. If we meet some day, and you think *this stuff is worth it, you can buy me a cola in return. Peng-HaiJie *---------------------------------------------------------------------------- * $Id: tocps.c,v 1.5 1999/11/03 04:42:11 phj Exp $ */ #include #include #include #include #include #define DEFAULT_FONT_PATH "/usr/local/share/chinese/gb/" #define DEFAULT_FONT "csong24.ccf" #define LINE_SIZE_OF_FONT_FILE 150 #define SET_BEGIN_1 "/SB1 {dup 0 -1 rmoveto gsave currentpoint translate scale 24 24 true [24 0 0 -24 0 24]} def" #define SET_BEGIN_2 "/SB2 {dup dup 0 rmoveto gsave currentpoint translate scale 24 24 true [24 0 0 -24 0 24]} def" #define SET_BEGIN_3 "/SB3 {dup dup 12 sub -1 rmoveto gsave currentpoint translate scale 24 24 true [24 0 0 -24 0 24]} def" #define SET_END "/SE {imagemask grestore} def" #define MAX_QUWEI_CODE 8794 #define NORMAL_SIZE 1024 #define IF_OCTAL_ESCAPE_CHAR(X) ( ( *(X) >='0' && *(X) < '8') && \ ( *(X+1) >='0' && *(X+1) < '8') && \ ( *(X+2) >='0' && *(X+2) < '8')) static int quweima_table[MAX_QUWEI_CODE]; static int begin_position; static int end_position; static char font_path[512]=DEFAULT_FONT_PATH; static char *font_type[11]={ \ "kai" ,"ckai24.ccf", \ "song" ,"csong24.ccf", \ "fan" ,"cfan24.ccf", \ "fang" ,"cfang24.ccf", \ "hei" ,"chei24.ccf", \ NULL, \ }; int write_table(FILE * out) { char tmp_index[256], data[8]; int i, location; FILE *in; in = fopen(font_path, "rb"); if (in == NULL) { perror(font_path); exit(-1); } for (i = 0; i < MAX_QUWEI_CODE; ++i) { if (quweima_table[i]) { location = LINE_SIZE_OF_FONT_FILE * ((i / 100 - 1) * 94 + i % 100 - 1); fseek(in, location, SEEK_SET); fscanf(in, "%s %s", tmp_index, data); fprintf(out, "/C%04d {<%s>} def\n", i, data); } } fclose(in); return 0; } void write_macro(FILE * out) { fprintf(out, "%s\n", SET_BEGIN_1); fprintf(out, "%s\n", SET_BEGIN_2); fprintf(out, "%s\n", SET_BEGIN_3); fprintf(out, "%s\n", SET_END); } int prepare_table(char *argv) { char ch[4], ch2[4], buf[6]; int i,nch,nch2; FILE *in; int total_chars=0; in = fopen(argv, "rb"); if (in == NULL) { perror(argv); return -1; } for (i = 0; i < MAX_QUWEI_CODE; ++i) quweima_table[i] = 0; ch[3] = '\0'; ch2[3] = '\0'; buf[4] = '\0'; while (!feof(in)) { if (getc(in) == '\\') { fread(ch, sizeof(char), 3, in); if ( IF_OCTAL_ESCAPE_CHAR(ch) ){ nch=strtol(ch,NULL,8)-0xa0; if( nch < 0 || nch > 87) continue; if (getc(in) == '\\') { fread(ch2, sizeof(char), 3, in); if (!( IF_OCTAL_ESCAPE_CHAR(ch2))){ fseek(in, -3, SEEK_CUR); continue; } nch2=strtol(ch2,NULL,8)-0xa0; if( nch2 < 0 || ( nch == 87 && nch2 >94 )) continue; sprintf(buf, "%02d%02d",nch,nch2); i=atof(buf); quweima_table[i]=1; ++total_chars; } } else { fseek(in, -3, SEEK_CUR); } } } fclose(in); if( total_chars == 0){ fprintf(stderr,"[%s]\tNo chinese characters in it,pass it!\n",argv); return -2; } return 0; } int if_at_right_most(register char *tmp, register char *token) { register char *p, *p2; p = tmp; p2 = token; while (*p ) ++p; while (*p2) ++p2; while (p2 > token) if (*--p != *--p2 ) return 0; return 1; } void get_char(register char *p, register char *ret_char) { static int i; for (i = 0; i < 3; ++i) ret_char[i] = *(p + i); ret_char[3] = '\0'; } int if_chinese_char(register char *p, register char *token) { register char *p2; static char ch[6], ch2[6]; int nch,nch2; memset(ch, 0, sizeof(ch)); memset(ch2, 0, sizeof(ch2)); if (*p == '\\') { if ( IF_OCTAL_ESCAPE_CHAR(p+1) ){ get_char(p + 1, ch); nch=strtol(ch,NULL,8)-0xa0; if( nch < 0 || nch > 87 ){ strncpy(ch, p, 4); strcpy(token, ch); /* invalid \NNN */ return -1; } p2 = p + 4; if (*p2 == '\\') { if (!( IF_OCTAL_ESCAPE_CHAR(p2+1))){ strncpy(ch, p, 4); strcpy(token, ch); /* \nnn\xxx */ return 0; } get_char(p2 + 1, ch2); nch2=strtol(ch2,NULL,8)-0xa0; if( nch2 < 0 || (nch==87 && nch2> 94)){ strncpy(ch, p, 4); strcpy(token, ch); /* invalid \nnn\NNN */ return -2; } sprintf(token, "C%02d%02d",nch,nch2); /* valid \nnn\nnn */ return 1; } else{ strncpy(ch, p, 4); strcpy(token, ch); /* \nnnA */ return 2; } } else{ strncpy(ch, p, 2); strcpy(token, ch); /* \xxx */ return 3; } } else{ sprintf(token, "%c", *p); /* A */ return 4; } } void parse_content(register char *buf,register FILE *out) { char token[8]; char x[8], y[8], moveto[8]; char *p, *p_end; char font[3]; int scale; int if_at_head; int if_last_one_english; int ret; sscanf(buf, "%s %s %s %d %s", x, y, moveto, &scale, font); p = buf; p_end = p + end_position - begin_position - 7; while (*p != '(') ++p; ++p; if_at_head = 1; if_last_one_english = 0; while (p < p_end) { if ((ret = if_chinese_char(p, token)) == 1) { if (if_at_head) { fprintf(out, "%s %s %s\n", x, y, moveto); fprintf(out, "%d %s\n", scale, font); fprintf(out, "%d SB1 %s SE\n", scale, token); if_at_head = 0; } else { if (if_last_one_english) { fprintf(out, ") show\n"); fprintf(out, "%d SB3 %s SE\n", scale, token); } else { fprintf(out, "%d SB2 %s SE\n", scale, token); } } if_last_one_english = 0; p += 8; }else{ /* assume that it is english characters */ if (if_at_head) { fprintf(out, "%s %s %s\n", x, y, moveto); fprintf(out, "%d %s\n", scale, font); fprintf(out, "(%s", token); if_at_head = 0; } else { if (if_last_one_english) { fprintf(out, "%s", token); } else { fprintf(out, "%d 1 rmoveto\n", scale); fprintf(out, "%d %s\n", scale, font); fprintf(out, "(%s", token); } } if_last_one_english = 1; switch( ret){ case -1: case -2: case 0: case 2: p+=4;break; case 3: p+=2;break; case 4: ++p;break; default: ; } } } if (if_last_one_english) fprintf(out, ") show\n"); } int write_output_file(char *argv,FILE *out) { FILE *in; char buf[NORMAL_SIZE]; char buf2[NORMAL_SIZE]; char buf3[NORMAL_SIZE]; in = fopen(argv, "rb"); if (in == NULL) { perror("in_file error!"); return -1; } fgets(buf, NORMAL_SIZE, in); if (buf[0] != '%' && buf[1] != '!') { fprintf(stderr, "Hmm..Maybe not a PostScript File,"); fprintf(stderr, "Give up translating!\n"); fclose(in); return -1; } fprintf(out, "%s", buf); write_table(out); write_macro(out); while (!feof(in)) { begin_position = ftell(in); fgets(buf, sizeof(buf), in); if (!if_at_right_most(buf, "moveto\n") ){ fprintf(out, "%s", buf); continue; } fgets(buf2, sizeof(buf), in); if (!( (isdigit(*buf2) && isdigit(*(buf2 + 1)) && isspace(*(buf2+2)) && *(buf2 + 3) == 'f' && isdigit(*(buf2 + 4)) ) ||( isdigit(*buf2) && isspace(*(buf2+1)) && *(buf2+2)== 'f' && isdigit(*(buf2+3))) )) { fprintf(out, "%s", buf); fprintf(out, "%s", buf2); continue; } fgets(buf3, sizeof(buf3), in); if (if_at_right_most(buf3, "show\n") ){ end_position = ftell(in); fseek(in, begin_position, SEEK_SET); fread(buf3, sizeof(char), end_position - begin_position, in); parse_content(buf3,out); } else { fprintf(out, "%s", buf); fprintf(out, "%s", buf2); fprintf(out, "%s", buf3); } } fclose(in); return 0; } void usage(char *argv) { fprintf(stderr, "Usage: %s [-t font_type] netscape.ps ...\n", argv); } int set_font_type(char *f) { char **p=font_type; for(;*p;p+=2){ if(strcasecmp(f,*p) == 0){ sprintf(font_path,"%s%s",DEFAULT_FONT_PATH,*(++p)); return 1; } } return 0; } int main(int argc, char *argv[]) { int ch,font_type_flag=0; char filename[512]; FILE *output; if( argc < 2){ usage(*argv); exit(-1); } while( (ch=getopt(argc,argv,"t")) != -1){ if( ch == 't' ){ font_type_flag=1; } } argc -=optind; argv +=optind; if( font_type_flag ){ if( set_font_type(*argv)){ ++argv; }else{ fprintf(stderr,"%s","Not found this type of font!\n"); exit(-2); } }else{ sprintf(font_path,"%s%s",DEFAULT_FONT_PATH,DEFAULT_FONT); } for(;*argv;++argv){ if (prepare_table(*argv) < 0) { continue; } sprintf(filename,"%s.cps",*argv); output=fopen(filename,"wb"); if( output == NULL){ fprintf(stderr,"Error in openning %s",*argv); continue; } write_output_file(*argv,output); fclose(output); } exit(0); }