Skip to content

Commit

Permalink
Merge pull request #45 from YetiForceCompany/developer
Browse files Browse the repository at this point in the history
YetiForcePDF v0.1.41
  • Loading branch information
rskrzypczak authored Mar 26, 2024
2 parents 0775b80 + 6e12654 commit dc4218e
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 34 deletions.
13 changes: 12 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
[![Latest Stable Version](https://poser.pugx.org/yetiforce/yetiforcepdf/v/stable)](https://packagist.org/packages/yetiforce/yetiforcepdf)
[![Build Status](https://travis-ci.org/YetiForceCompany/YetiForcePDF.svg?branch=developer)](https://travis-ci.org/YetiForceCompany/YetiForcePDF)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/YetiForceCompany/YetiForcePDF/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/YetiForceCompany/YetiForcePDF/?branch=master)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b2e8645f5091496089ed203d05a05d61)](https://app.codacy.com/app/mariuszkrzaczkowski/YetiForcePDF?utm_source=github.com&utm_medium=referral&utm_content=YetiForceCompany/YetiForcePDF&utm_campaign=Badge_Grade_Settings)
[![Maintainability](https://api.codeclimate.com/v1/badges/af478ddd07cf7278841a/maintainability)](https://codeclimate.com/github/YetiForceCompany/YetiForcePDF/maintainability)

## PDF generation library for PHP
The best library in the world to generate PDF from HTML

## Issues & bugs
Report errors related to PDF in https://github.com/YetiForceCompany/YetiForceCRM/issues

## Basic usage (for more take a look at examples folder)

```php
Expand Down Expand Up @@ -196,3 +198,12 @@ When you want to place page number (in header or footer for example) you can do
## License

Distributed under the MIT license. See LICENSE for details.

## 👥 Contributors

This project exists thanks to all the people who contribute.

<a href="https://github.com/YetiForceCompany/YetiForcePDF/graphs/contributors">
<img src="https://contrib.rocks/image?repo=YetiForceCompany/YetiForcePDF" />
</a>

2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"phenx/php-font-lib": "^0.5",
"guzzlehttp/guzzle": "^7",
"composer/ca-bundle": "^1",
"milon/barcode": "^9",
"milon/barcode": "^11",
"sabberworm/php-css-parser": "^8"
},
"autoload": {
Expand Down
65 changes: 50 additions & 15 deletions lib/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

namespace YetiForcePDF;

use Exception;
use YetiForcePDF\Html\Parser;
use YetiForcePDF\Layout\FooterBox;
use YetiForcePDF\Layout\HeaderBox;
use YetiForcePDF\Layout\WatermarkBox;
Expand All @@ -31,34 +33,40 @@ class Document
* @var int
*/
protected $actualId = 0;

/**
* Main output buffer / content for pdf file.
*
* @var string
*/
protected $buffer = '';

/**
* Main entry point - root element.
*
* @var \YetiForcePDF\Catalog
*/
protected $catalog;

/**
* Pages dictionary.
*
* @var Pages
*/
protected $pagesObject;

/**
* Current page object.
*
* @var Page
*/
protected $currentPageObject;

/**
* @var string default page format
*/
protected $defaultFormat = 'A4';

/**
* @var string default page orientation
*/
Expand All @@ -68,6 +76,7 @@ class Document
* @var Page[] all pages in the document
*/
protected $pages = [];

/**
* Default page margins.
*
Expand All @@ -79,68 +88,82 @@ class Document
'right' => 40,
'bottom' => 40,
];

/**
* All objects inside document.
*
* @var \YetiForcePDF\Objects\PdfObject[]
*/
protected $objects = [];

/**
* @var \YetiForcePDF\Html\Parser
* @var Parser
*/
protected $htmlParser;

/**
* Fonts data.
*
* @var array
*/
protected $fontsData = [];

/**
* @var array
*/
protected $fontInstances = [];

/**
* Actual font id.
*
* @var int
*/
protected $actualFontId = 0;

/**
* Actual graphic state id.
*
* @var int
*/
protected $actualGraphicStateId = 0;

/**
* @var bool
*/
protected $debugMode = false;

/**
* @var HeaderBox|null
*/
protected $header;

/**
* @var FooterBox|null
*/
protected $footer;

/**
* @var WatermarkBox|null
*/
protected $watermark;

/**
* @var Meta
*/
protected $meta;

/**
* @var bool
*/
protected $parsed = false;

/**
* Characters int values cache for fonts.
*
* @var array
*/
protected $ordCache = [];
public $ordCache = [];

/**
* Css selectors like classes ids.
*
Expand Down Expand Up @@ -444,7 +467,7 @@ public function getFontData(string $family, string $weight, string $style)
*/
public static function addFonts(array $fonts)
{
return \YetiForcePDF\Objects\Font::loadFromArray($fonts);
\YetiForcePDF\Objects\Font::loadFromArray($fonts);
}

/**
Expand Down Expand Up @@ -765,14 +788,19 @@ public function removeObject(PdfObject $object): self
* Load html string.
*
* @param string $html
* @param string $inputEncoding
* @param string $fromEncoding
*
* @return $this
* @throws Exception
*/
public function loadHtml(string $html, string $inputEncoding = 'UTF-8')
public function loadHtml(string $html, string $fromEncoding = 'UTF-8'): self
{
$this->htmlParser = (new \YetiForcePDF\Html\Parser())->setDocument($this)->init();
$this->htmlParser->loadHtml($html, $inputEncoding);
if ($fromEncoding === '') {
throw new Exception('Encoding can not be empty');
}

$this->htmlParser = (new Parser())->setDocument($this)->init();
$this->htmlParser->loadHtml($html, $fromEncoding);

return $this;
}
Expand Down Expand Up @@ -872,34 +900,41 @@ public function parse()
*/
public function render(): string
{
$xref = $this->buffer = '';
$xref = '';
$this->buffer = '';

$this->buffer .= $this->getDocumentHeader();
$this->parse();
$objectSize = 0;

foreach ($this->objects as $object) {
if (\in_array($object->getBasicType(), ['Dictionary', 'Stream', 'Array'])) {
$xref .= sprintf("%010d 00000 n \n", \strlen($this->buffer));
$this->buffer .= $object->render() . "\n";
++$objectSize;
}
}

$offset = \strlen($this->buffer);
$this->buffer .= implode("\n", [
'xref',
'0 ' . ($objectSize + 1),
'0 ' . $objectSize,
'0000000000 65535 f ',
$xref,
]);

$trailer = (new \YetiForcePDF\Objects\Trailer())
->setDocument($this)->setRootObject($this->catalog)->setSize($objectSize);

$this->buffer .= $trailer->render() . "\n";
// $this->buffer .= implode("\n", [
// 'startxref',
// $offset,
// '',
// ]);
$this->buffer .= implode("\n", [
'startxref',
$offset,
'',
]);
$this->buffer .= $this->getDocumentFooter();
$this->removeObject($trailer);

return $this->buffer;
}

Expand All @@ -910,7 +945,7 @@ public function render(): string
*
* @return array
*/
public function getCssSelectorRules(string $selector)
public function getCssSelectorRules(string $selector): array
{
$rules = [];
foreach (explode(' ', $selector) as $className) {
Expand Down
23 changes: 17 additions & 6 deletions lib/Html/Parser.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

/**
* Parser class.
*
Expand All @@ -13,25 +14,29 @@

namespace YetiForcePDF\Html;

use YetiForcePDF\Base;
use YetiForcePDF\Layout\PageGroupBox;

/**
* Class Parser.
*/
class Parser extends \YetiForcePDF\Base
class Parser extends Base
{
/**
* @var \DOMDocument
*/
protected $domDocument;

/**
* @var string
*/
protected $html = '';

/**
* @var array page groups with html content divided
*/
protected $htmlPageGroups = [];

/**
* @var array
*/
Expand All @@ -57,13 +62,19 @@ protected function cleanUpHtml(string $html)
* @param string $html
* @param string $fromEncoding
*
* @return \YetiForcePDF\Html\Parser
* @return Parser
*/
public function loadHtml(string $html, string $fromEncoding = ''): self
public function loadHtml(string $html, string $fromEncoding): self
{
$html = htmlspecialchars_decode($html, ENT_HTML5);
$this->html = htmlspecialchars_decode($html, ENT_HTML5);
$this->html = $this->cleanUpHtml($html);
$this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', $fromEncoding);

// 0x80 - start of unicode range
// 0x10FFFF - end of unicode range
// 0 - do not ommit any unicode char
// ~0 - negated 0 - convert negation of nothing (so convert all)
$this->html = mb_encode_numericentity($this->html, [0x80, 0x10FFFF, 0, ~0], $fromEncoding);

return $this;
}

Expand All @@ -72,7 +83,7 @@ public function loadHtml(string $html, string $fromEncoding = ''): self
*
* @return string
*/
public function getHtml()
public function getHtml(): string
{
return $this->html;
}
Expand Down
Loading

0 comments on commit dc4218e

Please sign in to comment.