From e92a71fbd66bb441984f45d91227c3cedfa94f75 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Thu, 22 Oct 2020 09:00:29 +0000 Subject: [PATCH] FOP-2980: Reduce filesize for AFP Graphics2D git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1882752 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/afp/AFPGraphics2D.java | 39 +++++++++++++++---- .../apache/fop/afp/AFPGraphics2DTestCase.java | 26 +++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/afp/AFPGraphics2D.java b/fop-core/src/main/java/org/apache/fop/afp/AFPGraphics2D.java index c34a7dff0..88a15ad12 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/AFPGraphics2D.java +++ b/fop-core/src/main/java/org/apache/fop/afp/AFPGraphics2D.java @@ -42,6 +42,8 @@ import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -432,9 +434,11 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand private void processPathIterator(PathIterator iter) { double[] dstPts = new double[6]; double[] currentPosition = new double[2]; + List fillets = new ArrayList(); for (int[] openingCoords = new int[2]; !iter.isDone(); iter.next()) { switch (iter.currentSegment(dstPts)) { case PathIterator.SEG_LINETO: + flush(fillets); graphicsObj.addLine(new int[] { (int)Math.round(dstPts[X]), (int)Math.round(dstPts[Y]) @@ -442,12 +446,13 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand currentPosition = new double[]{dstPts[X], dstPts[Y]}; break; case PathIterator.SEG_QUADTO: + flush(fillets); graphicsObj.addFillet(new int[] { (int)Math.round(dstPts[X1]), (int)Math.round(dstPts[Y1]), (int)Math.round(dstPts[X2]), (int)Math.round(dstPts[Y2]) - }, true); + }, true); currentPosition = new double[]{dstPts[X2], dstPts[Y2]}; break; case PathIterator.SEG_CUBICTO: @@ -458,18 +463,17 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand if (quadParts.length >= 4) { for (double[] quadPts : quadParts) { if (quadPts != null && quadPts.length == 4) { - graphicsObj.addFillet(new int[]{ - (int) Math.round(quadPts[X1]), - (int) Math.round(quadPts[Y1]), - (int) Math.round(quadPts[X2]), - (int) Math.round(quadPts[Y2]) - }, true); + fillets.add((int) Math.round(quadPts[X1])); + fillets.add((int) Math.round(quadPts[Y1])); + fillets.add((int) Math.round(quadPts[X2])); + fillets.add((int) Math.round(quadPts[Y2])); currentPosition = new double[]{quadPts[X2], quadPts[Y2]}; } } } break; case PathIterator.SEG_MOVETO: + flush(fillets); openingCoords = new int[] { (int)Math.round(dstPts[X]), (int)Math.round(dstPts[Y]) @@ -478,6 +482,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand graphicsObj.setCurrentPosition(openingCoords); break; case PathIterator.SEG_CLOSE: + flush(fillets); graphicsObj.addLine(openingCoords, true); currentPosition = new double[]{openingCoords[0], openingCoords[1]}; break; @@ -486,6 +491,26 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand break; } } + flush(fillets); + } + + private void flush(List fillets) { + List intList = listToIntLists(fillets); + for (int[] ints : intList) { + graphicsObj.addFillet(ints, true); + } + } + + private List listToIntLists(List input) { + List out = new ArrayList(); + while (!input.isEmpty()) { + int[] data = new int[Math.min(100, input.size())]; + for (int i = 0; i < data.length; i++) { + data[i] = input.remove(0); + } + out.add(data); + } + return out; } /** {@inheritDoc} */ diff --git a/fop-core/src/test/java/org/apache/fop/afp/AFPGraphics2DTestCase.java b/fop-core/src/test/java/org/apache/fop/afp/AFPGraphics2DTestCase.java index 7b261d482..7045e80ee 100644 --- a/fop-core/src/test/java/org/apache/fop/afp/AFPGraphics2DTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/afp/AFPGraphics2DTestCase.java @@ -20,13 +20,22 @@ package org.apache.fop.afp; import java.awt.BasicStroke; +import java.awt.Rectangle; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import org.junit.Assert; import org.junit.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.apache.xmlgraphics.java2d.GraphicContext; + import org.apache.fop.afp.modca.GraphicsObject; import org.apache.fop.fonts.FontInfo; @@ -54,4 +63,21 @@ public class AFPGraphics2DTestCase { verify(gObject).setLineWidth(correctedLineWidth); } + @Test + public void testDrawGraphicsFillet() throws IOException { + GraphicContext gc = new GraphicContext(); + gc.setClip(new Rectangle(0, 0, 2, 2)); + graphics2D.setGraphicContext(gc); + GraphicsObject go = new GraphicsObject(new Factory(), "test"); + graphics2D.setGraphicsObject(go); + graphics2D.draw(new Area(new Ellipse2D.Double(0, 0, 100, 100))); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + go.writeToStream(bos); + ByteArrayInputStream is = new ByteArrayInputStream(bos.toByteArray()); + is.skip(17 + 9 + 14 + 6); + int graphicsFilletMarker = 0x85; + Assert.assertEquals(is.read(), graphicsFilletMarker); + int sizeOfGraphicsFillet = 128; + Assert.assertEquals(is.read(), sizeOfGraphicsFillet); + } } -- 2.39.5