function _findfont($name, $encoding) { $font =& $this->font_factory->get_type1($name, $encoding); if (is_null($font)) { $this->error_message .= $this->font_factory->error_message(); $dummy = null; return $dummy; } if (!isset($this->used_encodings[$encoding])) { $this->used_encodings[$encoding] = true; $manager = ManagerEncoding::get(); $this->_write_document_prolog($manager->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(); }
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; }
function get_content_callback($word, $encoding) { $manager_encoding =& ManagerEncoding::get(); return $manager_encoding->to_utf8($word, $encoding); }
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; }
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); }