1
/*
2
 * Copyright © 2008 Chris Wilson <chris@chris-wilson.co.uk>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it either under the terms of the GNU Lesser General Public
6
 * License version 2.1 as published by the Free Software Foundation
7
 * (the "LGPL") or, at your option, under the terms of the Mozilla
8
 * Public License Version 1.1 (the "MPL"). If you do not alter this
9
 * notice, a recipient may use your version of this file under either
10
 * the MPL or the LGPL.
11
 *
12
 * You should have received a copy of the LGPL along with this library
13
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
15
 * You should have received a copy of the MPL along with this library
16
 * in the file COPYING-MPL-1.1
17
 *
18
 * The contents of this file are subject to the Mozilla Public License
19
 * Version 1.1 (the "License"); you may not use this file except in
20
 * compliance with the License. You may obtain a copy of the License at
21
 * http://www.mozilla.org/MPL/
22
 *
23
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
24
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
25
 * the specific language governing rights and limitations.
26
 *
27
 * The Original Code is the cairo graphics library.
28
 *
29
 * The Initial Developer of the Original Code is Chris Wilson.
30
 *
31
 * Contributor(s):
32
 *	Chris Wilson <chris@chris-wilson.co.uk>
33
 */
34

            
35
#ifndef CAIRO_SCRIPT_PRIVATE_H
36
#define CAIRO_SCRIPT_PRIVATE_H
37

            
38
#include "config.h"
39

            
40
#include "cairo-script-interpreter.h"
41

            
42
#include <stddef.h>
43
#include <setjmp.h>
44

            
45
#ifdef _MSC_VER
46
#undef inline
47
#define inline __inline
48
#endif
49

            
50
#ifndef FALSE
51
#define FALSE 0
52
#endif
53

            
54
#ifndef TRUE
55
#define TRUE (!FALSE)
56
#endif
57

            
58
#ifndef NULL
59
#define NULL (void *) 0
60
#endif
61

            
62
#if   HAVE_STDINT_H
63
# include <stdint.h>
64
#elif HAVE_INTTYPES_H
65
# include <inttypes.h>
66
#elif HAVE_SYS_INT_TYPES_H
67
# include <sys/int_types.h>
68
#elif defined(_MSC_VER)
69
  typedef __int8 int8_t;
70
  typedef unsigned __int8 uint8_t;
71
  typedef __int16 int16_t;
72
  typedef unsigned __int16 uint16_t;
73
  typedef __int32 int32_t;
74
  typedef unsigned __int32 uint32_t;
75
  typedef __int64 int64_t;
76
  typedef unsigned __int64 uint64_t;
77
# ifndef HAVE_UINT64_T
78
#  define HAVE_UINT64_T 1
79
# endif
80
#else
81
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
82
#endif
83

            
84
#if HAVE_BYTESWAP_H
85
# include <byteswap.h>
86
#endif
87
#ifndef bswap_16
88
# define bswap_16(p) \
89
	(((((uint16_t)(p)) & 0x00ff) << 8) | \
90
	  (((uint16_t)(p))           >> 8))
91
#endif
92
#ifndef bswap_32
93
# define bswap_32(p) \
94
         (((((uint32_t)(p)) & 0x000000ff) << 24) | \
95
	  ((((uint32_t)(p)) & 0x0000ff00) << 8)  | \
96
	  ((((uint32_t)(p)) & 0x00ff0000) >> 8)  | \
97
	  ((((uint32_t)(p)))              >> 24))
98
#endif
99

            
100

            
101
#if __GNUC__ >= 3
102
#define csi_pure __attribute__((pure))
103
#define csi_const __attribute__((const))
104
#else
105
#define csi_pure
106
#define csi_const
107
#endif
108

            
109
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
110
#define _CSI_BOOLEAN_EXPR(expr)                   \
111
 __extension__ ({                               \
112
   int _csi_boolean_var_;                         \
113
   if (expr)                                    \
114
      _csi_boolean_var_ = 1;                      \
115
   else                                         \
116
      _csi_boolean_var_ = 0;                      \
117
   _csi_boolean_var_;                             \
118
})
119
#define _csi_likely(expr) (__builtin_expect (_CSI_BOOLEAN_EXPR(expr), 1))
120
#define _csi_unlikely(expr) (__builtin_expect (_CSI_BOOLEAN_EXPR(expr), 0))
121
#else
122
#define _csi_likely(expr) (expr)
123
#define _csi_unlikely(expr) (expr)
124
#endif
125

            
126
#ifdef __GNUC__
127
#define csi_container_of(ptr, type, member) ({ \
128
    const typeof(((type *) 0)->member) *mptr__ = (ptr); \
129
    (type *) ((char *) mptr__ - offsetof (type, member)); \
130
})
131
#else
132
#define csi_container_of(ptr, type, member) \
133
    (type *)((char *) (ptr) - (char *) &((type *)0)->member)
134
#endif
135

            
136
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
137
#define csi_private_no_warn	__attribute__((__visibility__("hidden")))
138
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
139
#define csi_private_no_warn	__hidden
140
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
141
#define csi_private_no_warn
142
#endif
143

            
144
#undef  ARRAY_LENGTH
145
#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
146

            
147
#ifndef WARN_UNUSED_RESULT
148
#define WARN_UNUSED_RESULT
149
#endif
150
/* Add attribute(warn_unused_result) if supported */
151
#define csi_warn	    WARN_UNUSED_RESULT
152
#define csi_private	    csi_private_no_warn csi_warn
153

            
154
#define CSI_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
155
#ifdef WORDS_BIGENDIAN
156
#define CSI_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
157
#else
158
#define CSI_BITSWAP8_IF_LITTLE_ENDIAN(c) CSI_BITSWAP8(c)
159
#endif
160

            
161
typedef enum _csi_status {
162
    CSI_STATUS_SUCCESS = CAIRO_STATUS_SUCCESS,
163
    CSI_STATUS_NO_MEMORY = CAIRO_STATUS_NO_MEMORY,
164
    CSI_STATUS_INVALID_RESTORE = CAIRO_STATUS_INVALID_RESTORE,
165
    CSI_STATUS_INVALID_POP_GROUP = CAIRO_STATUS_INVALID_POP_GROUP,
166
    CSI_STATUS_NO_CURRENT_POINT = CAIRO_STATUS_NO_CURRENT_POINT,
167
    CSI_STATUS_INVALID_MATRIX = CAIRO_STATUS_INVALID_MATRIX,
168
    CSI_STATUS_INVALID_STATUS = CAIRO_STATUS_INVALID_STATUS,
169
    CSI_STATUS_NULL_POINTER = CAIRO_STATUS_NULL_POINTER,
170
    CSI_STATUS_INVALID_STRING = CAIRO_STATUS_INVALID_STRING,
171
    CSI_STATUS_INVALID_PATH_DATA = CAIRO_STATUS_INVALID_PATH_DATA,
172
    CSI_STATUS_READ_ERROR = CAIRO_STATUS_READ_ERROR,
173
    CSI_STATUS_WRITE_ERROR = CAIRO_STATUS_WRITE_ERROR,
174
    CSI_STATUS_SURFACE_FINISHED = CAIRO_STATUS_SURFACE_FINISHED,
175
    CSI_STATUS_SURFACE_TYPE_MISMATCH = CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
176
    CSI_STATUS_PATTERN_TYPE_MISMATCH = CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
177
    CSI_STATUS_INVALID_CONTENT = CAIRO_STATUS_INVALID_CONTENT,
178
    CSI_STATUS_INVALID_FORMAT = CAIRO_STATUS_INVALID_FORMAT,
179
    CSI_STATUS_INVALID_VISUAL = CAIRO_STATUS_INVALID_VISUAL,
180
    CSI_STATUS_FILE_NOT_FOUND = CAIRO_STATUS_FILE_NOT_FOUND,
181
    CSI_STATUS_INVALID_DASH = CAIRO_STATUS_INVALID_DASH,
182
    CSI_STATUS_INVALID_DSC_COMMENT = CAIRO_STATUS_INVALID_DSC_COMMENT,
183
    CSI_STATUS_INVALID_INDEX = CAIRO_STATUS_INVALID_INDEX,
184
    CSI_STATUS_CLIP_NOT_REPRESENTABLE = CAIRO_STATUS_CLIP_NOT_REPRESENTABLE,
185
    CSI_STATUS_TEMP_FILE_ERROR = CAIRO_STATUS_TEMP_FILE_ERROR,
186
    CSI_STATUS_INVALID_STRIDE = CAIRO_STATUS_INVALID_STRIDE,
187
    CSI_STATUS_FONT_TYPE_MISMATCH = CAIRO_STATUS_FONT_TYPE_MISMATCH,
188
    CSI_STATUS_USER_FONT_IMMUTABLE = CAIRO_STATUS_USER_FONT_IMMUTABLE,
189
    CSI_STATUS_USER_FONT_ERROR = CAIRO_STATUS_USER_FONT_ERROR,
190
    CSI_STATUS_NEGATIVE_COUNT = CAIRO_STATUS_NEGATIVE_COUNT,
191
    CSI_STATUS_INVALID_CLUSTERS = CAIRO_STATUS_INVALID_CLUSTERS,
192
    CSI_STATUS_INVALID_SLANT = CAIRO_STATUS_INVALID_SLANT,
193
    CSI_STATUS_INVALID_WEIGHT = CAIRO_STATUS_INVALID_WEIGHT,
194
    CSI_STATUS_INVALID_SIZE = CAIRO_STATUS_INVALID_SIZE,
195
    CSI_STATUS_USER_FONT_NOT_IMPLEMENTED = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED,
196
    CSI_STATUS_DEVICE_TYPE_MISMATCH = CAIRO_STATUS_DEVICE_TYPE_MISMATCH,
197
    CSI_STATUS_DEVICE_ERROR = CAIRO_STATUS_DEVICE_ERROR,
198
    CSI_STATUS_INVALID_MESH_CONSTRUCTION = CAIRO_STATUS_INVALID_MESH_CONSTRUCTION,
199
    CSI_STATUS_DEVICE_FINISHED = CAIRO_STATUS_DEVICE_FINISHED,
200
    CSI_STATUS_JBIG2_GLOBAL_MISSING = CAIRO_STATUS_JBIG2_GLOBAL_MISSING,
201
    CSI_STATUS_PNG_ERROR = CAIRO_STATUS_PNG_ERROR,
202
    CSI_STATUS_FREETYPE_ERROR = CAIRO_STATUS_FREETYPE_ERROR,
203
    CSI_STATUS_WIN32_GDI_ERROR = CAIRO_STATUS_WIN32_GDI_ERROR,
204

            
205
    /* cairo-script-interpreter specific errors */
206

            
207
    CSI_STATUS_INVALID_SCRIPT,
208
    CSI_STATUS_SCRIPT_INVALID_TYPE,
209
    CSI_STATUS_SCRIPT_INVALID_INDEX,
210
    CSI_STATUS_SCRIPT_UNDEFINED_NAME,
211
    CSI_STATUS_INTERPRETER_FINISHED,
212

            
213
    _CSI_STATUS_SCRIPT_LAST_ERROR,
214
    CSI_INT_STATUS_UNSUPPORTED
215
} csi_status_t;
216

            
217
typedef enum {
218
    CSI_OBJECT_TYPE_NULL = 0,
219

            
220
    /* atomics */
221
    CSI_OBJECT_TYPE_BOOLEAN,
222
    CSI_OBJECT_TYPE_INTEGER,
223
    CSI_OBJECT_TYPE_MARK,
224
    CSI_OBJECT_TYPE_NAME,
225
    CSI_OBJECT_TYPE_OPERATOR,
226
    CSI_OBJECT_TYPE_REAL,
227

            
228
    /* compound */
229
    CSI_OBJECT_TYPE_ARRAY = 0x8,
230
    CSI_OBJECT_TYPE_DICTIONARY,
231
    CSI_OBJECT_TYPE_FILE,
232
    CSI_OBJECT_TYPE_MATRIX,
233
    CSI_OBJECT_TYPE_STRING,
234

            
235
    /* cairo */
236
    CSI_OBJECT_TYPE_CONTEXT = 0x10,
237
    CSI_OBJECT_TYPE_FONT,
238
    CSI_OBJECT_TYPE_PATTERN,
239
    CSI_OBJECT_TYPE_SCALED_FONT,
240
    CSI_OBJECT_TYPE_SURFACE
241
} csi_object_type_t;
242

            
243
#define CSI_OBJECT_IS_ATOM(OBJ) (((OBJ)->type & CSI_OBJECT_TYPE_MASK) < 0x08)
244
#define CSI_OBJECT_IS_COMPOUND(OBJ) ((OBJ)->type & 0x08)
245
#define CSI_OBJECT_IS_CAIRO(OBJ) ((OBJ)->type & 0x10)
246

            
247
enum { /* attributes */
248
    CSI_OBJECT_ATTR_EXECUTABLE = 1 << 6,
249
    CSI_OBJECT_ATTR_WRITABLE   = 1 << 7
250
};
251
#define CSI_OBJECT_ATTR_MASK (CSI_OBJECT_ATTR_EXECUTABLE | \
252
			      CSI_OBJECT_ATTR_WRITABLE)
253
#define CSI_OBJECT_TYPE_MASK (~CSI_OBJECT_ATTR_MASK)
254

            
255
typedef struct _cairo_script_interpreter csi_t;
256

            
257
typedef cairo_bool_t csi_boolean_t;
258
typedef csi_status_t (*csi_operator_t) (csi_t *);
259
typedef float csi_real_t;
260
typedef long csi_integer_t;
261
typedef intptr_t csi_name_t;
262
typedef struct _csi_array csi_array_t;
263
typedef struct _csi_buffer csi_buffer_t;
264
typedef struct _csi_compound_object csi_compound_object_t;
265
typedef struct _csi_dictionary csi_dictionary_t;
266
typedef struct _csi_file csi_file_t;
267
typedef struct _csi_hash_entry csi_hash_entry_t;
268
typedef struct _csi_hash_table csi_hash_table_t;
269
typedef struct _csi_hash_table_arrangement csi_hash_table_arrangement_t;
270
typedef struct _csi_list csi_list_t;
271
typedef struct _csi_matrix csi_matrix_t;
272
typedef struct _csi_object csi_object_t;
273
typedef struct _csi_scanner csi_scanner_t;
274
typedef struct _csi_stack csi_stack_t;
275
typedef struct _csi_string csi_string_t;
276

            
277
typedef cairo_bool_t
278
(*csi_hash_predicate_func_t) (void *entry);
279

            
280
typedef void
281
(*csi_hash_callback_func_t) (void *entry,
282
			     void *closure);
283

            
284
typedef cairo_bool_t
285
(*csi_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
286

            
287
struct _csi_object {
288
    csi_object_type_t type;
289
    union {
290
	cairo_t *cr;
291
	cairo_font_face_t *font_face;
292
	cairo_pattern_t *pattern;
293
	cairo_scaled_font_t *scaled_font;
294
	cairo_surface_t *surface;
295
	csi_array_t *array;
296
	csi_boolean_t boolean;
297
	csi_compound_object_t *object;
298
	csi_dictionary_t *dictionary;
299
	csi_file_t *file;
300
	csi_integer_t integer;
301
	csi_matrix_t *matrix;
302
	csi_operator_t op;
303
	csi_name_t name;
304
	csi_real_t real;
305
	csi_string_t *string;
306
	void *ptr;
307
    } datum;
308
};
309

            
310
struct _csi_compound_object {
311
    csi_object_type_t type;
312
    unsigned int ref;
313
};
314

            
315
struct _csi_hash_entry {
316
    unsigned long hash;
317
};
318

            
319
struct _csi_hash_table_arrangement {
320
    unsigned long high_water_mark;
321
    unsigned long size;
322
    unsigned long rehash;
323
};
324

            
325
struct _csi_hash_table {
326
    csi_hash_keys_equal_func_t keys_equal;
327

            
328
    const csi_hash_table_arrangement_t *arrangement;
329
    csi_hash_entry_t **entries;
330

            
331
    unsigned long live_entries;
332
    unsigned long used_entries;
333
    unsigned long iterating;   /* Iterating, no insert, no resize */
334
};
335

            
336

            
337
/* simple, embedded doubly-linked links */
338
struct _csi_list {
339
    struct _csi_list *next, *prev;
340
};
341

            
342
struct _csi_buffer {
343
    char *base, *ptr, *end;
344
    unsigned int size;
345
};
346

            
347
struct _csi_stack {
348
    csi_object_t *objects;
349
    csi_integer_t len;
350
    csi_integer_t size;
351
};
352

            
353
struct _csi_array {
354
    csi_compound_object_t base;
355
    csi_stack_t stack;
356
};
357

            
358
typedef struct _csi_dictionary_entry {
359
    csi_hash_entry_t hash_entry;
360
    csi_object_t value;
361
} csi_dictionary_entry_t;
362

            
363
struct _csi_dictionary {
364
    csi_compound_object_t base;
365
    csi_hash_table_t hash_table;
366
};
367

            
368
struct _csi_matrix {
369
    csi_compound_object_t base;
370
    cairo_matrix_t matrix;
371
};
372

            
373
struct _csi_string {
374
    csi_compound_object_t base;
375
    csi_integer_t len;
376
    csi_integer_t deflate;
377
    enum {
378
	NONE,
379
	ZLIB,
380
	LZO,
381
    } method;
382
    char *string;
383
};
384

            
385
typedef struct _csi_filter_funcs {
386
    int (*filter_getc) (csi_file_t *);
387
    void (*filter_putc) (csi_file_t *, int);
388
    int (*filter_read) (csi_file_t *, uint8_t *, int);
389
    void (*filter_destroy) (csi_t *, void *);
390
} csi_filter_funcs_t;
391

            
392
struct _csi_file {
393
    csi_compound_object_t base;
394
    enum {
395
	STDIO,
396
	BYTES,
397
	PROCEDURE,
398
	FILTER
399
    } type;
400
    unsigned int flags;
401
    void *src;
402
    void *data;
403
    uint8_t *bp;
404
    int rem;
405
    const csi_filter_funcs_t *filter;
406
};
407

            
408
union _csi_union_object {
409
    void *ptr[2];
410
    csi_stack_t stack;
411
    csi_array_t arry;
412
    csi_dictionary_t dictionary;
413
    csi_matrix_t matrix;
414
    csi_string_t string;
415
    csi_file_t file;
416
    csi_object_t object;
417
};
418

            
419
struct _csi_scanner {
420
    jmp_buf jump_buffer;
421
    int depth;
422

            
423
    int bind;
424
    csi_status_t (*push) (csi_t *ctx, csi_object_t *obj);
425
    csi_status_t (*execute) (csi_t *ctx, csi_object_t *obj);
426
    void *closure;
427

            
428
    csi_buffer_t buffer;
429
    csi_stack_t procedure_stack;
430
    csi_object_t build_procedure;
431

            
432
    unsigned int accumulator;
433
    unsigned int accumulator_count;
434

            
435
    unsigned int line_number;
436
};
437

            
438
typedef cairo_script_interpreter_hooks_t csi_hooks_t;
439

            
440
typedef struct _csi_chunk {
441
    struct _csi_chunk *next;
442
    int rem;
443
    char *ptr;
444
} csi_chunk_t;
445

            
446
struct _cairo_script_interpreter {
447
    int ref_count;
448
    csi_status_t status;
449

            
450
    unsigned int finished : 1;
451

            
452
    csi_hooks_t hooks;
453

            
454
    csi_hash_table_t strings;
455

            
456
    csi_stack_t ostack;
457
    csi_stack_t dstack;
458

            
459
    csi_scanner_t scanner;
460

            
461
    csi_chunk_t *perm_chunk;
462
    struct {
463
	csi_chunk_t *chunk;
464
	void *free_list;
465
    } slabs[16];
466
    csi_array_t *free_array;
467
    csi_dictionary_t *free_dictionary;
468
    csi_string_t *free_string;
469

            
470
    csi_operator_t opcode[256];
471

            
472
    /* caches of live data */
473
    csi_list_t *_images;
474
    csi_list_t *_faces;
475
};
476

            
477
typedef struct _csi_operator_def {
478
    const char *name;
479
    csi_operator_t op;
480
} csi_operator_def_t;
481

            
482
typedef struct _csi_integer_constant_def {
483
    const char *name;
484
    csi_integer_t value;
485
} csi_integer_constant_def_t;
486

            
487
typedef struct _csi_real_constant_def {
488
    const char *name;
489
    csi_real_t value;
490
} csi_real_constant_def_t;
491

            
492
/* cairo-script-file.c */
493

            
494
csi_private csi_status_t
495
csi_file_new (csi_t *ctx,
496
	      csi_object_t *obj,
497
	      const char *path, const char *mode);
498

            
499
csi_private csi_status_t
500
csi_file_new_for_stream (csi_t *ctx,
501
	                 csi_object_t *obj,
502
			 FILE *stream);
503

            
504
csi_private csi_status_t
505
csi_file_new_for_bytes (csi_t *ctx,
506
			csi_object_t *obj,
507
			const char *bytes,
508
			unsigned int length);
509

            
510
csi_private csi_status_t
511
csi_file_new_from_string (csi_t *ctx,
512
			  csi_object_t *obj,
513
			  csi_string_t *src);
514

            
515
csi_private csi_status_t
516
csi_file_new_ascii85_decode (csi_t *ctx,
517
			     csi_object_t *obj,
518
			     csi_dictionary_t *dict,
519
			     csi_object_t *src);
520

            
521
csi_private csi_status_t
522
csi_file_new_deflate_decode (csi_t *ctx,
523
			     csi_object_t *obj,
524
			     csi_dictionary_t *dict,
525
			     csi_object_t *src);
526

            
527
csi_private csi_status_t
528
_csi_file_execute (csi_t *ctx, csi_file_t *obj);
529

            
530
csi_private int
531
csi_file_getc (csi_file_t *obj);
532

            
533
csi_private int
534
csi_file_read (csi_file_t *obj, void *buf, int len);
535

            
536
csi_private void
537
csi_file_putc (csi_file_t *obj, int c);
538

            
539
csi_private void
540
csi_file_flush (csi_file_t *obj);
541

            
542
csi_private void
543
csi_file_close (csi_t *ctx, csi_file_t *obj);
544

            
545
csi_private void
546
_csi_file_free (csi_t *ctx, csi_file_t *obj);
547

            
548
csi_private csi_status_t
549
_csi_file_as_string (csi_t *ctx,
550
		     csi_file_t *file,
551
		     csi_object_t *obj);
552

            
553
/* cairo-script-hash.c */
554

            
555
csi_private csi_status_t
556
_csi_hash_table_init (csi_hash_table_t *hash_table,
557
		      csi_hash_keys_equal_func_t keys_equal);
558

            
559
csi_private void
560
_csi_hash_table_fini (csi_hash_table_t *hash_table);
561

            
562
csi_private void *
563
_csi_hash_table_lookup (csi_hash_table_t  *hash_table,
564
			csi_hash_entry_t  *key);
565

            
566
csi_private csi_status_t
567
_csi_hash_table_insert (csi_hash_table_t *hash_table,
568
			csi_hash_entry_t *entry);
569

            
570
csi_private void
571
_csi_hash_table_remove (csi_hash_table_t *hash_table,
572
			csi_hash_entry_t *key);
573

            
574
csi_private void
575
_csi_hash_table_foreach (csi_hash_table_t	      *hash_table,
576
			 csi_hash_callback_func_t  hash_callback,
577
			 void			      *closure);
578

            
579
/* cairo-script-interpreter.c */
580

            
581
csi_private void *
582
_csi_alloc (csi_t *ctx, int size);
583

            
584
csi_private void *
585
_csi_alloc0 (csi_t *ctx, int size);
586

            
587
csi_private void *
588
_csi_realloc (csi_t *ctx, void *ptr, int size);
589

            
590
csi_private void
591
_csi_free (csi_t *ctx, void *ptr);
592

            
593
csi_private void *
594
_csi_slab_alloc (csi_t *ctx, int size);
595

            
596
csi_private void *
597
_csi_perm_alloc (csi_t *ctx, int size);
598

            
599
csi_private void
600
_csi_slab_free (csi_t *ctx, void *ptr, int size);
601

            
602
csi_private csi_status_t
603
csi_push_ostack (csi_t *ctx, csi_object_t *obj);
604

            
605
csi_private csi_status_t
606
_csi_name_define (csi_t *ctx, csi_name_t name, csi_object_t *obj);
607

            
608
csi_private csi_status_t
609
_csi_name_lookup (csi_t *ctx, csi_name_t name, csi_object_t *obj);
610

            
611
csi_private csi_status_t
612
_csi_name_undefine (csi_t *ctx, csi_name_t name);
613

            
614
csi_private csi_status_t
615
_csi_intern_string (csi_t *ctx, const char **str_inout, int len);
616

            
617
csi_private csi_status_t
618
_csi_error (csi_status_t status);
619

            
620
/* cairo-script-objects.c */
621

            
622
csi_private csi_status_t
623
csi_array_new (csi_t *ctx,
624
	       csi_integer_t initial_size,
625
	       csi_object_t *obj);
626

            
627
csi_private csi_status_t
628
_csi_array_execute (csi_t *ctx, csi_array_t *array);
629

            
630
csi_private csi_status_t
631
csi_array_get (csi_t *ctx,
632
	       csi_array_t *array,
633
	       long elem,
634
	       csi_object_t *value);
635

            
636
csi_private csi_status_t
637
csi_array_put (csi_t *ctx,
638
	       csi_array_t *array,
639
	       csi_integer_t elem,
640
	       csi_object_t *value);
641

            
642
csi_private csi_status_t
643
csi_array_append (csi_t *ctx,
644
		  csi_array_t *array,
645
		  csi_object_t *obj);
646

            
647
csi_private void
648
csi_array_free (csi_t *ctx, csi_array_t *array);
649

            
650
static inline void
651
csi_boolean_new (csi_object_t *obj,
652
		 csi_boolean_t v)
653
{
654
    obj->type = CSI_OBJECT_TYPE_BOOLEAN;
655
    obj->datum.boolean = v;
656
}
657

            
658
csi_private csi_status_t
659
csi_dictionary_new (csi_t *ctx,
660
		    csi_object_t *obj);
661

            
662
csi_private csi_status_t
663
csi_dictionary_put (csi_t *ctx,
664
		    csi_dictionary_t *dict,
665
		    csi_name_t name,
666
		    csi_object_t *value);
667

            
668
csi_private csi_status_t
669
csi_dictionary_get (csi_t *ctx,
670
		    csi_dictionary_t *dict,
671
		    csi_name_t name,
672
		    csi_object_t *value);
673

            
674
csi_private csi_boolean_t
675
csi_dictionary_has (csi_dictionary_t *dict,
676
		    csi_name_t name);
677

            
678
csi_private void
679
csi_dictionary_remove (csi_t *ctx,
680
		       csi_dictionary_t *dict,
681
		       csi_name_t name);
682

            
683
csi_private void
684
csi_dictionary_free (csi_t *ctx,
685
		     csi_dictionary_t *dict);
686

            
687
static inline void
688
csi_integer_new (csi_object_t *obj,
689
		 csi_integer_t v)
690
{
691
    obj->type = CSI_OBJECT_TYPE_INTEGER;
692
    obj->datum.integer = v;
693
}
694

            
695

            
696
csi_private csi_status_t
697
csi_matrix_new (csi_t *ctx,
698
		csi_object_t *obj);
699

            
700
csi_private csi_status_t
701
csi_matrix_new_from_array (csi_t *ctx,
702
			   csi_object_t *obj,
703
			   csi_array_t *array);
704

            
705
csi_private csi_status_t
706
csi_matrix_new_from_matrix (csi_t *ctx,
707
			    csi_object_t *obj,
708
			    const cairo_matrix_t *m);
709

            
710
csi_private csi_status_t
711
csi_matrix_new_from_values (csi_t *ctx,
712
			    csi_object_t *obj,
713
			    double v[6]);
714

            
715
csi_private void
716
csi_matrix_free (csi_t *ctx,
717
		 csi_matrix_t *obj);
718

            
719
csi_private csi_status_t
720
csi_name_new (csi_t *ctx,
721
	      csi_object_t *obj,
722
	      const char *str,
723
	      int len);
724

            
725
csi_private csi_status_t
726
csi_name_new_static (csi_t *ctx,
727
		     csi_object_t *obj,
728
		     const char *str);
729

            
730
static inline void
731
csi_operator_new (csi_object_t *obj,
732
		  csi_operator_t op)
733
{
734
    obj->type = CSI_OBJECT_TYPE_OPERATOR | CSI_OBJECT_ATTR_EXECUTABLE;
735
    obj->datum.op = op;
736
}
737

            
738
static inline void
739
csi_real_new (csi_object_t *obj,
740
	      csi_real_t v)
741
{
742
    obj->type = CSI_OBJECT_TYPE_REAL;
743
    obj->datum.real = v;
744
}
745

            
746
csi_private csi_status_t
747
csi_string_new (csi_t *ctx,
748
		csi_object_t *obj,
749
		const char *str,
750
		int len);
751

            
752
csi_private csi_status_t
753
csi_string_deflate_new (csi_t *ctx,
754
			csi_object_t *obj,
755
			void *bytes,
756
			int in_len,
757
			int out_len);
758

            
759
csi_private csi_status_t
760
csi_string_new_from_bytes (csi_t *ctx,
761
	                   csi_object_t *obj,
762
			   char *bytes,
763
			   unsigned int len);
764

            
765
csi_private void
766
csi_string_free (csi_t *ctx, csi_string_t *string);
767

            
768
csi_private csi_status_t
769
csi_object_execute (csi_t *ctx, csi_object_t *obj);
770

            
771
csi_private csi_object_t *
772
csi_object_reference (csi_object_t *obj);
773

            
774
csi_private void
775
csi_object_free (csi_t *ctx,
776
		 csi_object_t *obj);
777

            
778
csi_private csi_status_t
779
csi_object_as_file (csi_t *ctx,
780
		    csi_object_t *src,
781
		    csi_object_t *file);
782

            
783
csi_private csi_boolean_t
784
csi_object_eq (csi_object_t *a,
785
	       csi_object_t *b);
786

            
787
csi_private csi_status_t
788
csi_object_compare (csi_object_t *a,
789
		    csi_object_t *b,
790
		    int          *out_cmp);
791

            
792
/* cairo-script-operators.c */
793

            
794
csi_private const csi_operator_def_t *
795
_csi_operators (void);
796

            
797
csi_private const csi_integer_constant_def_t *
798
_csi_integer_constants (void);
799

            
800
csi_private const csi_real_constant_def_t *
801
_csi_real_constants (void);
802

            
803
/* cairo-script-scanner.c */
804

            
805
csi_private csi_status_t
806
_csi_scanner_init (csi_t *ctx, csi_scanner_t *scanner);
807

            
808
csi_private csi_status_t
809
_csi_scan_file (csi_t *ctx, csi_file_t *src);
810

            
811
csi_private csi_status_t
812
_csi_translate_file (csi_t *ctx,
813
	             csi_file_t *file,
814
		     cairo_write_func_t write_func,
815
		     void *closure);
816

            
817
csi_private void
818
_csi_scanner_fini (csi_t *ctx, csi_scanner_t *scanner);
819

            
820
csi_private csi_boolean_t
821
_csi_parse_number (csi_object_t *obj, const char *s, int len);
822

            
823
/* cairo-script-stack.c */
824

            
825
csi_private csi_status_t
826
_csi_stack_init (csi_t *ctx, csi_stack_t *stack, csi_integer_t size);
827

            
828
csi_private void
829
_csi_stack_fini (csi_t *ctx, csi_stack_t *stack);
830

            
831
csi_private csi_status_t
832
_csi_stack_roll (csi_t *ctx,
833
		 csi_stack_t *stack,
834
		 csi_integer_t mod,
835
		 csi_integer_t n);
836

            
837
csi_private csi_status_t
838
_csi_stack_grow (csi_t *ctx, csi_stack_t *stack, csi_integer_t cnt);
839

            
840
csi_private csi_status_t
841
_csi_stack_push_internal (csi_t *ctx, csi_stack_t *stack,
842
			  const csi_object_t *obj);
843

            
844
csi_private csi_object_t *
845
_csi_stack_peek (csi_stack_t *stack, csi_integer_t i);
846

            
847
csi_private void
848
_csi_stack_pop (csi_t *ctx, csi_stack_t *stack, csi_integer_t count);
849

            
850
csi_private csi_status_t
851
_csi_stack_exch (csi_stack_t *stack);
852

            
853
static inline csi_object_type_t
854
csi_object_get_type (const csi_object_t *obj)
855
{
856
    return obj->type & CSI_OBJECT_TYPE_MASK;
857
}
858

            
859
static inline csi_boolean_t
860
csi_object_is_procedure (const csi_object_t *obj)
861
{
862
    return obj->type == (CSI_OBJECT_TYPE_ARRAY | CSI_OBJECT_ATTR_EXECUTABLE);
863
}
864

            
865
static inline csi_boolean_t
866
csi_object_is_number (const csi_object_t *obj)
867
{
868
    int type = csi_object_get_type (obj);
869
    switch (type) {
870
    case CSI_OBJECT_TYPE_BOOLEAN:
871
    case CSI_OBJECT_TYPE_INTEGER:
872
    case CSI_OBJECT_TYPE_REAL:
873
	return 1;
874
    default:
875
	return 0;
876
    }
877
}
878

            
879
static inline double
880
csi_number_get_value (const csi_object_t *obj)
881
{
882
    int type = csi_object_get_type (obj);
883
    switch (type) {
884
    case CSI_OBJECT_TYPE_BOOLEAN: return obj->datum.boolean;
885
    case CSI_OBJECT_TYPE_INTEGER: return obj->datum.integer;
886
    case CSI_OBJECT_TYPE_REAL: return obj->datum.real;
887
    default: return 0.;
888
    }
889
}
890

            
891
csi_private csi_status_t
892
_csi_stack_push (csi_t *ctx, csi_stack_t *stack,
893
		 const csi_object_t *obj);
894

            
895
static inline csi_boolean_t
896
_csi_check_ostack (csi_t *ctx, csi_integer_t count)
897
{
898
    return ctx->ostack.len >= count;
899
}
900

            
901
static inline csi_object_t *
902
_csi_peek_ostack (csi_t *ctx, csi_integer_t i)
903
{
904
    return &ctx->ostack.objects[ctx->ostack.len - i -1];
905
}
906

            
907
static inline void
908
_csi_pop_ostack (csi_t *ctx, csi_integer_t count)
909
{
910
    do
911
	csi_object_free (ctx, &ctx->ostack.objects[--ctx->ostack.len]);
912
    while (--count);
913
}
914

            
915
static inline csi_status_t
916
_csi_push_ostack_copy (csi_t *ctx, csi_object_t *obj)
917
{
918
    return _csi_stack_push (ctx, &ctx->ostack, csi_object_reference (obj));
919
}
920

            
921
static inline csi_status_t
922
_csi_push_ostack (csi_t *ctx, csi_object_t *obj)
923
{
924
    return _csi_stack_push (ctx, &ctx->ostack, obj);
925
}
926

            
927
static inline csi_status_t
928
_csi_push_ostack_boolean (csi_t *ctx, csi_boolean_t v)
929
{
930
    csi_object_t obj;
931
    obj.type = CSI_OBJECT_TYPE_BOOLEAN;
932
    obj.datum.boolean = v;
933
    return _csi_stack_push (ctx, &ctx->ostack, &obj);
934
}
935
static inline csi_status_t
936
_csi_push_ostack_integer (csi_t *ctx, csi_integer_t v)
937
{
938
    csi_object_t obj;
939
    obj.type = CSI_OBJECT_TYPE_INTEGER;
940
    obj.datum.integer = v;
941
    return _csi_stack_push (ctx, &ctx->ostack, &obj);
942
}
943
static inline csi_status_t
944
_csi_push_ostack_mark (csi_t *ctx)
945
{
946
    csi_object_t obj;
947
    obj.type = CSI_OBJECT_TYPE_MARK;
948
    return _csi_stack_push (ctx, &ctx->ostack, &obj);
949
}
950
static inline csi_status_t
951
_csi_push_ostack_null (csi_t *ctx)
952
{
953
    csi_object_t obj;
954
    obj.type = CSI_OBJECT_TYPE_NULL;
955
    return _csi_stack_push (ctx, &ctx->ostack, &obj);
956
}
957
static inline csi_status_t
958
_csi_push_ostack_real (csi_t *ctx, csi_real_t v)
959
{
960
    csi_object_t obj;
961
    obj.type = CSI_OBJECT_TYPE_REAL;
962
    obj.datum.real = v;
963
    return _csi_stack_push (ctx, &ctx->ostack, &obj);
964
}
965

            
966
#endif /* CAIRO_SCRIPT_PRIVATE_H */