]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/pstext.c
cfd8f08bb934859e035c54d9e10d208923013404
4 * Common PostScript text code for CUPS.
6 * Copyright 2008-2010 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/language-private.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
);
89 _cupsLangPrintError("ERROR", _("Unable to open print file"));
90 fprintf(stderr
, "DEBUG: Unable to open \"%s\".\n", filename
);
93 puts("\n%%EndResource");
97 * Write the encoding arrays...
100 puts("% Character encodings");
102 for (i
= 0; i
< fonts
->num_fonts
; i
++)
104 printf("/cupsEncoding%02x [\n", i
);
106 for (ch
= 0; ch
< 256; ch
++)
108 if (fonts
->glyphs
[fonts
->codes
[i
* 256 + ch
]])
109 printf("/%s", fonts
->glyphs
[fonts
->codes
[i
* 256 + ch
]]);
110 else if (fonts
->codes
[i
* 256 + ch
] > 255)
111 printf("/uni%04X", fonts
->codes
[i
* 256 + ch
]);
123 * Construct composite fonts... Start by reencoding the base fonts...
126 puts("% Reencode base fonts");
128 for (i
= 0; i
< 4; i
++)
129 for (j
= 0; j
< fonts
->num_fonts
; j
++)
131 printf("/%s findfont\n", fonts
->fonts
[j
][i
]);
132 printf("dup length 1 add dict begin\n"
133 " { 1 index /FID ne { def } { pop pop } ifelse } forall\n"
134 " /Encoding cupsEncoding%02x def\n"
137 printf("/%s%02x exch definefont /%s%02x exch def\n", ps_font_names
[i
], j
,
138 ps_font_names
[i
], j
);
142 * Then merge them into composite fonts...
145 puts("% Create composite fonts");
147 for (i
= 0; i
< 4; i
++)
149 puts("8 dict begin");
150 puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def"
152 for (j
= 0; j
< fonts
->num_fonts
; j
++)
153 if (j
== (fonts
->num_fonts
- 1))
155 else if ((j
& 15) == 15)
159 puts("]def/FDepVector[");
160 for (j
= 0; j
< fonts
->num_fonts
; j
++)
161 if (j
== (fonts
->num_fonts
- 1))
162 printf("%s%02x", ps_font_names
[i
], j
);
163 else if ((j
& 3) == 3)
164 printf("%s%02x\n", ps_font_names
[i
], j
);
166 printf("%s%02x ", ps_font_names
[i
], j
);
167 puts("]def currentdict end");
168 printf("/%s exch definefont pop\n", ps_font_names
[i
]);
175 puts("% Procedures to justify text...\n"
176 "/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n"
177 "/showleft{show}bind def\n"
178 "/showright{dup stringwidth pop neg 0 rmoveto show}bind def");
183 * 'psTextListFonts()' - List PostScript fonts.
187 psTextListFonts(ps_text_t
*fonts
) /* I - Font data */
189 char *font
; /* Current font */
192 font
= (char *)cupsArrayFirst(fonts
->unique
);
193 printf("%%%%DocumentSuppliedResources: font %s\n", font
);
194 while ((font
= (char *)cupsArrayNext(fonts
->unique
)) != NULL
)
195 printf("%%%%+ font %s\n", font
);
200 * 'psTextInitialize()' - Load and embed font data for UTF-8 text.
203 ps_text_t
* /* O - Font data */
204 psTextInitialize(void)
206 ps_text_t
*fonts
; /* Font data */
207 int i
, j
; /* Looping vars */
208 char filename
[1024]; /* Current filename */
209 FILE *fp
; /* Current file */
210 const char *cups_datadir
; /* CUPS_DATADIR environment variable */
211 char line
[1024], /* Line from file */
212 *lineptr
, /* Pointer into line */
213 *valptr
; /* Pointer to value in line */
214 int unicode
; /* Character value */
215 int start
, end
; /* Start and end values for range */
216 char glyph
[64]; /* Glyph name */
220 * Get the data directory...
223 if ((cups_datadir
= getenv("CUPS_DATADIR")) == NULL
)
224 cups_datadir
= CUPS_DATADIR
;
227 * Initialize the PostScript text data...
230 fonts
= (ps_text_t
*)calloc(1, sizeof(ps_text_t
));
235 * Load the PostScript glyph names...
238 snprintf(filename
, sizeof(filename
), "%s/data/psglyphs", cups_datadir
);
240 if ((fp
= fopen(filename
, "r")) != NULL
)
242 while (fscanf(fp
, "%x%63s", &unicode
, glyph
) == 2)
243 fonts
->glyphs
[unicode
] = _cupsStrAlloc(glyph
);
249 _cupsLangPrintError("ERROR", _("Unable to open print file"));
250 fprintf(stderr
, "DEBUG: Unable to open \"%s\".\n", filename
);
255 * Open the UTF-8 character set definition...
258 snprintf(filename
, sizeof(filename
), "%s/charsets/utf-8", cups_datadir
);
260 if ((fp
= fopen(filename
, "r")) == NULL
)
263 * Can't open charset file!
266 _cupsLangPrintError("ERROR", _("Unable to open print file"));
267 fprintf(stderr
, "DEBUG: Unable to open \"%s\".\n", filename
);
271 if (!fgets(line
, sizeof(line
), fp
) || strncmp(line
, "charset utf8", 12))
274 * Bad/empty charset file!
278 _cupsLangPrintFilter(stderr
, "ERROR", _("Bad charset file \"%s\"."),
284 * Read the font descriptions...
287 fonts
->unique
= cupsArrayNew((cups_array_func_t
)strcmp
, NULL
);
289 while (fgets(line
, sizeof(line
), fp
) != NULL
)
292 * Skip comment and blank lines...
295 if (line
[0] == '#' || line
[0] == '\n')
299 * Read the font descriptions that should look like:
301 * start end direction width normal [bold italic bold-italic]
306 start
= strtol(lineptr
, &lineptr
, 16);
307 end
= strtol(lineptr
, &lineptr
, 16);
309 while (isspace(*lineptr
& 255))
314 while (!isspace(*lineptr
& 255) && *lineptr
)
320 * Can't have a font without all required values...
323 _cupsLangPrintFilter(stderr
, "ERROR",
324 _("Bad font description line \"%s\"."), valptr
);
331 if (!strcmp(valptr
, "ltor"))
332 fonts
->directions
[fonts
->num_fonts
] = 1;
333 else if (!strcmp(valptr
, "rtol"))
334 fonts
->directions
[fonts
->num_fonts
] = -1;
337 _cupsLangPrintFilter(stderr
, "ERROR", _("Bad text direction \"%s\"."),
344 * Got the direction, now get the width...
347 while (isspace(*lineptr
& 255))
352 while (!isspace(*lineptr
& 255) && *lineptr
)
358 * Can't have a font without all required values...
361 _cupsLangPrintFilter(stderr
, "ERROR",
362 _("Bad font description line \"%s\"."), valptr
);
369 if (!strcmp(valptr
, "single"))
370 fonts
->widths
[fonts
->num_fonts
] = 1;
371 else if (!strcmp(valptr
, "double"))
372 fonts
->widths
[fonts
->num_fonts
] = 2;
375 _cupsLangPrintFilter(stderr
, "ERROR", _("Bad text width \"%s\"."),
385 for (i
= 0; *lineptr
&& i
< 4; i
++)
387 while (isspace(*lineptr
& 255))
392 while (!isspace(*lineptr
& 255) && *lineptr
)
398 if (lineptr
> valptr
)
400 if (!cupsArrayFind(fonts
->unique
, valptr
))
401 cupsArrayAdd(fonts
->unique
, _cupsStrAlloc(valptr
));
403 fonts
->fonts
[fonts
->num_fonts
][i
] = _cupsStrAlloc(valptr
);
408 * Fill in remaining fonts as needed...
411 for (j
= i
; j
< 4; j
++)
412 fonts
->fonts
[fonts
->num_fonts
][j
] =
413 _cupsStrAlloc(fonts
->fonts
[fonts
->num_fonts
][0]);
416 * Define the character mappings...
419 for (i
= start
, j
= fonts
->num_fonts
* 256; i
<= end
; i
++, j
++)
426 * Move to the next font, stopping if needed...
430 if (fonts
->num_fonts
>= 256)
436 if (cupsArrayCount(fonts
->unique
) == 0)
438 _cupsLangPrintFilter(stderr
, "ERROR", _("No fonts in charset file."));
447 * 'psTextUTF8()' - Output UTF-8 text at the current position.
451 psTextUTF8(ps_text_t
*fonts
, /* I - Font data */
452 float size
, /* I - Size in points */
453 int style
, /* I - Style */
454 int align
, /* I - Alignment */
455 const char *text
) /* I - UTF-8 text */
457 cups_utf32_t utf32
[2048]; /* Temporary buffer */
458 int utf32len
; /* Number of characters */
467 if ((utf32len
= cupsUTF8ToUTF32(utf32
, (cups_utf8_t
*)text
,
468 (int)(sizeof(utf32
) / sizeof(utf32
[0])))) > 0)
469 psTextUTF32(fonts
, size
, style
, align
, utf32
, utf32len
);
474 * 'psTextUTF32()' - Output UTF-32 text at the current position.
478 psTextUTF32(ps_text_t
*fonts
, /* I - Font data */
479 float size
, /* I - Size in points */
480 int style
, /* I - Font style */
481 int align
, /* I - Alignment */
482 const cups_utf32_t
*text
, /* I - UTF-32 text */
483 int textlen
) /* I - Length of text */
485 if (size
!= fonts
->size
|| style
!= fonts
->style
)
487 printf("/%s findfont %g scalefont setfont\n", ps_font_names
[style
], size
);
489 fonts
->style
= style
;
495 printf("%04x", fonts
->chars
[*text
]);
500 if (align
== PS_CENTER
)
502 else if (align
== PS_RIGHT
)