| 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 |