<s> """<STR_LIT>""" <EOL> from __future__ import division , unicode_literals <EOL> from . markers import list_marker_layout <EOL> from . min_max import handle_min_max_width <EOL> from . percentages import resolve_percentages , resolve_position_percentages <EOL> from . preferred import shrink_to_fit <EOL> from . tables import table_wrapper_width <EOL> from . . formatting_structure import boxes <EOL> @ handle_min_max_width <EOL> def float_width ( box , context , containing_block ) : <EOL> if box . width == '<STR_LIT>' : <EOL> box . width = shrink_to_fit ( context , box , containing_block . width ) <EOL> def float_layout ( context , box , containing_block , device_size , absolute_boxes , <EOL> fixed_boxes ) : <EOL> """<STR_LIT>""" <EOL> from . blocks import block_container_layout <EOL> from . inlines import inline_replaced_box_width_height <EOL> resolve_percentages ( box , ( containing_block . width , containing_block . height ) ) <EOL> resolve_position_percentages ( <EOL> box , ( containing_block . width , containing_block . height ) ) <EOL> if box . margin_left == '<STR_LIT>' : <EOL> box . margin_left = <NUM_LIT:0> <EOL> if box . margin_right == '<STR_LIT>' : <EOL> box . margin_right = <NUM_LIT:0> <EOL> if box . margin_top == '<STR_LIT>' : <EOL> box . margin_top = <NUM_LIT:0> <EOL> if box . margin_bottom == '<STR_LIT>' : <EOL> box . margin_bottom = <NUM_LIT:0> <EOL> clearance = get_clearance ( context , box ) <EOL> if clearance is not None : <EOL> box . position_y += clearance <EOL> if isinstance ( box , boxes . BlockReplacedBox ) : <EOL> inline_replaced_box_width_height ( box , device_size = None ) <EOL> elif box . width == '<STR_LIT>' : <EOL> float_width ( box , context , containing_block ) <EOL> if box . is_table_wrapper : <EOL> table_wrapper_width ( <EOL> context , box , ( containing_block . width , containing_block . height ) ) <EOL> if isinstance ( box , boxes . BlockBox ) : <EOL> context . create_block_formatting_context ( ) <EOL> box , _ , _ , _ , _ = block_container_layout ( <EOL> context , box , max_position_y = float ( '<STR_LIT>' ) , <EOL> skip_stack = None , device_size = device_size , page_is_empty = False , <EOL> absolute_boxes = absolute_boxes , fixed_boxes = fixed_boxes , <EOL> adjoining_margins = None ) <EOL> list_marker_layout ( context , box ) <EOL> context . finish_block_formatting_context ( box ) <EOL> else : <EOL> assert isinstance ( box , boxes . BlockReplacedBox ) <EOL> box = find_float_position ( context , box , containing_block ) <EOL> context . excluded_shapes . append ( box ) <EOL> return box <EOL> def find_float_position ( context , box , containing_block ) : <EOL> """<STR_LIT>""" <EOL> if context . excluded_shapes : <EOL> highest_y = context . excluded_shapes [ - <NUM_LIT:1> ] . position_y <EOL> if box . position_y < highest_y : <EOL> box . translate ( <NUM_LIT:0> , highest_y - box . position_y ) <EOL> position_x , position_y , available_width = avoid_collisions ( <EOL> context , box , containing_block ) <EOL> if box . style . float == '<STR_LIT:right>' : <EOL> position_x += available_width - box . margin_width ( ) <EOL> box . translate ( position_x - box . position_x , position_y - box . position_y ) <EOL> return box <EOL> def get_clearance ( context , box , collapsed_margin = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> clearance = None <EOL> hypothetical_position = box . position_y + collapsed_margin <EOL> for excluded_shape in context . excluded_shapes : <EOL> if box . style . clear in ( excluded_shape . style . float , '<STR_LIT>' ) : <EOL> y , h = excluded_shape . position_y , excluded_shape . margin_height ( ) <EOL> if hypothetical_position < y + h : <EOL> clearance = max ( <EOL> ( clearance or <NUM_LIT:0> ) , y + h - hypothetical_position ) <EOL> return clearance <EOL> def avoid_collisions ( context , box , containing_block , outer = True ) : <EOL> excluded_shapes = context . excluded_shapes <EOL> position_y = box . position_y if outer else box . border_box_y ( ) <EOL> box_width = box . margin_width ( ) if outer else box . border_width ( ) <EOL> box_height = box . margin_height ( ) if outer else box . border_height ( ) <EOL> if box . border_height ( ) == <NUM_LIT:0> and box . is_floated ( ) : <EOL> return <NUM_LIT:0> , <NUM_LIT:0> , containing_block . width <EOL> while True : <EOL> colliding_shapes = [ <EOL> shape for shape in excluded_shapes <EOL> if ( shape . position_y < position_y < <EOL> shape . position_y + shape . margin_height ( ) ) or <EOL> ( shape . position_y < position_y + box_height < <EOL> shape . position_y + shape . margin_height ( ) ) or <EOL> ( shape . position_y >= position_y and <EOL> shape . position_y + shape . margin_height ( ) <= <EOL> position_y + box_height ) <EOL> ] <EOL> left_bounds = [ <EOL> shape . position_x + shape . margin_width ( ) <EOL> for shape in colliding_shapes <EOL> if shape . style . float == '<STR_LIT:left>' ] <EOL> right_bounds = [ <EOL> shape . position_x <EOL> for shape in colliding_shapes <EOL> if shape . style . float == '<STR_LIT:right>' ] <EOL> max_left_bound = containing_block . content_box_x ( ) <EOL> max_right_bound = containing_block . content_box_x ( ) + containing_block . width <EOL> if not outer : <EOL> max_left_bound += box . margin_left <EOL> max_right_bound -= box . margin_right <EOL> if left_bounds or right_bounds : <EOL> if left_bounds : <EOL> max_left_bound = max ( max ( left_bounds ) , max_left_bound ) <EOL> if right_bounds : <EOL> max_right_bound = min ( min ( right_bounds ) , max_right_bound ) <EOL> if box_width > max_right_bound - max_left_bound : <EOL> new_positon_y = min ( <EOL> shape . position_y + shape . margin_height ( ) <EOL> for shape in colliding_shapes ) <EOL> if new_positon_y > position_y : <EOL> position_y = new_positon_y <EOL> continue <EOL> break <EOL> position_x = max_left_bound <EOL> available_width = max_right_bound - max_left_bound <EOL> if not outer : <EOL> position_x -= box . margin_left <EOL> position_y -= box . margin_top <EOL> return position_x , position_y , available_width </s>
