]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/pstext.c
4 * Common PostScript text code for the Common UNIX Printing System (CUPS).
6 * Copyright 2008 by Apple Inc.
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
14 * This file is subject to the Apple OS-Developed Software exception.
18 * psTextEmbedFonts() - Embed PostScript fonts.
19 * psTextListFonts() - List PostScript fonts.
20 * psTextInitialize() - Load and embed font data for UTF-8 text.
21 * psTextUTF8() - Output UTF-8 text at the current position.
22 * psTextUTF32() - Output UTF-32 text at the current position.
26 * Include necessary headers...
30 #include <cups/i18n.h>
34 * Composite font names...
37 static const char * const ps_font_names
[] =
47 * 'psTextEmbedFonts()'- Embed PostScript fonts.
51 psTextEmbedFonts(ps_text_t
*fonts
) /* I - Font data */
53 int i
, j
; /* Looping vars */
54 const char *cups_datadir
; /* CUPS_DATADIR environment variable */
55 char *font
; /* Current font */
56 char filename
[1024]; /* Current filename */
57 FILE *fp
; /* Current file */
58 char line
[1024]; /* Line from file */
59 int ch
; /* Character value */
63 * Get the data directory...
66 if ((cups_datadir
= getenv("CUPS_DATADIR")) == NULL
)
67 cups_datadir
= CUPS_DATADIR
;
73 for (font
= (char *)cupsArrayFirst(fonts
->unique
);
75 font
= (char *)cupsArrayNext(fonts
->unique
))
77 printf("%%%%BeginResource: font %s\n", font
);
79 snprintf(filename
, sizeof(filename
), "%s/fonts/%s", cups_datadir
, font
);
80 if ((fp
= fopen(filename
, "rb")) != NULL
)
82 while ((j
= fread(line
, 1, sizeof(line
), fp
)) > 0)
83 fwrite(line
, 1, j
, stdout
);
88 fprintf(stderr
, "DEBUG: Unable to open font file \"%s\" - %s\n",
89 filename
, strerror(errno
));
91 puts("\n%%EndResource");
95 * Write the encoding arrays...
98 puts("% Character encodings");
100 for (i
= 0; i
< fonts
->num_fonts
; i
++)
102 printf("/cupsEncoding%02x [\n", i
);
104 for (ch
= 0; ch
< 256; ch
++)
106 if (fonts
->glyphs
[fonts
->codes
[i
* 256 + ch
]])
107 printf("/%s", fonts
->glyphs
[fonts
->codes
[i
* 256 + ch
]]);
108 else if (fonts
->codes
[i
* 256 + ch
] > 255)
109 printf("/uni%04X", fonts
->codes
[i
* 256 + ch
]);
121 * Construct composite fonts... Start by reencoding the base fonts...
124 puts("% Reencode base fonts");
126 for (i
= 0; i
< 4; i
++)
127 for (j
= 0; j
< fonts
->num_fonts
; j
++)
129 printf("/%s findfont\n", fonts
->fonts
[j
][i
]);
130 printf("dup length 1 add dict begin\n"
131 " { 1 index /FID ne { def } { pop pop } ifelse } forall\n"
132 " /Encoding cupsEncoding%02x def\n"
135 printf("/%s%02x exch definefont /%s%02x exch def\n", ps_font_names
[i
], j
,
136 ps_font_names
[i
], j
);
140 * Then merge them into composite fonts...
143 puts("% Create composite fonts");
145 for (i
= 0; i
< 4; i
++)
147 puts("8 dict begin");
148 puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def"
150 for (j
= 0; j
< fonts
->num_fonts
; j
++)
151 if (j
== (fonts
->num_fonts
- 1))
153 else if ((j
& 15) == 15)
157 puts("]def/FDepVector[");
158 for (j
= 0; j
< fonts
->num_fonts
; j
++)
159 if (j
== (fonts
->num_fonts
- 1))
160 printf("%s%02x", ps_font_names
[i
], j
);
161 else if ((j
& 3) == 3)
162 printf("%s%02x\n", ps_font_names
[i
], j
);
164 printf("%s%02x ", ps_font_names
[i
], j
);
165 puts("]def currentdict end");
166 printf("/%s exch definefont pop\n", ps_font_names
[i
]);
173 puts("% Procedures to justify text...\n"
174 "/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n"
175 "/showleft{show}bind def\n"
176 "/showright{dup stringwidth pop neg 0 rmoveto show}bind def");
181 * 'psTextListFonts()' - List PostScript fonts.
185 psTextListFonts(ps_text_t
*fonts
) /* I - Font data */
187 char *font
; /* Current font */
190 font
= (char *)cupsArrayFirst(fonts
->unique
);
191 printf("%%%%DocumentSuppliedResources: font %s\n", font
);
192 while ((font
= (char *)cupsArrayNext(fonts
->unique
)) != NULL
)
193 printf("%%%%+ font %s\n", font
);
198 * 'psTextInitialize()' - Load and embed font data for UTF-8 text.
201 ps_text_t
* /* O - Font data */
202 psTextInitialize(void)
204 ps_text_t
*fonts
; /* Font data */
205 int i
, j
; /* Looping vars */
206 char filename
[1024]; /* Current filename */
207 FILE *fp
; /* Current file */
208 const char *cups_datadir
; /* CUPS_DATADIR environment variable */
209 char line
[1024], /* Line from file */
210 *lineptr
, /* Pointer into line */
211 *valptr
; /* Pointer to value in line */
212 int unicode
; /* Character value */
213 int start
, end
; /* Start and end values for range */
214 char glyph
[64]; /* Glyph name */
218 * Get the data directory...
221 if ((cups_datadir
= getenv("CUPS_DATADIR")) == NULL
)
222 cups_datadir
= CUPS_DATADIR
;
225 * Initialize the PostScript text data...
228 fonts
= (ps_text_t
*)calloc(1, sizeof(ps_text_t
));
233 * Load the PostScript glyph names...
236 snprintf(filename
, sizeof(filename
), "%s/data/psglyphs", cups_datadir
);
238 if ((fp
= fopen(filename
, "r")) != NULL
)
240 while (fscanf(fp
, "%x%63s", &unicode
, glyph
) == 2)
241 fonts
->glyphs
[unicode
] = _cupsStrAlloc(glyph
);
247 _cupsLangPrintf(stderr
, _("ERROR: Unable to open \"%s\" - %s\n"), filename
,
253 * Open the UTF-8 character set definition...
256 snprintf(filename
, sizeof(filename
), "%s/charsets/utf-8", cups_datadir
);
258 if ((fp
= fopen(filename
, "r")) == NULL
)
261 * Can't open charset file!
264 _cupsLangPrintf(stderr
, _("ERROR: Unable to open %s: %s\n"), filename
,
269 if (!fgets(line
, sizeof(line
), fp
) || strncmp(line
, "charset utf8", 12))
272 * Bad/empty charset file!
276 _cupsLangPrintf(stderr
, _("ERROR: Bad charset file %s\n"), filename
);
281 * Read the font descriptions...
284 fonts
->unique
= cupsArrayNew((cups_array_func_t
)strcmp
, NULL
);
286 while (fgets(line
, sizeof(line
), fp
) != NULL
)
289 * Skip comment and blank lines...
292 if (line
[0] == '#' || line
[0] == '\n')
296 * Read the font descriptions that should look like:
298 * start end direction width normal [bold italic bold-italic]
303 start
= strtol(lineptr
, &lineptr
, 16);
304 end
= strtol(lineptr
, &lineptr
, 16);
306 while (isspace(*lineptr
& 255))
311 while (!isspace(*lineptr
& 255) && *lineptr
)
317 * Can't have a font without all required values...
320 _cupsLangPrintf(stderr
, _("ERROR: Bad font description line: %s\n"),
328 if (!strcmp(valptr
, "ltor"))
329 fonts
->directions
[fonts
->num_fonts
] = 1;
330 else if (!strcmp(valptr
, "rtol"))
331 fonts
->directions
[fonts
->num_fonts
] = -1;
334 _cupsLangPrintf(stderr
, _("ERROR: Bad text direction %s\n"), valptr
);
340 * Got the direction, now get the width...
343 while (isspace(*lineptr
& 255))
348 while (!isspace(*lineptr
& 255) && *lineptr
)
354 * Can't have a font without all required values...
357 _cupsLangPrintf(stderr
, _("ERROR: Bad font description line: %s\n"),
365 if (!strcmp(valptr
, "single"))
366 fonts
->widths
[fonts
->num_fonts
] = 1;
367 else if (!strcmp(valptr
, "double"))
368 fonts
->widths
[fonts
->num_fonts
] = 2;
371 _cupsLangPrintf(stderr
, _("ERROR: Bad text width %s\n"), valptr
);
380 for (i
= 0; *lineptr
&& i
< 4; i
++)
382 while (isspace(*lineptr
& 255))
387 while (!isspace(*lineptr
& 255) && *lineptr
)
393 if (lineptr
> valptr
)
395 if (!cupsArrayFind(fonts
->unique
, valptr
))
396 cupsArrayAdd(fonts
->unique
, _cupsStrAlloc(valptr
));
398 fonts
->fonts
[fonts
->num_fonts
][i
] = _cupsStrAlloc(valptr
);
403 * Fill in remaining fonts as needed...
406 for (j
= i
; j
< 4; j
++)
407 fonts
->fonts
[fonts
->num_fonts
][j
] =
408 _cupsStrAlloc(fonts
->fonts
[fonts
->num_fonts
][0]);
411 * Define the character mappings...
414 for (i
= start
, j
= fonts
->num_fonts
* 256; i
<= end
; i
++, j
++)
421 * Move to the next font, stopping if needed...
425 if (fonts
->num_fonts
>= 256)
431 if (cupsArrayCount(fonts
->unique
) == 0)
433 _cupsLangPrintf(stderr
, _("ERROR: No fonts in charset file %s\n"), filename
);
442 * 'psTextUTF8()' - Output UTF-8 text at the current position.
446 psTextUTF8(ps_text_t
*fonts
, /* I - Font data */
447 float size
, /* I - Size in points */
448 int style
, /* I - Style */
449 int align
, /* I - Alignment */
450 const char *text
) /* I - UTF-8 text */
452 cups_utf32_t utf32
[2048]; /* Temporary buffer */
453 int utf32len
; /* Number of characters */
462 if ((utf32len
= cupsUTF8ToUTF32(utf32
, (cups_utf8_t
*)text
,
463 (int)(sizeof(utf32
) / sizeof(utf32
[0])))) > 0)
464 psTextUTF32(fonts
, size
, style
, align
, utf32
, utf32len
);
469 * 'psTextUTF32()' - Output UTF-32 text at the current position.
473 psTextUTF32(ps_text_t
*fonts
, /* I - Font data */
474 float size
, /* I - Size in points */
475 int style
, /* I - Font style */
476 int align
, /* I - Alignment */
477 const cups_utf32_t
*text
, /* I - UTF-32 text */
478 int textlen
) /* I - Length of text */
480 if (size
!= fonts
->size
|| style
!= fonts
->style
)
482 printf("/%s findfont %g scalefont setfont\n", ps_font_names
[style
], size
);
484 fonts
->style
= style
;
490 printf("%04x", fonts
->chars
[*text
]);
495 if (align
== PS_CENTER
)
497 else if (align
== PS_RIGHT
)