function get_float_offsets() { $enable_css_float = $this->_block_frame->get_dompdf()->get_option("enable_css_float"); if (!$enable_css_float) { return; } static $anti_infinite_loop = 500; // FIXME smelly hack $reflower = $this->_block_frame->get_reflower(); if (!$reflower) { return; } $cb_w = null; $block = $this->_block_frame; $root = $block->get_root(); if (!$root) { return; } $floating_frames = $this->get_floats_inside($root); foreach ($floating_frames as $child_key => $floating_frame) { $id = $floating_frame->get_id(); if (isset($this->floating_blocks[$id])) { continue; } $floating_style = $floating_frame->get_style(); $float = $floating_style->float; $floating_width = $floating_frame->get_margin_width(); if (!$cb_w) { $cb_w = $floating_frame->get_containing_block("w"); } $line_w = $this->get_width(); if (!$floating_frame->_float_next_line && $cb_w <= $line_w + $floating_width && $cb_w > $line_w) { $floating_frame->_float_next_line = true; continue; } // If the child is still shifted by the floating element if ($anti_infinite_loop-- > 0 && $floating_frame->get_position("y") + $floating_frame->get_margin_height() > $this->y && $block->get_position("x") + $block->get_margin_width() > $floating_frame->get_position("x")) { if ($float === "left") { $this->left += $floating_width; } else { $this->right += $floating_width; } $this->floating_blocks[$id] = true; } else { $root->remove_floating_frame($child_key); } } }
/** * @param Frame $child * @param float $cb_x * @param float $cb_w */ function process_float(Frame $child, $cb_x, $cb_w) { $enable_css_float = $this->_frame->get_dompdf()->get_option("enable_css_float"); if (!$enable_css_float) { return; } $child_style = $child->get_style(); $root = $this->_frame->get_root(); // Handle "float" if ($child_style->float !== "none") { $root->add_floating_frame($child); // Remove next frame's beginning whitespace $next = $child->get_next_sibling(); if ($next && $next instanceof TextFrameDecorator) { $next->set_text(ltrim($next->get_text())); } $line_box = $this->_frame->get_current_line_box(); list($old_x, $old_y) = $child->get_position(); $float_x = $cb_x; $float_y = $old_y; $float_w = $child->get_margin_width(); if ($child_style->clear === "none") { switch ($child_style->float) { case "left": $float_x += $line_box->left; break; case "right": $float_x += $cb_w - $line_box->right - $float_w; break; } } else { if ($child_style->float === "right") { $float_x += $cb_w - $float_w; } } if ($cb_w < $float_x + $float_w - $old_x) { // TODO handle when floating elements don't fit } $line_box->get_float_offsets(); if ($child->_float_next_line) { $float_y += $line_box->h; } $child->set_position($float_x, $float_y); $child->move($float_x - $old_x, $float_y - $old_y, true); } }