diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index fe18530168..57934cb893 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,8 +37,9 @@ - 45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings - 45728 Fix for SlideShow.reorderSlide in HSLF + 45738 - Initial HWPF support for Office Art Shapes + 45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings + 45728 - Fix for SlideShow.reorderSlide in HSLF Initial support for embedded movies and controls in HSLF 45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF() Support for HPBF Publisher hyperlinks, including during text extraction diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 0cc173d6b8..9cbedfcaf0 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,8 +34,9 @@ - 45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings - 45728 Fix for SlideShow.reorderSlide in HSLF + 45738 - Initial HWPF support for Office Art Shapes + 45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings + 45728 - Fix for SlideShow.reorderSlide in HSLF Initial support for embedded movies and controls in HSLF 45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF() Support for HPBF Publisher hyperlinks, including during text extraction diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index daf1c8e172..f1898c082b 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -103,6 +103,9 @@ public class HWPFDocument extends POIDocument /** Escher Drawing Group information */ protected EscherRecordHolder _dgg; + /** Holds Office Art objects */ + protected ShapesTable _officeArts; + protected HWPFDocument() { super(null, null); @@ -252,6 +255,8 @@ public class HWPFDocument extends POIDocument // read in the pictures stream _pictures = new PicturesTable(this, _dataStream, _mainStream, _fspa, _dgg); + // And the art shapes stream + _officeArts = new ShapesTable(_tableStream, _fib); _st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin, _tpt, _cpSplit); _ss = new StyleSheet(_tableStream, _fib.getFcStshf()); @@ -392,6 +397,13 @@ public class HWPFDocument extends POIDocument public PicturesTable getPicturesTable() { return _pictures; } + + /** + * @return ShapesTable object, that is able to extract office are shapes from this document + */ + public ShapesTable getShapesTable() { + return _officeArts; + } /** * Writes out the word file that is represented by an instance of this class. diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java new file mode 100644 index 0000000000..998ea2d8fe --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java @@ -0,0 +1,54 @@ +/* ==================================================================== + 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.hwpf.model; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.hwpf.usermodel.Shape; + +public class ShapesTable { + private List _shapes; + private List _shapesVisibili; //holds visible shapes + + public ShapesTable(byte [] tblStream, FileInformationBlock fib) { + PlexOfCps binTable = new PlexOfCps(tblStream, + fib.getFcPlcspaMom(), fib.getLcbPlcspaMom(), 26); + + _shapes = new ArrayList(); + _shapesVisibili = new ArrayList(); + + + for(int i = 0; i < binTable.length(); i++) { + GenericPropertyNode nodo = binTable.getProperty(i); + + Shape sh = new Shape(nodo); + _shapes.add(sh); + if(sh.isWithinDocument()) + _shapesVisibili.add(sh); + } + } + + public List getAllShapes() { + return _shapes; + } + + public List getVisibleShapes() { + return _shapesVisibili; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java new file mode 100644 index 0000000000..1f798b620c --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java @@ -0,0 +1,74 @@ +/* ==================================================================== + 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.hwpf.usermodel; + +import org.apache.poi.hwpf.model.GenericPropertyNode; +import org.apache.poi.util.LittleEndian; + +public class Shape { + int _id, _left, _right, _top, _bottom; + /** + * true if the Shape bounds are within document (for + * example, it's false if the image left corner is outside the doc, like for + * embedded documents) + */ + boolean _inDoc; + + public Shape(GenericPropertyNode nodo) { + byte [] contenuto = nodo.getBytes(); + _id = LittleEndian.getInt(contenuto); + _left = LittleEndian.getInt(contenuto, 4); + _top = LittleEndian.getInt(contenuto, 8); + _right = LittleEndian.getInt(contenuto, 12); + _bottom = LittleEndian.getInt(contenuto, 16); + _inDoc = (_left >= 0 && _right >= 0 && _top >= 0 && _bottom >= +0); + } + + public int getId() { + return _id; + } + + public int getLeft() { + return _left; + } + + public int getRight() { + return _right; + } + + public int getTop() { + return _top; + } + + public int getBottom() { + return _bottom; + } + + public int getWidth() { + return _right - _left + 1; + } + + public int getHeight() { + return _bottom - _top + 1; + } + + public boolean isWithinDocument() { + return _inDoc; + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc b/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc new file mode 100644 index 0000000000..27793c37a4 Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc differ diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java new file mode 100644 index 0000000000..273a03432b --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java @@ -0,0 +1,83 @@ +/* +* 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.hwpf.usermodel; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.poi.hwpf.HWPFDocument; + +/** + * Test the shapes handling + */ +public class TestShapes extends TestCase { + private String dirname = System.getProperty("HWPF.testdata.path"); + + /** + * two shapes, second is a group + */ + public void testShapes() throws Exception { + HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/WithArtShapes.doc")); + + List shapes = doc.getShapesTable().getAllShapes(); + List vshapes = doc.getShapesTable().getVisibleShapes(); + + assertEquals(2, shapes.size()); + assertEquals(2, vshapes.size()); + + Shape s1 = (Shape)shapes.get(0); + Shape s2 = (Shape)shapes.get(1); + + assertEquals(3616, s1.getWidth()); + assertEquals(1738, s1.getHeight()); + assertEquals(true, s1.isWithinDocument()); + + assertEquals(4817, s2.getWidth()); + assertEquals(2164, s2.getHeight()); + assertEquals(true, s2.isWithinDocument()); + + + // Re-serialisze, check still there + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.write(baos); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + doc = new HWPFDocument(bais); + + shapes = doc.getShapesTable().getAllShapes(); + vshapes = doc.getShapesTable().getVisibleShapes(); + + assertEquals(2, shapes.size()); + assertEquals(2, vshapes.size()); + + s1 = (Shape)shapes.get(0); + s2 = (Shape)shapes.get(1); + + assertEquals(3616, s1.getWidth()); + assertEquals(1738, s1.getHeight()); + assertEquals(true, s1.isWithinDocument()); + + assertEquals(4817, s2.getWidth()); + assertEquals(2164, s2.getHeight()); + assertEquals(true, s2.isWithinDocument()); + + } +}