Author: fanningpj
Date: Wed Mar 6 11:53:17 2024
New Revision: 1916146
URL: http://svn.apache.org/viewvc?rev=1916146&view=rev
Log:
[github-604] XDGF: add support for poly lines. Thanks to Dmitrii Komarov. This
closes #604
Added:
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/TestPolylineTo.java
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryTestUtils.java
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java?rev=1916146&r1=1916145&r2=1916146&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java
Wed Mar 6 11:53:17 2024
@@ -27,6 +27,9 @@ import com.microsoft.schemas.office.visi
public class PolyLineTo implements GeometryRow {
+ private static final String POLYLINE_FORMULA_PREFIX = "POLYLINE(";
+ private static final String POLYLINE_FORMULA_SUFFIX = ")";
+
PolyLineTo _master;
// The x-coordinate of the ending vertex of a polyline.
@@ -96,6 +99,39 @@ public class PolyLineTo implements Geome
public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) {
if (getDel())
return;
- throw new POIXMLException("Polyline support not implemented");
+
+ // A polyline formula: POLYLINE(xType, yType, x1, y1, x2, y2, ...)
+ String formula = getA().trim();
+ if (!formula.startsWith(POLYLINE_FORMULA_PREFIX) ||
!formula.endsWith(POLYLINE_FORMULA_SUFFIX)) {
+ throw new POIXMLException("Invalid POLYLINE formula: " + formula);
+ }
+
+ String[] components = formula
+ .substring(POLYLINE_FORMULA_PREFIX.length(), formula.length()
- POLYLINE_FORMULA_SUFFIX.length())
+ .split(",");
+
+ if (components.length < 2) {
+ throw new POIXMLException("Invalid POLYLINE formula (not enough
arguments): " + formula);
+ }
+
+ if (components.length % 2 != 0) {
+ throw new POIXMLException("Invalid POLYLINE formula -- need 2 +
n*2 arguments, got " + components.length);
+ }
+
+ if (components.length > 2) {
+ // If xType is zero, the X coordinates are interpreted as relative
coordinates
+ double xScale = Integer.parseInt(components[0].trim()) == 0 ?
parent.getWidth() : 1.0;
+ // If yType is zero, the Y coordinates are interpreted as relative
coordinates
+ double yScale = Integer.parseInt(components[1].trim()) == 0 ?
parent.getHeight() : 1.0;
+
+ for (int i = 2; i < components.length - 1; i += 2) {
+ double x = Double.parseDouble(components[i].trim());
+ double y = Double.parseDouble(components[i + 1].trim());
+
+ path.lineTo(x * xScale, y * yScale);
+ }
+ }
+
+ path.lineTo(getX(), getY());
}
}
Modified:
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryTestUtils.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryTestUtils.java?rev=1916146&r1=1916145&r2=1916146&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryTestUtils.java
(original)
+++
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryTestUtils.java
Wed Mar 6 11:53:17 2024
@@ -19,7 +19,9 @@ package org.apache.poi.xdgf.usermodel.se
import com.microsoft.schemas.office.visio.x2012.main.CellType;
import com.microsoft.schemas.office.visio.x2012.main.RowType;
+import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType;
import org.apache.poi.util.LocaleUtil;
+import org.apache.poi.xdgf.usermodel.XDGFShape;
import org.junit.jupiter.api.Assertions;
import java.awt.geom.Path2D;
@@ -99,4 +101,19 @@ public final class GeometryTestUtils {
}
}
+ /**
+ * Mocks a shape for testing geometries with relative coordinates.
+ */
+ public static XDGFShape mockShape(double width, double height) {
+ ShapeSheetType shapeSheet = ShapeSheetType.Factory.newInstance();
+ CellType[] cells = {
+ createCell("Width", Double.toString(width)),
+ createCell("Height", Double.toString(height))
+ };
+ shapeSheet.setCellArray(cells);
+
+ // Parent page and document is not used during parsing. It's safe to
leave them as nulls for mocking
+ return new XDGFShape(shapeSheet, null, null);
+ }
+
}
Added:
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/TestPolylineTo.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/TestPolylineTo.java?rev=1916146&view=auto
==============================================================================
---
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/TestPolylineTo.java
(added)
+++
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xdgf/usermodel/section/geometry/TestPolylineTo.java
Wed Mar 6 11:53:17 2024
@@ -0,0 +1,109 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xdgf.usermodel.section.geometry;
+
+import com.microsoft.schemas.office.visio.x2012.main.RowType;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.xdgf.usermodel.XDGFShape;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.awt.geom.Path2D;
+import java.util.HashMap;
+
+public class TestPolylineTo {
+
+ private static final double X0 = 0.0;
+ private static final double Y0 = 0.0;
+ private static final double X = 100.0;
+ private static final double Y = 100.0;
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "POLYLINE(1, 1, 0.0, 50.0, 100.0, 50.0)",
+ "POLYLINE(1, 0, 0.0, 0.5, 100.0, 0.5)",
+ "POLYLINE(0, 1, 0.0, 50.0, 1.0, 50.0)",
+ "POLYLINE(0, 0, 0.0, 0.5, 1.0, 0.5)"
+ })
+ public void shouldAddMultipleLinesToPath(String formula) {
+ PolyLineTo polyLine = createPolyLine(formula);
+
+ XDGFShape parent = GeometryTestUtils.mockShape(X - X0, Y - Y0);
+
+ Path2D.Double actualPath = new Path2D.Double();
+ actualPath.moveTo(X0, Y0);
+
+ polyLine.addToPath(actualPath, parent);
+
+ Path2D expectedPath = new Path2D.Double();
+ expectedPath.moveTo(X0, Y0);
+ expectedPath.lineTo(0.0, 50.0);
+ expectedPath.lineTo(100.0, 50.0);
+ expectedPath.lineTo(X, Y);
+
+ GeometryTestUtils.assertPath(expectedPath, actualPath);
+ }
+
+ @Test
+ public void shouldAddSingleLineToPath() {
+ PolyLineTo polyLine = createPolyLine("POLYLINE(1, 1)");
+
+ XDGFShape parent = GeometryTestUtils.mockShape(X - X0, Y - Y0);
+
+ Path2D.Double actualPath = new Path2D.Double();
+ actualPath.moveTo(X0, Y0);
+
+ polyLine.addToPath(actualPath, parent);
+
+ Path2D expectedPath = new Path2D.Double();
+ expectedPath.moveTo(X0, Y0);
+ expectedPath.lineTo(X, Y);
+
+ GeometryTestUtils.assertPath(expectedPath, actualPath);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "1, 1)", // Does not start with POLYLINE(
+ "POLYLINE(1, 1", // Does not end with )
+ "POLYLINE()", // Empty arguments
+ "POLYLINE(1)", // Not enough arguments (less than two)
+ "POLYLINE(1, 1, 100.0)", // Odd number of arguments
+ })
+ public void shouldThrowExceptionWhenPolyLineFormulaIsIncorrect(String
formula) {
+ PolyLineTo polyLine = createPolyLine(formula);
+
+ Path2D.Double path = new Path2D.Double();
+ Assertions.assertThrows(POIXMLException.class, () ->
polyLine.addToPath(path, null));
+ }
+
+ private static PolyLineTo createPolyLine(String formula) {
+ RowType row = GeometryTestUtils.createRow(
+ 0L,
+ new HashMap<String, Object>() {{
+ put("X", X);
+ put("Y", Y);
+ put("A", formula);
+ }}
+ );
+ return new PolyLineTo(row);
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]