function _findfont($name, $encoding)
 {
     $font =& $this->font_factory->get_type1($name, $encoding);
     if ($font == null) {
         $this->error_message .= $this->font_factory->error_message();
         $dummy = null;
         return $dummy;
     }
     if (!isset($this->used_encodings[$encoding])) {
         $this->used_encodings[$encoding] = true;
         $this->_write_document_prolog(ManagerEncoding::get_ps_encoding_vector($encoding));
         $this->_write_document_prolog("\n");
     }
     $fontname = $font->name();
     if (!isset($this->found_fonts[$fontname])) {
         $this->found_fonts[$fontname] = true;
         $this->_write_document_prolog("/{$fontname} /{$name} {$encoding} findfont-enc def\n");
     }
     return $font;
 }
 /**
  * TODO: cache results; replace makefont with this utility
  */
 function _read($file, $encoding)
 {
     error_log(sprintf("Parsing font file file %s for encoding %s", $file, $encoding));
     $font = new OpenTypeFile();
     $font->open($file);
     $hhea = $font->getTable('hhea');
     $head = $font->getTable('head');
     $hmtx = $font->getTable('hmtx');
     $post = $font->getTable('post');
     $cmap = $font->getTable('cmap');
     $subtable = $cmap->findSubtable(OT_CMAP_PLATFORM_WINDOWS, OT_CMAP_PLATFORM_WINDOWS_UNICODE);
     /**
      * Read character widths for selected encoding
      */
     $widths = array();
     $manager = ManagerEncoding::get();
     $map = $manager->getEncodingVector($encoding);
     foreach ($map as $code => $ucs2) {
         $glyphIndex = $subtable->lookup($ucs2);
         if (!is_null($glyphIndex)) {
             $widths[$code] = floor($hmtx->_hMetrics[$glyphIndex]['advanceWidth'] * 1000 / $head->_unitsPerEm);
         } else {
             $widths[$code] = DEFAULT_CHAR_WIDTH;
         }
     }
     // Fill unknown characters with the default char width
     for ($i = 0; $i < 256; $i++) {
         if (!isset($widths[chr($i)])) {
             $widths[chr($i)] = DEFAULT_CHAR_WIDTH;
         }
     }
     $this->ascender = floor($hhea->_ascender * 1000 / $head->_unitsPerEm);
     $this->descender = floor($hhea->_descender * 1000 / $head->_unitsPerEm);
     $this->bbox = array($head->_xMin * 1000 / $head->_unitsPerEm, $head->_yMin * 1000 / $head->_unitsPerEm, $head->_xMax * 1000 / $head->_unitsPerEm, $head->_yMax * 1000 / $head->_unitsPerEm);
     $this->underline_position = floor($post->_underlinePosition * 1000 / $head->_unitsPerEm);
     $this->underline_thickness = floor($post->_underlineThickness * 1000 / $head->_unitsPerEm);
     $this->char_widths = $widths;
     $font->close();
 }
예제 #3
0
 function generate_cpg($encoding, $force = false)
 {
     if (!$force) {
         $filename = CACHE_DIR . $encoding . '.cpg';
     } else {
         $filename = CACHE_DIR . uniqid('', false) . '.cpg';
     }
     if (file_exists($filename)) {
         return $filename;
     }
     $output = fopen($filename, 'w');
     $manager_encoding =& ManagerEncoding::get();
     $vector = $manager_encoding->get_encoding_vector($encoding);
     foreach ($vector as $code => $utf) {
         fwrite($output, sprintf("0x%04X 0x%02X\n", $utf, ord($code)));
     }
     fclose($output);
     return $filename;
 }
예제 #4
0
 function get_content_callback($word, $encoding)
 {
     $manager_encoding =& ManagerEncoding::get();
     return $manager_encoding->to_utf8($word, $encoding);
 }
예제 #5
0
 function break_into_words($content)
 {
     $content = trim($content);
     if ($content == '') {
         return array();
     }
     // Extract Unicode characters from the raw content data
     $ptr = 0;
     $utf8_chars = array();
     $ucs2_chars = array();
     $size = strlen($content);
     while ($ptr < $size) {
         $utf8_char = ManagerEncoding::get_next_utf8_char($content, $ptr);
         $utf8_chars[] = $utf8_char;
         $ucs2_chars[] = utf8_to_code($utf8_char);
     }
     // Get unicode line breaking classes
     $classes = array_map(array($this, 'get_line_break_class'), $ucs2_chars);
     $this->find_line_break($classes, $breaks, count($classes));
     // Make words array
     $words = array();
     $word = '';
     for ($i = 0, $size = count($breaks); $i < $size; $i++) {
         $word .= $utf8_chars[$i];
         $break = $breaks[$i];
         if ($break == LB_INDIRECT || $break == LB_INDIRECT_CM || $break == LB_DIRECT || $break == LB_EXPLICIT) {
             $words[] = trim($word);
             $word = '';
         }
     }
     return $words;
 }
 function process_word($raw_content, &$pipeline)
 {
     if ($raw_content === '') {
         return false;
     }
     $ptr = 0;
     $word = '';
     $hyphens = array();
     $encoding = 'iso-8859-1';
     $manager_encoding =& ManagerEncoding::get();
     $text_box =& TextBox::create_empty($pipeline);
     $len = strlen($raw_content);
     while ($ptr < $len) {
         $char = $manager_encoding->getNextUTF8Char($raw_content, $ptr);
         // Check if current  char is a soft hyphen  character. It it is,
         // remove it from the word  (as it should not be drawn normally)
         // and store its location
         if ($char == SYMBOL_SHY) {
             $hyphens[] = strlen($word);
         } else {
             $mapping = $manager_encoding->getMapping($char);
             /**
              * If this character is not found in predefined encoding vectors,
              * we'll use "Custom" encoding and add single-character TextBox
              *
              * @TODO: handle characters without known glyph names
              */
             if (is_null($mapping)) {
                 /**
                  * No mapping to default encoding vectors found for this character
                  */
                 /**
                  * Add last word
                  */
                 if ($word !== '') {
                     $text_box->add_subword($word, $encoding, $hyphens);
                 }
                 /**
                  * Add current symbol
                  */
                 $custom_char = $manager_encoding->addCustomChar(utf8_to_code($char));
                 $text_box->add_subword($custom_char, $manager_encoding->getCustomEncodingName(), $hyphens);
                 $word = '';
             } else {
                 if (isset($mapping[$encoding])) {
                     $word .= $mapping[$encoding];
                 } else {
                     // This condition prevents empty text boxes from appearing; say, if word starts with a national
                     // character, an () - text box with no letters will be generated, in rare case causing a random line
                     // wraps, if container is narrow
                     if ($word !== '') {
                         $text_box->add_subword($word, $encoding, $hyphens);
                     }
                     reset($mapping);
                     list($encoding, $add) = each($mapping);
                     $word = $mapping[$encoding];
                     $hyphens = array();
                 }
             }
         }
     }
     if ($word !== '') {
         $text_box->add_subword($word, $encoding, $hyphens);
     }
     $this->add_child($text_box);
     return true;
 }
예제 #7
0
function MakeFont($fontfile, $afmfile, $destdir, $destfile, $enc)
{
    // Generate a font definition file
    set_magic_quotes_runtime(0);
    ini_set('auto_detect_line_endings', '1');
    $manager = ManagerEncoding::get();
    $map = $manager->get_encoding_glyphs($enc);
    $fm = ReadAFM($afmfile, $map);
    if (is_null($fm)) {
        error_log(sprintf("Notice: Missing AFM file '%s'; attempting to parse font file '%s' directly", $afmfile, $fontfile));
        $fm = ReadTTF($fontfile, $manager->getEncodingVector($enc));
        if (is_null($fm)) {
            die(sprintf("Cannot get font metrics for '%s'", $fontfile));
        }
    }
    $diff = MakeFontEncoding($map);
    $cmap = MakeFontCMap($enc);
    $fd = MakeFontDescriptor($fm, empty($map));
    //Find font type
    if ($fontfile) {
        $ext = strtolower(substr($fontfile, -3));
        if ($ext == 'ttf') {
            $type = 'TrueType';
        } elseif ($ext == 'pfb') {
            $type = 'Type1';
        } else {
            die('<B>Error:</B> unrecognized font file extension: ' . $ext);
        }
    } else {
        if ($type != 'TrueType' and $type != 'Type1') {
            die('<B>Error:</B> incorrect font type: ' . $type);
        }
    }
    //Start generation
    $s = '<?php' . "\n";
    $s .= '$type=\'' . $type . "';\n";
    $s .= '$name=\'' . $fm['FontName'] . "';\n";
    $s .= '$desc=' . $fd . ";\n";
    if (!isset($fm['UnderlinePosition'])) {
        $fm['UnderlinePosition'] = -100;
    }
    if (!isset($fm['UnderlineThickness'])) {
        $fm['UnderlineThickness'] = 50;
    }
    $s .= '$up=' . $fm['UnderlinePosition'] . ";\n";
    $s .= '$ut=' . $fm['UnderlineThickness'] . ";\n";
    $w = MakeWidthArray($fm);
    $s .= '$cw=' . $w . ";\n";
    $s .= '$enc=\'' . $enc . "';\n";
    $s .= '$diff=\'' . $diff . "';\n";
    $s .= '$cmap=' . $cmap . ";\n";
    $basename = substr(basename($afmfile), 0, -4);
    if ($fontfile) {
        //Embedded font
        if (!file_exists($fontfile)) {
            die('<B>Error:</B> font file not found: ' . $fontfile);
        }
        if ($type == 'TrueType') {
            CheckTTF($fontfile);
        }
        $f = fopen($fontfile, 'rb');
        if (!$f) {
            die('<B>Error:</B> Can\'t open ' . $fontfile);
        }
        $file = fread($f, filesize($fontfile));
        fclose($f);
        if ($type == 'Type1') {
            //Find first two sections and discard third one
            $header = ord($file[0]) == 128;
            if ($header) {
                //Strip first binary header
                $file = substr($file, 6);
            }
            $pos = strpos($file, 'eexec');
            if (!$pos) {
                die('<B>Error:</B> font file does not seem to be valid Type1');
            }
            $size1 = $pos + 6;
            if ($header and ord($file[$size1]) == 128) {
                //Strip second binary header
                $file = substr($file, 0, $size1) . substr($file, $size1 + 6);
            }
            $pos = strpos($file, '00000000');
            if (!$pos) {
                die('<B>Error:</B> font file does not seem to be valid Type1');
            }
            $size2 = $pos - $size1;
            $file = substr($file, 0, $size1 + $size2);
        }
        $gzcompress_exists = function_exists('gzcompress');
        if ($gzcompress_exists) {
            $cmp = $basename . '.z';
            SaveToFile($destdir . $cmp, gzcompress($file), 'b');
            $s .= '$file=\'' . $cmp . "';\n";
        } else {
            $cmp = $basename . '.ttf';
            SaveToFile($destdir . $cmp, $file, 'b');
            $s .= '$file=\'' . basename($fontfile) . "';\n";
            error_log('Notice: font file could not be compressed (zlib extension not available)');
        }
        if ($type == 'Type1') {
            $s .= '$size1=' . $size1 . ";\n";
            $s .= '$size2=' . $size2 . ";\n";
        } else {
            $s .= '$originalsize=' . filesize($fontfile) . ";\n";
        }
    } else {
        //Not embedded font
        $s .= '$file=' . "'';\n";
    }
    $s .= "?>\n";
    SaveToFile($destdir . $destfile, $s);
}
예제 #8
0
 function _LoadFont($fontkey, $family, $encoding)
 {
     if (!isset($this->fonts[$fontkey])) {
         global $g_font_resolver_pdf;
         $file = $g_font_resolver_pdf->ttf_mappings[$family];
         $embed = $g_font_resolver_pdf->embed[$family];
         // Remove the '.ttf' suffix
         $file = substr($file, 0, strlen($file) - 4);
         // Generate (if required) PHP font description files
         if (!file_exists($this->_getfontpath() . $fontkey . '.php') || ManagerEncoding::is_custom_encoding($encoding)) {
             // As MakeFont squeaks a lot, we'll need to capture and discard its output
             MakeFont(TTF_FONTS_REPOSITORY . $file . '.ttf', TTF_FONTS_REPOSITORY . $file . '.afm', $this->_getfontpath(), $fontkey . '.php', $encoding);
         }
         $this->AddFont($fontkey, $family, $encoding, $fontkey . '.php', $embed);
     }
 }