Skip to content

Tiling pattern with negative bbox coordinates is not fully rendered #16038

Description

@muzimuzhi

Attach (recommended) or Link to PDF file here:

Configuration:

Steps to reproduce the problem:

  1. Visit https://mozilla.github.io/pdf.js/web/viewer.html
  2. Open dvisvgm-gh228(-readable).pdf

What is the expected behavior? (add screenshot)
image

What went wrong? (add screenshot)
image

Link to a viewer (if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension):

Background

The pdf is created by LaTeX using tikz package. dvisvgm-gh228.tex.zip

Specifically, the broken left pattern can be generated by the short LaTeX example below, shortened from mgieseki/dvisvgm#228:

\documentclass[margin=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{patterns.meta}

\begin{document}
\begin{tikzpicture}[pattern color=blue]
  \draw[draw, pattern={Lines}] (0,0) rectangle (1,1);
\end{tikzpicture}
\end{document}

Analysis
The broken left pattern has

  • /BBox [ -1.49442 -1.49442 1.49442 1.49442 ] and
  • content stream q 0.3985 w -1.49442 0.0 m 1.49442 0.0 l S Q

while the right pattern has

  • /BBox [ 0 0 2.98883 2.98883 ] and
  • content stream q 0.3985 w 0.0 0.0 m 2.98883 0.0 l 0.0 2.98883 m 2.98883 2.98883 l S Q

In class TilingPattern, when the bounding box is shifted to ensure coordinates x0 and y0 non-negative, it seems some transformations like 1 0 0 1 -x0 0 and 1 0 0 1 -y0 0 should be additionally applied to the stream content. The corresponding code is added in a52c0c6. Actually its commit message already said that negative bounding boxes on tiling patterns is still broken:

These fixes broke #11473, but highlighted that we were drawing that correctly by
accident and not correctly handling negative bounding boxes on tiling patterns.

let adjustedX0 = x0;
let adjustedY0 = y0;
let adjustedX1 = x1;
let adjustedY1 = y1;
// Some bounding boxes have negative x0/y0 coordinates which will cause the
// some of the drawing to be off of the canvas. To avoid this shift the
// bounding box over.
if (x0 < 0) {
adjustedX0 = 0;
adjustedX1 += Math.abs(x0);
}
if (y0 < 0) {
adjustedY0 = 0;
adjustedY1 += Math.abs(y0);
}
tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0));
graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0);

Current issue is different from the already fixed #11473:

  • The example in Wrong rendering of pattern #11473 uses patterns provided by tikz library patterns, which have larger bounding box than X-/Y-steps. For tikz pattern crosshatch, it's /BBox [ -.99628 -.99628 3.9851 3.9851 ] /XStep 2.98883 /YStep 2.98883.
  • The example in current issue uses (relatively newer and more powerful) pattern Lines provided by tikz library patterns.meta, which has the size of bounding box exactly the same as X-/Y-steps. For the broken left pattern, it's /BBox [ -1.49442 -1.49442 1.49442 1.49442 ] /XStep 2.98883 /YStep 2.98883, and for the right it's /BBox [ 0 0 2.98883 2.98883 ] /XStep 2.98883 /YStep 2.98883.

Also the specific stream content used in the attached example shows since the content will be clipped, shifting the bounding box may raise the need to manipulating the contents as well, which I guess could be non-trivial.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status
Closed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions