3 This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5 Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6 the dvipdfmx project team.
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???");