diff --git a/CHANGELOG-GRAVITYPDF.md b/CHANGELOG-GRAVITYPDF.md index 6bce1654b..9d6c4f7c1 100644 --- a/CHANGELOG-GRAVITYPDF.md +++ b/CHANGELOG-GRAVITYPDF.md @@ -271,6 +271,7 @@ Bugfixes * `text-outline-width` with no `text-outline-color` raised an undefined-key warning (`outline-COLOR`) and drew the outline black. The warning is gone in either `cssMode`. In standard mode the outline is now drawn in the colour of the text, as `text-outline-color` is `currentColor` by default, and `text-outline` with a width alone, such as `text-outline: 0.2mm`, which was ignored, outlines the text in its colour too. A text outline in `currentColor`, written or by default, is passed on as the keyword, so a `` of another colour inside the outlined text is outlined in its own colour. Set `'cssMode' => \Mpdf\CssMode::LEGACY` to keep black outlines and to ignore that shorthand. [#552] [#650] [#681] * A percentage `border-radius` on a block, such as `border-radius: 50%` on a box 40 mm by 12 mm, drew a pill instead of an ellipse. Both radii were taken of the width of the block around it, and then shrunk to fit. A percentage is now of the block's own border box, as in CSS: a horizontal radius of its width and a vertical one of its height, so `50%` draws an ellipse and `10%` a corner a tenth of each side. A block split across pages resolves a vertical percentage against the height of the part on each page. With `autoPadding` on, a percentage radius no longer adds padding, since the box is not known when the padding is set. In both `cssMode`s. [#552] [#586] * `list-style: U+2022`, the shorthand, numbered the list where `list-style-type: U+2022` drew a bullet. The shorthand dropped the `U+` from the marker it set. It now keeps it, so the shorthand draws the character as the longhand does, in either `cssMode`. [#552] [#746] [#755] +* `text-decoration: overline` was drawn heavier than an underline on the same text, 2.4 pt against 1.76 pt at 40pt in DejaVu Serif Condensed. The overline is now as thick as the font's underline, sits at the font's cap height rather than a fixed 700/1000 em, and in a table shrunk to fit is thinned and placed with its text. In either `cssMode`. [#741] ### Images and SVG @@ -971,4 +972,5 @@ These changes do not change output. [#746]: https://github.com/GravityPDF/mpdf/issues/746 [#755]: https://github.com/GravityPDF/mpdf/pull/755 [#743]: https://github.com/GravityPDF/mpdf/issues/743 +[#741]: https://github.com/GravityPDF/mpdf/issues/741 [#748]: https://github.com/GravityPDF/mpdf/issues/748 diff --git a/src/Mpdf.php b/src/Mpdf.php index 28b1a1eed..7db1ce968 100644 --- a/src/Mpdf.php +++ b/src/Mpdf.php @@ -6265,8 +6265,8 @@ function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = } // mPDF 5.7.3 inline text-decoration parameters - $decorationfontkey = (int) (((float) $this->textparam['o-decoration']['fontkey']) / $shrin_k); - $decorationfontsize = $this->textparam['o-decoration']['fontsize']; + $decorationfontkey = $this->textparam['o-decoration']['fontkey']; + $decorationfontsize = $this->textparam['o-decoration']['fontsize'] / $shrin_k; if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize; diff --git a/tests/Mpdf/OverlineThicknessTest.php b/tests/Mpdf/OverlineThicknessTest.php new file mode 100644 index 000000000..122f6f7e5 --- /dev/null +++ b/tests/Mpdf/OverlineThicknessTest.php @@ -0,0 +1,86 @@ +modes()) as $mode) { + $cases[$mode . ', DejaVu Serif Condensed'] = [$mode, ['mode' => '', 'default_font' => 'dejavuserifcondensed'], 1.76]; + $cases[$mode . ', core Times'] = [$mode, ['mode' => 'c', 'default_font' => 'times'], 2.0]; + } + + return $cases; + } + + /** + * At 40pt an overline and an underline are both drawn at the font's underline thickness, in either CSS mode + * + * @dataProvider modesAndFonts + * + * @param string $mode + * @param array $font + * @param float $points The font's underline thickness at 40pt + */ + public function testAnOverlineIsAsThickAsTheFontsUnderline($mode, array $font, $points) + { + $widths = $this->lineWidths( + '

Decorated

Decorated

', + $font + ['cssMode' => $mode] + ); + + $this->assertSame([$points, $points], $widths); + } + + /** + * In a table shrunk to fit, the overline is thinned with the text to the width of the underline beside it + * + * @dataProvider modes + * + * @param string $mode + */ + public function testAnOverlineIsShrunkWithItsTable($mode) + { + $widths = $this->lineWidths( + '
DecoratedDecoratedDecorated
', + ['mode' => '', 'default_font' => 'dejavuserifcondensed', 'cssMode' => $mode] + ); + + $this->assertCount(2, $widths); + $this->assertLessThan(1.76, $widths[0]); + $this->assertSame($widths[0], $widths[1]); + } + + /** + * The line widths, in points, a document sets for its text decorations, in the order they are drawn + * + * @param string $html + * @param array $config + * + * @return float[] + */ + private function lineWidths($html, array $config) + { + preg_match_all('/([\d.]+) w 0 j 0 J/', implode("\n", $this->pages($this->render($html, $config))), $matches); + + return array_map('floatval', $matches[1]); + } + +} diff --git a/tests/Snapshots/OverlineThicknessSnapshotTest.php b/tests/Snapshots/OverlineThicknessSnapshotTest.php new file mode 100644 index 000000000..a330ee197 --- /dev/null +++ b/tests/Snapshots/OverlineThicknessSnapshotTest.php @@ -0,0 +1,57 @@ + + body { font-size: 9pt; } + h1 { font-size: 13pt; margin: 0 0 2mm 0; } + p.caption { margin: 3mm 0 0 0; } + div.sample { font-size: 40pt; margin: 0; } + +

text-decoration: overline thickness

'; + + foreach (['DejaVu Serif Condensed' => 'dejavuserifcondensed', 'DejaVu Sans Condensed' => 'dejavusanscondensed'] as $name => $family) { + $html .= '

' . $name . ', underline: a line under the text.

+
Decorated
+

' . $name . ', overline: a line over the text, as thick as the underline above.

+
Decorated
+

' . $name . ', underline overline: the two lines the same thickness.

+
Decorated
'; + } + + $html .= '

A table shrunk to fit the page: the line over the text as thin as the line under it.

+ + +
DecoratedDecoratedDecoratedDecorated
'; + + $this->mpdf = $this->createMpdf(); + + $this->mpdf->WriteHTML($html); + } + +} diff --git a/tests/data/snapshots/decorations-amendment-legacy.pdf b/tests/data/snapshots/decorations-amendment-legacy.pdf index 80136f2af..4b0c605bf 100644 Binary files a/tests/data/snapshots/decorations-amendment-legacy.pdf and b/tests/data/snapshots/decorations-amendment-legacy.pdf differ diff --git a/tests/data/snapshots/decorations-amendment-standard.pdf b/tests/data/snapshots/decorations-amendment-standard.pdf index 66ceacdb2..19c40cc3e 100644 Binary files a/tests/data/snapshots/decorations-amendment-standard.pdf and b/tests/data/snapshots/decorations-amendment-standard.pdf differ diff --git a/tests/data/snapshots/decorations-propagate.pdf b/tests/data/snapshots/decorations-propagate.pdf index 3504d908e..b51b44816 100644 Binary files a/tests/data/snapshots/decorations-propagate.pdf and b/tests/data/snapshots/decorations-propagate.pdf differ diff --git a/tests/data/snapshots/overline-thickness.pdf b/tests/data/snapshots/overline-thickness.pdf new file mode 100644 index 000000000..cdc429971 Binary files /dev/null and b/tests/data/snapshots/overline-thickness.pdf differ