/* $Id: chersh.c,v 1.1.1.1 2003/07/21 16:18:41 pturner Exp $ * * hershey fonts * */ #include #include #include #include "hersh.h" /* character defs */ #include "special.h" /* character defs */ #ifndef M_PI # define M_PI 3.14159265358979323846 #endif /* * TODO - change the mapping of Greek and special chars */ static struct { unsigned char *h_tables; int *h_indices; } hershey_fonts[12] = { Romanc_table, Romanc_indices, Romant_table, Romant_indices, Italicc_table, Italicc_indices, Italict_table, Italict_indices, Romans_table, Romans_indices, Romand_table, Romand_indices, Italicc_table, Italicc_indices, Italict_table, Italict_indices, Greekc_table, Greekc_indices, Special_table, Special_indices, Special_table, Special_indices, 0, 0 }; static unsigned char *chartable = Romanc_table; static int *indices = Romanc_indices; static int curfont; static double hscale = 1.0; /* select a font to use below */ void hselectfont(int f) { chartable = hershey_fonts[f].h_tables; indices = hershey_fonts[f].h_indices; curfont = f; /* fudge factors to make for differences in hershey and PS fonts */ switch (curfont) { case 0: case 1: case 2: case 3: hscale = 0.8; break; case 4: case 5: hscale = 0.9; break; case 6: case 7: hscale = 0.8; break; case 8: case 9: case 10: case 11: hscale = 0.9; break; default: hscale = 1.0; } /* if you are used to the old scaling then uncomment the following */ /* hscale = 1.0; */ } /* write s at xpos, ypos in device coordinates of size scale, direction dir, color color, using vector TODO - fix underlining */ void puthersh(int xpos, int ypos, double scale, int dir, int just, int color, int (*vector) (), char *s) { int i, j, len = 0, ind, it1, it2, tind, sfont = curfont, slen = strlen(s); int sscript = 0, subscript = 0, underline = 0; int ilenx, ileny; int sx = xpos, sy = ypos; int newlines = 0; unsigned char charx, chary; double charw, x, y, xtmp, ytmp, saves = scale, slastx = 0.0, slasty = 0.0; double si = sin(M_PI / 180.0 * dir); double co = cos(M_PI / 180.0 * dir); double dxpos, dypos; ilenx = stringextentx(scale, s); /* ileny = stringextenty(scale, s); switch (just) { case 1: xpos = xpos - co * ilenx + si * ileny; ypos = ypos - si * ilenx - co * ileny; break; case 2: xpos = xpos - (co * ilenx - si * ileny) / 2; ypos = ypos - (si * ilenx + co * ileny) / 2; break; } */ ileny = 0; switch (just) { case 1: xpos = xpos - co * ilenx; ypos = ypos - si * ilenx; break; case 2: xpos = xpos - (co * ilenx) / 2; ypos = ypos - (si * ilenx) / 2; break; } sx = dxpos = xpos; sy = dypos = ypos; setcolor(color); color = 1; for (i = 0; i < slen; i++) { if (s[i] < 32) { continue; } if (s[i] == '\\' && isdigit(s[i + 1])) { hselectfont(s[i + 1] - '0'); i++; continue; } else if (s[i] == '\\' && s[i + 1] == '\\') { continue; } else if (s[i] == '\\' && isoneof(s[i + 1], "cCbxsSnNuU+-")) { switch (s[i + 1]) { case 'x': hselectfont(10); i++; break; case 's': scale = 0.6 * saves; sscript += 20; i++; break; case 'S': scale = 0.6 * saves; sscript += -20; i++; break; case 'N': scale = saves; sscript = 0; i++; break; case 'n': newlines++; xpos = dxpos = sx; ypos = dypos = sy - newlines * 20; i++; break; case 'b': xpos = dxpos = dxpos - slastx; ypos = dypos = dypos - slasty; i++; break; case 'c': i++; break; case 'C': i++; break; case 'u': underline = 1; i++; break; case 'U': underline = 0; i++; break; case '-': scale -= 0.2; i++; break; case '+': scale += 0.2; i++; break; } continue; } ind = s[i] - ' '; len = indices[ind + 1] - indices[ind]; tind = 2 * indices[ind]; it1 = chartable[tind]; it2 = chartable[tind + 1]; x = (it1 - 'R'); y = (it2 - 'R'); charw = y - x; for (j = 1; j < len; j++) { charx = chartable[tind + 2 * j]; chary = chartable[tind + 2 * j + 1] + sscript; if (charx & 128) { charx &= 127; it1 = charx; it2 = chary; xtmp = hscale * scale * (it1 - 'R' - x); ytmp = (-scale * (it2 - 'R')); (*vector) ((int) (xpos + xtmp * co - ytmp * si), (int) (ypos + xtmp * si + ytmp * co), 0); } else { it1 = charx; it2 = chary; xtmp = hscale * scale * (it1 - 'R' - x); ytmp = (-scale * (it2 - 'R')); (*vector) ((int) (xpos + xtmp * co - ytmp * si), (int) (ypos + xtmp * si + ytmp * co), 1); } } if (underline) { (*vector) ((int) xpos, (int) (ypos - scale * 12.0), 0); } xpos = dxpos = dxpos + (slastx = hscale * scale * charw * co); ypos = dypos = dypos + (slasty = scale * charw * si); if (underline) { (*vector) ((int) xpos, (int) (ypos - scale * 12.0), 1); } } hselectfont(sfont); } /* get the x extent of the string in hershey coordinates given size */ int stringextentx(double scale, char *s) { int i, ind, xpos = 0, it1, it2, sfont = curfont, slen = strlen(s); double charw, x, y, dxpos, saves = scale, slastx = 0.0; dxpos = xpos; for (i = 0; i < slen; i++) { if (s[i] < 32) { continue; } if (s[i] == '\\' && isdigit(s[i + 1])) { hselectfont(s[i + 1] - '0'); i++; continue; } else if (s[i] == '\\' && s[i + 1] == '\\') { continue; } else if (s[i] == '\\' && (isalpha(s[i + 1]) || s[i + 1] == '+' || s[i + 1] == '-')) { switch (s[i + 1]) { case 'x': hselectfont(10); i++; break; case 's': scale = 0.6 * saves; i++; break; case 'S': scale = 0.6 * saves; i++; break; case 'N': scale = saves; i++; break; case 'b': xpos = dxpos = dxpos - slastx; i++; break; case 'c': i++; break; case 'C': i++; break; case '-': scale -= 0.2; i++; break; case '+': scale += 0.2; i++; break; } continue; } ind = s[i] - ' '; it1 = chartable[2 * indices[ind]]; it2 = chartable[2 * indices[ind] + 1]; x = it1 - 'R'; y = it2 - 'R'; charw = y - x; xpos = dxpos = dxpos + (slastx = hscale * scale * charw); } hselectfont(sfont); return xpos; } /* get the y extent of the string in hershey coordinates given size */ int stringextenty(double scale, char *s) { int i, j, len = 0, ind, it2; char charx, chary; double ytmp, ymin = 0, ymax = 0; for (i = 0; i < strlen(s); i++) { if (s[i] < 32) { continue; } ind = s[i] - ' '; len = indices[ind + 1] - indices[ind]; for (j = 1; j < len; j++) { charx = chartable[2 * indices[ind] + 2 * j]; chary = chartable[2 * indices[ind] + 2 * j + 1]; if (charx & 128) { charx &= 127; it2 = chary; ytmp = (-scale * (it2 - 'R')); } else { it2 = chary; ytmp = (-scale * (it2 - 'R')); } if (ymax < ytmp) ymax = ytmp; if (ymin > ytmp) ymin = ytmp; } } return ymax - ymin; }