1
/* $Header: /home/cvsroot/dvipdfmx/src/pdfresource.c,v 1.9 2008/11/30 21:12:27 matthias Exp $
3
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5
Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
6
the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
8
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
* Currently, this is nearly useless.
41
#include "pdfresource.h"
43
#define PDF_RESOURCE_DEBUG_STR "PDF"
44
#define PDF_RESOURCE_DEBUG 3
46
#define PDF_RESOURCE_FONT 0
47
#define PDF_RESOURCE_CIDFONT 1
48
#define PDF_RESOURCE_ENCODING 2
49
#define PDF_RESOURCE_CMAP 3
50
#define PDF_RESOURCE_XOBJECT 4
51
#define PDF_RESOURCE_COLORSPACE 5
52
#define PDF_RESOURCE_SHADING 6
53
#define PDF_RESOURCE_PATTERN 7
54
#define PDF_RESOURCE_GSTATE 8
56
typedef struct pdf_res
72
} pdf_resource_categories[] = {
73
{"Font", PDF_RESOURCE_FONT},
74
{"CIDFont", PDF_RESOURCE_CIDFONT},
75
{"Encoding", PDF_RESOURCE_ENCODING},
76
{"CMap", PDF_RESOURCE_CMAP},
77
{"XObject", PDF_RESOURCE_XOBJECT},
78
{"ColorSpace", PDF_RESOURCE_COLORSPACE},
79
{"Shading", PDF_RESOURCE_SHADING},
80
{"Pattern", PDF_RESOURCE_PATTERN},
81
{"ExtGState", PDF_RESOURCE_GSTATE},
84
#define PDF_NUM_RESOURCE_CATEGORIES (sizeof(pdf_resource_categories)/sizeof(pdf_resource_categories[0]))
86
#define CACHE_ALLOC_SIZE 16u
94
static struct res_cache resources[PDF_NUM_RESOURCE_CATEGORIES];
97
pdf_init_resource (pdf_res *res)
106
res->reference = NULL;
112
pdf_flush_resource (pdf_res *res)
116
pdf_release_obj(res->reference);
118
pdf_release_obj(res->object);
120
res->reference = NULL;
126
pdf_clean_resource (pdf_res *res)
129
if (res->reference || res->object)
130
WARN("Trying to release un-flushed object.");
132
pdf_release_obj(res->reference);
134
pdf_release_obj(res->object);
144
pdf_init_resources (void)
149
i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
150
resources[i].count = 0;
151
resources[i].capacity = 0;
152
resources[i].resources = NULL;
157
pdf_close_resources (void)
162
i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
163
struct res_cache *rc;
167
for (j = 0; j < rc->count; j++) {
168
pdf_flush_resource(&rc->resources[j]);
169
pdf_clean_resource(&rc->resources[j]);
171
RELEASE(rc->resources);
175
rc->resources = NULL;
180
get_category (const char *category)
185
i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
186
if (!strcmp(category, pdf_resource_categories[i].name)) {
187
return pdf_resource_categories[i].cat_id;
195
pdf_defineresource (const char *category,
196
const char *resname, pdf_obj *object, int flags)
199
struct res_cache *rc;
203
ASSERT(category && object);
205
cat_id = get_category(category);
207
ERROR("Unknown resource category: %s", category);
211
rc = &resources[cat_id];
213
for (res_id = 0; res_id < rc->count; res_id++) {
214
res = &rc->resources[res_id];
215
if (!strcmp(resname, res->ident)) {
216
WARN("Resource %s (category: %s) already defined...",
218
pdf_flush_resource(res);
220
if (flags & PDF_RES_FLUSH_IMMEDIATE) {
221
res->reference = pdf_ref_obj(object);
222
pdf_release_obj(object);
224
res->object = object;
226
return (long) ((cat_id << 16)|(res_id));
233
if (res_id == rc->count) {
234
if (rc->count >= rc->capacity) {
235
rc->capacity += CACHE_ALLOC_SIZE;
236
rc->resources = RENEW(rc->resources, rc->capacity, pdf_res);
238
res = &rc->resources[res_id];
240
pdf_init_resource(res);
241
if (resname && resname[0] != '\0') {
242
res->ident = NEW(strlen(resname) + 1, char);
243
strcpy(res->ident, resname);
245
res->category = cat_id;
247
if (flags & PDF_RES_FLUSH_IMMEDIATE) {
248
res->reference = pdf_ref_obj(object);
249
pdf_release_obj(object);
251
res->object = object;
256
return (long) ((cat_id << 16)|(res_id));
261
pdf_resource_exist (const char *category, const char *resname)
264
struct res_cache *rc;
267
ASSERT(resname && category);
269
cat_id = get_category(category);
271
ERROR("Unknown resource category: %s", category);
273
rc = &resources[cat_id];
274
for (res_id = 0; res_id < rc->count; res_id++) {
277
res = &rc->resources[res_id];
278
if (!strcmp(resname, res->ident)) {
288
pdf_findresource (const char *category, const char *resname)
292
struct res_cache *rc;
294
ASSERT(resname && category);
296
cat_id = get_category(category);
298
ERROR("Unknown resource category: %s", category);
302
rc = &resources[cat_id];
303
for (res_id = 0; res_id < rc->count; res_id++) {
304
res = &rc->resources[res_id];
305
if (!strcmp(resname, res->ident)) {
306
return (long) (cat_id << 16|res_id);
314
pdf_get_resource_reference (long rc_id)
317
struct res_cache *rc;
320
cat_id = (rc_id >> 16) & 0xffff;
321
res_id = rc_id & 0xffff;
324
cat_id >= PDF_NUM_RESOURCE_CATEGORIES) {
325
ERROR("Invalid category ID: %d", cat_id);
328
rc = &resources[cat_id];
329
if (res_id < 0 || res_id >= rc->count) {
330
ERROR("Invalid resource ID: %d", res_id);
334
res = &rc->resources[res_id];
335
if (!res->reference) {
337
ERROR("Undefined object...");
340
res->reference = pdf_ref_obj(res->object);
344
return pdf_link_obj(res->reference);
349
pdf_get_resource (long rc_id)
352
struct res_cache *rc;
355
cat_id = (rc_id >> 16) & 0xffff;
356
res_id = rc_id & 0xffff;
359
cat_id >= PDF_NUM_RESOURCE_CATEGORIES) {
360
ERROR("Invalid category ID: %d", cat_id);
363
rc = &resources[cat_id];
364
if (res_id < 0 || res_id >= rc->count) {
365
ERROR("Invalid resource ID: %d", res_id);
369
res = &rc->resources[res_id];
371
ERROR("Object already flushed???");