diff options
Diffstat (limited to 'filter/texttops.c')
-rw-r--r-- | filter/texttops.c | 1165 |
1 files changed, 0 insertions, 1165 deletions
diff --git a/filter/texttops.c b/filter/texttops.c deleted file mode 100644 index 361fe4cc..00000000 --- a/filter/texttops.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * "$Id: texttops.c 9399 2010-12-03 06:29:20Z mike $" - * - * Text to PostScript filter for CUPS. - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Main entry for text to PostScript filter. - * WriteEpilogue() - Write the PostScript file epilogue. - * WritePage() - Write a page of text. - * WriteProlog() - Write the PostScript file prolog with options. - * write_line() - Write a row of text. - * write_string() - Write a string of text. - */ - -/* - * Include necessary headers... - */ - -#include "textcommon.h" -#include <cups/language-private.h> - - -/* - * Globals... - */ - -char *Glyphs[65536]; /* PostScript glyphs for Unicode */ -int NumFonts; /* Number of fonts to use */ -char *Fonts[256][4]; /* Fonts to use */ -unsigned short Chars[65536]; /* 0xffcc (ff = font, cc = char) */ -unsigned short Codes[65536]; /* Unicode glyph mapping to fonts */ -int Widths[256]; /* Widths of each font */ -int Directions[256];/* Text directions for each font */ - - -/* - * Local functions... - */ - -static void write_line(int row, lchar_t *line); -static void write_string(int col, int row, int len, lchar_t *s); -static void write_text(const char *s); - - -/* - * 'main()' - Main entry for text to PostScript filter. - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ -{ - return (TextMain("texttops", argc, argv)); -} - - -/* - * 'WriteEpilogue()' - Write the PostScript file epilogue. - */ - -void -WriteEpilogue(void) -{ - puts("%%Trailer"); - printf("%%%%Pages: %d\n", NumPages); - puts("%%EOF"); - - free(Page[0]); - free(Page); -} - - -/* - * 'WritePage()' - Write a page of text. - */ - -void -WritePage(void) -{ - int line; /* Current line */ - - - NumPages ++; - printf("%%%%Page: %d %d\n", NumPages, NumPages); - - puts("gsave"); - - if (PrettyPrint) - printf("%d H\n", NumPages); - - for (line = 0; line < SizeLines; line ++) - write_line(line, Page[line]); - - puts("grestore"); - puts("showpage"); - - memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines); -} - - -/* - * 'WriteProlog()' - Write the PostScript file prolog with options. - */ - -void -WriteProlog(const char *title, /* I - Title of job */ - const char *user, /* I - Username */ - const char *classification, /* I - Classification */ - const char *label, /* I - Page label */ - ppd_file_t *ppd) /* I - PPD file info */ -{ - int i, j, k; /* Looping vars */ - char *charset; /* Character set string */ - char filename[1024]; /* Glyph filenames */ - FILE *fp; /* Glyph files */ - const char *datadir; /* CUPS_DATADIR environment variable */ - char line[1024], /* Line from file */ - *lineptr, /* Pointer into line */ - *valptr; /* Pointer to value in line */ - int ch, unicode; /* Character values */ - int start, end; /* Start and end values for range */ - char glyph[64]; /* Glyph name */ - time_t curtime; /* Current time */ - struct tm *curtm; /* Current date */ - char curdate[255]; /* Current date (text format) */ - int num_fonts; /* Number of unique fonts */ - char *fonts[1024]; /* Unique fonts */ - static char *names[] = /* Font names */ - { - "cupsNormal", - "cupsBold", - "cupsItalic" - }; - - - /* - * Get the data directory... - */ - - if ((datadir = getenv("CUPS_DATADIR")) == NULL) - datadir = CUPS_DATADIR; - - /* - * Adjust margins as necessary... - */ - - if (classification || label) - { - /* - * Leave room for labels... - */ - - PageBottom += 36; - PageTop -= 36; - } - - /* - * Allocate memory for the page... - */ - - SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch; - SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch; - - if (SizeColumns <= 0 || SizeColumns > 32767 || - SizeLines <= 0 || SizeLines > 32767) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - if ((Page = calloc(sizeof(lchar_t *), SizeLines)) == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - if ((Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines)) == NULL) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %dx%d text page."), - SizeColumns, SizeLines); - exit(1); - } - - for (i = 1; i < SizeLines; i ++) - Page[i] = Page[0] + i * SizeColumns; - - if (PageColumns > 1) - { - ColumnGutter = CharsPerInch / 2; - ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) / - PageColumns; - } - else - ColumnWidth = SizeColumns; - - if (ColumnWidth <= 0) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to print %d text columns."), PageColumns); - exit(1); - } - - /* - * Output the DSC header... - */ - - curtime = time(NULL); - curtm = localtime(&curtime); - strftime(curdate, sizeof(curdate), "%c", curtm); - - puts("%!PS-Adobe-3.0"); - printf("%%%%BoundingBox: 0 0 %.0f %.0f\n", PageWidth, PageLength); - printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); - puts("%%Creator: texttops/" CUPS_SVERSION); - printf("%%%%CreationDate: %s\n", curdate); - WriteTextComment("Title", title); - WriteTextComment("For", user); - puts("%%Pages: (atend)"); - - /* - * Initialize globals... - */ - - NumFonts = 0; - memset(Fonts, 0, sizeof(Fonts)); - memset(Glyphs, 0, sizeof(Glyphs)); - memset(Chars, 0, sizeof(Chars)); - memset(Codes, 0, sizeof(Codes)); - - /* - * Load the PostScript glyph names and the corresponding character - * set definition... - */ - - snprintf(filename, sizeof(filename), "%s/data/psglyphs", datadir); - - if ((fp = fopen(filename, "r")) != NULL) - { - while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) - Glyphs[unicode] = strdup(glyph); - - fclose(fp); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open psglyphs")); - exit(1); - } - - /* - * Get the output character set... - */ - - charset = getenv("CHARSET"); - if (charset != NULL && strcmp(charset, "us-ascii") != 0) - { - snprintf(filename, sizeof(filename), "%s/charsets/%s", datadir, charset); - - if ((fp = fopen(filename, "r")) == NULL) - { - /* - * Can't open charset file! - */ - - _cupsLangPrintError("ERROR", _("Unable to open charset file")); - exit(1); - } - - /* - * Opened charset file; now see if this is really a charset file... - */ - - if (fgets(line, sizeof(line), fp) == NULL) - { - /* - * Bad/empty charset file! - */ - - fclose(fp); - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."), - filename); - exit(1); - } - - if (strncmp(line, "charset", 7) != 0) - { - /* - * Bad format/not a charset file! - */ - - fclose(fp); - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset file \"%s\"."), - filename); - exit(1); - } - - /* - * See if this is an 8-bit or UTF-8 character set file... - */ - - line[strlen(line) - 1] = '\0'; /* Drop \n */ - for (lineptr = line + 7; isspace(*lineptr & 255); lineptr ++); /* Skip whitespace */ - - if (strcmp(lineptr, "utf8") == 0) - { - /* - * UTF-8 (Unicode) text... - */ - - NumFonts = 0; - - while (fgets(line, sizeof(line), fp) != NULL) - { - /* - * Skip comment and blank lines... - */ - - if (line[0] == '#' || line[0] == '\n') - continue; - - /* - * Read the font descriptions that should look like: - * - * start end direction width normal [bold italic bold-italic] - */ - - 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) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line: %s"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "ltor") == 0) - Directions[NumFonts] = 1; - else if (strcmp(valptr, "rtol") == 0) - Directions[NumFonts] = -1; - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad text direction: %s"), - valptr); - fclose(fp); - exit(1); - } - - /* - * Got the direction, now get the width... - */ - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad font description line: %s"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "single") == 0) - Widths[NumFonts] = 1; - else if (strcmp(valptr, "double") == 0) - Widths[NumFonts] = 2; - else - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Bad text width: %s"), valptr); - fclose(fp); - exit(1); - } - - /* - * Get the fonts... - */ - - 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) - Fonts[NumFonts][i] = strdup(valptr); - } - - /* - * Fill in remaining fonts as needed... - */ - - for (j = i; j < 4; j ++) - Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); - - /* - * Define the character mappings... - */ - - for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) - { - Chars[i] = j; - Codes[j] = i; - } - - /* - * Move to the next font, stopping if needed... - */ - - NumFonts ++; - if (NumFonts >= 256) - break; - } - - fclose(fp); - } - else - { - _cupsLangPrintFilter(stderr, "ERROR", _("Bad charset type: %s"), lineptr); - fclose(fp); - exit(1); - } - } - else - { - /* - * Standard ASCII output just uses Courier, Courier-Bold, and - * possibly Courier-Oblique. - */ - - NumFonts = 1; - - Fonts[0][ATTR_NORMAL] = strdup("Courier"); - Fonts[0][ATTR_BOLD] = strdup("Courier-Bold"); - Fonts[0][ATTR_ITALIC] = strdup("Courier-Oblique"); - Fonts[0][ATTR_BOLDITALIC] = strdup("Courier-BoldOblique"); - - Widths[0] = 1; - Directions[0] = 1; - - /* - * Define US-ASCII characters... - */ - - for (i = 32; i < 127; i ++) - { - Chars[i] = i; - Codes[i] = i; - } - } - - /* - * Generate a list of unique fonts to use... - */ - - for (i = 0, num_fonts = 0; i < NumFonts; i ++) - for (j = PrettyPrint ? 2 : 1; j >= 0; j --) - { - for (k = 0; k < num_fonts; k ++) - if (strcmp(Fonts[i][j], fonts[k]) == 0) - break; - - if (k >= num_fonts) - { - /* - * Add new font... - */ - - fonts[num_fonts] = Fonts[i][j]; - num_fonts ++; - } - } - - /* - * List the fonts that will be used... - */ - - for (i = 0; i < num_fonts; i ++) - if (i == 0) - printf("%%%%DocumentNeededResources: font %s\n", fonts[i]); - else - printf("%%%%+ font %s\n", fonts[i]); - - puts("%%DocumentSuppliedResources: procset texttops 1.1 0"); - - for (i = 0; i < num_fonts; i ++) - { - if (ppd != NULL) - { - fprintf(stderr, "DEBUG: ppd->num_fonts = %d\n", ppd->num_fonts); - - for (j = 0; j < ppd->num_fonts; j ++) - { - fprintf(stderr, "DEBUG: ppd->fonts[%d] = %s\n", j, ppd->fonts[j]); - - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; - } - } - else - j = 0; - - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ - - printf("%%%%+ font %s\n", fonts[i]); - } - } - - puts("%%EndComments"); - - puts("%%BeginProlog"); - - /* - * Download any missing fonts... - */ - - for (i = 0; i < num_fonts; i ++) - { - if (ppd != NULL) - { - for (j = 0; j < ppd->num_fonts; j ++) - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; - } - else - j = 0; - - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ - - printf("%%%%BeginResource: font %s\n", fonts[i]); - - /**** MRS: Need to use CUPS_FONTPATH env var! ****/ - /**** Also look for Fontmap file or name.pfa, name.pfb... ****/ - snprintf(filename, sizeof(filename), "%s/fonts/%s", datadir, fonts[i]); - if ((fp = fopen(filename, "rb")) != NULL) - { - while ((j = fread(line, 1, sizeof(line), fp)) > 0) - fwrite(line, 1, j, stdout); - - fclose(fp); - } - - puts("\n%%EndResource"); - } - } - - /* - * Write the encoding array(s)... - */ - - puts("% character encoding(s)"); - - for (i = 0; i < NumFonts; i ++) - { - printf("/cupsEncoding%02x [\n", i); - - for (ch = 0; ch < 256; ch ++) - { - if (Glyphs[Codes[i * 256 + ch]]) - printf("/%s", Glyphs[Codes[i * 256 + ch]]); - else if (Codes[i * 256 + ch] > 255) - printf("/uni%04X", Codes[i * 256 + ch]); - else - printf("/.notdef"); - - if ((ch & 7) == 7) - putchar('\n'); - } - - puts("] def"); - } - - /* - * Create the fonts... - */ - - if (NumFonts == 1) - { - /* - * Just reencode the named fonts... - */ - - puts("% Reencode fonts"); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - { - printf("/%s findfont\n", Fonts[0][i]); - puts("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding00 def\n" - " currentdict\n" - "end"); - printf("/%s exch definefont pop\n", names[i]); - } - } - else - { - /* - * Construct composite fonts... Start by reencoding the base fonts... - */ - - puts("% Reencode base fonts"); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - for (j = 0; j < NumFonts; j ++) - { - printf("/%s findfont\n", 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", names[i], j, - names[i], j); - } - - /* - * Then merge them into composite fonts... - */ - - puts("% Create composite fonts..."); - - for (i = PrettyPrint ? 2 : 1; i >= 0; 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 < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%d", j); - else if ((j & 15) == 15) - printf("%d\n", j); - else - printf("%d ", j); - puts("]def/FDepVector["); - for (j = 0; j < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%s%02x", names[i], j); - else if ((j & 3) == 3) - printf("%s%02x\n", names[i], j); - else - printf("%s%02x ", names[i], j); - puts("]def currentdict end"); - printf("/%s exch definefont pop\n", names[i]); - } - } - - /* - * Output the texttops procset... - */ - - puts("%%BeginResource: procset texttops 1.1 0"); - - puts("% Define fonts"); - - printf("/FN /cupsNormal findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - printf("/FB /cupsBold findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - if (PrettyPrint) - printf("/FI /cupsItalic findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - - puts("% Common procedures"); - - puts("/N { FN setfont moveto } bind def"); - puts("/B { FB setfont moveto } bind def"); - printf("/U { gsave 0.5 setlinewidth 0 %.3f rmoveto " - "0 rlineto stroke grestore } bind def\n", -6.8 / LinesPerInch); - - if (PrettyPrint) - { - if (ColorDevice) - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.5 0.0 0.0 setrgbcolor show } bind def"); - puts("/g { 0.0 0.5 0.0 setrgbcolor show } bind def"); - puts("/b { 0.0 0.0 0.5 setrgbcolor show } bind def"); - } - else - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.2 setgray show } bind def"); - puts("/g { 0.2 setgray show } bind def"); - puts("/b { 0.2 setgray show } bind def"); - } - - puts("/I { FI setfont moveto } bind def"); - - puts("/n {"); - puts("\t20 string cvs % convert page number to string"); - if (NumFonts > 1) - { - /* - * Convert a number to double-byte chars... - */ - - puts("\tdup length % get length"); - puts("\tdup 2 mul string /P exch def % P = string twice as long"); - puts("\t0 1 2 index 1 sub { % loop through each character in the page number"); - puts("\t\tdup 3 index exch get % get character N from the page number"); - puts("\t\texch 2 mul dup % compute offset in P"); - puts("\t\tP exch 0 put % font 0"); - puts("\t\t1 add P exch 2 index put % character"); - puts("\t\tpop % discard character"); - puts("\t} for % do for loop"); - puts("\tpop pop % discard string and length"); - puts("\tP % put string on stack"); - } - puts("} bind def"); - - printf("/T"); - write_text(title); - puts("def"); - - printf("/D"); - write_text(curdate); - puts("def"); - - puts("/H {"); - puts("\tgsave"); - puts("\t0.9 setgray"); - - if (Duplex) - { - puts("\tdup 2 mod 0 eq {"); - printf("\t\t%.3f %.3f translate } {\n", - PageWidth - PageRight, PageTop + 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f translate } ifelse\n", - PageLeft, PageTop + 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f translate\n", - PageLeft, PageTop + 72.0f / LinesPerInch); - - printf("\t0 0 %.3f %.3f rectfill\n", PageRight - PageLeft, - 144.0f / LinesPerInch); - - puts("\tFB setfont"); - puts("\t0 setgray"); - - if (Duplex) - { - puts("\tdup 2 mod 0 eq {"); - printf("\t\tT stringwidth pop neg %.3f add %.3f } {\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f } ifelse\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - - puts("\tmoveto T show"); - - printf("\tD dup stringwidth pop neg 2 div %.3f add %.3f\n", - (PageRight - PageLeft) * 0.5, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - puts("\tmoveto show"); - - if (Duplex) - { - puts("\tdup n exch 2 mod 0 eq {"); - printf("\t\t%.3f %.3f } {\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\tdup stringwidth pop neg %.3f add %.3f } ifelse\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\tn dup stringwidth pop neg %.3f add %.3f\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - - puts("\tmoveto show"); - puts("\tgrestore"); - puts("} bind def"); - } - else - puts("/S { show } bind def"); - - puts("%%EndResource"); - - puts("%%EndProlog"); -} - - -/* - * 'write_line()' - Write a row of text. - */ - -static void -write_line(int row, /* I - Row number (0 to N) */ - lchar_t *line) /* I - Line to print */ -{ - int i; /* Looping var */ - int col; /* Current column */ - int attr; /* Current attribute */ - int font, /* Font to use */ - lastfont, /* Last font */ - mono; /* Monospaced? */ - lchar_t *start; /* First character in sequence */ - - - for (col = 0; col < SizeColumns;) - { - while (col < SizeColumns && (line->ch == ' ' || line->ch == 0)) - { - col ++; - line ++; - } - - if (col >= SizeColumns) - break; - - if (NumFonts == 1) - { - /* - * All characters in a single font - assume monospaced... - */ - - attr = line->attr; - start = line; - - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - col ++; - line ++; - } - - write_string(col - (line - start), row, line - start, start); - } - else - { - /* - * Multiple fonts; break up based on the font... - */ - - attr = line->attr; - start = line; - lastfont = Chars[line->ch] / 256; - mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0; - col ++; - line ++; - - if (mono) - { - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - font = Chars[line->ch] / 256; - if (strncmp(Fonts[font][0], "Courier", 7) != 0 || - font != lastfont) - break; - - col ++; - line ++; - } - } - - if (Directions[lastfont] > 0) - write_string(col - (line - start), row, line - start, start); - else - { - /* - * Do right-to-left text... - */ - - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - if (Directions[Chars[line->ch] / 256] > 0 && - !ispunct(line->ch & 255) && !isspace(line->ch & 255)) - break; - - col ++; - line ++; - } - - for (i = 1; start < line; i ++, start ++) - if (!isspace(start->ch & 255)) - write_string(col - i, row, 1, start); - } - } - } -} - - -/* - * 'write_string()' - Write a string of text. - */ - -static void -write_string(int col, /* I - Start column */ - int row, /* I - Row */ - int len, /* I - Number of characters */ - lchar_t *s) /* I - String to print */ -{ - int ch; /* Current character */ - float x, y; /* Position of text */ - unsigned attr; /* Character attributes */ - - - /* - * Position the text and set the font... - */ - - if (Duplex && (NumPages & 1) == 0) - { - x = PageWidth - PageRight; - y = PageTop; - } - else - { - x = PageLeft; - y = PageTop; - } - - x += (float)col * 72.0f / (float)CharsPerInch; - y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch; - - attr = s->attr; - - if (attr & ATTR_RAISED) - y += 36.0 / (float)LinesPerInch; - else if (attr & ATTR_LOWERED) - y -= 36.0 / (float)LinesPerInch; - - if (x == (int)x) - printf("%.0f ", x); - else - printf("%.3f ", x); - - if (y == (int)y) - printf("%.0f ", y); - else - printf("%.3f ", y); - - if (attr & ATTR_BOLD) - putchar('B'); - else if (attr & ATTR_ITALIC) - putchar('I'); - else - putchar('N'); - - if (attr & ATTR_UNDERLINE) - printf(" %.3f U", (float)len * 72.0 / (float)CharsPerInch); - - if (NumFonts > 1) - { - /* - * Write a hex string... - */ - - putchar('<'); - - while (len > 0) - { - printf("%04x", Chars[s->ch]); - - len --; - s ++; - } - - putchar('>'); - } - else - { - /* - * Write a quoted string... - */ - - putchar('('); - - while (len > 0) - { - ch = Chars[s->ch]; - - if (ch < 32 || ch > 126) - { - /* - * Quote 8-bit and control characters... - */ - - printf("\\%03o", ch); - } - else - { - /* - * Quote the parenthesis and backslash as needed... - */ - - if (ch == '(' || ch == ')' || ch == '\\') - putchar('\\'); - - putchar(ch); - } - - len --; - s ++; - } - - putchar(')'); - } - - if (PrettyPrint) - { - if (attr & ATTR_RED) - puts("r"); - else if (attr & ATTR_GREEN) - puts("g"); - else if (attr & ATTR_BLUE) - puts("b"); - else - puts("S"); - } - else - puts("S"); -} - - -/* - * 'write_text()' - Write a text string, quoting/encoding as needed. - */ - -static void -write_text(const char *s) /* I - String to write */ -{ - int ch; /* Actual character value (UTF8) */ - const unsigned char *utf8; /* UTF8 text */ - - - if (NumFonts > 1) - { - /* - * 8/8 encoding... - */ - - putchar('<'); - - utf8 = (const unsigned char *)s; - - while (*utf8) - { - if (*utf8 < 0xc0) - ch = *utf8 ++; - else if ((*utf8 & 0xe0) == 0xc0) - { - /* - * Two byte character... - */ - - ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f); - utf8 += 2; - } - else - { - /* - * Three byte character... - */ - - ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) | - (utf8[2] & 0x3f); - utf8 += 3; - } - - printf("%04x", Chars[ch]); - } - - putchar('>'); - } - else - { - /* - * Standard 8-bit encoding... - */ - - putchar('('); - - while (*s) - { - if (*s < 32 || *s > 126) - printf("\\%03o", *s); - else - { - if (*s == '(' || *s == ')' || *s == '\\') - putchar('\\'); - - putchar(*s); - } - - s ++; - } - - putchar(')'); - } -} - - -/* - * End of "$Id: texttops.c 9399 2010-12-03 06:29:20Z mike $". - */ |