a
    V$cg                     @   s   d dl mZmZmZmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZm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mZmZmZmZm Z  G dd de!Z"e" gZ#dd Z$d	d
 Z%dd Z&dd Z'dd Z(dd Z)G dd de!Z*dS )    )divisionabsolute_importwith_statementprint_functionunicode_literals)PY2
basestringbchrbordchropenpystrrangeroundstrtobytesunicodeN)	blit_lockIDENTITYBLITDISSOLVEIMAGEDISSOLVE	PIXELLATEFLATTENc                   @   s    e Zd ZdZdd Zdd ZdS )Clipperz~
    This is used to calculate the clipping rectangle and update rectangles
    used for a particular draw of the screen.
    c                 C   s(   g | _ g | _t | _t | _t | _d S N)blits	old_blitssetforced
old_forcedmutatedself r$   renpy/display\swdraw.py__init__*   s
    zClipper.__init__c           '      C   s  | j }| j}| j}| j}| j}|| _ g | _|| _t | _t | _tjj}tjj	}|| }	dd||f}
|rr|
|
gfS ||B }|
|v r|
|
gfS d}d}t|}|t
|ks|t
|krqH|| }|| }||krt|d |v r||dd  |d7 }|d7 }q||vr,||dd  |d7 }q||dd  |d7 }q|dd ||d D  |dd ||d D  |sdg fS g }|D ]\}}}}\}}}}|d7 }|d7 }||k r|}||k r|}||kr|}||kr|}|| }|| }|dks|dkrq|| }||	kr<|
|
gf  S ||||||f q|  g }d}|r| \}}}}}d}|| |	krdd||fdd||fgfS d} | t
|k r||  \}!}"}#}$}%||"  kr|ksn ||$  kr|krn n~||#  kr|ks8n ||%  kr4|krn nHd	}t||"}t||$}t||#}t||%}|| ||  }||  n| d7 } q|r||||||f n|||||f ||7 }qd|sdg fS | \}}}}t|}t|}tt|}tt|}|||| || fg}&|D ]|\}"}#}$}%t|"}"t|#}#tt|$}$tt|%}%t||"}t||#}t||$}t||%}|&|"|#|$|" |%|# f q*|||| || f|&fS )
z
        This returns a clipping rectangle, and a list of update rectangles
        that cover the changes between the old and new frames.
        r      N   c                 s   s   | ]}|d d V  qd S Nr'   r$   .0ir$   r$   r%   	<genexpr>}       z"Clipper.compute.<locals>.<genexpr>c                 s   s   | ]}|d d V  qd S r)   r$   r*   r$   r$   r%   r-   ~   r.   FT)r   r   r    r   r!   r   renpyconfigscreen_widthscreen_heightlenidaddupdateappendsortpopminmaxintmathceil)'r#   full_redrawbl0bl1r    r   r!   swshsa
fullscreenchangesi0i1bl1setb0b1sizedx0y0x1y1sx0sy0sx1sy1whareanoncontncamergedr,   _iareaix0iy0ix1iy1updatesr$   r$   r%   compute9   s    	











6










zClipper.computeN)__name__
__module____qualname____doc__r&   ra   r$   r$   r$   r%   r   $   s   r   c                 C   sJ   |r t | d |d ft j}nt | d |d fd}|dd| |fS )zd
    Creates a surface that shares a pixel format with the screen. The created
    surface will
       r      )pygameSurfaceSRCALPHA
subsurface)rU   rV   alpharvr$   r$   r%   surface   s    rn   c                 C   s,   |   \}}t||d}tjj| | |S NT)get_sizern   r/   displayaccelerator
nogil_copy)surfrU   rV   rm   r$   r$   r%   copy_surface   s    ru   c                 C   s  |  \}}t|| j| }t|| j| }|dks<|dkr@dS | jtkr| jd d d}| jd d d}	| jrt	||d}
n|
dd||f}
tjj|
| | ||f|	
| | ||f|
t| jd  | jr||
d n| jtkr| jd d d}| jd d d}| jd d d}	| jrNt	||d}
n|
dd||f}
| j}d}td|D ]}|td| | 7 }qt|d	7 }t| jd
|  }|||d
  }tjj|
| | ||f|	
| | ||f|
|
| | ||f| | jr||
d n| jtkr| jd d | d }| j}tjj|
| | ||f|
dd||f|||| nR| jtkr| jd d | d }|
dd||f|d ntd| j dS )z
    This handles the special drawing operations, such as dissolve and
    image dissolve. `x` and `y` are the offsets of the thing to be drawn
    relative to the destination rectangle, and are always negative.
    r   NTr(      r   r   rg   s                                                                                                                                                                                                                                                                   s         zUnknown operation: %d)rp   r:   widthheight	operationr   childrenrender_to_textureoperation_alpharn   rk   r/   rq   moduleblendr<   operation_completeblitr   operation_parameterr   r	   
imageblendr   	get_masks	pixellater   	Exception)whatdestxydwdhrU   rV   bottomtoptargetimageramplenrampr,   steprt   pxr$   r$   r%   draw_special  sl    
r   c           "   
   C   s  t |tjjjst |trt |tr|rX| \}}| j|||| || ||df qz$t	
  | |||f W t	  qt	  0 nH|r| \}}| j|||| || ||df ntjj|| || dS |jr|||dtjj_|jtkrt|}t|}|r0|\}}	}
}|
| }||	 }n|  \}}|dkrPd}|}n|}d}|dkrld}|}n|}d}||ks||krdS t|| |j| }t|| |j| }|dks|dkrdS |r| j|||| || |f n | ||||f}t|||| dS |js&|jr4|r|\}}}}t||}t||}t|||j }t|||j }||ks||krdS ||||f}| j||f  dS |dkr|}d}nd}|dkr|}d}nd}|  \}}t|| |j| }t|| |j| }|dk s|dk r"dS | ||||f} |jdksd|j dksd|j!dur|j!t"ur|j#D ]:\}}}} }!t$| |||| || |j|j  |j!|j% qjdS |j#D ]*\}}}} }!t&| |||| || | qdS )a  
    This is the simple draw routine, which only works when alpha is 1.0
    and the matrices are None. If those aren't the case, draw_complex
    is used instead.

    `dest` - Either a destination surface, or a clipper.
    `clip` - If None, we should draw. Otherwise we should clip, and this is
    the rectangle to clip to.
    `what` - The Render or Surface we're drawing to.
    `xo` - The X offset.
    `yo` - The Y offset.
    `screen` - True if this is a blit to the screen, False otherwise.
    Nr   r(         ?)'
isinstancer/   rq   renderRenderr<   rp   r   r7   r   acquirer   releaser   subpixel
text_inputscreen_rect	interface	text_rectr|   r   r:   rz   r{   r   r5   rk   r   	xclipping	yclippingr;   rl   overforwardr   r}   draw_transformedreversedraw)"r   clipr   xoyoscreenrU   rV   dx0dy0dx1dy1r   r   newxsubxnewysubysubwsubhnewdestcx0cy0cx1cy1r   r   rz   r{   childcxocyo_focus_mainr$   r$   r%   r   \  s    $$


 



0r   c           -      C   s(  |dkrd S |d u rt }t }t|tjjjs| \}}	|r\|\}
}}}||
 }|| }n|  \}}d\}}||d\}}|||	\}}|d|	\}}t	t
||||| }tt||||| }t	t
||||| }tt||||| }|dk rd}|dk rd}||kr*|}||kr8|}||ks`||ks`|dk s`|dk rdd S ||| || \}}|r| j||||
 || |||||j|j|j|j|ff nB| |||| || f} tjj|| |||j|j|j|j|d
 d S |jr||||tjj_|js.|jr||js>|jr^t| ||d||||| d S |j|j }|j|j }|r|\} }!}"}#t| |} t|!|}!t
|"|| }"t
|#|| }#| |"ks|!|#krd S | |!|"|#f}| j ||f  d S |dkr|}$d}nd}$|dkr|}%d}nd}%|  \}}t
||$ || }t
||% || }|dk sf|dk rjd S | |$|%||f} |j!t"kr|d}&t| ||&||||| d S |j#D ]p\}&}'}(})}*||'|(\}'}(|j$r|j$| }+||j% },n|}+|},t| ||&||' ||( ||j& |j' |+|, qd S )Ng~jth?)        r   r   r   T)(r   r   r/   rq   r   r   rp   	transformr=   floorr:   r>   r;   r   r7   xdxydxxdyydyrk   r   r   r   r   r   r   r   r   pygame_surfacerz   r{   r   r5   r|   r   r}   r   r   rl   r   )-r   r   r   r   r   rl   r   r   rB   rC   r   r   r   r   r   r   rM   rN   rO   rP   x2y2x3y3minxmaxxminymaxycxcyrz   r{   r   r   r   r   r   r   r   r   r   r   r   child_forwardchild_reverser$   r$   r%   r     s    




(	





r   c                 C   s   d }}|||| j  || j f}td }t||| ||d ||\}}|du rTg S |\}	}
}}|j|}t|d| |	 |
 d |S )zC
    Draws the render produced by render_screen to the screen.
    r   TN)rz   r{   clippersr   ra   windowrk   )screen_renderr?   swdrawyoffsetxoffsetr   clippercliprectr`   r   r   _w_hr   r$   r$   r%   do_draw_screen  s    r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd7d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" Zd#d$ Zd%d& Zd'd( Zd)i fd*d+Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6S )8SWDrawz@
    This uses the software renderer to draw to the screen.
    c                 C   s   d | _ |   d S r   )display_inforesetr"   r$   r$   r%   r&     s    zSWDraw.__init__c                 C   sF   d| _ d| _dddd| _| jd u r0tj | _d| _d | _d | _	d S )NFr   rB   )renderer	resizableadditiver   )
suppressed_blit
next_frameinfor   r/   rq   get_infoscale_factorr   r   r"   r$   r$   r%   r     s    
zSWDraw.resetc                 C   s   dS )Nrw   r$   r"   r$   r$   r%   get_texture_size  s    zSWDraw.get_texture_sizec           	      C   s   t j  t jdd |   |\}}| jj}| jj}td| | d| | d}dt	j
v rltt	j
d }|| _t|| }t|| }t j||fdd| _|dkrt||d| _n| j| _tjj  d| _tjj| jdd| j| _tjjd| j ddd| j | _d| _| j| _dS )NSDL_OPENGL_ES_DRIVER0r   RENPY_SCALE_FACTORr       T)rh   rq   gl_reset_attributeshintr   r   	current_w	current_hr:   osenvironfloatr   r<   set_moder   rn   r   r/   pgrenderset_rgba_masksdraw_per_virtr   Matrix2Dvirt_to_drawdraw_to_virtr?   fullscreen_surface)	r#   virtual_sizerz   r{   r1   r2   r   scaled_widthscaled_heightr$   r$   r%   init  s.    

"zSWDraw.initTc                 C   s   dt jj_d S NF)r/   gamepreferencesrE   )r#   forcer$   r$   r%   r6     s    zSWDraw.updatec                 C   s   d S r   r$   r"   r$   r$   r%   resize  s    zSWDraw.resizec                 C   s   d S r   r$   r"   r$   r$   r%   quit  s    zSWDraw.quitc                 C   s   || j  }|| j  }||fS r   r   r#   r   r   r$   r$   r%   translate_point  s    

zSWDraw.translate_pointc                 C   s   || j 9 }|| j 9 }||fS r   r
  r  r$   r$   r%   untranslate_point  s    

zSWDraw.untranslate_pointc                 C   s2   t |dtj \}}|| j }|| j }||fS )Npos)getattrrh   mouseget_posr   )r#   evr   r   r$   r$   r%   mouse_event  s    

zSWDraw.mouse_eventc                 C   s*   t j \}}|| j }|| j }||fS r   )rh   r  r  r   r  r$   r$   r%   get_mouse_pos  s    

zSWDraw.get_mouse_posc                 C   s$   || j 9 }|| j 9 }tj||gS r   )r   rh   r  set_posr  r$   r$   r%   set_mouse_pos  s    

zSWDraw.set_mouse_posc                 C   s   | j S )zC
        Returns a pygame surface containing a screenshot.
        )r   )r#   surftreer$   r$   r%   
screenshot  s    zSWDraw.screenshotc                 C   s   dS ro   r$   r"   r$   r$   r%   	can_block&  s    zSWDraw.can_blockc                 C   sf   |sdS t jj}|du rdS | j}tj }d| }||| krD|}||k rT|sTdS || }|| _dS )zN
        Uses the framerate to determine if we can and should redraw.
        FNTg     @@)r/   r0   	framerater   rh   time	get_ticks)r#   needs_redraw
first_passr  r  r   now	frametimer$   r$   r%   should_redraw)  s    
zSWDraw.should_redrawc                 C   sj   g }t || j| }|r || d| _| j| ju r@tj| n&tjj	
| j| j | j tj  dS )z#
        Draws the screen.
        FN)r   r?   extendr   r   rh   rq   r6   r/   scalesmoothscalerp   flip)r#   r  r`   damager$   r$   r%   draw_screenM  s    
zSWDraw.draw_screenc                 C   s&   t |j|j|}t|d |ddd |S )Nr   F)rn   rz   r{   r   )r#   r   rl   rm   r$   r$   r%   r~   d  s    zSWDraw.render_to_texturec                 C   sD  |j tkrB| |jd d ||}| |jd d ||}|| S |dk sf|dk sf||jksf||jkrjdS |jD ]\}}}}	}
|| }|| }|jr|j||\}}t|t	j
jjr| |||r dS qpt|}t|}|dk s|dk r dS | \}}||ks||kr dS | d r8|||fd rp dS qpdS )Nr   rg   TFry   )r|   r   is_pixel_opaquer}   rz   r{   r   r   r   r/   rq   r   r   r<   rp   r   get_at)r#   r   r   r   a0a2r   r   r   r   r   r   r   cwchr$   r$   r%   r(  k  s0    
$ zSWDraw.is_pixel_opaquec                 C   s   t D ]}|jt| qdS )zH
        Called to indicate that the given surface has changed.
        N)r   r!   r5   r4   )r#   rt   r,   r$   r$   r%   mutated_surface  s    zSWDraw.mutated_surfaceFc                 C   s   | | jS )z
        Creates a texture from the surface. In the software implementation,
        the only difference between a texture and a surface is that a texture
        is in the RLE cache.
        )convert_alphar   )r#   rt   	transient
propertiesr$   r$   r%   load_texture  s    zSWDraw.load_texturec                 C   s   dS r  r$   r"   r$   r$   r%   ready_one_texture  s    zSWDraw.ready_one_texturec                 C   sH   t |d |d d}|| | | |dd||f}| | |S )zC
        Creates a texture filled to the edges with color.
        rf   Trg   )rn   fillr.  rk   )r#   rU   rV   colorrt   r$   r$   r%   solid_texture  s    


zSWDraw.solid_texturec                 C   s   dS )z<
        Kills all textures and caches of textures.
        Nr$   r"   r$   r$   r%   kill_textures  s    zSWDraw.kill_texturesc                 C   s   t d dS )z@
        Wait a little bit so the CPU doesn't speed up.
        g-C6?N)r  sleepr"   r$   r$   r%   event_peek_sleep  s    zSWDraw.event_peek_sleepc                 C   s   t jjt jjfS )zE
        Return the physical width and height of the screen.
        )r/   r0   r1   r2   r"   r$   r$   r%   get_physical_size  s    zSWDraw.get_physical_sizeN)T)rb   rc   rd   re   r&   r   r   r  r6   r  r	  r  r  r  r  r  r  r  r!  r'  r~   r(  r.  r2  r3  r6  r7  r9  r:  r$   r$   r$   r%   r     s4   0
$+	r   )+
__future__r   r   r   r   r   renpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   r=   r  r   pygame_sdl2rh   r/   renpy.display.renderr   r   r   r   r   r   r   objectr   r   rn   ru   r   r   r   r   r   r$   r$   r$   r%   <module>   s&   8$ JV  