OLD | NEW |
| (Empty) |
1 | |
2 | |
3 import os | |
4 import sys | |
5 | |
6 import datatypes | |
7 from pdfspec_autogen import * | |
8 | |
9 # TODO(edisonn): date and some other types are in fact strings, with a custom fo
rmat!!! | |
10 # TODO(edisonn): refer to page 99 (PDF data types) | |
11 knowTypes = { | |
12 '(any)': ['SkPdfNativeObject*', 'ret', datatypes.CppNull(), 'true', 'use a mappe
r'], | |
13 # TODO(edisonn): return constant for undefined | |
14 '(undefined)': ['SkPdfNativeObject*', 'ret', datatypes.CppNull(), 'true', 'use a
mapper'], | |
15 '(various)': ['SkPdfNativeObject*', 'ret', datatypes.CppNull(), 'true', 'use a m
apper'], | |
16 'array': ['SkPdfArray*', '(SkPdfArray*)ret', datatypes.CppNull(), 'ret->isArray(
)'], | |
17 'boolean': ['bool', 'ret->boolValue()', datatypes.PdfBoolean('false'), 'ret->isB
oolean()'], | |
18 #date is a string, with special formating, add here the | |
19 'date': ['SkPdfDate', 'ret->dateValue()', datatypes.PdfDateNever(), 'ret->isDate
()'], | |
20 'dictionary': ['SkPdfDictionary*', '(SkPdfDictionary*)ret', datatypes.CppNull(),
'ret->isDictionary()', 'use a mapper'], | |
21 'function': ['SkPdfFunction', 'ret->functionValue()', datatypes.PdfFunctionNone(
), 'ret->isFunction()'], | |
22 'integer': ['int64_t', 'ret->intValue()', datatypes.PdfInteger(0), 'ret->isInteg
er()'], | |
23 'file_specification': ['SkPdfFileSpec', 'ret->fileSpecValue()', datatypes.FileSp
ecNone(), 'false'], | |
24 'name': ['SkString', 'ret->nameValue2()', datatypes.PdfString('SkString()'), 're
t->isName()'], | |
25 #should assert, references should never be allowed here, should be resolved way
earlier | |
26 'tree': ['SkPdfTree', 'ret->treeValue()', datatypes.EmptyTree(), 'false'], | |
27 'number': ['double', 'ret->numberValue()', datatypes.PdfNumber(0), 'ret->isNumbe
r()'], | |
28 'rectangle': ['SkRect', 'ret->rectangleValue()', datatypes.EmptyRect(), 'ret->is
Rectangle()'], | |
29 'stream': ['SkPdfStream*', 'ret->getStream()', datatypes.CppNull(), 'ret->hasSt
ream()'], | |
30 'string': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString()'),
'ret->isAnyString()'], | |
31 'text': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString()'), '
ret->isAnyString()'], | |
32 'text string': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString
()'), 'ret->isAnyString()'], | |
33 'matrix': ['SkMatrix', 'ret->matrixValue()', datatypes.IdentityMatrix(), 'ret->i
sMatrix()'], | |
34 } | |
35 | |
36 | |
37 class PdfField: | |
38 def __init__(self, parent, name, abr): | |
39 self.fParent = parent | |
40 self.fName = name | |
41 self.fAbr = abr | |
42 | |
43 self.fDefault = '' | |
44 self.fTypes = '' | |
45 self.fCppName = '' | |
46 self.fEnumValues = [] | |
47 self.fHasMust = False | |
48 self.fMustBe = [] | |
49 self.fComment = '' | |
50 | |
51 def must(self, value): | |
52 self.fHasMust = True | |
53 self.fMustBe = value | |
54 return self | |
55 | |
56 def default(self, value): | |
57 self.fDefault = value | |
58 return self | |
59 | |
60 def multiple(self, enumValues): | |
61 self.fEnumValues = enumValues | |
62 return self | |
63 | |
64 def name(self, name): | |
65 self.fCppName = name | |
66 return self | |
67 | |
68 def type(self, types): | |
69 # TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, an
d set a mask for valid types, like array or name | |
70 types = types.strip() | |
71 types = types.replace(' or ', ' ') | |
72 types = types.replace(' or,', ' ') | |
73 types = types.replace(',or ', ' ') | |
74 types = types.replace(',or,', ' ') | |
75 types = types.replace(',', ' ') | |
76 types = types.replace('text', ' ') # TODO(edisonn): what is the difference b
etween 'text string' and 'string'? | |
77 types = types.replace('file specification', 'file_specification') | |
78 | |
79 | |
80 self.fTypes = types | |
81 return self | |
82 | |
83 def comment(self, comment): | |
84 self.fComment = comment | |
85 return self | |
86 | |
87 def done(self): | |
88 return self.fParent | |
89 | |
90 | |
91 class PdfClassField: | |
92 def __init__(self, parent, required, version='', inheritable=False): | |
93 #self.fProp = '' | |
94 self.fParent = parent | |
95 self.fRequired = required | |
96 self.fVersion = version | |
97 self.fInheritable = inheritable | |
98 | |
99 def field(self, name, abr=''): | |
100 self.fProp = PdfField(self, name, abr) | |
101 return self.fProp | |
102 | |
103 def done(self): | |
104 return self.fParent | |
105 | |
106 class PdfClass: | |
107 def __init__(self, name, base, comment): | |
108 self.fFields = [] | |
109 self.fIncludes = [] | |
110 self.fCCPublicNative = [] | |
111 self.fCCPublicNativeCpp = [] | |
112 self.fName = name | |
113 self.fBase = base | |
114 self.fComment = comment | |
115 | |
116 self.fEnumSubclasses = [] | |
117 | |
118 self.fEnum = '!UNDEFINED' | |
119 self.fEnumEnd = '!UNDEFINED' | |
120 self.fCheck = '' | |
121 | |
122 def check(self, ifCheck): | |
123 self.fCheck = ifCheck | |
124 return self | |
125 | |
126 def required(self, badDefault): | |
127 field = PdfClassField(self, True) | |
128 field.fBadDefault = badDefault | |
129 self.fFields.append(field) | |
130 return field | |
131 | |
132 def optional(self): | |
133 field = PdfClassField(self, False) | |
134 self.fFields.append(field) | |
135 return field | |
136 | |
137 #([Required] [;] [inheritable] [;] [version]; [comments]) | |
138 # version: PDF [d].[d] | |
139 # ; separate props | |
140 #inheritable | |
141 #version | |
142 #required, if | |
143 #optional, if | |
144 | |
145 def include(self, path): | |
146 self.fIncludes.append(path) | |
147 return self | |
148 | |
149 def carbonCopyPublicNative(self, cc): | |
150 self.fCCPublicNative.append(cc) | |
151 return self | |
152 | |
153 def carbonCopyPublicNativeCpp(self, cc): | |
154 self.fCCPublicNativeCpp.append(cc) | |
155 return self | |
156 | |
157 def done(self): | |
158 return | |
159 | |
160 class PdfClassManager: | |
161 def __init__(self): | |
162 self.fClasses = {} | |
163 self.fClassesNamesInOrder = [] | |
164 | |
165 def addClass(self, name, base='', comment=''): | |
166 if name == 'Dictionary': | |
167 cls = PdfClass(name, '', comment) | |
168 else: | |
169 cls = PdfClass(name, base, comment) | |
170 self.fClasses[name] = cls | |
171 self.fClassesNamesInOrder.append(name) | |
172 return cls | |
173 | |
174 def writeEnum(self, fileEnums, enum, enumToCls): | |
175 fileEnums.write(' ' + enum + ',\n') | |
176 cls = enumToCls[enum] | |
177 cls.fEnumSubclasses.sort() | |
178 | |
179 cnt = 0 | |
180 for sub in cls.fEnumSubclasses: | |
181 self.writeEnum(fileEnums, cls.fEnumSubclasses[cnt], enumToCls) | |
182 cnt = cnt + 1 | |
183 | |
184 if cnt != 0: | |
185 fileEnums.write(' ' + cls.fEnumEnd + ',\n') | |
186 | |
187 | |
188 def writeAsNull(self, nativeFileClass, cls, enumToCls): | |
189 nativeFileClass.write(' SkPdf' + cls.fName +'* as' + cls.fName + '() {retu
rn (SkPdf' + cls.fName + '*)this;}\n') | |
190 nativeFileClass.write(' const SkPdf' + cls.fName +'* as' + cls.fName + '()
const {return (const SkPdf' + cls.fName + '*)this;}\n') | |
191 nativeFileClass.write('\n') | |
192 | |
193 cnt = 0 | |
194 for sub in cls.fEnumSubclasses: | |
195 self.writeAsNull(nativeFileClass, enumToCls[cls.fEnumSubclasses[cnt]], enu
mToCls) | |
196 cnt = cnt + 1 | |
197 | |
198 | |
199 def writeAsFoo(self, nativeFileClass, cls, enumToCls): | |
200 # TODO(edisonn): add a container, with sections, public, private, default, .
.. | |
201 # the end code will be grouped | |
202 | |
203 # me | |
204 nativeFileClass.write('public:\n') | |
205 | |
206 nativeFileClass.write('public:\n') | |
207 nativeFileClass.write(' SkPdf' + cls.fName +'* as' + cls.fName + '() {retu
rn this;}\n') | |
208 nativeFileClass.write(' const SkPdf' + cls.fName +'* as' + cls.fName + '()
const {return this;}\n') | |
209 nativeFileClass.write('\n') | |
210 | |
211 if cls.fName == 'Dictionary': | |
212 cnt = 0 | |
213 for sub in cls.fEnumSubclasses: | |
214 self.writeAsNull(nativeFileClass, enumToCls[cls.fEnumSubclasses[cnt]], e
numToCls) | |
215 cnt = cnt + 1 | |
216 | |
217 if cls.fName != 'Dictionary': | |
218 nativeFileClass.write('private:\n') | |
219 base = self.fClasses[cls.fBase] | |
220 cnt = 0 | |
221 for sub in base.fEnumSubclasses: | |
222 if enumToCls[base.fEnumSubclasses[cnt]].fName != cls.fName: | |
223 self.writeAsNull(nativeFileClass, enumToCls[base.fEnumSubclasses[cnt]]
, enumToCls) | |
224 cnt = cnt + 1 | |
225 | |
226 | |
227 def determineAllMustBe(self, cls, field, enumToCls): | |
228 mustBe = [] | |
229 for sub in cls.fEnumSubclasses: | |
230 mustBe = mustBe + self.determineAllMustBe(enumToCls[sub], field, enumToCls
) | |
231 | |
232 for subField in cls.fFields: | |
233 if subField.fProp.fName == field.fProp.fName: | |
234 mustBe = mustBe + subField.fProp.fMustBe | |
235 | |
236 # while cls.fBase != '': | |
237 # cls = self.fClasses[cls.fBase] | |
238 # # TODO(edisonn): bad perf | |
239 # for subField in cls.fFields: | |
240 # if subField.fProp.fName == field.fProp.fName: | |
241 # mustBe = mustBe + subField.fProp.fMustBe | |
242 | |
243 return mustBe | |
244 | |
245 def write(self): | |
246 global fileHeadersNative | |
247 global fileHeadersNativeCpp | |
248 global knowTypes | |
249 | |
250 # generate enum | |
251 enumsRoot = [] | |
252 | |
253 enumToCls = {} | |
254 | |
255 for name in self.fClasses: | |
256 cls = self.fClasses[name] | |
257 cls.fEnum = 'k' + name + '_SkPdfNativeObjectType' | |
258 cls.fEnumEnd = 'k' + name + '__End_SkPdfNativeObjectType' | |
259 | |
260 fileHeadersNative.write('#include "SkPdf' + cls.fName + '_autogen.h"\n') | |
261 fileHeadersNativeCpp.write('#include "SkPdf' + cls.fName + '_autogen.cpp"\
n') | |
262 | |
263 if cls.fBase != '': | |
264 self.fClasses[cls.fBase].fEnumSubclasses.append(cls.fEnum) | |
265 | |
266 if cls.fBase == '': | |
267 enumsRoot.append(cls.fEnum) | |
268 | |
269 enumToCls[cls.fEnum] = cls | |
270 | |
271 enumsRoot.sort() | |
272 | |
273 | |
274 # TODO(edisonn): move each .h in it's own file | |
275 # write imports | |
276 | |
277 # write enums | |
278 fileEnums = open(os.path.join(sys.argv[1], 'native', 'autogen', 'SkPdfEnums_
autogen.h'), 'w') | |
279 fileEnums.write('#ifndef __DEFINED__SkPdfEnums\n') | |
280 fileEnums.write('#define __DEFINED__SkPdfEnums\n') | |
281 fileEnums.write('\n') | |
282 | |
283 fileEnums.write('enum SkPdfNativeObjectType {\n') | |
284 fileEnums.write(' kNone_SkPdfNativeObjectType = 0,\n') | |
285 for enum in enumsRoot: | |
286 self.writeEnum(fileEnums, enum, enumToCls) | |
287 fileEnums.write('};\n') | |
288 fileEnums.write('\n') | |
289 | |
290 # write forward class declaration | |
291 for name in self.fClassesNamesInOrder: | |
292 fileEnums.write('class SkPdf' + name + ';\n') | |
293 fileEnums.write('\n') | |
294 | |
295 fileEnums.write('#endif // __DEFINED__SkPdfEnums\n') | |
296 fileEnums.close() | |
297 | |
298 for name in self.fClassesNamesInOrder: | |
299 cls = self.fClasses[name] | |
300 enum = cls.fEnum | |
301 | |
302 nativeFileClass = open(os.path.join(sys.argv[1], 'native', 'autogen', 'SkP
df' + cls.fName + '_autogen.h'), 'w') | |
303 nativeFileClassCpp = open(os.path.join(sys.argv[1], 'native', 'autogen', '
SkPdf' + cls.fName + '_autogen.cpp'), 'w') | |
304 | |
305 nativeFileClass.write('#ifndef __DEFINED__SkPdf' + cls.fName + '\n') | |
306 nativeFileClass.write('#define __DEFINED__SkPdf' + cls.fName + '\n') | |
307 nativeFileClass.write('\n') | |
308 | |
309 nativeFileClassCpp.write('#include "SkPdf' + cls.fName + '_autogen.h"\n\n'
) | |
310 nativeFileClassCpp.write('\n') | |
311 | |
312 | |
313 if cls.fBase == '': | |
314 nativeFileClass.write('#include "stddef.h"\n') | |
315 nativeFileClass.write('#include "SkPdfEnums_autogen.h"\n') | |
316 nativeFileClass.write('#include "SkPdfNYI.h"\n') | |
317 nativeFileClass.write('#include "SkPdfNativeObject.h"\n') | |
318 nativeFileClass.write('class SkPdfNativeDoc;\n') | |
319 | |
320 if cls.fBase != '': | |
321 nativeFileClass.write('#include "SkPdf' + cls.fBase + '_autogen.h"\n') | |
322 | |
323 nativeFileClassCpp.write('#include "SkPdfNativeDoc.h"\n') | |
324 | |
325 | |
326 nativeFileClass.write('\n') | |
327 | |
328 if cls.fComment != '': | |
329 nativeFileClass.write('// ' + cls.fComment + '\n') | |
330 | |
331 if cls.fBase == '': | |
332 nativeFileClass.write('class SkPdf' + cls.fName + ' : public SkPdfNative
Object {\n') | |
333 else: | |
334 nativeFileClass.write('class SkPdf' + cls.fName + ' : public SkPdf' + cl
s.fBase + ' {\n') | |
335 | |
336 self.writeAsFoo(nativeFileClass, cls, enumToCls) | |
337 | |
338 nativeFileClass.write('public:\n') | |
339 | |
340 for cc in cls.fCCPublicNative: | |
341 nativeFileClass.write(' ' + cc + '\n') | |
342 | |
343 for cc in cls.fCCPublicNativeCpp: | |
344 nativeFileClassCpp.write(cc + '\n\n') | |
345 | |
346 | |
347 if cls.fBase == '': | |
348 nativeFileClass.write('public:\n') | |
349 | |
350 # TODO(edisonn): add is valid ? | |
351 #check required fieds, also, there should be an internal_valid() manually
wrote for complex | |
352 # situations | |
353 # right now valid return true | |
354 # TODO(edisonn): cache the value of valid, have a set of bits that would r
emember what types are valid for this type | |
355 nativeFileClass.write(' bool valid() const {return true;}\n') | |
356 #nativeFileClass.write('\n') | |
357 | |
358 for field in cls.fFields: | |
359 prop = field.fProp | |
360 if prop.fCppName != '': | |
361 | |
362 lines = prop.fComment.split('\n') | |
363 if prop.fComment != '' and len(lines) > 0: | |
364 nativeFileClass.write('/** ' + lines[0] + '\n') | |
365 for line in lines[1:]: | |
366 nativeFileClass.write(' * ' + line + '\n') | |
367 nativeFileClass.write('**/\n') | |
368 | |
369 if prop.fCppName[0] == '[': | |
370 nativeFileClass.write('/*\n') # comment code of the atributes that
can have any name | |
371 nativeFileClassCpp.write('/*\n') # comment code of the atributes th
at can have any name | |
372 | |
373 | |
374 if len(prop.fTypes.split()) == 1: | |
375 t = prop.fTypes.strip() | |
376 | |
377 nativeFileClass.write(' ' + knowTypes[t][0] + ' ' + prop.fCppName +
'(SkPdfNativeDoc* doc);\n') | |
378 nativeFileClassCpp.write('' + knowTypes[t][0] + ' SkPdf' + cls.fName
+ '::' + prop.fCppName + '(SkPdfNativeDoc* doc) {\n') | |
379 nativeFileClassCpp.write(' SkPdfNativeObject* ret = get(\"' + prop.
fName + '\", \"' + prop.fAbr + '\");\n') | |
380 nativeFileClassCpp.write(' if (doc) {ret = doc->resolveReference(re
t);}\n') | |
381 nativeFileClassCpp.write(' if ((ret != NULL && ' + knowTypes[t][3]
+ ') || (doc == NULL && ret != NULL && ret->isReference())) return ' + knowTypes
[t][1] + ';\n') | |
382 | |
383 if field.fRequired: | |
384 nativeFileClassCpp.write(' // TODO(edisonn): warn about missing r
equired field, assert for known good pdfs\n') | |
385 nativeFileClassCpp.write(' return ' + knowTypes[t][2].toCpp() + '
;\n'); | |
386 elif prop.fDefault != '': | |
387 nativeFileClassCpp.write(' return ' + prop.fDefault.toCpp() + ';\
n'); | |
388 else: | |
389 nativeFileClassCpp.write(' // TODO(edisonn): warn about missing d
efault value for optional fields\n') | |
390 nativeFileClassCpp.write(' return ' + knowTypes[t][2].toCpp() + '
;\n'); | |
391 | |
392 nativeFileClassCpp.write('}\n') | |
393 nativeFileClassCpp.write('\n') | |
394 else: | |
395 for type in prop.fTypes.split(): | |
396 t = type.strip() | |
397 | |
398 nativeFileClass.write(' bool is' + prop.fCppName + 'A' + t.title(
) + '(SkPdfNativeDoc* doc);\n') | |
399 | |
400 nativeFileClassCpp.write('bool SkPdf' + cls.fName + '::is' + prop.
fCppName + 'A' + t.title() + '(SkPdfNativeDoc* doc) {\n') | |
401 nativeFileClassCpp.write(' SkPdfNativeObject* ret = get(\"' + pro
p.fName + '\", \"' + prop.fAbr + '\");\n') | |
402 nativeFileClassCpp.write(' if (doc) {ret = doc->resolveReference(
ret);}\n') | |
403 nativeFileClassCpp.write(' return ret != NULL && ' + knowTypes[t]
[3] + ';\n') | |
404 nativeFileClassCpp.write('}\n') | |
405 nativeFileClassCpp.write('\n') | |
406 | |
407 nativeFileClass.write(' ' + knowTypes[t][0] + ' get' + prop.fCppN
ame + 'As' + t.title() + '(SkPdfNativeDoc* doc);\n') | |
408 nativeFileClassCpp.write('' + knowTypes[t][0] + ' SkPdf' + cls.fNa
me + '::get' + prop.fCppName + 'As' + t.title() + '(SkPdfNativeDoc* doc) {\n') | |
409 | |
410 nativeFileClassCpp.write(' SkPdfNativeObject* ret = get(\"' + pro
p.fName + '\", \"' + prop.fAbr + '\");\n') | |
411 nativeFileClassCpp.write(' if (doc) {ret = doc->resolveReference(
ret);}\n') | |
412 nativeFileClassCpp.write(' if ((ret != NULL && ' + knowTypes[t][3
] + ') || (doc == NULL && ret != NULL && ret->isReference())) return ' + knowTyp
es[t][1] + ';\n') | |
413 | |
414 | |
415 if field.fRequired: | |
416 nativeFileClassCpp.write(' // TODO(edisonn): warn about missing
required field, assert for known good pdfs\n') | |
417 nativeFileClassCpp.write(' return ' + knowTypes[t][2].toCpp() +
';\n'); | |
418 elif prop.fDefault != '': | |
419 nativeFileClassCpp.write(' return ' + prop.fDefault.toCpp() + '
;\n'); | |
420 else: | |
421 nativeFileClassCpp.write(' // TODO(edisonn): warn about missing
default value for optional fields\n') | |
422 nativeFileClassCpp.write(' return ' + knowTypes[t][2].toCpp() +
';\n'); | |
423 | |
424 nativeFileClassCpp.write('}\n') | |
425 nativeFileClassCpp.write('\n') | |
426 | |
427 nativeFileClass.write(' bool has_' + prop.fCppName + '() const;\n') | |
428 nativeFileClassCpp.write('bool SkPdf' + cls.fName + '::has_' + prop.fC
ppName + '() const {\n') | |
429 # TODO(edisonn): has_foo() does not check type, add has_valid_foo(), a
nd check that type is expected (e.g. number, string, ...) | |
430 nativeFileClassCpp.write(' return get(\"' + prop.fName + '\", \"' + p
rop.fAbr + '\") != NULL;\n') | |
431 nativeFileClassCpp.write('}\n') | |
432 nativeFileClassCpp.write('\n') | |
433 | |
434 if prop.fCppName[0] == '[': | |
435 nativeFileClass.write('*/\n') # comment code of the atributes that
can have any name | |
436 nativeFileClassCpp.write('*/\n') # comment code of the atributes th
at can have any name | |
437 | |
438 | |
439 nativeFileClass.write('};\n') | |
440 nativeFileClass.write('\n') | |
441 | |
442 nativeFileClass.write('#endif // __DEFINED__NATIVE_SkPdf' + cls.fName + '
\n') | |
443 | |
444 nativeFileClass.close() | |
445 nativeFileClassCpp.close() | |
446 | |
447 # generate constructor when knowing the type | |
448 # later, p2, generate constructor when not knowing the type - very similar
with parsing? | |
449 | |
450 # generate parser | |
451 # TODO(edisonn): fast recognition based on must attributes. | |
452 fileMapperNative = open(os.path.join(sys.argv[1], 'native', 'autogen', 'SkPd
fMapper_autogen.h'), 'w') | |
453 fileMapperNativeCpp = open(os.path.join(sys.argv[1], 'native', 'autogen', 'S
kPdfMapper_autogen.cpp'), 'w') | |
454 | |
455 fileMapperNative.write('#ifndef __DEFINED__SkPdfMapper\n') | |
456 fileMapperNative.write('#define __DEFINED__SkPdfMapper\n') | |
457 fileMapperNative.write('\n') | |
458 | |
459 fileMapperNative.write('#include "SkPdfHeaders_autogen.h"\n') | |
460 fileMapperNative.write('#include "SkPdfNativeDoc.h"\n') | |
461 fileMapperNative.write('#include "SkPdfNativeObject.h"\n') | |
462 | |
463 | |
464 fileMapperNativeCpp.write('#include "SkPdfMapper_autogen.h"\n') | |
465 fileMapperNativeCpp.write('#include "SkPdfUtils.h"\n') | |
466 fileMapperNativeCpp.write('#include "SkPdfNativeObject.h"\n') | |
467 fileMapperNativeCpp.write('\n') | |
468 | |
469 fileMapperNative.write('class SkPdfMapper {\n') | |
470 | |
471 fileMapperNative.write('public:\n') | |
472 | |
473 fileMapperNative.write(' SkPdfMapper() {}\n') | |
474 fileMapperNative.write('\n') | |
475 | |
476 for name in self.fClassesNamesInOrder: | |
477 cls = self.fClasses[name] | |
478 | |
479 fileMapperNative.write(' SkPdfNativeObjectType map' + name + '(const SkPd
fNativeObject* in) const;\n') | |
480 | |
481 fileMapperNativeCpp.write('SkPdfNativeObjectType SkPdfMapper::map' + name
+ '(const SkPdfNativeObject* in) const {\n') | |
482 fileMapperNativeCpp.write(' if (in == NULL || !is' + name + '(in)) return
kNone_SkPdfNativeObjectType;\n') | |
483 fileMapperNativeCpp.write('\n') | |
484 if len(cls.fEnumSubclasses) > 0: | |
485 fileMapperNativeCpp.write(' SkPdfNativeObjectType ret;\n') | |
486 | |
487 # stream must be last one | |
488 hasStream = False | |
489 for sub in cls.fEnumSubclasses: | |
490 fileMapperNativeCpp.write(' if (kNone_SkPdfNativeObjectType != (ret = m
ap' + enumToCls[sub].fName + '(in))) return ret;\n') | |
491 | |
492 fileMapperNativeCpp.write('\n') | |
493 | |
494 fileMapperNativeCpp.write(' return k' + name + '_SkPdfNativeObjectType;\n
') | |
495 fileMapperNativeCpp.write('}\n') | |
496 fileMapperNativeCpp.write('\n') | |
497 | |
498 for name in self.fClassesNamesInOrder: | |
499 cls = self.fClasses[name] | |
500 | |
501 fileMapperNative.write(' bool is' + name + '(const SkPdfNativeObject* nat
iveObj) const ;\n') | |
502 fileMapperNativeCpp.write('bool SkPdfMapper::is' + name + '(const SkPdfNat
iveObject* nativeObj) const {\n') | |
503 | |
504 if cls.fCheck != '': | |
505 fileMapperNativeCpp.write(' return ' + cls.fCheck + ';\n') | |
506 else: | |
507 cntMust = 0 | |
508 emitedRet = False | |
509 for field in cls.fFields: | |
510 prop = field.fProp | |
511 if prop.fHasMust: | |
512 if emitedRet == False: | |
513 fileMapperNativeCpp.write(' const SkPdfNativeObject* ret = NULL;\
n') | |
514 emitedRet = True | |
515 cntMust = cntMust + 1 | |
516 fileMapperNativeCpp.write(' if (!nativeObj->isDictionary()) return
false;\n') | |
517 fileMapperNativeCpp.write(' ret = nativeObj->get(\"' + prop.fName +
'\", \"' + prop.fAbr + '\");\n') | |
518 fileMapperNativeCpp.write(' if (ret == NULL || !' + knowTypes[prop.
fTypes.strip()][3] + ') return false;\n') | |
519 | |
520 eval = ''; | |
521 # TODO(edisonn): this could get out of hand, and could have poor per
formance if continued on this path | |
522 # but if we would write our parser, then best thing would be to crea
te a map of (key, value) -> to bits | |
523 # and at each (key, value) we do an and with the bits existent, then
we check what bits are left, which would tell the posible types of this diction
ary | |
524 # and for non unique posinilities (if any) based on context, or the
requester of dictionry we can determine fast the dictionary type | |
525 mustBe = self.determineAllMustBe(cls, field, enumToCls) | |
526 if len(mustBe) > 0: | |
527 for cnd in mustBe: | |
528 if eval == '': | |
529 eval = '(' + knowTypes[prop.fTypes.strip()][1] + ' != ' + cnd
.toCpp() + ')' | |
530 else: | |
531 eval = eval + ' && ' + '(' + knowTypes[prop.fTypes.strip()][1]
+ ' != ' + cnd.toCpp() + ')' | |
532 fileMapperNativeCpp.write(' if (' + eval + ') return false;\n') | |
533 fileMapperNativeCpp.write('\n') | |
534 | |
535 fileMapperNativeCpp.write(' return true;\n') | |
536 | |
537 fileMapperNativeCpp.write('}\n') | |
538 fileMapperNativeCpp.write('\n') | |
539 | |
540 # TODO(edisonn): dict should be a SkPdfDictionary ? | |
541 fileMapperNative.write(' bool SkPdf' + name + 'FromDictionary(const SkPdf
NativeObject* dict, const char* key, SkPdf' + name + '** data) const ;\n') | |
542 fileMapperNativeCpp.write('bool SkPdfMapper::SkPdf' + name + 'FromDictiona
ry(const SkPdfNativeObject* dict, const char* key, SkPdf' + name + '** data) con
st {\n') | |
543 fileMapperNativeCpp.write(' const SkPdfNativeObject* value = dict->get(ke
y);\n') | |
544 fileMapperNativeCpp.write(' if (value == NULL) { return false; }\n') | |
545 fileMapperNativeCpp.write(' if (data == NULL) { return true; }\n') | |
546 fileMapperNativeCpp.write(' if (kNone_SkPdfNativeObjectType == map' + nam
e + '(value)) return false;\n') | |
547 fileMapperNativeCpp.write(' *data = (SkPdf' + name + '*)value;\n') | |
548 fileMapperNativeCpp.write(' return true;\n'); | |
549 fileMapperNativeCpp.write('}\n') | |
550 fileMapperNativeCpp.write('\n') | |
551 | |
552 fileMapperNative.write(' bool SkPdf' + name + 'FromDictionary(const SkPdf
NativeObject* dict, const char* key, const char* abr, SkPdf' + name + '** data)
const ;\n') | |
553 fileMapperNativeCpp.write('bool SkPdfMapper::SkPdf' + name + 'FromDictiona
ry(const SkPdfNativeObject* dict, const char* key, const char* abr, SkPdf' + nam
e + '** data) const {\n') | |
554 fileMapperNativeCpp.write(' if (SkPdf' + name + 'FromDictionary(dict, key
, data)) return true;\n') | |
555 fileMapperNativeCpp.write(' if (abr == NULL || *abr == \'\\0\') return fa
lse;\n') | |
556 fileMapperNativeCpp.write(' return SkPdf' + name + 'FromDictionary(dict,
abr, data);\n') | |
557 fileMapperNativeCpp.write('}\n') | |
558 fileMapperNativeCpp.write('\n') | |
559 | |
560 fileMapperNative.write('};\n') | |
561 fileMapperNative.write('\n') | |
562 | |
563 fileMapperNative.write('#endif // __DEFINED__SkPdfMapper\n') | |
564 | |
565 fileMapperNative.close() | |
566 fileMapperNativeCpp.close() | |
567 | |
568 return | |
569 | |
570 def generateCode(): | |
571 global fileHeadersNative | |
572 global fileHeadersNativeCpp | |
573 global knowTypes | |
574 | |
575 nativeAutogenPath = os.path.join(sys.argv[1], 'native', 'autogen') | |
576 if not os.path.exists(nativeAutogenPath): | |
577 os.makedirs(nativeAutogenPath) | |
578 | |
579 fileHeadersNative = open(os.path.join(sys.argv[1], 'native', 'autogen', 'SkPdf
Headers_autogen.h'), 'w') | |
580 fileHeadersNativeCpp = open(os.path.join(sys.argv[1], 'native', 'autogen', 'Sk
PdfHeaders_autogen.cpp'), 'w') | |
581 | |
582 fileHeadersNative.write('#ifndef __DEFINED__SkPdfHeaders\n') | |
583 fileHeadersNative.write('#define __DEFINED__SkPdfHeaders\n') | |
584 fileHeadersNative.write('\n') | |
585 | |
586 fileHeadersNativeCpp.write('#include "SkPdfHeaders_autogen.h"\n') | |
587 | |
588 manager = PdfClassManager() | |
589 | |
590 # these classes are not explicitely backed by a table in the pdf spec | |
591 manager.addClass('Dictionary') | |
592 manager.addClass('XObjectDictionary', 'Dictionary') | |
593 | |
594 manager.addClass('FontDictionary', 'Dictionary') | |
595 | |
596 manager.addClass('TrueTypeFontDictionary', 'Type1FontDictionary')\ | |
597 .required('NULL')\ | |
598 .field('Subtype')\ | |
599 .name('Subtype')\ | |
600 .type('name')\ | |
601 .comment('')\ | |
602 .must([datatypes.PdfName('TrueType')])\ | |
603 .done().done()\ | |
604 | |
605 addDictionaryTypesTo(knowTypes) | |
606 buildPdfSpec(manager) | |
607 | |
608 manager.addClass('MultiMasterFontDictionary', 'Type1FontDictionary')\ | |
609 .required('NULL')\ | |
610 .field('Subtype')\ | |
611 .name('Subtype')\ | |
612 .type('name')\ | |
613 .comment('')\ | |
614 .must([datatypes.PdfName('MMType1')])\ | |
615 .done().done()\ | |
616 | |
617 | |
618 manager.write() | |
619 | |
620 fileHeadersNative.write('#endif // __DEFINED__SkPdfHeaders\n') | |
621 | |
622 fileHeadersNative.close() | |
623 fileHeadersNativeCpp.close() | |
624 | |
625 if '__main__' == __name__: | |
626 #print sys.argv | |
627 sys.exit(generateCode()) | |
628 | |
OLD | NEW |