3
Copyright (c) 2006-2007, BBR Inc. All rights reserved.
5
Permission is hereby granted, free of charge, to any person obtaining
6
a copy of this software and associated documentation files (the
7
"Software"), to deal in the Software without restriction, including
8
without limitation the rights to use, copy, modify, merge, publish,
9
distribute, sublicense, and/or sell copies of the Software, and to
10
permit persons to whom the Software is furnished to do so, subject to
11
the following conditions:
13
The above copyright notice and this permission notice shall be included
14
in all copies or substantial portions of the Software.
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
pdftopdf resources dictionary
33
#include "P2PResources.h"
37
P2PResourceMap::P2PResourceMap()
41
for (i = 0;i < P2PResources::NDict;i++) {
46
P2PResourceMap::~P2PResourceMap()
50
for (i = 0;i < P2PResources::NDict;i++) {
57
const char *P2PResources::dictNames[NDict] = {
66
P2PResources::P2PResources(XRef *xrefA)
71
for (i = 0;i < NDict;i++) {
82
P2PResources::~P2PResources()
86
for (i = 0;i < NDict;i++) {
87
if (dictionaries[i] != 0) {
88
delete dictionaries[i];
91
if (patternDict != 0) delete[] patternDict;
93
for (i = 0;i < nOldForms;i++) {
94
if (oldForms[i] != 0) delete oldForms[i];
98
/* fontResource is deleted in other Class,
102
void P2PResources::output(P2POutputStream *str)
107
for (i = 0;i < NDict;i++) {
108
if (i == Font && fontResource != 0 && fontResource->getNDicts() > 0) {
109
str->printf(" /%s ",dictNames[i]);
110
fontResource->output(str,xref);
112
} else if (i == Pattern) {
116
str->printf(" /%s << ",dictNames[i]);
117
for (j = 0;j < nPattern;j++) {
118
if (patternDict[j].pattern != 0) {
119
/* output body later */
120
P2PXRef::put(patternDict[j].pattern);
121
/* output refrence here */
122
P2POutput::outputName(patternDict[j].name,str);
124
patternDict[j].pattern->outputRef(str);
130
} else if (i == XObject && nOldForms > 0 && dictionaries[i] != 0) {
133
/* There is any old form in XObject dictionary */
134
Dict *xobjDict = dictionaries[i];
135
int n = xobjDict->getLength();
136
str->printf(" /%s << ",dictNames[i]);
137
for (j = 0;j < n;j++) {
138
char *key = xobjDict->getKey(j);
140
P2POutput::outputName(key,str);
142
if (j < nOldForms && oldForms[j] != 0) {
143
P2PXRef::put(oldForms[j]);
144
oldForms[j]->outputRef(str);
148
xobjDict->getValNF(j,&obj);
149
P2POutput::outputObject(&obj,str,xref);
156
if (dictionaries[i] != 0) {
157
str->printf(" /%s ",dictNames[i]);
158
P2POutput::outputDict(dictionaries[i],str,xref);
164
/* Notice: constant values */
165
str->puts(" /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ");
167
/* Notice: no Properties */
172
void P2PResources::handleOldForm(P2PResourceMap *map)
177
/* find Forms without Resources and replace them */
178
Dict *xobjDict = dictionaries[XObject];
179
if (xobjDict == 0) return;
180
n = xobjDict->getLength();
181
for (i = 0;i < n;i++) {
187
xobjDict->getVal(i,&xobj);
188
if (!xobj.isStream()) {
192
strDict = xobj.streamGetDict();
193
strDict->lookupNF("Subtype",&obj);
194
if (!obj.isName() || strcmp("Form",obj.getName()) != 0) {
200
strDict->lookupNF("Resources",&obj);
206
if (nOldForms <= i || oldForms[i] == 0) {
207
/* found a Form without Resource,
208
replace it with a refrence to a P2PForm */
209
form = new P2PForm(&xobj,this,map);
212
P2PObject **oldp = oldForms;
213
oldForms = new P2PObject *[n];
214
memset(oldForms,0,n*sizeof(P2PForm *));
216
memcpy(oldForms,oldp,nOldForms*sizeof(P2PForm *));
225
P2PResourceMap *P2PResources::merge(Dict *res)
227
P2PResourceMap *map = 0;
231
if (res == 0) return 0;
232
for (i = 0;i < NDict;i++) {
233
if (res->lookup(const_cast<char *>(dictNames[i]),&obj) != 0
236
map = new P2PResourceMap();
238
if (dictionaries[i] == 0) {
239
dictionaries[i] = new Dict(xref);
241
if (map->tables[i] == 0) {
242
map->tables[i] = new Dict((XRef *)0);
244
mergeOneDict(dictionaries[i],obj.getDict(),map->tables[i],i != Pattern);
252
P2PResourceMap *P2PResources::merge(P2PResources *res)
254
P2PResourceMap *map = 0;
257
for (i = 0;i < NDict;i++) {
258
if (res->dictionaries[i] != 0) {
260
map = new P2PResourceMap();
262
if (dictionaries[i] == 0) {
263
dictionaries[i] = new Dict(xref);
265
if (map->tables[i] == 0) {
266
map->tables[i] = new Dict((XRef *)0);
268
mergeOneDict(dictionaries[i],res->dictionaries[i],map->tables[i],
276
void P2PResources::mergeOneDict(Dict *dst, Dict *src, Dict *map, GBool unify)
279
int srcn = src->getLength();
282
for (i = 0;i < srcn;i++) {
284
GBool found = gFalse;
285
#ifdef HAVE_UGOOSTRING_H
291
src->getValNF(i,&srcobj);
292
srckey = src->getKey(i);
293
if (srcobj.isRef() && unify) {
294
dstn = dst->getLength();
295
for (j = 0;j < dstn;j++) {
298
dst->getValNF(j,&dstobj);
299
if (dstobj.isRef() && srcobj.getRefNum() == dstobj.getRefNum()
300
&& srcobj.getRefGen() == dstobj.getRefGen()) {
302
#ifdef HAVE_UGOOSTRING_H
303
addMap(srckey,dst->getKey(j)->getCString(),map);
305
addMap(srckey,dst->getKey(j),map);
314
addDict(dst,&srcobj,srckey,map);
321
#ifdef HAVE_UGOOSTRING_H
322
void P2PResources::addDict(Dict *dict, Object *obj,
323
UGooString *srckey, Dict *map)
328
snprintf(name,20,"R%d",resourceNo++);
329
dict->addOwnVal(name,obj);
330
addMap(srckey,name,map);
333
void P2PResources::addDict(Dict *dict, Object *obj,
334
char *srckey, Dict *map)
339
snprintf(name,20,"R%d",resourceNo++);
340
dict->add(strdup(name),obj);
341
addMap(srckey,name,map);
345
#ifdef HAVE_UGOOSTRING_H
346
void P2PResources::addMap(UGooString *org, char *mapped, Dict *map)
350
obj.initName(mapped);
354
void P2PResources::addMap(char *org, char *mapped, Dict *map)
358
obj.initName(mapped);
359
map->add(strdup(org),&obj);
363
void P2PResources::setupPattern()
367
if (patternDict != NULL) {
370
if (dictionaries[Pattern] == 0) return;
371
nPattern = dictionaries[Pattern]->getLength();
372
patternDict = new P2PPatternDict[nPattern];
374
for (i = 0;i < nPattern;i++) {
375
#ifdef HAVE_UGOOSTRING_H
376
char *p = dictionaries[Pattern]->getKey(i)->getCString();
378
char *p = strdup(dictionaries[Pattern]->getKey(i));
380
patternDict[i].name = p;
384
void P2PResources::refPattern(char *name, P2PMatrix *matA)
388
if (dictionaries[Pattern] == 0) return; /* no pattern */
389
for (i = 0;i < nPattern;i++) {
390
if (strcmp(name,patternDict[i].name) == 0) {
391
if (patternDict[i].pattern == 0) {
394
dictionaries[Pattern]->lookupNF(name,&patObj);
395
if (patObj.isRef() || patObj.isDict()) {
396
patternDict[i].pattern = new P2PPattern(&patObj,xref,matA);