Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid invalid PDF operators when drawing SVG text #1554

Merged
merged 1 commit into from
Jan 30, 2022

Conversation

rianmcguire
Copy link
Contributor

This was causing display problems and warning messages in some PDF software.

Example HTML

<p>SVG with text:</p>
<svg width="300" height="50">
    <rect width="300" height="50" fill="none" stroke="red" />
    <text rotate="10" x="10" y="25" letter-spacing="3" font-size="30" font-family="Noto Sans">This is text</text>
</svg>

Before

PDF X-Change Viewer[1] doesn't render SVG text:
before-pdfxchange

Adobe Acrobat Reader DC [2] renders SVG text:
before-adobe
but displays this warning message after printing (printing to a virtual printer is sufficient):
before-adobe-print

After

PDF X-Change Viewer renders SVG text:
after-pdfxchange

Adobe Acrobat Reader DC now prints with no warning messages.

Root cause

I managed to narrow this down to the PDF content stream that's being emitted for the SVG text. I used pikepdf to parse it.

SVG text PDF content stream before (invalid operators marked with **):

BT []
**q []
**m [10, 25]
**cm [1, 0, 0, 1, 10, 25]
**cm [Decimal('0.984808'), Decimal('0.173648'), Decimal('-0.173648'), Decimal('0.984808'), 0, 0]
**cm [1, 0, 0, 1, -10, -25]
rg [0, 0, 0]
gs [pikepdf.Name("/a1.0")]
w [1]
J [0]
j [0]
M [4]
Tr [0]
Tm [30, 0, 0, -30, 10, 25]
Tf [pikepdf.Name("/JDIZPJ"), 1]
TJ [pikepdf.Array([ "7" ])]
**Q []
ET []

According to the PDF specification, "special graphics state" operators (q, Q, cm) and "path construction" operators (m) aren't permitted while a text object is being drawn. See page 134-135, Table 4.1 Operator categories, and Figure 4.1 Graphics objects.

PDF readers seem to be quite tolerant of invalid content streams in general, but apparently this was too much!

Content stream after:

BT []
rg [0, 0, 0]
gs [pikepdf.Name("/a1.0")]
w [1]
J [0]
j [0]
M [4]
Tr [0]
Tm [Decimal('29.544233'), Decimal('5.209445'), Decimal('5.209445'), Decimal('-29.544233'), 10, 25]
Tf [pikepdf.Name("/BBQVNM"), 1]
TJ [pikepdf.Array([ "7" ])]
ET []

[1] PDF-XChange Viewer 2.5 (Build 322.10) - https://www.tracker-software.com/product/pdf-xchange-viewer
[2] Adobe Acrobat Reader DC 2021.011.20039

According to the PDF specification, "special graphics state" operators (q, Q, cm) aren't permitted while a text object is being drawn.
@liZe
Copy link
Member

liZe commented Jan 30, 2022

Hello!

Thanks a lot for this pull request ❤️. There’s definitely a problem with the old code, and this PR does what needs to be done, that’s perfect!

Strange to see Adobe Reader complaining, while Ghostscript doesn’t. That’s annoying to add a non-regression test.

@liZe liZe merged commit 9705746 into Kozea:master Jan 30, 2022
@liZe liZe added the bug Existing features not working as expected label Jan 30, 2022
@liZe liZe added this to the 55.0 milestone Jan 30, 2022
liZe added a commit that referenced this pull request Jan 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants