Repository navigation
Draw border-radius, box-shadow and 3D border styles on every element, blur text-shadow, and draw outline #603
Description
Part of #552 (step 28, missing support, medium priority).
Several border and shadow effects mPDF draws on some elements and not on others:
border-radius: blocks and images only.box-shadow: blocks only.groove,ridge,inset,outset: two-tone in tables, flat everywhere else.text-shadow: blur is parsed and never drawn.outline: drawn nowhere.
Rounded table cards and cells, shadowed tables, outlined boxes and soft text shadows all come out square, flat or missing.
Measured on gravitypdf at 60b82630, PHP 8.5.4, rasterised.
| Rule | Browser | mPDF |
|---|---|---|
<span style="border:1mm solid #00f;border-radius:3mm;background:#0f0"> |
rounded | square |
<td style="border:1mm solid #00f;border-radius:3mm;background:#0f0">, border-collapse: separate |
rounded | square |
<table style="border:1mm solid #00f;border-radius:3mm;background:#0f0"> |
rounded | square |
box-shadow: 2mm 2mm #f00 on a span, a td, a table and an img |
a red shadow | none |
<div style="outline:1mm solid #f00"> |
a red line outside the border box | none |
<div style="border:3mm groove #36c"> |
two-tone groove | flat blue |
<td style="border:3mm groove #36c"> |
two-tone groove | two-tone (works) |
<p style="text-shadow:1mm 1mm 2mm #f00"> |
a blurred red shadow | a sharp red copy |
Where each is drawn today.
- Block radius and shadow. Read in
setCSS()(src/Mpdf.php:19298-19328) and drawn inPaintDivBB(): the radius clips throughRoundedBox::fit()andpath()(:17901), and the shadow is drawn from:18303. - Image radius.
Img::open()(src/Tag/Img.php:295-320), and drawn throughRoundedBox::imageBox()(src/Mpdf.php:8199-8204). - Inline borders and backgrounds. Drawn per text run in
Cell()(src/Mpdf.php:5788onwards), with no radius. - Table and cell borders. The table border code draws
groove,ridge,insetandoutsetin two tones withColorConverter::lighten()anddarken()(src/Mpdf.php:22106-22140). Block borders go through_setBorderLine(), which draws one colour. - Text shadows. Drawn as offset copies of the text (
src/Mpdf.php:6253-6268). TheblurthatShadowParserreads (src/Css/ShadowParser.php:225) is never used. outline. No box outline is drawn anywhere. Stop reading outline-width and outline-color as the text outline #578 stopsoutline-widthandoutline-colorstroking the element's text, as mPDF's owntext-outline, and leaves drawing a real outline to this issue.
Fix. Each can be its own PR.
-
Radius on cells and tables. Clip the cell's background to a rounded path with
RoundedBox, and draw the border along it. Withborder-collapse: collapse, CSS ignoresborder-radiuson cells and on the table, so only the separate model changes. -
Radius on inline elements. Round only the first fragment's left corners and the last fragment's right corners (
box-decoration-break: slice). -
Shadows on cells, tables, inline elements and images. Reuse the
PaintDivBB()shadow code for a box given its corners and radii. -
3D styles on blocks, inline elements and images. Reuse the two-tone colours from the table code.
-
text-shadowblur. PDF has no blur, so approximate it:- draw several copies of the text around the offset, at falling alpha
- or stroke the text at growing widths and falling alpha
Both need transparency. Under PDF/A-1 and PDF/X-1a, draw it sharp with a warning, as
box-shadowdoes (transparencyAllowed()). -
outline.- Read
outline,outline-style,outline-width,outline-colorandoutline-offset. - Draw the outline outside the border box, following the radius. It takes no space in layout.
outline-colordefaults tocurrentColor, whichcurrentColorin a border raises warnings and draws black, and a border with no colour is not drawn in the text colour #540 resolves.- Draw it on blocks, cells, images and inline elements, after the content. An outline is drawn on top.
- Read
Tests. Each row above, a rounded cell under collapse (unchanged), an inline element that wraps onto two lines, shadows with a radius, an outline with outline-offset, and a blurred text-shadow under PDF/A-1b. Snapshots for the drawing, and unit tests for the paths.
Activity
Run a border's rings out past a side with no border, so no hairline i…