2013-06-12 19:07:45 +00:00
2013-06-11 21:44:08 +00:00
2013-06-14 19:22:19 +00:00
import sys
2013-06-12 19:07:45 +00:00
2013-06-14 19:22:19 +00:00
import datatypes
2013-06-25 20:45:40 +00:00
from autogen . pdfspec_autogen import *
2013-06-11 21:44:08 +00:00
2013-06-17 23:36:45 +00:00
knowTypes = {
' (any) ' : [ ' SkPdfObject* ' , ' ObjectFromDictionary ' , datatypes . CppNull ( ) , ' true ' ] ,
' (undefined) ' : [ ' SkPdfObject* ' , ' ObjectFromDictionary ' , datatypes . CppNull ( ) , ' true ' ] ,
' (various) ' : [ ' SkPdfObject* ' , ' ObjectFromDictionary ' , datatypes . CppNull ( ) , ' true ' ] ,
2013-06-25 20:45:40 +00:00
' array ' : [ ' SkPdfArray* ' , ' ArrayFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Array ' ] ,
2013-06-17 23:36:45 +00:00
' boolean ' : [ ' bool ' , ' BoolFromDictionary ' , datatypes . PdfBoolean ( ' false ' ) , ' ret->podofo()->GetDataType() == ePdfDataType_Bool ' ] ,
' date ' : [ ' SkPdfDate ' , ' DateFromDictionary ' , datatypes . PdfDateNever ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Array ' ] ,
' dictionary ' : [ ' SkPdfDictionary* ' , ' DictionaryFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Dictionary ' ] ,
' function ' : [ ' SkPdfFunction ' , ' FunctionFromDictionary ' , datatypes . PdfFunctionNone ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Reference ' ] ,
' integer ' : [ ' long ' , ' LongFromDictionary ' , datatypes . PdfInteger ( 0 ) , ' ret->podofo()->GetDataType() == ePdfDataType_Number ' ] ,
' file_specification ' : [ ' SkPdfFileSpec ' , ' FileSpecFromDictionary ' , datatypes . FileSpecNone ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Reference ' ] ,
' name ' : [ ' std::string ' , ' NameFromDictionary ' , datatypes . PdfString ( ' " " ' ) , ' ret->podofo()->GetDataType() == ePdfDataType_Name ' ] ,
' tree ' : [ ' SkPdfTree* ' , ' TreeFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Reference ' ] ,
2013-06-18 22:00:40 +00:00
' number ' : [ ' double ' , ' DoubleFromDictionary ' , datatypes . PdfNumber ( 0 ) , ' ret->podofo()->GetDataType() == ePdfDataType_Real || ret->podofo()->GetDataType() == ePdfDataType_Number ' ] ,
2013-06-25 20:45:40 +00:00
' rectangle ' : [ ' SkRect* ' , ' SkRectFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Array && ret->podofo()->GetArray().GetLength() == 4 ' ] ,
2013-06-21 21:03:15 +00:00
' stream ' : [ ' SkPdfStream* ' , ' StreamFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->HasStream() ' ] ,
2013-06-17 23:36:45 +00:00
' string ' : [ ' std::string ' , ' StringFromDictionary ' , datatypes . PdfString ( ' " " ' ) , ' ret->podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetDataType() == ePdfDataType_HexString ' ] ,
' text ' : [ ' std::string ' , ' StringFromDictionary ' , datatypes . PdfString ( ' " " ' ) , ' ret->podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetDataType() == ePdfDataType_HexString ' ] ,
' text string ' : [ ' std::string ' , ' StringFromDictionary ' , datatypes . PdfString ( ' " " ' ) , ' ret->podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetDataType() == ePdfDataType_HexString ' ] ,
2013-06-25 20:45:40 +00:00
' matrix ' : [ ' SkMatrix* ' , ' SkMatrixFromDictionary ' , datatypes . CppNull ( ) , ' ret->podofo()->GetDataType() == ePdfDataType_Array && ret->podofo()->GetArray().GetLength() == 4 ' ] ,
2013-06-17 23:36:45 +00:00
}
2013-06-13 20:02:29 +00:00
2013-06-11 21:44:08 +00:00
class PdfField :
def __init__ ( self , parent , name , abr ) :
self . fParent = parent
self . fName = name
self . fAbr = abr
self . fDefault = ' '
2013-06-17 23:36:45 +00:00
self . fTypes = ' '
2013-06-12 19:07:45 +00:00
self . fCppName = ' '
2013-06-17 23:36:45 +00:00
self . fEnumValues = [ ]
self . fHasMust = False
2013-06-21 21:03:15 +00:00
self . fMustBe = [ ]
2013-06-19 17:42:17 +00:00
self . fComment = ' '
2013-06-11 21:44:08 +00:00
def must ( self , value ) :
2013-06-12 19:07:45 +00:00
self . fHasMust = True
self . fMustBe = value
return self
2013-06-11 21:44:08 +00:00
def default ( self , value ) :
self . fDefault = value
return self
2013-06-17 23:36:45 +00:00
def multiple ( self , enumValues ) :
self . fEnumValues = enumValues
2013-06-11 21:44:08 +00:00
return self
2013-06-12 19:07:45 +00:00
def name ( self , name ) :
self . fCppName = name
2013-06-11 21:44:08 +00:00
return self
2013-06-17 23:36:45 +00:00
def type ( self , types ) :
2013-06-13 20:02:29 +00:00
# TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, and set a mask for valid types, like array or name
2013-06-17 23:36:45 +00:00
types = types . strip ( )
2013-06-27 20:03:43 +00:00
types = types . replace ( ' or ' , ' ' )
types = types . replace ( ' or, ' , ' ' )
types = types . replace ( ' ,or ' , ' ' )
types = types . replace ( ' ,or, ' , ' ' )
2013-06-17 23:36:45 +00:00
types = types . replace ( ' , ' , ' ' )
types = types . replace ( ' text ' , ' ' ) # TODO(edisonn): what is the difference between 'text string' and 'string'?
types = types . replace ( ' file specification ' , ' file_specification ' )
2013-06-14 19:22:19 +00:00
2013-06-17 23:36:45 +00:00
self . fTypes = types
2013-06-13 20:02:29 +00:00
return self
def comment ( self , comment ) :
2013-06-19 17:42:17 +00:00
self . fComment = comment
2013-06-13 20:02:29 +00:00
return self
2013-06-11 21:44:08 +00:00
def done ( self ) :
return self . fParent
class PdfClassField :
2013-06-19 17:42:17 +00:00
def __init__ ( self , parent , required , version = ' ' , inheritable = False ) :
2013-06-12 19:07:45 +00:00
#self.fProp = ''
2013-06-11 21:44:08 +00:00
self . fParent = parent
self . fRequired = required
2013-06-13 20:02:29 +00:00
self . fVersion = version
self . fInheritable = inheritable
2013-06-11 21:44:08 +00:00
2013-06-12 19:07:45 +00:00
def field ( self , name , abr = ' ' ) :
self . fProp = PdfField ( self , name , abr )
return self . fProp
2013-06-11 21:44:08 +00:00
def done ( self ) :
return self . fParent
class PdfClass :
2013-06-13 20:02:29 +00:00
def __init__ ( self , name , base , comment ) :
2013-06-11 21:44:08 +00:00
self . fFields = [ ]
self . fIncludes = [ ]
2013-06-12 19:07:45 +00:00
self . fCCPublic = [ ]
self . fCCPrivate = [ ]
2013-06-11 21:44:08 +00:00
self . fName = name
self . fBase = base
2013-06-13 20:02:29 +00:00
self . fComment = comment
2013-06-11 21:44:08 +00:00
2013-06-11 23:06:16 +00:00
self . fEnumSubclasses = [ ]
self . fEnum = ' !UNDEFINED '
self . fEnumEnd = ' !UNDEFINED '
2013-06-14 19:22:19 +00:00
self . fCheck = ' '
2013-06-11 23:06:16 +00:00
2013-06-14 19:22:19 +00:00
def check ( self , ifCheck ) :
self . fCheck = ifCheck
return self
2013-06-12 19:07:45 +00:00
def required ( self , badDefault ) :
2013-06-11 21:44:08 +00:00
field = PdfClassField ( self , True )
2013-06-12 19:07:45 +00:00
field . fBadDefault = badDefault
2013-06-11 21:44:08 +00:00
self . fFields . append ( field )
return field
def optional ( self ) :
field = PdfClassField ( self , False )
self . fFields . append ( field )
return field
2013-06-13 20:02:29 +00:00
#([Required] [;] [inheritable] [;] [version]; [comments])
# version: PDF [d].[d]
# ; separate props
#inheritable
#version
#required, if
#optional, if
2013-06-11 21:44:08 +00:00
def include ( self , path ) :
self . fIncludes . append ( path )
return self
2013-06-12 19:07:45 +00:00
def carbonCopyPublic ( self , cc ) :
self . fCCPublic . append ( cc )
return self
def carbonCopyPrivate ( self , cc ) :
self . fCCPrivate . append ( cc )
2013-06-11 21:44:08 +00:00
return self
2013-06-13 20:02:29 +00:00
def done ( self ) :
return
2013-06-11 21:44:08 +00:00
class PdfClassManager :
def __init__ ( self ) :
2013-06-11 23:06:16 +00:00
self . fClasses = { }
2013-06-12 19:07:45 +00:00
self . fClassesNamesInOrder = [ ]
2013-06-11 21:44:08 +00:00
2013-06-13 20:02:29 +00:00
def addClass ( self , name , base = ' Object ' , comment = ' ' ) :
2013-06-12 19:07:45 +00:00
if name == ' Object ' :
2013-06-13 20:02:29 +00:00
cls = PdfClass ( name , ' ' , comment )
2013-06-12 19:07:45 +00:00
else :
2013-06-13 20:02:29 +00:00
cls = PdfClass ( name , base , comment )
2013-06-11 23:06:16 +00:00
self . fClasses [ name ] = cls
2013-06-12 19:07:45 +00:00
self . fClassesNamesInOrder . append ( name )
2013-06-11 21:44:08 +00:00
return cls
2013-06-18 22:00:40 +00:00
def writeEnum ( self , fileEnums , enum , enumToCls ) :
fileEnums . write ( ' ' + enum + ' , \n ' )
2013-06-11 23:06:16 +00:00
cls = enumToCls [ enum ]
cls . fEnumSubclasses . sort ( )
cnt = 0
for sub in cls . fEnumSubclasses :
2013-06-18 22:00:40 +00:00
self . writeEnum ( fileEnums , cls . fEnumSubclasses [ cnt ] , enumToCls )
2013-06-11 23:06:16 +00:00
cnt = cnt + 1
if cnt != 0 :
2013-06-18 22:00:40 +00:00
fileEnums . write ( ' ' + cls . fEnumEnd + ' , \n ' )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
def writeAsNull ( self , fileClass , cls , enumToCls ) :
fileClass . write ( ' virtual SkPdf ' + cls . fName + ' * as ' + cls . fName + ' () { return NULL;} \n ' )
fileClass . write ( ' virtual const SkPdf ' + cls . fName + ' * as ' + cls . fName + ' () const { return NULL;} \n ' )
fileClass . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
cnt = 0
for sub in cls . fEnumSubclasses :
2013-06-18 22:00:40 +00:00
self . writeAsNull ( fileClass , enumToCls [ cls . fEnumSubclasses [ cnt ] ] , enumToCls )
2013-06-12 19:07:45 +00:00
cnt = cnt + 1
2013-06-18 22:00:40 +00:00
def writeAsFoo ( self , fileClass , cls , enumToCls ) :
2013-06-12 19:07:45 +00:00
# TODO(edisonn): add a container, with sections, public, private, default, ...
# the end code will be grouped
# me
2013-06-18 22:00:40 +00:00
fileClass . write ( ' public: \n ' )
fileClass . write ( ' virtual SkPdf ' + cls . fName + ' * as ' + cls . fName + ' () { return this;} \n ' )
fileClass . write ( ' virtual const SkPdf ' + cls . fName + ' * as ' + cls . fName + ' () const { return this;} \n ' )
fileClass . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
if cls . fName == ' Object ' :
cnt = 0
for sub in cls . fEnumSubclasses :
2013-06-18 22:00:40 +00:00
self . writeAsNull ( fileClass , enumToCls [ cls . fEnumSubclasses [ cnt ] ] , enumToCls )
2013-06-12 19:07:45 +00:00
cnt = cnt + 1
if cls . fName != ' Object ' :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' private: \n ' )
2013-06-12 19:07:45 +00:00
base = self . fClasses [ cls . fBase ]
cnt = 0
for sub in base . fEnumSubclasses :
if enumToCls [ base . fEnumSubclasses [ cnt ] ] . fName != cls . fName :
2013-06-18 22:00:40 +00:00
self . writeAsNull ( fileClass , enumToCls [ base . fEnumSubclasses [ cnt ] ] , enumToCls )
2013-06-12 19:07:45 +00:00
cnt = cnt + 1
2013-06-21 21:03:15 +00:00
def determineAllMustBe ( self , cls , field , enumToCls ) :
mustBe = [ ]
for sub in cls . fEnumSubclasses :
mustBe = mustBe + self . determineAllMustBe ( enumToCls [ sub ] , field , enumToCls )
for subField in cls . fFields :
if subField . fProp . fName == field . fProp . fName :
mustBe = mustBe + subField . fProp . fMustBe
# while cls.fBase != '':
# cls = self.fClasses[cls.fBase]
# # TODO(edisonn): bad perf
# for subField in cls.fFields:
# if subField.fProp.fName == field.fProp.fName:
# mustBe = mustBe + subField.fProp.fMustBe
return mustBe
2013-06-11 23:06:16 +00:00
2013-06-11 21:44:08 +00:00
def write ( self ) :
2013-06-18 22:00:40 +00:00
global fileHeaders
2013-06-26 17:48:12 +00:00
global fileHeadersCpp
2013-06-17 23:36:45 +00:00
global knowTypes
2013-06-11 23:06:16 +00:00
# generate enum
enumsRoot = [ ]
enumToCls = { }
for name in self . fClasses :
cls = self . fClasses [ name ]
2013-06-18 22:00:40 +00:00
cls . fEnum = ' k ' + name + ' _SkPdfObjectType '
cls . fEnumEnd = ' k ' + name + ' __End_SkPdfObjectType '
fileHeaders . write ( ' #include " SkPdf ' + cls . fName + ' _autogen.h " \n ' )
2013-06-26 17:48:12 +00:00
fileHeadersCpp . write ( ' #include " SkPdf ' + cls . fName + ' _autogen.cpp " \n ' )
2013-06-11 23:06:16 +00:00
if cls . fBase != ' ' :
self . fClasses [ cls . fBase ] . fEnumSubclasses . append ( cls . fEnum )
if cls . fBase == ' ' :
enumsRoot . append ( cls . fEnum )
enumToCls [ cls . fEnum ] = cls
enumsRoot . sort ( )
2013-06-12 19:07:45 +00:00
# TODO(edisonn): move each .h in it's own file
# write imports
2013-06-11 23:06:16 +00:00
# write enums
2013-06-18 22:00:40 +00:00
fileEnums = open ( ' SkPdfEnums_autogen.h ' , ' w ' )
fileEnums . write ( ' #ifndef __DEFINED__SkPdfEnums \n ' )
fileEnums . write ( ' #define __DEFINED__SkPdfEnums \n ' )
fileEnums . write ( ' \n ' )
fileEnums . write ( ' enum SkPdfObjectType { \n ' )
2013-06-11 23:06:16 +00:00
for enum in enumsRoot :
2013-06-18 22:00:40 +00:00
self . writeEnum ( fileEnums , enum , enumToCls )
fileEnums . write ( ' }; \n ' )
fileEnums . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
# write forward class declaration
for name in self . fClassesNamesInOrder :
2013-06-18 22:00:40 +00:00
fileEnums . write ( ' class SkPdf ' + name + ' ; \n ' )
fileEnums . write ( ' \n ' )
fileEnums . write ( ' #endif // __DEFINED__SkPdfEnums \n ' )
fileEnums . close ( )
2013-06-12 19:07:45 +00:00
for name in self . fClassesNamesInOrder :
cls = self . fClasses [ name ]
enum = cls . fEnum
2013-06-18 22:00:40 +00:00
fileClass = open ( ' SkPdf ' + cls . fName + ' _autogen.h ' , ' w ' )
2013-06-26 17:48:12 +00:00
fileClassCpp = open ( ' SkPdf ' + cls . fName + ' _autogen.cpp ' , ' w ' )
2013-06-18 22:00:40 +00:00
fileClass . write ( ' #ifndef __DEFINED__SkPdf ' + cls . fName + ' \n ' )
fileClass . write ( ' #define __DEFINED__SkPdf ' + cls . fName + ' \n ' )
fileClass . write ( ' \n ' )
2013-06-26 17:48:12 +00:00
fileClassCpp . write ( ' #include " SkPdf ' + cls . fName + ' _autogen.h " \n \n ' )
2013-06-25 20:45:40 +00:00
fileClass . write ( ' #include " SkPdfUtils.h " \n ' )
2013-06-18 22:00:40 +00:00
fileClass . write ( ' #include " SkPdfEnums_autogen.h " \n ' )
fileClass . write ( ' #include " SkPdfArray_autogen.h " \n ' )
2013-06-19 17:42:17 +00:00
if cls . fBase != ' ' :
fileClass . write ( ' #include " SkPdf ' + cls . fBase + ' _autogen.h " \n ' )
fileClass . write ( ' \n ' )
if cls . fComment != ' ' :
fileClass . write ( ' // ' + cls . fComment + ' \n ' )
2013-06-18 22:00:40 +00:00
2013-06-12 19:07:45 +00:00
if cls . fBase == ' ' :
2013-06-19 17:42:17 +00:00
fileClass . write ( ' class SkPdf ' + cls . fName + ' { \n ' )
2013-06-12 19:07:45 +00:00
else :
2013-06-19 17:42:17 +00:00
fileClass . write ( ' class SkPdf ' + cls . fName + ' : public SkPdf ' + cls . fBase + ' { \n ' )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
fileClass . write ( ' public: \n ' )
fileClass . write ( ' virtual SkPdfObjectType getType() const { return ' + cls . fEnum + ' ;} \n ' )
2013-06-12 19:07:45 +00:00
if len ( cls . fEnumSubclasses ) == 0 :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' virtual SkPdfObjectType getTypeEnd() const { return (SkPdfObjectType)( ' + cls . fEnum + ' + 1);} \n ' )
2013-06-12 19:07:45 +00:00
else :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' virtual SkPdfObjectType getTypeEnd() const { return ' + cls . fEnumEnd + ' ;} \n ' )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
self . writeAsFoo ( fileClass , cls , enumToCls )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
fileClass . write ( ' public: \n ' )
2013-06-12 19:07:45 +00:00
for cc in cls . fCCPublic :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' ' + cc + ' \n ' )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
fileClass . write ( ' private: \n ' )
2013-06-12 19:07:45 +00:00
for cc in cls . fCCPrivate :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' ' + cc + ' \n ' )
2013-06-12 19:07:45 +00:00
if cls . fBase == ' ' :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' protected: \n ' )
fileClass . write ( ' const PdfMemDocument* fPodofoDoc; \n ' )
fileClass . write ( ' const PdfObject* fPodofoObj; \n ' )
fileClass . write ( ' \n ' )
fileClass . write ( ' public: \n ' )
fileClass . write ( ' SkPdf ' + cls . fName + ' (const PdfMemDocument* podofoDoc = NULL, const PdfObject* podofoObj = NULL) : fPodofoDoc(podofoDoc), fPodofoObj(podofoObj) {} \n ' )
2013-06-25 20:45:40 +00:00
fileClass . write ( ' SkPdf ' + cls . fName + ' (const SkPdf ' + cls . fName + ' & from) : fPodofoDoc(from.fPodofoDoc), fPodofoObj(from.fPodofoObj) {} \n ' )
fileClass . write ( ' \n ' )
2013-06-18 22:00:40 +00:00
fileClass . write ( ' const PdfMemDocument* doc() const { return fPodofoDoc;} \n ' )
fileClass . write ( ' const PdfObject* podofo() const { return fPodofoObj;} \n ' )
2013-06-12 19:07:45 +00:00
else :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' public: \n ' )
fileClass . write ( ' SkPdf ' + cls . fName + ' (const PdfMemDocument* podofoDoc = NULL, const PdfObject* podofoObj = NULL) : SkPdf ' + cls . fBase + ' (podofoDoc, podofoObj) {} \n ' )
fileClass . write ( ' \n ' )
2013-06-25 20:45:40 +00:00
fileClass . write ( ' SkPdf ' + cls . fName + ' (const SkPdf ' + cls . fName + ' & from) : SkPdf ' + cls . fBase + ' (from.fPodofoDoc, from.fPodofoObj) {} \n ' )
fileClass . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
#check required fieds, also, there should be an internal_valid() manually wrote for complex
# situations
# right now valid return true
2013-06-18 22:00:40 +00:00
fileClass . write ( ' virtual bool valid() const { return true;} \n ' )
fileClass . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
fileClass . write ( ' SkPdf ' + cls . fName + ' & operator=(const SkPdf ' + cls . fName + ' & from) { this->fPodofoDoc = from.fPodofoDoc; this->fPodofoObj = from.fPodofoObj; return *this;} \n ' )
fileClass . write ( ' \n ' )
2013-06-17 20:46:27 +00:00
2013-06-12 19:07:45 +00:00
for field in cls . fFields :
prop = field . fProp
if prop . fCppName != ' ' :
2013-06-19 17:42:17 +00:00
lines = prop . fComment . split ( ' \n ' )
if prop . fComment != ' ' and len ( lines ) > 0 :
fileClass . write ( ' /** ' + lines [ 0 ] + ' \n ' )
for line in lines [ 1 : ] :
fileClass . write ( ' * ' + line + ' \n ' )
fileClass . write ( ' **/ \n ' )
2013-06-14 19:22:19 +00:00
if prop . fCppName [ 0 ] == ' [ ' :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' /* \n ' ) # comment code of the atributes that can have any name
2013-06-26 17:48:12 +00:00
fileClassCpp . write ( ' /* \n ' ) # comment code of the atributes that can have any name
2013-06-17 23:36:45 +00:00
# TODO(edisonn): has_foo();
2013-06-19 17:42:17 +00:00
fileClass . write ( ' bool has_ ' + prop . fCppName + ' () const { \n ' )
fileClass . write ( ' return (ObjectFromDictionary(fPodofoDoc, fPodofoObj->GetDictionary(), \" ' + prop . fName + ' \" , \" ' + prop . fAbr + ' \" , NULL)); \n ' )
fileClass . write ( ' } \n ' )
fileClass . write ( ' \n ' )
2013-06-17 23:36:45 +00:00
if len ( prop . fTypes . split ( ) ) == 1 :
t = prop . fTypes . strip ( )
2013-06-26 17:48:12 +00:00
fileClass . write ( ' ' + knowTypes [ t ] [ 0 ] + ' ' + prop . fCppName + ' () const; \n ' )
fileClassCpp . write ( ' ' + knowTypes [ t ] [ 0 ] + ' SkPdf ' + cls . fName + ' :: ' + prop . fCppName + ' () const { \n ' )
fileClassCpp . write ( ' ' + knowTypes [ t ] [ 0 ] + ' ret; \n ' )
fileClassCpp . write ( ' if ( ' + knowTypes [ t ] [ 1 ] + ' (fPodofoDoc, fPodofoObj->GetDictionary(), \" ' + prop . fName + ' \" , \" ' + prop . fAbr + ' \" , &ret)) return ret; \n ' )
2013-06-17 23:36:45 +00:00
if field . fRequired == False and prop . fDefault != ' ' :
2013-06-26 17:48:12 +00:00
fileClassCpp . write ( ' return ' + prop . fDefault . toCpp ( ) + ' ; \n ' ) ;
2013-06-17 23:36:45 +00:00
else :
2013-06-26 17:48:12 +00:00
fileClassCpp . write ( ' // TODO(edisonn): warn about missing required field, assert for known good pdfs \n ' )
fileClassCpp . write ( ' return ' + knowTypes [ t ] [ 2 ] . toCpp ( ) + ' ; \n ' ) ;
fileClassCpp . write ( ' } \n ' )
fileClassCpp . write ( ' \n ' )
2013-06-17 23:36:45 +00:00
else :
for type in prop . fTypes . split ( ) :
t = type . strip ( )
2013-06-18 22:00:40 +00:00
fileClass . write ( ' bool is ' + prop . fCppName + ' A ' + t . title ( ) + ' () const { \n ' )
fileClass . write ( ' SkPdfObject* ret = NULL; \n ' )
fileClass . write ( ' if (!ObjectFromDictionary(fPodofoDoc, fPodofoObj->GetDictionary(), \" ' + prop . fName + ' \" , \" ' + prop . fAbr + ' \" , &ret)) return false; \n ' )
fileClass . write ( ' return ' + knowTypes [ t ] [ 3 ] + ' ; \n ' )
fileClass . write ( ' } \n ' )
fileClass . write ( ' \n ' )
2013-06-26 17:48:12 +00:00
fileClass . write ( ' ' + knowTypes [ t ] [ 0 ] + ' get ' + prop . fCppName + ' As ' + t . title ( ) + ' () const; \n ' )
fileClassCpp . write ( ' ' + knowTypes [ t ] [ 0 ] + ' SkPdf ' + cls . fName + ' ::get ' + prop . fCppName + ' As ' + t . title ( ) + ' () const { \n ' )
fileClassCpp . write ( ' ' + knowTypes [ t ] [ 0 ] + ' ret = ' + knowTypes [ t ] [ 2 ] . toCpp ( ) + ' ; \n ' )
fileClassCpp . write ( ' if ( ' + knowTypes [ t ] [ 1 ] + ' (fPodofoDoc, fPodofoObj->GetDictionary(), \" ' + prop . fName + ' \" , \" ' + prop . fAbr + ' \" , &ret)) return ret; \n ' )
fileClassCpp . write ( ' // TODO(edisonn): warn about missing required field, assert for known good pdfs \n ' )
fileClassCpp . write ( ' return ' + knowTypes [ t ] [ 2 ] . toCpp ( ) + ' ; \n ' )
fileClassCpp . write ( ' } \n ' )
fileClassCpp . write ( ' \n ' )
2013-06-17 23:36:45 +00:00
2013-06-13 20:02:29 +00:00
2013-06-14 19:22:19 +00:00
if prop . fCppName [ 0 ] == ' [ ' :
2013-06-18 22:00:40 +00:00
fileClass . write ( ' */ \n ' ) # comment code of the atributes that can have any name
2013-06-26 17:48:12 +00:00
fileClassCpp . write ( ' */ \n ' ) # comment code of the atributes that can have any name
2013-06-13 20:02:29 +00:00
2013-06-12 19:07:45 +00:00
2013-06-18 22:00:40 +00:00
fileClass . write ( ' }; \n ' )
fileClass . write ( ' \n ' )
fileClass . write ( ' #endif // __DEFINED__SkPdf ' + cls . fName + ' \n ' )
fileClass . close ( )
2013-06-26 17:48:12 +00:00
fileClassCpp . close ( )
2013-06-12 19:07:45 +00:00
# generate constructor when knowing the type
# later, p2, generate constructor when not knowing the type - very similar with parsing?
2013-06-11 23:06:16 +00:00
# generate parser
2013-06-12 19:07:45 +00:00
# TODO(edisonn): fast recognition based on must attributes.
2013-06-18 22:00:40 +00:00
fileMapper = open ( ' SkPdfPodofoMapper_autogen.h ' , ' w ' )
2013-06-26 17:48:12 +00:00
fileMapperCpp = open ( ' SkPdfPodofoMapper_autogen.cpp ' , ' w ' )
2013-06-18 22:00:40 +00:00
fileMapper . write ( ' #ifndef __DEFINED__SkPdfPodofoMapper \n ' )
fileMapper . write ( ' #define __DEFINED__SkPdfPodofoMapper \n ' )
fileMapper . write ( ' \n ' )
fileMapper . write ( ' #include " SkPdfHeaders_autogen.h " \n ' )
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' #include " SkPdfPodofoMapper_autogen.h " \n ' )
# fileMapper.write('class PodofoMapper {\n')
# fileMapper.write('public:\n')
2013-06-12 19:07:45 +00:00
for name in self . fClassesNamesInOrder :
cls = self . fClasses [ name ]
2013-06-17 20:46:27 +00:00
2013-06-26 17:48:12 +00:00
fileMapper . write ( ' bool map ' + name + ' (const SkPdfObject& in, SkPdf ' + name + ' ** out); \n ' )
fileMapperCpp . write ( ' bool map ' + name + ' (const SkPdfObject& in, SkPdf ' + name + ' ** out) { \n ' )
fileMapperCpp . write ( ' return map ' + name + ' (*in.doc(), *in.podofo(), out); \n ' )
fileMapperCpp . write ( ' } \n ' )
fileMapperCpp . write ( ' \n ' )
2013-06-17 20:46:27 +00:00
2013-06-26 17:48:12 +00:00
fileMapper . write ( ' bool map ' + name + ' (const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf ' + name + ' ** out); \n ' )
fileMapperCpp . write ( ' bool map ' + name + ' (const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf ' + name + ' ** out) { \n ' )
fileMapperCpp . write ( ' if (!is ' + name + ' (podofoDoc, podofoObj)) return false; \n ' )
fileMapperCpp . write ( ' \n ' )
2013-06-21 21:03:15 +00:00
# stream must be last one
hasStream = False
2013-06-12 19:07:45 +00:00
for sub in cls . fEnumSubclasses :
2013-06-21 21:03:15 +00:00
if cls . fName == ' Object ' and enumToCls [ sub ] . fName == ' Stream ' :
hasStream = True
else :
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' if (map ' + enumToCls [ sub ] . fName + ' (podofoDoc, podofoObj, (SkPdf ' + enumToCls [ sub ] . fName + ' **)out)) return true; \n ' )
2013-06-21 21:03:15 +00:00
if hasStream :
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' if (mapStream(podofoDoc, podofoObj, (SkPdfStream**)out)) return true; \n ' )
2013-06-21 21:03:15 +00:00
2013-06-12 19:07:45 +00:00
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' *out = new SkPdf ' + name + ' (&podofoDoc, &podofoObj); \n ' )
fileMapperCpp . write ( ' return true; \n ' )
fileMapperCpp . write ( ' } \n ' )
fileMapperCpp . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
for name in self . fClassesNamesInOrder :
cls = self . fClasses [ name ]
2013-06-26 17:48:12 +00:00
fileMapper . write ( ' bool is ' + name + ' (const PdfMemDocument& podofoDoc, const PdfObject& podofoObj); \n ' )
fileMapperCpp . write ( ' bool is ' + name + ' (const PdfMemDocument& podofoDoc, const PdfObject& podofoObj) { \n ' )
2013-06-12 19:07:45 +00:00
2013-06-14 19:22:19 +00:00
if cls . fCheck != ' ' :
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' return ' + cls . fCheck + ' ; \n ' )
2013-06-12 19:07:45 +00:00
else :
2013-06-14 19:22:19 +00:00
cntMust = 0
for field in cls . fFields :
prop = field . fProp
if prop . fHasMust :
cntMust = cntMust + 1
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' ' + knowTypes [ prop . fTypes . strip ( ) ] [ 0 ] + ' ' + prop . fCppName + ' ; \n ' )
fileMapperCpp . write ( ' if (! ' + knowTypes [ prop . fTypes . strip ( ) ] [ 1 ] + ' (&podofoDoc, podofoObj.GetDictionary(), \" ' + prop . fName + ' \" , \" ' + prop . fAbr + ' \" , & ' + prop . fCppName + ' )) return false; \n ' )
2013-06-21 21:03:15 +00:00
eval = ' ' ;
# TODO(edisonn): this could get out of hand, and could have poor performance if continued on this path
# but if we would write our parser, then best thing would be to create a map of (key, value) -> to bits
# 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 dictionary
# and for non unique posinilities (if any) based on context, or the requester of dictionry we can determine fast the dictionary type
mustBe = self . determineAllMustBe ( cls , field , enumToCls )
if len ( mustBe ) > 0 :
for cnd in mustBe :
if eval == ' ' :
eval = ' ( ' + prop . fCppName + ' != ' + cnd . toCpp ( ) + ' ) '
else :
eval = eval + ' && ' + ' ( ' + prop . fCppName + ' != ' + cnd . toCpp ( ) + ' ) '
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' if ( ' + eval + ' ) return false; \n ' )
fileMapperCpp . write ( ' \n ' )
2013-06-14 19:22:19 +00:00
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' return true; \n ' )
2013-06-12 19:07:45 +00:00
2013-06-26 17:48:12 +00:00
fileMapperCpp . write ( ' } \n ' )
fileMapperCpp . write ( ' \n ' )
2013-06-12 19:07:45 +00:00
2013-06-26 17:48:12 +00:00
fileMapper . write ( ' bool ' + name + ' FromDictionary(const PdfMemDocument* pdfDoc, const PdfDictionary& dict, const char* key, SkPdf ' + name + ' ** data); \n ' )
fileMapperCpp . write ( ' bool ' + name + ' FromDictionary(const PdfMemDocument* pdfDoc, const PdfDictionary& dict, const char* key, SkPdf ' + name + ' ** data) { \n ' )
fileMapperCpp . write ( ' const PdfObject* value = resolveReferenceObject(pdfDoc, dict.GetKey(PdfName(key)), true); \n ' )
fileMapperCpp . write ( ' if (value == NULL) { return false; } \n ' )
fileMapperCpp . write ( ' if (data == NULL) { return true; } \n ' )
fileMapperCpp . write ( ' return map ' + name + ' (*pdfDoc, *value, (SkPdf ' + name + ' **)data); \n ' )
fileMapperCpp . write ( ' } \n ' )
fileMapperCpp . write ( ' \n ' )
fileMapper . write ( ' bool ' + name + ' FromDictionary(const PdfMemDocument* pdfDoc, const PdfDictionary& dict, const char* key, const char* abr, SkPdf ' + name + ' ** data); \n ' )
fileMapperCpp . write ( ' bool ' + name + ' FromDictionary(const PdfMemDocument* pdfDoc, const PdfDictionary& dict, const char* key, const char* abr, SkPdf ' + name + ' ** data) { \n ' )
fileMapperCpp . write ( ' if ( ' + name + ' FromDictionary(pdfDoc, dict, key, data)) return true; \n ' )
fileMapperCpp . write ( ' if (abr == NULL || *abr == \' \\ 0 \' ) return false; \n ' )
fileMapperCpp . write ( ' return ' + name + ' FromDictionary(pdfDoc, dict, abr, data); \n ' )
fileMapperCpp . write ( ' } \n ' )
fileMapperCpp . write ( ' \n ' )
#fileMapper.write('};\n')
2013-06-18 22:00:40 +00:00
fileMapper . write ( ' \n ' )
fileMapper . write ( ' #endif // __DEFINED__SkPdfPodofoMapper \n ' )
fileMapper . close ( )
2013-06-12 19:07:45 +00:00
2013-06-11 21:44:08 +00:00
return
def generateCode ( ) :
2013-06-18 22:00:40 +00:00
global fileHeaders
2013-06-26 17:48:12 +00:00
global fileHeadersCpp
2013-06-25 20:45:40 +00:00
global knowTypes
2013-06-18 22:00:40 +00:00
fileHeaders = open ( ' SkPdfHeaders_autogen.h ' , ' w ' )
2013-06-26 17:48:12 +00:00
fileHeadersCpp = open ( ' SkPdfHeaders_autogen.cpp ' , ' w ' )
2013-06-18 22:00:40 +00:00
fileHeaders . write ( ' #ifndef __DEFINED__SkPdfHeaders \n ' )
fileHeaders . write ( ' #define __DEFINED__SkPdfHeaders \n ' )
fileHeaders . write ( ' \n ' )
fileHeaders . write ( ' #include " SkPdfEnums_autogen.h " \n ' )
2013-06-26 17:48:12 +00:00
fileHeadersCpp . write ( ' #include " SkPdfHeaders_autogen.h " \n ' )
2013-06-14 19:22:19 +00:00
manager = PdfClassManager ( )
manager . addClass ( ' Object ' )
manager . addClass ( ' Null ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Null ' )
2013-06-18 14:51:21 +00:00
manager . addClass ( ' Boolean ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Bool ' ) \
. carbonCopyPublic ( ' bool value() const { return fPodofoObj->GetBool();} ' )
2013-06-18 22:00:40 +00:00
manager . addClass ( ' Integer ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Number || podofoObj.GetDataType() == ePdfDataType_Real ' ) \
2013-06-18 14:51:21 +00:00
. carbonCopyPublic ( ' long value() const { return fPodofoObj->GetNumber();} ' )
2013-06-18 22:00:40 +00:00
manager . addClass ( ' Number ' , ' Integer ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Number || podofoObj.GetDataType() == ePdfDataType_Real ' ) \
2013-06-18 14:51:21 +00:00
. carbonCopyPublic ( ' double value() const { return fPodofoObj->GetReal();} ' )
manager . addClass ( ' Name ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Name ' ) \
. carbonCopyPublic ( ' const std::string& value() const { return fPodofoObj->GetName().GetName();} ' )
2013-06-14 19:22:19 +00:00
manager . addClass ( ' Reference ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Reference ' )
2013-06-18 14:51:21 +00:00
manager . addClass ( ' Array ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Array ' ) \
. carbonCopyPublic ( ' const int size() const { return fPodofoObj->GetArray().GetSize();} ' ) \
2013-06-21 21:43:09 +00:00
. carbonCopyPublic ( ' SkPdfObject* operator[](int i) const { SkPdfObject* ret = NULL; skpdfmap(*fPodofoDoc, fPodofoObj->GetArray()[i], &ret); return ret; } ' ) \
2013-06-18 14:51:21 +00:00
2013-06-18 22:00:40 +00:00
manager . addClass ( ' String ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_String || podofoObj.GetDataType() == ePdfDataType_HexString ' ) \
2013-06-18 14:51:21 +00:00
. carbonCopyPublic ( ' const std::string& value() const { return fPodofoObj->GetString().GetStringUtf8();} ' )
2013-06-18 22:00:40 +00:00
manager . addClass ( ' HexString ' , ' String ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_HexString ' ) \
2013-06-18 14:51:21 +00:00
. carbonCopyPublic ( ' const std::string& value() const { return fPodofoObj->GetString().GetStringUtf8();} ' )
2013-06-14 19:22:19 +00:00
2013-06-18 22:00:40 +00:00
manager . addClass ( ' Dictionary ' ) . check ( ' podofoObj.GetDataType() == ePdfDataType_Dictionary ' ) \
2013-06-25 20:45:40 +00:00
. carbonCopyPublic ( ' SkPdfObject* get(const char* dictionaryKeyName) const { return new SkPdfObject(fPodofoDoc, resolveReferenceObject(fPodofoDoc, fPodofoObj->GetDictionary().GetKey(PdfName(dictionaryKeyName))));} ' ) \
. carbonCopyPublic ( ' SkPdfObject* get(const char* dictionaryKeyName) { return new SkPdfObject(fPodofoDoc, resolveReferenceObject(fPodofoDoc, fPodofoObj->GetDictionary().GetKey(PdfName(dictionaryKeyName))));} ' ) \
2013-06-21 21:03:15 +00:00
manager . addClass ( ' Stream ' ) # attached to a dictionary in podofo
2013-06-18 22:00:40 +00:00
2013-06-14 19:22:19 +00:00
# these classes are not explicitely backed by a table in the pdf spec
manager . addClass ( ' XObjectDictionary ' , ' Dictionary ' )
manager . addClass ( ' FontDictionary ' , ' Dictionary ' )
2013-06-11 21:44:08 +00:00
2013-06-21 21:03:15 +00:00
manager . addClass ( ' TrueTypeFontDictionary ' , ' Type1FontDictionary ' ) \
. required ( ' NULL ' ) \
. field ( ' Subtype ' ) \
. name ( ' Subtype ' ) \
. type ( ' name ' ) \
. comment ( ' ' ) \
. must ( [ datatypes . PdfName ( ' TrueType ' ) ] ) \
. done ( ) . done ( ) \
2013-06-11 21:44:08 +00:00
2013-06-25 20:45:40 +00:00
addDictionaryTypesTo ( knowTypes )
buildPdfSpec ( manager )
2013-06-14 19:22:19 +00:00
manager . addClass ( ' MultiMasterFontDictionary ' , ' Type1FontDictionary ' ) \
. required ( ' NULL ' ) \
. field ( ' Subtype ' ) \
. name ( ' Subtype ' ) \
2013-06-13 20:02:29 +00:00
. type ( ' name ' ) \
2013-06-14 19:22:19 +00:00
. comment ( ' ' ) \
2013-06-21 21:03:15 +00:00
. must ( [ datatypes . PdfName ( ' MMType1 ' ) ] ) \
2013-06-13 20:02:29 +00:00
. done ( ) . done ( ) \
2013-06-14 19:22:19 +00:00
manager . write ( )
2013-06-11 21:44:08 +00:00
2013-06-18 22:00:40 +00:00
fileHeaders . write ( ' #endif // __DEFINED__SkPdfHeaders \n ' )
fileHeaders . close ( )
2013-06-26 17:48:12 +00:00
fileHeadersCpp . close ( )
2013-06-18 22:00:40 +00:00
2013-06-11 21:44:08 +00:00
return 1
if ' __main__ ' == __name__ :
sys . exit ( generateCode ( ) )
2013-06-13 20:02:29 +00:00