コード例 #1
0
 function get_min_max_width()
 {
     $style = $this->_frame->get_style();
     $this->_block_parent = $this->_frame->find_block_parent();
     $line_width = $this->_frame->get_containing_block("w");
     $str = $text = $this->_frame->get_text();
     $size = $style->font_size;
     $font = $style->font_family;
     $word_spacing = $style->length_in_pt($style->word_spacing);
     $char_spacing = $style->length_in_pt($style->letter_spacing);
     switch ($style->white_space) {
         default:
         case "normal":
             $str = preg_replace(self::$_whitespace_pattern, " ", $str);
         case "pre-wrap":
         case "pre-line":
             // Find the longest word (i.e. minimum length)
             // This technique (using arrays & an anonymous function) is actually
             // faster than doing a single-pass character by character scan.  Heh,
             // yes I took the time to bench it ;)
             $words = array_flip(preg_split("/[\\s-]+/u", $str, -1, PREG_SPLIT_DELIM_CAPTURE));
             array_walk($words, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');'));
             arsort($words);
             $min = reset($words);
             break;
         case "pre":
             $lines = array_flip(preg_split("/\n/u", $str));
             array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');'));
             arsort($lines);
             $min = reset($lines);
             break;
         case "nowrap":
             $min = Font_Metrics::get_text_width($this->_collapse_white_space($str), $font, $size, $word_spacing, $char_spacing);
             break;
     }
     switch ($style->white_space) {
         default:
         case "normal":
         case "nowrap":
             $str = preg_replace(self::$_whitespace_pattern, " ", $text);
             break;
         case "pre-line":
             //XXX: Is this correct?
             $str = preg_replace("/[ \t]+/u", " ", $text);
         case "pre-wrap":
             // Find the longest word (i.e. minimum length)
             $lines = array_flip(preg_split("/\n/", $text));
             array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . $font . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');'));
             arsort($lines);
             reset($lines);
             $str = key($lines);
             break;
     }
     $max = Font_Metrics::get_text_width($str, $font, $size, $word_spacing, $char_spacing);
     $delta = $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);
     $min += $delta;
     $max += $delta;
     return array($min, $max, "min" => $min, "max" => $max);
 }
コード例 #2
0
 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;
     // split the text into words
     $words = preg_split('/([\\s-]+)/u', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
     $wc = count($words);
     // 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 = Font_Metrics::get_text_width($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:
     //    pre_r("Text: '" . htmlspecialchars($text). "'");
     //    pre_r("width: " .$frame_width);
     //    pre_r("textwidth + delta: $text_width + $mbp_width");
     //    pre_r("font-size: $size");
     //    pre_r("cb[w]: " .$line_width);
     //    pre_r("available width: " . $available_width);
     //    pre_r("current line width: " . $current_line_width);
     //     pre_r($words);
     if ($frame_width <= $available_width) {
         return false;
     }
     // 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 = Font_Metrics::get_text_width($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 = Font_Metrics::get_text_width($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:
     //     pre_var_dump($str);
     //     pre_r("Width: ". $width);
     //     pre_r("Offset: " . $offset);
     return $offset;
 }
コード例 #3
0
        if (self::$_buggy_splittext) {
            // workaround to solve DOMText::spliText() bug parsing multibyte strings
            $node = $this->_frame->get_node();
            $txt0 = $node->substringData(0, $offset);
            $txt1 = $node->substringData($offset, mb_strlen($node->textContent) - 1);
            $node->replaceData(0, mb_strlen($node->textContent), $txt0);
            $split = $node->parentNode->appendChild(new DOMText($txt1));
        } else {
            $split = $this->_frame->get_node()->splitText($offset);
        }
        $deco = $this->copy($split);
        $p = $this->get_parent();
        $p->insert_child_after($deco, $this, false);
        if ($p instanceof Inline_Frame_Decorator) {
            $p->split($deco);
        }
        return $deco;
    }
    //........................................................................
    function delete_text($offset, $count)
    {
        $this->_frame->get_node()->deleteData($offset, $count);
    }
    //........................................................................
    function set_text($text)
    {
        $this->_frame->get_node()->data = $text;
    }
}
Text_Frame_Decorator::$_buggy_splittext = PHP_VERSION_ID < 50207;
コード例 #4
0
        if (self::$_buggy_splittext) {
            // workaround to solve DOMText::spliText() bug parsing multibyte strings
            $node = $this->_frame->get_node();
            $txt0 = $node->substringData(0, $offset);
            $txt1 = $node->substringData($offset, mb_strlen($node->textContent) - 1);
            $node->replaceData(0, mb_strlen($node->textContent), $txt0);
            $split = $node->parentNode->appendChild(new DOMText($txt1));
        } else {
            $split = $this->_frame->get_node()->splitText($offset);
        }
        $deco = $this->copy($split);
        $p = $this->get_parent();
        $p->insert_child_after($deco, $this, false);
        if ($p instanceof Inline_Frame_Decorator) {
            $p->split($deco);
        }
        return $deco;
    }
    //........................................................................
    function delete_text($offset, $count)
    {
        $this->_frame->get_node()->deleteData($offset, $count);
    }
    //........................................................................
    function set_text($text)
    {
        $this->_frame->get_node()->data = $text;
    }
}
Text_Frame_Decorator::$_buggy_splittext = version_compare(PHP_VERSION, '5.2.6', '<=');