📄 cidfont.php
字号:
<?php/** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @package Zend_Pdf * @subpackage Fonts * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License *//** Zend_Pdf_Resource_Font */require_once 'Zend/Pdf/Resource/Font.php';
/** Zend_Pdf_FileParser_Font_OpenType */
require_once 'Zend/Pdf/FileParser/Font/OpenType.php';
/** Zend_Pdf_Cmap */
require_once 'Zend/Pdf/Cmap.php';
/**
* Adobe PDF CIDFont font object implementation
*
* A CIDFont program contains glyph descriptions that are accessed using a CID as
* the character selector. There are two types of CIDFont. A Type 0 CIDFont contains
* glyph descriptions based on Adobe鈥檚 Type 1 font format, whereas those in a
* Type 2 CIDFont are based on the TrueType font format.
*
* A CIDFont dictionary is a PDF object that contains information about a CIDFont program.
* Although its Type value is Font, a CIDFont is not actually a font. It does not have an Encoding
* entry, it cannot be listed in the Font subdictionary of a resource dictionary, and it cannot be
* used as the operand of the Tf operator. It is used only as a descendant of a Type 0 font.
* The CMap in the Type 0 font is what defines the encoding that maps character codes to CIDs
* in the CIDFont.
*
* Font objects should be normally be obtained from the factory methods * {@link Zend_Pdf_Font::fontWithName} and {@link Zend_Pdf_Font::fontWithPath}. * * @package Zend_Pdf * @subpackage Fonts * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */abstract class Zend_Pdf_Resource_Font_CidFont extends Zend_Pdf_Resource_Font{ /**
* Object representing the font's cmap (character to glyph map).
* @var Zend_Pdf_Cmap
*/
protected $_cmap = null;
/**
* Array containing the widths of each character that have entries in used character map.
*
* @var array
*/
protected $_charWidths = null;
/**
* Width for characters missed in the font
*
* @var integer
*/
protected $_missingCharWidth = 0;
/** * Object constructor * * @param Zend_Pdf_FileParser_Font_OpenType $fontParser Font parser object
* containing OpenType file.
* @param integer $embeddingOptions Options for font embedding.
* @throws Zend_Pdf_Exception
*/ public function __construct(Zend_Pdf_FileParser_Font_OpenType $fontParser) {
parent::__construct();
$fontParser->parse();
/* Object properties */
$this->_fontNames = $fontParser->names;
$this->_isBold = $fontParser->isBold;
$this->_isItalic = $fontParser->isItalic;
$this->_isMonospaced = $fontParser->isMonospaced;
$this->_underlinePosition = $fontParser->underlinePosition;
$this->_underlineThickness = $fontParser->underlineThickness;
$this->_strikePosition = $fontParser->strikePosition;
$this->_strikeThickness = $fontParser->strikeThickness;
$this->_unitsPerEm = $fontParser->unitsPerEm;
$this->_ascent = $fontParser->ascent;
$this->_descent = $fontParser->descent;
$this->_lineGap = $fontParser->lineGap;
$this->_cmap = $fontParser->cmap;
/* Resource dictionary */
$baseFont = $this->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT, 'en', 'UTF-8');
$this->_resource->BaseFont = new Zend_Pdf_Element_Name($baseFont);
/**
* Prepare widths array.
*/
/* Constract characters widths array using font CMap and glyphs widths array */
$glyphWidths = $fontParser->glyphWidths;
$charGlyphs = $this->_cmap->getCoveredCharactersGlyphs();
$charWidths = array();
foreach ($charGlyphs as $charCode => $glyph) {
$charWidths[$charCode] = $glyphWidths[$glyph];
}
$this->_charWidths = $charWidths;
$this->_missingCharWidth = $glyphWidths[0];
/* Width array optimization. Step1: extract default value */
$widthFrequencies = array_count_values($charWidths);
$defaultWidth = null;
$defaultWidthFrequency = -1;
foreach ($widthFrequencies as $width => $frequency) {
if ($frequency > $defaultWidthFrequency) {
$defaultWidth = $width;
$defaultWidthFrequency = $frequency;
}
}
// Store default value in the font dictionary
$this->_resource->DW = new Zend_Pdf_Element_Numeric($this->toEmSpace($defaultWidth));
// Remove characters which corresponds to default width from the widths array
$defWidthChars = array_keys($charWidths, $defaultWidth);
foreach ($defWidthChars as $charCode) {
unset($charWidths[$charCode]);
}
// Order cheracter widths aray by character codes
ksort($charWidths, SORT_NUMERIC);
/* Width array optimization. Step2: Compact character codes sequences */
$lastCharCode = -1;
$widthsSequences = array();
foreach ($charWidths as $charCode => $width) {
if ($lastCharCode == -1) {
$charCodesSequense = array();
$sequenceStartCode = $charCode;
} else if ($charCode != $lastCharCode + 1) {
// New chracters sequence detected
$widthsSequences[$sequenceStartCode] = $charCodesSequense;
$charCodesSequense = array();
$sequenceStartCode = $charCode;
}
$charCodesSequense[] = $width;
$lastCharCode = $charCode;
}
// Save last sequence, if widths array is not empty (it may happens for monospaced fonts)
if (count($charWidths) != 0) {
$widthsSequences[$sequenceStartCode] = $charCodesSequense;
}
$pdfCharsWidths = array();
foreach ($widthsSequences as $startCode => $widthsSequence) {
/* Width array optimization. Step3: Compact widths sequences */
$pdfWidths = array();
$lastWidth = -1;
$widthsInSequence = 0;
foreach ($widthsSequence as $width) {
if ($lastWidth != $width) {
// New width is detected
if ($widthsInSequence != 0) {
// Previous width value was a part of the widths sequence. Save it as 'c_1st c_last w'.
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode); // First character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode + $widthsInSequence - 1); // Last character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($this->toEmSpace($lastWidth)); // Width
// Reset widths sequence
$startCode = $startCode + $widthsInSequence;
$widthsInSequence = 0;
}
// Collect new width
$pdfWidths[] = new Zend_Pdf_Element_Numeric($this->toEmSpace($width));
$lastWidth = $width;
} else {
// Width is equal to previous
if (count($pdfWidths) != 0) {
// We already have some widths collected
// So, we've just detected new widths sequence
// Remove last element from widths list, since it's a part of widths sequence
array_pop($pdfWidths);
// and write the rest if it's not empty
if (count($pdfWidths) != 0) {
// Save it as 'c_1st [w1 w2 ... wn]'.
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode); // First character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Array($pdfWidths); // Widths array
// Reset widths collection
$startCode += count($pdfWidths);
$pdfWidths = array();
}
$widthsInSequence = 2;
} else {
// Continue widths sequence
$widthsInSequence++;
}
}
}
// Check if we have widths collection or widths sequence to wite it down
if (count($pdfWidths) != 0) {
// We have some widths collected
// Save it as 'c_1st [w1 w2 ... wn]'.
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode); // First character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Array($pdfWidths); // Widths array
} else if ($widthsInSequence != 0){
// We have widths sequence
// Save it as 'c_1st c_last w'.
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode); // First character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($startCode + $widthsInSequence - 1); // Last character code
$pdfCharsWidths[] = new Zend_Pdf_Element_Numeric($this->toEmSpace($lastWidth)); // Width
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -