Repository navigation
Apply opacity and transform to blocks, tables and inline elements, not only images #602
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Part of #552 (step 28, missing support, medium priority).
opacity and transform are read on images only. On blocks, tables, cells and inline elements they are ignored. Templates use opacity for faded "PAID" or "DRAFT" stamps and muted text, and transform: rotate() for stamps and angled labels.
Measured on gravitypdf at 60b82630, PHP 8.5.4, from the ExtGState objects and cm operators written.
| Rule | Browser | mPDF |
|---|---|---|
<div style="opacity:.3;background:#f00">op</div> |
block and text at 30% | opaque; no /ca written |
<p><span style="opacity:.3">op</span></p> |
text at 30% | opaque |
<td style="opacity:.3"> |
cell at 30% | opaque |
<img style="opacity:.3"> |
30% | 30% (works) |
<div style="transform:rotate(30deg);width:40mm">tr</div> |
rotated 30° about its centre | not rotated |
<img style="transform:rotate(30deg)"> |
rotated | rotated (works) |
<p><span style="transform:scale(2)">tr</span></p> |
not transformed: CSS does not transform inline boxes that are not replaced | not transformed (correct) |
Cause.
Img::open()readsOPACITY(src/Tag/Img.php:143-145) andTRANSFORM(:338-339) into the image's object attributes.printobjectbuffer()applies them when it draws the image (src/Mpdf.php:8120-8130), usingtransformRotate(),transformScale()and the other transform helpers (:27774onwards).setCSS()andBlockTag,TableandTdnever read either property. mPDF's ownrotateon positioned blocks and tables is separate.
Fix.
opacityon a block, cell or table.- CSS applies it to the element and its content as one group, so overlapping children do not show through each other. In PDF that is a transparency group: draw the element's output for each page into a Form XObject with
/Group << /S /Transparency >>, then paint it with/caand/CA. - Setting
/caon each piece instead is simpler, but wrong where a background and text overlap: the background shows through the text. - A block that crosses a page needs a group per page.
- CSS applies it to the element and its content as one group, so overlapping children do not show through each other. In PDF that is a transparency group: draw the element's output for each page into a Form XObject with
opacityon an inline element. Text runs have nothing to overlap but themselves, soSetAlpha()(src/Mpdf.php:2432) around each run of the element is close enough.transformon a block or table.- Transforms do not affect layout. Lay the box out as normal, then wrap everything it drew on the page in
q <matrix> cm … Q. transform-origindefaults to the centre of the border box, whose height is known only at the close. Insert theq … cmat the block's start in the page's content when it closes, as mPDF does for backgrounds (___BACKGROUND___PATTERNS).- Decide what a transformed block does at a page break: transform each fragment, or keep the block whole as
page-break-inside: avoiddoes. - Link and annotation rectangles are axis-aligned in PDF. Transform the corners, and use the bounding box for anything rotated.
- Accept the same functions as images, and
transform-origin.
- Transforms do not affect layout. Lay the box out as normal, then wrap everything it drew on the page in
- Standards. PDF/A-1 and PDF/X-1a forbid transparency. Follow the
transparencyAllowed()path box shadows use: warn, and draw opaque.
Tests. opacity on a block with a background and overlapping text, on a nested block with its own opacity (the values multiply), on a block across a page break, on a span, and on a cell. rotate, scale, translate and a list of transforms on a block, with transform-origin. A rotated block holding a link. opacity under PDF/A-1b.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity