Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/scripts/wrap/classes.py @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 ''' | |
| 2 Extra information to customise how we wrap MuPDF structs into C++ classes. | |
| 3 ''' | |
| 4 | |
| 5 import textwrap | |
| 6 | |
| 7 import jlib | |
| 8 | |
| 9 from . import rename | |
| 10 from . import state | |
| 11 from . import util | |
| 12 | |
| 13 | |
| 14 class ExtraMethod: | |
| 15 ''' | |
| 16 Defines a prototype and implementation of a custom method in a generated | |
| 17 class. | |
| 18 ''' | |
| 19 def __init__( self, return_, name_args, body, comment, overload=None): | |
| 20 ''' | |
| 21 return_: | |
| 22 Return type as a string. | |
| 23 name_args: | |
| 24 A string describing name and args of the method: | |
| 25 <method-name>(<args>) | |
| 26 body: | |
| 27 Implementation code including the enclosing '{...}'. | |
| 28 comment: | |
| 29 Optional comment; should include /* and */ or //. | |
| 30 overload: | |
| 31 If true, we allow auto-generation of methods with same name. | |
| 32 ''' | |
| 33 assert name_args | |
| 34 self.return_ = return_ | |
| 35 self.name_args = name_args | |
| 36 self.body = body | |
| 37 self.comment = comment | |
| 38 self.overload = overload | |
| 39 assert '\t' not in body | |
| 40 def __str__(self): | |
| 41 return f'{self.name_args} => {self.return_}' | |
| 42 | |
| 43 | |
| 44 class ExtraConstructor: | |
| 45 ''' | |
| 46 Defines a prototype and implementation of a custom constructor in a | |
| 47 generated class. | |
| 48 ''' | |
| 49 def __init__( self, name_args, body, comment): | |
| 50 ''' | |
| 51 name_args: | |
| 52 A string of the form: (<args>) | |
| 53 body: | |
| 54 Implementation code including the enclosing '{...}'. | |
| 55 comment: | |
| 56 Optional comment; should include /* and */ or //. | |
| 57 ''' | |
| 58 self.return_ = '' | |
| 59 self.name_args = name_args | |
| 60 self.body = body | |
| 61 self.comment = comment | |
| 62 assert '\t' not in body | |
| 63 | |
| 64 | |
| 65 class ClassExtra: | |
| 66 ''' | |
| 67 Extra methods/features when wrapping a particular MuPDF struct into a C++ | |
| 68 class. | |
| 69 ''' | |
| 70 def __init__( self, | |
| 71 accessors=None, | |
| 72 class_bottom='', | |
| 73 class_post='', | |
| 74 class_pre='', | |
| 75 class_top='', | |
| 76 constructor_default=True, | |
| 77 constructor_excludes=None, | |
| 78 constructor_prefixes=None, | |
| 79 constructor_raw=True, | |
| 80 constructors_extra=None, | |
| 81 constructors_wrappers=None, | |
| 82 copyable=True, | |
| 83 extra_cpp='', | |
| 84 iterator_next=None, | |
| 85 methods_extra=None, | |
| 86 method_wrappers=None, | |
| 87 method_wrappers_static=None, | |
| 88 opaque=False, | |
| 89 pod=False, | |
| 90 virtual_fnptrs=False, | |
| 91 ): | |
| 92 ''' | |
| 93 accessors: | |
| 94 If true, we generate accessors methods for all items in the | |
| 95 underlying struct. | |
| 96 | |
| 97 Defaults to True if pod is True, else False. | |
| 98 | |
| 99 class_bottom: | |
| 100 Extra text at end of class definition, e.g. for member variables. | |
| 101 | |
| 102 class_post: | |
| 103 Extra text after class definition, e.g. complete definition of | |
| 104 iterator class. | |
| 105 | |
| 106 class_pre: | |
| 107 Extra text before class definition, e.g. forward declaration of | |
| 108 iterator class. | |
| 109 | |
| 110 class_top: | |
| 111 Extra text at start of class definition, e.g. for enums. | |
| 112 | |
| 113 constructor_default: | |
| 114 If None we set to true if `pod` is true, otherwise false. If | |
| 115 true, we create a default constructor. If `pod` is true this | |
| 116 constructor will default-initialise each member, otherwise it will | |
| 117 set `m_internal` to null. | |
| 118 | |
| 119 constructor_excludes: | |
| 120 Lists of constructor functions to ignore. | |
| 121 | |
| 122 constructor_prefixes: | |
| 123 Extra fz_*() function name prefixes that can be used by class | |
| 124 constructors_wrappers. We find all functions whose name starts with one of | |
| 125 the specified prefixes and which returns a pointer to the relevant | |
| 126 fz struct. | |
| 127 | |
| 128 For each function we find, we make a constructor that takes the | |
| 129 required arguments and set m_internal to what this function | |
| 130 returns. | |
| 131 | |
| 132 If there is a '-' item, we omit the default 'fz_new_<type>' prefix. | |
| 133 | |
| 134 constructor_raw: | |
| 135 If true, create a constructor that takes a pointer to an instance | |
| 136 of the wrapped fz_ struct. If 'default', this constructor arg | |
| 137 defaults to NULL. If 'declaration_only' we declare the constructor | |
| 138 but do not write out the function definition - typically this will | |
| 139 be instead specified as custom code in <extra_cpp>. | |
| 140 | |
| 141 constructors_extra: | |
| 142 List of ExtraConstructor's, allowing arbitrary constructors_wrappers to be | |
| 143 specified. | |
| 144 | |
| 145 constructors_wrappers: | |
| 146 List of fns to use as constructors_wrappers. | |
| 147 | |
| 148 copyable: | |
| 149 If 'default' we allow default copy constructor to be created by C++ | |
| 150 compiler. This is useful for plain structs that are not referenced | |
| 151 counted but can still be copied, but which we don't want to specify | |
| 152 pod=True. | |
| 153 | |
| 154 Otherwise if true, generated wrapper class must be copyable. If | |
| 155 pod is false, we generate a copy constructor by looking for a | |
| 156 fz_keep_*() function; it's an error if we can't find this function | |
| 157 [2024-01-24 fixme: actually we don't appear to raise an | |
| 158 error in this case, instead we make class non-copyable. | |
| 159 e.g. FzCompressedBuffer.]. | |
| 160 | |
| 161 Otherwise if false we create a private copy constructor. | |
| 162 | |
| 163 [todo: need to check docs for interaction of pod/copyable.] | |
| 164 | |
| 165 extra_cpp: | |
| 166 Extra text for .cpp file, e.g. implementation of iterator class | |
| 167 methods. | |
| 168 | |
| 169 iterator_next: | |
| 170 Support for iterating forwards over linked list. | |
| 171 | |
| 172 Should be (first, last). | |
| 173 | |
| 174 first: | |
| 175 Name of element within the wrapped class that points to the | |
| 176 first item in the linked list. We assume that this element will | |
| 177 have 'next' pointers that terminate in NULL. | |
| 178 | |
| 179 If <first> is '', the container is itself the first element in | |
| 180 the linked list. | |
| 181 | |
| 182 last: | |
| 183 Currently unused, but could be used for reverse iteration in | |
| 184 the future. | |
| 185 | |
| 186 We generate begin() and end() methods, plus a separate iterator | |
| 187 class, to allow iteration over the linked list starting at | |
| 188 <structname>::<first> and iterating to ->next until we reach NULL. | |
| 189 | |
| 190 methods_extra: | |
| 191 List of ExtraMethod's, allowing arbitrary methods to be specified. | |
| 192 | |
| 193 method_wrappers: | |
| 194 Extra fz_*() function names that should be wrapped in class | |
| 195 methods. | |
| 196 | |
| 197 E.g. 'fz_foo_bar' is converted to a method called foo_bar() | |
| 198 that takes same parameters as fz_foo_bar() except context and | |
| 199 any pointer to struct and fz_context*. The implementation calls | |
| 200 fz_foo_bar(), converting exceptions etc. | |
| 201 | |
| 202 The first arg that takes underlying fz_*_s type is omitted and | |
| 203 implementation passes <this>. | |
| 204 | |
| 205 method_wrappers_static: | |
| 206 Like <method_wrappers>, but generates static methods, where no args | |
| 207 are replaced by <this>. | |
| 208 | |
| 209 opaque: | |
| 210 If true, we generate a wrapper even if there's no definition | |
| 211 available for the struct, i.e. it's only available as a forward | |
| 212 declaration. | |
| 213 | |
| 214 pod: | |
| 215 If 'inline', there is no m_internal; instead, each member of the | |
| 216 underlying class is placed in the wrapper class and special method | |
| 217 `internal()` returns a fake pointer to underlying class. | |
| 218 | |
| 219 If 'none', there is no m_internal member at all. Typically | |
| 220 <extra_cpp> could be used to add in custom members. | |
| 221 | |
| 222 If True, underlying class is POD and m_internal is an instance of | |
| 223 the underlying class instead of a pointer to it. | |
| 224 | |
| 225 virtual_fnptrs: | |
| 226 If true, should be a dict with these keys: | |
| 227 | |
| 228 alloc: | |
| 229 A string containing C++ code to be embedded in the | |
| 230 virtual_fnptrs wrapper class's constructor. | |
| 231 | |
| 232 If the wrapper class is a POD, the MuPDF struct is already | |
| 233 available as part of the wrapper class instance (as | |
| 234 m_internal, or `internal()` if inline). Otherwise this | |
| 235 code should set `m_internal` to point to a newly allocated | |
| 236 instance of the MuPDF struct. | |
| 237 | |
| 238 Should typically set up the MuPDF struct so that `self_()` | |
| 239 can return the original C++ wrapper class instance. | |
| 240 comment: | |
| 241 Extra comment for the wrapper class. | |
| 242 free: | |
| 243 Optional code for freeing the virtual_fnptrs wrapper | |
| 244 class. If specified this causes creation of a destructor | |
| 245 function. | |
| 246 | |
| 247 This is only needed for non-ref-counted classes that are | |
| 248 not marked as POD. In this case the wrapper class has a | |
| 249 pointer `m_internal` member that will not be automatically | |
| 250 freed by the destructor, and `alloc` will usually have set | |
| 251 it to a newly allocated struct. | |
| 252 self_: | |
| 253 A callable that returns a string containing C++ code for | |
| 254 embedding in each low-level callback. It should returns a | |
| 255 pointer to the original C++ virtual_fnptrs wrapper class. | |
| 256 | |
| 257 If `self_n` is None, this callable takes no args. Otherwise | |
| 258 it takes the name of the `self_n`'th arg. | |
| 259 self_n: | |
| 260 Index of arg in each low-level callback, for the arg that | |
| 261 should be passed to `self_`. We use the same index for all | |
| 262 low-level callbacks. If not specified, default is 1 (we | |
| 263 generally expect args to be (fz_context* ctx, void*, ...). | |
| 264 If None, `self_` is called with no arg; this is for if we | |
| 265 use a different mechanism such as a global variable. | |
| 266 | |
| 267 We generate a virtual_fnptrs wrapper class, derived from the main | |
| 268 wrapper class, where the main wrapper class's function pointers end | |
| 269 up calling the virtual_fnptrs wrapper class's virtual methods. We | |
| 270 then use SWIG's 'Director' support to allow these virtual methods | |
| 271 to be overridden in Python/C#. Thus one can make MuPDF function | |
| 272 pointers call Python/C# code. | |
| 273 ''' | |
| 274 if accessors is None and pod is True: | |
| 275 accessors = True | |
| 276 if constructor_default is None: | |
| 277 constructor_default = pod | |
| 278 self.accessors = accessors | |
| 279 self.class_bottom = class_bottom | |
| 280 self.class_post = class_post | |
| 281 self.class_pre = class_pre | |
| 282 self.class_top = class_top | |
| 283 self.constructor_default = constructor_default | |
| 284 self.constructor_excludes = constructor_excludes or [] | |
| 285 self.constructor_prefixes = constructor_prefixes or [] | |
| 286 self.constructor_raw = constructor_raw | |
| 287 self.constructors_extra = constructors_extra or [] | |
| 288 self.constructors_wrappers = constructors_wrappers or [] | |
| 289 self.copyable = copyable | |
| 290 self.extra_cpp = extra_cpp | |
| 291 self.iterator_next = iterator_next | |
| 292 self.methods_extra = methods_extra or [] | |
| 293 self.method_wrappers = method_wrappers or [] | |
| 294 self.method_wrappers_static = method_wrappers_static or [] | |
| 295 self.opaque = opaque | |
| 296 self.pod = pod | |
| 297 self.virtual_fnptrs = virtual_fnptrs | |
| 298 | |
| 299 assert self.pod in (False, True, 'inline', 'none'), f'{self.pod}' | |
| 300 | |
| 301 def assert_list_of( items, type_): | |
| 302 assert isinstance( items, list) | |
| 303 for item in items: | |
| 304 assert isinstance( item, type_) | |
| 305 | |
| 306 assert_list_of( self.constructor_prefixes, str) | |
| 307 assert_list_of( self.method_wrappers, str) | |
| 308 assert_list_of( self.method_wrappers_static, str) | |
| 309 assert_list_of( self.methods_extra, ExtraMethod) | |
| 310 assert_list_of( self.constructors_extra, ExtraConstructor) | |
| 311 | |
| 312 if virtual_fnptrs: | |
| 313 assert isinstance(virtual_fnptrs, dict), f'virtual_fnptrs={virtual_fnptrs!r}' | |
| 314 | |
| 315 def __str__( self): | |
| 316 ret = '' | |
| 317 ret += f' accessors={self.accessors}' | |
| 318 ret += f' class_bottom={self.class_bottom}' | |
| 319 ret += f' class_post={self.class_post}' | |
| 320 ret += f' class_pre={self.class_pre}' | |
| 321 ret += f' class_top={self.class_top}' | |
| 322 ret += f' constructor_default={self.constructor_default}' | |
| 323 ret += f' constructor_excludes={self.constructor_excludes}' | |
| 324 ret += f' constructor_prefixes={self.constructor_prefixes}' | |
| 325 ret += f' constructor_raw={self.constructor_raw}' | |
| 326 ret += f' constructors_extra={self.constructors_extra}' | |
| 327 ret += f' constructors_wrappers={self.constructors_wrappers}' | |
| 328 ret += f' copyable={self.copyable}' | |
| 329 ret += f' extra_cpp={self.extra_cpp}' | |
| 330 ret += f' iterator_next={self.iterator_next}' | |
| 331 ret += f' methods_extra={self.methods_extra}' | |
| 332 ret += f' method_wrappers={self.method_wrappers}' | |
| 333 ret += f' method_wrappers_static={self.method_wrappers_static}' | |
| 334 ret += f' opaque={self.opaque}' | |
| 335 ret += f' pod={self.pod}' | |
| 336 ret += f' virtual_fnptrs={self.virtual_fnptrs}' | |
| 337 return ret | |
| 338 | |
| 339 | |
| 340 | |
| 341 class ClassExtras: | |
| 342 ''' | |
| 343 Extra methods/features for each of our auto-generated C++ wrapper classes. | |
| 344 ''' | |
| 345 def __init__( self, **namevalues): | |
| 346 ''' | |
| 347 namevalues: | |
| 348 Named args mapping from struct name (e.g. fz_document) to a | |
| 349 ClassExtra. | |
| 350 ''' | |
| 351 self.items = dict() | |
| 352 for name, value in namevalues.items(): | |
| 353 self.items[ name] = value | |
| 354 | |
| 355 def get( self, tu, name): | |
| 356 ''' | |
| 357 Searches for <name> and returns a ClassExtra instance. If <name> is not | |
| 358 found, we insert an empty ClassExtra instance and return it. We do this | |
| 359 for any name, e.g. name could be 'foo *'. | |
| 360 | |
| 361 We return None if <name> is a known enum. | |
| 362 ''' | |
| 363 verbose = state.state_.show_details( name) | |
| 364 if 0 and verbose: | |
| 365 jlib.log( 'ClassExtras.get(): {=name}') | |
| 366 name = util.clip( name, ('const ', 'struct ')) | |
| 367 if 0 and verbose: | |
| 368 jlib.log( 'ClassExtras.get(): {=name}') | |
| 369 if not name.startswith( ('fz_', 'pdf_')): | |
| 370 return | |
| 371 | |
| 372 ret = self.items.setdefault( name, ClassExtra()) | |
| 373 | |
| 374 if name in state.state_.enums[ tu]: | |
| 375 #jlib.log( '*** name is an enum: {name=}') | |
| 376 return None | |
| 377 | |
| 378 if ' ' not in name and not ret.pod and ret.copyable and ret.copyable != 'default': | |
| 379 # Check whether there is a _keep() fn. | |
| 380 keep_name = f'fz_keep_{name[3:]}' if name.startswith( 'fz_') else f'pdf_keep_{name[4:]}' | |
| 381 keep_cursor = state.state_.find_function( tu, keep_name, method=True) | |
| 382 if not keep_cursor: | |
| 383 if ret.copyable: | |
| 384 if 0: | |
| 385 jlib.log( '*** Changing .copyable to False for {=name keep_name}') | |
| 386 ret.copyable = False | |
| 387 return ret | |
| 388 | |
| 389 def get_or_none( self, name): | |
| 390 return self.items.get( name) | |
| 391 | |
| 392 | |
| 393 # Customisation information for selected wrapper classes. | |
| 394 # | |
| 395 # We use MuPDF struct names as keys. | |
| 396 # | |
| 397 classextras = ClassExtras( | |
| 398 | |
| 399 fz_aa_context = ClassExtra( | |
| 400 pod='inline', | |
| 401 ), | |
| 402 | |
| 403 fz_band_writer = ClassExtra( | |
| 404 class_top = ''' | |
| 405 /* We use these enums to support construction via all the relevant MuPDF functions. */ | |
| 406 | |
| 407 enum Cm | |
| 408 { | |
| 409 MONO, | |
| 410 COLOR, | |
| 411 }; | |
| 412 enum P | |
| 413 { | |
| 414 PNG, | |
| 415 PNM, | |
| 416 PAM, | |
| 417 PBM, | |
| 418 PKM, | |
| 419 PS, | |
| 420 PSD, | |
| 421 }; | |
| 422 ''', | |
| 423 constructors_extra = [ | |
| 424 ExtraConstructor( | |
| 425 f'({rename.class_("fz_output")}& out, Cm cm, const {rename.class_("fz_pcl_options")}& options)', | |
| 426 f''' | |
| 427 {{ | |
| 428 ::fz_output* out2 = out.m_internal; | |
| 429 const ::fz_pcl_options* options2 = options.m_internal; | |
| 430 if (0) {{}} | |
| 431 else if (cm == MONO) m_internal = {rename.ll_fn('fz_new_mono_pcl_band_writer' )}( out2, options2); | |
| 432 else if (cm == COLOR) m_internal = {rename.ll_fn('fz_new_color_pcl_band_writer')}( out2, options2); | |
| 433 else throw std::runtime_error( "Unrecognised fz_band_writer_s Cm type"); | |
| 434 }} | |
| 435 ''', | |
| 436 comment = f'/* Constructor using fz_new_mono_pcl_band_writer() or fz_new_color_pcl_band_writer(). */', | |
| 437 ), | |
| 438 ExtraConstructor( | |
| 439 f'({rename.class_("fz_output")}& out, P p)', | |
| 440 f''' | |
| 441 {{ | |
| 442 ::fz_output* out2 = out.m_internal; | |
| 443 if (0) {{}} | |
| 444 else if (p == PNG) m_internal = {rename.ll_fn('fz_new_png_band_writer')}( out2); | |
| 445 else if (p == PNM) m_internal = {rename.ll_fn('fz_new_pnm_band_writer')}( out2); | |
| 446 else if (p == PAM) m_internal = {rename.ll_fn('fz_new_pam_band_writer')}( out2); | |
| 447 else if (p == PBM) m_internal = {rename.ll_fn('fz_new_pbm_band_writer')}( out2); | |
| 448 else if (p == PKM) m_internal = {rename.ll_fn('fz_new_pkm_band_writer')}( out2); | |
| 449 else if (p == PS) m_internal = {rename.ll_fn('fz_new_ps_band_writer' )}( out2); | |
| 450 else if (p == PSD) m_internal = {rename.ll_fn('fz_new_psd_band_writer')}( out2); | |
| 451 else throw std::runtime_error( "Unrecognised fz_band_writer_s P type"); | |
| 452 }} | |
| 453 ''', | |
| 454 comment = f'/* Constructor using fz_new_p*_band_writer(). */', | |
| 455 ), | |
| 456 ExtraConstructor( | |
| 457 f'({rename.class_("fz_output")}& out, Cm cm, const {rename.class_("fz_pwg_options")}& options)', | |
| 458 f''' | |
| 459 {{ | |
| 460 ::fz_output* out2 = out.m_internal; | |
| 461 const ::fz_pwg_options* options2 = &options.m_internal; | |
| 462 if (0) {{}} | |
| 463 else if (cm == MONO) m_internal = {rename.ll_fn('fz_new_mono_pwg_band_writer' )}( out2, options2); | |
| 464 else if (cm == COLOR) m_internal = {rename.ll_fn('fz_new_pwg_band_writer')}( out2, options2); | |
| 465 else throw std::runtime_error( "Unrecognised fz_band_writer_s Cm type"); | |
| 466 }} | |
| 467 ''', | |
| 468 comment = f'/* Constructor using fz_new_mono_pwg_band_writer() or fz_new_pwg_band_writer(). */', | |
| 469 ), | |
| 470 ], | |
| 471 copyable = False, | |
| 472 ), | |
| 473 | |
| 474 fz_bitmap = ClassExtra( | |
| 475 accessors = True, | |
| 476 ), | |
| 477 | |
| 478 fz_buffer = ClassExtra( | |
| 479 constructor_raw = 'default', | |
| 480 constructors_wrappers = [ | |
| 481 'fz_read_file', | |
| 482 ], | |
| 483 ), | |
| 484 | |
| 485 fz_color_params = ClassExtra( | |
| 486 pod='inline', | |
| 487 constructors_extra = [ | |
| 488 ExtraConstructor('()', | |
| 489 f''' | |
| 490 {{ | |
| 491 this->ri = fz_default_color_params.ri; | |
| 492 this->bp = fz_default_color_params.bp; | |
| 493 this->op = fz_default_color_params.op; | |
| 494 this->opm = fz_default_color_params.opm; | |
| 495 }} | |
| 496 ''', | |
| 497 comment = '/* Equivalent to fz_default_color_params. */', | |
| 498 ), | |
| 499 ], | |
| 500 ), | |
| 501 | |
| 502 fz_colorspace = ClassExtra( | |
| 503 constructors_extra = [ | |
| 504 ExtraConstructor( | |
| 505 '(Fixed fixed)', | |
| 506 f''' | |
| 507 {{ | |
| 508 if (0) {{}} | |
| 509 else if ( fixed == Fixed_GRAY) m_internal = {rename.ll_fn( 'fz_device_gray')}(); | |
| 510 else if ( fixed == Fixed_RGB) m_internal = {rename.ll_fn( 'fz_device_rgb' )}(); | |
| 511 else if ( fixed == Fixed_BGR) m_internal = {rename.ll_fn( 'fz_device_bgr' )}(); | |
| 512 else if ( fixed == Fixed_CMYK) m_internal = {rename.ll_fn( 'fz_device_cmyk')}(); | |
| 513 else if ( fixed == Fixed_LAB) m_internal = {rename.ll_fn( 'fz_device_lab' )}(); | |
| 514 else {{ | |
| 515 std::string message = "Unrecognised fixed colorspace id"; | |
| 516 throw {rename.error_class("FZ_ERROR_GENERIC")}(message.c_str()); | |
| 517 }} | |
| 518 {rename.ll_fn('fz_keep_colorspace')}(m_internal); | |
| 519 }} | |
| 520 ''', | |
| 521 comment = '/* Construct using one of: fz_device_gray(), fz_device_rgb(), fz_device_bgr(), fz_device_cmyk(), fz_device_lab(). */', | |
| 522 ), | |
| 523 ], | |
| 524 constructor_raw=1, | |
| 525 class_top = ''' | |
| 526 /* We use this enums to support construction via all the relevant MuPDF functions. */ | |
| 527 enum Fixed | |
| 528 { | |
| 529 Fixed_GRAY, | |
| 530 Fixed_RGB, | |
| 531 Fixed_BGR, | |
| 532 Fixed_CMYK, | |
| 533 Fixed_LAB, | |
| 534 }; | |
| 535 ''', | |
| 536 ), | |
| 537 | |
| 538 fz_compressed_buffer = ClassExtra( | |
| 539 methods_extra = [ | |
| 540 ExtraMethod( | |
| 541 rename.class_('fz_buffer'), | |
| 542 'get_buffer()', | |
| 543 textwrap.dedent(f''' | |
| 544 {{ | |
| 545 return {rename.class_('fz_buffer')}( | |
| 546 {rename.ll_fn('fz_keep_buffer')}(m_internal->buffer) | |
| 547 ); | |
| 548 }} | |
| 549 '''), | |
| 550 '/* Returns wrapper class for fz_buffer *m_internal.buffer. */', | |
| 551 ), | |
| 552 ], | |
| 553 ), | |
| 554 | |
| 555 fz_context = ClassExtra( | |
| 556 copyable = False, | |
| 557 ), | |
| 558 | |
| 559 fz_cookie = ClassExtra( | |
| 560 constructors_extra = [ | |
| 561 ExtraConstructor( '()', | |
| 562 ''' | |
| 563 { | |
| 564 this->m_internal.abort = 0; | |
| 565 this->m_internal.progress = 0; | |
| 566 this->m_internal.progress_max = (size_t) -1; | |
| 567 this->m_internal.errors = 0; | |
| 568 this->m_internal.incomplete = 0; | |
| 569 } | |
| 570 ''', | |
| 571 comment = '/* Default constructor sets all fields to default values. */', | |
| 572 ), | |
| 573 ], | |
| 574 constructor_raw = False, | |
| 575 methods_extra = [ | |
| 576 ExtraMethod( | |
| 577 'void', | |
| 578 'set_abort()', | |
| 579 '{ m_internal.abort = 1; }\n', | |
| 580 '/* Sets m_internal.abort to 1. */', | |
| 581 ), | |
| 582 ExtraMethod( | |
| 583 'void', | |
| 584 'increment_errors(int delta)', | |
| 585 '{ m_internal.errors += delta; }\n', | |
| 586 '/* Increments m_internal.errors by <delta>. */', | |
| 587 ), | |
| 588 ], | |
| 589 pod = True, | |
| 590 # Other code asynchronously writes to our fields, so we are not | |
| 591 # copyable. todo: maybe tie us to all objects to which we have | |
| 592 # been associated? | |
| 593 # | |
| 594 copyable=False, | |
| 595 ), | |
| 596 | |
| 597 fz_device = ClassExtra( | |
| 598 virtual_fnptrs = dict( | |
| 599 self_ = lambda name: f'(*({rename.class_("fz_device")}2**) ({name} + 1))', | |
| 600 alloc = textwrap.dedent( f''' | |
| 601 m_internal = {rename.ll_fn("fz_new_device_of_size")}( | |
| 602 sizeof(*m_internal) + sizeof({rename.class_("fz_device")}2*) | |
| 603 ); | |
| 604 *(({rename.class_("fz_device")}2**) (m_internal + 1)) = this; | |
| 605 '''), | |
| 606 ), | |
| 607 constructor_raw = True, | |
| 608 ), | |
| 609 | |
| 610 fz_document = ClassExtra( | |
| 611 constructor_excludes = [ | |
| 612 'fz_new_xhtml_document_from_document', | |
| 613 ], | |
| 614 constructor_prefixes = [ | |
| 615 'fz_open_accelerated_document', | |
| 616 'fz_open_document', | |
| 617 ], | |
| 618 constructors_extra = [ | |
| 619 ExtraConstructor( f'({rename.class_("pdf_document")}& pdfdocument)', | |
| 620 f''' | |
| 621 {{ | |
| 622 m_internal = {rename.ll_fn('fz_keep_document')}(&pdfdocument.m_internal->super); | |
| 623 }} | |
| 624 ''', | |
| 625 f'/* Returns a {rename.class_("fz_document")} for pdfdocument.m_internal.super. */', | |
| 626 ), | |
| 627 ], | |
| 628 constructor_raw = 'default', | |
| 629 method_wrappers = [ | |
| 630 'fz_load_outline', | |
| 631 ], | |
| 632 method_wrappers_static = [ | |
| 633 'fz_new_xhtml_document_from_document', | |
| 634 ], | |
| 635 ), | |
| 636 | |
| 637 # This is a little complicated. Many of the functions that we would | |
| 638 # like to wrap to form constructors, have the same set of args. C++ | |
| 639 # does not support named constructors so we differentiate between | |
| 640 # constructors with identical args using enums. | |
| 641 # | |
| 642 # Also, fz_document_writer is not reference counted so the wrapping | |
| 643 # class is not copyable or assignable, so our normal approach of making | |
| 644 # static class functions that return a newly constructed instance by | |
| 645 # value, does not work. | |
| 646 # | |
| 647 # So instead we define enums that are passed to our constructors, | |
| 648 # allowing the constructor to decide which fz_ function to use to | |
| 649 # create the new fz_document_writer. | |
| 650 # | |
| 651 # There should be no commented-out constructors in the generated code | |
| 652 # marked as 'Disabled because same args as ...'. | |
| 653 # | |
| 654 fz_document_writer = ClassExtra( | |
| 655 class_top = ''' | |
| 656 /* Used for constructor that wraps fz_ functions taking (const char *path, const char *options). */ | |
| 657 enum PathType | |
| 658 { | |
| 659 PathType_CBZ, | |
| 660 PathType_DOCX, | |
| 661 PathType_ODT, | |
| 662 PathType_PAM_PIXMAP, | |
| 663 PathType_PBM_PIXMAP, | |
| 664 PathType_PCL, | |
| 665 PathType_PCLM, | |
| 666 PathType_PDF, | |
| 667 PathType_PDFOCR, | |
| 668 PathType_PGM_PIXMAP, | |
| 669 PathType_PKM_PIXMAP, | |
| 670 PathType_PNG_PIXMAP, | |
| 671 PathType_PNM_PIXMAP, | |
| 672 PathType_PPM_PIXMAP, | |
| 673 PathType_PS, | |
| 674 PathType_PWG, | |
| 675 PathType_SVG, | |
| 676 }; | |
| 677 | |
| 678 /* Used for constructor that wraps fz_ functions taking (Output& out, const char *options). */ | |
| 679 enum OutputType | |
| 680 { | |
| 681 OutputType_CBZ, | |
| 682 OutputType_DOCX, | |
| 683 OutputType_ODT, | |
| 684 OutputType_PCL, | |
| 685 OutputType_PCLM, | |
| 686 OutputType_PDF, | |
| 687 OutputType_PDFOCR, | |
| 688 OutputType_PS, | |
| 689 OutputType_PWG, | |
| 690 }; | |
| 691 | |
| 692 /* Used for constructor that wraps fz_ functions taking (const char *format, const char *path, const char *options). */ | |
| 693 enum FormatPathType | |
| 694 { | |
| 695 FormatPathType_DOCUMENT, | |
| 696 FormatPathType_TEXT, | |
| 697 }; | |
| 698 ''', | |
| 699 # These excludes should match the functions called by the | |
| 700 # extra constructors defined below. This ensures that we don't | |
| 701 # generate commented-out constructors with a comment saying | |
| 702 # 'Disabled because same args as ...'. | |
| 703 constructor_excludes = [ | |
| 704 'fz_new_cbz_writer', | |
| 705 'fz_new_docx_writer', | |
| 706 'fz_new_odt_writer', | |
| 707 'fz_new_pam_pixmap_writer', | |
| 708 'fz_new_pbm_pixmap_writer', | |
| 709 'fz_new_pcl_writer', | |
| 710 'fz_new_pclm_writer', | |
| 711 'fz_new_pdfocr_writer', | |
| 712 'fz_new_pdf_writer', | |
| 713 'fz_new_pgm_pixmap_writer', | |
| 714 'fz_new_pkm_pixmap_writer', | |
| 715 'fz_new_png_pixmap_writer', | |
| 716 'fz_new_pnm_pixmap_writer', | |
| 717 'fz_new_ppm_pixmap_writer', | |
| 718 'fz_new_ps_writer', | |
| 719 'fz_new_pwg_writer', | |
| 720 'fz_new_svg_writer', | |
| 721 | |
| 722 'fz_new_cbz_writer_with_output', | |
| 723 'fz_new_docx_writer_with_output', | |
| 724 'fz_new_odt_writer_with_output', | |
| 725 'fz_new_pcl_writer_with_output', | |
| 726 'fz_new_pclm_writer_with_output', | |
| 727 'fz_new_pdf_writer_with_output', | |
| 728 'fz_new_pdfocr_writer_with_output', | |
| 729 'fz_new_ps_writer_with_output', | |
| 730 'fz_new_pwg_writer_with_output', | |
| 731 | |
| 732 'fz_new_document_writer', | |
| 733 'fz_new_text_writer', | |
| 734 | |
| 735 'fz_new_document_writer_with_output', | |
| 736 'fz_new_text_writer_with_output', | |
| 737 ], | |
| 738 | |
| 739 copyable=False, | |
| 740 methods_extra = [ | |
| 741 # 2022-08-26: we used to provide a custom wrapper of | |
| 742 # fz_begin_page(), but this is not longer necessary | |
| 743 # because function_wrapper_class_aware_body() knows | |
| 744 # that fz_begin_page() returns a borrowed reference. | |
| 745 # | |
| 746 ], | |
| 747 constructors_extra = [ | |
| 748 ExtraConstructor( | |
| 749 '(const char *path, const char *options, PathType path_type)', | |
| 750 f''' | |
| 751 {{ | |
| 752 if (0) {{}} | |
| 753 else if (path_type == PathType_CBZ) m_internal = {rename.ll_fn( 'fz_new_cbz_writer')}(path, options); | |
| 754 else if (path_type == PathType_DOCX) m_internal = {rename.ll_fn( 'fz_new_docx_writer')}(path, options); | |
| 755 else if (path_type == PathType_ODT) m_internal = {rename.ll_fn( 'fz_new_odt_writer')}(path, options); | |
| 756 else if (path_type == PathType_PAM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pam_pixmap_writer')}(path, options); | |
| 757 else if (path_type == PathType_PBM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pbm_pixmap_writer')}(path, options); | |
| 758 else if (path_type == PathType_PCL) m_internal = {rename.ll_fn( 'fz_new_pcl_writer')}(path, options); | |
| 759 else if (path_type == PathType_PCLM) m_internal = {rename.ll_fn( 'fz_new_pclm_writer')}(path, options); | |
| 760 else if (path_type == PathType_PDF) m_internal = {rename.ll_fn( 'fz_new_pdf_writer')}(path, options); | |
| 761 else if (path_type == PathType_PDFOCR) m_internal = {rename.ll_fn( 'fz_new_pdfocr_writer')}(path, options); | |
| 762 else if (path_type == PathType_PGM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pgm_pixmap_writer')}(path, options); | |
| 763 else if (path_type == PathType_PKM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pkm_pixmap_writer')}(path, options); | |
| 764 else if (path_type == PathType_PNG_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_png_pixmap_writer')}(path, options); | |
| 765 else if (path_type == PathType_PNM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_pnm_pixmap_writer')}(path, options); | |
| 766 else if (path_type == PathType_PPM_PIXMAP) m_internal = {rename.ll_fn( 'fz_new_ppm_pixmap_writer')}(path, options); | |
| 767 else if (path_type == PathType_PS) m_internal = {rename.ll_fn( 'fz_new_ps_writer')}(path, options); | |
| 768 else if (path_type == PathType_PWG) m_internal = {rename.ll_fn( 'fz_new_pwg_writer')}(path, options); | |
| 769 else if (path_type == PathType_SVG) m_internal = {rename.ll_fn( 'fz_new_svg_writer')}(path, options); | |
| 770 else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised Type value"); | |
| 771 }} | |
| 772 ''', | |
| 773 comment = textwrap.dedent(''' | |
| 774 /* Constructor using one of: | |
| 775 fz_new_cbz_writer() | |
| 776 fz_new_docx_writer() | |
| 777 fz_new_odt_writer() | |
| 778 fz_new_pam_pixmap_writer() | |
| 779 fz_new_pbm_pixmap_writer() | |
| 780 fz_new_pcl_writer() | |
| 781 fz_new_pclm_writer() | |
| 782 fz_new_pdf_writer() | |
| 783 fz_new_pdfocr_writer() | |
| 784 fz_new_pgm_pixmap_writer() | |
| 785 fz_new_pkm_pixmap_writer() | |
| 786 fz_new_png_pixmap_writer() | |
| 787 fz_new_pnm_pixmap_writer() | |
| 788 fz_new_ppm_pixmap_writer() | |
| 789 fz_new_ps_writer() | |
| 790 fz_new_pwg_writer() | |
| 791 fz_new_svg_writer() | |
| 792 */'''), | |
| 793 ), | |
| 794 ExtraConstructor( | |
| 795 f'({rename.class_("fz_output")}& out, const char *options, OutputType output_type)', | |
| 796 f''' | |
| 797 {{ | |
| 798 /* All fz_new_*_writer_with_output() functions take | |
| 799 ownership of the fz_output, even if they throw an | |
| 800 exception. So we need to set out.m_internal to null | |
| 801 here so its destructor does nothing. */ | |
| 802 ::fz_output* out2 = out.m_internal; | |
| 803 out.m_internal = NULL; | |
| 804 if (0) {{}} | |
| 805 else if (output_type == OutputType_CBZ) m_internal = {rename.ll_fn( 'fz_new_cbz_writer_with_output')}(out2, options); | |
| 806 else if (output_type == OutputType_DOCX) m_internal = {rename.ll_fn( 'fz_new_docx_writer_with_output')}(out2, options); | |
| 807 else if (output_type == OutputType_ODT) m_internal = {rename.ll_fn( 'fz_new_odt_writer_with_output')}(out2, options); | |
| 808 else if (output_type == OutputType_PCL) m_internal = {rename.ll_fn( 'fz_new_pcl_writer_with_output')}(out2, options); | |
| 809 else if (output_type == OutputType_PCLM) m_internal = {rename.ll_fn( 'fz_new_pclm_writer_with_output')}(out2, options); | |
| 810 else if (output_type == OutputType_PDF) m_internal = {rename.ll_fn( 'fz_new_pdf_writer_with_output')}(out2, options); | |
| 811 else if (output_type == OutputType_PDFOCR) m_internal = {rename.ll_fn( 'fz_new_pdfocr_writer_with_output')}(out2, options); | |
| 812 else if (output_type == OutputType_PS) m_internal = {rename.ll_fn( 'fz_new_ps_writer_with_output')}(out2, options); | |
| 813 else if (output_type == OutputType_PWG) m_internal = {rename.ll_fn( 'fz_new_pwg_writer_with_output')}(out2, options); | |
| 814 else | |
| 815 {{ | |
| 816 /* Ensure that out2 is dropped before we return. */ | |
| 817 {rename.ll_fn( 'fz_drop_output')}(out2); | |
| 818 throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised OutputType value"); | |
| 819 }} | |
| 820 }} | |
| 821 ''', | |
| 822 comment = textwrap.dedent(''' | |
| 823 /* Constructor using one of: | |
| 824 fz_new_cbz_writer_with_output() | |
| 825 fz_new_docx_writer_with_output() | |
| 826 fz_new_odt_writer_with_output() | |
| 827 fz_new_pcl_writer_with_output() | |
| 828 fz_new_pclm_writer_with_output() | |
| 829 fz_new_pdf_writer_with_output() | |
| 830 fz_new_pdfocr_writer_with_output() | |
| 831 fz_new_ps_writer_with_output() | |
| 832 fz_new_pwg_writer_with_output() | |
| 833 | |
| 834 This constructor takes ownership of <out> - | |
| 835 out.m_internal is set to NULL after this constructor | |
| 836 returns so <out> must not be used again. | |
| 837 */ | |
| 838 '''), | |
| 839 ), | |
| 840 ExtraConstructor( | |
| 841 '(const char *format, const char *path, const char *options, FormatPathType format_path_type)', | |
| 842 f''' | |
| 843 {{ | |
| 844 if (0) {{}} | |
| 845 else if (format_path_type == FormatPathType_DOCUMENT) m_internal = {rename.ll_fn( 'fz_new_document_writer')}(format, path, options); | |
| 846 else if (format_path_type == FormatPathType_TEXT) m_internal = {rename.ll_fn( 'fz_new_text_writer')}(format, path, options); | |
| 847 else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised OutputType value"); | |
| 848 }} | |
| 849 ''', | |
| 850 comment = textwrap.dedent(''' | |
| 851 /* Constructor using one of: | |
| 852 fz_new_document_writer() | |
| 853 fz_new_text_writer() | |
| 854 */'''), | |
| 855 ), | |
| 856 ExtraConstructor( | |
| 857 f'({rename.class_("fz_output")}& out, const char *format, const char *options)', | |
| 858 f''' | |
| 859 {{ | |
| 860 /* Need to transfer ownership of <out>. */ | |
| 861 ::fz_output* out2 = out.m_internal; | |
| 862 out.m_internal = NULL; | |
| 863 m_internal = {rename.ll_fn( 'fz_new_document_writer_with_output')}(out2, format, options); | |
| 864 }} | |
| 865 ''', | |
| 866 comment = textwrap.dedent(''' | |
| 867 /* Constructor using fz_new_document_writer_with_output(). | |
| 868 | |
| 869 This constructor takes ownership of <out> - | |
| 870 out.m_internal is set to NULL after this constructor | |
| 871 returns so <out> must not be used again. | |
| 872 */'''), | |
| 873 ), | |
| 874 ExtraConstructor( | |
| 875 f'(const char *format, {rename.class_("fz_output")}& out, const char *options)', | |
| 876 f''' | |
| 877 {{ | |
| 878 /* Need to transfer ownership of <out>. */ | |
| 879 ::fz_output* out2 = out.m_internal; | |
| 880 out.m_internal = NULL; | |
| 881 m_internal = {rename.ll_fn( 'fz_new_text_writer_with_output')}(format, out2, options); | |
| 882 }} | |
| 883 ''', | |
| 884 comment = textwrap.dedent(''' | |
| 885 /* Constructor using fz_new_text_writer_with_output(). | |
| 886 | |
| 887 This constructor takes ownership of <out> - | |
| 888 out.m_internal is set to NULL after this constructor | |
| 889 returns so <out> must not be used again. | |
| 890 */'''), | |
| 891 ), | |
| 892 ], | |
| 893 | |
| 894 ), | |
| 895 | |
| 896 fz_draw_options = ClassExtra( | |
| 897 constructors_wrappers = [ | |
| 898 'fz_parse_draw_options', | |
| 899 ], | |
| 900 copyable=False, | |
| 901 pod='inline', | |
| 902 ), | |
| 903 | |
| 904 fz_halftone = ClassExtra( | |
| 905 constructor_raw = 'default', | |
| 906 ), | |
| 907 | |
| 908 fz_image = ClassExtra( | |
| 909 accessors=True, | |
| 910 ), | |
| 911 | |
| 912 fz_install_load_system_font_funcs_args = ClassExtra( | |
| 913 pod = True, | |
| 914 virtual_fnptrs = dict( | |
| 915 alloc = textwrap.dedent( f''' | |
| 916 /* | |
| 917 There can only be one active instance of the wrapper | |
| 918 class so we simply keep a pointer to it in a global | |
| 919 variable. | |
| 920 */ | |
| 921 fz_install_load_system_font_funcs2_state = this; | |
| 922 '''), | |
| 923 self_ = lambda: f'({rename.class_("fz_install_load_system_font_funcs_args")}2*) fz_install_load_system_font_funcs2_state', | |
| 924 self_n = None, | |
| 925 ), | |
| 926 ), | |
| 927 | |
| 928 fz_irect = ClassExtra( | |
| 929 constructor_prefixes = [ | |
| 930 'fz_irect_from_rect', | |
| 931 'fz_make_irect', | |
| 932 ], | |
| 933 pod='inline', | |
| 934 constructor_raw = True, | |
| 935 ), | |
| 936 | |
| 937 fz_link = ClassExtra( | |
| 938 constructors_extra = [ | |
| 939 ExtraConstructor( f'({rename.class_("fz_rect")}& rect, const char *uri)', | |
| 940 f''' | |
| 941 {{ | |
| 942 m_internal = {rename.ll_fn('fz_new_link_of_size')}( sizeof(fz_link), *rect.internal(), uri); | |
| 943 }} | |
| 944 ''', | |
| 945 '/* Construct by calling fz_new_link_of_size() with size=sizeof(fz_link). */', | |
| 946 ) | |
| 947 ], | |
| 948 accessors = True, | |
| 949 iterator_next = ('', ''), | |
| 950 constructor_raw = 'default', | |
| 951 copyable = True, | |
| 952 ), | |
| 953 | |
| 954 fz_location = ClassExtra( | |
| 955 constructor_prefixes = [ | |
| 956 'fz_make_location', | |
| 957 ], | |
| 958 pod='inline', | |
| 959 constructor_raw = True, | |
| 960 ), | |
| 961 | |
| 962 fz_matrix = ClassExtra( | |
| 963 constructor_prefixes = [ | |
| 964 'fz_make_matrix', | |
| 965 ], | |
| 966 method_wrappers_static = [ | |
| 967 'fz_concat', | |
| 968 'fz_scale', | |
| 969 'fz_shear', | |
| 970 'fz_rotate', | |
| 971 'fz_translate', | |
| 972 'fz_transform_page', | |
| 973 ], | |
| 974 constructors_extra = [ | |
| 975 ExtraConstructor( '()', | |
| 976 ''' | |
| 977 : a(1), b(0), c(0), d(1), e(0), f(0) | |
| 978 { | |
| 979 } | |
| 980 ''', | |
| 981 comment = '/* Constructs identity matrix (like fz_identity). */'), | |
| 982 ], | |
| 983 pod='inline', | |
| 984 constructor_raw = True, | |
| 985 ), | |
| 986 | |
| 987 fz_md5 = ClassExtra( | |
| 988 pod = True, | |
| 989 constructors_extra = [ | |
| 990 ExtraConstructor( | |
| 991 '()', | |
| 992 f''' | |
| 993 {{ | |
| 994 {rename.ll_fn( 'fz_md5_init')}( &m_internal); | |
| 995 }} | |
| 996 ''', | |
| 997 '/* Default constructor calls md5_init(). */', | |
| 998 ) | |
| 999 ], | |
| 1000 ), | |
| 1001 | |
| 1002 fz_outline = ClassExtra( | |
| 1003 # We add various methods to give depth-first iteration of outlines. | |
| 1004 # | |
| 1005 constructor_prefixes = [ | |
| 1006 'fz_load_outline', | |
| 1007 ], | |
| 1008 accessors=True, | |
| 1009 ), | |
| 1010 | |
| 1011 fz_outline_item = ClassExtra( | |
| 1012 class_top = f''' | |
| 1013 FZ_FUNCTION bool valid() const; | |
| 1014 FZ_FUNCTION const std::string& title() const; /* Will throw if valid() is not true. */ | |
| 1015 FZ_FUNCTION const std::string& uri() const; /* Will throw if valid() is not true. */ | |
| 1016 FZ_FUNCTION int is_open() const; /* Will throw if valid() is not true. */ | |
| 1017 ''', | |
| 1018 class_bottom = f''' | |
| 1019 private: | |
| 1020 bool m_valid; | |
| 1021 std::string m_title; | |
| 1022 std::string m_uri; | |
| 1023 int m_is_open; | |
| 1024 ''', | |
| 1025 constructors_extra = [ | |
| 1026 ], | |
| 1027 constructor_raw = 'declaration_only', | |
| 1028 copyable = 'default', | |
| 1029 pod = 'none', | |
| 1030 extra_cpp = f''' | |
| 1031 FZ_FUNCTION {rename.class_("fz_outline_item")}::{rename.class_("fz_outline_item")}(const ::fz_outline_item* item) | |
| 1032 {{ | |
| 1033 if (item) | |
| 1034 {{ | |
| 1035 m_valid = true; | |
| 1036 m_title = item->title; | |
| 1037 m_uri = item->uri; | |
| 1038 m_is_open = item->is_open; | |
| 1039 }} | |
| 1040 else | |
| 1041 {{ | |
| 1042 m_valid = false; | |
| 1043 }} | |
| 1044 }} | |
| 1045 FZ_FUNCTION bool {rename.class_("fz_outline_item")}::valid() const | |
| 1046 {{ | |
| 1047 return m_valid; | |
| 1048 }} | |
| 1049 FZ_FUNCTION const std::string& {rename.class_("fz_outline_item")}::title() const | |
| 1050 {{ | |
| 1051 if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid"); | |
| 1052 return m_title; | |
| 1053 }} | |
| 1054 FZ_FUNCTION const std::string& {rename.class_("fz_outline_item")}::uri() const | |
| 1055 {{ | |
| 1056 if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid"); | |
| 1057 return m_uri; | |
| 1058 }} | |
| 1059 FZ_FUNCTION int {rename.class_("fz_outline_item")}::is_open() const | |
| 1060 {{ | |
| 1061 if (!m_valid) throw {rename.error_class("FZ_ERROR_GENERIC")}("fz_outline_item is invalid"); | |
| 1062 return m_is_open; | |
| 1063 }} | |
| 1064 ''', | |
| 1065 ), | |
| 1066 | |
| 1067 fz_outline_iterator = ClassExtra( | |
| 1068 copyable = False, | |
| 1069 methods_extra = [ | |
| 1070 ExtraMethod( | |
| 1071 'int', | |
| 1072 f'{rename.method("fz_outline_iterator", "fz_outline_iterator_insert")}({rename.class_("fz_outline_item")}& item)', | |
| 1073 f''' | |
| 1074 {{ | |
| 1075 /* Create a temporary fz_outline_item. */ | |
| 1076 ::fz_outline_item item2; | |
| 1077 item2.title = (char*) item.title().c_str(); | |
| 1078 item2.uri = (char*) item.uri().c_str(); | |
| 1079 item2.is_open = item.is_open(); | |
| 1080 return {rename.ll_fn("fz_outline_iterator_insert")}(m_internal, &item2); | |
| 1081 }} | |
| 1082 ''', | |
| 1083 comment = '/* Custom wrapper for fz_outline_iterator_insert(). */', | |
| 1084 ), | |
| 1085 ExtraMethod( | |
| 1086 'void', | |
| 1087 f'{rename.method("fz_outline_iterator", "fz_outline_iterator_update")}({rename.class_("fz_outline_item")}& item)', | |
| 1088 f''' | |
| 1089 {{ | |
| 1090 /* Create a temporary fz_outline_item. */ | |
| 1091 ::fz_outline_item item2; | |
| 1092 item2.title = (char*) item.title().c_str(); | |
| 1093 item2.uri = (char*) item.uri().c_str(); | |
| 1094 item2.is_open = item.is_open(); | |
| 1095 return {rename.ll_fn("fz_outline_iterator_update")}(m_internal, &item2); | |
| 1096 }} | |
| 1097 ''', | |
| 1098 comment = '/* Custom wrapper for fz_outline_iterator_update(). */', | |
| 1099 ), | |
| 1100 ], | |
| 1101 ), | |
| 1102 | |
| 1103 fz_output = ClassExtra( | |
| 1104 virtual_fnptrs = dict( | |
| 1105 self_ = lambda name: f'({rename.class_("fz_output")}2*) {name}', | |
| 1106 alloc = f'm_internal = {rename.ll_fn("fz_new_output")}(0 /*bufsize*/, this /*state*/, nullptr /*write*/, nullptr /*close*/, nullptr /*drop*/);\n', | |
| 1107 ), | |
| 1108 constructor_raw = 'default', | |
| 1109 constructor_excludes = [ | |
| 1110 # These all have the same prototype, so are used by | |
| 1111 # constructors_extra below. | |
| 1112 'fz_new_asciihex_output', | |
| 1113 'fz_new_ascii85_output', | |
| 1114 'fz_new_rle_output', | |
| 1115 ], | |
| 1116 constructors_extra = [ | |
| 1117 ExtraConstructor( '(Fixed out)', | |
| 1118 f''' | |
| 1119 {{ | |
| 1120 if (0) {{}} | |
| 1121 else if (out == Fixed_STDOUT) {{ | |
| 1122 m_internal = {rename.ll_fn('fz_stdout')}(); | |
| 1123 }} | |
| 1124 else if (out == Fixed_STDERR) {{ | |
| 1125 m_internal = {rename.ll_fn('fz_stderr')}(); | |
| 1126 }} | |
| 1127 else {{ | |
| 1128 throw {rename.error_class('FZ_ERROR_ABORT')}("Unrecognised Fixed value"); | |
| 1129 }} | |
| 1130 }} | |
| 1131 ''', | |
| 1132 '/* Uses fz_stdout() or fz_stderr(). */', | |
| 1133 # Note that it's ok to call fz_drop_output() on fz_stdout and fz_stderr. | |
| 1134 ), | |
| 1135 ExtraConstructor( | |
| 1136 f'(const {rename.class_("fz_output")}& chain, Filter filter)', | |
| 1137 f''' | |
| 1138 {{ | |
| 1139 if (0) {{}} | |
| 1140 else if (filter == Filter_HEX) {{ | |
| 1141 m_internal = {rename.ll_fn('fz_new_asciihex_output')}(chain.m_internal); | |
| 1142 }} | |
| 1143 else if (filter == Filter_85) {{ | |
| 1144 m_internal = {rename.ll_fn('fz_new_ascii85_output')}(chain.m_internal); | |
| 1145 }} | |
| 1146 else if (filter == Filter_RLE) {{ | |
| 1147 m_internal = {rename.ll_fn('fz_new_rle_output')}(chain.m_internal); | |
| 1148 }} | |
| 1149 else {{ | |
| 1150 throw {rename.error_class('FZ_ERROR_ABORT')}("Unrecognised Filter value"); | |
| 1151 }} | |
| 1152 }} | |
| 1153 ''', | |
| 1154 comment = '/* Calls one of: fz_new_asciihex_output(), fz_new_ascii85_output(), fz_new_rle_output(). */', | |
| 1155 ), | |
| 1156 ], | |
| 1157 class_top = ''' | |
| 1158 enum Fixed | |
| 1159 { | |
| 1160 Fixed_STDOUT=1, | |
| 1161 Fixed_STDERR=2, | |
| 1162 }; | |
| 1163 enum Filter | |
| 1164 { | |
| 1165 Filter_HEX, | |
| 1166 Filter_85, | |
| 1167 Filter_RLE, | |
| 1168 }; | |
| 1169 ''' | |
| 1170 , | |
| 1171 copyable=False, # No fz_keep_output() fn? | |
| 1172 ), | |
| 1173 | |
| 1174 fz_page = ClassExtra( | |
| 1175 constructor_prefixes = [ | |
| 1176 'fz_load_page', | |
| 1177 'fz_load_chapter_page', | |
| 1178 ], | |
| 1179 constructors_extra = [ | |
| 1180 ExtraConstructor( f'({rename.class_("pdf_page")}& pdfpage)', | |
| 1181 f''' | |
| 1182 {{ | |
| 1183 m_internal = {rename.ll_fn('fz_keep_page')}(&pdfpage.m_internal->super); | |
| 1184 }} | |
| 1185 ''', | |
| 1186 f'/* Return {rename.class_("fz_page")} for pdfpage.m_internal.super. */', | |
| 1187 ), | |
| 1188 ], | |
| 1189 methods_extra = [ | |
| 1190 ExtraMethod( | |
| 1191 f'{rename.class_("fz_document")}', | |
| 1192 'doc()', | |
| 1193 f''' | |
| 1194 {{ | |
| 1195 return {rename.class_("fz_document")}( {rename.ll_fn('fz_keep_document')}( m_internal->doc)); | |
| 1196 }} | |
| 1197 ''', | |
| 1198 f'/* Returns wrapper for .doc member. */', | |
| 1199 ), | |
| 1200 ], | |
| 1201 constructor_raw = True, | |
| 1202 ), | |
| 1203 | |
| 1204 fz_path_walker = ClassExtra( | |
| 1205 constructor_raw = 'default', | |
| 1206 virtual_fnptrs = dict( | |
| 1207 self_ = lambda name: f'*({rename.class_("fz_path_walker")}2**) ((fz_path_walker*) {name} + 1)', | |
| 1208 alloc = textwrap.dedent( f''' | |
| 1209 m_internal = (::fz_path_walker*) {rename.ll_fn("fz_calloc")}( | |
| 1210 1, | |
| 1211 sizeof(*m_internal) + sizeof({rename.class_("fz_path_walker")}2*) | |
| 1212 ); | |
| 1213 *({rename.class_("fz_path_walker")}2**) (m_internal + 1) = this; | |
| 1214 '''), | |
| 1215 free = f'{rename.ll_fn("fz_free")}(m_internal);\n', | |
| 1216 comment = textwrap.dedent(f''' | |
| 1217 /* | |
| 1218 We require that the `void* arg` passed to callbacks | |
| 1219 is the original `fz_path_walker*`. So, for example, | |
| 1220 class-aware wrapper mupdf::fz_walk_path() should be | |
| 1221 called like: | |
| 1222 | |
| 1223 mupdf.FzPath path = ...; | |
| 1224 struct Walker : mupdf.FzPathWalker2 {...}; | |
| 1225 Walker walker(...); | |
| 1226 mupdf::fz_walk_path(path, walker, walker.m_internal); | |
| 1227 */ | |
| 1228 ''') | |
| 1229 ), | |
| 1230 ), | |
| 1231 | |
| 1232 fz_pcl_options = ClassExtra( | |
| 1233 constructors_wrappers = [ | |
| 1234 'fz_parse_pcl_options', | |
| 1235 ], | |
| 1236 copyable=False, | |
| 1237 ), | |
| 1238 | |
| 1239 fz_pclm_options = ClassExtra( | |
| 1240 constructor_prefixes = [ | |
| 1241 'fz_parse_pclm_options', | |
| 1242 ], | |
| 1243 copyable=False, | |
| 1244 constructors_extra = [ | |
| 1245 ExtraConstructor( '(const char *args)', | |
| 1246 f''' | |
| 1247 {{ | |
| 1248 {rename.ll_fn('fz_parse_pclm_options')}(m_internal, args); | |
| 1249 }} | |
| 1250 ''', | |
| 1251 '/* Construct using fz_parse_pclm_options(). */', | |
| 1252 ) | |
| 1253 ], | |
| 1254 ), | |
| 1255 | |
| 1256 fz_pdfocr_options = ClassExtra( | |
| 1257 pod = 'inline', | |
| 1258 methods_extra = [ | |
| 1259 ExtraMethod( | |
| 1260 'void', | |
| 1261 'language_set2(const char* language)', | |
| 1262 f''' | |
| 1263 {{ | |
| 1264 fz_strlcpy(this->language, language, sizeof(this->language)); | |
| 1265 }} | |
| 1266 ''', | |
| 1267 '/* Copies <language> into this->language, truncating if necessary. */', | |
| 1268 ), | |
| 1269 ExtraMethod( | |
| 1270 'void', | |
| 1271 'datadir_set2(const char* datadir)', | |
| 1272 f''' | |
| 1273 {{ | |
| 1274 fz_strlcpy(this->datadir, datadir, sizeof(this->datadir)); | |
| 1275 }} | |
| 1276 ''', | |
| 1277 '/* Copies <datadir> into this->datadir, truncating if necessary. */', | |
| 1278 ), | |
| 1279 ], | |
| 1280 ), | |
| 1281 | |
| 1282 fz_pixmap = ClassExtra( | |
| 1283 constructor_raw = True, | |
| 1284 accessors = True, | |
| 1285 ), | |
| 1286 | |
| 1287 fz_point = ClassExtra( | |
| 1288 method_wrappers_static = [ | |
| 1289 'fz_transform_point', | |
| 1290 'fz_transform_point_xy', | |
| 1291 'fz_transform_vector', | |
| 1292 | |
| 1293 ], | |
| 1294 constructors_extra = [ | |
| 1295 ExtraConstructor( '(float x, float y)', | |
| 1296 ''' | |
| 1297 : x(x), y(y) | |
| 1298 { | |
| 1299 } | |
| 1300 ''', | |
| 1301 comment = '/* Construct using specified values. */', | |
| 1302 ), | |
| 1303 ], | |
| 1304 methods_extra = [ | |
| 1305 ExtraMethod( | |
| 1306 f'{rename.class_("fz_point")}&', | |
| 1307 f'transform(const {rename.class_("fz_matrix")}& m)', | |
| 1308 ''' | |
| 1309 { | |
| 1310 double old_x = x; | |
| 1311 x = old_x * m.a + y * m.c + m.e; | |
| 1312 y = old_x * m.b + y * m.d + m.f; | |
| 1313 return *this; | |
| 1314 } | |
| 1315 ''', | |
| 1316 comment = '/* Post-multiply *this by <m> and return *this. */', | |
| 1317 ), | |
| 1318 ], | |
| 1319 pod='inline', | |
| 1320 constructor_raw = True, | |
| 1321 ), | |
| 1322 | |
| 1323 fz_pwg_options = ClassExtra( | |
| 1324 pod=True, | |
| 1325 ), | |
| 1326 | |
| 1327 fz_quad = ClassExtra( | |
| 1328 constructor_prefixes = [ | |
| 1329 'fz_transform_quad', | |
| 1330 'fz_quad_from_rect' | |
| 1331 ], | |
| 1332 pod='inline', | |
| 1333 constructor_raw = True, | |
| 1334 ), | |
| 1335 | |
| 1336 fz_rect = ClassExtra( | |
| 1337 constructor_prefixes = [ | |
| 1338 'fz_transform_rect', | |
| 1339 'fz_bound_display_list', | |
| 1340 'fz_rect_from_irect', | |
| 1341 'fz_rect_from_quad', | |
| 1342 ], | |
| 1343 method_wrappers_static = [ | |
| 1344 'fz_intersect_rect', | |
| 1345 'fz_union_rect', | |
| 1346 ], | |
| 1347 constructors_extra = [ | |
| 1348 ExtraConstructor( | |
| 1349 '(double x0, double y0, double x1, double y1)', | |
| 1350 ''' | |
| 1351 : | |
| 1352 x0(x0), | |
| 1353 x1(x1), | |
| 1354 y0(y0), | |
| 1355 y1(y1) | |
| 1356 { | |
| 1357 } | |
| 1358 ''', | |
| 1359 comment = '/* Construct from specified values. */', | |
| 1360 ), | |
| 1361 ExtraConstructor( | |
| 1362 f'(const {rename.class_("fz_rect")}& rhs)', | |
| 1363 ''' | |
| 1364 : | |
| 1365 x0(rhs.x0), | |
| 1366 y0(rhs.y0), | |
| 1367 x1(rhs.x1), | |
| 1368 y1(rhs.y1) | |
| 1369 { | |
| 1370 } | |
| 1371 ''', | |
| 1372 comment = '/* Copy constructor using plain copy. */', | |
| 1373 ), | |
| 1374 ExtraConstructor( '(Fixed fixed)', | |
| 1375 f''' | |
| 1376 {{ | |
| 1377 if (0) {{}} | |
| 1378 else if (fixed == Fixed_UNIT) *this->internal() = {rename.c_fn('fz_unit_rect')}; | |
| 1379 else if (fixed == Fixed_EMPTY) *this->internal() = {rename.c_fn('fz_empty_rect')}; | |
| 1380 else if (fixed == Fixed_INFINITE) *this->internal() = {rename.c_fn('fz_infinite_rect')}; | |
| 1381 else throw {rename.error_class('FZ_ERROR_ABORT')}( "Unrecognised From value"); | |
| 1382 }} | |
| 1383 ''', | |
| 1384 comment = '/* Construct from fz_unit_rect, fz_empty_rect or fz_infinite_rect. */', | |
| 1385 ), | |
| 1386 ], | |
| 1387 methods_extra = [ | |
| 1388 ExtraMethod( | |
| 1389 'void', | |
| 1390 f'transform(const {rename.class_("fz_matrix")}& m)', | |
| 1391 f''' | |
| 1392 {{ | |
| 1393 *(::fz_rect*) &this->x0 = {rename.c_fn('fz_transform_rect')}(*(::fz_rect*) &this->x0, *(::fz_matrix*) &m.a); | |
| 1394 }} | |
| 1395 ''', | |
| 1396 comment = '/* Transforms *this using fz_transform_rect() with <m>. */', | |
| 1397 ), | |
| 1398 ExtraMethod( 'bool', 'contains(double x, double y)', | |
| 1399 ''' | |
| 1400 { | |
| 1401 if (is_empty()) { | |
| 1402 return false; | |
| 1403 } | |
| 1404 return true | |
| 1405 && x >= x0 | |
| 1406 && x < x1 | |
| 1407 && y >= y0 | |
| 1408 && y < y1 | |
| 1409 ; | |
| 1410 } | |
| 1411 ''', | |
| 1412 comment = '/* Convenience method using fz_contains_rect(). */', | |
| 1413 ), | |
| 1414 ExtraMethod( 'bool', f'contains({rename.class_("fz_rect")}& rhs)', | |
| 1415 f''' | |
| 1416 {{ | |
| 1417 return {rename.c_fn('fz_contains_rect')}(*(::fz_rect*) &x0, *(::fz_rect*) &rhs.x0); | |
| 1418 }} | |
| 1419 ''', | |
| 1420 comment = '/* Uses fz_contains_rect(*this, rhs). */', | |
| 1421 ), | |
| 1422 ExtraMethod( 'bool', 'is_empty()', | |
| 1423 f''' | |
| 1424 {{ | |
| 1425 return {rename.c_fn('fz_is_empty_rect')}(*(::fz_rect*) &x0); | |
| 1426 }} | |
| 1427 ''', | |
| 1428 comment = '/* Uses fz_is_empty_rect(). */', | |
| 1429 ), | |
| 1430 ExtraMethod( 'void', f'union_({rename.class_("fz_rect")}& rhs)', | |
| 1431 f''' | |
| 1432 {{ | |
| 1433 *(::fz_rect*) &x0 = {rename.c_fn('fz_union_rect')}(*(::fz_rect*) &x0, *(::fz_rect*) &rhs.x0); | |
| 1434 }} | |
| 1435 ''', | |
| 1436 comment = '/* Updates *this using fz_union_rect(). */', | |
| 1437 ), | |
| 1438 ], | |
| 1439 pod='inline', | |
| 1440 constructor_raw = True, | |
| 1441 copyable = True, | |
| 1442 class_top = ''' | |
| 1443 enum Fixed | |
| 1444 { | |
| 1445 Fixed_UNIT, | |
| 1446 Fixed_EMPTY, | |
| 1447 Fixed_INFINITE, | |
| 1448 }; | |
| 1449 ''', | |
| 1450 ), | |
| 1451 | |
| 1452 fz_separations = ClassExtra( | |
| 1453 constructor_raw = 'default', | |
| 1454 opaque = True, | |
| 1455 ), | |
| 1456 | |
| 1457 fz_shade = ClassExtra( | |
| 1458 methods_extra = [ | |
| 1459 ExtraMethod( 'void', | |
| 1460 f'{rename.method( "fz_shade", "fz_paint_shade_no_cache")}(' | |
| 1461 + f' const {rename.class_("fz_colorspace")}& override_cs' | |
| 1462 + f', {rename.class_("fz_matrix")}& ctm' | |
| 1463 + f', const {rename.class_("fz_pixmap")}& dest' | |
| 1464 + f', {rename.class_("fz_color_params")}& color_params' | |
| 1465 + f', {rename.class_("fz_irect")}& bbox' | |
| 1466 + f', const {rename.class_("fz_overprint")}& eop' | |
| 1467 + f')' | |
| 1468 , | |
| 1469 f''' | |
| 1470 {{ | |
| 1471 return {rename.ll_fn('fz_paint_shade')}( | |
| 1472 this->m_internal, | |
| 1473 override_cs.m_internal, | |
| 1474 *(::fz_matrix*) &ctm.a, | |
| 1475 dest.m_internal, | |
| 1476 *(::fz_color_params*) &color_params.ri, | |
| 1477 *(::fz_irect*) &bbox.x0, | |
| 1478 eop.m_internal, | |
| 1479 NULL /*cache*/ | |
| 1480 ); | |
| 1481 }} | |
| 1482 ''', | |
| 1483 comment = f'/* Extra wrapper for fz_paint_shade(), passing cache=NULL. */', | |
| 1484 ), | |
| 1485 ], | |
| 1486 ), | |
| 1487 | |
| 1488 fz_shade_color_cache = ClassExtra( | |
| 1489 ), | |
| 1490 | |
| 1491 # Our wrappers of the fz_stext_* structs all have a default copy | |
| 1492 # constructor - there are no fz_keep_stext_*() functions. | |
| 1493 # | |
| 1494 # We define explicit accessors for fz_stext_block::u.i.* because SWIG | |
| 1495 # does not handle nested unions. | |
| 1496 # | |
| 1497 fz_stext_block = ClassExtra( | |
| 1498 iterator_next = ('u.t.first_line', 'u.t.last_line'), | |
| 1499 copyable='default', | |
| 1500 methods_extra = [ | |
| 1501 ExtraMethod( f'{rename.class_("fz_matrix")}', 'i_transform()', | |
| 1502 f''' | |
| 1503 {{ | |
| 1504 if (m_internal->type != FZ_STEXT_BLOCK_IMAGE) {{ | |
| 1505 throw std::runtime_error("Not an image"); | |
| 1506 }} | |
| 1507 return m_internal->u.i.transform; | |
| 1508 }} | |
| 1509 ''', | |
| 1510 comment=f'/* Returns m_internal.u.i.transform if m_internal->type is FZ_STEXT_BLOCK_IMAGE, else throws. */', | |
| 1511 ), | |
| 1512 ExtraMethod( f'{rename.class_("fz_image")}', 'i_image()', | |
| 1513 f''' | |
| 1514 {{ | |
| 1515 if (m_internal->type != FZ_STEXT_BLOCK_IMAGE) {{ | |
| 1516 throw std::runtime_error("Not an image"); | |
| 1517 }} | |
| 1518 return {rename.class_("fz_image")}({rename.ll_fn('fz_keep_image')}(m_internal->u.i.image)); | |
| 1519 }} | |
| 1520 ''', | |
| 1521 comment=f'/* Returns m_internal.u.i.image if m_internal->type is FZ_STEXT_BLOCK_IMAGE, else throws. */', | |
| 1522 ), | |
| 1523 ], | |
| 1524 ), | |
| 1525 | |
| 1526 fz_stext_char = ClassExtra( | |
| 1527 copyable='default', | |
| 1528 ), | |
| 1529 | |
| 1530 fz_stext_line = ClassExtra( | |
| 1531 iterator_next = ('first_char', 'last_char'), | |
| 1532 copyable='default', | |
| 1533 constructor_raw=True, | |
| 1534 ), | |
| 1535 | |
| 1536 fz_stext_options = ClassExtra( | |
| 1537 constructors_extra = [ | |
| 1538 ExtraConstructor( '(int flags, float scale=1.0)', | |
| 1539 ''' | |
| 1540 : | |
| 1541 flags(flags), | |
| 1542 scale(scale) | |
| 1543 { | |
| 1544 assert(!(flags & FZ_STEXT_CLIP_RECT)); | |
| 1545 } | |
| 1546 ''', | |
| 1547 comment = '/* Construct with .flags, .scale but no clip. */', | |
| 1548 ), | |
| 1549 ExtraConstructor( '(int flags, fz_rect clip, float scale=1.0)', | |
| 1550 ''' | |
| 1551 : | |
| 1552 flags(flags | FZ_STEXT_CLIP_RECT), | |
| 1553 scale(scale), | |
| 1554 clip(clip) | |
| 1555 { | |
| 1556 } | |
| 1557 ''', | |
| 1558 comment = | |
| 1559 '/* Construct with .flags, .scale and .clip; FZ_STEXT_CLIP_RECT\n' | |
| 1560 'is automatically set in .flags. */' | |
| 1561 , | |
| 1562 ), | |
| 1563 ], | |
| 1564 pod='inline', | |
| 1565 ), | |
| 1566 | |
| 1567 fz_stext_page = ClassExtra( | |
| 1568 methods_extra = [ | |
| 1569 ExtraMethod( | |
| 1570 'std::string', | |
| 1571 f'{rename.method( "fz_stext_page", "fz_copy_selection")}(' | |
| 1572 + f'{rename.class_("fz_point")}& a' | |
| 1573 + f', {rename.class_("fz_point")}& b' | |
| 1574 + f', int crlf' | |
| 1575 + f')', | |
| 1576 f''' | |
| 1577 {{ | |
| 1578 char* text = {rename.ll_fn('fz_copy_selection')}(m_internal, *(::fz_point *) &a.x, *(::fz_point *) &b.x, crlf); | |
| 1579 std::string ret(text); | |
| 1580 {rename.ll_fn('fz_free')}(text); | |
| 1581 return ret; | |
| 1582 }} | |
| 1583 ''', | |
| 1584 comment = f'/* Wrapper for fz_copy_selection() that returns std::string. */', | |
| 1585 ), | |
| 1586 ExtraMethod( | |
| 1587 'std::string', | |
| 1588 f'{rename.method( "fz_stext_page", "fz_copy_rectangle")}({rename.class_("fz_rect")}& area, int crlf)', | |
| 1589 f''' | |
| 1590 {{ | |
| 1591 char* text = {rename.ll_fn('fz_copy_rectangle')}(m_internal, *(::fz_rect*) &area.x0, crlf); | |
| 1592 std::string ret(text); | |
| 1593 {rename.ll_fn('fz_free')}(text); | |
| 1594 return ret; | |
| 1595 }} | |
| 1596 ''', | |
| 1597 comment = f'/* Wrapper for fz_copy_rectangle() that returns a std::string. */', | |
| 1598 ), | |
| 1599 ExtraMethod( | |
| 1600 f'std::vector<{rename.class_("fz_quad")}>', | |
| 1601 f'{rename.method( "fz_stext_page", "search_stext_page")}(const char* needle, int *hit_mark, int max_quads)', | |
| 1602 f''' | |
| 1603 {{ | |
| 1604 std::vector<{rename.class_("fz_quad")}> ret(max_quads); | |
| 1605 int n = {rename.ll_fn('fz_search_stext_page')}(m_internal, needle, hit_mark, ret[0].internal(), max_quads); | |
| 1606 ret.resize(n); | |
| 1607 return ret; | |
| 1608 }} | |
| 1609 ''', | |
| 1610 '/* Wrapper for fz_search_stext_page() that returns std::vector of Quads. */', | |
| 1611 ) | |
| 1612 ], | |
| 1613 iterator_next = ('first_block', 'last_block'), | |
| 1614 copyable=False, | |
| 1615 constructor_raw = True, | |
| 1616 ), | |
| 1617 | |
| 1618 fz_text_span = ClassExtra( | |
| 1619 copyable=False, | |
| 1620 methods_extra = [ | |
| 1621 # We provide class-aware accessors where possible. (Some | |
| 1622 # types' wrapper classes are not copyable so we can't do | |
| 1623 # this for all data). | |
| 1624 ExtraMethod( | |
| 1625 f'{rename.class_("fz_font")}', | |
| 1626 f'font()', | |
| 1627 f''' | |
| 1628 {{ | |
| 1629 return {rename.class_("fz_font")}( ll_fz_keep_font( m_internal->font)); | |
| 1630 }} | |
| 1631 ''', | |
| 1632 f'/* Gives class-aware access to m_internal->font. */', | |
| 1633 ), | |
| 1634 ExtraMethod( | |
| 1635 f'{rename.class_("fz_matrix")}', | |
| 1636 f'trm()', | |
| 1637 f''' | |
| 1638 {{ | |
| 1639 return {rename.class_("fz_matrix")}( m_internal->trm); | |
| 1640 }} | |
| 1641 ''', | |
| 1642 f'/* Gives class-aware access to m_internal->trm. */', | |
| 1643 ), | |
| 1644 ExtraMethod( | |
| 1645 f'fz_text_item&', | |
| 1646 f'items( int i)', | |
| 1647 f''' | |
| 1648 {{ | |
| 1649 assert( i < m_internal->len); | |
| 1650 return m_internal->items[i]; | |
| 1651 }} | |
| 1652 ''', | |
| 1653 ''' | |
| 1654 /* Gives access to m_internal->items[i]. | |
| 1655 Returned reference is only valid as long as `this`. | |
| 1656 Provided mainly for use by SWIG bindings. | |
| 1657 */ | |
| 1658 ''', | |
| 1659 ), | |
| 1660 ], | |
| 1661 ), | |
| 1662 | |
| 1663 fz_stream = ClassExtra( | |
| 1664 constructor_prefixes = [ | |
| 1665 'fz_open_file', | |
| 1666 'fz_open_memory', | |
| 1667 ], | |
| 1668 constructors_extra = [ | |
| 1669 ExtraConstructor( '(const std::string& filename)', | |
| 1670 f''' | |
| 1671 : m_internal({rename.ll_fn('fz_open_file')}(filename.c_str())) | |
| 1672 {{ | |
| 1673 }} | |
| 1674 ''', | |
| 1675 comment = '/* Construct using fz_open_file(). */', | |
| 1676 ) | |
| 1677 ], | |
| 1678 ), | |
| 1679 | |
| 1680 fz_story_element_position = ClassExtra( | |
| 1681 pod='inline', | |
| 1682 ), | |
| 1683 | |
| 1684 fz_transition = ClassExtra( | |
| 1685 pod='inline', | |
| 1686 constructor_raw = True, | |
| 1687 ), | |
| 1688 | |
| 1689 pdf_annot = ClassExtra( | |
| 1690 constructor_raw = 'default', | |
| 1691 ), | |
| 1692 | |
| 1693 pdf_clean_options = ClassExtra( | |
| 1694 constructors_extra = [ | |
| 1695 ExtraConstructor( '()', | |
| 1696 f''' | |
| 1697 {{ | |
| 1698 /* Use memcpy() otherwise we get 'invalid array assignment' errors. */ | |
| 1699 memcpy(&this->internal()->write, &pdf_default_write_options, sizeof(this->internal()->write)); | |
| 1700 memset(&this->internal()->image, 0, sizeof(this->internal()->image)); | |
| 1701 }} | |
| 1702 ''', | |
| 1703 comment = '/* Default constructor, makes copy of pdf_default_write_options. */' | |
| 1704 ), | |
| 1705 ExtraConstructor( | |
| 1706 f'(const {rename.class_("pdf_clean_options")}& rhs)', | |
| 1707 f''' | |
| 1708 {{ | |
| 1709 *this = rhs; | |
| 1710 }} | |
| 1711 ''', | |
| 1712 comment = '/* Copy constructor using raw memcopy(). */' | |
| 1713 ), | |
| 1714 ], | |
| 1715 methods_extra = [ | |
| 1716 ExtraMethod( | |
| 1717 f'{rename.class_("pdf_clean_options")}&', | |
| 1718 f'operator=(const {rename.class_("pdf_clean_options")}& rhs)', | |
| 1719 f''' | |
| 1720 {{ | |
| 1721 memcpy(this->internal(), rhs.internal(), sizeof(*this->internal())); | |
| 1722 return *this; | |
| 1723 }} | |
| 1724 ''', | |
| 1725 comment = '/* Assignment using plain memcpy(). */', | |
| 1726 ), | |
| 1727 ExtraMethod( | |
| 1728 f'void', | |
| 1729 f'write_opwd_utf8_set(const std::string& text)', | |
| 1730 f''' | |
| 1731 {{ | |
| 1732 size_t len = std::min(text.size(), sizeof(write.opwd_utf8) - 1); | |
| 1733 memcpy(write.opwd_utf8, text.c_str(), len); | |
| 1734 write.opwd_utf8[len] = 0; | |
| 1735 }} | |
| 1736 ''', | |
| 1737 '/* Copies <text> into write.opwd_utf8[]. */', | |
| 1738 ), | |
| 1739 ExtraMethod( | |
| 1740 f'void', | |
| 1741 f'write_upwd_utf8_set(const std::string& text)', | |
| 1742 f''' | |
| 1743 {{ | |
| 1744 size_t len = std::min(text.size(), sizeof(write.upwd_utf8) - 1); | |
| 1745 memcpy(write.upwd_utf8, text.c_str(), len); | |
| 1746 write.upwd_utf8[len] = 0; | |
| 1747 }} | |
| 1748 ''', | |
| 1749 '/* Copies <text> into upwd_utf8[]. */', | |
| 1750 ), | |
| 1751 ], | |
| 1752 pod = 'inline', | |
| 1753 copyable = 'default', | |
| 1754 ), | |
| 1755 | |
| 1756 pdf_document = ClassExtra( | |
| 1757 constructor_prefixes = [ | |
| 1758 'pdf_open_document', | |
| 1759 'pdf_create_document', | |
| 1760 'pdf_document_from_fz_document', | |
| 1761 ], | |
| 1762 methods_extra = [ | |
| 1763 ExtraMethod( | |
| 1764 f'{rename.class_("fz_document")}', | |
| 1765 'super()', | |
| 1766 f''' | |
| 1767 {{ | |
| 1768 return {rename.class_("fz_document")}( {rename.ll_fn('fz_keep_document')}( &m_internal->super)); | |
| 1769 }} | |
| 1770 ''', | |
| 1771 f'/* Returns wrapper for .super member. */', | |
| 1772 ), | |
| 1773 ], | |
| 1774 ), | |
| 1775 | |
| 1776 pdf_filter_factory = ClassExtra( | |
| 1777 pod = 'inline', | |
| 1778 virtual_fnptrs = dict( | |
| 1779 self_ = lambda name: f'({rename.class_("pdf_filter_factory")}2*) {name}', | |
| 1780 self_n = 6, | |
| 1781 alloc = f'this->options = this;\n', | |
| 1782 ), | |
| 1783 ), | |
| 1784 | |
| 1785 pdf_filter_options = ClassExtra( | |
| 1786 pod = 'inline', | |
| 1787 # We don't need to allocate extra space, and because we are a | |
| 1788 # POD class, we can simply let our default constructor run. | |
| 1789 # | |
| 1790 # this->opaque is passed as arg[2]. | |
| 1791 # | |
| 1792 virtual_fnptrs = dict( | |
| 1793 self_ = lambda name: f'({rename.class_("pdf_filter_options")}2*) {name}', | |
| 1794 self_n = 2, | |
| 1795 alloc = f'this->opaque = this;\n', | |
| 1796 ), | |
| 1797 constructors_extra = [ | |
| 1798 ExtraConstructor( '()', | |
| 1799 f''' | |
| 1800 {{ | |
| 1801 this->recurse = 0; | |
| 1802 this->instance_forms = 0; | |
| 1803 this->ascii = 0; | |
| 1804 this->opaque = nullptr; | |
| 1805 this->complete = nullptr; | |
| 1806 this->filters = nullptr; | |
| 1807 pdf_filter_factory eof = {{ nullptr, nullptr}}; | |
| 1808 m_filters.push_back( eof); | |
| 1809 this->newlines = 0; | |
| 1810 }} | |
| 1811 ''', | |
| 1812 comment = '/* Default constructor initialises all fields to null/zero. */', | |
| 1813 ) | |
| 1814 ], | |
| 1815 methods_extra = [ | |
| 1816 ExtraMethod( | |
| 1817 'void', | |
| 1818 f'add_factory( const pdf_filter_factory& factory)', | |
| 1819 textwrap.dedent( f''' | |
| 1820 {{ | |
| 1821 this->m_filters.back() = factory; | |
| 1822 pdf_filter_factory eof = {{ nullptr, nullptr}}; | |
| 1823 this->m_filters.push_back( eof); | |
| 1824 this->filters = &this->m_filters[0]; | |
| 1825 }} | |
| 1826 '''), | |
| 1827 comment = f'/* Appends `factory` to internal vector and updates this->filters. */', | |
| 1828 ), | |
| 1829 ], | |
| 1830 class_bottom = textwrap.dedent( f''' | |
| 1831 std::vector< pdf_filter_factory> m_filters; | |
| 1832 '''), | |
| 1833 ), | |
| 1834 | |
| 1835 pdf_lexbuf = ClassExtra( | |
| 1836 constructors_extra = [ | |
| 1837 ExtraConstructor( '(int size)', | |
| 1838 f''' | |
| 1839 {{ | |
| 1840 m_internal = new ::pdf_lexbuf; | |
| 1841 {rename.ll_fn('pdf_lexbuf_init')}(m_internal, size); | |
| 1842 }} | |
| 1843 ''', | |
| 1844 comment = '/* Constructor that calls pdf_lexbuf_init(size). */', | |
| 1845 ), | |
| 1846 ], | |
| 1847 methods_extra = [ | |
| 1848 ExtraMethod( | |
| 1849 '', | |
| 1850 '~()', | |
| 1851 f''' | |
| 1852 {{ | |
| 1853 {rename.ll_fn('pdf_lexbuf_fin')}(m_internal); | |
| 1854 delete m_internal; | |
| 1855 }} | |
| 1856 ''', | |
| 1857 comment = '/* Destructor that calls pdf_lexbuf_fin(). */', | |
| 1858 ), | |
| 1859 ], | |
| 1860 ), | |
| 1861 | |
| 1862 pdf_layer_config = ClassExtra( | |
| 1863 pod = 'inline', | |
| 1864 ), | |
| 1865 | |
| 1866 pdf_layer_config_ui = ClassExtra( | |
| 1867 pod = 'inline', | |
| 1868 constructors_extra = [ | |
| 1869 ExtraConstructor( '()', | |
| 1870 f''' | |
| 1871 {{ | |
| 1872 this->text = nullptr; | |
| 1873 this->depth = 0; | |
| 1874 this->type = PDF_LAYER_UI_LABEL; | |
| 1875 this->selected = 0; | |
| 1876 this->locked = 0; | |
| 1877 }} | |
| 1878 ''', | |
| 1879 comment = '/* Default constructor sets .text to null, .type to PDF_LAYER_UI_LABEL, and other fields to zero. */', | |
| 1880 ), | |
| 1881 ], | |
| 1882 ), | |
| 1883 | |
| 1884 pdf_obj = ClassExtra( | |
| 1885 constructor_raw = 'default', | |
| 1886 methods_extra = [ | |
| 1887 ExtraMethod( | |
| 1888 f'{rename.class_("pdf_obj")}', | |
| 1889 f'{rename.method( "pdf_obj", "pdf_dict_get")}(int key)', | |
| 1890 f''' | |
| 1891 {{ | |
| 1892 ::pdf_obj* temp = {rename.ll_fn('pdf_dict_get')}(this->m_internal, (::pdf_obj*)(uintptr_t) key); | |
| 1893 {rename.ll_fn('pdf_keep_obj')}(temp); | |
| 1894 auto ret = {rename.class_('pdf_obj')}(temp); | |
| 1895 return ret; | |
| 1896 }} | |
| 1897 ''', | |
| 1898 comment = '/* Typesafe wrapper for looking up things such as PDF_ENUM_NAME_Annots. */', | |
| 1899 overload=True, | |
| 1900 ), | |
| 1901 ExtraMethod( | |
| 1902 f'std::string', | |
| 1903 f'{rename.method( "pdf_obj", "pdf_load_field_name2")}()', | |
| 1904 f''' | |
| 1905 {{ | |
| 1906 return {rename.namespace_fn('pdf_load_field_name2')}( *this); | |
| 1907 }} | |
| 1908 ''', | |
| 1909 comment = f'/* Alternative to `{rename.fn("pdf_load_field_name")}()` that returns a std::string. */', | |
| 1910 ), | |
| 1911 ] | |
| 1912 ), | |
| 1913 | |
| 1914 pdf_page = ClassExtra( | |
| 1915 methods_extra = [ | |
| 1916 ExtraMethod( | |
| 1917 f'{rename.class_("fz_page")}', | |
| 1918 'super()', | |
| 1919 f''' | |
| 1920 {{ | |
| 1921 return {rename.class_("fz_page")}( {rename.ll_fn('fz_keep_page')}( &m_internal->super)); | |
| 1922 }} | |
| 1923 ''', | |
| 1924 f'/* Returns wrapper for .super member. */', | |
| 1925 ), | |
| 1926 ExtraMethod( | |
| 1927 f'{rename.class_("pdf_document")}', | |
| 1928 'doc()', | |
| 1929 f''' | |
| 1930 {{ | |
| 1931 return {rename.class_("pdf_document")}( {rename.ll_fn('pdf_keep_document')}( m_internal->doc)); | |
| 1932 }} | |
| 1933 ''', | |
| 1934 f'/* Returns wrapper for .doc member. */', | |
| 1935 ), | |
| 1936 ExtraMethod( | |
| 1937 f'{rename.class_("pdf_obj")}', | |
| 1938 'obj()', | |
| 1939 f''' | |
| 1940 {{ | |
| 1941 return {rename.class_("pdf_obj")}( {rename.ll_fn('pdf_keep_obj')}( m_internal->obj)); | |
| 1942 }} | |
| 1943 ''', | |
| 1944 f'/* Returns wrapper for .obj member. */', | |
| 1945 ), | |
| 1946 ], | |
| 1947 ), | |
| 1948 | |
| 1949 pdf_image_rewriter_options = ClassExtra( | |
| 1950 pod = 'inline', | |
| 1951 copyable = 'default', | |
| 1952 ), | |
| 1953 | |
| 1954 pdf_processor = ClassExtra( | |
| 1955 virtual_fnptrs = dict( | |
| 1956 self_ = lambda name: f'(*({rename.class_("pdf_processor")}2**) ({name} + 1))', | |
| 1957 alloc = textwrap.dedent( f''' | |
| 1958 m_internal = (::pdf_processor*) {rename.ll_fn("pdf_new_processor")}( | |
| 1959 sizeof(*m_internal) | |
| 1960 + sizeof({rename.class_("pdf_processor")}2*) | |
| 1961 ); | |
| 1962 *(({rename.class_("pdf_processor")}2**) (m_internal + 1)) = this; | |
| 1963 '''), | |
| 1964 ), | |
| 1965 ), | |
| 1966 | |
| 1967 pdf_recolor_options = ClassExtra( | |
| 1968 pod = 'inline', | |
| 1969 ), | |
| 1970 | |
| 1971 pdf_redact_options = ClassExtra( | |
| 1972 pod = 'inline', | |
| 1973 ), | |
| 1974 | |
| 1975 pdf_sanitize_filter_options = ClassExtra( | |
| 1976 pod = 'inline', | |
| 1977 # this->opaque is passed as arg[1]. | |
| 1978 virtual_fnptrs = dict( | |
| 1979 self_ = lambda name: f'({rename.class_("pdf_sanitize_filter_options")}2*) {name}', | |
| 1980 alloc = f'this->opaque = this;\n', | |
| 1981 ), | |
| 1982 ), | |
| 1983 | |
| 1984 pdf_write_options = ClassExtra( | |
| 1985 constructors_extra = [ | |
| 1986 ExtraConstructor( '()', | |
| 1987 f''' | |
| 1988 {{ | |
| 1989 /* Use memcpy() otherwise we get 'invalid array assignment' errors. */ | |
| 1990 memcpy(this->internal(), &pdf_default_write_options, sizeof(*this->internal())); | |
| 1991 }} | |
| 1992 ''', | |
| 1993 comment = '/* Default constructor, makes copy of pdf_default_write_options. */' | |
| 1994 ), | |
| 1995 ExtraConstructor( | |
| 1996 f'(const {rename.class_("pdf_write_options")}& rhs)', | |
| 1997 f''' | |
| 1998 {{ | |
| 1999 *this = rhs; | |
| 2000 }} | |
| 2001 ''', | |
| 2002 comment = '/* Copy constructor using raw memcopy(). */' | |
| 2003 ), | |
| 2004 ], | |
| 2005 methods_extra = [ | |
| 2006 ExtraMethod( | |
| 2007 f'{rename.class_("pdf_write_options")}&', | |
| 2008 f'operator=(const {rename.class_("pdf_write_options")}& rhs)', | |
| 2009 f''' | |
| 2010 {{ | |
| 2011 memcpy(this->internal(), rhs.internal(), sizeof(*this->internal())); | |
| 2012 return *this; | |
| 2013 }} | |
| 2014 ''', | |
| 2015 comment = '/* Assignment using plain memcpy(). */', | |
| 2016 ), | |
| 2017 ExtraMethod( | |
| 2018 # Would prefer to call this opwd_utf8_set() but | |
| 2019 # this conflicts with SWIG-generated accessor for | |
| 2020 # opwd_utf8. | |
| 2021 f'void', | |
| 2022 f'opwd_utf8_set_value(const std::string& text)', | |
| 2023 f''' | |
| 2024 {{ | |
| 2025 size_t len = std::min(text.size(), sizeof(opwd_utf8) - 1); | |
| 2026 memcpy(opwd_utf8, text.c_str(), len); | |
| 2027 opwd_utf8[len] = 0; | |
| 2028 }} | |
| 2029 ''', | |
| 2030 '/* Copies <text> into opwd_utf8[]. */', | |
| 2031 ), | |
| 2032 ExtraMethod( | |
| 2033 f'void', | |
| 2034 f'upwd_utf8_set_value(const std::string& text)', | |
| 2035 f''' | |
| 2036 {{ | |
| 2037 size_t len = std::min(text.size(), sizeof(upwd_utf8) - 1); | |
| 2038 memcpy(upwd_utf8, text.c_str(), len); | |
| 2039 upwd_utf8[len] = 0; | |
| 2040 }} | |
| 2041 ''', | |
| 2042 '/* Copies <text> into upwd_utf8[]. */', | |
| 2043 ), | |
| 2044 ], | |
| 2045 pod = 'inline', | |
| 2046 copyable = 'default', | |
| 2047 ) | |
| 2048 ) |
