diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java index 8192c8f00..29d0dfc34 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Layer.java @@ -90,6 +90,7 @@ public class Layer { private int _selectionEndY; private boolean _forDeletion; + private boolean _hasFixedAncester; /** * @see {@link #getCurrentTransformMatrix()} @@ -117,6 +118,7 @@ public Layer(Layer parent, Box master, CssContext c) { master.setLayer(this); master.setContainingLayer(this); _hasLocalTransform = !master.getStyle().isIdent(CSSName.TRANSFORM, IdentValue.NONE); + _hasFixedAncester = (parent != null && parent._hasFixedAncester) || master.getStyle().isFixed(); } /** @@ -159,6 +161,10 @@ public boolean isForDeletion() { return this._forDeletion; } + public boolean hasFixedAncester() { + return _hasFixedAncester; + } + public Layer getParent() { return _parent; } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/DisplayListCollector.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/DisplayListCollector.java index 4005bc5bc..34e5296c3 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/DisplayListCollector.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/DisplayListCollector.java @@ -108,8 +108,12 @@ protected void collect(RenderingContext c, Layer layer, DisplayListContainer dlP } } return; + } else if (layer.hasFixedAncester()) { + // Fixed child layers are handled when the fixed layer is painted by + // the SimplePainter. + return; } - + List layerPages = PagedBoxCollector.findLayerPages(c, layer, _pages); int layerPageStart = findStartPage(c, layer); int layerPageEnd = findEndPage(c, layer); diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/TransformCreator.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/TransformCreator.java index 843e5b110..1c18eb771 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/TransformCreator.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/displaylist/TransformCreator.java @@ -95,8 +95,8 @@ public static AffineTransform createDocumentCoordinatesTransform(Box master, Css return ctm; } - private static float getPageTranslateX(float absTranslateX, int shadowPageNumber, PageBox page, CssContext c) { - if (shadowPageNumber == -1) { + private static float getPageTranslateX(float absTranslateX, int shadowPageNumber, PageBox page, CssContext c, Box box) { + if (shadowPageNumber == -1 || box.getContainingLayer().hasFixedAncester()) { return absTranslateX + page.getMarginBorderPadding(c, CalculatedStyle.LEFT); } @@ -132,12 +132,12 @@ private static void createTransform(CssContext c, Box box, PageBox page, AffineT if (transformYOrigin == TransformYOrigin.PAGE_BOTTOM) { // The transform point is the lower left of the page (PDF coordinate system). - pageTranslateX = getPageTranslateX(absTranslateX, shadowPageNumber, page, c); + pageTranslateX = getPageTranslateX(absTranslateX, shadowPageNumber, page, c, box); float topDownPageTranslateY = (absTranslateY + page.getMarginBorderPadding(c, CalculatedStyle.TOP)) - page.getPaintingTop(); pageTranslateY = (page.getHeight(c) - topDownPageTranslateY); } else { // PAGE_TOP // The transform point is the upper left of the page. - pageTranslateX = getPageTranslateX(absTranslateX, shadowPageNumber, page, c); + pageTranslateX = getPageTranslateX(absTranslateX, shadowPageNumber, page, c, box); pageTranslateY = (absTranslateY - page.getPaintingTop()) + page.getMarginBorderPadding(c, CalculatedStyle.TOP); } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/simplepainter/SimplePainter.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/simplepainter/SimplePainter.java index d1d4cf3cd..a5f8f8459 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/simplepainter/SimplePainter.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/simplepainter/SimplePainter.java @@ -39,9 +39,12 @@ public void paintLayer(RenderingContext c, Layer layer) { if (parentClip != null) { c.getOutputDevice().pushClip(parentClip); } - + if (layer.hasLocalTransform()) { - AffineTransform transform = TransformCreator.createPageMarginCoordinatesTransform(c, master, c.getPage(), xTranslate, yTranslate); + AffineTransform transform = c.isInPageMargins() ? + TransformCreator.createPageMarginCoordinatesTransform(c, master, c.getPage(), xTranslate, yTranslate) : + TransformCreator.createPageCoordinatesTranform(c, master, c.getPage(), c.getShadowPageNumber()); + c.getOutputDevice().pushTransformLayer(transform); } @@ -56,7 +59,7 @@ public void paintLayer(RenderingContext c, Layer layer) { paintLayerBackgroundAndBorder(c, master); } - if (layer.isRootLayer() || layer.isStackingContext()) { + if (layer.isRootLayer() || layer.isStackingContext() || master.getStyle().isFixed()) { paintLayers(c, layer.getSortedLayers(Layer.NEGATIVE)); } @@ -69,7 +72,7 @@ public void paintLayer(RenderingContext c, Layer layer) { paintInlineContent(c, boxCollector.inlines()); paintReplacedElements(c, boxCollector.replaceds()); - if (layer.isRootLayer() || layer.isStackingContext()) { + if (layer.isRootLayer() || layer.isStackingContext() || master.getStyle().isFixed()) { paintLayers(c, layer.collectLayers(Layer.AUTO)); // TODO z-index: 0 layers should be painted atomically paintLayers(c, layer.getSortedLayers(Layer.ZERO)); @@ -213,6 +216,10 @@ private void paintLayers(RenderingContext c, List layers) { } public void paintAsLayer(RenderingContext c, BlockBox startingPoint) { + if (startingPoint.getStyle().requiresLayer()) { + return; + } + SimpleBoxCollector collector = new SimpleBoxCollector(); collector.collect(c, startingPoint.getContainingLayer(), startingPoint); diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/expected/text/fixed-nested-transform.pdf b/openhtmltopdf-examples/src/main/resources/visualtest/expected/text/fixed-nested-transform.pdf new file mode 100644 index 000000000..671f76ddb Binary files /dev/null and b/openhtmltopdf-examples/src/main/resources/visualtest/expected/text/fixed-nested-transform.pdf differ diff --git a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/TextVisualRegressionTest.java b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/TextVisualRegressionTest.java index d0162c67f..4ed766c49 100644 --- a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/TextVisualRegressionTest.java +++ b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/TextVisualRegressionTest.java @@ -452,8 +452,6 @@ public void testFixedNestedInlineBlock() throws IOException { * Tests that a nested transform in a fixed element renders correctly. */ @Test - @Ignore // Failing due to using the wrong transform offsets. - // Also boxes being painted twice. public void testFixedNestedTransform() throws IOException { assertTrue(run("fixed-nested-transform")); }