3
% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
5
% This file is part of LuaTeX.
7
% LuaTeX is free software; you can redistribute it and/or modify it under
8
% the terms of the GNU General Public License as published by the Free
9
% Software Foundation; either version 2 of the License, or (at your
10
% option) any later version.
12
% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
% License for more details.
17
% You should have received a copy of the GNU General Public License along
18
% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
23
static const char _svn_version[] =
24
"$Id: pdfcolorstack.w 3612 2010-04-13 09:29:42Z taco $"
25
"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.1/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w $";
28
@* Color Stack and Matrix Transformation Support.
31
@ In the following array and especially stack data structures are used.
33
They have the following properties:
35
\item{-} They automatically grow dynamically.
36
\item{-} The size never decreases.
37
\item{-} The variable with name ending in "size" contains the number how many
38
entries the data structure can hold.
39
\item{-} The variable with name ending in "used" contains the number of
40
actually used entries.
41
\item{-} Memory of strings in stack entries must be allocated and
42
freed if the stack is cleared.
47
#define MAX_COLORSTACKS 32768
48
/* The colorstack number is stored in two bytes (info field of the node) */
49
/* Condition (newcolorstack): |MAX_COLORSTACKS mod STACK_INCREMENT = 0| */
51
#define COLOR_DEFAULT "0 g 0 G"
52
/* |literal_mode|s, see pdftex.web */
55
#define DIRECT_ALWAYS 2
57
/* remember shipout mode: page/form */
74
static colstack_type *colstacks = NULL;
75
static int colstacks_size = 0;
76
static int colstacks_used = 0;
78
@ Initialization is done, if the color stacks are used,
79
|init_colorstacks()| is defined as macro to avoid unnecessary
82
#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init();
84
static void colstacks_first_init(void)
86
colstacks_size = STACK_INCREMENT;
87
colstacks = xtalloc((unsigned) colstacks_size, colstack_type);
89
colstacks[0].page_stack = NULL;
90
colstacks[0].form_stack = NULL;
91
colstacks[0].page_size = 0;
92
colstacks[0].form_size = 0;
93
colstacks[0].page_used = 0;
94
colstacks[0].form_used = 0;
95
colstacks[0].page_current = xstrdup(COLOR_DEFAULT);
96
colstacks[0].form_current = xstrdup(COLOR_DEFAULT);
97
colstacks[0].form_init = xstrdup(COLOR_DEFAULT);
98
colstacks[0].literal_mode = DIRECT_ALWAYS;
99
colstacks[0].page_start = true;
103
int colorstackused(void)
106
return colstacks_used;
110
A new color stack is setup with the given parameters.
111
The stack number is returned or -1 in case of error (no room).
113
int newcolorstack(int s, int literal_mode, boolean page_start)
115
colstack_type *colstack;
122
if (colstacks_used == MAX_COLORSTACKS) {
125
if (colstacks_used == colstacks_size) {
126
colstacks_size += STACK_INCREMENT;
127
/* If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't
128
need to check the case that size overruns |MAX_COLORSTACKS|. */
130
xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size);
132
/* claim new color stack */
133
colstack_num = colstacks_used++;
134
colstack = &colstacks[colstack_num];
135
/* configure the new color stack */
136
colstack->page_stack = NULL;
137
colstack->form_stack = NULL;
138
colstack->page_size = 0;
139
colstack->page_used = 0;
140
colstack->form_size = 0;
141
colstack->form_used = 0;
142
colstack->literal_mode = literal_mode;
143
colstack->page_start = page_start;
144
str = makecstring(s);
146
colstack->page_current = NULL;
147
colstack->form_current = NULL;
148
colstack->form_init = NULL;
150
colstack->page_current = xstrdup(str);
151
colstack->form_current = xstrdup(str);
152
colstack->form_init = xstrdup(str);
159
#define get_colstack(n) (&colstacks[n])
161
@ Puts a string on top of the string pool and updates |pool_ptr|.
163
static void put_cstring_on_str_pool(char *str)
165
int save_selector = selector;
166
selector = new_string;
167
if (str == NULL || *str == 0) {
171
selector = save_selector;
175
static int colorstackset(int colstack_no, str_number s)
177
colstack_type *colstack = get_colstack(colstack_no);
180
xfree(colstack->page_current);
181
colstack->page_current = makecstring(s);
183
xfree(colstack->form_current);
184
colstack->form_current = makecstring(s);
186
return colstack->literal_mode;
190
int colorstackcurrent(int colstack_no)
192
colstack_type *colstack = get_colstack(colstack_no);
195
put_cstring_on_str_pool(colstack->page_current);
197
put_cstring_on_str_pool(colstack->form_current);
199
return colstack->literal_mode;
203
static int colorstackpush(int colstack_no, str_number s)
205
colstack_type *colstack = get_colstack(colstack_no);
208
if (colstack->page_used == colstack->page_size) {
209
colstack->page_size += STACK_INCREMENT;
210
colstack->page_stack = xretalloc(colstack->page_stack,
211
(unsigned) colstack->page_size,
214
colstack->page_stack[colstack->page_used++] = colstack->page_current;
215
str = makecstring(s);
217
colstack->page_current = NULL;
219
colstack->page_current = xstrdup(str);
223
if (colstack->form_used == colstack->form_size) {
224
colstack->form_size += STACK_INCREMENT;
225
colstack->form_stack = xretalloc(colstack->form_stack,
226
(unsigned) colstack->form_size,
229
colstack->form_stack[colstack->form_used++] = colstack->form_current;
230
str = makecstring(s);
232
colstack->form_current = NULL;
234
colstack->form_current = xstrdup(str);
238
return colstack->literal_mode;
242
int colorstackpop(int colstack_no)
244
colstack_type *colstack = get_colstack(colstack_no);
247
if (colstack->page_used == 0) {
248
pdftex_warn("pop empty color page stack %u",
249
(unsigned int) colstack_no);
250
return colstack->literal_mode;
252
xfree(colstack->page_current);
253
colstack->page_current = colstack->page_stack[--colstack->page_used];
254
put_cstring_on_str_pool(colstack->page_current);
256
if (colstack->form_used == 0) {
257
pdftex_warn("pop empty color form stack %u",
258
(unsigned int) colstack_no);
259
return colstack->literal_mode;
261
xfree(colstack->form_current);
262
colstack->form_current = colstack->form_stack[--colstack->form_used];
263
put_cstring_on_str_pool(colstack->form_current);
265
return colstack->literal_mode;
269
void colorstackpagestart(void)
272
colstack_type *colstack;
275
/* see procedure |pdf_out_colorstack_startpage| */
279
for (i = 0; i < colstacks_used; i++) {
280
colstack = &colstacks[i];
281
for (j = 0; j < colstack->form_used; j++) {
282
xfree(colstack->form_stack[j]);
284
colstack->form_used = 0;
285
xfree(colstack->form_current);
286
if (colstack->form_init == NULL) {
287
colstack->form_current = NULL;
289
colstack->form_current = xstrdup(colstack->form_init);
295
int colorstackskippagestart(int colstack_no)
297
colstack_type *colstack = get_colstack(colstack_no);
299
if (!colstack->page_start) {
302
if (colstack->page_current == NULL) {
305
if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) {
313
void pdf_out_colorstack(PDF pdf, halfword p)
320
cmd = pdf_colorstack_cmd(p);
321
stack_no = pdf_colorstack_stack(p);
323
if (stack_no >= colorstackused()) {
325
tprint("Color stack ");
327
tprint(" is not initialized for use!");
333
case colorstack_push:
334
old_setting = selector;
335
selector = new_string;
336
show_token_list(token_link(pdf_colorstack_data(p)), null, -1);
337
selector = old_setting;
339
if (cmd == colorstack_set)
340
literal_mode = colorstackset(stack_no, s);
342
literal_mode = colorstackpush(stack_no, s);
343
if (str_length(s) > 0)
344
pdf_literal(pdf, s, literal_mode, false);
349
literal_mode = colorstackpop(stack_no);
351
case colorstack_current:
352
literal_mode = colorstackcurrent(stack_no);
357
if (cur_length > 0) {
359
pdf_literal(pdf, s, literal_mode, false);
365
void pdf_out_colorstack_startpage(PDF pdf)
373
max = colorstackused();
375
start_status = colorstackskippagestart(i);
376
if (start_status == 0) {
377
literal_mode = colorstackcurrent(i);
378
if (cur_length > 0) {
380
pdf_literal(pdf, s, literal_mode, false);