
    Kwg6                        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mZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZmZ ddlmZmZmZ dd	l dd
lmZ ddlmZmZmZ ddlmZmZ ddlm Z  ddl!m"Z" ejF                  Z#ejH                  Z$ejJ                  Z%djM                         Z'djM                         Z(djM                         Z)djM                         Z*djM                         Z+ejX                  fdZ-ejX                  fdZ.ddejX                  fdZ/d Z0d'dZ1 G d de2      Z3edddddedddddiZ4d  Z5 G d! d"      Z6 G d# d$e      Z7d(d%Z8e9d&k(  r e8        yy))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)BytesIOStringIO)stringWidth)fp_str)asNative)getStateDeltaRendererrenderScaledDrawing)STATE_DEFAULTSPathUserNode)*)	rl_config)RLString	isUnicodeisBytes)FILL_EVEN_ODDFILL_NON_ZERO   )	_getImage)getDOMImplementationzsstroke-width stroke-linecap stroke stroke-opacity fill fill-opacity stroke-dasharray stroke-dashoffset fill-rule idzWstroke-width stroke-linecap stroke stroke-opacity stroke-dasharray stroke-dashoffset idz<font-family font-weight font-style font-variant font-size idzTstroke-width stroke-linecap stroke stroke-opacity stroke-dasharray stroke-dashoffsetzfill fill-opacityc                 T    t               }t        | |fd|i| |j                         S )z>Returns a SVG as a string in memory, without touching the diskshowBoundary)r   
drawToFilegetvalue)dr   kwdsss       S/var/www/horilla/myenv/lib/python3.12/site-packages/reportlab/graphics/renderSVG.pydrawToStringr    '   s)    
Aq!6,66::<    c                     t        |       } t        | j                  | j                  ffi |}t	        | |dd|       |j                  |       y )Nr   r   )r
   	SVGCanvaswidthheightdrawsave)r   fnr   r   cs        r   r   r   -   sC    AA177AHH%--AAq!,/FF2Jr!   c                 V    t               }|j                  t        |       ||||       y)zAs it says.r#   N)_SVGRendererr'   r
   )drawingcanvasxyr   rs         r   r'   r'   3   s%    AFFw'ALFQr!   c                 x    g }t        dt        |       d      D ]  }|j                  | |   | |dz      f         |S )zo
    given a list of coordinates [x0, y0, x1, y1....]
    produce a list of points [(x0,y0), (y1,y0),....]
    r      r   )rangelenappend)LPis      r   _pointsFromListr:   9   sH     	A1SVQ !	!A$!A# ! Hr!   c                     | j                  |      }|j                         D ]L  \  }}t        |      }|s|j                  ||       &|j	                  |      }|j                  ||xs |       N |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attrVals	            r   transformNoderJ   E   sv    ( 'G!) <T  %0''.G  '*:U;< Nr!   c                       e Zd ZdZej
                  ej                  ej                  ej                  ej                  ej                  dZddZd Zd Zy)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-lec                     t         j                  |        t        j                  |      j                  x| _        }|rd|v sd|v r| j                  | j                  |          y y )N1632)list__init__codecslookupnameencodingwriteBOMS)selfrU   boms      r   rQ   zEncodedWriter.__init__r   sT    d#)==#:#?#??48#tx'7JJtyy*+ (8r!   c                    t        |      r	 |j                  d      }n"t        |      st        dt        |      z        | j                  |       y #  t        j                         \  }}}t	        |      }~~t        d|d|      xY w)Nutf-8zString z not encoded as 'utf-8'
error=z?EncodedWriter.write(%s) argument should be 'utf-8' bytes or str)	r   decodesysexc_infor>   
ValueErrorr   asciir6   )rX   uetevtbs        r   rV   zEncodedWriter.writex   s    1:XXXg& 1^afghaiijjAX \\^
BW QRSU!VWWs   A 8Bc                 2    dj                  |       }| d d = |S )N join)rX   r1   s     r   r   zEncodedWriter.getvalue   s    GGDMGr!   N)F)__name__
__module____qualname____doc__rR   	BOM_UTF32BOM_UTF32_BEBOM_UTF32_LE	BOM_UTF16BOM_UTF16_BEBOM_UTF16_LErW   rQ   rV   r    r!   r   rL   rL   d   sU     !!''''!!''''
D,r!   rL   nonzeroznon-zeroevenoddzeven-oddc                  2    dj                  d | D              S )N c              3   b   K   | ]'  }d |z  j                  d      j                  d       ) yw)z%f0.N)rstrip).0as     r   	<genexpr>zpy_fp_str.<locals>.<genexpr>   s*     FAdQh&&s+2237Fs   -/rg   )argss    r   	py_fp_strr      s    88FFGGr!   c                   V   e Zd Zd/dZd0dZd1dZg dfdZd Zd	 Zdde	dfd
Z
d Zd Zg dfdZd Zd Zd Zd Zd Zd Zd2dZd2dZd3dZ	 	 d4dZ	 	 d5dZd Zd6dZd Zd0dZd0dZd7dZd8dZd9d Z d1d!Z!d" Z" e#d#      fd$Z$d% Z%d& Z&d' Z'd( Z(d) Z)d* Z*d+ Z+d, Z,d- Z-d. Z.y):r$   r   c                 	    | _         t        j                  |      j                   _        | _        |j                  dd      }|j                  di        _        |j                  dd       _        |j                  dd      }t         _
        |x\   _         _         _        g  _        i  _        d _        dx _        x _        x _        x _        x _        x _         _        |j                  dd      rt0         _        nt2         _         fd	 _        t7        d
      }|j9                  ddd      }	|j;                  dd|	       _         j<                  j>                   _         tC        tE        |d         tE         j                        dd j                   j                  fz  dd      }
tF         j                     |
d<   d|
d<   |
jI                  |j                  di              |
jK                         D ]!  \  }} j@                  jM                  ||       #  j<                  jO                  d      } j<                  jQ                  d      }|jS                  |        j@                  jS                  |        j<                  jO                  d      } j<                  jQ                  d      }|jS                  |        j@                  jS                  |        jU                  tV        d   tV        d           jY                  tV        d           j[                  d        j]                  d        j_                  d       |sta         j<                  d d!"      }ta         j<                  d#dd j                   j                  $      }|jS                  |        j@                  jS                  |       tC        d%&      }n%tC        d j                   j                  fz  '      }ta         j<                  d(fd)d* j                  z  d+| _1        |rita         j<                  d(|d,+       _2         jd                  jS                   jb                          j@                  jS                   jd                         n% j@                  jS                   jb                          jb                   _3        y)-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extraXmlDeclrf   scaleGroupIdN
use_fp_strc                  B     j                   |  j                  dd      S )Nrw   ,)r   replace)r   rX   s    r   <lambda>z$SVGCanvas.__init__.<locals>.<lambda>   s    [T[[$%7%?%?C%H r!   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strokeColorr3   r   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))4verboserR   rS   rT   rU   rY   popr   r   r   	_fillModer%   r&   sizecoder   path_strokeColor
_fillColor
_lineWidth_font	_fontSize_lineCap	_lineJoinr   r   cfp_strr   createDocumentTypecreateDocumentrA   documentElementr   dictr>   _fillRuleMapupdater=   r?   r<   createTextNodeappendChildsetFontr   setStrokeColor
setLineCapsetLineJoinsetLineWidthrJ   	groupTree	scaleTree	currGroup)rX   r   rU   r   rY   r   r   r   implementationdoctyper   kvr   textr   r   clipRectgtkws   `                  r   rQ   zSVGCanvas.__init__   s    h/44((9U++b1 HH^B7xxr2&.22
DK$)	
	 "	" 	"DO 	"do 	"J	"	"*.-N88L' DK#DKH-i8 !33E+LN "00eGD88++QLt{{+(7'4::t{{*CC 7!
 !-T^^ <"@B/0>># 	'CAaHH!!!A&	' &&w/xx&&u-$U#xx%%f-xx&&u-T"^J/
1KLN=9:!$TXXzfEH$TXXvajj6H  *HH  *56D[DJJt{{+CCDD&txx 4t{{B  *488S\UabDNNN&&t~~6HH  0HH  0r!   Nc                    t        | j                  | j                        }| j                  j	                  |dd| j                         t        |d      r|}nt        |d| j                        }|j                         }| j                  }|r|j                  dd|z         }|j                  |       ||ur|j                          y y )	N)rY   	
)	addindentnewlrU   rV   w)rU   z?>)rL   rU   rY   rA   writexmlhasattropenr   r   r   rV   close)rX   r)   writerfr   exds         r   r(   zSVGCanvas.save  s    t}}:&4T4==Q2gARdmm4Aoo++d48,C	B;GGI r!   c                 \    |xs | j                   }|xs | 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   )rX   r   fontr   s       r   NOTUSED_stringWidthzSVGCanvas.NOTUSED_stringWidth  s/    
 !tzz-t~~1dH--r!   rf   c                    | j                   j                         }|j                  |       t        |j	                               }|r|D cg c]	  }||v s| }}|r7|j                         }|D cg c]  }||vs|dz   t        ||         z    }}n!|D cg c]  }|dz   t        ||         z    }}dj                  |      dz   S c c}w c c}w c c}w )Nz: z; ;)r   copyr   rP   keyssplitr>   rh   )rX   includeexcluder   r   r   r   r=   s           r   _formatStylezSVGCanvas._formatStyle   s    

!TEJJL!#4!qG|A4D4mmoG37La1G;KQtVCaM)LEL378aQtVCaM)8E8yy#%% 5 M8s   	C	C	1	C;CCc                     |S )zKI don't think this was ever needed; seems to have been copied from renderPSrs   )rX   r   s     r   _escapezSVGCanvas._escape-  s    r!   c                      y)zXCalculate the path for an arc inscribed in rectangle defined
        by (x1,y1),(x2,y2).N)abs)rX   x1y1x2y2startAngextentxScaleyScaler/   r0   codelinearcdatas                 r   _genArcCodezSVGCanvas._genArcCode1  s     	r!   c                     i }|rt         |   |d<   t        | j                  d| j                  | j	                  |            }|r| j                  ||      }| j                  j                  |       d| _        y )Nr   r   r   r   rf   )r   rJ   rA   r   r   	_add_linkr   r   )rX   r   r   	link_infostylesfillModextrar   s           r   _fillAndStrokezSVGCanvas._fillAndStrokeG  sm     ,X 6DTXXviit008 >>$	2D""4(	r!   c                 b    dddd}| j                   |k7  r|| _         ||   | j                  d<   y y )Nbuttroundsquarer   r   r3   stroke-linecap)r   r   rX   r   valss      r   r   zSVGCanvas.setLineCapU  s9    Gx0==ADM+/7DJJ'( r!   c                 b    dddd}| j                   |k7  r|| _         ||   | j                  d<   y y )Nmiterr   bevelr   r   )r   r   r   s      r   r   zSVGCanvas.setLineJoin[  s9    W0>>QDN+/7DJJ'( r!   c                    t        |t        t        f      r/dj                  t	        t
        ||g            | j                  d<   yt        |t        t        f      rft        |      dkD  rW|dk\  sJ d       dj                  t	        t
        |            | j                  d<   |dkD  rt        |      | j                  d<   yyyy)z7Two notations. Pass two numbers, or an array and phase., zstroke-dasharrayr   zphase is a length in user spacezstroke-dashoffsetN)

isinstancefloatintrh   mapr>   r   tuplerP   r5   )rX   arrayphases      r   setDashzSVGCanvas.setDasha  s     eU3K(-1YYs3%7Q-RDJJ)*uTl+E
QA:@@@:-1YYs3-GDJJ)*Qw25e*

./  1?+r!   c                 @   || _         |d k(  rd| j                  d<   y |j                  |j                  |j                  }}}d|dz  |dz  |dz  fz  | j                  d<   |j
                  }|dk7  rd|z  | j                  d<   y d| j                  v r| j                  d= y y )Nnonestrokergb(%d%%,%d%%,%d%%)d   r   %szstroke-opacity)r   r   redgreenbluenormalizedAlpharX   colorr1   r   balphas         r   r   zSVGCanvas.setStrokeColorl  s    !D=#)DJJx iiejj!qA#8AcE1S5!C%;P#PDJJx ))Eax/3e|

+,!TZZ/JJ/0 0r!   c                 @   || _         |d k(  rd| j                  d<   y |j                  |j                  |j                  }}}d|dz  |dz  |dz  fz  | j                  d<   |j
                  }|dk7  rd|z  | j                  d<   y d| j                  v r| j                  d= y y )Nr  fillr  r  r   r  zfill-opacity)r   r   r  r  r  r  r  s         r   setFillColorzSVGCanvas.setFillColory  s    D=!'DJJviiejj!qA!6!C%3#9N!NDJJv))Eax-1E\

>*4::-JJ~. .r!   c                 >    || _         t        |   | j                  d<   y )Nr   )r   r   r   )rX   r   s     r   setFillModezSVGCanvas.setFillMode  s    ".q/

;r!   c                 P    || j                   k7  r|| _         || j                  d<   y y )Nzstroke-width)r   r   )rX   r%   s     r   r   zSVGCanvas.setLineWidth  s(    DOO##DO).DJJ~& $r!   c                    | j                   |k7  s| j                  |k7  r|| _         || _        | j                  }t        D ]
  }||v s||=  || j                  v r| j                  |   ni }t        |t              r2|j                  t        |j                  j                                      |r+|j                         D ]  \  }}d|z   }|t        v s|||<    d|vr||d<   d|z  |d<   y y )Nzfont-zfont-familyz%spxz	font-size)r   r   r   TEXT_STYLESr   r  r   r   iterr   r=   )rX   r   r   r   r   r   r   r}   s           r   r   zSVGCanvas.setFont  s    ::8!;DJ%DNJJE  !:a! 04t~~/Et~~d+2H$x(T]]%8%8%: ;<#>>+ %CAa	AK'#$a% E)'+m$!'(!2E+# "<r!   c                 z    t        |t              sJ t        | j                  dfi |}|j	                  |       |S )Nr}   )r  r   rJ   rA   r   )rX   
dom_objectr   links       r   r   zSVGCanvas._add_link  s:    )T***TXXs8i8$r!   c           
      X   | j                   rt        d       t        ||      }	t        ||      }
i }t        | j                  df|	|
t        ||      |	z
  t        ||      |
z
  | j                  t              d|}|r| j                  ||      }| j                  j                  |       y)z)Draw a rectangle between x1,y1 and x2,y2.z+++ SVGCanvas.rectr   )r/   r0   r%   r&   r   N)r   printminrJ   rA   maxr   AREA_STYLESr   r   r   )rX   r   r   r   r   rxryr   	_svgAttrsr/   r0   r   r   s                r   r   zSVGCanvas.rect  s     <<342J2JTXXv >1C2JqLRA##K0>3<> >>$	2D""4(r!   c                     t        | j                  df||||z
  ||z
  ||| j                  t              d|}	|r| j	                  |	|      }	| j
                  j                  |	       y)zDraw 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rJ   rA   r   r)  r   r   r   )
rX   r   r   r   r   r*  r+  r   r,  r   s
             r   	roundRectzSVGCanvas.roundRect  sm     TXXv ?BbeBrEbR##K0?4=? >>$	2D""4(r!   c           	         |dk(  ry t        |      }| j                  rt        d       |dk(  xs |dk(  xs |dk(  xs |dk(  }	|dk(  xs |dk(  xs |dk(  xs |dk(  }
| j                  d k7  r|	s| j                  d k7  r|
r|d	vr}t        || j                  | j                        }|d
k(  r||z  }nQ|dk(  r	||dz  z  }nC|dk(  r'|t        |||| j                  | j                        z  }nt        dt        |      z         | j                  |      }| j                  t              }|dk7  r|d| j                  |||      z  z   }|	r|| j                  t              z  }n|dz  }|
r|| j                  t               z  }n|dz  }t#        | j$                  df|||dd|z  z  d|}| j$                  j'                  |      }|j)                  |       |r| j+                  ||      }| j,                  j)                  |       y y y )N   z+++ SVGCanvas.drawStringr   r3         r      )start	inheritedleftendmiddle       @numericzbad value for text_anchor z rotate(%s);z fill:none;z stroke:none;r   ztranslate(0,%d) scale(1,-1))r/   r0   r   r   )r   r   r&  r   r   r   r   r   numericXShiftr_   r>   r   r   r   r   EXTRA_FILL_STYLESEXTRA_STROKE_STYLESrJ   rA   r   r   r   r   )rX   r   r/   r0   angler   text_anchortextRenderModer,  needFill
needStroketextLenstr   contents                  r   
drawStringzSVGCanvas.drawString  s(   1fQK<<9:!1$c(9c^Q=NcR`bcRc#Q&e.!*;e~q?PeTbdeTe
OOT!hD4E4Et4KPZ"@@%a

4>>B%LA (*OA )+{1WTZZWWA$%ACDT%TUUQA"";/Bz$++eQ*BBBrd''(9::m#d''(;<<o% !6 q71Q3? D
 hh--a0GW%~~dI6NN&&t,I Q[4Kr!   c                 f    | j                   rt        d        | j                  |||f||||d| y )Nz+++ SVGCanvas.drawCentredStringr?  r   r@  rA  r   r&  rG  )	rX   r   r/   r0   r?  r@  r   rA  r,  s	            r   drawCentredStringzSVGCanvas.drawCentredString  s;    <<@A!A 	<EYK-	<1:	<r!   c                 f    | j                   rt        d        | j                  |||f||||d| y )Nz+++ SVGCanvas.drawRightStringrI  rJ  )	rX   r   r/   r0   r?  r@  r   rA  r,  s	            r   drawRightStringzSVGCanvas.drawRightString  s;    <<>?Qq 	<u	{-	<1:	<r!   c                 :    | j                   j                  |      }y)zAdd a comment.N)rA   createComment)rX   r   comments      r   rP  zSVGCanvas.comment  s     ((((.r!   c                 @   t               }|j                  |d       t        t        j                  |j                                     }| j                  j                  t        | j                  d||||d|z   d| j                  ddddd|d|z  z         z  	             y )
Npngimagezdata:image/png;base64,
matrix(%s)r   r   r3   )r/   r0   r%   r&   hrefr   )r   r(   r   base64	b64encoder   r   r   rJ   rA   r   )rX   rS  r/   r0   r%   r&   embedbufs           r   	drawImagezSVGCanvas.drawImage
  s    i

3uv''78""dhhw!%v1#5*T\\!Aa1VAaCZ-PP	r!   c                    | j                   d k7  rp	 t        | j                  dd| j                  ||      d| j                  ||      d| j                  t                    }| j
                  j                  |       y y )Nr   M  L z Zr   )r   rJ   rA   r   LINE_STYLESr   r   r   )rX   r   r   r   r   liner   s          r   r`  zSVGCanvas.line  sl    $
 !6#'<<2#6t||Br7JK''46D NN&&t, %r!   c                     t        | j                  d||z   dz  ||z   dz  ||z
  dz  ||z
  dz  | j                  t                    }|r| j	                  ||      }| j
                  j                  |       y)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.  )rX   r   r   r   r   r   rb  s          r   rb  zSVGCanvas.ellipse"  st    
  )2s{2s{2s{2s{##K02 nnWi8G""7+r!   c           
          t        | j                  d|||| j                  t                    }|r| j	                  ||      }| j
                  j                  |       y )Ncircle)rc  rd  r1   r   r.  )rX   xcycr1   r   rf  s         r   rf  zSVGCanvas.circle0  sP    txxbA##K02 ^^FI6F""6*r!   c
                      	 y N)r   r   r   r6   r   )rX   r   r   r   r   x3y3x4y4closedr   r   s               r   	drawCurvezSVGCanvas.drawCurve:  s    r!   c                    ||z   dz  ||z   dz  }	}||z
  dz  ||z
  dz  }}
|
t        |t        z  dz        z  |z   }|t        |t        z  dz        z  |	z   }|
t        ||z   t        z  dz        z  |z   }|t        ||z   t        z  dz        z  |	z   }| j                  }g j                  }|r |d |||	      d |||             |r" |d ||
|      d|dk\  d |||      fz         n) |d |||       ||
|      d|dk\  d |||      fz         |r |d |||	      z         t        | j                  d	d
j                  |j                        | j                               }| j                  j                  |       y)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:     r]  r^  zA %s %d %d %d %sr   zM %s A %s %d %d %d %s ZzL %s Zr   rw   r   N)cospisinr   r6   rJ   rA   rh   __self__r   r   r   )rX   r   r   r   r   r   r   
fromcenterrc  rd  r*  r+  mxmyaxayr   r   r   s                      r   drawArczSVGCanvas.drawArcG  s    R%r"uckBR%r"uckB#hrk#o&&+#hrk#o&&+#x*3.//"4#x*3.//"4,,IIWR_gb"o>? r263;72r?CD E 'r2BFCKGBPROTU V hR()TXXvhhqzz"$*;*;*=?""4(r!   c                 v   t        |      dk\  sJ d       | j                  d k7  s| j                  d k7  rdj                  |D cg c]
  }t	        |  c}      }t        | j                  d|| j                  t                    }|r| j                  ||      }| j                  j                  |       y y c c}w )Nr3   z"Polygon must have 2 or more pointsr  polygonpointsr   )r5   r   r   rh   r   rJ   rA   r   r)  r   r   r   )rX   r  ro  r   pptspolylines          r   r~  zSVGCanvas.polygoni  s    6{aE!EEd"doot&;))8AVQZ89C$TXXy$"3"3K"@BH >>(I>NN&&x0 '<8s   B6c                      y rj  )r   r   r6   r   )rX   lineListr  r%   r   r`  s         r   lineszSVGCanvas.linesx  s    r!   c           	      4   t        |      dk\  sJ d       | j                  d k7  rodj                  |D cg c]
  }t        |  c}      }t	        | j
                  d|| j                  t        d             }| j                  j                  |       y y c c}w )Nr   z#Polyline must have 1 or more pointsr  r  )r  r  )
r5   r   rh   r   rJ   rA   r   r)  r   r   )rX   r  r  r  r  s        r   polyLinezSVGCanvas.polyLine  s    6{aF!FF$))8AVQZ89C$TXXz$"3"3KT"3"JLHNN&&x0	 %8s   B)r   c                     | j                   rt        d       | j                  }t        | j                  dfi |}|j                  |       || _        | j                   rt        d       |S )Nz+++ begin SVGCanvas.startGroupr   z+++ end SVGCanvas.startGroup)r   r&  r   rJ   rA   r   )rX   rD   r   r   s       r   
startGroupzSVGCanvas.startGroup  sY    <<?@NN	dhh8x8e$<<=>r!   c                 p    | j                   rt        d       || _        | j                   rt        d       y y )Nz+++ begin SVGCanvas.endGroupz+++ end SVGCanvas.endGroup)r   r&  r   )rX   r   s     r   endGroupzSVGCanvas.endGroup  s)    <<=>"<<;<<r!   c           	          | j                   rt        d||||||       | j                  j                  d      }||||||fdk7  r;d| j	                  ||||||      z  }| j                  j                  d|d|       y y )Nz!!! begin SVGCanvas.transformr   )r   r   r   r   r   r   rT  rw   )r   r&  r   r@   r   r?   )	rX   r}   r  r*   r   er   trts	            r   r   zSVGCanvas.transform  s    <<>1aAqQ^^((5q!Q1!33t||Aa!Aa88ANN''A5FG 4r!   c           
          ||fdk7  rN| j                   j                  d| j                   j                  d      dd| j                  ||      z         y y )N)r   r   r   rw   ztranslate(%s))r   r?   r@   r   rX   r/   r0   s      r   	translatezSVGCanvas.translate  sP    a5E>NN''>>..{;#dll1Q&7769 : r!   c           
          ||fdk7  rQ| j                   j                  d| j                  d   j                  d      dd| j	                  ||      z         y y )N)r   r   r   rU  rw   z	scale(%s))r   r?   groupsr@   r   )rX   sxsys      r   scalezSVGCanvas.scale  sU    r7eNN''{{233K@#dll2r&::6< = r!   c                 R    | j                   d| j                  ||      z  z   | _         y )NzM %s r   r   r  s      r   moveTozSVGCanvas.moveTo  "    II$++a*; ;;	r!   c                 R    | j                   d| j                  ||      z  z   | _         y )NzL %s r  r  s      r   lineTozSVGCanvas.lineTo  r  r!   c           
      Z    | j                   d| j                  ||||||      z  z   | _         y )NzC %s r  )rX   r   r   r   r   rk  rl  s          r   curveTozSVGCanvas.curveTo  s*    II$++b"b"b"*M MM	r!   c                 ,    | j                   dz   | _         y )NzZ )r   rX   s    r   	closePathzSVGCanvas.closePath  s    II$	r!   c                      y rj  rs   r  s    r   	saveStatezSVGCanvas.saveState      r!   c                      y rj  rs   r  s    r   restoreStatezSVGCanvas.restoreState  r  r!   )),  r  r[   r   Frj  )NN)   r  N)r   Nr7  r   )r   r9  Nr   )r   r8  Nr   )T)r   )r   ih  r   )r   N)/ri   rj   rk   rQ   r(   r   r   r   r   r)  r   r   r   r
  r   r  r  r   r   r   r   r/  rG  rK  rM  rP  r[  r`  rb  rf  rp  r|  r~  r  r  r   r  r  r   r  r  r  r  r  r  r  r  rs   r!   r   r$   r$      s   j(X$. $&r &, )*TVZ 
33 a 	=1/2/
3()") +-Z ?G+,< ?D+,</

-,+) )D1P1 "&!3 =
H:=<<N%r!   r$   c                       e Zd ZdZd Zd Zdddddd	d
dZd Zd Zd Z	d Z
d Zd Zd Zd Zd Zd ZefdZd Zd Zy)r,   z%This draws onto an SVG document.
    c                     d| _         y )Nr   )r   r  s    r   rQ   z_SVGRenderer.__init__  s	    r!   c                     | j                   rt        d|z         | j                  j                  d|z         | j                  j                  j                         }t        |t              r|j                  s	 t        |      }| j                  j                  |       | j                  |i        | j                  |       | j                  j                         }t        |t              r|j                  s	 | j                  j                  d|z         |j                         D ]8  \  }}|| j                   v st#        | j                  | j                   |   |       : || j                  _        | j                   rt        d|z         yy)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&  _canvasrP  r   r   r  r   
isClipPathr   _trackerpushapplyStateChangesdrawNodeDispatcherr   r=   	_restoressetattr)rX   rC   r   deltasrDeltasr   r   s          r   drawNodez_SVGRenderer.drawNode  s8    <<DtKL_T12""'')4&4?? t$6"vr* 	%--##%4&4??]4/0 MMO 	:DAqDNN"T^^A%6q9	: #<<BTIJ<r!   r   r   r   r   r   r   r   )r   strokeWidthstrokeLineCapstrokeLineJoin	fillColorr   r   c                 X    t        |dd      xs d}t        |dd      xs d}|r||ddS y )NhrefURLrf   	hrefTitle_top)z
xlink:hrefzxlink:titletarget)getattr)rX   objurlr   s       r   _get_link_info_dictz _SVGRenderer._get_link_info_dict  sA     c9b)/R["-3 "%EFKK$ r!   c                    | j                   rt        d       | j                  j                         }| j                  j                         d   \  }}}}}}|j                         D ]6  }	t        |	t              r|	j                         }
n|	}
| j                  |
       8 | j                  j                  ||||||       | j                  j                  |       | j                   rt        d       y y )Nz ### begin _SVGRenderer.drawGroupr   z### end _SVGRenderer.drawGroup)r   r&  r  r  r  getStategetContentsr  r   provideNoder  r   r  )rX   r   r   r}   r  r*   r   r  r   	childNodenode2s              r   	drawGroupz_SVGRenderer.drawGroup	  s    <<ABLL++-	==113K@1aAq**, 	!I)X.!--/!MM% 	! 	q!Q1a0i(<<?@<r!   c                 B   | j                  |      }t        |di       }|j                  |j                  cxk(  rdk(  rhn ne | j                  j
                  |j                  |j                  |j                  |j                  z   |j                  |j                  z   fd|i| y  | j                  j                  |j                  |j                  |j                  |j                  z   |j                  |j                  z   |j                  |j                  fd|i| y )Nr,  r   r   )r  r  r*  r+  r  r   r/   r0   r%   r&   r/  )rX   r   r   r   s       r   drawRectz_SVGRenderer.drawRect  s    ,,T2	4B/77dgg""DLLFFDFFFF4::%tvvdkk'9\EN\RZ\ #DLL""FFDFFFF4::%tvvdkk'9GGTWW5 (	5 ,4	5r!   c           
          | j                   j                         }|d   |j                  |j                  |j                  f\  }}}} | j
                  j                  |||f| j                  |      |t        |dd      dt        |di        y )N
textAnchorrA  r   )r   r@  rA  r,  )	r  r  r/   r0   r   r  rG  r  r  )rX   	stringObjSr@  r/   r0   r   s          r   rG  z_SVGRenderer.drawString*  s    MM""$"#L/9;;	Y^^"[Q4Qq 	943K3KI3V'	JZ[\8]	9iB7	9r!   c                     | j                   j                  rG| j                   j                  |j                  |j                  |j
                  |j                         y y rj  )r  r   r`  r   r   r   r   )rX   r`  s     r   drawLinez_SVGRenderer.drawLine1  s<    <<$$LLdggtwwA %r!   c                     | j                   j                  |j                  |j                  |j                  | j                  |             y N)r   )r  rf  rc  rd  r1   r  )rX   rf  s     r   
drawCirclez_SVGRenderer.drawCircle5  s5    VYY		688tG_G_`fGghr!   c           	         |j                         \  }}}|dk(  s||dk(  s||j                  s|j                  |j                  |j                  |j
                  |j                  f\  }}}}}	|j                  xs |j                  }||z
  ||z
  }}
||z   ||z   }}|	|z
  }| j                  j                  |
|||||d       y |j                         }t        |t              r| j                  |       y | j                  |       y )Nr   r   )rw  )
_xtraRadiiannularcenterxcenteryradiusstartangledegreesendangledegreesyradiusr  r|  	asPolygonr  r   drawPathdrawPolygon)rX   wedger  radius1yradius1r  r  r  r  r  r   r   r   r   r   r8   s                   r   	drawWedgez_SVGRenderer.drawWedge8  s    %*%5%5%7"(QJ'/!x?OY^YfYf]]EMM5<<9P9PRWRgRgg IGWf&7mm3u||GRR$'88FLL  RR1BFWX Y!A!D!a   #r!   c                     | j                   j                  r/| j                   j                  t        |j                               y y rj  )r  r   r  r:   r  rX   r  s     r   drawPolyLinez_SVGRenderer.drawPolyLineI  s/    <<$$LL!!/!((";< %r!   c           	      *   |j                   |j                  z
  }|j                   |j                  z   }|j                  |j                  z
  }|j                  |j                  z   }| j                  j                  ||||| j                  |             y r  )rc  r*  rd  r+  r  rb  r  )rX   rb  r   r   r   r   s         r   drawEllipsez_SVGRenderer.drawEllipseM  sr    ZZ'**$ZZ'**$ZZ'**$ZZ'**$R2bD4L4LW4UVr!   c                     | j                   j                  t        |j                        d| j	                  |             y )Nr   )ro  r   )r  r~  r:   r  r  r  s     r   r  z_SVGRenderer.drawPolygonU  s0    _QXX6qDLdLdefLghr!   c                   	
 ddl m	 | j                  }|j                  |j                  |j
                  |j                  f
|t        dt              }| j                        }t        dd      }	
fd}|dk(  r' |        |j                  g j                  ||       y |d	k(  r) |d
       |j                  g j                  ||       y  |       }|sQ|j                  }|j                  d        	 d }|j                  g j                  ||       |j                  |       y |j                  g j                  ||       y # |j                  |       w xY w)Nr   )_renderPathr   	autocloserf   c                       fi | S rj  rs   )r   r  	drawFuncsr   s    r   rPz!_SVGRenderer.drawPath.<locals>.rPa  s    tY7$77r!   r   )r   r   r   pdfT)
forceClose)reportlab.graphics.shapesr  r  r  r  r  r  r  r   r  r   r  r   r  )rX   r   r   r*   r   r  r  isClosedofcr  r  s    `       @@r   r  z_SVGRenderer.drawPathX  s6   9LLXXqxxAKK@	tJ}=H,,T2	DR0		8eDRdooU]^$RdooU]^tHllt$( $I$$Rdoo]e$fNN3'  $//YYa b NN3's   =!E E#c                    |j                   }t        |t              r<|rt        j                   j	                  |      sy t               j                  |      }nt        |d      r|}ny |j                  \  }}|j                  |j                  }}||}||}| j                  j                  ||j                  |j                  ||d       y )NconvertT)rY  )r   r  r>   osisfiler   r   r   r   r%   r&   r  r[  r/   r0   )rX   rS  r   imsrcWsrcHdstWdstHs           r   r[  z_SVGRenderer.drawImagev  s    zzd3RWW^^D1F!!$'BT)$BWW
d[[%,,d<<r577EGGT4tLr!   c                    |j                         D ]  \  }}|dk(  r|dk(  r| j                  j                  |       .|dk(  r| j                  j                  |       O|dk(  r| j                  j	                  |       p|dk(  r| j                  j                  |       |dk(  r|rgt        |t        t        f      r2t        |      dk(  r$t        |d   t        t        f      r|d	   }|d   }nd	}| j                  j                  ||       | j                  j                          |d
k(  r| j                  j                  |       =|dv rj|j                  d| j                  j                        }|j                  d| j                  j                        }| j                  j                  ||       |dk(  s| j                  j!                  |        y)z\This takes a set of states, and outputs the operators
        needed to set those propertiesr   r   r  r  r  strokeDashArrayr3   r   r   r  )r   r   r   r   r   N)r=   r  r   r   r   r   r  rP   r  r5   r
  r  getr   r   r   r  )rX   deltanewStatekeyvaluer	  fontnamefontsizes           r   r  z_SVGRenderer.applyStateChanges  s     ++- 	0JCk!%++E2%))%0'''.((((/))!%e5#e*a-JW\]^W_afgk`lLm %a %a !LL((u5LL((*#))%000 99Z1C1CD 99Z1G1GH$$Xx8
"((/;	0r!   N)ri   rj   rk   rl   rQ   r  r  r  r  r  rG  r  r  r  r  r  r  r   r  r[  r  rs   r!   r   r,   r,     s|    K@  .\Zd!,QX&(I>A 5"9Bi$"=Wi '4 c<M!0r!   r,   c                    t         j                  j                  |       st        j                  |        ddlm} g }t        |      D ]>  }|dd dk(  st        ||      } |       }t        |dd      }|j                  ||f       @ d}|D ]9  \  }}t         j                  j                  | d|z        }	t        ||	       |dz  }; dd	lm}
  |
       }t        |t         j                  j                  | d
             ddlm} ddlm}  |       } ||j"                  |j$                        }|j'                  |       t        |t         j                  j                  | d             y )Nr   )
testshapes
   
getDrawingrl   rf   zrenderSVG_%d.svgr   )getDrawing01ztest.svg)RL_CorpLogo)Drawingzcorplogo.svg)r  r   isdirmkdirreportlab.graphicsr  dirr  r6   rh   r   reportlab.graphics.testshapesr  reportlab.lib.corpr  r  r  r%   r&   add)outDirr  drawingsfuncnamefuncr-   	docstringr9   r   filenamer  r  r  rls                 r   testr     s,    77== 
-H
O 2Ab>\):h/DfGYr2IOOWi012 	
A" I77<<'9A'=>1h	Q
 ;Aq"'',,vj12.1	B#AEE"Iq"'',,vn56r!   __main__rj  )zout-svg):rl   mathr]   r  rR   rW  ior   r   reportlab.pdfbase.pdfmetricsr   reportlab.lib.rl_accelr   reportlab.lib.utilsr   reportlab.graphics.renderbaser   r	   r
   r  r   r   r   	reportlabr   r   r   r   reportlab.pdfgen.canvasr   r   renderPMr   xml.domr   ru  rs  rt  r   r)  r_  r   r>  r=  r   r    r   r'   r:   rJ   rP   rL   r   r   r$   r,   r   ri   rs   r!   r   <module>r,     sd  	 % $ $   4 ) ( V V D D '  < < @  ( hh
hh	WW D  J  J  LgmmoLRRTlrrt '--/  "+!7!7  $-#9#9  1G1G R
>$D $N 	yI9yI9
Hf fPg08 g0R 7D ZF r!   