
    'j=                    ^   d dl mZ d dlmZmZmZ d dlZd dlmZ	 d dl
Zd dlmZmZmZ d dlmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZ ddlmZ ddlmZm Z  dgZ! G d de j"                  Z#d.dZ$d/dZ% G d d          Z&dZ'dZ(dZ)dZ*dZ+dZ,dZ-d Z.d!Z/ G d" d#e          Z0d0d&Z1	 	 d1d2d-Z2dS )3    )annotations)IterableSequenceno_type_checkN)ElementTree)Vec2BoundingBox2dMatrix44)Command   )Color)BackendInterfaceBkPath2d
BkPoints2d	ImageData)ConfigurationLineweightPolicy)BackendProperties)layoutrecorder
SVGBackendc                       e Zd ZdZd fdZ ej                    ddddZ ej                    dddddZe	dd            Z
 xZS )r   zThis is a native SVG rendering backend and does not require any external packages
    to render SVG images other than the core dependencies.  This backend support content
    cropping at page margins.
    returnNonec                d    t                                                       d| _        d | _        d S )NT)super__init___init_flip_ytransformation_matrix)self	__class__s    R/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/addons/drawing/svg.pyr   zSVGBackend.__init__   s/     6:"""    Nsettings
render_boxpagelayout.Pager%   layout.Settingsr&   BoundingBox2d | None
ET.Elementc                  d}t          j         |          }|                                 }||                                }t          j        || j                  }|                    ||          }|j        dk    s|j        dk    rt          j
        d          S |                    |||          | _        |                    | j                   |j        rP|                    |          \  }}|                    |          }	d|	z  }
|                    ||	z  ||	z  |
           d| _        |                     ||          }|                    |           |                                S )	NT)flip_yr   svg)r%   
top_origin)r/   g?F)copyplayerbboxr   Layoutr   get_final_pagewidthheightETElementget_placement_matrixr   	transformcrop_at_marginsget_margin_rectpage_output_scale_factor	crop_rectmake_backendreplayget_xml_root_element)r    r'   r%   r&   r/   r1   output_layoutp1p2output_scalemax_sagittabackends               r"   rA   zSVGBackend.get_xml_root_element"   ss    
9X&& J j9JKKK++D(;;:??dkQ..:e$$$%2%G%G8
 &H &
 &
" 	3444# 	P))Z)@@FB#<<TBBL,KR,.\0A;OOO!##D(33g++---r#   T)r%   r&   xml_declarationstrc               `    |                      |||          }t          j        |d|          S )a  Returns the XML data as unicode string.

        Args:
            page: page definition, see :class:`~ezdxf.addons.drawing.layout.Page`
            settings: layout settings, see :class:`~ezdxf.addons.drawing.layout.Settings`
            render_box: set explicit region to render, default is content bounding box
            xml_declaration: inserts the "<?xml version='1.0' encoding='utf-8'?>" string
                in front of the <svg> element

        r$   unicode)encodingrH   )rA   r7   tostring)r    r'   r%   r&   rH   xmls         r"   
get_stringzSVGBackend.get_stringI   s5    $ ''xJ'WW{3OTTTTr#   SVGRenderBackendc                "    t          | |          S )z8Override this method to use a customized render backend.)rP   )r'   r%   s     r"   r?   zSVGBackend.make_backend^   s      h///r#   r   r   )r'   r(   r%   r)   r&   r*   r   r+   )r'   r(   r%   r)   r&   r*   r   rI   )r'   r(   r%   r)   r   rP   )__name__
__module____qualname____doc__r   r   SettingsrA   rO   staticmethodr?   __classcell__)r!   s   @r"   r   r      s         
; ; ; ; ; ; %4FO$5$5+/%. %. %. %. %. %.V %4FO$5$5+/U U U U U U* 0 0 0 \0 0 0 0 0r#   r'   r(   output_coordinate_spacefloatr   tuple[int, int]c                    t          |          }| j        | j        k    r!|t          || j        | j        z  z            fS t          || j        | j        z  z            |fS N)roundr5   r6   )r'   rZ   sizes      r"   make_view_boxra   d   sa    ())DzDKU44;#;<====dk1233T99r#   c                B    t          || j        z  || j        z            S r^   )minr5   r6   )r'   rZ   s     r"   scale_page_to_view_boxrd   k   s(    $*,$+-  r#   c                  4    e Zd ZddZddddddddZddZdS )StylesrN   r+   r   r   c                H    || _         t                      | _        d| _        d S )Nr   )_xmldict_class_names_counter)r    rN   s     r"   r   zStyles.__init__t   s     	,0FFr#   none      ?)strokestroke_widthstroke_opacityfillfill_opacityrn   r   ro   	int | strrp   r[   rq   rr   rI   c                   d| d| d|dd| d|dd}t          |          }	 | j        |         S # t          $ r Y nw xY wd| j        d	}| xj        d
z  c_        |                     ||           || j        |<   |S )Nz	{stroke: z; stroke-width: z; stroke-opacity: z.3fz; fill: z; fill-opacity: z;}CXr   )hashrj   KeyErrorrk   
_add_class)	r    rn   ro   rp   rq   rr   stylekeynames	            r"   	get_classzStyles.get_classy   s    3 3 3)3 3-53 3 3 3 *2	3 3 3 	 5kk	$S)) 	 	 	D	$4=$$$e$$$!%#s   2 
??	style_strc                |    t          j        d          }d| d| |_        | j                            |           d S )Nrz   . )r7   r8   textrh   append)r    r|   r~   rz   s       r"   ry   zStyles._add_class   sD    
7##+++	++
	r#   N)rN   r+   r   r   )rn   r   ro   rs   rp   r[   rq   r   rr   r[   r   rI   )r~   rI   r   r   )rS   rT   rU   r   r}   ry    r#   r"   rf   rf   s   sk            "( #!     6           r#   rf   zM {0.x:.0f} {0.y:.0f}zm {0.x:.0f} {0.y:.0f}zL {0.x:.0f} {0.y:.0f}zl {0.x:.0f} {0.y:.0f}z)Q {0.x:.0f} {0.y:.0f} {1.x:.0f} {1.y:.0f}z)q {0.x:.0f} {0.y:.0f} {1.x:.0f} {1.y:.0f}z=C {0.x:.0f} {0.y:.0f} {1.x:.0f} {1.y:.0f} {2.x:.0f} {2.y:.0f}z=c {0.x:.0f} {0.y:.0f} {1.x:.0f} {1.y:.0f} {2.x:.0f} {2.y:.0f}z{0.x:.0f} {0.y:.0f}c                     e Zd ZdZd=dZd>d
Zd?dZd?dZd@dZdAdZ	dBdZ
dCdZdDdZdEd"ZdFd%ZdGd(ZdHd+ZdId.ZedJdKd1            ZedLd3            ZeedJdMd4                        ZdNd7ZdOd8ZdOd9ZdOd:ZdOd;Zd<S )PrP   aN  Creates the SVG output.

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

    - Scale the content in y-axis by -1 to invert the y-axis (SVG).
    - Move content in the first quadrant of the coordinate system.
    - The viewBox is defined by the lower left corner in the origin (0, 0) and
      the upper right corner at (view_box_width, view_box_height)
    - The output coordinates are integer values, scale the content appropriately.
    - Replay the recorded output on this backend.

    r'   r(   r%   r)   r   r   c                   || _         t                      | _        t          ||j                  \  }}||j        z  | _        d| _        d| _        t          j
        | _        t          |j        |j        z            | _        t          | j        |j        z            | _        t          | j        |j        z            | _        t!          j        dd|j        dd|j        ddd| d| 	          | _        t)          t!          j        | j        d
                    | _        t!          j        | j        ddddt/          |          t/          |                    | _        t!          j        | j        d          | _        | j                            dd           | j                            dd           | j                            dd           d S )N皙?rm   r.   zhttp://www.w3.org/2000/svggmmz0 0 r   )xmlnsr5   r6   viewBoxdefsrectwhite0)rq   xyr5   r6   zstroke-linecapr_   zstroke-linejoinz	fill-ruleevenodd)r%   ri   _stroke_width_cachera   rZ   width_in_mmstroke_width_scalemin_lineweightlineweight_scalingr   ABSOLUTElineweight_policyintmax_stroke_widthmin_stroke_widthfixed_stroke_widthr7   r8   height_in_mmrootrf   
SubElementstylesrI   
backgroundentitiesset)r    r'   r%   view_box_widthview_box_heights        r"   r   zSVGRenderBackend.__init__   s    59VV *7(2+
 +
'
 *8$:J)J""%!1!: &),x/HH&
 &
 &)!H$==&
 &

 (+!H$??(
 (
 J.%++++'----=>==O==
 
 
	 R]49f==>>-In%%''
 
 
 di55*G444+W555+y11111r#   r+   c                    | j         S r^   )r   r    s    r"   rA   z%SVGRenderBackend.get_xml_root_element   s
    yr#   drI   
propertiesr   c                   |sd S t          j        | j        d|          }|                     |j                  }|                     |j                  \  }}| j                            |||          }|	                    d|           d S )Npathr   )rn   ro   rp   class)
r7   r   r   resolve_stroke_width
lineweightresolve_colorcolorr   r}   r   )r    r   r   elementro   stroke_colorrp   clss           r"   add_strokeszSVGRenderBackend.add_strokes   s     	F-v;;;001FGG'+'9'9*:J'K'K$nk##%) $ 
 

 	GS!!!!!r#   c                    |sd S t          j        | j        d|          }|                     |j                  \  }}| j                            ||          }|                    d|           d S )Nr   r   )rq   rr   r   )r7   r   r   r   r   r   r}   r   )r    r   r   r   
fill_colorrr   r   s          r"   add_fillingzSVGRenderBackend.add_filling   sv     	F-v;;;#'#5#5j6F#G#G 
Lk##,#OOGS!!!!!r#   r   r   tuple[Color, float]c                D    |d d         t          |dd                   fS )N   	   )alpha_to_opacity)r    r   s     r"   r   zSVGRenderBackend.resolve_color   s&    RaRy*51:6666r#   r5   r[   r   c                r   	 | j         |         S # t          $ r 	 | j        }Y nw xY w| j        }|t          j        k    rD| j        rt          | j        |          | j        z  }n| j        }t          || j
        z            }n+|t          j        k    rt          || j        | j                  }|| j         |<   |S r^   )r   rx   r   r   r   r   r   maxr   r_   r   RELATIVEmap_lineweight_to_stroke_widthr   r   )r    r5   ro   policys       r"   r   z%SVGRenderBackend.resolve_stroke_width  s    	3+E22 	3 	3 	32LLL	3 '%...& ,D/77$:QQ+ )@!@AALL'0009t,d.C L +7 's    $$c                    |d d         }t          |dd                   }| j                            d|           | j                            dt          |                     d S )Nr   r   rq   zfill-opacity)r   r   r   rI   )r    r   	color_stropacitys       r"   set_backgroundzSVGRenderBackend.set_background  s`    "1"I	"51:..FI...NCLL99999r#   posr   c                \    |                      |                     ||g          |           d S r^   r   make_polyline_str)r    r   r   s      r"   
draw_pointzSVGRenderBackend.draw_point  s0    //c
;;ZHHHHHr#   startendc                \    |                      |                     ||g          |           d S r^   r   )r    r   r   r   s       r"   	draw_linezSVGRenderBackend.draw_line   s0    //==zJJJJJr#   linesIterable[tuple[Vec2, Vec2]]c                    t          |          }t          |          dk    rd S |                     |                     |          |           d S )Nr   )listlenr   make_multi_line_str)r    r   r   s      r"   draw_solid_linesz!SVGRenderBackend.draw_solid_lines#  sM     Uu::??F11%88*EEEEEr#   r   r   c                X    |                      |                     |          |           d S r^   )r   make_path_str)r    r   r   s      r"   	draw_pathzSVGRenderBackend.draw_path+  s,    ++D11:>>>>>r#   pathsIterable[BkPath2d]c                    g }|D ];}t          |          r*|                    |                     |d                     <|                     d                    |          |           d S )NTcloser   )r   r   r   r   join)r    r   r   r   r   s        r"   draw_filled_pathsz"SVGRenderBackend.draw_filled_paths.  sr      	? 	?D4yy ?++D+==>>>!j11111r#   pointsr   c                    |                      |                     |                                d          |           d S )NTr   )r   r   vertices)r    r   r   s      r"   draw_filled_polygonz$SVGRenderBackend.draw_filled_polygon7  sH     	""6??#4#4D"AA:	
 	
 	
 	
 	
r#   
image_datar   c                    d S r^   r   )r    r   r   s      r"   
draw_imagezSVGRenderBackend.draw_image>      r#   FSequence[Vec2]c                N   t          |           dk     rdS | d         }t                              |          dg}| dd          D ]6}||z
  }|}|                    t                              |                     7|r|                    d           d                    |          S )N    r   lr   Zr   )r   	CMD_M_ABSformatr   CMD_CONTr   )r   r   currentr   pointrelatives         r"   r   z"SVGRenderBackend.make_polyline_strA  s    v;;??2)!((1137ABBZ 	0 	0EwHGHHX__X..//// 	HHSMMMxx{{r#   Sequence[tuple[Vec2, Vec2]]c                   t          |           dk    sJ | d         \  }}t                              |          t                              ||z
            g}|}| dd          D ]i\  }}|                    t
                              ||z
                       |}|                    t                              ||z
                       |}jd                    |          S )Nr   r   r   )r   r   r   	CMD_L_RELr   	CMD_M_RELr   )r   r   r   r   r   s        r"   r   z$SVGRenderBackend.make_multi_line_strP  s    5zzA~~~~1X
s!((//1A1A#+1N1NO) 	 	JE3HHY%%ego66777GHHY%%cGm44555GGxx{{r#   c           	     z   t                               | j                  g}t          |           dk    rdS | j        }|                                 D ]>}|j        }|j        t          j        k    r1|	                    t                              ||z
                       n|j        t          j        k    r1|	                    t                              ||z
                       n|j        t          j        k    r:|	                    t                              |j        |z
  ||z
                       nW|j        t          j        k    rB|	                    t"                              |j        |z
  |j        |z
  ||z
                       |}@|r|	                    d           d                    |          S )Nr   r   r   r   )r   r   r   r   commandsr   typer   MOVE_TOr   r   LINE_TOr   	CURVE3_TO
CMD_C3_RELctrl	CURVE4_TO
CMD_C4_RELctrl1ctrl2r   )r   r   r   r   cmdr   s         r"   r   zSVGRenderBackend.make_path_str]  s    "((445t99>>2*==?? 	 	C'Cx7?**))#-889999W_,,))#-889999W...**38g+=sW}MMNNNNW...%%	G+SY-@#-   
 GG 	HHSMMMxx{{r#   configr   c                    |j         | _         |j        r"|j        dz  dz  }t          d|          | _        |j        | _        d S )Ngffffff9@i,  r   )r   r   r   r   )r    r  min_lineweight_mms      r"   	configurezSVGRenderBackend.configurey  sO    !'!9  	? & 5 <s B"%d,=">">D"(";r#   c                    d S r^   r   r   s    r"   clearzSVGRenderBackend.clear  r   r#   c                    d S r^   r   r   s    r"   finalizezSVGRenderBackend.finalize  r   r#   c                    d S r^   r   )r    entityr   s      r"   enter_entityzSVGRenderBackend.enter_entity  r   r#   c                    d S r^   r   )r    r  s     r"   exit_entityzSVGRenderBackend.exit_entity  r   r#   N)r'   r(   r%   r)   r   r   )r   r+   )r   rI   r   r   )r   r   r   r   )r5   r[   r   r   )r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )F)r   r   r   rI   )r   r   r   rI   )r   r   r   rI   )r  r   r   r   rR   )rS   rT   rU   rV   r   rA   r   r   r   r   r   r   r   r   r   r   r   r   rX   r   r   r   r   r
  r  r  r  r  r   r#   r"   rP   rP      s        22 22 22 22h   " " " "" " " "7 7 7 7   (: : : :I I I IK K K KF F F F? ? ? ?2 2 2 2
 
 
 
        \ 
 
 
 \
     ] \4< < < <              r#   rP   alpharI   c                l    t          |           r$	 t          | d          dz  S # t          $ r Y nw xY wdS )N      rm   )r   r   
ValueError)r  s    r"   r   r     sO     5zz 	ub>>C'' 	 	 	D	3s   $ 
11r   zG @r   r   r   r   c                    t          t          | |          |          |z
  } ||z
  ||z
  z  }|t          | |z            z   S )zDMap the DXF lineweight in mm to stroke-width in viewBox coordinates.)r   rc   r_   )r   r   r   r   max_lineweightfactors         r"   r   r     sO     S^44nEEVJ!11n~6UVFeJ$78888r#   )r'   r(   rZ   r[   r   r\   )r'   r(   rZ   r[   r   r[   )r  rI   r   r[   )r   r  )r   r[   r   r   r   r   r   r   )3
__future__r   typingr   r   r   r0   	xml.etreer   r7   numpynp
ezdxf.mathr   r	   r
   
ezdxf.pathr   
type_hintsr   rG   r   r   r   r   r  r   r   r   r   r   r   r   __all__Recorderr   ra   rd   rf   r   r   	CMD_L_ABSr   
CMD_C3_ABSr   
CMD_C4_ABSr  r   rP   r   r   r   r#   r"   <module>r*     s8   # " " " " " 4 4 4 4 4 4 4 4 4 4  ' ' ' ' ' '     4 4 4 4 4 4 4 4 4 4             F F F F F F F F F F F F 3 3 3 3 3 3 3 3 ) ) ) ) ) )        .J0 J0 J0 J0 J0" J0 J0 J0Z: : : :   $  $  $  $  $  $  $  $ N $	#	#	#	8
8
L
L
 f f f f f' f f fR    
9 
9 
9 
9 
9 
9 
9r#   