
    hAH                       % S SK Jr  S SKrS SKJrJrJr  S SKrS SKr	S SK
rS SKJrJr  S SKJr  S SKJr  S SKJr  S SKJr  S	S
KJr  S	SKJrJrJrJr  S	SKJ r J!r!  S	SK"J#r#  S	SK$J%r%J&r&  Sr'Sr(S\)S'    S SK(r(SS/r,Sr-Sr. " S S\&R^                  5      r0SS jr1 " S S\5      r2\S S j5       r3  S!       S"S jjr4S#S jr5g! \* a    \+" S5        Sr' N_f = f)$    )annotationsN)Iterableno_type_checkAny)Vec2BoundingBox2d)RGB)Command)__version__)make_table_key   )Color)BackendInterfaceBkPath2d
BkPoints2d	ImageData)ConfigurationLineweightPolicy)BackendProperties)layoutrecorderTr   pymupdfzLPython module PyMuPDF (AGPL!) is required: https://pypi.org/project/PyMuPDF/FPyMuPdfBackendis_pymupdf_installedgjZ@)pngppmpbmc                    ^  \ rS rSrSrSU 4S jjr\R                  " 5       SS.       SS jjr\R                  " 5       SS.       SS jjr	S\R                  " 5       S	S
SS.         SS jjr
\      SS j5       rSrU =r$ )r   +   a  This backend uses the `PyMuPdf`_ package to create PDF, PNG, PPM and PBM output.
This backend support content cropping at page margins.

PyMuPDF is licensed under the `AGPL`_. Sorry, but it's the best package for the job
I've found so far.

Install package::

    pip install pymupdf

.. _PyMuPdf: https://pypi.org/project/PyMuPDF/
.. _AGPL: https://www.gnu.org/licenses/agpl-3.0.html

c                0   > [         TU ]  5         SU l        g )NT)super__init___init_flip_y)self	__class__s    N/var/www/html/env/lib/python3.13/site-packages/ezdxf/addons/drawing/pymupdf.pyr"   PyMuPdfBackend.__init__;   s         Nsettings
render_boxc               4   SnU R                  5       nUc  UR                  5       n[        R                  " X0R                  S9nUR                  X5      n[        R                  " U5      n[        U5      Ul        UR                  XUS9nUR                  U5        UR                  (       aB  UR                  US9u  pUR                  U5      n
S[        -  nUR                  X-  X-  U5        SU l        U R!                  X5      nUR#                  U5        U$ )  Returns the PDF document as bytes.

Args:
    page: page definition, see :class:`~ezdxf.addons.drawing.layout.Page`
    settings: layout settings, see :class:`~ezdxf.addons.drawing.layout.Settings`
    render_box: set explicit region to render, default is content bounding box
T)flip_y)r*   
top_origin)r/   皙?F)playerbboxr   Layoutr#   get_final_pagecopyget_coordinate_output_spaceoutput_coordinate_spaceget_placement_matrix	transformcrop_at_marginsget_margin_rectpage_output_scale_factorMM_TO_POINTS	crop_rectmake_backendreplay)r$   pager*   r+   r/   r1   output_layoutmp1p2output_scalemax_sagittabackends                r&   
get_replayPyMuPdfBackend.get_replay?   s    
J j9J9JK++D; 99X&+Ft+L(..
 / 
 	##))Z)@FB#<<TBL,KR.0A;O!##D3gr(   c               B    U R                  XUS9nUR                  5       $ )r-   r)   )rI   get_pdf_bytes)r$   rA   r*   r+   rH   s        r&   rL   PyMuPdfBackend.get_pdf_bytesm   s%     //$j/Q$$&&r(   r   `   F)fmtr*   dpialphar+   c                   U[         ;  a  [        SU S35      eU R                  XUS9n UR                  XES9nUR	                  US9$ ! [
         a!  n	[        S[        U	5       35         Sn	A	gSn	A	ff = f)	aB  Returns a pixel image as bytes, supported image formats:

=== =========================
png Portable Network Graphics
ppm Portable Pixmap (no alpha channel)
pbm Portable Bitmap (no alpha channel)
=== =========================

Args:
    page: page definition, see :class:`~ezdxf.addons.drawing.layout.Page`
    fmt: image format
    settings: layout settings, see :class:`~ezdxf.addons.drawing.layout.Settings`
    dpi: output resolution in dots per inch
    alpha: add alpha channel (transparency)
    render_box: set explicit region to render, default is content bounding box
zunsupported image format: ''r)   rP   rQ   )outputzPyMuPDF Runtime Error: Nr(   )SUPPORTED_IMAGE_FORMATS
ValueErrorrI   
get_pixmaptobytesRuntimeErrorprintstr)
r$   rA   rO   r*   rP   rQ   r+   rH   pixmapes
             r&   get_pixmap_bytesPyMuPdfBackend.get_pixmap_bytes~   s    4 --:3%qABB//$j/Q	''C'=F>>>-- 	+CF845	s   A	 	
A4A//A4c                    [        X5      $ )z8Override this method to use a customized render backend.)PyMuPdfRenderBackend)rA   r*   s     r&   r?   PyMuPdfBackend.make_backend   s    
 $D33r(   )r#   returnNone)rA   layout.Pager*   layout.Settingsr+   BoundingBox2d | Nonere   rb   )rA   rg   r*   rh   r+   ri   re   bytes)
rA   rg   r*   rh   rP   intr+   ri   re   rj   )rA   rg   r*   rh   re   rb   )__name__
__module____qualname____firstlineno____doc__r"   r   SettingsrI   rL   r_   staticmethodr?   __static_attributes____classcell__)r%   s   @r&   r   r   +   s    ! %+OO$5+/,, "	,
 ), 
,d %+OO$5+/'' "	'
 )' 
'* $*OO$5+/""
 "" " )" 
"H 44%44	4 4r(   c                    [        U R                  [        -  5      n[        U R                  [        -  5      n[	        X5      $ N)rk   width_in_mmr=   height_in_mmmax)rA   page_width_in_ptpage_height_in_pts      r&   r6   r6      s:    4++l:;D--<=33r(   c                  "   \ rS rSrSrSS jrSS jrSSS jjrS S jrS!S jr	S r
S"S	 jrS#S
 jrS$S jrS%S jrS&S jrS'S jrS(S jr      S)S jrS*S jr      S+S jr      S,S jrS-S jrS.S jrS/S jrS/S jrS/S jrS/S jrSrg)0rb      aI  Creates the PDF/PNG/PSD/SVG output.

This backend requires some preliminary work, record the frontend output via the
Recorder backend to accomplish the following requirements:

- Move content in the first quadrant of the coordinate system.
- The page is defined by the upper left corner in the origin (0, 0) and
  the lower right corner at (page-width, page-height)
- The output coordinates are floats in 1/72 inch, scale the content appropriately
- Replay the recorded output on this backend.

.. important::

    Python module PyMuPDF is required: https://pypi.org/project/PyMuPDF/

c                   [         (       d   S5       e[        R                  " 5       U l        U R                  R	                  S[        R
                  S    3S[         3S.5        X l        0 U l        0 U l	        0 U l
        [        UR                  [        -  5      U l        [        UR                  [        -  5      U l        SU l        SU l        [&        R(                  U l        SU l        [/        U R,                  [        UR0                  UR2                  -  5      5      U l        [/        U R,                  [        U R2                  UR4                  -  5      5      U l        [/        U R,                  [        U R2                  UR6                  -  5      5      U l        U R                  R9                  S	U R                  U R                   5      U l        g )
NzDPython module PyMuPDF is required: https://pypi.org/project/PyMuPDF/zPyMuPDF r   zezdxf )producercreator皙?      ?r0   )r   r   opendocset_metadataversionr   r*   _optional_content_groups_stroke_width_cache_color_cacherk   rw   r=   rz   rx   r{   min_lineweightlineweight_scalingr   ABSOLUTElineweight_policyabs_min_stroke_widthry   r7   max_stroke_widthmin_stroke_widthfixed_stroke_widthnew_pagerA   )r$   rA   r*   s      r&   r"   PyMuPdfRenderBackend.__init__   s     	RQ	R <<>&wq'9&:;#K=1	
 !8:%79 CE #D$4$4|$C D!$T%6%6%E!F""%!1!:!: %(! (+%%0083L3LLM(

 (+%%%%(A(AAB(
 *-%%%%(C(CCD*
 HH%%b$*?*?AWAWX	r(   c                6    U R                   R                  5       $ rv   )r   rY   r$   s    r&   rL   "PyMuPdfRenderBackend.get_pdf_bytes   s    xx!!r(   c                4    U R                   R                  XS9$ )NrT   )rA   rX   )r$   rP   rQ   s      r&   rX   PyMuPdfRenderBackend.get_pixmap   s    yy###99r(   c                6    U R                   R                  5       $ rv   )rA   get_svg_imager   s    r&   r   "PyMuPdfRenderBackend.get_svg_image   s    yy&&((r(   c                   U R                  U5      n[        USS 5      nUS:X  d  US:X  a  g U R                  5       nUR                  SSU R                  U R
                  /5        UR                  S S X#S9  UR                  5         g )N   	   )r   r   r           r   )widthcolorfillfill_opacity)resolve_coloralpha_to_opacity	new_shape	draw_rectrz   r{   finishcommit)r$   r   rgbopacityshapes        r&   set_background#PyMuPdfRenderBackend.set_background   s{      '"51:.O#w#~ At44d6L6LMN4t#Lr(   c                6    U R                   R                  5       $ rv   )rA   r   r   s    r&   r   PyMuPdfRenderBackend.new_shape  s    yy""$$r(   c                    U R                   R                  (       d  g[        U5      nXR                  ;  a(  U R                  R                  USSS9U R                  U'   U R                  U   $ )Nr   r   T)nameconfigon)r*   output_layers	layer_keyr   r   add_ocg)r$   
layer_names     r&   get_optional_content_group/PyMuPdfRenderBackend.get_optional_content_group  si    }}**z*
:::8<8H8H 9I 9D))*5
 ,,Z88r(   c                    U R                  UR                  5      nU R                  UR                  5      nUR	                  UUS SS[        UR                  SS 5      UU R                  UR                  5      S9  g )Nr   r   r   )r   r   r   lineJoinlineCapstroke_opacity	closePathoc)r   r   resolve_stroke_width
lineweightr   r   r   layer)r$   r   
propertiescloser   r   s         r&   finish_line PyMuPdfRenderBackend.finish_line  sz    "":#3#34))**?*?@+J,<,<Qq,AB..z/?/?@ 	 		
r(   c                    UR                  S S U R                  UR                  5      [        UR                  SS 5      SSSSU R	                  UR
                  5      S9	  g )Nr   r   r   T)	r   r   r   r   r   r   r   even_oddr   )r   r   r   r   r   r   )r$   r   r   s      r&   finish_filling#PyMuPdfRenderBackend.finish_filling  sb    ##J$4$45)**:*:1Q*?@..z/?/?@ 	 
	
r(   c                    US S n U R                   U   $ ! [         a     Of = f[        R                  " U5      R	                  5       nX0R                   U'   U$ )Nr   )r   KeyErrorr	   from_hex	to_floats)r$   r   keycolor_floatss       r&   r   "PyMuPdfRenderBackend.resolve_color+  s`    BQi	$$S)) 		||E*446!-#s    
##c                    U R                   U   $ ! [         a     Of = fU R                  nU R                  [        R
                  :X  a+  [        U R                  U5      [        -  U R                  -  nO>U R                  [        R                  :X  a   [        XR                  U R                  5      n[        U R                  U5      nX R                   U'   U$ rv   )r   r   r   r   r   r   ry   r   r=   r   RELATIVEmap_lineweight_to_stroke_widthr   r   )r$   r   stroke_widths      r&   r   )PyMuPdfRenderBackend.resolve_stroke_width5  s    	++E22 		,,!!%5%>%>>D''/,>AXAXX  ##'7'@'@@9,,d.C.CL 444lC*6  's    
c                    U R                  5       n[        U5      nUR                  X5        U R                  X2SS9  UR	                  5         g NFr   )r   r   	draw_liner   r   )r$   posr   r   s       r&   
draw_pointPyMuPdfRenderBackend.draw_pointG  s?     3i!%8r(   c                    U R                  5       nUR                  [        U5      [        U5      5        U R                  XCSS9  UR	                  5         g r   )r   r   r   r   r   )r$   startendr   r   s        r&   r   PyMuPdfRenderBackend.draw_lineN  s@     UT#Y/%8r(   c                    U R                  5       nU H  u  pEUR                  XE5        M     U R                  X2SS9  UR                  5         g r   )r   r   r   r   )r$   linesr   r   r   r   s         r&   draw_solid_lines%PyMuPdfRenderBackend.draw_solid_linesT  sD      JEOOE'  %8r(   c                    [        U5      S:X  a  g U R                  5       n[        X1SS9  U R                  X2SS9  UR	                  5         g )Nr   Fr   )lenr   add_path_to_shaper   r   )r$   pathr   r   s       r&   	draw_pathPyMuPdfRenderBackend.draw_path]  sB    t9> %U3%8r(   c                    U R                  5       nU H  n[        X4SS9  M     U R                  X25        UR                  5         g )NTr   )r   r   r   r   )r$   pathsr   r   ps        r&   draw_filled_paths&PyMuPdfRenderBackend.draw_filled_pathse  s;      Aed3 E.r(   c                    UR                  5       n[        U5      S:  a  g U R                  5       nUR                  U5        U R	                  XB5        UR                  5         g )N   )to_listr   r   draw_polyliner   r   )r$   pointsr   verticesr   s        r&   draw_filled_polygon(PyMuPdfRenderBackend.draw_filled_polygonn  sR     >>#x=1  H%E.r(   c                   UR                   nUR                  nUR                  u  pVnUS:X  d   e[        UR	                  [        SS5      [        US5      [        Xe5      [        SU5      /5      5      nU V	s/ s H  oR                  PM     n
n	U V	s/ s H  oR                  PM     nn	[        R                  " [        U
5      [        U5      4[        U
5      [        U5      45      nUS   US   -
  R                  n[        R                  " US5      (       + nUR                  5       S:  nU(       d  U(       a  [         R"                  R%                  USS9nU(       a3  UR'                  [         R"                  R(                  R*                  5      nU(       a5  UR-                  U* [         R"                  R.                  R0                  SSS	9n[2        R4                  " U5      nUR                  u  pVn[        R6                  " [        R8                  " [        R:                  5      Xe[=        UR>                  5      S5      nU R@                  RC                  US
UU RE                  URF                  5      S9  g s  sn	f s  sn	f )N   r   r   r   RGBA)modeT)r   r   r   r   )resampleexpand	fillcolorF)keep_proportionr]   r   )$r9   imager   listtransform_verticesr   xyr   Rectminry   	angle_degmathisclosedeterminantPILImage	fromarray	transpose	TransposeFLIP_TOP_BOTTOMrotate
ResamplingBICUBICnpasarrayPixmap
ColorspaceCS_RGBrj   datarA   insert_imager   r   )r$   
image_datar   r9   r  heightr   depthcornersr   xsysrangleneed_rotate	need_flip	pil_imager]   s                     r&   
draw_imagePyMuPdfRenderBackend.draw_image{  s
   ((	  ${{uzz((aT%^T%-@$q&/R

 ##7acc7#"#7acc7#LL#b'3r7+c"gs2w-?@ gaj(33,,uc22 ))+a/	)		++E+?I%//		0C0C0S0ST	%,,F YY1199*	 - 	 JJy)E#(;; F5w~~.uUZZ?PRV

 			!..z/?/?@	 	 	
= $#s   9I9I>c                    UR                   U l         UR                  (       a#  UR                  S-  S-  n[        SU5      U l        UR                  U l        g )Ngffffff9@i,  r   )r   r   ry   r   )r$   r   min_lineweight_mms      r&   	configurePyMuPdfRenderBackend.configure  sM    !'!9!9   & 5 5 <s B"%d,=">D"(";";r(   c                    g rv    r   s    r&   clearPyMuPdfRenderBackend.clear      r(   c                    g rv   r0  r   s    r&   finalizePyMuPdfRenderBackend.finalize  r3  r(   c                    g rv   r0  )r$   entityr   s      r&   enter_entity!PyMuPdfRenderBackend.enter_entity  r3  r(   c                    g rv   r0  )r$   r8  s     r&   exit_entity PyMuPdfRenderBackend.exit_entity  r3  r(   )r   r   r   r   r   r   r   r   r   r   r   rA   r{   rz   r*   N)rA   rg   r*   rh   re   rf   )re   rj   )F)rP   rk   )re   r\   )r   r   re   rf   )r   r\   re   rk   )r   r   r   boolre   rf   )r   r   re   rf   )r   r   re   ztuple[float, float, float])r   floatre   r?  )r   r   r   r   re   rf   )r   r   r   r   r   r   re   rf   )r   zIterable[tuple[Vec2, Vec2]]r   r   re   rf   )r   r   r   r   re   rf   )r   zIterable[BkPath2d]r   r   re   rf   )r   r   r   r   re   rf   )r  r   r   r   re   rf   )r   r   re   rf   rd   )rl   rm   rn   ro   rp   r"   rL   rX   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)  r-  r1  r5  r9  r<  rs   r0  r(   r&   rb   rb      s    "*YX":)%
9

$0>O	'5F	 .?	.
`<r(   rb   c                   UR                   nUnUnUR                  5        GH  nUR                  nUR                  [        R
                  :X  a1  U(       a'  UR                  U5      (       d  U R                  X45        UnOUR                  [        R                  :X  a  U R                  X75        OUR                  [        R                  :X  a  U R                  X6R                  U5        OEUR                  [        R                  :X  a'  U R                  X6R                  UR                  U5        UnUnGM     U(       a)  UR                  U5      (       d  U R                  XT5        g g g rv   )r   commandsr   typer
   MOVE_TOr  r   LINE_TO	CURVE3_TO
draw_curvectrl	CURVE4_TOdraw_bezierctrl1ctrl2)r   r   r   r   sub_path_start
last_pointcommandr   s           r&   r   r     s   JJENJ==?kk<<7??*^33C886 N\\W__,OOE'\\W...ULL#6\\W...e]]GMM3G
 # ^++J77
3 8ur(   c                f    [        [        X5      U5      U-
  n X!-
  XC-
  -  nU[        X-  S5      -   $ )zDMap the DXF lineweight in mm to stroke-width in viewBox coordinates.r   )ry   r	  round)r   r   r   r   max_lineweightfactors         r&   r   r     s?     S4nEVJ1n6UVFeJ$7;;;r(   c                d    [        U 5      (       a   [        U S5      S-  $ g! [         a     gf = f)N      r   )r   rk   rW   )rQ   s    r&   r   r     s?     5zz	ub>C''   		s   " 
//)rA   rg   re   rk   )r   r   r   r>  re   rf   )r   gzG @)r   r?  r   r?  r   r?  re   r?  )rQ   r\   re   r?  )6
__future__r   r  typingr   r   r   r5   	PIL.Imager  numpyr  
ezdxf.mathr   r   ezdxf.colorsr	   
ezdxf.pathr
   ezdxf.versionr   ezdxf.lldxf.validatorr   r   
type_hintsr   rH   r   r   r   r   r   r   r   r   r    r   r   r   r   __annotations__ImportErrorr[   __all__r=   rV   Recorderr   r6   rb   r   r   r   r0  r(   r&   <module>re     s   #  / /    *   % =  F F 3 )   ! 3
4 / |4X&& |4~4M+ M` 4 44 
<
<
< 
< 
<Q  !	V !	!s   4C CC