4dfb16e26cf4a3b2093c6491dfad4c30105f98c5 braney Mon Oct 21 08:39:57 2024 -0700 get the ps driver to use the Windows 1252 encoding to get the 8-bit characters with the high bit set to print correctly diff --git src/lib/psGfx.c src/lib/psGfx.c index 062ffb6..611955a 100644 --- src/lib/psGfx.c +++ src/lib/psGfx.c @@ -1,29 +1,32 @@ /* PostScript graphics - * This provides a bit of a shell around writing graphics to * a postScript file. Perhaps the most important thing it * does is convert 0,0 from being at the bottom left to * being at the top left. */ /* Copyright (C) 2011 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "psPoly.h" #include "psGfx.h" #include "linefile.h" #include "pipeline.h" +#include "iconv.h" + +#include "reEncodeFont.c" // a windows 1252 encoding static void psFloatOut(FILE *f, double x) /* Write out a floating point number, but not in too much * precision. */ { int i = round(x); if (i == x) fprintf(f, "%d ", i); else fprintf(f, "%0.4f ", x); } void psClipRect(struct psGfx *ps, double x, double y, double width, double height) /* Set clipping rectangle. */ @@ -112,30 +115,33 @@ ps->xOff = ptMargin; ps->yOff = ptMargin; ps->fontHeight = 10; /* Cope with fact y coordinates are bottom to top rather * than top to bottom. */ ps->yScale = -ps->yScale; ps->yOff = ps->ptHeight - ps->yOff; ps->newTransOps = supportNewTrans(); psWriteHeader(ps, ptWidth, ptHeight); /* adding a gsave here fixes an old ghostview bug with cliprestore */ fprintf(ps->f, "gsave\n"); +/* put out the Windows 1252 encoding */ +fputs(encodeFont, ps->f); + /* Set initial clipping rectangle. */ psClipRect(ps, 0, 0, ps->userWidth, ps->userHeight); /* Set line width to a single pixel. */ psSetLineWidth(ps,1); return ps; } void psTranslate(struct psGfx *ps, double xTrans, double yTrans) /* add a constant to translate all coordinates */ { ps->xOff += xTrans*ps->xScale; ps->yOff += yTrans*ps->yScale; } @@ -215,56 +221,87 @@ * y2 on the right. */ { FILE *f = ps->f; fprintf(f, "newpath\n"); psMoveTo(ps, x1, y1); psLineTo(ps, x2, y2); psLineTo(ps, x2, bottom); psLineTo(ps, x1, bottom); fprintf(f, "closepath\n"); fprintf(f, "fill\n"); } void psSetFont(struct psGfx *ps, char *fontName, double size) { FILE *f = ps->f; -fprintf(f, "/%s findfont ", fontName); +fprintf(f, "/%s-Win /%s reencodefont ", fontName, fontName); /* Note the 1.2 and the 1.0 below seem to get it to * position about where the stuff developed for pixel * based systems expects it. It is all a kludge though! */ fprintf(f, "%f scalefont setfont\n", -size*ps->yScale*1.2); ps->fontHeight = size*0.8; } void psTimesFont(struct psGfx *ps, double size) /* Set font to times of a certain size. */ { FILE *f = ps->f; fprintf(f, "/Helvetica findfont "); /* Note the 1.2 and the 1.0 below seem to get it to * position about where the stuff developed for pixel * based systems expects it. It is all a kludge though! */ fprintf(f, "%f scalefont setfont\n", -size*ps->yScale*1.2); ps->fontHeight = size*0.8; } +static iconv_t ourIconv; // convert context UTF-8 > Windows 1252 + +static size_t utf8ToWindows1252(char *text, unsigned char *buffer, size_t nLength) +/* Convert UTF-8 string to Unicode string. */ +{ +if (ourIconv == NULL) + { + ourIconv = iconv_open("WINDOWS-1252//", "UTF-8"); + + if (ourIconv == NULL) + errAbort("iconv problem errno %d\n",errno); + } + +size_t length = strlen(text); +char *newText = (char *)buffer; + +int ret = iconv(ourIconv, &text, &length, &newText, &nLength); + +if (ret < 0) + errAbort("iconv problem errno %d\n",errno); + +return (newText - (char *)buffer); +} + void psTextOutEscaped(struct psGfx *ps, char *text) /* Output post-script-escaped text. * Notice that ps uses escaping similar to C itself.*/ { +size_t length = strlen(text); +unsigned char buff[length * 2]; // should be way too much + +length = utf8ToWindows1252(text, buff, length * 4); +buff[length] = '\0'; + +text = (char *)buff; char c; while ((c = *text++) != 0) { if (c == '(') fprintf(ps->f, "\\("); // left-paren else if (c == ')') fprintf(ps->f, "\\)"); // right-paren else if (c == '\\') fprintf(ps->f, "\\\\"); // back-slash else if (c == '\n') fprintf(ps->f, "\\n"); // new-line else if (c == '\r') fprintf(ps->f, "\\r"); // carriage-return else if (c == '\t') fprintf(ps->f, "\\t"); // tab