<s> """<STR_LIT>""" <EOL> from __future__ import division , unicode_literals <EOL> import contextlib <EOL> import math <EOL> import operator <EOL> import cairocffi as cairo <EOL> from . formatting_structure import boxes <EOL> from . stacking import StackingContext <EOL> from . text import show_first_line <EOL> from . compat import xrange <EOL> SIDES = ( '<STR_LIT>' , '<STR_LIT:right>' , '<STR_LIT>' , '<STR_LIT:left>' ) <EOL> @ contextlib . contextmanager <EOL> def stacked ( context ) : <EOL> """<STR_LIT>""" <EOL> context . save ( ) <EOL> try : <EOL> yield <EOL> finally : <EOL> context . restore ( ) <EOL> def hsv2rgb ( hue , saturation , value ) : <EOL> """<STR_LIT>""" <EOL> c = value * saturation <EOL> x = c * ( <NUM_LIT:1> - abs ( ( hue / <NUM_LIT> ) % <NUM_LIT:2> - <NUM_LIT:1> ) ) <EOL> m = value - c <EOL> if <NUM_LIT:0> <= hue < <NUM_LIT> : <EOL> return c + m , x + m , m <EOL> elif <NUM_LIT> <= hue < <NUM_LIT> : <EOL> return x + m , c + m , m <EOL> elif <NUM_LIT> <= hue < <NUM_LIT> : <EOL> return m , c + m , x + m <EOL> elif <NUM_LIT> <= hue < <NUM_LIT> : <EOL> return m , x + m , c + m <EOL> elif <NUM_LIT> <= hue < <NUM_LIT> : <EOL> return x + m , m , c + m <EOL> elif <NUM_LIT> <= hue < <NUM_LIT> : <EOL> return c + m , m , x + m <EOL> def rgb2hsv ( red , green , blue ) : <EOL> """<STR_LIT>""" <EOL> cmax = max ( red , green , blue ) <EOL> cmin = min ( red , green , blue ) <EOL> delta = cmax - cmin <EOL> if delta == <NUM_LIT:0> : <EOL> hue = <NUM_LIT:0> <EOL> elif cmax == red : <EOL> hue = <NUM_LIT> * ( ( green - blue ) / delta % <NUM_LIT:6> ) <EOL> elif cmax == green : <EOL> hue = <NUM_LIT> * ( ( blue - red ) / delta + <NUM_LIT:2> ) <EOL> elif cmax == blue : <EOL> hue = <NUM_LIT> * ( ( red - green ) / delta + <NUM_LIT:4> ) <EOL> saturation = <NUM_LIT:0> if delta == <NUM_LIT:0> else delta / cmax <EOL> return hue , saturation , cmax <EOL> def darken ( color ) : <EOL> """<STR_LIT>""" <EOL> hue , saturation , value = rgb2hsv ( color . red , color . green , color . blue ) <EOL> value /= <NUM_LIT> <EOL> saturation /= <NUM_LIT> <EOL> return hsv2rgb ( hue , saturation , value ) + ( color . alpha , ) <EOL> def lighten ( color ) : <EOL> """<STR_LIT>""" <EOL> hue , saturation , value = rgb2hsv ( color . red , color . green , color . blue ) <EOL> value = <NUM_LIT:1> - ( <NUM_LIT:1> - value ) / <NUM_LIT> <EOL> if saturation : <EOL> saturation = <NUM_LIT:1> - ( <NUM_LIT:1> - saturation ) / <NUM_LIT> <EOL> return hsv2rgb ( hue , saturation , value ) + ( color . alpha , ) <EOL> def draw_page ( page , context , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> stacking_context = StackingContext . from_page ( page ) <EOL> draw_background ( <EOL> context , stacking_context . box . background , enable_hinting , <EOL> clip_box = False ) <EOL> draw_background ( <EOL> context , page . canvas_background , enable_hinting , clip_box = False ) <EOL> draw_border ( context , page , enable_hinting ) <EOL> draw_stacking_context ( context , stacking_context , enable_hinting ) <EOL> def draw_box_background_and_border ( context , page , box , enable_hinting ) : <EOL> draw_background ( context , box . background , enable_hinting ) <EOL> if isinstance ( box , boxes . TableBox ) : <EOL> draw_table_backgrounds ( context , page , box , enable_hinting ) <EOL> if box . style . border_collapse == '<STR_LIT>' : <EOL> draw_border ( context , box , enable_hinting ) <EOL> for row_group in box . children : <EOL> for row in row_group . children : <EOL> for cell in row . children : <EOL> if cell . style . empty_cells == '<STR_LIT>' or not cell . empty : <EOL> draw_border ( context , cell , enable_hinting ) <EOL> else : <EOL> draw_collapsed_borders ( context , box , enable_hinting ) <EOL> else : <EOL> draw_border ( context , box , enable_hinting ) <EOL> def draw_stacking_context ( context , stacking_context , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> with stacked ( context ) : <EOL> box = stacking_context . box <EOL> if box . is_absolutely_positioned ( ) and box . style . clip : <EOL> top , right , bottom , left = box . style . clip <EOL> if top == '<STR_LIT>' : <EOL> top = <NUM_LIT:0> <EOL> if right == '<STR_LIT>' : <EOL> right = <NUM_LIT:0> <EOL> if bottom == '<STR_LIT>' : <EOL> bottom = box . border_height ( ) <EOL> if left == '<STR_LIT>' : <EOL> left = box . border_width ( ) <EOL> context . rectangle ( <EOL> box . border_box_x ( ) + right , <EOL> box . border_box_y ( ) + top , <EOL> left - right , <EOL> bottom - top ) <EOL> context . clip ( ) <EOL> if box . style . opacity < <NUM_LIT:1> : <EOL> context . push_group ( ) <EOL> if box . transformation_matrix : <EOL> context . transform ( box . transformation_matrix ) <EOL> if isinstance ( box , ( boxes . BlockBox , boxes . MarginBox , <EOL> boxes . InlineBlockBox , boxes . TableCellBox ) ) : <EOL> draw_box_background_and_border ( <EOL> context , stacking_context . page , box , enable_hinting ) <EOL> with stacked ( context ) : <EOL> if box . style . overflow != '<STR_LIT>' : <EOL> rounded_box_path ( context , box . rounded_padding_box ( ) ) <EOL> context . clip ( ) <EOL> for child_context in stacking_context . negative_z_contexts : <EOL> draw_stacking_context ( context , child_context , enable_hinting ) <EOL> for block in stacking_context . block_level_boxes : <EOL> draw_box_background_and_border ( <EOL> context , stacking_context . page , block , enable_hinting ) <EOL> for child_context in stacking_context . float_contexts : <EOL> draw_stacking_context ( context , child_context , enable_hinting ) <EOL> if isinstance ( box , boxes . InlineBox ) : <EOL> draw_inline_level ( <EOL> context , stacking_context . page , box , enable_hinting ) <EOL> for block in [ box ] + stacking_context . blocks_and_cells : <EOL> marker_box = getattr ( block , '<STR_LIT>' , None ) <EOL> if marker_box : <EOL> draw_inline_level ( <EOL> context , stacking_context . page , marker_box , <EOL> enable_hinting ) <EOL> if isinstance ( block , boxes . ReplacedBox ) : <EOL> draw_replacedbox ( context , block ) <EOL> else : <EOL> for child in block . children : <EOL> if isinstance ( child , boxes . LineBox ) : <EOL> draw_inline_level ( <EOL> context , stacking_context . page , child , <EOL> enable_hinting ) <EOL> for child_context in stacking_context . zero_z_contexts : <EOL> draw_stacking_context ( context , child_context , enable_hinting ) <EOL> for child_context in stacking_context . positive_z_contexts : <EOL> draw_stacking_context ( context , child_context , enable_hinting ) <EOL> draw_outlines ( context , box , enable_hinting ) <EOL> if box . style . opacity < <NUM_LIT:1> : <EOL> context . pop_group_to_source ( ) <EOL> context . paint_with_alpha ( box . style . opacity ) <EOL> def rounded_box_path ( context , radii ) : <EOL> """<STR_LIT>""" <EOL> x , y , w , h , tl , tr , br , bl = radii <EOL> if <NUM_LIT:0> in tl : <EOL> tl = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> if <NUM_LIT:0> in tr : <EOL> tr = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> if <NUM_LIT:0> in br : <EOL> br = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> if <NUM_LIT:0> in bl : <EOL> bl = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> if ( tl , tr , br , bl ) == <NUM_LIT:4> * ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , ) : <EOL> context . rectangle ( x , y , w , h ) <EOL> return <EOL> context . move_to ( x , y ) <EOL> for i , ( w , h , ( rx , ry ) ) in enumerate ( ( <EOL> ( <NUM_LIT:0> , <NUM_LIT:0> , tl ) , ( w , <NUM_LIT:0> , tr ) , ( w , h , br ) , ( <NUM_LIT:0> , h , bl ) ) ) : <EOL> context . save ( ) <EOL> context . translate ( x + w , y + h ) <EOL> radius = max ( rx , ry ) <EOL> if radius : <EOL> context . scale ( min ( rx / ry , <NUM_LIT:1> ) , min ( ry / rx , <NUM_LIT:1> ) ) <EOL> context . arc ( <EOL> ( - <NUM_LIT:1> if w else <NUM_LIT:1> ) * radius , ( - <NUM_LIT:1> if h else <NUM_LIT:1> ) * radius , radius , <EOL> ( <NUM_LIT:2> + i ) * math . pi / <NUM_LIT:2> , ( <NUM_LIT:3> + i ) * math . pi / <NUM_LIT:2> ) <EOL> context . restore ( ) <EOL> def draw_background ( context , bg , enable_hinting , clip_box = True ) : <EOL> """<STR_LIT>""" <EOL> if bg is None : <EOL> return <EOL> with stacked ( context ) : <EOL> if enable_hinting : <EOL> context . set_antialias ( cairo . ANTIALIAS_NONE ) <EOL> if clip_box : <EOL> for box in bg . layers [ - <NUM_LIT:1> ] . clipped_boxes : <EOL> rounded_box_path ( context , box ) <EOL> context . clip ( ) <EOL> if bg . color . alpha > <NUM_LIT:0> : <EOL> with stacked ( context ) : <EOL> painting_area = bg . layers [ - <NUM_LIT:1> ] . painting_area <EOL> if painting_area : <EOL> context . rectangle ( * painting_area ) <EOL> context . clip ( ) <EOL> context . set_source_rgba ( * bg . color ) <EOL> context . paint ( ) <EOL> for layer in reversed ( bg . layers ) : <EOL> draw_background_image ( context , layer , bg . image_rendering ) <EOL> def draw_table_backgrounds ( context , page , table , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> for column_group in table . column_groups : <EOL> draw_background ( context , column_group . background , enable_hinting ) <EOL> for column in column_group . children : <EOL> draw_background ( context , column . background , enable_hinting ) <EOL> for row_group in table . children : <EOL> draw_background ( context , row_group . background , enable_hinting ) <EOL> for row in row_group . children : <EOL> draw_background ( context , row . background , enable_hinting ) <EOL> for cell in row . children : <EOL> if table . style . border_collapse == '<STR_LIT>' or ( <EOL> cell . style . empty_cells == '<STR_LIT>' or not cell . empty ) : <EOL> draw_background ( context , cell . background , enable_hinting ) <EOL> def draw_background_image ( context , layer , image_rendering ) : <EOL> if layer . image is None : <EOL> return <EOL> painting_x , painting_y , painting_width , painting_height = ( <EOL> layer . painting_area ) <EOL> positioning_x , positioning_y , positioning_width , positioning_height = ( <EOL> layer . positioning_area ) <EOL> position_x , position_y = layer . position <EOL> repeat_x , repeat_y = layer . repeat <EOL> image_width , image_height = layer . size <EOL> if repeat_x == '<STR_LIT>' : <EOL> repeat_width = painting_width * <NUM_LIT:2> <EOL> elif repeat_x in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> repeat_width = image_width <EOL> else : <EOL> assert repeat_x == '<STR_LIT>' <EOL> n_repeats = math . floor ( positioning_width / image_width ) <EOL> if n_repeats >= <NUM_LIT:2> : <EOL> repeat_width = ( positioning_width - image_width ) / ( n_repeats - <NUM_LIT:1> ) <EOL> position_x = <NUM_LIT:0> <EOL> else : <EOL> repeat_width = image_width <EOL> if repeat_y == '<STR_LIT>' : <EOL> repeat_height = painting_height * <NUM_LIT:2> <EOL> elif repeat_y in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> repeat_height = image_height <EOL> else : <EOL> assert repeat_y == '<STR_LIT>' <EOL> n_repeats = math . floor ( positioning_height / image_height ) <EOL> if n_repeats >= <NUM_LIT:2> : <EOL> repeat_height = ( <EOL> positioning_height - image_height ) / ( n_repeats - <NUM_LIT:1> ) <EOL> position_y = <NUM_LIT:0> <EOL> else : <EOL> repeat_height = image_height <EOL> sub_surface = cairo . PDFSurface ( None , repeat_width , repeat_height ) <EOL> sub_context = cairo . Context ( sub_surface ) <EOL> sub_context . rectangle ( <NUM_LIT:0> , <NUM_LIT:0> , image_width , image_height ) <EOL> sub_context . clip ( ) <EOL> layer . image . draw ( sub_context , image_width , image_height , image_rendering ) <EOL> pattern = cairo . SurfacePattern ( sub_surface ) <EOL> pattern . set_extend ( cairo . EXTEND_REPEAT ) <EOL> with stacked ( context ) : <EOL> if not layer . unbounded : <EOL> context . rectangle ( painting_x , painting_y , <EOL> painting_width , painting_height ) <EOL> context . clip ( ) <EOL> context . translate ( positioning_x + position_x , <EOL> positioning_y + position_y ) <EOL> context . set_source ( pattern ) <EOL> context . paint ( ) <EOL> def xy_offset ( x , y , offset_x , offset_y , offset ) : <EOL> """<STR_LIT>""" <EOL> return x + offset_x * offset , y + offset_y * offset <EOL> def styled_color ( style , color , side ) : <EOL> if style in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> do_lighten = ( side in ( '<STR_LIT>' , '<STR_LIT:left>' ) ) ^ ( style == '<STR_LIT>' ) <EOL> return ( lighten if do_lighten else darken ) ( color ) <EOL> elif style in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if ( side in ( '<STR_LIT>' , '<STR_LIT:left>' ) ) ^ ( style == '<STR_LIT>' ) : <EOL> return lighten ( color ) , darken ( color ) <EOL> else : <EOL> return darken ( color ) , lighten ( color ) <EOL> return color <EOL> def draw_border ( context , box , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> if box . style . visibility != '<STR_LIT>' : <EOL> return <EOL> widths = [ getattr ( box , '<STR_LIT>' % side ) for side in SIDES ] <EOL> if all ( width == <NUM_LIT:0> for width in widths ) : <EOL> return <EOL> colors = [ box . style . get_color ( '<STR_LIT>' % side ) for side in SIDES ] <EOL> styles = [ <EOL> colors [ i ] . alpha and box . style [ '<STR_LIT>' % side ] <EOL> for ( i , side ) in enumerate ( SIDES ) ] <EOL> if set ( styles ) in ( set ( ( '<STR_LIT>' , ) ) , set ( ( '<STR_LIT>' , ) ) ) and ( <EOL> len ( set ( colors ) ) == <NUM_LIT:1> ) : <EOL> draw_rounded_border ( context , box , styles [ <NUM_LIT:0> ] , colors [ <NUM_LIT:0> ] ) <EOL> return <EOL> for side , width , color , style in zip ( SIDES , widths , colors , styles ) : <EOL> if width == <NUM_LIT:0> or not color : <EOL> continue <EOL> with stacked ( context ) : <EOL> clip_border_segment ( <EOL> context , enable_hinting , style , width , side , <EOL> box . rounded_border_box ( ) [ : <NUM_LIT:4> ] , widths , <EOL> box . rounded_border_box ( ) [ <NUM_LIT:4> : ] ) <EOL> draw_rounded_border ( <EOL> context , box , style , styled_color ( style , color , side ) ) <EOL> def clip_border_segment ( context , enable_hinting , style , width , side , <EOL> border_box , border_widths = None , radii = None ) : <EOL> """<STR_LIT>""" <EOL> if enable_hinting and style != '<STR_LIT>' and ( <EOL> math . hypot ( * context . user_to_device ( width , <NUM_LIT:0> ) ) >= <NUM_LIT:1> and <EOL> math . hypot ( * context . user_to_device ( <NUM_LIT:0> , width ) ) >= <NUM_LIT:1> ) : <EOL> context . set_antialias ( cairo . ANTIALIAS_NONE ) <EOL> bbx , bby , bbw , bbh = border_box <EOL> ( tlh , tlv ) , ( trh , trv ) , ( brh , brv ) , ( blh , blv ) = radii or <NUM_LIT:4> * ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , ) <EOL> bt , br , bb , bl = border_widths or <NUM_LIT:4> * ( width , ) <EOL> def transition_point ( x1 , y1 , x2 , y2 ) : <EOL> """<STR_LIT>""" <EOL> return ( <EOL> ( ( x1 , y1 ) , True ) if abs ( x1 ) > abs ( x2 ) and abs ( y1 ) > abs ( y2 ) <EOL> else ( ( x2 , y2 ) , False ) ) <EOL> def corner_half_length ( a , b ) : <EOL> """<STR_LIT>""" <EOL> x = ( a - b ) / ( a + b ) <EOL> return math . pi / <NUM_LIT:8> * ( a + b ) * ( <EOL> <NUM_LIT:1> + <NUM_LIT:3> * x ** <NUM_LIT:2> / ( <NUM_LIT:10> + math . sqrt ( <NUM_LIT:4> - <NUM_LIT:3> * x ** <NUM_LIT:2> ) ) ) <EOL> if side == '<STR_LIT>' : <EOL> ( px1 , py1 ) , rounded1 = transition_point ( tlh , tlv , bl , bt ) <EOL> ( px2 , py2 ) , rounded2 = transition_point ( - trh , trv , - br , bt ) <EOL> width = bt <EOL> way = <NUM_LIT:1> <EOL> angle = <NUM_LIT:1> <EOL> main_offset = bby <EOL> elif side == '<STR_LIT:right>' : <EOL> ( px1 , py1 ) , rounded1 = transition_point ( - trh , trv , - br , bt ) <EOL> ( px2 , py2 ) , rounded2 = transition_point ( - brh , - brv , - br , - bb ) <EOL> width = br <EOL> way = <NUM_LIT:1> <EOL> angle = <NUM_LIT:2> <EOL> main_offset = bbx + bbw <EOL> elif side == '<STR_LIT>' : <EOL> ( px1 , py1 ) , rounded1 = transition_point ( blh , - blv , bl , - bb ) <EOL> ( px2 , py2 ) , rounded2 = transition_point ( - brh , - brv , - br , - bb ) <EOL> width = bb <EOL> way = - <NUM_LIT:1> <EOL> angle = <NUM_LIT:3> <EOL> main_offset = bby + bbh <EOL> elif side == '<STR_LIT:left>' : <EOL> ( px1 , py1 ) , rounded1 = transition_point ( tlh , tlv , bl , bt ) <EOL> ( px2 , py2 ) , rounded2 = transition_point ( blh , - blv , bl , - bb ) <EOL> width = bl <EOL> way = - <NUM_LIT:1> <EOL> angle = <NUM_LIT:4> <EOL> main_offset = bbx <EOL> if side in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> a1 , b1 = px1 - bl / <NUM_LIT:2> , way * py1 - width / <NUM_LIT:2> <EOL> a2 , b2 = - px2 - br / <NUM_LIT:2> , way * py2 - width / <NUM_LIT:2> <EOL> line_length = bbw - px1 + px2 <EOL> length = bbw <EOL> context . move_to ( bbx + bbw , main_offset ) <EOL> context . rel_line_to ( - bbw , <NUM_LIT:0> ) <EOL> context . rel_line_to ( px1 , py1 ) <EOL> context . rel_line_to ( - px1 + bbw + px2 , - py1 + py2 ) <EOL> elif side in ( '<STR_LIT:left>' , '<STR_LIT:right>' ) : <EOL> a1 , b1 = - way * px1 - width / <NUM_LIT:2> , py1 - bt / <NUM_LIT:2> <EOL> a2 , b2 = - way * px2 - width / <NUM_LIT:2> , - py2 - bb / <NUM_LIT:2> <EOL> line_length = bbh - py1 + py2 <EOL> length = bbh <EOL> context . move_to ( main_offset , bby + bbh ) <EOL> context . rel_line_to ( <NUM_LIT:0> , - bbh ) <EOL> context . rel_line_to ( px1 , py1 ) <EOL> context . rel_line_to ( - px1 + px2 , - py1 + bbh + py2 ) <EOL> context . set_fill_rule ( cairo . FILL_RULE_EVEN_ODD ) <EOL> if style in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> dash = width if style == '<STR_LIT>' else <NUM_LIT:3> * width <EOL> if rounded1 or rounded2 : <EOL> chl1 = corner_half_length ( a1 , b1 ) <EOL> chl2 = corner_half_length ( a2 , b2 ) <EOL> length = line_length + chl1 + chl2 <EOL> dash_length = round ( length / dash ) <EOL> if rounded1 and rounded2 : <EOL> dash = length / ( dash_length + dash_length % <NUM_LIT:2> ) <EOL> else : <EOL> dash = length / ( dash_length + dash_length % <NUM_LIT:2> - <NUM_LIT:0.5> ) <EOL> dashes1 = int ( math . ceil ( ( chl1 - dash / <NUM_LIT:2> ) / dash ) ) <EOL> dashes2 = int ( math . ceil ( ( chl2 - dash / <NUM_LIT:2> ) / dash ) ) <EOL> line = int ( math . floor ( line_length / dash ) ) <EOL> def draw_dots ( dashes , line , way , x , y , px , py , chl ) : <EOL> if not dashes : <EOL> return line + <NUM_LIT:1> , <NUM_LIT:0> <EOL> for i in range ( <NUM_LIT:0> , dashes , <NUM_LIT:2> ) : <EOL> i += <NUM_LIT:0.5> <EOL> angle1 = ( <EOL> ( ( <NUM_LIT:2> * angle - way ) + i * way * dash / chl ) / <EOL> <NUM_LIT:4> * math . pi ) <EOL> angle2 = ( min if way > <NUM_LIT:0> else max ) ( <EOL> ( ( <NUM_LIT:2> * angle - way ) + ( i + <NUM_LIT:1> ) * way * dash / chl ) / <EOL> <NUM_LIT:4> * math . pi , <EOL> angle * math . pi / <NUM_LIT:2> ) <EOL> if side in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> context . move_to ( x + px , main_offset + py ) <EOL> context . line_to ( <EOL> x + px - way * px * <NUM_LIT:1> / math . tan ( angle2 ) , <EOL> main_offset ) <EOL> context . line_to ( <EOL> x + px - way * px * <NUM_LIT:1> / math . tan ( angle1 ) , <EOL> main_offset ) <EOL> elif side in ( '<STR_LIT:left>' , '<STR_LIT:right>' ) : <EOL> context . move_to ( main_offset + px , y + py ) <EOL> context . line_to ( <EOL> main_offset , <EOL> y + py + way * py * math . tan ( angle2 ) ) <EOL> context . line_to ( <EOL> main_offset , <EOL> y + py + way * py * math . tan ( angle1 ) ) <EOL> if angle2 == angle * math . pi / <NUM_LIT:2> : <EOL> offset = ( angle1 - angle2 ) / ( ( <EOL> ( ( <NUM_LIT:2> * angle - way ) + ( i + <NUM_LIT:1> ) * way * dash / chl ) / <EOL> <NUM_LIT:4> * math . pi ) - angle1 ) <EOL> line += <NUM_LIT:1> <EOL> break <EOL> else : <EOL> offset = <NUM_LIT:1> - ( <EOL> ( angle * math . pi / <NUM_LIT:2> - angle2 ) / ( angle2 - angle1 ) ) <EOL> return line , offset <EOL> line , offset = draw_dots ( <EOL> dashes1 , line , way , bbx , bby , px1 , py1 , chl1 ) <EOL> line = draw_dots ( <EOL> dashes2 , line , - way , bbx + bbw , bby + bbh , px2 , py2 , chl2 ) [ <NUM_LIT:0> ] <EOL> if line_length > <NUM_LIT> : <EOL> for i in range ( <NUM_LIT:0> , line , <NUM_LIT:2> ) : <EOL> i += offset <EOL> if side in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> x1 = max ( bbx + px1 + i * dash , bbx + px1 ) <EOL> x2 = min ( bbx + px1 + ( i + <NUM_LIT:1> ) * dash , bbx + bbw + px2 ) <EOL> y1 = main_offset - ( width if way < <NUM_LIT:0> else <NUM_LIT:0> ) <EOL> y2 = y1 + width <EOL> elif side in ( '<STR_LIT:left>' , '<STR_LIT:right>' ) : <EOL> y1 = max ( bby + py1 + i * dash , bby + py1 ) <EOL> y2 = min ( bby + py1 + ( i + <NUM_LIT:1> ) * dash , bby + bbh + py2 ) <EOL> x1 = main_offset - ( width if way > <NUM_LIT:0> else <NUM_LIT:0> ) <EOL> x2 = x1 + width <EOL> context . rectangle ( x1 , y1 , x2 - x1 , y2 - y1 ) <EOL> else : <EOL> context . clip ( ) <EOL> dash = length / ( <EOL> round ( length / dash ) - ( round ( length / dash ) + <NUM_LIT:1> ) % <NUM_LIT:2> ) or <NUM_LIT:1> <EOL> for i in range ( <NUM_LIT:0> , int ( round ( length / dash ) ) , <NUM_LIT:2> ) : <EOL> if side == '<STR_LIT>' : <EOL> context . rectangle ( <EOL> bbx + i * dash , bby , dash , width ) <EOL> elif side == '<STR_LIT:right>' : <EOL> context . rectangle ( <EOL> bbx + bbw - width , bby + i * dash , width , dash ) <EOL> elif side == '<STR_LIT>' : <EOL> context . rectangle ( <EOL> bbx + i * dash , bby + bbh - width , dash , width ) <EOL> elif side == '<STR_LIT:left>' : <EOL> context . rectangle ( <EOL> bbx , bby + i * dash , width , dash ) <EOL> context . clip ( ) <EOL> def draw_rounded_border ( context , box , style , color ) : <EOL> context . set_fill_rule ( cairo . FILL_RULE_EVEN_ODD ) <EOL> rounded_box_path ( context , box . rounded_padding_box ( ) ) <EOL> if style in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> rounded_box_path ( context , box . rounded_box_ratio ( <NUM_LIT:1> / <NUM_LIT:2> ) ) <EOL> context . set_source_rgba ( * color [ <NUM_LIT:0> ] ) <EOL> context . fill ( ) <EOL> rounded_box_path ( context , box . rounded_box_ratio ( <NUM_LIT:1> / <NUM_LIT:2> ) ) <EOL> rounded_box_path ( context , box . rounded_border_box ( ) ) <EOL> context . set_source_rgba ( * color [ <NUM_LIT:1> ] ) <EOL> context . fill ( ) <EOL> return <EOL> if style == '<STR_LIT>' : <EOL> rounded_box_path ( context , box . rounded_box_ratio ( <NUM_LIT:1> / <NUM_LIT:3> ) ) <EOL> rounded_box_path ( context , box . rounded_box_ratio ( <NUM_LIT:2> / <NUM_LIT:3> ) ) <EOL> rounded_box_path ( context , box . rounded_border_box ( ) ) <EOL> context . set_source_rgba ( * color ) <EOL> context . fill ( ) <EOL> def draw_rect_border ( context , box , widths , style , color ) : <EOL> context . set_fill_rule ( cairo . FILL_RULE_EVEN_ODD ) <EOL> bbx , bby , bbw , bbh = box <EOL> bt , br , bb , bl = widths <EOL> context . rectangle ( * box ) <EOL> if style in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> context . rectangle ( <EOL> bbx + bl / <NUM_LIT:2> , bby + bt / <NUM_LIT:2> , <EOL> bbw - ( bl + br ) / <NUM_LIT:2> , bbh - ( bt + bb ) / <NUM_LIT:2> ) <EOL> context . set_source_rgba ( * color [ <NUM_LIT:0> ] ) <EOL> context . fill ( ) <EOL> context . rectangle ( <EOL> bbx + bl / <NUM_LIT:2> , bby + bt / <NUM_LIT:2> , <EOL> bbw - ( bl + br ) / <NUM_LIT:2> , bbh - ( bt + bb ) / <NUM_LIT:2> ) <EOL> context . rectangle ( <EOL> bbx + bl , bby + bt , bbw - bl - br , bbh - bt - bb ) <EOL> context . set_source_rgba ( * color [ <NUM_LIT:1> ] ) <EOL> context . fill ( ) <EOL> return <EOL> if style == '<STR_LIT>' : <EOL> context . rectangle ( <EOL> bbx + bl / <NUM_LIT:3> , bby + bt / <NUM_LIT:3> , <EOL> bbw - ( bl + br ) / <NUM_LIT:3> , bbh - ( bt + bb ) / <NUM_LIT:3> ) <EOL> context . rectangle ( <EOL> bbx + bl * <NUM_LIT:2> / <NUM_LIT:3> , bby + bt * <NUM_LIT:2> / <NUM_LIT:3> , <EOL> bbw - ( bl + br ) * <NUM_LIT:2> / <NUM_LIT:3> , bbh - ( bt + bb ) * <NUM_LIT:2> / <NUM_LIT:3> ) <EOL> context . rectangle ( bbx + bl , bby + bt , bbw - bl - br , bbh - bt - bb ) <EOL> context . set_source_rgba ( * color ) <EOL> context . fill ( ) <EOL> def draw_outlines ( context , box , enable_hinting ) : <EOL> width = box . style . outline_width <EOL> color = box . style . get_color ( '<STR_LIT>' ) <EOL> style = box . style . outline_style <EOL> if box . style . visibility == '<STR_LIT>' and width != <NUM_LIT:0> and color . alpha != <NUM_LIT:0> : <EOL> outline_box = ( <EOL> box . border_box_x ( ) - width , box . border_box_y ( ) - width , <EOL> box . border_width ( ) + <NUM_LIT:2> * width , box . border_height ( ) + <NUM_LIT:2> * width ) <EOL> for side in SIDES : <EOL> with stacked ( context ) : <EOL> clip_border_segment ( <EOL> context , enable_hinting , style , width , side , outline_box ) <EOL> draw_rect_border ( <EOL> context , outline_box , <NUM_LIT:4> * ( width , ) , style , <EOL> styled_color ( style , color , side ) ) <EOL> if isinstance ( box , boxes . ParentBox ) : <EOL> for child in box . children : <EOL> if isinstance ( child , boxes . Box ) : <EOL> draw_outlines ( context , child , enable_hinting ) <EOL> def draw_collapsed_borders ( context , table , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> row_heights = [ row . height for row_group in table . children <EOL> for row in row_group . children ] <EOL> column_widths = table . column_widths <EOL> if not ( row_heights and column_widths ) : <EOL> return <EOL> row_positions = [ row . position_y for row_group in table . children <EOL> for row in row_group . children ] <EOL> column_positions = list ( table . column_positions ) <EOL> grid_height = len ( row_heights ) <EOL> grid_width = len ( column_widths ) <EOL> assert grid_width == len ( column_positions ) <EOL> column_positions += [ column_positions [ - <NUM_LIT:1> ] + column_widths [ - <NUM_LIT:1> ] ] <EOL> row_positions . append ( row_positions [ - <NUM_LIT:1> ] + row_heights [ - <NUM_LIT:1> ] ) <EOL> vertical_borders , horizontal_borders = table . collapsed_border_grid <EOL> if table . children [ <NUM_LIT:0> ] . is_header : <EOL> header_rows = len ( table . children [ <NUM_LIT:0> ] . children ) <EOL> else : <EOL> header_rows = <NUM_LIT:0> <EOL> if table . children [ - <NUM_LIT:1> ] . is_footer : <EOL> footer_rows = len ( table . children [ - <NUM_LIT:1> ] . children ) <EOL> else : <EOL> footer_rows = <NUM_LIT:0> <EOL> skipped_rows = table . skipped_rows <EOL> if skipped_rows : <EOL> body_rows_offset = skipped_rows - header_rows <EOL> else : <EOL> body_rows_offset = <NUM_LIT:0> <EOL> if header_rows == <NUM_LIT:0> : <EOL> header_rows = - <NUM_LIT:1> <EOL> if footer_rows : <EOL> first_footer_row = grid_height - footer_rows - <NUM_LIT:1> <EOL> else : <EOL> first_footer_row = grid_height + <NUM_LIT:1> <EOL> original_grid_height = len ( vertical_borders ) <EOL> footer_rows_offset = original_grid_height - grid_height <EOL> def row_number ( y , horizontal ) : <EOL> if y < ( header_rows + int ( horizontal ) ) : <EOL> return y <EOL> elif y >= ( first_footer_row + int ( horizontal ) ) : <EOL> return y + footer_rows_offset <EOL> else : <EOL> return y + body_rows_offset <EOL> segments = [ ] <EOL> def half_max_width ( border_list , yx_pairs , vertical = True ) : <EOL> result = <NUM_LIT:0> <EOL> for y , x in yx_pairs : <EOL> if ( <EOL> ( <NUM_LIT:0> <= y < grid_height and <NUM_LIT:0> <= x <= grid_width ) <EOL> if vertical else <EOL> ( <NUM_LIT:0> <= y <= grid_height and <NUM_LIT:0> <= x < grid_width ) <EOL> ) : <EOL> yy = row_number ( y , horizontal = not vertical ) <EOL> _ , ( _ , width , _ ) = border_list [ yy ] [ x ] <EOL> result = max ( result , width ) <EOL> return result / <NUM_LIT:2> <EOL> def add_vertical ( x , y ) : <EOL> yy = row_number ( y , horizontal = False ) <EOL> score , ( style , width , color ) = vertical_borders [ yy ] [ x ] <EOL> if width == <NUM_LIT:0> or color . alpha == <NUM_LIT:0> : <EOL> return <EOL> pos_x = column_positions [ x ] <EOL> pos_y1 = row_positions [ y ] - half_max_width ( horizontal_borders , [ <EOL> ( y , x - <NUM_LIT:1> ) , ( y , x ) ] , vertical = False ) <EOL> pos_y2 = row_positions [ y + <NUM_LIT:1> ] + half_max_width ( horizontal_borders , [ <EOL> ( y + <NUM_LIT:1> , x - <NUM_LIT:1> ) , ( y + <NUM_LIT:1> , x ) ] , vertical = False ) <EOL> segments . append ( ( <EOL> score , style , width , color , '<STR_LIT:left>' , <EOL> ( pos_x - width / <NUM_LIT:2> , pos_y1 , <NUM_LIT:0> , pos_y2 - pos_y1 ) ) ) <EOL> def add_horizontal ( x , y ) : <EOL> yy = row_number ( y , horizontal = True ) <EOL> score , ( style , width , color ) = horizontal_borders [ yy ] [ x ] <EOL> if width == <NUM_LIT:0> or color . alpha == <NUM_LIT:0> : <EOL> return <EOL> pos_y = row_positions [ y ] <EOL> pos_x1 = column_positions [ x ] - half_max_width ( vertical_borders , [ <EOL> ( y - <NUM_LIT:1> , x ) , ( y , x ) ] ) <EOL> pos_x2 = column_positions [ x + <NUM_LIT:1> ] + half_max_width ( vertical_borders , [ <EOL> ( y - <NUM_LIT:1> , x + <NUM_LIT:1> ) , ( y , x + <NUM_LIT:1> ) ] ) <EOL> segments . append ( ( <EOL> score , style , width , color , '<STR_LIT>' , <EOL> ( pos_x1 , pos_y - width / <NUM_LIT:2> , pos_x2 - pos_x1 , <NUM_LIT:0> ) ) ) <EOL> for x in xrange ( grid_width ) : <EOL> add_horizontal ( x , <NUM_LIT:0> ) <EOL> for y in xrange ( grid_height ) : <EOL> add_vertical ( <NUM_LIT:0> , y ) <EOL> for x in xrange ( grid_width ) : <EOL> add_vertical ( x + <NUM_LIT:1> , y ) <EOL> add_horizontal ( x , y + <NUM_LIT:1> ) <EOL> segments . sort ( key = operator . itemgetter ( <NUM_LIT:0> ) ) <EOL> for segment in segments : <EOL> _ , style , width , color , side , border_box = segment <EOL> if side == '<STR_LIT>' : <EOL> widths = ( width , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> else : <EOL> widths = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , width ) <EOL> with stacked ( context ) : <EOL> clip_border_segment ( <EOL> context , enable_hinting , style , width , side , border_box , <EOL> widths ) <EOL> draw_rect_border ( <EOL> context , border_box , widths , style , <EOL> styled_color ( style , color , side ) ) <EOL> def draw_replacedbox ( context , box ) : <EOL> """<STR_LIT>""" <EOL> if box . style . visibility != '<STR_LIT>' or box . width == <NUM_LIT:0> or box . height == <NUM_LIT:0> : <EOL> return <EOL> with stacked ( context ) : <EOL> rounded_box_path ( context , box . rounded_content_box ( ) ) <EOL> context . clip ( ) <EOL> context . translate ( box . content_box_x ( ) , box . content_box_y ( ) ) <EOL> box . replacement . draw ( <EOL> context , box . width , box . height , box . style . image_rendering ) <EOL> def draw_inline_level ( context , page , box , enable_hinting ) : <EOL> if isinstance ( box , StackingContext ) : <EOL> stacking_context = box <EOL> assert isinstance ( stacking_context . box , boxes . InlineBlockBox ) <EOL> draw_stacking_context ( context , stacking_context , enable_hinting ) <EOL> else : <EOL> draw_background ( context , box . background , enable_hinting ) <EOL> draw_border ( context , box , enable_hinting ) <EOL> if isinstance ( box , ( boxes . InlineBox , boxes . LineBox ) ) : <EOL> for child in box . children : <EOL> if isinstance ( child , boxes . TextBox ) : <EOL> draw_text ( context , child , enable_hinting ) <EOL> else : <EOL> draw_inline_level ( context , page , child , enable_hinting ) <EOL> elif isinstance ( box , boxes . InlineReplacedBox ) : <EOL> draw_replacedbox ( context , box ) <EOL> else : <EOL> assert isinstance ( box , boxes . TextBox ) <EOL> draw_text ( context , box , enable_hinting ) <EOL> def draw_text ( context , textbox , enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> assert textbox . style . font_size <EOL> if textbox . style . visibility != '<STR_LIT>' : <EOL> return <EOL> context . move_to ( textbox . position_x , textbox . position_y + textbox . baseline ) <EOL> context . set_source_rgba ( * textbox . style . color ) <EOL> show_first_line ( context , textbox . pango_layout , enable_hinting ) <EOL> values = textbox . style . text_decoration <EOL> metrics = textbox . pango_layout . get_font_metrics ( ) <EOL> thickness = textbox . style . font_size / <NUM_LIT> <EOL> if enable_hinting and thickness < <NUM_LIT:1> : <EOL> thickness = <NUM_LIT:1> <EOL> if '<STR_LIT>' in values : <EOL> draw_text_decoration ( <EOL> context , textbox , <EOL> textbox . baseline - metrics . ascent + thickness / <NUM_LIT:2> , <EOL> thickness , enable_hinting ) <EOL> if '<STR_LIT>' in values : <EOL> draw_text_decoration ( <EOL> context , textbox , <EOL> textbox . baseline - metrics . underline_position + thickness / <NUM_LIT:2> , <EOL> thickness , enable_hinting ) <EOL> if '<STR_LIT>' in values : <EOL> draw_text_decoration ( <EOL> context , textbox , <EOL> textbox . baseline - metrics . strikethrough_position , <EOL> thickness , enable_hinting ) <EOL> def draw_text_decoration ( context , textbox , offset_y , thickness , <EOL> enable_hinting ) : <EOL> """<STR_LIT>""" <EOL> with stacked ( context ) : <EOL> if enable_hinting : <EOL> context . set_antialias ( cairo . ANTIALIAS_NONE ) <EOL> context . set_source_rgba ( * textbox . style . color ) <EOL> context . set_line_width ( thickness ) <EOL> context . move_to ( textbox . position_x , textbox . position_y + offset_y ) <EOL> context . rel_line_to ( textbox . width , <NUM_LIT:0> ) <EOL> context . stroke ( ) </s>
