
    Rj                        U d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZ ddlmZ ddlmZmZmZmZ 	 dd	lmZ n!# e$ r  ej        d
           dd	lmZ Y nw xY wddlmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 e
rddlm8Z8 ddlm9Z9 ddl:m;Z; ddl3m<Z<  ej=        e>          Z?dddZ@ ejA        d          ZB ejA        d          ZC ejA        dejD                  ZE ejA        d          ZFdeeG         deeG         fdZHe/ G d d eI                      ZJ ejA        d!          ZKh d"ZLd#d$d%dd&d'd(d)ZMejN        d*z  ejN        d+z  dejN        d,ZOe/d|d.eGd/eGdeIfd0            ZPe/d}d2eGd/eGdeIfd3            ZQe/d4eGd5eGdeGfd6            ZRe/d4eGd7eGdeSeGeGf         fd8            ZTe/d9eGdeGfd:            ZU eTd;d<d=d>d?d@dA          ZVe/dBeGde*e)z  fdC            ZWe/dDeGdeeI         fdE            ZXe/dDeGdeIfdF            ZYe/dGeIdHeIdeeGgeIf         fdI            ZZe/dJ fdeGdKeeGgef         defdL            Z[e/dM fdeeG         dKeeGgef         defdN            Z\dO dP dQ dR dS dT dU dV dW dX dY dZZ]eSeGef         e^d[<   e/	 d~d\e$e"z  d]d^d_eeSeGef                  ddfd`            Z_daeSeGef         dbd^de`fdcZaddeeeG         dfe`deGfdgZbdheeG         dieGdeGfdjZc	 d~dbd^d5eGdaeeSeGef                  deeG         fdkZd	 d~dbd^daeeSeGef                  deeeeG         eGeeI         eGf         fdlZf	 	 ddbd^daeeSeGef                  dmeeI         deeeIeIeIeIf         fdnZgdoeGdeheeeGeSeGef         f                  fdpZie/ G dq dr                      Zje/dseGde,fdt            Zke/due$dveGddfdw            Zl G dx dy          Zm G dz d{e          ZndS )aA  
Utilities to parse SVG graphics into fpdf.drawing objects.

The contents of this module are internal to fpdf2, and not part of the public API.
They may change at any time without prior warning or any deprecation period,
in non-backward-compatible ways.

Usage documentation at: <https://py-pdf.github.io/fpdf2/SVG.html>
    N)deepcopy)PathLike)TYPE_CHECKINGAnyCallable
NamedTupleOptional)
parse_path   )GradientSpreadMethodGradientUnitsPathPaintRuleStrokeCapStyle)
fromstringzYdefusedxml could not be imported - fpdf2 will not be able to sanitize SVG images provided)html)	BoundingBoxClippingPathGradientPaintGraphicsContextGraphicsStylePaintedPathPathPenTextTextRun)
DeviceGray	DeviceRGBPoint	Transformcolor_from_hex_stringcolor_from_rgb_stringforce_nodocument)
ImageCacheVectorImageInfo)stream_content_for_raster_image)shape_linear_gradientshape_radial_gradient)Element)
Renderable)FPDF)ResourceCatalogzhttp://www.w3.org/2000/svgzhttp://www.w3.org/1999/xlink)svgxlinkz(?:\s+,\s+|\s+,|,\s+|\s+|,)zf(matrix|rotate|scale|scaleX|scaleY|skew|skewX|skewY|translate|translateX|translateY)\(([\d\.,\s+-]+)\)z	/\*.*?\*/z(?s)([^{}]+)\{([^{}]*)\}valuereturnc                 l    | d S t          | t                    r|                                 }|sd S |S | S N)
isinstancestrstrip)r-   strippeds     I/usr/local/lib/hermes-agent/venv/lib/python3.11/site-packages/fpdf/svg.py_normalize_css_valuer6   X   sB    }t% ;;== 	4L    c                       e Zd ZdZdS )Percentz$class to represent percentage valuesN)__name__
__module____qualname____doc__ r7   r5   r9   r9   c   s        ....r7   r9   z2\s*(?P<value>[-+]?[\d\.]+)\s*(?P<unit>%|[a-zA-Z]*)>   chemexiclhvbvhvivwcapremrlhvmaxvmin%H   gbX<@gjZ@   g      ?gjZ?)incmmmptpcpxQih  i  )deggradradturnrS   
length_strdefault_unitc                 V   t                               |           }|t          d|  d          d|                                \  }}|s|}	 t	          |          t
          |         z  S # t          $ r4 |t          v rt          |  d|           dt          |  d|           dw xY w)z7Convert a length unit to our canonical length unit, pt.NzUnable to parse 'z' as a lengthz" uses unsupported relative length z contains unrecognized unit )unit_splittermatch
ValueErrorgroupsfloatabsolute_length_unitsKeyErrorrelative_length_units)r[   r\   r_   r-   units        r5   resolve_lengthrg      s     
++E}FZFFFGGTQ,,..KE4 VU||3D999 V V V(((GGGG  JJJDJJKKQUUVs   A* *>B(rW   	angle_strc                     t                               |           }||                                \  }}n| }|s|}	 t          |          t          |         z  S # t
          $ r t          d|  d|           dw xY w)z;Convert an angle value to our canonical angle unit, radiansNzangle z has unknown unit )r^   r_   ra   rb   angle_unitsrd   r`   )rh   r\   mr-   rf   s        r5   resolve_anglerl      s     	I&&A}hhjjtt QU||k$/// Q Q QE)EEtEEFFDPQs   A !A:spacenamec                 X    	 dt           |           d} n# t          $ r d} Y nw xY w|  | S )zECreate an XML namespace string representation for the given tag name.{} )_HANDY_NAMESPACESrd   )rm   rn   s     r5   xmlnsrt      sV    1&u-111    Ts    ##namesc                 D    i }|D ]}||t          | |          <   |||<   |S )z>Create a lookup for the given name in the given XML namespace.)rt   )rm   ru   resultrn   s       r5   xmlns_lookuprx      s<     F  %)uUD!!"tMr7   qualified_tagc                 V    |                      d          }|dk    r| |dz   d         S | S )z8Remove the xmlns namespace from a qualified XML tag namerq   r   r   N)index)ry   is     r5   
without_nsr}      s9     	C  AAvvQUWW%%r7   r+   rectcircleellipselinepolylinepolygoncolorstrc                     	 t           j        |          } n# t          $ r Y nw xY w|                     d          rt	          |           S |                     d          rt          |           S t          d|            )N#rgbz unsupported color specification )r   
COLOR_DICTrd   
startswithr   r    r`   r   s    r5   svgcolorr      s    ?8,    3 /$X...5!! /$X...
BBB
C
CCs    
""incomingc                 f    t          |           }|dk     rt          d|  d          |dk    rd S |S )Nr   zstroke width z cannot be negative)rg   r`   r   vals     r5   convert_stroke_widthr      sE    

"
"C
QwwFFFFGGG
axxtJr7   c                 V    t          |           }|dk     rt          d|  d          |S )N      ?zmiter limit z cannot be less than 1)rb   r`   r   s     r5   convert_miterlimitr      s5    
//C
SyyHHHHIIIJr7   min_valmax_valc                 4     dt           dt          f fd}|S )Nr-   r.   c                 F    t          |           }|k     rS |k    rS |S r0   rb   )r-   r   r   r   s     r5   	converterzclamp_float.<locals>.converter  s/    Ell==N==N
r7   )r2   rb   )r   r   r   s   `` r5   clamp_floatr     s=             r7   c                     | S r0   r>   )r-   s    r5   <lambda>r     s     r7   r   c                 8    | dv rt           j        S  ||           S )N)inheritcurrentColor)r   INHERITr-   r   s     r5   inheritabler     s)     +++$$9Ur7   c                     | S r0   r>   )noops    r5   r   r     s     r7   c                     | d S t          | t                    r|                                 sd S | dk    rd S t          | |          S )Nnone)r1   r2   r3   r   r   s     r5   optionalr     sR    
 }t% ekkmm ttui(((r7   c                 b    d| r|                      d          st          | t                    nd fS )N
fill_colorurl(r   r   r   r   s    r5   r   r   .  s>     !)!4!4V!<!<HXx((( r7   c                 $    dt          |           fS )Nintersection_ruler   )fillrulestrs    r5   r   r   7  s    &9;{;S;S%T r7   c                 B    dt          | t          dd                    fS )Nfill_opacity        r   r   r   )filopstrs    r5   r   r   9  s#    Hk#s3344& r7   c                 b    d| r|                      d          st          | t                    nd fS )Nstroke_colorr   r   r   s    r5   r   r   >  s>     !)!4!4V!<!<HXx(((  r7   c                 0    dt          | t                    fS )Nstroke_width)r   r   )valuestrs    r5   r   r   G  s    H233& r7   c                 (    dt          | d           fS )Nstroke_dash_patternc                 J    d t                               |           D             S )Nc                 0    g | ]}|t          |          S r>   r   ).0items     r5   
<listcomp>z.<lambda>.<locals>.<lambda>.<locals>.<listcomp>P  s#    OOO$OdOOOr7   )NUMBER_SPLITsplit)das    r5   r   z<lambda>.<locals>.<lambda>P  s#    OO0B0B20F0FOOO r7   )r   )	dasharrays    r5   r   r   L  s"    OO	
 	
+ r7   c                 0    dt          | t                    fS )Nstroke_dash_phase)r   rb   )dashoffs    r5   r   r   U  s    GU##* r7   c                 $    dt          |           fS )Nstroke_cap_styler   )capstrs    r5   r   r   Z  s    &8+f:M:M%N r7   c                 $    dt          |           fS )Nstroke_join_styler   )joinstrs    r5   r   r   \  s    (;[=Q=Q'R r7   c                 0    dt          | t                    fS )Nstroke_miter_limit)r   r   )limstrs    r5   r   r   ^  s    F.//) r7   c                 B    dt          | t          dd                    fS )Nstroke_opacityr   r   r   )stropstrs    r5   r   r   c  s#    Hk#s3344( r7   )fillz	fill-rulezfill-opacitystrokezstroke-widthzstroke-dasharrayzstroke-dashoffsetzstroke-linecapzstroke-linejoinzstroke-miterlimitzstroke-opacitysvg_attr_mapstylablesvg_elementr'   computed_stylec                 <   ||}n]i }t          j        |j                            dd                                                    D ]\  }}t          |          }||||<   d| j        _        t                                          D ]m\  }}t          |                    |                    }	|	't          |j                            |                    }	|	t          | j        g ||	          R   nt          |                    d                    }
|
't          |j                            d                    }
|
't          |
          }|| j        _        || j        _        |j                            d          }|rt          |          | _        dS dS )zKApply the known styles from `svg_element` to the pdf path/group `stylable`.Nstylerr   Fopacity	transform)r   parse_css_styleattribgetitemsr6   r   
auto_closer   setattrrb   r   r   convert_transformsr   )r   r   r   r   keyr-   
norm_value	attr_namer   
attr_valueopacity_strr   tfstrs                r5   apply_stylesr   j  s    !.""7B//
 

%''	( 	(JC .e44J%'c
 %HN , 2 2 4 4 < <	9)%))I*>*>??
-k.@.D.DY.O.OPPJ!HN;YYz%:%:;;;; 'uyy';';<<K*;+=+A+A)+L+LMM$$&-#(/%"";//E 7/667 7r7   	style_maptagc                     |                      d          pd                                }|dv rdS |j                             d          }t          |dk              S )Nwhite-spacerr   )prezpre-wrapzbreak-spacesTz+{http://www.w3.org/XML/1998/namespace}spacepreserve)r   r3   r   bool)r   r   ws	xml_spaces       r5   _preserve_wsr     s\    
--
&
&
,"	3	3	5	5B	000t
LMMI	Z'(((r7   Fsr   c                 >    | dS |r| S t          j        dd|           S )z
    Collapse sequences of whitespace characters (spaces, tabs, etc.) to a single space
    In some cases, like with `pre` tags, whitespace should be preserved.
    Nrr   z\s+ )resub)r   r   s     r5   _collapse_wsr     s/    
 	yr 6&#q!!!r7   
font_stylefont_weightc                 (   d}d}|rQ|                                                                 }|dv p&|                                ot          |          dk    }| r*|                                                                  }|dv }|r|rdS |rdS |rdS dS )	NF)boldbolderiX  )italicobliqueBIBIrr   )r3   lowerisdigitint)r   r   br|   fwfss         r5   _svg_font_style_to_emphasisr    s    AA J  &&(($$I)H#b''S. (%%'''' Q t s s2r7   c                 J   |&t          |                    |                    }||S |St          j        | j                            dd                    }t          |                    |                    }||S t          | j                            |                    S )zJReturn the value for a given attribute, honoring computed style overrides.Nr   rr   )r6   r   r   r   r   )r   rn   r   r-   inlines        r5   _get_attr_or_styler    s     $Y]]4%8%899L%cjnnWb&A&ABB$VZZ%5%566L
t 4 4555r7   c                    t          | d|          }|rg }|                    d          D ]U}|                                                    dd                              dd          }|r|                    |           V|rd                    |          nd}nd}t          | d|          pd}t          | d|          pd}t          ||          }	t          | d	|          }
|
t          |
          nd}t          | d
|          pd                                                                }|dvrd}||	|t          |          nd|fS )zUReturns (font_family or None, font_style_emphasis, font_size_pt or None, text_anchor)font-family,"rr   'N
font-stylefont-weight	font-sizetext-anchorstart)r  middleend)
r  r   r3   replaceappendjoinr  rg   r  rb   )r   r   family_valuecleanedr   r4   familyr   r   emphasisr  size_pttas                r5   _parse_font_attrsr%    sq    &c=)DDL  &&s++ 	) 	)Dzz||++C44<<S"EEH )x(((&-7'"""4 $CyAAGRJ$S-CCIrK*:{CCH 
Ci	8	8B nr$ 
 S-
;
;
Fw	M	M	O	O	U	U	W	WB	+++8w/BU7^^^bPPr7   	font_sizec           	           dt           fdt          dt          dt          t          gt          f         dt          f fd} |dd          } |dd          } |d	d          } |d
d          }||||fS )z0x,y (default 0,0) and optional dx,dy (default 0)r   rn   defaultresolverr.   c                    d }
| 
v r	
|          }n| j         v rj         |          }|s|S t                              |                                          }|r|d         s|S |d         }t                              |          }|r|                    d          }|                    d          pd                                }|                                dv rR	$t          	                    d|j
        |            |S 	 t          |          	z  S # t          t          f$ r |cY S w xY w|                                dk    rT	#t          	                    dj
        |            |S 	 t          |          	z  d	z  S # t          t          f$ r |cY S w xY w	 t           ||                    S # t          $ r' t          	                    d
|j
        |            |cY S w xY w)Nr   r-   rf   rr   >   r@   rI   zCIgnoring relative %s length on <%s %s> because font size is unknownrA   zCIgnoring relative ex length on <%s %s> because font size is unknowng      ?z+Ignoring unsupported length '%s' on <%s %s>)r   r   r   r3   r^   	fullmatchgroupr  LOGGERwarningr   rb   	TypeErrorr`   )rn   r(  r)  attrpartstokenr_   	value_strrf   r&  r   r   s            r5   first_numberz%_parse_xy_delta.<locals>.first_number  sF   
  TY%6%6T?DDSZ:d#D 	N""4::<<00 	E!H 	Na''.. 	#G,,IKK''-24466Dzz||},,$NN]	   #N# ++i77!:. # # #"NNN#zz||t##$NN]  
 #N# ++i7#==!:. # # #"NNN#		%))) 	 	 	NN=	   NNN	s6   D D-,D-.F FFF5 5.G&%G&xydxdy)rg   r2   rb   r   )r   r   r&  r4  r5  r6  r7  r8  s   ```     r5   _parse_xy_deltar9    s     +96 666 C5%<(6 
	6 6 6 6 6 6 6 6p 	S#AS#A	dC	 	 B	dC	 	 BaR<r7   css_textc                 N   g }| s|S t                               d|           }t                              |          D ]\  }}t	          j        |          }|si }|                                D ]\  }}t          |          }	|	|	||<   |sQd |                    d          D             }
|
D ]u}|	                    d          s|dd                              dd          d         
                                }|sQ|                    |t          |          f           v|S )Nrr   c                 6    g | ]}|                                 S r>   )r3   )r   selectors     r5   r   z-_extract_css_class_styles.<locals>.<listcomp>E  s"    PPP(X^^%%PPPr7   r  .r   :r   )CSS_COMMENT_REr   CSS_BLOCK_REfindallr   r   r   r6   r   r   r3   r  dict)r:  stylesr   selector_blockbodydeclarations
normalizedr   r-   r   	selectorsr=  
class_names                r5   _extract_css_class_stylesrK  4  sb   /1F   X..G , 4 4W = = : :+D11 	
&,,.. 	- 	-JC-e44J%",
3 	PPn6J6J36O6OPPP	! 	: 	:H&&s++ !!""++C33A6<<>>J MM:tJ'7'789999	: Mr7   c                      e Zd ZdZeddddedefd            Zeddddedefd            Z	eddddedefd	            Z
eddddedefd
            Zedddefd            Zedddefd            Zeddddedefd            ZdS )ShapeBuilderzNA namespace within which methods for converting basic shapes can be looked up.Fr   r'   clipping_pathr.   c                 b    t                      }|rt                      }t          ||            |S )z.Create a new path with the appropriate styles.)r   r   r   )r   rN  paths      r5   new_pathzShapeBuilder.new_pathT  s3     }} 	">>DT3r7   c                 |   t          |j                            dd                    }t          |j                            dd                    }|j                            d          pd}|                    d          rt	          |dd                   }nt          |          }|j                            d          pd}|                    d          rt	          |dd                   }nt          |          }|j                            d	          pd
}	|j                            d          pd
}
|	dk    rd}	|
dk    rd}
|	|
cxk    rd
k    rn ndx}}nN|	d
k    rt          |
          x}}n6|
d
k    rt          |	          x}}nt          |	          }t          |
          }|dk     s|dk     s|dk     s|dk     rt          d|           |dk    s|dk    rt                      S ||dz  k    r|dz  }||dz  k    r|dz  }|                     ||          }|	                    ||||||           |S )z&Convert an SVG <rect> into a PDF path.r5  0r6  widthrM   Nheightrxautoryr   r   z	bad rect    )
rg   r   r   endswithr9   rb   r`   r   rQ  	rectangle)clsr   rN  r5  r6  	width_strrT  
height_strrV  rx_strry_strrW  rY  rP  s                 r5   r~   zShapeBuilder.rect]  sh    3:>>#s33443:>>#s3344JNN7++2s	c"" 	.%,Yss^%<%<EE"9--EZ^^H--4
s## 	0&-j"o&>&>FF#J//F%%/%%/VFVF
 V%%%%v%%%%%KBvFmm#BvFmm#BvBvBAII6A::266rAvv...///QJJFaKK== B!!B||C//q!UFB333r7   c                 4   t          |j                            dd                    }t          |j                            dd                    }t          |j        d                   }|                     ||          }|                    |||           |S )z(Convert an SVG <circle> into a PDF path.cxr   cyr)rb   r   r   rQ  r   )r]  r   rN  rc  rd  re  rP  s          r5   r   zShapeBuilder.circle  s     3:>>$**++3:>>$**++#*S/""||C//BAr7   c                 H   t          |j                            dd                    }t          |j                            dd                    }|j                            d          pd}|j                            d          pd}|                     ||          }||cxk    rdk    sn |dk    s|dk    r|S |dk    rt          |          x}}	n6|dk    rt          |          x}}	nt          |          }t          |          }	|                    ||||	           |S )z)Convert an SVG <ellipse> into a PDF path.rc  r   rd  rW  rX  rY  rS  )rb   r   r   rQ  r   )
r]  r   rN  rc  rd  r`  ra  rP  rW  rY  s
             r5   r   zShapeBuilder.ellipse  s"    3:>>$**++3:>>$**++%%/%%/||C//f&&&&&&&&FcMMv}}KVFmm#BvFmm#BvBvBRR$$$r7   c                 X   t          |j        d                   }t          |j        d                   }t          |j        d                   }t          |j        d                   }|                     |          }|                    ||           |                    ||           |S )z&Convert an SVG <line> into a PDF path.x1y1x2y2)rb   r   rQ  move_toline_to)r]  r   rh  ri  rj  rk  rP  s          r5   r   zShapeBuilder.line  s     3:d#$$3:d#$$3:d#$$3:d#$$||C  RRr7   c                 p    |                      |          }d|j        d         z   }t          ||           |S )z*Convert an SVG <polyline> into a PDF path.MpointsrQ  r   svg_path_converter)r]  r   rP  rp  s       r5   r   zShapeBuilder.polyline  s;     ||C  sz(++4(((r7   c                 x    |                      ||          }d|j        d         z   dz   }t          ||           |S )z)Convert an SVG <polygon> into a PDF path.ro  rp  Zrq  )r]  r   rN  rP  rp  s        r5   r   zShapeBuilder.polygon  sB     ||C//sz(++c14(((r7   NF)r:   r;   r<   r=   staticmethodr   r   rQ  classmethodr~   r   r   r   r   r   r>   r7   r5   rM  rM  P  s       XX i      \ 1 1y 1 1+ 1 1 1 [1f   4 K    [  ) D [    [0 
y 
[ 
 
 
 [
 9     [  ) D [    [  r7   rM  r   c           	      	   t                               |           }t          j                    }|D ]\  }}|                                }|dk    rPt          d t                              |          D                       \  }}}}}	}
t          |||||	|
          |z  }p|dk    rt                              |          ^}}t          |          }t          j	        |          }|rft          |          dk    r=|                    t          |d                   t          |d                             }nt          d| d	| d
          ||z  }%|dk    rt                              |          }t          |          dk    r+t          |d                   }t          |d                   }n=t          |          dk    rt          |d                   x}}nt          d|            t          j        ||          |z  }|dk    r(t          j        t          |          d          |z  }	|dk    r(t          j        dt          |                    |z  }7|dk    rt                              |          }t          |          dk    r+t          |d                   }t          |d                   }n=t          |          dk    rt          |d                   }d}nt          d|            t          j        t!          j        |          t!          j        |                    |z  }|dk    r:t          j        t!          j        t          |                    d          |z  }Q|dk    r:t          j        dt!          j        t          |                              |z  }|dk    rt                              |          }t          |          dk    r+t%          |d                   }t%          |d                   }n=t          |          dk    rt%          |d                   }d}nt          d|            t          j        ||          |z  }G|dk    r(t          j        t%          |          d          |z  }u|dk    r&t          j        dt%          |                    |z  }|S )z8Convert SVG/CSS transform functions into PDF transforms.matrixc              3   4   K   | ]}t          |          V  d S r0   r   )r   ns     r5   	<genexpr>z%convert_transforms.<locals>.<genexpr>  s(      $P$P!U1XX$P$P$P$P$P$Pr7   rotate)thetarZ  r   r   zrotation transform (z) is malformedscalezbad scale transform r5  r6  scaleXscaleYskewzbad skew transform skewXskewY	translatezbad translation transform 
translateX
translateY)TRANSFORM_GETTERrB  r   identityr3   tupler   r   rl   rotationlenaboutrb   r`   scalingshearingmathtanrg   translation)r   parsedr   tf_typeargsar	  cdefr~  r  r  sxsyr5  r6  s                     r5   r   r     s    %%e,,F"$$I SW SWzz||h$$P$P|7I7I$7O7O$P$P$PPPAq!Q1!!Q1a33i?II  (..t44MEE!%((E )666H  u::??'~~eE!HoouU1XOOHH$LgLLLLL   !9,II%%d++D4yyA~~47^^47^^TaQ..(RR !?!?!?@@@!)B"555	AII  !)E$KK1===	III  !)At===	III%%d++D4yyA~~"47++"47++Ta"47++ !>u!>!>???!*TXb\\TXb\\JJJYVII"TXmD.A.A%B%BaHHH9T I "Q$(=3F3F*G*GHHH9T I ##%%d++D4yyA~~"47++"47++Ta"47++ !Ee!E!EFFF!-Q777)CII$$!-t0D0DJJJYVII$$!-^D5I5IJJJYVIr7   pdf_pathsvg_pathc                 p    t          |           }t          ||           |j        st          d          d S )Nz"Path does not start with move item)r   r
   first_is_mover`   )r  r  pens      r5   rr  rr  7  sC    
(

Cx ?=>>>? ?r7   c                      e Zd ZdZedddeee         z  dedededd f
d	            Z	 dJdee	z  de
e         dd
fdZede
e         dedd
fd            ZdKdZdddeeef         fdZeedLdededefd                        Zeedddeeeeez  f                  fd                        Zeede
e         de
e         fd                        ZedMd            ZedMd             Ze	 dJd!ed"dd#e
eeef                  dd
fd$            ZedKd%            ZedKd&            Z 	 dNd(d)d*e!deeee"f         fd+Z#	 	 dOd-ed.ee$z  d/ee$z  d*e!d0e!deeee"f         fd1Z%	 	 	 dPd(d)d2e
e         d3e
e         d4e
e!         dd
f
d5Z&edQd7            Z'ed8dde"fd9            Z(e	 	 dRd:dd;e
e"         d<e
eeef                  de"fd=            Z)ed>ddefd?            Z*ed@ddefdA            Z+ed@ddBe
e         dd
fdC            Z,e	 dJd!ed"dd#e
eeef                  dd
fdD            Z-edSdG            Z.e	 dJdHdd<e
eeef                  de
e         fdI            Z/d
S )T	SVGObjectzU
    A representation of an SVG that has been converted to a PDF representation.
    zutf-8encodingfilenamer  r  kwargsr.   c                    t          |d|          5 } | |                                g|R i |cddd           S # 1 swxY w Y   dS )a  
        Create an `SVGObject` from the contents of the file at `filename`.

        Args:
            filename (path-like): the path to a file containing SVG data.
            *args: forwarded directly to the SVGObject initializer. For subclass use.
            encoding (str): optional charset encoding to use when reading the file.
            **kwargs: forwarded directly to the SVGObject initializer. For subclass use.

        Returns:
            A converted `SVGObject`.
        re  r  N)openread)r]  r  r  r  r  svgfiles         r5   	from_filezSVGObject.from_fileD  s    ( (C(333 	8w3w||~~777777	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s   >AANsvg_textimage_cachec                 R   || _         i | _        i | _        i | _        d | _        d | _        t          |          }|j        t          dd          vrt          d|j                   | 
                    |           |                     |           |                     |           d S )Nr+   zroot tag must be svg, not )r  cross_referencescss_class_stylesgradient_definitionsrT  rV  parse_xml_strr   rx   r`   _collect_css_stylesextract_shape_infoconvert_graphics)selfr  r  svg_trees       r5   __init__zSVGObject.__init__[  s     '02;= 	! 15
15+H55<|E59999H(,HHIII  ***)))h'''''r7   r   
referencedc                 Z    |r(|                     d          sd|z   n|}|| j        |<   d S d S )Nr   )r   r  )r  r   r  s      r5   update_xrefzSVGObject.update_xrefp  sE     	4#&>>##6#6?#))CC)3D!#&&&	4 	4r7   root_tagr'   c                 >   |                                 D ]}|j        t          dd          v rnd                    |                                pg           }t          |          D ]5\  }}| j                            |i           }|                    |           6d S )Nr+   r   rr   )	iterr   rx   r  itertextrK  r  
setdefaultupdate)r  r  noder:  rJ  rG  existings          r5   r  zSVGObject._collect_css_stylesv  s    MMOO 	2 	2Dx<w7777774==??#8b990I(0S0S 2 2,J#4??
BOOHOOL1111	2 	2r7   r   c                 n   i }| j         rd|j                            d          }|rH|                                D ]3}| j                             |          }|r|                    |           4t          j        |j                            dd                    }|                                D ]6\  }}t          |          }	|	|	||<   ||v r|	                    |d            7d}
|
D ]J}||j        v r?t          |j                            |                    }	|	|
                    ||	           K|S )Nclassr   rr   )r  r  r  r  r  r   )r  r   r   r   r  r   r   r   r6   popr  )r  r   r   
class_attrrJ  class_stylesr  r   r-   r   inheritable_attrsr0  s               r5   _style_map_forzSVGObject._style_map_for~  sX   $&	  	700J 7","2"2"4"4 7 7J#'#8#<#<Z#H#HL# 7!((666%cjnnWb&A&ABB ,,.. 	) 	)JC-e44J%!+	#	!!c4(((
 & 	; 	;Dsz!!1#*..2F2FGG
)((z:::r7   rS  r-   r(  c                 V   | | dk    r|} |                                  } |                     d          rt          | dd                   dz  S 	 t          |           S # t          $ r@ 	 t	          |           cY S # t          $ r  t
                              d|            Y Y dS w xY ww xY w)z@Convert SVG gradient coordinate (percentage or number) to float.Nrr   rM   rU        Y@z1Could not parse gradient coordinate '%s', using 0r   )r3   r[  rb   r`   rg   r-  r.  )r-   r(  s     r5   _convert_gradient_coordinatez&SVGObject._convert_gradient_coordinate  s     =ERKKE>># 	-ss$$u,,		<< 	 	 	%e,,,,,   G   sss		s0   A 
B()A:7B(:%B$B(#B$$B(gradient_elementc                 *   g }| D ]}t          |j                  }|dk    r|j                            d          }|t                              d           U|                                }|                    d          rt          |dd                   dz  }nt          |          }t          dt          d	|                    }d}d	}|j                            d
d          }|r|t          j        |          }	|	                    d          }|	                    d          }
|
r<	 t          |
          }n+# t          $ r t                              d|
           Y nw xY w||j                            dd          }d|j        v r;	 t          |j                            d          pd          }n# t          $ r Y nw xY w	 t          |          }|d	k     r`t          |t                     r!t!          |j        |j        |j        |          }t          |t(                    rt)          |j        |          }|                    ||f           S# t          t,          f$ r'}t                              d||           Y d}~d}~ww xY w|S )z,Parse <stop> children of a gradient element.stopoffsetNz%Found <stop> without offset, skippingrM   rU  r  r   r   r   rr   z
stop-colorzstop-opacityzInvalid stop-opacity value: %sblack1z#Could not parse stop color '%s': %s)r}   r   r   r   r-  r.  r3   r[  rb   maxminr   r   r`   r   r1   r   re  gr	  r   r  rd   )r  stopsstop_elementtag_name
offset_strr  
stop_colorstop_opacityr   
style_dictstop_opacity_str	color_objr  s                r5   _parse_gradient_stopszSVGObject._parse_gradient_stops  s    =?, 9	 9	L!,"233H6!!%,00::J!FGGG#))++J""3'' +z#2#//%7z**c#v..//FJL '++GR88E 
!1%88
'^^L99
#->>.#A#A # ',-='>'>%   <>N    
 !)044\7KK
!444#()<)@)@)P)P)WTW#X#XLL!   D$Z00	#%%!)Y77 $-%Kik<% %	 ")Z88 J$.y{L$I$I	fi01111)   DjRSTTT s=   -D==%E%$E%)F99
GG
BIJ)JJ	url_valuec                     | rt          | t                    sdS t          j        d|           }|rd|                    d          z   S dS )z)Extract gradient ID from url(#id) format.Nzurl\(\s*["\']?\s*#([^)"\'\s]+)r   r   )r1   r2   r   searchr,  )r  r_   s     r5   _extract_gradient_idzSVGObject._extract_gradient_id  sV      	
9c : : 	4	;YGG 	(Q''tr7   grad_elementc                    |j                             d          }|st                              d           dS |                    d          sd|z   }|j                             dd          }|j                             dd          }|j                             dd	          }|j                             d
d          }|                     |d          }|                     |d          }|                     |d          }	|                     |d          }
|j                             dd          }|dk    rt          j        }nt          j        }|j                             dd          }	 t          j
        |          }n># t          t          f$ r* t          j        }t                              d|           Y nw xY wd}|j                             d          }|rP	 t          |          }n?# t          t          t          f$ r%}t                              d|           Y d}~nd}~ww xY w|                     |          }|st                              d|           dS t#          |||	|
||          }t%          |||pt'          j                    |          }|| j        |<   t                              d|t/          |                     dS )zFParse a <linearGradient> element and store it in gradient_definitions.idz5Found <linearGradient> without id attribute, skippingNr   rh  0%ri  rj  z100%rk  rS  r  gradientUnitsobjectBoundingBoxuserSpaceOnUsespreadMethodpadz$Invalid spreadMethod '%s', using PADgradientTransform%Could not parse gradientTransform: %sz1Linear gradient '%s' has no valid stops, skipping)rh  ri  rj  rk  r  spread_methodgradientunitsgradient_transformr  z)Parsed linear gradient '%s' with %d stops)r   r   r-  r.  r   r  r   USER_SPACE_ON_USEOBJECT_BOUNDING_BOXr   coercer`   AttributeErrorPADr   r/  r  r%   r   r   r  r  debugr  )r  r  grad_idrh  ri  rj  rk  x1_valy1_valx2_valy2_val	units_strr  
spread_strr  r   transform_strr  r  r  gradient_paints                        r5   _parse_linear_gradientz SVGObject._parse_linear_gradient  s    ".!4!8!8!>!> 	NNRSSSF!!#&& 	$GmG $$T400 $$T400 $$T622 $$T400222s;;222s;;222s;;222s;; '++O=PQQ	(((!3EE!5E!(,,^UCC
	O07
CCMMN+ 	O 	O 	O04MNNA:NNNNN	O 	$+//0CDD 	KK.}==			: K K KFJJJJJJJJK **<88 	NNNPWXXXF('
 
 
 '(@I,>,@,@'	
 
 
 .<!'*@'3u::VVVVVs*   -F 8F=<F=G/ /H+H&&H+c           
         |j                             d          }|st                              d           dS |                    d          sd|z   }|j                             dd          }|j                             dd          }|j                             dd          }|j                             d	|          }|j                             d
|          }|j                             dd          }|                     |d          }	|                     |d          }
|                     |d          }|                     |t          |	                    }|                     |t          |
                    }|                     |d          }|dk    rt                              d||           dS |j                             dd          }|dk    rt          j        nt          j	        }|j                             dd          }	 t          j        |          }n## t          t          f$ r t          j        }Y nw xY wd}|j                             d          }|rP	 t          |          }n?# t          t          t           f$ r%}t                              d|           Y d}~nd}~ww xY w|                     |          }|st                              d|           dS t%          |	|
||||||          }t'          |||pt)          j                    |          }|| j        |<   t                              d|t1          |                     dS )zFParse a <radialGradient> element and store it in gradient_definitions.r  z5Found <radialGradient> without id attribute, skippingNr   rc  z50%rd  re  fxfyfrr  z0.5rS  r   z4Radial gradient '%s' has invalid radius %s, skippingr  r  r  r  r  r  r  z1Radial gradient '%s' has no valid stops, skipping)rc  rd  re  r  r	  r
  r  r  r  z)Parsed radial gradient '%s' with %d stops)r   r   r-  r.  r   r  r2   r   r  r  r   r  r`   r  r  r   r/  r  r&   r   r   r  r  r  r  )r  r  r  rc  rd  re  r	  r
  r  cx_valcy_valr_valfx_valfy_valfr_valr  r  r  r  r   r  r  r  r  r  s                            r5   _parse_radial_gradientz SVGObject._parse_radial_gradientH  s    %))$// 	NNRSSSF!!#&& 	$GmG $$T511 $$T511##C// $$T2.. $$T2.. $$T400222u==222u==11!U;;222s6{{CC222s6{{CC222s;;A::NNFQV   F '++O=PQQ	 ,,, ++2 	 "(,,^UCC
	507
CCMMN+ 	5 	5 	504MMM	5 	$+//0CDD 	KK.}==			: K K KFJJJJJJJJK **<88 	NNNPWXXXF('	
 	
 	
 '(@I,>,@,@'	
 
 
 .<!'*@'3u::VVVVVs*   H! !I I#I3 3J/
J**J/r   r   r   c                    t          |d|          }|rR|                     |          }|r;|| j        v r2| j        |         |j        _        t
                              d|           t          |d|          }|rT|                     |          }|r?|| j        v r8| j        |         |j        _        t
                              d|           dS dS dS dS )zPApply gradient paint to fill or stroke if a url(#gradientId) reference is found.r   zApplied gradient %s to fillr   zApplied gradient %s to strokeN)r  r  r  r   r   r-  r  r   )r  r   r   r   
fill_valuer  stroke_values          r5   _apply_gradient_paintzSVGObject._apply_gradient_paint  s     (VYGG
 	E//
;;G E7d&???,0,Eg,N):GDDD)+xKK 	G//==G G7d&???.2.G.P+<gFFFFF		G 	GG G??r7   c                 H   |                     d          }|                     d          }|                     d          }|                     dd          }|dk    rd| _        nd| _        d| _        |Z|                                 |                    d          rt          |dd	                   | _        nt          |          | _        d| _        |Z|                                 |                    d          rt          |dd	                   | _        nt          |          | _        |	d| _        dS |                                }d
 t          
                    |          D             \  }}}}	|dk     s|	dk     rt          d|           ||||	g| _        dS )z&Collect shape info from the given SVG.rT  rV  viewBoxpreserveAspectRatioTr   NrM   rU  c                 ,    g | ]}t          |          S r>   r   )r   nums     r5   r   z0SVGObject.extract_shape_info.<locals>.<listcomp>  s    PPPSeCjjPPPr7   r   z)invalid negative width/height in viewbox )r   preserve_arrT  r3   r[  r9   rg   rV  viewboxr   r   r`   )
r  r  r^  r_  r  r  vxvyrG   rE   s
             r5   r  zSVGObject.extract_shape_info  s    LL))	\\(++
,,y))ll#8$??&  #D#D
 OO!!#&& 7$Yss^44

+I66
!""3'' 9%j"o66,Z88?DLLLmmooGPPL4F4Fw4O4OPPPNBBQBFF !VW!V!VWWWB+DLLLr7   c                     t                      }d|j        _        d|j        _        t          j        |j        _        |                     ||           || _        dS )zFConvert the graphics contained in the SVG into the PDF representation.NF)	r   r   r   r   r   BUTTr   build_group
base_group)r  r  r#  s      r5   r  zSVGObject.convert_graphics  sT     %&&
(,
%&+
#,:,?
):...$r7   Tpdfr)   align_viewboxc                 P    |                      |j        |j        |j        |          S )a  
        Size the converted SVG paths to the page viewport.

        The SVG document size can be specified relative to the rendering viewport
        (e.g. width=50%). If the converted SVG sizes are relative units, then this
        computes the appropriate scale transform to size the SVG to the correct
        dimensions for a page in the current PDF document.

        If the SVG document size is specified in absolute units, then it is not scaled.

        Args:
            pdf (fpdf.fpdf.FPDF): the pdf to use the page size of.
            align_viewbox (bool): if True, mimic some of the SVG alignment rules if the
                viewbox aspect ratio does not match that of the viewport.

        Returns:
            The same thing as `SVGObject.transform_to_rect_viewport`.
        )transform_to_rect_viewportkepweph)r  r$  r%  s      r5   transform_to_page_viewportz$SVGObject.transform_to_page_viewport  s$    , ..sucgswVVVr7   Fr  rT  rV  ignore_svg_top_attrsc                     |r5t          |t                    rt          |          }nRt          |          }nBt          | j        t                    r|st	          d          | j        |z  dz  }n	| j        p|}|r5t          |t                    rt          |          }nRt          |          }nBt          | j        t                    r|st	          d          | j        |z  dz  }n	| j        p|}|dk    rt          j                    }nt          j        d|z            }| j	        r| j	        \  }	}
}}|dk    s|dk    rddt                      fS ||z  }||z  }|s| j        r||k    rt          ||          x}}|t          j        |	 |
           z  t          j        ||          z  }|r1|t          j        |dz  |dz  |z  z
  |dz  |dz  |z  z
            z  }|| j        _        ||z  ||z  | j        fS )a  
        Size the converted SVG paths to an arbitrarily sized viewport.

        The SVG document size can be specified relative to the rendering viewport
        (e.g. width=50%). If the converted SVG sizes are relative units, then this
        computes the appropriate scale transform to size the SVG to the correct
        dimensions for a page in the current PDF document.

        Args:
            scale (Number): the scale factor from document units to PDF points.
            width (Number): the width of the viewport to scale to in document units.
            height (Number): the height of the viewport to scale to in document units.
            align_viewbox (bool): if True, mimic some of the SVG alignment rules if the
                viewbox aspect ratio does not match that of the viewport.
            ignore_svg_top_attrs (bool): ignore <svg> top attributes like "width", "height"
                or "preserveAspectRatio" when figuring the image dimensions.
                Require width & height to be provided as parameters.

        Returns:
            A tuple of (width, height, `fpdf.drawing.GraphicsContext`), where width and
            height are the resolved width and height (they may be 0. If 0, the returned
            `fpdf.drawing.GraphicsContext` will be empty). The
            `fpdf.drawing.GraphicsContext` contains all of the paths that were
            converted from the SVG, scaled to the given viewport size.
        z?SVG "width" is a percentage, hence a viewport width is requiredd   zASVG "height" is a percentage, hence a viewport height is requiredr   r   r  rZ  )r1   r9   rb   rT  r`   rV  r   r  r  r  r   r  r  r  r#  r   )r  r  rT  rV  r%  r,  vp_width	vp_heightr   r  r  rG   rE   w_ratioh_ratios                  r5   r'  z$SVGObject.transform_to_rect_viewport  sr   H   	+%)) ( << <<
G,, 	+  U   zE)C/HHz*UH 	.&'** *!&MM		!&MM		W-- 	.  W   f,s2II-vIA::!*,,II!)!e)44I< 	!\NBBaR1WW!_....mG"nG' :D,< :'WBTBT$'$9$99' '2#"5556#g999:   %	(=lb1f%77!mrAv&88) ) ) 	
 %.!%U!2DOCCr7   r5  r6  debug_streamc                    |j         | _         |                     |          \  }}}|j        |j        }}	 |C|A|                    dd           |j        J |j        t          j        ||          z  |_        |                    ||           |                    ||           dS # |                    ||           w xY w)a  
        Directly draw the converted SVG to the given PDF's current page.

        The page viewport is used for sizing the SVG.

        Args:
            pdf (fpdf.fpdf.FPDF): the document to which the converted SVG is rendered.
            x (Number): abscissa of the converted SVG's top-left corner.
            y (Number): ordinate of the converted SVG's top-left corner.
            debug_stream (io.TextIO): *DEPRECATED* the stream to which rendering debug info will be
                written.
        Nr   )	r  r+  r5  r6  set_xyr   r   r  	draw_path)	r  r$  r5  r6  r3  _rP  old_xold_ys	            r5   draw_to_pagezSVGObject.draw_to_pageZ  s    & ?44S99
1duceu		%}

1a   ~111!%)2G12M2M!MMM$--- JJue$$$$$CJJue$$$$s   AB( (C defsc                    |D ]}|j         t          dd          v r|                     |           0|j         t          dd          v r0t                              d           |                     |           w|j         t          dd          v r|                     |           |j         t          dd          v r|                     |           |j         t          v r|                     |           |j         t          dd          v r| 	                    |           #|j         t          dd          v r| 
                    |           Q|j         t          dd	          v r>	 |j        d
         }n# t          $ r d}Y nw xY w|D ]}|                     ||           |j         t          dd          v rt                              dt          |j                              dS )z:Produce lookups for groups and paths inside the <defs> tagr+   r  r  SIgnoring unsupported SVG tag: <a> (contributions are welcome to add support for it)rP  imagelinearGradientradialGradientclipPathr  Nr   TIgnoring unsupported SVG tag: <%s> (contributions are welcome to add support for it))r   rx   r"  r-  r.  
build_pathbuild_image
shape_tagsbuild_shaper  r  r   rd   build_clipping_pathr}   )r  r;  childclip_idchild_s        r5   handle_defszSVGObject.handle_defs~  s2     "	 "	EyL4444  ''''l5#6666 i     ''''l5&9999&&&&l5'::::  ''''j((  ''''l52BCCCC++E2222l52BCCCC++E2222l5*====##l40GG # # #"GGG## > >F,,VW====>l5'::::juy))   ?"	 "	s   ,E::F	F	xrefc                    |                      |          }t                      }t          |||           t          ddd          D ]!}	 |j        |         } n## t
          $ r Y w xY wt          d| d          	 |                    | j        |                    n$# t
          $ r t          d| d|           dw xY wd|j        v s	d	|j        v rkt          |j        
                    dd
                    t          |j        
                    d	d
                    }}t          j        ||          |_        |S )z?Resolve a cross-reference to an already-seen SVG element by ID.r,   hrefr  zuse z% doesn't contain known xref attributez references nonexistent ref id Nr5  r6  r   r  )r  r   r   rx   r   rd   r`   add_itemr  rb   r   r   r  r   )r  rL  r   	pdf_group	candidaterefr5  r6  s           r5   
build_xrefzSVGObject.build_xref  s    ''--	#%%	Yi000%gvt<< 	Q 	QIk),    ODOOOPPP	t4S9:::: 	 	 	AtAACAA 	
 $+!3!3 a00115a9P9P3Q3QqA"+"7!q"A"A"AI s   	A
A%$A%< B !B>r,  rP  inherited_stylec                     |                      |          }t          |pi           }|                    |           |t                      }t	          |||           d |D             D ]}|                     |           |D ][}|j        t          dd          v r|                     |           0|j        t          dd          v rH|j        t          dd          v r,|                    | 	                    |d|          d           |j        t          dd          v rFt                              d	           |                    | 	                    |d|          d           |j        t          dd
          v r+|                    |                     |          d           *|j        t          v r+|                    |                     |          d           c|j        t          dd          v r+|                    |                     |          d           |j        t          dd          v r+|                    |                     |          d           |j        t          dd          v r0|                     ||          }|r|                    |d           .t                              dt%          |j                             ]|                     |j                            d          |           |S )z+Handle nested items within a group <g> tag.Nc                 @    g | ]}|j         t          d d          v |S )r+   r;  )r   rx   )r   rH  s     r5   r   z)SVGObject.build_group.<locals>.<listcomp>  s5     
 
 
	\%5P5P(P(PE(P(P(Pr7   r+   r;  r   r  Fr  r=  rP  user>  textrB  r  )r  rC  r  r   r   rK  r   rx   rO  r"  r-  r.  rC  rE  rF  rS  rD  
build_textr}   r  r   r   )r  r,  rP  rT  local_stylemerged_stylerH  	text_paths           r5   r"  zSVGObject.build_group  s'    ))%00O1r22K((('))IY|444
 
$
 
 
 	$ 	$E U#### 	 	EyL7777  ''''l5'::::l5#6666""4#3#3E4#N#NPUVVVVl5#6666 i   ""4#3#3E4#N#NPUVVVVl5&9999""4??5#9#95AAAAj((""4#3#3E#:#:EBBBBl5%8888""4??5#9#95AAAAl5'::::""4#3#3E#:#:EBBBBl5&9999 OOE<@@	 9&&y%888juy))   
 	))$//;;;r7   rP  c                 ~   |                      |          }t                      }t          |||           |                     |||           |                     |||           |j                            d          }|t          ||           |                     |j                            d          |           |S )z1Convert an SVG <path> tag into a PDF path object.r  Nr  )	r  r   r   r  apply_clipping_pathr   r   rr  r  )r  rP  r   r  r  s        r5   rC  zSVGObject.build_path  s     ''--	==XtY///""8T9===  4;;;;??3''x222..999r7   shapec                    |                      |          }t          t          t          |j                           } ||          }t          |t                    sJ t          |||           |                     |||           | 	                    |||           | 
                    |j                            d          |           |S )zConvert an SVG shape tag into a PDF path object. Necessary to make xref (because ShapeBuilder doesn't have access to this object.)r  )r  getattrrM  rE  r   r1   r   r   r  r^  r  r   r   )r  r_  r   shape_builder
shape_paths        r5   rF  zSVGObject.build_shape  s     ''..	j.CDD"]5))
*k22222Z	222"":ui@@@  UI>>>))$//<<<r7   rI  c                 n   |j         t          v rX|                     |          }t          t          t          |j                            } ||d          }t          |||           n|j         t          dd          v rr|                     |          }t                      }t          |||           t          j	        |_
        |j                            d          }|t          ||           n/t                              dt!          |j                              d S |                     ||           d S )NTr+   rP  r  zaIgnoring unsupported <clipPath> child tag: <%s> (contributions are welcome to add support for it))r   rE  r  ra  rM  r   rx   r   r   
DONT_PAINT
paint_ruler   r   rr  r-  r.  r}   r  )r  r_  rI  r   rb  clipping_path_shaper  s          r5   rG  zSVGObject.build_clipping_path  s*   9
""++E22I#L*UY2GHHM"/-t"<"<,eY????Y,uf5555++E22I"---,eY???-:-E*|'',,H#"#6AAANNs59%%   F"566666r7   c                     d }|rd|v r|d         }||j                             d          }|r3t          j        d|          }|J | j        |d                  |_        d S d S )Nz	clip-pathzurl\((\#\w+)\)r   )r   r   r   r  r  rN  )r  r   r   r   
clip_valueclipping_path_ids         r5   r^  zSVGObject.apply_clipping_path3  s     
 	0	11";/J$+//<<J 	P!y):JGG#///%)%:;KA;N%OH"""	P 	Pr7   r>  SVGImagec           
         d }t          dd          D ]}||j        v r|j        |         } n|st          d          t          |j                            dd                    }t          |j                            dd                    }d|j        v rt
                              d           d	|j        v rt
                              d
           d|j        v rt
                              d           t          |t          |j                            dd                    t          |j                            dd                    |||           }|                     |j                            d          |           |S )Nr,   rN  z#<image> is missing a href attributerT  r   rV  r  zu"preserveAspectRatio" defined on <image> is currently not supported (contributions are welcome to add support for it)r   zg"style" defined on <image> is currently not supported (contributions are welcome to add support for it)r   zk"transform" defined on <image> is currently not supported (contributions are welcome to add support for it)r5  rS  r6  rN  r5  r6  rT  rV  svg_objr  )	rx   r   r`   rb   r   r-  r.  rk  r  )r  r>  rN  r   rT  rV  	svg_images          r5   rD  zSVGObject.build_imageD  s   00 	 	Cel""|C( #  	DBCCCel&&w2233u|''!4455 EL00NN H   el""NNy   %,&&NN}   EL$$S#..//EL$$S#..//
 
 
	 	))$//;;;r7   text_tagc                 d  "#$%&'( |                      |          }t          |pi           }|                    |           t                      }t	          |||           |                     |||           t          ||          }t          ||          \  $#}}$d$||nt          d          %t          ||%          \  }	}
}}|	|z   }|
|z   }g (d&d'dt          d         dt          t          t          t          f                  d	t          t                   fd
"	 	 	 	 	 	 d!dt          dt          t                   dt          t                   dt          t                   dt          dt          dt          dt          t                   dt          t                   dt          d         dt          t          t          t          f                  d	df"#$%&'(fd} ||j        pd$#||dd           |D ]O}|j        t%          dd          v r4|                      |          }t          |          }|                    |           t          ||          \  }}}}||n%}t          |||          \  }}}}t          ||          }d                    |                                          }|j        pd}|r.|                    |          r|dt/          |                    }n|}d} d}!d|j        v s|d|v r|} d|j        v s|d|v r|}! ||||||||| |!||            ||j        pd$#||dd           OQ(r5|                    t5          ||t7          (          |          d           |                     |j                            d           |           |S )"a  
        Convert <text> (and simple <tspan>) into a PaintedPath with Text runs.
        - Uses Text baseline at (x,y)
        - Honors x/y and dx/dy on <text> and direct child <tspan>
        - Flattens nested tspans; advanced per-character positioning is not implemented
        N
sans-serif16px)r&  r   r   r'   style_map_for_tagr.   c                     | |d S t                      t          | |           t          j        j        _        t          fdt          j        D                       }|sd S t          j                  S )Nc              3   Z   K   | ]%}t          j        |          t          j        uV  &d S r0   )ra  r   r   r   )r   propcontexts     r5   r|  z?SVGObject.build_text.<locals>._style_for_run.<locals>.<genexpr>  sK         t,,M4II     r7   )	r   r   r   r   r   r   anyMERGE_PROPERTIESr   )r   rt  	overridesrx  s      @r5   _style_for_runz,SVGObject.build_text.<locals>._style_for_run  s     {/7t%''G#'8999'4'<GM$    ):    I  tGM***r7   raw_textr!  r"  sizer   dx_extrady_extraabs_xabs_y	style_tagc                 >   | pd}t          ||          }|r|}n|                                }|rE|}|d d                                         rd|z   }|dd                                          r|dz   }n?|d d                                         s|dd                                          rrd}nd}|s|z  |z  d S ||n}|ppd}||npd}|z   }|z   }dd |	|
          }                    t	          |||||||||	  	                   d S )	Nrr   )r   r   r   rU  rr  r   )	rX  r!  r"  r~  r7  r8  r  r  	run_style)r   r3   isspacer  r   )r}  r!  r"  r~  r   r  r  r  r  r  rt  raw	collapsedcontenttrimmedrun_size
run_familyrun_emphasisrun_dxrun_dyr  r|  	base_emphbase_familydefault_font_size
pending_dx
pending_dy	text_runss                        r5   _add_runz&SVGObject.build_text.<locals>._add_run  s    .bC$S8<<<I %##//++ 
%%G2A2w(( 0"%-233x'')) 0")C-BQB)) %SX-=-=-?-? %Y %"%"$ h&
h&
#/tt5FH>;>,J(0(<HH)RPRL(*F(*FJJ&y2CDDI %)!'
 
 
    r7   rr   )r   r  rt  r+   tspanr5  r6  )r   r  r  r  r  r  rt  )r5  r6  r  text_anchorF)cloner  )r   r   NNNN)r  rC  r  r   r   r^  r   r%  rg   r9  r	   r2   r   r   rb   r   rX  r   rx   r  r  tailr[  r  r   add_path_elementr   r  r  r   ))r  rp  rT  rZ  effective_stylerP  preserve_parent	base_sizebase_anchorbase_xbase_ybase_dxbase_dyanchor_xanchor_yr  rH  child_local_stylechild_effective_stylefamemphr~  _anchorrun_font_sizer5  r6  r7  r8  child_preserveraw_itertext	tail_textrun_textr  r  r|  r  r  r  r  r  r  s)                                     @@@@@@@r5   rY  zSVGObject.build_textg  s    ))(334"55{+++}}T8[111  xAAA&AA9Jo:
 :
6Y	; &K".IIN64J4J 	 ,;o1B,
 ,
 ,
( G#G##%	

	+)$	+9A$sCx.9Q	+m$	+ 	+ 	+ 	+, "!%)%)-1:>9	 9	9	SM9	 sm9	 5/	9	
 9	 9	 9	 E?9	 E?9	  	*9	  (S#X79	 9	 9	 9	 9	 9	 9	 9	 9	 9	 9	 9	 9	x 	MR$"	
 	
 	
 	
  9	 9	EyL8888$($7$7$>$>!(,_(=(=%%,,->???+<0, ,(T4 )-(8>O.0M     1b" "..CU!K!K!wwu~~'7'788!J,"	 ,!6!6y!A!A ,+,=s9~~o,=>HH+H%,&&%1c=N6N6NE%,&&%1c=N6N6NE+#&7    J$","&*      		!!#I.. +	    "    	,,T22D999r7   r0   )r  r'   r.   N)rS  )r  r'   r.   N)T)TF)NNN)r;  r'   r.   NNN)r>  r'   r.   rk  )0r:   r;   r<   r=   rw  r2   r   r   r  bytesr	   r"   r  r!   r  r  rC  r  rv  rb   r  listr  r   r   r  r  r  r  r   r  r  r  r   r   r+  r9   r'  r:  rK  rS  r"  rC  rF  rG  r^  rD  rY  r>   r7   r5   r  r  ?  s         
  	8 8 8%8 8 	8
 8 
8 8 8 [8. JN( (e(2::2F(	( ( ( (* 4x} 4# 4$ 4 4 4 4
2 2 2 2) S#X    >  C #     \ * A#A	eE9z112	3A A A \ AF  (3-    \  AW AW AW AWF KW KW KW KWZ 
 /3	G GG G DcN+	G
 
G G G G* %, %, %, %,N 	% 	% 	% 	% 26W WW*.W	ue_,	-W W W W: #%*`D `D`D w`D 	`D
 `D #`D 
ue_,	-`D `D `D `DJ "!'+ %  % % E? % E?	 %
 tn % 
 %  %  %  %H $ $ $ $P y _    >  0448	7 77 O,7 "$sCx.1	7
 
7 7 7 7r y [     
 
{ 
 
 
 
 7 7Xc] 7t 7 7 7 7, 
 /3	P PP P DcN+	P
 
P P P P         D OSA A!A4<T#s(^4LA	+	A A A A A Ar7   r  c                       e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   dd deee	f         d	d fd
Z
edddeddded	eedef         f
d            Zed	efd            Zded	eeef         fdZdS )rk  rN  r5  r6  rT  rV  rn  r  _memor.   c                 h    t          | j        | j        | j        | j        | j        | j                  S )Nrm  )rk  rN  r5  r6  rT  rV  rn  )r  r  s     r5   __deepcopy__zSVGImage.__deepcopy__4  s7    ff*;L
 
 
 	
r7   resource_registryr*   r   	last_itemr(   initial_pointc                 v   | j         o| j         j        }|st          d          ddlm}  ||| j                  \  }}}t          |t                    rt          	                    d           d||fS |
                    | j        | j                  \  }	}
t          || j        | j        |	|
d          }|||fS )NzHfpdf2 bug - Cannot render a raster image without a SVGObject.image_cacher   )preload_imagez{Inserting .svg vector graphics in <image> tags is currently not supported (contributions are welcome to add support for it)rr   T)infor5  r6  whkeep_aspect_ratio)rn  r  AssertionErrorimage_parsingr  rN  r1   r#   r-  r.  size_in_document_unitsrT  rV  r$   r5  r6  )r  r  r   r  r  r  r  r7  r  r  r  stream_contents               r5   renderzSVGImage.render@  s     l?t|'? 	 Z   	100000"];	::
1ddO,, 	0NN N   y-//**4:t{CC18ff"
 
 
 y-77r7   c                 6    t          | j        | j                  S r0   )r   r5  r6  )r  s    r5   	end_pointzSVGImage.end_pointc  s    TVTV$$$r7   r  c           	      2   | j         }| j        }| j         | j        z   }| j        | j        z   }t	          j        t          ||          t          ||          t          ||          t          ||          g          }|t          | j         | j                  fS r0   )r5  r6  rT  rV  r   from_pointsr   )r  r  x0y0rh  ri  bboxs          r5   bounding_boxzSVGImage.bounding_boxh  s    VVVdj Vdk!&b"b"b"b"	
 
 U4646****r7   N)r:   r;   r<   r2   __annotations__rb   r  rC  r  r   r  r!   r   r   r  r  propertyr  r   r  r>   r7   r5   rk  rk  ,  s1        
IIIHHHHHHLLLMMM	
: 	
d38n 	
 	
 	
 	
 	
  8, 8  8  	 8
  8 
sL%'	( 8  8  8  8D %5 % % % X%+% +E+u2D,E + + + + + +r7   rk  )rS   )rW   r0   ru  r  )or=   loggingr  r   warningscopyr   osr   typingr   r   r   r   r	   fontTools.svgLib.pathr
   enumsr   r   r   r   defusedxml.ElementTreer   r  ImportErrorwarnxml.etree.ElementTreerr   r   drawingr   r   r   r   r   r   r   r   r   drawing_primitivesr   r   r   r   r   r    r!   image_datastructuresr"   r#   outputr$   patternr%   r&   r'   r(   fpdfr)   r*   	getLoggerr:   r-  rs   compiler   r  DOTALLr@  rA  r2   r6   rb   r9   r^   re   rc   taurj   rg   rl   rt   rC  rx   r}   rE  r   r   r   r   r   r   r   r  r   r   r   r   r  r  r  r%  r9  r  rK  rM  r   rr  r  rk  r>   r7   r5   <module>r     s
       				              E E E E E E E E E E E E E E      V U U U U U U U U U U UBBBBBBBB B B BHMc   BAAAAAAAB      
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  > = = = = = = = 3 3 3 3 3 3 A A A A A A A A (------######'''''' 
	8	$	$ (+  
 rz8992:m   L")44rz566 (3-     / / / / /e / / / 
PQQ   * 




		 	  8c>HsNH	  V Vs V# V V V V V( Q QS Q Q Q Q Q Q"  C C      S T#s(^     c c     \	68Y
I 

 Ds Dy:5 D D D D 3 8E?           	 	 	8SE5L3I 	 	 	 	 2E2E #SE3J/    <M<M
) 
)C=
)%-seSj%9
)
) 
) 
) 
)"  UT 
  
  
 ONRR 
 o;  ; d38n ; ; ;|  04$7 $7O+$7$7 T#s(^,$7 
	$7 $7 $7 $7N)DcN ) )t ) ) ) )	" 	"HSM 	"T 	"c 	" 	" 	" 	"HSM  PS    * FJ6 6	66*24S>*B6c]6 6 6 6" ;?Q Q	Q'S#X7Q
8C=#x34Q Q Q QH +/!%D D	DS#X'D D 5%%&	D D D DN U3S#X;N5O0P    8        D `c `i ` ` ` `F ? ? ? ? ? ? ?j j j j j j j jZJ+ J+ J+ J+ J+z J+ J+ J+ J+ J+s   A A&%A&