/** * Object constructor * * $fontDictionary is a \Zend\Pdf\InternalType\IndirectObjectReference or * \Zend\Pdf\InternalType\IndirectObject object * * @param mixed $fontDictionary * @throws \Zend\Pdf\Exception */ public function __construct($fontDictionary) { // Extract object factory and resource object from font dirctionary object $this->_objectFactory = $fontDictionary->getFactory(); $this->_resource = $fontDictionary; if ($fontDictionary->Encoding !== null) { $this->_encoding = $fontDictionary->Encoding->value; } switch ($fontDictionary->Subtype->value) { case 'Type0': // Composite type 0 font if (count($fontDictionary->DescendantFonts->items) != 1) { // Multiple descendant fonts are not supported throw new Exception\NotImplementedException(self::TYPE_NOT_SUPPORTED); } $fontDictionaryIterator = $fontDictionary->DescendantFonts->items->getIterator(); $fontDictionaryIterator->rewind(); $descendantFont = $fontDictionaryIterator->current(); $fontDescriptor = $descendantFont->FontDescriptor; break; case 'Type1': if ($fontDictionary->FontDescriptor === null) { // That's one of the standard fonts $standardFont = Pdf\Font::fontWithName($fontDictionary->BaseFont->value); $this->_fontNames = $standardFont->getFontNames(); $this->_isBold = $standardFont->isBold(); $this->_isItalic = $standardFont->isItalic(); $this->_isMonospace = $standardFont->isMonospace(); $this->_underlinePosition = $standardFont->getUnderlinePosition(); $this->_underlineThickness = $standardFont->getUnderlineThickness(); $this->_strikePosition = $standardFont->getStrikePosition(); $this->_strikeThickness = $standardFont->getStrikeThickness(); $this->_unitsPerEm = $standardFont->getUnitsPerEm(); $this->_ascent = $standardFont->getAscent(); $this->_descent = $standardFont->getDescent(); $this->_lineGap = $standardFont->getLineGap(); return; } $fontDescriptor = $fontDictionary->FontDescriptor; break; case 'TrueType': $fontDescriptor = $fontDictionary->FontDescriptor; break; default: throw new Exception\NotImplementedException(self::TYPE_NOT_SUPPORTED); } $this->_fontNames[Pdf\Font::NAME_POSTSCRIPT]['en'] = iconv('UTF-8', 'UTF-16BE', $fontDictionary->BaseFont->value); $this->_isBold = false; // this property is actually not used anywhere $this->_isItalic = ( ($fontDescriptor->Flags->value & (1 << 6)) != 0 ); // Bit-7 is set $this->_isMonospace = ( ($fontDescriptor->Flags->value & (1 << 0)) != 0 ); // Bit-1 is set $this->_underlinePosition = null; // Can't be extracted $this->_underlineThickness = null; // Can't be extracted $this->_strikePosition = null; // Can't be extracted $this->_strikeThickness = null; // Can't be extracted $this->_unitsPerEm = null; // Can't be extracted $this->_ascent = $fontDescriptor->Ascent->value; $this->_descent = $fontDescriptor->Descent->value; $this->_lineGap = null; // Can't be extracted }
public function testFontExtracting() { if (PHP_OS == 'AIX') { $this->markTestSkipped('Not supported on AIX'); } $pdf = new Pdf\PdfDocument(); $fontsList = array(Pdf\Font::FONT_COURIER, Pdf\Font::FONT_HELVETICA_BOLD, Pdf\Font::FONT_TIMES_BOLD_ITALIC); foreach ($fontsList as $fontName) { // Add new page generated by Zend_PDF object (page is attached to the specified the document) $pdf->pages[] = $page = $pdf->newPage(Pdf\Page::SIZE_A4_LANDSCAPE); $font = Pdf\Font::fontWithName($fontName); $page->setFont($font, 10)->drawText($font->getFontName(Pdf\Font::NAME_POSTSCRIPT, 'en') . ':', 100, 400); $page->setFont($font, 20)->drawText("'The quick brown fox jumps over the lazy dog'", 100, 360); $type = $font->getFontType(); } $TTFFontsList = array('VeraBd.ttf', 'VeraBI.ttf', 'VeraIt.ttf', 'VeraMoBd.ttf', 'VeraMoBI.ttf', 'VeraMoIt.ttf', 'VeraMono.ttf', 'VeraSeBd.ttf', 'VeraSe.ttf', 'Vera.ttf'); foreach ($TTFFontsList as $fontName) { // Add new page generated by Zend_PDF object (page is attached to the specified the document) $pdf->pages[] = $page = $pdf->newPage(Pdf\Page::SIZE_A4_LANDSCAPE); $font = Pdf\Font::fontWithPath(__DIR__ . '/_fonts/' . $fontName); $page->setFont($font, 10)->drawText($font->getFontName(Pdf\Font::NAME_POSTSCRIPT, 'en', 'CP1252') . ':', 100, 400); $page->setFont($font, 20)->drawText("'The quick brown fox jumps over the lazy dog'", 100, 360); $type = $font->getFontType(); } $pdf->save(__DIR__ . '/_files/output.pdf'); unset($pdf); $pdf1 = Pdf\PdfDocument::load(__DIR__ . '/_files/output.pdf'); $newPages = array(); $fontList = array(); $fontNames = array(); foreach ($pdf1->pages as $page) { $pageFonts = $page->extractFonts(); foreach ($pageFonts as $font) { $fontList[] = $font; $fontNames[] = $font->getFontName(Pdf\Font::NAME_POSTSCRIPT, 'en', 'UTF-8'); } } $this->assertEquals(array(Pdf\Font::FONT_COURIER, Pdf\Font::FONT_HELVETICA_BOLD, Pdf\Font::FONT_TIMES_BOLD_ITALIC, 'BitstreamVeraSans-Bold', 'BitstreamVeraSans-BoldOblique', 'BitstreamVeraSans-Oblique', 'BitstreamVeraSansMono-Bold', 'BitstreamVeraSansMono-BoldOb', 'BitstreamVeraSansMono-Oblique', 'BitstreamVeraSansMono-Roman', 'BitstreamVeraSerif-Bold', 'BitstreamVeraSerif-Roman', 'BitstreamVeraSans-Roman'), $fontNames); $pdf1->pages[] = $page = $pdf1->newPage(Pdf\Page::SIZE_A4); $yPosition = 700; foreach ($fontList as $font) { $page->setFont($font, 15)->drawText("The quick brown fox jumps over the lazy dog", 100, $yPosition); $yPosition -= 30; } $fontNames1 = array(); foreach ($pdf1->extractFonts() as $font) { $fontNames1[] = $font->getFontName(Pdf\Font::NAME_POSTSCRIPT, 'en', 'UTF-8'); } $this->assertEquals(array(Pdf\Font::FONT_COURIER, Pdf\Font::FONT_HELVETICA_BOLD, Pdf\Font::FONT_TIMES_BOLD_ITALIC, 'BitstreamVeraSans-Bold', 'BitstreamVeraSans-BoldOblique', 'BitstreamVeraSans-Oblique', 'BitstreamVeraSansMono-Bold', 'BitstreamVeraSansMono-BoldOb', 'BitstreamVeraSansMono-Oblique', 'BitstreamVeraSansMono-Roman', 'BitstreamVeraSerif-Bold', 'BitstreamVeraSerif-Roman', 'BitstreamVeraSans-Roman'), $fontNames1); $page = reset($pdf1->pages); $font = $page->extractFont(Pdf\Font::FONT_COURIER); $this->assertTrue($font instanceof Font\Extracted); $font = $page->extractFont(Pdf\Font::FONT_TIMES_BOLD_ITALIC); $this->assertNull($font); $font = $pdf1->extractFont(Pdf\Font::FONT_TIMES_BOLD_ITALIC); $this->assertTrue($font instanceof Font\Extracted); $font = $pdf1->extractFont(Pdf\Font::FONT_TIMES_ROMAN); $this->assertNull($font); $pdf1->save(__DIR__ . '/_files/output1.pdf'); unset($pdf1); $pdf2 = Pdf\PdfDocument::load(__DIR__ . '/_files/output1.pdf'); $this->assertTrue($pdf2 instanceof Pdf\PdfDocument); unset($pdf2); unlink(__DIR__ . '/_files/output.pdf'); unlink(__DIR__ . '/_files/output1.pdf'); }
public function testPageCloning() { $pdf = PDF\PDFDocument::load(dirname(__FILE__) . '/_files/pdfarchiving.pdf'); $srcPageCount = count($pdf->pages); try { $newPage = clone reset($pdf->pages); } catch (PDF\Exception $e) { if (strpos($e->getMessage(), 'Cloning \\Zend\\PDF\\Page object using \'clone\' keyword is not supported.') !== 0) { throw $e; } // Exception is thrown } $outputPageSet = array(); foreach ($pdf->pages as $srcPage) { $page = new PDF\Page($srcPage); $outputPageSet[] = $srcPage; $outputPageSet[] = $page; $page->saveGS(); // Create new Style $page->setFillColor(new Color\RGB(0, 0, 0.9))->setLineColor(new Color\GrayScale(0.2))->setLineWidth(3)->setLineDashingPattern(array(3, 2, 3, 4), 1.6)->setFont(PDF\Font::fontWithName(PDF\Font::FONT_HELVETICA_BOLD), 32); $page->rotate(0, 0, M_PI_2 / 3); $page->drawText('Modified by Zend Framework!', 150, 0); $page->restoreGS(); } // Add new page generated by Zend_PDF object (page is attached to the specified the document) $pdf->pages = $outputPageSet; $pdf->save(dirname(__FILE__) . '/_files/output.pdf'); unset($pdf); $pdf1 = PDF\PDFDocument::load(dirname(__FILE__) . '/_files/output.pdf'); $this->assertTrue($pdf1 instanceof PDF\PDFDocument); $this->assertEquals($srcPageCount * 2, count($pdf1->pages)); unset($pdf1); unlink(dirname(__FILE__) . '/_files/output.pdf'); }
public function testPageCloning() { $pdf = Pdf\PdfDocument::load(__DIR__ . '/_files/pdfarchiving.pdf'); $pdf1 = new Pdf\PdfDocument(); $srcPageCount = count($pdf->pages); $outputPageSet = array(); foreach ($pdf->pages as $srcPage) { $page = clone $srcPage; $page->saveGS(); // Create new Style $page->setFillColor(new Color\Rgb(0, 0, 0.9))->setLineColor(new Color\GrayScale(0.2))->setLineWidth(3)->setLineDashingPattern(array(3, 2, 3, 4), 1.6)->setFont(Pdf\Font::fontWithName(Pdf\Font::FONT_HELVETICA_BOLD), 32); $page->rotate(0, 0, M_PI_2 / 3); $page->drawText('Modified by Zend Framework!', 150, 0); $page->restoreGS(); $pdf1->pages[] = $page; } $pdf1->save(__DIR__ . '/_files/output.pdf'); unset($pdf); unset($pdf1); $pdf2 = Pdf\PdfDocument::load(__DIR__ . '/_files/output.pdf'); $this->assertTrue($pdf2 instanceof Pdf\PdfDocument); $this->assertEquals($srcPageCount, count($pdf2->pages)); unset($pdf2); unlink(__DIR__ . '/_files/output.pdf'); }
/** * Calculate the width of a string: * in case of using alignment parameter in drawText * @param string $text * @param \Zend\Pdf\Font $font * @param float $fontSize * @return float */ public function widthForStringUsingFontSize($text, $font, $fontSize) { $drawingString = iconv('UTF-8', 'UTF-16BE//IGNORE', $text); $characters = array(); for ($i = 0; $i < strlen($drawingString); $i++) { $characters[] = ord($drawingString[$i++]) << 8 | ord($drawingString[$i]); } $glyphs = $font->glyphNumbersForCharacters($characters); $widths = $font->widthsForGlyphs($glyphs); $stringWidth = array_sum($widths) / $font->getUnitsPerEm() * $fontSize; return $stringWidth; }