diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
commit | f372862c42d234710b6057449b46818e63181c90 (patch) | |
tree | a9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w | |
parent | 2dad291ab056f30816e0aea61970f38033c2f6a5 (diff) |
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf
git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w new file mode 100644 index 00000000000..1e472c7f713 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w @@ -0,0 +1,386 @@ +% pdfcolorstack.w +% +% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX 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. + +% LuaTeX 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 Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c +#include "ptexlib.h" + +static const char _svn_version[] = + "$Id: pdfcolorstack.w 3571 2010-04-02 13:50:45Z taco $" + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w $"; + + +@* Color Stack and Matrix Transformation Support. + + +@ In the following array and especially stack data structures are used. + +They have the following properties: + + \item{-} They automatically grow dynamically. + \item{-} The size never decreases. + \item{-} The variable with name ending in "size" contains the number how many + entries the data structure can hold. + \item{-} The variable with name ending in "used" contains the number of + actually used entries. + \item{-} Memory of strings in stack entries must be allocated and + freed if the stack is cleared. + + +@ Color Stack +@c +#define MAX_COLORSTACKS 32768 +/* The colorstack number is stored in two bytes (info field of the node) */ +/* Condition (newcolorstack): |MAX_COLORSTACKS mod STACK_INCREMENT = 0| */ + +#define COLOR_DEFAULT "0 g 0 G" +/* |literal_mode|s, see pdftex.web */ +#define SET_ORIGIN 0 +#define DIRECT_PAGE 1 +#define DIRECT_ALWAYS 2 + +/* remember shipout mode: page/form */ +boolean page_mode; + +typedef struct { + char **page_stack; + char **form_stack; + char *page_current; + char *form_current; + char *form_init; + int page_size; + int form_size; + int page_used; + int form_used; + int literal_mode; + boolean page_start; +} colstack_type; + +static colstack_type *colstacks = NULL; +static int colstacks_size = 0; +static int colstacks_used = 0; + +@ Initialization is done, if the color stacks are used, + |init_colorstacks()| is defined as macro to avoid unnecessary + procedure calls. +@c +#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init(); + +void colstacks_first_init(void) +{ + colstacks_size = STACK_INCREMENT; + colstacks = xtalloc((unsigned) colstacks_size, colstack_type); + colstacks_used = 1; + colstacks[0].page_stack = NULL; + colstacks[0].form_stack = NULL; + colstacks[0].page_size = 0; + colstacks[0].form_size = 0; + colstacks[0].page_used = 0; + colstacks[0].form_used = 0; + colstacks[0].page_current = xstrdup(COLOR_DEFAULT); + colstacks[0].form_current = xstrdup(COLOR_DEFAULT); + colstacks[0].form_init = xstrdup(COLOR_DEFAULT); + colstacks[0].literal_mode = DIRECT_ALWAYS; + colstacks[0].page_start = true; +} + +@ @c +int colorstackused(void) +{ + init_colorstacks(); + return colstacks_used; +} + +@ |newcolorstack()| + A new color stack is setup with the given parameters. + The stack number is returned or -1 in case of error (no room). +@c +int newcolorstack(int s, int literal_mode, boolean page_start) +{ + colstack_type *colstack; + int colstack_num; + char *str; + + init_colorstacks(); + + /* make room */ + if (colstacks_used == MAX_COLORSTACKS) { + return -1; + } + if (colstacks_used == colstacks_size) { + colstacks_size += STACK_INCREMENT; + /* If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't + need to check the case that size overruns |MAX_COLORSTACKS|. */ + colstacks = + xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size); + } + /* claim new color stack */ + colstack_num = colstacks_used++; + colstack = &colstacks[colstack_num]; + /* configure the new color stack */ + colstack->page_stack = NULL; + colstack->form_stack = NULL; + colstack->page_size = 0; + colstack->page_used = 0; + colstack->form_size = 0; + colstack->form_used = 0; + colstack->literal_mode = literal_mode; + colstack->page_start = page_start; + str = makecstring(s); + if (*str == 0) { + colstack->page_current = NULL; + colstack->form_current = NULL; + colstack->form_init = NULL; + } else { + colstack->page_current = xstrdup(str); + colstack->form_current = xstrdup(str); + colstack->form_init = xstrdup(str); + } + free(str); + return colstack_num; +} + +@ @c +#define get_colstack(n) (&colstacks[n]) + +@ Puts a string on top of the string pool and updates |pool_ptr|. +@c +static void put_cstring_on_str_pool(char *str) +{ + int save_selector = selector; + selector = new_string; + if (str == NULL || *str == 0) { + return; + } + tprint(str); + selector = save_selector; +} + +@ @c +int colorstackset(int colstack_no, str_number s) +{ + colstack_type *colstack = get_colstack(colstack_no); + + if (page_mode) { + xfree(colstack->page_current); + colstack->page_current = makecstring(s); + } else { + xfree(colstack->form_current); + colstack->form_current = makecstring(s); + } + return colstack->literal_mode; +} + +@ @c +int colorstackcurrent(int colstack_no) +{ + colstack_type *colstack = get_colstack(colstack_no); + + if (page_mode) { + put_cstring_on_str_pool(colstack->page_current); + } else { + put_cstring_on_str_pool(colstack->form_current); + } + return colstack->literal_mode; +} + +@ @c +static int colorstackpush(int colstack_no, str_number s) +{ + colstack_type *colstack = get_colstack(colstack_no); + char *str; + if (page_mode) { + if (colstack->page_used == colstack->page_size) { + colstack->page_size += STACK_INCREMENT; + colstack->page_stack = xretalloc(colstack->page_stack, + (unsigned) colstack->page_size, + char *); + } + colstack->page_stack[colstack->page_used++] = colstack->page_current; + str = makecstring(s); + if (*str == 0) { + colstack->page_current = NULL; + } else { + colstack->page_current = xstrdup(str); + } + free(str); + } else { + if (colstack->form_used == colstack->form_size) { + colstack->form_size += STACK_INCREMENT; + colstack->form_stack = xretalloc(colstack->form_stack, + (unsigned) colstack->form_size, + char *); + } + colstack->form_stack[colstack->form_used++] = colstack->form_current; + str = makecstring(s); + if (*str == 0) { + colstack->form_current = NULL; + } else { + colstack->form_current = xstrdup(str); + } + free(str); + } + return colstack->literal_mode; +} + +@ @c +int colorstackpop(int colstack_no) +{ + colstack_type *colstack = get_colstack(colstack_no); + + if (page_mode) { + if (colstack->page_used == 0) { + pdftex_warn("pop empty color page stack %u", + (unsigned int) colstack_no); + return colstack->literal_mode; + } + xfree(colstack->page_current); + colstack->page_current = colstack->page_stack[--colstack->page_used]; + put_cstring_on_str_pool(colstack->page_current); + } else { + if (colstack->form_used == 0) { + pdftex_warn("pop empty color form stack %u", + (unsigned int) colstack_no); + return colstack->literal_mode; + } + xfree(colstack->form_current); + colstack->form_current = colstack->form_stack[--colstack->form_used]; + put_cstring_on_str_pool(colstack->form_current); + } + return colstack->literal_mode; +} + +@ @c +void colorstackpagestart(void) +{ + int i, j; + colstack_type *colstack; + + if (page_mode) { + /* see procedure |pdf_out_colorstack_startpage| */ + return; + } + + for (i = 0; i < colstacks_used; i++) { + colstack = &colstacks[i]; + for (j = 0; j < colstack->form_used; j++) { + xfree(colstack->form_stack[j]); + } + colstack->form_used = 0; + xfree(colstack->form_current); + if (colstack->form_init == NULL) { + colstack->form_current = NULL; + } else { + colstack->form_current = xstrdup(colstack->form_init); + } + } +} + +@ @c +int colorstackskippagestart(int colstack_no) +{ + colstack_type *colstack = get_colstack(colstack_no); + + if (!colstack->page_start) { + return 1; + } + if (colstack->page_current == NULL) { + return 0; + } + if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) { + return 2; + } + return 0; +} + + +@ @c +void pdf_out_colorstack(PDF pdf, halfword p) +{ + int old_setting; + str_number s; + int cmd; + int stack_no; + int literal_mode; + cmd = pdf_colorstack_cmd(p); + stack_no = pdf_colorstack_stack(p); + literal_mode = 0; + if (stack_no >= colorstackused()) { + tprint_nl(""); + tprint("Color stack "); + print_int(stack_no); + tprint(" is not initialized for use!"); + tprint_nl(""); + return; + } + switch (cmd) { + case colorstack_set: + case colorstack_push: + old_setting = selector; + selector = new_string; + show_token_list(token_link(pdf_colorstack_data(p)), null, -1); + selector = old_setting; + s = make_string(); + if (cmd == colorstack_set) + literal_mode = colorstackset(stack_no, s); + else + literal_mode = colorstackpush(stack_no, s); + if (str_length(s) > 0) + pdf_literal(pdf, s, literal_mode, false); + flush_str(s); + return; + break; + case colorstack_pop: + literal_mode = colorstackpop(stack_no); + break; + case colorstack_current: + literal_mode = colorstackcurrent(stack_no); + break; + default: + break; + } + if (cur_length > 0) { + s = make_string(); + pdf_literal(pdf, s, literal_mode, false); + flush_str(s); + } +} + +@ @c +void pdf_out_colorstack_startpage(PDF pdf) +{ + int i; + int max; + int start_status; + int literal_mode; + str_number s; + i = 0; + max = colorstackused(); + while (i < max) { + start_status = colorstackskippagestart(i); + if (start_status == 0) { + literal_mode = colorstackcurrent(i); + if (cur_length > 0) { + s = make_string(); + pdf_literal(pdf, s, literal_mode, false); + flush_str(s); + } + } + incr(i); + } +} |