From 77d33a75930c5bc87f8010d9a7cec19c45eace36 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Sun, 6 Sep 2020 04:59:35 +0000 Subject: Add a new special pdfcolorstack. (S. Hirata) git-svn-id: svn://tug.org/texlive/trunk@56274 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/spc_misc.c | 373 +++++++++++++++++++++++++++++++-- 1 file changed, 353 insertions(+), 20 deletions(-) (limited to 'Build/source/texk/dvipdfm-x/spc_misc.c') diff --git a/Build/source/texk/dvipdfm-x/spc_misc.c b/Build/source/texk/dvipdfm-x/spc_misc.c index 87678486f99..9b9c7a7d9bf 100644 --- a/Build/source/texk/dvipdfm-x/spc_misc.c +++ b/Build/source/texk/dvipdfm-x/spc_misc.c @@ -32,6 +32,8 @@ #include "mfileio.h" +#include "dpxutil.h" + #include "pdfparse.h" #include "pdfobj.h" @@ -47,6 +49,340 @@ #include "spc_util.h" #include "spc_misc.h" +/* pdfcolorstack: + * This special is provoded as a compatibility feature to pdftex. + */ +struct stack +{ + int page; + int direct; + dpx_stack stack; +}; + +#define PDFCOLORSTACK_MAX_STACK 256 +struct spc_stack +{ + struct stack stacks[PDFCOLORSTACK_MAX_STACK]; +}; + +static struct spc_stack spc_stack; + +static int +pdfcolorstack__get_id (struct spc_env *spe, int *id, struct spc_arg *args) +{ + char *q; + + if (args->curptr >= args->endptr) { + spc_warn(spe, "Stack ID number expected but not found."); + return -1; + } + q = parse_number(&args->curptr, args->endptr); + if (!q) { + spc_warn(spe, "Stack ID number expected but not found."); + return -1; + } + *id = atoi(q); + RELEASE(q); + + skip_white(&args->curptr, args->endptr); + + return 0; +} + +static int +pdfcolorstack__init (void *dp) +{ + struct spc_stack *sd = dp; + int i; + + for (i = 0; i < 64; i++) { + sd->stacks[i].page = 0; + sd->stacks[i].direct = 0; + dpx_stack_init(&sd->stacks[i].stack); + } + + return 0; +} + +static int +pdfcolorstack__clean (void *dp) +{ + struct spc_stack *sd = dp; + int i; + + for (i = 0; i < PDFCOLORSTACK_MAX_STACK; i++) { + pdf_obj *litstr; + dpx_stack *stk = &sd->stacks[i].stack; + + while ((litstr = dpx_stack_pop(stk)) != NULL) { + pdf_release_obj(litstr); + } + } + + return 0; +} + +static void +pdfcolorstack__set_litstr (pdf_coord cp, pdf_obj *litstr, int direct) +{ + pdf_tmatrix M; + + if (!litstr) + return; + + if (!direct) { + M.a = M.d = 1.0; M.b = M.c = 0.0; + M.e = cp.x; M.f = cp.y; + pdf_dev_concat(&M); + } + pdf_doc_add_page_content(" ", 1); + pdf_doc_add_page_content(pdf_string_value(litstr), pdf_string_length(litstr)); + if (!direct) { + M.e = -cp.x; M.f = -cp.y; + pdf_dev_concat(&M); + } +} + +static int +spc_handler_pdfcolorstackinit (struct spc_env *spe, struct spc_arg *args) +{ + int id = -1; + struct stack *st; + char *q; + pdf_coord cp = {0.0, 0.0}; + pdf_obj *litstr; + + skip_white(&args->curptr, args->endptr); + if (args->curptr >= args->endptr) + return -1; + + if (pdfcolorstack__get_id(spe, &id, args) < 0) + return -1; + if (id < 0 || id >= PDFCOLORSTACK_MAX_STACK) { + spc_warn(spe, "Invalid stack number specified: %d", id); + return -1; + } + skip_white(&args->curptr, args->endptr); + + st = &spc_stack.stacks[id]; + if (dpx_stack_depth(&st->stack) > 0) { + spc_warn(spe, "Stadk ID=%d already initialized?", id); + return -1; + } + + while ((q = parse_c_ident(&args->curptr, args->endptr)) != NULL) { + if (!strcmp(q, "page")) { + st->page = 1; + } else if (!strcmp(q, "direct")) { + st->direct = 1; + } else { + spc_warn(spe, "Ignoring unknown option for pdfcolorstack special (init): %s", q); + } + RELEASE(q); + skip_white(&args->curptr, args->endptr); + } + + if (args->curptr < args->endptr) { + litstr = parse_pdf_string(&args->curptr, args->endptr); + if (litstr) { + dpx_stack_push(&st->stack, litstr); + pdfcolorstack__set_litstr(cp, litstr, st->direct); + } + skip_white(&args->curptr, args->endptr); + } else { + spc_warn(spe, "No valid PDF literal specified."); + return -1; + } + + return 0; +} + +static int +pdfcolorstack__set (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args) +{ + pdf_obj *litstr; + + skip_white(&args->curptr, args->endptr); + if (args->curptr >= args->endptr) + return -1; + + litstr = dpx_stack_pop(&st->stack); + if (!litstr) { + spc_warn(spe, "Stack empty!"); + return -1; + } + pdf_release_obj(litstr); + + litstr = parse_pdf_string(&args->curptr, args->endptr); + if (litstr) { + dpx_stack_push(&st->stack, litstr); + pdfcolorstack__set_litstr(cp, litstr, st->direct); + skip_white(&args->curptr, args->endptr); + } + + return 0; +} + +static int +pdfcolorstack__push (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args) +{ + pdf_obj *litstr; + + skip_white(&args->curptr, args->endptr); + if (args->curptr >= args->endptr) + return -1; + + litstr = parse_pdf_string(&args->curptr, args->endptr); + if (litstr) { + dpx_stack_push(&st->stack, litstr); + pdfcolorstack__set_litstr(cp, litstr, st->direct); + skip_white(&args->curptr, args->endptr); + } + + return 0; +} + +static int +pdfcolorstack__current (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args) +{ + pdf_obj *litstr; + + litstr = dpx_stack_top(&st->stack); + if (litstr) { + pdfcolorstack__set_litstr(cp, litstr, st->direct); + skip_white(&args->curptr, args->endptr); + } else { + spc_warn(spe, "Stack empty!"); + return -1; + } + + return 0; +} + +static int +pdfcolorstack__pop (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args) +{ + int error = 0; + pdf_obj *litstr; + + /* "default" at the bottom */ + if (dpx_stack_depth(&st->stack) < 2) { + spc_warn(spe, "Stack underflow"); + return -1; + } + litstr = dpx_stack_pop(&st->stack); + if (litstr) { + pdf_release_obj(litstr); + } + litstr = dpx_stack_top(&st->stack); + if (litstr) { + pdfcolorstack__set_litstr(cp, litstr, st->direct); + } + + return error; +} + +static int +spc_handler_pdfcolorstack (struct spc_env *spe, struct spc_arg *args) +{ + int error = 0; + int id; + char *command; + struct stack *st; + pdf_coord cp; + + skip_white(&args->curptr, args->endptr); + if (args->curptr >= args->endptr) + return -1; + + if (pdfcolorstack__get_id(spe, &id, args) < 0) + return -1; + if (id < 0 || id >= PDFCOLORSTACK_MAX_STACK) { + spc_warn(spe, "Invalid stack ID specified: %d", id); + return -1; + } + skip_white(&args->curptr, args->endptr); + + st = &spc_stack.stacks[id]; + if (dpx_stack_depth(&st->stack) < 1) { + spc_warn(spe, "Stack ID=%d not properly initialized?", id); + return -1; + } + + command = parse_c_ident(&args->curptr, args->endptr); + if (!command) + return -1; + + spc_get_current_point(spe, &cp); + if (!strcmp(command, "set")) { + error = pdfcolorstack__set(spe, st, cp, args); + } else if (!strcmp(command, "push")) { + error = pdfcolorstack__push(spe, st, cp, args); + } else if (!strcmp(command, "pop")) { + error = pdfcolorstack__pop(spe, st, cp, args); + } else if (!strcmp(command, "current")) { + error = pdfcolorstack__current(spe, st, cp, args); + } else { + spc_warn(spe, "Unknown action: %s", command); + } + + if (error) { + spc_warn(spe, "Error occurred while processing pdfcolorstack: id=%d command=\"%s\"", id, command); + } + + RELEASE(command); + + return error; +} + + +int +spc_misc_at_begin_document (void) +{ + struct spc_stack *sd = &spc_stack; + return pdfcolorstack__init(sd); +} + +int +spc_misc_at_end_document (void) +{ + struct spc_stack *sd = &spc_stack; + return pdfcolorstack__clean(sd); +} + +int +spc_misc_at_begin_page (void) +{ + struct spc_stack *sd = &spc_stack; + int i; + + for (i = 0; i < 64; i++) { + dpx_stack *stk = &sd->stacks[i].stack; + + if (sd->stacks[i].page) { + pdf_obj *litstr = dpx_stack_top(stk); + pdf_coord cp = {0.0, 0.0}; + + if (litstr) + pdfcolorstack__set_litstr(cp, litstr, sd->stacks[i].direct); + } + } + + return 0; +} + +int +spc_misc_at_begin_form (void) +{ + return spc_misc_at_begin_page(); +} + +int +spc_misc_at_end_form (void) +{ + return spc_misc_at_begin_page(); +} + static int spc_handler_postscriptbox (struct spc_env *spe, struct spc_arg *ap) { @@ -130,12 +466,14 @@ spc_handler_null (struct spc_env *spe, struct spc_arg *args) } static struct spc_handler misc_handlers[] = { - {"postscriptbox", spc_handler_postscriptbox}, - {"landscape", spc_handler_null}, /* handled at bop */ - {"papersize", spc_handler_null}, /* handled at bop */ - {"src:", spc_handler_null}, /* simply ignore */ - {"pos:", spc_handler_null}, /* simply ignore */ - {"om:", spc_handler_null} /* simply ignore */ + {"postscriptbox", spc_handler_postscriptbox}, + {"pdfcolorstackinit", spc_handler_pdfcolorstackinit}, + {"pdfcolorstack", spc_handler_pdfcolorstack}, + {"landscape", spc_handler_null}, /* handled at bop */ + {"papersize", spc_handler_null}, /* handled at bop */ + {"src:", spc_handler_null}, /* simply ignore */ + {"pos:", spc_handler_null}, /* simply ignore */ + {"om:", spc_handler_null} /* simply ignore */ }; @@ -143,18 +481,16 @@ int spc_misc_check_special (const char *buffer, int size) { const char *p, *endptr; - int i; + int i; p = buffer; endptr = p + size; skip_white(&p, endptr); - size = (int) (endptr - p); - for (i = 0; - i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) { + size = (int) (endptr - p); + for (i = 0; i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) { if (size >= strlen(misc_handlers[i].key) && - !strncmp(p, misc_handlers[i].key, - strlen(misc_handlers[i].key))) { + !strncmp(p, misc_handlers[i].key, strlen(misc_handlers[i].key))) { return 1; } } @@ -163,19 +499,17 @@ spc_misc_check_special (const char *buffer, int size) } int -spc_misc_setup_handler (struct spc_handler *handle, - struct spc_env *spe, struct spc_arg *args) +spc_misc_setup_handler (struct spc_handler *handle, struct spc_env *spe, struct spc_arg *args) { const char *key; - int i, keylen; + int i, keylen; ASSERT(handle && spe && args); skip_white(&args->curptr, args->endptr); key = args->curptr; - while (args->curptr < args->endptr && - isalpha((unsigned char)args->curptr[0])) { + while (args->curptr < args->endptr && isalpha((unsigned char)args->curptr[0])) { args->curptr++; } @@ -189,10 +523,9 @@ spc_misc_setup_handler (struct spc_handler *handle, return -1; } - for (i = 0; - i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) { + for (i = 0; i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) { if (keylen == strlen(misc_handlers[i].key) && - !strncmp(key, misc_handlers[i].key, keylen)) { + !strncmp(key, misc_handlers[i].key, keylen)) { skip_white(&args->curptr, args->endptr); -- cgit v1.2.3