diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2015-11-08 23:13:28 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2015-11-08 23:13:28 +0000 |
commit | f9c8f0826d4e576ecc237c6c01c61214d882439d (patch) | |
tree | cb9797c4d5f0885454ef82cd04eeb7c8d25185ab | |
parent | 9aef48e6b536628036cd7ad0d44a1ffa3b7ecec3 (diff) | |
download | poi-f9c8f0826d4e576ecc237c6c01c61214d882439d.tar.gz poi-f9c8f0826d4e576ecc237c6c01c61214d882439d.zip |
Add support for HSLF metro blobs
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1713318 13f79535-47bb-0310-9956-ffa450edef68
10 files changed, 235 insertions, 50 deletions
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java index ae9c8bac66..5f66e9fca1 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java @@ -61,7 +61,7 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { protected XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){
super(shape,sheet);
- _shapes = sheet.buildShapes(shape);
+ _shapes = XSLFSheet.buildShapes(shape, sheet);
_grpSpPr = shape.getGrpSpPr();
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java new file mode 100644 index 0000000000..87278f701a --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java @@ -0,0 +1,60 @@ +/* ====================================================================
+ 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.xslf.usermodel;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
+
+/**
+ * Experimental class for metro blobs, i.e. an alternative escher property
+ * containing an ooxml representation of the shape.
+ * This is the helper class for HSLFMetroShape to dive into OOXML classes
+ */
+@Internal
+public class XSLFMetroShape {
+ /*
+ * parses the metro bytes to a XSLF shape
+ */
+ public static Shape<?,?> parseShape(byte metroBytes[])
+ throws InvalidFormatException, IOException, XmlException {
+ PackagePartName shapePN = PackagingURIHelper.createPartName("/drs/shapexml.xml");
+ OPCPackage pkg = null;
+ try {
+ pkg = OPCPackage.open(new ByteArrayInputStream(metroBytes));
+ PackagePart shapePart = pkg.getPart(shapePN);
+ CTGroupShape gs = CTGroupShape.Factory.parse(shapePart.getInputStream());
+ XSLFGroupShape xgs = new XSLFGroupShape(gs, null);
+ return xgs.getShapes().get(0);
+ } finally {
+ if (pkg != null) {
+ pkg.close();
+ }
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java index daca97131d..547e01fe8a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java @@ -90,20 +90,20 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { throw new IllegalStateException("SlideShow was not found"); } - protected List<XSLFShape> buildShapes(CTGroupShape spTree){ + protected static List<XSLFShape> buildShapes(CTGroupShape spTree, XSLFSheet sheet){ List<XSLFShape> shapes = new ArrayList<XSLFShape>(); for(XmlObject ch : spTree.selectPath("*")){ if(ch instanceof CTShape){ // simple shape - XSLFAutoShape shape = XSLFAutoShape.create((CTShape)ch, this); + XSLFAutoShape shape = XSLFAutoShape.create((CTShape)ch, sheet); shapes.add(shape); } else if (ch instanceof CTGroupShape){ - shapes.add(new XSLFGroupShape((CTGroupShape)ch, this)); + shapes.add(new XSLFGroupShape((CTGroupShape)ch, sheet)); } else if (ch instanceof CTConnector){ - shapes.add(new XSLFConnectorShape((CTConnector)ch, this)); + shapes.add(new XSLFConnectorShape((CTConnector)ch, sheet)); } else if (ch instanceof CTPicture){ - shapes.add(new XSLFPictureShape((CTPicture)ch, this)); + shapes.add(new XSLFPictureShape((CTPicture)ch, sheet)); } else if (ch instanceof CTGraphicalObjectFrame){ - XSLFGraphicFrame shape = XSLFGraphicFrame.create((CTGraphicalObjectFrame)ch, this); + XSLFGraphicFrame shape = XSLFGraphicFrame.create((CTGraphicalObjectFrame)ch, sheet); shapes.add(shape); } } @@ -156,7 +156,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { _drawing = new XSLFDrawing(this, cgs); } if (_shapes == null) { - _shapes = buildShapes(cgs); + _shapes = buildShapes(cgs, this); } } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java index 18632ffbf0..c8a1aeebd5 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -25,10 +25,15 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue;
import java.awt.Color;
+import java.io.File;
import java.io.IOException;
import java.util.List;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.HSLFTextShape;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples;
@@ -40,9 +45,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
-/**
- * @author Yegor Kozlov
- */
public class TestXSLFTextShape {
@Test
@@ -913,4 +915,16 @@ public class TestXSLFTextShape { ppt.close();
}
+
+ @Test
+ public void metroBlob() throws IOException {
+ File f = POIDataSamples.getSlideShowInstance().getFile("bug52297.ppt");
+ SlideShow<?,?> ppt = SlideShowFactory.create(f);
+ HSLFTextShape sh = (HSLFTextShape)ppt.getSlides().get(1).getShapes().get(3);
+ XSLFAutoShape xsh = (XSLFAutoShape)sh.getMetroShape();
+ String textExp = " ___ ___ ___ ________ __ _______ ___ ___________ __________ __ _____ ___ ___ ___ _______ ____ ______ ___________ _____________ ___ _______ ______ ____ ______ __ ___________ __________ ___ _________ _____ ________ __________ ___ _______ __________ ";
+ String textAct = xsh.getText();
+ ppt.close();
+ assertEquals(textExp, textAct);
+ }
}
\ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java new file mode 100644 index 0000000000..e5d9f93a95 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.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.hslf.model;
+
+import java.lang.reflect.Method;
+
+import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherComplexProperty;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherTertiaryOptRecord;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Experimental class for metro blobs, i.e. an alternative escher property
+ * containing an ooxml representation of the shape
+ */
+@Internal
+public class HSLFMetroShape<T extends Shape<?,?>> {
+ private static final POILogger LOGGER = POILogFactory.getLogger(HSLFMetroShape.class);
+
+ private final HSLFShape shape;
+
+ public HSLFMetroShape(HSLFShape shape) {
+ this.shape = shape;
+ }
+
+ /**
+ * @return the bytes of the metro blob, which are bytes of an OPCPackage, i.e. a zip stream
+ */
+ public byte[] getMetroBytes() {
+ AbstractEscherOptRecord opt = shape.getEscherChild(EscherTertiaryOptRecord.RECORD_ID);
+ if (opt != null) {
+ EscherComplexProperty ep = (EscherComplexProperty)opt.lookup(EscherProperties.GROUPSHAPE__METROBLOB);
+ if (ep != null) {
+ return ep.getComplexData();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the metro blob shape or null if either there's no metro blob or the ooxml classes
+ * aren't in the classpath
+ */
+ @SuppressWarnings("unchecked")
+ public T getShape() {
+ byte metroBytes[] = getMetroBytes();
+ if (metroBytes == null) {
+ return null;
+ }
+
+ // org.apache.poi.xslf.usermodel.XSLFMetroShape
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ Class<?> ms = cl.loadClass("org.apache.poi.xslf.usermodel.XSLFMetroShape");
+ Method m = ms.getMethod("parseShape", byte[].class);
+ return (T)m.invoke(null, new Object[]{metroBytes});
+ } catch (Exception e) {
+ LOGGER.log(POILogger.ERROR, "can't process metro blob, check if all dependencies for POI OOXML are in the classpath.", e);
+ return null;
+ }
+ }
+}
+
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java index 8e94421c5d..1e485de9ff 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java @@ -499,4 +499,9 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTe // TODO Auto-generated method stub } + + @Override + public boolean getFollowMasterGraphics() { + return getFollowMasterObjects(); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java index 792928d1ea..3872ecf5b8 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java @@ -17,8 +17,12 @@ package org.apache.poi.hslf.usermodel; -import org.apache.poi.ddf.*; -import org.apache.poi.sl.usermodel.*; +import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.sl.usermodel.ShapeContainer; +import org.apache.poi.sl.usermodel.ShapeType; +import org.apache.poi.sl.usermodel.TextBox; +import org.apache.poi.sl.usermodel.VerticalAlignment; /** * Represents a TextFrame shape in PowerPoint. @@ -88,5 +92,4 @@ public class HSLFTextBox extends HSLFTextShape implements TextBox<HSLFShape,HSLF setVerticalAlignment(VerticalAlignment.TOP); setEscherProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20002); } - } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java index bc8ac93c6e..f15cea2085 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java @@ -993,6 +993,15 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText }
return sb.toString();
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (HSLFTextRun r : getTextRuns()) {
+ sb.append(r.getRawText());
+ }
+ return toExternalString(sb.toString(), getRunType());
+ }
/**
* Returns a new string with line breaks converted into internal ppt
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java index f24173e204..cee75686f7 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java @@ -34,6 +34,7 @@ import org.apache.poi.ddf.EscherProperties; import org.apache.poi.ddf.EscherSimpleProperty; import org.apache.poi.ddf.EscherTextboxRecord; import org.apache.poi.hslf.exceptions.HSLFException; +import org.apache.poi.hslf.model.HSLFMetroShape; import org.apache.poi.hslf.record.EscherTextboxWrapper; import org.apache.poi.hslf.record.InteractiveInfo; import org.apache.poi.hslf.record.InteractiveInfoAtom; @@ -102,7 +103,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { */ public static final int WrapThrough = 4; - + /** * TextRun object which holds actual text and format data */ @@ -116,11 +117,11 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { /** * This setting is used for supporting a deprecated alignment - * + * * @see <a href=""></a> */ boolean alignToBaseline = false; - + /** * Used to calculate text bounds */ @@ -176,11 +177,11 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { super.afterInsert(sh); storeText(); - + EscherTextboxWrapper thisTxtbox = getEscherTextboxWrapper(); if(thisTxtbox != null){ _escherContainer.addChildRecord(thisTxtbox.getEscherRecord()); - + PPDrawing ppdrawing = sh.getPPDrawing(); ppdrawing.addTextboxWrapper(thisTxtbox); // Ensure the escher layer knows about the added records @@ -199,10 +200,10 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { protected EscherTextboxWrapper getEscherTextboxWrapper(){ if(_txtbox != null) return _txtbox; - + EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID); if (textRecord == null) return null; - + HSLFSheet sheet = getSheet(); if (sheet != null) { PPDrawing drawing = sheet.getPPDrawing(); @@ -219,7 +220,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { } } } - + _txtbox = new EscherTextboxWrapper(textRecord); return _txtbox; } @@ -236,15 +237,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { anchor.setSize(200, (int)anchor.getHeight()); setAnchor(anchor); } - double height = getTextHeight(); + double height = getTextHeight(); height += 1; // add a pixel to compensate rounding errors - + anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height); setAnchor(anchor); - + return anchor; - } - + } + /** * Returns the type of the text, from the TextHeaderAtom. * Possible values can be seen from TextHeaderAtom @@ -271,7 +272,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { paras.get(0).setRunType(type); } } - + /** * Returns the type of vertical alignment for the text. * One of the <code>Anchor*</code> constants defined in this class. @@ -310,7 +311,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { alignToBaseline = (align == AnchorBottomBaseline || align == AnchorBottomCenteredBaseline || align == AnchorTopBaseline || align == AnchorTopCenteredBaseline); - + return align; } @@ -334,15 +335,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { align = new int[]{AnchorBottom, AnchorBottomCentered, AnchorBottomBaseline, AnchorBottomCenteredBaseline}; break; } - + int align2 = align[(isCentered ? 1 : 0)+(alignToBaseline ? 2 : 0)]; - + setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align2); } - + /** * @return true, if vertical alignment is relative to baseline - * this is only used for older versions less equals Office 2003 + * this is only used for older versions less equals Office 2003 */ public boolean isAlignToBaseline() { getAlignment(); @@ -358,7 +359,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { this.alignToBaseline = alignToBaseline; setAlignment(isHorizontalCentered(), getVerticalAlignment()); } - + @Override public boolean isHorizontalCentered() { int va = getAlignment(); @@ -378,7 +379,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { public void setHorizontalCentered(Boolean isCentered) { setAlignment(isCentered, getVerticalAlignment()); } - + @Override public VerticalAlignment getVerticalAlignment() { int va = getAlignment(); @@ -492,7 +493,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { * Returns the distance (in points) between the edge of the text frame * and the edge of the inscribed rectangle of the shape that contains the text. * Default value is 1/20 inch. - * + * * @param propId the id of the inset edge * @return the inset in points */ @@ -500,7 +501,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { AbstractEscherOptRecord opt = getEscherOptRecord(); EscherSimpleProperty prop = getEscherProperty(opt, propId); int val = prop == null ? (int)(Units.toEMU(Units.POINT_DPI)*defaultInch) : prop.getPropertyValue(); - return Units.toPoints(val); + return Units.toPoints(val); } /** @@ -509,8 +510,8 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { */ private void setInset(short propId, double margin){ setEscherProperty(propId, Units.toEMU(margin)); - } - + } + /** * Returns the value indicating word wrap. * @@ -524,7 +525,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT); return prop == null ? WrapSquare : prop.getPropertyValue(); } - + /** * Specifies how the text should be wrapped * @@ -545,7 +546,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { public void setWordWrap(boolean wrap) { setWordWrapEx(wrap ? WrapSquare : WrapNone); } - + /** * @return id for the text. */ @@ -567,7 +568,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { @Override public List<HSLFTextParagraph> getTextParagraphs(){ if (!_paragraphs.isEmpty()) return _paragraphs; - + _txtbox = getEscherTextboxWrapper(); if (_txtbox == null) { _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph()); @@ -578,7 +579,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { // there are actually TextBoxRecords without extra data - see #54722 _paragraphs = HSLFTextParagraph.createEmptyParagraph(_txtbox); } - + if (_paragraphs.isEmpty()) { logger.log(POILogger.WARN, "TextRecord didn't contained any text lines"); } @@ -594,7 +595,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { for (HSLFTextParagraph p : _paragraphs) { p.setParentShape(this); } - + return _paragraphs; } @@ -675,7 +676,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { // them to \n String text = rawText.replace('\r','\n').replace('\u000b', replChr); */ - + /** * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder. * @@ -777,13 +778,13 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { return HSLFTextParagraph.toExternalString(rawText, getRunType()); } - + // Update methods follow /** * Adds the supplied text onto the end of the TextParagraphs, * creating a new RichTextRun for it to sit in. - * + * * @param text the text string used by this object. */ public HSLFTextRun appendText(String text, boolean newParagraph) { @@ -800,7 +801,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { setTextId(text.hashCode()); return htr; } - + /** * Saves the modified paragraphs/textrun to the records. * Also updates the styles to the correct text length. @@ -813,7 +814,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { /** * Returns the array of all hyperlinks in this text run - * + * * @return the array of all hyperlinks in this text run or <code>null</code> * if not found. */ @@ -880,5 +881,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { } } - + + /** + * Get alternative representation of text shape stored as metro blob escher property. + * The returned shape is the first shape in stored group shape of the metro blob + * + * @return null, if there's no alternative representation, otherwise the text shape + */ + public TextShape<?,?> getMetroShape() { + HSLFMetroShape<TextShape<?,?>> mbs = new HSLFMetroShape<TextShape<?,?>>(this); + return mbs.getShape(); + } }
\ No newline at end of file diff --git a/test-data/slideshow/bug52297.ppt b/test-data/slideshow/bug52297.ppt Binary files differnew file mode 100644 index 0000000000..79fd609b80 --- /dev/null +++ b/test-data/slideshow/bug52297.ppt |