summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdf-x/spc_xtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdf-x/spc_xtx.c')
-rw-r--r--Build/source/texk/dvipdf-x/spc_xtx.c457
1 files changed, 457 insertions, 0 deletions
diff --git a/Build/source/texk/dvipdf-x/spc_xtx.c b/Build/source/texk/dvipdf-x/spc_xtx.c
new file mode 100644
index 00000000000..a039c36371c
--- /dev/null
+++ b/Build/source/texk/dvipdf-x/spc_xtx.c
@@ -0,0 +1,457 @@
+/*
+ This is xdvipdfmx, an extended version of dvipdfmx,
+ an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (c) 2006 SIL International
+ Written by Jonathan Kew
+
+ This file based on spc_pdfm.c, part of the dvipdfmx project:
+
+ Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <ctype.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+
+#include "numbers.h"
+
+#include "fontmap.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+
+#include "pdfdoc.h"
+
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+#include "pdfdev.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_xtx.h"
+
+
+int
+spc_handler_xtx_do_transform (double x_user, double y_user, double a, double b, double c, double d, double e, double f)
+{
+ pdf_tmatrix M = { 0, 0, 0, 0, 0, 0 };
+ pdf_coord pt;
+
+ /* Create transformation matrix */
+ M.a = a;
+ M.b = b;
+ M.c = c;
+ M.d = d;
+ M.e = ((1.0 - M.a) * x_user - M.c * y_user) + e;
+ M.f = ((1.0 - M.d) * y_user - M.b * x_user) + f;
+
+ pdf_dev_concat(&M);
+ pdf_dev_get_fixed_point(&pt);
+ pdf_dev_set_fixed_point(x_user - pt.x, y_user - pt.y);
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_scale (struct spc_env *spe, struct spc_arg *args)
+{
+ double values[2];
+
+ if (spc_util_read_numbers(&values[0], 2, spe, args) < 2) {
+ return -1;
+ }
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform(spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+}
+
+/* Scaling without gsave/grestore. */
+static pdf_coord *scaleFactors = 0;
+static int scaleFactorCount = -1;
+
+static int
+spc_handler_xtx_bscale (struct spc_env *spe, struct spc_arg *args)
+{
+ double values[2];
+
+ if (!(++scaleFactorCount & 0x0f))
+ scaleFactors = realloc(scaleFactors, (scaleFactorCount + 16) * sizeof(pdf_coord));
+ if (spc_util_read_numbers(&values[0], 2, spe, args) < 2) {
+ return -1;
+ }
+ if (fabs(values[0]) < 1.e-7 || fabs(values[1]) < 1.e-7) {
+ return -1;
+ }
+ scaleFactors[scaleFactorCount].x = 1 / values[0];
+ scaleFactors[scaleFactorCount].y = 1 / values[1];
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+}
+
+static int
+spc_handler_xtx_escale (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_coord factor = scaleFactors[scaleFactorCount--];
+
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe->x_user, spe->y_user, factor.x, 0, 0, factor.y, 0, 0);
+}
+
+static int
+spc_handler_xtx_rotate (struct spc_env *spe, struct spc_arg *args)
+{
+ double value;
+
+ if (spc_util_read_numbers(&value, 1, spe, args) < 1) {
+ return -1;
+ }
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe->x_user, spe->y_user,
+ cos(value * M_PI / 180), sin(value * M_PI / 180),
+ -sin(value * M_PI / 180), cos(value * M_PI / 180),
+ 0, 0);
+}
+
+int
+spc_handler_xtx_gsave (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_gsave();
+
+ return 0;
+}
+
+int
+spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_grestore();
+
+ /*
+ * Unfortunately, the following line is necessary in case
+ * of a font or color change inside of the save/restore pair.
+ * Anything that was done there must be redone, so in effect,
+ * we make no assumptions about what fonts. We act like we are
+ * starting a new page.
+ */
+ pdf_dev_reset_fonts();
+ pdf_dev_reset_color();
+
+ return 0;
+}
+
+/* Please remove this.
+ * This should be handled before processing pages!
+ */
+static int
+spc_handler_xtx_papersize (struct spc_env *spe, struct spc_arg *args)
+{
+ return 0;
+}
+
+static int
+spc_handler_xtx_backgroundcolor (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_colorspec(spe, &colorspec, args, 0);
+ if (error)
+ spc_warn(spe, "No valid color specified?");
+ else {
+ pdf_doc_set_bgcolor(&colorspec);
+ }
+
+ return error;
+}
+
+/* FIXME: xdv2pdf's x:fontmapline and x:fontmapfile may have slightly different syntax/semantics */
+static int
+spc_handler_xtx_fontmapline (struct spc_env *spe, struct spc_arg *ap)
+{
+ fontmap_rec *mrec;
+ char *map_name, opchr;
+ int error = 0;
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr) {
+ spc_warn(spe, "Empty fontmapline special?");
+ return -1;
+ }
+
+ opchr = ap->curptr[0];
+ if (opchr == '-' || opchr == '+')
+ ap->curptr++;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ switch (opchr) {
+ case '-':
+ map_name = parse_ident(&ap->curptr, ap->endptr);
+ if (map_name) {
+ pdf_remove_fontmap_record(map_name);
+ RELEASE(map_name);
+ } else {
+ spc_warn(spe, "Invalid fontmap line: Missing TFM name.");
+ error = -1;
+ }
+ break;
+ case '+':
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr),
+ is_pdfm_mapline(ap->curptr));
+ if (error)
+ spc_warn(spe, "Invalid fontmap line.");
+ else {
+ pdf_append_fontmap_record(mrec->map_name, mrec);
+ }
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ break;
+ default:
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr),
+ is_pdfm_mapline(ap->curptr));
+ if (error)
+ spc_warn(spe, "Invalid fontmap line.");
+ else {
+ pdf_insert_fontmap_record(mrec->map_name, mrec);
+ }
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ break;
+ }
+ if (!error)
+ ap->curptr = ap->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_fontmapfile (struct spc_env *spe, struct spc_arg *args)
+{
+ char *mapfile;
+ int mode, error = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return 0;
+
+ switch (args->curptr[0]) {
+ case '-':
+ mode = FONTMAP_RMODE_REMOVE;
+ args->curptr++;
+ break;
+ case '+':
+ mode = FONTMAP_RMODE_APPEND;
+ args->curptr++;
+ break;
+ default:
+ mode = FONTMAP_RMODE_REPLACE;
+ break;
+ }
+
+ mapfile = parse_val_ident(&args->curptr, args->endptr);
+ if (!mapfile) {
+ spc_warn(spe, "No fontmap file specified.");
+ return -1;
+ } else {
+ error = pdf_load_fontmap_file(mapfile, mode);
+ }
+
+ return error;
+}
+
+static char overlay_name[256];
+
+static int
+spc_handler_xtx_initoverlay (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+ strncpy(overlay_name, args->curptr, args->endptr - args->curptr);
+ overlay_name[args->endptr - args->curptr] = 0;
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_clipoverlay (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+ pdf_dev_grestore();
+ pdf_dev_gsave();
+ if (strncmp(overlay_name, args->curptr, strlen(overlay_name)) != 0
+ && strncmp("all", args->curptr, strlen("all")) != 0)
+ pdf_doc_add_page_content(" 0 0 m W n", 10);
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_renderingmode (struct spc_env *spe, struct spc_arg *args)
+{
+ double value;
+
+ if (spc_util_read_numbers(&value, 1, spe, args) < 1) {
+ return -1;
+ }
+ if ((int) value < 0 || (int) value > 7) {
+ spc_warn(spe, "Invalid text rendering mode %d.\n", (int) value);
+ return -1;
+ }
+ sprintf(work_buffer, " %d Tr", (int) value);
+ pdf_doc_add_page_content(work_buffer, strlen(work_buffer));
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ pdf_doc_add_page_content(" ", 1);
+ pdf_doc_add_page_content(args->curptr, args->endptr - args->curptr);
+ }
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_unsupportedcolor (struct spc_env *spe, struct spc_arg *args)
+{
+ spc_warn(spe, "xetex-style \\special{x:%s} is not supported by this driver;\n"
+ "update document or driver to use \\special{color} instead.", args->command);
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_unsupported (struct spc_env *spe, struct spc_arg *args)
+{
+ spc_warn(spe, "xetex-style \\special{x:%s} is not supported by this driver.", args->command);
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static struct spc_handler xtx_handlers[] = {
+ {"textcolor", spc_handler_xtx_unsupportedcolor},
+ {"textcolorpush", spc_handler_xtx_unsupportedcolor},
+ {"textcolorpop", spc_handler_xtx_unsupportedcolor},
+
+ {"rulecolor", spc_handler_xtx_unsupportedcolor},
+ {"rulecolorpush", spc_handler_xtx_unsupportedcolor},
+ {"rulecolorpop", spc_handler_xtx_unsupportedcolor},
+
+ {"papersize", spc_handler_xtx_papersize},
+ {"backgroundcolor", spc_handler_xtx_backgroundcolor},
+
+ {"gsave", spc_handler_xtx_gsave},
+ {"grestore", spc_handler_xtx_grestore},
+
+ {"scale", spc_handler_xtx_scale},
+ {"bscale", spc_handler_xtx_bscale},
+ {"escale", spc_handler_xtx_escale},
+ {"rotate", spc_handler_xtx_rotate},
+
+ {"fontmapline", spc_handler_xtx_fontmapline},
+ {"fontmapfile", spc_handler_xtx_fontmapfile},
+
+ {"shadow", spc_handler_xtx_unsupported},
+ {"colorshadow", spc_handler_xtx_unsupported},
+ {"renderingmode", spc_handler_xtx_renderingmode},
+
+ {"initoverlay", spc_handler_xtx_initoverlay},
+ {"clipoverlay", spc_handler_xtx_clipoverlay},
+};
+
+int
+spc_xtx_check_special (const char *buf, long len)
+{
+ int r = 0;
+ const char *p, *endptr;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_white(&p, endptr);
+ if (p + strlen("x:") <= endptr &&
+ !memcmp(p, "x:", strlen("x:"))) {
+ r = 1;
+ }
+
+ return r;
+}
+
+int
+spc_xtx_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = -1, i;
+ char *q;
+
+ ASSERT(sph && spe && ap);
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr + strlen("x:") >= ap->endptr ||
+ memcmp(ap->curptr, "x:", strlen("x:"))) {
+ spc_warn(spe, "Not x: special???");
+ return -1;
+ }
+ ap->curptr += strlen("x:");
+
+ skip_white(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (q) {
+ for (i = 0;
+ i < sizeof(xtx_handlers) / sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, xtx_handlers[i].key)) {
+ ap->command = xtx_handlers[i].key;
+ sph->key = "x:";
+ sph->exec = xtx_handlers[i].exec;
+ skip_white(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
+