#include "pstext.h"
#include <cups/language-private.h>
static const char * const ps_font_names[] =
{
"cupsNormal",
"cupsBold",
"cupsItalic",
"cupsBoldItalic"
};
void
psTextEmbedFonts(ps_text_t *fonts)
{
int i, j;
const char *cups_datadir;
char *font;
char filename[1024];
FILE *fp;
char line[1024];
int ch;
if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL)
cups_datadir = CUPS_DATADIR;
for (font = (char *)cupsArrayFirst(fonts->unique);
font;
font = (char *)cupsArrayNext(fonts->unique))
{
printf("%%%%BeginResource: font %s\n", font);
snprintf(filename, sizeof(filename), "%s/fonts/%s", cups_datadir, font);
if ((fp = fopen(filename, "rb")) != NULL)
{
while ((j = fread(line, 1, sizeof(line), fp)) > 0)
fwrite(line, 1, j, stdout);
fclose(fp);
}
else
{
_cupsLangPrintError("ERROR", _("Unable to open print file"));
fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename);
}
puts("\n%%EndResource");
}
puts("% Character encodings");
for (i = 0; i < fonts->num_fonts; i ++)
{
printf("/cupsEncoding%02x [\n", i);
for (ch = 0; ch < 256; ch ++)
{
if (fonts->glyphs[fonts->codes[i * 256 + ch]])
printf("/%s", fonts->glyphs[fonts->codes[i * 256 + ch]]);
else if (fonts->codes[i * 256 + ch] > 255)
printf("/uni%04X", fonts->codes[i * 256 + ch]);
else
printf("/.notdef");
if ((ch & 7) == 7)
putchar('\n');
}
puts("] def");
}
puts("% Reencode base fonts");
for (i = 0; i < 4; i ++)
for (j = 0; j < fonts->num_fonts; j ++)
{
printf("/%s findfont\n", fonts->fonts[j][i]);
printf("dup length 1 add dict begin\n"
" { 1 index /FID ne { def } { pop pop } ifelse } forall\n"
" /Encoding cupsEncoding%02x def\n"
" currentdict\n"
"end\n", j);
printf("/%s%02x exch definefont /%s%02x exch def\n", ps_font_names[i], j,
ps_font_names[i], j);
}
puts("% Create composite fonts");
for (i = 0; i < 4; i ++)
{
puts("8 dict begin");
puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def"
"/Encoding[");
for (j = 0; j < fonts->num_fonts; j ++)
if (j == (fonts->num_fonts - 1))
printf("%d", j);
else if ((j & 15) == 15)
printf("%d\n", j);
else
printf("%d ", j);
puts("]def/FDepVector[");
for (j = 0; j < fonts->num_fonts; j ++)
if (j == (fonts->num_fonts - 1))
printf("%s%02x", ps_font_names[i], j);
else if ((j & 3) == 3)
printf("%s%02x\n", ps_font_names[i], j);
else
printf("%s%02x ", ps_font_names[i], j);
puts("]def currentdict end");
printf("/%s exch definefont pop\n", ps_font_names[i]);
}
puts("% Procedures to justify text...\n"
"/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n"
"/showleft{show}bind def\n"
"/showright{dup stringwidth pop neg 0 rmoveto show}bind def");
}
void
psTextListFonts(ps_text_t *fonts)
{
char *font;
font = (char *)cupsArrayFirst(fonts->unique);
printf("%%%%DocumentSuppliedResources: font %s\n", font);
while ((font = (char *)cupsArrayNext(fonts->unique)) != NULL)
printf("%%%%+ font %s\n", font);
}
ps_text_t *
psTextInitialize(void)
{
ps_text_t *fonts;
int i, j;
char filename[1024];
FILE *fp;
const char *cups_datadir;
char line[1024],
*lineptr,
*valptr;
int unicode;
int start, end;
char glyph[64];
if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL)
cups_datadir = CUPS_DATADIR;
fonts = (ps_text_t *)calloc(1, sizeof(ps_text_t));
fonts->size = -1.0;
fonts->style = -1;
snprintf(filename, sizeof(filename), "%s/data/psglyphs", cups_datadir);
if ((fp = fopen(filename, "r")) != NULL)
{
while (fscanf(fp, "%x%63s", &unicode, glyph) == 2)
fonts->glyphs[unicode] = _cupsStrAlloc(glyph);
fclose(fp);
}
else
{
_cupsLangPrintError("ERROR", _("Unable to open print file"));
fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename);
exit(1);
}
snprintf(filename, sizeof(filename), "%s/charsets/utf-8", cups_datadir);
if ((fp = fopen(filename, "r")) == NULL)
{
_cupsLangPrintError("ERROR", _("Unable to open print file"));
fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename);
exit(1);
}
if (!fgets(line, sizeof(line), fp) || strncmp(line, "charset utf8", 12))
{
fclose(fp);
_cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."),
filename);
exit(1);
}
fonts->unique = cupsArrayNew((cups_array_func_t)strcmp, NULL);
while (fgets(line, sizeof(line), fp) != NULL)
{
if (line[0] == '#' || line[0] == '\n')
continue;
lineptr = line;
start = strtol(lineptr, &lineptr, 16);
end = strtol(lineptr, &lineptr, 16);
while (isspace(*lineptr & 255))
lineptr ++;
valptr = lineptr;
while (!isspace(*lineptr & 255) && *lineptr)
lineptr ++;
if (!*lineptr)
{
_cupsLangPrintFilter(stderr, "ERROR",
_("Bad font description line \"%s\"."), valptr);
fclose(fp);
exit(1);
}
*lineptr++ = '\0';
if (!strcmp(valptr, "ltor"))
fonts->directions[fonts->num_fonts] = 1;
else if (!strcmp(valptr, "rtol"))
fonts->directions[fonts->num_fonts] = -1;
else
{
_cupsLangPrintFilter(stderr, "ERROR", _("Bad text direction \"%s\"."),
valptr);
fclose(fp);
exit(1);
}
while (isspace(*lineptr & 255))
lineptr ++;
valptr = lineptr;
while (!isspace(*lineptr & 255) && *lineptr)
lineptr ++;
if (!*lineptr)
{
_cupsLangPrintFilter(stderr, "ERROR",
_("Bad font description line \"%s\"."), valptr);
fclose(fp);
exit(1);
}
*lineptr++ = '\0';
if (!strcmp(valptr, "single"))
fonts->widths[fonts->num_fonts] = 1;
else if (!strcmp(valptr, "double"))
fonts->widths[fonts->num_fonts] = 2;
else
{
_cupsLangPrintFilter(stderr, "ERROR", _("Bad text width \"%s\"."),
valptr);
fclose(fp);
exit(1);
}
for (i = 0; *lineptr && i < 4; i ++)
{
while (isspace(*lineptr & 255))
lineptr ++;
valptr = lineptr;
while (!isspace(*lineptr & 255) && *lineptr)
lineptr ++;
if (*lineptr)
*lineptr++ = '\0';
if (lineptr > valptr)
{
if (!cupsArrayFind(fonts->unique, valptr))
cupsArrayAdd(fonts->unique, _cupsStrAlloc(valptr));
fonts->fonts[fonts->num_fonts][i] = _cupsStrAlloc(valptr);
}
}
for (j = i; j < 4; j ++)
fonts->fonts[fonts->num_fonts][j] =
_cupsStrAlloc(fonts->fonts[fonts->num_fonts][0]);
for (i = start, j = fonts->num_fonts * 256; i <= end; i ++, j ++)
{
fonts->chars[i] = j;
fonts->codes[j] = i;
}
fonts->num_fonts ++;
if (fonts->num_fonts >= 256)
break;
}
fclose(fp);
if (cupsArrayCount(fonts->unique) == 0)
{
_cupsLangPrintFilter(stderr, "ERROR", _("No fonts in charset file."));
exit(1);
}
return (fonts);
}
void
psTextUTF8(ps_text_t *fonts,
float size,
int style,
int align,
const char *text)
{
cups_utf32_t utf32[2048];
int utf32len;
if (!text)
{
puts("");
return;
}
if ((utf32len = cupsUTF8ToUTF32(utf32, (cups_utf8_t *)text,
(int)(sizeof(utf32) / sizeof(utf32[0])))) > 0)
psTextUTF32(fonts, size, style, align, utf32, utf32len);
}
void
psTextUTF32(ps_text_t *fonts,
float size,
int style,
int align,
const cups_utf32_t *text,
int textlen)
{
if (size != fonts->size || style != fonts->style)
{
printf("/%s findfont %g scalefont setfont\n", ps_font_names[style], size);
fonts->size = size;
fonts->style = style;
}
putchar('<');
while (textlen > 0)
{
printf("%04x", fonts->chars[*text]);
text ++;
textlen --;
}
if (align == PS_CENTER)
puts(">showcenter");
else if (align == PS_RIGHT)
puts(">showright");
else
puts(">showleft");
}