protected function _line_break($text) { $style = $this->_frame->get_style(); $size = $style->font_size; $font = $style->font_family; $current_line = $this->_block_parent->get_current_line_box(); // Determine the available width $line_width = $this->_frame->get_containing_block("w"); $current_line_width = $current_line->left + $current_line->w + $current_line->right; $available_width = $line_width - $current_line_width; // Account for word-spacing $word_spacing = $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); // Determine the frame width including margin, padding & border $text_width = $this->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); $mbp_width = $style->length_in_pt(array($style->margin_left, $style->border_left_width, $style->padding_left, $style->padding_right, $style->border_right_width, $style->margin_right), $line_width); $frame_width = $text_width + $mbp_width; // Debugging: // Helpers::pre_r("Text: '" . htmlspecialchars($text). "'"); // Helpers::pre_r("width: " .$frame_width); // Helpers::pre_r("textwidth + delta: $text_width + $mbp_width"); // Helpers::pre_r("font-size: $size"); // Helpers::pre_r("cb[w]: " .$line_width); // Helpers::pre_r("available width: " . $available_width); // Helpers::pre_r("current line width: " . $current_line_width); // Helpers::pre_r($words); if ($frame_width <= $available_width) { return false; } // split the text into words $words = preg_split('/([\\s-]+)/u', $text, -1, PREG_SPLIT_DELIM_CAPTURE); $wc = count($words); // Determine the split point $width = 0; $str = ""; reset($words); // @todo support <shy>, <wbr> for ($i = 0; $i < $wc; $i += 2) { $word = $words[$i] . (isset($words[$i + 1]) ? $words[$i + 1] : ""); $word_width = $this->getFontMetrics()->getTextWidth($word, $font, $size, $word_spacing, $char_spacing); if ($width + $word_width + $mbp_width > $available_width) { break; } $width += $word_width; $str .= $word; } $break_word = $style->word_wrap === "break-word"; // The first word has overflowed. Force it onto the line if ($current_line_width == 0 && $width == 0) { $s = ""; $last_width = 0; if ($break_word) { for ($j = 0; $j < strlen($word); $j++) { $s .= $word[$j]; $_width = $this->getFontMetrics()->getTextWidth($s, $font, $size, $word_spacing, $char_spacing); if ($_width > $available_width) { break; } $last_width = $_width; } } if ($break_word && $last_width > 0) { $width += $last_width; $str .= substr($s, 0, -1); } else { $width += $word_width; $str .= $word; } } $offset = mb_strlen($str); // More debugging: // var_dump($str); // print_r("Width: ". $width); // print_r("Offset: " . $offset); return $offset; }
/** * Determine current frame width based on contents * * @return float */ public function calculate_auto_width() { return $this->_frame->recalculate_width(); }