~ubuntu-branches/ubuntu/wily/luatex/wily

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/pdf/pdfcolorstack.w

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2010-04-29 00:47:19 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100429004719-o42etkqe90n97b9e
Tags: 0.60.1-1
* new upstream release, adapt build-script patch
* disable patch: upstream-epstopdf_cc_no_xpdf_patching, included upstream
* disable patch: libpoppler-0.12, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
% pdfcolorstack.w
 
2
 
3
% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
 
4
 
 
5
% This file is part of LuaTeX.
 
6
 
 
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.
 
11
 
 
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.
 
16
 
 
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/>. 
 
19
 
 
20
@ @c
 
21
#include "ptexlib.h"
 
22
 
 
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 $";
 
26
 
 
27
 
 
28
@* Color Stack and Matrix Transformation Support.
 
29
 
 
30
 
 
31
@ In the following array and especially stack data structures are used.
 
32
 
 
33
They have the following properties:
 
34
 
 
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.
 
43
 
 
44
 
 
45
@ Color Stack 
 
46
@c
 
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| */
 
50
 
 
51
#define COLOR_DEFAULT "0 g 0 G"
 
52
/* |literal_mode|s, see pdftex.web */
 
53
#define SET_ORIGIN 0
 
54
#define DIRECT_PAGE 1
 
55
#define DIRECT_ALWAYS 2
 
56
 
 
57
/* remember shipout mode: page/form */
 
58
boolean page_mode;
 
59
 
 
60
typedef struct {
 
61
    char **page_stack;
 
62
    char **form_stack;
 
63
    char *page_current;
 
64
    char *form_current;
 
65
    char *form_init;
 
66
    int page_size;
 
67
    int form_size;
 
68
    int page_used;
 
69
    int form_used;
 
70
    int literal_mode;
 
71
    boolean page_start;
 
72
} colstack_type;
 
73
 
 
74
static colstack_type *colstacks = NULL;
 
75
static int colstacks_size = 0;
 
76
static int colstacks_used = 0;
 
77
 
 
78
@ Initialization is done, if the color stacks are used,
 
79
    |init_colorstacks()| is defined as macro to avoid unnecessary
 
80
    procedure calls.
 
81
@c
 
82
#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init();
 
83
 
 
84
static void colstacks_first_init(void)
 
85
{
 
86
    colstacks_size = STACK_INCREMENT;
 
87
    colstacks = xtalloc((unsigned) colstacks_size, colstack_type);
 
88
    colstacks_used = 1;
 
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;
 
100
}
 
101
 
 
102
@ @c
 
103
int colorstackused(void)
 
104
{
 
105
    init_colorstacks();
 
106
    return colstacks_used;
 
107
}
 
108
 
 
109
@  |newcolorstack()|
 
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).
 
112
@c
 
113
int newcolorstack(int s, int literal_mode, boolean page_start)
 
114
{
 
115
    colstack_type *colstack;
 
116
    int colstack_num;
 
117
    char *str;
 
118
 
 
119
    init_colorstacks();
 
120
 
 
121
    /* make room */
 
122
    if (colstacks_used == MAX_COLORSTACKS) {
 
123
        return -1;
 
124
    }
 
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|. */
 
129
        colstacks =
 
130
            xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size);
 
131
    }
 
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);
 
145
    if (*str == 0) {
 
146
        colstack->page_current = NULL;
 
147
        colstack->form_current = NULL;
 
148
        colstack->form_init = NULL;
 
149
    } else {
 
150
        colstack->page_current = xstrdup(str);
 
151
        colstack->form_current = xstrdup(str);
 
152
        colstack->form_init = xstrdup(str);
 
153
    }
 
154
    free(str);
 
155
    return colstack_num;
 
156
}
 
157
 
 
158
@ @c
 
159
#define get_colstack(n) (&colstacks[n])
 
160
 
 
161
@ Puts a string on top of the string pool and updates |pool_ptr|. 
 
162
@c
 
163
static void put_cstring_on_str_pool(char *str)
 
164
{
 
165
    int save_selector = selector;
 
166
    selector = new_string;
 
167
    if (str == NULL || *str == 0) {
 
168
        return;
 
169
    }
 
170
    tprint(str);
 
171
    selector = save_selector;
 
172
}
 
173
 
 
174
@ @c
 
175
static int colorstackset(int colstack_no, str_number s)
 
176
{
 
177
    colstack_type *colstack = get_colstack(colstack_no);
 
178
 
 
179
    if (page_mode) {
 
180
        xfree(colstack->page_current);
 
181
        colstack->page_current = makecstring(s);
 
182
    } else {
 
183
        xfree(colstack->form_current);
 
184
        colstack->form_current = makecstring(s);
 
185
    }
 
186
    return colstack->literal_mode;
 
187
}
 
188
 
 
189
@ @c
 
190
int colorstackcurrent(int colstack_no)
 
191
{
 
192
    colstack_type *colstack = get_colstack(colstack_no);
 
193
 
 
194
    if (page_mode) {
 
195
        put_cstring_on_str_pool(colstack->page_current);
 
196
    } else {
 
197
        put_cstring_on_str_pool(colstack->form_current);
 
198
    }
 
199
    return colstack->literal_mode;
 
200
}
 
201
 
 
202
@ @c
 
203
static int colorstackpush(int colstack_no, str_number s)
 
204
{
 
205
    colstack_type *colstack = get_colstack(colstack_no);
 
206
    char *str;
 
207
    if (page_mode) {
 
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,
 
212
                                             char *);
 
213
        }
 
214
        colstack->page_stack[colstack->page_used++] = colstack->page_current;
 
215
        str = makecstring(s);
 
216
        if (*str == 0) {
 
217
            colstack->page_current = NULL;
 
218
        } else {
 
219
            colstack->page_current = xstrdup(str);
 
220
        }
 
221
        free(str);
 
222
    } else {
 
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,
 
227
                                             char *);
 
228
        }
 
229
        colstack->form_stack[colstack->form_used++] = colstack->form_current;
 
230
        str = makecstring(s);
 
231
        if (*str == 0) {
 
232
            colstack->form_current = NULL;
 
233
        } else {
 
234
            colstack->form_current = xstrdup(str);
 
235
        }
 
236
        free(str);
 
237
    }
 
238
    return colstack->literal_mode;
 
239
}
 
240
 
 
241
@ @c
 
242
int colorstackpop(int colstack_no)
 
243
{
 
244
    colstack_type *colstack = get_colstack(colstack_no);
 
245
 
 
246
    if (page_mode) {
 
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;
 
251
        }
 
252
        xfree(colstack->page_current);
 
253
        colstack->page_current = colstack->page_stack[--colstack->page_used];
 
254
        put_cstring_on_str_pool(colstack->page_current);
 
255
    } else {
 
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;
 
260
        }
 
261
        xfree(colstack->form_current);
 
262
        colstack->form_current = colstack->form_stack[--colstack->form_used];
 
263
        put_cstring_on_str_pool(colstack->form_current);
 
264
    }
 
265
    return colstack->literal_mode;
 
266
}
 
267
 
 
268
@ @c
 
269
void colorstackpagestart(void)
 
270
{
 
271
    int i, j;
 
272
    colstack_type *colstack;
 
273
 
 
274
    if (page_mode) {
 
275
        /* see procedure |pdf_out_colorstack_startpage| */
 
276
        return;
 
277
    }
 
278
 
 
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]);
 
283
        }
 
284
        colstack->form_used = 0;
 
285
        xfree(colstack->form_current);
 
286
        if (colstack->form_init == NULL) {
 
287
            colstack->form_current = NULL;
 
288
        } else {
 
289
            colstack->form_current = xstrdup(colstack->form_init);
 
290
        }
 
291
    }
 
292
}
 
293
 
 
294
@ @c
 
295
int colorstackskippagestart(int colstack_no)
 
296
{
 
297
    colstack_type *colstack = get_colstack(colstack_no);
 
298
 
 
299
    if (!colstack->page_start) {
 
300
        return 1;
 
301
    }
 
302
    if (colstack->page_current == NULL) {
 
303
        return 0;
 
304
    }
 
305
    if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) {
 
306
        return 2;
 
307
    }
 
308
    return 0;
 
309
}
 
310
 
 
311
 
 
312
@ @c
 
313
void pdf_out_colorstack(PDF pdf, halfword p)
 
314
{
 
315
    int old_setting;
 
316
    str_number s;
 
317
    int cmd;
 
318
    int stack_no;
 
319
    int literal_mode;
 
320
    cmd = pdf_colorstack_cmd(p);
 
321
    stack_no = pdf_colorstack_stack(p);
 
322
    literal_mode = 0;
 
323
    if (stack_no >= colorstackused()) {
 
324
        tprint_nl("");
 
325
        tprint("Color stack ");
 
326
        print_int(stack_no);
 
327
        tprint(" is not initialized for use!");
 
328
        tprint_nl("");
 
329
        return;
 
330
    }
 
331
    switch (cmd) {
 
332
    case colorstack_set:
 
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;
 
338
        s = make_string();
 
339
        if (cmd == colorstack_set)
 
340
            literal_mode = colorstackset(stack_no, s);
 
341
        else
 
342
            literal_mode = colorstackpush(stack_no, s);
 
343
        if (str_length(s) > 0)
 
344
            pdf_literal(pdf, s, literal_mode, false);
 
345
        flush_str(s);
 
346
        return;
 
347
        break;
 
348
    case colorstack_pop:
 
349
        literal_mode = colorstackpop(stack_no);
 
350
        break;
 
351
    case colorstack_current:
 
352
        literal_mode = colorstackcurrent(stack_no);
 
353
        break;
 
354
    default:
 
355
        break;
 
356
    }
 
357
    if (cur_length > 0) {
 
358
        s = make_string();
 
359
        pdf_literal(pdf, s, literal_mode, false);
 
360
        flush_str(s);
 
361
    }
 
362
}
 
363
 
 
364
@ @c
 
365
void pdf_out_colorstack_startpage(PDF pdf)
 
366
{
 
367
    int i;
 
368
    int max;
 
369
    int start_status;
 
370
    int literal_mode;
 
371
    str_number s;
 
372
    i = 0;
 
373
    max = colorstackused();
 
374
    while (i < max) {
 
375
        start_status = colorstackskippagestart(i);
 
376
        if (start_status == 0) {
 
377
            literal_mode = colorstackcurrent(i);
 
378
            if (cur_length > 0) {
 
379
                s = make_string();
 
380
                pdf_literal(pdf, s, literal_mode, false);
 
381
                flush_str(s);
 
382
            }
 
383
        }
 
384
        incr(i);
 
385
    }
 
386
}