Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
3 1øªjéã@spddlZddlmZddlmZddlmZddlmZddl m Z m Z m Z m Z mZmZmZmZmZmZmZmZmZmZddlmZmZdd lmZdd lmZmZm Z m!Z!m"Z"dd l#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z+dd l)m,Z-ddl)m.Z/ddl)m0Z1ddl2m3Z3m4Z4ddl5m6Z6ddl7m8Z8m9Z9m:Z:m;Z;mZ>m?Z?m@Z@mAZAmBZBmCZCmDZDyddlEmFZFdZGWneHk �r†eIZFdZGYnXdZJe eKe eKeBdœdd„ZLe eKeeBeMfddœdd„ZNe eKddœdd„ZOeKe eKePd œd!d"„ZQGd#d$„d$ƒZReGd%d&„d&ƒƒZSGd'd(„d(eeSƒZTGd)d*„d*e:ƒZUGd+d,„d,eeUƒZVe:eeKeeKeeeKeeKfd-œd.d/„ZWdS)0éN)Ú dataclass)ÚDecimal)ÚBytesIO)ÚPath)ÚAnyÚCallableÚDictÚIterableÚIteratorÚListÚLiteralÚOptionalÚSequenceÚSetÚTupleÚUnionÚcastÚoverloadé)Úbuild_char_mapÚunknown_char_map)ÚPdfCommonDocProtocol)ÚOrientationNotFoundErrorÚ _layout_modeÚcrlf_space_checkÚ handle_tjÚmult)ÚCompressedTransformationMatrixÚTransformationMatrixTypeÚ_human_readable_bytesÚlogger_warningÚmatrix_multiply)ÚAnnotationDictionaryAttributes)ÚImageAttributes)ÚPageAttributes)Ú Resources)ÚPageSizeNotDefinedErrorÚ PdfReadError)Ú_xobj_to_image) Ú ArrayObjectÚ ContentStreamÚDictionaryObjectÚEncodedStreamObjectÚ FloatObjectÚIndirectObjectÚ NameObjectÚ NullObjectÚ NumberObjectÚ PdfObjectÚRectangleObjectÚ StreamObjectÚis_null_or_none)ÚImageFTÚcropbox)ÚselfÚnameÚdefaultsÚreturncCsp|j|ƒ}t|tƒr|St|ƒrBx |D]}|j|ƒ}|dk r&Pq&Wt|tƒrX|jj|ƒ}t|ƒ}t|||ƒ|S)N)ÚgetÚ isinstancer3r5r.ÚpdfÚ get_objectÚ_set_rectangle)r8r9r:ÚretvalÚd©rCú,/tmp/pip-build-_d5lkt3n/pypdf/pypdf/_page.pyÚ_get_rectanglees       rE)r8r9Úvaluer;cCst|ƒ}|||<dS)N)r/)r8r9rFrCrCrDr@usr@)r8r9r;cCs ||=dS)NrC)r8r9rCrCrDÚ_delete_rectanglezsrG)r9Úfallbackr;cs&t‡‡fdd„‡fdd„‡fdd„ƒS)Ncs t|ˆˆƒS)N)rE)r8)rHr9rCrDÚ€sz,_create_rectangle_accessor..cs t|ˆ|ƒS)N)r@)r8rF)r9rCrDrI�scs t|ˆƒS)N)rG)r8)r9rCrDrI‚s)Úproperty)r9rHrC)rHr9rDÚ_create_rectangle_accessor~s  rKc@s(eZdZdZd#edœdd„Zeedœdd „ƒZe eed œd d „ƒZ ddd œdd„Z d$e e ddœdd„Z d%ee ee ddœdd„Ze ddœdd„Zedœdd„Zed&ee eee dœdd„ƒZed'ee e feee e fdœd d„ƒZd(eee e fee feeee e fee fdœd!d„ZdS))ÚTransformationuò Represent a 2D transformation. The transformation between two coordinate systems is represented by a 3-by-3 transformation matrix matrix with the following form:: a b 0 c d 0 e f 1 Because a transformation matrix has only six elements that can be changed, it is usually specified in PDF as the six-element array [ a b c d e f ]. Coordinate transformations are expressed as matrix multiplications:: a b 0 [ x′ y′ 1 ] = [ x y 1 ] × c d 0 e f 1 Example: >>> from pypdf import Transformation >>> op = Transformation().scale(sx=2, sy=3).translate(tx=10, ty=20) >>> page.add_transformation(op) rr)ÚctmcCs ||_dS)N)rM)r8rMrCrCrDÚ__init__£szTransformation.__init__)r;cCs@|jd|jddf|jd|jddf|jd|jddffS)z Return the transformation matrix as a tuple of tuples in the form: ((a, b, 0), (c, d, 0), (e, f, 1)) rréééé)rM)r8rCrCrDÚmatrix¦szTransformation.matrix)rSr;cCs@|dd|dd|dd|dd|dd|ddfS)a Compresses the transformation matrix into a tuple of (a, b, c, d, e, f). Args: matrix: The transformation matrix as a tuple of tuples. Returns: A tuple representing the transformation matrix as (a, b, c, d, e, f) rrrOrC)rSrCrCrDÚcompress³s     zTransformation.compress)Úmr;cCstjt|j|jƒƒ}t|ƒS)aÜ Apply one transformation to another. Args: m: a Transformation to apply. Returns: A new ``Transformation`` instance Example: >>> from pypdf import Transformation >>> op = Transformation((1, 0, 0, -1, 0, height)) # vertical mirror >>> op = Transformation().transform(Transformation((-1, 0, 0, 1, iwidth, 0))) # horizontal mirror >>> page.add_transformation(op) )rLrTr!rS)r8rUrMrCrCrDÚ transformÇszTransformation.transform)ÚtxÚtyr;cCs<|j}t|d|d|d|d|d||d|fd�S)zæ Translate the contents of a page. Args: tx: The translation along the x-axis. ty: The translation along the y-axis. Returns: A new ``Transformation`` instance rrrOrPrQrR)rM)rMrL)r8rWrXrUrCrCrDÚ translateÚs zTransformation.translateN)ÚsxÚsyr;cCsx|dkr|dkrtdƒ‚|dkr$|}|dkr0|}|dk sr=r6rÚsaveÚpagesÚimagesr]r?Ú_objectsÚidnumrr9ÚrfindÚdataÚimage) r8rzr{r|r(r+r2ÚbÚreaderÚ extensionÚ byte_streamÚimgrCrCrDÚreplaceVs0    (zImageFile.replace)r;cCs&|jj›d|j›dtt|jƒƒ›d�S)Nz(name=z, data: rf)Ú __class__rpr9rÚlenr‹)r8rCrCrDÚ__str__ŽszImageFile.__str__cCs"|jƒdd…dt|jƒ›d�S)Nrz, hash: rféÿÿÿÿ)r•Úhashr‹)r8rCrCrDrg‘szImageFile.__repr__)rprqrrrsr9rur‹ÚbytesrŒr r6r‚r.rr’r•rgrCrCrCrDrw:s   8rwc@s4eZdZdZegeeeeeffeeeeeeefge fddœdd„Z e dœdd„Z eeeeefdœd d „Z eeeeeefe fdœd d „Zeee eeefe d œdd„ƒZeeee d œdd„ƒZee eeeeeefee ee fd œdd„Zee dœdd„Zedœdd„ZdS)ÚVirtualListImageszÊ Provides access to images referenced within a page. Only one copy will be returned if the usage is used on the same page multiple times. See :func:`PageObject.images` for more details. N)Ú ids_functionÚ get_functionr;cCs||_||_d|_dS)Nrr–)ršr›Úcurrent)r8ršr›rCrCrDrNœszVirtualListImages.__init__)r;cCs t|jƒƒS)N)r”rš)r8rCrCrDÚ__len__¥szVirtualListImages.__len__cCs|jƒS)N)rš)r8rCrCrDÚkeys¨szVirtualListImages.keyscs‡fdd„ˆjƒDƒS)Ncsg|]}|ˆ|f‘qSrCrC)Ú.0Úx)r8rCrDú ¬sz+VirtualListImages.items..)rš)r8rC)r8rDÚitems«szVirtualListImages.items)Úindexr;cCsdS)NrC)r8r£rCrCrDÚ __getitem__®szVirtualListImages.__getitem__cCsdS)NrC)r8r£rCrCrDr¤²scs¼|jƒ‰t|tƒrRt|jt|ƒƒŽ}‡fdd„|Dƒ‰t|ƒ}|‡fdd„|jƒSt|tt t fƒrl|j|ƒSt|t ƒs~t dƒ‚tˆƒ}|dkr–||}|dks¦||kr®t dƒ‚|jˆ|ƒS)Ncsg|] }ˆ|‘qSrCrC)rŸr )ÚlstrCrDr¡¼sz1VirtualListImages.__getitem__..csˆS)NrCrC)r¥rCrDrI¾sz/VirtualListImages.__getitem__..zinvalid sequence indices typerzsequence index out of range)ršr=ÚsliceÚrangeÚindicesr”Útyper›rurlÚtupleÚintrƒÚ IndexError)r8r£r¨ÚclsÚlen_selfrC)r¥rDr¤¶s    ccs$xtt|ƒƒD]}||VqWdS)N)r§r”)r8ÚirCrCrDÚ__iter__ËszVirtualListImages.__iter__cCs(dd„t|jƒƒDƒ}ddj|ƒ›d�S)NcSs g|]\}}d|›d|›�‘qS)ZImage_ú=rC)rŸr¯ÚnrCrCrDr¡Ðsz-VirtualListImages.__str__..ú[z, ú])Ú enumerateršÚjoin)r8ÚprCrCrDr•ÏszVirtualListImages.__str__)rprqrrrsrr rrurrwrNr«r�ržr¢rr¤r¦rr r°r•rCrCrCrDr™•s& r™csÈeZdZUdZdd†eeeeddœdd„Ze dœdd„Z e dœ‡fd d „ Z e edœd d „ƒZed‡eeeeedfeeedfdd œdd„ƒZdˆeeeeeeeeeeeeefdœdd„Zd‰eeeeeefeeedœdd„Ze edœdd„ƒZeeedœdd„Ze eefdœdd„Z!e e dœdd„ƒZ"e"j#eddœd d„ƒZ"ddœd!d"„Z$e dd#œd$d%„Z%dŠeeee&ee eefe eeffd'œd(d)„Z'ee(e eefeee(d*œd+d,„ƒZ)eeeee*e(d-œd.d/„ƒZ+ee dœd0d1„Z,ee(dœd2d3„Z-ede(e.e/fdd4œd5d6„Z0d‹de&e&dd8œd9d:„Z1dŒdee2ege(fee*e&e&dd;œdd?„Z4dee*dd@œdAdB„Z5dŽdee*e6fe&e&ddCœdDdE„Z7d�dee&e&ddFœdGdH„Z8d�dee&e&ddIœdJdK„Z9d‘deee&e&ddLœdMdN„Z:d’ee6e*fe&ddOœdPdQ„Z;eeddRœdSdT„Zd”e dd\œd]d^„Z?e ee dœd_d`„ƒZ@edœdadb„ZAd•dgeBjCdddfeeee dhfeeeee2eeeegdfee2eeeegdfee2eeeeegdfediœ djdk„ZDe eeEjFfdœdldm„ZGd–e&ee&eeHedoœdpdq„ZId—dgddddrdsœeee ee dhffeee2eeeegdfee2eeeegdfee2eeeeegdfeJd˜eeduœ dvdw„ZKdše.ee dhfeee2eeeegdfee2eeeegdfee2eeeeegdfedyœdzd{„ZLeeMeeMefdœd|d}„ZNeOeBjPfƒZQeOd~eBjPfƒZReOdd~eBjPfƒZSeOd€d~eBjPfƒZTeOd�d~eBjPfƒZUe ee/dœd‚dƒ„ƒZVeVj#ee/dd„œd…dƒ„ƒZV‡ZWS)›Ú PageObjecta" PageObject represents a single page within a PDF file. Typically these objects will be created by accessing the :attr:`pages` property of the :class:`PdfReader` class, but it is also possible to create an empty page with the :meth:`create_blank_page()` static method. Args: pdf: PDF file the page belongs to. indirect_reference: Stores the original indirect reference to this object in its source PDF N)r>r‚r;cCsLtj|ƒ||_d|_||_t|ƒsH|dk s4tdƒ‚|jtt|j ƒƒƒdS)NÚmypy) r+rNr>Ú inline_imagesr‚r5r]Úupdaterr?)r8r>r‚rCrCrDrNæs zPageObject.__init__)r;cCstttdd„|jƒDƒƒfƒS)zÕ Used to detect modified object. Note: this function is overloaded to return the same results as a DictionaryObject. Returns: Hash considering type and value. css|]\}}||jƒfVqdS)N)Úhash_bin)rŸÚkÚvrCrCrDú ÿsz&PageObject.hash_bin..)r—r+rªr¢)r8rCrCrDr¼ôs zPageObject.hash_bincstƒjƒ}|dt|ƒ7}|S)Ns%d)ÚsuperÚhash_value_dataÚid)r8r‹)r“rCrDrÁs zPageObject.hash_value_datacCs|jtjdƒS)a A read-only positive number giving the size of user space units. It is in multiples of 1/72 inch. Hence a value of 1 means a user space unit is 1/72 inch, and a value of 3 means that a user space unit is 3/72 inch. r)r<ÚPGZ USER_UNIT)r8rCrCrDÚ user_units zPageObject.user_unit)r>ÚwidthÚheightr;cCs¸t|ƒ}|jttjƒtdƒƒ|jttjƒtƒƒ|jttjƒtƒƒ|dksV|dkr–|dk r’t |j ƒdkr’|j t |j ƒd}|j j }|j j }nt‚|jttjƒtdd||fƒƒ|S)aB Return a new blank page. If ``width`` or ``height`` is ``None``, try to get the page size from the last page of *pdf*. Args: pdf: PDF file the page is within. width: The width of the new page expressed in default user space units. height: The height of the new page expressed in default user space units. Returns: The new blank page Raises: PageSizeNotDefinedError: if ``pdf`` is ``None`` or contains no page z/PageNrr)r¸Ú __setitem__r/rÃZTYPEZPARENTr0Ú RESOURCESr+r”r†ÚmediaboxrÅrÆr&ÚMEDIABOXr3)r>rÅrÆÚpageZlastpagerCrCrDÚcreate_blank_pages zPageObject.create_blank_page)ÚobjÚancestÚ call_stackr;cCsH|dkr g}t|ddƒ}||kr$gS|j|ƒ|jdkrB|jƒ|_|dkrN|}|dkrZg}g}tj|ks~tjtt |tjƒkrš|jdkrŒgSt |jj ƒƒS|tjtjj ƒ}xp|D]h}t ||tƒsÈq´||tjdk�rþ|jt|ƒdkrð|n||gƒq´|j|j||||g|ƒƒq´W|jdk �s0t‚|jt |jj ƒƒƒ|S)Nr‚z/Imager)ÚgetattrÚappendrºÚ_get_inline_imagesrÃrÈÚRESÚXOBJECTrr+rlržr?r=r4ÚIAZSUBTYPEr”ÚextendÚ_get_ids_imager])r8rÍrÎrÏZ_ir¥Zx_objectÚorCrCrDr×?s4     ""zPageObject._get_ids_image)rÂrÍr;c Cs`|dkrtt|ƒ}t|tƒr$t|ƒ}t|tƒrBt|ƒdkrB|d}y tttt|tjƒt j ƒ}Wn.t k r�|ddkoˆ|ddksŒ‚YnXt|t ƒ�r6|ddkræ|ddkræ|j dkrÊ|jƒ|_ |j dkrÜt dƒ‚|j |Sttt||ƒƒ}|dd…\}}t|dd…›|›�||d||jd�}|S|dd…}|j|tt||dƒƒSdS) Nrrú~zno inline image can be foundrO)r9r‹rŒr‚r–r–)rr+r=rªrlr r”rÃrÈrÓrÔÚKeyErrorrurºrÒr(rwr‚Ú _get_image) r8rÂrÍZxobjsZimgdr�r�ÚfÚidsrCrCrDrÛds:        zPageObject._get_imagecCst|j|jƒS)aH Read-only property emulating a list of images on a page. Get a list of all images on the page. The key can be: - A string (for the top object) - A tuple (for images within XObject forms) - An integer Examples: * `reader.pages[0].images[0]` # return fist image * `reader.pages[0].images['/I0']` # return image '/I0' * `reader.pages[0].images['/TP1','/Image1']` # return image '/Image1' within '/TP1' Xobject/Form * `for img in reader.pages[0].images:` # loops through all objects images.keys() and images.items() can be used. The ImageFile has the following properties: * `.name` : name of the object * `.data` : bytes of the object * `.image` : PIL Image Object * `.indirect_reference` : object reference and the following methods: `.replace(new_image: PIL.Image.Image, **kwargs)` : replace the image in the pdf with the new image applying the saving parameters indicated (such as quality) Example usage: reader.pages[0].images[0]=replace(Image.open("new_image.jpg", quality = 20) Inline images are extracted and named ~0~, ~1~, ..., with the indirect_reference set to None. )r™r×rÛ)r8rCrCrDr‡‹s%zPageObject.images)r½r¾r;cCsºyDtddddddddd d d ddddddddd d d d œtt|ƒƒ}Wnpttfk r´t|tƒr°y$tt|d ƒd}tt|ƒ|}Wn(tk r®td|›d|›�ƒ‚YnXYnX|S)z%Translate values used in inline imagez /DeviceGrayz /DeviceRGBz /DeviceCMYKz/Indexedz/ASCIIHexDecodez/ASCII85Decodez /LZWDecodez /FlateDecodez/RunLengthDecodez/CCITTFaxDecodez /DCTDecode)z/Gz/RGBz/CMYKz/Iz/AHxz/A85z/LZWz/Flz/RLz/CCFz/DCTz /DeviceGrayz /DeviceRGBz /DeviceCMYKz/Indexedz/ASCIIHexDecodez/ASCII85Decodez /LZWDecodez /FlateDecodez/RunLengthDecodez/CCITTFaxDecodez /DCTDecodez /Resourcesz /ColorSpacezCannot find resource entry z for )r/rrurƒrÚr=r+r')r8r½r¾ÚresrCrCrDÚ_translate_value_inlineimage²sB  z'PageObject._translate_value_inlineimagec sŒˆjƒ}t|ƒriSg}|dk s(tdƒ‚xJ|jD]@\}}|dkrZ|j|d|ddœƒq0|dkr0t|›d �ƒ‚q0Wi}�x t|ƒD�]þ\}}|d t|d ƒd œ}x–|djƒD]†\‰} ˆd krÄq²t | t ƒrèt ‡‡fdd„| Dƒƒ} n ˆj ˆ| ƒ} t ddddddddddddddddddddœˆƒ‰ˆ|kr²| |ˆ<q²Wtj|ƒ|d<t|dƒ\} } } td|›d| ›�| | dd�|d|›d�<q„W|S)!zM get inline_images entries will be identified as ~1~ Nr¹s INLINE IMAGEÚsettingsr‹)ràÚ__streamdata__óBIóEIóIDzK operator met whereas not expected,please share usecase with pypdf dev teamrá)ráz/Lengthú/Lengthú/Lcsg|]}ˆjˆ|ƒ‘qSrC)rß)rŸr )r½r8rCrDr¡ sz1PageObject._get_inline_images..z/BitsPerComponentz /ColorSpacez/Decodez /DecodeParmsz/Filterz/Heightz/Widthz /Interpolatez/Intentz /ImageMask)z/BPCz/CSz/Dz/DPz/Fz/Hz/Wz/Iz/Intentz/IMz/BitsPerComponentz /ColorSpacez/Decodez /DecodeParmsz/Filterz/Heightz/Widthz /Interpolatez /ImageMaskÚobjectrÙ)r9r‹rŒr‚)rârãrä>råræ)Ú get_contentsr5r]Ú operationsrÑr'rµr”r¢r=rlr)rßr/r,Zinitialize_from_dictionaryr(rw) r8ÚcontentZ imgs_dataÚparamÚopeÚfilesÚnumÚiiÚinitr¾r�r�r‘rC)r½r8rDrÒÚsn    zPageObject._get_inline_imagescCs$|jtjdƒ}t|tƒr|S|jƒS)zÅ The visual rotation of the page. This number has to be a multiple of 90 degrees: 0, 90, 180, or 270 are valid values. This property does not affect ``/Contents``. r)r<rÃÚROTATEr=r«r?)r8Z rotate_objrCrCrDr`0szPageObject.rotation)Úrr;cCs*tt|ƒddddƒ|ttjƒ<dS)Né-éZih)r1r«r/rÃrñ)r8ròrCrCrDr`;sc Cs.|j }d|_t|jƒ}tƒjt|j|jdƒ t|j|j dƒ ƒj |ƒ}|j |j ƒ}|j |j ƒ}|jt|d|dƒ t|d|dƒ ƒ}|j|dƒxˆd D]€}||kr¦t||ƒ}|j |j ƒ}|j |j ƒ}tt|d|dƒt|d|dƒt|d|dƒt|d|dƒfƒ|t|ƒ<q¦Wd S) z¬ Apply the rotation of the page to the content and the media/crop/... boxes. It is recommended to apply this function before page merging. rrOrFú /MediaBoxú/CropBoxú /BleedBoxú/TrimBoxú/ArtBoxN)rõrör÷rørù)r`r3rÉrLrYrkÚleftrÅÚbottomrÆrerjÚ lower_leftÚ upper_rightÚminÚadd_transformationÚmaxr/)r8ròÚmbÚtrsfrnÚpt2r�ZrrrCrCrDÚtransfer_rotation_to_content?s( ,  ,     z'PageObject.transfer_rotation_to_content)Úangler;cCs0|ddkrtdƒ‚t|j|ƒ|ttjƒ<|S)z× Rotate a page clockwise by increments of 90 degrees. Args: angle: Angle to rotate the page. Must be an increment of 90 deg. Returns: The rotated PageObject rôrz'Rotation angle must be a multiple of 90)r\r1r`r/rÃrñ)r8rrCrCrDrebs zPageObject.rotateT)Úres1Úres2ÚresourceÚnew_res1r;cs|y&t|jtƒst‚|jj}t|dƒ}Wn ttfk rFd}d}YnXtttt fdœ‡‡fdd„ }|rŠt ƒ‰ˆj |j |t ƒƒj ƒƒntt ||ƒ‰tt |j |t ƒƒj ƒƒ‰i}x¾ˆD]¶} || ƒ\} } t| ƒ} | | krâ| || <| �s<|�r.ˆj| ƒj|ƒˆ| <yˆ| jˆ| <Wntk �r*YnXnˆj| ƒˆ| <tˆjƒƒ} ˆjƒx| D]}|dˆ|d<�qVWqºWˆ|fS)NÚ _add_objectF)Úbase_keyr;csTˆj|ƒ}|}d}x8|ˆkrJˆj|ƒ|kr2|dfS|›d|›�}|d7}qW|dfS)a¤ Find a key that either doesn't already exist or has the same value (indicated by the bool) Args: base_key: An index is added to this to get the computed key Returns: A tuple (computed key, bool) where the boolean indicates if there is a resource of the given computed_key with the same value. rTú-rF)Úraw_get)r rFZ computed_keyÚidx)Únew_resÚpage2resrCrDÚcompute_unique_key‚s   z7PageObject._merge_resources..compute_unique_keyrr)r=r‚r.r]r>r„ÚAttributeErrorrurrvr+r»r<r?rr/r ÚcloneÚsortedr¢Úclear)r8rrrr r>Z is_pdf_writerrZ rename_resÚkeyZ unique_keyZ same_valueZnewnamer¥ÚelrC)rrrDÚ_merge_resourcesqsD       zPageObject._merge_resources)ÚstreamÚrenamer>r;cCs´|s|St||ƒ}xœ|jD]’\}}t|tƒr^x~t|ƒD]"\}}t|tƒr6|j||ƒ||<q6Wqt|tƒršxB|jƒD]"\}}t|tƒrr|j||ƒ||<qrWqt dt |ƒ›�ƒ‚qW|S)Nztype of operands is ) r*rér=rlrµr/r<Údictr¢rÚr©)rrr>ÚoperandsÚ _operatorr¯r^rCrCrDÚ_content_stream_renameÁs     z!PageObject._content_stream_rename)Úcontentsr>rMr;c CsT|\}}}}}}t||ƒ}|jjdt|ƒt|ƒt|ƒt|ƒt|ƒt|ƒgdgƒ|S)zHAdd transformation matrix at the beginning of the given contents stream.rscm)r*réÚinsertr-) rr>rMÚar�ÚcrBÚerÜrCrCrDÚ_add_transformation_matrix×s z%PageObject._add_transformation_matrixcCsNtj|krF|tjjƒ}t|tƒr6djdd„|DƒƒStt|ƒjƒSndSdS)z— Return the page contents as bytes. Returns: The ``/Contents`` object as bytes, or ``None`` if it doesn't exist. rycss|]}|jƒjƒVqdS)N)r?Úget_data)rŸr rCrCrDr¿ûsz4PageObject._get_contents_as_bytes..N) rÃÚCONTENTSr?r=rlr¶rr,r%)r8rÍrCrCrDÚ_get_contents_as_bytesðs   z!PageObject._get_contents_as_bytesc Csftj|kr^ytt|jƒj}Wntk r4d}YnX|tjjƒ}t|t ƒrRdSt ||ƒSndSdS)uÜ Access the page contents. Returns: The ``/Contents`` object, or ``None`` if it does not exist. ``/Contents`` is optional, as described in §7.7.3.3 of the PDF Reference. N) rÃr&rr.r‚r>rr?r=r0r*)r8r>rÍrCrCrDrès    zPageObject.get_contents)rêr;c CsÚt|dƒ s|jdkr(||ttjƒ<dSt|jtjdƒtƒr~x@|tjD]2}ytƒ|j |jj d<WqHt k rxYqHXqHWt|tƒr´x*t t |ƒƒD]}|jjj||ƒ||<q–Wt|ƒ�rtj|krÌdS|jdk sÚt‚|tjjdk sît‚tƒ|jjj |tjjj d<|tj=nºt|jtjdƒdƒ�spy|jjj|ƒ|ttjƒ<Wn$t k �rl||ttjƒ<YnXn`|dk �s‚tdƒ‚|tjj|_y||jjj |jj d<Wn$t k �rÎ||ttjƒ<YnXd|_dS)zª Replace the page contents with the new content and nullify old objects Args: content: new content; if None delete the content field. r‚Nrr¹)r„r‚r/rÃr&r=r<r)r0rˆr‰rr§r”r>r r5r]rº)r8rêrØr¯rCrCrDÚreplace_contentssB      zPageObject.replace_contentsF)Úpage2ÚexpandÚoverr;cCs|j|||d�dS)añ Merge the content streams of two pages into one. Resource references (i.e. fonts) are maintained from both pages. The mediabox/cropbox/etc of this page are not altered. The parameter page's content stream will be added to the end of this page's content stream, meaning that it will be drawn after, or "on top" of this page. Args: page2: The page to be merged into this one. Should be an instance of :class:`PageObject`. over: set the page2 content over page1 if True (default) else under expand: If True, the current page dimensions will be expanded to accommodate the dimensions of the page to be merged. )r+r*N)Ú _merge_page)r8r)r*r+rCrCrDÚ merge_pageRszPageObject.merge_page)r)Úpage2transformationrMr+r*r;c Cs¼y4t|jtƒst‚t|jjdƒr2|j|||||ƒSWnttfk rLYnXtƒ}i}yt t|t j j ƒƒ}Wnt k rŠtƒ}YnXyt t|t j j ƒƒ} Wnt k r¾tƒ} YnXtƒ} x8||fD],} t j| krÐ| t j} t| tƒrÐ| j| ƒqÐWxXtjtjtjtjtjtjtjfD]4} |j|| | ƒ\}}|�r"||t| ƒ<|j|ƒ�q"Wttt|jtjtƒƒj ƒƒj t| jtjtƒƒj ƒƒƒƒƒ|ttjƒ<tƒ}|j!ƒ}|dk �rÈ|j"ƒ|j#|ƒ|j!ƒ}|dk �rxt$|t%ƒ}|j&j'dt(t)|j*|j+|j,|j-gƒdfƒ|j&j'dgdfƒ|j&j'dgdfƒ|dk �rB||ƒ}t.j/|||jƒ}|j"ƒ|�rl|j#|ƒn |j'd|ƒ|�rŠ|j0||ƒ|j1t2||jƒƒ||tt j ƒ<| |tt jƒ<dS)Nr rsreróWrOón)3r=r‚r.r]r„r>Ú_merge_page_writerrr+rrÃrÈr?rÚr)ÚANNOTSrÖrÓÚ EXT_G_STATEÚFONTrÔÚ COLOR_SPACEÚPATTERNÚSHADINGÚ PROPERTIESrr/r»rÚsetr<ÚPROC_SETÚunionrèÚisolate_graphics_staterÑrÐÚMERGE_CROP_BOXrér Úmapr-rúrûrÅrÆr¸rÚ_expand_mediaboxr(r*)r8r)r.rMr+r*Z new_resourcesrÚoriginal_resourcesÚpage2resourcesZ new_annotsrËÚannotsrÞÚnewÚ newrenameÚnew_content_arrayÚoriginal_contentÚ page2contentÚrectrCrCrDr,gs”         (         zPageObject._merge_pagecCsBt|jtƒst‚|jj}i}tj|kr6tƒ|ttjƒ<t t|tjj ƒƒ}tj|kr\tƒ} nt t|tjj ƒƒ} xdt j t j t jt jt jt jt jfD]@} | | kr’| |kr´tƒ|t| ƒ<|j|| | dƒ\} } |j| ƒq’Wt j| k�rDt j|krütƒ|tt jƒ<t t|t jƒ} x.t t| t jƒD]}|| k�r| j|ƒ�qW| jƒtj|k�rHtj|k�rltƒ|ttjƒ<t t|tjj ƒƒ}|dk�r’tƒ}nt|ƒ}�xªt t|tjƒD�]”}|j ƒ}|j|ddd�}t t|dƒ}|j|d|d fdƒ}|j|d |d fdƒ}tt|d|dƒt|d |d ƒt|d|dƒt|d |d ƒfƒ|tdƒ<d |k�rÞt t|d ƒ}t|j|d|d fdƒ|j|d |d fdƒ|j|d |dfdƒ|j|d|dfdƒƒ|td ƒ<y|j|dtdƒ<Wntk �r YnXy|j|tdƒ<|j|jƒWnt k �r@YnX�q®Wtƒ}|j!ƒ}|dk �rr|j"ƒ|j|ƒ|j!ƒ}|dk �r"t#|t$ƒ}|j%j&dt't(|j)|j*|j+|j,gƒdfƒ|j%j&d gdfƒ|j%j&d gdfƒ|dk �rì||ƒ}t-j.|||jƒ}|j"ƒ|�r|j|ƒn |j&d|ƒ|�r4|j/||ƒ|j0|ƒdS)NFú/Pú /StructParentú/ParentT)Z ignore_fieldsZforce_duplicatez/RectrrrOrPz /QuadPointsrQrRééz/Popupsrer/r0)rIrJrK)1r=r‚r.r]r>rÃrÈr+r/rr?rÓr3r4rÔr5r6r7r8rr»r:r)rÑÚsortr2rLrrjrþrrÚrrèr<rÐr=rér r>r-rúrûrÅrÆr¸rr?r()r8r)r.rMr+r*r>rr@rArÞÚ_rDZarrr rBrr!ZaaròrnrÚqrErFrGrHrCrCrDr1×s¾           j          zPageObject._merge_page_writer)r)rMr;cst|jjjƒ|jjjƒ|jjjƒ|jjjƒf}|jjjƒ|jjjƒ|jjjƒ|jjjƒ|jjjƒ|jjjƒ|jjjƒ|jjjƒf‰ˆdk rÜtdd„ˆDƒƒ‰t‡‡fdd„tdddƒDƒƒ}t‡‡fdd„tdddƒDƒƒ}nˆddd…}ˆddd…}t|ƒt|ƒf}t |ƒt |ƒf}t|d|dƒt|d|dƒf}t |d|dƒt |d |dƒf}||j_ ||j_ dS) Ncss|]}t|ƒVqdS)N)rk)rŸr rCrCrDr¿vsz.PageObject._expand_mediabox..c3s:|]2}ˆdˆ|ˆdˆ|dˆdVqdS)rrOrrQNrC)rŸr¯)Úcorners2rMrCrDr¿xsrérOc3s:|]2}ˆdˆ|ˆdˆ|dˆdVqdS)rrPrRNrC)rŸr¯)rQrMrCrDr¿|srrP) rÉrúÚ as_numericrûÚrightÚtoprªr§rþrrürý)r8r)rMZcorners1Únew_xÚnew_yÚ lowerleftÚ upperrightrC)rQrMrDr?bs:            $zPageObject._expand_mediabox)r)rMr+r*r;cs0tˆtƒrˆj‰|jˆ‡‡fdd„ˆ||ƒdS)aó merge_transformed_page is similar to merge_page, but a transformation matrix is applied to the merged stream. Args: page2: The page to be merged into this one. ctm: a 6-element tuple containing the operands of the transformation matrix over: set the page2 content over page1 if True (default) else under expand: Whether the page should be expanded to fit the dimensions of the page to be merged. cstj|ˆjttˆƒƒS)N)r¸r$r>rr)Z page2Content)rMr)rCrDrI¤sz3PageObject.merge_transformed_page..N)r=rLrMr,)r8r)rMr+r*rC)rMr)rDÚmerge_transformed_page�s  z!PageObject.merge_transformed_page)r)r_r+r*r;cCs"tƒj||ƒ}|j||||ƒdS)a¹ merge_scaled_page is similar to merge_page, but the stream to be merged is scaled by applying a transformation matrix. Args: page2: The page to be merged into this one. scale: The scaling factor over: set the page2 content over page1 if True (default) else under expand: Whether the page should be expanded to fit the dimensions of the page to be merged. N)rLr_rZ)r8r)r_r+r*r^rCrCrDÚmerge_scaled_page¬szPageObject.merge_scaled_page)r)r`r+r*r;cCs tƒj|ƒ}|j||||ƒdS)aÑ merge_rotated_page is similar to merge_page, but the stream to be merged is rotated by applying a transformation matrix. Args: page2: The page to be merged into this one. rotation: The angle of the rotation, in degrees over: set the page2 content over page1 if True (default) else under expand: Whether the page should be expanded to fit the dimensions of the page to be merged. N)rLrerZ)r8r)r`r+r*r^rCrCrDÚmerge_rotated_page½s zPageObject.merge_rotated_page)r)rWrXr+r*r;cCs"tƒj||ƒ}|j||||ƒdS)aë mergeTranslatedPage is similar to merge_page, but the stream to be merged is translated by applying a transformation matrix. Args: page2: the page to be merged into this one. tx: The translation on X axis ty: The translation on Y axis over: set the page2 content over page1 if True (default) else under expand: Whether the page should be expanded to fit the dimensions of the page to be merged. N)rLrYrZ)r8r)rWrXr+r*r^rCrCrDÚmerge_translated_pageÒsz PageObject.merge_translated_page)rMr*r;cstˆtƒrˆj‰|jƒ}|dk rBtj||jˆƒ}|jƒ|j|ƒ|�r|j j j ƒ|j j j ƒ|j j j ƒ|j j j ƒ|j jj ƒ|j j j ƒ|j jj ƒ|j j j ƒg‰tdd„ˆDƒƒ‰‡‡fdd„tdddƒDƒ}‡‡fd d„tdddƒDƒ}t|ƒt|ƒf}t|ƒt|ƒf}||j _||j _dS) aa Apply a transformation matrix to the page. Args: ctm: A 6-element tuple containing the operands of the transformation matrix. Alternatively, a :py:class:`Transformation` object can be passed. See :doc:`/user/cropping-and-transforming`. Ncss|]}t|ƒVqdS)N)rk)rŸr rCrCrDr¿ sz0PageObject.add_transformation..cs8g|]0}ˆdˆ|ˆdˆ|dˆd‘qS)rrOrrQrC)rŸr¯)ÚcornersrMrCrDr¡sz1PageObject.add_transformation..rrRrOcs8g|]0}ˆdˆ|ˆdˆ|dˆd‘qS)rrPrRrC)rŸr¯)r^rMrCrDr¡s)r=rLrMrèr¸r$r>r<r(rÉrúrSrûrUrTrªr§rþrrürý)r8rMr*rêrVrWrXrYrC)r^rMrDrÿés2           zPageObject.add_transformation)rZr[r;c CsÚ|j|dd|ddfƒ|jj||ƒ|_|jj||ƒ|_|jj||ƒ|_|jj||ƒ|_|jj||ƒ|_tj|k�r|tj}t |t ƒ�rx’|D]Š}|j ƒ}t j |krŽ|t j }t |t ƒrŽtt|dƒ|ƒ|d<tt|dƒ|ƒ|d<tt|dƒ|ƒ|d<tt|dƒ|ƒ|d<qŽWtj|k�rÖ|tj}t |t ƒ�rL|dd}n|d}tt|dƒ|t|dƒ|t|dƒ|t|dƒ|fƒ} t |t ƒ�rÀ| |ttjƒtdƒtdƒ<n| |ttjƒtdƒ<dS)a\ Scale a page by the given factors by applying a transformation matrix to its content and updating the page size. This updates the mediabox, the cropbox, and the contents of the page. Args: sx: The scaling factor on horizontal axis. sy: The scaling factor on vertical axis. rrrOrPz/BBoxN)rÿr7r_ÚartboxÚbleedboxÚtrimboxrÉrÃr2r=r)r?ÚADAZRectr-rkZVPr3r/r1) r8rZr[Ú annotationsÚ annotationZannotation_objZ rectangleZviewportZbboxZ scaled_bboxrCrCrDr_s>             zPageObject.scale)Úfactorr;cCs|j||ƒdS)zØ Scale a page by the given factor by applying a transformation matrix to its content and updating the page size. Args: factor: The scaling factor (for both X and Y axis). N)r_)r8rerCrCrDÚscale_byRszPageObject.scale_by)rÅrÆr;cCs0|t|jjƒ}|t|jjƒ}|j||ƒdS)zæ Scale a page to the specified dimensions by applying a transformation matrix to its content and updating the page size. Args: width: The new width. height: The new height. N)rkrÉrÅrÆr_)r8rÅrÆrZr[rCrCrDÚscale_to\s zPageObject.scale_tor)Úlevelr;c Csz|jƒ}|dk rv|j|ƒ}y||jjj|jjd<Wn@tk rt|jdk rht|jjdƒrh|j|ƒnt dƒ‚YnXdS)a Compress the size of this page by joining all content streams and applying a FlateDecode filter. However, it is possible that this function will perform no action if content stream compression becomes "automatic". Nrr z Page must be part of a PdfWriter) rèZ flate_encoder‚r>rˆr‰rr„r(r\)r8rhrêZ content_objrCrCrDÚcompress_content_streamsis    z#PageObject.compress_content_streamsc Cs<|jdkrdSy|jjj}|j|ƒStk r6dSXdS)z³ Read-only property which returns the page number within the PDF file. Returns: int : page number; None if the page is not attached to a PDF. N)r‚r>r†r£r\)r8r¥rCrCrDÚ page_number€s   zPageObject.page_numbercCsfd}xlt|djƒ|jdƒjD]P\}}|dkrBdd„|dDƒ}ng}||jdƒd dj|ƒ|jƒd 7}qW|d 7}yÈxÂ|tjd D]°}||d 7}||tjd |jƒd 7}y*|tjd |d jƒ}||d 7}Wnt k røYnXy*||tjd |dj ƒjƒd 7}WqŒt k �r:YqŒXqŒWWnt k �r`|d7}YnX|S)Nrxz /Contentsr˜sTJcSsg|]}t|tƒr|‘qSrC)r=ru)rŸr rCrCrDr¡—sz1PageObject._debug_for_extract..rzutf-8ú Ú z ============================= z/Fontz /Encodingz /ToUnicodezNo Font ) r*r?r>réÚdecoder¶rgrÃrÈÚ Exceptionr%rÚ)r8Úoutrìr^ÚsÚfoZenc_reprrCrCrDÚ_debug_for_extract‘s8,    zPageObject._debug_for_extractrrôé´éçi@.) rÍr>Ú orientationsÚ space_widthÚ content_keyÚvisitor_operand_beforeÚvisitor_operand_afterÚ visitor_textr;c ,s†d‰d‰ d‰i‰y8|} xttjƒ| kr4| djƒ} qWtt| tjƒ} Wntk r\dSXd| krŽx&tt| dƒD]} t| ||ƒˆ| <qvWdiddf‰y4t|t ƒr²||jƒn|} t| t ƒsÌt | |dƒ} Wnt k râdSXd d d d d d g‰g‰d d d d d d g‰d d d d d d g‰d d d d d d g‰d d d d d d g‰ d d d d d d g‰ d ‰d ‰d ‰d ‰d ‰ t d œ‡fdd„ ‰t ttddœ‡‡‡‡‡‡‡‡‡‡ ‡ ‡ ‡ ‡ ‡‡‡‡‡‡fdd„ } �x | jD�]”\}}|dk �rÚ|||ˆˆƒ|dk�rü| dgƒ| d|ƒ�n8|dk�rF| d|dgƒ| d|dgƒ| dgƒ| d|dd…ƒ�nî|dk�rp| d|d gƒ| d|ƒ�nÄ|dk�rüx||dD]p}t|t t fƒ�r¤| d|gƒt|tt ttfƒ�r„tt |ƒƒˆk�r„tˆƒdk�r„ˆd(d k�r„| dd gƒ�q„W�n8|d!k�r*ˆ ˆ7‰ ˆdk �r,ˆˆˆ ˆ ˆd"ˆ ƒy8ˆ d)d#k�rbˆ d#7‰ ˆdk �rbˆd#ˆ ˆ ˆd"ˆ ƒWntk �rzYnXz”yd| d$}||dd%d&k�rà|j||dˆ |||ˆƒ‰ˆ ˆ7‰ ˆdk �ràˆˆˆ ˆ ˆd"ˆ ƒWn*tk �r td'|d›�tƒYnXWdd‰ˆjƒ‰ ˆjƒ‰ Xn | ||ƒ|dk �r¸|||ˆˆƒ�q¸Wˆ ˆ7‰ ˆdk�r‚ˆdk �r‚ˆˆˆ ˆ ˆd"ˆ ƒˆ S)*a See extract_text for most arguments. Args: content_key: indicate the default key where to extract data None = the object; this allow to reuse the function on XObject default = "/Content" rxFz/Parentz/FontÚcharmapZNotInitializedNr˜gð?gg@@g(@)r;csˆdS)Ng@�@rCrC)Ú _space_widthrCrDÚcurrent_spacewidthsz4PageObject._extract_text..current_spacewidth)Úoperatorrr;c!sbd}|dkrXddddddg‰ˆ ˆ7‰ ˆdk r@ˆˆˆ ˆ ˆdˆ ƒd‰ˆjƒ‰ ˆjƒ‰ dS|dkrœˆ ˆ7‰ ˆdk r„ˆˆˆ ˆ ˆdˆ ƒd‰ˆjƒ‰ ˆjƒ‰ �nV|dkrÀˆjˆˆˆ ˆˆˆˆfƒ�n2|d k�ryˆjƒ\‰‰‰ ‰‰‰‰Wn&tk �r ddddddg‰YnX�nâ|d k�ržˆ ˆ7‰ ˆdk �r@ˆˆˆ ˆ ˆdˆ ƒd‰tt|d ƒt|d ƒt|d ƒt|dƒt|dƒt|dƒgˆƒ‰ˆjƒ‰ ˆjƒ‰ �nT|dk�r¼t|d ƒd‰�n6|dk�rÚdt|d ƒ‰�n|dk�rôt|d ƒ‰�nþ|dk�ràˆdk�r.ˆ ˆ7‰ ˆdk �r.ˆˆˆ ˆ ˆdˆ ƒd‰ˆjƒ‰ ˆjƒ‰ y4ˆ|d }|d ‰|d |d|d |df‰Wn<tk �r²td ‰td tdd|d ›�df‰YnXyt|d ƒ‰ Wntk �rÚYnX�n|dk�rPd}t|d ƒ}t|d ƒ}ˆd|ˆd |ˆd 7<ˆd|ˆd |ˆd7<n¢|dk�r d}t|d ƒt|d ƒt|d ƒt|dƒt|dƒt|dƒg‰nR|dk�rÀd}ˆdˆ8<n2|dk�rîd}tˆ|ˆˆˆˆ ˆ ˆ ˆˆƒ \‰‰ndS|�r^yNt ˆˆˆfˆˆfˆ ˆ fˆˆ ˆ ˆ ˆˆƒƒ \‰‰ ‰‰ˆdk�rDˆjƒ‰ ˆjƒ‰ Wnt k �r\dSXdS)NFsBTgð?grPrxsETóqóQscmrrrOrQrRsTzgY@sTwsTLsTfz???sTdTsTmsT*sTj) ÚcopyrÑÚpoprnrrkrÚrrrr)rrZcheck_crlf_spaceZ charMapTuplerWrX)ÚTLr}Ú char_scaleÚ cm_matrixÚcm_prevÚcm_stackÚcmapÚcmapsr~Ú font_sizeÚmemo_cmÚmemo_tmrvÚoutputÚrtl_dirÚ space_scaleÚtextÚ tm_matrixÚtm_prevr{rCrDÚprocess_operation sü                          $&           z3PageObject._extract_text..process_operationó'sT*sTjó"sTwrsTcrrOsTDsTLsTdsTJrksDorPrlz/XObjectz/Subtypez/Imagez" impossible to decode XFormObject r–r–)r/rÃrÈr?rr+rnrr=rur*rÚrkr˜r rrér«r1r-Úabsr”r¬Úextract_xform_textr rpr‚)r8rÍr>rvrwrxryrzr{ÚobjrÚresources_dictrÜrêr”rrr^ZxobjrC)r„r}r…r†r‡rˆr‰rŠr~r‹rŒr�rvrŽr�r�r‘r’r“r{rDÚ _extract_text·sÜ @+                   zPageObject._extract_textcCsÈ|}i}xº|dk rÂy|tj}Wntk r8i}YnXd|kr–|jdk r–xH|dD]<}t|d|ƒ�^}}dd„|jƒDƒ}tj||fžŽ||<qVWy|djƒ}Wq tk r¾d}Yq Xq W|S)z´ Get fonts formatted for "layout" mode text extraction. Returns: Dict[str, Font]: dictionary of _layout_mode.Font instances keyed by font name Nz/Fontgi@cSs@i|]8\}}t|tƒr|jƒnt|tƒr6dd„|Dƒn||“qS)cSsg|] }|jƒ‘qSrC)r?)rŸZ_vrCrCrDr¡sz..)r=r.r?r))rŸr½r¾rCrCrDú sz1PageObject._layout_mode_fonts..z/Parent) rÃrÈrÚr>rr¢rÚFontr?)r8r™ÚfontsršZ font_namer‰Z font_dict_objZ font_dictrCrCrDÚ_layout_mode_fontss$   zPageObject._layout_mode_fontsçô?)Úspace_verticallyÚ scale_weightÚ strip_rotatedÚ debug_pathr;c Cs�|jƒ}|r6ddl}|jdƒj|j|ddd„d�dƒtt|d jƒ|jd ƒj ƒ}t j ||||ƒ}|sjd St j ||ƒ} t j ||ƒ} t j| | |ƒS) aØ Get text preserving fidelity to source PDF text layout. Args: space_vertically: include blank lines inferred from y distance + font height. Defaults to True. scale_weight: multiplier for string length when calculating weighted average character width. Defaults to 1.25. strip_rotated: Removes text that is rotated w.r.t. to the page from layout mode output. Defaults to True. debug_path (Path | None): if supplied, must target a directory. creates the following files with debug information for layout mode functions if supplied: - fonts.json: output of self._layout_mode_fonts - tjs.json: individual text render ops with corresponding transform matrices - bts.json: text render ops left justified and grouped by BT/ET operators - bt_groups.json: BT/ET operations grouped by rendered y-coord (aka lines) Defaults to None. Returns: str: multiline string containing page text in a fixed width format that closely adheres to the rendered layout in the source pdf. rNz fonts.jsonrOcSst|dtƒ|ƒS)NZto_dict)rÐru)r rCrCrDrILsz.PageObject._layout_mode_text..)ÚindentÚdefaultzutf-8z /Contentsr˜rx)rŸÚjsonZjoinpathZ write_textÚdumpsÚiterr*r?r>rérZtext_show_operationsZy_coordinate_groupsZfixed_char_widthZfixed_width_page) r8r¡r¢r£r¤ržr§ÚopsZ bt_groupsZ ty_groupsZ char_widthrCrCrDÚ_layout_mode_text(s     zPageObject._layout_mode_textÚplain)rvrwryrzr{Úextraction_modeÚlayout) Úargsrvrwryrzr{r­r{r;c Os°|dkrtd|›d�ƒ‚|dkr|x(dD] } tƒ| r&td| ›d �tƒq&W|j|jd d ƒ|jd d ƒ|jdd ƒ|jddƒd�St|ƒdk�r‚t|dtƒ�rt|ƒdkrÔt|dt t fƒrÂ|d}nt d|d›�ƒ‚t|ƒdk�r‚t|dt t fƒ�r|d}nt d|d›�ƒ‚nnt|dt t fƒ�rp|d}t|ƒdk�r‚t|dt t fƒ�r\|d}nt d|d›�ƒ‚nt d|d›�ƒ‚t|t ƒ�r”|f}|j ||j||tj|||ƒS)a� Locate all text drawing commands, in the order they are provided in the content stream, and extract the text. This works well for some PDF files, but poorly for others, depending on the generator used. This will be refined in the future. Do not rely on the order of text coming out of this function, as it will change if this function is made more sophisticated. Arabic and Hebrew are extracted in the correct order. If required a custom RTL range of characters can be defined; see function set_custom_rtl. Additionally you can provide visitor methods to get informed on all operations and all text objects. For example in some PDF files this can be useful to parse tables. Args: orientations: list of orientations extract_text will look for default = (0, 90, 180, 270) note: currently only 0 (up),90 (turned left), 180 (upside down), 270 (turned right) Silently ignored in "layout" mode. space_width: force default space width if not extracted from font (default: 200) Silently ignored in "layout" mode. visitor_operand_before: function to be called before processing an operation. It has four arguments: operator, operand-arguments, current transformation matrix and text matrix. Ignored with a warning in "layout" mode. visitor_operand_after: function to be called after processing an operation. It has four arguments: operator, operand-arguments, current transformation matrix and text matrix. Ignored with a warning in "layout" mode. visitor_text: function to be called when extracting some text at some position. It has five arguments: text, current transformation matrix, text matrix, font-dictionary and font-size. The font-dictionary may be None in case of unknown fonts. If not None it may e.g. contain key "/BaseFont" with value "/Arial,Bold". Ignored with a warning in "layout" mode. extraction_mode (Literal["plain", "layout"]): "plain" for legacy functionality, "layout" for experimental layout mode functionality. NOTE: orientations, space_width, and visitor_* parameters are NOT respected in "layout" mode. kwargs: layout_mode_space_vertically (bool): include blank lines inferred from y distance + font height. Defaults to True. layout_mode_scale_weight (float): multiplier for string length when calculating weighted average character width. Defaults to 1.25. layout_mode_strip_rotated (bool): layout mode does not support rotated text. Set to False to include rotated text anyway. If rotated text is discovered, layout will be degraded and a warning will result. Defaults to True. layout_mode_debug_path (Path | None): if supplied, must target a directory. creates the following files with debug information for layout mode functions if supplied: - fonts.json: output of self._layout_mode_fonts - tjs.json: individual text render ops with corresponding transform matrices - bts.json: text render ops left justified and grouped by BT/ET operators - bt_groups.json: BT/ET operations grouped by rendered y-coord (aka lines) Returns: The extracted text r¬r®zInvalid text extraction mode 'ú'ryrzr{z Argument z is ignored in layout modeZlayout_mode_space_verticallyTZlayout_mode_scale_weightgô?Zlayout_mode_strip_rotatedZlayout_mode_debug_pathN)r¡r¢r£r¤rrrPrOzInvalid positional parameter rQ)r¬r®)ryrzr{)r\Úlocalsr rpr«r<r”r=rurªr«rƒrkr›r>rÃr&) r8rvrwryrzr{r­r¯r{ÚvisitorrCrCrDÚ extract_textasXM           zPageObject.extract_textéh)Úxformrvrwryrzr{r;c Cs|j||j||d|||ƒS)a[ Extract text from an XObject. Args: xform: orientations: space_width: force default space width (if not extracted from font (default 200) visitor_operand_before: visitor_operand_after: visitor_text: Returns: The extracted text N)r›r>)r8rµrvrwryrzr{rCrCrDr˜åszPageObject.extract_xform_textcCsB|jƒ}t|tƒst‚tƒ}tƒ}t|||ƒ\}}||}||fS)zž Get the names of embedded fonts and unembedded fonts. Returns: A tuple (Set of embedded fonts, set of unembedded fonts) )r?r=r+r]r9Ú_get_fonts_walk)r8rÍržZembeddedZ unembeddedrCrCrDÚ _get_fonts szPageObject._get_fontsz/CropBoxz /BleedBoxz/TrimBoxz/ArtBoxcCsd|kr dStt|dƒSdS)Nz/Annots)rr))r8rCrCrDrc6 szPageObject.annotations)rFr;cCs$|dkr|tdƒ=n ||tdƒ<dS)zö Set the annotations array of the page. Typically you do not want to set this value, but append to it. If you append to it, remember to add the object first to the writer and only add the indirect object. Nz/Annots)r/)r8rFrCrCrDrc= s  )NN)NNN)NNN)N)T)FT)NNTF)NNTF)TF)TF)TF)TF)Fr–)r–)rrôrsrt)Tr TN)rrôrsrt)r¬r®©rrôrtr´)r¸ruNNN)XrprqrrrsZ original_pager rr.rNr«r¼r˜rÁrJrkrÄrtrrrÌr+r rurr×rrwrÛr™r‡r2rßrrÒr`Úsetterrrervrr*rrr$r'rèr,r)r(r-rr,r1r?rLrZr[r\r]rÿr_rfrgrirjrrrÃr&r›rr�rŸrr«r r³r˜rr·rKrÊrÉr7r`rar_rcÚ __classcell__rCrC)r“rDr¸Ôsð    *##&(V # &J ;l-   05  *^F%6f}T  r¸c@sÆeZdZegefeegefddœdd„Zedœdd„Zeeedœd d „ƒZ ee e edœd d „ƒZ e ee fe ee efdœd d „Z e ee fddœd d„Z eedœdd„Zedœdd„ZdS)Ú _VirtualListN)Úlength_functionr›r;cCs||_||_d|_dS)Nrr–)r¼r›rœ)r8r¼r›rCrCrDrNM sz_VirtualList.__init__)r;cCs|jƒS)N)r¼)r8rCrCrDr�V sz_VirtualList.__len__)r£r;cCsdS)NrC)r8r£rCrCrDr¤Y sz_VirtualList.__getitem__cCsdS)NrC)r8r£rCrCrDr¤] scs†t|tƒr:t|jtˆƒƒމtˆƒ}|ˆj‡‡fdd„ƒSt|tƒsLtdƒ‚tˆƒ}|dkrd||}|dkst||kr|t dƒ‚ˆj |ƒS)Ncs ˆˆ|S)NrC)r)r¨r8rCrDrIg sz*_VirtualList.__getitem__..z!sequence indices must be integersrzsequence index out of range) r=r¦r§r¨r”r©r�r«rƒr¬r›)r8r£r­r®rC)r¨r8rDr¤a s  c Cs¼t|tƒrHtt|jt|ƒƒŽƒ}|jƒ|jƒx|D] }||=q6WdSt|tƒsZt dƒ‚t|ƒ}|dkrr||}|dks‚||krŠt dƒ‚||j }|dk s t ‚t t|jƒƒjddƒ}d}xü|dk �r¶t t|jƒƒ}y²t t|dƒj|ƒ}t t|dƒ|=d}y|dk �st ‚|jj|=Wntk �r0YnXd|k�rZtt t|dƒd ƒ|tdƒ<tt t|dƒƒdk�rx|j }|jddƒ}Wq¼tk �r²|�r¬td |›�ƒ‚PYq¼Xq¼WdS) Nzindex must be integersrzindex out of rangez/ParentTz/KidsFz/CountrzPage not found in page tree: )r=r¦rlr§r¨r”rNÚreverser«rƒr¬r‚r]rr+r?r<r)r£r>Zflattened_pagesrnr1r/r\r') r8r£ròr·r®ÚindÚparentÚfirstr¯rCrCrDÚ __delitem__r sP        z_VirtualList.__delitem__ccs$xtt|ƒƒD]}||VqWdS)N)r§r”)r8r¯rCrCrDr°¡ sz_VirtualList.__iter__cCs(dd„t|jƒƒDƒ}ddj|ƒ›d�S)NcSsg|]}d|›d�‘qS)z PageObject(rfrC)rŸr¯rCrCrDr¡¦ sz(_VirtualList.__str__..r³z, r´)r§r¼r¶)r8r·rCrCrDr•¥ sz_VirtualList.__str__)rprqrrrr«r¸rNr�rr¤r¦rrrÁr r°rur•rCrCrCrDr»L s   /r»)rÍÚfntÚembr;cs¾d‰tddœ‡‡‡fdd„ }d|kr`d tt|dƒkr`x(tttt|dƒd ƒD] }||ƒqPWd |kröd tt|d ƒkr¨x,tttt|d ƒd ƒjƒD] }||ƒq˜Wd tt|d ƒkröx:tttt|d ƒd ƒjƒD]}ttt|jƒƒˆˆƒqØWd |k�r0x.tt|d ƒD]}ttt|jƒƒˆˆƒ�qWd |k�r¶tttt|d ƒdƒjdƒd k�r€ttttt|d ƒdƒˆˆƒn6x4tttt|d ƒdƒD]}ttt|ƒˆˆƒ�qšWˆˆfS)a Get the set of all fonts and all embedded fonts. Args: obj: Page resources dictionary fnt: font emb: embedded fonts Returns: A tuple (fnt, emb) If there is a key called 'BaseFont', that is a font that is used in the document. If there is a key called 'FontName' and another key in the same dictionary object that is called 'FontFilex' (where x is null, 2, or 3), then that fontname is embedded. We create and add to two sets, fnt = fonts used and emb = fonts embedded. ú /FontFileú /FontFile2ú /FontFile3N)rÜr;c sÜttˆjƒƒ‰dˆkr*ˆjttˆdƒƒdˆksŽdˆkrPt‡fdd„ˆDƒƒsŽdˆkrØdttttˆdƒdjƒƒkrØt‡fdd„ˆDƒƒrØyˆjttˆdƒƒWn0tk rÖˆjd ttˆd ƒd ƒYnXdS) Nz /BaseFontz /CharProcsz/FontDescriptorc3s |]}|ttˆdƒkVqdS)z/FontDescriptorN)rr+)rŸr )rÜrCrDr¿Î sz8_get_fonts_walk..process_font..z/DescendantFontsrc 3s8|]0}|ttttttˆdƒdjƒƒdƒkVqdS)z/DescendantFontsrz/FontDescriptorN)rr+r)r?)rŸr )rÜrCrDr¿Ù sú(z/Subtyperf)rr+r?ÚaddruÚanyr)rÚ)rÜ)rÃrÂÚfontkeys)rÜrDÚ process_fontà s&  z%_get_fonts_walk..process_fontz/DRz/Fontz /Resourcesz/XObjectz/Annotsz/APz/Nz/Type)rÄrÅrÆ)r+rÚvaluesr¶r?r)r<)rÍrÂrÃrËrÜr r!rC)rÃrÂrÊrDr¶ª s8(    r¶)XraZ dataclassesrÚdecimalrÚiorZpathlibrÚtypingrrrr r r r r rrrrrrZ_cmaprrZ _protocolsrZ_text_extractionrrrrrÚ_utilsrrrr r!Ú constantsr"rbr#rÕr$rÃr%rÓÚerrorsr&r'r€r(r�r)r*r+r,r-r.r/r0r1r2r3r4r5Z PIL.Imager6r~rrçr=rurErkr@rGrJrKrLrwr™r¸r»r¶rCrCrCrDÚsh    @      <  5[?_