From c2761bf4523deb05338672efeb2587107dd0b619 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 7 Sep 2008 18:32:51 +0000 Subject: [PATCH] Patch from bug #45738 - Initial HWPF support for Office Art Shapes git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692918 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 5 +- src/documentation/content/xdocs/status.xml | 5 +- .../src/org/apache/poi/hwpf/HWPFDocument.java | 12 +++ .../apache/poi/hwpf/model/ShapesTable.java | 54 ++++++++++++ .../org/apache/poi/hwpf/usermodel/Shape.java | 74 ++++++++++++++++ .../apache/poi/hwpf/data/WithArtShapes.doc | Bin 0 -> 53760 bytes .../apache/poi/hwpf/usermodel/TestShapes.java | 83 ++++++++++++++++++ 7 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java 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 0000000000000000000000000000000000000000..27793c37a4605ddb4f206acf2134b088f8f5f4b7 GIT binary patch literal 53760 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 literal 0 HcmV?d00001 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()); + + } +} -- 2.39.5