diff --git a/lib/pdflib.php b/lib/pdflib.php index cd2048b5770..0945ff8d4eb 100644 --- a/lib/pdflib.php +++ b/lib/pdflib.php @@ -22,12 +22,29 @@ * * The default location for fonts that are included with TCPDF is * lib/tcpdf/fonts/. If PDF_CUSTOM_FONT_PATH exists, this directory - * will be used instead of lib/tcpdf/fonts/. If there is only one font - * present in PDF_CUSTOM_FONT_PATH, the font is used as the default - * font. + * will be used instead of lib/tcpdf/fonts/, the default location is + * $CFG->dataroot.'/fonts/'. * - * See lib/tcpdf/fonts/README for details on how to convert fonts for use - * with TCPDF. + * You should always copy all fonts from lib/tcpdf/fonts/ to your + * PDF_CUSTOM_FONT_PATH and then add extra fonts. Alternatively + * you may download all TCPDF fonts from http://www.tcpdf.org/download.php + * and extract them to PDF_CUSTOM_FONT_PATH directory. + * + * You can specify your own default font family in config.php + * by defining PDF_DEFAULT_FONT constant there. + * + * If you want to add True Type fonts such as "Arial Unicode MS", + * you need to create a simple script and then execute it, it should add + * new file to your fonts directory: + * + * libdir . '/pdflib.php'); + * TCPDF_FONTS::addTTFfont('/full_path_to/ARIALUNI.TTF', 'TrueTypeUnicode'); + * + * This script will convert the TTF file to format compatible with TCPDF. + * + * Please note you need to have appropriate license to use the font files on your server! * * Example usage: * @@ -46,26 +63,71 @@ defined('MOODLE_INTERNAL') || die(); -/** defines the site-specific location of fonts */ -define('PDF_CUSTOM_FONT_PATH', $CFG->dataroot.'/fonts/'); +if (!defined('PDF_CUSTOM_FONT_PATH')) { + /** Defines the site-specific location of fonts. */ + define('PDF_CUSTOM_FONT_PATH', $CFG->dataroot.'/fonts/'); +} -/** default font to be used if there are more of them available */ -define('PDF_DEFAULT_FONT', 'FreeSerif'); +if (!defined('PDF_DEFAULT_FONT')) { + /** Default font to be used. */ + define('PDF_DEFAULT_FONT', 'FreeSerif'); +} /** tell tcpdf it is configured here instead of in its own config file */ define('K_TCPDF_EXTERNAL_CONFIG', 1); // The configuration constants needed by tcpdf follow +/** + * Init K_PATH_FONTS and PDF_FONT_NAME_MAIN constant. + * + * Unfortunately this hack is necessary because the constants need + * to be defined before inclusion of the tcpdf.php file. + */ +function tcpdf_init_k_font_path() { + global $CFG; + + $defaultfonts = $CFG->dirroot.'/lib/tcpdf/fonts/'; + + if (!defined('K_PATH_FONTS')) { + if (is_dir(PDF_CUSTOM_FONT_PATH)) { + // NOTE: + // There used to be an option to have just one file and having it set as default + // but that does not make sense any more because add-ons using standard fonts + // would fail very badly, also font families consist of multiple php files for + // regular, bold, italic, etc. + + // Check for some standard font files if present and if not do not use the custom path. + $somestandardfiles = array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats', 'freeserif', 'freesans'); + $missing = false; + foreach ($somestandardfiles as $file) { + if (!file_exists(PDF_CUSTOM_FONT_PATH . $file . '.php')) { + $missing = true; + break; + } + } + if ($missing) { + define('K_PATH_FONTS', $defaultfonts); + } else { + define('K_PATH_FONTS', PDF_CUSTOM_FONT_PATH); + } + } else { + define('K_PATH_FONTS', $defaultfonts); + } + } + + if (!defined('PDF_FONT_NAME_MAIN')) { + define('PDF_FONT_NAME_MAIN', strtolower(PDF_DEFAULT_FONT)); + } +} +tcpdf_init_k_font_path(); + /** tcpdf installation path */ define('K_PATH_MAIN', $CFG->dirroot.'/lib/tcpdf/'); /** URL path to tcpdf installation folder */ define('K_PATH_URL', $CFG->wwwroot . '/lib/tcpdf/'); -/** path for PDF fonts */ -define('K_PATH_FONTS', K_PATH_MAIN . 'fonts/'); - /** cache directory for temporary files (full path) */ define('K_PATH_CACHE', $CFG->cachedir . '/tcpdf/'); @@ -106,20 +168,6 @@ class pdf extends TCPDF { parent::__construct($orientation, $unit, $format, $unicode, $encoding); - if (is_dir(PDF_CUSTOM_FONT_PATH)) { - $fontfiles = $this->_getfontfiles(PDF_CUSTOM_FONT_PATH); - - if (count($fontfiles) == 1) { - $autofontname = substr($fontfiles[0], 0, -4); - $this->AddFont($autofontname, '', $autofontname.'.php'); - $this->SetFont($autofontname); - } else if (count($fontfiles == 0)) { - $this->SetFont(PDF_DEFAULT_FONT); - } - } else { - $this->SetFont(PDF_DEFAULT_FONT); - } - // theses replace the tcpdf's config/lang/ definitions $this->l['w_page'] = get_string('page'); $this->l['a_meta_language'] = current_language(); @@ -145,36 +193,61 @@ class pdf extends TCPDF { } /** - * Return fonts path - * Overriding TCPDF::_getfontpath() - * - * @global object + * Is this font family one of core fonts? + * @param string $fontfamily + * @return bool */ - protected function _getfontpath() { - global $CFG; - - if (is_dir(PDF_CUSTOM_FONT_PATH) - && count($this->_getfontfiles(PDF_CUSTOM_FONT_PATH)) > 0) { - $fontpath = PDF_CUSTOM_FONT_PATH; - } else { - $fontpath = K_PATH_FONTS; - } - return $fontpath; + public function is_core_font_family($fontfamily) { + return isset($this->CoreFonts[$fontfamily]); } /** - * Get the .php files for the fonts + * Returns list of font families and types of fonts. + * + * @return array multidimensional array with font families as keys and B, I, BI and N as values. */ - protected function _getfontfiles($fontdir) { - $dirlist = get_directory_list($fontdir); - $fontfiles = array(); - - foreach ($dirlist as $file) { - if (substr($file, -4) == '.php') { - array_push($fontfiles, $file); + public function get_font_families() { + $families = array(); + foreach ($this->fontlist as $font) { + if (strpos($font, 'uni2cid') === 0) { + // This is not an font file. + continue; } + if (strpos($font, 'cid0') === 0) { + // These do not seem to work with utf-8, better ignore them for now. + continue; + } + if (substr($font, -2) === 'bi') { + $family = substr($font, 0, -2); + if (in_array($family, $this->fontlist)) { + $families[$family]['BI'] = 'BI'; + continue; + } + } + if (substr($font, -1) === 'i') { + $family = substr($font, 0, -1); + if (in_array($family, $this->fontlist)) { + $families[$family]['I'] = 'I'; + continue; + } + } + if (substr($font, -1) === 'b') { + $family = substr($font, 0, -1); + if (in_array($family, $this->fontlist)) { + $families[$family]['B'] = 'B'; + continue; + } + } + // This must be a Family or incomplete set of fonts present. + $families[$font]['R'] = 'R'; } - return $fontfiles; - } + // Sort everything consistently. + ksort($families); + foreach ($families as $k => $v) { + krsort($families[$k]); + } + + return $families; + } } diff --git a/lib/tests/other/pdflibtestpage.php b/lib/tests/other/pdflibtestpage.php index 8a0f8754e04..f96937d0ebb 100644 --- a/lib/tests/other/pdflibtestpage.php +++ b/lib/tests/other/pdflibtestpage.php @@ -30,7 +30,11 @@ $context = context_system::instance(); require_capability('moodle/site:config', $context); $getpdf = optional_param('getpdf', 0, PARAM_INT); -$fontfamily = optional_param('fontfamily', PDF_DEFAULT_FONT, PARAM_ALPHA); // to be configurable +$fontfamily = optional_param('fontfamily', PDF_FONT_NAME_MAIN, PARAM_ALPHA); // to be configurable + +if (!$fontfamily) { + $fontfamily = PDF_FONT_NAME_MAIN; +} /** * Extend the standard PDF class to get access to some protected values we want to display @@ -39,17 +43,8 @@ $fontfamily = optional_param('fontfamily', PDF_DEFAULT_FONT, PARAM_ALPHA); // t * @copyright 2009 David Mudrak * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class testable_pdf extends pdf { - public function returnFontsList() { - return $this->fontlist; - } - public function _getfontpath() { - return parent::_getfontpath(); - } -} - if ($getpdf) { - $doc = new testable_pdf(); + $doc = new pdf(); $doc->SetTitle('Moodle PDF library test'); $doc->SetAuthor('Moodle ' . $CFG->release); @@ -81,48 +76,63 @@ if ($getpdf) { $c = '

General information

'; $c .= 'Moodle release: ' . $CFG->release . '
'; $c .= 'PDF producer: TCPDF ' . TCPDF_STATIC::getTCPDFVersion() . ' (http://www.tcpdf.org)
'; - $c .= 'Font of this test page: ' . $fontfamily . '
'; + $c .= 'Font family used: ' . $fontfamily . '
'; $c .= '

Current settings

'; $c .= ''; - foreach (array('K_PATH_MAIN', 'K_PATH_URL', 'K_PATH_FONTS', 'K_PATH_CACHE', 'K_PATH_IMAGES', 'K_BLANK_IMAGE', + foreach (array('K_PATH_MAIN', 'K_PATH_URL', 'K_PATH_FONTS', 'PDF_FONT_NAME_MAIN', 'K_PATH_CACHE', 'K_PATH_IMAGES', 'K_BLANK_IMAGE', 'K_CELL_HEIGHT_RATIO', 'K_SMALL_RATIO', 'PDF_CUSTOM_FONT_PATH', 'PDF_DEFAULT_FONT') as $setting) { if (defined($setting)) { $c .= ''; } } - $c .= ''; $c .= '
' . $setting . '' . constant($setting) . '
Effective font path' . $doc->_getfontpath() . '

'; - $c .= '

Available font files

'; - $fontfiles = $doc->returnFontsList(); - sort($fontfiles); - $c .= implode(', ', $fontfiles); - $c .= '
'; + $c .= '

Available font families

'; + $fontfamilies = $doc->get_font_families(); + $list = array(); + foreach ($fontfamilies as $family => $fonts) { + $f = $family; + $spacer = ''; + if ($doc->is_core_font_family($family)) { + $f .= '*'; + } else { + $spacer = ' '; + } + if (count($fonts) > 1) { + $f .= $spacer . '(' . implode(', ', $fonts) . ')'; + } + $list[] = $f; + } + $c .= implode($list, ', '); + $c .= '

Note: * Standard core fonts are not embedded in PDF files, PDF viewers are using local fonts.

'; $c .= '

Installed languages and their alphabets

'; $languages = array(); $langdirs = get_list_of_plugins('lang', '', $CFG->dataroot); array_unshift($langdirs, 'en'); foreach ($langdirs as $langdir) { + $enlangconfig = $CFG->dirroot . '/lang/en/langconfig.php'; if ('en' == $langdir) { - $langconfig = $CFG->dirroot . '/lang/en/langconfig.php'; + $langconfig = $enlangconfig; } else { $langconfig = $CFG->dataroot . '/lang/' . $langdir . '/langconfig.php'; } + // Ignore parents here for now. + $string = array(); if (is_readable($langconfig)) { include($langconfig); if (is_array($string)) { $languages[$langdir] = new stdClass(); $languages[$langdir]->langname = isset($string['thislanguage']) ? $string['thislanguage'] : '(unknown)'; - $languages[$langdir]->alphabet = isset($string['alphabet']) ? $string['alphabet'] : '(no alphabet defined)'; + $languages[$langdir]->alphabet = isset($string['alphabet']) ? '"' . $string['alphabet'] . '"': '(no alphabet defined)'; } } } $c .= '
'; foreach ($languages as $langcode => $language) { $c .= '
' . $language->langname . ' (' . $langcode . ')
'; - $c .= '
"' . $language->alphabet . '"
'; + $c .= '
' . $language->alphabet . '
'; } $c .= '
'; @@ -139,5 +149,5 @@ $PAGE->set_heading('PDF library test'); echo $OUTPUT->header(); echo $OUTPUT->heading('Press the button to generate test PDF', 2); -echo $OUTPUT->continue_button(new moodle_url($PAGE->url, array('getpdf' => 1))); +echo $OUTPUT->continue_button(new moodle_url($PAGE->url, array('getpdf' => 1, 'fontfamily' => PDF_FONT_NAME_MAIN))); echo $OUTPUT->footer();