Skip to content

Commit

Permalink
Merge in dompdf develop branch (#1)
Browse files Browse the repository at this point in the history
* Moving the PDF version to a `const`

* Remove unused import

* Coding standards: Enable more PSR-2 rules

Enable rules which should be uncontroversial and easy to fix.

* Apply coding-standards changes to files

* Travis: Also check tests dir for coding standards

* Update IMagick version check logic

fixes dompdf#1296

* Fix scoping issue for IMagick version check

* fix Trying to access array offset on value of type null (dompdf#2227)

* fix Trying to access array offset on value of type null

* space

* fix css selector issue

* Fall back to decimals for roman numerals, if out of range

Consistent with how web browsers do it.

See https://en.wikipedia.org/wiki/Roman_numerals#Standard_form

* Stylesheet: Rename and document `_image` method for clarity

* Stylesheet: Make `resolve_url` public to reduce code duplication

* FontMetrics: Fix text-width calculations when using different backends

Fixes issue dompdf#2403.

* FontMetrics: Use direct access for protected properties

* Extend tests for resolving URLs in stylesheets

Without `$sheet->set_base_path(__DIR__)`, the stylesheet location would
be the location of phpunit.

* Fix instantiating CPDF Adapter without Dompdf

* Avoid offset error in CPDF line trasparency logic

related to dompdf#2227

* Use strict comparison in CPDF transparency logic

* Stylesheet: Improve return-value check

* Remove temporary file created when caching an image. (dompdf#2411)

* Remove temporary file created when caching an image.
dompdf#2377

* move unlink() to exception catch block

* Fix text-width calulation with letter spacing (dompdf#2414)

* Consistent doc for `get_text_width` arguments

To clear up the confusion about whether word and char spacing can be
float.

* CPDF: Fix text-width calulation with letter spacing

The letter spacing was counted twice for every space character.

* PDFLib: Fix text-width calculation with letter spacing

See discussion in dompdf#2414.

* Use OS-indepenent file path for unit test

* BlockFrameReflower: Always resolve `auto` widths

* Fix undefined variable (dompdf#2466)

* Bump version to 0.8.6

* Reset version string to commit hash

* Bump version to 1.0.1

* Reset version string to commit hash

* Bump version to 1.0.2

* Reset version string to commit hash

* Fix undefined variable

* Fix indentation

* Fix undefined variable

* Update src/FontMetrics.php

* Update src/FontMetrics.php

Co-authored-by: Brian Sweeney <brian@eclecticgeek.com>

* Add support for `page-break-before/-after` on table rows

pr dompdf#2512:

* Fix some typos

* Update documentation text for `_page_break_allowed`

Mainly to clear up a few unclear points that have changed. The comment
about table headers does not apply anymore.

* Add support for `page-break-before/-after` on table rows

Caveat: `page-break-after: always` does not work if the row is the last
of its table row group. I want to keep things simple now; this might be
better fixed in a proper rework of the page-break-properties handling,
e.g. by properly propagating the property values as per
https://www.w3.org/TR/css-break-3/#break-propagation.

Fixes dompdf#329

* BlockFrameReflower: Fixes to height calculations (dompdf#2511)

Brings the code closer to the spec:
* Always resolve `auto` heights
* Apply `min-/max-height` independently of the `overflow` property
value
* `min-height` overrules `max-height` (swapping removed)

* Prevent case exception in text renderer (dompdf#2423)

In case of " auto " width is throws an error as following and breaks the PDF render.
ErrorException: A non-numeric value encountered in /Path_To_Project/vendor/dompdf/dompdf/src/Renderer/Text.php:158

type casting the $width to float will prevent the ErrorException

* Resolve auto margins in more cases (dompdf#2531)

Fixes dompdf#1482

* Properly skip checking for page breaks on empty text nodes (dompdf#2506)

Before, page breaks before empty text nodes were not allowed, but they
were still checked; and as they report their line height as the space
needed, they could force a page break, which then would continue to
search backwards in the tree for an element that allowed a page break
(even though it would fit on the current page).

Based on work in dompdf#1356
Fixes dompdf#2468

* Fix table column widths after page break (dompdf#2502)

Node attributes are always string, so when a table was laid out, and
then a page break occurred before the table at a later point, `$colspan`
and `$rowspan` would always be string values and fail the checks below,
most notably the check where the minimum column width is set, so that
all columns received `0` minimum width.

Fixes dompdf#2395

* Add support for any inline-positioned frames in text alignment

This notably adds support for inline-block.

Fixes dompdf#1761

* Fix `justify` text alignment with letter spacing

The old logic seemed to correct for wrong text-width calculation
involving letter spacing when using the CPDF backend. With the fix in
dompdf#2414 this is no longer needed.

* Improve support for relative positioning

* Move handling of relative positioning to after the reflow process, so
that it does not affect layout.
* Handle `right` and `bottom` properties plus `auto` values (except for
RTL language support, which is an easy FIXME).
* As a side-effet, this adds support for relative positioning on inline
and inline-block elements.

Fixes dompdf#516

* Fix logic error in `add_frame_to_line` function

The block must check its own content-box width, not the content-box
width of its containing block when placing child frames.

Fixes dompdf#2476.

* Apply line shift to justified lines with break

* Tweak Style border/outline method color handling

fixes dompdf#2367

* BlockFrameReflower: Fix handling of `100%` width

The condition is wrong, as an `auto` width can resolve to more than
100% if the minimum width of the content is larger.

* BlockFrameReflower: Remove swapping of `min-/max-width`

Per spec, `min-width` overrules `max-width`.

https://www.w3.org/TR/CSS21/visudet.html#min-max-widths

* Remove erroneous ‘degenerate’ case handling in `get_min_max_width`

If the frame has no children, it might still have a fixed width set.

Fixes dompdf#2366

* Small code cleanups (dompdf#2547)

* Clean up `get_margin_height/width` functions

For simplicity, return a `float` value consistently.
The `get_break_margins` method was unused.

* TextReflower: Small cleanup for `get_min_max_width`

Also, add type declarations to `_collapse_white_space`.

* Clean up `split` method signatures

Consistent argument names and more type declarations.

Co-authored-by: Thomas Landauer <thomas@landauer.at>
Co-authored-by: Till Berger <till@mellthas.de>
Co-authored-by: Brian Sweeney <brian@eclecticgeek.com>
Co-authored-by: Edwin Manuel Cerrón Angeles <xerron.angels@gmail.com>
Co-authored-by: Ion Bazan <ion.bazan@gmail.com>
Co-authored-by: bradbulger <1234634+bradbulger@users.noreply.github.com>
Co-authored-by: Jáchym Toušek <enumag@gmail.com>
Co-authored-by: Madi <mudasser.ismail@gmail.com>
  • Loading branch information
9 people committed Sep 16, 2021
1 parent 69dab14 commit eb85eb5
Show file tree
Hide file tree
Showing 52 changed files with 682 additions and 624 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ before_script:

script:
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- vendor/bin/phpcs --standard=phpcs.xml src
- vendor/bin/phpcs --standard=phpcs.xml src tests

matrix:
allow_failures:
Expand Down
55 changes: 35 additions & 20 deletions lib/Cpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

class Cpdf
{
const PDF_VERSION = '1.7';

const ACROFORM_SIG_SIGNATURESEXISTS = 0x0001;
const ACROFORM_SIG_APPENDONLY = 0x0002;
Expand Down Expand Up @@ -3186,7 +3187,7 @@ function output($debug = false)
$this->checkAllHere();

$xref = [];
$content = '%PDF-1.7';
$content = '%PDF-' . self::PDF_VERSION;
$pos = mb_strlen($content, '8bit');

// pre-process o_font objects before output of all objects
Expand Down Expand Up @@ -3297,7 +3298,7 @@ private function openFont($font)
}

//$name filename without folder and extension of font metrics
//$dir folder of font metrics
//$dir folder of font metrics
//$fontcache folder of runtime created php serialized version of font metrics.
// If this is not given, the same folder as the font metrics will be used.
// Storing and reusing serialized versions improves speed much
Expand Down Expand Up @@ -3782,10 +3783,14 @@ function setLineTransparency($mode, $opacity)
$mode = "Normal";
}

// Only create a new graphics state if required
if ($mode === $this->currentLineTransparency["mode"] &&
$opacity == $this->currentLineTransparency["opacity"]
) {
if (is_null($this->currentLineTransparency)) {
$this->currentLineTransparency = [];
}

if ($mode === (key_exists('mode', $this->currentLineTransparency) ?
$this->currentLineTransparency['mode'] : '') &&
$opacity === (key_exists('opacity', $this->currentLineTransparency) ?
$this->currentLineTransparency["opacity"] : '')) {
return;
}

Expand Down Expand Up @@ -3833,9 +3838,14 @@ function setFillTransparency($mode, $opacity)
$mode = "Normal";
}

if ($mode === $this->currentFillTransparency["mode"] &&
$opacity == $this->currentFillTransparency["opacity"]
) {
if (is_null($this->currentFillTransparency)) {
$this->currentFillTransparency = [];
}

if ($mode === (key_exists('mode', $this->currentFillTransparency) ?
$this->currentFillTransparency['mode'] : '') &&
$opacity === (key_exists('opacity', $this->currentFillTransparency) ?
$this->currentFillTransparency["opacity"] : '')) {
return;
}

Expand Down Expand Up @@ -5121,11 +5131,11 @@ function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSp
* calculate how wide a given text string will be on a page, at a given size.
* this can be called externally, but is also used by the other class functions
*
* @param $size
* @param $text
* @param int $word_spacing
* @param int $char_spacing
* @return float|int
* @param float $size
* @param string $text
* @param float $word_spacing
* @param float $char_spacing
* @return float
*/
function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0)
{
Expand All @@ -5151,7 +5161,6 @@ function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0)
$cf = $this->currentFont;
$current_font = $this->fonts[$cf];
$space_scale = 1000 / ($size > 0 ? $size : 1);
$n_spaces = 0;

if ($current_font['isUnicode']) {
// for Unicode, use the code points array to calculate width rather
Expand All @@ -5173,14 +5182,13 @@ function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0)
// add additional padding for space
if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space
$w += $word_spacing * $space_scale;
$n_spaces++;
}
}
}

// add additional char spacing
if ($char_spacing != 0) {
$w += $char_spacing * $space_scale * (count($unicode) + $n_spaces);
$w += $char_spacing * $space_scale * count($unicode);
}

} else {
Expand Down Expand Up @@ -5209,14 +5217,13 @@ function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0)
// add additional padding for space
if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space
$w += $word_spacing * $space_scale;
$n_spaces++;
}
}
}

// add additional char spacing
if ($char_spacing != 0) {
$w += $char_spacing * $space_scale * ($len + $n_spaces);
$w += $char_spacing * $space_scale * $len;
}
}

Expand Down Expand Up @@ -5676,7 +5683,15 @@ protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte)
// the first version containing it was 3.0.1RC1
static $imagickClonable = null;
if ($imagickClonable === null) {
$imagickClonable = version_compare(\Imagick::IMAGICK_EXTVER, '3.0.1rc1') > 0;
$imagickClonable = true;
if (defined('Imagick::IMAGICK_EXTVER')) {
$imagickVersion = \Imagick::IMAGICK_EXTVER;
} else {
$imagickVersion = '0';
}
if (version_compare($imagickVersion, '0.0.1', '>=')) {
$imagickClonable = version_compare($imagickVersion, '3.0.1rc1', '>=');
}
}

$imagick = new \Imagick($file);
Expand Down
190 changes: 96 additions & 94 deletions lib/fonts/dompdf_font_family_cache.dist.php
Original file line number Diff line number Diff line change
@@ -1,95 +1,97 @@
<?php
$distFontDir = $rootDir . '/lib/fonts';
return [
'sans-serif' =>
[
'normal' => $distFontDir . '/Helvetica',
'bold' => $distFontDir . '/Helvetica-Bold',
'italic' => $distFontDir . '/Helvetica-Oblique',
'bold_italic' => $distFontDir . '/Helvetica-BoldOblique'
],
'times' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'times-roman' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'courier' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'helvetica' =>
[
'normal' => $distFontDir . '/Helvetica',
'bold' => $distFontDir . '/Helvetica-Bold',
'italic' => $distFontDir . '/Helvetica-Oblique',
'bold_italic' => $distFontDir . '/Helvetica-BoldOblique'
],
'zapfdingbats' =>
[
'normal' => $distFontDir . '/ZapfDingbats',
'bold' => $distFontDir . '/ZapfDingbats',
'italic' => $distFontDir . '/ZapfDingbats',
'bold_italic' => $distFontDir . '/ZapfDingbats'
],
'symbol' =>
[
'normal' => $distFontDir . '/Symbol',
'bold' => $distFontDir . '/Symbol',
'italic' => $distFontDir . '/Symbol',
'bold_italic' => $distFontDir . '/Symbol'
],
'serif' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'monospace' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'fixed' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'dejavu sans' =>
[
'bold' => $distFontDir . '/DejaVuSans-Bold',
'bold_italic' => $distFontDir . '/DejaVuSans-BoldOblique',
'italic' => $distFontDir . '/DejaVuSans-Oblique',
'normal' => $distFontDir . '/DejaVuSans'
],
'dejavu sans mono' =>
[
'bold' => $distFontDir . '/DejaVuSansMono-Bold',
'bold_italic' => $distFontDir . '/DejaVuSansMono-BoldOblique',
'italic' => $distFontDir . '/DejaVuSansMono-Oblique',
'normal' => $distFontDir . '/DejaVuSansMono'
],
'dejavu serif' =>
[
'bold' => $distFontDir . '/DejaVuSerif-Bold',
'bold_italic' => $distFontDir . '/DejaVuSerif-BoldItalic',
'italic' => $distFontDir . '/DejaVuSerif-Italic',
'normal' => $distFontDir . '/DejaVuSerif'
]
];
return function ($rootDir) {
$distFontDir = $rootDir . '/lib/fonts';
return [
'sans-serif' =>
[
'normal' => $distFontDir . '/Helvetica',
'bold' => $distFontDir . '/Helvetica-Bold',
'italic' => $distFontDir . '/Helvetica-Oblique',
'bold_italic' => $distFontDir . '/Helvetica-BoldOblique'
],
'times' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'times-roman' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'courier' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'helvetica' =>
[
'normal' => $distFontDir . '/Helvetica',
'bold' => $distFontDir . '/Helvetica-Bold',
'italic' => $distFontDir . '/Helvetica-Oblique',
'bold_italic' => $distFontDir . '/Helvetica-BoldOblique'
],
'zapfdingbats' =>
[
'normal' => $distFontDir . '/ZapfDingbats',
'bold' => $distFontDir . '/ZapfDingbats',
'italic' => $distFontDir . '/ZapfDingbats',
'bold_italic' => $distFontDir . '/ZapfDingbats'
],
'symbol' =>
[
'normal' => $distFontDir . '/Symbol',
'bold' => $distFontDir . '/Symbol',
'italic' => $distFontDir . '/Symbol',
'bold_italic' => $distFontDir . '/Symbol'
],
'serif' =>
[
'normal' => $distFontDir . '/Times-Roman',
'bold' => $distFontDir . '/Times-Bold',
'italic' => $distFontDir . '/Times-Italic',
'bold_italic' => $distFontDir . '/Times-BoldItalic'
],
'monospace' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'fixed' =>
[
'normal' => $distFontDir . '/Courier',
'bold' => $distFontDir . '/Courier-Bold',
'italic' => $distFontDir . '/Courier-Oblique',
'bold_italic' => $distFontDir . '/Courier-BoldOblique'
],
'dejavu sans' =>
[
'bold' => $distFontDir . '/DejaVuSans-Bold',
'bold_italic' => $distFontDir . '/DejaVuSans-BoldOblique',
'italic' => $distFontDir . '/DejaVuSans-Oblique',
'normal' => $distFontDir . '/DejaVuSans'
],
'dejavu sans mono' =>
[
'bold' => $distFontDir . '/DejaVuSansMono-Bold',
'bold_italic' => $distFontDir . '/DejaVuSansMono-BoldOblique',
'italic' => $distFontDir . '/DejaVuSansMono-Oblique',
'normal' => $distFontDir . '/DejaVuSansMono'
],
'dejavu serif' =>
[
'bold' => $distFontDir . '/DejaVuSerif-Bold',
'bold_italic' => $distFontDir . '/DejaVuSerif-BoldItalic',
'italic' => $distFontDir . '/DejaVuSerif-Italic',
'normal' => $distFontDir . '/DejaVuSerif'
]
];
};

0 comments on commit eb85eb5

Please sign in to comment.