| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048 |
- '''
- Extra information to customise how we wrap MuPDF structs into C++ classes.
- '''
- import textwrap
- import jlib
- from . import rename
- from . import state
- from . import util
- class ExtraMethod:
- '''
- Defines a prototype and implementation of a custom method in a generated
- class.
- '''
- def __init__( self, return_, name_args, body, comment, overload=None):
- '''
- return_:
- Return type as a string.
- name_args:
- A string describing name and args of the method:
- <method-name>(<args>)
- body:
- Implementation code including the enclosing '{...}'.
- comment:
- Optional comment; should include /* and */ or //.
- overload:
- If true, we allow auto-generation of methods with same name.
- '''
- assert name_args
- self.return_ = return_
- self.name_args = name_args
- self.body = body
- self.comment = comment
- self.overload = overload
- assert '\t' not in body
- def __str__(self):
- return f'{self.name_args} => {self.return_}'
- class ExtraConstructor:
- '''
- Defines a prototype and implementation of a custom constructor in a
- generated class.
- '''
- def __init__( self, name_args, body, comment):
- '''
- name_args:
- A string of the form: (<args>)
- body:
- Implementation code including the enclosing '{...}'.
- comment:
- Optional comment; should include /* and */ or //.
- '''
- self.return_ = ''
- self.name_args = name_args
- self.body = body
- self.comment = comment
- assert '\t' not in body
- class ClassExtra:
- '''
- Extra methods/features when wrapping a particular MuPDF struct into a C++
- class.
- '''
- def __init__( self,
- accessors=None,
- class_bottom='',
- class_post='',
- class_pre='',
- class_top='',
- constructor_default=True,
- constructor_excludes=None,
- constructor_prefixes=None,
- constructor_raw=True,
- constructors_extra=None,
- constructors_wrappers=None,
- copyable=True,
- extra_cpp='',
- iterator_next=None,
- methods_extra=None,
- method_wrappers=None,
- method_wrappers_static=None,
- opaque=False,
- pod=False,
- virtual_fnptrs=False,
- ):
- '''
- accessors:
- If true, we generate accessors methods for all items in the
- underlying struct.
- Defaults to True if pod is True, else False.
- class_bottom:
- Extra text at end of class definition, e.g. for member variables.
- class_post:
- Extra text after class definition, e.g. complete definition of
- iterator class.
- class_pre:
- Extra text before class definition, e.g. forward declaration of
- iterator class.
- class_top:
- Extra text at start of class definition, e.g. for enums.
- constructor_default:
- If None we set to true if `pod` is true, otherwise false. If
- true, we create a default constructor. If `pod` is true this
- constructor will default-initialise each member, otherwise it will
- set `m_internal` to null.
- constructor_excludes:
- Lists of constructor functions to ignore.
- constructor_prefixes:
- Extra fz_*() function name prefixes that can be used by class
- constructors_wrappers. We find all functions whose name starts with one of
- the specified prefixes and which returns a pointer to the relevant
- fz struct.
- For each function we find, we make a constructor that takes the
- required arguments and set m_internal to what this function
- returns.
- If there is a '-' item, we omit the default 'fz_new_<type>' prefix.
- constructor_raw:
- If true, create a constructor that takes a pointer to an instance
- of the wrapped fz_ struct. If 'default', this constructor arg
- defaults to NULL. If 'declaration_only' we declare the constructor
- but do not write out the function definition - typically this will
- be instead specified as custom code in <extra_cpp>.
- constructors_extra:
- List of ExtraConstructor's, allowing arbitrary constructors_wrappers to be
- specified.
- constructors_wrappers:
- List of fns to use as constructors_wrappers.
- copyable:
- If 'default' we allow default copy constructor to be created by C++
- compiler. This is useful for plain structs that are not referenced
- counted but can still be copied, but which we don't want to specify
- pod=True.
- Otherwise if true, generated wrapper class must be copyable. If
- pod is false, we generate a copy constructor by looking for a
- fz_keep_*() function; it's an error if we can't find this function
- [2024-01-24 fixme: actually we don't appear to raise an
- error in this case, instead we make class non-copyable.
- e.g. FzCompressedBuffer.].
- Otherwise if false we create a private copy constructor.
- [todo: need to check docs for interaction of pod/copyable.]
- extra_cpp:
- Extra text for .cpp file, e.g. implementation of iterator class
- methods.
- iterator_next:
- Support for iterating forwards over linked list.
- Should be (first, last).
- first:
- Name of element within the wrapped class that points to the
- first item in the linked list. We assume that this element will
- have 'next' pointers that terminate in NULL.
- If <first> is '', the container is itself the first element in
- the linked list.
- last:
- Currently unused, but could be used for reverse iteration in
- the future.
- We generate begin() and end() methods, plus a separate iterator
- class, to allow iteration over the linked list starting at
- <structname>::<first> and iterating to ->next until we reach NULL.
- methods_extra:
- List of ExtraMethod's, allowing arbitrary methods to be specified.
- method_wrappers:
- Extra fz_*() function names that should be wrapped in class
- methods.
- E.g. 'fz_foo_bar' is converted to a method called foo_bar()
- that takes same parameters as fz_foo_bar() except context and
- any pointer to struct and fz_context*. The implementation calls
- fz_foo_bar(), converting exceptions etc.
- The first arg that takes underlying fz_*_s type is omitted and
- implementation passes <this>.
- method_wrappers_static:
- Like <method_wrappers>, but generates static methods, where no args
- are replaced by <this>.
- opaque:
- If true, we generate a wrapper even if there's no definition
- available for the struct, i.e. it's only available as a forward
- declaration.
- pod:
- If 'inline', there is no m_internal; instead, each member of the
- underlying class is placed in the wrapper class and special method
- `internal()` returns a fake pointer to underlying class.
- If 'none', there is no m_internal member at all. Typically
- <extra_cpp> could be used to add in custom members.
- If True, underlying class is POD and m_internal is an instance of
- the underlying class instead of a pointer to it.
- virtual_fnptrs:
- If true, should be a dict with these keys:
- alloc:
- A string containing C++ code to be embedded in the
- virtual_fnptrs wrapper class's constructor.
- If the wrapper class is a POD, the MuPDF struct is already
- available as part of the wrapper class instance (as
- m_internal, or `internal()` if inline). Otherwise this
- code should set `m_internal` to point to a newly allocated
- instance of the MuPDF struct.
- Should typically set up the MuPDF struct so that `self_()`
- can return the original C++ wrapper class instance.
- comment:
- Extra comment for the wrapper class.
- free:
- Optional code for freeing the virtual_fnptrs wrapper
- class. If specified this causes creation of a destructor
- function.
- This is only needed for non-ref-counted classes that are
- not marked as POD. In this case the wrapper class has a
- pointer `m_internal` member that will not be automatically
- freed by the destructor, and `alloc` will usually have set
- it to a newly allocated struct.
- self_:
- A callable that returns a string containing C++ code for
- embedding in each low-level callback. It should returns a
- pointer to the original C++ virtual_fnptrs wrapper class.
- If `self_n` is None, this callable takes no args. Otherwise
- it takes the name of the `self_n`'th arg.
- self_n:
- Index of arg in each low-level callback, for the arg that
- should be passed to `self_`. We use the same index for all
- low-level callbacks. If not specified, default is 1 (we
- generally expect args to be (fz_context* ctx, void*, ...).
- If None, `self_` is called with no arg; this is for if we
- use a different mechanism such as a global variable.
- We generate a virtual_fnptrs wrapper class, derived from the main
- wrapper class, where the main wrapper class's function pointers end
- up calling the virtual_fnptrs wrapper class's virtual methods. We
- then use SWIG's 'Director' support to allow these virtual methods
- to be overridden in Python/C#. Thus one can make MuPDF function
- pointers call Python/C# code.
- '''
- if accessors is None and pod is True:
- accessors = True
- if constructor_default is None:
- constructor_default = pod
- self.accessors = accessors
- self.class_bottom = class_bottom
- self.class_post = class_post
- self.class_pre = class_pre
- self.class_top = class_top
- self.constructor_default = constructor_default
- self.constructor_excludes = constructor_excludes or []
- self.constructor_prefixes = constructor_prefixes or []
- self.constructor_raw = constructor_raw
- self.constructors_extra = constructors_extra or []
- self.constructors_wrappers = constructors_wrappers or []
- self.copyable = copyable
- self.extra_cpp = extra_cpp
- self.iterator_next = iterator_next
- self.methods_extra = methods_extra or []
- self.method_wrappers = method_wrappers or []
- self.method_wrappers_static = method_wrappers_static or []
- self.opaque = opaque
- self.pod = pod
- self.virtual_fnptrs = virtual_fnptrs
- assert self.pod in (False, True, 'inline', 'none'), f'{self.pod}'
- def assert_list_of( items, type_):
- assert isinstance( items, list)
- for item in items:
- assert isinstance( item, type_)
- assert_list_of( self.constructor_prefixes, str)
- assert_list_of( self.method_wrappers, str)
- assert_list_of( self.method_wrappers_static, str)
- assert_list_of( self.methods_extra, ExtraMethod)
- assert_list_of( self.constructors_extra, ExtraConstructor)
- if virtual_fnptrs:
- assert isinstance(virtual_fnptrs, dict), f'virtual_fnptrs={virtual_fnptrs!r}'
- def __str__( self):
- ret = ''
- ret += f' accessors={self.accessors}'
- ret += f' class_bottom={self.class_bottom}'
- ret += f' class_post={self.class_post}'
- ret += f' class_pre={self.class_pre}'
- ret += f' class_top={self.class_top}'
- ret += f' constructor_default={self.constructor_default}'
- ret += f' constructor_excludes={self.constructor_excludes}'
- ret += f' constructor_prefixes={self.constructor_prefixes}'
- ret += f' constructor_raw={self.constructor_raw}'
- ret += f' constructors_extra={self.constructors_extra}'
- ret += f' constructors_wrappers={self.constructors_wrappers}'
- ret += f' copyable={self.copyable}'
- ret += f' extra_cpp={self.extra_cpp}'
- ret += f' iterator_next={self.iterator_next}'
- ret += f' methods_extra={self.methods_extra}'
- ret += f' method_wrappers={self.method_wrappers}'
- ret += f' method_wrappers_static={self.method_wrappers_static}'
- ret += f' opaque={self.opaque}'
- ret += f' pod={self.pod}'
- ret += f' virtual_fnptrs={self.virtual_fnptrs}'
- return ret
- class ClassExtras:
- '''
- Extra methods/features for each of our auto-generated C++ wrapper classes.
- '''
- def __init__( self, **namevalues):
- '''
- namevalues:
- Named args mapping from struct name (e.g. fz_document) to a
- ClassExtra.
- '''
- self.items = dict()
- for name, value in namevalues.items():
- self.items[ name] = value
- def get( self, tu, name):
- '''
- Searches for <name> and returns a ClassExtra instance. If <name> is not
- found, we insert an empty ClassExtra instance and return it. We do this
- for any name, e.g. name could be 'foo *'.
- We return None if <name> is a known enum.
- '''
- verbose = state.state_.show_details( name)
- if 0 and verbose:
- jlib.log( 'ClassExtras.get(): {=name}')
- name = util.clip( name, ('const ', 'struct '))
- if 0 and verbose:
- jlib.log( 'ClassExtras.get(): {=name}')
- if not name.startswith( ('fz_', 'pdf_')):
- return
- ret = self.items.setdefault( name, ClassExtra())
- if name in state.state_.enums[ tu]:
- #jlib.log( '*** name is an enum: {name=}')
- return None
- if ' ' not in name and not ret.pod and ret.copyable and ret.copyable != 'default':
- # Check whether there is a _keep() fn.
- keep_name = f'fz_keep_{name[3:]}' if name.startswith( 'fz_') else f'pdf_keep_{name[4:]}'
- keep_cursor = state.state_.find_function( tu, keep_name, method=True)
- if not keep_cursor:
- if ret.copyable:
- if 0:
- jlib.log( '*** Changing .copyable to False for {=name keep_name}')
- ret.copyable = False
- return ret
- def get_or_none( self, name):
- return self.items.get( name)
- # Customisation information for selected wrapper classes.
- #
- # We use MuPDF struct names as keys.
- #
- classextras = ClassExtras(
- fz_aa_context = ClassExtra(
- pod='inline',
- ),
- fz_band_writer = ClassExtra(
- class_top = '''
- /* We use these enums to support construction via all the relevant MuPDF functions. */
- enum Cm
- {
- MONO,
- COLOR,
- };
- enum P
- {
- PNG,
- PNM,
- PAM,
- PBM,
- PKM,
- PS,
- PSD,
- };
- ''',
- constructors_extra = [
- ExtraConstructor(
- f'({rename.class_("fz_output")}& out, Cm cm, const {rename.class_("fz_pcl_options")}& options)',
- f'''
- {{
- ::fz_output* out2 = out.m_internal;
- const ::fz_pcl_options* options2 = options.m_internal;
- if (0) {{}}
- else if (cm == MONO) m_internal = {rename.ll_fn('fz_new_mono_pcl_band_writer' )}( out2, options2);
- else if (cm == COLOR) m_internal = {rename.ll_fn('fz_new_color_pcl_band_writer')}( out2, options2);
- else throw std::runtime_error( "Unrecognised fz_band_writer_s Cm type");
- }}
- ''',
- comment = f'/* Constructor using fz_new_mono_pcl_band_writer() or fz_new_color_pcl_band_writer(). */',
- ),
- ExtraConstructor(
- f'({rename.class_("fz_output")}& out, P p)',
- f'''
- {{
- ::fz_output* out2 = out.m_internal;
- if (0) {{}}
- else if (p == PNG) m_internal = {rename.ll_fn('fz_new_png_band_writer')}( out2);
- else if (p == PNM) m_internal = {rename.ll_fn('fz_new_pnm_band_writer')}( out2);
- else if (p == PAM) m_internal = {rename.ll_fn('fz_new_pam_band_writer')}( out2);
- else if (p == PBM) m_internal = {rename.ll_fn('fz_new_pbm_band_writer')}( out2);
- else if (p == PKM) m_internal = {rename.ll_fn('fz_new_pkm_band_writer')}( out2);
- else if (p == PS) m_internal = {rename.ll_fn('fz_new_ps_band_writer' )}( out2);
- else if (p == PSD) m_internal = {rename.ll_fn('fz_new_psd_band_writer')}( out2);
- else throw std::runtime_error( "Unrecognised fz_band_writer_s P type");
- }}
- ''',
- comment = f'/* Constructor using fz_new_p*_band_writer(). */',
- ),
- ExtraConstructor(
- f'({rename.class_("fz_output")}& out, Cm cm, const {rename.class_("fz_pwg_options")}& options)',
- f'''
- {{
- ::fz_output* out2 = out.m_internal;
- const ::fz_pwg_options* options2 = &options.m_internal;
- if (0) {{}}
- else if (cm == MONO) m_internal = {rename.ll_fn('fz_new_mono_pwg_band_writer' )}( out2, options2);
- else if (cm == COLOR) m_internal = {rename.ll_fn('fz_new_pwg_band_writer')}( out2, options2);
- else throw std::runtime_error( "Unrecognised fz_band_writer_s Cm type");
- }}
- ''',
- comment = f'/* Constructor using fz_new_mono_pwg_band_writer() or fz_new_pwg_band_writer(). */',
- ),
- ],
- copyable = False,
- ),
- fz_bitmap = ClassExtra(
- accessors = True,
- ),
- fz_buffer = ClassExtra(
- constructor_raw = 'default',
- constructors_wrappers = [
- 'fz_read_file',
- ],
- ),
- fz_color_params = ClassExtra(
- pod='inline',
- constructors_extra = [
- ExtraConstructor('()',
- f'''
- {{
- this->ri = fz_default_color_params.ri;
- this->bp = fz_default_color_params.bp;
- this->op = fz_default_color_params.op;
- this->opm = fz_default_color_params.opm;
- }}
- ''',
- comment = '/* Equivalent to fz_default_color_params. */',
- ),
- ],
- ),
- fz_colorspace = ClassExtra(
- constructors_extra = [
- ExtraConstructor(
- '(Fixed fixed)',
- f'''
- {{
- if (0) {{}}
- else if ( fixed == Fixed_GRAY) m_internal = {rename.ll_fn( 'fz_device_gray')}();
- else if ( fixed == Fixed_RGB) m_internal = {rename.ll_fn( 'fz_device_rgb' )}();
- else if ( fixed == Fixed_BGR) m_internal = {rename.ll_fn( 'fz_device_bgr' )}();
- else if ( fixed == Fixed_CMYK) m_internal = {rename.ll_fn( 'fz_device_cmyk')}();
- else if ( fixed == Fixed_LAB) m_internal = {rename.ll_fn( 'fz_device_lab' )}();
- else {{
- std::string message = "Unrecognised fixed colorspace id";
- throw {rename.error_class("FZ_ERROR_GENERIC")}(message.c_str());
- }}
- {rename.ll_fn('fz_keep_colorspace')}(m_internal);
- }}
- ''',
- comment = '/* Construct using one of: fz_device_gray(), fz_device_rgb(), fz_device_bgr(), fz_device_cmyk(), fz_device_lab(). */',
- ),
- ],
- constructor_raw=1,
- class_top = '''
- /* We use this enums to support construction via all the relevant MuPDF functions. */
- enum Fixed
- {
- Fixed_GRAY,
- Fixed_RGB,
- Fixed_BGR,
- Fixed_CMYK,
- Fixed_LAB,
- };
- ''',
- ),
- fz_compressed_buffer = ClassExtra(
- methods_extra = [
- ExtraMethod(
- rename.class_('fz_buffer'),
- 'get_buffer()',
- textwrap.dedent(f'''
- {{
- return {rename.class_('fz_buffer')}(
- {rename.ll_fn('fz_keep_buffer')}(m_internal->buffer)
- );
- }}
- '''),
- '/* Returns wrapper class for fz_buffer *m_internal.buffer. */',
- ),
- ],
- ),
- fz_context = ClassExtra(
- copyable = False,
- ),
- fz_cookie = ClassExtra(
- constructors_extra = [
- ExtraConstructor( '()',
- '''
- {
- this->m_internal.abort = 0;
- this->m_internal.progress = 0;
- this->m_internal.progress_max = (size_t) -1;
- this->m_internal.errors = 0;
- this->m_internal.incomplete = 0;
- }
- ''',
- comment = '/* Default constructor sets all fields to default values. */',
- ),
- ],
- constructor_raw = False,
- methods_extra = [
- ExtraMethod(
- 'void',
- 'set_abort()',
- '{ m_internal.abort = 1; }\n',
- '/* Sets m_internal.abort to 1. */',
- ),
- ExtraMethod(
- 'void',
- 'increment_errors(int delta)',
- '{ m_internal.errors += delta; }\n',
- '/* Increments m_internal.errors by <delta>. */',
- ),
- ],
- pod = True,
- # Other code asynchronously writes to our fields, so we are not
- # copyable. todo: maybe tie us to all objects to which we have
- # been associated?
- #
- copyable=False,
- ),
- fz_device = ClassExtra(
- virtual_fnptrs = dict(
- self_ = lambda name: f'(*({rename.class_("fz_device")}2**) ({name} + 1))',
- alloc = textwrap.dedent( f'''
- m_internal = {rename.ll_fn("fz_new_device_of_size")}(
- sizeof(*m_internal) + sizeof({rename.class_("fz_device")}2*)
- );
- *(({rename.class_("fz_device")}2**) (m_internal + 1)) = this;
- '''),
- ),
- constructor_raw = True,
- ),
- fz_document = ClassExtra(
- constructor_excludes = [
- 'fz_new_xhtml_document_from_document',
- ],
- constructor_prefixes = [
- 'fz_open_accelerated_document',
- 'fz_open_document',
- ],
- constructors_extra = [
- ExtraConstructor( f'({rename.class_("pdf_document")}& pdfdocument)',
- f'''
- {{
- m_internal = {rename.ll_fn('fz_keep_document')}(&pdfdocument.m_internal->super);
- }}
- ''',
- f'/* Returns a {rename.class_("fz_document")} for pdfdocument.m_internal.super. */',
- ),
- ],
- constructor_raw = 'default',
- method_wrappers = [
- 'fz_load_outline',
- ],
- method_wrappers_static = [
- 'fz_new_xhtml_document_from_document',
- ],
- ),
- # This is a little complicated. Many of the functions that we would
- # like to wrap to form constructors, have the same set of args. C++
- # does not support named constructors so we differentiate between
- # constructors with identical args using enums.
- #
- # Also, fz_document_writer is not reference counted so the wrapping
- # class is not copyable or assignable, so our normal approach of making
- # static class functions that return a newly constructed instance by
- # value, does not work.
- #
- # So instead we define enums that are passed to our constructors,
- # allowing the constructor to decide which fz_ function to use to
- # create the new fz_document_writer.
- #
- # There should be no commented-out constructors in the generated code
- # marked as 'Disabled because same args as ...'.
- #
- fz_document_writer = ClassExtra(
- class_top = '''
- /* Used for constructor that wraps fz_ functions taking (const char *path, const char *options). */
- enum PathType
- {
- PathType_CBZ,
- PathType_DOCX,
- PathType_ODT,
- PathType_PAM_PIXMAP,
- PathType_PBM_PIXMAP,
- PathType_PCL,
- PathType_PCLM,
- PathType_PDF,
- PathType_PDFOCR,
- PathType_PGM_PIXMAP,
- PathType_PKM_PIXMAP,
- PathType_PNG_PIXMAP,
- PathType_PNM_PIXMAP,
- PathType_PPM_PIXMAP,
- PathType_PS,
- PathType_PWG,
- PathType_SVG,
- };
- /* Used for constructor that wraps fz_ functions taking (Output& out, const char *options). */
- enum OutputType
- {
- OutputType_CBZ,
- OutputType_DOCX,
- OutputType_ODT,
- OutputType_PCL,
- OutputType_PCLM,
- OutputType_PDF,
- OutputType_PDFOCR,
- OutputType_PS,
- OutputType_PWG,
- };
- /* Used for constructor that wraps fz_ functions taking (const char *format, const char *path, const char *options). */
- enum FormatPathType
- {
- FormatPathType_DOCUMENT,
- FormatPathType_TEXT,
- };
- ''',
- # These excludes should match the functions called by the
- # extra constructors defined below. This ensures that we don't
- # generate commented-out constructors with a comment saying
- # 'Disabled because same args as ...'.
- constructor_excludes = [
- 'fz_new_cbz_writer',
- 'fz_new_docx_writer',
- 'fz_new_odt_writer',
- 'fz_new_pam_pixmap_writer',
- 'fz_new_pbm_pixmap_writer',
- 'fz_new_pcl_writer',
- 'fz_new_pclm_writer',
- 'fz_new_pdfocr_writer',
- 'fz_new_pdf_writer',
- 'fz_new_pgm_pixmap_writer',
- 'fz_new_pkm_pixmap_writer',
- 'fz_new_png_pixmap_writer',
- 'fz_new_pnm_pixmap_writer',
- 'fz_new_ppm_pixmap_writer',
- 'fz_new_ps_writer',
- 'fz_new_pwg_writer',
- 'fz_new_svg_writer',
- 'fz_new_cbz_writer_with_output',
- 'fz_new_docx_writer_with_output',
- 'fz_new_odt_writer_with_output',
- 'fz_new_pcl_writer_with_output',
- 'fz_new_pclm_writer_with_output',
- 'fz_new_pdf_writer_with_output',
- 'fz_new_pdfocr_writer_with_output',
- 'fz_new_ps_writer_with_output',
- 'fz_new_pwg_writer_with_output',
- 'fz_new_document_writer',
- 'fz_new_text_writer',
- 'fz_new_document_writer_with_output',
- 'fz_new_text_writer_with_output',
- ],
- copyable=False,
- methods_extra = [
- # 2022-08-26: we used to provide a custom wrapper of
- # fz_begin_page(), but this is not longer necessary
- # because function_wrapper_class_aware_body() knows
- # that fz_begin_page() returns a borrowed reference.
- #
- ],
- constructors_extra = [
- ExtraConstructor(
- '(const char *path, const char *options, PathType path_type)',
- f'''
- {{
- if (0) {{}}
- else if (path_type == PathType_CBZ) m_internal = {rename.ll_fn( 'fz_new_cbz_writer')}(path, options);
- else if (path_type == PathType_DOCX) m_internal = {rename.ll_fn( 'fz_new_docx_writer')}(path, options);
- else if (path_type == PathType_ODT) m_internal = {rename.ll_fn( 'fz_new_odt_writer')}(path, options);
- else if (path_type == PathType_PAM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pam_pixmap_writer')}(path, options);
- else if (path_type == PathType_PBM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pbm_pixmap_writer')}(path, options);
- else if (path_type == PathType_PCL) m_internal = {rename.ll_fn( 'fz_new_pcl_writer')}(path, options);
- else if (path_type == PathType_PCLM) m_internal = {rename.ll_fn( 'fz_new_pclm_writer')}(path, options);
- else if (path_type == PathType_PDF) m_internal = {rename.ll_fn( 'fz_new_pdf_writer')}(path, options);
- else if (path_type == PathType_PDFOCR) m_internal = {rename.ll_fn( 'fz_new_pdfocr_writer')}(path, options);
- else if (path_type == PathType_PGM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pgm_pixmap_writer')}(path, options);
- else if (path_type == PathType_PKM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pkm_pixmap_writer')}(path, options);
- else if (path_type == PathType_PNG_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_png_pixmap_writer')}(path, options);
- else if (path_type == PathType_PNM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pnm_pixmap_writer')}(path, options);
- else if (path_type == PathType_PPM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_ppm_pixmap_writer')}(path, options);
- else if (path_type == PathType_PS) m_internal = {rename.ll_fn( 'fz_new_ps_writer')}(path, options);
- else if (path_type == PathType_PWG) m_internal = {rename.ll_fn( 'fz_new_pwg_writer')}(path, options);
- else if (path_type == PathType_SVG) m_internal = {rename.ll_fn( 'fz_new_svg_writer')}(path, options);
- else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised Type value");
- }}
- ''',
- comment = textwrap.dedent('''
- /* Constructor using one of:
- fz_new_cbz_writer()
- fz_new_docx_writer()
- fz_new_odt_writer()
- fz_new_pam_pixmap_writer()
- fz_new_pbm_pixmap_writer()
- fz_new_pcl_writer()
- fz_new_pclm_writer()
- fz_new_pdf_writer()
- fz_new_pdfocr_writer()
- fz_new_pgm_pixmap_writer()
- fz_new_pkm_pixmap_writer()
- fz_new_png_pixmap_writer()
- fz_new_pnm_pixmap_writer()
- fz_new_ppm_pixmap_writer()
- fz_new_ps_writer()
- fz_new_pwg_writer()
- fz_new_svg_writer()
- */'''),
- ),
- ExtraConstructor(
- f'({rename.class_("fz_output")}& out, const char *options, OutputType output_type)',
- f'''
- {{
- /* All fz_new_*_writer_with_output() functions take
- ownership of the fz_output, even if they throw an
- exception. So we need to set out.m_internal to null
- here so its destructor does nothing. */
- ::fz_output* out2 = out.m_internal;
- out.m_internal = NULL;
- if (0) {{}}
- else if (output_type == OutputType_CBZ) m_internal = {rename.ll_fn( 'fz_new_cbz_writer_with_output')}(out2, options);
- else if (output_type == OutputType_DOCX) m_internal = {rename.ll_fn( 'fz_new_docx_writer_with_output')}(out2, options);
- else if (output_type == OutputType_ODT) m_internal = {rename.ll_fn( 'fz_new_odt_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PCL) m_internal = {rename.ll_fn( 'fz_new_pcl_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PCLM) m_internal = {rename.ll_fn( 'fz_new_pclm_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PDF) m_internal = {rename.ll_fn( 'fz_new_pdf_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PDFOCR) m_internal = {rename.ll_fn( 'fz_new_pdfocr_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PS) m_internal = {rename.ll_fn( 'fz_new_ps_writer_with_output')}(out2, options);
- else if (output_type == OutputType_PWG) m_internal = {rename.ll_fn( 'fz_new_pwg_writer_with_output')}(out2, options);
- else
- {{
- /* Ensure that out2 is dropped before we return. */
- {rename.ll_fn( 'fz_drop_output')}(out2);
- throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised OutputType value");
- }}
- }}
- ''',
- comment = textwrap.dedent('''
- /* Constructor using one of:
- fz_new_cbz_writer_with_output()
- fz_new_docx_writer_with_output()
- fz_new_odt_writer_with_output()
- fz_new_pcl_writer_with_output()
- fz_new_pclm_writer_with_output()
- fz_new_pdf_writer_with_output()
- fz_new_pdfocr_writer_with_output()
- fz_new_ps_writer_with_output()
- fz_new_pwg_writer_with_output()
- This constructor takes ownership of <out> -
- out.m_internal is set to NULL after this constructor
- returns so <out> must not be used again.
- */
- '''),
- ),
- ExtraConstructor(
- '(const char *format, const char *path, const char *options, FormatPathType format_path_type)',
- f'''
- {{
- if (0) {{}}
- else if (format_path_type == FormatPathType_DOCUMENT) m_internal = {rename.ll_fn( 'fz_new_document_writer')}(format, path, options);
- else if (format_path_type == FormatPathType_TEXT) m_internal = {rename.ll_fn( 'fz_new_text_writer')}(format, path, options);
- else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised OutputType value");
- }}
- ''',
- comment = textwrap.dedent('''
- /* Constructor using one of:
- fz_new_document_writer()
- fz_new_text_writer()
- */'''),
- ),
- ExtraConstructor(
- f'({rename.class_("fz_output")}& out, const char *format, const char *options)',
- f'''
- {{
- /* Need to transfer ownership of <out>. */
- ::fz_output* out2 = out.m_internal;
- out.m_internal = NULL;
- m_internal = {rename.ll_fn( 'fz_new_document_writer_with_output')}(out2, format, options);
- }}
- ''',
- comment = textwrap.dedent('''
- /* Constructor using fz_new_document_writer_with_output().
- This constructor takes ownership of <out> -
- out.m_internal is set to NULL after this constructor
- returns so <out> must not be used again.
- */'''),
- ),
- ExtraConstructor(
- f'(const char *format, {rename.class_("fz_output")}& out, const char *options)',
- f'''
- {{
- /* Need to transfer ownership of <out>. */
- ::fz_output* out2 = out.m_internal;
- out.m_internal = NULL;
- m_internal = {rename.ll_fn( 'fz_new_text_writer_with_output')}(format, out2, options);
- }}
- ''',
- comment = textwrap.dedent('''
- /* Constructor using fz_new_text_writer_with_output().
- This constructor takes ownership of <out> -
- out.m_internal is set to NULL after this constructor
- returns so <out> must not be used again.
- */'''),
- ),
- ],
- ),
- fz_draw_options = ClassExtra(
- constructors_wrappers = [
- 'fz_parse_draw_options',
- ],
- copyable=False,
- pod='inline',
- ),
- fz_halftone = ClassExtra(
- constructor_raw = 'default',
- ),
- fz_image = ClassExtra(
- accessors=True,
- ),
- fz_install_load_system_font_funcs_args = ClassExtra(
- pod = True,
- virtual_fnptrs = dict(
- alloc = textwrap.dedent( f'''
- /*
- There can only be one active instance of the wrapper
- class so we simply keep a pointer to it in a global
- variable.
- */
- fz_install_load_system_font_funcs2_state = this;
- '''),
- self_ = lambda: f'({rename.class_("fz_install_load_system_font_funcs_args")}2*) fz_install_load_system_font_funcs2_state',
- self_n = None,
- ),
- ),
- fz_irect = ClassExtra(
- constructor_prefixes = [
- 'fz_irect_from_rect',
- 'fz_make_irect',
- ],
- pod='inline',
- constructor_raw = True,
- ),
- fz_link = ClassExtra(
- constructors_extra = [
- ExtraConstructor( f'({rename.class_("fz_rect")}& rect, const char *uri)',
- f'''
- {{
- m_internal = {rename.ll_fn('fz_new_link_of_size')}( sizeof(fz_link), *rect.internal(), uri);
- }}
- ''',
- '/* Construct by calling fz_new_link_of_size() with size=sizeof(fz_link). */',
- )
- ],
- accessors = True,
- iterator_next = ('', ''),
- constructor_raw = 'default',
- copyable = True,
- ),
- fz_location = ClassExtra(
- constructor_prefixes = [
- 'fz_make_location',
- ],
- pod='inline',
- constructor_raw = True,
- ),
- fz_matrix = ClassExtra(
- constructor_prefixes = [
- 'fz_make_matrix',
- ],
- method_wrappers_static = [
- 'fz_concat',
- 'fz_scale',
- 'fz_shear',
- 'fz_rotate',
- 'fz_translate',
- 'fz_transform_page',
- ],
- constructors_extra = [
- ExtraConstructor( '()',
- '''
- : a(1), b(0), c(0), d(1), e(0), f(0)
- {
- }
- ''',
- comment = '/* Constructs identity matrix (like fz_identity). */'),
- ],
- pod='inline',
- constructor_raw = True,
- ),
- fz_md5 = ClassExtra(
- pod = True,
- constructors_extra = [
- ExtraConstructor(
- '()',
- f'''
- {{
- {rename.ll_fn( 'fz_md5_init')}( &m_internal);
- }}
- ''',
- '/* Default constructor calls md5_init(). */',
- )
- ],
- ),
- fz_outline = ClassExtra(
- # We add various methods to give depth-first iteration of outlines.
- #
- constructor_prefixes = [
- 'fz_load_outline',
- ],
- accessors=True,
- ),
- fz_outline_item = ClassExtra(
- class_top = f'''
- FZ_FUNCTION bool valid() const;
- FZ_FUNCTION const std::string& title() const; /* Will throw if valid() is not true. */
- FZ_FUNCTION const std::string& uri() const; /* Will throw if valid() is not true. */
- FZ_FUNCTION int is_open() const; /* Will throw if valid() is not true. */
- ''',
- class_bottom = f'''
- private:
- bool m_valid;
- std::string m_title;
- std::string m_uri;
- int m_is_open;
- ''',
- constructors_extra = [
- ],
- constructor_raw = 'declaration_only',
- copyable = 'default',
- pod = 'none',
- extra_cpp = f'''
- FZ_FUNCTION {rename.class_("fz_outline_item")}::{rename.class_("fz_outline_item")}(const ::fz_outline_item* item)
- {{
- if (item)
- {{
- m_valid = true;
- m_title = item->title;
- m_uri = item->uri;
- m_is_open = item->is_open;
- }}
- else
- {{
- m_valid = false;
- }}
- }}
- FZ_FUNCTION bool {rename.class_("fz_outline_item")}::valid() const
- {{
- return m_valid;
- }}
- FZ_FUNCTION const std::string& {rename.class_("fz_outline_item")}::title() const
- {{
- if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid");
- return m_title;
- }}
- FZ_FUNCTION const std::string& {rename.class_("fz_outline_item")}::uri() const
- {{
- if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid");
- return m_uri;
- }}
- FZ_FUNCTION int {rename.class_("fz_outline_item")}::is_open() const
- {{
- if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid");
- return m_is_open;
- }}
- ''',
- ),
- fz_outline_iterator = ClassExtra(
- copyable = False,
- methods_extra = [
- ExtraMethod(
- 'int',
- f'{rename.method("fz_outline_iterator", "fz_outline_iterator_insert")}({rename.class_("fz_outline_item")}& item)',
- f'''
- {{
- /* Create a temporary fz_outline_item. */
- ::fz_outline_item item2;
- item2.title = (char*) item.title().c_str();
- item2.uri = (char*) item.uri().c_str();
- item2.is_open = item.is_open();
- return {rename.ll_fn("fz_outline_iterator_insert")}(m_internal, &item2);
- }}
- ''',
- comment = '/* Custom wrapper for fz_outline_iterator_insert(). */',
- ),
- ExtraMethod(
- 'void',
- f'{rename.method("fz_outline_iterator", "fz_outline_iterator_update")}({rename.class_("fz_outline_item")}& item)',
- f'''
- {{
- /* Create a temporary fz_outline_item. */
- ::fz_outline_item item2;
- item2.title = (char*) item.title().c_str();
- item2.uri = (char*) item.uri().c_str();
- item2.is_open = item.is_open();
- return {rename.ll_fn("fz_outline_iterator_update")}(m_internal, &item2);
- }}
- ''',
- comment = '/* Custom wrapper for fz_outline_iterator_update(). */',
- ),
- ],
- ),
- fz_output = ClassExtra(
- virtual_fnptrs = dict(
- self_ = lambda name: f'({rename.class_("fz_output")}2*) {name}',
- alloc = f'm_internal = {rename.ll_fn("fz_new_output")}(0 /*bufsize*/, this /*state*/, nullptr /*write*/, nullptr /*close*/, nullptr /*drop*/);\n',
- ),
- constructor_raw = 'default',
- constructor_excludes = [
- # These all have the same prototype, so are used by
- # constructors_extra below.
- 'fz_new_asciihex_output',
- 'fz_new_ascii85_output',
- 'fz_new_rle_output',
- ],
- constructors_extra = [
- ExtraConstructor( '(Fixed out)',
- f'''
- {{
- if (0) {{}}
- else if (out == Fixed_STDOUT) {{
- m_internal = {rename.ll_fn('fz_stdout')}();
- }}
- else if (out == Fixed_STDERR) {{
- m_internal = {rename.ll_fn('fz_stderr')}();
- }}
- else {{
- throw {rename.error_class('FZ_ERROR_ABORT')}("Unrecognised Fixed value");
- }}
- }}
- ''',
- '/* Uses fz_stdout() or fz_stderr(). */',
- # Note that it's ok to call fz_drop_output() on fz_stdout and fz_stderr.
- ),
- ExtraConstructor(
- f'(const {rename.class_("fz_output")}& chain, Filter filter)',
- f'''
- {{
- if (0) {{}}
- else if (filter == Filter_HEX) {{
- m_internal = {rename.ll_fn('fz_new_asciihex_output')}(chain.m_internal);
- }}
- else if (filter == Filter_85) {{
- m_internal = {rename.ll_fn('fz_new_ascii85_output')}(chain.m_internal);
- }}
- else if (filter == Filter_RLE) {{
- m_internal = {rename.ll_fn('fz_new_rle_output')}(chain.m_internal);
- }}
- else {{
- throw {rename.error_class('FZ_ERROR_ABORT')}("Unrecognised Filter value");
- }}
- }}
- ''',
- comment = '/* Calls one of: fz_new_asciihex_output(), fz_new_ascii85_output(), fz_new_rle_output(). */',
- ),
- ],
- class_top = '''
- enum Fixed
- {
- Fixed_STDOUT=1,
- Fixed_STDERR=2,
- };
- enum Filter
- {
- Filter_HEX,
- Filter_85,
- Filter_RLE,
- };
- '''
- ,
- copyable=False, # No fz_keep_output() fn?
- ),
- fz_page = ClassExtra(
- constructor_prefixes = [
- 'fz_load_page',
- 'fz_load_chapter_page',
- ],
- constructors_extra = [
- ExtraConstructor( f'({rename.class_("pdf_page")}& pdfpage)',
- f'''
- {{
- m_internal = {rename.ll_fn('fz_keep_page')}(&pdfpage.m_internal->super);
- }}
- ''',
- f'/* Return {rename.class_("fz_page")} for pdfpage.m_internal.super. */',
- ),
- ],
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("fz_document")}',
- 'doc()',
- f'''
- {{
- return {rename.class_("fz_document")}( {rename.ll_fn('fz_keep_document')}( m_internal->doc));
- }}
- ''',
- f'/* Returns wrapper for .doc member. */',
- ),
- ],
- constructor_raw = True,
- ),
- fz_path_walker = ClassExtra(
- constructor_raw = 'default',
- virtual_fnptrs = dict(
- self_ = lambda name: f'*({rename.class_("fz_path_walker")}2**) ((fz_path_walker*) {name} + 1)',
- alloc = textwrap.dedent( f'''
- m_internal = (::fz_path_walker*) {rename.ll_fn("fz_calloc")}(
- 1,
- sizeof(*m_internal) + sizeof({rename.class_("fz_path_walker")}2*)
- );
- *({rename.class_("fz_path_walker")}2**) (m_internal + 1) = this;
- '''),
- free = f'{rename.ll_fn("fz_free")}(m_internal);\n',
- comment = textwrap.dedent(f'''
- /*
- We require that the `void* arg` passed to callbacks
- is the original `fz_path_walker*`. So, for example,
- class-aware wrapper mupdf::fz_walk_path() should be
- called like:
- mupdf.FzPath path = ...;
- struct Walker : mupdf.FzPathWalker2 {...};
- Walker walker(...);
- mupdf::fz_walk_path(path, walker, walker.m_internal);
- */
- ''')
- ),
- ),
- fz_pcl_options = ClassExtra(
- constructors_wrappers = [
- 'fz_parse_pcl_options',
- ],
- copyable=False,
- ),
- fz_pclm_options = ClassExtra(
- constructor_prefixes = [
- 'fz_parse_pclm_options',
- ],
- copyable=False,
- constructors_extra = [
- ExtraConstructor( '(const char *args)',
- f'''
- {{
- {rename.ll_fn('fz_parse_pclm_options')}(m_internal, args);
- }}
- ''',
- '/* Construct using fz_parse_pclm_options(). */',
- )
- ],
- ),
- fz_pdfocr_options = ClassExtra(
- pod = 'inline',
- methods_extra = [
- ExtraMethod(
- 'void',
- 'language_set2(const char* language)',
- f'''
- {{
- fz_strlcpy(this->language, language, sizeof(this->language));
- }}
- ''',
- '/* Copies <language> into this->language, truncating if necessary. */',
- ),
- ExtraMethod(
- 'void',
- 'datadir_set2(const char* datadir)',
- f'''
- {{
- fz_strlcpy(this->datadir, datadir, sizeof(this->datadir));
- }}
- ''',
- '/* Copies <datadir> into this->datadir, truncating if necessary. */',
- ),
- ],
- ),
- fz_pixmap = ClassExtra(
- constructor_raw = True,
- accessors = True,
- ),
- fz_point = ClassExtra(
- method_wrappers_static = [
- 'fz_transform_point',
- 'fz_transform_point_xy',
- 'fz_transform_vector',
- ],
- constructors_extra = [
- ExtraConstructor( '(float x, float y)',
- '''
- : x(x), y(y)
- {
- }
- ''',
- comment = '/* Construct using specified values. */',
- ),
- ],
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("fz_point")}&',
- f'transform(const {rename.class_("fz_matrix")}& m)',
- '''
- {
- double old_x = x;
- x = old_x * m.a + y * m.c + m.e;
- y = old_x * m.b + y * m.d + m.f;
- return *this;
- }
- ''',
- comment = '/* Post-multiply *this by <m> and return *this. */',
- ),
- ],
- pod='inline',
- constructor_raw = True,
- ),
- fz_pwg_options = ClassExtra(
- pod=True,
- ),
- fz_quad = ClassExtra(
- constructor_prefixes = [
- 'fz_transform_quad',
- 'fz_quad_from_rect'
- ],
- pod='inline',
- constructor_raw = True,
- ),
- fz_rect = ClassExtra(
- constructor_prefixes = [
- 'fz_transform_rect',
- 'fz_bound_display_list',
- 'fz_rect_from_irect',
- 'fz_rect_from_quad',
- ],
- method_wrappers_static = [
- 'fz_intersect_rect',
- 'fz_union_rect',
- ],
- constructors_extra = [
- ExtraConstructor(
- '(double x0, double y0, double x1, double y1)',
- '''
- :
- x0(x0),
- x1(x1),
- y0(y0),
- y1(y1)
- {
- }
- ''',
- comment = '/* Construct from specified values. */',
- ),
- ExtraConstructor(
- f'(const {rename.class_("fz_rect")}& rhs)',
- '''
- :
- x0(rhs.x0),
- y0(rhs.y0),
- x1(rhs.x1),
- y1(rhs.y1)
- {
- }
- ''',
- comment = '/* Copy constructor using plain copy. */',
- ),
- ExtraConstructor( '(Fixed fixed)',
- f'''
- {{
- if (0) {{}}
- else if (fixed == Fixed_UNIT) *this->internal() = {rename.c_fn('fz_unit_rect')};
- else if (fixed == Fixed_EMPTY) *this->internal() = {rename.c_fn('fz_empty_rect')};
- else if (fixed == Fixed_INFINITE) *this->internal() = {rename.c_fn('fz_infinite_rect')};
- else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised From value");
- }}
- ''',
- comment = '/* Construct from fz_unit_rect, fz_empty_rect or fz_infinite_rect. */',
- ),
- ],
- methods_extra = [
- ExtraMethod(
- 'void',
- f'transform(const {rename.class_("fz_matrix")}& m)',
- f'''
- {{
- *(::fz_rect*) &this->x0 = {rename.c_fn('fz_transform_rect')}(*(::fz_rect*) &this->x0, *(::fz_matrix*) &m.a);
- }}
- ''',
- comment = '/* Transforms *this using fz_transform_rect() with <m>. */',
- ),
- ExtraMethod( 'bool', 'contains(double x, double y)',
- '''
- {
- if (is_empty()) {
- return false;
- }
- return true
- && x >= x0
- && x < x1
- && y >= y0
- && y < y1
- ;
- }
- ''',
- comment = '/* Convenience method using fz_contains_rect(). */',
- ),
- ExtraMethod( 'bool', f'contains({rename.class_("fz_rect")}& rhs)',
- f'''
- {{
- return {rename.c_fn('fz_contains_rect')}(*(::fz_rect*) &x0, *(::fz_rect*) &rhs.x0);
- }}
- ''',
- comment = '/* Uses fz_contains_rect(*this, rhs). */',
- ),
- ExtraMethod( 'bool', 'is_empty()',
- f'''
- {{
- return {rename.c_fn('fz_is_empty_rect')}(*(::fz_rect*) &x0);
- }}
- ''',
- comment = '/* Uses fz_is_empty_rect(). */',
- ),
- ExtraMethod( 'void', f'union_({rename.class_("fz_rect")}& rhs)',
- f'''
- {{
- *(::fz_rect*) &x0 = {rename.c_fn('fz_union_rect')}(*(::fz_rect*) &x0, *(::fz_rect*) &rhs.x0);
- }}
- ''',
- comment = '/* Updates *this using fz_union_rect(). */',
- ),
- ],
- pod='inline',
- constructor_raw = True,
- copyable = True,
- class_top = '''
- enum Fixed
- {
- Fixed_UNIT,
- Fixed_EMPTY,
- Fixed_INFINITE,
- };
- ''',
- ),
- fz_separations = ClassExtra(
- constructor_raw = 'default',
- opaque = True,
- ),
- fz_shade = ClassExtra(
- methods_extra = [
- ExtraMethod( 'void',
- f'{rename.method( "fz_shade", "fz_paint_shade_no_cache")}('
- + f' const {rename.class_("fz_colorspace")}& override_cs'
- + f', {rename.class_("fz_matrix")}& ctm'
- + f', const {rename.class_("fz_pixmap")}& dest'
- + f', {rename.class_("fz_color_params")}& color_params'
- + f', {rename.class_("fz_irect")}& bbox'
- + f', const {rename.class_("fz_overprint")}& eop'
- + f')'
- ,
- f'''
- {{
- return {rename.ll_fn('fz_paint_shade')}(
- this->m_internal,
- override_cs.m_internal,
- *(::fz_matrix*) &ctm.a,
- dest.m_internal,
- *(::fz_color_params*) &color_params.ri,
- *(::fz_irect*) &bbox.x0,
- eop.m_internal,
- NULL /*cache*/
- );
- }}
- ''',
- comment = f'/* Extra wrapper for fz_paint_shade(), passing cache=NULL. */',
- ),
- ],
- ),
- fz_shade_color_cache = ClassExtra(
- ),
- # Our wrappers of the fz_stext_* structs all have a default copy
- # constructor - there are no fz_keep_stext_*() functions.
- #
- # We define explicit accessors for fz_stext_block::u.i.* because SWIG
- # does not handle nested unions.
- #
- fz_stext_block = ClassExtra(
- iterator_next = ('u.t.first_line', 'u.t.last_line'),
- copyable='default',
- methods_extra = [
- ExtraMethod( f'{rename.class_("fz_matrix")}', 'i_transform()',
- f'''
- {{
- if (m_internal->type != FZ_STEXT_BLOCK_IMAGE) {{
- throw std::runtime_error("Not an image");
- }}
- return m_internal->u.i.transform;
- }}
- ''',
- comment=f'/* Returns m_internal.u.i.transform if m_internal->type is FZ_STEXT_BLOCK_IMAGE, else throws. */',
- ),
- ExtraMethod( f'{rename.class_("fz_image")}', 'i_image()',
- f'''
- {{
- if (m_internal->type != FZ_STEXT_BLOCK_IMAGE) {{
- throw std::runtime_error("Not an image");
- }}
- return {rename.class_("fz_image")}({rename.ll_fn('fz_keep_image')}(m_internal->u.i.image));
- }}
- ''',
- comment=f'/* Returns m_internal.u.i.image if m_internal->type is FZ_STEXT_BLOCK_IMAGE, else throws. */',
- ),
- ],
- ),
- fz_stext_char = ClassExtra(
- copyable='default',
- ),
- fz_stext_line = ClassExtra(
- iterator_next = ('first_char', 'last_char'),
- copyable='default',
- constructor_raw=True,
- ),
- fz_stext_options = ClassExtra(
- constructors_extra = [
- ExtraConstructor( '(int flags, float scale=1.0)',
- '''
- :
- flags(flags),
- scale(scale)
- {
- assert(!(flags & FZ_STEXT_CLIP_RECT));
- }
- ''',
- comment = '/* Construct with .flags, .scale but no clip. */',
- ),
- ExtraConstructor( '(int flags, fz_rect clip, float scale=1.0)',
- '''
- :
- flags(flags | FZ_STEXT_CLIP_RECT),
- scale(scale),
- clip(clip)
- {
- }
- ''',
- comment =
- '/* Construct with .flags, .scale and .clip; FZ_STEXT_CLIP_RECT\n'
- 'is automatically set in .flags. */'
- ,
- ),
- ],
- pod='inline',
- ),
- fz_stext_page = ClassExtra(
- methods_extra = [
- ExtraMethod(
- 'std::string',
- f'{rename.method( "fz_stext_page", "fz_copy_selection")}('
- + f'{rename.class_("fz_point")}& a'
- + f', {rename.class_("fz_point")}& b'
- + f', int crlf'
- + f')',
- f'''
- {{
- char* text = {rename.ll_fn('fz_copy_selection')}(m_internal, *(::fz_point *) &a.x, *(::fz_point *) &b.x, crlf);
- std::string ret(text);
- {rename.ll_fn('fz_free')}(text);
- return ret;
- }}
- ''',
- comment = f'/* Wrapper for fz_copy_selection() that returns std::string. */',
- ),
- ExtraMethod(
- 'std::string',
- f'{rename.method( "fz_stext_page", "fz_copy_rectangle")}({rename.class_("fz_rect")}& area, int crlf)',
- f'''
- {{
- char* text = {rename.ll_fn('fz_copy_rectangle')}(m_internal, *(::fz_rect*) &area.x0, crlf);
- std::string ret(text);
- {rename.ll_fn('fz_free')}(text);
- return ret;
- }}
- ''',
- comment = f'/* Wrapper for fz_copy_rectangle() that returns a std::string. */',
- ),
- ExtraMethod(
- f'std::vector<{rename.class_("fz_quad")}>',
- f'{rename.method( "fz_stext_page", "search_stext_page")}(const char* needle, int *hit_mark, int max_quads)',
- f'''
- {{
- std::vector<{rename.class_("fz_quad")}> ret(max_quads);
- int n = {rename.ll_fn('fz_search_stext_page')}(m_internal, needle, hit_mark, ret[0].internal(), max_quads);
- ret.resize(n);
- return ret;
- }}
- ''',
- '/* Wrapper for fz_search_stext_page() that returns std::vector of Quads. */',
- )
- ],
- iterator_next = ('first_block', 'last_block'),
- copyable=False,
- constructor_raw = True,
- ),
- fz_text_span = ClassExtra(
- copyable=False,
- methods_extra = [
- # We provide class-aware accessors where possible. (Some
- # types' wrapper classes are not copyable so we can't do
- # this for all data).
- ExtraMethod(
- f'{rename.class_("fz_font")}',
- f'font()',
- f'''
- {{
- return {rename.class_("fz_font")}( ll_fz_keep_font( m_internal->font));
- }}
- ''',
- f'/* Gives class-aware access to m_internal->font. */',
- ),
- ExtraMethod(
- f'{rename.class_("fz_matrix")}',
- f'trm()',
- f'''
- {{
- return {rename.class_("fz_matrix")}( m_internal->trm);
- }}
- ''',
- f'/* Gives class-aware access to m_internal->trm. */',
- ),
- ExtraMethod(
- f'fz_text_item&',
- f'items( int i)',
- f'''
- {{
- assert( i < m_internal->len);
- return m_internal->items[i];
- }}
- ''',
- '''
- /* Gives access to m_internal->items[i].
- Returned reference is only valid as long as `this`.
- Provided mainly for use by SWIG bindings.
- */
- ''',
- ),
- ],
- ),
- fz_stream = ClassExtra(
- constructor_prefixes = [
- 'fz_open_file',
- 'fz_open_memory',
- ],
- constructors_extra = [
- ExtraConstructor( '(const std::string& filename)',
- f'''
- : m_internal({rename.ll_fn('fz_open_file')}(filename.c_str()))
- {{
- }}
- ''',
- comment = '/* Construct using fz_open_file(). */',
- )
- ],
- ),
- fz_story_element_position = ClassExtra(
- pod='inline',
- ),
- fz_transition = ClassExtra(
- pod='inline',
- constructor_raw = True,
- ),
- pdf_annot = ClassExtra(
- constructor_raw = 'default',
- ),
- pdf_clean_options = ClassExtra(
- constructors_extra = [
- ExtraConstructor( '()',
- f'''
- {{
- /* Use memcpy() otherwise we get 'invalid array assignment' errors. */
- memcpy(&this->internal()->write, &pdf_default_write_options, sizeof(this->internal()->write));
- memset(&this->internal()->image, 0, sizeof(this->internal()->image));
- }}
- ''',
- comment = '/* Default constructor, makes copy of pdf_default_write_options. */'
- ),
- ExtraConstructor(
- f'(const {rename.class_("pdf_clean_options")}& rhs)',
- f'''
- {{
- *this = rhs;
- }}
- ''',
- comment = '/* Copy constructor using raw memcopy(). */'
- ),
- ],
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("pdf_clean_options")}&',
- f'operator=(const {rename.class_("pdf_clean_options")}& rhs)',
- f'''
- {{
- memcpy(this->internal(), rhs.internal(), sizeof(*this->internal()));
- return *this;
- }}
- ''',
- comment = '/* Assignment using plain memcpy(). */',
- ),
- ExtraMethod(
- f'void',
- f'write_opwd_utf8_set(const std::string& text)',
- f'''
- {{
- size_t len = std::min(text.size(), sizeof(write.opwd_utf8) - 1);
- memcpy(write.opwd_utf8, text.c_str(), len);
- write.opwd_utf8[len] = 0;
- }}
- ''',
- '/* Copies <text> into write.opwd_utf8[]. */',
- ),
- ExtraMethod(
- f'void',
- f'write_upwd_utf8_set(const std::string& text)',
- f'''
- {{
- size_t len = std::min(text.size(), sizeof(write.upwd_utf8) - 1);
- memcpy(write.upwd_utf8, text.c_str(), len);
- write.upwd_utf8[len] = 0;
- }}
- ''',
- '/* Copies <text> into upwd_utf8[]. */',
- ),
- ],
- pod = 'inline',
- copyable = 'default',
- ),
- pdf_document = ClassExtra(
- constructor_prefixes = [
- 'pdf_open_document',
- 'pdf_create_document',
- 'pdf_document_from_fz_document',
- ],
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("fz_document")}',
- 'super()',
- f'''
- {{
- return {rename.class_("fz_document")}( {rename.ll_fn('fz_keep_document')}( &m_internal->super));
- }}
- ''',
- f'/* Returns wrapper for .super member. */',
- ),
- ],
- ),
- pdf_filter_factory = ClassExtra(
- pod = 'inline',
- virtual_fnptrs = dict(
- self_ = lambda name: f'({rename.class_("pdf_filter_factory")}2*) {name}',
- self_n = 6,
- alloc = f'this->options = this;\n',
- ),
- ),
- pdf_filter_options = ClassExtra(
- pod = 'inline',
- # We don't need to allocate extra space, and because we are a
- # POD class, we can simply let our default constructor run.
- #
- # this->opaque is passed as arg[2].
- #
- virtual_fnptrs = dict(
- self_ = lambda name: f'({rename.class_("pdf_filter_options")}2*) {name}',
- self_n = 2,
- alloc = f'this->opaque = this;\n',
- ),
- constructors_extra = [
- ExtraConstructor( '()',
- f'''
- {{
- this->recurse = 0;
- this->instance_forms = 0;
- this->ascii = 0;
- this->opaque = nullptr;
- this->complete = nullptr;
- this->filters = nullptr;
- pdf_filter_factory eof = {{ nullptr, nullptr}};
- m_filters.push_back( eof);
- this->newlines = 0;
- }}
- ''',
- comment = '/* Default constructor initialises all fields to null/zero. */',
- )
- ],
- methods_extra = [
- ExtraMethod(
- 'void',
- f'add_factory( const pdf_filter_factory& factory)',
- textwrap.dedent( f'''
- {{
- this->m_filters.back() = factory;
- pdf_filter_factory eof = {{ nullptr, nullptr}};
- this->m_filters.push_back( eof);
- this->filters = &this->m_filters[0];
- }}
- '''),
- comment = f'/* Appends `factory` to internal vector and updates this->filters. */',
- ),
- ],
- class_bottom = textwrap.dedent( f'''
- std::vector< pdf_filter_factory> m_filters;
- '''),
- ),
- pdf_lexbuf = ClassExtra(
- constructors_extra = [
- ExtraConstructor( '(int size)',
- f'''
- {{
- m_internal = new ::pdf_lexbuf;
- {rename.ll_fn('pdf_lexbuf_init')}(m_internal, size);
- }}
- ''',
- comment = '/* Constructor that calls pdf_lexbuf_init(size). */',
- ),
- ],
- methods_extra = [
- ExtraMethod(
- '',
- '~()',
- f'''
- {{
- {rename.ll_fn('pdf_lexbuf_fin')}(m_internal);
- delete m_internal;
- }}
- ''',
- comment = '/* Destructor that calls pdf_lexbuf_fin(). */',
- ),
- ],
- ),
- pdf_layer_config = ClassExtra(
- pod = 'inline',
- ),
- pdf_layer_config_ui = ClassExtra(
- pod = 'inline',
- constructors_extra = [
- ExtraConstructor( '()',
- f'''
- {{
- this->text = nullptr;
- this->depth = 0;
- this->type = PDF_LAYER_UI_LABEL;
- this->selected = 0;
- this->locked = 0;
- }}
- ''',
- comment = '/* Default constructor sets .text to null, .type to PDF_LAYER_UI_LABEL, and other fields to zero. */',
- ),
- ],
- ),
- pdf_obj = ClassExtra(
- constructor_raw = 'default',
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("pdf_obj")}',
- f'{rename.method( "pdf_obj", "pdf_dict_get")}(int key)',
- f'''
- {{
- ::pdf_obj* temp = {rename.ll_fn('pdf_dict_get')}(this->m_internal, (::pdf_obj*)(uintptr_t) key);
- {rename.ll_fn('pdf_keep_obj')}(temp);
- auto ret = {rename.class_('pdf_obj')}(temp);
- return ret;
- }}
- ''',
- comment = '/* Typesafe wrapper for looking up things such as PDF_ENUM_NAME_Annots. */',
- overload=True,
- ),
- ExtraMethod(
- f'std::string',
- f'{rename.method( "pdf_obj", "pdf_load_field_name2")}()',
- f'''
- {{
- return {rename.namespace_fn('pdf_load_field_name2')}( *this);
- }}
- ''',
- comment = f'/* Alternative to `{rename.fn("pdf_load_field_name")}()` that returns a std::string. */',
- ),
- ]
- ),
- pdf_page = ClassExtra(
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("fz_page")}',
- 'super()',
- f'''
- {{
- return {rename.class_("fz_page")}( {rename.ll_fn('fz_keep_page')}( &m_internal->super));
- }}
- ''',
- f'/* Returns wrapper for .super member. */',
- ),
- ExtraMethod(
- f'{rename.class_("pdf_document")}',
- 'doc()',
- f'''
- {{
- return {rename.class_("pdf_document")}( {rename.ll_fn('pdf_keep_document')}( m_internal->doc));
- }}
- ''',
- f'/* Returns wrapper for .doc member. */',
- ),
- ExtraMethod(
- f'{rename.class_("pdf_obj")}',
- 'obj()',
- f'''
- {{
- return {rename.class_("pdf_obj")}( {rename.ll_fn('pdf_keep_obj')}( m_internal->obj));
- }}
- ''',
- f'/* Returns wrapper for .obj member. */',
- ),
- ],
- ),
- pdf_image_rewriter_options = ClassExtra(
- pod = 'inline',
- copyable = 'default',
- ),
- pdf_processor = ClassExtra(
- virtual_fnptrs = dict(
- self_ = lambda name: f'(*({rename.class_("pdf_processor")}2**) ({name} + 1))',
- alloc = textwrap.dedent( f'''
- m_internal = (::pdf_processor*) {rename.ll_fn("pdf_new_processor")}(
- sizeof(*m_internal)
- + sizeof({rename.class_("pdf_processor")}2*)
- );
- *(({rename.class_("pdf_processor")}2**) (m_internal + 1)) = this;
- '''),
- ),
- ),
- pdf_recolor_options = ClassExtra(
- pod = 'inline',
- ),
- pdf_redact_options = ClassExtra(
- pod = 'inline',
- ),
- pdf_sanitize_filter_options = ClassExtra(
- pod = 'inline',
- # this->opaque is passed as arg[1].
- virtual_fnptrs = dict(
- self_ = lambda name: f'({rename.class_("pdf_sanitize_filter_options")}2*) {name}',
- alloc = f'this->opaque = this;\n',
- ),
- ),
- pdf_write_options = ClassExtra(
- constructors_extra = [
- ExtraConstructor( '()',
- f'''
- {{
- /* Use memcpy() otherwise we get 'invalid array assignment' errors. */
- memcpy(this->internal(), &pdf_default_write_options, sizeof(*this->internal()));
- }}
- ''',
- comment = '/* Default constructor, makes copy of pdf_default_write_options. */'
- ),
- ExtraConstructor(
- f'(const {rename.class_("pdf_write_options")}& rhs)',
- f'''
- {{
- *this = rhs;
- }}
- ''',
- comment = '/* Copy constructor using raw memcopy(). */'
- ),
- ],
- methods_extra = [
- ExtraMethod(
- f'{rename.class_("pdf_write_options")}&',
- f'operator=(const {rename.class_("pdf_write_options")}& rhs)',
- f'''
- {{
- memcpy(this->internal(), rhs.internal(), sizeof(*this->internal()));
- return *this;
- }}
- ''',
- comment = '/* Assignment using plain memcpy(). */',
- ),
- ExtraMethod(
- # Would prefer to call this opwd_utf8_set() but
- # this conflicts with SWIG-generated accessor for
- # opwd_utf8.
- f'void',
- f'opwd_utf8_set_value(const std::string& text)',
- f'''
- {{
- size_t len = std::min(text.size(), sizeof(opwd_utf8) - 1);
- memcpy(opwd_utf8, text.c_str(), len);
- opwd_utf8[len] = 0;
- }}
- ''',
- '/* Copies <text> into opwd_utf8[]. */',
- ),
- ExtraMethod(
- f'void',
- f'upwd_utf8_set_value(const std::string& text)',
- f'''
- {{
- size_t len = std::min(text.size(), sizeof(upwd_utf8) - 1);
- memcpy(upwd_utf8, text.c_str(), len);
- upwd_utf8[len] = 0;
- }}
- ''',
- '/* Copies <text> into upwd_utf8[]. */',
- ),
- ],
- pod = 'inline',
- copyable = 'default',
- )
- )
|