3
?WQ                 @   s  d Z ddlmZmZ ddlmZ ddlm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 ydd
l	mZ W n ek
r   dZY nX ejje	kstde	j dkZe	je	je	jdZG dd deZ G dd de!Z"G dd dejj#Z$G dd de!Z%G dd de!Z&d)ddZ'dd Z(dd Z)dd Z*d d! Z+e,e	j-e	j.e	j/d"Z0G d#d$ d$e!Z1G d%d& d&e1Z-G d'd( d(e1Z.dS )*z
    weasyprint.images
    -----------------

    Fetch and decode images in various formats.

    :copyright: Copyright 2011-2014 Simon Sapin and contributors, see AUTHORS.
    :license: BSD, see LICENSE for details.

    )divisionunicode_literals)BytesIO)ElementTreeN   )fetchURLFetchingError)LOGGER)xrange)pixbufz_CairoSVG is using pycairo instead of cairocffi. Make sure it is not imported before WeasyPrint.i*  )autozcrisp-edgesZ	pixelatedc               @   s   e Zd ZdZedd ZdS )ImageLoadingErrorzpAn error occured when loading an image.

    The image data is probably corrupted or in an invalid format.

    c             C   s*   t |j}t|}| |r$d||f n|S )Nz%s: %s)type__name__str)cls	exceptionnamevalue r   Q/var/www/html/enquirykeeper_venv/lib/python3.6/site-packages/weasyprint/images.pyfrom_exception7   s    
z ImageLoadingError.from_exceptionN)r   
__module____qualname____doc__classmethodr   r   r   r   r   r   0   s   r   c               @   s$   e Zd Zdd Zdd Zdd ZdS )RasterImagec             C   s>   || _ |j | _|j | _| jdkr0| j| j ntd| _d S )Nr   inf)image_surfaceZ	get_width_intrinsic_widthZ
get_height_intrinsic_heightfloatintrinsic_ratio)selfr   r   r   r   __init__?   s    

zRasterImage.__init__c             C   s   | j | | j| fS )N)r   r    )r#   Zimage_resolution
_font_sizer   r   r   get_intrinsic_sizeG   s    zRasterImage.get_intrinsic_sizec             C   sf   |dkrb|dkrb| j dkrb| jdkrb|j|| j  || j  |j| j |j jt|  |j  d S )Nr   )	r   r    scaleset_source_surfacer   
get_sourceZ
set_filterIMAGE_RENDERING_TO_FILTERpaint)r#   contextconcrete_widthconcrete_heightZimage_renderingr   r   r   drawL   s    
zRasterImage.drawN)r   r   r   r$   r&   r/   r   r   r   r   r   >   s   r   c                   s$   e Zd ZdZe fddZ  ZS )ScaledSVGSurfaceza
    Have the cairo Surface object have intrinsic dimension
    in pixels instead of points.
    c                s   t t| j}|d S )Ng      ?)superr0   device_units_per_user_units)r#   r'   )	__class__r   r   r2   ^   s    z,ScaledSVGSurface.device_units_per_user_units)r   r   r   r   propertyr2   __classcell__r   r   )r3   r   r0   Y   s   r0   c               @   s    e Zd ZdZdZdZdZdZdS )FakeSurfacez1Fake CairoSVG surface used to get SVG attributes.r      `   N)r   r   r   r   Zcontext_heightZcontext_width	font_sizedpir   r   r   r   r6   d   s
   r6   c               @   s$   e Zd Zdd Zdd Zdd ZdS )SVGImagec             C   sb   |j  jds|nd | _|| _ytj| j| _W n, tk
r\ } ztj	|W Y d d }~X nX d S )Nzdata:)
lower
startswith	_base_url	_svg_datar   
fromstring_tree	Exceptionr   r   )r#   Zsvg_dataZbase_urler   r   r   r$   m   s    zSVGImage.__init__c             C   s  t  }||_tjj|| jjd| _tjj|| jjd| _tjj	|| j\}}}| jpZd | _
| jpfd | _d | _|r| jr| jr| j| j | _q|d r|d r|d |d  | _| jr| j| j | _q| jr| j| j | _
n| jr| jr| j| j | _| j
| jfS )Nwidthheight      )r6   r9   cairosvgsurfacesizerA   get_widthZ_heightZnode_formatr   r    r"   )r#   _image_resolutionr9   Zfake_surface_Zviewboxr   r   r   r&   y   s,    zSVGImage.get_intrinsic_sizec             C   s   y^t tjj| j| jdd d||d}|jr\|jr\|j||j ||j  |j	|j
 |j  W n2 tk
r } ztjd| j| W Y d d }~X nX d S )N)Z
bytestringurlr8   )outputr:   Zparent_widthZparent_heightz&Failed to draw an SVG image at %s : %s)r0   rH   parserZTreer?   r>   rD   rE   r'   r(   cairor+   rB   r	   warning)r#   r,   r-   r.   _image_renderingZsvgrC   r   r   r   r/      s    zSVGImage.drawN)r   r   r   r$   r&   r/   r   r   r   r   r;   l   s   r;   c          2   C   s  t  }| j||}||k	r|S yPt||:}d|krB|d }n|d j }|pX|d }|dkrnt||}ny\|dkrytjjt|}	W n, t	k
r }
 zt
j|
W Y dd}
~
X qX t|	}nd}W n t
k
r   d}Y nX |sdtdkrt
dytj|\}	}W n2 tj
k
r> }
 zt
t|
W Y dd}
~
X nX |dkr\tr\|	jd	| t|	}W dQ R X W n: tt
fk
r } ztjd
|| d}W Y dd}~X nX || |< |S )z&Get a cairo Pattern from an image URI.stringZfile_obj	mime_typezimage/svg+xmlz	image/pngNzLCould not load GDK-Pixbuf. PNG and SVG are the only image formats available.Zjpegz
image/jpegz!Failed to load image at "%s" (%s))objectrK   r   readr;   	cairocffiZImageSurfaceZcreate_from_pngr   rB   r   r   r   r   Zdecode_to_image_surfacer   CAIRO_HAS_MIME_DATAZset_mime_datar   r	   rS   )cacheZurl_fetcherrO   Zforced_mime_typemissingimageresultrU   rV   rI   r   Zformat_nameexcr   r   r   get_image_from_uri   sN    


r`   c             C   s<   | dkr| S | j dkr| jS | j dks*t|| j d S dS )z>Return the evaluated percentage value, or the value unchanged.NZpx%d   )unitr   AssertionError)r   Zrefer_tor   r   r   
percentage   s    
re   c       	         s    fdd|D }|d dkr&d|d< |d dkr: |d< |d }x2t |D ]&\}}|dk	rL||k rn|||< qL|}qLW d}x`t |D ]T\}}|dk	r|| }|| ||  }x&t|d |D ]}|||  ||< qW |}qW |S )	aA  
    Gradient line size: distance between the starting point and ending point.
    Positions: list of None, or Dimension in px or %.
               0 is the starting point, 1 the ending point.

    http://dev.w3.org/csswg/css-images-3/#color-stop-syntax

    Return processed color stops, as a list of floats in px.

    c                s   g | ]}t | qS r   )re   ).0position)gradient_line_sizer   r   
<listcomp>   s   z'process_color_stops.<locals>.<listcomp>r   Nr   rj   rj   )	enumerater
   )	rh   	positionsZprevious_posirg   Z
previous_ibaseZ	incrementjr   )rh   r   process_color_stops   s*    

rp   c                sN   | d  | d }|  dkr6 fdd| D } ndd | D }  || fS )zNormalize to [0..1].r   r   c                s   g | ]}|   qS r   r   )rf   pos)firsttotal_lengthr   r   ri     s    z+normalize_stop_postions.<locals>.<listcomp>c             S   s   g | ]}d qS )r   r   )rf   rN   r   r   r   ri     s    rj   r   )rl   lastr   )rr   rs   r   normalize_stop_postions  s    ru   c             C   sP  t |}|dkst|t | ks$t|d
 |d  }|dkrPtt|}|d }dd | D }dd | D }dd | D }dd | D }d } }	 }
}d| }xt|dd	 dD ]r\}}|||d   | }xT|d |fD ]D}||| | 7 }|	|| | 7 }	|
|| | 7 }
||| | 7 }qW qW |dkrL|| |	| |
| |fS dS )zT
    http://dev.w3.org/csswg/css-images-3/#find-the-average-color-of-a-gradient
    r   r   c             S   s   g | ]\}}}}|| qS r   r   )rf   rgbar   r   r   ri   *  s    z*gradient_average_color.<locals>.<listcomp>c             S   s   g | ]\}}}}|| qS r   r   )rf   rv   rw   rx   ry   r   r   r   ri   +  s    c             S   s   g | ]\}}}}|| qS r   r   )rf   rv   rw   rx   ry   r   r   r   ri   ,  s    c             S   s   g | ]\}}}}|qS r   r   )rf   rv   rw   rx   ry   r   r   r   ri   -  s    rF   Nrj   )r   r   r   r   )lenrd   listrangerk   )colorsrl   Znb_stopsrs   Zpremul_rZpremul_gZpremul_balphaZresult_rZresult_gZresult_bZresult_aZtotal_weightrm   rg   Zweightro   r   r   r   gradient_average_color  s*    r   )linearradialsolidc               @   s0   e Zd Zdd Zdd ZdZdd Zdd	 ZdS )
Gradientc             C   s2   |st dd |D | _dd |D | _|| _d S )Nc             S   s   g | ]\}}|qS r   r   )rf   colorrg   r   r   r   ri   F  s    z%Gradient.__init__.<locals>.<listcomp>c             S   s   g | ]\}}|qS r   r   )rf   r   rg   r   r   r   ri   G  s    )rd   r}   stop_positions	repeating)r#   color_stopsr   r   r   r   r$   C  s    zGradient.__init__c             C   s   dS )N)NNr   )r#   rM   r%   r   r   r   r&   K  s    zGradient.get_intrinsic_sizeNc             C   s   | j |||j\}}}}}	|jd| t| | }
x&t||	D ]\}}|
j|f|  q>W |
j| jrjtj	ntj
 |j|
 |j  d S )Nr   )layoutuser_to_device_distancer'   PATTERN_TYPESzipZadd_color_stop_rgbaZ
set_extendr   rY   ZEXTEND_REPEATZ
EXTEND_PADZ
set_sourcer+   )r#   r,   r-   r.   rT   scale_ytype_initr   Zstop_colorspatternrg   r   r   r   r   r/   Q  s    
zGradient.drawc             C   s   t dS )a  width, height: Gradient box. Top-left is at coordinates (0, 0).
        user_to_device_distance: a (dx, dy) -> (ddx, ddy) function

        Returns (scale_y, type_, init, positions, colors).
        scale_y: float, used for ellipses radial gradients. 1 otherwise.
        positions: list of floats in [0..1].
                   0 at the starting point, 1 at the ending point.
        colors: list of (r, g, b, a)
        type_ is either:
            'solid': init is (r, g, b, a). positions and colors are empty.
            'linear': init is (x0, y0, x1, y1)
                      coordinates of the starting and ending points.
            'radial': init is (cx0, cy0, radius0, cx1, cy1, radius1)
                      coordinates of the starting end ending circles

        N)NotImplementedError)r#   rD   rE   r   r   r   r   r   ]  s    zGradient.layout)r   r   r   r$   r&   r"   r/   r   r   r   r   r   r   B  s
   r   c               @   s   e Zd Zdd Zdd ZdS )LinearGradientc             C   s   t j| || |\| _| _d S )N)r   r$   direction_type	direction)r#   r   r   r   r   r   r   r$   r  s    zLinearGradient.__init__c                s  t | jdkr"dd| jd g g fS | jdkrjddddd| j \}}tj||}|| | }|| | }n| j}	tj|	}tj|	 }t|| t||  }
t	|
| j
}t|\}}}tj||| }|| | t |k r@| jr t| j|}dd|g g fS d| }||kr8|| | ||    fdd|D }||7 }|||
  d	 }|||
  d	 }|||  |||  |||  |||  f}dd
||| jfS )Nr   r   r   Zcorner)Ztop_leftZ	top_rightZbottom_leftZbottom_rightrb   c                s   g | ]}|  qS r   r   )rf   rq   )factorr   r   ri     s    z)LinearGradient.layout.<locals>.<listcomp>rF   r   rj   rj   )rj   rj   rj   )r   rj   rj   )rj   r   )r   r   )rz   r}   r   r   mathhypotsincosabsrp   r   ru   r   r   )r#   rD   rE   r   Zfactor_xZfactor_yZdiagonalZdxZdyZangleZdistancerl   rr   rt   Zdevice_per_user_unitsr   offsetZstart_xZstart_yZpointsr   )r   r   r   w  s:    


zLinearGradient.layoutN)r   r   r   r$   r   r   r   r   r   r   q  s   r   c               @   s$   e Zd Zdd Zdd Zdd ZdS )RadialGradientc             C   s*   t j| || || _|| _|\| _| _d S )N)r   r$   centershape	size_typerJ   )r#   r   r   rJ   r   r   r   r   r   r$     s    zRadialGradient.__init__c                sv  t | jdkr"dd| jd g g fS | j\}}}}t||}t||}|dkrT|| }|dkrd|| }| j||||\}}	||	  kodkn  rd }}	n"|dkrd}d}	n|	dkrd}d}	|	| }
| j}t|| jd d   | jr<t fdd	t	j
|dd t	j
|d|
 fD r<t|}dd|g g fS d dk r0| jr~ t	jd     fd
dD nxtD ]\}}|dkr|dkst|| }||d  }|d  }|dk stt||||g|dd|g}|g||d   }dg|d   P qW dd| jd g g fS t\}}||krP|d7 }|||
 ||||
 |f}|
d||fS )Nr   r   r   rightbottomgHz>g    cAc             3   s   | ]} | t k V  qd S )N)rz   )rf   rc   )rh   rl   r   r   	<genexpr>  s   z(RadialGradient.layout.<locals>.<genexpr>c                s   g | ]}|  qS r   r   )rf   p)r   r   r   ri     s    z)RadialGradient.layout.<locals>.<listcomp>rb   r   rj   rj   )rz   r}   r   re   _resolve_sizerp   r   r   anyr   r   r   ceilrk   rd   ru   )r#   rD   rE   r   Zorigin_xcenter_xZorigin_ycenter_ysize_xsize_yr   r}   r   rm   rg   Z	neg_colorZneg_positionZintermediate_colorrr   rt   Zcirclesr   )rh   r   rl   r   r     sj    








zRadialGradient.layoutc             C   s*  | j dkr(| j\}}t||t||fS t|}t|| }t|}	t|| }
| jjdr`tnt}| jjdr| jdkr||||	|
}||fS |||||	|
fS | jdkr|t	j
||	t	j
||
t	j
||	t	j
||
}||fS |||	f||
f||	f||
fdd d\}}|t	jd |t	jd fS )	NexplicitZclosestZsideZcirclec             S   s
   t j|  S )N)r   r   )ry   r   r   r   <lambda>  s    z.RadialGradient._resolve_size.<locals>.<lambda>)keyrF   )r   rJ   re   r   r=   minmaxendswithr   r   r   sqrt)r#   rD   rE   r   r   r   r   leftr   topr   ZpickZsize_xyZcorner_xZcorner_yr   r   r   r     s*    



zRadialGradient._resolve_sizeN)r   r   r   r$   r   r   r   r   r   r   r     s   Er   )N)2r   
__future__r   r   ior   Z	xml.etreer   r   rY   Zcairosvg.parserrH   Zcairosvg.surfaceZurlsr   r   loggerr	   compatr
   r   OSErrorrI   rR   rd   Zcairo_versionrZ   ZFILTER_BILINEARZFILTER_BESTZFILTER_NEARESTr*   
ValueErrorr   rW   r   Z
SVGSurfacer0   r6   r;   r`   re   rp   ru   r   dictr   r   ZSolidPatternr   r   r   r   r   r   <module>   sJ   

=
7(
/0