o
    ¢�Zÿ�  ã                   @   sÄ  d Z ddlZddl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 ddlmZ ddlmZmZ ddlmZmZmZmZ dd	lmZmZmZ dd
lT ddlmZmZ ddlmZmZm Z m!Z!m"Z" ddl#m$Z$m%Z% ddl&m'Z' ej(Z(ej)Z)ej*Z*d +¡ Z,d +¡ Z-d +¡ Z.ej/fdd„Z0ej/fdd„Z1ddej/fdd„Z2dd„ Z3d*dd„Z4G dd„ de5ƒZ6e%ddddde$d d!d d d iZ7G d"d#„ d#ƒZ8G d$d%„ d%eƒZ9d+d'd(„Z:e;d)kràe:ƒ  dS dS ),a  An experimental SVG renderer for the ReportLab graphics framework.

This will create SVG code from the ReportLab Graphics API (RLG).
To read existing SVG code and convert it into ReportLab graphics
objects download the svglib module here:

  http://python.net/~gherman/#svglib
é    N)Úgetitem)ÚstringWidth©Úfp_str)Úblack)ÚasNativeÚ
getBytesIO)ÚStateTrackerÚgetStateDeltaÚRendererÚrenderScaledDrawing)ÚSTATE_DEFAULTSÚPathÚUserNode)Ú*)Ú	rl_configÚascii)ÚgetStringIOÚRLStringÚisPy3Ú	isUnicodeÚisBytes)ÚFILL_EVEN_ODDÚFILL_NON_ZERO)ÚgetDOMImplementationzWstroke-width stroke-linecap stroke stroke-opacity fill fill-opacity stroke-dasharray idzEstroke-width stroke-linecap stroke stroke-opacity stroke-dasharray idz<font-family font-weight font-style font-variant font-size idc                 K   s$   t ƒ }t| |fd|i|¤Ž | ¡ S )z>Returns a SVG as a string in memory, without touching the diskÚshowBoundary)r   Ú
drawToFileÚgetvalue)Údr   ÚkwdsÚs© r!   úN/var/www/html/env/lib/python3.10/site-packages/reportlab/graphics/renderSVG.pyÚdrawToString%   s   r#   c                 K   s@   t | ƒ} t| j| jffi |¤Ž}t| |dd|d� | |¡ d S )Nr   ©r   )r   Ú	SVGCanvasÚwidthÚheightÚdrawÚsave)r   Úfnr   r   Úcr!   r!   r"   r   +   s   r   c                 C   s"   t ƒ }|jt| ƒ||||d� dS )zAs it says.r$   N)Ú_SVGRendererr(   r   )ÚdrawingÚcanvasÚxÚyr   Úrr!   r!   r"   r(   1   s   r(   c                 C   s8   g }t dt| ƒdƒD ]}| | | | |d  f¡ q
|S )zo
    given a list of coordinates [x0, y0, x1, y1....]
    produce a list of points [(x0,y0), (y1,y0),....]
    r   é   é   )ÚrangeÚlenÚappend)ÚLÚPÚir!   r!   r"   Ú_pointsFromList7   s   r:   c           	      K   sT   |   |¡}| ¡ D ]\}}t|ƒ}|s| ||¡ q	| |¡}| ||p%|¡ q	|S )aŸ  Transform a DOM node into new node and copy selected attributes.

    Creates a new DOM node with tag name 'newTag' for document 'doc'
    and copies selected attributes from an existing 'node' as provided
    in 'attrDict'. The source 'node' can be None. Attribute values will
    be converted to strings.

    E.g.

        n = transformNode(doc, "node1", x="0", y="1")
        -> DOM node for <node1 x="0" y="1"/>

        n = transformNode(doc, "node1", x=0, y=1+1)
        -> DOM node for <node1 x="0" y="2"/>

        n = transformNode(doc, "node1", node0, x="x0", y="x0", zoo=bar())
        -> DOM node for <node1 x="[node0.x0]" y="[node0.y0]" zoo="[bar()]"/>
    )ÚcreateElementÚitemsÚstrÚsetAttributeÚgetAttribute)	ÚdocÚnewTagÚnodeÚattrDictÚnewNodeÚnewAttrÚattrÚsattrÚattrValr!   r!   r"   ÚtransformNodeC   s   

rI   c                   @   sH   e Zd ZdZejejejejej	ej
dœZddd„Zdd„ Zdd	„ Zd
S )ÚEncodedWriterz�
    EncodedWriter(encoding) assumes .write will be called with
    either unicode or utf8 encoded bytes. it will accumulate
    unicode
    )zutf-32z	utf-32-bez	utf-32-lezutf-16z	utf-16-bez	utf-16-leFc                 C   sH   t  | ¡ t |¡j | _}|rd|v sd|v r"|  | j| ¡ d S d S )NÚ16Ú32)ÚlistÚ__init__ÚcodecsÚlookupÚnameÚencodingÚwriteÚBOMS)ÚselfrR   Úbomr!   r!   r"   rN   p   s
   
ÿzEncodedWriter.__init__c                 C   sn   t |ƒr$z| d¡}W n$   t ¡ \}}}t|ƒ}~~td||f ƒ‚t|ƒs0tdt|ƒ ƒ‚|  |¡ d S )Núutf-8z)String %r not encoded as 'utf-8'
error=%sz?EncodedWriter.write(%s) argument should be 'utf-8' bytes or str)	r   ÚdecodeÚsysÚexc_infor=   Ú
ValueErrorr   r   r6   )rU   ÚuÚetÚevÚtbr!   r!   r"   rS   v   s   zEncodedWriter.writec                 C   s   d  | ¡}| d d …= |S )NÚ )Újoin)rU   r1   r!   r!   r"   r   ƒ   s   

zEncodedWriter.getvalueN)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rO   Ú	BOM_UTF32ÚBOM_UTF32_BEÚBOM_UTF32_LEÚ	BOM_UTF16ÚBOM_UTF16_BEÚBOM_UTF16_LErT   rN   rS   r   r!   r!   r!   r"   rJ   b   s    ú
rJ   Únonzeroznon-zeroÚevenoddzeven-oddc                   @   s�  e Zd Zd_dd„Zd`dd	„Zdad
d„Zg dfdd„Zdd„ Zdd„ Zdde	dfdd„Z
dd„ Zdd„ Zg dfdd„Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zdbd(d)„Zdbd*d+„Zdcd,d-„Zddd/d0„Zdcd1d2„Zd3d4„ Zded6d7„Zd8d9„ Zd`d:d;„Zd`d<d=„Zdfd>d?„ZdgdAdB„ZdcdCdD„Z dadEdF„Z!dGdH„ Z"dIdJ„ Z#dKdL„ Z$dMdN„ Z%dOdP„ Z&dQdR„ Z'dSdT„ Z(dUdV„ Z)dWdX„ Z*dYdZ„ Z+d[d\„ Z,d]d^„ Z-dS )hr%   ©é,  ro   rW   r   Fc                    sì  |ˆ _ t |¡jˆ _|ˆ _| dd¡}| di ¡ˆ _| dd¡ˆ _| dd¡}t	ˆ _
| \ˆ _ˆ _ˆ _g ˆ _i ˆ _dˆ _d ˆ _ ˆ _ ˆ _ ˆ _ ˆ _ ˆ _ˆ _| dd¡r[tˆ _nd	d
„ ˆ _‡ fdd
„ˆ _tdƒ}| ddd¡}	| dd|	¡ˆ _ˆ jjˆ _t t!|d ƒt!ˆ jƒddˆ jˆ jf ddd�}
t"ˆ j
 |
d< d|
d< |
 #| di ¡¡ |
 $¡ D ]\}}ˆ j %||¡ q®ˆ j &d¡}ˆ j 'd¡}| (|¡ ˆ j (|¡ ˆ j &d¡}ˆ j 'd¡}| (|¡ ˆ j (|¡ ˆ  )t*d t*d ¡ ˆ  +t*d ¡ ˆ  ,d ¡ ˆ  -d¡ ˆ  .d!¡ |�s1t/ˆ jd"d#d$�}t/ˆ jd%ddˆ jˆ jd&�}| (|¡ ˆ j (|¡ t d'd(�}nt dˆ jˆ jf d)�}t/ˆ jd*fd+d,ˆ j d-œ|¤Žˆ _0|�rit/ˆ jd*|d.d-�ˆ _1ˆ j1 (ˆ j0¡ ˆ j (ˆ j1¡ nˆ j (ˆ j0¡ ˆ j0ˆ _2dS )/aØ  
        verbose = 0 >0 means do verbose stuff
        useClip = False True means don't use a clipPath definition put the global clip into the clip property
                        to get around an issue with safari
        extraXmlDecl = ''   use to add extra xml declarations
        scaleGroupId = ''   id of an extra group to add around the drawing to allow easy scaling
        svgAttrs = {}       dictionary of attributes to be applied to the svg tag itself
        ÚuseClipFÚ	fontHacksÚextraXmlDeclr`   ÚscaleGroupIdNÚ
use_fp_strc                  W   s   d  t| ƒdg ¡|  S )Nú z%f)ra   r5   ©Úargsr!   r!   r"   Ú<lambda>°   ó    z$SVGCanvas.__init__.<locals>.<lambda>c                     s   ˆ j | Ž  dd¡S )Nru   ú,)r   Úreplacerv   ©rU   r!   r"   rx   ±   s    ÚminidomÚsvgz-//W3C//DTD SVG 1.0//ENz8http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtdr   zxMinYMin meetz	0 0 %d %dzhttp://www.w3.org/2000/svgz1.0)r&   r'   ÚpreserveAspectRatioÚviewBoxÚxmlnsÚversionú	fill-rulezhttp://www.w3.org/1999/xlinkzxmlns:xlinkÚsvgAttrsÚtitlez...ÚdescÚfontNameÚfontSizeÚstrokeColorr2   r3   ÚclipPathÚclip)ÚidÚrect)r/   r0   r&   r'   zclip-path: url(#clip)©Ústyle)r‹   ÚgÚgroupzscale(1,-1) translate(0,-%d))rŒ   Ú	transformz
scale(1,1))3ÚverboserO   rP   rQ   rR   rV   Úpoprq   rr   r   Ú	_fillModer&   r'   ÚsizeÚcoder�   ÚpathÚ_strokeColorÚ
_fillColorÚ
_lineWidthÚ_fontÚ	_fontSizeÚ_lineCapÚ	_lineJoinr   Úcfp_strr   ÚcreateDocumentTypeÚcreateDocumentr@   ÚdocumentElementr~   Údictr=   Ú_fillRuleMapÚupdater<   r>   r;   ÚcreateTextNodeÚappendChildÚsetFontr   ÚsetStrokeColorÚ
setLineCapÚsetLineJoinÚsetLineWidthrI   Ú	groupTreeÚ	scaleTreeÚ	currGroup)rU   r–   rR   r“   rV   r   rp   rs   ÚimplementationÚdoctyper„   ÚkÚvr…   Útextr†   rŠ   ÚclipRectÚgtkwr!   r|   r"   rN   “   sœ   	þÿÿ
þ

÷




ÿ

þýzSVGCanvas.__init__Nc                 C   sª   t | j| jd�}| jj|dd| jd� t|dƒr|}ntr&t|d| jd�}nt|dƒ}| ¡ }| j	}|r<| 
dd| ¡}| trB|n| | j¡¡ ||urS| ¡  d S d S )	N)rV   ú	Ú
)Ú	addindentÚnewlrR   rS   Úw)rR   z?>)rJ   rR   rV   r@   ÚwritexmlÚhasattrr   Úopenr   rr   r{   rS   ÚencodeÚclose)rU   r*   ÚwriterÚfr~   Úexdr!   r!   r"   r)   ÿ   s   

ÿzSVGCanvas.savec                 C   s    |p| j }|p	| j}t|||ƒS )zuReturn the logical width of the string if it were drawn
        in the current font (defaults to self.font).
        )rœ   r�   r   )rU   r    Úfontrˆ   r!   r!   r"   ÚNOTUSED_stringWidth  s   

zSVGCanvas.NOTUSED_stringWidthr`   c                    sx   | j  ¡ ‰ˆ |¡ tˆ ¡ ƒ}ˆr‡fdd„|D ƒ}ˆ r,ˆ  ¡ ‰ ‡ ‡fdd„|D ƒ}n	‡fdd„|D ƒ}d |¡d S )Nc                    s   g | ]}|ˆ v r|‘qS r!   r!   ©Ú.0r³   )Úincluder!   r"   Ú
<listcomp>#  ry   z*SVGCanvas._formatStyle.<locals>.<listcomp>c                    s(   g | ]}|ˆ vr|d  t ˆ| ƒ ‘qS ©z: ©r=   rÇ   )Úexcluder�   r!   r"   rÊ   &  s   ( c                    s    g | ]}|d  t ˆ | ƒ ‘qS rË   rÌ   rÇ   rŽ   r!   r"   rÊ   (  s     z; ú;)r�   Úcopyr¦   rM   ÚkeysÚsplitra   )rU   rÉ   rÍ   r   rÐ   r<   r!   )rÍ   rÉ   r�   r"   Ú_formatStyle  s   

zSVGCanvas._formatStylec                 C   s   |S )zKI don't think this was ever needed; seems to have been copied from renderPSr!   )rU   r    r!   r!   r"   Ú_escape+  ó   zSVGCanvas._escapec                 C   s   dS )zXCalculate the path for an arc inscribed in rectangle defined
        by (x1,y1),(x2,y2).N)Úabs)rU   Úx1Úy1Úx2Úy2ÚstartAngÚextentÚxScaleÚyScaler/   r0   ÚcodelineÚarcÚdatar!   r!   r"   Ú_genArcCode/  s   zSVGCanvas._genArcCodec                 C   sT   i }|r
t |ƒ|d< t| jd| j|  |¡d�}|r|  ||¡}| j |¡ d| _d S )Nrƒ   r˜   ©r   r�   r`   )Ú_fillRuleNamerI   r@   r˜   rÒ   Ú	_add_linkr°   r¨   )rU   r—   r‹   Ú	link_infoÚstylesÚfillModeÚxtrar˜   r!   r!   r"   Ú_fillAndStrokeE  s   ÿ
zSVGCanvas._fillAndStrokec                 C   ó2   ddddœ}| j |kr|| _ || | jd< d S d S )NÚbuttÚroundÚsquare©r   r3   r2   ústroke-linecap)rž   r�   ©rU   r´   Úvalsr!   r!   r"   r«   S  ó
   
þzSVGCanvas.setLineCapc                 C   rê   )NÚmiterrì   Úbevelrî   rï   )rŸ   r�   rð   r!   r!   r"   r¬   Y  rò   zSVGCanvas.setLineJoinc                 C   s~   t |ttfƒrd tt||gƒ¡| jd< dS t |ttfƒr;t	|ƒdkr=|dks+J dƒ‚d tt||g ƒ¡| jd< dS dS dS )z7Two notations. Pass two numbers, or an array and phase.ú, zstroke-dasharrayr   zphase is a length in user spaceN)
Ú
isinstanceÚfloatÚintra   Úmapr=   r�   ÚtuplerM   r5   )rU   ÚarrayÚphaser!   r!   r"   ÚsetDash_  s    þzSVGCanvas.setDashc                 C   óŒ   || _ |d krd| jd< d S |j|j|j}}}d|d |d |d f | jd< |j}|dkr9d| | jd< d S d| jv rD| jd= d S d S )NÚnoneÚstrokeúrgb(%d%%,%d%%,%d%%)éd   r3   ú%szstroke-opacity)r™   r�   ÚredÚgreenÚblueÚnormalizedAlpha©rU   Úcolorr1   r�   ÚbÚalphar!   r!   r"   rª   h  ó    
ÿzSVGCanvas.setStrokeColorc                 C   rþ   )Nrÿ   Úfillr  r  r3   r  zfill-opacity)rš   r�   r  r  r  r  r  r!   r!   r"   ÚsetFillColoru  r  zSVGCanvas.setFillColorc                 C   s   || _ t| | jd< d S )Nrƒ   )r•   r¥   r�   )rU   r´   r!   r!   r"   ÚsetFillMode‚  s   zSVGCanvas.setFillModec                 C   s"   || j kr|| _ || jd< d S d S )Nzstroke-width)r›   r�   )rU   r&   r!   r!   r"   r­   †  s   
þzSVGCanvas.setLineWidthc                 C   sÆ   | j |ks
| j|kra|| _ || _| j}tD ]	}||v r||= q|| jv r)| j| ni }t|tƒr:| t|j	 
¡ ƒ¡ |rQ| 
¡ D ]\}}d| }|tv rP|||< q@d|vrY||d< d| |d< d S d S )Nzfont-zfont-familyz%spxz	font-size)rœ   r�   r�   ÚTEXT_STYLESrq   rö   r   r¦   Úiterr„   r<   )rU   rÅ   rˆ   r�   r³   r„   r´   Úar!   r!   r"   r©   ‹  s*   €
€ïzSVGCanvas.setFontc                 C   s0   t |tƒsJ ‚t| jdfi |¤Ž}| |¡ |S )Nr  )rö   r¤   rI   r@   r¨   )rU   Ú
dom_objectrå   Úlinkr!   r!   r"   rä   Ÿ  s   
zSVGCanvas._add_linké   c              	   K   s€   | j rtdƒ t||ƒ}	t||ƒ}
i }t| jdf|	|
t||ƒ|	 t||ƒ|
 |  t¡dœ|¤Ž}|r8|  ||¡}| j	 
|¡ dS )z)Draw a rectangle between x1,y1 and x2,y2.z+++ SVGCanvas.rectr�   )r/   r0   r&   r'   r�   N)r“   ÚprintÚminrI   r@   ÚmaxrÒ   ÚAREA_STYLESrä   r°   r¨   )rU   rÖ   r×   rØ   rÙ   ÚrxÚryrå   Ú	_svgAttrsr/   r0   r   r�   r!   r!   r"   r�   ¦  s   


þþzSVGCanvas.rectc           
      K   sR   t | jdf|||| || |||  t¡dœ|¤Ž}	|r!|  |	|¡}	| j |	¡ dS )z·Draw a rounded rectangle between x1,y1 and x2,y2.

        Corners inset as ellipses with x-radius rx and y-radius ry.
        These should have x1<x2, y1<y2, rx>0, and ry>0.
        r�   )r/   r0   r&   r'   r  r  r�   N©rI   r@   rÒ   r  rä   r°   r¨   )
rU   rÖ   r×   rØ   rÙ   r  r  rå   r  r�   r!   r!   r"   Ú	roundRect·  s   
þþzSVGCanvas.roundRectc           
      K   sÄ   t |ƒ}| jrtdƒ | jd kr`|  |¡}|  t¡}|dkr)|d|  |||¡  }|d| jd   }t	| j
df|||dd|  d	œ|¤Ž}| j
 |¡}	| |	¡ |rX|  ||¡}| j |¡ d S d S )
Nz+++ SVGCanvas.drawStringr   z rotate(%s);z
 fill: %s;r  rµ   ztranslate(0,%d) scale(1,-1)r2   )r/   r0   r�   r’   )r   r“   r  rš   rÓ   rÒ   r  r   r�   rI   r@   r§   r¨   rä   r°   )
rU   r    r/   r0   Úanglerå   r  Ústrµ   Úcontentr!   r!   r"   Ú
drawStringÇ  s(   




þý
ïzSVGCanvas.drawStringÚmiddlec                 C   s¢   | j rtdƒ | jd krE|dvrEt|| j| jƒ}|dkr!||8 }n$|dkr,||d 8 }n|dkr=|t|||| j| jƒ8 }ntdt|ƒ ƒ‚| j	||t
||d� d S )	Nz+++ SVGCanvas.drawCentredString©ÚstartÚ	inheritedÚendr#  ç       @Únumericúbad value for text_anchor )r  rå   )r“   r  rš   r   rœ   r�   ÚnumericXShiftr[   r=   r"  rµ   )rU   r    r/   r0   r  Útext_anchorrå   ÚtextLenr!   r!   r"   ÚdrawCentredStringÞ  s   

zSVGCanvas.drawCentredStringc                 C   s   | j ||||d|d� d S )Nr'  )r  r,  rå   )r.  )rU   rµ   r/   r0   r  rå   r!   r!   r"   ÚdrawRightStringî  s   zSVGCanvas.drawRightStringc                 C   s   | j  |¡}dS )zAdd a comment.N)r@   ÚcreateComment)rU   rà   Úcommentr!   r!   r"   r1  ñ  s   zSVGCanvas.commentTc                 C   sL   t ƒ }| |d¡ tt | ¡ ¡ƒ}| j t| j	d||||d| d�¡ d S )NÚpngÚimagezdata:image/png;base64,)r/   r0   r&   r'   Úhref)
r   r)   r   Úbase64Ú	b64encoder   r°   r¨   rI   r@   )rU   r3  r/   r0   r&   r'   ÚembedÚbufr!   r!   r"   Ú	drawImage÷  s   þÿzSVGCanvas.drawImagec              	   C   sP   | j d kr&	 t| jdd|  ||¡|  ||¡f |  t¡d�}| j |¡ d S d S )Nr   Úline)r/   r0   rØ   rÙ   r�   r˜   zM %s L %s Zrâ   )r™   rI   r@   rÒ   ÚLINE_STYLESr°   r¨   r    )rU   rÖ   r×   rØ   rÙ   r:  r˜   r!   r!   r"   r:    s   
þ÷zSVGCanvas.linec              
   C   s^   t | jd|| d || d || d || d |  t¡d�}|r'|  ||¡}| j |¡ dS )z{Draw an orthogonal ellipse inscribed within the rectangle x1,y1,x2,y2.

        These should have x1<x2 and y1<y2.
        Úellipser(  )ÚcxÚcyr  r  r�   Nr  )rU   rÖ   r×   rØ   rÙ   rå   r<  r!   r!   r"   r<    s   (þzSVGCanvas.ellipsec              	   C   s<   t | jd||||  t¡d�}|r|  ||¡}| j |¡ d S )NÚcircle)r=  r>  r1   r�   r  )rU   ÚxcÚycr1   rå   r?  r!   r!   r"   r?    s   þzSVGCanvas.circlec
                 C   s   	 d S ©N)r   rš   r—   r6   r™   )rU   rÖ   r×   rØ   rÙ   Úx3Úy3Úx4Úy4ÚclosedrÞ   rà   r!   r!   r"   Ú	drawCurve&  s   zSVGCanvas.drawCurveéh  c              
   C   sf  || d || d }}	|| d || d }
}|
t |t d ƒ | }|t|t d ƒ |	 }|
t || t d ƒ | }|t|| t d ƒ |	 }| j}g j}|rd|d|||	ƒ|||ƒf ƒ |rz|d||
|ƒd|dkd|||ƒf ƒ n|d|||ƒ||
|ƒd|dkd|||ƒf ƒ |rœ|d|||	ƒ ƒ t| jdd	 |j¡|  	¡ d
�}| j
 |¡ dS )a  Draw a partial ellipse inscribed within the rectangle x1,y1,x2,y2.

        Starting at startAng degrees and covering extent degrees. Angles
        start with 0 to the right (+x) and increase counter-clockwise.
        These should have x1<x2 and y1<y2.
        r(  é´   z	M %s L %szA %s %d %d %d %sr   zM %s A %s %d %d %d %s ZzL %s Zr˜   ru   râ   N)ÚcosÚpiÚsinr    r6   rI   r@   ra   Ú__self__rÒ   r°   r¨   )rU   rÖ   r×   rØ   rÙ   rÚ   rÛ   Ú
fromcenterr=  r>  r  r  ÚmxÚmyÚaxÚayr    r    r˜   r!   r!   r"   ÚdrawArc3  s.   ÿ$ÿÿzSVGCanvas.drawArcc                 C   sx   t |ƒdks
J dƒ‚| jd ks| jd kr:d dd„ |D ƒ¡}t| jd||  t¡d�}|r2|  ||¡}| j	 
|¡ d S d S )Nr2   z"Polygon must have 2 or more pointsrõ   c                 S   ó   g | ]}t |Ž ‘qS r!   r   ©rÈ   Úpr!   r!   r"   rÊ   Y  ó    z%SVGCanvas.polygon.<locals>.<listcomp>Úpolygon©Úpointsr�   )r5   r™   rš   ra   rI   r@   rÒ   r  rä   r°   r¨   )rU   r[  rG  rå   ÚptsÚpolyliner!   r!   r"   rY  U  s   
ÿøzSVGCanvas.polygonc                 C   ó   d S rB  )r™   r—   r6   r   )rU   ÚlineListr	  r&   rÞ   r:  r!   r!   r"   Úlinesd  rÔ   zSVGCanvas.linesc                 C   sb   t |ƒdks
J dƒ‚| jd kr/d dd„ |D ƒ¡}t| jd|| jtd d�d�}| j |¡ d S d S )	Nr3   z#Polyline must have 1 or more pointsrõ   c                 S   rU  r!   r   rV  r!   r!   r"   rÊ   q  rX  z&SVGCanvas.polyLine.<locals>.<listcomp>r]  )r  rZ  )	r5   r™   ra   rI   r@   rÒ   r  r°   r¨   )rU   r[  r\  r]  r!   r!   r"   ÚpolyLinem  s   
ÿüzSVGCanvas.polyLinec                 C   sH   | j rtdƒ | jt| jddd�}}| |¡ || _| j r"tdƒ |S )Nz+++ begin SVGCanvas.startGroupr�   r`   )r’   z+++ end SVGCanvas.startGroup)r“   r  r°   rI   r@   r¨   )rU   r°   r‘   r!   r!   r"   Ú
startGroupw  s   
zSVGCanvas.startGroupc                 C   s*   | j rtdƒ || _| j rtdƒ d S d S )Nz+++ begin SVGCanvas.endGroupz+++ end SVGCanvas.endGroup)r“   r  r°   )rU   r°   r!   r!   r"   ÚendGroup  s   zSVGCanvas.endGroupc           	   	   C   sp   | j rtd||||||ƒ | j d¡}||||||fdkr6d|  ||||||¡ }| j dd||f ¡ d S d S )Nz!!! begin SVGCanvas.transformr’   )r3   r   r   r3   r   r   z
matrix(%s)z%s %s)r“   r  r°   r?   r    r>   )	rU   r  r
  r+   r   ÚerÃ   ÚtrÚtr!   r!   r"   r’   „  s   þzSVGCanvas.transformc                 C   ó   t dƒ d S )Nz!!! begin SVGCanvas.translate)r  r°   r?   r    r>   ©rU   r/   r0   re  rf  r!   r!   r"   Ú	translate‹  ó   zSVGCanvas.translatec                 C   rg  )Nz!!! begin SVGCanvas.scale)r  Úgroupsr?   r    r°   r>   rh  r!   r!   r"   Úscale”  rj  zSVGCanvas.scalec                 C   ó   | j d|  ||¡  | _ d S )NzM %s ©r˜   r   ©rU   r/   r0   r!   r!   r"   ÚmoveTož  ó   zSVGCanvas.moveToc                 C   rm  )NzL %s rn  ro  r!   r!   r"   ÚlineTo¡  rq  zSVGCanvas.lineToc              
   C   s$   | j d|  ||||||¡  | _ d S )NzC %s rn  )rU   rÖ   r×   rØ   rÙ   rC  rD  r!   r!   r"   ÚcurveTo¤  ó   $zSVGCanvas.curveToc                 C   s   | j d | _ d S )NzZ )r˜   r|   r!   r!   r"   Ú	closePath§  s   zSVGCanvas.closePathc                 C   r^  rB  r!   r|   r!   r!   r"   Ú	saveStateª  ó   zSVGCanvas.saveStatec                 C   r^  rB  r!   r|   r!   r!   r"   ÚrestoreState­  rw  zSVGCanvas.restoreState)rn   rW   r   FrB  )NN)r  r  N)r   N)r   r#  N)T)r   )r   rI  r   ).rb   rc   rd   rN   r)   rÆ   rÒ   rÓ   rá   r  ré   r«   r¬   rý   rª   r  r  r­   r©   rä   r�   r  r"  r.  r/  r1  r9  r:  r<  r?  rH  rT  rY  r`  ra  rb  rc  r’   ri  rl  rp  rr  rs  ru  rv  rx  r!   r!   r!   r"   r%   ’   sV    

l

	











"
	
	
r%   c                   @   sž   e Zd ZdZdd„ Zdd„ Zdddd	d
dddœZdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd)d#d$„Zd%d&„ Zd'd(„ Zd"S )*r,   z%This draws onto an SVG document.
    c                 C   s
   d| _ d S )Nr   )r“   r|   r!   r!   r"   rN   ´  s   
z_SVGRenderer.__init__c                 C   sè   | j r	td| ƒ | j d| ¡ | jj ¡ }t|tƒr|js 	 t	|ƒ}| j
 |¡ |  |i ¡ |  |¡ | j
 ¡ }t|tƒrB|jsC	 | j d| ¡ | ¡ D ]\}}|| jv rbt| j| j| |ƒ qO|| j_| j rrtd| ƒ dS dS )zGThis is the recursive method called for each node in the tree.
        z#### begin _SVGRenderer.drawNode(%r)zbegin node %rzend node %rz!### end _SVGRenderer.drawNode(%r)N)r“   r  Ú_canvasr1  r�   rÏ   rö   r   Ú
isClipPathr
   Ú_trackerÚpushÚapplyStateChangesÚdrawNodeDispatcherr”   r<   Ú	_restoresÚsetattr)rU   rB   r�   ÚdeltasÚrDeltasr³   r´   r!   r!   r"   ÚdrawNode·  s&   


€z_SVGRenderer.drawNoder™   r›   rž   rŸ   rš   rœ   r�   )r‰   ÚstrokeWidthÚstrokeLineCapÚstrokeLineJoinÚ	fillColorr‡   rˆ   c                 C   s4   t |ddƒpd}t |ddƒpd}|r||ddœS d S )NÚhrefURLr`   Ú	hrefTitleÚ_top)z
xlink:hrefzxlink:titleÚtarget)Úgetattr)rU   ÚobjÚurlr…   r!   r!   r"   Ú_get_link_info_dictÛ  s
   z _SVGRenderer._get_link_info_dictc                 C   sš   | j rtdƒ | j ¡ }| j ¡ d \}}}}}}| ¡ D ]}	t|	tƒr)|	 	¡ }
n|	}
|  
|
¡ q| j ||||||¡ | j |¡ | j rKtdƒ d S d S )Nz ### begin _SVGRenderer.drawGroupr’   z### end _SVGRenderer.drawGroup)r“   r  ry  rb  r{  ÚgetStateÚgetContentsrö   r   ÚprovideNoderƒ  r’   rc  )rU   r‘   r°   r  r
  r+   r   rd  rÃ   Ú	childNodeÚnode2r!   r!   r"   Ú	drawGroupú  s   


z_SVGRenderer.drawGroupc                 C   s¦   |   |¡}t|di ƒ}|j|j  krdkr4n n| jj|j|j|j|j |j|j	 fd|i|¤Ž d S | jj
|j|j|j|j |j|j	 |j|jfd|i|¤Ž d S )Nr  r   rå   )r�  rŒ  r  r  ry  r�   r/   r0   r&   r'   r  )rU   r�   rå   r„   r!   r!   r"   ÚdrawRect
  s(   
þþ
þýü
üz_SVGRenderer.drawRectc           
      C   sÞ   | j jrm| j ¡ }|d |j|j|jf\}}}}|dvrV|d |d }}t|||ƒ}	|dkr4||	8 }n"|dkr?||	d 8 }n|dkrN|t|||	||ƒ8 }nt	d	t
|ƒ ƒ‚| j j|||fd
|  |¡it|di ƒ¤Ž d S d S )NÚ
textAnchorr$  r‡   rˆ   r'  r#  r2   r)  r*  rå   r  )ry  rš   r{  r�  r/   r0   rµ   r   r+  r[   r=   r"  r�  rŒ  )
rU   Ú	stringObjÚSr,  r/   r0   rµ   rÅ   rˆ   r-  r!   r!   r"   r"    s   

.òz_SVGRenderer.drawStringc                 C   s*   | j jr| j  |j|j|j|j¡ d S d S rB  )ry  r™   r:  rÖ   r×   rØ   rÙ   )rU   r:  r!   r!   r"   ÚdrawLine,  s   ÿz_SVGRenderer.drawLinec                 C   s$   | j j|j|j|j|  |¡d� d S ©N)rå   )ry  r?  r=  r>  r1   r�  )rU   r?  r!   r!   r"   Ú
drawCircle0  rt  z_SVGRenderer.drawCirclec              	   C   sÚ   |  ¡ \}}}|dks|d u rV|dks|d u rV|jsV|j|j|j|j|jf\}}}}}	|jp0|j}|| || }
}|| || }}|	| }| jj	|
|||||dd� d S | 
¡ }t|tƒrf|  |¡ d S |  |¡ d S )Nr   r3   )rO  )Ú
_xtraRadiiÚannularÚcenterxÚcenteryÚradiusÚstartangledegreesÚendangledegreesÚyradiusry  rT  Ú	asPolygonrö   r   ÚdrawPathÚdrawPolygon)rU   Úwedger¤  Úradius1Úyradius1rŸ  r   r¡  r¢  r£  rÖ   r×   rØ   rÙ   rÛ   r8   r!   r!   r"   Ú	drawWedge3  s   &ÿ
z_SVGRenderer.drawWedgec                 C   s"   | j jr| j  t|jƒ¡ d S d S rB  )ry  r™   ra  r:   r[  ©rU   rW  r!   r!   r"   ÚdrawPolyLineD  s   ÿz_SVGRenderer.drawPolyLinec                 C   sP   |j |j }|j |j }|j|j }|j|j }| jj|||||  |¡d� d S r›  )r=  r  r>  r  ry  r<  r�  )rU   r<  rÖ   rØ   r×   rÙ   r!   r!   r"   ÚdrawEllipseH  s
    z_SVGRenderer.drawEllipsec                 C   s"   | j jt|jƒd|  |¡d� d S )Nr3   )rG  rå   )ry  rY  r:   r[  r�  r¬  r!   r!   r"   r§  P  s   "z_SVGRenderer.drawPolygonNc           	   	      s  ddl m‰  | j}|j|j|j|jf‰|d u rtˆdd ƒ}|  ˆ¡}tˆddƒ}‡ ‡‡fdd„}|dkrC|ƒ  |j	g ˆj
||d	� d S |d
krX|dd� |j	g ˆj
||d	� d S |ƒ }|s€|j}| d ¡ zd }|j	g ˆj
||d	� W | |¡ d S | |¡ w |j	g ˆj
||d	� d S )Nr   )Ú_renderPathrç   Ú	autocloser`   c                     s   ˆ ˆˆfi | ¤ŽS rB  r!   )r   ©r¯  Ú	drawFuncsr˜   r!   r"   ÚrP\  s   z!_SVGRenderer.drawPath.<locals>.rPr~   )r‹   rå   rç   ÚpdfT)Ú
forceClose)Úreportlab.graphics.shapesr¯  ry  rp  rr  rs  ru  rŒ  r�  ré   rz  rš   r  )	rU   r˜   rç   r+   rå   r°  r³  ÚisClosedÚofcr!   r±  r"   r¦  S  s.   


z_SVGRenderer.drawPathc                 C   s–   |j }t|tƒr|rtj  |¡sd S tƒ  |¡}n
t|dƒr!|}nd S |j\}}|j	|j
}}|d u r5|}|d u r;|}| jj||j|j||dd� d S )NÚconvertT)r7  )r˜   rö   r=   ÚosÚisfileÚ	_getImager¿   r¾   r–   r&   r'   ry  r9  r/   r0   )rU   r3  r˜   ÚimÚsrcWÚsrcHÚdstWÚdstHr!   r!   r"   r9  q  s   


 z_SVGRenderer.drawImagec                 C   sD  |  ¡ D ]›\}}|dkrq|dkr| j |¡ q|dkr#| j |¡ q|dkr.| j |¡ q|dkr9| j |¡ q|dkrn|rht|ttfƒr^t	|ƒdkr^t|d ttfƒr^|d	 }|d }nd	}| j 
||¡ q| j 
¡  q|d
kry| j |¡ q|dv r•| d| jj¡}| d| jj¡}| j ||¡ q|dkrŸ| j |¡ qdS )z\This takes a set of states, and outputs the operators
        needed to set those propertiesr’   r‰   r„  r…  r†  ÚstrokeDashArrayr2   r3   r   r‡  )rˆ   r‡   r‡   rˆ   rç   N)r<   ry  rª   r­   r«   r¬   rö   rM   rú   r5   rý   r  Úgetrœ   r�   r©   r  )rU   ÚdeltaÚnewStateÚkeyÚvaluerü   ÚfontnameÚfontsizer!   r!   r"   r}  €  s:   ,
€ãz_SVGRenderer.applyStateChangesrB  )rb   rc   rd   re   rN   rƒ  r  r�  r•  r–  r"  rš  rœ  r«  r­  r®  r§  r¦  r9  r}  r!   r!   r!   r"   r,   °  s*     þ
r,   úout-svgc                 C   s  t j | ¡st  | ¡ ddlm} g }t|ƒD ]!}|dd… dkr8td| d ƒ}td| d ƒ}| ||f¡ qd}|D ]\}}t j 	| d| ¡}t
||ƒ |d	7 }q=dd
lm}	 |	ƒ }t
|t j 	| d¡ƒ ddlm}
 ddlm} |
ƒ }||j|jƒ}| |¡ t
|t j 	| d¡ƒ d S )Nr   )Ú
testshapesé
   Ú
getDrawingztestshapes.z()z.__doc__zrenderSVG_%d.svgr3   )ÚgetDrawing01ztest.svg)ÚRL_CorpLogo)ÚDrawingzcorplogo.svg)rº  r˜   ÚisdirÚmkdirÚreportlab.graphicsrË  ÚdirÚevalr6   ra   r   Úreportlab.graphics.testshapesrÎ  Úreportlab.lib.corprÏ  r¶  rÐ  r&   r'   Úadd)ÚoutDirrË  ÚdrawingsÚfuncnamer-   Ú	docstringr9   r   ÚfilenamerÎ  rÏ  rÐ  Úrlr!   r!   r"   Útest£  s0   
€


rß  Ú__main__rB  )rÊ  )<re   ÚmathÚtypesrY   rº  rO   r5  Úoperatorr   Úreportlab.pdfbase.pdfmetricsr   Úreportlab.lib.rl_accelr   Úreportlab.lib.colorsr   Úreportlab.lib.utilsr   r   Úreportlab.graphics.renderbaser	   r
   r   r   r¶  r   r   r   Ú	reportlabr   r   r   r   r   r   r   Úreportlab.pdfgen.canvasr   r   Úxml.domr   rM  rK  rL  rÑ   r  r;  r  r   r#   r   r(   r:   rI   rM   rJ   r¥   r%   r,   rß  rb   r!   r!   r!   r"   Ú<module>   sX    0	
'ú
    " 
t$
ÿ