<?
require_once "Font.php";
class PdfFontCollection {
/**
* track if the current font is bolded or italicised
*/
var $currentTextState = '';
var $currentBaseFont;
var $currentFont;
var $currentFontNum;
var $selectedFont;
var $fontFamilies;
var $fonts = array();
var $fontNum = 0;
var $baseFontDir;
var $baseCFontDir;
var $objects;
function PdfFontCollection (&$objects,$path=false,$cPath=false) {
$this->objects = &$objects;
$this->baseFontDir = $path;
$this->baseCFontDir = $cPath;
}
function add(&$font,$path=false) {
$fnt = pathinfo($font);
if (isset($fnt['extension']))
$font = str_replace('.'.$fnt['extension'],"",$fnt['basename']);
else
$font = $fnt['basename'];
if (!isset($this->fonts[$font])){
// echo "Font was not set: ".$font."<br>";
$path = !$path?$this->baseFontDir:$path;
$f = &new PdfFont($this->objects,$font,$path,$this->baseCFontDir);
if ($f->isLoaded) {
$this->fontNum++;
$f->fontNum=$this->fontNum;
$this->fonts[$font]=$f;
// $this->fonts[$font]['fontNum']=fontNum;
// $this->fonts[$font]['fontNum']=$this->fontNum++;
return $this->fonts[$font];
} else {
$f = false;
return $f;
}
}
// echo "Font is set: ".$font."<br>";
return false;
}
/**
* if the font is not loaded then load it and make the required object
* else just make it the current font
* the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding'
* note that encoding='none' will need to be used for symbolic fonts
* and 'differences' => an array of mappings between numbers 0->255 and character names.
*
*/
function select($font,$encoding='',$set=true) {
// load the file
$fl = &$this->add($font);
if (false !== $fl) {
$fontExt = array();
// $this->numObj++;
// $this->numFonts++;
$options=array('name' =>$font,
'fontNum'=>$this->fontNum);
if (is_array($encoding)){
// then encoding and differences might be set
if (isset($encoding['encoding'])) $options['encoding']=$encoding['encoding'];
if (isset($encoding['differences'])) $options['differences']=$encoding['differences'];
} else if (strlen($encoding)>0){
// then perhaps only the encoding has been set
$options['encoding']=$encoding;
}
// $fontObj = $this->numObj; //®¬¥à ä®â = ®¬¥à ⥪ã饣® ®¡ê¥ªâ
// $this->objects->font'][] = $options;
$this->objects->createObject('PdfObjectFont',$options); //á®§¤ ¥¬ ®¡ê¥ªâ ä®â
$fl->addPfbTtf($font,$options,$fontExt);
////////////////////////////////////////////
////////////////////////////////////////////
////////////////////////////////////////////
// also set the differences here, note that this means that these will take effect only the
//first time that a font is selected, else they are ignored
if (isset($options['differences'])){
$this->fonts[$font]['differences']=$options['differences'];
}
}
if ($set && isset($this->fonts[$font])){
// so if for some reason the font was not set in the last one then it will not be selected
$this->currentBaseFont=$font;
// the next line means that if a new font is selected, then the current text state will be
// applied to it as well.
$this->setCurrentFont();
}
return $this->currentFontNum;
}
/**
* define font families, this is used to initialize the font families for the default fonts
* and for the user to add new ones for their fonts. The default bahavious can be overridden should
* that be desired.
*/
function setFontFamily($family,$options=''){
if (!is_array($options)) {
if ($family=='init'){
// set the known family groups
// these font families will be used to enable bold and italic markers to be included
// within text streams. html forms will be used... <b></b> <i></i>
$this->fontFamilies['Helvetica'] = array('b'=>'Helvetica-Bold',
'i'=>'Helvetica-Oblique',
'bi'=>'Helvetica-BoldOblique',
'ib'=>'Helvetica-BoldOblique');
$this->fontFamilies['Courier'] = array('b'=>'Courier-Bold',
'i'=>'Courier-Oblique',
'bi'=>'Courier-BoldOblique',
'ib'=>'Courier-BoldOblique');
$this->fontFamilies['Times-Roman'] = array('b'=>'Times-Bold',
'i'=>'Times-Italic',
'bi'=>'Times-BoldItalic',
'ib'=>'Times-BoldItalic');
}
} else {
// the user is trying to set a font family
// note that this can also be used to set the base ones to something else
if (strlen($family)) $this->fontFamilies[$family] = $options;
}
}
/**
* sets up the current font, based on the font families, and the current text state
* note that this system is quite flexible, a <b><i> font can be completely different to a
* <i><b> font, and even <b><b> will have to be defined within the family to have meaning
* This function is to be called whenever the currentTextState is changed, it will update
* the currentFont setting to whatever the appropriatte family one is.
* If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont
* This function will change the currentFont to whatever it should be, but will not change the
* currentBaseFont.
*
* @access private
*/
function setCurrentFont($textState=false){
if (strlen($this->currentBaseFont)==0){
// then assume an initial font
$this->select('Helvetica');
}
$cf = $this->currentBaseFont;
if (strlen($textState) && isset($this->fontFamilies[$cf]) && isset($this->fontFamilies[$cf][$textState])) {
// then we are in some state or another
// and this font has a family, and the current setting exists within it
// select the font, then return it
$nf = $this->fontFamilies[$cf][$textState];
$this->selectFont($nf,'',false);
$this->currentFont = $nf;
// $this->currentFontNum = $this->fonts[$nf]['fontNum'];
$this->currentFontNum = $this->fonts[$nf]->fontNum;
} else {
// the this font must not have the right family member for the current state
// simply assume the base font
$this->currentFont = $this->currentBaseFont;
// $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum'];
$this->currentFontNum = $this->fonts[$this->currentFont]->fontNum;
}
}
/**
* return the height in units of the current font in the given size
*/
function getFontHeight($size){
if (!$this->hasFonts()){
$this->selectFont('Helvetica');
}
// for the current font, and the given size, what is the height of the font in user units
$h = $this->fonts[$this->currentFont]->fontDesc['FontBBox'][3]-$this->fonts[$this->currentFont]->fontDesc['FontBBox'][1];
return $size*$h/1000;
}
/**
* return the font decender, this will normally return a negative number
* if you add this number to the baseline, you get the level of the bottom of the font
* it is in the pdf user units
*/
function getFontDecender($size){
// note that this will most likely return a negative value
if (!$this->hasFonts()){
$this->selectFont('Helvetica');
}
$h = $this->fonts[$this->currentFont]->fontDesc['FontBBox'][1];
return $size*$h/1000;
}
function hasFonts() {
return (boolean)$this->fontNum;
}
}
?>