OLD | NEW |
| 1 |
| 2 |
1 import sys | 3 import sys |
2 | 4 |
3 class PdfName: | 5 import datatypes |
4 def __init__(self, name, abr=''): | 6 import pdfspec_autogen |
5 self.fName = name | |
6 self.fAbr = abr | |
7 | |
8 def toCpp(self): | |
9 return '\"' + self.fName + '\"' | |
10 | 7 |
11 class PdfString: | |
12 def __init__(self, value): | |
13 self.fValue = value | |
14 | |
15 def toCpp(self): | |
16 return '\"' + self.fValue + '\"' | |
17 | 8 |
18 class PdfInteger: | |
19 def __init__(self, value): | |
20 self.fValue = value | |
21 | |
22 def toCpp(self): | |
23 return str(self.fValue) | |
24 | |
25 class PdfReal: | |
26 def __init__(self, value): | |
27 self.fValue = value | |
28 | |
29 def toCpp(self): | |
30 return str(self.fValue) | |
31 | |
32 class PdfString: | |
33 def __init__(self, value): | |
34 self.fValue = value | |
35 | |
36 def toCpp(self): | |
37 return self.fValue | |
38 | |
39 class PdfBoolean: | |
40 def __init__(self, value): | |
41 self.fValue = value | |
42 | |
43 def toCpp(self): | |
44 return self.fValue | |
45 | |
46 class CppNull: | |
47 def toCpp(self): | |
48 return 'NULL' | |
49 | 9 |
50 | 10 |
51 class PdfField: | 11 class PdfField: |
52 def __init__(self, parent, name, abr): | 12 def __init__(self, parent, name, abr): |
53 self.fParent = parent | 13 self.fParent = parent |
54 self.fName = name | 14 self.fName = name |
55 self.fAbr = abr | 15 self.fAbr = abr |
56 | 16 |
57 self.fDefault = '' | 17 self.fDefault = '' |
58 self.fType = '' | 18 self.fType = '' |
(...skipping 20 matching lines...) Expand all Loading... |
79 self.fCppReader = 'DoubleFromDictionary' | 39 self.fCppReader = 'DoubleFromDictionary' |
80 return self | 40 return self |
81 | 41 |
82 def integer(self, name): | 42 def integer(self, name): |
83 self.fType = 'integer' | 43 self.fType = 'integer' |
84 self.fCppName = name | 44 self.fCppName = name |
85 self.fCppType = 'long' | 45 self.fCppType = 'long' |
86 self.fCppReader = 'LongFromDictionary' | 46 self.fCppReader = 'LongFromDictionary' |
87 return self | 47 return self |
88 | 48 |
89 def real(self, name): | |
90 self.fType = 'real' | |
91 self.fCppName = name | |
92 self.fCppType = 'double' | |
93 self.fCppReader = 'DoubleFromDictionary' | |
94 return self | |
95 | |
96 def name(self, name): | 49 def name(self, name): |
97 self.fType = 'name' | 50 self.fType = 'name' |
98 self.fCppName = name | 51 self.fCppName = name |
99 self.fCppType = 'std::string' | 52 self.fCppType = 'std::string' |
100 self.fCppReader = 'NameFromDictionary' | 53 self.fCppReader = 'NameFromDictionary' |
101 return self | 54 return self |
102 | 55 |
103 def string(self, name): | 56 def string(self, name): |
104 self.fType = 'string' | 57 self.fType = 'string' |
105 self.fCppName = name | 58 self.fCppName = name |
106 self.fCppType = 'std::string' | 59 self.fCppType = 'std::string' |
107 self.fCppReader = 'StringFromDictionary' | 60 self.fCppReader = 'StringFromDictionary' |
108 return self | 61 return self |
109 | 62 |
110 def multiple(self, validOptions): | 63 def multiple(self, validOptions): |
111 self.fValidOptions = validOptions | 64 self.fValidOptions = validOptions |
112 return self | 65 return self |
113 | 66 |
114 def dictionary(self, name): | 67 def dictionary(self, name): |
115 self.fType = 'dictionary' | 68 self.fType = 'dictionary' |
116 self.fCppName = name | 69 self.fCppName = name |
117 self.fDictionaryType = 'Resources' # TODO(edisonn): Dictionary? | 70 self.fDictionaryType = 'Dictionary' |
| 71 self.fCppType = 'SkPdfDictionary*' |
118 self.fCppReader = 'DictionaryFromDictionary' | 72 self.fCppReader = 'DictionaryFromDictionary' |
119 self.fDefault = CppNull() | 73 self.fDefault = datatypes.CppNull() |
120 return self | 74 return self |
121 | 75 |
122 def type(self, type): | 76 def type(self, type): |
123 # TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, an
d set a mask for valid types, like array or name | 77 # TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, an
d set a mask for valid types, like array or name |
124 self.fType = 'dictionary' | 78 type = type.replace('or', ' ') |
125 self.fDictionaryType = 'Dictionary' | 79 type = type.replace(',', ' ') |
126 self.fCppReader = 'DictionaryFromDictionary' | 80 type = type.replace('text', ' ') # TODO(edisonn): what is the difference bet
ween 'text string' and 'string'? |
127 self.fDefault = CppNull() | 81 |
| 82 type = type.strip() |
| 83 types = type.split() |
| 84 |
| 85 if len(types) == 1: |
| 86 if type == 'integer': |
| 87 self.integer(self.fCppName) |
| 88 self.default(datatypes.PdfInteger(0)) |
| 89 return self |
| 90 |
| 91 if type == 'number': |
| 92 self.number(self.fCppName) |
| 93 self.default(datatypes.PdfNumber(0)) |
| 94 return self |
| 95 |
| 96 if type == 'string': |
| 97 self.string(self.fCppName) |
| 98 self.default(datatypes.PdfString('""')) |
| 99 return self |
| 100 |
| 101 if type == 'name': |
| 102 self.name(self.fCppName) |
| 103 self.default(datatypes.PdfName('""')) |
| 104 return self |
| 105 |
| 106 if type == 'dictionary': |
| 107 self.dictionary(self.fCppName) |
| 108 self.default(datatypes.CppNull()) |
| 109 return self |
| 110 |
| 111 self.fType = 'object' |
| 112 self.fDictionaryType = 'Object' |
| 113 self.fCppType = 'SkPdfObject*' |
| 114 self.fCppReader = 'ObjectFromDictionary' |
| 115 self.fDefault = datatypes.CppNull() |
128 return self | 116 return self |
129 | 117 |
130 def comment(self, comment): | 118 def comment(self, comment): |
131 return self | 119 return self |
132 | 120 |
133 def done(self): | 121 def done(self): |
134 return self.fParent | 122 return self.fParent |
135 | 123 |
136 | 124 |
137 class PdfClassField: | 125 class PdfClassField: |
(...skipping 19 matching lines...) Expand all Loading... |
157 self.fCCPublic = [] | 145 self.fCCPublic = [] |
158 self.fCCPrivate = [] | 146 self.fCCPrivate = [] |
159 self.fName = name | 147 self.fName = name |
160 self.fBase = base | 148 self.fBase = base |
161 self.fComment = comment | 149 self.fComment = comment |
162 | 150 |
163 self.fEnumSubclasses = [] | 151 self.fEnumSubclasses = [] |
164 | 152 |
165 self.fEnum = '!UNDEFINED' | 153 self.fEnum = '!UNDEFINED' |
166 self.fEnumEnd = '!UNDEFINED' | 154 self.fEnumEnd = '!UNDEFINED' |
| 155 self.fCheck = '' |
167 | 156 |
| 157 def check(self, ifCheck): |
| 158 self.fCheck = ifCheck |
| 159 return self |
| 160 |
168 def required(self, badDefault): | 161 def required(self, badDefault): |
169 field = PdfClassField(self, True) | 162 field = PdfClassField(self, True) |
170 field.fBadDefault = badDefault | 163 field.fBadDefault = badDefault |
171 self.fFields.append(field) | 164 self.fFields.append(field) |
172 return field | 165 return field |
173 | 166 |
174 def optional(self): | 167 def optional(self): |
175 field = PdfClassField(self, False) | 168 field = PdfClassField(self, False) |
176 self.fFields.append(field) | 169 self.fFields.append(field) |
177 return field | 170 return field |
(...skipping 29 matching lines...) Expand all Loading... |
207 def addClass(self, name, base='Object', comment=''): | 200 def addClass(self, name, base='Object', comment=''): |
208 if name == 'Object': | 201 if name == 'Object': |
209 cls = PdfClass(name, '', comment) | 202 cls = PdfClass(name, '', comment) |
210 else: | 203 else: |
211 cls = PdfClass(name, base, comment) | 204 cls = PdfClass(name, base, comment) |
212 self.fClasses[name] = cls | 205 self.fClasses[name] = cls |
213 self.fClassesNamesInOrder.append(name) | 206 self.fClassesNamesInOrder.append(name) |
214 return cls | 207 return cls |
215 | 208 |
216 def longName(self, name): | 209 def longName(self, name): |
| 210 #return name |
| 211 # TODO(edisonn): we need the long name to nenerate and sort enums, but we ca
n generate them recursively |
217 ret = '' | 212 ret = '' |
218 while name != '': | 213 while name != '': |
219 cls = self.fClasses[name] | 214 cls = self.fClasses[name] |
220 ret = name + ret | 215 ret = name + ret |
221 name = cls.fBase | 216 name = cls.fBase |
222 | 217 |
223 return ret | 218 return ret |
224 | 219 |
225 | 220 |
226 def writeEnum(self, enum, enumToCls): | 221 def writeEnum(self, enum, enumToCls): |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 350 |
356 #check required fieds, also, there should be an internal_valid() manually
wrote for complex | 351 #check required fieds, also, there should be an internal_valid() manually
wrote for complex |
357 # situations | 352 # situations |
358 # right now valid return true | 353 # right now valid return true |
359 print(' virtual bool valid() const {return true;}') | 354 print(' virtual bool valid() const {return true;}') |
360 print | 355 print |
361 | 356 |
362 for field in cls.fFields: | 357 for field in cls.fFields: |
363 prop = field.fProp | 358 prop = field.fProp |
364 if prop.fCppName != '': | 359 if prop.fCppName != '': |
365 if prop.fType != 'dictionary': | 360 if prop.fCppName[0] == '[': |
366 print(' ' + prop.fCppType + ' ' + prop.fCppName + '() const {') | 361 print('/*') # comment code of the atributes that can have any name |
367 print(' ' + prop.fCppType + ' ret;') | 362 |
368 print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDi
ctionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;') | 363 print(' ' + prop.fCppType + ' ' + prop.fCppName + '() const {') |
369 if field.fRequired == False: | 364 print(' ' + prop.fCppType + ' ret;') |
370 print(' return ' + prop.fDefault.toCpp() + ';'); | 365 print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDict
ionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;') |
371 if field.fRequired == True: | 366 if field.fRequired == False: |
372 print(' // TODO(edisonn): warn about missing required field, as
sert for known good pdfs') | 367 print(' return ' + prop.fDefault.toCpp() + ';'); |
373 print(' return ' + field.fBadDefault + ';'); | 368 if field.fRequired == True: |
374 print(' }') | 369 print(' // TODO(edisonn): warn about missing required field, asse
rt for known good pdfs') |
375 print | 370 print(' return ' + field.fBadDefault + ';'); |
376 | 371 print(' }') |
377 if prop.fType == 'dictionary': | 372 print |
378 print(' SkPdf' + prop.fDictionaryType + '* ' + prop.fCppName + '()
const {') | |
379 print(' SkPdfObject* dict = NULL;') | |
380 print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDi
ctionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &dict) && dict != NUL
L) {') | |
381 print(' SkPdf' + prop.fDictionaryType + '* ret = new SkPdf' + p
rop.fDictionaryType + '(fPodofoDoc, dict->podofo());') | |
382 print(' delete dict; dict = NULL;') | |
383 print(' return ret;') | |
384 print(' }') | |
385 if field.fRequired == False: | |
386 print(' return ' + prop.fDefault.toCpp() + ';'); | |
387 if field.fRequired == True: | |
388 print(' // TODO(edisonn): warn about missing required field, as
sert for known good pdfs') | |
389 print(' return ' + field.fBadDefault + ';'); | |
390 print(' }') | |
391 print | |
392 | 373 |
| 374 if prop.fCppName[0] == '[': |
| 375 print('*/') # comment code of the atributes that can have any name |
393 | 376 |
394 | 377 |
395 print('};') | 378 print('};') |
396 print | 379 print |
397 print | 380 print |
398 | 381 |
399 | 382 |
400 | 383 |
401 # generate constructor when knowing the type | 384 # generate constructor when knowing the type |
402 # later, p2, generate constructor when not knowing the type - very similar
with parsing? | 385 # later, p2, generate constructor when not knowing the type - very similar
with parsing? |
(...skipping 18 matching lines...) Expand all Loading... |
421 print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);') | 404 print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);') |
422 print(' return true;') | 405 print(' return true;') |
423 print(' }') | 406 print(' }') |
424 print | 407 print |
425 | 408 |
426 for name in self.fClassesNamesInOrder: | 409 for name in self.fClassesNamesInOrder: |
427 cls = self.fClasses[name] | 410 cls = self.fClasses[name] |
428 | 411 |
429 print(' static bool isA' + name + '(const PdfMemDocument& podofoDoc, cons
t PdfObject& podofoObj) {') | 412 print(' static bool isA' + name + '(const PdfMemDocument& podofoDoc, cons
t PdfObject& podofoObj) {') |
430 | 413 |
431 cntMust = 0 | 414 if cls.fCheck != '': |
432 for field in cls.fFields: | 415 print(' return ' + cls.fCheck + ';') |
433 prop = field.fProp | 416 else: |
434 if prop.fHasMust: | 417 cntMust = 0 |
435 cntMust = cntMust + 1 | 418 for field in cls.fFields: |
436 print(' ' + prop.fCppType + ' ' + prop.fCppName + ';') | 419 prop = field.fProp |
437 print(' if (!' + prop.fCppReader + '(&podofoDoc, podofoObj.GetDicti
onary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' + prop.fCppName + '))
return false;') | 420 if prop.fHasMust: |
438 print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + ')
return false;') | 421 cntMust = cntMust + 1 |
439 print | 422 print(' ' + prop.fCppType + ' ' + prop.fCppName + ';') |
| 423 print(' if (!' + prop.fCppReader + '(&podofoDoc, podofoObj.GetDic
tionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' + prop.fCppName + '
)) return false;') |
| 424 print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + '
) return false;') |
| 425 print |
440 | 426 |
441 # hack, we only care about dictionaries now, so ret tru only if there is a
match | 427 # hack, we only care about dictionaries now, so ret tru only if there is
a match |
442 if cntMust != 0 or name == 'Object' or name == 'Dictionary': | 428 if cntMust != 0 or len(cls.fEnumSubclasses) > 0: |
443 print(' return true;') | 429 print(' return true;') |
444 else: | 430 else: |
445 print(' return false;') | 431 print(' return false;') |
446 | 432 |
447 print(' }') | 433 print(' }') |
448 print | 434 print |
449 | 435 |
450 print('};') | 436 print('};') |
451 print | 437 print |
452 | 438 |
453 return | 439 return |
454 | 440 |
455 def generateCode(): | 441 def generateCode(): |
456 all = PdfClassManager() | 442 manager = PdfClassManager() |
457 | 443 |
458 all.addClass('Object') | 444 manager.addClass('Object') |
459 all.addClass('Null') | 445 |
460 all.addClass('Boolean') | 446 manager.addClass('Null').check('podofoObj.GetDataType() == ePdfDataType_Null') |
461 all.addClass('Integer') | 447 manager.addClass('Boolean').check('podofoObj.GetDataType() == ePdfDataType_Boo
l') |
462 all.addClass('Real') | 448 manager.addClass('Integer').check('podofoObj.GetDataType() == ePdfDataType_Num
ber') |
463 all.addClass('Name') | 449 manager.addClass('Number').check('podofoObj.GetDataType() == ePdfDataType_Real
') |
464 all.addClass('Stream') | 450 manager.addClass('Name').check('podofoObj.GetDataType() == ePdfDataType_Name') |
465 all.addClass('Reference') | 451 #manager.addClass('Stream') - attached to a dictionary |
466 all.addClass('Array') | 452 manager.addClass('Reference').check('podofoObj.GetDataType() == ePdfDataType_R
eference') |
467 all.addClass('Dictionary').optional().field('Resources', '').dictionary("r") #
.inherited_from_page_tree() | 453 manager.addClass('Array').check('podofoObj.GetDataType() == ePdfDataType_Array
') |
| 454 manager.addClass('String').check('podofoObj.GetDataType() == ePdfDataType_Stri
ng') |
| 455 manager.addClass('HexString').check('podofoObj.GetDataType() == ePdfDataType_H
exString') |
| 456 |
| 457 manager.addClass('Dictionary').check('podofoObj.GetDataType() == ePdfDataType_
Dictionary') |
| 458 |
| 459 # these classes are not explicitely backed by a table in the pdf spec |
| 460 manager.addClass('XObjectDictionary', 'Dictionary') |
| 461 |
| 462 manager.addClass('FontDictionary', 'Dictionary') |
| 463 |
| 464 manager.addClass('TrueTypeFontDictionary', 'FontDictionary') |
| 465 |
| 466 pdfspec_autogen.buildPdfSpec(manager) |
468 | 467 |
469 all.addClass('Resources', 'Dictionary') | 468 manager.addClass('MultiMasterFontDictionary', 'Type1FontDictionary')\ |
470 | 469 .required('NULL')\ |
471 all.addClass('XObject', 'Dictionary').required('""').field('Type').must(PdfNam
e('XObject')).name('t') | 470 .field('Subtype')\ |
472 | 471 .name('Subtype')\ |
473 all.addClass('Image', 'XObject').required('""').field('Type').must(PdfName('XO
bject')).name('t').done()\ | 472 .type('name')\ |
474 .done()\ | 473 .comment('')\ |
475 .required('""').field('Subtype').must(PdfName(
'Image')).name('s').done()\ | 474 .must(datatypes.PdfName('MMType1'))\ |
476 .done()\ | 475 .done().done()\ |
477 .required('-1').field('Width', 'W').integer('w
').done()\ | |
478 .done()\ | |
479 .required('-1').field('Height', 'H').integer('
h').done()\ | |
480 .done()\ | |
481 .required('""').field('ColorSpace').name('cs')
.multiple([PdfName('/DeviceRGB', '/RGB'), PdfName('/DeviceGray', '/Gray')]).done
()\ | |
482 .done()\ | |
483 .optional().field('BitsPerComponent', 'BPC').i
nteger('bpc').multiple([PdfInteger(1), PdfInteger(2), PdfInteger(4), PdfInteger(
8)])\ | |
484
.default(PdfInteger(1)).done()\ | |
485
.done()\ | |
486 .carbonCopyPrivate('SkBitmap bitmap;') | |
487 | |
488 all.addClass('Form', 'XObject').required('""').field('Type').must(PdfName('XOb
ject')).name('t').done()\ | |
489 .done()\ | |
490 .required('""').field('Subtype').must(PdfName('
Form')).name('s').done()\ | |
491 .done()\ | |
492 .carbonCopyPublic('void test() {}') | |
493 | 476 |
494 | 477 |
495 | 478 manager.write() |
496 all.addClass('SpecificToATrapNetworkAppearanceStream', 'Dictionary', 'Addition
al entries specific to a trap network appearance stream')\ | |
497 .required('NULL')\ | |
498 .field('PCM')\ | |
499 .name('PCM')\ | |
500 .type('name')\ | |
501 .comment('(Required) The name of the process color model that was assu
med when this trap network was created; equivalent to the PostScript page device
parameter ProcessColorModel (see Section 6.2.5 of the PostScript Language Refer
ence, Third Edition). Valid values are DeviceGray, DeviceRGB, DeviceCMYK, Device
CMY, DeviceRGBK, and DeviceN.')\ | |
502 .done().done()\ | |
503 .optional()\ | |
504 .field('SeparationColorNames')\ | |
505 .name('SeparationColorNames')\ | |
506 .type('array')\ | |
507 .comment('(Optional) An array of names identifying the colorants that
were assumed when this network was created; equivalent to the Post- Script page
device parameter of the same name (see Section 6.2.5 of the PostScript Language
Reference, Third Edition). Colorants im- plied by the process color model PCM ar
e available automatically and need not be explicitly declared. If this entry is
absent, the colorants implied by PCM are assumed.')\ | |
508 .done().done()\ | |
509 .optional()\ | |
510 .field('TrapRegions')\ | |
511 .name('TrapRegions')\ | |
512 .type('array')\ | |
513 .comment('(Optional) An array of indirect references to TrapRegion obj
ects defining the page\'s trapping zones and the associated trapping parameters,
as described in Adobe Technical Note #5620, Portable Job Ticket Format. These r
eferences are to objects comprising portions of a PJTF job ticket that is embedd
ed in the PDF file. When the trapping zones and parameters are defined by an ext
ernal job ticket (or by some other means, such as with JDF), this entry is absen
t.')\ | |
514 .done().done()\ | |
515 .optional()\ | |
516 .field('TrapStyles')\ | |
517 .name('TrapStyles')\ | |
518 .type('text string')\ | |
519 .comment('(Optional) A human-readable text string that applications ca
n use to describe this trap network to the user (for example, to allow switching
between trap networks).')\ | |
520 .done().done()\ | |
521 .done() | |
522 | |
523 all.addClass('OpiVersionDictionary', 'Dictionary', 'Entry in an OPI version di
ctionary')\ | |
524 .required('NULL')\ | |
525 .field('version_number')\ | |
526 .name('version_number')\ | |
527 .type('dictionary')\ | |
528 .comment('(Required; PDF 1.2) An OPI dictionary specifying the attribu
tes of this proxy (see Tables 9.50 and 9.51). The key for this entry must be the
name 1.3 or 2.0, identifying the version of OPI to which the proxy corresponds.
')\ | |
529 .done().done()\ | |
530 .done() | |
531 | |
532 | |
533 | |
534 all.write() | |
535 | 479 |
536 return 1 | 480 return 1 |
537 | 481 |
538 if '__main__' == __name__: | 482 if '__main__' == __name__: |
539 sys.exit(generateCode()) | 483 sys.exit(generateCode()) |
540 | 484 |
541 | 485 |
OLD | NEW |