3aabd4ebbd6ca4a1b8a28ae7ced12bc9af79584c
galt
  Thu Jul 30 13:54:41 2015 -0700
Fixes #15788. Properly escaping text for postscript output. plus it reduces the amount of duplicated escaping code and makes it easier to maintain. It also escapes a full set of characters and not just left and right parens.

diff --git src/lib/psGfx.c src/lib/psGfx.c
index 3e891b5..a7b1088 100644
--- src/lib/psGfx.c
+++ src/lib/psGfx.c
@@ -198,95 +198,108 @@
 }
 
 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;
 }
 
-void psTextBox(struct psGfx *ps, double x, double y, char *text)
-/* Output text in current font at given position. */
+void psTextOutEscaped(struct psGfx *ps, char *text)
+/* Output espcaed text. */
 {
 char c;
-psMoveTo(ps, x, y + ps->fontHeight);
-fprintf(ps->f, "(");
 while ((c = *text++) != 0)
     {
-    if (c == ')' || c == '(')
-        fprintf(ps->f, "\\");
+    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
+    else if (c == '\b')
+        fprintf(ps->f, "\\b");  // back-space
+    else if (c == '\f')
+        fprintf(ps->f, "\\f");  // form-feed
+    else
 	fprintf(ps->f, "%c", c);
     }
+}
+
+void psTextBox(struct psGfx *ps, double x, double y, char *text)
+/* Output text in current font at given position. */
+{
+psMoveTo(ps, x, y + ps->fontHeight);
+fprintf(ps->f, "(");
+psTextOutEscaped(ps, text);
 fprintf(ps->f, ") fillTextBox\n");
 }
 
 void psTextAt(struct psGfx *ps, double x, double y, char *text)
 /* Output text in current font at given position. */
 {
-char c;
 psMoveTo(ps, x, y + ps->fontHeight);
 fprintf(ps->f, "(");
-while ((c = *text++) != 0)
-    {
-    if (c == ')' || c == '(')
-        fprintf(ps->f, "\\");
-    fprintf(ps->f, "%c", c);
-    }
+psTextOutEscaped(ps, text);
 fprintf(ps->f, ") show\n");
 }
 
 void psTextRight(struct psGfx *ps, double x, double y, 
 	double width, double height, 
 	char *text)
 /* Draw a line of text right justified in box defined by x/y/width/height */
 {
 y += (height - ps->fontHeight)/2;
 psMoveTo(ps, x+width, y + ps->fontHeight);
-fprintf(ps->f, "(%s) showBefore\n", text);
+fprintf(ps->f, "(");
+psTextOutEscaped(ps, text);
+fprintf(ps->f, ") showBefore\n");
 }
 
 void psTextCentered(struct psGfx *ps, double x, double y, 
 	double width, double height, 
 	char *text)
 /* Draw a line of text centered in box defined by x/y/width/height */
 {
-char c;
 y += (height - ps->fontHeight)/2;
 psMoveTo(ps, x+width/2, y + ps->fontHeight);
 fprintf(ps->f, "(");
-while ((c = *text++) != 0)
-    {
-    if (c == ')' || c == '(')
-        fprintf(ps->f, "\\");
-    fprintf(ps->f, "%c", c);
-    }
+psTextOutEscaped(ps, text);
 fprintf(ps->f, ") showMiddle\n");
 }
 
 void psTextDown(struct psGfx *ps, double x, double y, char *text)
 /* Output text going downwards rather than across at position. */
 {
 psMoveTo(ps, x, y);
 fprintf(ps->f, "gsave\n");
 fprintf(ps->f, "-90 rotate\n");
-fprintf(ps->f, "(%s) show\n", text);
+fprintf(ps->f, "(");
+psTextOutEscaped(ps, text);
+fprintf(ps->f, ") show\n");
 fprintf(ps->f, "grestore\n");
 }
 
 void psSetColor(struct psGfx *ps, int r, int g, int b)
 /* Set current color. */
 {
 FILE *f = ps->f;
 double scale = 1.0/255;
 if (r == g && g == b)
     {
     psFloatOut(f, scale * r);
     fprintf(f, "setgray\n");
     }
 else
     {