Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Side by Side Diff: experimental/PdfViewer/generate_code.py

Issue 17095004: Object model generated from pdf spec 1.4, draft code (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « experimental/PdfViewer/datatypes.py ('k') | experimental/PdfViewer/pdf_viewer_main.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « experimental/PdfViewer/datatypes.py ('k') | experimental/PdfViewer/pdf_viewer_main.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698