24 #require_once 'Zend/Pdf/FileParser/Font.php'; 86 if ($this->_isScreened) {
102 if ($this->_isParsed) {
154 $this->
_debugLog(
'%d tables', $tableCount);
164 if (($tableCount < 7) || ($tableCount > 50)) {
165 #require_once 'Zend/Pdf/Exception.php'; 178 for ($tableIndex = 0; $tableIndex < $tableCount; $tableIndex++) {
194 $fileSize = $this->_dataSource->getSize();
195 if (($tableOffset < 0) || ($tableOffset > $fileSize)) {
196 #require_once 'Zend/Pdf/Exception.php'; 200 if (($tableLength < 0) || (($tableOffset + $tableLength) > $fileSize)) {
201 #require_once 'Zend/Pdf/Exception.php'; 206 $this->_tableDirectory[
$tableName][
'offset'] = $tableOffset;
207 $this->_tableDirectory[
$tableName][
'length'] = $tableLength;
233 if ($magicNumber != 0x5f0f3cf5) {
234 #require_once 'Zend/Pdf/Exception.php'; 236 . sprintf(
'%x', $magicNumber),
244 $this->baselineAtZero = $this->
isBitSet(0, $flags);
245 $this->useIntegerScaling = $this->
isBitSet(3, $flags);
247 $this->unitsPerEm = $this->
readUInt(2);
248 $this->
_debugLog(
'Units per em: %d', $this->unitsPerEm);
254 $this->xMin = $this->
readInt(2);
255 $this->yMin = $this->
readInt(2);
256 $this->xMax = $this->
readInt(2);
257 $this->yMax = $this->
readInt(2);
258 $this->
_debugLog(
'Font bounding box: %d %d %d %d',
259 $this->xMin, $this->yMin, $this->xMax, $this->yMax);
265 $this->isBold = $this->
isBitSet(0, $macStyleBits);
266 $this->isItalic = $this->
isBitSet(1, $macStyleBits);
285 $baseOffset = $this->_tableDirectory[
'name'][
'offset'];
294 if ($tableFormat != 0) {
295 #require_once 'Zend/Pdf/Exception.php'; 299 $this->
_debugLog(
'Format %d table', $tableFormat);
302 $this->
_debugLog(
'%d name strings', $nameCount);
304 $storageOffset = $this->
readUInt(2) + $baseOffset;
305 $this->
_debugLog(
'Storage offset: 0x%x', $storageOffset);
313 $nameRecords = array();
314 for ($nameIndex = 0; $nameIndex < $nameCount; $nameIndex++) {
319 if (! ( (($platformID == 3) && ($encodingID == 1)) ||
320 (($platformID == 1) && ($encodingID == 0))
332 if ($languageCode ===
null) {
333 $this->
_debugLog(
'Skipping languageID: 0x%x; platformID %d', $languageID, $platformID);
337 $this->
_debugLog(
'Adding nameID: %d; languageID: 0x%x; platformID: %d; offset: 0x%x (0x%x); length: %d',
338 $nameID, $languageID, $platformID, $baseOffset + $nameOffset, $nameOffset, $nameLength);
344 $nameRecords[$nameID][$languageCode] = array(
'platform' => $platformID,
345 'offset' => $nameOffset,
346 'length' => $nameLength );
351 $fontNames = array();
352 foreach ($nameRecords as
$name => $languages) {
354 $stringOffset = $storageOffset +
$attributes[
'offset'];
361 $fontNames[
$name][$language] = $string;
365 $this->names = $fontNames;
386 $this->italicAngle = $this->
readFixed(16, 16);
388 $this->underlinePosition = $this->
readInt(2);
389 $this->underlineThickness = $this->
readInt(2);
392 $this->isMonospaced = ($fixedPitch !== 0);
427 $this->ascent = $this->
readInt(2);
428 $this->descent = $this->
readInt(2);
429 $this->lineGap = $this->
readInt(2);
436 if ($this->descent > 0) {
437 $this->
_debugLog(
'Warning: Font should specify negative descent. Actual: %d; Using %d',
438 $this->descent, -$this->descent);
439 $this->descent = -$this->descent;
449 $this->metricDataFormat = $this->
readInt(2);
450 $this->numberHMetrics = $this->
readUInt(2);
451 $this->
_debugLog(
'hmtx data format: %d; number of metrics: %d',
452 $this->metricDataFormat, $this->numberHMetrics);
475 $this->numGlyphs = $this->
readUInt(2);
476 $this->
_debugLog(
'number of glyphs: %d', $this->numGlyphs);
495 if (! $this->numberHMetrics) {
496 #require_once 'Zend/Pdf/Exception.php'; 497 throw new Zend_Pdf_Exception(
"hhea table must be parsed prior to calling this method",
506 #require_once 'Zend/Pdf/Exception.php'; 508 $this->
_debugLog(
'No OS/2 table found. Using default values');
511 $this->isEmbeddable =
true;
512 $this->isSubsettable =
true;
513 $this->strikeThickness = $this->unitsPerEm * 0.05;
514 $this->strikePosition = $this->unitsPerEm * 0.225;
515 $this->isSerifFont =
false;
516 $this->isSansSerifFont =
false;
517 $this->isOrnamentalFont =
false;
518 $this->isScriptFont =
false;
519 $this->isSymbolicFont =
false;
520 $this->isAdobeLatinSubset =
false;
521 $this->vendorID =
'';
523 $this->capitalHeight = 0;
553 if (($tableVersion < 0) || ($tableVersion > 3)) {
554 #require_once 'Zend/Pdf/Exception.php'; 558 $this->
_debugLog(
'Version %d table', $tableVersion);
560 $this->averageCharWidth = $this->
readInt(2);
567 $this->fontWeight = $this->
readUInt(2);
568 $this->fontWidth = $this->
readUInt(2);
578 $embeddingFlags = $this->
readUInt(2);
579 $this->
_debugLog(
'Embedding flags: %d', $embeddingFlags);
580 if ($this->
isBitSet(9, $embeddingFlags)) {
584 $this->isEmbeddable =
false;
586 || $this->
isBitSet(3, $embeddingFlags)
587 || $this->
isBitSet(4, $embeddingFlags)
595 $this->isEmbeddable =
true;
602 $this->isEmbeddable =
false;
608 $this->isEmbeddable =
true;
610 $this->
_debugLog(
'Font ' . ($this->isEmbeddable ?
'may' :
'may not') .
' be embedded');
611 $isSubsettable = $this->
isBitSet($embeddingFlags, 8);
615 $this->subscriptXSize = $this->
readInt(2);
616 $this->subscriptYSize = $this->
readInt(2);
617 $this->subscriptXOffset = $this->
readInt(2);
618 $this->subscriptYOffset = $this->
readInt(2);
622 $this->superscriptXSize = $this->
readInt(2);
623 $this->superscriptYSize = $this->
readInt(2);
624 $this->superscriptXOffset = $this->
readInt(2);
625 $this->superscriptYOffset = $this->
readInt(2);
629 $this->strikeThickness = $this->
readInt(2);
630 $this->strikePosition = $this->
readInt(2);
636 $familyClass = ($this->
readUInt(2) >> 8);
637 $this->
_debugLog(
'Font family class: %d', $familyClass);
638 $this->isSerifFont = ((($familyClass >= 1) && ($familyClass <= 5)) ||
639 ($familyClass == 7));
640 $this->isSansSerifFont = ($familyClass == 8);
641 $this->isOrnamentalFont = ($familyClass == 9);
642 $this->isScriptFont = ($familyClass == 10);
643 $this->isSymbolicFont = ($familyClass == 12);
655 $unicodeRange1 = $this->
readUInt(4);
656 $unicodeRange2 = $this->
readUInt(4);
657 $unicodeRange3 = $this->
readUInt(4);
658 $unicodeRange4 = $this->
readUInt(4);
659 $this->
_debugLog(
'Unicode ranges: 0x%x 0x%x 0x%x 0x%x',
660 $unicodeRange1, $unicodeRange2, $unicodeRange3, $unicodeRange4);
674 $this->isAdobeLatinSubset = (($unicodeRange1 == 1) && ($unicodeRange2 == 0) &&
675 ($unicodeRange3 == 0) && ($unicodeRange4 == 0));
676 $this->
_debugLog(($this->isAdobeLatinSubset ?
'Is' :
'Is not') .
' a subset of Adobe Latin');
689 $this->ascent = $this->
readInt(2);
690 $this->descent = $this->
readInt(2);
691 $this->lineGap = $this->
readInt(2);
698 if ($this->descent > 0) {
699 $this->
_debugLog(
'Warning: Font should specify negative descent. Actual: %d; Using %d',
700 $this->descent, -$this->descent);
701 $this->descent = -$this->descent;
711 if ($tableVersion < 2) {
713 $this->capitalHeight = 0;
721 $this->xHeight = $this->
readInt(2);
722 $this->capitalHeight = $this->
readInt(2);
747 if (! $this->numberHMetrics) {
748 #require_once 'Zend/Pdf/Exception.php'; 749 throw new Zend_Pdf_Exception(
"hhea table must be parsed prior to calling this method",
755 if ($this->metricDataFormat != 0) {
756 #require_once 'Zend/Pdf/Exception.php'; 765 $glyphWidths = array();
766 for (
$i = 0;
$i < $this->numberHMetrics;
$i++) {
772 while (count($glyphWidths) < $this->numGlyphs) {
773 $glyphWidths[] = end($glyphWidths);
775 $this->glyphWidths = $glyphWidths;
803 $baseOffset = $this->_tableDirectory[
'cmap'][
'offset'];
808 if ($tableVersion != 0) {
809 #require_once 'Zend/Pdf/Exception.php'; 813 $this->
_debugLog(
'Version %d table', $tableVersion);
815 $subtableCount = $this->
readUInt(2);
816 $this->
_debugLog(
'%d subtables', $subtableCount);
821 $subtables = array();
822 for ($subtableIndex = 0; $subtableIndex < $subtableCount; $subtableIndex++) {
827 if (! ( (($platformID == 0) && ($encodingID == 3)) ||
828 (($platformID == 0) && ($encodingID == 0)) ||
829 (($platformID == 3) && ($encodingID == 1)) ||
830 (($platformID == 1) && ($encodingID == 0))
832 $this->
_debugLog(
'Unsupported encoding: platformID: %d; encodingID: %d; skipping',
833 $platformID, $encodingID);
838 $subtableOffset = $this->
readUInt(4);
839 if ($subtableOffset < 0) {
840 $this->
_debugLog(
'Offset 0x%x out of range for platformID: %d; skipping',
841 $subtableOffset, $platformID);
845 $this->
_debugLog(
'Found subtable; platformID: %d; encodingID: %d; offset: 0x%x (0x%x)',
846 $platformID, $encodingID, $baseOffset + $subtableOffset, $subtableOffset);
848 $subtables[$platformID][$encodingID][] = $subtableOffset;
857 if (isset($subtables[0][3])) {
858 foreach ($subtables[0][3] as $offset) {
859 $offsets[] = $offset;
865 if (isset($subtables[0][0])) {
866 foreach ($subtables[0][0] as $offset) {
867 $offsets[] = $offset;
873 if (isset($subtables[3][1])) {
874 foreach ($subtables[3][1] as $offset) {
875 $offsets[] = $offset;
881 if (isset($subtables[1][0])) {
882 foreach ($subtables[1][0] as $offset) {
883 $offsets[] = $offset;
889 foreach ($offsets as $offset) {
890 $cmapOffset = $baseOffset + $offset;
898 if ($language != 0) {
899 $this->
_debugLog(
'Type 0 cmap tables must be language-independent;' 900 .
' language: %d; skipping', $language);
909 if ($language != 0) {
910 $this->
_debugLog(
'Warning: cmap tables must be language-independent - this font' 911 .
' may not work properly; language: %d', $language);
937 if ($cmapType == -1) {
938 #require_once 'Zend/Pdf/Exception.php'; 945 $this->
_debugLog(
'Using cmap type %d; offset: 0x%x; length: %d',
946 $cmapType, $cmapOffset, $cmapLength);
948 $cmapData = $this->
readBytes($cmapLength);
950 #require_once 'Zend/Pdf/Cmap.php'; 968 if ($this->_scalerType != 0) {
974 $this->_scalerType = $this->
readUInt(4);
976 switch ($this->_scalerType) {
978 $this->
_debugLog(
'Windows TrueType signature');
982 $this->
_debugLog(
'Macintosh TrueType signature');
986 $this->
_debugLog(
'PostScript CFF signature');
990 #require_once 'Zend/Pdf/Exception.php'; 995 #require_once 'Zend/Pdf/Exception.php'; 1011 if (empty($this->_tableDirectory[
$tableName])) {
1012 #require_once 'Zend/Pdf/Exception.php'; 1016 $this->
_debugLog(
"Parsing $tableName table...");
1032 $tableVersion = $this->
readFixed(16, 16);
1033 if (($tableVersion < $minVersion) || ($tableVersion > $maxVersion)) {
1034 #require_once 'Zend/Pdf/Exception.php'; 1038 $this->
_debugLog(
'Version %.2f table', $tableVersion);
1039 return $tableVersion;
1053 if ($platformID == 3) {
1059 $languageID &= 0xff;
1060 switch ($languageID) {
1096 }
else if ($platformID == 1) {
1097 switch ($languageID) {
readInt($size, $byteOrder=Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
const DONT_UNDERSTAND_TABLE_VERSION
const CANT_FIND_GOOD_CMAP
const PARSED_OUT_OF_ORDER
isBitSet($bit, $bitField)
_languageCodeForPlatform($platformID, $languageID)
elseif(isset( $params[ 'redirect_parent']))
const REQUIRED_TABLE_NOT_FOUND
_readTableVersion($minVersion, $maxVersion)
readFixed($mantissaBits, $fractionBits, $byteOrder=Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
static cmapWithTypeData($cmapType, $cmapData)
readStringUTF16($byteCount, $byteOrder=Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN, $characterSet='')
readStringMacRoman($byteCount, $characterSet='')
readUInt($size, $byteOrder=Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
if(!isset($_GET['name'])) $name