#include #include #include #include int f3_width[256] = { /*0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 1 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 2 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 3 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 4 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 5 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 6 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 7 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 8 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D */ -1, -1, -1, -1, -1, -1,229, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* F */ -1, -1, -1, -1, -1, -1, -1,771,448,354,479,365, -1, -1, -1, -1, }; int f2_width[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 250,219,406,667,448,823,729,177,292,292,427,667,219,313,219,500, 469,469,469,469,469,469,469,469,469,469,219,219,667,667,667,365, 917,677,615,635,771,656,563,771,760,354,333,740,573,833,771,781, 563,771,625,479,615,708,677,885,698,656,656,271,500,271,500,500, 333,406,510,417,500,417,323,448,510,229,229,469,229,771,510,510, 510,490,333,365,292,490,469,667,458,417,427,479,500,479,667,750, 469,750,219,615,448,1000,427,427,333,1021,479,198,938,750,656,750, 750,219,219,448,448,354,500,1000,333,979,365,198,698,750,427,656, 250,219,417,573,677,656,500,427,333,760,260,365,667,313,760,500, 396,667,313,313,333,500,448,333,333,313,333,365,813,813,823,365, 677,677,677,677,677,677,854,635,656,656,656,656,354,354,354,354, 771,771,781,781,781,781,781,667,781,708,708,708,708,656,563,500, 406,406,406,406,406,406,583,417,417,417,417,417,229,229,229,229, 521,510,510,510,510,510,510,549,510,490,490,490,490,417,510,417 }; int f1_width[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 250,260,552,667,469,833,802,281,354,354,490,667,260,333,260,552, 469,396,469,469,469,469,469,469,469,469,260,260,667,667,667,417, 927,656,677,677,781,708,615,729,865,396,375,677,635,917,844,792, 615,792,698,510,688,760,667,896,688,656,667,365,552,365,583,500, 333,479,552,469,552,469,302,542,552,281,260,531,260,844,552,521, 552,552,344,417,313,552,458,708,500,469,469,396,542,396,667,750, 469,750,250,708,490,1000,500,500,333,1031,510,281,990,750,667,750, 750,250,250,490,490,354,500,1000,333,1000,417,281,729,750,469,656, 250,260,469,677,688,656,542,500,333,750,302,458,667,333,750,500, 396,667,313,313,333,458,542,333,333,313,333,458,833,833,833,417, 656,656,656,656,656,656,917,677,708,708,708,708,396,396,396,396, 781,844,792,792,792,792,792,667,792,760,760,760,760,656,615,542, 479,479,479,479,479,479,698,469,469,469,469,469,281,281,281,281, 521,552,521,521,521,521,521,667,521,552,552,552,552,469,552,469 }; int *width; double scale; int font = -1; int x = -1, y = -1; int next_x, next_y; int last_x = -1, last_y = -1; int last_w = 0; char *buf; int size; int maxsize; void put(char c) { if (size == maxsize) { buf = realloc(buf, maxsize+=1024); if (!buf)abort();} buf[size++] = c; } void get_line(void) { size = 0; while (1) { int c = getchar(); if (c == EOF || c == '\n') break; put(c); } put(0); } void Tf(void) { char *s; s = strstr(buf, "/"); if (!s) { fprintf(stderr, "ERROR: bad Tf '%s'\n", buf); return ; } if (!s[1] || !s[2] || !s[3]) abort(); if (sscanf(s+3, "%lf", &scale) != 1) abort(); if (s[1] == 'F' && s[2] == '1' && s[3] == ' ') { font = 1; width = f1_width; return; } if (s[1] == 'F' && s[2] == '2' && s[3] == ' ') { font = 2; width = f2_width; return; } if (s[1] == 'F' && s[2] == '3' && s[3] == ' ') { font = 3; width = f3_width; return; } font = -1; width = 0; scale = 0; fprintf(stderr, "ERROR: Tf unknown font '%s'\n", s); } void Tm(void) { int a, b, c, d, e, f; if (sscanf(buf, "%d %d %d %d %d %d", &a, &b, &c, &d, &e, &f) != 6 || a != 1 || b != 0 || c != 0 || d != 1) { fprintf(stderr, "ERROR: bad Tm '%s'\n", buf); return; } e*=1000; f*=1000; next_x = e; next_y = f; } int my_isalnum(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } void output(char *s, int w) { if (next_y != last_y) printf("\n"); else { if (next_x > last_x + last_w + 1000) printf(" "); } if (abs(next_y-last_y) > 20000) printf("WORD "); last_y = next_y; last_x = next_x; next_x += w; last_w = w; printf("%s", s); } char *win2utf(int x) { switch (x) { case 231: return "ç"; case 252: return "ü"; case 246: return "ö"; case 226: return "a"; /* â */ case 238: return "i"; /* î */ case 199: return "Ç"; case 214: return "Ö"; case 220: return "Ü"; case 146: return "'"; /* ’ */ case 251: return "u"; /* û */ case 194: return "A"; /* Â */ case 176: if(0)fprintf(stderr, "what °? %s\n", buf); return "°"; case 178: if(0)fprintf(stderr, "what ²? %s\n", buf); return "²"; case 241: if(0)fprintf(stderr, "what ñ? %s\n", buf); return "ñ"; case 141: return "[[[ ERROR 141 ]]]"; case 233: return "é"; case 179: return "³"; case 167: return "§"; } fprintf(stderr, "ERROR: unknown %d in win2utf\n", x); return ""; } void Tj(void) { if (buf[0] == '(') { if (buf[1] == ')' && buf[2] == 'T') return; /* empty */ if (buf[1] == '\\' && buf[2] == ')' && buf[3] == ')') { output(")", width[')'] * scale); return; /* closepar */ } if (buf[1] == '\\' && buf[2] == '\\' && buf[3] == ')') { output("\\", width['\\'] * scale); return; /* backslash */ } if (buf[1] == '\\' && buf[2] == '(' && buf[3] == ')') { output("(", width['('] * scale); return; /* openpar */ } if (buf[1] == '\\' && isdigit(buf[2]) && isdigit(buf[3]) && isdigit(buf[4]) && buf[5] == ')') { char *t = win2utf((buf[2] - '0') * 8 * 8 + (buf[3] - '0') * 8 + (buf[4] - '0')); output(t, width[(buf[2] - '0') * 8 * 8 + (buf[3] - '0') * 8 + (buf[4] - '0')] * scale); return; /* octal stuff */ } if ((my_isalnum(buf[1]) || buf[1] == '.' || buf[1] == '-' || buf[1] == '?' || buf[1] == '*' || buf[1] == ',' || buf[1] == '!' || buf[1] == '/' || buf[1] == '\'') && buf[2] == ')') { char t[2]; t[0] = buf[1]; t[1] = 0; output(t, width[(unsigned char)buf[1]] * scale); return; /* empty */ } goto err; } if (buf[0] == '<' && buf[5] == '>') { if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'd' && buf[4] == '6') { output("ı", width[0xd6] * scale); return; } if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'f' && buf[4] == '7') { output("Ğ", width[0xf7] * scale); return; } if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'f' && buf[4] == '8') { output("ğ", width[0xf8] * scale); return; } if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'f' && buf[4] == '9') { output("İ", width[0xf9] * scale); return; } if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'f' && buf[4] == 'a') { output("Ş", width[0xfa] * scale); return; } if (buf[1] == '0' && buf[2] == '0' && buf[3] == 'f' && buf[4] == 'b') { output("ş", width[0xfb] * scale); return; } goto err; } err: fprintf(stderr, "ERROR: bad Tj '%s'\n", buf); } char *num(char *s) { int v; if (sscanf(s, "%d", &v) != 1) abort(); next_x -= v * scale; if (*s == '-') s++; while (*s >= '0' && *s <= '9') s++; return s; } char *oppar(char *s) { char t[2]; t[1] = 0; next: if (*s == ')') return s+1; if (*s == '\\') { s++; if (*s == '(') { output("(", width['(']*scale); s++; goto next; } if (*s == ')') { output(")", width[')']*scale); s++; goto next; } if (s[0] >= '0' && s[0] <= '9' && s[1] >= '0' && s[1] <= '9' && s[2] >= '0' && s[2] <= '9') { output(win2utf((s[0] - '0') * 8 * 8 + (s[1] - '0') * 8 + (s[2] - '0')), width[(s[0]-'0')*8*8 + (s[1] - '0') * 8 + (s[2] - '0')]*scale); s+=3; goto next; } fprintf(stderr, "ERROR: bad Tj '%s'\n", buf); } t[0] = *s; output(t, width[(unsigned char)*s] * scale); s++; goto next; } void TJ(void) { char *s = buf; if (*s != '[') abort(); s++; next: if (*s == '(') { s++; s = oppar(s); goto next; } if (*s == '-' || (*s >= '0' && *s <= '9')) { s = num(s); goto next; } if (*s == ']') return; printf("bad TJ '%s' (s='%s')\n", buf, s); return; } void xxx(void) { font = -1; last_y = -1; last_x = -1; last_w = 0; next_x = next_y = 0; width = 0; scale = 0; } void do_line(void) { if (size < 3) { fprintf(stderr, "ERROR: too short '%s'\n", buf); return; } if (buf[size-3] == 'T' && buf[size-2] == 'f') { Tf(); return; } if (buf[size-3] == 'T' && buf[size-2] == 'm') { Tm(); return; } if (buf[size-3] == 'T' && buf[size-2] == 'j') { Tj(); return; } if (buf[size-3] == 'T' && buf[size-2] == 'J') { TJ(); return; } if (!strcmp(buf, "XXX")){ xxx(); return; } fprintf(stderr, "ERROR: unhandled '%s'\n", buf); } int main(void) { while (1) { get_line(); if (size == 1) break; do_line(); } return 0; }