]> source.dussan.org Git - poi.git/commitdiff
committing intermediate results - hslf is mostly migrated to common interface - junit...
authorAndreas Beeker <kiwiwings@apache.org>
Mon, 27 Apr 2015 20:13:43 +0000 (20:13 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Mon, 27 Apr 2015 20:13:43 +0000 (20:13 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1676365 13f79535-47bb-0310-9956-ffa450edef68

201 files changed:
src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
src/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java
src/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java
src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java
src/examples/src/org/apache/poi/hslf/examples/HeadersFootersDemo.java
src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java
src/examples/src/org/apache/poi/hslf/examples/PPT2PNG.java
src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java
src/examples/src/org/apache/poi/hslf/examples/TableDemo.java
src/examples/src/org/apache/poi/hssf/usermodel/examples/EmeddedObjects.java
src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step1.java
src/examples/src/org/apache/poi/xssf/usermodel/examples/EmbeddedObjects.java
src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java
src/java/org/apache/poi/ddf/EscherContainerRecord.java
src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java
src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFChart.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShapeContainer.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSheet.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableStyles.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java
src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java
src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java
src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java
src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
src/scratchpad/src/org/apache/poi/hslf/dev/PPDrawingTextListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/SLWTTextListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/SlideAndNotesAtomListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/SlideIdListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java
src/scratchpad/src/org/apache/poi/hslf/dev/TextStyleListing.java
src/scratchpad/src/org/apache/poi/hslf/dev/UserEditAndPersistListing.java
src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java
src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java
src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFAutoShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFBackground.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFFill.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFFreeformShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFMasterSheet.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFNotes.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFPictureShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFSheet.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFSimpleShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlide.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowEncrypted.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowImpl.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextBox.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextShape.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java
src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/Line.java
src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java
src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/ShapePainter.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/Table.java
src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java
src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/IndentProp.java
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java
src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java
src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java
src/scratchpad/src/org/apache/poi/sl/draw/geom/PresetGeometries.java
src/scratchpad/src/org/apache/poi/sl/usermodel/Line.java
src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java
src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java
src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeType.java
src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java
src/scratchpad/src/org/apache/poi/sl/usermodel/SlideShow.java
src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
src/scratchpad/src/org/apache/poi/sl/usermodel/TextRun.java
src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java
src/scratchpad/testcases/org/apache/poi/TestPOIDocumentScratchpad.java
src/scratchpad/testcases/org/apache/poi/hslf/HSLFTestDataSamples.java
src/scratchpad/testcases/org/apache/poi/hslf/TestEncryptedFile.java
src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java
src/scratchpad/testcases/org/apache/poi/hslf/TestReWriteSanity.java
src/scratchpad/testcases/org/apache/poi/hslf/TestRecordCounts.java
src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java
src/scratchpad/testcases/org/apache/poi/hslf/model/AllHSLFModelTests.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestHeadersFooters.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestMovieShape.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPFont.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPicture.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideChangeNotes.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlides.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java [deleted file]
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRunReWrite.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextShape.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TextPainterTest.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestCurrentUserAtom.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestDocument.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestDocumentEncryption.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExObjList.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordContainer.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestMostRecentRecords.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNotesText.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList2.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList3.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRecordSetup.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSheetText.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSlideOrdering.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java [new file with mode: 0644]

index 7a4b20c187c0b7088950fe5175fbbe0a5b44a39c..229d7576e735eaab92f407ab129b7cec9c1fde85 100644 (file)
@@ -60,22 +60,22 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
         tr1.setText("POI-HSLF");
         box1.setAnchor(new Rectangle(54, 78, 612, 115));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
         tr2.setText("Java API To Access Microsoft PowerPoint Format Files");
         box2.setAnchor(new Rectangle(108, 204, 504, 138));
         slide.addShape(box2);
 
         HSLFTextBox box3 = new HSLFTextBox();
-        HSLFTextParagraph tr3 = box3.getTextParagraph();
-        tr3.getRichTextRuns()[0].setFontSize(32);
+        HSLFTextParagraph tr3 = box3.getTextParagraphs();
+        tr3.getTextRuns()[0].setFontSize(32);
         box3.setHorizontalAlignment(HSLFTextBox.AlignCenter);
         tr3.setText(
                 "Yegor Kozlov\r" +
@@ -88,14 +88,14 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("What is HSLF?");
         box1.setAnchor(new Rectangle(36, 21, 648, 90));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.BODY_TYPE);
         tr2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " +
                 "of the Powerpoint binary file format. \r" +
@@ -111,25 +111,25 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("HSLF in a Nutshell");
         box1.setAnchor(new Rectangle(36, 15, 648, 65));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.BODY_TYPE);
         tr2.setText(
                 "HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
                 "Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
                 "Comprehensive support of PowerPoint objects");
-        tr2.getRichTextRuns()[0].setFontSize(28);
+        tr2.getTextRuns()[0].setFontSize(28);
         box2.setAnchor(new Rectangle(36, 80, 648, 200));
         slide.addShape(box2);
 
         HSLFTextBox box3 = new HSLFTextBox();
-        HSLFTextParagraph tr3 = box3.getTextParagraph();
+        HSLFTextParagraph tr3 = box3.getTextParagraphs();
         tr3.setRunType(TextHeaderAtom.BODY_TYPE);
         tr3.setText(
                 "Rich text\r" +
@@ -137,13 +137,13 @@ public final class ApacheconEU08 {
                 "Shapes\r" +
                 "Pictures\r" +
                 "Master slides");
-        tr3.getRichTextRuns()[0].setFontSize(24);
-        tr3.getRichTextRuns()[0].setIndentLevel(1);
+        tr3.getTextRuns()[0].setFontSize(24);
+        tr3.getTextRuns()[0].setIndentLevel(1);
         box3.setAnchor(new Rectangle(36, 265, 648, 150));
         slide.addShape(box3);
 
         HSLFTextBox box4 = new HSLFTextBox();
-        HSLFTextParagraph tr4 = box4.getTextParagraph();
+        HSLFTextParagraph tr4 = box4.getTextParagraphs();
         tr4.setRunType(TextHeaderAtom.BODY_TYPE);
         tr4.setText("Access to low level data structures");
         box4.setAnchor(new Rectangle(36, 430, 648, 50));
@@ -162,8 +162,8 @@ public final class ApacheconEU08 {
             for (int j = 0; j < txt1[i].length; j++) {
                 TableCell cell = table1.getCell(i, j);
                 cell.setText(txt1[i][j]);
-                cell.getTextParagraph().getRichTextRuns()[0].setFontSize(10);
-                HSLFTextRun rt = cell.getTextParagraph().getRichTextRuns()[0];
+                cell.getTextParagraphs().getTextRuns()[0].setFontSize(10);
+                HSLFTextRun rt = cell.getTextParagraphs().getTextRuns()[0];
                 rt.setFontName("Arial");
                 rt.setBold(true);
                 if(i == 0){
@@ -197,10 +197,10 @@ public final class ApacheconEU08 {
 
         HSLFTextBox box1 = new HSLFTextBox();
         box1.setHorizontalAlignment(HSLFTextBox.AlignCenter);
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setText("The source code is available at\r" +
                 "http://people.apache.org/~yegor/apachecon_eu08/");
-        HSLFTextRun rt = tr1.getRichTextRuns()[0];
+        HSLFTextRun rt = tr1.getTextRuns()[0];
         rt.setFontSize(24);
         box1.setAnchor(new Rectangle(80, 356, 553, 65));
         slide.addShape(box1);
@@ -211,14 +211,14 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("HSLF in Action - 1\rData Extraction");
         box1.setAnchor(new Rectangle(36, 21, 648, 100));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.BODY_TYPE);
         tr2.setText(
                 "Text from slides and notes\r" +
@@ -234,22 +234,22 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("HSLF in Action - 2");
         box1.setAnchor(new Rectangle(36, 20, 648, 90));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
-        tr2.getRichTextRuns()[0].setFontSize(18);
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
+        tr2.getTextRuns()[0].setFontSize(18);
         tr2.setText("Creating a simple presentation from scratch");
         box2.setAnchor(new Rectangle(170, 100, 364, 30));
         slide.addShape(box2);
 
         HSLFTextBox box3 = new HSLFTextBox();
-        HSLFTextParagraph tr3 = box3.getTextParagraph();
-        HSLFTextRun rt3 = tr3.getRichTextRuns()[0];
+        HSLFTextParagraph tr3 = box3.getTextParagraphs();
+        HSLFTextRun rt3 = tr3.getTextRuns()[0];
         rt3.setFontName("Courier New");
         rt3.setFontSize(8);
         tr3.setText(
@@ -296,7 +296,7 @@ public final class ApacheconEU08 {
         HSLFTextBox box2 = new HSLFTextBox();
         box2.setHorizontalAlignment(HSLFTextBox.AlignCenter);
         box2.setVerticalAlignment(HSLFTextBox.AnchorMiddle);
-        box2.getTextParagraph().setText("Java Code");
+        box2.getTextParagraphs().setText("Java Code");
         box2.getFill().setForegroundColor(new Color(187, 224, 227));
         box2.setLineColor(Color.black);
         box2.setLineWidth(0.75);
@@ -306,7 +306,7 @@ public final class ApacheconEU08 {
         HSLFTextBox box3 = new HSLFTextBox();
         box3.setHorizontalAlignment(HSLFTextBox.AlignCenter);
         box3.setVerticalAlignment(HSLFTextBox.AnchorMiddle);
-        box3.getTextParagraph().setText("*.ppt file");
+        box3.getTextParagraphs().setText("*.ppt file");
         box3.setLineWidth(0.75);
         box3.setLineColor(Color.black);
         box3.getFill().setForegroundColor(new Color(187, 224, 227));
@@ -325,14 +325,14 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("Wait, there is more!");
         box1.setAnchor(new Rectangle(36, 21, 648, 90));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.BODY_TYPE);
         tr2.setText(
                 "Rich text\r" +
@@ -347,22 +347,22 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("HSLF in Action - 3");
         box1.setAnchor(new Rectangle(36, 20, 648, 50));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
-        tr2.getRichTextRuns()[0].setFontSize(18);
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
+        tr2.getTextRuns()[0].setFontSize(18);
         tr2.setText("PPGraphics2D: PowerPoint Graphics2D driver");
         box2.setAnchor(new Rectangle(178, 70, 387, 30));
         slide.addShape(box2);
 
         HSLFTextBox box3 = new HSLFTextBox();
-        HSLFTextParagraph tr3 = box3.getTextParagraph();
-        HSLFTextRun rt3 = tr3.getRichTextRuns()[0];
+        HSLFTextParagraph tr3 = box3.getTextParagraphs();
+        HSLFTextRun rt3 = tr3.getTextRuns()[0];
         rt3.setFontName("Courier New");
         rt3.setFontSize(8);
         tr3.setText(
@@ -449,16 +449,16 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
         tr1.setText("HSLF Development Plans");
         box1.setAnchor(new Rectangle(36, 21, 648, 90));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.BODY_TYPE);
-        tr2.getRichTextRuns()[0].setFontSize(32);
+        tr2.getTextRuns()[0].setFontSize(32);
         tr2.setText(
                 "Support for more PowerPoint functionality\r" +
                 "Rendering slides into java.awt.Graphics2D");
@@ -466,27 +466,27 @@ public final class ApacheconEU08 {
         slide.addShape(box2);
 
         HSLFTextBox box3 = new HSLFTextBox();
-        HSLFTextParagraph tr3 = box3.getTextParagraph();
+        HSLFTextParagraph tr3 = box3.getTextParagraphs();
         tr3.setRunType(TextHeaderAtom.BODY_TYPE);
-        tr3.getRichTextRuns()[0].setIndentLevel(1);
+        tr3.getTextRuns()[0].setIndentLevel(1);
         tr3.setText(
                 "A way to export slides into images or other formats");
         box3.setAnchor(new Rectangle(36, 220, 648, 70));
         slide.addShape(box3);
 
         HSLFTextBox box4 = new HSLFTextBox();
-        HSLFTextParagraph tr4 = box4.getTextParagraph();
+        HSLFTextParagraph tr4 = box4.getTextParagraphs();
         tr4.setRunType(TextHeaderAtom.BODY_TYPE);
-        tr4.getRichTextRuns()[0].setFontSize(32);
+        tr4.getTextRuns()[0].setFontSize(32);
         tr4.setText(
                 "Integration with Apache FOP - Formatting Objects Processor");
         box4.setAnchor(new Rectangle(36, 290, 648, 90));
         slide.addShape(box4);
 
         HSLFTextBox box5 = new HSLFTextBox();
-        HSLFTextParagraph tr5 = box5.getTextParagraph();
+        HSLFTextParagraph tr5 = box5.getTextParagraphs();
         tr5.setRunType(TextHeaderAtom.BODY_TYPE);
-        tr5.getRichTextRuns()[0].setIndentLevel(1);
+        tr5.getTextRuns()[0].setIndentLevel(1);
         tr5.setText(
                 "Transformation of XSL-FO into PPT\r" +
                 "PPT2PDF transcoder");
@@ -498,14 +498,14 @@ public final class ApacheconEU08 {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox box1 = new HSLFTextBox();
-        HSLFTextParagraph tr1 = box1.getTextParagraph();
+        HSLFTextParagraph tr1 = box1.getTextParagraphs();
         tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
         tr1.setText("Questions?");
         box1.setAnchor(new Rectangle(54, 167, 612, 115));
         slide.addShape(box1);
 
         HSLFTextBox box2 = new HSLFTextBox();
-        HSLFTextParagraph tr2 = box2.getTextParagraph();
+        HSLFTextParagraph tr2 = box2.getTextParagraphs();
         tr2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
         tr2.setText(
                 "http://poi.apache.org/hslf/\r" +
index ed6dd1231df73b9996928d04fc5d6d1249183e3b..58aaf1fff2c9226366093e87eeacddc9807ae8df 100644 (file)
 
 package org.apache.poi.hslf.examples;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.model.HSLFSlide;
-import org.apache.poi.hslf.model.HSLFTextBox;
+import org.apache.poi.hslf.usermodel.*;
 
 import java.io.FileOutputStream;
 
@@ -39,7 +36,7 @@ public final class BulletsDemo {
         HSLFSlide slide = ppt.createSlide();
 
         HSLFTextBox shape = new HSLFTextBox();
-        HSLFTextRun rt = shape.getTextParagraph().getRichTextRuns()[0];
+        HSLFTextRun rt = shape.getTextParagraphs().getTextRuns()[0];
         shape.setText(
                 "January\r" +
                 "February\r" +
index 99c5d7d31f8b441a8c2c24f5b00fb42a78abae61..873215232473ea51f836729b658ab0de850b3233 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.examples;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hslf.model.*;
 
 import java.io.FileOutputStream;
@@ -43,7 +43,7 @@ public final class CreateHyperlink {
         textBox1.setAnchor(new Rectangle(100, 100, 200, 50));
 
         String text = textBox1.getText();
-        Hyperlink link = new Hyperlink();
+        HSLFHyperlink link = new HSLFHyperlink();
         link.setAddress("http://www.apache.org");
         link.setTitle(textBox1.getText());
         int linkId = ppt.addHyperlink(link);
@@ -58,7 +58,7 @@ public final class CreateHyperlink {
         textBox2.setText("Go to slide #3");
         textBox2.setAnchor(new Rectangle(100, 300, 200, 50));
 
-        Hyperlink link2 = new Hyperlink();
+        HSLFHyperlink link2 = new HSLFHyperlink();
         link2.setAddress(slideC);
         ppt.addHyperlink(link2);
 
index 4e678ba64d5ba332bb4c61d0433c94881f71b7ec..19fe496769651810a094a9b0caf1a839bd478a75 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.examples;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hslf.model.*;
 
 import java.awt.*;
index 068d6753473394b54c4e8be8448d81c62aca92d1..b335e1f1e140729405e3b63dc863783d67a710d4 100644 (file)
@@ -16,9 +16,9 @@
 ==================================================================== */
 package org.apache.poi.hslf.examples;
 
+import org.apache.poi.hslf.usermodel.HSLFSlide;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.hslf.model.HeadersFooters;
-import org.apache.poi.hslf.model.HSLFSlide;
 
 import java.io.FileOutputStream;
 
index 89dcb636afc6f039dffce049bd24cf2da378d743..b9af6d2d56cafd273e392d8ae60315770ec90b8e 100644 (file)
 
 package org.apache.poi.hslf.examples;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.model.HSLFSlide;
-import org.apache.poi.hslf.model.HSLFTextParagraph;
-import org.apache.poi.hslf.model.Hyperlink;
-import org.apache.poi.hslf.model.HSLFShape;
+import org.apache.poi.hslf.usermodel.*;
 
 import java.io.FileInputStream;
 
@@ -44,12 +40,12 @@ public final class Hyperlinks {
 
                 //read hyperlinks from the slide's text runs
                 System.out.println("reading hyperlinks from the text runs");
-                HSLFTextParagraph[] txt = slide[j].getTextRuns();
+                HSLFTextParagraph[] txt = slide[j].getTextParagraphs();
                 for (int k = 0; k < txt.length; k++) {
-                    String text = txt[k].getText();
-                    Hyperlink[] links = txt[k].getHyperlinks();
+                    String text = txt[k].getRawText();
+                    HSLFHyperlink[] links = txt[k].getHyperlinks();
                     if(links != null) for (int l = 0; l < links.length; l++) {
-                        Hyperlink link = links[l];
+                        HSLFHyperlink link = links[l];
                         String title = link.getTitle();
                         String address = link.getAddress();
                         System.out.println("  " + title);
@@ -65,7 +61,7 @@ public final class Hyperlinks {
                 System.out.println("  reading hyperlinks from the slide's shapes");
                 HSLFShape[] sh = slide[j].getShapes();
                 for (int k = 0; k < sh.length; k++) {
-                    Hyperlink link = sh[k].getHyperlink();
+                    HSLFHyperlink link = sh[k].getHyperlink();
                     if(link != null)  {
                         String title = link.getTitle();
                         String address = link.getAddress();
index 373f942844914f37f6c8e229e93a546494f5e224..784d912c0ef760fcd830568949100ebbdf188874 100644 (file)
@@ -21,6 +21,7 @@ import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hslf.model.*;
 
 import javax.imageio.ImageIO;
+
 import java.io.FileOutputStream;
 import java.io.FileInputStream;
 import java.awt.*;
index 765ba3ef4953d41fa0fa0b7fad85ec5f480c3f27..7ebbea9f17fa659e17a2b6a95cc610fd01929be5 100644 (file)
@@ -21,6 +21,7 @@ import org.apache.poi.hslf.record.InteractiveInfo;
 import org.apache.poi.hslf.record.InteractiveInfoAtom;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.usermodel.*;
+
 import java.io.FileInputStream;
 import java.util.Iterator;
 import java.util.List;
index 5dd1edea06e8277f1641ff02994a041daa9fef27..1d03e1b6f12d148710c0de9ee9b7e3eccf9f128b 100644 (file)
@@ -17,8 +17,7 @@
 
 package org.apache.poi.hslf.examples;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hslf.model.*;
 
 import java.awt.*;
@@ -53,7 +52,7 @@ public final class TableDemo {
             for (int j = 0; j < txt1[i].length; j++) {
                 TableCell cell = table1.getCell(i, j);
                 cell.setText(txt1[i][j]);
-                HSLFTextRun rt = cell.getTextParagraph().getRichTextRuns()[0];
+                HSLFTextRun rt = cell.getTextParagraphs().getTextRuns()[0];
                 rt.setFontName("Arial");
                 rt.setFontSize(10);
                 if(i == 0){
@@ -92,7 +91,7 @@ public final class TableDemo {
             for (int j = 0; j < txt2[i].length; j++) {
                 TableCell cell = table2.getCell(i, j);
                 cell.setText(txt2[i][j]);
-                HSLFTextRun rt = cell.getTextParagraph().getRichTextRuns()[0];
+                HSLFTextRun rt = cell.getTextParagraphs().getTextRuns()[0];
                 rt.setFontSize(10);
                 rt.setFontName("Arial");
                 if(i == 0){
index caf96a84c83e4553a9c2b7729cc401e79cbe9ab6..c656e7c5c69f04f139ac5b9363108c9b2e697a36 100644 (file)
@@ -21,8 +21,8 @@ import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.Entry;\r
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;\r
 import org.apache.poi.hwpf.HWPFDocument;\r
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;\r
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;\r
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;\r
 \r
 import java.io.FileInputStream;\r
 import java.util.Iterator;\r
index a83a17e4b85ff724162d5d13a19290f8db1ae8ff..2f0e7e751534cec4df0915527e9e4fda4a3d1294 100644 (file)
@@ -52,10 +52,10 @@ public class Step1 {
                     for(XSLFTextParagraph p : tsh){
                         System.out.println("Paragraph level: " + p.getLevel());
                         for(XSLFTextRun r : p){
-                            System.out.println(r.getText());
+                            System.out.println(r.getRawText());
                             System.out.println("  bold: " + r.isBold());
                             System.out.println("  italic: " + r.isItalic());
-                            System.out.println("  underline: " + r.isUnderline());
+                            System.out.println("  underline: " + r.isUnderlined());
                             System.out.println("  font.family: " + r.getFontFamily());
                             System.out.println("  font.size: " + r.getFontSize());
                             System.out.println("  font.color: " + r.getFontColor());
index ea3a5b28e10d666a48e7db6474badb6770212b3e..69b570f7d3ea94b0c3e88b92d46c0f6f220aebb3 100644 (file)
@@ -20,7 +20,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.openxml4j.opc.OPCPackage;\r
 import org.apache.poi.openxml4j.opc.PackagePart;\r
 import org.apache.poi.xwpf.usermodel.XWPFDocument;\r
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;\r
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;\r
 import org.apache.poi.hwpf.HWPFDocument;\r
 import org.apache.poi.xslf.XSLFSlideShow;\r
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
index 6b2ee5f09e39d6cf80934d96e79079c4e108f41e..a946b18c12881fb0596c0119ea1186c3776881cc 100644 (file)
@@ -22,8 +22,8 @@ import static org.junit.Assert.assertTrue;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.junit.Test;
 
 public class HSLFFileHandler extends POIFSFileHandler {
index 8454231cf14db389bfdce181d001a5ba0e573c7b..d6139436aaa857fcfbe144c3062db0a15e6fe5ce 100644 (file)
 package org.apache.poi.ddf;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
+import java.util.*;
 
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
@@ -154,30 +151,9 @@ public final class EscherContainerRecord extends EscherRecord {
     }
 
     public Iterator<EscherRecord> getChildIterator() {
-        return new ReadOnlyIterator(_childRecords);
+        return Collections.unmodifiableList(_childRecords).iterator();
     }
-    private static final class ReadOnlyIterator implements Iterator<EscherRecord> {
-        private final List<EscherRecord> _list;
-        private int _index;
 
-        public ReadOnlyIterator(List<EscherRecord> list) {
-            _list = list;
-            _index = 0;
-        }
-
-        public boolean hasNext() {
-            return _index < _list.size();
-        }
-        public EscherRecord next() {
-            if (!hasNext()) {
-                throw new NoSuchElementException();
-            }
-            return _list.get(_index++);
-        }
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
     /**
      * replaces the internal child list with the contents of the supplied <tt>childRecords</tt>
      */
index 67f1067b71f2cc8472625861127926204903e4fd..266ebb395d4667908bf408520fb5852075faea5d 100644 (file)
@@ -17,6 +17,7 @@
 package org.apache.poi.xslf.extractor;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@@ -122,7 +123,7 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
    public String getText(boolean slideText, boolean notesText, boolean masterText) {
       StringBuffer text = new StringBuffer();
 
-      XSLFSlide[] slides = slideshow.getSlides();
+      List<XSLFSlide> slides = slideshow.getSlides();
       XSLFCommentAuthors commentAuthors = slideshow.getCommentAuthors();
 
       for (XSLFSlide slide : slides) {
index 26780f9662410148bed2831cd46bba9dd9ff2a54..6bdca81d6f8aed2b82ea22655b42386d9864990f 100644 (file)
 package org.apache.poi.xslf.usermodel;
 
 import java.awt.Dimension;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.io.*;
+import java.util.*;
 import java.util.regex.Pattern;
 
-import org.apache.poi.POIXMLDocument;
-import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.POIXMLException;
-import org.apache.poi.POIXMLRelation;
+import org.apache.poi.*;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-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.TargetMode;
-import org.apache.poi.sl.usermodel.MasterSheet;
-import org.apache.poi.sl.usermodel.Resources;
-import org.apache.poi.sl.usermodel.SlideShow;
-import org.apache.poi.util.Beta;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.Internal;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.PackageHelper;
-import org.apache.poi.util.Units;
+import org.apache.poi.openxml4j.opc.*;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.util.*;
 import org.apache.poi.xslf.XSLFSlideShow;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.*;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdList;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdListEntry;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideSize;
-import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import com.sun.org.apache.xml.internal.utils.UnImplNode;
+import org.openxmlformats.schemas.presentationml.x2006.main.*;
 
 /**
  * High level representation of a ooxml slideshow.
@@ -334,7 +302,7 @@ public class XMLSlideShow extends POIXMLDocument implements SlideShow {
         
         XSLFTheme theme = (XSLFTheme) createRelationship(XSLFRelation.THEME, 
                 XSLFFactory.getInstance(), themeIndex);
-        theme.importTheme(getSlides()[0].getTheme());
+        theme.importTheme(getSlides().get(0).getTheme());
         
         _notesMaster.addRelation(theme.getPackageRelationship().getId(), theme);
         PackagePartName themePackagePartName = theme.getPackagePart().getPartName();
@@ -350,15 +318,16 @@ public class XMLSlideShow extends POIXMLDocument implements SlideShow {
         return _notesMaster; 
     }
 
-    public XSLFSlideMaster[] getSlideMasters() {
-        return _masters.values().toArray(new XSLFSlideMaster[_masters.size()]);
+    @Override
+    public List<XSLFSlideMaster> getSlideMasters() {
+        return new ArrayList<XSLFSlideMaster>(_masters.values());
     }
 
     /**
      * Return all the slides in the slideshow
      */
-    public XSLFSlide[] getSlides() {
-        return _slides.toArray(new XSLFSlide[_slides.size()]);
+    public List<XSLFSlide> getSlides() {
+        return _slides;
     }
     
     /**
@@ -496,10 +465,6 @@ public class XMLSlideShow extends POIXMLDocument implements SlideShow {
         return null;
     }
 
-    public XSLFSlideMaster[] getMasterSheet() {
-        return getSlideMasters();
-    }
-
     public MasterSheet createMasterSheet() throws IOException {
         // TODO: implement!
         throw new UnsupportedOperationException();
index 9a58a5128a6544009d97a06881b136a9e4e205a1..685ae46da5414d0ba4d20aabecc7e6043841eb62 100644 (file)
@@ -27,8 +27,7 @@ import java.util.regex.Pattern;
 import org.apache.poi.openxml4j.opc.*;\r
 import org.apache.poi.sl.usermodel.PlaceableShape;\r
 import org.apache.poi.sl.usermodel.ShapeGroup;\r
-import org.apache.poi.util.Beta;\r
-import org.apache.poi.util.Units;\r
+import org.apache.poi.util.*;\r
 import org.apache.xmlbeans.XmlObject;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.*;\r
@@ -40,6 +39,8 @@ import org.openxmlformats.schemas.presentationml.x2006.main.*;
  */\r
 @Beta\r
 public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, ShapeGroup<XSLFShape> {\r
+    private static POILogger _logger = POILogFactory.getLogger(XSLFGroupShape.class);\r
+    \r
     private final List<XSLFShape> _shapes;\r
     private final CTGroupShapeProperties _grpSpPr;\r
     private XSLFDrawing _drawing;\r
@@ -135,8 +136,9 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, Sha
      *\r
      * @return child shapes contained witin this group\r
      */\r
-    public XSLFShape[] getShapes(){\r
-        return _shapes.toArray(new XSLFShape[_shapes.size()]);\r
+    @Override\r
+    public List<XSLFShape> getShapes(){\r
+        return _shapes;\r
     }\r
 \r
     /**\r
@@ -246,6 +248,13 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, Sha
         return sh;\r
     }\r
 \r
+    public XSLFTable createTable(){\r
+        XSLFTable sh = getDrawing().createTable();\r
+        _shapes.add(sh);\r
+        sh.setParent(this);\r
+        return sh;\r
+    }\r
+    \r
     @Override\r
     public void setFlipHorizontal(boolean flip){\r
         getSafeXfrm().setFlipH(flip);\r
@@ -282,14 +291,36 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, Sha
     @Override\r
     void copy(XSLFShape src){\r
         XSLFGroupShape gr = (XSLFGroupShape)src;\r
+        \r
+        // clear shapes\r
+        clear();\r
+        \r
         // recursively update each shape\r
-        XSLFShape[] tgtShapes = getShapes();\r
-        XSLFShape[] srcShapes = gr.getShapes();\r
-        for(int i = 0; i < tgtShapes.length; i++){\r
-            XSLFShape s1 = srcShapes[i];\r
-            XSLFShape s2 = tgtShapes[i];\r
-\r
-            s2.copy(s1);\r
+        for(XSLFShape shape : gr.getShapes()) {\r
+            XSLFShape newShape = null;\r
+            if (shape instanceof XSLFTextBox) {\r
+                newShape = createTextBox();\r
+            } else if (shape instanceof XSLFAutoShape) {\r
+                newShape = createAutoShape();\r
+            } else if (shape instanceof XSLFConnectorShape) {\r
+                newShape = createConnector();\r
+            } else if (shape instanceof XSLFFreeformShape) {\r
+                newShape = createFreeform();\r
+            } else if (shape instanceof XSLFPictureShape) {\r
+                XSLFPictureShape p = (XSLFPictureShape)shape;\r
+                XSLFPictureData pd = p.getPictureData();\r
+                int picId = getSheet().getSlideShow().addPicture(pd.getData(), pd.getPictureType());\r
+                newShape = createPicture(picId);\r
+            } else if (shape instanceof XSLFGroupShape) {\r
+                newShape = createGroup();\r
+            } else if (shape instanceof XSLFTable) {\r
+                newShape = createTable();\r
+            } else {\r
+                _logger.log(POILogger.WARN, "copying of class "+shape.getClass()+" not supported.");\r
+                continue;\r
+            }\r
+\r
+            newShape.copy(shape);\r
         }\r
     }\r
 \r
index a953e2013e5865faad825158977826d5d84bf3f4..7296d1d450ec6b149d6a98a372feab6e8663e6fa 100644 (file)
@@ -91,12 +91,12 @@ public final class XSLFNotes extends XSLFSheet implements Notes<XSLFShape,XMLSli
     }
 
     @Override
-    public List<XSLFTextParagraph> getTextParagraphs() {
-        List<XSLFTextParagraph> tp = new ArrayList<XSLFTextParagraph>();
+    public List<List<XSLFTextParagraph>> getTextParagraphs() {
+        List<List<XSLFTextParagraph>> tp = new ArrayList<List<XSLFTextParagraph>>();
         for (XSLFShape sh : super.getShapes()) {
             if (sh instanceof XSLFTextShape) {
                 XSLFTextShape txt = (XSLFTextShape)sh;
-                tp.addAll(txt.getTextParagraphs());
+                tp.add(txt.getTextParagraphs());
             }
         }
         return tp;
index 38dea1b462f9b2998e871ebf8d02a5ea86e1f2d8..43ec701301a1dc0968d4ba0c08d3ef9bcaa1a7fa 100644 (file)
@@ -199,8 +199,8 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeC
      *
      * @return an array of all shapes in this sheet
      */
-    public XSLFShape[] getShapes(){
-        return getShapeList().toArray(new XSLFShape[_shapes.size()]);
+    public List<XSLFShape> getShapes(){
+        return getShapeList();
     }
 
     /**
@@ -301,6 +301,9 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeC
         _spTree = null;
         _placeholders = null;
 
+        // fix-me: wth would this ever happen to work ...
+        
+        
         // first copy the source xml
         getSpTree().set(src.getSpTree());
 
index ee62ee9d793a2487347d53a0ae8464228c86540c..b6ee1bc8e25b7c7ebdac0d558dc52393ab1f1ee6 100644 (file)
@@ -29,7 +29,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.*;
 import org.openxmlformats.schemas.presentationml.x2006.main.*;
 
 @Beta
-public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSlideShow> {
+public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSlideShow, XSLFNotes> {
    private final CTSlide _slide;
    private XSLFSlideLayout _layout;
    private XSLFComments _comments;
@@ -245,7 +245,7 @@ public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSl
         throw new UnsupportedOperationException();
     }
 
-    public void setNotes(Notes<XSLFShape,XMLSlideShow> notes) {
+    public void setNotes(XSLFNotes notes) {
         // TODO Auto-generated method stub
         
     }
index 6f6dad8ee8ca06f959f254df38abe66a5f729de1..ca369ea9574e74076361e5f1b112ef8391908857 100644 (file)
@@ -68,7 +68,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
     public String getText(){\r
         StringBuilder out = new StringBuilder();\r
         for (XSLFTextRun r : _runs) {\r
-            out.append(r.getText());\r
+            out.append(r.getRawText());\r
         }\r
         return out.toString();\r
     }\r
@@ -171,6 +171,39 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
         }\r
     }\r
 \r
+    @Override\r
+    public FontAlign getFontAlign(){\r
+        ParagraphPropertyFetcher<FontAlign> fetcher = new ParagraphPropertyFetcher<FontAlign>(getLevel()){\r
+            public boolean fetch(CTTextParagraphProperties props){\r
+                if(props.isSetFontAlgn()){\r
+                    FontAlign val = FontAlign.values()[props.getFontAlgn().intValue() - 1];\r
+                    setValue(val);\r
+                    return true;\r
+                }\r
+                return false;\r
+            }\r
+        };\r
+        fetchParagraphProperty(fetcher);\r
+        return fetcher.getValue() == null ? FontAlign.AUTO : fetcher.getValue();\r
+    }\r
+\r
+    /**\r
+     * Specifies the font alignment that is to be applied to the paragraph.\r
+     * Possible values for this include auto, top, center, baseline and bottom.\r
+     * see {@link org.apache.poi.sl.usermodel.TextParagraph.FontAlign}.\r
+     *\r
+     * @param align font align\r
+     */\r
+    public void setFontAlign(FontAlign align){\r
+        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
+        if(align == null) {\r
+            if(pr.isSetFontAlgn()) pr.unsetFontAlgn();\r
+        } else {\r
+            pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1));\r
+        }\r
+    }\r
+\r
+    \r
 \r
     /**\r
      * @return the font to be used on bullet characters within a given paragraph\r
@@ -306,6 +339,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
      *\r
      * @param value the indent in points. \r
      */\r
+    @Override\r
     public void setIndent(double value){\r
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         if(value == -1) {\r
@@ -319,6 +353,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
      *\r
      * @return the indent applied to the first line of text in the paragraph.\r
      */\r
+    @Override\r
     public double getIndent(){\r
 \r
         ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){\r
@@ -340,8 +375,9 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
      * inset and applies only to this text paragraph. That is the text body Inset and the LeftMargin\r
      * attributes are additive with respect to the text position.\r
      *\r
-     * @param value the left margin of the paragraph\r
+     * @param value the left margin (in points) of the paragraph\r
      */\r
+    @Override\r
     public void setLeftMargin(double value){\r
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         if(value == -1) {\r
@@ -353,9 +389,9 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
     }\r
 \r
     /**\r
-     *\r
-     * @return the left margin of the paragraph\r
+     * @return the left margin (in points) of the paragraph\r
      */\r
+    @Override\r
     public double getLeftMargin(){\r
         ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){\r
             public boolean fetch(CTTextParagraphProperties props){\r
@@ -372,10 +408,28 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
         return fetcher.getValue() == null ? 0 : fetcher.getValue();\r
     }\r
 \r
+    /**\r
+     * Specifies the right margin of the paragraph. This is specified in addition to the text body\r
+     * inset and applies only to this text paragraph. That is the text body Inset and the RightMargin\r
+     * attributes are additive with respect to the text position.\r
+     *\r
+     * @param value the right margin (in points) of the paragraph\r
+     */\r
+    @Override\r
+    public void setRightMargin(double value){\r
+        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
+        if(value == -1) {\r
+            if(pr.isSetMarR()) pr.unsetMarR();\r
+        } else {\r
+            pr.setMarR(Units.toEMU(value));\r
+        }\r
+    }\r
+\r
     /**\r
      *\r
      * @return the right margin of the paragraph\r
      */\r
+    @Override\r
     public double getRightMargin(){\r
         ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){\r
             public boolean fetch(CTTextParagraphProperties props){\r
@@ -834,11 +888,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
         }\r
     }\r
 \r
+    @Override\r
     public double getDefaultFontSize() {\r
         CTTextCharacterProperties endPr = _p.getEndParaRPr();\r
         return (endPr == null || !endPr.isSetSz()) ? 12 : (endPr.getSz() / 100);\r
     }\r
 \r
+    @Override\r
     public String getDefaultFontFamily() {\r
         return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily());\r
     }\r
index 0a6daf6ceaa70f58ee4e5764ac3051ced38de3ec..2b63a5809997cc3df8019b392f496413fc72a96b 100644 (file)
@@ -59,7 +59,7 @@ public class XSLFTextRun implements TextRun {
         return _p;\r
     }\r
 \r
-    public String getText(){\r
+    public String getRawText(){\r
         return _r.getT();\r
     }\r
 \r
@@ -479,7 +479,7 @@ public class XSLFTextRun implements TextRun {
     /**\r
      * @return whether this run of text is formatted as underlined text\r
      */\r
-    public boolean isUnderline(){\r
+    public boolean isUnderlined(){\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
                 if(props.isSetU()){\r
@@ -499,7 +499,7 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public String toString(){\r
-        return "[" + getClass() + "]" + getText();\r
+        return "[" + getClass() + "]" + getRawText();\r
     }\r
 \r
     public XSLFHyperlink createHyperlink(){\r
@@ -568,8 +568,8 @@ public class XSLFTextRun implements TextRun {
         boolean italic = r.isItalic();\r
         if(italic != isItalic()) setItalic(italic);\r
 \r
-        boolean underline = r.isUnderline();\r
-        if(underline != isUnderline()) setUnderline(underline);\r
+        boolean underline = r.isUnderlined();\r
+        if(underline != isUnderlined()) setUnderline(underline);\r
 \r
         boolean strike = r.isStrikethrough();\r
         if(strike != isStrikethrough()) setStrikethrough(strike);\r
index ac482a981f4c929decd9cfd09da778415bcb58cf..5b58adbf1aa8f09222c203723beed12a611e883e 100644 (file)
@@ -112,7 +112,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape
      * Sets the type of vertical alignment for the text.
      *
      * @param anchor - the type of alignment.
-     * A <code>null</code> values unsets this property.
+     * A {@code null} values unsets this property.
      */
     public void setVerticalAlignment(VerticalAlignment anchor){
         CTTextBodyProperties bodyPr = getTextBodyPr();
@@ -145,6 +145,40 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape
         return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue();
     }
 
+    /**
+     * Sets if the paragraphs are horizontal centered
+     *
+     * @param isCentered true, if the paragraphs are horizontal centered
+     * A {@code null} values unsets this property.
+     * 
+     * @see TextShape#isHorizontalCentered()
+     */
+    public void setHorizontalCentered(Boolean isCentered){
+        CTTextBodyProperties bodyPr = getTextBodyPr();
+        if (bodyPr != null) {
+             if (isCentered == null) {
+                if (bodyPr.isSetAnchorCtr()) bodyPr.unsetAnchorCtr();
+            } else {
+                bodyPr.setAnchorCtr(isCentered);
+            }
+        }
+    }
+
+    @Override
+    public boolean isHorizontalCentered(){
+        PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
+            public boolean fetch(CTTextBodyProperties props){
+                if(props.isSetAnchorCtr()){
+                    setValue(props.getAnchorCtr());
+                    return true;
+                }
+                return false;
+            }
+        };
+        fetchShapeProperty(fetcher);
+        return fetcher.getValue() == null ? false : fetcher.getValue();
+    }
+    
     /**
      *
      * @param orientation vertical orientation of the text
@@ -266,7 +300,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape
     }
 
     /**
-     * Sets the botom margin.
+     * Sets the bottom margin.
      * @see #getBottomInset()
      *
      * @param margin    the bottom margin
@@ -429,9 +463,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape
         }
     }
 
-    /**
-     * Compute the cumulative height occupied by the text
-     */
+    @Override
     public double getTextHeight(){
         DrawFactory drawFact = DrawFactory.getInstance(null);
         DrawTextShape<XSLFTextShape> dts = drawFact.getDrawable(this);
index 76bb08559f22c8e33453e6ed57fa7dc88042f60f..400c637ca8c6549fe3a7e7bc4694366ddcf882b2 100644 (file)
@@ -24,12 +24,14 @@ import org.apache.poi.xslf.usermodel.XMLSlideShow;
 import org.apache.poi.xslf.usermodel.XSLFSlide;\r
 \r
 import javax.imageio.ImageIO;\r
+\r
 import java.awt.Color;\r
 import java.awt.Dimension;\r
 import java.awt.Graphics2D;\r
 import java.awt.RenderingHints;\r
 import java.awt.image.BufferedImage;\r
 import java.io.FileOutputStream;\r
+import java.util.List;\r
 \r
 /**\r
  * An utulity to convert slides of a .pptx slide show to a PNG image\r
@@ -79,11 +81,11 @@ public class PPTX2PNG {
         int width = (int) (pgsize.width * scale);\r
         int height = (int) (pgsize.height * scale);\r
 \r
-        XSLFSlide[] slide = ppt.getSlides();\r
-        for (int i = 0; i < slide.length; i++) {\r
+        List<XSLFSlide> slide = ppt.getSlides();\r
+        for (int i = 0; i < slide.size(); i++) {\r
             if (slidenum != -1 && slidenum != (i + 1)) continue;\r
 \r
-            String title = slide[i].getTitle();\r
+            String title = slide.get(i).getTitle();\r
             System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title));\r
 \r
             BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\r
@@ -101,7 +103,7 @@ public class PPTX2PNG {
             graphics.scale(scale, scale);\r
 \r
             // draw stuff\r
-            slide[i].draw(graphics);\r
+            slide.get(i).draw(graphics);\r
 \r
             // save the result\r
             int sep = file.lastIndexOf(".");\r
index 7d18541d9be4e330ff8143832f78ae509b9c1420..6d66caefe058b2b0bc0618723cedf82641174443 100644 (file)
@@ -55,8 +55,8 @@ public class TestXSLFBugs {
     public void bug51187() throws Exception {
        XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("51187.pptx");
        
-       assertEquals(1, ss.getSlides().length);
-       XSLFSlide slide = ss.getSlides()[0];
+       assertEquals(1, ss.getSlides().size());
+       XSLFSlide slide = ss.getSlides().get(0);
        
        // Check the relations on it
        // Note - rId3 is a self reference
@@ -71,7 +71,7 @@ public class TestXSLFBugs {
        
        // Save and re-load
        ss = XSLFTestDataSamples.writeOutAndReadBack(ss);
-       assertEquals(1, ss.getSlides().length);
+       assertEquals(1, ss.getSlides().size());
        
        slidePart = ss._getXSLFSlideShow().getSlidePart(
              ss._getXSLFSlideShow().getSlideReferences().getSldIdArray(0)
@@ -92,8 +92,8 @@ public class TestXSLFBugs {
        XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("with_japanese.pptx");
        
        // Should have one slide
-       assertEquals(1, ss.getSlides().length);
-       XSLFSlide slide = ss.getSlides()[0];
+       assertEquals(1, ss.getSlides().size());
+       XSLFSlide slide = ss.getSlides().get(0);
        
        // Check the relations from this
        List<POIXMLDocumentPart> rels = slide.getRelations();
@@ -142,20 +142,20 @@ public class TestXSLFBugs {
         XSLFSlide slide; 
         
         // Should find 4 slides
-        assertEquals(4, ss.getSlides().length);
+        assertEquals(4, ss.getSlides().size());
         
         // Check the text, to see we got them in order
-        slide = ss.getSlides()[0];
+        slide = ss.getSlides().get(0);
         assertContains("POI cannot read this", getSlideText(slide));
         
-        slide = ss.getSlides()[1];
+        slide = ss.getSlides().get(1);
         assertContains("POI can read this", getSlideText(slide));
         assertContains("Has a relationship to another slide", getSlideText(slide));
         
-        slide = ss.getSlides()[2];
+        slide = ss.getSlides().get(2);
         assertContains("POI can read this", getSlideText(slide));
         
-        slide = ss.getSlides()[3];
+        slide = ss.getSlides().get(3);
         assertContains("POI can read this", getSlideText(slide));
     }
     
@@ -196,13 +196,13 @@ public class TestXSLFBugs {
     }
 
     @Test
-    @Ignore("Similar to TestFontRendering it doesn't make sense to compare images because of tiny rendering differences in windows/unix")
+    // @Ignore("Similar to TestFontRendering it doesn't make sense to compare images because of tiny rendering differences in windows/unix")
     public void bug54542() throws Exception {
         XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("54542_cropped_bitmap.pptx");
         
         Dimension pgsize = ss.getPageSize();
         
-        XSLFSlide slide = ss.getSlides()[0];
+        XSLFSlide slide = ss.getSlides().get(0);
         
         // render it
         double zoom = 1;
@@ -265,10 +265,10 @@ public class TestXSLFBugs {
             ss = XSLFTestDataSamples.writeOutAndReadBack(ss);
         }
 
-        assertEquals(slideTexts.length, ss.getSlides().length);
+        assertEquals(slideTexts.length, ss.getSlides().size());
 
         for (int i = 0; i < slideTexts.length; i++) {
-            XSLFSlide slide = ss.getSlides()[i];
+            XSLFSlide slide = ss.getSlides().get(i);
             assertContains(getSlideText(slide), slideTexts[i]);
         }
     }
index 47d2277712f963808b60b60a0edba8da605be496..36d42471ca2e3e921a4114eaee14a7291e5288ba 100644 (file)
  */
 package org.apache.poi.xslf.geom;
 
-import junit.framework.TestCase;
-import org.apache.poi.xslf.model.geom.Context;
-import org.apache.poi.xslf.model.geom.CustomGeometry;
-import org.apache.poi.xslf.model.geom.Formula;
-import org.apache.poi.xslf.model.geom.Guide;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
+import org.apache.poi.sl.draw.geom.*;
+import org.junit.Test;
 
 /**
  * Date: 10/24/11
  *
  * @author Yegor Kozlov
  */
-public class TestFormulaParser extends TestCase {
+public class TestFormulaParser {
+    @Test
     public void testParse(){
 
         Formula[] ops = {
@@ -44,18 +44,18 @@ public class TestFormulaParser extends TestCase {
             new Guide("a5", "abs -2"),
         };
 
-        CustomGeometry geom = new CustomGeometry(CTCustomGeometry2D.Factory.newInstance());
+        CustomGeometry geom = new CustomGeometry(new CTCustomGeometry2D());
         Context ctx = new Context(geom, null, null);
         for(Formula fmla : ops) {
             ctx.evaluate(fmla);
         }
 
-        assertEquals(100.0, ctx.getValue("adj1"));
-        assertEquals(200.0, ctx.getValue("adj2"));
-        assertEquals(1.0, ctx.getValue("a1"));
-        assertEquals(101.0, ctx.getValue("a2"));
-        assertEquals(1.5, ctx.getValue("a3"));
-        assertEquals(200.0, ctx.getValue("a4"));
-        assertEquals(2.0, ctx.getValue("a5"));
+        assertEquals(100.0, ctx.getValue("adj1"), 0.0);
+        assertEquals(200.0, ctx.getValue("adj2"), 0.0);
+        assertEquals(1.0, ctx.getValue("a1"), 0.0);
+        assertEquals(101.0, ctx.getValue("a2"), 0.0);
+        assertEquals(1.5, ctx.getValue("a3"), 0.0);
+        assertEquals(200.0, ctx.getValue("a4"), 0.0);
+        assertEquals(2.0, ctx.getValue("a5"), 0.0);
     }
 }
index 50a66667abcd5f1cf0159e9f6db8007649ba1bc6..5001dc8b91c4ee0c037110b61005a3b28ba17b3f 100644 (file)
  */
 package org.apache.poi.xslf.geom;
 
-import junit.framework.TestCase;
-import org.apache.poi.xslf.model.geom.Context;
-import org.apache.poi.xslf.model.geom.CustomGeometry;
-import org.apache.poi.xslf.model.geom.Guide;
-import org.apache.poi.xslf.model.geom.IAdjustableShape;
-import org.apache.poi.xslf.model.geom.Path;
-import org.apache.poi.xslf.model.geom.PresetGeometries;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
 import java.util.Map;
 
+import org.apache.poi.sl.draw.geom.*;
+import org.junit.Test;
+
 /**
  * Date: 10/24/11
  *
  * @author Yegor Kozlov
  */
-public class TestPresetGeometries extends TestCase {
+public class TestPresetGeometries {
+    @Test
     public void testRead(){
 
         Map<String, CustomGeometry> shapes = PresetGeometries.getInstance();
index 5c616cd43a370a2337545ee4a868ebf237ba0604..e2124eca3bdfae92d5f0c2b668de0326e31fde4c 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.image.BufferedImage;
 import java.util.HashMap;\r
 import java.util.Map;\r
 \r
-import org.apache.poi.hslf.model.TextPainter;\r
+import org.apache.poi.sl.draw.Drawable;\r
 import org.apache.poi.util.JvmBugs;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.junit.Test;\r
@@ -56,10 +56,10 @@ public class TestPPTX2PNG {
     @SuppressWarnings("unchecked")\r
     private void fixFonts(Graphics2D graphics) {\r
         if (!JvmBugs.hasLineBreakMeasurerBug()) return;\r
-        Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);\r
+        Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);\r
         if (fontMap == null) fontMap = new HashMap<String,String>();\r
         fontMap.put("Calibri", "Lucida Sans");\r
         fontMap.put("Cambria", "Lucida Bright");\r
-        graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap);        \r
+        graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);        \r
     }\r
 }\r
index 604f68fffb5e1d1e631c6c4a797e1d2b07f9f9df..5b615ee828e376c816bb525b6359896730fc952b 100644 (file)
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.*;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdListEntry;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
+import org.junit.Before;
+import org.junit.Test;
+import org.openxmlformats.schemas.presentationml.x2006.main.*;
 
-public class TestXMLSlideShow extends TestCase {
+public class TestXMLSlideShow {
    private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
    private OPCPackage pack;
 
-   protected void setUp() throws Exception {
+   @Before
+   public void setUp() throws Exception {
       pack = OPCPackage.open(slTests.openResourceAsStream("sample.pptx"));
    }
 
+   @Test
    public void testContainsMainContentType() throws Exception {
       boolean found = false;
       for(PackagePart part : pack.getParts()) {
@@ -43,6 +45,7 @@ public class TestXMLSlideShow extends TestCase {
       assertTrue(found);
    }
 
+   @Test
    public void testOpen() throws Exception {
       XMLSlideShow xml;
 
@@ -52,22 +55,20 @@ public class TestXMLSlideShow extends TestCase {
       assertNotNull(xml.getCTPresentation());
 
       // Check it has some slides
-      assertNotNull(xml.getSlides().length);
-      assertTrue(xml.getSlides().length > 0);
-
-      assertNotNull(xml.getSlideMasters().length);
-      assertTrue(xml.getSlideMasters().length > 0);
+      assertFalse(xml.getSlides().isEmpty());
+      assertFalse(xml.getSlideMasters().isEmpty());
    }
 
+   @Test
    @SuppressWarnings("deprecation")
    public void testSlideBasics() throws Exception {
       XMLSlideShow xml = new XMLSlideShow(pack);
 
       // Should have 1 master
-      assertEquals(1, xml.getSlideMasters().length);
+      assertEquals(1, xml.getSlideMasters().size());
 
       // Should have two sheets
-      assertEquals(2, xml.getSlides().length);
+      assertEquals(2, xml.getSlides().size());
 
       // Check they're as expected
       CTSlideIdListEntry[] slides = xml.getCTPresentation().getSldIdLst().getSldIdArray();
@@ -78,19 +79,19 @@ public class TestXMLSlideShow extends TestCase {
       assertEquals("rId3", slides[1].getId2());
 
       // Now get those objects
-      assertNotNull(xml.getSlides()[0]);
-      assertNotNull(xml.getSlides()[1]);
+      assertNotNull(xml.getSlides().get(0));
+      assertNotNull(xml.getSlides().get(1));
 
       // And check they have notes as expected
-      assertNotNull(xml.getSlides()[0].getNotes());
-      assertNotNull(xml.getSlides()[1].getNotes());
+      assertNotNull(xml.getSlides().get(0).getNotes());
+      assertNotNull(xml.getSlides().get(1).getNotes());
 
       // Next up look for the slide master
       CTSlideMasterIdListEntry[] masters = xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdArray();
 
       assertEquals(2147483648l, masters[0].getId());
       assertEquals("rId1", masters[0].getId2());
-      assertNotNull(xml.getSlideMasters()[0]);
+      assertNotNull(xml.getSlideMasters().get(0));
 
       // Finally look for the notes master
       CTNotesMasterIdListEntry notesMaster =
@@ -100,6 +101,7 @@ public class TestXMLSlideShow extends TestCase {
       assertNotNull(xml.getNotesMaster());
    }
        
+   @Test
    public void testMetadataBasics() throws Exception {
       XMLSlideShow xml = new XMLSlideShow(pack);
 
@@ -114,6 +116,7 @@ public class TestXMLSlideShow extends TestCase {
       assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
    }
    
+   @Test
    public void testComments() throws Exception {
       // Default sample file has none
       XMLSlideShow xml = new XMLSlideShow(pack);
@@ -134,8 +137,9 @@ public class TestXMLSlideShow extends TestCase {
       assertEquals("XPVMWARE01", xmlComments.getCommentAuthors().getAuthorById(0).getName());
       
       // First two slides have comments
-      for (int i=0; i<xmlComments.getSlides().length; i++) {
-         XSLFSlide slide = xmlComments.getSlides()[i];
+      int i = -1;
+      for (XSLFSlide slide : xmlComments.getSlides()) {
+         i++;
          
          if(i == 0) {
             assertNotNull(slide.getComments());
index 5b7109059ff1bbd0d176f60d9d7dfcfb75af2281..6fc5690cca2b775b8fe4ff7e73920c4d33e6089f 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
 \r
 import org.apache.poi.sl.usermodel.*;\r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
 import org.apache.poi.sl.usermodel.TextShape.TextAutofit;\r
 import org.apache.poi.sl.usermodel.TextShape.TextDirection;\r
 import org.apache.poi.util.Units;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFAutoShape extends TestCase {\r
+public class TestXSLFAutoShape {\r
+    @Test\r
     public void testTextBodyProperies() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -38,38 +40,38 @@ public class TestXSLFAutoShape extends TestCase {
         shape.addNewTextParagraph().addNewTextRun().setText("POI");\r
 \r
         // default margins from slide master\r
-        assertEquals(3.6, shape.getBottomInset());\r
-        assertEquals(3.6, shape.getTopInset());\r
-        assertEquals(7.2, shape.getLeftInset());\r
-        assertEquals(7.2, shape.getRightInset());\r
+        assertEquals(3.6, shape.getBottomInset(), 0);\r
+        assertEquals(3.6, shape.getTopInset(), 0);\r
+        assertEquals(7.2, shape.getLeftInset(), 0);\r
+        assertEquals(7.2, shape.getRightInset(), 0);\r
 \r
         shape.setBottomInset(1.0);\r
-        assertEquals(1.0, shape.getBottomInset());\r
+        assertEquals(1.0, shape.getBottomInset(), 0);\r
         shape.setTopInset(2.0);\r
-        assertEquals(2.0, shape.getTopInset());\r
+        assertEquals(2.0, shape.getTopInset(), 0);\r
         shape.setLeftInset(3.0);\r
-        assertEquals(3.0, shape.getLeftInset());\r
+        assertEquals(3.0, shape.getLeftInset(), 0);\r
         shape.setRightInset(4.0);\r
-        assertEquals(4.0, shape.getRightInset());\r
+        assertEquals(4.0, shape.getRightInset(), 0);\r
 \r
         shape.setBottomInset(0.0);\r
-        assertEquals(0.0, shape.getBottomInset());\r
+        assertEquals(0.0, shape.getBottomInset(), 0);\r
         shape.setTopInset(0.0);\r
-        assertEquals(0.0, shape.getTopInset());\r
+        assertEquals(0.0, shape.getTopInset(), 0);\r
         shape.setLeftInset(0.0);\r
-        assertEquals(0.0, shape.getLeftInset());\r
+        assertEquals(0.0, shape.getLeftInset(), 0);\r
         shape.setRightInset(0.0);\r
-        assertEquals(0.0, shape.getRightInset());\r
+        assertEquals(0.0, shape.getRightInset(), 0);\r
 \r
         // unset to defauls\r
         shape.setBottomInset(-1);\r
-        assertEquals(3.6, shape.getBottomInset());\r
+        assertEquals(3.6, shape.getBottomInset(), 0);\r
         shape.setTopInset(-1);\r
-        assertEquals(3.6, shape.getTopInset());\r
+        assertEquals(3.6, shape.getTopInset(), 0);\r
         shape.setLeftInset(-1);\r
-        assertEquals(7.2, shape.getLeftInset());\r
+        assertEquals(7.2, shape.getLeftInset(), 0);\r
         shape.setRightInset(-1);\r
-        assertEquals(7.2, shape.getRightInset());\r
+        assertEquals(7.2, shape.getRightInset(), 0);\r
 \r
         // shape\r
         assertTrue(shape.getWordWrap());\r
@@ -102,31 +104,32 @@ public class TestXSLFAutoShape extends TestCase {
         assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection());\r
     }\r
 \r
+    @Test\r
     public void testTextParagraph() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
-        assertEquals(0, slide.getShapes().length);\r
+        assertTrue(slide.getShapes().isEmpty());\r
 \r
         XSLFAutoShape shape = slide.createAutoShape();\r
         assertEquals(0, shape.getTextParagraphs().size());\r
         XSLFTextParagraph p = shape.addNewTextParagraph();\r
         assertEquals(1, shape.getTextParagraphs().size());\r
 \r
-        assertEquals(0., p.getIndent());\r
-        assertEquals(0., p.getLeftMargin());\r
-        assertEquals(100., p.getLineSpacing());\r
-        assertEquals(0., p.getSpaceAfter());\r
-        assertEquals(0., p.getSpaceBefore());\r
+        assertEquals(0., p.getIndent(), 0);\r
+        assertEquals(0., p.getLeftMargin(), 0);\r
+        assertEquals(100., p.getLineSpacing(), 0);\r
+        assertEquals(0., p.getSpaceAfter(), 0);\r
+        assertEquals(0., p.getSpaceBefore(), 0);\r
         assertEquals(0, p.getLevel());\r
 \r
         p.setIndent(2.0);\r
-        assertEquals(2.0, p.getIndent());\r
+        assertEquals(2.0, p.getIndent(), 0);\r
         assertTrue(p.getXmlObject().getPPr().isSetIndent());\r
         p.setIndent(-1);\r
-        assertEquals(0.0, p.getIndent());\r
+        assertEquals(0.0, p.getIndent(), 0);\r
         assertFalse(p.getXmlObject().getPPr().isSetIndent());\r
         p.setIndent(10.0);\r
-        assertEquals(10., p.getIndent());\r
+        assertEquals(10., p.getIndent(), 0);\r
         assertTrue(p.getXmlObject().getPPr().isSetIndent());\r
 \r
 \r
@@ -138,10 +141,10 @@ public class TestXSLFAutoShape extends TestCase {
         assertEquals(2, p.getLevel());\r
 \r
         p.setLeftMargin(2.0);\r
-        assertEquals(2.0, p.getLeftMargin());\r
+        assertEquals(2.0, p.getLeftMargin(), 0);\r
         assertTrue(p.getXmlObject().getPPr().isSetMarL());\r
         p.setLeftMargin(10.0);\r
-        assertEquals(10., p.getLeftMargin());\r
+        assertEquals(10., p.getLeftMargin(), 0);\r
         assertEquals(Units.toEMU(10), p.getXmlObject().getPPr().getMarL());\r
 \r
 \r
@@ -201,6 +204,7 @@ public class TestXSLFAutoShape extends TestCase {
         assertFalse(p.getXmlObject().getPPr().isSetAlgn());\r
     }\r
 \r
+    @Test\r
     public void testTextRun() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -214,7 +218,7 @@ public class TestXSLFAutoShape extends TestCase {
         assertEquals(1, p.getTextRuns().size());\r
         assertSame(r, p.getTextRuns().get(0));\r
 \r
-        assertEquals(18.0, r.getFontSize()); // default font size for text boxes\r
+        assertEquals(18.0, r.getFontSize(), 0); // default font size for text boxes\r
         assertFalse(r.getXmlObject().getRPr().isSetSz());\r
         r.setFontSize(10.0);\r
         assertTrue(r.getXmlObject().isSetRPr());\r
@@ -256,20 +260,21 @@ public class TestXSLFAutoShape extends TestCase {
         assertTrue(r.isItalic());\r
         assertEquals(true, r.getXmlObject().getRPr().getI());\r
 \r
-        assertFalse(r.isUnderline());\r
+        assertFalse(r.isUnderlined());\r
         assertFalse(r.getXmlObject().getRPr().isSetU());\r
         r.setUnderline(true);\r
-        assertTrue(r.isUnderline());\r
+        assertTrue(r.isUnderlined());\r
         assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU());\r
 \r
         r.setText("Apache");\r
-        assertEquals("Apache", r.getText());\r
+        assertEquals("Apache", r.getRawText());\r
         r.setText("POI");\r
-        assertEquals("POI", r.getText());\r
+        assertEquals("POI", r.getRawText());\r
         r.setText(null);\r
-        assertNull(r.getText());\r
+        assertNull(r.getRawText());\r
     }\r
 \r
+    @Test\r
     public void testShapeType() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
index 941c44b7f664744743dcca0aac4179248be3d4e5..02fa668ef8f8e1b682fd31087f1a4870c192ab63 100644 (file)
@@ -46,7 +46,7 @@ public class TestXSLFChart extends TestCase {
         String chartTitle = "Apache POI";  // first line is chart title\r
 \r
         XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("pie-chart.pptx");\r
-        XSLFSlide slide = pptx.getSlides()[0];\r
+        XSLFSlide slide = pptx.getSlides().get(0);\r
 \r
         // find chart in the slide\r
         XSLFChart chart = null;\r
index 0dc9c4d6f7d2ab5e60ae99a1474ebf69c2725bc0..beed20719f6d5a1bbd6aed840780e0f97fad0a9a 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+\r
 import java.awt.Color;\r
 import java.awt.Rectangle;\r
 \r
-import junit.framework.TestCase;\r
-\r
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;\r
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;\r
 import org.apache.poi.sl.usermodel.*;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFConnectorShape extends TestCase {\r
+public class TestXSLFConnectorShape {\r
 \r
+    @Test\r
     public void testLineDecorations() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
 \r
         XSLFConnectorShape shape = slide.createConnector();\r
-        assertEquals(1, slide.getShapes().length);\r
+        assertEquals(1, slide.getShapes().size());\r
 \r
         assertFalse(shape.getSpPr().getLn().isSetHeadEnd());\r
         assertFalse(shape.getSpPr().getLn().isSetTailEnd());\r
@@ -112,6 +115,7 @@ public class TestXSLFConnectorShape extends TestCase {
 \r
     }\r
 \r
+    @Test\r
     public void testAddConnector(){\r
         XMLSlideShow pptx = new XMLSlideShow();\r
         XSLFSlide slide = pptx.createSlide();\r
index f212abeae4db409abcd250009189a3ded8147c9a..92eb9a7988fee695e2c0cab218e7129867645d7a 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
 \r
 import java.awt.Rectangle;\r
 import java.awt.geom.Ellipse2D;\r
 import java.awt.geom.GeneralPath;\r
 \r
+import org.junit.Test;\r
+\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFFreeformShape extends TestCase {\r
+public class TestXSLFFreeformShape {\r
 \r
+    @Test\r
     public void testSetPath() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
index 7f11ecc762be7df2b7d62e841ccdf197d90e7d61..4a6e0ff2a0772765d1985a2bbb473aacd195c0fb 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
 \r
 import java.awt.Dimension;\r
 import java.awt.geom.Rectangle2D;\r
 \r
+import org.junit.Test;\r
+\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFGroupShape extends TestCase {\r
+public class TestXSLFGroupShape {\r
 \r
+    @Test\r
     public void testCreateShapes() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -33,7 +36,7 @@ public class TestXSLFGroupShape extends TestCase {
         ppt.setPageSize(new Dimension(792, 612));\r
         \r
         XSLFGroupShape group = slide.createGroup();\r
-        assertEquals(1, slide.getShapes().length);\r
+        assertEquals(1, slide.getShapes().size());\r
 \r
         Rectangle2D interior = new Rectangle2D.Double(-10, -10, 20, 20);\r
         group.setInteriorAnchor(interior);\r
@@ -43,45 +46,46 @@ public class TestXSLFGroupShape extends TestCase {
         group.setAnchor(anchor);\r
         assertEquals(anchor, group.getAnchor());\r
 \r
-        assertEquals(0, group.getShapes().length);\r
+        assertTrue(group.getShapes().isEmpty());\r
 \r
         XSLFTextBox shape1 = group.createTextBox();\r
-        assertEquals(1, group.getShapes().length);\r
-        assertSame(shape1, group.getShapes()[0]);\r
+        assertEquals(1, group.getShapes().size());\r
+        assertSame(shape1, group.getShapes().get(0));\r
         assertEquals(3, shape1.getShapeId());\r
 \r
         XSLFAutoShape shape2 = group.createAutoShape();\r
-        assertEquals(2, group.getShapes().length);\r
-        assertSame(shape1, group.getShapes()[0]);\r
-        assertSame(shape2, group.getShapes()[1]);\r
+        assertEquals(2, group.getShapes().size());\r
+        assertSame(shape1, group.getShapes().get(0));\r
+        assertSame(shape2, group.getShapes().get(1));\r
         assertEquals(4, shape2.getShapeId());\r
 \r
         XSLFConnectorShape shape3 = group.createConnector();\r
-        assertEquals(3, group.getShapes().length);\r
-        assertSame(shape3, group.getShapes()[2]);\r
+        assertEquals(3, group.getShapes().size());\r
+        assertSame(shape3, group.getShapes().get(2));\r
         assertEquals(5, shape3.getShapeId());\r
 \r
         XSLFGroupShape shape4 = group.createGroup();\r
-        assertEquals(4, group.getShapes().length);\r
-        assertSame(shape4, group.getShapes()[3]);\r
+        assertEquals(4, group.getShapes().size());\r
+        assertSame(shape4, group.getShapes().get(3));\r
         assertEquals(6, shape4.getShapeId());\r
 \r
         group.removeShape(shape2);\r
-        assertEquals(3, group.getShapes().length);\r
-        assertSame(shape1, group.getShapes()[0]);\r
-        assertSame(shape3, group.getShapes()[1]);\r
-        assertSame(shape4, group.getShapes()[2]);\r
+        assertEquals(3, group.getShapes().size());\r
+        assertSame(shape1, group.getShapes().get(0));\r
+        assertSame(shape3, group.getShapes().get(1));\r
+        assertSame(shape4, group.getShapes().get(2));\r
 \r
         group.removeShape(shape3);\r
-        assertEquals(2, group.getShapes().length);\r
-        assertSame(shape1, group.getShapes()[0]);\r
-        assertSame(shape4, group.getShapes()[1]);\r
+        assertEquals(2, group.getShapes().size());\r
+        assertSame(shape1, group.getShapes().get(0));\r
+        assertSame(shape4, group.getShapes().get(1));\r
 \r
         group.removeShape(shape1);\r
         group.removeShape(shape4);\r
-        assertEquals(0, group.getShapes().length);\r
+        assertTrue(group.getShapes().isEmpty());\r
     }\r
 \r
+    @Test\r
     public void testRemoveShapes() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
index 33cf3225e71eccc372f57318b866a424e530f9ef..b919eab0114fb5850b02b6e1dcdd8173237349bd 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+\r
+import java.net.URI;\r
+import java.util.List;\r
+\r
 import org.apache.poi.openxml4j.opc.PackageRelationship;\r
 import org.apache.poi.openxml4j.opc.TargetMode;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
-\r
-import java.net.URI;\r
+import org.junit.Test;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFHyperlink extends TestCase {\r
+public class TestXSLFHyperlink {\r
 \r
+    @Test\r
     public void testRead(){\r
         XMLSlideShow  ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
 \r
-        XSLFSlide slide = ppt.getSlides()[4];\r
-        XSLFShape[] shapes = slide.getShapes();\r
-        XSLFTable tbl = (XSLFTable)shapes[0];\r
+        XSLFSlide slide = ppt.getSlides().get(4);\r
+        List<XSLFShape> shapes = slide.getShapes();\r
+        XSLFTable tbl = (XSLFTable)shapes.get(0);\r
         XSLFTableCell cell1 = tbl.getRows().get(1).getCells().get(0);\r
         assertEquals("Web Page", cell1.getText());\r
         XSLFHyperlink link1 = cell1.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink();\r
@@ -53,6 +58,7 @@ public class TestXSLFHyperlink extends TestCase {
         assertEquals(URI.create("mailto:dev@poi.apache.org?subject=Hi%20There"), link3.getTargetURI());\r
     }\r
 \r
+    @Test\r
     public void testCreate() throws Exception  {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide1 = ppt.createSlide();\r
index 955b273c1e4610a9bd1fe7dab8a704292441217e..0ec9b972a07421c6a1a089f58d7cb9295b798a73 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.*;\r
 \r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import junit.framework.TestCase;\r
+import java.util.*;\r
 \r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFPictureShape extends TestCase {\r
+public class TestXSLFPictureShape {\r
 \r
+    @Test\r
     public void testCreate() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         assertEquals(0, ppt.getAllPictures().size());\r
@@ -61,11 +59,12 @@ public class TestXSLFPictureShape extends TestCase {
         assertArrayEquals(data1, pics.get(0).getData());\r
         assertArrayEquals(data2, pics.get(1).getData());\r
 \r
-        XSLFShape[] shapes = ppt.getSlides()[0].getShapes();\r
-        assertArrayEquals(data1, ((XSLFPictureShape) shapes[0]).getPictureData().getData());\r
-        assertArrayEquals(data2, ((XSLFPictureShape) shapes[1]).getPictureData().getData());\r
+        List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();\r
+        assertArrayEquals(data1, ((XSLFPictureShape) shapes.get(0)).getPictureData().getData());\r
+        assertArrayEquals(data2, ((XSLFPictureShape) shapes.get(1)).getPictureData().getData());\r
     }\r
 \r
+    @Test\r
     public void testCreateMultiplePictures() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide1 = ppt.createSlide();\r
@@ -118,6 +117,7 @@ public class TestXSLFPictureShape extends TestCase {
         }\r
     }\r
 \r
+    @Test\r
     public void testImageCaching() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         byte[] img1 = new byte[]{1,2,3};\r
@@ -137,6 +137,7 @@ public class TestXSLFPictureShape extends TestCase {
 \r
     }\r
 \r
+    @Test\r
     public void testMerge() {\r
         XMLSlideShow ppt1 = new XMLSlideShow();\r
         byte[] data1 = new byte[100];\r
@@ -150,7 +151,7 @@ public class TestXSLFPictureShape extends TestCase {
         XMLSlideShow ppt2 = new XMLSlideShow();\r
 \r
         XSLFSlide slide2 = ppt2.createSlide().importContent(slide1);\r
-        XSLFPictureShape shape2 = (XSLFPictureShape)slide2.getShapes()[0];\r
+        XSLFPictureShape shape2 = (XSLFPictureShape)slide2.getShapes().get(0);\r
 \r
         assertArrayEquals(data1, shape2.getPictureData().getData());\r
 \r
index e6c4728474321a642ee518415ec1539966e84e18..3983d0b392153b5fffb1e6d3a76492895ab8e86b 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
+\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
 import java.util.List;\r
@@ -25,17 +27,18 @@ import java.util.List;
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFShape extends TestCase {\r
+public class TestXSLFShape {\r
 \r
+    @Test\r
     public void testReadTextShapes() {\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
-        XSLFSlide[] slides = ppt.getSlides();\r
+        List<XSLFSlide> slides = ppt.getSlides();\r
 \r
-        XSLFSlide slide1 = slides[0];\r
-        XSLFShape[] shapes1 = slide1.getShapes();\r
-        assertEquals(7, shapes1.length);\r
-        assertEquals("TextBox 3", shapes1[0].getShapeName());\r
-        XSLFAutoShape sh0 = (XSLFAutoShape) shapes1[0];\r
+        XSLFSlide slide1 = slides.get(0);\r
+        List<XSLFShape> shapes1 = slide1.getShapes();\r
+        assertEquals(7, shapes1.size());\r
+        assertEquals("TextBox 3", shapes1.get(0).getShapeName());\r
+        XSLFAutoShape sh0 = (XSLFAutoShape) shapes1.get(0);\r
         assertEquals("Learning PPTX", sh0.getText());\r
         List<XSLFTextParagraph> paragraphs0 = sh0.getTextParagraphs();\r
         assertEquals(1, paragraphs0.size());\r
@@ -43,28 +46,28 @@ public class TestXSLFShape extends TestCase {
         assertEquals("Learning PPTX", p0.getText());\r
         assertEquals(1, p0.getTextRuns().size());\r
         XSLFTextRun r0 = p0.getTextRuns().get(0);\r
-        assertEquals("Learning PPTX", r0.getText());\r
+        assertEquals("Learning PPTX", r0.getRawText());\r
 \r
-        XSLFSlide slide2 = slides[1];\r
-        XSLFShape[] shapes2 = slide2.getShapes();\r
-        assertTrue(shapes2[0] instanceof XSLFAutoShape);\r
-        assertEquals("PPTX Title", ((XSLFAutoShape) shapes2[0]).getText());\r
-        XSLFAutoShape sh1 = (XSLFAutoShape) shapes2[0];\r
+        XSLFSlide slide2 = slides.get(1);\r
+        List<XSLFShape> shapes2 = slide2.getShapes();\r
+        assertTrue(shapes2.get(0) instanceof XSLFAutoShape);\r
+        assertEquals("PPTX Title", ((XSLFAutoShape) shapes2.get(0)).getText());\r
+        XSLFAutoShape sh1 = (XSLFAutoShape) shapes2.get(0);\r
         List<XSLFTextParagraph> paragraphs1 = sh1.getTextParagraphs();\r
         assertEquals(1, paragraphs1.size());\r
         XSLFTextParagraph p1 = paragraphs1.get(0);\r
         assertEquals("PPTX Title", p1.getText());\r
         List<XSLFTextRun> r2 = paragraphs1.get(0).getTextRuns();\r
         assertEquals(2, r2.size());\r
-        assertEquals("PPTX ", r2.get(0).getText());\r
-        assertEquals("Title", r2.get(1).getText());\r
+        assertEquals("PPTX ", r2.get(0).getRawText());\r
+        assertEquals("Title", r2.get(1).getRawText());\r
         // Title is underlined\r
         assertEquals(STTextUnderlineType.SNG, r2.get(1).getXmlObject().getRPr().getU());\r
 \r
 \r
-        assertTrue(shapes2[1] instanceof XSLFAutoShape);\r
-        assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape) shapes2[1]).getText());\r
-        XSLFAutoShape sh2 = (XSLFAutoShape) shapes2[1];\r
+        assertTrue(shapes2.get(1) instanceof XSLFAutoShape);\r
+        assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape) shapes2.get(1)).getText());\r
+        XSLFAutoShape sh2 = (XSLFAutoShape) shapes2.get(1);\r
         List<XSLFTextParagraph> paragraphs2 = sh2.getTextParagraphs();\r
         assertEquals(2, paragraphs2.size());\r
         assertEquals("Subtitle", paragraphs2.get(0).getText());\r
@@ -73,20 +76,20 @@ public class TestXSLFShape extends TestCase {
         assertEquals(1, paragraphs2.get(0).getTextRuns().size());\r
         assertEquals(1, paragraphs2.get(1).getTextRuns().size());\r
 \r
-        assertEquals("Subtitle", paragraphs2.get(0).getTextRuns().get(0).getText());\r
+        assertEquals("Subtitle", paragraphs2.get(0).getTextRuns().get(0).getRawText());\r
         assertTrue(paragraphs2.get(0).getTextRuns().get(0).getXmlObject().getRPr().getB());\r
-        assertEquals("And second line", paragraphs2.get(1).getTextRuns().get(0).getText());\r
+        assertEquals("And second line", paragraphs2.get(1).getTextRuns().get(0).getRawText());\r
     }\r
 \r
     public void testCreateShapes() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
-        assertEquals(0, slide.getShapes().length);\r
+        assertTrue(slide.getShapes().isEmpty());\r
 \r
         XSLFTextBox textBox = slide.createTextBox();\r
 \r
-        assertEquals(1, slide.getShapes().length);\r
-        assertSame(textBox, slide.getShapes()[0]);\r
+        assertEquals(1, slide.getShapes().size());\r
+        assertSame(textBox, slide.getShapes().get(0));\r
 \r
         assertEquals("", textBox.getText());\r
         assertEquals(0, textBox.getTextParagraphs().size());\r
index 8f8e46d94411ceb3301fdd00460b9ece9787a08a..d880966909955392110925748e181eb611461778 100644 (file)
  */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
+\r
+import org.junit.Test;\r
 \r
 /**\r
  * test common operations on containers of shapes (sheets and groups of shapes)\r
  *\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFShapeContainer extends TestCase {\r
+public class TestXSLFShapeContainer {\r
 \r
+    @SuppressWarnings("unused")\r
+    @Test\r
     public void verifyContainer(XSLFShapeContainer container) {\r
         container.clear();\r
-        assertEquals(0, container.getShapes().length);\r
+        assertEquals(0, container.getShapes().size());\r
 \r
         XSLFGroupShape shape1 = container.createGroup();\r
-        assertEquals(1, container.getShapes().length);\r
+        assertEquals(1, container.getShapes().size());\r
 \r
         XSLFTextBox shape2 = container.createTextBox();\r
-        assertEquals(2, container.getShapes().length);\r
+        assertEquals(2, container.getShapes().size());\r
 \r
         XSLFAutoShape shape3 = container.createAutoShape();\r
-        assertEquals(3, container.getShapes().length);\r
+        assertEquals(3, container.getShapes().size());\r
 \r
         XSLFConnectorShape shape4 = container.createConnector();\r
-        assertEquals(4, container.getShapes().length);\r
+        assertEquals(4, container.getShapes().size());\r
 \r
         container.clear();\r
-        assertEquals(0, container.getShapes().length);\r
+        assertEquals(0, container.getShapes().size());\r
     }\r
 \r
+    @Test\r
     public void testSheet() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSheet sheet = ppt.createSlide();\r
index d605a051982fc28e7423679033230ec475d1b92c..92c30b62d5b92a74bf5bf89cec1bff85ada51eee 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
+\r
+import java.util.List;\r
+\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 \r
 /**\r
  * test common properties for sheets (slides, masters, layouts, etc.)\r
  *\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFSheet extends TestCase {\r
+public class TestXSLFSheet {\r
+    \r
+    @Test\r
     public void testCreateShapes(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
-        assertEquals(0, slide.getShapes().length);\r
+        assertTrue(slide.getShapes().isEmpty());\r
 \r
         XSLFSimpleShape shape1 = slide.createAutoShape();\r
-        assertEquals(1, slide.getShapes().length);\r
-        assertSame(shape1, slide.getShapes()[0]);\r
+        assertEquals(1, slide.getShapes().size());\r
+        assertSame(shape1, slide.getShapes().get(0));\r
 \r
         XSLFTextBox shape2 = slide.createTextBox();\r
-        assertEquals(2, slide.getShapes().length);\r
-        assertSame(shape1, slide.getShapes()[0]);\r
-        assertSame(shape2, slide.getShapes()[1]);\r
+        assertEquals(2, slide.getShapes().size());\r
+        assertSame(shape1, slide.getShapes().get(0));\r
+        assertSame(shape2, slide.getShapes().get(1));\r
 \r
         XSLFConnectorShape shape3 = slide.createConnector();\r
-        assertEquals(3, slide.getShapes().length);\r
-        assertSame(shape1, slide.getShapes()[0]);\r
-        assertSame(shape2, slide.getShapes()[1]);\r
-        assertSame(shape3, slide.getShapes()[2]);\r
+        assertEquals(3, slide.getShapes().size());\r
+        assertSame(shape1, slide.getShapes().get(0));\r
+        assertSame(shape2, slide.getShapes().get(1));\r
+        assertSame(shape3, slide.getShapes().get(2));\r
 \r
         XSLFGroupShape shape4 = slide.createGroup();\r
-        assertEquals(4, slide.getShapes().length);\r
-        assertSame(shape1, slide.getShapes()[0]);\r
-        assertSame(shape2, slide.getShapes()[1]);\r
-        assertSame(shape3, slide.getShapes()[2]);\r
-        assertSame(shape4, slide.getShapes()[3]);\r
+        assertEquals(4, slide.getShapes().size());\r
+        assertSame(shape1, slide.getShapes().get(0));\r
+        assertSame(shape2, slide.getShapes().get(1));\r
+        assertSame(shape3, slide.getShapes().get(2));\r
+        assertSame(shape4, slide.getShapes().get(3));\r
 \r
         ppt = XSLFTestDataSamples.writeOutAndReadBack(ppt);\r
-        slide = ppt.getSlides()[0];\r
-        XSLFShape[] shapes = slide.getShapes();\r
-        assertEquals(4, shapes.length);\r
+        slide = ppt.getSlides().get(0);\r
+        List<XSLFShape> shapes = slide.getShapes();\r
+        assertEquals(4, shapes.size());\r
 \r
-        assertTrue(shapes[0] instanceof XSLFAutoShape);\r
-        assertTrue(shapes[1] instanceof XSLFTextBox);\r
-        assertTrue(shapes[2] instanceof XSLFConnectorShape);\r
-        assertTrue(shapes[3] instanceof XSLFGroupShape);\r
+        assertTrue(shapes.get(0) instanceof XSLFAutoShape);\r
+        assertTrue(shapes.get(1) instanceof XSLFTextBox);\r
+        assertTrue(shapes.get(2) instanceof XSLFConnectorShape);\r
+        assertTrue(shapes.get(3) instanceof XSLFGroupShape);\r
     }\r
 }
\ No newline at end of file
index b3a5fc211efc97429e7d02c9f51dd814accf4cde..064ebe6cb7e18989d8e1164f5b0e126e22ae2cb1 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.Color;\r
+import static org.junit.Assert.*;\r
 \r
-import junit.framework.TestCase;\r
+import java.awt.Color;\r
+import java.util.List;\r
 \r
 import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;\r
 import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;\r
 import org.apache.poi.util.Units;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFSimpleShape extends TestCase {\r
+public class TestXSLFSimpleShape {\r
+    \r
+    @Test\r
     public void testLineStyles() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
 \r
         XSLFSimpleShape shape = slide.createAutoShape();\r
-        assertEquals(1, slide.getShapes().length);\r
+        assertEquals(1, slide.getShapes().size());\r
         // line properties are not set by default\r
         assertFalse(shape.getSpPr().isSetLn());\r
 \r
-        assertEquals(0., shape.getLineWidth());\r
+        assertEquals(0., shape.getLineWidth(), 0);\r
         assertEquals(null, shape.getLineColor());\r
         assertEquals(null, shape.getLineDash());\r
         assertEquals(null, shape.getLineCap());\r
@@ -54,10 +58,10 @@ public class TestXSLFSimpleShape extends TestCase {
 \r
         // line width\r
         shape.setLineWidth(1.0);\r
-        assertEquals(1.0, shape.getLineWidth());\r
+        assertEquals(1.0, shape.getLineWidth(), 0);\r
         assertEquals(Units.EMU_PER_POINT, shape.getSpPr().getLn().getW());\r
         shape.setLineWidth(5.5);\r
-        assertEquals(5.5, shape.getLineWidth());\r
+        assertEquals(5.5, shape.getLineWidth(), 0);\r
         assertEquals(Units.toEMU(5.5), shape.getSpPr().getLn().getW());\r
         shape.setLineWidth(0.0);\r
         // setting line width to zero unsets the W attribute\r
@@ -108,17 +112,18 @@ public class TestXSLFSimpleShape extends TestCase {
         ln2.setLineDash(LineDash.DOT);\r
         assertEquals(LineDash.DOT, ln2.getLineDash());\r
         ln2.setLineWidth(0.);\r
-        assertEquals(0., ln2.getLineWidth());\r
+        assertEquals(0., ln2.getLineWidth(), 0);\r
 \r
         XSLFSimpleShape ln3 = slide.createAutoShape();\r
         ln3.setLineWidth(1.);\r
-        assertEquals(1., ln3.getLineWidth());\r
+        assertEquals(1., ln3.getLineWidth(), 0);\r
         ln3.setLineDash(null);\r
         assertEquals(null, ln3.getLineDash());\r
         ln3.setLineCap(null);\r
         assertEquals(null, ln3.getLineDash());\r
     }\r
 \r
+    @Test\r
     public void testFill() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -143,29 +148,30 @@ public class TestXSLFSimpleShape extends TestCase {
         assertFalse(shape.getSpPr().isSetSolidFill());\r
     }\r
 \r
+    @Test\r
     public void testDefaultProperties() {\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
 \r
-        XSLFSlide slide6 = ppt.getSlides()[5];\r
-        XSLFShape[] shapes = slide6.getShapes();\r
-        for(int i = 1; i < shapes.length; i++){\r
-            XSLFSimpleShape s = (XSLFSimpleShape) shapes[i];\r
+        XSLFSlide slide6 = ppt.getSlides().get(5);\r
+        List<XSLFShape> shapes = slide6.getShapes();\r
+        for(XSLFShape xs : shapes){\r
+            XSLFSimpleShape s = (XSLFSimpleShape)xs;\r
             // all shapes have a theme color="accent1"\r
             assertEquals("accent1", s.getSpStyle().getFillRef().getSchemeClr().getVal().toString());\r
-            assertEquals(2.0, s.getLineWidth());\r
+            assertEquals(2.0, s.getLineWidth(), 0);\r
             assertEquals(LineCap.FLAT, s.getLineCap());\r
             // YK: calculated color is slightly different from PowerPoint\r
             assertEquals(new Color(39, 64, 94), s.getLineColor());\r
         }\r
 \r
-        XSLFSimpleShape s0 = (XSLFSimpleShape) shapes[0];\r
+        XSLFSimpleShape s0 = (XSLFSimpleShape) shapes.get(0);\r
         // fill is not set\r
         assertNull(s0.getSpPr().getSolidFill());\r
         //assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor());\r
         assertEquals(new Color(79, 129, 189), s0.getFillColor());\r
 \r
         // lighter 80%\r
-        XSLFSimpleShape s1 = (XSLFSimpleShape)shapes[1];\r
+        XSLFSimpleShape s1 = (XSLFSimpleShape)shapes.get(1);\r
         CTSchemeColor ref1 = s1.getSpPr().getSolidFill().getSchemeClr();\r
         assertEquals(1, ref1.sizeOfLumModArray());\r
         assertEquals(1, ref1.sizeOfLumOffArray());\r
@@ -175,7 +181,7 @@ public class TestXSLFSimpleShape extends TestCase {
         assertEquals(new Color(220, 230, 242), s1.getFillColor());\r
 \r
         // lighter 60%\r
-        XSLFSimpleShape s2 = (XSLFSimpleShape)shapes[2];\r
+        XSLFSimpleShape s2 = (XSLFSimpleShape)shapes.get(2);\r
         CTSchemeColor ref2 = s2.getSpPr().getSolidFill().getSchemeClr();\r
         assertEquals(1, ref2.sizeOfLumModArray());\r
         assertEquals(1, ref2.sizeOfLumOffArray());\r
@@ -185,7 +191,7 @@ public class TestXSLFSimpleShape extends TestCase {
         assertEquals(new Color(185, 205, 229), s2.getFillColor());\r
 \r
         // lighter 40%\r
-        XSLFSimpleShape s3 = (XSLFSimpleShape)shapes[3];\r
+        XSLFSimpleShape s3 = (XSLFSimpleShape)shapes.get(3);\r
         CTSchemeColor ref3 = s3.getSpPr().getSolidFill().getSchemeClr();\r
         assertEquals(1, ref3.sizeOfLumModArray());\r
         assertEquals(1, ref3.sizeOfLumOffArray());\r
@@ -195,7 +201,7 @@ public class TestXSLFSimpleShape extends TestCase {
         assertEquals(new Color(149, 179, 215), s3.getFillColor());\r
 \r
         // darker 25%\r
-        XSLFSimpleShape s4 = (XSLFSimpleShape)shapes[4];\r
+        XSLFSimpleShape s4 = (XSLFSimpleShape)shapes.get(4);\r
         CTSchemeColor ref4 = s4.getSpPr().getSolidFill().getSchemeClr();\r
         assertEquals(1, ref4.sizeOfLumModArray());\r
         assertEquals(0, ref4.sizeOfLumOffArray());\r
@@ -204,7 +210,7 @@ public class TestXSLFSimpleShape extends TestCase {
         // YK: calculated color is slightly different from PowerPoint\r
         assertEquals(new Color(59, 97, 142), s4.getFillColor());\r
 \r
-        XSLFSimpleShape s5 = (XSLFSimpleShape)shapes[5];\r
+        XSLFSimpleShape s5 = (XSLFSimpleShape)shapes.get(5);\r
         CTSchemeColor ref5 = s5.getSpPr().getSolidFill().getSchemeClr();\r
         assertEquals(1, ref5.sizeOfLumModArray());\r
         assertEquals(0, ref5.sizeOfLumOffArray());\r
@@ -214,26 +220,27 @@ public class TestXSLFSimpleShape extends TestCase {
         assertEquals(new Color(40, 65, 95), s5.getFillColor());\r
     }\r
 \r
+    @Test\r
     public void testAnchor(){\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
-        XSLFSlide[] slide = ppt.getSlides();\r
+        List<XSLFSlide> slide = ppt.getSlides();\r
 \r
-        XSLFSlide slide2 = slide[1];\r
+        XSLFSlide slide2 = slide.get(1);\r
         XSLFSlideLayout layout2 = slide2.getSlideLayout();\r
-        XSLFShape[] shapes2 = slide2.getShapes();\r
-        XSLFTextShape sh1 = (XSLFTextShape)shapes2[0];\r
+        List<XSLFShape> shapes2 = slide2.getShapes();\r
+        XSLFTextShape sh1 = (XSLFTextShape)shapes2.get(0);\r
         assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType());\r
         assertEquals("PPTX Title", sh1.getText());\r
         assertNull(sh1.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout\r
         assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor());\r
 \r
-        XSLFTextShape sh2 = (XSLFTextShape)shapes2[1];\r
+        XSLFTextShape sh2 = (XSLFTextShape)shapes2.get(1);\r
         assertEquals("Subtitle\nAnd second line", sh2.getText());\r
         assertEquals(Placeholder.SUBTITLE, sh2.getTextType());\r
         assertNull(sh2.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout\r
         assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor());\r
 \r
-        XSLFSlide slide5 = slide[4];\r
+        XSLFSlide slide5 = slide.get(4);\r
         XSLFSlideLayout layout5 = slide5.getSlideLayout();\r
         XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE);\r
         assertEquals("Hyperlinks", shTitle.getText());\r
@@ -247,6 +254,7 @@ public class TestXSLFSimpleShape extends TestCase {
     }\r
 \r
     @SuppressWarnings({ "deprecation", "unused" })\r
+    @Test\r
     public void testShadowEffects(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
index ecfd70eac246e2046b0be9eca2556ff5dee68f0f..fdfb46ee9a7e9cc6448c7205aecc710ee46d390e 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.*;\r
 \r
 import java.awt.Color;\r
-\r
-import junit.framework.TestCase;\r
+import java.util.List;\r
 \r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFSlide extends TestCase {\r
+public class TestXSLFSlide {\r
+    \r
+    @Test\r
     public void testReadShapes(){\r
         XMLSlideShow  ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
-        XSLFSlide[] slides = ppt.getSlides();\r
-\r
-        XSLFSlide slide1 = slides[0];\r
-        XSLFShape[] shapes1 = slide1.getShapes();\r
-        assertEquals(7, shapes1.length);\r
-        assertEquals("TextBox 3", shapes1[0].getShapeName());\r
-        assertTrue(shapes1[0] instanceof XSLFTextBox);\r
-        XSLFAutoShape sh0 = (XSLFAutoShape)shapes1[0];\r
+        List<XSLFSlide> slides = ppt.getSlides();\r
+\r
+        XSLFSlide slide1 = slides.get(0);\r
+        List<XSLFShape> shapes1 = slide1.getShapes();\r
+        assertEquals(7, shapes1.size());\r
+        assertEquals("TextBox 3", shapes1.get(0).getShapeName());\r
+        assertTrue(shapes1.get(0) instanceof XSLFTextBox);\r
+        XSLFAutoShape sh0 = (XSLFAutoShape)shapes1.get(0);\r
         assertEquals("Learning PPTX", sh0.getText());\r
 \r
 \r
-        assertEquals("Straight Connector 5", shapes1[1].getShapeName());\r
-        assertTrue(shapes1[1] instanceof XSLFConnectorShape);\r
+        assertEquals("Straight Connector 5", shapes1.get(1).getShapeName());\r
+        assertTrue(shapes1.get(1) instanceof XSLFConnectorShape);\r
 \r
-        assertEquals("Freeform 6", shapes1[2].getShapeName());\r
-        assertTrue(shapes1[2] instanceof XSLFFreeformShape);\r
-        XSLFAutoShape sh2 = (XSLFAutoShape)shapes1[2];\r
+        assertEquals("Freeform 6", shapes1.get(2).getShapeName());\r
+        assertTrue(shapes1.get(2) instanceof XSLFFreeformShape);\r
+        XSLFAutoShape sh2 = (XSLFAutoShape)shapes1.get(2);\r
         assertEquals("Cloud", sh2.getText());\r
 \r
-        assertEquals("Picture 1", shapes1[3].getShapeName());\r
-        assertTrue(shapes1[3] instanceof XSLFPictureShape);\r
+        assertEquals("Picture 1", shapes1.get(3).getShapeName());\r
+        assertTrue(shapes1.get(3) instanceof XSLFPictureShape);\r
 \r
-        assertEquals("Table 2", shapes1[4].getShapeName());\r
-        assertTrue(shapes1[4] instanceof XSLFGraphicFrame);\r
+        assertEquals("Table 2", shapes1.get(4).getShapeName());\r
+        assertTrue(shapes1.get(4) instanceof XSLFGraphicFrame);\r
 \r
-        assertEquals("Straight Arrow Connector 7", shapes1[5].getShapeName());\r
-        assertTrue(shapes1[5] instanceof XSLFConnectorShape);\r
+        assertEquals("Straight Arrow Connector 7", shapes1.get(5).getShapeName());\r
+        assertTrue(shapes1.get(5) instanceof XSLFConnectorShape);\r
 \r
-        assertEquals("Elbow Connector 9", shapes1[6].getShapeName());\r
-        assertTrue(shapes1[6] instanceof XSLFConnectorShape);\r
+        assertEquals("Elbow Connector 9", shapes1.get(6).getShapeName());\r
+        assertTrue(shapes1.get(6) instanceof XSLFConnectorShape);\r
 \r
         // titles on slide2\r
-        XSLFSlide slide2 = slides[1];\r
-        XSLFShape[] shapes2 = slide2.getShapes();\r
-        assertEquals(2, shapes2.length);\r
-        assertTrue(shapes2[0] instanceof XSLFAutoShape);\r
-        assertEquals("PPTX Title", ((XSLFAutoShape)shapes2[0]).getText());\r
-        assertTrue(shapes2[1] instanceof XSLFAutoShape);\r
-        assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape)shapes2[1]).getText());\r
+        XSLFSlide slide2 = slides.get(1);\r
+        List<XSLFShape> shapes2 = slide2.getShapes();\r
+        assertEquals(2, shapes2.size());\r
+        assertTrue(shapes2.get(0) instanceof XSLFAutoShape);\r
+        assertEquals("PPTX Title", ((XSLFAutoShape)shapes2.get(0)).getText());\r
+        assertTrue(shapes2.get(1) instanceof XSLFAutoShape);\r
+        assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape)shapes2.get(1)).getText());\r
 \r
         //  group shape on slide3\r
-        XSLFSlide slide3 = slides[2];\r
-        XSLFShape[] shapes3 = slide3.getShapes();\r
-        assertEquals(1, shapes3.length);\r
-        assertTrue(shapes3[0] instanceof XSLFGroupShape);\r
-        XSLFShape[] groupShapes = ((XSLFGroupShape)shapes3[0]).getShapes();\r
-        assertEquals(3, groupShapes.length);\r
-        assertTrue(groupShapes[0] instanceof XSLFAutoShape);\r
-        assertEquals("Rectangle 1", groupShapes[0].getShapeName());\r
-\r
-        assertTrue(groupShapes[1] instanceof XSLFAutoShape);\r
-        assertEquals("Oval 2", groupShapes[1].getShapeName());\r
-\r
-        assertTrue(groupShapes[2] instanceof XSLFAutoShape);\r
-        assertEquals("Right Arrow 3", groupShapes[2].getShapeName());\r
-\r
-        XSLFSlide slide4 = slides[3];\r
-        XSLFShape[] shapes4 = slide4.getShapes();\r
-        assertEquals(1, shapes4.length);\r
-        assertTrue(shapes4[0] instanceof XSLFTable);\r
-        XSLFTable tbl = (XSLFTable)shapes4[0];\r
+        XSLFSlide slide3 = slides.get(2);\r
+        List<XSLFShape> shapes3 = slide3.getShapes();\r
+        assertEquals(1, shapes3.size());\r
+        assertTrue(shapes3.get(0) instanceof XSLFGroupShape);\r
+        List<XSLFShape> groupShapes = ((XSLFGroupShape)shapes3.get(0)).getShapes();\r
+        assertEquals(3, groupShapes.size());\r
+        assertTrue(groupShapes.get(0) instanceof XSLFAutoShape);\r
+        assertEquals("Rectangle 1", groupShapes.get(0).getShapeName());\r
+\r
+        assertTrue(groupShapes.get(1) instanceof XSLFAutoShape);\r
+        assertEquals("Oval 2", groupShapes.get(1).getShapeName());\r
+\r
+        assertTrue(groupShapes.get(2) instanceof XSLFAutoShape);\r
+        assertEquals("Right Arrow 3", groupShapes.get(2).getShapeName());\r
+\r
+        XSLFSlide slide4 = slides.get(3);\r
+        List<XSLFShape> shapes4 = slide4.getShapes();\r
+        assertEquals(1, shapes4.size());\r
+        assertTrue(shapes4.get(0) instanceof XSLFTable);\r
+        XSLFTable tbl = (XSLFTable)shapes4.get(0);\r
         assertEquals(3, tbl.getNumberOfColumns());\r
         assertEquals(6, tbl.getNumberOfRows());\r
     }\r
 \r
+    @Test\r
     public void testCreateSlide(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
-        assertEquals(0, ppt.getSlides().length);\r
+        assertEquals(0, ppt.getSlides().size());\r
 \r
         XSLFSlide slide = ppt.createSlide();\r
         assertTrue(slide.getFollowMasterGraphics());\r
@@ -107,34 +110,35 @@ public class TestXSLFSlide extends TestCase {
         assertTrue(slide.getFollowMasterGraphics());\r
     }\r
 \r
+    @Test\r
     public void testImportContent(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
         XMLSlideShow  src = XSLFTestDataSamples.openSampleDocument("themes.pptx");\r
 \r
         // create a blank slide and import content from the 4th slide of themes.pptx\r
-        XSLFSlide slide1 = ppt.createSlide().importContent(src.getSlides()[3]);\r
-        XSLFShape[] shapes1 = slide1.getShapes();\r
-        assertEquals(2, shapes1.length);\r
+        XSLFSlide slide1 = ppt.createSlide().importContent(src.getSlides().get(3));\r
+        List<XSLFShape> shapes1 = slide1.getShapes();\r
+        assertEquals(2, shapes1.size());\r
 \r
-        XSLFTextShape sh1 = (XSLFTextShape)shapes1[0];\r
+        XSLFTextShape sh1 = (XSLFTextShape)shapes1.get(0);\r
         assertEquals("Austin Theme", sh1.getText());\r
         XSLFTextRun r1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Century Gothic", r1.getFontFamily());\r
-        assertEquals(40.0, r1.getFontSize());\r
+        assertEquals(40.0, r1.getFontSize(), 0);\r
         assertTrue(r1.isBold());\r
         assertTrue(r1.isItalic());\r
         assertEquals(new Color(148, 198, 0), r1.getFontColor());\r
         assertNull(sh1.getFillColor());\r
         assertNull(sh1.getLineColor());\r
 \r
-        XSLFTextShape sh2 = (XSLFTextShape)shapes1[1];\r
+        XSLFTextShape sh2 = (XSLFTextShape)shapes1.get(1);\r
         assertEquals(\r
                 "Text in a autoshape is white\n" +\r
                 "Fill: RGB(148, 198,0)", sh2.getText());\r
         XSLFTextRun r2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Century Gothic", r2.getFontFamily());\r
-        assertEquals(18.0, r2.getFontSize());\r
+        assertEquals(18.0, r2.getFontSize(), 0);\r
         assertFalse(r2.isBold());\r
         assertFalse(r2.isItalic());\r
         assertEquals(Color.white, r2.getFontColor());\r
@@ -142,11 +146,11 @@ public class TestXSLFSlide extends TestCase {
         assertEquals(new Color(74, 99, 0), sh2.getLineColor()); // slightly different from PowerPoint!\r
 \r
         // the 5th slide has a picture and a texture fill\r
-        XSLFSlide slide2 = ppt.createSlide().importContent(src.getSlides()[4]);\r
-        XSLFShape[] shapes2 = slide2.getShapes();\r
-        assertEquals(2, shapes2.length);\r
+        XSLFSlide slide2 = ppt.createSlide().importContent(src.getSlides().get(4));\r
+        List<XSLFShape> shapes2 = slide2.getShapes();\r
+        assertEquals(2, shapes2.size());\r
 \r
-        XSLFTextShape sh3 = (XSLFTextShape)shapes2[0];\r
+        XSLFTextShape sh3 = (XSLFTextShape)shapes2.get(0);\r
         assertEquals("This slide overrides master background with a texture fill", sh3.getText());\r
         XSLFTextRun r3 = sh3.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Century Gothic", r3.getFontFamily());\r
@@ -157,11 +161,12 @@ public class TestXSLFSlide extends TestCase {
         assertNull(sh3.getFillColor());\r
         assertNull(sh3.getLineColor());\r
 \r
-        XSLFPictureShape sh4 = (XSLFPictureShape)shapes2[1];\r
-        XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides()[4].getShapes()[1];\r
+        XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);\r
+        XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);\r
         assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());\r
     }\r
 \r
+    @Test\r
     public void testMergeSlides(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"};\r
@@ -173,6 +178,6 @@ public class TestXSLFSlide extends TestCase {
                 ppt.createSlide().importContent(srcSlide);\r
             }\r
         }\r
-        assertEquals(30, ppt.getSlides().length);\r
+        assertEquals(30, ppt.getSlides().size());\r
     }    \r
 }
\ No newline at end of file
index c3057d590fd5e47a3ee5112dd59a127de25eafe6..3d20be87eab208b816242237010a8034c1943669 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
-import org.apache.poi.POIXMLDocumentPart;\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import static org.junit.Assert.*;\r
 \r
 import java.awt.Dimension;\r
 import java.util.List;\r
 \r
+import org.apache.poi.POIXMLDocumentPart;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
+\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFSlideShow extends TestCase {\r
+public class TestXSLFSlideShow {\r
+    @Test\r
     public void testCreateSlide(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
-        assertEquals(0, ppt.getSlides().length);\r
+        assertEquals(0, ppt.getSlides().size());\r
 \r
         XSLFSlide slide1 = ppt.createSlide();\r
-        assertEquals(1, ppt.getSlides().length);\r
-        assertSame(slide1, ppt.getSlides()[0]);\r
+        assertEquals(1, ppt.getSlides().size());\r
+        assertSame(slide1, ppt.getSlides().get(0));\r
 \r
         List<POIXMLDocumentPart> rels =  slide1.getRelations();\r
         assertEquals(1, rels.size());\r
         assertEquals(slide1.getSlideMaster().getLayout(SlideLayout.BLANK), rels.get(0));\r
 \r
         XSLFSlide slide2 = ppt.createSlide();\r
-        assertEquals(2, ppt.getSlides().length);\r
-        assertSame(slide2, ppt.getSlides()[1]);\r
+        assertEquals(2, ppt.getSlides().size());\r
+        assertSame(slide2, ppt.getSlides().get(1));\r
 \r
         ppt.setSlideOrder(slide2, 0);\r
-        assertSame(slide2, ppt.getSlides()[0]);\r
-        assertSame(slide1, ppt.getSlides()[1]);\r
+        assertSame(slide2, ppt.getSlides().get(0));\r
+        assertSame(slide1, ppt.getSlides().get(1));\r
 \r
         ppt = XSLFTestDataSamples.writeOutAndReadBack(ppt);\r
-        assertEquals(2, ppt.getSlides().length);\r
-        rels =  ppt.getSlides()[0].getRelations();\r
+        assertEquals(2, ppt.getSlides().size());\r
+        rels =  ppt.getSlides().get(0).getRelations();\r
     }\r
 \r
+    @Test\r
     public void testRemoveSlide(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
-        assertEquals(0, ppt.getSlides().length);\r
+        assertEquals(0, ppt.getSlides().size());\r
 \r
         XSLFSlide slide1 = ppt.createSlide();\r
         XSLFSlide slide2 = ppt.createSlide();\r
 \r
-        assertEquals(2, ppt.getSlides().length);\r
-        assertSame(slide1, ppt.getSlides()[0]);\r
-        assertSame(slide2, ppt.getSlides()[1]);\r
+        assertEquals(2, ppt.getSlides().size());\r
+        assertSame(slide1, ppt.getSlides().get(0));\r
+        assertSame(slide2, ppt.getSlides().get(1));\r
 \r
         XSLFSlide removedSlide = ppt.removeSlide(0);\r
         assertSame(slide1, removedSlide);\r
 \r
-        assertEquals(1, ppt.getSlides().length);\r
-        assertSame(slide2, ppt.getSlides()[0]);\r
+        assertEquals(1, ppt.getSlides().size());\r
+        assertSame(slide2, ppt.getSlides().get(0));\r
 \r
         ppt = XSLFTestDataSamples.writeOutAndReadBack(ppt);\r
-        assertEquals(1, ppt.getSlides().length);\r
+        assertEquals(1, ppt.getSlides().size());\r
     }\r
 \r
+    @Test\r
     public void testDimension(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
         Dimension sz = ppt.getPageSize();\r
@@ -84,24 +89,26 @@ public class TestXSLFSlideShow extends TestCase {
         assertEquals(612, sz.height);\r
     }\r
 \r
+    @Test\r
     public void testSlideMasters(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
-        XSLFSlideMaster[] masters = ppt.getSlideMasters();\r
-        assertEquals(1, masters.length);\r
+        List<XSLFSlideMaster> masters = ppt.getSlideMasters();\r
+        assertEquals(1, masters.size());\r
 \r
         XSLFSlide slide = ppt.createSlide();\r
-        assertSame(masters[0], slide.getSlideMaster());\r
+        assertSame(masters.get(0), slide.getSlideMaster());\r
     }\r
 \r
+    @Test\r
     public void testSlideLayout(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
-        XSLFSlideMaster[] masters = ppt.getSlideMasters();\r
-        assertEquals(1, masters.length);\r
+        List<XSLFSlideMaster> masters = ppt.getSlideMasters();\r
+        assertEquals(1, masters.size());\r
 \r
         XSLFSlide slide = ppt.createSlide();\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
         assertNotNull(layout);\r
 \r
-        assertSame(masters[0], layout.getSlideMaster());\r
+        assertSame(masters.get(0), layout.getSlideMaster());\r
     }\r
 }\r
index 80a52fd2cc719dbef73e86d5be2fdbcb9c7741aa..3b7c5cbcc219bca3e57628209cc237da126d58cf 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.*;\r
 \r
 import org.apache.poi.sl.usermodel.VerticalAlignment;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
 \r
@@ -29,16 +30,16 @@ import java.util.List;
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTable extends TestCase {\r
-\r
+public class TestXSLFTable {\r
+    @Test\r
     public void testRead(){\r
         XMLSlideShow  ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");\r
 \r
-        XSLFSlide slide = ppt.getSlides()[3];\r
-        XSLFShape[] shapes = slide.getShapes();\r
-        assertEquals(1, shapes.length);\r
-        assertTrue(shapes[0] instanceof XSLFTable);\r
-        XSLFTable tbl = (XSLFTable)shapes[0];\r
+        XSLFSlide slide = ppt.getSlides().get(3);\r
+        List<XSLFShape> shapes = slide.getShapes();\r
+        assertEquals(1, shapes.size());\r
+        assertTrue(shapes.get(0) instanceof XSLFTable);\r
+        XSLFTable tbl = (XSLFTable)shapes.get(0);\r
         assertEquals(3, tbl.getNumberOfColumns());\r
         assertEquals(6, tbl.getNumberOfRows());\r
         assertNotNull(tbl.getCTTable());\r
@@ -46,13 +47,13 @@ public class TestXSLFTable extends TestCase {
         List<XSLFTableRow> rows = tbl.getRows();\r
         assertEquals(6, rows.size());\r
 \r
-        assertEquals(90.0, tbl.getColumnWidth(0));\r
-        assertEquals(240.0, tbl.getColumnWidth(1));\r
-        assertEquals(150.0, tbl.getColumnWidth(2));\r
+        assertEquals(90.0, tbl.getColumnWidth(0), 0);\r
+        assertEquals(240.0, tbl.getColumnWidth(1), 0);\r
+        assertEquals(150.0, tbl.getColumnWidth(2), 0);\r
 \r
         for(XSLFTableRow row : tbl){\r
             // all rows have the same height\r
-            assertEquals(29.2, row.getHeight());\r
+            assertEquals(29.2, row.getHeight(), 0);\r
         }\r
 \r
         XSLFTableRow row0 = rows.get(0);\r
@@ -70,6 +71,7 @@ public class TestXSLFTable extends TestCase {
         assertEquals("C1", cells1.get(2).getText());\r
     }\r
 \r
+    @Test\r
     public void testCreate() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -92,9 +94,9 @@ public class TestXSLFTable extends TestCase {
         assertNotNull(row0.getXmlObject());\r
         assertEquals(1, tbl.getNumberOfRows());\r
         assertSame(row0, tbl.getRows().get(0));\r
-        assertEquals(20.0, row0.getHeight());\r
+        assertEquals(20.0, row0.getHeight(), 0);\r
         row0.setHeight(30.0);\r
-        assertEquals(30.0, row0.getHeight());\r
+        assertEquals(30.0, row0.getHeight(), 0);\r
 \r
         assertEquals(0, row0.getCells().size());\r
         XSLFTableCell cell0 = row0.addCell();\r
@@ -108,41 +110,41 @@ public class TestXSLFTable extends TestCase {
 \r
         assertSame(cell0, row0.getCells().get(0));\r
         assertEquals(1, tbl.getNumberOfColumns());\r
-        assertEquals(100.0, tbl.getColumnWidth(0));\r
+        assertEquals(100.0, tbl.getColumnWidth(0), 0);\r
         cell0.addNewTextParagraph().addNewTextRun().setText("POI");\r
         assertEquals("POI", cell0.getText());\r
 \r
         XSLFTableCell cell1 = row0.addCell();\r
         assertSame(cell1, row0.getCells().get(1));\r
         assertEquals(2, tbl.getNumberOfColumns());\r
-        assertEquals(100.0, tbl.getColumnWidth(1));\r
+        assertEquals(100.0, tbl.getColumnWidth(1), 0);\r
         cell1.addNewTextParagraph().addNewTextRun().setText("Apache");\r
         assertEquals("Apache", cell1.getText());\r
 \r
-        assertEquals(1.0, cell1.getBorderBottom());\r
+        assertEquals(1.0, cell1.getBorderBottom(), 0);\r
         cell1.setBorderBottom(2.0);\r
-        assertEquals(2.0, cell1.getBorderBottom());\r
+        assertEquals(2.0, cell1.getBorderBottom(), 0);\r
         assertNull(cell1.getBorderBottomColor());\r
         cell1.setBorderBottomColor(Color.yellow);\r
         assertEquals(Color.yellow, cell1.getBorderBottomColor());\r
 \r
-        assertEquals(1.0, cell1.getBorderTop());\r
+        assertEquals(1.0, cell1.getBorderTop(), 0);\r
         cell1.setBorderTop(2.0);\r
-        assertEquals(2.0, cell1.getBorderTop());\r
+        assertEquals(2.0, cell1.getBorderTop(), 0);\r
         assertNull(cell1.getBorderTopColor());\r
         cell1.setBorderTopColor(Color.yellow);\r
         assertEquals(Color.yellow, cell1.getBorderTopColor());\r
 \r
-        assertEquals(1.0, cell1.getBorderLeft());\r
+        assertEquals(1.0, cell1.getBorderLeft(), 0);\r
         cell1.setBorderLeft(2.0);\r
-        assertEquals(2.0, cell1.getBorderLeft());\r
+        assertEquals(2.0, cell1.getBorderLeft(), 0);\r
         assertNull(cell1.getBorderLeftColor());\r
         cell1.setBorderLeftColor(Color.yellow);\r
         assertEquals(Color.yellow, cell1.getBorderLeftColor());\r
 \r
-        assertEquals(1.0, cell1.getBorderRight());\r
+        assertEquals(1.0, cell1.getBorderRight(), 0);\r
         cell1.setBorderRight(2.0);\r
-        assertEquals(2.0, cell1.getBorderRight());\r
+        assertEquals(2.0, cell1.getBorderRight(), 0);\r
         assertNull(cell1.getBorderRightColor());\r
         cell1.setBorderRightColor(Color.yellow);\r
         assertEquals(Color.yellow, cell1.getBorderRightColor());\r
index 3ce6c3b6d28b4fb5ae4ef67946260e3ac10c7d35..49b5fd4944264777e861edd828a4e0232bdfc543 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyle;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTableStyles extends TestCase {\r
+public class TestXSLFTableStyles {\r
 \r
+    @Test\r
     public void testRead(){\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
         XSLFTableStyles tblStyles = ppt.getTableStyles();\r
@@ -32,6 +36,8 @@ public class TestXSLFTableStyles extends TestCase {
         assertEquals(0, tblStyles.getStyles().size());\r
     }\r
 \r
+    @SuppressWarnings("unused")\r
+    @Test\r
     public void testStyle(){\r
         CTTableStyle obj = CTTableStyle.Factory.newInstance();\r
         XSLFTableStyle style = new XSLFTableStyle(obj);\r
index 2176a1b2ea45b4dcc503a8dd2abc91ac2e415582..40e07a691042941cf0765fb46b2bc6c1f32c07dc 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNull;\r
+\r
+import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTextBox extends TestCase {\r
+public class TestXSLFTextBox {\r
 \r
+    @Test\r
     public void testPlaceholder() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -40,6 +44,7 @@ public class TestXSLFTextBox extends TestCase {
     /**\r
      * text box inherits default text proeprties from presentation.xml\r
      */\r
+    @Test\r
     public void testDefaultTextStyle() {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
@@ -55,12 +60,12 @@ public class TestXSLFTextBox extends TestCase {
         XSLFTextRun r = shape.getTextParagraphs().get(0).getTextRuns().get(0);\r
 \r
         assertEquals(1800, pPr.getSz());\r
-        assertEquals(18.0, r.getFontSize());\r
+        assertEquals(18.0, r.getFontSize(), 0);\r
         assertEquals("Calibri", r.getFontFamily());\r
 \r
         pPr.setSz(900);\r
         pPr.getLatin().setTypeface("Arial");\r
-        assertEquals(9.0, r.getFontSize());\r
+        assertEquals(9.0, r.getFontSize(), 0);\r
         assertEquals("Arial", r.getFontFamily());\r
 \r
         // unset font size in presentation.xml. The value should be taken from master slide\r
@@ -68,12 +73,12 @@ public class TestXSLFTextBox extends TestCase {
         ppt.getCTPresentation().getDefaultTextStyle().getLvl1PPr().getDefRPr().unsetSz();\r
         pPr = slide.getSlideMaster().getXmlObject().getTxStyles().getOtherStyle().getLvl1PPr().getDefRPr();\r
         assertEquals(1800, pPr.getSz());\r
-        assertEquals(18.0, r.getFontSize());\r
+        assertEquals(18.0, r.getFontSize(), 0);\r
         pPr.setSz(2000);\r
-        assertEquals(20.0, r.getFontSize());\r
+        assertEquals(20.0, r.getFontSize(), 0);\r
 \r
         pPr.unsetSz();  // Should never be\r
-        assertEquals(-1.0, r.getFontSize());\r
+        assertEquals(-1.0, r.getFontSize(), 0);\r
 \r
     }\r
 }
\ No newline at end of file
index fb906ed3a10c06597a334b75b4a2864f73dd6970..0998ee8e7290e056420ef3ded4d0a3ecac67f092 100644 (file)
@@ -242,14 +242,14 @@ public class TestXSLFTextParagraph {
     @Test\r
     public void testThemeInheritance(){\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");\r
-        XSLFShape[] shapes = ppt.getSlides()[0].getShapes();\r
-        XSLFTextShape sh1 = (XSLFTextShape)shapes[0];\r
+        List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();\r
+        XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0);\r
         assertEquals("Apache", sh1.getText());\r
         assertEquals(TextAlign.CENTER, sh1.getTextParagraphs().get(0).getTextAlign());\r
-        XSLFTextShape sh2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape sh2 = (XSLFTextShape)shapes.get(1);\r
         assertEquals("Software", sh2.getText());\r
         assertEquals(TextAlign.CENTER, sh2.getTextParagraphs().get(0).getTextAlign());\r
-        XSLFTextShape sh3 = (XSLFTextShape)shapes[2];\r
+        XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2);\r
         assertEquals("Foundation", sh3.getText());\r
         assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());\r
     }\r
@@ -350,7 +350,7 @@ public class TestXSLFTextParagraph {
         XSLFTextRun r1 = p.addNewTextRun();\r
         r1.setText("Hello,");\r
         XSLFTextRun r2 = p.addLineBreak();\r
-        assertEquals("\n", r2.getText());\r
+        assertEquals("\n", r2.getRawText());\r
         r2.setFontSize(10.0);\r
         assertEquals(10.0, r2.getFontSize(), 0);\r
         XSLFTextRun r3 = p.addNewTextRun();\r
index f9232a1733a765428332ee30f22f25a80d20beaf..b19d069b0d689d93e9dc605611680abd298d23c4 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.Color;\r
+import static org.junit.Assert.*;\r
 \r
-import junit.framework.TestCase;\r
+import java.awt.Color;\r
+import java.util.List;\r
 \r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
 import org.apache.poi.sl.usermodel.VerticalAlignment;\r
@@ -30,28 +31,28 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTextShape extends TestCase {\r
+public class TestXSLFTextShape {\r
 \r
     public void testLayouts(){\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx");\r
 \r
-        XSLFSlide[] slide = ppt.getSlides();\r
+        List<XSLFSlide> slide = ppt.getSlides();\r
 \r
-        verifySlide1(slide[0]);\r
-        verifySlide2(slide[1]);\r
-        verifySlide3(slide[2]);\r
-        verifySlide4(slide[3]);\r
-        verifySlide7(slide[6]);\r
-        verifySlide8(slide[7]);\r
-        verifySlide10(slide[9]);\r
+        verifySlide1(slide.get(0));\r
+        verifySlide2(slide.get(1));\r
+        verifySlide3(slide.get(2));\r
+        verifySlide4(slide.get(3));\r
+        verifySlide7(slide.get(6));\r
+        verifySlide8(slide.get(7));\r
+        verifySlide10(slide.get(9));\r
     }\r
 \r
     void verifySlide1(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Title Slide",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -68,20 +69,20 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
         assertEquals("Centered Title", shape1.getText());\r
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(44.0, r1.getFontSize());\r
+        assertEquals(44.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType());\r
         // anchor is not defined in the shape\r
@@ -98,26 +99,26 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());\r
 \r
         assertEquals("subtitle", shape2.getText());\r
         XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Calibri", r2.getFontFamily());\r
-        assertEquals(32.0, r2.getFontSize());\r
+        assertEquals(32.0, r2.getFontSize(), 0);\r
         // TODO fix calculation of tint\r
         //assertEquals(new Color(137, 137, 137), r2.getFontColor());\r
     }\r
 \r
     void verifySlide2(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Title and Content",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -137,20 +138,20 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
         assertEquals("Title", shape1.getText());\r
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(44.0, r1.getFontSize());\r
+        assertEquals(44.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
         assertFalse(ph2.isSetType()); // <p:ph idx="1"/>\r
         assertTrue(ph2.isSetIdx());\r
@@ -172,54 +173,54 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());\r
 \r
         XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr1.getParentParagraph().getLevel());\r
-        assertEquals("Content", pr1.getText());\r
+        assertEquals("Content", pr1.getRawText());\r
         assertEquals("Calibri", pr1.getFontFamily());\r
-        assertEquals(32.0, pr1.getFontSize());\r
-        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin()); \r
+        assertEquals(32.0, pr1.getFontSize(), 0);\r
+        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0); \r
         assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); \r
         assertEquals("Arial", pr1.getParentParagraph().getBulletFont());\r
 \r
         XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0);\r
         assertEquals(1, pr2.getParentParagraph().getLevel());\r
-        assertEquals("Level 2", pr2.getText());\r
+        assertEquals("Level 2", pr2.getRawText());\r
         assertEquals("Calibri", pr2.getFontFamily());\r
-        assertEquals(28.0, pr2.getFontSize());\r
-        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin());\r
+        assertEquals(28.0, pr2.getFontSize(), 0);\r
+        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr2.getParentParagraph().getBulletFont());\r
 \r
         XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0);\r
         assertEquals(2, pr3.getParentParagraph().getLevel());\r
-        assertEquals("Level 3", pr3.getText());\r
+        assertEquals("Level 3", pr3.getRawText());\r
         assertEquals("Calibri", pr3.getFontFamily());\r
-        assertEquals(24.0, pr3.getFontSize());\r
-        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin());\r
+        assertEquals(24.0, pr3.getFontSize(), 0);\r
+        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr3.getParentParagraph().getBulletFont());\r
 \r
         XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0);\r
         assertEquals(3, pr4.getParentParagraph().getLevel());\r
-        assertEquals("Level 4", pr4.getText());\r
+        assertEquals("Level 4", pr4.getRawText());\r
         assertEquals("Calibri", pr4.getFontFamily());\r
-        assertEquals(20.0, pr4.getFontSize());\r
-        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin());\r
+        assertEquals(20.0, pr4.getFontSize(), 0);\r
+        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr4.getParentParagraph().getBulletFont());\r
 \r
         XSLFTextRun pr5 = shape2.getTextParagraphs().get(4).getTextRuns().get(0);\r
         assertEquals(4, pr5.getParentParagraph().getLevel());\r
-        assertEquals("Level 5", pr5.getText());\r
+        assertEquals("Level 5", pr5.getRawText());\r
         assertEquals("Calibri", pr5.getFontFamily());\r
-        assertEquals(20.0, pr5.getFontSize());\r
-        assertEquals(162.0, pr5.getParentParagraph().getLeftMargin());\r
+        assertEquals(20.0, pr5.getFontSize(), 0);\r
+        assertEquals(162.0, pr5.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u00bb", pr5.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr5.getParentParagraph().getBulletFont());\r
 \r
@@ -227,10 +228,10 @@ public class TestXSLFTextShape extends TestCase {
 \r
     void verifySlide3(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Section Header",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -247,10 +248,10 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
@@ -258,13 +259,13 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(40.0, r1.getFontSize());\r
+        assertEquals(40.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
         assertTrue(r1.isBold());\r
         assertFalse(r1.isItalic());\r
-        assertFalse(r1.isUnderline());\r
+        assertFalse(r1.isUnderlined());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.BODY, ph2.getType());\r
         // anchor is not defined in the shape\r
@@ -281,27 +282,27 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.BOTTOM, shape2.getVerticalAlignment());\r
 \r
         assertEquals("Section Header", shape2.getText());\r
         XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.LEFT, r2.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r2.getFontFamily());\r
-        assertEquals(20.0, r2.getFontSize());\r
+        assertEquals(20.0, r2.getFontSize(), 0);\r
         // TODO fix calculation of tint\r
         //assertEquals(new Color(137, 137, 137), r2.getFontColor());\r
     }\r
 \r
     void verifySlide4(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Two Content",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -321,10 +322,10 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
@@ -332,10 +333,10 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(44.0, r1.getFontSize());\r
+        assertEquals(44.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
         assertFalse(ph2.isSetType());\r
         assertTrue(ph2.isSetIdx());\r
@@ -354,18 +355,18 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());\r
 \r
         XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr1.getParentParagraph().getLevel());\r
-        assertEquals("Left", pr1.getText());\r
+        assertEquals("Left", pr1.getRawText());\r
         assertEquals("Calibri", pr1.getFontFamily());\r
-        assertEquals(28.0, pr1.getFontSize());\r
-        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin());\r
+        assertEquals(28.0, pr1.getFontSize(), 0);\r
+        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr1.getParentParagraph().getBulletFont());\r
 \r
@@ -373,8 +374,8 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(1, pr2.getParentParagraph().getLevel());\r
         assertEquals("Level 2", pr2.getParentParagraph().getText());\r
         assertEquals("Calibri", pr2.getFontFamily());\r
-        assertEquals(24.0, pr2.getFontSize());\r
-        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin());\r
+        assertEquals(24.0, pr2.getFontSize(), 0);\r
+        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr2.getParentParagraph().getBulletFont());\r
 \r
@@ -382,8 +383,8 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(2, pr3.getParentParagraph().getLevel());\r
         assertEquals("Level 3", pr3.getParentParagraph().getText());\r
         assertEquals("Calibri", pr3.getFontFamily());\r
-        assertEquals(20.0, pr3.getFontSize());\r
-        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin());\r
+        assertEquals(20.0, pr3.getFontSize(), 0);\r
+        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr3.getParentParagraph().getBulletFont());\r
 \r
@@ -391,31 +392,32 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(3, pr4.getParentParagraph().getLevel());\r
         assertEquals("Level 4", pr4.getParentParagraph().getText());\r
         assertEquals("Calibri", pr4.getFontFamily());\r
-        assertEquals(18.0, pr4.getFontSize());\r
-        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin());\r
+        assertEquals(18.0, pr4.getFontSize(), 0);\r
+        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr4.getParentParagraph().getBulletFont());\r
 \r
-        XSLFTextShape shape3 = (XSLFTextShape)shapes[2];\r
+        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);\r
         XSLFTextRun pr5 = shape3.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr5.getParentParagraph().getLevel());\r
-        assertEquals("Right", pr5.getText());\r
+        assertEquals("Right", pr5.getRawText());\r
         assertEquals("Calibri", pr5.getFontFamily());\r
         assertEquals(Color.black, pr5.getFontColor());\r
     }\r
 \r
+    @SuppressWarnings("unused")\r
     void verifySlide5(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         // TODO\r
     }    \r
 \r
     void verifySlide7(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Blank",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -428,10 +430,10 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
@@ -439,11 +441,11 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(44.0, r1.getFontSize());\r
+        assertEquals(44.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
         assertFalse(r1.isBold());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
 \r
         CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();\r
         // none of the following properties are set in the shapes and fetched from the master shape\r
@@ -452,19 +454,19 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());\r
 \r
         XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr1.getParentParagraph().getLevel());\r
-        assertEquals("Default Text", pr1.getText());\r
+        assertEquals("Default Text", pr1.getRawText());\r
         assertEquals("Calibri", pr1.getFontFamily());\r
-        assertEquals(18.0, pr1.getFontSize());\r
+        assertEquals(18.0, pr1.getFontSize(), 0);\r
 \r
-        XSLFTextShape shape3 = (XSLFTextShape)shapes[2];\r
+        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);\r
         assertEquals("Default", shape3.getTextParagraphs().get(0).getText());\r
         assertEquals("Text with levels", shape3.getTextParagraphs().get(1).getText());\r
         assertEquals("Level 1", shape3.getTextParagraphs().get(2).getText());\r
@@ -474,16 +476,16 @@ public class TestXSLFTextShape extends TestCase {
         for(int p = 0; p < 5; p++) {\r
             XSLFTextParagraph pr = shape3.getTextParagraphs().get(p);\r
             assertEquals("Calibri", pr.getTextRuns().get(0).getFontFamily());\r
-            assertEquals(18.0, pr.getTextRuns().get(0).getFontSize());\r
+            assertEquals(18.0, pr.getTextRuns().get(0).getFontSize(), 0);\r
         }\r
     }\r
 \r
     void verifySlide8(XSLFSlide slide){\r
         XSLFSlideLayout layout = slide.getSlideLayout();\r
-        XSLFShape[] shapes = slide.getShapes();\r
+        List<XSLFShape> shapes = slide.getShapes();\r
         assertEquals("Content with Caption",layout.getName());\r
 \r
-        XSLFTextShape shape1 = (XSLFTextShape)shapes[0];\r
+        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);\r
         CTPlaceholder ph1 = shape1.getCTPlaceholder();\r
         assertEquals(STPlaceholderType.TITLE, ph1.getType());\r
         // anchor is not defined in the shape\r
@@ -501,10 +503,10 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&\r
                 !bodyPr1.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape1.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape1.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape1.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape1.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.BOTTOM, shape1.getVerticalAlignment());\r
 \r
         // now check text properties\r
@@ -512,11 +514,11 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(20.0, r1.getFontSize());\r
+        assertEquals(20.0, r1.getFontSize(), 0);\r
         assertEquals(Color.black, r1.getFontColor());\r
         assertTrue(r1.isBold());\r
 \r
-        XSLFTextShape shape2 = (XSLFTextShape)shapes[1];\r
+        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
         assertFalse(ph2.isSetType());\r
         assertTrue(ph2.isSetIdx());\r
@@ -535,18 +537,18 @@ public class TestXSLFTextShape extends TestCase {
                 !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&\r
                 !bodyPr2.isSetAnchor()\r
         );\r
-        assertEquals(7.2, shape2.getLeftInset());  // 0.1"\r
-        assertEquals(7.2, shape2.getRightInset()); // 0.1"\r
-        assertEquals(3.6, shape2.getTopInset());  // 0.05"\r
-        assertEquals(3.6, shape2.getBottomInset()); // 0.05"\r
+        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"\r
+        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"\r
+        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"\r
+        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"\r
         assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());\r
 \r
         XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr1.getParentParagraph().getLevel());\r
-        assertEquals("Level 1", pr1.getText());\r
+        assertEquals("Level 1", pr1.getRawText());\r
         assertEquals("Calibri", pr1.getFontFamily());\r
-        assertEquals(32.0, pr1.getFontSize());\r
-        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin());\r
+        assertEquals(32.0, pr1.getFontSize(), 0);\r
+        assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr1.getParentParagraph().getBulletFont());\r
 \r
@@ -554,8 +556,8 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(1, pr2.getParentParagraph().getLevel());\r
         assertEquals("Level 2", pr2.getParentParagraph().getText());\r
         assertEquals("Calibri", pr2.getFontFamily());\r
-        assertEquals(28.0, pr2.getFontSize());\r
-        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin());\r
+        assertEquals(28.0, pr2.getFontSize(), 0);\r
+        assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr2.getParentParagraph().getBulletFont());\r
 \r
@@ -563,8 +565,8 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(2, pr3.getParentParagraph().getLevel());\r
         assertEquals("Level 3", pr3.getParentParagraph().getText());\r
         assertEquals("Calibri", pr3.getFontFamily());\r
-        assertEquals(24.0, pr3.getFontSize());\r
-        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin());\r
+        assertEquals(24.0, pr3.getFontSize(), 0);\r
+        assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr3.getParentParagraph().getBulletFont());\r
 \r
@@ -572,20 +574,20 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(3, pr4.getParentParagraph().getLevel());\r
         assertEquals("Level 4", pr4.getParentParagraph().getText());\r
         assertEquals("Calibri", pr4.getFontFamily());\r
-        assertEquals(20.0, pr4.getFontSize());\r
-        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin());\r
+        assertEquals(20.0, pr4.getFontSize(), 0);\r
+        assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0);\r
         assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter());\r
         assertEquals("Arial", pr4.getParentParagraph().getBulletFont());\r
 \r
-        XSLFTextShape shape3 = (XSLFTextShape)shapes[2];\r
+        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);\r
         assertEquals(VerticalAlignment.TOP, shape3.getVerticalAlignment());\r
         assertEquals("Content with caption", shape3.getText());\r
 \r
         pr1 = shape3.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(0, pr1.getParentParagraph().getLevel());\r
-        assertEquals("Content with caption", pr1.getText());\r
+        assertEquals("Content with caption", pr1.getRawText());\r
         assertEquals("Calibri", pr1.getFontFamily());\r
-        assertEquals(14.0, pr1.getFontSize());\r
+        assertEquals(14.0, pr1.getFontSize(), 0);\r
 \r
     }\r
 \r
@@ -599,7 +601,7 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextRun r1 = footer.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
-        assertEquals(12.0, r1.getFontSize());\r
+        assertEquals(12.0, r1.getFontSize(), 0);\r
         // TODO calculation of tint is incorrect\r
         assertEquals(new Color(64,64,64), r1.getFontColor());\r
 \r
@@ -614,14 +616,14 @@ public class TestXSLFTextShape extends TestCase {
     public void testTitleStyles(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
-        XSLFSlideMaster master = ppt.getSlideMasters()[0];\r
+        XSLFSlideMaster master = ppt.getSlideMasters().get(0);\r
         XSLFTheme theme = master.getTheme();\r
         XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE);\r
         XSLFSlide slide = ppt.createSlide(layout) ;\r
         assertSame(layout, slide.getSlideLayout());\r
         assertSame(master, slide.getSlideMaster());\r
 \r
-        XSLFTextShape titleShape = (XSLFTextShape)slide.getPlaceholder(0);\r
+        XSLFTextShape titleShape = slide.getPlaceholder(0);\r
         titleShape.setText("Apache POI");\r
         XSLFTextParagraph paragraph = titleShape.getTextParagraphs().get(0);\r
         XSLFTextRun textRun = paragraph.getTextRuns().get(0);\r
@@ -631,12 +633,12 @@ public class TestXSLFTextShape extends TestCase {
         CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getTitleStyle().getLvl1PPr();\r
         CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr();\r
         assertEquals(4400, lv1CPr.getSz());\r
-        assertEquals(44.0, textRun.getFontSize());\r
+        assertEquals(44.0, textRun.getFontSize(), 0);\r
         assertEquals("+mj-lt", lv1CPr.getLatin().getTypeface());\r
         assertEquals("Calibri", theme.getMajorFont());\r
         assertEquals("Calibri", textRun.getFontFamily());\r
         lv1CPr.setSz(3200);\r
-        assertEquals(32.0, textRun.getFontSize());\r
+        assertEquals(32.0, textRun.getFontSize(), 0);\r
         lv1CPr.getLatin().setTypeface("Arial");\r
         assertEquals("Arial", textRun.getFontFamily());\r
         assertEquals(STTextAlignType.CTR, lv1PPr.getAlgn());\r
@@ -650,7 +652,7 @@ public class TestXSLFTextShape extends TestCase {
         CTTextParagraphProperties lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
         CTTextCharacterProperties lv2CPr = lv2PPr.addNewDefRPr();\r
         lv2CPr.setSz(3300);\r
-        assertEquals(33.0, textRun.getFontSize());\r
+        assertEquals(33.0, textRun.getFontSize(), 0);\r
         lv2CPr.addNewLatin().setTypeface("Times");\r
         assertEquals("Times", textRun.getFontFamily());\r
         lv2PPr.setAlgn(STTextAlignType.R);\r
@@ -663,7 +665,7 @@ public class TestXSLFTextShape extends TestCase {
         CTTextParagraphProperties lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
         CTTextCharacterProperties lv3CPr = lv3PPr.addNewDefRPr();\r
         lv3CPr.setSz(3400);\r
-        assertEquals(34.0, textRun.getFontSize());\r
+        assertEquals(34.0, textRun.getFontSize(), 0);\r
         lv3CPr.addNewLatin().setTypeface("Courier New");\r
         assertEquals("Courier New", textRun.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.CTR);\r
@@ -674,7 +676,7 @@ public class TestXSLFTextShape extends TestCase {
         CTTextParagraphProperties lv4PPr = titleShape.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
         CTTextCharacterProperties lv4CPr = lv4PPr.addNewDefRPr();\r
         lv4CPr.setSz(3500);\r
-        assertEquals(35.0, textRun.getFontSize());\r
+        assertEquals(35.0, textRun.getFontSize(), 0);\r
         lv4CPr.addNewLatin().setTypeface("Arial");\r
         assertEquals("Arial", textRun.getFontFamily());\r
         lv4PPr.setAlgn(STTextAlignType.L);\r
@@ -684,7 +686,7 @@ public class TestXSLFTextShape extends TestCase {
         CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr();\r
         CTTextCharacterProperties lv5CPr = textRun.getXmlObject().getRPr();\r
         lv5CPr.setSz(3600);\r
-        assertEquals(36.0, textRun.getFontSize());\r
+        assertEquals(36.0, textRun.getFontSize(), 0);\r
         lv5CPr.addNewLatin().setTypeface("Calibri");\r
         assertEquals("Calibri", textRun.getFontFamily());\r
         lv5PPr.setAlgn(STTextAlignType.CTR);\r
@@ -694,14 +696,14 @@ public class TestXSLFTextShape extends TestCase {
     public void testBodyStyles(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
-        XSLFSlideMaster master = ppt.getSlideMasters()[0];\r
+        XSLFSlideMaster master = ppt.getSlideMasters().get(0);\r
         XSLFTheme theme = master.getTheme();\r
         XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT);\r
         XSLFSlide slide = ppt.createSlide(layout) ;\r
         assertSame(layout, slide.getSlideLayout());\r
         assertSame(master, slide.getSlideMaster());\r
 \r
-        XSLFTextShape tx1 = (XSLFTextShape)slide.getPlaceholder(1);\r
+        XSLFTextShape tx1 = slide.getPlaceholder(1);\r
         tx1.clearText();\r
 \r
         XSLFTextParagraph p1 = tx1.addNewTextParagraph();\r
@@ -731,12 +733,12 @@ public class TestXSLFTextShape extends TestCase {
         CTTextCharacterProperties lv3CPr = lv3PPr.getDefRPr();\r
         // lv1\r
         assertEquals(3200, lv1CPr.getSz());\r
-        assertEquals(32.0, r1.getFontSize());\r
+        assertEquals(32.0, r1.getFontSize(), 0);\r
         assertEquals("+mn-lt", lv1CPr.getLatin().getTypeface());\r
         assertEquals("Calibri", theme.getMinorFont());\r
         assertEquals("Calibri", r1.getFontFamily());\r
         lv1CPr.setSz(3300);\r
-        assertEquals(33.0, r1.getFontSize());\r
+        assertEquals(33.0, r1.getFontSize(), 0);\r
         lv1CPr.getLatin().setTypeface("Arial");\r
         assertEquals("Arial", r1.getFontFamily());\r
         assertEquals(STTextAlignType.L, lv1PPr.getAlgn());\r
@@ -745,9 +747,9 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(TextAlign.RIGHT, p1.getTextAlign());\r
         //lv2\r
         assertEquals(2800, lv2CPr.getSz());\r
-        assertEquals(28.0, r2.getFontSize());\r
+        assertEquals(28.0, r2.getFontSize(), 0);\r
         lv2CPr.setSz(3300);\r
-        assertEquals(33.0, r2.getFontSize());\r
+        assertEquals(33.0, r2.getFontSize(), 0);\r
         lv2CPr.getLatin().setTypeface("Times");\r
         assertEquals("Times", r2.getFontFamily());\r
         assertEquals(STTextAlignType.L, lv2PPr.getAlgn());\r
@@ -756,9 +758,9 @@ public class TestXSLFTextShape extends TestCase {
         assertEquals(TextAlign.RIGHT, p2.getTextAlign());\r
         //lv3\r
         assertEquals(2400, lv3CPr.getSz());\r
-        assertEquals(24.0, r3.getFontSize());\r
+        assertEquals(24.0, r3.getFontSize(), 0);\r
         lv3CPr.setSz(2500);\r
-        assertEquals(25.0, r3.getFontSize());\r
+        assertEquals(25.0, r3.getFontSize(), 0);\r
         lv3CPr.getLatin().setTypeface("Courier New");\r
         assertEquals("Courier New", r3.getFontFamily());\r
         assertEquals(STTextAlignType.L, lv3PPr.getAlgn());\r
@@ -780,21 +782,21 @@ public class TestXSLFTextShape extends TestCase {
         lv3CPr = lv3PPr.addNewDefRPr();\r
 \r
         lv1CPr.setSz(3300);\r
-        assertEquals(33.0, r1.getFontSize());\r
+        assertEquals(33.0, r1.getFontSize(), 0);\r
         lv1CPr.addNewLatin().setTypeface("Times");\r
         assertEquals("Times", r1.getFontFamily());\r
         lv1PPr.setAlgn(STTextAlignType.L);\r
         assertEquals(TextAlign.LEFT, p1.getTextAlign());\r
 \r
         lv2CPr.setSz(3300);\r
-        assertEquals(33.0, r2.getFontSize());\r
+        assertEquals(33.0, r2.getFontSize(), 0);\r
         lv2CPr.addNewLatin().setTypeface("Times");\r
         assertEquals("Times", r2.getFontFamily());\r
         lv2PPr.setAlgn(STTextAlignType.L);\r
         assertEquals(TextAlign.LEFT, p2.getTextAlign());\r
 \r
         lv3CPr.setSz(3300);\r
-        assertEquals(33.0, r3.getFontSize());\r
+        assertEquals(33.0, r3.getFontSize(), 0);\r
         lv3CPr.addNewLatin().setTypeface("Times");\r
         assertEquals("Times", r3.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.L);\r
@@ -812,21 +814,21 @@ public class TestXSLFTextShape extends TestCase {
         lv3CPr = lv3PPr.addNewDefRPr();\r
 \r
         lv1CPr.setSz(3400);\r
-        assertEquals(34.0, r1.getFontSize());\r
+        assertEquals(34.0, r1.getFontSize(), 0);\r
         lv1CPr.addNewLatin().setTypeface("Courier New");\r
         assertEquals("Courier New", r1.getFontFamily());\r
         lv1PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, p1.getTextAlign());\r
 \r
         lv2CPr.setSz(3400);\r
-        assertEquals(34.0, r2.getFontSize());\r
+        assertEquals(34.0, r2.getFontSize(), 0);\r
         lv2CPr.addNewLatin().setTypeface("Courier New");\r
         assertEquals("Courier New", r2.getFontFamily());\r
         lv2PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, p2.getTextAlign());\r
 \r
         lv3CPr.setSz(3400);\r
-        assertEquals(34.0, r3.getFontSize());\r
+        assertEquals(34.0, r3.getFontSize(), 0);\r
         lv3CPr.addNewLatin().setTypeface("Courier New");\r
         assertEquals("Courier New", r3.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.CTR);\r
@@ -842,21 +844,21 @@ public class TestXSLFTextShape extends TestCase {
         lv3CPr = lv3PPr.addNewDefRPr();\r
 \r
         lv1CPr.setSz(3500);\r
-        assertEquals(35.0, r1.getFontSize());\r
+        assertEquals(35.0, r1.getFontSize(), 0);\r
         lv1CPr.addNewLatin().setTypeface("Arial");\r
         assertEquals("Arial", r1.getFontFamily());\r
         lv1PPr.setAlgn(STTextAlignType.L);\r
         assertEquals(TextAlign.LEFT, p1.getTextAlign());\r
 \r
         lv2CPr.setSz(3500);\r
-        assertEquals(35.0, r2.getFontSize());\r
+        assertEquals(35.0, r2.getFontSize(), 0);\r
         lv2CPr.addNewLatin().setTypeface("Arial");\r
         assertEquals("Arial", r2.getFontFamily());\r
         lv2PPr.setAlgn(STTextAlignType.L);\r
         assertEquals(TextAlign.LEFT, p2.getTextAlign());\r
 \r
         lv3CPr.setSz(3500);\r
-        assertEquals(35.0, r3.getFontSize());\r
+        assertEquals(35.0, r3.getFontSize(), 0);\r
         lv3CPr.addNewLatin().setTypeface("Arial");\r
         assertEquals("Arial", r3.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.L);\r
@@ -871,21 +873,21 @@ public class TestXSLFTextShape extends TestCase {
         lv3CPr = r3.getXmlObject().getRPr();\r
 \r
         lv1CPr.setSz(3600);\r
-        assertEquals(36.0, r1.getFontSize());\r
+        assertEquals(36.0, r1.getFontSize(), 0);\r
         lv1CPr.addNewLatin().setTypeface("Calibri");\r
         assertEquals("Calibri", r1.getFontFamily());\r
         lv1PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, p1.getTextAlign());\r
 \r
         lv2CPr.setSz(3600);\r
-        assertEquals(36.0, r2.getFontSize());\r
+        assertEquals(36.0, r2.getFontSize(), 0);\r
         lv2CPr.addNewLatin().setTypeface("Calibri");\r
         assertEquals("Calibri", r2.getFontFamily());\r
         lv2PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, p2.getTextAlign());\r
 \r
         lv3CPr.setSz(3600);\r
-        assertEquals(36.0, r3.getFontSize());\r
+        assertEquals(36.0, r3.getFontSize(), 0);\r
         lv3CPr.addNewLatin().setTypeface("Calibri");\r
         assertEquals("Calibri", r3.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.CTR);\r
index 650bfcd0cf24ef8789f7e2c79f4dc2c891280b60..3e85f75c5721e34b8484a415972786db51366782 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import static org.junit.Assert.*;\r
 \r
 import java.awt.Color;\r
-import java.awt.TexturePaint;\r
+import java.util.List;\r
+\r
+import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
 \r
 /**\r
  * test reading properties from a multi-theme and multi-master document\r
  *\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTheme extends TestCase {\r
+public class TestXSLFTheme {\r
+    @Test\r
     public void testRead(){\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("themes.pptx");\r
-        XSLFSlide[] slides = ppt.getSlides();\r
-\r
-        slide1(slides[0]);\r
-        slide2(slides[1]);\r
-        slide3(slides[2]);\r
-        slide4(slides[3]);\r
-        slide5(slides[4]);\r
-        slide6(slides[5]);\r
-        slide7(slides[6]);\r
-        slide8(slides[7]);\r
-        slide9(slides[8]);\r
-        slide10(slides[9]);\r
+        List<XSLFSlide> slides = ppt.getSlides();\r
+\r
+        slide1(slides.get(0));\r
+        slide2(slides.get(1));\r
+        slide3(slides.get(2));\r
+        slide4(slides.get(3));\r
+        slide5(slides.get(4));\r
+        slide6(slides.get(5));\r
+        slide7(slides.get(6));\r
+        slide8(slides.get(7));\r
+        slide9(slides.get(8));\r
+        slide10(slides.get(9));\r
     }\r
 \r
     private XSLFShape getShape(XSLFSheet sheet, String name){\r
@@ -58,11 +65,10 @@ public class TestXSLFTheme extends TestCase {
         assertEquals("Office Theme", theme.getName());\r
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3");\r
-        RenderableShape rsh1 = new RenderableShape(sh1);\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(Color.white, run1.getFontColor());\r
         assertEquals(new Color(79, 129, 189), sh1.getFillColor());\r
-        assertTrue(rsh1.getFillPaint(null) instanceof Color) ;   // solid fill\r
+        assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ;   // solid fill\r
 \r
     }\r
 \r
@@ -73,20 +79,19 @@ public class TestXSLFTheme extends TestCase {
     }\r
 \r
     void slide3(XSLFSlide slide){\r
-        assertNull(slide.getBackground().getFillColor());\r
-        assertTrue(slide.getBackground().getPaint(null).getClass().getName().indexOf("Gradient") > 0);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof GradientPaint);\r
     }\r
 \r
     void slide4(XSLFSlide slide){\r
-        assertNull(slide.getBackground().getFillColor());\r
-        assertTrue(slide.getBackground().getPaint(null).getClass().getName().indexOf("Gradient") > 0);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof GradientPaint);\r
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4");\r
-        RenderableShape rsh1 = new RenderableShape(sh1);\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(Color.white, run1.getFontColor());\r
         assertEquals(new Color(148, 198, 0), sh1.getFillColor());\r
-        assertTrue(rsh1.getFillPaint(null) instanceof Color) ;   // solid fill\r
+        assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ;   // solid fill\r
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
@@ -97,14 +102,15 @@ public class TestXSLFTheme extends TestCase {
     }\r
 \r
     void slide5(XSLFSlide slide){\r
-        assertTrue(slide.getBackground().getPaint(null) instanceof TexturePaint);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof TexturePaint);\r
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals(new Color(148, 198, 0), run2.getFontColor());\r
         assertNull(sh2.getFillColor());  // no fill\r
         // font size is 40pt and scale factor is 90%\r
-        assertEquals(36.0, run2.getFontSize());\r
+        assertEquals(36.0, run2.getFontSize(), 0);\r
 \r
         assertTrue(slide.getSlideLayout().getFollowMasterGraphics());\r
     }\r
@@ -133,15 +139,18 @@ public class TestXSLFTheme extends TestCase {
     }\r
 \r
     void slide8(XSLFSlide slide){\r
-        assertTrue(slide.getBackground().getPaint(null) instanceof TexturePaint);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof TexturePaint);\r
     }\r
 \r
     void slide9(XSLFSlide slide){\r
-        assertTrue(slide.getBackground().getPaint(null) instanceof TexturePaint);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof TexturePaint);\r
     }\r
 \r
     void slide10(XSLFSlide slide){\r
-        assertTrue(slide.getBackground().getPaint(null).getClass().getName().indexOf("Gradient") > 0);\r
+        PaintStyle fs = slide.getBackground().getFillStyle().getPaint();\r
+        assertTrue(fs instanceof GradientPaint);\r
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3");\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
index 6795601a6c436bef1b139306939f18316a4fd7aa..cfeffb800822d23f032a9cb3d8ac11a58600277d 100644 (file)
 package org.apache.poi.hslf.blip;
 
 import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.model.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.POILogFactory;
 
 
 
 
+
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
index 401ac434762459d3f2ae88da54a80f42448f7c06..5eb8149b12ebf470fa3f9418de62e10c55ea8124 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.hslf.model.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 import org.apache.poi.util.LittleEndian;
 
 import java.io.IOException;
@@ -35,7 +35,7 @@ public final class DIB extends Bitmap {
 
     /**
      * @return type of  this picture
-     * @see  org.apache.poi.hslf.model.HSLFPictureShape#DIB
+     * @see  org.apache.poi.hslf.usermodel.HSLFPictureShape#DIB
      */
     public int getType(){
         return HSLFPictureShape.DIB;
index 5fe55f181959868aa5f80eb246b4c0e6c1a9ab19..d7dadb6c5aea17d2f4fabd433217d6a1247c13eb 100644 (file)
@@ -17,8 +17,8 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.hslf.model.HSLFPictureShape;
-import org.apache.poi.hslf.model.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
 import org.apache.poi.hslf.exceptions.HSLFException;
 
 import java.io.ByteArrayOutputStream;
index 0f1afecb9852fc8c1db06055174c05238fc066f8..76359dc3040d2519b6346e7f2deaab96c5a991ad 100644 (file)
@@ -17,8 +17,8 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.hslf.model.HSLFPictureShape;
 import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 
 import java.awt.*;
 
index 567fc996ee94d8b846507a795d8e31e51efac499..08ba5ceb983778359eba08341fa23accdff406be 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.hslf.model.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 
 /**
  * Represents a JPEG picture data in a PPT file
@@ -28,7 +28,7 @@ public final class JPEG extends Bitmap {
 
     /**
      * @return type of  this picture
-     * @see  org.apache.poi.hslf.model.HSLFPictureShape#JPEG
+     * @see  org.apache.poi.hslf.usermodel.HSLFPictureShape#JPEG
      */
     public int getType(){
         return HSLFPictureShape.JPEG;
index 9b2df642625dc57e7aa79e84dda18bf75e2d92c4..016c50f875c1e9281a310d785c14ea8190145404 100644 (file)
@@ -23,8 +23,8 @@ import java.io.IOException;
 import java.util.zip.InflaterInputStream;
 
 import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.model.HSLFPictureShape;
-import org.apache.poi.hslf.model.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
 
 /**
  * Represents Macintosh PICT picture data.
@@ -102,7 +102,7 @@ public final class PICT extends Metafile {
     }
 
     /**
-     * @see org.apache.poi.hslf.model.HSLFPictureShape#PICT
+     * @see org.apache.poi.hslf.usermodel.HSLFPictureShape#PICT
      */
     public int getType(){
         return HSLFPictureShape.PICT;
index a1d9aa50a90c4b12083bf0dd808065a58256638f..114b736bfa71aaaafee07c849c11f2658f2b9efb 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.hslf.model.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 import org.apache.poi.util.PngUtils;
 
 /**
@@ -46,7 +46,7 @@ public final class PNG extends Bitmap {
 
     /**
      * @return type of  this picture
-     * @see  org.apache.poi.hslf.model.HSLFPictureShape#PNG
+     * @see  org.apache.poi.hslf.usermodel.HSLFPictureShape#PNG
      */
     public int getType(){
         return HSLFPictureShape.PNG;
index 3270b3259625e0aa879f1216a5eda84fce7a7243..a84aed2e6fd773fb7e9294381ab9ba50e2a682d2 100644 (file)
@@ -19,8 +19,8 @@ package org.apache.poi.hslf.blip;
 
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
-import org.apache.poi.hslf.model.HSLFPictureShape;
-import org.apache.poi.hslf.model.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
 import org.apache.poi.hslf.exceptions.HSLFException;
 
 import java.io.*;
index e437f9504eac8106d27beb9df0e14fb9a550868b..c26e5cae1efd7df552fcb920e03eac9080f05305 100644 (file)
@@ -18,8 +18,8 @@
 package org.apache.poi.hslf.dev;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 
 /**
index d0ab5ec98fd6fd0f791e43308bda9b52f94a315e..91d6086b1beb3accde01d9f258271ff0ce101586 100644 (file)
 
 package org.apache.poi.hslf.dev;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.Document;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.hslf.record.SlideListWithText;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 /**
  * Uses record level code to Documents.
index fc9b224801fc414c36e75d8e96661ac8e9704960..0f4f5db60be6598d008e45ae6bd96b7e36e38333 100644 (file)
@@ -18,8 +18,8 @@
 package org.apache.poi.hslf.dev;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 /**
  * Uses record level code to locate SlideListWithText entries.
index 2a69c17d81840c1bb6c038ea9e2e654f90f7216c..44c2cd8b4a05f15f221cb8d8a79c2daf02282fa7 100644 (file)
@@ -18,8 +18,8 @@
 package org.apache.poi.hslf.dev;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 
 /**
index b4f487ab8abc3fdea948f88b374394905f4d1632..1398175f42d65404400876d7705af8b2a12f481b 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.poi.hslf.dev;
 import java.io.ByteArrayOutputStream;
 import java.util.Map;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.Document;
 import org.apache.poi.hslf.record.Notes;
 import org.apache.poi.hslf.record.NotesAtom;
@@ -32,6 +31,7 @@ import org.apache.poi.hslf.record.SlideAtom;
 import org.apache.poi.hslf.record.SlideListWithText;
 import org.apache.poi.hslf.record.SlidePersistAtom;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.util.LittleEndian;
 
 /**
index 77415ff2dccc46e67907ab20f8d346baf5c3fa15..45ededed15f9b18dbb3231bd6bb08b53f6176335 100644 (file)
@@ -21,7 +21,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.ddf.DefaultEscherRecordFactory;
@@ -32,6 +31,7 @@ import org.apache.poi.hslf.record.EscherTextboxWrapper;
 import org.apache.poi.hslf.record.TextCharsAtom;
 import org.apache.poi.hslf.record.TextBytesAtom;
 import org.apache.poi.hslf.record.StyleTextPropAtom;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 /**
  * This class provides a way to view the contents of a powerpoint file.
index d7fcbc6fd17045ae5bd2037ca21a245b17102274..14b7706fbdadd6bc6c7dc8b69f1686105b662e06 100644 (file)
 
 package org.apache.poi.hslf.dev;
 
-import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.*;
+import java.util.List;
 
-import java.util.LinkedList;
+import org.apache.poi.hslf.model.textproperties.*;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 /**
  * Uses record level code to locate StyleTextPropAtom entries.
@@ -73,19 +70,19 @@ public final class TextStyleListing {
        public static void showStyleTextPropAtom(StyleTextPropAtom stpa) {
                System.out.println("\nFound a StyleTextPropAtom");
 
-               LinkedList paragraphStyles = stpa.getParagraphStyles();
+               List<TextPropCollection> paragraphStyles = stpa.getParagraphStyles();
                System.out.println("Contains " + paragraphStyles.size() + " paragraph styles:");
                for(int i=0; i<paragraphStyles.size(); i++) {
-                       TextPropCollection tpc = (TextPropCollection)paragraphStyles.get(i);
+                       TextPropCollection tpc = paragraphStyles.get(i);
                        System.out.println(" In paragraph styling " + i + ":");
                        System.out.println("  Characters covered is " + tpc.getCharactersCovered());
                        showTextProps(tpc);
                }
 
-               LinkedList charStyles = stpa.getCharacterStyles();
+               List<TextPropCollection> charStyles = stpa.getCharacterStyles();
                System.out.println("Contains " + charStyles.size() + " character styles:");
                for(int i=0; i<charStyles.size(); i++) {
-                       TextPropCollection tpc = (TextPropCollection)charStyles.get(i);
+                       TextPropCollection tpc = charStyles.get(i);
                        System.out.println("  In character styling " + i + ":");
                        System.out.println("    Characters covered is " + tpc.getCharactersCovered());
                        showTextProps(tpc);
@@ -93,10 +90,10 @@ public final class TextStyleListing {
        }
 
        public static void showTextProps(TextPropCollection tpc) {
-               LinkedList textProps = tpc.getTextPropList();
+               List<TextProp> textProps = tpc.getTextPropList();
                System.out.println("    Contains " + textProps.size() + " TextProps");
                for(int i=0; i<textProps.size(); i++) {
-                       TextProp tp = (TextProp)textProps.get(i);
+                       TextProp tp = textProps.get(i);
                        System.out.println("      " + i + " - " + tp.getName());
                        System.out.println("          = " + tp.getValue());
                        System.out.println("          @ " + tp.getMask());
index c7c8057171902b33d66eba0ad8021db3ac50c6ca..34759eaa6360cb1601f8b313c9c4c1e4e0759f88 100644 (file)
@@ -20,12 +20,12 @@ package org.apache.poi.hslf.dev;
 import java.io.ByteArrayOutputStream;
 import java.util.Map;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.CurrentUserAtom;
 import org.apache.poi.hslf.record.PersistPtrHolder;
 import org.apache.poi.hslf.record.PositionDependentRecord;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.UserEditAtom;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.util.LittleEndian;
 
 /**
index 268eb3b2fb81991a3d99ff950b515d018bfe986d..e90abbbcb106001e01739005ca5b3509542118ea 100644 (file)
 
 package org.apache.poi.hslf.extractor;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.model.HSLFPictureShape;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.*;
 
 import java.io.IOException;
 import java.io.FileOutputStream;
index 621d2b6fcdee914e5b83b4e91486663616b46d46..5dceebf9c5c0bc50a27a4f6a159ea7f68378bb83 100644 (file)
 
 package org.apache.poi.hslf.extractor;
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ArrayList;
+import java.io.*;
+import java.util.*;
 
 import org.apache.poi.POIOLE2TextExtractor;
 import org.apache.poi.hslf.model.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.poifs.filesystem.DirectoryNode;
-import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.poifs.filesystem.*;
 
 /**
  * This class can be used to extract text from a PowerPoint file. Can optionally
@@ -40,7 +34,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 public final class PowerPointExtractor extends POIOLE2TextExtractor {
    private HSLFSlideShowImpl _hslfshow;
    private HSLFSlideShow _show;
-   private HSLFSlide[] _slides;
+   private List<HSLFSlide> _slides;
 
    private boolean _slidesByDefault = true;
    private boolean _notesByDefault = false;
@@ -74,6 +68,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
 
                PowerPointExtractor ppe = new PowerPointExtractor(file);
                System.out.println(ppe.getText(true, notes, comments, master));
+               ppe.close();
        }
 
        /**
@@ -188,13 +183,10 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
        public List<OLEShape> getOLEShapes() {
                List<OLEShape> list = new ArrayList<OLEShape>();
 
-               for (int i = 0; i < _slides.length; i++) {
-                       HSLFSlide slide = _slides[i];
-
-                       HSLFShape[] shapes = slide.getShapes();
-                       for (int j = 0; j < shapes.length; j++) {
-                               if (shapes[j] instanceof OLEShape) {
-                                       list.add((OLEShape) shapes[j]);
+               for (HSLFSlide slide : _slides) {
+                       for (HSLFShape shape : slide.getShapes()) {
+                               if (shape instanceof OLEShape) {
+                                       list.add((OLEShape) shape);
                                }
                        }
                }
@@ -219,7 +211,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
 
                if (getSlideText) {
             if (getMasterText) {
-                for (SlideMaster master : _show.getSlidesMasters()) {
+                for (HSLFSlideMaster master : _show.getSlideMasters()) {
                     for(HSLFShape sh : master.getShapes()){
                         if(sh instanceof HSLFTextShape){
                             if(HSLFMasterSheet.isPlaceholder(sh)) {
@@ -241,8 +233,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
                 }
             }
 
-            for (int i = 0; i < _slides.length; i++) {
-                               HSLFSlide slide = _slides[i];
+            for (int i = 0; i < _slides.size(); i++) {
+                               HSLFSlide slide = _slides.get(i);
 
                                // Slide header, if set
                                HeadersFooters hf = slide.getHeadersFooters();
@@ -251,7 +243,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
                                }
 
                                // Slide text
-                textRunsToText(ret, slide.getTextRuns());
+                textRunsToText(ret, slide.getTextParagraphs());
 
                 // Table text
                 for (HSLFShape shape : slide.getShapes()){
@@ -284,8 +276,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
                        HashSet<Integer> seenNotes = new HashSet<Integer>();
                        HeadersFooters hf = _show.getNotesHeadersFooters();
 
-                       for (int i = 0; i < _slides.length; i++) {
-                               HSLFNotes notes = _slides[i].getNotesSheet();
+                       for (int i = 0; i < _slides.size(); i++) {
+                               HSLFNotes notes = _slides.get(i).getNotes();
                                if (notes == null) {
                                        continue;
                                }
@@ -301,7 +293,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
                                }
 
                                // Notes text
-                textRunsToText(ret, notes.getTextRuns());
+                textRunsToText(ret, notes.getTextParagraphs());
 
                                // Repeat the notes footer, if set
                                if (hf != null && hf.isFooterVisible() && hf.getFooterText() != null) {
@@ -330,17 +322,17 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
             ret.append('\n');
         }
     }
-    private void textRunsToText(StringBuffer ret, HSLFTextParagraph[] runs) {
-        if (runs==null) {
+    private void textRunsToText(StringBuffer ret, List<List<HSLFTextParagraph>> paragraphs) {
+        if (paragraphs==null) {
             return;
         }
 
-        for (int j = 0; j < runs.length; j++) {
-            HSLFTextParagraph run = runs[j];
-            if (run != null) {
-                String text = run.getText();
-                ret.append(text);
-                if (!text.endsWith("\n")) {
+        for (List<HSLFTextParagraph> lp : paragraphs) {
+            for (HSLFTextParagraph p : lp) {
+                for (HSLFTextRun r : p.getTextRuns()) {
+                    ret.append(r.getRawText());
+                }
+                if (ret.length() > 0 && ret.charAt(ret.length()-1) != '\n') {
                     ret.append("\n");
                 }
             }
index 9c92c5c59170cdf123d67e3606bab7d2b567d34e..260eebd60ff8013644ef43e8dd8fcab6c845f8e1 100644 (file)
 
 package org.apache.poi.hslf.extractor;
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.poi.hslf.model.HSLFTextParagraph;
-import org.apache.poi.hslf.record.CString;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.StyleTextPropAtom;
-import org.apache.poi.hslf.record.TextBytesAtom;
-import org.apache.poi.hslf.record.TextCharsAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
+import org.apache.poi.hslf.usermodel.HSLFTextShape;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
@@ -174,18 +167,19 @@ public final class QuickButCruddyTextExtractor {
                }
 
                // Otherwise, check the type to see if it's text
-               long type = LittleEndian.getUShort(pptContents,startPos+2);
-               HSLFTextParagraph trun = null;
+               int type = LittleEndian.getUShort(pptContents,startPos+2);
 
                // TextBytesAtom
                if(type == RecordTypes.TextBytesAtom.typeID) {
                        TextBytesAtom tba = (TextBytesAtom)Record.createRecordForType(type, pptContents, startPos, len+8);
-                       trun = new HSLFTextParagraph((TextHeaderAtom)null,tba,(StyleTextPropAtom)null);
+                       String text = HSLFTextParagraph.toExternalString(tba.getText(), -1);
+                       textV.add(text);
                }
                // TextCharsAtom
                if(type == RecordTypes.TextCharsAtom.typeID) {
                        TextCharsAtom tca = (TextCharsAtom)Record.createRecordForType(type, pptContents, startPos, len+8);
-                       trun = new HSLFTextParagraph((TextHeaderAtom)null,tca,(StyleTextPropAtom)null);
+            String text = HSLFTextParagraph.toExternalString(tca.getText(), -1);
+            textV.add(text);
                }
 
                // CString (doesn't go via a TextRun)
@@ -201,10 +195,6 @@ public final class QuickButCruddyTextExtractor {
                        }
                }
 
-               // If we found text via a TextRun, save it in the vector
-               if(trun != null) {
-                       textV.add(trun.getText());
-               }
 
                // Wind on by the atom length, and check we're not at the end
                int newPos = (startPos + 8 + len);
index 95f83a38349c8ab8fb04f6bc72135410beca2900..567b8297e08bd68dc697cb45b2ecd654858874ee 100644 (file)
@@ -34,6 +34,7 @@ import org.apache.poi.hslf.record.ExObjList;
 import org.apache.poi.hslf.record.OEShapeAtom;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.apache.poi.util.LittleEndian;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java
deleted file mode 100644 (file)
index 0afc710..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/* ====================================================================
-   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.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
-
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.sl.usermodel.ShapeType;
-
-/**
- * Stores definition of auto-shapes.
- * See the Office Drawing 97-2007 Binary Format Specification for details.
- *
- * TODO: follow the spec and define all the auto-shapes
- *
- * @author Yegor Kozlov
- */
-public final class AutoShapes {
-       protected static final ShapeOutline[] shapes;
-
-
-    /**
-     * Return shape outline by shape type
-     * @param type shape type see {@link ShapeTypes}
-     *
-     * @return the shape outline
-     */
-    public static ShapeOutline getShapeOutline(ShapeType type){
-        ShapeOutline outline = shapes[type.nativeId];
-        return outline;
-    }
-
-    /**
-     * Auto-shapes are defined in the [0,21600] coordinate system.
-     * We need to transform it into normal slide coordinates
-     *
-    */
-    public static java.awt.Shape transform(java.awt.Shape outline, Rectangle2D anchor){
-        AffineTransform at = new AffineTransform();
-        at.translate(anchor.getX(), anchor.getY());
-        at.scale(
-                1.0f/21600*anchor.getWidth(),
-                1.0f/21600*anchor.getHeight()
-        );
-        return at.createTransformedShape(outline);
-    }
-
-    static {
-        shapes = new ShapeOutline[255];
-
-        shapes[ShapeType.RECT.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                Rectangle2D path = new Rectangle2D.Float(0, 0, 21600, 21600);
-                return path;
-            }
-        };
-
-        shapes[ShapeType.ROUND_RECT.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-                RoundRectangle2D path = new RoundRectangle2D.Float(0, 0, 21600, 21600, adjval, adjval);
-                return path;
-            }
-        };
-
-        shapes[ShapeType.ELLIPSE.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                Ellipse2D path = new Ellipse2D.Float(0, 0, 21600, 21600);
-                return path;
-            }
-        };
-
-        shapes[ShapeType.DIAMOND.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                GeneralPath path = new GeneralPath();
-                path.moveTo(10800, 0);
-                path.lineTo(21600, 10800);
-                path.lineTo(10800, 21600);
-                path.lineTo(0, 10800);
-                path.closePath();
-                return path;
-           }
-        };
-
-        //m@0,l,21600r21600
-        shapes[ShapeType.TRIANGLE.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 10800);
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(0, 21600);
-                path.lineTo(21600, 21600);
-                path.closePath();
-                return path;
-           }
-        };
-
-        shapes[ShapeType.RT_TRIANGLE.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                GeneralPath path = new GeneralPath();
-                path.moveTo(0, 0);
-                path.lineTo(21600, 21600);
-                path.lineTo(0, 21600);
-                path.closePath();
-                return path;
-           }
-        };
-
-        shapes[ShapeType.PARALLELOGRAM.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(21600, 0);
-                path.lineTo(21600 - adjval, 21600);
-                path.lineTo(0, 21600);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.TRAPEZOID.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(0, 0);
-                path.lineTo(adjval, 21600);
-                path.lineTo(21600 - adjval, 21600);
-                path.lineTo(21600, 0);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.HEXAGON.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(21600 - adjval, 0);
-                path.lineTo(21600, 10800);
-                path.lineTo(21600 - adjval, 21600);
-                path.lineTo(adjval, 21600);
-                path.lineTo(0, 10800);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.OCTAGON.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 6326);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(21600 - adjval, 0);
-                path.lineTo(21600, adjval);
-                path.lineTo(21600, 21600-adjval);
-                path.lineTo(21600-adjval, 21600);
-                path.lineTo(adjval, 21600);
-                path.lineTo(0, 21600-adjval);
-                path.lineTo(0, adjval);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.PLUS.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(21600 - adjval, 0);
-                path.lineTo(21600 - adjval, adjval);
-                path.lineTo(21600, adjval);
-                path.lineTo(21600, 21600-adjval);
-                path.lineTo(21600-adjval, 21600-adjval);
-                path.lineTo(21600-adjval, 21600);
-                path.lineTo(adjval, 21600);
-                path.lineTo(adjval, 21600-adjval);
-                path.lineTo(0, 21600-adjval);
-                path.lineTo(0, adjval);
-                path.lineTo(adjval, adjval);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.PENTAGON.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(10800, 0);
-                path.lineTo(21600, 8259);
-                path.lineTo(21600 - 4200, 21600);
-                path.lineTo(4200, 21600);
-                path.lineTo(0, 8259);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.DOWN_ARROW.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m0@0 l@1@0 @1,0 @2,0 @2@0,21600@0,10800,21600xe
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 16200);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
-                GeneralPath path = new GeneralPath();
-                path.moveTo(0, adjval);
-                path.lineTo(adjval2, adjval);
-                path.lineTo(adjval2, 0);
-                path.lineTo(21600-adjval2, 0);
-                path.lineTo(21600-adjval2, adjval);
-                path.lineTo(21600, adjval);
-                path.lineTo(10800, 21600);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.UP_ARROW.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m0@0 l@1@0 @1,21600@2,21600@2@0,21600@0,10800,xe
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
-                GeneralPath path = new GeneralPath();
-                path.moveTo(0, adjval);
-                path.lineTo(adjval2, adjval);
-                path.lineTo(adjval2, 21600);
-                path.lineTo(21600-adjval2, 21600);
-                path.lineTo(21600-adjval2, adjval);
-                path.lineTo(21600, adjval);
-                path.lineTo(10800, 0);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.RIGHT_ARROW.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m@0, l@0@1 ,0@1,0@2@0@2@0,21600,21600,10800xe
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 16200);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(adjval, adjval2);
-                path.lineTo(0, adjval2);
-                path.lineTo(0, 21600-adjval2);
-                path.lineTo(adjval, 21600-adjval2);
-                path.lineTo(adjval, 21600);
-                path.lineTo(21600, 10800);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.LEFT_ARROW.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m@0, l@0@1,21600@1,21600@2@0@2@0,21600,,10800xe
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
-                GeneralPath path = new GeneralPath();
-                path.moveTo(adjval, 0);
-                path.lineTo(adjval, adjval2);
-                path.lineTo(21600, adjval2);
-                path.lineTo(21600, 21600-adjval2);
-                path.lineTo(adjval, 21600-adjval2);
-                path.lineTo(adjval, 21600);
-                path.lineTo(0, 10800);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.CAN.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m10800,qx0@1l0@2qy10800,21600,21600@2l21600@1qy10800,xem0@1qy10800@0,21600@1nfe
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
-
-                GeneralPath path = new GeneralPath();
-
-                path.append(new Arc2D.Float(0, 0, 21600, adjval, 0, 180, Arc2D.OPEN), false);
-                path.moveTo(0, adjval/2);
-
-                path.lineTo(0, 21600 - adjval/2);
-                path.closePath();
-
-                path.append(new Arc2D.Float(0, 21600 - adjval, 21600, adjval, 180, 180, Arc2D.OPEN), false);
-                path.moveTo(21600, 21600 - adjval/2);
-
-                path.lineTo(21600, adjval/2);
-                path.append(new Arc2D.Float(0, 0, 21600, adjval, 180, 180, Arc2D.OPEN), false);
-                path.moveTo(0, adjval/2);
-                path.closePath();
-                return path;
-            }
-        };
-
-        shapes[ShapeType.LEFT_BRACE.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m21600,qx10800@0l10800@2qy0@11,10800@3l10800@1qy21600,21600e
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(21600, 0);
-
-                path.append(new Arc2D.Float(10800, 0, 21600, adjval*2, 90, 90, Arc2D.OPEN), false);
-                path.moveTo(10800, adjval);
-
-                path.lineTo(10800, adjval2 - adjval);
-
-                path.append(new Arc2D.Float(-10800, adjval2 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false);
-                path.moveTo(0, adjval2);
-
-                path.append(new Arc2D.Float(-10800, adjval2, 21600, adjval*2, 0, 90, Arc2D.OPEN), false);
-                path.moveTo(10800, adjval2 + adjval);
-
-                path.lineTo(10800, 21600 - adjval);
-
-                path.append(new Arc2D.Float(10800, 21600 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false);
-
-                return path;
-            }
-        };
-
-        shapes[ShapeType.RIGHT_BRACE.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                //m,qx10800@0 l10800@2qy21600@11,10800@3l10800@1qy,21600e
-                int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
-                int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
-
-                GeneralPath path = new GeneralPath();
-                path.moveTo(0, 0);
-
-                path.append(new Arc2D.Float(-10800, 0, 21600, adjval*2, 0, 90, Arc2D.OPEN), false);
-                path.moveTo(10800, adjval);
-
-                path.lineTo(10800, adjval2 - adjval);
-
-                path.append(new Arc2D.Float(10800, adjval2 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false);
-                path.moveTo(21600, adjval2);
-
-                path.append(new Arc2D.Float(10800, adjval2, 21600, adjval*2, 90, 90, Arc2D.OPEN), false);
-                path.moveTo(10800, adjval2 + adjval);
-
-                path.lineTo(10800, 21600 - adjval);
-
-                path.append(new Arc2D.Float(-10800, 21600 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false);
-
-                return path;
-            }
-        };
-
-        shapes[ShapeType.STRAIGHT_CONNECTOR_1.nativeId] = new ShapeOutline(){
-            public java.awt.Shape getOutline(HSLFShape shape){
-                return new Line2D.Float(0, 0, 21600, 21600);
-            }
-        };
-
-
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFAutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFAutoShape.java
deleted file mode 100644 (file)
index 1f74f2c..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.ddf.*;
-import org.apache.poi.sl.draw.geom.CustomGeometry;
-import org.apache.poi.sl.draw.geom.Guide;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.util.POILogger;
-
-import java.awt.geom.Rectangle2D;
-import java.util.Iterator;
-
-/**
- * Represents an AutoShape.
- * <p>
- * AutoShapes are drawing objects with a particular shape that may be customized through smart resizing and adjustments.
- * See {@link ShapeTypes}
- * </p>
- *
- *  @author Yegor Kozlov
- */
-public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFTextParagraph> {
-
-    protected HSLFAutoShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-    }
-
-    public HSLFAutoShape(ShapeType type, ShapeContainer<HSLFShape> parent){
-        super(null, parent);
-        _escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape);
-    }
-
-    public HSLFAutoShape(ShapeType type){
-        this(type, null);
-    }
-
-    protected EscherContainerRecord createSpContainer(ShapeType shapeType, boolean isChild){
-        _escherContainer = super.createSpContainer(isChild);
-
-        setShapeType(shapeType);
-
-        //set default properties for an autoshape
-        setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);
-        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
-        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
-        setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
-        setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010);
-        setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001);
-        setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008);
-        setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
-
-        return _escherContainer;
-    }
-
-    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
-        setVerticalAlignment(HSLFTextBox.AnchorMiddle);
-        setHorizontalAlignment(HSLFTextBox.AlignCenter);
-        setWordWrap(HSLFTextBox.WrapNone);
-    }
-
-    /**
-     * Gets adjust value which controls smart resizing of the auto-shape.
-     *
-     * <p>
-     * The adjustment values are given in shape coordinates:
-     * the origin is at the top-left, positive-x is to the right, positive-y is down.
-     * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
-     * </p>
-     *
-     * @param idx the adjust index in the [0, 9] range
-     * @return the adjustment value
-     */
-    public int getAdjustmentValue(int idx){
-        if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range");
-
-        return getEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx));
-    }
-
-    /**
-     * Sets adjust value which controls smart resizing of the auto-shape.
-     *
-     * <p>
-     * The adjustment values are given in shape coordinates:
-     * the origin is at the top-left, positive-x is to the right, positive-y is down.
-     * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
-     * </p>
-     *
-     * @param idx the adjust index in the [0, 9] range
-     * @param val the adjustment value
-     */
-    public void setAdjustmentValue(int idx, int val){
-        if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range");
-
-        setEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx), val);
-    }
-
-    public java.awt.Shape getOutline(){
-        ShapeOutline outline = AutoShapes.getShapeOutline(getShapeType());
-        Rectangle2D anchor = getLogicalAnchor2D();
-        if(outline == null){
-            logger.log(POILogger.WARN, "Outline not found for " + getShapeType().nativeName);
-            return anchor;
-        }
-        java.awt.Shape shape = outline.getOutline(this);
-        return AutoShapes.transform(shape, anchor);
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFBackground.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFBackground.java
deleted file mode 100644 (file)
index 8d581f5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.sl.usermodel.Background;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-
-/**
- * Background shape
- *
- * @author Yegor Kozlov
- */
-public final class HSLFBackground extends HSLFShape implements Background {
-
-    protected HSLFBackground(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
-        super(escherRecord, parent);
-    }
-
-    protected EscherContainerRecord createSpContainer(boolean isChild) {
-        return null;
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFFill.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFFill.java
deleted file mode 100644 (file)
index 14846e1..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/* ====================================================================
-   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.awt.Color;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.List;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.Document;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
-import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint.
- *
- * @author Yegor Kozlov
- */
-public final class HSLFFill {
-    // For logging
-    protected POILogger logger = POILogFactory.getLogger(this.getClass());
-
-    /**
-     *  Fill with a solid color
-     */
-    public static final int FILL_SOLID = 0;
-
-    /**
-     *  Fill with a pattern (bitmap)
-     */
-    public static final int FILL_PATTERN = 1;
-
-    /**
-     *  A texture (pattern with its own color map)
-     */
-    public static final int FILL_TEXTURE = 2;
-
-    /**
-     *  Center a picture in the shape
-     */
-    public static final int FILL_PICTURE = 3;
-
-    /**
-     *  Shade from start to end points
-     */
-    public static final int FILL_SHADE = 4;
-
-    /**
-     *  Shade from bounding rectangle to end point
-     */
-    public static final int FILL_SHADE_CENTER = 5;
-
-    /**
-     *  Shade from shape outline to end point
-     */
-    public static final int FILL_SHADE_SHAPE = 6;
-
-    /**
-     *  Similar to FILL_SHADE, but the fill angle
-     *  is additionally scaled by the aspect ratio of
-     *  the shape. If shape is square, it is the same as FILL_SHADE
-     */
-    public static final int FILL_SHADE_SCALE = 7;
-
-    /**
-     *  shade to title
-     */
-    public static final int FILL_SHADE_TITLE = 8;
-
-    /**
-     *  Use the background fill color/pattern
-     */
-    public static final int FILL_BACKGROUND = 9;
-
-
-
-    /**
-     * The shape this background applies to
-     */
-    protected HSLFShape shape;
-
-    /**
-     * Construct a <code>Fill</code> object for a shape.
-     * Fill information will be read from shape's escher properties.
-     *
-     * @param shape the shape this background applies to
-     */
-    public HSLFFill(HSLFShape shape){
-        this.shape = shape;
-    }
-
-
-    public FillStyle getFillStyle() {
-        return new FillStyle() {
-            public PaintStyle getPaint() {
-                switch (getFillType()) {
-                    case FILL_SOLID: {
-                        return new SolidPaint() {
-                            public ColorStyle getSolidColor() {
-                                return new ColorStyle() {
-                                    public Color getColor() { return getForegroundColor(); }
-                                    public int getAlpha() { return -1; }
-                                    public int getLumOff() { return -1; }
-                                    public int getLumMod() { return -1; }
-                                    public int getShade()  { return -1; }
-                                    public int getTint()  { return -1; }
-                                };
-                            }
-                        };
-                    }
-                    case FILL_PICTURE: {
-                        return new TexturePaint() {
-                            final HSLFPictureData pd = getPictureData();
-                            
-                            public InputStream getImageData() {
-                                return new ByteArrayInputStream(pd.getData());
-                            }
-
-                            public String getContentType() {
-                                return pd.getContentType();
-                            }
-
-                            public int getAlpha() {
-                                return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0);
-                            }
-                        };
-                    }
-                    default:
-                        logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
-                        break;
-                }
-                return PaintStyle.TRANSPARENT_PAINT;
-            }
-        };
-    }
-    
-    /**
-     * Returns fill type.
-     * Must be one of the <code>FILL_*</code> constants defined in this class.
-     *
-     * @return type of fill
-     */
-    public int getFillType(){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        EscherSimpleProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE);
-        return prop == null ? FILL_SOLID : prop.getPropertyValue();
-    }
-
-    /**
-     */
-    protected void afterInsert(HSLFSheet sh){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
-        if(p != null) {
-            int idx = p.getPropertyValue();
-            EscherBSERecord bse = getEscherBSERecord(idx);
-            bse.setRef(bse.getRef() + 1);
-        }
-    }
-
-    protected EscherBSERecord getEscherBSERecord(int idx){
-        HSLFSheet sheet = shape.getSheet();
-        if(sheet == null) {
-            logger.log(POILogger.DEBUG, "Fill has not yet been assigned to a sheet");
-            return null;
-        }
-        HSLFSlideShow ppt = sheet.getSlideShow();
-        Document doc = ppt.getDocumentRecord();
-        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
-        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
-        if(bstore == null) {
-            logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
-            return null;
-        }
-        List<EscherRecord> lst = bstore.getChildRecords();
-        return (EscherBSERecord)lst.get(idx-1);
-    }
-
-    /**
-     * Sets fill type.
-     * Must be one of the <code>FILL_*</code> constants defined in this class.
-     *
-     * @param type type of the fill
-     */
-    public void setFillType(int type){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type);
-    }
-
-    /**
-     * Foreground color
-     */
-    public Color getForegroundColor(){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
-
-        if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
-
-        return shape.getColor(EscherProperties.FILL__FILLCOLOR, EscherProperties.FILL__FILLOPACITY, -1);
-
-    }
-
-    /**
-     * Foreground color
-     */
-    public void setForegroundColor(Color color){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        if (color == null) {
-            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
-        }
-        else {
-            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
-            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
-            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
-        }
-    }
-
-    /**
-     * Background color
-     */
-    public Color getBackgroundColor(){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
-
-        if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
-
-        return shape.getColor(EscherProperties.FILL__FILLBACKCOLOR, EscherProperties.FILL__FILLOPACITY, -1);
-    }
-
-    /**
-     * Background color
-     */
-    public void setBackgroundColor(Color color){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        if (color == null) {
-            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1);
-        }
-        else {
-            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
-            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb);
-        }
-    }
-
-    /**
-     * <code>PictureData</code> object used in a texture, pattern of picture fill.
-     */
-    public HSLFPictureData getPictureData(){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
-        if (p == null) return null;
-
-        HSLFSlideShow ppt = shape.getSheet().getSlideShow();
-        HSLFPictureData[] pict = ppt.getPictureData();
-        Document doc = ppt.getDocumentRecord();
-
-        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
-        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
-
-        java.util.List<EscherRecord> lst = bstore.getChildRecords();
-        int idx = p.getPropertyValue();
-        if (idx == 0){
-            logger.log(POILogger.WARN, "no reference to picture data found ");
-        } else {
-            EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1);
-            for ( int i = 0; i < pict.length; i++ ) {
-                if (pict[i].getOffset() ==  bse.getOffset()){
-                    return pict[i];
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Assign picture used to fill the underlying shape.
-     *
-     * @param idx 0-based index of the picture added to this ppt by <code>SlideShow.addPicture</code> method.
-     */
-    public void setPictureData(int idx){
-        EscherOptRecord opt = shape.getEscherOptRecord();
-        HSLFShape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx);
-        if( idx != 0 ) {
-            if( shape.getSheet() != null ) {
-                EscherBSERecord bse = getEscherBSERecord(idx);
-                bse.setRef(bse.getRef() + 1);
-            }
-        }
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFFreeformShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFFreeformShape.java
deleted file mode 100644 (file)
index 685e2da..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/* ====================================================================
-   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.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.poi.ddf.EscherArrayProperty;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
-
-/**
- * A "Freeform" shape.
- *
- * <p>
- * Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections
- * and straight-line segments in the straight sections. This object closely corresponds to <code>java.awt.geom.GeneralPath</code>.
- * </p>
- * @author Yegor Kozlov
- */
-public final class HSLFFreeformShape extends HSLFAutoShape {
-
-    public static final byte[] SEGMENTINFO_MOVETO   = new byte[]{0x00, 0x40};
-    public static final byte[] SEGMENTINFO_LINETO   = new byte[]{0x00, (byte)0xAC};
-    public static final byte[] SEGMENTINFO_ESCAPE   = new byte[]{0x01, 0x00};
-    public static final byte[] SEGMENTINFO_ESCAPE2  = new byte[]{0x01, 0x20};
-    public static final byte[] SEGMENTINFO_CUBICTO  = new byte[]{0x00, (byte)0xAD};
-    public static final byte[] SEGMENTINFO_CUBICTO2 = new byte[]{0x00, (byte)0xB3}; //OpenOffice inserts 0xB3 instead of 0xAD.
-    public static final byte[] SEGMENTINFO_CLOSE    = new byte[]{0x01, (byte)0x60};
-    public static final byte[] SEGMENTINFO_END      = new byte[]{0x00, (byte)0x80};
-
-    /**
-     * Create a Freeform object and initialize it from the supplied Record container.
-     *
-     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
-     * @param parent    the parent of the shape
-     */
-   protected HSLFFreeformShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-
-    }
-
-    /**
-     * Create a new Freeform. This constructor is used when a new shape is created.
-     *
-     * @param parent    the parent of this Shape. For example, if this text box is a cell
-     * in a table then the parent is Table.
-     */
-    public HSLFFreeformShape(ShapeContainer<HSLFShape> parent){
-        super((EscherContainerRecord)null, parent);
-        _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
-    }
-
-    /**
-     * Create a new Freeform. This constructor is used when a new shape is created.
-     *
-     */
-    public HSLFFreeformShape(){
-        this(null);
-    }
-
-    /**
-     * Set the shape path
-     *
-     * @param path
-     */
-    public void setPath(GeneralPath path)
-    {
-        Rectangle2D bounds = path.getBounds2D();
-        PathIterator it = path.getPathIterator(new AffineTransform());
-
-        List<byte[]> segInfo = new ArrayList<byte[]>();
-        List<Point2D.Double> pntInfo = new ArrayList<Point2D.Double>();
-        boolean isClosed = false;
-        while (!it.isDone()) {
-            double[] vals = new double[6];
-            int type = it.currentSegment(vals);
-            switch (type) {
-                case PathIterator.SEG_MOVETO:
-                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
-                    segInfo.add(SEGMENTINFO_MOVETO);
-                    break;
-                case PathIterator.SEG_LINETO:
-                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
-                    segInfo.add(SEGMENTINFO_LINETO);
-                    segInfo.add(SEGMENTINFO_ESCAPE);
-                    break;
-                case PathIterator.SEG_CUBICTO:
-                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
-                    pntInfo.add(new Point2D.Double(vals[2], vals[3]));
-                    pntInfo.add(new Point2D.Double(vals[4], vals[5]));
-                    segInfo.add(SEGMENTINFO_CUBICTO);
-                    segInfo.add(SEGMENTINFO_ESCAPE2);
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    //TODO: figure out how to convert SEG_QUADTO into SEG_CUBICTO
-                    logger.log(POILogger.WARN, "SEG_QUADTO is not supported");
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    pntInfo.add(pntInfo.get(0));
-                    segInfo.add(SEGMENTINFO_LINETO);
-                    segInfo.add(SEGMENTINFO_ESCAPE);
-                    segInfo.add(SEGMENTINFO_LINETO);
-                    segInfo.add(SEGMENTINFO_CLOSE);
-                    isClosed = true;
-                    break;
-            }
-
-            it.next();
-        }
-        if(!isClosed) segInfo.add(SEGMENTINFO_LINETO);
-        segInfo.add(new byte[]{0x00, (byte)0x80});
-
-        EscherOptRecord opt = getEscherOptRecord();
-        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
-
-        EscherArrayProperty verticesProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__VERTICES + 0x4000), false, null);
-        verticesProp.setNumberOfElementsInArray(pntInfo.size());
-        verticesProp.setNumberOfElementsInMemory(pntInfo.size());
-        verticesProp.setSizeOfElements(0xFFF0);
-        for (int i = 0; i < pntInfo.size(); i++) {
-            Point2D.Double pnt = pntInfo.get(i);
-            byte[] data = new byte[4];
-            LittleEndian.putShort(data, 0, (short)((pnt.getX() - bounds.getX())*MASTER_DPI/POINT_DPI));
-            LittleEndian.putShort(data, 2, (short)((pnt.getY() - bounds.getY())*MASTER_DPI/POINT_DPI));
-            verticesProp.setElement(i, data);
-        }
-        opt.addEscherProperty(verticesProp);
-
-        EscherArrayProperty segmentsProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000), false, null);
-        segmentsProp.setNumberOfElementsInArray(segInfo.size());
-        segmentsProp.setNumberOfElementsInMemory(segInfo.size());
-        segmentsProp.setSizeOfElements(0x2);
-        for (int i = 0; i < segInfo.size(); i++) {
-            byte[] seg = segInfo.get(i);
-            segmentsProp.setElement(i, seg);
-        }
-        opt.addEscherProperty(segmentsProp);
-
-        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, (int)(bounds.getWidth()*MASTER_DPI/POINT_DPI)));
-        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, (int)(bounds.getHeight()*MASTER_DPI/POINT_DPI)));
-
-        opt.sortProperties();
-
-        setAnchor(bounds);
-    }
-
-    /**
-     * Gets the freeform path
-     *
-     * @return the freeform path
-     */
-     public GeneralPath getPath(){
-        EscherOptRecord opt = getEscherOptRecord();
-        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
-
-        EscherArrayProperty verticesProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__VERTICES + 0x4000));
-        if(verticesProp == null) verticesProp = getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
-
-        EscherArrayProperty segmentsProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000));
-        if(segmentsProp == null) segmentsProp = getEscherProperty(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
-
-        //sanity check
-        if(verticesProp == null) {
-            logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__VERTICES ");
-            return null;
-        }
-        if(segmentsProp == null) {
-            logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__SEGMENTINFO ");
-            return null;
-        }
-
-        GeneralPath path = new GeneralPath();
-        int numPoints = verticesProp.getNumberOfElementsInArray();
-        int numSegments = segmentsProp.getNumberOfElementsInArray();
-        for (int i = 0, j = 0; i < numSegments && j < numPoints; i++) {
-            byte[] elem = segmentsProp.getElement(i);
-            if(Arrays.equals(elem, SEGMENTINFO_MOVETO)){
-                byte[] p = verticesProp.getElement(j++);
-                short x = LittleEndian.getShort(p, 0);
-                short y = LittleEndian.getShort(p, 2);
-                path.moveTo(
-                        ((float)x*POINT_DPI/MASTER_DPI),
-                        ((float)y*POINT_DPI/MASTER_DPI));
-            } else if (Arrays.equals(elem, SEGMENTINFO_CUBICTO) || Arrays.equals(elem, SEGMENTINFO_CUBICTO2)){
-                i++;
-                byte[] p1 = verticesProp.getElement(j++);
-                short x1 = LittleEndian.getShort(p1, 0);
-                short y1 = LittleEndian.getShort(p1, 2);
-                byte[] p2 = verticesProp.getElement(j++);
-                short x2 = LittleEndian.getShort(p2, 0);
-                short y2 = LittleEndian.getShort(p2, 2);
-                byte[] p3 = verticesProp.getElement(j++);
-                short x3 = LittleEndian.getShort(p3, 0);
-                short y3 = LittleEndian.getShort(p3, 2);
-                path.curveTo(
-                        ((float)x1*POINT_DPI/MASTER_DPI), ((float)y1*POINT_DPI/MASTER_DPI),
-                        ((float)x2*POINT_DPI/MASTER_DPI), ((float)y2*POINT_DPI/MASTER_DPI),
-                        ((float)x3*POINT_DPI/MASTER_DPI), ((float)y3*POINT_DPI/MASTER_DPI));
-
-            } else if (Arrays.equals(elem, SEGMENTINFO_LINETO)){
-                i++;
-                byte[] pnext = segmentsProp.getElement(i);
-                if(Arrays.equals(pnext, SEGMENTINFO_ESCAPE)){
-                    if(j + 1 < numPoints){
-                        byte[] p = verticesProp.getElement(j++);
-                        short x = LittleEndian.getShort(p, 0);
-                        short y = LittleEndian.getShort(p, 2);
-                        path.lineTo(
-                                ((float)x*POINT_DPI/MASTER_DPI), ((float)y*POINT_DPI/MASTER_DPI));
-                    }
-                } else if (Arrays.equals(pnext, SEGMENTINFO_CLOSE)){
-                    path.closePath();
-                }
-            }
-        }
-        return path;
-    }
-
-    public java.awt.Shape getOutline(){
-        GeneralPath path =  getPath();
-        if(path == null) {
-            // return empty path if either GEOMETRY__VERTICES or GEOMETRY__SEGMENTINFO is missing, see Bugzilla 54188
-            return new GeneralPath();
-        }
-
-        Rectangle2D anchor = getAnchor2D();
-        Rectangle2D bounds = path.getBounds2D();
-        AffineTransform at = new AffineTransform();
-        at.translate(anchor.getX(), anchor.getY());
-        at.scale(
-                anchor.getWidth()/bounds.getWidth(),
-                anchor.getHeight()/bounds.getHeight()
-        );
-        return at.createTransformedShape(path);
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java
deleted file mode 100644 (file)
index 64d4de2..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/* ====================================================================
-   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.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.poi.ddf.EscherChildAnchorRecord;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.ddf.EscherSpgrRecord;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
-
-/**
- *  Represents a group of shapes.
- *
- * @author Yegor Kozlov
- */
-public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShape> {
-
-    /**
-      * Create a new ShapeGroup. This constructor is used when a new shape is created.
-      *
-      */
-    public HSLFGroupShape(){
-        this(null, null);
-        _escherContainer = createSpContainer(false);
-    }
-
-    /**
-      * Create a ShapeGroup object and initilize it from the supplied Record container.
-      *
-      * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
-      * @param parent    the parent of the shape
-      */
-    protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-    }
-
-    /**
-     * @return the shapes contained in this group container
-     */
-    public HSLFShape[] getShapes() {
-        List<HSLFShape> shapeList = getShapeList();
-        HSLFShape[] shapes = shapeList.toArray(new HSLFShape[shapeList.size()]);
-        return shapes;
-    }
-
-    /**
-     * Sets the anchor (the bounding box rectangle) of this shape.
-     * All coordinates should be expressed in Master units (576 dpi).
-     *
-     * @param anchor new anchor
-     */
-    public void setAnchor(java.awt.Rectangle anchor){
-
-        EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
-        //hack. internal variable EscherClientAnchorRecord.shortRecord can be
-        //initialized only in fillFields(). We need to set shortRecord=false;
-        byte[] header = new byte[16];
-        LittleEndian.putUShort(header, 0, 0);
-        LittleEndian.putUShort(header, 2, 0);
-        LittleEndian.putInt(header, 4, 8);
-        clientAnchor.fillFields(header, 0, null);
-
-        clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
-        clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
-        clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
-        clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
-
-        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
-        spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI);
-        spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI);
-        spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI);
-        spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
-    }
-
-    /**
-     * Sets the coordinate space of this group.  All children are constrained
-     * to these coordinates.
-     *
-     * @param anchor the coordinate space of this group
-     */
-    public void setCoordinates(Rectangle2D anchor){
-        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
-        int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
-        int y1 = (int)Math.round(anchor.getY()*MASTER_DPI/POINT_DPI);
-        int x2 = (int)Math.round((anchor.getX() + anchor.getWidth())*MASTER_DPI/POINT_DPI);
-        int y2 = (int)Math.round((anchor.getY() + anchor.getHeight())*MASTER_DPI/POINT_DPI);
-
-        spgr.setRectX1(x1);
-        spgr.setRectY1(y1);
-        spgr.setRectX2(x2);
-        spgr.setRectY2(y2);
-
-    }
-
-    /**
-     * Gets the coordinate space of this group.  All children are constrained
-     * to these coordinates.
-     *
-     * @return the coordinate space of this group
-     */
-    public Rectangle2D getCoordinates(){
-        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
-        Rectangle2D.Float anchor = new Rectangle2D.Float();
-        anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
-        anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
-        anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
-        anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;
-
-        return anchor;
-    }
-
-    /**
-     * Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
-     */
-    protected EscherContainerRecord createSpContainer(boolean isChild) {
-        EscherContainerRecord spgr = new EscherContainerRecord();
-        spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
-        spgr.setOptions((short)15);
-
-        //The group itself is a shape, and always appears as the first EscherSpContainer in the group container.
-        EscherContainerRecord spcont = new EscherContainerRecord();
-        spcont.setRecordId(EscherContainerRecord.SP_CONTAINER);
-        spcont.setOptions((short)15);
-
-        EscherSpgrRecord spg = new EscherSpgrRecord();
-        spg.setOptions((short)1);
-        spcont.addChildRecord(spg);
-
-        EscherSpRecord sp = new EscherSpRecord();
-        short type = (short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2);
-        sp.setOptions(type);
-        sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP);
-        spcont.addChildRecord(sp);
-
-        EscherClientAnchorRecord anchor = new EscherClientAnchorRecord();
-        spcont.addChildRecord(anchor);
-
-        spgr.addChildRecord(spcont);
-        return spgr;
-    }
-
-    /**
-     * Add a shape to this group.
-     *
-     * @param shape - the Shape to add
-     */
-    public void addShape(HSLFShape shape){
-        _escherContainer.addChildRecord(shape.getSpContainer());
-
-        HSLFSheet sheet = getSheet();
-        shape.setSheet(sheet);
-        shape.setShapeId(sheet.allocateShapeId());
-        shape.afterInsert(sheet);
-    }
-
-    /**
-     * Moves this <code>ShapeGroup</code> to the specified location.
-     * <p>
-     * @param x the x coordinate of the top left corner of the shape in new location
-     * @param y the y coordinate of the top left corner of the shape in new location
-     */
-    public void moveTo(int x, int y){
-        java.awt.Rectangle anchor = getAnchor();
-        int dx = x - anchor.x;
-        int dy = y - anchor.y;
-        anchor.translate(dx, dy);
-        setAnchor(anchor);
-
-        HSLFShape[] shape = getShapes();
-        for (int i = 0; i < shape.length; i++) {
-            java.awt.Rectangle chanchor = shape[i].getAnchor();
-            chanchor.translate(dx, dy);
-            shape[i].setAnchor(chanchor);
-        }
-    }
-
-    /**
-     * Returns the anchor (the bounding box rectangle) of this shape group.
-     * All coordinates are expressed in points (72 dpi).
-     *
-     * @return the anchor of this shape group
-     */
-    public Rectangle2D getAnchor2D(){
-        EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
-        Rectangle2D.Float anchor = new Rectangle2D.Float();
-        if(clientAnchor == null){
-            logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
-            EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
-            anchor = new Rectangle2D.Float(
-                (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
-                (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
-                (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
-                (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
-            );
-        } else {
-            anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
-            anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
-            anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
-            anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
-        }
-
-        return anchor;
-    }
-
-    /**
-     * Return type of the shape.
-     * In most cases shape group type is {@link org.apache.poi.hslf.model.ShapeTypes#NotPrimitive}
-     *
-     * @return type of the shape.
-     */
-    public ShapeType getShapeType(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        int nativeId = spRecord.getOptions() >> 4;
-        return ShapeType.forId(nativeId, false);
-    }
-
-    /**
-     * Returns <code>null</code> - shape groups can't have hyperlinks
-     *
-     * @return <code>null</code>.
-     */
-     public Hyperlink getHyperlink(){
-        return null;
-    }
-
-    public void draw(Graphics2D graphics){
-
-        AffineTransform at = graphics.getTransform();
-
-        HSLFShape[] sh = getShapes();
-        for (int i = 0; i < sh.length; i++) {
-            sh[i].draw(graphics);
-        }
-
-        graphics.setTransform(at);
-    }
-
-    @Override
-    public <T extends EscherRecord> T getEscherChild(int recordId){
-        EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
-        return groupInfoContainer.getChildById((short)recordId);
-    }
-
-    public Iterator<HSLFShape> iterator() {
-        return getShapeList().iterator();
-    }
-
-    public boolean removeShape(HSLFShape shape) {
-        // TODO: implement!
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * @return the shapes contained in this group container
-     */
-    protected List<HSLFShape> getShapeList() {
-        // Out escher container record should contain several
-        //  SpContainers, the first of which is the group shape itself
-        Iterator<EscherRecord> iter = _escherContainer.getChildIterator();
-
-        // Don't include the first SpContainer, it is always NotPrimitive
-        if (iter.hasNext()) {
-            iter.next();
-        }
-        List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
-        while (iter.hasNext()) {
-            EscherRecord r = iter.next();
-            if(r instanceof EscherContainerRecord) {
-                // Create the Shape for it
-                EscherContainerRecord container = (EscherContainerRecord)r;
-                HSLFShape shape = ShapeFactory.createShape(container, this);
-                shape.setSheet(getSheet());
-                shapeList.add( shape );
-            } else {
-                // Should we do anything special with these non
-                //  Container records?
-                logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName());
-            }
-        }
-
-        return shapeList;
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMasterSheet.java
deleted file mode 100644 (file)
index 6c7574b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.hslf.record.SheetContainer;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.sl.usermodel.MasterSheet;
-
-/**
- * The superclass of all master sheets - Slide masters, Notes masters, etc.
- *
- * For now it's empty. When we understand more about masters in ppt we will add the common functionality here.
- *
- * @author Yegor Kozlov
- */
-public abstract class HSLFMasterSheet extends HSLFSheet implements MasterSheet<HSLFShape,HSLFSlideShow> {
-    public HSLFMasterSheet(SheetContainer container, int sheetNo){
-        super(container, sheetNo);
-    }
-
-    /**
-     * Pickup a style attribute from the master.
-     * This is the "workhorse" which returns the default style attrubutes.
-     */
-    public abstract TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) ;
-
-
-    /**
-     * Checks if the shape is a placeholder.
-     * (placeholders aren't normal shapes, they are visible only in the Edit Master mode)
-     *
-     *
-     * @return true if the shape is a placeholder
-     */
-    public static boolean isPlaceholder(HSLFShape shape){
-        if(!(shape instanceof HSLFTextShape)) return false;
-
-        HSLFTextShape tx = (HSLFTextShape)shape;
-        return tx.getPlaceholderAtom() != null;
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFNotes.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFNotes.java
deleted file mode 100644 (file)
index 2a7698d..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ====================================================================
-   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.util.Arrays;
-import java.util.List;
-
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.usermodel.Notes;
-
-/**
- * This class represents a slide's notes in a PowerPoint Document. It
- *  allows access to the text within, and the layout. For now, it only
- *  does the text side of things though
- *
- * @author Nick Burch
- */
-
-public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFSlideShow> {
-    private HSLFTextParagraph[] _runs;
-
-    /**
-     * Constructs a Notes Sheet from the given Notes record.
-     * Initialises TextRuns, to provide easier access to the text
-     * 
-     * @param notes the Notes record to read from
-     */
-    public HSLFNotes(org.apache.poi.hslf.record.Notes notes) {
-        super(notes, notes.getNotesAtom().getSlideID());
-
-        // Now, build up TextRuns from pairs of TextHeaderAtom and
-        // one of TextBytesAtom or TextCharsAtom, found inside
-        // EscherTextboxWrapper's in the PPDrawing
-        _runs = findTextRuns(getPPDrawing());
-
-        // Set the sheet on each TextRun
-        for (HSLFTextParagraph tp : _runs) {
-            tp.supplySheet(this);
-        }
-    }
-
-    /**
-     * Returns an array of all the TextRuns found
-     */
-    public HSLFTextParagraph[] getTextRuns() {
-        return _runs;
-    }
-
-    @Override
-    public List<HSLFTextParagraph> getTextParagraphs() {
-        return Arrays.asList(_runs);
-    }
-    
-    /**
-     * Return <code>null</code> - Notes Masters are not yet supported
-     */
-    public HSLFMasterSheet getMasterSheet() {
-        return null;
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFPictureShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFPictureShape.java
deleted file mode 100644 (file)
index e6b72a6..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* ====================================================================
-   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.awt.Graphics2D;
-import java.awt.Insets;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.List;
-
-import javax.imageio.ImageIO;
-
-import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.ddf.EscherComplexProperty;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.hslf.blip.Bitmap;
-import org.apache.poi.hslf.record.Document;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.StringUtil;
-import org.apache.poi.util.Units;
-
-
-/**
- * Represents a picture in a PowerPoint document.
- *
- * @author Yegor Kozlov
- */
-public class HSLFPictureShape extends HSLFSimpleShape {
-
-    /**
-    *  Windows Enhanced Metafile (EMF)
-    */
-    public static final int EMF = 2;
-
-    /**
-    *  Windows Metafile (WMF)
-    */
-    public static final int WMF = 3;
-
-    /**
-    * Macintosh PICT
-    */
-    public static final int PICT = 4;
-
-    /**
-    *  JPEG
-    */
-    public static final int JPEG = 5;
-
-    /**
-    *  PNG
-    */
-    public static final int PNG = 6;
-
-    /**
-     * Windows DIB (BMP)
-     */
-    public static final byte DIB = 7;
-
-    /**
-     * Create a new <code>Picture</code>
-     *
-    * @param idx the index of the picture
-     */
-    public HSLFPictureShape(int idx){
-        this(idx, null);
-    }
-
-    /**
-     * Create a new <code>Picture</code>
-     *
-     * @param idx the index of the picture
-     * @param parent the parent shape
-     */
-    public HSLFPictureShape(int idx, ShapeContainer<HSLFShape> parent) {
-        super(null, parent);
-        _escherContainer = createSpContainer(idx, parent instanceof HSLFGroupShape);
-    }
-
-    /**
-      * Create a <code>Picture</code> object
-      *
-      * @param escherRecord the <code>EscherSpContainer</code> record which holds information about
-      *        this picture in the <code>Slide</code>
-      * @param parent the parent shape of this picture
-      */
-     protected HSLFPictureShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-    }
-
-    /**
-     * Returns index associated with this picture.
-     * Index starts with 1 and points to a EscherBSE record which
-     * holds information about this picture.
-     *
-     * @return the index to this picture (1 based).
-     */
-    public int getPictureIndex(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY);
-        return prop == null ? 0 : prop.getPropertyValue();
-    }
-
-    /**
-     * Create a new Picture and populate the inital structure of the <code>EscherSp</code> record which holds information about this picture.
-
-     * @param idx the index of the picture which refers to <code>EscherBSE</code> container.
-     * @return the create Picture object
-     */
-    protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
-        _escherContainer = super.createSpContainer(isChild);
-        _escherContainer.setOptions((short)15);
-
-        EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
-        spRecord.setOptions((short)((ShapeType.FRAME.nativeId << 4) | 0x2));
-
-        //set default properties for a picture
-        EscherOptRecord opt = getEscherOptRecord();
-        setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x800080);
-
-        //another weird feature of powerpoint: for picture id we must add 0x4000.
-        setEscherProperty(opt, (short)(EscherProperties.BLIP__BLIPTODISPLAY + 0x4000), idx);
-
-        return _escherContainer;
-    }
-
-    /**
-     * Resize this picture to the default size.
-     * For PNG and JPEG resizes the image to 100%,
-     * for other types sets the default size of 200x200 pixels.
-     */
-    public void setDefaultSize(){
-        HSLFPictureData pict = getPictureData();
-        if (pict  instanceof Bitmap){
-            BufferedImage img = null;
-            try {
-                       img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
-            }
-            catch (IOException e){}
-            catch (NegativeArraySizeException ne) {}
-
-            if(img != null) {
-                // Valid image, set anchor from it
-                setAnchor(new java.awt.Rectangle(0, 0, img.getWidth()*POINT_DPI/PIXEL_DPI, img.getHeight()*POINT_DPI/PIXEL_DPI));
-            } else {
-                // Invalid image, go with the default metafile size
-                setAnchor(new java.awt.Rectangle(0, 0, 200, 200));
-            }
-        } else {
-            //default size of a metafile picture is 200x200
-            setAnchor(new java.awt.Rectangle(50, 50, 200, 200));
-        }
-    }
-
-    /**
-     * Returns the picture data for this picture.
-     *
-     * @return the picture data for this picture.
-     */
-    public HSLFPictureData getPictureData(){
-        HSLFSlideShow ppt = getSheet().getSlideShow();
-        HSLFPictureData[] pict = ppt.getPictureData();
-
-        EscherBSERecord bse = getEscherBSERecord();
-        if (bse == null){
-            logger.log(POILogger.ERROR, "no reference to picture data found ");
-        } else {
-            for ( int i = 0; i < pict.length; i++ ) {
-                if (pict[i].getOffset() ==  bse.getOffset()){
-                    return pict[i];
-                }
-            }
-            logger.log(POILogger.ERROR, "no picture found for our BSE offset " + bse.getOffset());
-        }
-        return null;
-    }
-
-    protected EscherBSERecord getEscherBSERecord(){
-        HSLFSlideShow ppt = getSheet().getSlideShow();
-        Document doc = ppt.getDocumentRecord();
-        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
-        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
-        if(bstore == null) {
-            logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
-            return null;
-        }
-        List<EscherRecord> lst = bstore.getChildRecords();
-        int idx = getPictureIndex();
-        if (idx == 0){
-            logger.log(POILogger.DEBUG, "picture index was not found, returning ");
-            return null;
-        }
-        return (EscherBSERecord)lst.get(idx-1);
-    }
-
-    /**
-     * Name of this picture.
-     *
-     * @return name of this picture
-     */
-    public String getPictureName(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherComplexProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPFILENAME);
-        if (prop == null) return null;
-        String name = StringUtil.getFromUnicodeLE(prop.getComplexData());
-        return name.trim();
-    }
-
-    /**
-     * Name of this picture.
-     *
-     * @param name of this picture
-     */
-    public void setPictureName(String name){
-        EscherOptRecord opt = getEscherOptRecord();
-        byte[] data = StringUtil.getToUnicodeLE(name + '\u0000');
-        EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.BLIP__BLIPFILENAME, false, data);
-        opt.addEscherProperty(prop);
-    }
-
-    /**
-     * By default set the orininal image size
-     */
-    protected void afterInsert(HSLFSheet sh){
-        super.afterInsert(sh);
-
-        EscherBSERecord bse = getEscherBSERecord();
-        bse.setRef(bse.getRef() + 1);
-
-        java.awt.Rectangle anchor = getAnchor();
-        if (anchor.equals(new java.awt.Rectangle())){
-            setDefaultSize();
-        }
-    }
-
-    public void draw(Graphics2D graphics){
-        AffineTransform at = graphics.getTransform();
-        ShapePainter.paint(this, graphics);
-
-        HSLFPictureData data = getPictureData();
-        if(data != null) data.draw(graphics, this);
-
-        graphics.setTransform(at);
-    }
-
-    /**
-     * Returns the clipping values as percent ratio relatively to the image size.
-     * The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size,
-     * i.e. the size of the already clipped image
-     * 
-     * @return the clipping as insets converted/scaled to 100000 (=100%) 
-     */
-    public Insets getBlipClip() {
-        EscherOptRecord opt = getEscherOptRecord();
-        
-        double top    = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP);
-        double bottom = getFractProp(opt, EscherProperties.BLIP__CROPFROMBOTTOM);
-        double left   = getFractProp(opt, EscherProperties.BLIP__CROPFROMLEFT);
-        double right  = getFractProp(opt, EscherProperties.BLIP__CROPFROMRIGHT);
-        
-        // if all crop values are zero (the default) then no crop rectangle is set, return null
-        return (top==0 && bottom==0 && left==0 && right==0)
-            ? null
-            : new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000));
-    }
-    
-    /**
-     * @return the fractional property or 0 if not defined
-     */
-    private static double getFractProp(EscherOptRecord opt, short propertyId) {
-        EscherSimpleProperty prop = getEscherProperty(opt, propertyId);
-        if (prop == null) return 0;
-        int fixedPoint = prop.getPropertyValue();
-        return Units.fixedPointToDouble(fixedPoint);
-    }
-}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java
deleted file mode 100644 (file)
index 4e22299..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-/* ====================================================================
-   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.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-import java.util.Iterator;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.util.*;
-
-/**
- *  <p>
-  * Represents a Shape which is the elemental object that composes a drawing.
- *  This class is a wrapper around EscherSpContainer which holds all information
- *  about a shape in PowerPoint document.
- *  </p>
- *  <p>
- *  When you add a shape, you usually specify the dimensions of the shape and the position
- *  of the upper'left corner of the bounding box for the shape relative to the upper'left
- *  corner of the page, worksheet, or slide. Distances in the drawing layer are measured
- *  in points (72 points = 1 inch).
- *  </p>
- * <p>
-  *
-  * @author Yegor Kozlov
- */
-public abstract class HSLFShape implements Shape {
-
-    // For logging
-    protected POILogger logger = POILogFactory.getLogger(this.getClass());
-
-    /**
-     * In Escher absolute distances are specified in
-     * English Metric Units (EMUs), occasionally referred to as A units;
-     * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
-     */
-    public static final int EMU_PER_INCH = 914400;
-    public static final int EMU_PER_POINT = 12700;
-    public static final int EMU_PER_CENTIMETER = 360000;
-
-    /**
-     * Master DPI (576 pixels per inch).
-     * Used by the reference coordinate system in PowerPoint.
-     */
-    public static final int MASTER_DPI = 576;
-
-    /**
-     * Pixels DPI (96 pixels per inch)
-     */
-    public static final int PIXEL_DPI = 96;
-
-    /**
-     * Points DPI (72 pixels per inch)
-     */
-    public static final int POINT_DPI = 72;
-
-    /**
-     * Either EscherSpContainer or EscheSpgrContainer record
-     * which holds information about this shape.
-     */
-    protected EscherContainerRecord _escherContainer;
-
-    /**
-     * Parent of this shape.
-     * <code>null</code> for the topmost shapes.
-     */
-    protected ShapeContainer<HSLFShape> _parent;
-
-    /**
-     * The <code>Sheet</code> this shape belongs to
-     */
-    protected HSLFSheet _sheet;
-
-    /**
-     * Fill
-     */
-    protected HSLFFill _fill;
-
-    /**
-     * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
-     *
-     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
-     * @param parent             the parent of this Shape
-     */
-      protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        _escherContainer = escherRecord;
-        _parent = parent;
-     }
-
-    /**
-     * Creates the lowerlevel escher records for this shape.
-     */
-    protected abstract EscherContainerRecord createSpContainer(boolean isChild);
-
-    /**
-     *  @return the parent of this shape
-     */
-    public ShapeContainer<HSLFShape> getParent(){
-        return _parent;
-    }
-
-    /**
-     * @return name of the shape.
-     */
-    public String getShapeName(){
-        return getShapeType().nativeName;
-    }
-
-    /**
-     * @return type of the shape.
-     * @see org.apache.poi.hslf.record.RecordTypes
-     */
-    public ShapeType getShapeType(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        return ShapeType.forId(spRecord.getShapeType(), false);
-    }
-
-    /**
-     * @param type type of the shape.
-     * @see org.apache.poi.hslf.record.RecordTypes
-     */
-    public void setShapeType(ShapeType type){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        spRecord.setShapeType( (short) type.nativeId );
-        spRecord.setVersion( (short) 0x2 );
-    }
-
-    /**
-     * Returns the anchor (the bounding box rectangle) of this shape.
-     * All coordinates are expressed in points (72 dpi).
-     *
-     * @return the anchor of this shape
-     */
-    public java.awt.Rectangle getAnchor(){
-        Rectangle2D anchor2d = getAnchor2D();
-        return anchor2d.getBounds();
-    }
-
-    /**
-     * Returns the anchor (the bounding box rectangle) of this shape.
-     * All coordinates are expressed in points (72 dpi).
-     *
-     * @return the anchor of this shape
-     */
-    public Rectangle2D getAnchor2D(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        int flags = spRecord.getFlags();
-        Rectangle2D anchor=null;
-        if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
-            EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
-            anchor = new java.awt.Rectangle();
-            if(rec == null){
-                logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
-                EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
-                anchor = new java.awt.Rectangle();
-                anchor = new Rectangle2D.Float(
-                    (float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
-                    (float)clrec.getFlag()*POINT_DPI/MASTER_DPI,
-                    (float)(clrec.getDx1()-clrec.getCol1())*POINT_DPI/MASTER_DPI,
-                    (float)(clrec.getRow1()-clrec.getFlag())*POINT_DPI/MASTER_DPI
-                );
-            } else {
-                anchor = new Rectangle2D.Float(
-                    (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
-                    (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
-                    (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
-                    (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
-                );
-            }
-        }
-        else {
-            EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
-            anchor = new java.awt.Rectangle();
-            anchor = new Rectangle2D.Float(
-                (float)rec.getCol1()*POINT_DPI/MASTER_DPI,
-                (float)rec.getFlag()*POINT_DPI/MASTER_DPI,
-                (float)(rec.getDx1()-rec.getCol1())*POINT_DPI/MASTER_DPI,
-                (float)(rec.getRow1()-rec.getFlag())*POINT_DPI/MASTER_DPI
-            );
-        }
-        return anchor;
-    }
-
-    public Rectangle2D getLogicalAnchor2D(){
-        return getAnchor2D();
-    }
-
-    /**
-     * Sets the anchor (the bounding box rectangle) of this shape.
-     * All coordinates should be expressed in points (72 dpi).
-     *
-     * @param anchor new anchor
-     */
-    public void setAnchor(Rectangle2D anchor){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        int flags = spRecord.getFlags();
-        if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
-            EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID);
-            rec.setDx1((int)(anchor.getX()*MASTER_DPI/POINT_DPI));
-            rec.setDy1((int)(anchor.getY()*MASTER_DPI/POINT_DPI));
-            rec.setDx2((int)((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI));
-            rec.setDy2((int)((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI));
-        }
-        else {
-            EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID);
-            rec.setFlag((short)(anchor.getY()*MASTER_DPI/POINT_DPI));
-            rec.setCol1((short)(anchor.getX()*MASTER_DPI/POINT_DPI));
-            rec.setDx1((short)(((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI)));
-            rec.setRow1((short)(((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI)));
-        }
-
-    }
-
-    /**
-     * Moves the top left corner of the shape to the specified point.
-     *
-     * @param x the x coordinate of the top left corner of the shape
-     * @param y the y coordinate of the top left corner of the shape
-     */
-    public void moveTo(float x, float y){
-        Rectangle2D anchor = getAnchor2D();
-        anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
-        setAnchor(anchor);
-    }
-
-    /**
-     * Helper method to return escher child by record ID
-     *
-     * @return escher record or <code>null</code> if not found.
-     */
-    public static <T extends EscherRecord> T getEscherChild(EscherContainerRecord owner, int recordId){
-        return owner.getChildById((short)recordId);
-    }
-
-    public <T extends EscherRecord> T getEscherChild(int recordId){
-        return _escherContainer.getChildById((short)recordId);
-    }
-    
-    /**
-     * Returns  escher property by id.
-     *
-     * @return escher property or <code>null</code> if not found.
-     */
-     public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
-        return opt.lookup(propId);
-    }
-
-    /**
-     * Set an escher property for this shape.
-     *
-     * @param opt       The opt record to set the properties to.
-     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
-     * @param value     value of the property. If value = -1 then the property is removed.
-     */
-     public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
-        java.util.List<EscherProperty> props = opt.getEscherProperties();
-        for ( Iterator<EscherProperty> iterator = props.iterator(); iterator.hasNext(); ) {
-            if (iterator.next().getPropertyNumber() == propId){
-                iterator.remove();
-                break;
-            }
-        }
-        if (value != -1) {
-            opt.addEscherProperty(new EscherSimpleProperty(propId, value));
-            opt.sortProperties();
-        }
-    }
-
-    /**
-     * Set an simple escher property for this shape.
-     *
-     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
-     * @param value     value of the property. If value = -1 then the property is removed.
-     */
-    public void setEscherProperty(short propId, int value){
-        EscherOptRecord opt = getEscherOptRecord();
-        setEscherProperty(opt, propId, value);
-    }
-
-    /**
-     * Get the value of a simple escher property for this shape.
-     *
-     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
-     */
-   public int getEscherProperty(short propId){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, propId);
-        return prop == null ? 0 : prop.getPropertyValue();
-    }
-
-    /**
-     * Get the value of a simple escher property for this shape.
-     *
-     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
-     */
-   public int getEscherProperty(short propId, int defaultValue){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, propId);
-        return prop == null ? defaultValue : prop.getPropertyValue();
-    }
-
-    /**
-     * @return  The shape container and it's children that can represent this
-     *          shape.
-     */
-    public EscherContainerRecord getSpContainer(){
-        return _escherContainer;
-    }
-
-    /**
-     * Event which fires when a shape is inserted in the sheet.
-     * In some cases we need to propagate changes to upper level containers.
-     * <br>
-     * Default implementation does nothing.
-     *
-     * @param sh - owning shape
-     */
-    protected void afterInsert(HSLFSheet sh){
-        if(_fill != null) {
-            _fill.afterInsert(sh);
-        }
-    }
-
-    /**
-     *  @return the <code>SlideShow</code> this shape belongs to
-     */
-    public HSLFSheet getSheet(){
-        return _sheet;
-    }
-
-    /**
-     * Assign the <code>SlideShow</code> this shape belongs to
-     *
-     * @param sheet owner of this shape
-     */
-    public void setSheet(HSLFSheet sheet){
-        _sheet = sheet;
-    }
-
-    Color getColor(short colorProperty, short opacityProperty, int defaultColor){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty p = getEscherProperty(opt, colorProperty);
-        if(p == null && defaultColor == -1) return null;
-
-        int val = (p == null) ? defaultColor : p.getPropertyValue();
-
-        EscherColorRef ecr = new EscherColorRef(val);
-        
-        boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
-        boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
-        boolean fSystemRGB = ecr.hasSystemRGBFlag();
-        boolean fSchemeIndex = ecr.hasSchemeIndexFlag();
-        boolean fSysIndex = ecr.hasSysIndexFlag();
-        
-        int rgb[] = ecr.getRGB();
-
-        HSLFSheet sheet = getSheet();
-        if (fSchemeIndex && sheet != null) {
-            //red is the index to the color scheme
-            ColorSchemeAtom ca = sheet.getColorScheme();
-            int schemeColor = ca.getColor(ecr.getSchemeIndex());
-
-            rgb[0] = (schemeColor >> 0) & 0xFF;
-            rgb[1] = (schemeColor >> 8) & 0xFF;
-            rgb[2] = (schemeColor >> 16) & 0xFF;
-        } else if (fPaletteIndex){
-            //TODO
-        } else if (fPaletteRGB){
-            //TODO
-        } else if (fSystemRGB){
-            //TODO
-        } else if (fSysIndex){
-            //TODO
-        }
-
-        double alpha = getAlpha(opacityProperty);
-        return new Color(rgb[0], rgb[1], rgb[2], (int)(alpha*255.0));
-    }
-
-    double getAlpha(short opacityProperty) {
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
-        int defaultOpacity = 0x00010000;
-        int opacity = (op == null) ? defaultOpacity : op.getPropertyValue();
-        return Units.fixedPointToDouble(opacity);
-    }
-    
-    Color toRGB(int val){
-        int a = (val >> 24) & 0xFF;
-        int b = (val >> 16) & 0xFF;
-        int g = (val >> 8) & 0xFF;
-        int r = (val >> 0) & 0xFF;
-
-        if(a == 0xFE){
-            // Color is an sRGB value specified by red, green, and blue fields.
-        } else if (a == 0xFF){
-            // Color is undefined.
-        } else {
-            // index in the color scheme
-            ColorSchemeAtom ca = getSheet().getColorScheme();
-            int schemeColor = ca.getColor(a);
-
-            r = (schemeColor >> 0) & 0xFF;
-            g = (schemeColor >> 8) & 0xFF;
-            b = (schemeColor >> 16) & 0xFF;
-        }
-        return new Color(r, g, b);
-    }
-
-    /**
-     * @return id for the shape.
-     */
-    public int getShapeId(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        return spRecord == null ? 0 : spRecord.getShapeId();
-    }
-
-    /**
-     * Sets shape ID
-     *
-     * @param id of the shape
-     */
-    public void setShapeId(int id){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        if(spRecord != null) spRecord.setShapeId(id);
-    }
-
-    /**
-     * Fill properties of this shape
-     *
-     * @return fill properties of this shape
-     */
-    public HSLFFill getFill(){
-        if(_fill == null) {
-            _fill = new HSLFFill(this);
-        }
-        return _fill;
-    }
-
-    public FillStyle getFillStyle() {
-        return getFill().getFillStyle();
-    }
-
-    /**
-     * Returns the hyperlink assigned to this shape
-     *
-     * @return the hyperlink assigned to this shape
-     * or <code>null</code> if not found.
-     */
-    public Hyperlink getHyperlink(){
-        return Hyperlink.find(this);
-    }
-
-    public void draw(Graphics2D graphics){
-        logger.log(POILogger.INFO, "Rendering " + getShapeName());
-    }
-
-    /**
-     * Return shape outline as a java.awt.Shape object
-     *
-     * @return the shape outline
-     */
-    public java.awt.Shape getOutline(){
-        return getLogicalAnchor2D();
-    }
-    
-    public EscherOptRecord getEscherOptRecord() {
-        return getEscherChild(EscherOptRecord.RECORD_ID);
-    }
-    
-    public boolean getFlipHorizontal(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
-    }
-     
-    public void setFlipHorizontal(boolean flip) {
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ;
-        spRecord.setFlags(flag);
-    }
-
-    public boolean getFlipVertical(){
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
-    }
-    
-    public void setFlipVertical(boolean flip) {
-        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-        int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPVERT;
-        spRecord.setFlags(flag);
-    }
-
-    public double getRotation(){
-        int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
-        double angle = Units.fixedPointToDouble(rot) % 360.0;
-        return angle;
-    }
-    
-    public void setRotation(double theta){
-        int rot = Units.doubleToFixedPoint(theta % 360.0);
-        setEscherProperty(EscherProperties.TRANSFORM__ROTATION, rot);
-    }
-
-    public boolean isPlaceholder() {
-        return false;
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSheet.java
deleted file mode 100644 (file)
index 5156f37..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/* ====================================================================
-   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.awt.Graphics2D;
-import java.util.*;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.usermodel.Sheet;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * This class defines the common format of "Sheets" in a powerpoint
- * document. Such sheets could be Slides, Notes, Master etc
- *
- * @author Nick Burch
- * @author Yegor Kozlov
- */
-
-public abstract class HSLFSheet implements Sheet<HSLFShape,HSLFSlideShow> {
-       private static POILogger logger = POILogFactory.getLogger(HSLFSheet.class);
-
-    /**
-     * The <code>SlideShow</code> we belong to
-     */
-    private HSLFSlideShow _slideShow;
-
-    /**
-     * Sheet background
-     */
-    private HSLFBackground _background;
-
-    /**
-     * Record container that holds sheet data.
-     * For slides it is org.apache.poi.hslf.record.Slide,
-     * for notes it is org.apache.poi.hslf.record.Notes,
-     * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
-     */
-    private SheetContainer _container;
-
-    private int _sheetNo;
-
-    public HSLFSheet(SheetContainer container, int sheetNo) {
-        _container = container;
-        _sheetNo = sheetNo;
-    }
-
-    /**
-     * Returns an array of all the TextRuns in the sheet.
-     */
-    public abstract HSLFTextParagraph[] getTextRuns();
-
-    /**
-     * Returns the (internal, RefID based) sheet number, as used
-     * to in PersistPtr stuff.
-     */
-    public int _getSheetRefId() {
-        return _container.getSheetId();
-    }
-
-    /**
-     * Returns the (internal, SlideIdentifier based) sheet number, as used
-     * to reference this sheet from other records.
-     */
-    public int _getSheetNumber() {
-        return _sheetNo;
-    }
-
-    /**
-     * Fetch the PPDrawing from the underlying record
-     */
-    protected PPDrawing getPPDrawing() {
-        return _container.getPPDrawing();
-    }
-
-    /**
-     * Fetch the SlideShow we're attached to
-     */
-    public HSLFSlideShow getSlideShow() {
-        return _slideShow;
-    }
-
-    /**
-     * Return record container for this sheet
-     */
-    public SheetContainer getSheetContainer() {
-        return _container;
-    }
-
-    /**
-     * Set the SlideShow we're attached to.
-     * Also passes it on to our child RichTextRuns
-     */
-    public void setSlideShow(HSLFSlideShow ss) {
-        _slideShow = ss;
-        HSLFTextParagraph[] trs = getTextRuns();
-        if (trs == null) return;
-        for (HSLFTextParagraph tp : trs) {
-            tp.supplySheet(this);
-        }
-    }
-
-
-    /**
-     * For a given PPDrawing, grab all the TextRuns
-     */
-    public static HSLFTextParagraph[] findTextRuns(PPDrawing ppdrawing) {
-        final List<HSLFTextParagraph> runsV = new ArrayList<HSLFTextParagraph>();
-        final EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers();
-        for (int i = 0; i < wrappers.length; i++) {
-            int s1 = runsV.size();
-
-            // propagate parents to parent-aware records
-            RecordContainer.handleParentAwareRecords(wrappers[i]);
-            findTextRuns(wrappers[i], runsV);
-            int s2 = runsV.size();
-            if (s2 != s1){
-                HSLFTextParagraph t = runsV.get(runsV.size()-1);
-                t.setShapeId(wrappers[i].getShapeId());
-            }
-        }
-        return runsV.toArray(new HSLFTextParagraph[runsV.size()]);
-    }
-    /**
-     * Scans through the supplied record array, looking for
-     * a TextHeaderAtom followed by one of a TextBytesAtom or
-     * a TextCharsAtom. Builds up TextRuns from these
-     *
-     * @param records the records to build from
-     * @param found   vector to add any found to
-     */
-    protected static void findTextParagraphs(final Record[] records, final List<HSLFTextParagraph> found) {
-       findTextRuns(records, found, null); 
-    }
-    /**
-     * Scans through the supplied record array, looking for
-     * a TextHeaderAtom followed by one of a TextBytesAtom or
-     * a TextCharsAtom. Builds up TextRuns from these
-     *
-     * @param wrapper an EscherTextboxWrapper
-     * @param found   vector to add any found to
-     */
-    protected static void findTextRuns(final EscherTextboxWrapper wrapper, final List<HSLFTextParagraph> found) {
-       findTextRuns(wrapper.getChildRecords(), found, wrapper.getStyleTextProp9Atom());
-    }
-    /**
-     * Scans through the supplied record array, looking for
-     * a TextHeaderAtom followed by one of a TextBytesAtom or
-     * a TextCharsAtom. Builds up TextRuns from these
-     *
-     * @param records the records to build from
-     * @param found   vector to add any found to
-     * @param styleTextProp9Atom a StyleTextProp9Atom with numbered lists info
-     */
-    protected static void findTextRuns(final Record[] records, final List<HSLFTextParagraph> found, final StyleTextProp9Atom styleTextProp9Atom) {
-        for (int i = 0, slwtIndex=0; i < (records.length - 1); i++) {
-            if (records[i] instanceof TextHeaderAtom) {
-                TextHeaderAtom tha = (TextHeaderAtom) records[i];
-                StyleTextPropAtom stpa = null;
-                HSLFTextParagraph trun = null;
-                Record next = null;
-                Record subs = null;
-                
-                // See what follows the TextHeaderAtom
-                next = records[i+1];
-                if (i < records.length - 2) {
-                    subs = records[i+2];
-                }
-                
-                // Is the next record one we need to skip over?
-                if (subs != null) {
-                    if (next instanceof TextRulerAtom ||
-                        next instanceof MasterTextPropAtom ||
-                        next instanceof TextSpecInfoAtom) {
-                        // Ignore this one, check the one after
-                        next = subs;
-                        if (i < records.length - 3) {
-                            subs = records[i+3];
-                        } else {
-                            subs = null;
-                        }
-                    }
-                }
-                
-                // Is the subsequent record a style one?
-                if (subs != null && subs instanceof StyleTextPropAtom) {
-                    stpa = (StyleTextPropAtom)subs;
-                }
-                
-                // Now, check if the next record is one to record
-                if (next instanceof TextCharsAtom) {
-                    TextCharsAtom tca = (TextCharsAtom)next;
-                    trun = new HSLFTextParagraph(tha, tca, stpa);
-                } else if (next instanceof TextBytesAtom) {
-                    TextBytesAtom tba = (TextBytesAtom)next;
-                    trun = new HSLFTextParagraph(tha, tba, stpa);
-                } else if (next instanceof StyleTextPropAtom) {
-                    stpa = (StyleTextPropAtom)next;
-                } else if (next instanceof TextHeaderAtom) {
-                    // Seems to be a mostly, but not completely deleted block of
-                    //  text. Only the header remains, which isn't useful alone 
-                    // Skip on to the next TextHeaderAtom
-                    continue;
-                } else {
-                    logger.log(POILogger.ERROR, "Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + next.getRecordType());
-                }
-
-                if (trun != null) {
-                    List<Record> lst = new ArrayList<Record>();
-                    for (int j = i; j < records.length; j++) {
-                        if(j > i && records[j] instanceof TextHeaderAtom) break;
-                        lst.add(records[j]);
-                    }
-                    Record[] recs = new Record[lst.size()];
-                    lst.toArray(recs);
-                    trun._records = recs;
-                    trun.setIndex(slwtIndex);
-                    trun.setStyleTextProp9Atom(styleTextProp9Atom);
-                    found.add(trun);
-                    i++;
-                } else {
-                    // Not a valid one, so skip on to next and look again
-                }
-                slwtIndex++;
-            }
-        }
-    }
-
-    /**
-     * Returns all shapes contained in this Sheet
-     *
-     * @return all shapes contained in this Sheet (Slide or Notes)
-     */
-    public HSLFShape[] getShapes() {
-        List<HSLFShape> shapeList = getShapeList();
-        return shapeList.toArray(new HSLFShape[shapeList.size()]);
-    }
-
-    /**
-     * Add a new Shape to this Slide
-     *
-     * @param shape - the Shape to add
-     */
-    public void addShape(HSLFShape shape) {
-        PPDrawing ppdrawing = getPPDrawing();
-
-        EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
-        EscherContainerRecord spgr = (EscherContainerRecord) HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
-        spgr.addChildRecord(shape.getSpContainer());
-
-        shape.setSheet(this);
-        shape.setShapeId(allocateShapeId());
-        shape.afterInsert(this);
-    }
-
-    /**
-     * Allocates new shape id for the new drawing group id.
-     *
-     * @return a new shape id.
-     */
-    public int allocateShapeId()
-    {
-        EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
-        EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
-
-        dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
-
-        // Add to existing cluster if space available
-        for (int i = 0; i < dgg.getFileIdClusters().length; i++)
-        {
-            EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
-            if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
-            {
-                int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
-                c.incrementShapeId();
-                dg.setNumShapes( dg.getNumShapes() + 1 );
-                dg.setLastMSOSPID( result );
-                if (result >= dgg.getShapeIdMax())
-                    dgg.setShapeIdMax( result + 1 );
-                return result;
-            }
-        }
-
-        // Create new cluster
-        dgg.addCluster( dg.getDrawingGroupId(), 0, false );
-        dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
-        dg.setNumShapes( dg.getNumShapes() + 1 );
-        int result = (1024 * dgg.getFileIdClusters().length);
-        dg.setLastMSOSPID( result );
-        if (result >= dgg.getShapeIdMax())
-            dgg.setShapeIdMax( result + 1 );
-        return result;
-    }
-
-    /**
-     * Removes the specified shape from this sheet.
-     *
-     * @param shape shape to be removed from this sheet, if present.
-     * @return <tt>true</tt> if the shape was deleted.
-     */
-    public boolean removeShape(HSLFShape shape) {
-        PPDrawing ppdrawing = getPPDrawing();
-
-        EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
-        EscherContainerRecord spgr = null;
-
-        for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
-            EscherRecord rec = it.next();
-            if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
-                spgr = (EscherContainerRecord) rec;
-                break;
-            }
-        }
-        if(spgr == null) {
-            return false;
-        }
-
-        List<EscherRecord> lst = spgr.getChildRecords();
-        boolean result = lst.remove(shape.getSpContainer());
-        spgr.setChildRecords(lst);
-        return result;
-    }
-
-    /**
-     * Called by SlideShow ater a new sheet is created
-     */
-    public void onCreate(){
-
-    }
-
-    /**
-     * Return the master sheet .
-     */
-    public abstract HSLFMasterSheet getMasterSheet();
-
-    /**
-     * Color scheme for this sheet.
-     */
-    public ColorSchemeAtom getColorScheme() {
-        return _container.getColorScheme();
-    }
-
-    /**
-     * Returns the background shape for this sheet.
-     *
-     * @return the background shape for this sheet.
-     */
-    public HSLFBackground getBackground() {
-        if (_background == null) {
-            PPDrawing ppdrawing = getPPDrawing();
-
-            EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
-            EscherContainerRecord spContainer = null;
-
-            for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
-                EscherRecord rec = it.next();
-                if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
-                    spContainer = (EscherContainerRecord) rec;
-                    break;
-                }
-            }
-            _background = new HSLFBackground(spContainer, null);
-            _background.setSheet(this);
-        }
-        return _background;
-    }
-
-    public void draw(Graphics2D graphics){
-
-    }
-
-    /**
-     * Subclasses should call this method and update the array of text runs
-     * when a text shape is added
-     *
-     * @param shape
-     */
-    protected void onAddTextShape(HSLFTextShape shape) {
-
-    }
-
-    /**
-     * Return placeholder by text type
-     *
-     * @param type  type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom}
-     * @return  <code>TextShape</code> or <code>null</code>
-     */
-    public HSLFTextShape getPlaceholderByTextType(int type){
-        HSLFShape[] shape = getShapes();
-        for (int i = 0; i < shape.length; i++) {
-            if(shape[i] instanceof HSLFTextShape){
-                HSLFTextShape tx = (HSLFTextShape)shape[i];
-                HSLFTextParagraph run = tx.getTextParagraph();
-                if(run != null && run.getRunType() == type){
-                    return tx;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Search text placeholer by its type
-     *
-     * @param type  type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
-     * @return  <code>TextShape</code> or <code>null</code>
-     */
-    public HSLFTextShape getPlaceholder(int type){
-        HSLFShape[] shape = getShapes();
-        for (int i = 0; i < shape.length; i++) {
-            if(shape[i] instanceof HSLFTextShape){
-                HSLFTextShape tx = (HSLFTextShape)shape[i];
-                int placeholderId = 0;
-                OEPlaceholderAtom oep = tx.getPlaceholderAtom();
-                if(oep != null) {
-                    placeholderId = oep.getPlaceholderId();
-                } else {
-                    //special case for files saved in Office 2007
-                    RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
-                    if(hldr != null) placeholderId = hldr.getPlaceholderId();
-                }
-                if(placeholderId == type){
-                    return tx;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return programmable tag associated with this sheet, e.g. <code>___PPT12</code>.
-     *
-     * @return programmable tag associated with this sheet.
-     */
-    public String getProgrammableTag(){
-        String tag = null;
-        RecordContainer progTags = (RecordContainer)
-                getSheetContainer().findFirstOfType(
-                            RecordTypes.ProgTags.typeID
-        );
-        if(progTags != null) {
-            RecordContainer progBinaryTag = (RecordContainer)
-                progTags.findFirstOfType(
-                        RecordTypes.ProgBinaryTag.typeID
-            );
-            if(progBinaryTag != null) {
-                CString binaryTag = (CString)
-                    progBinaryTag.findFirstOfType(
-                            RecordTypes.CString.typeID
-                );
-                if(binaryTag != null) tag = binaryTag.getText();
-            }
-        }
-
-        return tag;
-
-    }
-
-    public Iterator<HSLFShape> iterator() {
-        return getShapeList().iterator();
-    }
-
-
-    /**
-     * Returns all shapes contained in this Sheet
-     *
-     * @return all shapes contained in this Sheet (Slide or Notes)
-     */
-    protected List<HSLFShape> getShapeList() {
-        PPDrawing ppdrawing = getPPDrawing();
-
-        EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
-        EscherContainerRecord spgr = null;
-
-        for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
-            EscherRecord rec = it.next();
-            if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
-                spgr = (EscherContainerRecord) rec;
-                break;
-            }
-        }
-        if (spgr == null) {
-            throw new IllegalStateException("spgr not found");
-        }
-
-        List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
-        Iterator<EscherRecord> it = spgr.getChildIterator();
-        if (it.hasNext()) {
-            // skip first item
-            it.next();
-        }
-        for (; it.hasNext();) {
-            EscherContainerRecord sp = (EscherContainerRecord) it.next();
-            HSLFShape sh = ShapeFactory.createShape(sp, null);
-            sh.setSheet(this);
-            shapeList.add(sh);
-        }
-
-        return shapeList;
-    }
-
-    /**
-     * @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
-     * Sheets that support the notion of master (slide, slideLayout) should override it and
-     * check this setting
-     */
-    public boolean getFollowMasterGraphics() {
-        return false;
-    }
-
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSimpleShape.java
deleted file mode 100644 (file)
index 71c3c34..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/* ====================================================================
-   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.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-
-import org.apache.poi.ddf.DefaultEscherRecordFactory;
-import org.apache.poi.ddf.EscherChildAnchorRecord;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
-import org.apache.poi.ddf.EscherClientDataRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.record.InteractiveInfo;
-import org.apache.poi.hslf.record.InteractiveInfoAtom;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.sl.usermodel.StrokeStyle.*;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.Units;
-
-/**
- *  An abstract simple (non-group) shape.
- *  This is the parent class for all primitive shapes like Line, Rectangle, etc.
- *
- *  @author Yegor Kozlov
- */
-public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
-
-    public final static double DEFAULT_LINE_WIDTH = 0.75;
-
-    /**
-     * Records stored in EscherClientDataRecord
-     */
-    protected Record[] _clientRecords;
-    protected EscherClientDataRecord _clientData;
-
-    /**
-     * Create a SimpleShape object and initialize it from the supplied Record container.
-     *
-     * @param escherRecord    <code>EscherSpContainer</code> container which holds information about this shape
-     * @param parent    the parent of the shape
-     */
-    protected HSLFSimpleShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-    }
-
-    /**
-     * Create a new Shape
-     *
-     * @param isChild   <code>true</code> if the Line is inside a group, <code>false</code> otherwise
-     * @return the record container which holds this shape
-     */
-    protected EscherContainerRecord createSpContainer(boolean isChild) {
-        _escherContainer = new EscherContainerRecord();
-        _escherContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
-        _escherContainer.setOptions((short)15);
-
-        EscherSpRecord sp = new EscherSpRecord();
-        int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE;
-        if (isChild) flags |= EscherSpRecord.FLAG_CHILD;
-        sp.setFlags(flags);
-        _escherContainer.addChildRecord(sp);
-
-        EscherOptRecord opt = new EscherOptRecord();
-        opt.setRecordId(EscherOptRecord.RECORD_ID);
-        _escherContainer.addChildRecord(opt);
-
-        EscherRecord anchor;
-        if(isChild) anchor = new EscherChildAnchorRecord();
-        else {
-            anchor = new EscherClientAnchorRecord();
-
-            //hack. internal variable EscherClientAnchorRecord.shortRecord can be
-            //initialized only in fillFields(). We need to set shortRecord=false;
-            byte[] header = new byte[16];
-            LittleEndian.putUShort(header, 0, 0);
-            LittleEndian.putUShort(header, 2, 0);
-            LittleEndian.putInt(header, 4, 8);
-            anchor.fillFields(header, 0, null);
-        }
-        _escherContainer.addChildRecord(anchor);
-
-        return _escherContainer;
-    }
-
-    /**
-     *  Returns width of the line in in points
-     */
-    public double getLineWidth(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
-        double width = (prop == null) ? DEFAULT_LINE_WIDTH : Units.toPoints(prop.getPropertyValue());
-        return width;
-    }
-
-    /**
-     *  Sets the width of line in in points
-     *  @param width  the width of line in in points
-     */
-    public void setLineWidth(double width){
-        EscherOptRecord opt = getEscherOptRecord();
-        setEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH, Units.toEMU(width));
-    }
-
-    /**
-     * Sets the color of line
-     *
-     * @param color new color of the line
-     */
-    public void setLineColor(Color color){
-        EscherOptRecord opt = getEscherOptRecord();
-        if (color == null) {
-            setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
-        } else {
-            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
-            setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb);
-            setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, color == null ? 0x180010 : 0x180018);
-        }
-    }
-
-    /**
-     * @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
-     */
-    public Color getLineColor(){
-        EscherOptRecord opt = getEscherOptRecord();
-
-        EscherSimpleProperty p = getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
-        if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
-
-        Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
-        return clr == null ? Color.black : clr;
-    }
-
-    /**
-     * Gets line dashing.
-     *
-     * @return dashing of the line.
-     */
-    public LineDash getLineDashing(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
-        return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue());
-    }
-
-    /**
-     * Sets line dashing.
-     *
-     * @param pen new style of the line.
-     */
-    public void setLineDashing(LineDash pen){
-        EscherOptRecord opt = getEscherOptRecord();
-        setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId);
-    }
-
-    /**
-     * Gets the line compound style
-     *
-     * @return the compound style of the line.
-     */
-    public LineCompound getLineCompound() {
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE);
-        return (prop == null) ? LineCompound.SINGLE : LineCompound.fromNativeId(prop.getPropertyValue());
-    }
-    
-    /**
-     * Sets the line compound style
-     *
-     * @param style new compound style of the line.
-     */
-    public void setLineCompound(LineCompound style){
-        EscherOptRecord opt = getEscherOptRecord();
-        setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == LineCompound.SINGLE ? -1 : style.nativeId);
-    }
-
-    /**
-     * Returns line style. One of the constants defined in this class.
-     *
-     * @return style of the line.
-     */
-    public StrokeStyle getStrokeStyle(){
-        return new StrokeStyle() {
-            public PaintStyle getPaint() {
-                return null;
-            }
-
-            public LineCap getLineCap() {
-                return null;
-            }
-
-            public LineDash getLineDash() {
-                return null;
-            }
-
-            public LineCompound getLineCompound() {
-                return null;
-            }
-
-            public double getLineWidth() {
-                return 0;
-            }
-            
-        };
-    }
-
-    /**
-     * The color used to fill this shape.
-     */
-    public Color getFillColor(){
-        return getFill().getForegroundColor();
-    }
-
-    /**
-     * The color used to fill this shape.
-     *
-     * @param color the background color
-     */
-    public void setFillColor(Color color){
-        getFill().setForegroundColor(color);
-    }
-
-    /**
-     *
-     * @return 'absolute' anchor of this shape relative to the parent sheet
-     */
-    public Rectangle2D getLogicalAnchor2D(){
-        Rectangle2D anchor = getAnchor2D();
-
-        //if it is a groupped shape see if we need to transform the coordinates
-        if (getParent() != null){
-            ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
-            for (ShapeContainer<HSLFShape> parent=this.getParent();
-                parent instanceof HSLFGroupShape;
-                parent = ((HSLFGroupShape)parent).getParent()) {
-                lst.add(0, (HSLFGroupShape)parent);
-            }
-            
-            AffineTransform tx = new AffineTransform();
-            for(HSLFGroupShape prnt : lst) {
-                Rectangle2D exterior = prnt.getAnchor2D();
-                Rectangle2D interior = prnt.getCoordinates();
-
-                double scaleX =  exterior.getWidth() / interior.getWidth();
-                double scaleY = exterior.getHeight() / interior.getHeight();
-
-                tx.translate(exterior.getX(), exterior.getY());
-                tx.scale(scaleX, scaleY);
-                tx.translate(-interior.getX(), -interior.getY());
-                
-            }
-            anchor = tx.createTransformedShape(anchor).getBounds2D();
-        }
-
-        double angle = getRotation();
-        if(angle != 0.){
-            double centerX = anchor.getX() + anchor.getWidth()/2;
-            double centerY = anchor.getY() + anchor.getHeight()/2;
-
-            AffineTransform trans = new AffineTransform();
-            trans.translate(centerX, centerY);
-            trans.rotate(Math.toRadians(angle));
-            trans.translate(-centerX, -centerY);
-
-            Rectangle2D rect = trans.createTransformedShape(anchor).getBounds2D();
-            if((anchor.getWidth() < anchor.getHeight() && rect.getWidth() > rect.getHeight()) ||
-                (anchor.getWidth() > anchor.getHeight() && rect.getWidth() < rect.getHeight())    ){
-                trans = new AffineTransform();
-                trans.translate(centerX, centerY);
-                trans.rotate(Math.PI/2);
-                trans.translate(-centerX, -centerY);
-                anchor = trans.createTransformedShape(anchor).getBounds2D();
-            }
-        }
-        return anchor;
-    }
-
-    public void draw(Graphics2D graphics){
-        AffineTransform at = graphics.getTransform();
-        ShapePainter.paint(this, graphics);
-        graphics.setTransform(at);
-    }
-
-    /**
-     *  Find a record in the underlying EscherClientDataRecord
-     *
-     * @param recordType type of the record to search
-     */
-    @SuppressWarnings("unchecked")
-    protected <T extends Record> T getClientDataRecord(int recordType) {
-
-        Record[] records = getClientRecords();
-        if(records != null) for (int i = 0; i < records.length; i++) {
-            if(records[i].getRecordType() == recordType){
-                return (T)records[i];
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Search for EscherClientDataRecord, if found, convert its contents into an array of HSLF records
-     *
-     * @return an array of HSLF records contained in the shape's EscherClientDataRecord or <code>null</code>
-     */
-    protected Record[] getClientRecords() {
-        if(_clientData == null){
-            EscherRecord r = getEscherChild(EscherClientDataRecord.RECORD_ID);
-            //ddf can return EscherContainerRecord with recordId=EscherClientDataRecord.RECORD_ID
-            //convert in to EscherClientDataRecord on the fly
-            if(r != null && !(r instanceof EscherClientDataRecord)){
-                byte[] data = r.serialize();
-                r = new EscherClientDataRecord();
-                r.fillFields(data, 0, new DefaultEscherRecordFactory());
-            }
-            _clientData = (EscherClientDataRecord)r;
-        }
-        if(_clientData != null && _clientRecords == null){
-            byte[] data = _clientData.getRemainingData();
-            _clientRecords = Record.findChildRecords(data, 0, data.length);
-        }
-        return _clientRecords;
-    }
-
-    protected void updateClientData() {
-        if(_clientData != null && _clientRecords != null){
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            try {
-                for (int i = 0; i < _clientRecords.length; i++) {
-                    _clientRecords[i].writeOut(out);
-                }
-            } catch(Exception e){
-                throw new HSLFException(e);
-            }
-            _clientData.setRemainingData(out.toByteArray());
-        }
-    }
-
-    public void setHyperlink(Hyperlink link){
-        if(link.getId() == -1){
-            throw new HSLFException("You must call SlideShow.addHyperlink(Hyperlink link) first");
-        }
-
-        EscherClientDataRecord cldata = new EscherClientDataRecord();
-        cldata.setOptions((short)0xF);
-        getSpContainer().addChildRecord(cldata); // TODO - junit to prove getChildRecords().add is wrong
-
-        InteractiveInfo info = new InteractiveInfo();
-        InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
-
-        switch(link.getType()){
-            case Hyperlink.LINK_FIRSTSLIDE:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_FIRSTSLIDE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_FirstSlide);
-                break;
-            case Hyperlink.LINK_LASTSLIDE:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_LASTSLIDE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_LastSlide);
-                break;
-            case Hyperlink.LINK_NEXTSLIDE:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_NEXTSLIDE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_NextSlide);
-                break;
-            case Hyperlink.LINK_PREVIOUSSLIDE:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_PREVIOUSSLIDE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_PreviousSlide);
-                break;
-            case Hyperlink.LINK_URL:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_NONE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_Url);
-                break;
-            case Hyperlink.LINK_SLIDENUMBER:
-                infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
-                infoAtom.setJump(InteractiveInfoAtom.JUMP_NONE);
-                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_SlideNumber);
-                break;
-        }
-
-        infoAtom.setHyperlinkID(link.getId());
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try {
-            info.writeOut(out);
-        } catch(Exception e){
-            throw new HSLFException(e);
-        }
-        cldata.setRemainingData(out.toByteArray());
-
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlide.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlide.java
deleted file mode 100644 (file)
index 7030ce7..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/* ====================================================================
-   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.awt.Graphics2D;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.hslf.record.Comment2000;
-import org.apache.poi.hslf.record.EscherTextboxWrapper;
-import org.apache.poi.hslf.record.HeadersFootersContainer;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordContainer;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.SSSlideInfoAtom;
-import org.apache.poi.hslf.record.SlideAtom;
-import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
-import org.apache.poi.hslf.record.StyleTextProp9Atom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.sl.usermodel.Slide;
-
-/**
- * This class represents a slide in a PowerPoint Document. It allows
- *  access to the text within, and the layout. For now, it only does
- *  the text side of things though
- *
- * @author Nick Burch
- * @author Yegor Kozlov
- */
-
-public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSlideShow> {
-       private int _slideNo;
-       private SlideAtomsSet _atomSet;
-       private HSLFTextParagraph[] _runs;
-       private HSLFNotes _notes; // usermodel needs to set this
-
-       /**
-        * Constructs a Slide from the Slide record, and the SlideAtomsSet
-        *  containing the text.
-        * Initializes TextRuns, to provide easier access to the text
-        *
-        * @param slide the Slide record we're based on
-        * @param notes the Notes sheet attached to us
-        * @param atomSet the SlideAtomsSet to get the text from
-        */
-       public HSLFSlide(org.apache.poi.hslf.record.Slide slide, HSLFNotes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
-        super(slide, slideIdentifier);
-
-               _notes = notes;
-               _atomSet = atomSet;
-               _slideNo = slideNumber;
-
-               // Grab the TextRuns from the PPDrawing
-               HSLFTextParagraph[] _otherRuns = findTextRuns(getPPDrawing());
-
-               // For the text coming in from the SlideAtomsSet:
-               // Build up TextRuns from pairs of TextHeaderAtom and
-               //  one of TextBytesAtom or TextCharsAtom
-               final List<HSLFTextParagraph> textParagraphs = new LinkedList<HSLFTextParagraph>();
-               if(_atomSet != null) {
-                       findTextParagraphs(_atomSet.getSlideRecords(),textParagraphs);
-               } else {
-                       // No text on the slide, must just be pictures
-               }
-
-               // Build an array, more useful than a vector
-               _runs = new HSLFTextParagraph[textParagraphs.size()+_otherRuns.length];
-               // Grab text from SlideListWithTexts entries
-               int i=0;
-               for(HSLFTextParagraph tp : textParagraphs) {
-                   _runs[i++] = tp;
-                       tp.supplySheet(this);
-               }
-               // Grab text from slide's PPDrawing
-               for(HSLFTextParagraph tp : _otherRuns) {
-                       _runs[i++] = tp;
-                       tp.supplySheet(this);
-            tp.setIndex(-1); // runs found in PPDrawing are not linked with SlideListWithTexts
-               }
-       }
-
-       /**
-       * Create a new Slide instance
-       * @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder
-       * @param slideNumber The user facing number of the sheet
-       */
-       public HSLFSlide(int sheetNumber, int sheetRefId, int slideNumber){
-               super(new org.apache.poi.hslf.record.Slide(), sheetNumber);
-               _slideNo = slideNumber;
-        getSheetContainer().setSheetId(sheetRefId);
-       }
-
-       /**
-        * Sets the Notes that are associated with this. Updates the
-        *  references in the records to point to the new ID
-        */
-       public void setNotes(HSLFNotes notes) {
-               _notes = notes;
-
-               // Update the Slide Atom's ID of where to point to
-               SlideAtom sa = getSlideRecord().getSlideAtom();
-
-               if(notes == null) {
-                       // Set to 0
-                       sa.setNotesID(0);
-               } else {
-                       // Set to the value from the notes' sheet id
-                       sa.setNotesID(notes._getSheetNumber());
-               }
-       }
-
-       /**
-       * Changes the Slide's (external facing) page number.
-       * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#reorderSlide(int, int)
-       */
-       public void setSlideNumber(int newSlideNumber) {
-               _slideNo = newSlideNumber;
-       }
-
-    /**
-     * Called by SlideShow ater a new slide is created.
-     * <p>
-     * For Slide we need to do the following:
-     *  <li> set id of the drawing group.
-     *  <li> set shapeId for the container descriptor and background
-     * </p>
-     */
-    public void onCreate(){
-        //initialize drawing group id
-        EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
-        EscherContainerRecord dgContainer = (EscherContainerRecord)getSheetContainer().getPPDrawing().getEscherRecords()[0];
-        EscherDgRecord dg = (EscherDgRecord) HSLFShape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
-        int dgId = dgg.getMaxDrawingGroupId() + 1;
-        dg.setOptions((short)(dgId << 4));
-        dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
-        dgg.setMaxDrawingGroupId(dgId);
-
-        for (EscherContainerRecord c : dgContainer.getChildContainers()) {
-            EscherSpRecord spr = null;
-            switch(c.getRecordId()){
-                case EscherContainerRecord.SPGR_CONTAINER:
-                    EscherContainerRecord dc = (EscherContainerRecord)c.getChild(0);
-                    spr = dc.getChildById(EscherSpRecord.RECORD_ID);
-                    break;
-                case EscherContainerRecord.SP_CONTAINER:
-                    spr = c.getChildById(EscherSpRecord.RECORD_ID);
-                    break;
-            }
-            if(spr != null) spr.setShapeId(allocateShapeId());
-        }
-
-        //PPT doen't increment the number of saved shapes for group descriptor and background
-        dg.setNumShapes(1);
-    }
-
-       /**
-        * Create a <code>TextBox</code> object that represents the slide's title.
-        *
-        * @return <code>TextBox</code> object that represents the slide's title.
-        */
-       public HSLFTextBox addTitle() {
-               Placeholder pl = new Placeholder();
-               pl.setShapeType(ShapeType.RECT);
-               pl.getTextParagraph().setRunType(TextHeaderAtom.TITLE_TYPE);
-               pl.setText("Click to edit title");
-               pl.setAnchor(new java.awt.Rectangle(54, 48, 612, 90));
-               addShape(pl);
-               return pl;
-       }
-
-
-       // Complex Accesser methods follow
-
-       /**
-        * Return title of this slide or <code>null</code> if the slide does not have title.
-        * <p>
-        * The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
-        * <code>TextHeaderAtom.TITLE_TYPE</code>
-        * </p>
-        *
-        * @see TextHeaderAtom
-        *
-        * @return title of this slide
-        */
-       public String getTitle(){
-               HSLFTextParagraph[] txt = getTextRuns();
-               for (int i = 0; i < txt.length; i++) {
-                       int type = txt[i].getRunType();
-                       if (type == TextHeaderAtom.CENTER_TITLE_TYPE ||
-                       type == TextHeaderAtom.TITLE_TYPE ){
-                               String title = txt[i].getText();
-                               return title;
-                       }
-               }
-               return null;
-       }
-
-       // Simple Accesser methods follow
-
-       /**
-        * Returns an array of all the TextRuns found
-        */
-       public HSLFTextParagraph[] getTextRuns() { return _runs; }
-
-       /**
-        * Returns the (public facing) page number of this slide
-        */
-       public int getSlideNumber() { return _slideNo; }
-
-       /**
-        * Returns the underlying slide record
-        */
-       public org.apache.poi.hslf.record.Slide getSlideRecord() {
-        return (org.apache.poi.hslf.record.Slide)getSheetContainer();
-    }
-
-       /**
-        * Returns the Notes Sheet for this slide, or null if there isn't one
-        */
-       public HSLFNotes getNotesSheet() { return _notes; }
-
-       /**
-        * @return set of records inside <code>SlideListWithtext</code> container
-        *  which hold text data for this slide (typically for placeholders).
-        */
-       protected SlideAtomsSet getSlideAtomsSet() { return _atomSet;  }
-
-    /**
-     * Returns master sheet associated with this slide.
-     * It can be either SlideMaster or TitleMaster objects.
-     *
-     * @return the master sheet associated with this slide.
-     */
-     public HSLFMasterSheet getMasterSheet(){
-        SlideMaster[] master = getSlideShow().getSlidesMasters();
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        int masterId = sa.getMasterID();
-        HSLFMasterSheet sheet = null;
-        for (int i = 0; i < master.length; i++) {
-            if (masterId == master[i]._getSheetNumber()) {
-                sheet = master[i];
-                break;
-            }
-        }
-        if (sheet == null){
-            TitleMaster[] titleMaster = getSlideShow().getTitleMasters();
-            if(titleMaster != null) for (int i = 0; i < titleMaster.length; i++) {
-                if (masterId == titleMaster[i]._getSheetNumber()) {
-                    sheet = titleMaster[i];
-                    break;
-                }
-            }
-        }
-        return sheet;
-    }
-
-    /**
-     * Change Master of this slide.
-     */
-    public void setMasterSheet(HSLFMasterSheet master){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        int sheetNo = master._getSheetNumber();
-        sa.setMasterID(sheetNo);
-    }
-
-    /**
-     * Sets whether this slide follows master background
-     *
-     * @param flag  <code>true</code> if the slide follows master,
-     * <code>false</code> otherwise
-     */
-    public void setFollowMasterBackground(boolean flag){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        sa.setFollowMasterBackground(flag);
-    }
-
-    /**
-     * Whether this slide follows master sheet background
-     *
-     * @return <code>true</code> if the slide follows master background,
-     * <code>false</code> otherwise
-     */
-    public boolean getFollowMasterBackground(){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        return sa.getFollowMasterBackground();
-    }
-
-    /**
-     * Sets whether this slide draws master sheet objects
-     *
-     * @param flag  <code>true</code> if the slide draws master sheet objects,
-     * <code>false</code> otherwise
-     */
-    public void setFollowMasterObjects(boolean flag){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        sa.setFollowMasterObjects(flag);
-    }
-
-    /**
-     * Whether this slide follows master color scheme
-     *
-     * @return <code>true</code> if the slide follows master color scheme,
-     * <code>false</code> otherwise
-     */
-    public boolean getFollowMasterScheme(){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        return sa.getFollowMasterScheme();
-    }
-
-    /**
-     * Sets whether this slide draws master color scheme
-     *
-     * @param flag  <code>true</code> if the slide draws master color scheme,
-     * <code>false</code> otherwise
-     */
-    public void setFollowMasterScheme(boolean flag){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        sa.setFollowMasterScheme(flag);
-    }
-
-    /**
-     * Whether this slide draws master sheet objects
-     *
-     * @return <code>true</code> if the slide draws master sheet objects,
-     * <code>false</code> otherwise
-     */
-    public boolean getFollowMasterObjects(){
-        SlideAtom sa = getSlideRecord().getSlideAtom();
-        return sa.getFollowMasterObjects();
-    }
-
-    /**
-     * Background for this slide.
-     */
-     public HSLFBackground getBackground() {
-        if(getFollowMasterBackground()) {
-            return getMasterSheet().getBackground();
-        }
-        return super.getBackground();
-    }
-
-    /**
-     * Color scheme for this slide.
-     */
-    public ColorSchemeAtom getColorScheme() {
-        if(getFollowMasterScheme()){
-            return getMasterSheet().getColorScheme();
-        }
-        return super.getColorScheme();
-    }
-
-    /**
-     * Get the comment(s) for this slide.
-     * Note - for now, only works on PPT 2000 and
-     *  PPT 2003 files. Doesn't work for PPT 97
-     *  ones, as they do their comments oddly.
-     */
-    public Comment[] getComments() {
-       // If there are any, they're in
-       //  ProgTags -> ProgBinaryTag -> BinaryTagData
-       RecordContainer progTags = (RecordContainer)
-                       getSheetContainer().findFirstOfType(
-                                               RecordTypes.ProgTags.typeID
-       );
-       if(progTags != null) {
-               RecordContainer progBinaryTag = (RecordContainer)
-                       progTags.findFirstOfType(
-                                       RecordTypes.ProgBinaryTag.typeID
-               );
-               if(progBinaryTag != null) {
-                       RecordContainer binaryTags = (RecordContainer)
-                               progBinaryTag.findFirstOfType(
-                                               RecordTypes.BinaryTagData.typeID
-                       );
-                       if(binaryTags != null) {
-                               // This is where they'll be
-                               int count = 0;
-                               for(int i=0; i<binaryTags.getChildRecords().length; i++) {
-                                       if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
-                                               count++;
-                                       }
-                               }
-
-                               // Now build
-                               Comment[] comments = new Comment[count];
-                               count = 0;
-                               for(int i=0; i<binaryTags.getChildRecords().length; i++) {
-                                       if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
-                                               comments[i] = new Comment(
-                                                               (Comment2000)binaryTags.getChildRecords()[i]
-                                               );
-                                               count++;
-                                       }
-                               }
-
-                               return comments;
-                       }
-               }
-       }
-
-       // None found
-       return new Comment[0];
-    }
-
-    public void draw(Graphics2D graphics){
-        HSLFMasterSheet master = getMasterSheet();
-        HSLFBackground bg = getBackground();
-        if(bg != null)bg.draw(graphics);
-
-        if(getFollowMasterObjects()){
-            HSLFShape[] sh = master.getShapes();
-            for (int i = 0; i < sh.length; i++) {
-                if(HSLFMasterSheet.isPlaceholder(sh[i])) continue;
-
-                sh[i].draw(graphics);
-            }
-        }
-
-        HSLFShape[] sh = getShapes();
-        for (int i = 0; i < sh.length; i++) {
-            sh[i].draw(graphics);
-        }
-    }
-
-    /**
-     * Header / Footer settings for this slide.
-     *
-     * @return Header / Footer settings for this slide
-     */
-     public HeadersFooters getHeadersFooters(){
-        HeadersFootersContainer hdd = null;
-        Record[] ch = getSheetContainer().getChildRecords();
-        boolean ppt2007 = false;
-        for (int i = 0; i < ch.length; i++) {
-            if(ch[i] instanceof HeadersFootersContainer){
-                hdd = (HeadersFootersContainer)ch[i];
-            } else if (ch[i].getRecordType() == RecordTypes.RoundTripContentMasterId.typeID){
-                ppt2007 = true;
-            }
-        }
-        boolean newRecord = false;
-        if(hdd == null && !ppt2007) {
-            return getSlideShow().getSlideHeadersFooters();
-        }
-        if(hdd == null) {
-            hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
-            newRecord = true;
-        }
-        return new HeadersFooters(hdd, this, newRecord, ppt2007);
-    }
-
-    protected void onAddTextShape(HSLFTextShape shape) {
-        HSLFTextParagraph run = shape.getTextParagraph();
-
-        if(_runs == null) _runs = new HSLFTextParagraph[]{run};
-        else {
-            HSLFTextParagraph[] tmp = new HSLFTextParagraph[_runs.length + 1];
-            System.arraycopy(_runs, 0, tmp, 0, _runs.length);
-            tmp[tmp.length-1] = run;
-            _runs = tmp;
-        }
-    }
-
-    /** This will return an atom per TextBox, so if the page has two text boxes the method should return two atoms. */
-    public StyleTextProp9Atom[] getNumberedListInfo() {
-       return this.getPPDrawing().getNumberedListInfo();
-    }
-
-       public EscherTextboxWrapper[] getTextboxWrappers() {
-               return this.getPPDrawing().getTextboxWrappers();
-       }
-
-       public void setHidden(boolean hidden) {
-               org.apache.poi.hslf.record.Slide cont = getSlideRecord();
-               
-               SSSlideInfoAtom slideInfo = 
-                       (SSSlideInfoAtom)cont.findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
-               if (slideInfo == null) {
-                       slideInfo = new SSSlideInfoAtom();
-                       cont.addChildAfter(slideInfo, cont.findFirstOfType(RecordTypes.SlideAtom.typeID));
-               }
-               
-               slideInfo.setEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT, hidden);
-       }
-       
-       public boolean getHidden() {
-               SSSlideInfoAtom slideInfo = 
-                       (SSSlideInfoAtom)getSlideRecord().findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
-               return (slideInfo == null)
-                       ? false
-                       : slideInfo.getEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT);
-       }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowEncrypted.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowEncrypted.java
deleted file mode 100644 (file)
index 803aeac..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* ====================================================================
-   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.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.TreeMap;
-
-import javax.crypto.Cipher;
-import javax.crypto.CipherOutputStream;
-
-import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
-import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
-import org.apache.poi.hslf.record.DocumentEncryptionAtom;
-import org.apache.poi.hslf.record.PersistPtrHolder;
-import org.apache.poi.hslf.record.PositionDependentRecord;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.UserEditAtom;
-import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
-import org.apache.poi.poifs.crypt.Decryptor;
-import org.apache.poi.poifs.crypt.EncryptionInfo;
-import org.apache.poi.poifs.crypt.Encryptor;
-import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor;
-import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.Internal;
-import org.apache.poi.util.LittleEndian;
-
-/**
- * This class provides helper functions for encrypted PowerPoint documents.
- */
-@Internal
-public class HSLFSlideShowEncrypted {
-    DocumentEncryptionAtom dea;
-    CryptoAPIEncryptor enc = null;
-    CryptoAPIDecryptor dec = null;
-    Cipher cipher = null;
-    CipherOutputStream cyos = null;
-
-    private static final BitField fieldRecInst = new BitField(0xFFF0);
-    
-    protected HSLFSlideShowEncrypted(DocumentEncryptionAtom dea) {
-        this.dea = dea;
-    }
-
-    protected HSLFSlideShowEncrypted(byte[] docstream, NavigableMap<Integer,Record> recordMap) {
-        // check for DocumentEncryptionAtom, which would be at the last offset
-        // need to ignore already set UserEdit and PersistAtoms
-        UserEditAtom userEditAtomWithEncryption = null;
-        for (Map.Entry<Integer, Record> me : recordMap.descendingMap().entrySet()) {
-            Record r = me.getValue();
-            if (!(r instanceof UserEditAtom)) continue;
-            UserEditAtom uea = (UserEditAtom)r;
-            if (uea.getEncryptSessionPersistIdRef() != -1) {
-                userEditAtomWithEncryption = uea;
-                break;
-            }
-        }
-
-        if (userEditAtomWithEncryption == null) {
-            dea = null;
-            return;
-        }
-
-        Record r = recordMap.get(userEditAtomWithEncryption.getPersistPointersOffset());
-        assert(r instanceof PersistPtrHolder);
-        PersistPtrHolder ptr = (PersistPtrHolder)r;
-        
-        Integer encOffset = ptr.getSlideLocationsLookup().get(userEditAtomWithEncryption.getEncryptSessionPersistIdRef());
-        assert(encOffset != null);
-        
-        r = recordMap.get(encOffset);
-        if (r == null) {
-            r = Record.buildRecordAtOffset(docstream, encOffset);
-            recordMap.put(encOffset, r);
-        }
-        assert(r instanceof DocumentEncryptionAtom);
-        this.dea = (DocumentEncryptionAtom)r;
-        
-        CryptoAPIDecryptor dec = (CryptoAPIDecryptor)dea.getEncryptionInfo().getDecryptor();
-        String pass = Biff8EncryptionKey.getCurrentUserPassword();
-        if(!dec.verifyPassword(pass != null ? pass : Decryptor.DEFAULT_PASSWORD)) {
-            throw new EncryptedPowerPointFileException("PowerPoint file is encrypted. The correct password needs to be set via Biff8EncryptionKey.setCurrentUserPassword()");
-        }
-     }
-
-    public DocumentEncryptionAtom getDocumentEncryptionAtom() {
-        return dea;
-    }
-    
-    protected void setPersistId(int persistId) {
-        if (enc != null && dec != null) {
-            throw new EncryptedPowerPointFileException("Use instance either for en- or decryption");
-        }
-        
-        try {
-            if (enc != null) cipher = enc.initCipherForBlock(cipher, persistId);
-            if (dec != null) cipher = dec.initCipherForBlock(cipher, persistId);
-        } catch (GeneralSecurityException e) {
-            throw new EncryptedPowerPointFileException(e);
-        }
-    }
-    
-    protected void decryptInit() {
-        if (dec != null) return;
-        EncryptionInfo ei = dea.getEncryptionInfo();
-        dec = (CryptoAPIDecryptor)ei.getDecryptor();
-    }
-    
-    protected void encryptInit() {
-        if (enc != null) return;
-        EncryptionInfo ei = dea.getEncryptionInfo();
-        enc = (CryptoAPIEncryptor)ei.getEncryptor();
-    }
-    
-
-    
-    protected OutputStream encryptRecord(OutputStream plainStream, int persistId, Record record) {
-        boolean isPlain = (dea == null 
-            || record instanceof UserEditAtom
-            || record instanceof PersistPtrHolder
-            || record instanceof DocumentEncryptionAtom
-        );
-        if (isPlain) return plainStream;
-
-        encryptInit();
-        setPersistId(persistId);
-        
-        if (cyos == null) {
-            cyos = new CipherOutputStream(plainStream, cipher);
-        }
-        return cyos;
-    }
-
-    protected void decryptRecord(byte[] docstream, int persistId, int offset) {
-        if (dea == null) return;
-
-        decryptInit();
-        setPersistId(persistId);
-        
-        try {
-            // decrypt header and read length to be decrypted
-            cipher.update(docstream, offset, 8, docstream, offset);
-            // decrypt the rest of the record
-            int rlen = (int)LittleEndian.getUInt(docstream, offset+4);
-            cipher.update(docstream, offset+8, rlen, docstream, offset+8);
-        } catch (GeneralSecurityException e) {
-            throw new CorruptPowerPointFileException(e);
-        }       
-    }        
-    
-    protected void decryptPicture(byte[] pictstream, int offset) {
-        if (dea == null) return;
-        
-        decryptInit();
-        setPersistId(0);
-        
-        try {
-            // decrypt header and read length to be decrypted
-            cipher.doFinal(pictstream, offset, 8, pictstream, offset);
-            int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
-            int recType = LittleEndian.getUShort(pictstream, offset+2);
-            int rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
-            offset += 8;
-            int endOffset = offset + rlen; 
-
-            if (recType == 0xF007) {
-                // TOOD: get a real example file ... to actual test the FBSE entry
-                // not sure where the foDelay block is
-                
-                // File BLIP Store Entry (FBSE)
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btWin32
-                offset++;
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btMacOS
-                offset++;
-                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid
-                offset += 16;
-                cipher.doFinal(pictstream, offset, 2, pictstream, offset); // tag
-                offset += 2;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // size
-                offset += 4;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // cRef
-                offset += 4;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // foDelay
-                offset += 4;
-                cipher.doFinal(pictstream, offset+0, 1, pictstream, offset+0); // unused1
-                cipher.doFinal(pictstream, offset+1, 1, pictstream, offset+1); // cbName
-                cipher.doFinal(pictstream, offset+2, 1, pictstream, offset+2); // unused2
-                cipher.doFinal(pictstream, offset+3, 1, pictstream, offset+3); // unused3
-                int cbName = LittleEndian.getUShort(pictstream, offset+1);
-                offset += 4;
-                if (cbName > 0) {
-                    cipher.doFinal(pictstream, offset, cbName, pictstream, offset); // nameData
-                    offset += cbName;
-                }
-                if (offset == endOffset) {
-                    return; // no embedded blip
-                }
-                // fall through, read embedded blip now
-
-                // update header data
-                cipher.doFinal(pictstream, offset, 8, pictstream, offset);
-                recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
-                recType = LittleEndian.getUShort(pictstream, offset+2);
-                rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
-                offset += 8;
-            }
-
-            int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 ||
-                recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1;
-            
-            for (int i=0; i<rgbUidCnt; i++) {
-                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid 1/2
-                offset += 16;
-            }
-            
-            if (recType == 0xF01A || recType == 0XF01B || recType == 0XF01C) {
-                cipher.doFinal(pictstream, offset, 34, pictstream, offset); // metafileHeader
-                offset += 34;
-            } else {
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // tag
-                offset += 1;
-            }
-            
-            int blipLen = endOffset - offset;
-            cipher.doFinal(pictstream, offset, blipLen, pictstream, offset);
-        } catch (GeneralSecurityException e) {
-            throw new CorruptPowerPointFileException(e);
-        }       
-    }
-
-    protected void encryptPicture(byte[] pictstream, int offset) {
-        if (dea == null) return;
-        
-        encryptInit();
-        setPersistId(0);
-
-        try {
-            int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
-            int recType = LittleEndian.getUShort(pictstream, offset+2);
-            int rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
-            cipher.doFinal(pictstream, offset, 8, pictstream, offset);
-            offset += 8;
-            int endOffset = offset + rlen; 
-
-            if (recType == 0xF007) {
-                // TOOD: get a real example file ... to actual test the FBSE entry
-                // not sure where the foDelay block is
-                
-                // File BLIP Store Entry (FBSE)
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btWin32
-                offset++;
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btMacOS
-                offset++;
-                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid
-                offset += 16;
-                cipher.doFinal(pictstream, offset, 2, pictstream, offset); // tag
-                offset += 2;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // size
-                offset += 4;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // cRef
-                offset += 4;
-                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // foDelay
-                offset += 4;
-                int cbName = LittleEndian.getUShort(pictstream, offset+1);
-                cipher.doFinal(pictstream, offset+0, 1, pictstream, offset+0); // unused1
-                cipher.doFinal(pictstream, offset+1, 1, pictstream, offset+1); // cbName
-                cipher.doFinal(pictstream, offset+2, 1, pictstream, offset+2); // unused2
-                cipher.doFinal(pictstream, offset+3, 1, pictstream, offset+3); // unused3
-                offset += 4;
-                if (cbName > 0) {
-                    cipher.doFinal(pictstream, offset, cbName, pictstream, offset); // nameData
-                    offset += cbName;
-                }
-                if (offset == endOffset) {
-                    return; // no embedded blip
-                }
-                // fall through, read embedded blip now
-
-                // update header data
-                recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
-                recType = LittleEndian.getUShort(pictstream, offset+2);
-                rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
-                cipher.doFinal(pictstream, offset, 8, pictstream, offset);
-                offset += 8;
-            }
-            
-            int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 ||
-                recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1;
-                
-            for (int i=0; i<rgbUidCnt; i++) {
-                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid 1/2
-                offset += 16;
-            }
-            
-            if (recType == 0xF01A || recType == 0XF01B || recType == 0XF01C) {
-                cipher.doFinal(pictstream, offset, 34, pictstream, offset); // metafileHeader
-                offset += 34;
-            } else {
-                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // tag
-                offset += 1;
-            }
-            
-            int blipLen = endOffset - offset;
-            cipher.doFinal(pictstream, offset, blipLen, pictstream, offset);
-        } catch (GeneralSecurityException e) {
-            throw new CorruptPowerPointFileException(e);
-        }       
-    }
-
-    protected Record[] updateEncryptionRecord(Record records[]) {
-        String password = Biff8EncryptionKey.getCurrentUserPassword();
-        if (password == null) {
-            if (dea == null) {
-                // no password given, no encryption record exits -> done
-                return records;
-            } else {
-                // need to remove password data
-                dea = null;
-                return removeEncryptionRecord(records);
-            }
-        } else {
-            // create password record
-            if (dea == null) {
-                dea = new DocumentEncryptionAtom();
-            }
-            EncryptionInfo ei = dea.getEncryptionInfo();
-            byte salt[] = ei.getVerifier().getSalt();
-            Encryptor enc = ei.getEncryptor();
-            if (salt == null) {
-                enc.confirmPassword(password);
-            } else {
-                byte verifier[] = ei.getDecryptor().getVerifier();
-                enc.confirmPassword(password, null, null, verifier, salt, null);
-            }
-
-            // move EncryptionRecord to last slide position
-            records = normalizeRecords(records);
-            return addEncryptionRecord(records, dea);
-        }
-    }
-
-    /**
-     * remove duplicated UserEditAtoms and merge PersistPtrHolder.
-     * Before this method is called, make sure that the offsets are correct,
-     * i.e. call {@link HSLFSlideShowImpl#updateAndWriteDependantRecords(OutputStream, Map)}
-     */
-    protected static Record[] normalizeRecords(Record records[]) {
-        // http://msdn.microsoft.com/en-us/library/office/gg615594(v=office.14).aspx
-        // repeated slideIds can be overwritten, i.e. ignored
-        
-        UserEditAtom uea = null;
-        PersistPtrHolder pph = null;
-        TreeMap<Integer,Integer> slideLocations = new TreeMap<Integer,Integer>();
-        TreeMap<Integer,Record> recordMap = new TreeMap<Integer,Record>();
-        List<Integer> obsoleteOffsets = new ArrayList<Integer>();
-        int duplicatedCount = 0;
-        for (Record r : records) {
-            assert(r instanceof PositionDependentRecord);
-            PositionDependentRecord pdr = (PositionDependentRecord)r;
-            if (pdr instanceof UserEditAtom) {
-                uea = (UserEditAtom)pdr;
-                continue;
-            }
-            
-            if (pdr instanceof PersistPtrHolder) {
-                if (pph != null) {
-                    duplicatedCount++;
-                }
-                pph = (PersistPtrHolder)pdr;
-                for (Map.Entry<Integer,Integer> me : pph.getSlideLocationsLookup().entrySet()) {
-                    Integer oldOffset = slideLocations.put(me.getKey(), me.getValue());
-                    if (oldOffset != null) obsoleteOffsets.add(oldOffset);
-                }
-                continue;
-            }
-            
-            recordMap.put(pdr.getLastOnDiskOffset(), r);
-        }
-        recordMap.put(pph.getLastOnDiskOffset(), pph);
-        recordMap.put(uea.getLastOnDiskOffset(), uea);
-
-        assert(uea != null && pph != null && uea.getPersistPointersOffset() == pph.getLastOnDiskOffset());
-        
-        if (duplicatedCount == 0 && obsoleteOffsets.isEmpty()) {
-            return records;
-        }
-
-        uea.setLastUserEditAtomOffset(0);
-        pph.clear();
-        for (Map.Entry<Integer,Integer> me : slideLocations.entrySet()) {
-            pph.addSlideLookup(me.getKey(), me.getValue());
-        }
-        
-        for (Integer oldOffset : obsoleteOffsets) {
-            recordMap.remove(oldOffset);
-        }
-        
-        return recordMap.values().toArray(new Record[recordMap.size()]);
-    }
-     
-    
-    protected static Record[] removeEncryptionRecord(Record records[]) {
-        int deaSlideId = -1;
-        int deaOffset = -1;
-        PersistPtrHolder ptr = null;
-        UserEditAtom uea = null;
-        List<Record> recordList = new ArrayList<Record>();
-        for (Record r : records) {
-            if (r instanceof DocumentEncryptionAtom) {
-                deaOffset = ((DocumentEncryptionAtom)r).getLastOnDiskOffset();
-                continue;
-            } else if (r instanceof UserEditAtom) {
-                uea = (UserEditAtom)r;
-                deaSlideId = uea.getEncryptSessionPersistIdRef();
-                uea.setEncryptSessionPersistIdRef(-1);
-            } else if (r instanceof PersistPtrHolder) {
-                ptr = (PersistPtrHolder)r;
-            }
-            recordList.add(r);
-        }
-        
-        assert(ptr != null);
-        if (deaSlideId == -1 && deaOffset == -1) return records;
-        
-        TreeMap<Integer,Integer> tm = new TreeMap<Integer,Integer>(ptr.getSlideLocationsLookup());
-        ptr.clear();
-        int maxSlideId = -1;
-        for (Map.Entry<Integer,Integer> me : tm.entrySet()) {
-            if (me.getKey() == deaSlideId || me.getValue() == deaOffset) continue;
-            ptr.addSlideLookup(me.getKey(), me.getValue());
-            maxSlideId = Math.max(me.getKey(), maxSlideId);
-        }
-        
-        uea.setMaxPersistWritten(maxSlideId);
-
-        records = recordList.toArray(new Record[recordList.size()]);
-        
-        return records;
-    }
-
-
-    protected static Record[] addEncryptionRecord(Record records[], DocumentEncryptionAtom dea) {
-        assert(dea != null);
-        int ueaIdx = -1, ptrIdx = -1, deaIdx = -1, idx = -1;
-        for (Record r : records) {
-            idx++;
-            if (r instanceof UserEditAtom) ueaIdx = idx;
-            else if (r instanceof PersistPtrHolder) ptrIdx = idx;
-            else if (r instanceof DocumentEncryptionAtom) deaIdx = idx;
-        }
-        assert(ueaIdx != -1 && ptrIdx != -1 && ptrIdx < ueaIdx);
-        if (deaIdx != -1) {
-            DocumentEncryptionAtom deaOld = (DocumentEncryptionAtom)records[deaIdx];
-            dea.setLastOnDiskOffset(deaOld.getLastOnDiskOffset());
-            records[deaIdx] = dea;
-            return records;
-        } else {
-            PersistPtrHolder ptr = (PersistPtrHolder)records[ptrIdx];
-            UserEditAtom uea = ((UserEditAtom)records[ueaIdx]);
-            dea.setLastOnDiskOffset(ptr.getLastOnDiskOffset()-1);
-            int nextSlideId = uea.getMaxPersistWritten()+1;
-            ptr.addSlideLookup(nextSlideId, ptr.getLastOnDiskOffset()-1);
-            uea.setEncryptSessionPersistIdRef(nextSlideId);
-            uea.setMaxPersistWritten(nextSlideId);
-            
-            Record newRecords[] = new Record[records.length+1];
-            if (ptrIdx > 0) System.arraycopy(records, 0, newRecords, 0, ptrIdx);
-            if (ptrIdx < records.length-1) System.arraycopy(records, ptrIdx, newRecords, ptrIdx+1, records.length-ptrIdx);
-            newRecords[ptrIdx] = dea;
-            return newRecords;
-        }
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowImpl.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFSlideShowImpl.java
deleted file mode 100644 (file)
index 48e52da..0000000
+++ /dev/null
@@ -1,808 +0,0 @@
-/* ====================================================================
-   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.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.TreeMap;
-
-import org.apache.poi.POIDocument;
-import org.apache.poi.hpsf.PropertySet;
-import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
-import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.record.CurrentUserAtom;
-import org.apache.poi.hslf.record.DocumentEncryptionAtom;
-import org.apache.poi.hslf.record.ExOleObjStg;
-import org.apache.poi.hslf.record.PersistPtrHolder;
-import org.apache.poi.hslf.record.PersistRecord;
-import org.apache.poi.hslf.record.PositionDependentRecord;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.UserEditAtom;
-import org.apache.poi.hslf.usermodel.HSLFObjectData;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor;
-import org.apache.poi.poifs.filesystem.DirectoryNode;
-import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.poifs.filesystem.DocumentInputStream;
-import org.apache.poi.poifs.filesystem.EntryUtils;
-import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * This class contains the main functionality for the Powerpoint file
- * "reader". It is only a very basic class for now
- *
- * @author Nick Burch
- */
-public final class HSLFSlideShowImpl extends POIDocument {
-    public static final int UNSET_OFFSET = -1;
-    
-    // For logging
-    private POILogger logger = POILogFactory.getLogger(this.getClass());
-
-       // Holds metadata on where things are in our document
-       private CurrentUserAtom currentUser;
-
-       // Low level contents of the file
-       private byte[] _docstream;
-
-       // Low level contents
-       private Record[] _records;
-
-       // Raw Pictures contained in the pictures stream
-       private List<HSLFPictureData> _pictures;
-
-    // Embedded objects stored in storage records in the document stream, lazily populated.
-    private HSLFObjectData[] _objects;
-    
-    /**
-        * Returns the underlying POIFSFileSystem for the document
-        *  that is open.
-        */
-       protected POIFSFileSystem getPOIFSFileSystem() {
-               return directory.getFileSystem();
-       }
-
-   /**
-    * Returns the directory in the underlying POIFSFileSystem for the 
-    *  document that is open.
-    */
-   protected DirectoryNode getPOIFSDirectory() {
-      return directory;
-   }
-
-       /**
-        * Constructs a Powerpoint document from fileName. Parses the document
-        * and places all the important stuff into data structures.
-        *
-        * @param fileName The name of the file to read.
-        * @throws IOException if there is a problem while parsing the document.
-        */
-       public HSLFSlideShowImpl(String fileName) throws IOException
-       {
-               this(new FileInputStream(fileName));
-       }
-
-       /**
-        * Constructs a Powerpoint document from an input stream. Parses the
-        * document and places all the important stuff into data structures.
-        *
-        * @param inputStream the source of the data
-        * @throws IOException if there is a problem while parsing the document.
-        */
-       public HSLFSlideShowImpl(InputStream inputStream) throws IOException {
-               //do Ole stuff
-               this(new POIFSFileSystem(inputStream));
-       }
-
-       /**
-        * Constructs a Powerpoint document from a POIFS Filesystem. Parses the
-        * document and places all the important stuff into data structures.
-        *
-        * @param filesystem the POIFS FileSystem to read from
-        * @throws IOException if there is a problem while parsing the document.
-        */
-       public HSLFSlideShowImpl(POIFSFileSystem filesystem) throws IOException
-       {
-               this(filesystem.getRoot());
-       }
-
-   /**
-    * Constructs a Powerpoint document from a POIFS Filesystem. Parses the
-    * document and places all the important stuff into data structures.
-    *
-    * @param filesystem the POIFS FileSystem to read from
-    * @throws IOException if there is a problem while parsing the document.
-    */
-   public HSLFSlideShowImpl(NPOIFSFileSystem filesystem) throws IOException
-   {
-      this(filesystem.getRoot());
-   }
-
-   /**
-    * Constructs a Powerpoint document from a specific point in a
-    *  POIFS Filesystem. Parses the document and places all the
-    *  important stuff into data structures.
-    *
-    * @deprecated Use {@link #HSLFSlideShow(DirectoryNode)} instead
-    * @param dir the POIFS directory to read from
-    * @param filesystem the POIFS FileSystem to read from
-    * @throws IOException if there is a problem while parsing the document.
-    */
-       @Deprecated
-   public HSLFSlideShowImpl(DirectoryNode dir, POIFSFileSystem filesystem) throws IOException
-   {
-      this(dir);
-   }
-   
-       /**
-        * Constructs a Powerpoint document from a specific point in a
-        *  POIFS Filesystem. Parses the document and places all the
-        *  important stuff into data structures.
-        *
-        * @param dir the POIFS directory to read from
-        * @throws IOException if there is a problem while parsing the document.
-        */
-       public HSLFSlideShowImpl(DirectoryNode dir) throws IOException {
-               super(handleDualStorage(dir));
-
-               // First up, grab the "Current User" stream
-               // We need this before we can detect Encrypted Documents
-               readCurrentUserStream();
-
-               // Next up, grab the data that makes up the
-               //  PowerPoint stream
-               readPowerPointStream();
-
-               // Now, build records based on the PowerPoint stream
-               buildRecords();
-
-               // Look for any other streams
-               readOtherStreams();
-       }
-       
-       private static DirectoryNode handleDualStorage(DirectoryNode dir) throws IOException {
-           // when there's a dual storage entry, use it, as the outer document can't be read quite probably ...
-           String dualName = "PP97_DUALSTORAGE";
-           if (!dir.hasEntry(dualName)) return dir;
-           dir = (DirectoryNode)dir.getEntry(dualName);
-           return dir;
-       }
-       
-       /**
-        * Constructs a new, empty, Powerpoint document.
-        */
-       public static final HSLFSlideShowImpl create() {
-               InputStream is = HSLFSlideShowImpl.class.getResourceAsStream("data/empty.ppt");
-               if (is == null) {
-                       throw new RuntimeException("Missing resource 'empty.ppt'");
-               }
-               try {
-                       return new HSLFSlideShowImpl(is);
-               } catch (IOException e) {
-                       throw new RuntimeException(e);
-               }
-       }
-
-       /**
-        * Extracts the main PowerPoint document stream from the
-        *  POI file, ready to be passed
-        *
-        * @throws IOException
-        */
-       private void readPowerPointStream() throws IOException
-       {
-               // Get the main document stream
-               DocumentEntry docProps =
-                       (DocumentEntry)directory.getEntry("PowerPoint Document");
-
-               // Grab the document stream
-               _docstream = new byte[docProps.getSize()];
-               directory.createDocumentInputStream("PowerPoint Document").read(_docstream);
-       }
-
-       /**
-        * Builds the list of records, based on the contents
-        *  of the PowerPoint stream
-        */
-       private void buildRecords()
-       {
-               // The format of records in a powerpoint file are:
-               //   <little endian 2 byte "info">
-               //   <little endian 2 byte "type">
-               //   <little endian 4 byte "length">
-               // If it has a zero length, following it will be another record
-               //              <xx xx yy yy 00 00 00 00> <xx xx yy yy zz zz zz zz>
-               // If it has a length, depending on its type it may have children or data
-               // If it has children, these will follow straight away
-               //              <xx xx yy yy zz zz zz zz <xx xx yy yy zz zz zz zz>>
-               // If it has data, this will come straigh after, and run for the length
-               //      <xx xx yy yy zz zz zz zz dd dd dd dd dd dd dd>
-               // All lengths given exclude the 8 byte record header
-               // (Data records are known as Atoms)
-
-               // Document should start with:
-               //   0F 00 E8 03 ## ## ## ##
-           //     (type 1000 = document, info 00 0f is normal, rest is document length)
-               //   01 00 E9 03 28 00 00 00
-               //     (type 1001 = document atom, info 00 01 normal, 28 bytes long)
-               //   80 16 00 00 E0 10 00 00 xx xx xx xx xx xx xx xx
-               //   05 00 00 00 0A 00 00 00 xx xx xx
-               //     (the contents of the document atom, not sure what it means yet)
-               //   (records then follow)
-
-               // When parsing a document, look to see if you know about that type
-               //  of the current record. If you know it's a type that has children,
-               //  process the record's data area looking for more records
-               // If you know about the type and it doesn't have children, either do
-               //  something with the data (eg TextRun) or skip over it
-               // If you don't know about the type, play safe and skip over it (using
-               //  its length to know where the next record will start)
-               //
-
-        _records = read(_docstream, (int)currentUser.getCurrentEditOffset());
-       }
-
-       private Record[] read(byte[] docstream, int usrOffset){
-        //sort found records by offset.
-        //(it is not necessary but SlideShow.findMostRecentCoreRecords() expects them sorted)
-           NavigableMap<Integer,Record> records = new TreeMap<Integer,Record>(); // offset -> record
-        Map<Integer,Integer> persistIds = new HashMap<Integer,Integer>(); // offset -> persistId
-        initRecordOffsets(docstream, usrOffset, records, persistIds);
-        HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(docstream, records);
-        
-        for (Map.Entry<Integer,Record> entry : records.entrySet()) {
-            Integer offset = entry.getKey();
-            Record record = entry.getValue();
-            Integer persistId = persistIds.get(offset);
-            if (record == null) {
-                // all plain records have been already added,
-                // only new records need to be decrypted (tbd #35897)
-                decryptData.decryptRecord(docstream, persistId, offset);
-                record = Record.buildRecordAtOffset(docstream, offset);
-                entry.setValue(record);
-            }
-            
-            if (record instanceof PersistRecord) {
-                ((PersistRecord)record).setPersistId(persistId);
-            }            
-        }
-        
-        return records.values().toArray(new Record[records.size()]);
-    }
-
-    private void initRecordOffsets(byte[] docstream, int usrOffset, NavigableMap<Integer,Record> recordMap, Map<Integer,Integer> offset2id) {
-        while (usrOffset != 0){
-            UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset);
-            recordMap.put(usrOffset, usr);
-            
-            int psrOffset = usr.getPersistPointersOffset();
-            PersistPtrHolder ptr = (PersistPtrHolder)Record.buildRecordAtOffset(docstream, psrOffset);
-            recordMap.put(psrOffset, ptr);
-            
-            for(Map.Entry<Integer,Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
-                Integer offset = entry.getValue();
-                Integer id = entry.getKey();
-                recordMap.put(offset, null); // reserve a slot for the record
-                offset2id.put(offset, id);
-            }
-            
-            usrOffset = usr.getLastUserEditAtomOffset();
-
-            // check for corrupted user edit atom and try to repair it
-            // if the next user edit atom offset is already known, we would go into an endless loop
-            if (usrOffset > 0 && recordMap.containsKey(usrOffset)) {
-                // a user edit atom is usually located 36 byte before the smallest known record offset 
-                usrOffset = recordMap.firstKey()-36;
-                // check that we really are located on a user edit atom
-                int ver_inst = LittleEndian.getUShort(docstream, usrOffset);
-                int type = LittleEndian.getUShort(docstream, usrOffset+2);
-                int len = LittleEndian.getInt(docstream, usrOffset+4);
-                if (ver_inst == 0 && type == 4085 && (len == 0x1C || len == 0x20)) {
-                    logger.log(POILogger.WARN, "Repairing invalid user edit atom");
-                    usr.setLastUserEditAtomOffset(usrOffset);
-                } else {
-                    throw new CorruptPowerPointFileException("Powerpoint document contains invalid user edit atom");
-                }
-            }
-        }       
-    }
-
-    public DocumentEncryptionAtom getDocumentEncryptionAtom() {
-        for (Record r : _records) {
-            if (r instanceof DocumentEncryptionAtom) {
-                return (DocumentEncryptionAtom)r;
-            }
-        }
-        return null;
-    }
-    
-    
-       /**
-        * Find the "Current User" stream, and load it
-        */
-       private void readCurrentUserStream() {
-               try {
-                       currentUser = new CurrentUserAtom(directory);
-               } catch(IOException ie) {
-                       logger.log(POILogger.ERROR, "Error finding Current User Atom:\n" + ie);
-                       currentUser = new CurrentUserAtom();
-               }
-       }
-
-       /**
-        * Find any other streams from the filesystem, and load them
-        */
-       private void readOtherStreams() {
-               // Currently, there aren't any
-       }
-       
-       /**
-        * Find and read in pictures contained in this presentation.
-        * This is lazily called as and when we want to touch pictures.
-        */
-    @SuppressWarnings("unused")
-       private void readPictures() throws IOException {
-        _pictures = new ArrayList<HSLFPictureData>();
-
-        // if the presentation doesn't contain pictures - will use a null set instead
-        if (!directory.hasEntry("Pictures")) return;
-
-        HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
-        
-               DocumentEntry entry = (DocumentEntry)directory.getEntry("Pictures");
-               byte[] pictstream = new byte[entry.getSize()];
-               DocumentInputStream is = directory.createDocumentInputStream(entry);
-               is.read(pictstream);
-               is.close();
-
-               
-        int pos = 0;
-               // An empty picture record (length 0) will take up 8 bytes
-        while (pos <= (pictstream.length-8)) {
-            int offset = pos;
-
-            decryptData.decryptPicture(pictstream, offset);
-            
-            // Image signature
-            int signature = LittleEndian.getUShort(pictstream, pos);
-            pos += LittleEndian.SHORT_SIZE;
-            // Image type + 0xF018
-            int type = LittleEndian.getUShort(pictstream, pos);
-            pos += LittleEndian.SHORT_SIZE;
-            // Image size (excluding the 8 byte header)
-            int imgsize = LittleEndian.getInt(pictstream, pos);
-            pos += LittleEndian.INT_SIZE;
-
-            // When parsing the BStoreDelay stream, [MS-ODRAW] says that we
-            //  should terminate if the type isn't 0xf007 or 0xf018->0xf117
-            if (!((type == 0xf007) || (type >= 0xf018 && type <= 0xf117)))
-                break;
-
-                       // The image size must be 0 or greater
-                       // (0 is allowed, but odd, since we do wind on by the header each
-                       //  time, so we won't get stuck)
-                       if(imgsize < 0) {
-                               throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
-                       }
-
-                       // If they type (including the bonus 0xF018) is 0, skip it
-                       if(type == 0) {
-                               logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
-                               logger.log(POILogger.ERROR, "" + pos);
-                       } else {
-                               // Build the PictureData object from the data
-                               try {
-                                       HSLFPictureData pict = HSLFPictureData.create(type - 0xF018);
-
-                    // Copy the data, ready to pass to PictureData
-                    byte[] imgdata = new byte[imgsize];
-                    System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
-                    pict.setRawData(imgdata);
-
-                    pict.setOffset(offset);
-                                       _pictures.add(pict);
-                               } catch(IllegalArgumentException e) {
-                                       logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
-                               }
-                       }
-
-            pos += imgsize;
-        }
-       }
-    
-    /**
-     * remove duplicated UserEditAtoms and merge PersistPtrHolder, i.e.
-     * remove document edit history
-     */
-    public void normalizeRecords() {
-        try {
-            updateAndWriteDependantRecords(null, null);
-        } catch (IOException e) {
-            throw new CorruptPowerPointFileException(e);
-        }
-        _records = HSLFSlideShowEncrypted.normalizeRecords(_records);
-    }
-   
-    
-       /**
-     * This is a helper functions, which is needed for adding new position dependent records
-     * or finally write the slideshow to a file.
-        *
-        * @param os the stream to write to, if null only the references are updated
-        * @param interestingRecords a map of interesting records (PersistPtrHolder and UserEditAtom)
-        *        referenced by their RecordType. Only the very last of each type will be saved to the map.
-        *        May be null, if not needed. 
-        * @throws IOException
-        */
-       public void updateAndWriteDependantRecords(OutputStream os, Map<RecordTypes.Type,PositionDependentRecord> interestingRecords)
-       throws IOException {
-        // For position dependent records, hold where they were and now are
-        // As we go along, update, and hand over, to any Position Dependent
-        //  records we happen across
-        Hashtable<Integer,Integer> oldToNewPositions = new Hashtable<Integer,Integer>();
-
-        // First pass - figure out where all the position dependent
-        //   records are going to end up, in the new scheme
-        // (Annoyingly, some powerpoint files have PersistPtrHolders
-        //  that reference slides after the PersistPtrHolder)
-        UserEditAtom usr = null;
-        PersistPtrHolder ptr = null;
-        CountingOS cos = new CountingOS();
-        for (Record record : _records) {
-            // all top level records are position dependent
-            assert(record instanceof PositionDependentRecord);
-            PositionDependentRecord pdr = (PositionDependentRecord)record;
-            int oldPos = pdr.getLastOnDiskOffset();
-            int newPos = cos.size();
-            pdr.setLastOnDiskOffset(newPos);
-            if (oldPos != UNSET_OFFSET) {
-                // new records don't need a mapping, as they aren't in a relation yet
-                oldToNewPositions.put(oldPos,newPos);
-            }
-
-            // Grab interesting records as they come past
-            // this will only save the very last record of each type
-            RecordTypes.Type saveme = null;
-            int recordType = (int)record.getRecordType();
-            if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
-                saveme = RecordTypes.PersistPtrIncrementalBlock;
-                ptr = (PersistPtrHolder)pdr;
-            } else if (recordType == RecordTypes.UserEditAtom.typeID) {
-                saveme = RecordTypes.UserEditAtom;
-                usr = (UserEditAtom)pdr;
-            }
-            if (interestingRecords != null && saveme != null) {
-                interestingRecords.put(saveme,pdr);
-            }
-            
-            // Dummy write out, so the position winds on properly
-            record.writeOut(cos);
-        }
-        
-        assert(usr != null && ptr != null);
-        
-        Map<Integer,Integer> persistIds = new HashMap<Integer,Integer>();
-        for (Map.Entry<Integer,Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
-            persistIds.put(oldToNewPositions.get(entry.getValue()), entry.getKey());
-        }
-        
-        HSLFSlideShowEncrypted encData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
-           
-           for (Record record : _records) {
-            assert(record instanceof PositionDependentRecord);
-            // We've already figured out their new location, and
-            // told them that
-            // Tell them of the positions of the other records though
-            PositionDependentRecord pdr = (PositionDependentRecord)record;
-            Integer persistId = persistIds.get(pdr.getLastOnDiskOffset());
-            if (persistId == null) persistId = 0;
-            
-            // For now, we're only handling PositionDependentRecord's that
-            // happen at the top level.
-            // In future, we'll need the handle them everywhere, but that's
-            // a bit trickier
-            pdr.updateOtherRecordReferences(oldToNewPositions);
-            
-            // Whatever happens, write out that record tree
-            if (os != null) {
-                record.writeOut(encData.encryptRecord(os, persistId, record));
-            }
-        }
-
-        // Update and write out the Current User atom
-        int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset();
-        Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos);
-        if(usr == null || newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) {
-            throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos);
-        }
-        currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset());
-       }
-
-    /**
-     * Writes out the slideshow file the is represented by an instance
-     *  of this class.
-     * It will write out the common OLE2 streams. If you require all
-     *  streams to be written out, pass in preserveNodes
-     * @param out The OutputStream to write to.
-     * @throws IOException If there is an unexpected IOException from
-     *           the passed in OutputStream
-     */
-    public void write(OutputStream out) throws IOException {
-        // Write out, but only the common streams
-        write(out,false);
-    }
-    /**
-     * Writes out the slideshow file the is represented by an instance
-     *  of this class.
-     * If you require all streams to be written out (eg Marcos, embeded
-     *  documents), then set preserveNodes to true
-     * @param out The OutputStream to write to.
-     * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones?
-     * @throws IOException If there is an unexpected IOException from
-     *           the passed in OutputStream
-     */
-    public void write(OutputStream out, boolean preserveNodes) throws IOException {
-        // read properties and pictures, with old encryption settings where appropriate 
-        if(_pictures == null) {
-           readPictures();
-        }
-        getDocumentSummaryInformation();
-
-        // set new encryption settings
-        HSLFSlideShowEncrypted encryptedSS = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
-        _records = encryptedSS.updateEncryptionRecord(_records);
-
-        // Get a new Filesystem to write into
-        POIFSFileSystem outFS = new POIFSFileSystem();
-
-        // The list of entries we've written out
-        List<String> writtenEntries = new ArrayList<String>(1);
-
-        // Write out the Property Streams
-        writeProperties(outFS, writtenEntries);
-        
-        BufAccessBAOS baos = new BufAccessBAOS();
-
-        // For position dependent records, hold where they were and now are
-        // As we go along, update, and hand over, to any Position Dependent
-        // records we happen across
-        updateAndWriteDependantRecords(baos, null);
-
-        // Update our cached copy of the bytes that make up the PPT stream
-        _docstream = new byte[baos.size()];
-        System.arraycopy(baos.getBuf(), 0, _docstream, 0, baos.size());
-
-        // Write the PPT stream into the POIFS layer
-        ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
-        outFS.createDocument(bais,"PowerPoint Document");
-        writtenEntries.add("PowerPoint Document");
-        
-        currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null);
-        currentUser.writeToFS(outFS);
-        writtenEntries.add("Current User");
-
-
-        if (_pictures.size() > 0) {
-            BufAccessBAOS pict = new BufAccessBAOS();
-            for (HSLFPictureData p : _pictures) {
-                int offset = pict.size();
-                p.write(pict);
-                encryptedSS.encryptPicture(pict.getBuf(), offset);
-            }
-            outFS.createDocument(
-                new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures"
-            );
-            writtenEntries.add("Pictures");
-        }
-
-        // If requested, write out any other streams we spot
-        if(preserveNodes) {
-            EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries);
-        }
-
-        // Send the POIFSFileSystem object out to the underlying stream
-        outFS.writeFilesystem(out);
-    }
-
-    /** 
-     * For a given named property entry, either return it or null if
-     *  if it wasn't found
-     *  
-     *  @param setName The property to read
-     *  @return The value of the given property or null if it wasn't found.
-     */
-    protected PropertySet getPropertySet(String setName) {
-        DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
-        return (dea == null)
-            ? super.getPropertySet(setName)
-            : super.getPropertySet(setName, dea.getEncryptionInfo());
-    }
-
-    /**
-     * Writes out the standard Documment Information Properties (HPSF)
-     * @param outFS the POIFSFileSystem to write the properties into
-     * @param writtenEntries a list of POIFS entries to add the property names too
-     * 
-     * @throws IOException if an error when writing to the 
-     *      {@link POIFSFileSystem} occurs
-     */
-    protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
-        super.writeProperties(outFS, writtenEntries);
-        DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
-        if (dea != null) {
-            CryptoAPIEncryptor enc = (CryptoAPIEncryptor)dea.getEncryptionInfo().getEncryptor();
-            try {
-                enc.getDataStream(outFS.getRoot()); // ignore OutputStream
-            } catch (IOException e) {
-                throw e;
-            } catch (GeneralSecurityException e) {
-                throw new IOException(e);
-            }
-        }
-    }
-    
-    /* ******************* adding methods follow ********************* */
-
-       /**
-        * Adds a new root level record, at the end, but before the last
-        *  PersistPtrIncrementalBlock.
-        */
-       public synchronized int appendRootLevelRecord(Record newRecord) {
-               int addedAt = -1;
-               Record[] r = new Record[_records.length+1];
-               boolean added = false;
-               for(int i=(_records.length-1); i>=0; i--) {
-                       if(added) {
-                               // Just copy over
-                               r[i] = _records[i];
-                       } else {
-                               r[(i+1)] = _records[i];
-                               if(_records[i] instanceof PersistPtrHolder) {
-                                       r[i] = newRecord;
-                                       added = true;
-                                       addedAt = i;
-                               }
-                       }
-               }
-               _records = r;
-               return addedAt;
-       }
-
-       /**
-        * Add a new picture to this presentation.
-     *
-     * @return offset of this picture in the Pictures stream
-        */
-       public int addPicture(HSLFPictureData img) {
-          // Process any existing pictures if we haven't yet
-          if(_pictures == null) {
-         try {
-            readPictures();
-         } catch(IOException e) {
-            throw new CorruptPowerPointFileException(e.getMessage());
-         }
-          }
-          
-          // Add the new picture in
-      int offset = 0;
-          if(_pictures.size() > 0) {
-             HSLFPictureData prev = _pictures.get(_pictures.size() - 1);
-             offset = prev.getOffset() + prev.getRawData().length + 8;
-          }
-          img.setOffset(offset);
-          _pictures.add(img);
-          return offset;
-   }
-
-       /* ******************* fetching methods follow ********************* */
-
-
-       /**
-        * Returns an array of all the records found in the slideshow
-        */
-       public Record[] getRecords() { return _records; }
-
-       /**
-        * Returns an array of the bytes of the file. Only correct after a
-        *  call to open or write - at all other times might be wrong!
-        */
-       public byte[] getUnderlyingBytes() { return _docstream; }
-
-       /**
-        * Fetch the Current User Atom of the document
-        */
-       public CurrentUserAtom getCurrentUserAtom() { return currentUser; }
-
-       /**
-        *  Return array of pictures contained in this presentation
-        *
-        *  @return array with the read pictures or <code>null</code> if the
-        *  presentation doesn't contain pictures.
-        */
-       public HSLFPictureData[] getPictures() {
-          if(_pictures == null) {
-             try {
-                readPictures();
-             } catch(IOException e) {
-                throw new CorruptPowerPointFileException(e.getMessage());
-             }
-          }
-          
-               return _pictures.toArray(new HSLFPictureData[_pictures.size()]);
-       }
-
-    /**
-     * Gets embedded object data from the slide show.
-     *
-     * @return the embedded objects.
-     */
-    public HSLFObjectData[] getEmbeddedObjects() {
-        if (_objects == null) {
-            List<HSLFObjectData> objects = new ArrayList<HSLFObjectData>();
-            for (Record r : _records) {
-                if (r instanceof ExOleObjStg) {
-                    objects.add(new HSLFObjectData((ExOleObjStg)r));
-                }
-            }
-            _objects = objects.toArray(new HSLFObjectData[objects.size()]);
-        }
-        return _objects;
-    }
-    
-    
-    private static class BufAccessBAOS extends ByteArrayOutputStream {
-        public byte[] getBuf() {
-            return buf;
-        }
-    }
-    
-    private static class CountingOS extends OutputStream {
-        int count = 0;
-        public void write(int b) throws IOException {
-            count++;
-        }
-
-        public void write(byte[] b) throws IOException {
-            count += b.length;
-        }
-
-        public void write(byte[] b, int off, int len) throws IOException {
-            count += len;
-        }
-        
-        public int size() {
-            return count;
-        }
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextBox.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextBox.java
deleted file mode 100644 (file)
index 25ea585..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.ddf.*;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-
-/**
- * Represents a TextFrame shape in PowerPoint.
- * <p>
- * Contains the text in a text frame as well as the properties and methods
- * that control alignment and anchoring of the text.
- * </p>
- *
- * @author Yegor Kozlov
- */
-public class HSLFTextBox extends HSLFTextShape {
-
-    /**
-     * Create a TextBox object and initialize it from the supplied Record container.
-     *
-     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
-     * @param parent    the parent of the shape
-     */
-   protected HSLFTextBox(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-
-    }
-
-    /**
-     * Create a new TextBox. This constructor is used when a new shape is created.
-     *
-     * @param parent    the parent of this Shape. For example, if this text box is a cell
-     * in a table then the parent is Table.
-     */
-    public HSLFTextBox(ShapeContainer<HSLFShape> parent){
-        super(parent);
-    }
-
-    /**
-     * Create a new TextBox. This constructor is used when a new shape is created.
-     *
-     */
-    public HSLFTextBox(){
-        this(null);
-    }
-
-    /**
-     * Create a new TextBox and initialize its internal structures
-     *
-     * @return the created <code>EscherContainerRecord</code> which holds shape data
-     */
-    protected EscherContainerRecord createSpContainer(boolean isChild){
-        _escherContainer = super.createSpContainer(isChild);
-
-        setShapeType(ShapeType.TEXT_BOX);
-
-        //set default properties for a TextBox
-        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
-        setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
-        setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100000);
-        setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001);
-        setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
-        setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
-
-        _txtrun = createTextRun();
-
-        return _escherContainer;
-    }
-
-    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
-        setVerticalAlignment(HSLFTextBox.AnchorTop);
-        setEscherProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20002);
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java
deleted file mode 100644 (file)
index b23c997..0000000
+++ /dev/null
@@ -1,744 +0,0 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.hslf.model;\r
-\r
-import java.util.ArrayList;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-\r
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;\r
-import org.apache.poi.hslf.record.PPDrawing;\r
-import org.apache.poi.hslf.record.Record;\r
-import org.apache.poi.hslf.record.RecordContainer;\r
-import org.apache.poi.hslf.record.SlideListWithText;\r
-import org.apache.poi.hslf.record.StyleTextProp9Atom;\r
-import org.apache.poi.hslf.record.StyleTextPropAtom;\r
-import org.apache.poi.hslf.record.TextBytesAtom;\r
-import org.apache.poi.hslf.record.TextCharsAtom;\r
-import org.apache.poi.hslf.record.TextHeaderAtom;\r
-import org.apache.poi.hslf.record.TextRulerAtom;\r
-import org.apache.poi.hslf.record.TextSpecInfoAtom;\r
-import org.apache.poi.hslf.usermodel.HSLFTextRun;\r
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;\r
-import org.apache.poi.sl.usermodel.TextParagraph;\r
-import org.apache.poi.util.StringUtil;\r
-\r
-/**\r
- * This class represents a run of text in a powerpoint document. That\r
- *  run could be text on a sheet, or text in a note.\r
- *  It is only a very basic class for now\r
- *\r
- * @author Nick Burch\r
- */\r
-\r
-public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun>\r
-{\r
-       // Note: These fields are protected to help with unit testing\r
-       //   Other classes shouldn't really go playing with them!\r
-       protected TextHeaderAtom _headerAtom;\r
-       protected TextBytesAtom  _byteAtom;\r
-       protected TextCharsAtom  _charAtom;\r
-       protected StyleTextPropAtom _styleAtom;\r
-    protected TextRulerAtom _ruler;\r
-    protected boolean _isUnicode;\r
-       protected HSLFTextRun[] _rtRuns;\r
-       protected HSLFTextShape _parentShape;\r
-       // private SlideShow slideShow;\r
-    private HSLFSheet _sheet;\r
-    private int shapeId;\r
-    private int slwtIndex = -1; //position in the owning SlideListWithText\r
-    /**\r
-     * all text run records that follow TextHeaderAtom.\r
-     * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)\r
-     */\r
-    protected Record[] _records;\r
-       // private StyleTextPropAtom styleTextPropAtom;\r
-       private StyleTextProp9Atom styleTextProp9Atom;\r
-\r
-       /**\r
-       * Constructs a Text Run from a Unicode text block\r
-       *\r
-       * @param tha the TextHeaderAtom that defines what's what\r
-       * @param tca the TextCharsAtom containing the text\r
-       * @param sta the StyleTextPropAtom which defines the character stylings\r
-       */\r
-       public HSLFTextParagraph(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta) {\r
-               this(tha,null,tca,sta);\r
-       }\r
-\r
-       /**\r
-       * Constructs a Text Run from a Ascii text block\r
-       *\r
-       * @param tha the TextHeaderAtom that defines what's what\r
-       * @param tba the TextBytesAtom containing the text\r
-       * @param sta the StyleTextPropAtom which defines the character stylings\r
-       */\r
-       public HSLFTextParagraph(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) {\r
-               this(tha,tba,null,sta);\r
-       }\r
-\r
-       /**\r
-        * Internal constructor and initializer\r
-        */\r
-       private HSLFTextParagraph(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) {\r
-               _headerAtom = tha;\r
-               _styleAtom = sta;\r
-               if(tba != null) {\r
-                       _byteAtom = tba;\r
-                       _isUnicode = false;\r
-               } else {\r
-                       _charAtom = tca;\r
-                       _isUnicode = true;\r
-               }\r
-               String runRawText = getText();\r
-\r
-               // Figure out the rich text runs\r
-               LinkedList<TextPropCollection> pStyles = new LinkedList<TextPropCollection>();\r
-               LinkedList<TextPropCollection> cStyles = new LinkedList<TextPropCollection>();\r
-               if(_styleAtom != null) {\r
-                       // Get the style atom to grok itself\r
-                       _styleAtom.setParentTextSize(runRawText.length());\r
-                       pStyles = _styleAtom.getParagraphStyles();\r
-                       cStyles = _styleAtom.getCharacterStyles();\r
-               }\r
-        buildRichTextRuns(pStyles, cStyles, runRawText);\r
-       }\r
-\r
-       public void buildRichTextRuns(LinkedList<TextPropCollection> pStyles, LinkedList<TextPropCollection> cStyles, String runRawText){\r
-\r
-        // Handle case of no current style, with a default\r
-        if(pStyles.size() == 0 || cStyles.size() == 0) {\r
-            _rtRuns = new HSLFTextRun[1];\r
-            _rtRuns[0] = new HSLFTextRun(this, 0, runRawText.length());\r
-        } else {\r
-            // Build up Rich Text Runs, one for each\r
-            //  character/paragraph style pair\r
-            List<HSLFTextRun> rtrs = new ArrayList<HSLFTextRun>();\r
-\r
-            int pos = 0;\r
-\r
-            int curP = 0;\r
-            int curC = 0;\r
-            int pLenRemain = -1;\r
-            int cLenRemain = -1;\r
-\r
-            // Build one for each run with the same style\r
-            while(pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) {\r
-                // Get the Props to use\r
-                TextPropCollection pProps = pStyles.get(curP);\r
-                TextPropCollection cProps = cStyles.get(curC);\r
-\r
-                int pLen = pProps.getCharactersCovered();\r
-                int cLen = cProps.getCharactersCovered();\r
-\r
-                // Handle new pass\r
-                boolean freshSet = false;\r
-                if(pLenRemain == -1 && cLenRemain == -1) { freshSet = true; }\r
-                if(pLenRemain == -1) { pLenRemain = pLen; }\r
-                if(cLenRemain == -1) { cLenRemain = cLen; }\r
-\r
-                // So we know how to build the eventual run\r
-                int runLen = -1;\r
-                boolean pShared = false;\r
-                boolean cShared = false;\r
-\r
-                // Same size, new styles - neither shared\r
-                if(pLen == cLen && freshSet) {\r
-                    runLen = cLen;\r
-                    pShared = false;\r
-                    cShared = false;\r
-                    curP++;\r
-                    curC++;\r
-                    pLenRemain = -1;\r
-                    cLenRemain = -1;\r
-                } else {\r
-                    // Some sharing\r
-\r
-                    // See if we are already in a shared block\r
-                    if(pLenRemain < pLen) {\r
-                        // Existing shared p block\r
-                        pShared = true;\r
-\r
-                        // Do we end with the c block, or either side of it?\r
-                        if(pLenRemain == cLenRemain) {\r
-                            // We end at the same time\r
-                            cShared = false;\r
-                            runLen = pLenRemain;\r
-                            curP++;\r
-                            curC++;\r
-                            pLenRemain = -1;\r
-                            cLenRemain = -1;\r
-                        } else if(pLenRemain < cLenRemain) {\r
-                            // We end before the c block\r
-                            cShared = true;\r
-                            runLen = pLenRemain;\r
-                            curP++;\r
-                            cLenRemain -= pLenRemain;\r
-                            pLenRemain = -1;\r
-                        } else {\r
-                            // We end after the c block\r
-                            cShared = false;\r
-                            runLen = cLenRemain;\r
-                            curC++;\r
-                            pLenRemain -= cLenRemain;\r
-                            cLenRemain = -1;\r
-                        }\r
-                    } else if(cLenRemain < cLen) {\r
-                        // Existing shared c block\r
-                        cShared = true;\r
-\r
-                        // Do we end with the p block, or either side of it?\r
-                        if(pLenRemain == cLenRemain) {\r
-                            // We end at the same time\r
-                            pShared = false;\r
-                            runLen = cLenRemain;\r
-                            curP++;\r
-                            curC++;\r
-                            pLenRemain = -1;\r
-                            cLenRemain = -1;\r
-                        } else if(cLenRemain < pLenRemain) {\r
-                            // We end before the p block\r
-                            pShared = true;\r
-                            runLen = cLenRemain;\r
-                            curC++;\r
-                            pLenRemain -= cLenRemain;\r
-                            cLenRemain = -1;\r
-                        } else {\r
-                            // We end after the p block\r
-                            pShared = false;\r
-                            runLen = pLenRemain;\r
-                            curP++;\r
-                            cLenRemain -= pLenRemain;\r
-                            pLenRemain = -1;\r
-                        }\r
-                    } else {\r
-                        // Start of a shared block\r
-                        if(pLenRemain < cLenRemain) {\r
-                            // Shared c block\r
-                            pShared = false;\r
-                            cShared = true;\r
-                            runLen = pLenRemain;\r
-                            curP++;\r
-                            cLenRemain -= pLenRemain;\r
-                            pLenRemain = -1;\r
-                        } else {\r
-                            // Shared p block\r
-                            pShared = true;\r
-                            cShared = false;\r
-                            runLen = cLenRemain;\r
-                            curC++;\r
-                            pLenRemain -= cLenRemain;\r
-                            cLenRemain = -1;\r
-                        }\r
-                    }\r
-                }\r
-\r
-                // Wind on\r
-                int prevPos = pos;\r
-                pos += runLen;\r
-                // Adjust for end-of-run extra 1 length\r
-                if(pos > runRawText.length()) {\r
-                    runLen--;\r
-                }\r
-\r
-                // Save\r
-                HSLFTextRun rtr = new HSLFTextRun(this, prevPos, runLen, pProps, cProps, pShared, cShared);\r
-                rtrs.add(rtr);\r
-            }\r
-\r
-            // Build the array\r
-            _rtRuns = rtrs.toArray(new HSLFTextRun[rtrs.size()]);\r
-        }\r
-\r
-    }\r
-\r
-    // Update methods follow\r
-\r
-       /**\r
-        * Adds the supplied text onto the end of the TextRun,\r
-        *  creating a new RichTextRun (returned) for it to\r
-        *  sit in.\r
-        * In many cases, before calling this, you'll want to add\r
-        *  a newline onto the end of your last RichTextRun\r
-        */\r
-       public HSLFTextRun appendText(String s) {\r
-               // We will need a StyleTextProp atom\r
-               ensureStyleAtomPresent();\r
-\r
-               // First up, append the text to the\r
-               //  underlying text atom\r
-               int oldSize = getRawText().length();\r
-               storeText(\r
-                               getRawText() + s\r
-               );\r
-\r
-               // If either of the previous styles overran\r
-               //  the text by one, we need to shuffle that\r
-               //  extra character onto the new ones\r
-               int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize;\r
-               int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize;\r
-               if(pOverRun > 0) {\r
-                       TextPropCollection tpc = _styleAtom.getParagraphStyles().getLast();\r
-                       tpc.updateTextSize(\r
-                                       tpc.getCharactersCovered() - pOverRun\r
-                       );\r
-               }\r
-               if(cOverRun > 0) {\r
-                       TextPropCollection tpc = _styleAtom.getCharacterStyles().getLast();\r
-                       tpc.updateTextSize(\r
-                                       tpc.getCharactersCovered() - cOverRun\r
-                       );\r
-               }\r
-\r
-               // Next, add the styles for its paragraph and characters\r
-               TextPropCollection newPTP =\r
-                       _styleAtom.addParagraphTextPropCollection(s.length()+pOverRun);\r
-               TextPropCollection newCTP =\r
-                       _styleAtom.addCharacterTextPropCollection(s.length()+cOverRun);\r
-\r
-               // Now, create the new RichTextRun\r
-               HSLFTextRun nr = new HSLFTextRun(\r
-                               this, oldSize, s.length(),\r
-                               newPTP, newCTP, false, false\r
-               );\r
-\r
-               // Add the new RichTextRun onto our list\r
-               HSLFTextRun[] newRuns = new HSLFTextRun[_rtRuns.length+1];\r
-               System.arraycopy(_rtRuns, 0, newRuns, 0, _rtRuns.length);\r
-               newRuns[newRuns.length-1] = nr;\r
-               _rtRuns = newRuns;\r
-\r
-               // And return the new run to the caller\r
-               return nr;\r
-       }\r
-\r
-       /**\r
-        * Saves the given string to the records. Doesn't\r
-        *  touch the stylings.\r
-        */\r
-       private void storeText(String s) {\r
-               // Store in the appropriate record\r
-               if(_isUnicode) {\r
-                       // The atom can safely convert to unicode\r
-                       _charAtom.setText(s);\r
-               } else {\r
-                       // Will it fit in a 8 bit atom?\r
-                       boolean hasMultibyte = StringUtil.hasMultibyte(s);\r
-                       if(! hasMultibyte) {\r
-                               // Fine to go into 8 bit atom\r
-                               byte[] text = new byte[s.length()];\r
-                               StringUtil.putCompressedUnicode(s,text,0);\r
-                               _byteAtom.setText(text);\r
-                       } else {\r
-                               // Need to swap a TextBytesAtom for a TextCharsAtom\r
-\r
-                               // Build the new TextCharsAtom\r
-                               _charAtom = new TextCharsAtom();\r
-                               _charAtom.setText(s);\r
-\r
-                               // Use the TextHeaderAtom to do the swap on the parent\r
-                               RecordContainer parent = _headerAtom.getParentRecord();\r
-                               Record[] cr = parent.getChildRecords();\r
-                               for(int i=0; i<cr.length; i++) {\r
-                                       // Look for TextBytesAtom\r
-                                       if(cr[i].equals(_byteAtom)) {\r
-                                               // Found it, so replace, then all done\r
-                                               cr[i] = _charAtom;\r
-                                               break;\r
-                                       }\r
-                               }\r
-\r
-                               // Flag the change\r
-                               _byteAtom = null;\r
-                               _isUnicode = true;\r
-                       }\r
-               }\r
-        /**\r
-         * If TextSpecInfoAtom is present, we must update the text size in it,\r
-         * otherwise the ppt will be corrupted\r
-         */\r
-        if(_records != null) for (int i = 0; i < _records.length; i++) {\r
-            if(_records[i] instanceof TextSpecInfoAtom){\r
-                TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];\r
-                if((s.length() + 1) != specAtom.getCharactersCovered()){\r
-                    specAtom.reset(s.length() + 1);\r
-                }\r
-            }\r
-        }\r
-       }\r
-\r
-       /**\r
-        * Handles an update to the text stored in one of the Rich Text Runs\r
-        * @param run\r
-        * @param s\r
-        */\r
-       public void changeTextInRichTextRun(HSLFTextRun run, String s) {\r
-               // Figure out which run it is\r
-               int runID = -1;\r
-               for(int i=0; i<_rtRuns.length; i++) {\r
-                       if(run.equals(_rtRuns[i])) {\r
-                               runID = i;\r
-                       }\r
-               }\r
-               if(runID == -1) {\r
-                       throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun");\r
-               }\r
-\r
-               // Ensure a StyleTextPropAtom is present, adding if required\r
-               ensureStyleAtomPresent();\r
-\r
-               // Update the text length for its Paragraph and Character stylings\r
-               // If it's shared:\r
-               //   * calculate the new length based on the run's old text\r
-               //   * this should leave in any +1's for the end of block if needed\r
-               // If it isn't shared:\r
-               //   * reset the length, to the new string's length\r
-               //   * add on +1 if the last block\r
-               // The last run needs its stylings to be 1 longer than the raw\r
-               //  text is. This is to define the stylings that any new text\r
-               //  that is added will inherit\r
-               TextPropCollection pCol = run._getRawParagraphStyle();\r
-               TextPropCollection cCol = run._getRawCharacterStyle();\r
-               int newSize = s.length();\r
-               if(runID == _rtRuns.length-1) {\r
-                       newSize++;\r
-               }\r
-\r
-               if(run._isParagraphStyleShared()) {\r
-                       pCol.updateTextSize( pCol.getCharactersCovered() - run.getLength() + s.length() );\r
-               } else {\r
-                       pCol.updateTextSize(newSize);\r
-               }\r
-               if(run._isCharacterStyleShared()) {\r
-                       cCol.updateTextSize( cCol.getCharactersCovered() - run.getLength() + s.length() );\r
-               } else {\r
-                       cCol.updateTextSize(newSize);\r
-               }\r
-\r
-               // Build up the new text\r
-               // As we go through, update the start position for all subsequent runs\r
-               // The building relies on the old text still being present\r
-               StringBuffer newText = new StringBuffer();\r
-               for(int i=0; i<_rtRuns.length; i++) {\r
-                       int newStartPos = newText.length();\r
-\r
-                       // Build up the new text\r
-                       if(i != runID) {\r
-                               // Not the affected run, so keep old text\r
-                               newText.append(_rtRuns[i].getRawText());\r
-                       } else {\r
-                               // Affected run, so use new text\r
-                               newText.append(s);\r
-                       }\r
-\r
-                       // Do we need to update the start position of this run?\r
-                       // (Need to get the text before we update the start pos)\r
-                       if(i <= runID) {\r
-                               // Change is after this, so don't need to change start position\r
-                       } else {\r
-                               // Change has occured, so update start position\r
-                               _rtRuns[i].updateStartPosition(newStartPos);\r
-                       }\r
-               }\r
-\r
-               // Now we can save the new text\r
-               storeText(newText.toString());\r
-       }\r
-\r
-       /**\r
-        * Changes the text, and sets it all to have the same styling\r
-        *  as the the first character has.\r
-        * If you care about styling, do setText on a RichTextRun instead\r
-        */\r
-       public void setRawText(String s) {\r
-               // Save the new text to the atoms\r
-               storeText(s);\r
-               HSLFTextRun fst = _rtRuns[0];\r
-\r
-               // Finally, zap and re-do the RichTextRuns\r
-               for(int i=0; i<_rtRuns.length; i++) { _rtRuns[i] = null; }\r
-               _rtRuns = new HSLFTextRun[1];\r
-        _rtRuns[0] = fst;\r
-\r
-               // Now handle record stylings:\r
-               // If there isn't styling\r
-               //  no change, stays with no styling\r
-               // If there is styling:\r
-               //  everthing gets the same style that the first block has\r
-        // Update the lengths +1 for since these will be the only runs\r
-               if(_styleAtom != null) {\r
-                       LinkedList<TextPropCollection> pStyles = _styleAtom.getParagraphStyles();\r
-                       while(pStyles.size() > 1) { pStyles.removeLast(); }\r
-\r
-            if (!pStyles.isEmpty()) {\r
-                pStyles.getFirst().updateTextSize( s.length()+1 );\r
-            }\r
-\r
-                       LinkedList<TextPropCollection> cStyles = _styleAtom.getCharacterStyles();\r
-                       while(cStyles.size() > 1) { cStyles.removeLast(); }\r
-            \r
-            if (!cStyles.isEmpty()) {\r
-                cStyles.getFirst().updateTextSize( s.length()+1 );\r
-            }\r
-                       \r
-                       _rtRuns[0].setText(s);\r
-               } else {\r
-                       // Recreate rich text run with no styling\r
-                       _rtRuns[0] = new HSLFTextRun(this,0,s.length());\r
-               }\r
-\r
-       }\r
-\r
-    /**\r
-     * Changes the text.\r
-     * Converts '\r' into '\n'\r
-     */\r
-    public void setText(String s) {\r
-        String text = normalize(s);\r
-        setRawText(text);\r
-    }\r
-\r
-    /**\r
-        * Ensure a StyleTextPropAtom is present for this run,\r
-        *  by adding if required. Normally for internal TextRun use.\r
-        */\r
-       public void ensureStyleAtomPresent() {\r
-               if(_styleAtom != null) {\r
-                       // All there\r
-                       return;\r
-               }\r
-\r
-               // Create a new one at the right size\r
-               _styleAtom = new StyleTextPropAtom(getRawText().length() + 1);\r
-\r
-               // Use the TextHeader atom to get at the parent\r
-               RecordContainer runAtomsParent = _headerAtom.getParentRecord();\r
-\r
-               // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom\r
-               Record addAfter = _byteAtom;\r
-               if(_byteAtom == null) { addAfter = _charAtom; }\r
-               runAtomsParent.addChildAfter(_styleAtom, addAfter);\r
-\r
-               // Feed this to our sole rich text run\r
-               if(_rtRuns.length != 1) {\r
-                       throw new IllegalStateException("Needed to add StyleTextPropAtom when had many rich text runs");\r
-               }\r
-               // These are the only styles for now\r
-               _rtRuns[0].supplyTextProps(\r
-                               _styleAtom.getParagraphStyles().get(0),\r
-                               _styleAtom.getCharacterStyles().get(0),\r
-                               false,\r
-                               false\r
-               );\r
-       }\r
-\r
-       // Accesser methods follow\r
-\r
-       /**\r
-        * Returns the text content of the run, which has been made safe\r
-        * for printing and other use.\r
-        */\r
-       public String getText() {\r
-               String rawText = getRawText();\r
-\r
-               // PowerPoint seems to store files with \r as the line break\r
-               // The messes things up on everything but a Mac, so translate\r
-               //  them to \n\r
-               String text = rawText.replace('\r','\n');\r
-\r
-        int type = _headerAtom == null ? 0 : _headerAtom.getTextType();\r
-        if(type == TextHeaderAtom.TITLE_TYPE || type == TextHeaderAtom.CENTER_TITLE_TYPE){\r
-            //0xB acts like cariage return in page titles and like blank in the others\r
-            text = text.replace((char) 0x0B, '\n');\r
-        } else {\r
-            text = text.replace((char) 0x0B, ' ');\r
-        }\r
-               return text;\r
-       }\r
-\r
-       /**\r
-       * Returns the raw text content of the run. This hasn't had any\r
-       *  changes applied to it, and so is probably unlikely to print\r
-       *  out nicely.\r
-       */\r
-       public String getRawText() {\r
-               if(_isUnicode) {\r
-                       return _charAtom.getText();\r
-               }\r
-               return _byteAtom.getText();\r
-       }\r
-\r
-       /**\r
-        * Fetch the rich text runs (runs of text with the same styling) that\r
-        *  are contained within this block of text\r
-        */\r
-       public HSLFTextRun[] getRichTextRuns() {\r
-               return  _rtRuns;\r
-       }\r
-\r
-       /**\r
-       * Returns the type of the text, from the TextHeaderAtom.\r
-       * Possible values can be seen from TextHeaderAtom\r
-       * @see org.apache.poi.hslf.record.TextHeaderAtom\r
-       */\r
-       public int getRunType() {\r
-               return _headerAtom.getTextType();\r
-       }\r
-\r
-       /**\r
-       * Changes the type of the text. Values should be taken\r
-       *  from TextHeaderAtom. No checking is done to ensure you\r
-       *  set this to a valid value!\r
-       * @see org.apache.poi.hslf.record.TextHeaderAtom\r
-       */\r
-       public void setRunType(int type) {\r
-               _headerAtom.setTextType(type);\r
-       }\r
-\r
-    /**\r
-     * Supply the Sheet we belong to, which might have an assigned SlideShow\r
-     * Also passes it on to our child RichTextRuns\r
-     */\r
-       public void supplySheet(HSLFSheet sheet){\r
-        this._sheet = sheet;\r
-\r
-        if (_rtRuns == null) return;\r
-        for(HSLFTextRun rt : _rtRuns) {\r
-            rt.updateSheet();\r
-        }\r
-       }\r
-\r
-    public HSLFSheet getSheet(){\r
-        return this._sheet;\r
-    }\r
-\r
-    /**\r
-     * @return  Shape ID\r
-     */\r
-    protected int getShapeId(){\r
-        return shapeId;\r
-    }\r
-\r
-    /**\r
-     *  @param id Shape ID\r
-     */\r
-    protected void setShapeId(int id){\r
-        shapeId = id;\r
-    }\r
-\r
-    /**\r
-     * @return  0-based index of the text run in the SLWT container\r
-     */\r
-    protected int getIndex(){\r
-        return slwtIndex;\r
-    }\r
-\r
-    /**\r
-     *  @param id 0-based index of the text run in the SLWT container\r
-     */\r
-    protected void setIndex(int id){\r
-        slwtIndex = id;\r
-    }\r
-    \r
-    /**\r
-     * Is this Text Run one from a {@link PPDrawing}, or is it\r
-     *  one from the {@link SlideListWithText}?\r
-     */\r
-    public boolean isDrawingBased() {\r
-        return (slwtIndex == -1);\r
-    }\r
-\r
-    /**\r
-     * Returns the array of all hyperlinks in this text run\r
-     *\r
-     * @return the array of all hyperlinks in this text run\r
-     * or <code>null</code> if not found.\r
-     */\r
-    public Hyperlink[] getHyperlinks(){\r
-        return Hyperlink.find(this);\r
-    }\r
-\r
-    /**\r
-     * Fetch RichTextRun at a given position\r
-     *\r
-     * @param pos 0-based index in the text\r
-     * @return RichTextRun or null if not found\r
-     */\r
-    public HSLFTextRun getRichTextRunAt(int pos){\r
-        for (int i = 0; i < _rtRuns.length; i++) {\r
-            int start = _rtRuns[i].getStartIndex();\r
-            int end = _rtRuns[i].getEndIndex();\r
-            if(pos >= start && pos < end) return _rtRuns[i];\r
-        }\r
-        return null;\r
-    }\r
-\r
-    public TextRulerAtom getTextRuler(){\r
-        if(_ruler == null){\r
-            if(_records != null) for (int i = 0; i < _records.length; i++) {\r
-                if(_records[i] instanceof TextRulerAtom) {\r
-                    _ruler = (TextRulerAtom)_records[i];\r
-                    break;\r
-                }\r
-            }\r
-\r
-        }\r
-        return _ruler;\r
-\r
-    }\r
-\r
-    public TextRulerAtom createTextRuler(){\r
-        _ruler = getTextRuler();\r
-        if(_ruler == null){\r
-            _ruler = TextRulerAtom.getParagraphInstance();\r
-            _headerAtom.getParentRecord().appendChildRecord(_ruler);\r
-        }\r
-        return _ruler;\r
-    }\r
-\r
-    /**\r
-     * Returns a new string with line breaks converted into internal ppt representation\r
-     */\r
-    public String normalize(String s){\r
-        String ns = s.replaceAll("\\r?\\n", "\r");\r
-        return ns;\r
-    }\r
-\r
-    /**\r
-     * Returns records that make up this text run\r
-     *\r
-     * @return text run records\r
-     */\r
-    public Record[] getRecords(){\r
-        return _records;\r
-    }\r
-    /** Numbered List info */\r
-       public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {\r
-               this.styleTextProp9Atom = styleTextProp9Atom;\r
-       }\r
-    /** Numbered List info */\r
-       public StyleTextProp9Atom getStyleTextProp9Atom() {\r
-               return this.styleTextProp9Atom;\r
-       }\r
-\r
-    /** Characters covered */\r
-       public StyleTextPropAtom getStyleTextPropAtom() {\r
-               return this._styleAtom;         \r
-       }\r
-\r
-}\r
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextShape.java
deleted file mode 100644 (file)
index 17e8b81..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-/* ====================================================================
-   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.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextLayout;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.io.IOException;
-
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.ddf.EscherTextboxRecord;
-import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.record.EscherTextboxWrapper;
-import org.apache.poi.hslf.record.InteractiveInfo;
-import org.apache.poi.hslf.record.InteractiveInfoAtom;
-import org.apache.poi.hslf.record.OEPlaceholderAtom;
-import org.apache.poi.hslf.record.OutlineTextRefAtom;
-import org.apache.poi.hslf.record.PPDrawing;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
-import org.apache.poi.hslf.record.StyleTextPropAtom;
-import org.apache.poi.hslf.record.TextBytesAtom;
-import org.apache.poi.hslf.record.TextCharsAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.util.POILogger;
-
-/**
- * A common superclass of all shapes that can hold text.
- *
- * @author Yegor Kozlov
- */
-public abstract class HSLFTextShape extends HSLFSimpleShape {
-
-    /**
-     * How to anchor the text
-     */
-    public static final int AnchorTop = 0;
-    public static final int AnchorMiddle = 1;
-    public static final int AnchorBottom = 2;
-    public static final int AnchorTopCentered = 3;
-    public static final int AnchorMiddleCentered = 4;
-    public static final int AnchorBottomCentered = 5;
-    public static final int AnchorTopBaseline = 6;
-    public static final int AnchorBottomBaseline = 7;
-    public static final int AnchorTopCenteredBaseline = 8;
-    public static final int AnchorBottomCenteredBaseline = 9;
-
-    /**
-     * How to wrap the text
-     */
-    public static final int WrapSquare = 0;
-    public static final int WrapByPoints = 1;
-    public static final int WrapNone = 2;
-    public static final int WrapTopBottom = 3;
-    public static final int WrapThrough = 4;
-
-    /**
-     * How to align the text
-     */
-    public static final int AlignLeft = 0;
-    public static final int AlignCenter = 1;
-    public static final int AlignRight = 2;
-    public static final int AlignJustify = 3;
-
-    /**
-     * TextRun object which holds actual text and format data
-     */
-    protected HSLFTextParagraph _txtrun;
-
-    /**
-     * Escher container which holds text attributes such as
-     * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
-     */
-    protected EscherTextboxWrapper _txtbox;
-
-    /**
-     * Used to calculate text bounds
-     */
-    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
-
-    /**
-     * Create a TextBox object and initialize it from the supplied Record container.
-     *
-     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
-     * @param parent    the parent of the shape
-     */
-   protected HSLFTextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
-        super(escherRecord, parent);
-
-    }
-
-    /**
-     * Create a new TextBox. This constructor is used when a new shape is created.
-     *
-     * @param parent    the parent of this Shape. For example, if this text box is a cell
-     * in a table then the parent is Table.
-     */
-    public HSLFTextShape(ShapeContainer<HSLFShape> parent){
-        super(null, parent);
-        _escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
-    }
-
-    /**
-     * Create a new TextBox. This constructor is used when a new shape is created.
-     *
-     */
-    public HSLFTextShape(){
-        this(null);
-    }
-
-    public HSLFTextParagraph createTextRun(){
-        _txtbox = getEscherTextboxWrapper();
-        if(_txtbox == null) _txtbox = new EscherTextboxWrapper();
-
-        _txtrun = getTextParagraph();
-        if(_txtrun == null){
-            TextHeaderAtom tha = new TextHeaderAtom();
-            tha.setParentRecord(_txtbox);
-            _txtbox.appendChildRecord(tha);
-
-            TextCharsAtom tca = new TextCharsAtom();
-            _txtbox.appendChildRecord(tca);
-
-            StyleTextPropAtom sta = new StyleTextPropAtom(0);
-            _txtbox.appendChildRecord(sta);
-
-            _txtrun = new HSLFTextParagraph(tha,tca,sta);
-            _txtrun._records = new Record[]{tha, tca, sta};
-            _txtrun.setText("");
-
-            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
-
-            setDefaultTextProperties(_txtrun);
-        }
-
-        return _txtrun;
-    }
-
-    /**
-     * Set default properties for the  TextRun.
-     * Depending on the text and shape type the defaults are different:
-     *   TextBox: align=left, valign=top
-     *   AutoShape: align=center, valign=middle
-     *
-     */
-    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
-
-    }
-
-    /**
-     * Returns the text contained in this text frame.
-     *
-     * @return the text string for this textbox.
-     */
-     public String getText(){
-        HSLFTextParagraph tx = getTextParagraph();
-        return tx == null ? null : tx.getText();
-    }
-
-    /**
-     * Sets the text contained in this text frame.
-     *
-     * @param text the text string used by this object.
-     */
-    public void setText(String text){
-        HSLFTextParagraph tx = getTextParagraph();
-        if(tx == null){
-            tx = createTextRun();
-        }
-        tx.setText(text);
-        setTextId(text.hashCode());
-    }
-
-    /**
-     * When a textbox is added to  a sheet we need to tell upper-level
-     * <code>PPDrawing</code> about it.
-     *
-     * @param sh the sheet we are adding to
-     */
-    protected void afterInsert(HSLFSheet sh){
-        super.afterInsert(sh);
-
-        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
-        if(_txtbox != null){
-            PPDrawing ppdrawing = sh.getPPDrawing();
-            ppdrawing.addTextboxWrapper(_txtbox);
-            // Ensure the escher layer knows about the added records
-            try {
-                _txtbox.writeOut(null);
-            } catch (IOException e){
-                throw new HSLFException(e);
-            }
-            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
-        }
-        if(_txtrun != null) {
-            _txtrun.setShapeId(getShapeId());
-            sh.onAddTextShape(this);
-        }
-    }
-
-    protected EscherTextboxWrapper getEscherTextboxWrapper(){
-        if(_txtbox == null){
-            EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
-            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
-        }
-        return _txtbox;
-    }
-    /**
-     * Adjust the size of the TextShape so it encompasses the text inside it.
-     *
-     * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.
-     */
-    public Rectangle2D resizeToFitText(){
-        String txt = getText();
-        if(txt == null || txt.length() == 0) return new Rectangle2D.Float();
-
-        HSLFTextRun rt = getTextParagraph().getRichTextRuns()[0];
-        int size = rt.getFontSize();
-        int style = 0;
-        if (rt.isBold()) style |= Font.BOLD;
-        if (rt.isItalic()) style |= Font.ITALIC;
-        String fntname = rt.getFontName();
-        Font font = new Font(fntname, style, size);
-
-        float width = 0, height = 0, leading = 0;
-        String[] lines = txt.split("\n");
-        for (int i = 0; i < lines.length; i++) {
-            if(lines[i].length() == 0) continue;
-
-            TextLayout layout = new TextLayout(lines[i], font, _frc);
-
-            leading = Math.max(leading, layout.getLeading());
-            width = Math.max(width, layout.getAdvance());
-            height = Math.max(height, (height + (layout.getDescent() + layout.getAscent())));
-        }
-
-        // add one character to width
-        Rectangle2D charBounds = font.getMaxCharBounds(_frc);
-        width += getMarginLeft() + getMarginRight() + charBounds.getWidth();
-
-        // add leading to height
-        height += getMarginTop() + getMarginBottom() + leading;
-
-        Rectangle2D anchor = getAnchor2D();
-        anchor.setRect(anchor.getX(), anchor.getY(), width, height);
-        setAnchor(anchor);
-
-        return anchor;
-    }
-
-    /**
-     * Returns the type of vertical alignment for the text.
-     * One of the <code>Anchor*</code> constants defined in this class.
-     *
-     * @return the type of alignment
-     */
-    public int getVerticalAlignment(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
-        int valign = HSLFTextShape.AnchorTop;
-        if (prop == null){
-            /**
-             * If vertical alignment was not found in the shape properties then try to
-             * fetch the master shape and search for the align property there.
-             */
-            int type = getTextParagraph().getRunType();
-            HSLFMasterSheet master = getSheet().getMasterSheet();
-            if(master != null){
-                HSLFTextShape masterShape = master.getPlaceholderByTextType(type);
-                if(masterShape != null) valign = masterShape.getVerticalAlignment();
-            } else {
-                //not found in the master sheet. Use the hardcoded defaults.
-                switch (type){
-                     case TextHeaderAtom.TITLE_TYPE:
-                     case TextHeaderAtom.CENTER_TITLE_TYPE:
-                         valign = HSLFTextShape.AnchorMiddle;
-                         break;
-                     default:
-                         valign = HSLFTextShape.AnchorTop;
-                         break;
-                 }
-            }
-        } else {
-            valign = prop.getPropertyValue();
-        }
-        return valign;
-    }
-
-    /**
-     * Sets the type of vertical alignment for the text.
-     * One of the <code>Anchor*</code> constants defined in this class.
-     *
-     * @param align - the type of alignment
-     */
-    public void setVerticalAlignment(int align){
-        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);
-    }
-
-    /**
-     * Sets the type of horizontal alignment for the text.
-     * One of the <code>Align*</code> constants defined in this class.
-     *
-     * @param align - the type of horizontal alignment
-     */
-    public void setHorizontalAlignment(int align){
-        HSLFTextParagraph tx = getTextParagraph();
-        if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);
-    }
-
-    /**
-     * Gets the type of horizontal alignment for the text.
-     * One of the <code>Align*</code> constants defined in this class.
-     *
-     * @return align - the type of horizontal alignment
-     */
-    public int getHorizontalAlignment(){
-        HSLFTextParagraph tx = getTextParagraph();
-        return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();
-    }
-
-    /**
-     * Returns the distance (in points) between the bottom of the text frame
-     * and the bottom of the inscribed rectangle of the shape that contains the text.
-     * Default value is 1/20 inch.
-     *
-     * @return the botom margin
-     */
-    public float getMarginBottom(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
-        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
-        return (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the botom margin.
-     * @see #getMarginBottom()
-     *
-     * @param margin    the bottom margin
-     */
-    public void setMarginBottom(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
-    }
-
-    /**
-     *  Returns the distance (in points) between the left edge of the text frame
-     *  and the left edge of the inscribed rectangle of the shape that contains
-     *  the text.
-     *  Default value is 1/10 inch.
-     *
-     * @return the left margin
-     */
-    public float getMarginLeft(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT);
-        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
-        return (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the left margin.
-     * @see #getMarginLeft()
-     *
-     * @param margin    the left margin
-     */
-    public void setMarginLeft(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
-    }
-
-    /**
-     *  Returns the distance (in points) between the right edge of the
-     *  text frame and the right edge of the inscribed rectangle of the shape
-     *  that contains the text.
-     *  Default value is 1/10 inch.
-     *
-     * @return the right margin
-     */
-    public float getMarginRight(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
-        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
-        return (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the right margin.
-     * @see #getMarginRight()
-     *
-     * @param margin    the right margin
-     */
-    public void setMarginRight(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
-    }
-
-     /**
-     *  Returns the distance (in points) between the top of the text frame
-     *  and the top of the inscribed rectangle of the shape that contains the text.
-     *  Default value is 1/20 inch.
-     *
-     * @return the top margin
-     */
-    public float getMarginTop(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
-        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
-        return (float)val/EMU_PER_POINT;
-    }
-
-   /**
-     * Sets the top margin.
-     * @see #getMarginTop()
-     *
-     * @param margin    the top margin
-     */
-    public void setMarginTop(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
-    }
-
-
-    /**
-     * Returns the value indicating word wrap.
-     *
-     * @return the value indicating word wrap.
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.
-     */
-    public int getWordWrap(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
-        return prop == null ? WrapSquare : prop.getPropertyValue();
-    }
-
-    /**
-     *  Specifies how the text should be wrapped
-     *
-     * @param wrap  the value indicating how the text should be wrapped.
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.
-     */
-    public void setWordWrap(int wrap){
-        setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
-    }
-
-    /**
-     * @return id for the text.
-     */
-    public int getTextId(){
-        EscherOptRecord opt = getEscherOptRecord();
-        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
-        return prop == null ? 0 : prop.getPropertyValue();
-    }
-
-    /**
-     * Sets text ID
-     *
-     * @param id of the text
-     */
-    public void setTextId(int id){
-        setEscherProperty(EscherProperties.TEXT__TEXTID, id);
-    }
-
-    /**
-      * @return the TextRun object for this text box
-      */
-    public HSLFTextParagraph getTextParagraph(){
-       if (null == this._txtrun) initTextRun();
-       if (null == this._txtrun && null != this._txtbox) {
-          TextHeaderAtom    tha = null; 
-          TextBytesAtom     tba = null;
-          TextCharsAtom     tca = null;
-          StyleTextPropAtom sta = null;
-          Record[] childRecords = this._txtbox.getChildRecords();
-          for (Record r : childRecords) {
-             if (r instanceof TextHeaderAtom) {
-                tha = (TextHeaderAtom) r;
-             } else if (r instanceof TextBytesAtom) {
-                tba = (TextBytesAtom) r;
-             } else if (r instanceof TextCharsAtom) {
-                tca = (TextCharsAtom) r;
-             } else if (r instanceof StyleTextPropAtom) {
-                sta = (StyleTextPropAtom) r;
-             }
-          }
-          if (tba != null) {
-             this._txtrun = new HSLFTextParagraph(tha, tba, sta);
-          } else if (tca != null) {
-             this._txtrun = new HSLFTextParagraph(tha, tca, sta);
-          }
-       }
-       return _txtrun;
-    }
-
-    public void setSheet(HSLFSheet sheet) {
-        _sheet = sheet;
-
-        // Initialize _txtrun object.
-        // (We can't do it in the constructor because the sheet
-        //  is not assigned then, it's only built once we have
-        //  all the records)
-        HSLFTextParagraph tx = getTextParagraph();
-        if (tx != null) {
-            // Supply the sheet to our child RichTextRuns
-            tx.supplySheet(_sheet);
-        }
-    }
-
-    protected void initTextRun(){
-        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
-        HSLFSheet sheet = getSheet();
-
-        if(sheet == null || txtbox == null) return;
-
-        OutlineTextRefAtom ota = null;
-
-        Record[] child = txtbox.getChildRecords();
-        for (int i = 0; i < child.length; i++) {
-            if (child[i] instanceof OutlineTextRefAtom) {
-                ota = (OutlineTextRefAtom)child[i];
-                break;
-            }
-        }
-
-        HSLFTextParagraph[] runs = _sheet.getTextRuns();
-        if (ota != null) {
-            int idx = ota.getTextIndex();
-            for (int i = 0; i < runs.length; i++) {
-                if(runs[i].getIndex() == idx){
-                    _txtrun = runs[i];
-                    break;
-                }
-            }
-            if(_txtrun == null) {
-                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
-            }
-        } else {
-            EscherSpRecord escherSpRecord = getEscherChild(EscherSpRecord.RECORD_ID);
-            int shapeId = escherSpRecord.getShapeId();
-            if(runs != null) for (int i = 0; i < runs.length; i++) {
-                if(runs[i].getShapeId() == shapeId){
-                    _txtrun = runs[i];
-                    break;
-                }
-            }
-        }
-        
-        // ensure the same references child records of TextRun
-        if(_txtrun != null) {
-            for (int i = 0; i < child.length; i++) {
-                for (Record r : _txtrun.getRecords()) {
-                    if (child[i].getRecordType() == r.getRecordType()) {
-                        child[i] = r;
-                    }
-                }
-            }
-        }
-    }
-
-    public void draw(Graphics2D graphics){
-        AffineTransform at = graphics.getTransform();
-        ShapePainter.paint(this, graphics);
-        new TextPainter(this).paint(graphics);
-        graphics.setTransform(at);
-    }
-
-    /**
-     * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder.
-     *
-     * @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
-     */
-    public OEPlaceholderAtom getPlaceholderAtom(){
-        return getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
-    }
-
-    /**
-     *
-     * Assigns a hyperlink to this text shape
-     *
-     * @param linkId    id of the hyperlink, @see org.apache.poi.hslf.usermodel.SlideShow#addHyperlink(Hyperlink)
-     * @param      beginIndex   the beginning index, inclusive.
-     * @param      endIndex     the ending index, exclusive.
-     * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#addHyperlink(Hyperlink)
-     */
-    public void setHyperlink(int linkId, int beginIndex, int endIndex){
-        //TODO validate beginIndex and endIndex and throw IllegalArgumentException
-
-        InteractiveInfo info = new InteractiveInfo();
-        InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
-        infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
-        infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_Url);
-        infoAtom.setHyperlinkID(linkId);
-
-        _txtbox.appendChildRecord(info);
-
-        TxInteractiveInfoAtom txiatom = new TxInteractiveInfoAtom();
-        txiatom.setStartIndex(beginIndex);
-        txiatom.setEndIndex(endIndex);
-        _txtbox.appendChildRecord(txiatom);
-
-    }
-
-    @Override
-    public boolean isPlaceholder() {
-        OEPlaceholderAtom oep = getPlaceholderAtom();
-        if (oep != null) return true;
-
-        //special case for files saved in Office 2007
-        RoundTripHFPlaceholder12 hldr = getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
-        if (hldr != null) return true;
-
-        return false;
-    }
-
-    
-}
index bd3a6da3994608b2ea42c9d79371af592f77937e..63ec3d7a6f01469aad69a5ba8d7c3f47fd7fb3df 100644 (file)
@@ -18,7 +18,7 @@
 package org.apache.poi.hslf.model;
 
 import org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 
 /**
  * Header / Footer settings.
@@ -240,7 +240,7 @@ public final class HeadersFooters {
     private boolean isVisible(int flag, int placeholderId){
         boolean visible;
         if(_ppt2007){
-            HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlidesMasters()[0];
+            HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlideMasters().get(0);
             HSLFTextShape placeholder = master.getPlaceholder(placeholderId);
             visible = placeholder != null && placeholder.getText() != null;
         } else {
@@ -252,7 +252,7 @@ public final class HeadersFooters {
     private String getPlaceholderText(int placeholderId, CString cs){
         String text = null;
         if(_ppt2007){
-            HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlidesMasters()[0];
+            HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlideMasters().get(0);
             HSLFTextShape placeholder = master.getPlaceholder(placeholderId);
             if(placeholder != null) text = placeholder.getText();
 
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java b/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java
deleted file mode 100644 (file)
index 2e1f1ec..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherClientDataRecord;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Iterator;
-
-/**
- * Represents a hyperlink in a PowerPoint document
- *
- * @author Yegor Kozlov
- */
-public final class Hyperlink {
-    public static final byte LINK_NEXTSLIDE = InteractiveInfoAtom.LINK_NextSlide;
-    public static final byte LINK_PREVIOUSSLIDE = InteractiveInfoAtom.LINK_PreviousSlide;
-    public static final byte LINK_FIRSTSLIDE = InteractiveInfoAtom.LINK_FirstSlide;
-    public static final byte LINK_LASTSLIDE = InteractiveInfoAtom.LINK_LastSlide;
-    public static final byte LINK_SLIDENUMBER = InteractiveInfoAtom.LINK_SlideNumber;
-    public static final byte LINK_URL = InteractiveInfoAtom.LINK_Url;
-    public static final byte LINK_NULL = InteractiveInfoAtom.LINK_NULL;
-
-    private int id=-1;
-    private int type;
-    private String address;
-    private String title;
-    private int startIndex, endIndex;
-
-    /**
-     * Gets the type of the hyperlink action.
-     * Must be a <code>LINK_*</code>  constant</code>
-     *
-     * @return the hyperlink URL
-     * @see InteractiveInfoAtom
-     */
-    public int getType() {
-        return type;
-    }
-
-    public void setType(int val) {
-        type = val;
-        switch(type){
-            case LINK_NEXTSLIDE:
-                title = "NEXT";
-                address = "1,-1,NEXT";
-                break;
-            case LINK_PREVIOUSSLIDE:
-                title = "PREV";
-                address = "1,-1,PREV";
-                break;
-            case LINK_FIRSTSLIDE:
-                title = "FIRST";
-                address = "1,-1,FIRST";
-                break;
-            case LINK_LASTSLIDE:
-                title = "LAST";
-                address = "1,-1,LAST";
-                break;
-            case LINK_SLIDENUMBER:
-                break;
-            default:
-                title = "";
-                address = "";
-                break;
-        }
-    }
-
-    /**
-     * Gets the hyperlink URL
-     *
-     * @return the hyperlink URL
-     */
-    public String getAddress() {
-        return address;
-    }
-
-    public void setAddress(HSLFSlide slide) {
-        String href = slide._getSheetNumber() + ","+slide.getSlideNumber()+",Slide " + slide.getSlideNumber();
-        setAddress(href);;
-        setTitle("Slide " + slide.getSlideNumber());
-        setType(Hyperlink.LINK_SLIDENUMBER);
-    }
-
-    public void setAddress(String str) {
-        address = str;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    /**
-     * Gets the hyperlink user-friendly title (if different from URL)
-     *
-     * @return the  hyperlink user-friendly title
-     */
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String str) {
-        title = str;
-    }
-
-    /**
-     * Gets the beginning character position
-     *
-     * @return the beginning character position
-     */
-    public int getStartIndex() {
-        return startIndex;
-    }
-
-    /**
-     * Gets the ending character position
-     *
-     * @return the ending character position
-     */
-    public int getEndIndex() {
-        return endIndex;
-    }
-
-    /**
-     * Find hyperlinks in a text run
-     *
-     * @param run  <code>TextRun</code> to lookup hyperlinks in
-     * @return found hyperlinks or <code>null</code> if not found
-     */
-    protected static Hyperlink[] find(HSLFTextParagraph run){
-        List<Hyperlink> lst = new ArrayList<Hyperlink>();
-        HSLFSlideShow ppt = run.getSheet().getSlideShow();
-        //document-level container which stores info about all links in a presentation
-        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
-        if (exobj == null) {
-            return null;
-        }
-        Record[] records = run._records;
-        if(records != null) find(records, exobj, lst);
-
-        Hyperlink[] links = null;
-        if (lst.size() > 0){
-            links = new Hyperlink[lst.size()];
-            lst.toArray(links);
-        }
-        return links;
-    }
-
-    /**
-     * Find hyperlink assigned to the supplied shape
-     *
-     * @param shape  <code>Shape</code> to lookup hyperlink in
-     * @return found hyperlink or <code>null</code>
-     */
-    protected static Hyperlink find(HSLFShape shape){
-        List<Hyperlink> lst = new ArrayList<Hyperlink>();
-        HSLFSlideShow ppt = shape.getSheet().getSlideShow();
-        //document-level container which stores info about all links in a presentation
-        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
-        if (exobj == null) {
-            return null;
-        }
-
-        EscherContainerRecord spContainer = shape.getSpContainer();
-        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext(); ) {
-            EscherRecord obj = it.next();
-            if (obj.getRecordId() ==  EscherClientDataRecord.RECORD_ID){
-                byte[] data = obj.serialize();
-                Record[] records = Record.findChildRecords(data, 8, data.length-8);
-                if(records != null) find(records, exobj, lst);
-            }
-        }
-
-        return lst.size() == 1 ? (Hyperlink)lst.get(0) : null;
-    }
-
-    private static void find(Record[] records, ExObjList exobj, List<Hyperlink> out){
-        for (int i = 0; i < records.length; i++) {
-            //see if we have InteractiveInfo in the textrun's records
-            if( records[i] instanceof InteractiveInfo){
-                InteractiveInfo hldr = (InteractiveInfo)records[i];
-                InteractiveInfoAtom info = hldr.getInteractiveInfoAtom();
-                int id = info.getHyperlinkID();
-                ExHyperlink linkRecord = exobj.get(id);
-                if (linkRecord != null){
-                    Hyperlink link = new Hyperlink();
-                    link.title = linkRecord.getLinkTitle();
-                    link.address = linkRecord.getLinkURL();
-                    link.type = info.getAction();
-
-                    if (++i < records.length && records[i] instanceof TxInteractiveInfoAtom){
-                        TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom)records[i];
-                        link.startIndex = txinfo.getStartIndex();
-                        link.endIndex = txinfo.getEndIndex();
-                    }
-                    out.add(link);
-                }
-            }
-        }
-    }
-}
index b2e0b35884c09aa1eafb819f030da73850c8f113..b28c88ec68cf2194da1182fc35bc61fe41a00763 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.hslf.model;
 
 import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
 
@@ -30,7 +31,7 @@ import java.awt.geom.Line2D;
  *  @author Yegor Kozlov
  */
 public final class Line extends HSLFSimpleShape {
-    protected Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+    public Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
         super(escherRecord, parent);
     }
 
index e366fdbe924b7b65c3da2f1d76c3b3ca894ea512..27b00005372383561b719203c30c3b011a634c2b 100644 (file)
@@ -24,7 +24,7 @@ import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherProperties;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 
 /**
@@ -67,7 +67,7 @@ public final class MovieShape extends HSLFPictureShape {
       *        this picture in the <code>Slide</code>
       * @param parent the parent shape of this picture
       */
-     protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+    public MovieShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
         super(escherRecord, parent);
     }
 
index 49ed8c2073d2cceab51ce2d15a3d9daef68df353..be680bfd815b3d2935b58d2186ccd1413d50636f 100644 (file)
@@ -18,8 +18,7 @@
 package org.apache.poi.hslf.model;
 
 import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFObjectData;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hslf.record.ExObjList;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.ExEmbed;
@@ -63,7 +62,7 @@ public final class OLEShape extends HSLFPictureShape {
       *        this picture in the <code>Slide</code>
       * @param parent the parent shape of this picture
       */
-     protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+    public OLEShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
         super(escherRecord, parent);
     }
 
index 47500df2f6106dcfe10328e5d94eb421b538214c..526ccc7dc126ce64e3aee443e1bc48398eb3aa48 100644 (file)
@@ -19,19 +19,20 @@ package org.apache.poi.hslf.model;
 
 
 import java.awt.*;
-import java.awt.Shape;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.font.TextLayout;
+import java.awt.font.*;
+import java.awt.geom.*;
 import java.awt.image.*;
 import java.awt.image.renderable.RenderableImage;
-import java.awt.geom.*;
 import java.text.AttributedCharacterIterator;
 import java.util.Map;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
+
 import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.util.POILogger;
+import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
 
 /**
  * Translates Graphics2D calls into PowerPoint.
@@ -251,10 +252,10 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
      */
     public void drawString(String s, float x, float y) {
         HSLFTextBox txt = new HSLFTextBox(_group);
-        txt.getTextParagraph().supplySheet(_group.getSheet());
+        txt.getTextParagraphs().get(0).supplySheet(_group.getSheet());
         txt.setText(s);
 
-        HSLFTextRun rt = txt.getTextParagraph().getRichTextRuns()[0];
+        HSLFTextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0);
         rt.setFontSize(_font.getSize());
         rt.setFontName(_font.getFamily());
 
@@ -262,13 +263,13 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
         if (_font.isBold()) rt.setBold(true);
         if (_font.isItalic()) rt.setItalic(true);
 
-        txt.setMarginBottom(0);
-        txt.setMarginTop(0);
-        txt.setMarginLeft(0);
-        txt.setMarginRight(0);
+        txt.setBottomInset(0);
+        txt.setTopInset(0);
+        txt.setLeftInset(0);
+        txt.setRightInset(0);
         txt.setWordWrap(HSLFTextBox.WrapNone);
-        txt.setHorizontalAlignment(HSLFTextBox.AlignLeft);
-        txt.setVerticalAlignment(HSLFTextBox.AnchorMiddle);
+        txt.setHorizontalCentered(false);
+        txt.setVerticalAlignment(VerticalAlignment.MIDDLE);
 
 
         TextLayout layout = new TextLayout(s, _font, getFontRenderContext());
@@ -1794,7 +1795,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
             float[] dash = bs.getDashArray();
             if (dash != null) {
                 //TODO: implement more dashing styles
-                shape.setLineDashing(Line.PEN_DASH);
+                shape.setLineDashing(StrokeStyle.LineDash.DASH);
             }
         }
     }
index 470f6a42048d23be8843161d7c68572f5dda0153..78e7a47350d5f8678e26a4fc145dbfb19bf963ab 100644 (file)
@@ -19,6 +19,8 @@ package org.apache.poi.hslf.model;
 
 import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.record.OEPlaceholderAtom;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFTextBox;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 
index 7bfd95a571ea3d2da687ee94049b94eca29eecff..25f93a4e89fe2852e3ad25ae8a0bad61dec71d1b 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.hslf.model;
 
 import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.apache.poi.util.LittleEndian;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
deleted file mode 100644 (file)
index d21cf9d..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* ====================================================================
-   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.util.Iterator;
-import java.util.List;
-
-import org.apache.poi.ddf.EscherClientDataRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherProperty;
-import org.apache.poi.ddf.EscherPropertyFactory;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.hslf.record.InteractiveInfo;
-import org.apache.poi.hslf.record.InteractiveInfoAtom;
-import org.apache.poi.hslf.record.OEShapeAtom;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * Create a <code>Shape</code> object depending on its type
- *
- * @author Yegor Kozlov
- */
-public final class ShapeFactory {
-    // For logging
-    protected static final POILogger logger = POILogFactory.getLogger(ShapeFactory.class);
-
-    /**
-     * Create a new shape from the data provided.
-     */
-    public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
-        if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
-            return createShapeGroup(spContainer, parent);
-        }
-        return createSimpeShape(spContainer, parent);
-    }
-
-    public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
-        HSLFGroupShape group = null;
-        EscherRecord opt = HSLFShape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
-        if(opt != null){
-            try {
-                EscherPropertyFactory f = new EscherPropertyFactory();
-                List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
-                EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
-                if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
-                    group = new Table(spContainer, parent);
-                } else {
-                    group = new HSLFGroupShape(spContainer, parent);
-                }
-            } catch (Exception e){
-                logger.log(POILogger.WARN, e.getMessage());
-                group = new HSLFGroupShape(spContainer, parent);
-            }
-        }  else {
-            group = new HSLFGroupShape(spContainer, parent);
-        }
-
-        return group;
-     }
-
-    public static HSLFShape createSimpeShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
-        HSLFShape shape = null;
-        EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
-
-        ShapeType type = ShapeType.forId(spRecord.getShapeType(), false);
-        switch (type){
-            case TEXT_BOX:
-                shape = new HSLFTextBox(spContainer, parent);
-                break;
-            case HOST_CONTROL:
-            case FRAME: {
-                InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
-                OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
-                if(info != null && info.getInteractiveInfoAtom() != null){
-                    switch(info.getInteractiveInfoAtom().getAction()){
-                        case InteractiveInfoAtom.ACTION_OLE:
-                            shape = new OLEShape(spContainer, parent);
-                            break;
-                        case InteractiveInfoAtom.ACTION_MEDIA:
-                            shape = new MovieShape(spContainer, parent);
-                            break;
-                        default:
-                            break;
-                    }
-                } else if (oes != null){
-                    shape = new OLEShape(spContainer, parent);
-                }
-
-                if(shape == null) shape = new HSLFPictureShape(spContainer, parent);
-                break;
-            }
-            case LINE:
-                shape = new Line(spContainer, parent);
-                break;
-            case NOT_PRIMITIVE: {
-                EscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
-                EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
-                if(prop != null)
-                    shape = new HSLFFreeformShape(spContainer, parent);
-                else {
-
-                    logger.log(POILogger.WARN, "Creating AutoShape for a NotPrimitive shape");
-                    shape = new HSLFAutoShape(spContainer, parent);
-                }
-                break;
-            }
-            default:
-                shape = new HSLFAutoShape(spContainer, parent);
-                break;
-        }
-        return shape;
-
-    }
-
-    @SuppressWarnings("unchecked")
-    protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
-        Record oep = null;
-        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
-            EscherRecord obj = it.next();
-            if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
-                byte[] data = obj.serialize();
-                Record[] records = Record.findChildRecords(data, 8, data.length - 8);
-                for (int j = 0; j < records.length; j++) {
-                    if (records[j].getRecordType() == recordType) {
-                        return (T)records[j];
-                    }
-                }
-            }
-        }
-        return (T)oep;
-    }
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java
deleted file mode 100644 (file)
index 52e5a86..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* ====================================================================
-   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;
-
-/**
- * Date: Apr 17, 2008
- *
- * @author Yegor Kozlov
- */
-public interface ShapeOutline {
-    java.awt.Shape getOutline(HSLFShape shape);
-
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapePainter.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapePainter.java
deleted file mode 100644 (file)
index e9686a6..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* ====================================================================
-   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.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Stroke;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * Paint a shape into java.awt.Graphics2D
- *
- * @author Yegor Kozlov
- */
-public final class ShapePainter {
-    protected static final POILogger logger = POILogFactory.getLogger(ShapePainter.class);
-
-    public static void paint(HSLFSimpleShape shape, Graphics2D graphics){
-        Rectangle2D anchor = shape.getLogicalAnchor2D();
-        java.awt.Shape outline = shape.getOutline();
-
-        //flip vertical
-        if(shape.getFlipVertical()){
-            graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
-            graphics.scale(1, -1);
-            graphics.translate(-anchor.getX(), -anchor.getY());
-        }
-        //flip horizontal
-        if(shape.getFlipHorizontal()){
-            graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
-            graphics.scale(-1, 1);
-            graphics.translate(-anchor.getX() , -anchor.getY());
-        }
-
-        //rotate transform
-        double angle = shape.getRotation();
-
-        if(angle != 0){
-            double centerX = anchor.getX() + anchor.getWidth()/2;
-            double centerY = anchor.getY() + anchor.getHeight()/2;
-
-            graphics.translate(centerX, centerY);
-            graphics.rotate(Math.toRadians(angle));
-            graphics.translate(-centerX, -centerY);
-        }
-
-        //fill
-        Color fillColor = shape.getFill().getForegroundColor();
-        if (fillColor != null) {
-            //TODO: implement gradient and texture fill patterns
-            graphics.setPaint(fillColor);
-            graphics.fill(outline);
-        }
-
-        //border
-        Color lineColor = shape.getLineColor();
-        if (lineColor != null){
-            graphics.setPaint(lineColor);
-            float width = (float)shape.getLineWidth();
-
-            int dashing = shape.getLineDashing();
-            //TODO: implement more dashing styles
-            float[] dashptrn = null;
-            switch(dashing){
-                case Line.PEN_SOLID:
-                    dashptrn = null;
-                    break;
-                case Line.PEN_PS_DASH:
-                    dashptrn = new float[]{width, width};
-                    break;
-                case Line.PEN_DOTGEL:
-                    dashptrn = new float[]{width*4, width*3};
-                    break;
-               default:
-                    logger.log(POILogger.WARN, "unsupported dashing: " + dashing);
-                    dashptrn = new float[]{width, width};
-                    break;
-            }
-
-            Stroke stroke = new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dashptrn, 0.0f);
-            graphics.setStroke(stroke);
-            graphics.draw(outline);
-        }
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java
deleted file mode 100644 (file)
index 859ceeb..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-
-/**
- * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation.
- * It stores information about default font styles, placeholder sizes and positions,
- * background design, and color schemes.
- *
- * @author Yegor Kozlov
- */
-public final class SlideMaster extends HSLFMasterSheet {
-    private HSLFTextParagraph[] _runs;
-
-    /**
-     * all TxMasterStyleAtoms available in this master
-     */
-    private TxMasterStyleAtom[] _txmaster;
-
-    /**
-     * Constructs a SlideMaster from the MainMaster record,
-     *
-     */
-    public SlideMaster(MainMaster record, int sheetNo) {
-        super(record, sheetNo);
-
-        _runs = findTextRuns(getPPDrawing());
-        for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
-    }
-
-    /**
-     * Returns an array of all the TextRuns found
-     */
-    public HSLFTextParagraph[] getTextRuns() {
-        return _runs;
-    }
-
-    /**
-     * Returns <code>null</code> since SlideMasters doen't have master sheet.
-     */
-    public HSLFMasterSheet getMasterSheet() {
-        return null;
-    }
-
-    /**
-     * Pickup a style attribute from the master.
-     * This is the "workhorse" which returns the default style attrubutes.
-     */
-    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
-
-        TextProp prop = null;
-        for (int i = level; i >= 0; i--) {
-            TextPropCollection[] styles =
-                    isCharacter ? _txmaster[txtype].getCharacterStyles() : _txmaster[txtype].getParagraphStyles();
-            if (i < styles.length) prop = styles[i].findByName(name);
-            if (prop != null) break;
-        }
-        if (prop == null) {
-            if(isCharacter) {
-                switch (txtype) {
-                    case TextHeaderAtom.CENTRE_BODY_TYPE:
-                    case TextHeaderAtom.HALF_BODY_TYPE:
-                    case TextHeaderAtom.QUARTER_BODY_TYPE:
-                        txtype = TextHeaderAtom.BODY_TYPE;
-                        break;
-                    case TextHeaderAtom.CENTER_TITLE_TYPE:
-                        txtype = TextHeaderAtom.TITLE_TYPE;
-                        break;
-                    default:
-                        return null;
-                }
-            } else {
-                switch (txtype) {
-                    case TextHeaderAtom.CENTRE_BODY_TYPE:
-                    case TextHeaderAtom.HALF_BODY_TYPE:
-                    case TextHeaderAtom.QUARTER_BODY_TYPE:
-                        txtype = TextHeaderAtom.BODY_TYPE;
-                        break;
-                    case TextHeaderAtom.CENTER_TITLE_TYPE:
-                        txtype = TextHeaderAtom.TITLE_TYPE;
-                        break;
-                    default:
-                        return null;
-                }
-            }
-            prop = getStyleAttribute(txtype, level, name, isCharacter);
-        }
-        return prop;
-    }
-
-    /**
-     * Assign SlideShow for this slide master.
-     * (Used interanlly)
-     */
-    public void setSlideShow(HSLFSlideShow ss) {
-        super.setSlideShow(ss);
-
-        //after the slide show is assigned collect all available style records
-        if (_txmaster == null) {
-            _txmaster = new TxMasterStyleAtom[9];
-
-            TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom();
-            _txmaster[txdoc.getTextType()] = txdoc;
-
-            TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms();
-            for (int i = 0; i < txrec.length; i++) {
-                int txType = txrec[i].getTextType();
-                if(_txmaster[txType] == null) _txmaster[txType] = txrec[i];
-            }
-        }
-    }
-
-    protected void onAddTextShape(HSLFTextShape shape) {
-        HSLFTextParagraph run = shape.getTextParagraph();
-
-        if(_runs == null) _runs = new HSLFTextParagraph[]{run};
-        else {
-            HSLFTextParagraph[] tmp = new HSLFTextParagraph[_runs.length + 1];
-            System.arraycopy(_runs, 0, tmp, 0, _runs.length);
-            tmp[tmp.length-1] = run;
-            _runs = tmp;
-        }
-    }
-
-    public TxMasterStyleAtom[] getTxMasterStyleAtoms(){
-        return _txmaster;
-    }
-}
index 99ee13f211ace0d467be60402e1e1d43750f75cd..c2cc0ce80bc55201612534b41c4762e9ba34e1f3 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.hslf.model;
 
 import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.util.LittleEndian;
 
@@ -319,9 +320,9 @@ public final class Table extends HSLFGroupShape {
     private Line cloneBorder(Line line){
         Line border = createBorder();
         border.setLineWidth(line.getLineWidth());
-        border.setLineStyle(line.getStrokeStyle());
         border.setLineDashing(line.getLineDashing());
         border.setLineColor(line.getLineColor());
+        border.setLineCompound(line.getLineCompound());
         return border;
     }
 
index 18431a720ca090f0a5ab57354594f35b32cbed9b..cfdee76633aec2184a3aa6925df0564d71fbcb70 100644 (file)
@@ -22,6 +22,8 @@ import java.awt.Rectangle;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherOptRecord;
 import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFTextBox;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
 
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java
deleted file mode 100644 (file)
index 038e28a..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/* ====================================================================
-   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.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineBreakMeasurer;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.poi.hslf.record.TextRulerAtom;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-/**
- * Paint text into java.awt.Graphics2D
- *
- * @author Yegor Kozlov
- */
-public final class TextPainter {
-    public static final Key KEY_FONTFALLBACK = new Key(50, "Font fallback map");
-    public static final Key KEY_FONTMAP = new Key(51, "Font map");
-    
-    protected POILogger logger = POILogFactory.getLogger(this.getClass());
-
-    /**
-     * Display unicode square if a bullet char can't be displayed,
-     * for example, if Wingdings font is used.
-     * TODO: map Wingdngs and Symbol to unicode Arial
-     */
-    protected static final char DEFAULT_BULLET_CHAR = '\u25a0';
-
-    protected HSLFTextShape _shape;
-
-    public TextPainter(HSLFTextShape shape){
-        _shape = shape;
-    }
-
-    public AttributedString getAttributedString(HSLFTextParagraph txrun) {
-        return getAttributedString(txrun, null);
-    }
-    
-    /**
-     * Convert the underlying set of rich text runs into java.text.AttributedString
-     */
-    public AttributedString getAttributedString(HSLFTextParagraph txrun, Graphics2D graphics){
-        String text = txrun.getText();
-        //TODO: properly process tabs
-        text = text.replace('\t', ' ');
-        text = text.replace((char)160, ' ');
-
-        AttributedString at = new AttributedString(text);
-        HSLFTextRun[] rt = txrun.getRichTextRuns();
-        for (int i = 0; i < rt.length; i++) {
-            int start = rt[i].getStartIndex();
-            int end = rt[i].getEndIndex();
-            if(start == end) {
-                logger.log(POILogger.INFO,  "Skipping RichTextRun with zero length");
-                continue;
-            }
-
-            String mappedFont = rt[i].getFontName();
-            String fallbackFont = Font.SANS_SERIF;
-            if (graphics != null) {
-                @SuppressWarnings("unchecked")
-                Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(KEY_FONTMAP);
-                if (fontMap != null && fontMap.containsKey(mappedFont)) {
-                    mappedFont = fontMap.get(mappedFont);
-                }
-                @SuppressWarnings("unchecked")
-                Map<String,String> fallbackMap = (Map<String,String>)graphics.getRenderingHint(KEY_FONTFALLBACK);
-                if (fallbackMap != null && fallbackMap.containsKey(mappedFont)) {
-                    fallbackFont = fallbackMap.get(mappedFont);
-                }
-            }
-            
-            at.addAttribute(TextAttribute.FAMILY, mappedFont, start, end);
-            at.addAttribute(TextAttribute.SIZE, new Float(rt[i].getFontSize()), start, end);
-            at.addAttribute(TextAttribute.FOREGROUND, rt[i].getFontColor(), start, end);
-            if(rt[i].isBold()) at.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, start, end);
-            if(rt[i].isItalic()) at.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, start, end);
-            if(rt[i].isUnderlined()) {
-                at.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, start, end);
-                at.addAttribute(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, start, end);
-            }
-            if(rt[i].isStrikethrough()) at.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, start, end);
-            int superScript = rt[i].getSuperscript();
-            if(superScript != 0) at.addAttribute(TextAttribute.SUPERSCRIPT, superScript > 0 ? TextAttribute.SUPERSCRIPT_SUPER : TextAttribute.SUPERSCRIPT_SUB, start, end);
-            
-            
-            int style = (rt[i].isBold() ? Font.BOLD : 0) | (rt[i].isItalic() ? Font.ITALIC : 0);
-            Font f = new Font(mappedFont, style, rt[i].getFontSize());
-            
-            // check for unsupported characters and add a fallback font for these
-            char textChr[] = text.toCharArray();
-            int nextEnd = f.canDisplayUpTo(textChr, start, end);
-            boolean isNextValid = nextEnd == start;
-            for (int last = start; nextEnd != -1 && nextEnd <= end; ) {
-                if (isNextValid) {
-                    nextEnd = f.canDisplayUpTo(textChr, nextEnd, end);
-                    isNextValid = false;
-                } else {
-                    if (nextEnd >= end || f.canDisplay(Character.codePointAt(textChr, nextEnd, end)) ) {
-                        at.addAttribute(TextAttribute.FAMILY, fallbackFont, last, Math.min(nextEnd,end));
-                        if (nextEnd >= end) break;
-                        last = nextEnd;
-                        isNextValid = true;
-                    } else {
-                        boolean isHS = Character.isHighSurrogate(textChr[nextEnd]);
-                        nextEnd+=(isHS?2:1);
-                    }
-                }
-            }            
-        }
-        return at;
-    }
-
-    public void paint(Graphics2D graphics){
-        AffineTransform tx = graphics.getTransform();
-
-        Rectangle2D anchor = _shape.getLogicalAnchor2D();
-        TextElement[] elem = getTextElements((float)anchor.getWidth(), graphics.getFontRenderContext(), graphics);
-        if(elem == null) return;
-
-        float textHeight = 0;
-        for (int i = 0; i < elem.length; i++) {
-            textHeight += elem[i].ascent + elem[i].descent;
-        }
-
-        int valign = _shape.getVerticalAlignment();
-        double y0 = anchor.getY();
-        switch (valign){
-            case HSLFTextShape.AnchorTopBaseline:
-            case HSLFTextShape.AnchorTop:
-                y0 += _shape.getMarginTop();
-                break;
-            case HSLFTextShape.AnchorBottom:
-                y0 += anchor.getHeight() - textHeight - _shape.getMarginBottom();
-                break;
-            default:
-            case HSLFTextShape.AnchorMiddle:
-                float delta =  (float)anchor.getHeight() - textHeight - _shape.getMarginTop() - _shape.getMarginBottom();
-                y0 += _shape.getMarginTop()  + delta/2;
-                break;
-        }
-
-
-        // Transform of text in flipped shapes is special.
-        // At this point the flip and rotation transform is already applied
-        // (see XSLFShape#applyTransform ), but we need to restore it to avoid painting "upside down".
-        // See Bugzilla 54210.
-        if(_shape.getFlipVertical()){
-            graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
-            graphics.scale(1, -1);
-            graphics.translate(-anchor.getX(), -anchor.getY());
-
-            // text in vertically flipped shapes is rotated by 180 degrees
-            double centerX = anchor.getX() + anchor.getWidth()/2;
-            double centerY = anchor.getY() + anchor.getHeight()/2;
-            graphics.translate(centerX, centerY);
-            graphics.rotate(Math.toRadians(180));
-            graphics.translate(-centerX, -centerY);
-        }
-
-        // Horizontal flipping applies only to shape outline and not to the text in the shape.
-        // Applying flip second time restores the original not-flipped transform
-        if(_shape.getFlipHorizontal()){
-            graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
-            graphics.scale(-1, 1);
-            graphics.translate(-anchor.getX() , -anchor.getY());
-        }
-
-        //finally draw the text fragments
-        for (int i = 0; i < elem.length; i++) {
-            y0 += elem[i].ascent;
-
-            Point2D.Double pen = new Point2D.Double();
-            pen.y = y0;
-            switch (elem[i]._align) {
-                default:
-                case HSLFTextShape.AlignLeft:
-                    pen.x = anchor.getX() + _shape.getMarginLeft();
-                    break;
-                case HSLFTextShape.AlignCenter:
-                    pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
-                    break;
-                case HSLFTextShape.AlignRight:
-                    pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight());
-                    break;
-            }
-            if(elem[i]._bullet != null){
-                graphics.drawString(elem[i]._bullet.getIterator(), (float)(pen.x + elem[i]._bulletOffset), (float)pen.y);
-            }
-            AttributedCharacterIterator chIt = elem[i]._text.getIterator();
-            if(chIt.getEndIndex() > chIt.getBeginIndex()) {
-                graphics.drawString(chIt, (float)(pen.x + elem[i]._textOffset), (float)pen.y);
-            }
-            y0 += elem[i].descent;
-        }
-
-        graphics.setTransform(tx);
-    }
-
-    public TextElement[] getTextElements(float textWidth, FontRenderContext frc){
-        return getTextElements(textWidth, frc, null);
-    }
-    
-    public TextElement[] getTextElements(float textWidth, FontRenderContext frc, Graphics2D graphics){
-        HSLFTextParagraph run = _shape.getTextParagraph();
-        if (run == null) return null;
-
-        String text = run.getText();
-        if (text == null || text.equals("")) return null;
-
-        AttributedString at = getAttributedString(run, graphics);
-
-        AttributedCharacterIterator it = at.getIterator();
-        int paragraphStart = it.getBeginIndex();
-        int paragraphEnd = it.getEndIndex();
-
-        List<TextElement> lines = new ArrayList<TextElement>();
-        LineBreakMeasurer measurer = new LineBreakMeasurer(it, frc);
-        measurer.setPosition(paragraphStart);
-        while (measurer.getPosition() < paragraphEnd) {
-            int startIndex = measurer.getPosition();
-            int nextBreak = text.indexOf('\n', measurer.getPosition() + 1);
-
-            boolean prStart = text.charAt(startIndex) == '\n';
-            if(prStart) measurer.setPosition(startIndex++);
-
-            HSLFTextRun rt = run.getRichTextRunAt(startIndex == text.length() ? (startIndex-1) : startIndex);
-            if(rt == null) {
-                logger.log(POILogger.WARN,  "RichTextRun not found at pos" + startIndex + "; text.length: " + text.length());
-                break;
-            }
-
-            float wrappingWidth = textWidth - _shape.getMarginLeft() - _shape.getMarginRight();
-            int bulletOffset = rt.getBulletOffset();
-            int textOffset = rt.getTextOffset();
-            int indent = rt.getIndentLevel();
-
-            TextRulerAtom ruler = run.getTextRuler();
-            if(ruler != null) {
-                int bullet_val = ruler.getBulletOffsets()[indent]*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-                int text_val = ruler.getTextOffsets()[indent]*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-                if(bullet_val > text_val){
-                    int a = bullet_val;
-                    bullet_val = text_val;
-                    text_val = a;
-                }
-                if(bullet_val != 0 ) bulletOffset = bullet_val;
-                if(text_val != 0) textOffset = text_val;
-            }
-
-            if(bulletOffset > 0 || prStart || startIndex == 0) wrappingWidth -= textOffset;
-
-            if (_shape.getWordWrap() == HSLFTextShape.WrapNone) {
-                wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
-            }
-
-            TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
-                    nextBreak == -1 ? paragraphEnd : nextBreak, true);
-            if (textLayout == null) {
-                textLayout = measurer.nextLayout(textWidth,
-                    nextBreak == -1 ? paragraphEnd : nextBreak, false);
-            }
-            if(textLayout == null){
-                logger.log(POILogger.WARN, "Failed to break text into lines: wrappingWidth: "+wrappingWidth+
-                        "; text: " + rt.getText());
-                measurer.setPosition(rt.getEndIndex());
-                continue;
-            }
-            int endIndex = measurer.getPosition();
-
-            float lineHeight = (float)textLayout.getBounds().getHeight();
-            int linespacing = rt.getLineSpacing();
-            if(linespacing == 0) linespacing = 100;
-
-            TextElement el = new TextElement();
-            if(linespacing >= 0){
-                el.ascent = textLayout.getAscent()*linespacing/100;
-            } else {
-                el.ascent = -linespacing*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-            }
-
-            el._align = rt.getAlignment();
-            el.advance = textLayout.getAdvance();
-            el._textOffset = textOffset;
-            el._text = new AttributedString(it, startIndex, endIndex);
-            el.textStartIndex = startIndex;
-            el.textEndIndex = endIndex;
-
-            if (prStart){
-                int sp = rt.getSpaceBefore();
-                float spaceBefore;
-                if(sp >= 0){
-                    spaceBefore = lineHeight * sp/100;
-                } else {
-                    spaceBefore = -sp*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-                }
-                el.ascent += spaceBefore;
-            }
-
-            float descent;
-            if(linespacing >= 0){
-                descent = (textLayout.getDescent() + textLayout.getLeading())*linespacing/100;
-            } else {
-                descent = -linespacing*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-            }
-            if (prStart){
-                int sp = rt.getSpaceAfter();
-                float spaceAfter;
-                if(sp >= 0){
-                    spaceAfter = lineHeight * sp/100;
-                } else {
-                    spaceAfter = -sp*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-                }
-                el.ascent += spaceAfter;
-            }
-            el.descent = descent;
-
-            if(rt.isBullet() && (prStart || startIndex == 0)){
-                it.setIndex(startIndex);
-
-                AttributedString bat = new AttributedString(Character.toString(rt.getBulletChar()));
-                Color clr = rt.getBulletColor();
-                if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
-                else bat.addAttribute(TextAttribute.FOREGROUND, it.getAttribute(TextAttribute.FOREGROUND));
-
-                int fontIdx = rt.getBulletFont();
-                if(fontIdx == -1) fontIdx = rt.getFontIndex();
-                PPFont bulletFont = _shape.getSheet().getSlideShow().getFont(fontIdx);
-                bat.addAttribute(TextAttribute.FAMILY, bulletFont.getFontName());
-
-                int bulletSize = rt.getBulletSize();
-                int fontSize = rt.getFontSize();
-                if(bulletSize != -1) fontSize = Math.round(fontSize*bulletSize*0.01f);
-                bat.addAttribute(TextAttribute.SIZE, new Float(fontSize));
-
-                if(!new Font(bulletFont.getFontName(), Font.PLAIN, 1).canDisplay(rt.getBulletChar())){
-                    bat.addAttribute(TextAttribute.FAMILY, "Arial");
-                    bat = new AttributedString("" + DEFAULT_BULLET_CHAR, bat.getIterator().getAttributes());
-                }
-
-                if(text.substring(startIndex, endIndex).length() > 1){
-                    el._bullet = bat;
-                    el._bulletOffset = bulletOffset;
-                }
-            }
-            lines.add(el);
-        }
-
-        //finally draw the text fragments
-        TextElement[] elems = new TextElement[lines.size()];
-        return lines.toArray(elems);
-    }
-
-    public static class TextElement {
-        public AttributedString _text;
-        public int _textOffset;
-        public AttributedString _bullet;
-        public int _bulletOffset;
-        public int _align;
-        public float ascent, descent;
-        public float advance;
-        public int textStartIndex, textEndIndex;
-    }
-
-    public static class Key extends RenderingHints.Key {
-      String description;
-
-      public Key(int paramInt, String paramString) {
-        super(paramInt);
-        this.description = paramString;
-      }
-
-      public final int getIndex() {
-        return intKey();
-      }
-
-      public final String toString() {
-        return this.description;
-      }
-
-      public boolean isCompatibleValue(Object paramObject) {
-        return true;
-      }
-    }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java b/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java
deleted file mode 100644 (file)
index 8184c03..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ====================================================================
-   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 org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.record.*;
-
-/**
- * Title masters define the design template for slides with a Title Slide layout.
- *
- * @author Yegor Kozlov
- */
-public final class TitleMaster extends HSLFMasterSheet {
-    private HSLFTextParagraph[] _runs;
-
-    /**
-     * Constructs a TitleMaster
-     *
-     */
-    public TitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
-        super(record, sheetNo);
-
-        _runs = findTextRuns(getPPDrawing());
-        for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
-    }
-
-    /**
-     * Returns an array of all the TextRuns found
-     */
-    public HSLFTextParagraph[] getTextRuns() {
-        return _runs;
-    }
-
-    /**
-     * Delegate the call to the underlying slide master.
-     */
-    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
-        HSLFMasterSheet master = getMasterSheet();
-        return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
-    }
-
-    /**
-     * Returns the slide master for this title master.
-     */
-    public HSLFMasterSheet getMasterSheet(){
-        SlideMaster[] master = getSlideShow().getSlidesMasters();
-        SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
-        int masterId = sa.getMasterID();
-        for (int i = 0; i < master.length; i++) {
-            if (masterId == master[i]._getSheetNumber()) return master[i];
-        }
-        return null;
-    }
-}
index cf25eb6cd196cfb5a4103b5e7db1a7fd76195c79..0f8bab418c9e825e4300e820e6cc6eed664ee688 100644 (file)
@@ -24,7 +24,7 @@ package org.apache.poi.hslf.model.textproperties;
  *  of the property is itself a mask, encoding several different
  *  (but related) properties
  */
-public class BitMaskTextProp extends TextProp implements Cloneable {
+public abstract class BitMaskTextProp extends TextProp implements Cloneable {
        private String[] subPropNames;
        private int[] subPropMasks;
        private boolean[] subPropMatches;
@@ -91,7 +91,8 @@ public class BitMaskTextProp extends TextProp implements Cloneable {
                subPropMatches[idx] = value;
        }
        
-       public Object clone(){
+       @Override
+       public BitMaskTextProp clone(){
                BitMaskTextProp newObj = (BitMaskTextProp)super.clone();
                
                // Don't carry over matches, but keep everything 
index 662833203f31c74bc350a6b71f3532b368ec8505..40adf46d8f819cdd473e666cbcd8391725c5db20 100644 (file)
@@ -41,7 +41,7 @@ public class IndentProp  {
     public int getCharactersCovered() { return charactersCovered; }
     
     public int getIndentLevel() {
-        return (int)indentLevel;
+        return indentLevel;
     }
     
     /**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java
new file mode 100644 (file)
index 0000000..786b373
--- /dev/null
@@ -0,0 +1,113 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hslf.model.textproperties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.poi.util.LittleEndian;\r
+import org.apache.poi.util.LittleEndianConsts;\r
+\r
+/**\r
+ * Container for tabstop lists\r
+ */\r
+public class TabStopPropCollection extends TextProp {\r
+    public enum TabStopType {\r
+        LEFT(0), CENTER(1), RIGHT(2), DECIMAL(3);\r
+        private final int val;\r
+        TabStopType(int val) {\r
+            this.val = val;\r
+        }\r
+        public static TabStopType fromRecordVal(int val)  {\r
+            for (TabStopType tst : values()) {\r
+                if (tst.val == val) return tst;\r
+            }\r
+            return LEFT;\r
+        }\r
+    }\r
+\r
+    public static class TabStop {\r
+        /**\r
+         * If the TextPFException record that contains this TabStop structure also contains a\r
+         * leftMargin, then the value of position is relative to the left margin of the paragraph;\r
+         * otherwise, the value is relative to the left side of the paragraph.\r
+         * \r
+         * If a TextRuler record contains this TabStop structure, the value is relative to the\r
+         * left side of the text ruler.\r
+         */\r
+        private int position;\r
+\r
+        /**\r
+         * A enumeration that specifies how text aligns at the tab stop.\r
+         */\r
+        private TabStopType type;\r
+\r
+        public TabStop(int position, TabStopType type) {\r
+            this.position = position;\r
+            this.type = type;\r
+        }\r
+        \r
+        public int getPosition() {\r
+            return position;\r
+        }\r
+\r
+        public void setPosition(int position) {\r
+            this.position = position;\r
+        }\r
+\r
+        public TabStopType getType() {\r
+            return type;\r
+        }\r
+\r
+        public void setType(TabStopType type) {\r
+            this.type = type;\r
+        }\r
+    }\r
+    \r
+    private List<TabStop> tabStops = new ArrayList<TabStop>();\r
+    \r
+    public TabStopPropCollection() {\r
+        super(0, 0x100000, "tabStops");\r
+    }\r
+    \r
+    /**\r
+     * Parses the tabstops from TxMasterStyle record\r
+     *\r
+     * @param data the data stream\r
+     * @param offset the offset within the data\r
+     * @return the new offset\r
+     */\r
+    public void parseProperty(byte data[], int offset) {\r
+        int count = LittleEndian.getUShort(data, offset);\r
+        offset += LittleEndianConsts.SHORT_SIZE;\r
+        for (int i=0; i<count; i++) {\r
+            int position = LittleEndian.getShort(data, offset);\r
+            offset += LittleEndianConsts.SHORT_SIZE;\r
+            int recVal = LittleEndian.getShort(data, offset);\r
+            TabStopType type = TabStopType.fromRecordVal(recVal);\r
+            offset += LittleEndianConsts.SHORT_SIZE;\r
+            tabStops.add(new TabStop(position, type));\r
+            \r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public int getSize() {\r
+        return LittleEndianConsts.SHORT_SIZE + tabStops.size()*LittleEndianConsts.INT_SIZE;\r
+    }\r
+}\r
index c42ac71839d21416f5297eff3f45e0a79f0f956f..07d663b4a99924a6b5f1da9a39937f81dceb448a 100644 (file)
@@ -44,6 +44,16 @@ public class TextProp implements Cloneable {
                this.dataValue = 0;
        }
 
+       /**
+        * Clones the property
+        */
+       public TextProp(TextProp other) {
+           this.sizeOfDataBlock = other.sizeOfDataBlock;
+           this.maskInHeader = other.maskInHeader;
+           this.propName = other.propName;
+           this.dataValue = other.dataValue;
+       }
+       
        /**
         * Name of the text property
         */
@@ -79,11 +89,36 @@ public class TextProp implements Cloneable {
        /**
         * Clone, eg when you want to actually make use of one of these.
         */
-       public Object clone(){
+       @Override
+       public TextProp clone(){
                try {
-                       return super.clone();
+                       return (TextProp)super.clone();
                } catch(CloneNotSupportedException e) {
                        throw new InternalError(e.getMessage());
                }
        }
+       
+       public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + dataValue;
+        result = prime * result + maskInHeader;
+        result = prime * result + ((propName == null) ? 0 : propName.hashCode());
+        result = prime * result + sizeOfDataBlock;
+        return result;
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        TextProp other = (TextProp) obj;
+        if (dataValue != other.dataValue) return false;
+        if (maskInHeader != other.maskInHeader) return false;
+        if (propName == null) {
+            if (other.propName != null) return false;
+        } else if (!propName.equals(other.propName)) return false;
+        if (sizeOfDataBlock != other.sizeOfDataBlock) return false;
+        return true;
+    }
 }
\ No newline at end of file
index c538f01a54b61f663c9199237724052c5cdc9d42..ac34bf1ffe1b4cdf086bc6389a3ab35b832b1f46 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.poi.hslf.model.textproperties;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.LinkedList;
+import java.util.*;
 
 import org.apache.poi.hslf.record.StyleTextPropAtom;
 import org.apache.poi.util.LittleEndian;
@@ -33,7 +33,7 @@ import org.apache.poi.util.LittleEndian;
 public class TextPropCollection {
        private int charactersCovered;
        private short reservedField;
-       private LinkedList<TextProp> textPropList;
+       private List<TextProp> textPropList;
     private int maskSpecial = 0;
     
     public int getSpecialMask() { return maskSpecial; }
@@ -41,7 +41,7 @@ public class TextPropCollection {
        /** Fetch the number of characters this styling applies to */
        public int getCharactersCovered() { return charactersCovered; }
        /** Fetch the TextProps that define this styling */
-       public LinkedList<TextProp> getTextPropList() { return textPropList; }
+       public List<TextProp> getTextPropList() { return textPropList; }
        
        /** Fetch the TextProp with this name, or null if it isn't present */
        public TextProp findByName(String textPropName) {
@@ -73,7 +73,7 @@ public class TextPropCollection {
                }
                
                // Add a copy of this property, in the right place to the list
-               TextProp textProp = (TextProp)base.clone();
+               TextProp textProp = base.clone();
                int pos = 0;
                for(int i=0; i<textPropList.size(); i++) {
                        TextProp curProp = textPropList.get(i);
@@ -95,28 +95,30 @@ public class TextPropCollection {
 
                // For each possible entry, see if we match the mask
                // If we do, decode that, save it, and shuffle on
-               for(int i=0; i<potentialProperties.length; i++) {
+               for(TextProp tp : potentialProperties) {
                        // Check there's still data left to read
 
                        // Check if this property is found in the mask
-                       if((containsField & potentialProperties[i].getMask()) != 0) {
+                       if((containsField & tp.getMask()) != 0) {
                 if(dataOffset+bytesPassed >= data.length) {
                     // Out of data, can't be any more properties to go
                     // remember the mask and return
-                    maskSpecial |= potentialProperties[i].getMask();
+                    maskSpecial |= tp.getMask();
                     return bytesPassed;
                 }
 
                                // Bingo, data contains this property
-                               TextProp prop = (TextProp)potentialProperties[i].clone();
+                               TextProp prop = tp.clone();
                                int val = 0;
-                               if(prop.getSize() == 2) {
+                               if (prop instanceof TabStopPropCollection) {
+                                   ((TabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed);
+                               } else if (prop.getSize() == 2) {
                                        val = LittleEndian.getShort(data,dataOffset+bytesPassed);
-                               } else if(prop.getSize() == 4){
+                               } else if(prop.getSize() == 4) {
                                        val = LittleEndian.getInt(data,dataOffset+bytesPassed);
-                               } else if (prop.getSize() == 0){
+                               } else if (prop.getSize() == 0) {
                     //remember "special" bits.
-                    maskSpecial |= potentialProperties[i].getMask();
+                    maskSpecial |= tp.getMask();
                     continue;
                 }
                                prop.setValue(val);
@@ -137,7 +139,7 @@ public class TextPropCollection {
        public TextPropCollection(int charactersCovered, short reservedField) {
                this.charactersCovered = charactersCovered;
                this.reservedField = reservedField;
-               textPropList = new LinkedList<TextProp>();
+               textPropList = new ArrayList<TextProp>();
        }
 
        /**
@@ -147,7 +149,27 @@ public class TextPropCollection {
        public TextPropCollection(int textSize) {
                charactersCovered = textSize;
                reservedField = -1;
-               textPropList = new LinkedList<TextProp>();
+               textPropList = new ArrayList<TextProp>();
+       }
+       
+    /**
+     * Clones the given text properties
+     */
+       public void copy(TextPropCollection other) {
+        this.charactersCovered = other.charactersCovered;
+        this.reservedField = other.reservedField;
+        this.textPropList.clear();
+        for (TextProp tp : other.textPropList) {
+            TextProp tpCopy = tp.clone();
+            if (tpCopy instanceof BitMaskTextProp) {
+                BitMaskTextProp bmt = (BitMaskTextProp)tpCopy;
+                boolean matches[] = ((BitMaskTextProp)tp).getSubPropMatches();
+                for (int i=0; i<matches.length; i++) {
+                    bmt.setSubValue(matches[i], i);
+                }
+            }
+            this.textPropList.add(tpCopy);
+        }
        }
        
        /**
@@ -173,7 +195,7 @@ public class TextPropCollection {
                // Then the mask field
                int mask = maskSpecial;
                for(int i=0; i<textPropList.size(); i++) {
-                       TextProp textProp = (TextProp)textPropList.get(i);
+                       TextProp textProp = textPropList.get(i);
             //sometimes header indicates that the bitmask is present but its value is 0
 
             if (textProp instanceof BitMaskTextProp) {
@@ -204,4 +226,44 @@ public class TextPropCollection {
     public void setReservedField(short val){
         reservedField = val;
     }
+    
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + charactersCovered;
+        result = prime * result + maskSpecial;
+        result = prime * result + reservedField;
+        result = prime * result + ((textPropList == null) ? 0 : textPropList.hashCode());
+        return result;
+    }
+    /**
+     * compares most properties apart of the covered characters length
+     */
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if (other == null) return false;
+        if (getClass() != other.getClass()) return false;
+        
+        TextPropCollection o = (TextPropCollection)other;
+        if (o.maskSpecial != this.maskSpecial || o.reservedField != this.reservedField) {
+            return false;
+        }
+
+        if (textPropList == null) {
+            return (o.textPropList == null);
+        }        
+        
+        Map<String,TextProp> m = new HashMap<String,TextProp>();
+        for (TextProp tp : o.textPropList) {
+            m.put(tp.getName(), tp);
+        }
+        
+        for (TextProp tp : this.textPropList) {
+            TextProp otp = m.get(tp.getName());
+            if (!tp.equals(otp)) return false;
+        }
+        
+        return true;
+    }
+
 }
index 3d99e0a716ca24e7e47c2add4f6d463d85b87a35..a3060583411be33d864cd27b45b379695f65902e 100644 (file)
@@ -273,8 +273,8 @@ public final class RecordTypes {
         *  offers methods to get either back out.
         */
        public static class Type {
-               public int typeID;
-               public Class<? extends Record> handlingClass;
+               public final int typeID;
+               public final Class<? extends Record> handlingClass;
                public Type(int typeID, Class<? extends Record> handlingClass) {
                        this.typeID = typeID;
                        this.handlingClass = handlingClass;
index 5730021c9001b2fe45e8e1c4a0235dba45eb121d..4e0654a8a6f7b34775521dcfb7fad59b7c9a14d6 100644 (file)
@@ -22,11 +22,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.LinkedList;
 
-import org.apache.poi.hslf.model.textproperties.AlignmentTextProp;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.model.textproperties.*;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
@@ -51,7 +47,7 @@ import org.apache.poi.util.POILogger;
 public final class StyleTextPropAtom extends RecordAtom
 {
     private byte[] _header;
-    private static long _type = 4001l;
+    private static final long _type = RecordTypes.StyleTextPropAtom.typeID;
     private byte[] reserved;
 
     private byte[] rawContents; // Holds the contents between write-outs
@@ -118,7 +114,9 @@ public final class StyleTextPropAtom extends RecordAtom
     }
 
     /** All the different kinds of paragraph properties we might handle */
-    public static final TextProp[] paragraphTextPropTypes = new TextProp[] {
+    public static final TextProp[] paragraphTextPropTypes = {
+        // TextProp order is according to 2.9.20 TextPFException,
+        // bitmask order can be different
         new TextProp(0, 0x1, "hasBullet"),
         new TextProp(0, 0x2, "hasBulletFont"),
         new TextProp(0, 0x4, "hasBulletColor"),
@@ -129,16 +127,22 @@ public final class StyleTextPropAtom extends RecordAtom
         new TextProp(2, 0x40, "bullet.size"),
         new TextProp(4, 0x20, "bullet.color"),
         new AlignmentTextProp(),
-        new TextProp(2, 0x100, "text.offset"),
-        new TextProp(2, 0x400, "bullet.offset"),
         new TextProp(2, 0x1000, "linespacing"),
         new TextProp(2, 0x2000, "spacebefore"),
         new TextProp(2, 0x4000, "spaceafter"),
+        new TextProp(2, 0x100, "text.offset"), // left margin
+        // 0x200 - Undefined and MUST be ignored
+        new TextProp(2, 0x400, "bullet.offset"), // indent
         new TextProp(2, 0x8000, "defaultTabSize"),
-        new TextProp(2, 0x100000, "tabStops"),
+        new TabStopPropCollection(), // tabstops size is variable!
         new TextProp(2, 0x10000, "fontAlign"),
-        new TextProp(2, 0xA0000, "wrapFlags"),
-        new TextProp(2, 0x200000, "textDirection")
+        new TextProp(2, 0xE0000, "wrapFlags"), // charWrap | wordWrap | overflow
+        new TextProp(2, 0x200000, "textDirection"),
+        // 0x400000 MUST be zero and MUST be ignored
+        new TextProp(0, 0x800000, "bullet.blip"), // TODO: check size
+        new TextProp(0, 0x1000000, "bullet.scheme"), // TODO: check size
+        new TextProp(0, 0x2000000, "hasBulletScheme"), // TODO: check size
+        // 0xFC000000 MUST be zero and MUST be ignored
     };
     /** All the different kinds of character properties we might handle */
     public static final TextProp[] characterTextPropTypes = new TextProp[] {
@@ -391,6 +395,14 @@ public final class StyleTextPropAtom extends RecordAtom
         initialised = false;
     }
 
+    /**
+     * Clear styles, so new collections can be added
+     */
+    public void clearStyles() {
+        paragraphStyles.clear();
+        charStyles.clear();
+    }
+    
     /**
      * Create a new Paragraph TextPropCollection, and add it to the list
      * @param charactersCovered The number of characters this TextPropCollection will cover
index b793613764238997c563848930b5cede11213a5e..a576146d09712b3f5aa89b8d4b33eba354e68057 100644 (file)
@@ -35,7 +35,7 @@ import java.io.OutputStream;
 public final class TextBytesAtom extends RecordAtom
 {
        private byte[] _header;
-       private static long _type = 4008l;
+       private static long _type = RecordTypes.TextBytesAtom.typeID;
 
        /** The bytes that make up the text */
        private byte[] _text;
index e279af060dedbe4c5c66d7c72af8db2a238cb593..3449250ada792fdef7b2e822b881d11712b616f2 100644 (file)
@@ -33,7 +33,7 @@ import java.io.OutputStream;
 public final class TextCharsAtom extends RecordAtom
 {
        private byte[] _header;
-       private static long _type = 4000l;
+       private static long _type = RecordTypes.TextCharsAtom.typeID;
 
        /** The bytes that make up the text */
        private byte[] _text;
index d19a6c1c0173234dbb35134ce17f725150ce4ffb..a63d8934d58823755a8af10d96d1f37c17876ee7 100644 (file)
@@ -32,7 +32,7 @@ import java.io.OutputStream;
 public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord
 {
        private byte[] _header;
-       private static long _type = 3999l;
+       private static long _type = RecordTypes.TextHeaderAtom.typeID;
        private RecordContainer parentRecord;
 
        public static final int TITLE_TYPE = 0;
@@ -46,9 +46,21 @@ public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecor
 
        /** The kind of text it is */
        private int textType;
+       /** position in the owning SlideListWithText */
+       private int index = -1;
 
        public int getTextType() { return textType; }
        public void setTextType(int type) { textType = type; }
+       
+    /**
+     * @return  0-based index of the text run in the SLWT container
+     */
+       public int getIndex() { return index; }
+
+    /**
+     *  @param id 0-based index of the text run in the SLWT container
+     */
+       public void setIndex(int index) { this.index = index; }
 
        public RecordContainer getParentRecord() { return parentRecord; }
        public void setParentRecord(RecordContainer record) { this.parentRecord = record; }
index f1452bcf589773ec2866f1c86898578b9a388010..a3624678a04d01dac4ade2ca54a7addd4bdef88b 100644 (file)
@@ -30,6 +30,8 @@ import java.util.ArrayList;
  * @author Yegor Kozlov
  */
 public final class TextSpecInfoAtom extends RecordAtom {
+    private static final long _type = RecordTypes.TextSpecInfoAtom.typeID;
+    
     /**
      * Record header.
      */
@@ -62,7 +64,7 @@ public final class TextSpecInfoAtom extends RecordAtom {
      * Gets the record type.
      * @return the record type.
      */
-    public long getRecordType() { return RecordTypes.TextSpecInfoAtom.typeID; }
+    public long getRecordType() { return _type; }
 
     /**
      * Write the contents of the record back, so it can be written
index 966c8eb8e31fcc4c1c8284dfb39d7802df7b666a..4037d11e44edfc1c31c95561c25ef7e0e254fc0c 100644 (file)
@@ -48,6 +48,37 @@ public final class TxMasterStyleAtom extends RecordAtom {
      */
     public static final int MAX_INDENT = 5;
 
+/*
+    private static TextProp paragraphSpecialPropTypes[] = {
+        new ParagraphFlagsTextProp(),
+        new TextProp(2, 0x80, "bullet.char"),
+        new TextProp(2, 0x10, "bullet.font"),
+        new TextProp(2, 0x40, "bullet.size"),
+        new TextProp(4, 0x20, "bullet.color"),
+        new TextProp(2, 0xD00, "alignment"),
+        new TextProp(2, 0x1000, "linespacing"),
+        new TextProp(2, 0x2000, "spacebefore"),
+        new TextProp(2, 0x4000, "spaceafter"),
+        new TextProp(2, 0x8000, "text.offset"),
+        new TextProp(2, 0x10000, "bullet.offset"),
+        new TextProp(2, 0x20000, "defaulttab"),
+        new TextProp(2, 0x40000, "para_unknown_2"),
+        new TextProp(2, 0x80000, "para_unknown_3"),
+        new TextProp(2, 0x100000, "para_unknown_4"),
+        new TextProp(2, 0x200000, "para_unknown_5")
+    };
+
+    private static TextProp characterSpecialPropTypes[] = {
+        new CharFlagsTextProp(),
+        new TextProp(2, 0x10000, "font.index"),
+        new TextProp(2, 0x20000, "char_unknown_1"),
+        new TextProp(4, 0x40000, "char_unknown_2"),
+        new TextProp(2, 0x80000, "font.size"),
+        new TextProp(2, 0x100000, "char_unknown_3"),
+        new TextProp(4, 0x200000, "font.color"),
+        new TextProp(2, 0x800000, "char_unknown_4")
+    };
+*/    
     private byte[] _header;
     private static long _type = 4003;
     private byte[] _data;
@@ -126,6 +157,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
     /**
      * parse the record data and initialize styles
      */
+    @SuppressWarnings("unused")
     protected void init(){
         //type of the text
         int type = getTextType();
@@ -170,28 +202,10 @@ public final class TxMasterStyleAtom extends RecordAtom {
      *  ones, or the standard StyleTextPropAtom ones
      */
     protected TextProp[] getParagraphProps(int type, int level){
-        if (level != 0 || type >= MAX_INDENT){
-            return StyleTextPropAtom.paragraphTextPropTypes;
-        }
-        return new TextProp[] {
-                new ParagraphFlagsTextProp(),
-                new TextProp(2, 0x80, "bullet.char"),
-                new TextProp(2, 0x10, "bullet.font"),
-                new TextProp(2, 0x40, "bullet.size"),
-                new TextProp(4, 0x20, "bullet.color"),
-                new TextProp(2, 0xD00, "alignment"),
-                new TextProp(2, 0x1000, "linespacing"),
-                new TextProp(2, 0x2000, "spacebefore"),
-                new TextProp(2, 0x4000, "spaceafter"),
-                new TextProp(2, 0x8000, "text.offset"),
-                new TextProp(2, 0x10000, "bullet.offset"),
-                new TextProp(2, 0x20000, "defaulttab"),
-                new TextProp(2, 0x40000, "para_unknown_2"),
-                new TextProp(2, 0x80000, "para_unknown_3"),
-                new TextProp(2, 0x100000, "para_unknown_4"),
-                new TextProp(2, 0x200000, "para_unknown_5")
-        };
-
+        return StyleTextPropAtom.paragraphTextPropTypes;
+//        return (level != 0 || type >= MAX_INDENT)
+//            ? StyleTextPropAtom.paragraphTextPropTypes
+//            : paragraphSpecialPropTypes;
     }
 
     /**
@@ -201,18 +215,9 @@ public final class TxMasterStyleAtom extends RecordAtom {
      *  ones, or the standard StyleTextPropAtom ones
      */
     protected TextProp[] getCharacterProps(int type, int level){
-        if (level != 0 || type >= MAX_INDENT){
-            return StyleTextPropAtom.characterTextPropTypes;
-        }
-        return new TextProp[] {
-                new CharFlagsTextProp(),
-                new TextProp(2, 0x10000, "font.index"),
-                new TextProp(2, 0x20000, "char_unknown_1"),
-                new TextProp(4, 0x40000, "char_unknown_2"),
-                new TextProp(2, 0x80000, "font.size"),
-                new TextProp(2, 0x100000, "char_unknown_3"),
-                new TextProp(4, 0x200000, "font.color"),
-                new TextProp(2, 0x800000, "char_unknown_4")
-        };
+        return StyleTextPropAtom.characterTextPropTypes;
+//        return (level != 0 || type >= MAX_INDENT) 
+//            ? StyleTextPropAtom.characterTextPropTypes
+//            : characterSpecialPropTypes;
     }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
new file mode 100644 (file)
index 0000000..ceb6552
--- /dev/null
@@ -0,0 +1,108 @@
+/* ====================================================================
+   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.usermodel;
+
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.ss.usermodel.ShapeTypes;
+
+/**
+ * Represents an AutoShape.
+ * <p>
+ * AutoShapes are drawing objects with a particular shape that may be customized through smart resizing and adjustments.
+ * See {@link ShapeTypes}
+ * </p>
+ *
+ *  @author Yegor Kozlov
+ */
+public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFTextParagraph> {
+
+    protected HSLFAutoShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+    }
+
+    public HSLFAutoShape(ShapeType type, ShapeContainer<HSLFShape> parent){
+        super(null, parent);
+        _escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape);
+    }
+
+    public HSLFAutoShape(ShapeType type){
+        this(type, null);
+    }
+
+    protected EscherContainerRecord createSpContainer(ShapeType shapeType, boolean isChild){
+        _escherContainer = super.createSpContainer(isChild);
+
+        setShapeType(shapeType);
+
+        //set default properties for an autoshape
+        setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);
+        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
+        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
+        setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
+        setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010);
+        setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001);
+        setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008);
+        setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
+
+        return _escherContainer;
+    }
+
+    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
+        setVerticalAlignment(VerticalAlignment.MIDDLE);
+        setHorizontalCentered(true);
+        setWordWrap(HSLFTextBox.WrapNone);
+    }
+
+    /**
+     * Gets adjust value which controls smart resizing of the auto-shape.
+     *
+     * <p>
+     * The adjustment values are given in shape coordinates:
+     * the origin is at the top-left, positive-x is to the right, positive-y is down.
+     * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
+     * </p>
+     *
+     * @param idx the adjust index in the [0, 9] range
+     * @return the adjustment value
+     */
+    public int getAdjustmentValue(int idx){
+        if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range");
+
+        return getEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx));
+    }
+
+    /**
+     * Sets adjust value which controls smart resizing of the auto-shape.
+     *
+     * <p>
+     * The adjustment values are given in shape coordinates:
+     * the origin is at the top-left, positive-x is to the right, positive-y is down.
+     * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
+     * </p>
+     *
+     * @param idx the adjust index in the [0, 9] range
+     * @param val the adjustment value
+     */
+    public void setAdjustmentValue(int idx, int val){
+        if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range");
+
+        setEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx), val);
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java
new file mode 100644 (file)
index 0000000..4b9846f
--- /dev/null
@@ -0,0 +1,38 @@
+/* ====================================================================
+   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.usermodel;
+
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.sl.usermodel.Background;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+
+/**
+ * Background shape
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFBackground extends HSLFShape implements Background {
+
+    protected HSLFBackground(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
+        super(escherRecord, parent);
+    }
+
+    protected EscherContainerRecord createSpContainer(boolean isChild) {
+        return null;
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
new file mode 100644 (file)
index 0000000..9b74711
--- /dev/null
@@ -0,0 +1,310 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.Color;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.Document;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint.
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFFill {
+    // For logging
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
+    /**
+     *  Fill with a solid color
+     */
+    public static final int FILL_SOLID = 0;
+
+    /**
+     *  Fill with a pattern (bitmap)
+     */
+    public static final int FILL_PATTERN = 1;
+
+    /**
+     *  A texture (pattern with its own color map)
+     */
+    public static final int FILL_TEXTURE = 2;
+
+    /**
+     *  Center a picture in the shape
+     */
+    public static final int FILL_PICTURE = 3;
+
+    /**
+     *  Shade from start to end points
+     */
+    public static final int FILL_SHADE = 4;
+
+    /**
+     *  Shade from bounding rectangle to end point
+     */
+    public static final int FILL_SHADE_CENTER = 5;
+
+    /**
+     *  Shade from shape outline to end point
+     */
+    public static final int FILL_SHADE_SHAPE = 6;
+
+    /**
+     *  Similar to FILL_SHADE, but the fill angle
+     *  is additionally scaled by the aspect ratio of
+     *  the shape. If shape is square, it is the same as FILL_SHADE
+     */
+    public static final int FILL_SHADE_SCALE = 7;
+
+    /**
+     *  shade to title
+     */
+    public static final int FILL_SHADE_TITLE = 8;
+
+    /**
+     *  Use the background fill color/pattern
+     */
+    public static final int FILL_BACKGROUND = 9;
+
+
+
+    /**
+     * The shape this background applies to
+     */
+    protected HSLFShape shape;
+
+    /**
+     * Construct a <code>Fill</code> object for a shape.
+     * Fill information will be read from shape's escher properties.
+     *
+     * @param shape the shape this background applies to
+     */
+    public HSLFFill(HSLFShape shape){
+        this.shape = shape;
+    }
+
+
+    public FillStyle getFillStyle() {
+        return new FillStyle() {
+            public PaintStyle getPaint() {
+                switch (getFillType()) {
+                    case FILL_SOLID: {
+                        return new SolidPaint() {
+                            public ColorStyle getSolidColor() {
+                                return new ColorStyle() {
+                                    public Color getColor() { return getForegroundColor(); }
+                                    public int getAlpha() { return -1; }
+                                    public int getLumOff() { return -1; }
+                                    public int getLumMod() { return -1; }
+                                    public int getShade()  { return -1; }
+                                    public int getTint()  { return -1; }
+                                };
+                            }
+                        };
+                    }
+                    case FILL_PICTURE: {
+                        return new TexturePaint() {
+                            final HSLFPictureData pd = getPictureData();
+                            
+                            public InputStream getImageData() {
+                                return new ByteArrayInputStream(pd.getData());
+                            }
+
+                            public String getContentType() {
+                                return pd.getContentType();
+                            }
+
+                            public int getAlpha() {
+                                return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0);
+                            }
+                        };
+                    }
+                    default:
+                        logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
+                        break;
+                }
+                return PaintStyle.TRANSPARENT_PAINT;
+            }
+        };
+    }
+    
+    /**
+     * Returns fill type.
+     * Must be one of the <code>FILL_*</code> constants defined in this class.
+     *
+     * @return type of fill
+     */
+    public int getFillType(){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        EscherSimpleProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE);
+        return prop == null ? FILL_SOLID : prop.getPropertyValue();
+    }
+
+    /**
+     */
+    protected void afterInsert(HSLFSheet sh){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+        if(p != null) {
+            int idx = p.getPropertyValue();
+            EscherBSERecord bse = getEscherBSERecord(idx);
+            bse.setRef(bse.getRef() + 1);
+        }
+    }
+
+    protected EscherBSERecord getEscherBSERecord(int idx){
+        HSLFSheet sheet = shape.getSheet();
+        if(sheet == null) {
+            logger.log(POILogger.DEBUG, "Fill has not yet been assigned to a sheet");
+            return null;
+        }
+        HSLFSlideShow ppt = sheet.getSlideShow();
+        Document doc = ppt.getDocumentRecord();
+        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
+        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+        if(bstore == null) {
+            logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
+            return null;
+        }
+        List<EscherRecord> lst = bstore.getChildRecords();
+        return (EscherBSERecord)lst.get(idx-1);
+    }
+
+    /**
+     * Sets fill type.
+     * Must be one of the <code>FILL_*</code> constants defined in this class.
+     *
+     * @param type type of the fill
+     */
+    public void setFillType(int type){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type);
+    }
+
+    /**
+     * Foreground color
+     */
+    public Color getForegroundColor(){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+
+        if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
+
+        return shape.getColor(EscherProperties.FILL__FILLCOLOR, EscherProperties.FILL__FILLOPACITY, -1);
+
+    }
+
+    /**
+     * Foreground color
+     */
+    public void setForegroundColor(Color color){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        if (color == null) {
+            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
+        }
+        else {
+            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
+            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
+            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
+        }
+    }
+
+    /**
+     * Background color
+     */
+    public Color getBackgroundColor(){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+
+        if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
+
+        return shape.getColor(EscherProperties.FILL__FILLBACKCOLOR, EscherProperties.FILL__FILLOPACITY, -1);
+    }
+
+    /**
+     * Background color
+     */
+    public void setBackgroundColor(Color color){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        if (color == null) {
+            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1);
+        }
+        else {
+            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
+            HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb);
+        }
+    }
+
+    /**
+     * <code>PictureData</code> object used in a texture, pattern of picture fill.
+     */
+    public HSLFPictureData getPictureData(){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+        if (p == null) return null;
+
+        HSLFSlideShow ppt = shape.getSheet().getSlideShow();
+        HSLFPictureData[] pict = ppt.getPictureData();
+        Document doc = ppt.getDocumentRecord();
+
+        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
+        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+
+        java.util.List<EscherRecord> lst = bstore.getChildRecords();
+        int idx = p.getPropertyValue();
+        if (idx == 0){
+            logger.log(POILogger.WARN, "no reference to picture data found ");
+        } else {
+            EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1);
+            for ( int i = 0; i < pict.length; i++ ) {
+                if (pict[i].getOffset() ==  bse.getOffset()){
+                    return pict[i];
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Assign picture used to fill the underlying shape.
+     *
+     * @param idx 0-based index of the picture added to this ppt by <code>SlideShow.addPicture</code> method.
+     */
+    public void setPictureData(int idx){
+        EscherOptRecord opt = shape.getEscherOptRecord();
+        HSLFShape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx);
+        if( idx != 0 ) {
+            if( shape.getSheet() != null ) {
+                EscherBSERecord bse = getEscherBSERecord(idx);
+                bse.setRef(bse.getRef() + 1);
+            }
+        }
+    }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
new file mode 100644 (file)
index 0000000..5128b55
--- /dev/null
@@ -0,0 +1,264 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.ddf.EscherArrayProperty;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+
+/**
+ * A "Freeform" shape.
+ *
+ * <p>
+ * Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections
+ * and straight-line segments in the straight sections. This object closely corresponds to <code>java.awt.geom.GeneralPath</code>.
+ * </p>
+ * @author Yegor Kozlov
+ */
+public final class HSLFFreeformShape extends HSLFAutoShape {
+
+    public static final byte[] SEGMENTINFO_MOVETO   = new byte[]{0x00, 0x40};
+    public static final byte[] SEGMENTINFO_LINETO   = new byte[]{0x00, (byte)0xAC};
+    public static final byte[] SEGMENTINFO_ESCAPE   = new byte[]{0x01, 0x00};
+    public static final byte[] SEGMENTINFO_ESCAPE2  = new byte[]{0x01, 0x20};
+    public static final byte[] SEGMENTINFO_CUBICTO  = new byte[]{0x00, (byte)0xAD};
+    public static final byte[] SEGMENTINFO_CUBICTO2 = new byte[]{0x00, (byte)0xB3}; //OpenOffice inserts 0xB3 instead of 0xAD.
+    public static final byte[] SEGMENTINFO_CLOSE    = new byte[]{0x01, (byte)0x60};
+    public static final byte[] SEGMENTINFO_END      = new byte[]{0x00, (byte)0x80};
+
+    /**
+     * Create a Freeform object and initialize it from the supplied Record container.
+     *
+     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent    the parent of the shape
+     */
+   protected HSLFFreeformShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+
+    }
+
+    /**
+     * Create a new Freeform. This constructor is used when a new shape is created.
+     *
+     * @param parent    the parent of this Shape. For example, if this text box is a cell
+     * in a table then the parent is Table.
+     */
+    public HSLFFreeformShape(ShapeContainer<HSLFShape> parent){
+        super((EscherContainerRecord)null, parent);
+        _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
+    }
+
+    /**
+     * Create a new Freeform. This constructor is used when a new shape is created.
+     *
+     */
+    public HSLFFreeformShape(){
+        this(null);
+    }
+
+    /**
+     * Set the shape path
+     *
+     * @param path
+     */
+    public void setPath(GeneralPath path)
+    {
+        Rectangle2D bounds = path.getBounds2D();
+        PathIterator it = path.getPathIterator(new AffineTransform());
+
+        List<byte[]> segInfo = new ArrayList<byte[]>();
+        List<Point2D.Double> pntInfo = new ArrayList<Point2D.Double>();
+        boolean isClosed = false;
+        while (!it.isDone()) {
+            double[] vals = new double[6];
+            int type = it.currentSegment(vals);
+            switch (type) {
+                case PathIterator.SEG_MOVETO:
+                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
+                    segInfo.add(SEGMENTINFO_MOVETO);
+                    break;
+                case PathIterator.SEG_LINETO:
+                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
+                    segInfo.add(SEGMENTINFO_LINETO);
+                    segInfo.add(SEGMENTINFO_ESCAPE);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    pntInfo.add(new Point2D.Double(vals[0], vals[1]));
+                    pntInfo.add(new Point2D.Double(vals[2], vals[3]));
+                    pntInfo.add(new Point2D.Double(vals[4], vals[5]));
+                    segInfo.add(SEGMENTINFO_CUBICTO);
+                    segInfo.add(SEGMENTINFO_ESCAPE2);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    //TODO: figure out how to convert SEG_QUADTO into SEG_CUBICTO
+                    logger.log(POILogger.WARN, "SEG_QUADTO is not supported");
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    pntInfo.add(pntInfo.get(0));
+                    segInfo.add(SEGMENTINFO_LINETO);
+                    segInfo.add(SEGMENTINFO_ESCAPE);
+                    segInfo.add(SEGMENTINFO_LINETO);
+                    segInfo.add(SEGMENTINFO_CLOSE);
+                    isClosed = true;
+                    break;
+            }
+
+            it.next();
+        }
+        if(!isClosed) segInfo.add(SEGMENTINFO_LINETO);
+        segInfo.add(new byte[]{0x00, (byte)0x80});
+
+        EscherOptRecord opt = getEscherOptRecord();
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
+
+        EscherArrayProperty verticesProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__VERTICES + 0x4000), false, null);
+        verticesProp.setNumberOfElementsInArray(pntInfo.size());
+        verticesProp.setNumberOfElementsInMemory(pntInfo.size());
+        verticesProp.setSizeOfElements(0xFFF0);
+        for (int i = 0; i < pntInfo.size(); i++) {
+            Point2D.Double pnt = pntInfo.get(i);
+            byte[] data = new byte[4];
+            LittleEndian.putShort(data, 0, (short)((pnt.getX() - bounds.getX())*MASTER_DPI/POINT_DPI));
+            LittleEndian.putShort(data, 2, (short)((pnt.getY() - bounds.getY())*MASTER_DPI/POINT_DPI));
+            verticesProp.setElement(i, data);
+        }
+        opt.addEscherProperty(verticesProp);
+
+        EscherArrayProperty segmentsProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000), false, null);
+        segmentsProp.setNumberOfElementsInArray(segInfo.size());
+        segmentsProp.setNumberOfElementsInMemory(segInfo.size());
+        segmentsProp.setSizeOfElements(0x2);
+        for (int i = 0; i < segInfo.size(); i++) {
+            byte[] seg = segInfo.get(i);
+            segmentsProp.setElement(i, seg);
+        }
+        opt.addEscherProperty(segmentsProp);
+
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, (int)(bounds.getWidth()*MASTER_DPI/POINT_DPI)));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, (int)(bounds.getHeight()*MASTER_DPI/POINT_DPI)));
+
+        opt.sortProperties();
+
+        setAnchor(bounds);
+    }
+
+    /**
+     * Gets the freeform path
+     *
+     * @return the freeform path
+     */
+     public GeneralPath getPath(){
+        EscherOptRecord opt = getEscherOptRecord();
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
+
+        EscherArrayProperty verticesProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__VERTICES + 0x4000));
+        if(verticesProp == null) verticesProp = getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
+
+        EscherArrayProperty segmentsProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000));
+        if(segmentsProp == null) segmentsProp = getEscherProperty(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
+
+        //sanity check
+        if(verticesProp == null) {
+            logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__VERTICES ");
+            return null;
+        }
+        if(segmentsProp == null) {
+            logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__SEGMENTINFO ");
+            return null;
+        }
+
+        GeneralPath path = new GeneralPath();
+        int numPoints = verticesProp.getNumberOfElementsInArray();
+        int numSegments = segmentsProp.getNumberOfElementsInArray();
+        for (int i = 0, j = 0; i < numSegments && j < numPoints; i++) {
+            byte[] elem = segmentsProp.getElement(i);
+            if(Arrays.equals(elem, SEGMENTINFO_MOVETO)){
+                byte[] p = verticesProp.getElement(j++);
+                short x = LittleEndian.getShort(p, 0);
+                short y = LittleEndian.getShort(p, 2);
+                path.moveTo(
+                        ((float)x*POINT_DPI/MASTER_DPI),
+                        ((float)y*POINT_DPI/MASTER_DPI));
+            } else if (Arrays.equals(elem, SEGMENTINFO_CUBICTO) || Arrays.equals(elem, SEGMENTINFO_CUBICTO2)){
+                i++;
+                byte[] p1 = verticesProp.getElement(j++);
+                short x1 = LittleEndian.getShort(p1, 0);
+                short y1 = LittleEndian.getShort(p1, 2);
+                byte[] p2 = verticesProp.getElement(j++);
+                short x2 = LittleEndian.getShort(p2, 0);
+                short y2 = LittleEndian.getShort(p2, 2);
+                byte[] p3 = verticesProp.getElement(j++);
+                short x3 = LittleEndian.getShort(p3, 0);
+                short y3 = LittleEndian.getShort(p3, 2);
+                path.curveTo(
+                        ((float)x1*POINT_DPI/MASTER_DPI), ((float)y1*POINT_DPI/MASTER_DPI),
+                        ((float)x2*POINT_DPI/MASTER_DPI), ((float)y2*POINT_DPI/MASTER_DPI),
+                        ((float)x3*POINT_DPI/MASTER_DPI), ((float)y3*POINT_DPI/MASTER_DPI));
+
+            } else if (Arrays.equals(elem, SEGMENTINFO_LINETO)){
+                i++;
+                byte[] pnext = segmentsProp.getElement(i);
+                if(Arrays.equals(pnext, SEGMENTINFO_ESCAPE)){
+                    if(j + 1 < numPoints){
+                        byte[] p = verticesProp.getElement(j++);
+                        short x = LittleEndian.getShort(p, 0);
+                        short y = LittleEndian.getShort(p, 2);
+                        path.lineTo(
+                                ((float)x*POINT_DPI/MASTER_DPI), ((float)y*POINT_DPI/MASTER_DPI));
+                    }
+                } else if (Arrays.equals(pnext, SEGMENTINFO_CLOSE)){
+                    path.closePath();
+                }
+            }
+        }
+        return path;
+    }
+
+    public java.awt.Shape getOutline(){
+        GeneralPath path =  getPath();
+        if(path == null) {
+            // return empty path if either GEOMETRY__VERTICES or GEOMETRY__SEGMENTINFO is missing, see Bugzilla 54188
+            return new GeneralPath();
+        }
+
+        Rectangle2D anchor = getAnchor2D();
+        Rectangle2D bounds = path.getBounds2D();
+        AffineTransform at = new AffineTransform();
+        at.translate(anchor.getX(), anchor.getY());
+        at.scale(
+                anchor.getWidth()/bounds.getWidth(),
+                anchor.getHeight()/bounds.getHeight()
+        );
+        return at.createTransformedShape(path);
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
new file mode 100644 (file)
index 0000000..5e47776
--- /dev/null
@@ -0,0 +1,289 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.geom.Rectangle2D;
+import java.util.*;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+
+/**
+ *  Represents a group of shapes.
+ *
+ * @author Yegor Kozlov
+ */
+public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShape> {
+
+    /**
+      * Create a new ShapeGroup. This constructor is used when a new shape is created.
+      *
+      */
+    public HSLFGroupShape(){
+        this(null, null);
+        _escherContainer = createSpContainer(false);
+    }
+
+    /**
+      * Create a ShapeGroup object and initilize it from the supplied Record container.
+      *
+      * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+      * @param parent    the parent of the shape
+      */
+    protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+    }
+
+    @Override
+    public List<HSLFShape> getShapes() {
+        return getShapeList();
+    }
+
+    /**
+     * Sets the anchor (the bounding box rectangle) of this shape.
+     * All coordinates should be expressed in Master units (576 dpi).
+     *
+     * @param anchor new anchor
+     */
+    public void setAnchor(java.awt.Rectangle anchor){
+
+        EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+        //hack. internal variable EscherClientAnchorRecord.shortRecord can be
+        //initialized only in fillFields(). We need to set shortRecord=false;
+        byte[] header = new byte[16];
+        LittleEndian.putUShort(header, 0, 0);
+        LittleEndian.putUShort(header, 2, 0);
+        LittleEndian.putInt(header, 4, 8);
+        clientAnchor.fillFields(header, 0, null);
+
+        clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
+        clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
+        clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
+        clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
+
+        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+        spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI);
+        spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI);
+        spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI);
+        spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
+    }
+
+    /**
+     * Sets the coordinate space of this group.  All children are constrained
+     * to these coordinates.
+     *
+     * @param anchor the coordinate space of this group
+     */
+    public void setCoordinates(Rectangle2D anchor){
+        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+        int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
+        int y1 = (int)Math.round(anchor.getY()*MASTER_DPI/POINT_DPI);
+        int x2 = (int)Math.round((anchor.getX() + anchor.getWidth())*MASTER_DPI/POINT_DPI);
+        int y2 = (int)Math.round((anchor.getY() + anchor.getHeight())*MASTER_DPI/POINT_DPI);
+
+        spgr.setRectX1(x1);
+        spgr.setRectY1(y1);
+        spgr.setRectX2(x2);
+        spgr.setRectY2(y2);
+
+    }
+
+    /**
+     * Gets the coordinate space of this group.  All children are constrained
+     * to these coordinates.
+     *
+     * @return the coordinate space of this group
+     */
+    public Rectangle2D getCoordinates(){
+        EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+        Rectangle2D.Float anchor = new Rectangle2D.Float();
+        anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
+        anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
+        anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
+        anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;
+
+        return anchor;
+    }
+
+    /**
+     * Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
+     */
+    protected EscherContainerRecord createSpContainer(boolean isChild) {
+        EscherContainerRecord spgr = new EscherContainerRecord();
+        spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
+        spgr.setOptions((short)15);
+
+        //The group itself is a shape, and always appears as the first EscherSpContainer in the group container.
+        EscherContainerRecord spcont = new EscherContainerRecord();
+        spcont.setRecordId(EscherContainerRecord.SP_CONTAINER);
+        spcont.setOptions((short)15);
+
+        EscherSpgrRecord spg = new EscherSpgrRecord();
+        spg.setOptions((short)1);
+        spcont.addChildRecord(spg);
+
+        EscherSpRecord sp = new EscherSpRecord();
+        short type = (short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2);
+        sp.setOptions(type);
+        sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP);
+        spcont.addChildRecord(sp);
+
+        EscherClientAnchorRecord anchor = new EscherClientAnchorRecord();
+        spcont.addChildRecord(anchor);
+
+        spgr.addChildRecord(spcont);
+        return spgr;
+    }
+
+    /**
+     * Add a shape to this group.
+     *
+     * @param shape - the Shape to add
+     */
+    public void addShape(HSLFShape shape){
+        _escherContainer.addChildRecord(shape.getSpContainer());
+
+        HSLFSheet sheet = getSheet();
+        shape.setSheet(sheet);
+        shape.setShapeId(sheet.allocateShapeId());
+        shape.afterInsert(sheet);
+    }
+
+    /**
+     * Moves this <code>ShapeGroup</code> to the specified location.
+     * <p>
+     * @param x the x coordinate of the top left corner of the shape in new location
+     * @param y the y coordinate of the top left corner of the shape in new location
+     */
+    public void moveTo(int x, int y){
+        java.awt.Rectangle anchor = getAnchor();
+        int dx = x - anchor.x;
+        int dy = y - anchor.y;
+        anchor.translate(dx, dy);
+        setAnchor(anchor);
+
+        
+        for (HSLFShape shape : getShapes()) {
+            java.awt.Rectangle chanchor = shape.getAnchor();
+            chanchor.translate(dx, dy);
+            shape.setAnchor(chanchor);
+        }
+    }
+
+    /**
+     * Returns the anchor (the bounding box rectangle) of this shape group.
+     * All coordinates are expressed in points (72 dpi).
+     *
+     * @return the anchor of this shape group
+     */
+    public Rectangle2D getAnchor2D(){
+        EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+        Rectangle2D.Float anchor = new Rectangle2D.Float();
+        if(clientAnchor == null){
+            logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
+            EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+            anchor = new Rectangle2D.Float(
+                (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
+                (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
+                (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
+                (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
+            );
+        } else {
+            anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
+            anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
+            anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
+            anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
+        }
+
+        return anchor;
+    }
+
+    /**
+     * Return type of the shape.
+     * In most cases shape group type is {@link org.apache.poi.hslf.model.ShapeTypes#NotPrimitive}
+     *
+     * @return type of the shape.
+     */
+    public ShapeType getShapeType(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        int nativeId = spRecord.getOptions() >> 4;
+        return ShapeType.forId(nativeId, false);
+    }
+
+    /**
+     * Returns <code>null</code> - shape groups can't have hyperlinks
+     *
+     * @return <code>null</code>.
+     */
+     public HSLFHyperlink getHyperlink(){
+        return null;
+    }
+
+    @Override
+    public <T extends EscherRecord> T getEscherChild(int recordId){
+        EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
+        return groupInfoContainer.getChildById((short)recordId);
+    }
+
+    public Iterator<HSLFShape> iterator() {
+        return getShapeList().iterator();
+    }
+
+    public boolean removeShape(HSLFShape shape) {
+        // TODO: implement!
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @return the shapes contained in this group container
+     */
+    protected List<HSLFShape> getShapeList() {
+        // Out escher container record should contain several
+        //  SpContainers, the first of which is the group shape itself
+        Iterator<EscherRecord> iter = _escherContainer.getChildIterator();
+
+        // Don't include the first SpContainer, it is always NotPrimitive
+        if (iter.hasNext()) {
+            iter.next();
+        }
+        List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
+        while (iter.hasNext()) {
+            EscherRecord r = iter.next();
+            if(r instanceof EscherContainerRecord) {
+                // Create the Shape for it
+                EscherContainerRecord container = (EscherContainerRecord)r;
+                HSLFShape shape = HSLFShapeFactory.createShape(container, this);
+                shape.setSheet(getSheet());
+                shapeList.add( shape );
+            } else {
+                // Should we do anything special with these non
+                //  Container records?
+                logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName());
+            }
+        }
+
+        return shapeList;
+    }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
new file mode 100644 (file)
index 0000000..baead9e
--- /dev/null
@@ -0,0 +1,248 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.*;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.*;
+
+/**
+ * Represents a hyperlink in a PowerPoint document
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFHyperlink {
+    public static final byte LINK_NEXTSLIDE = InteractiveInfoAtom.LINK_NextSlide;
+    public static final byte LINK_PREVIOUSSLIDE = InteractiveInfoAtom.LINK_PreviousSlide;
+    public static final byte LINK_FIRSTSLIDE = InteractiveInfoAtom.LINK_FirstSlide;
+    public static final byte LINK_LASTSLIDE = InteractiveInfoAtom.LINK_LastSlide;
+    public static final byte LINK_SLIDENUMBER = InteractiveInfoAtom.LINK_SlideNumber;
+    public static final byte LINK_URL = InteractiveInfoAtom.LINK_Url;
+    public static final byte LINK_NULL = InteractiveInfoAtom.LINK_NULL;
+
+    private int id=-1;
+    private int type;
+    private String address;
+    private String title;
+    private int startIndex, endIndex;
+
+    /**
+     * Gets the type of the hyperlink action.
+     * Must be a <code>LINK_*</code>  constant</code>
+     *
+     * @return the hyperlink URL
+     * @see InteractiveInfoAtom
+     */
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int val) {
+        type = val;
+        switch(type){
+            case LINK_NEXTSLIDE:
+                title = "NEXT";
+                address = "1,-1,NEXT";
+                break;
+            case LINK_PREVIOUSSLIDE:
+                title = "PREV";
+                address = "1,-1,PREV";
+                break;
+            case LINK_FIRSTSLIDE:
+                title = "FIRST";
+                address = "1,-1,FIRST";
+                break;
+            case LINK_LASTSLIDE:
+                title = "LAST";
+                address = "1,-1,LAST";
+                break;
+            case LINK_SLIDENUMBER:
+                break;
+            default:
+                title = "";
+                address = "";
+                break;
+        }
+    }
+
+    /**
+     * Gets the hyperlink URL
+     *
+     * @return the hyperlink URL
+     */
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(HSLFSlide slide) {
+        String href = slide._getSheetNumber() + ","+slide.getSlideNumber()+",Slide " + slide.getSlideNumber();
+        setAddress(href);;
+        setTitle("Slide " + slide.getSlideNumber());
+        setType(HSLFHyperlink.LINK_SLIDENUMBER);
+    }
+
+    public void setAddress(String str) {
+        address = str;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets the hyperlink user-friendly title (if different from URL)
+     *
+     * @return the  hyperlink user-friendly title
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String str) {
+        title = str;
+    }
+
+    /**
+     * Gets the beginning character position
+     *
+     * @return the beginning character position
+     */
+    public int getStartIndex() {
+        return startIndex;
+    }
+
+    /**
+     * Gets the ending character position
+     *
+     * @return the ending character position
+     */
+    public int getEndIndex() {
+        return endIndex;
+    }
+
+    /**
+     * Find hyperlinks in a text shape
+     *
+     * @param shape  <code>TextRun</code> to lookup hyperlinks in
+     * @return found hyperlinks or <code>null</code> if not found
+     */
+    public static HSLFHyperlink[] find(HSLFTextShape shape){
+        List<HSLFHyperlink> lst = new ArrayList<HSLFHyperlink>();
+        HSLFSlideShow ppt = shape.getSheet().getSlideShow();
+        //document-level container which stores info about all links in a presentation
+        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
+        if (exobj == null) {
+            return null;
+        }
+        
+        Record[] records = shape.getClientRecords();
+        find(records, exobj, lst);
+
+        HSLFHyperlink[] links = null;
+        if (lst.size() > 0){
+            links = new HSLFHyperlink[lst.size()];
+            lst.toArray(links);
+        }
+        return links;
+    }
+
+    /**
+     * Find hyperlinks in a text paragraph
+     *
+     * @param paragraph  <code>TextParagraph</code> to lookup hyperlinks in
+     * @return found hyperlinks or <code>null</code> if not found
+     */
+    public static HSLFHyperlink[] find(HSLFTextParagraph paragraph){
+        List<HSLFHyperlink> lst = new ArrayList<HSLFHyperlink>();
+        HSLFSlideShow ppt = paragraph.getSheet().getSlideShow();
+        //document-level container which stores info about all links in a presentation
+        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
+        if (exobj == null) {
+            return null;
+        }
+        
+        Record[] records = paragraph.getRecords();
+        find(records, exobj, lst);
+
+        HSLFHyperlink[] links = null;
+        if (lst.size() > 0){
+            links = new HSLFHyperlink[lst.size()];
+            lst.toArray(links);
+        }
+        return links;
+    }
+
+    /**
+     * Find hyperlink assigned to the supplied shape
+     *
+     * @param shape  <code>Shape</code> to lookup hyperlink in
+     * @return found hyperlink or <code>null</code>
+     */
+    public static HSLFHyperlink find(HSLFShape shape){
+        List<HSLFHyperlink> lst = new ArrayList<HSLFHyperlink>();
+        HSLFSlideShow ppt = shape.getSheet().getSlideShow();
+        //document-level container which stores info about all links in a presentation
+        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
+        if (exobj == null) {
+            return null;
+        }
+
+        EscherContainerRecord spContainer = shape.getSpContainer();
+        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext(); ) {
+            EscherRecord obj = it.next();
+            if (obj.getRecordId() ==  EscherClientDataRecord.RECORD_ID){
+                byte[] data = obj.serialize();
+                Record[] records = Record.findChildRecords(data, 8, data.length-8);
+                find(records, exobj, lst);
+            }
+        }
+
+        return lst.size() == 1 ? (HSLFHyperlink)lst.get(0) : null;
+    }
+
+    private static void find(Record[] records, ExObjList exobj, List<HSLFHyperlink> out){
+        if (records == null) return;
+        for (int i = 0; i < records.length; i++) {
+            //see if we have InteractiveInfo in the textrun's records
+            if( records[i] instanceof InteractiveInfo){
+                InteractiveInfo hldr = (InteractiveInfo)records[i];
+                InteractiveInfoAtom info = hldr.getInteractiveInfoAtom();
+                int id = info.getHyperlinkID();
+                ExHyperlink linkRecord = exobj.get(id);
+                if (linkRecord != null){
+                    HSLFHyperlink link = new HSLFHyperlink();
+                    link.title = linkRecord.getLinkTitle();
+                    link.address = linkRecord.getLinkURL();
+                    link.type = info.getAction();
+
+                    if (++i < records.length && records[i] instanceof TxInteractiveInfoAtom){
+                        TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom)records[i];
+                        link.startIndex = txinfo.getStartIndex();
+                        link.endIndex = txinfo.getEndIndex();
+                    }
+                    out.add(link);
+                }
+            }
+        }
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java
new file mode 100644 (file)
index 0000000..974a858
--- /dev/null
@@ -0,0 +1,56 @@
+/* ====================================================================
+   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.usermodel;
+
+import org.apache.poi.hslf.record.SheetContainer;
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.sl.usermodel.MasterSheet;
+
+/**
+ * The superclass of all master sheets - Slide masters, Notes masters, etc.
+ *
+ * For now it's empty. When we understand more about masters in ppt we will add the common functionality here.
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class HSLFMasterSheet extends HSLFSheet implements MasterSheet<HSLFShape,HSLFSlideShow> {
+    public HSLFMasterSheet(SheetContainer container, int sheetNo){
+        super(container, sheetNo);
+    }
+
+    /**
+     * Pickup a style attribute from the master.
+     * This is the "workhorse" which returns the default style attrubutes.
+     */
+    public abstract TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) ;
+
+
+    /**
+     * Checks if the shape is a placeholder.
+     * (placeholders aren't normal shapes, they are visible only in the Edit Master mode)
+     *
+     *
+     * @return true if the shape is a placeholder
+     */
+    public static boolean isPlaceholder(HSLFShape shape){
+        if(!(shape instanceof HSLFTextShape)) return false;
+
+        HSLFTextShape tx = (HSLFTextShape)shape;
+        return tx.getPlaceholderAtom() != null;
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java
new file mode 100644 (file)
index 0000000..50eb3a6
--- /dev/null
@@ -0,0 +1,79 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.sl.usermodel.Notes;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * This class represents a slide's notes in a PowerPoint Document. It
+ *  allows access to the text within, and the layout. For now, it only
+ *  does the text side of things though
+ *
+ * @author Nick Burch
+ */
+
+public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFSlideShow> {
+    protected static POILogger logger = POILogFactory.getLogger(HSLFNotes.class);
+    
+    private List<List<HSLFTextParagraph>> _runs;
+
+    /**
+     * Constructs a Notes Sheet from the given Notes record.
+     * Initialises TextRuns, to provide easier access to the text
+     * 
+     * @param notes the Notes record to read from
+     */
+    public HSLFNotes(org.apache.poi.hslf.record.Notes notes) {
+        super(notes, notes.getNotesAtom().getSlideID());
+
+        // Now, build up TextRuns from pairs of TextHeaderAtom and
+        // one of TextBytesAtom or TextCharsAtom, found inside
+        // EscherTextboxWrapper's in the PPDrawing
+        _runs = HSLFTextParagraph.findTextParagraphs(getPPDrawing());
+        if (_runs.isEmpty()) {
+            logger.log(POILogger.WARN, "No text records found for notes sheet");
+        }
+
+        // Set the sheet on each TextRun
+        for (List<HSLFTextParagraph> ltp : _runs) {
+            for (HSLFTextParagraph tp : ltp) {
+                tp.supplySheet(this);
+            }
+        }
+    }
+
+    /**
+     * Returns an array of all the TextParagraphs found
+     */
+    @Override
+    public List<List<HSLFTextParagraph>> getTextParagraphs() {
+        return _runs;
+    }
+
+    /**
+     * Return <code>null</code> - Notes Masters are not yet supported
+     */
+    public HSLFMasterSheet getMasterSheet() {
+        return null;
+    }
+}
index 9d9b0dc5942f72829e8fef7ba91e6e0a0e0a1ec7..b848a2cb9bdabab2bff0a8e8bac71b433f6b6e11 100644 (file)
@@ -30,7 +30,6 @@ import org.apache.poi.hslf.blip.JPEG;
 import org.apache.poi.hslf.blip.PICT;
 import org.apache.poi.hslf.blip.PNG;
 import org.apache.poi.hslf.blip.WMF;
-import org.apache.poi.hslf.model.HSLFPictureShape;
 import org.apache.poi.poifs.crypt.CryptoFunctions;
 import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.util.LittleEndian;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
new file mode 100644 (file)
index 0000000..c97c281
--- /dev/null
@@ -0,0 +1,279 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.Insets;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.blip.Bitmap;
+import org.apache.poi.hslf.record.Document;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.*;
+
+
+/**
+ * Represents a picture in a PowerPoint document.
+ *
+ * @author Yegor Kozlov
+ */
+public class HSLFPictureShape extends HSLFSimpleShape {
+
+    /**
+    *  Windows Enhanced Metafile (EMF)
+    */
+    public static final int EMF = 2;
+
+    /**
+    *  Windows Metafile (WMF)
+    */
+    public static final int WMF = 3;
+
+    /**
+    * Macintosh PICT
+    */
+    public static final int PICT = 4;
+
+    /**
+    *  JPEG
+    */
+    public static final int JPEG = 5;
+
+    /**
+    *  PNG
+    */
+    public static final int PNG = 6;
+
+    /**
+     * Windows DIB (BMP)
+     */
+    public static final byte DIB = 7;
+
+    /**
+     * Create a new <code>Picture</code>
+     *
+    * @param idx the index of the picture
+     */
+    public HSLFPictureShape(int idx){
+        this(idx, null);
+    }
+
+    /**
+     * Create a new <code>Picture</code>
+     *
+     * @param idx the index of the picture
+     * @param parent the parent shape
+     */
+    public HSLFPictureShape(int idx, ShapeContainer<HSLFShape> parent) {
+        super(null, parent);
+        _escherContainer = createSpContainer(idx, parent instanceof HSLFGroupShape);
+    }
+
+    /**
+      * Create a <code>Picture</code> object
+      *
+      * @param escherRecord the <code>EscherSpContainer</code> record which holds information about
+      *        this picture in the <code>Slide</code>
+      * @param parent the parent shape of this picture
+      */
+     protected HSLFPictureShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+    }
+
+    /**
+     * Returns index associated with this picture.
+     * Index starts with 1 and points to a EscherBSE record which
+     * holds information about this picture.
+     *
+     * @return the index to this picture (1 based).
+     */
+    public int getPictureIndex(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY);
+        return prop == null ? 0 : prop.getPropertyValue();
+    }
+
+    /**
+     * Create a new Picture and populate the inital structure of the <code>EscherSp</code> record which holds information about this picture.
+
+     * @param idx the index of the picture which refers to <code>EscherBSE</code> container.
+     * @return the create Picture object
+     */
+    protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
+        _escherContainer = super.createSpContainer(isChild);
+        _escherContainer.setOptions((short)15);
+
+        EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setOptions((short)((ShapeType.FRAME.nativeId << 4) | 0x2));
+
+        //set default properties for a picture
+        EscherOptRecord opt = getEscherOptRecord();
+        setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x800080);
+
+        //another weird feature of powerpoint: for picture id we must add 0x4000.
+        setEscherProperty(opt, (short)(EscherProperties.BLIP__BLIPTODISPLAY + 0x4000), idx);
+
+        return _escherContainer;
+    }
+
+    /**
+     * Resize this picture to the default size.
+     * For PNG and JPEG resizes the image to 100%,
+     * for other types sets the default size of 200x200 pixels.
+     */
+    public void setDefaultSize(){
+        HSLFPictureData pict = getPictureData();
+        if (pict  instanceof Bitmap){
+            BufferedImage img = null;
+            try {
+                       img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
+            }
+            catch (IOException e){}
+            catch (NegativeArraySizeException ne) {}
+
+            if(img != null) {
+                // Valid image, set anchor from it
+                setAnchor(new java.awt.Rectangle(0, 0, img.getWidth()*POINT_DPI/PIXEL_DPI, img.getHeight()*POINT_DPI/PIXEL_DPI));
+            } else {
+                // Invalid image, go with the default metafile size
+                setAnchor(new java.awt.Rectangle(0, 0, 200, 200));
+            }
+        } else {
+            //default size of a metafile picture is 200x200
+            setAnchor(new java.awt.Rectangle(50, 50, 200, 200));
+        }
+    }
+
+    /**
+     * Returns the picture data for this picture.
+     *
+     * @return the picture data for this picture.
+     */
+    public HSLFPictureData getPictureData(){
+        HSLFSlideShow ppt = getSheet().getSlideShow();
+        HSLFPictureData[] pict = ppt.getPictureData();
+
+        EscherBSERecord bse = getEscherBSERecord();
+        if (bse == null){
+            logger.log(POILogger.ERROR, "no reference to picture data found ");
+        } else {
+            for ( int i = 0; i < pict.length; i++ ) {
+                if (pict[i].getOffset() ==  bse.getOffset()){
+                    return pict[i];
+                }
+            }
+            logger.log(POILogger.ERROR, "no picture found for our BSE offset " + bse.getOffset());
+        }
+        return null;
+    }
+
+    protected EscherBSERecord getEscherBSERecord(){
+        HSLFSlideShow ppt = getSheet().getSlideShow();
+        Document doc = ppt.getDocumentRecord();
+        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
+        EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+        if(bstore == null) {
+            logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
+            return null;
+        }
+        List<EscherRecord> lst = bstore.getChildRecords();
+        int idx = getPictureIndex();
+        if (idx == 0){
+            logger.log(POILogger.DEBUG, "picture index was not found, returning ");
+            return null;
+        }
+        return (EscherBSERecord)lst.get(idx-1);
+    }
+
+    /**
+     * Name of this picture.
+     *
+     * @return name of this picture
+     */
+    public String getPictureName(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherComplexProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPFILENAME);
+        if (prop == null) return null;
+        String name = StringUtil.getFromUnicodeLE(prop.getComplexData());
+        return name.trim();
+    }
+
+    /**
+     * Name of this picture.
+     *
+     * @param name of this picture
+     */
+    public void setPictureName(String name){
+        EscherOptRecord opt = getEscherOptRecord();
+        byte[] data = StringUtil.getToUnicodeLE(name + '\u0000');
+        EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.BLIP__BLIPFILENAME, false, data);
+        opt.addEscherProperty(prop);
+    }
+
+    /**
+     * By default set the orininal image size
+     */
+    protected void afterInsert(HSLFSheet sh){
+        super.afterInsert(sh);
+
+        EscherBSERecord bse = getEscherBSERecord();
+        bse.setRef(bse.getRef() + 1);
+
+        java.awt.Rectangle anchor = getAnchor();
+        if (anchor.equals(new java.awt.Rectangle())){
+            setDefaultSize();
+        }
+    }
+
+    /**
+     * Returns the clipping values as percent ratio relatively to the image size.
+     * The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size,
+     * i.e. the size of the already clipped image
+     * 
+     * @return the clipping as insets converted/scaled to 100000 (=100%) 
+     */
+    public Insets getBlipClip() {
+        EscherOptRecord opt = getEscherOptRecord();
+        
+        double top    = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP);
+        double bottom = getFractProp(opt, EscherProperties.BLIP__CROPFROMBOTTOM);
+        double left   = getFractProp(opt, EscherProperties.BLIP__CROPFROMLEFT);
+        double right  = getFractProp(opt, EscherProperties.BLIP__CROPFROMRIGHT);
+        
+        // if all crop values are zero (the default) then no crop rectangle is set, return null
+        return (top==0 && bottom==0 && left==0 && right==0)
+            ? null
+            : new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000));
+    }
+    
+    /**
+     * @return the fractional property or 0 if not defined
+     */
+    private static double getFractProp(EscherOptRecord opt, short propertyId) {
+        EscherSimpleProperty prop = getEscherProperty(opt, propertyId);
+        if (prop == null) return 0;
+        int fixedPoint = prop.getPropertyValue();
+        return Units.fixedPointToDouble(fixedPoint);
+    }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
new file mode 100644 (file)
index 0000000..adb61e6
--- /dev/null
@@ -0,0 +1,526 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.util.*;
+
+/**
+ *  <p>
+  * Represents a Shape which is the elemental object that composes a drawing.
+ *  This class is a wrapper around EscherSpContainer which holds all information
+ *  about a shape in PowerPoint document.
+ *  </p>
+ *  <p>
+ *  When you add a shape, you usually specify the dimensions of the shape and the position
+ *  of the upper'left corner of the bounding box for the shape relative to the upper'left
+ *  corner of the page, worksheet, or slide. Distances in the drawing layer are measured
+ *  in points (72 points = 1 inch).
+ *  </p>
+ * <p>
+  *
+  * @author Yegor Kozlov
+ */
+public abstract class HSLFShape implements Shape {
+
+    // For logging
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
+    /**
+     * In Escher absolute distances are specified in
+     * English Metric Units (EMUs), occasionally referred to as A units;
+     * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
+     */
+    public static final int EMU_PER_INCH = 914400;
+    public static final int EMU_PER_POINT = 12700;
+    public static final int EMU_PER_CENTIMETER = 360000;
+
+    /**
+     * Master DPI (576 pixels per inch).
+     * Used by the reference coordinate system in PowerPoint.
+     */
+    public static final int MASTER_DPI = 576;
+
+    /**
+     * Pixels DPI (96 pixels per inch)
+     */
+    public static final int PIXEL_DPI = 96;
+
+    /**
+     * Points DPI (72 pixels per inch)
+     */
+    public static final int POINT_DPI = 72;
+
+    /**
+     * Either EscherSpContainer or EscheSpgrContainer record
+     * which holds information about this shape.
+     */
+    protected EscherContainerRecord _escherContainer;
+
+    /**
+     * Parent of this shape.
+     * <code>null</code> for the topmost shapes.
+     */
+    protected ShapeContainer<HSLFShape> _parent;
+
+    /**
+     * The <code>Sheet</code> this shape belongs to
+     */
+    protected HSLFSheet _sheet;
+
+    /**
+     * Fill
+     */
+    protected HSLFFill _fill;
+
+    /**
+     * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
+     *
+     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent             the parent of this Shape
+     */
+      protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        _escherContainer = escherRecord;
+        _parent = parent;
+     }
+
+    /**
+     * Creates the lowerlevel escher records for this shape.
+     */
+    protected abstract EscherContainerRecord createSpContainer(boolean isChild);
+
+    /**
+     *  @return the parent of this shape
+     */
+    public ShapeContainer<HSLFShape> getParent(){
+        return _parent;
+    }
+
+    /**
+     * @return name of the shape.
+     */
+    public String getShapeName(){
+        return getShapeType().nativeName;
+    }
+
+    /**
+     * @return type of the shape.
+     * @see org.apache.poi.hslf.record.RecordTypes
+     */
+    public ShapeType getShapeType(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        return ShapeType.forId(spRecord.getShapeType(), false);
+    }
+
+    /**
+     * @param type type of the shape.
+     * @see org.apache.poi.hslf.record.RecordTypes
+     */
+    public void setShapeType(ShapeType type){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        spRecord.setShapeType( (short) type.nativeId );
+        spRecord.setVersion( (short) 0x2 );
+    }
+
+    /**
+     * Returns the anchor (the bounding box rectangle) of this shape.
+     * All coordinates are expressed in points (72 dpi).
+     *
+     * @return the anchor of this shape
+     */
+    public java.awt.Rectangle getAnchor(){
+        Rectangle2D anchor2d = getAnchor2D();
+        return anchor2d.getBounds();
+    }
+
+    /**
+     * Returns the anchor (the bounding box rectangle) of this shape.
+     * All coordinates are expressed in points (72 dpi).
+     *
+     * @return the anchor of this shape
+     */
+    public Rectangle2D getAnchor2D(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        int flags = spRecord.getFlags();
+        Rectangle2D anchor=null;
+        if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
+            EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+            anchor = new java.awt.Rectangle();
+            if(rec == null){
+                logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
+                EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+                anchor = new java.awt.Rectangle();
+                anchor = new Rectangle2D.Float(
+                    (float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
+                    (float)clrec.getFlag()*POINT_DPI/MASTER_DPI,
+                    (float)(clrec.getDx1()-clrec.getCol1())*POINT_DPI/MASTER_DPI,
+                    (float)(clrec.getRow1()-clrec.getFlag())*POINT_DPI/MASTER_DPI
+                );
+            } else {
+                anchor = new Rectangle2D.Float(
+                    (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
+                    (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
+                    (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
+                    (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
+                );
+            }
+        }
+        else {
+            EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+            anchor = new java.awt.Rectangle();
+            anchor = new Rectangle2D.Float(
+                (float)rec.getCol1()*POINT_DPI/MASTER_DPI,
+                (float)rec.getFlag()*POINT_DPI/MASTER_DPI,
+                (float)(rec.getDx1()-rec.getCol1())*POINT_DPI/MASTER_DPI,
+                (float)(rec.getRow1()-rec.getFlag())*POINT_DPI/MASTER_DPI
+            );
+        }
+        return anchor;
+    }
+
+    public Rectangle2D getLogicalAnchor2D(){
+        return getAnchor2D();
+    }
+
+    /**
+     * Sets the anchor (the bounding box rectangle) of this shape.
+     * All coordinates should be expressed in points (72 dpi).
+     *
+     * @param anchor new anchor
+     */
+    public void setAnchor(Rectangle2D anchor){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        int flags = spRecord.getFlags();
+        if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
+            EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+            rec.setDx1((int)(anchor.getX()*MASTER_DPI/POINT_DPI));
+            rec.setDy1((int)(anchor.getY()*MASTER_DPI/POINT_DPI));
+            rec.setDx2((int)((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI));
+            rec.setDy2((int)((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI));
+        }
+        else {
+            EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+            rec.setFlag((short)(anchor.getY()*MASTER_DPI/POINT_DPI));
+            rec.setCol1((short)(anchor.getX()*MASTER_DPI/POINT_DPI));
+            rec.setDx1((short)(((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI)));
+            rec.setRow1((short)(((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI)));
+        }
+
+    }
+
+    /**
+     * Moves the top left corner of the shape to the specified point.
+     *
+     * @param x the x coordinate of the top left corner of the shape
+     * @param y the y coordinate of the top left corner of the shape
+     */
+    public void moveTo(float x, float y){
+        Rectangle2D anchor = getAnchor2D();
+        anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
+        setAnchor(anchor);
+    }
+
+    /**
+     * Helper method to return escher child by record ID
+     *
+     * @return escher record or <code>null</code> if not found.
+     */
+    public static <T extends EscherRecord> T getEscherChild(EscherContainerRecord owner, int recordId){
+        return owner.getChildById((short)recordId);
+    }
+
+    public <T extends EscherRecord> T getEscherChild(int recordId){
+        return _escherContainer.getChildById((short)recordId);
+    }
+    
+    /**
+     * Returns  escher property by id.
+     *
+     * @return escher property or <code>null</code> if not found.
+     */
+     public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
+        return opt.lookup(propId);
+    }
+
+    /**
+     * Set an escher property for this shape.
+     *
+     * @param opt       The opt record to set the properties to.
+     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
+     * @param value     value of the property. If value = -1 then the property is removed.
+     */
+     public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
+        java.util.List<EscherProperty> props = opt.getEscherProperties();
+        for ( Iterator<EscherProperty> iterator = props.iterator(); iterator.hasNext(); ) {
+            if (iterator.next().getPropertyNumber() == propId){
+                iterator.remove();
+                break;
+            }
+        }
+        if (value != -1) {
+            opt.addEscherProperty(new EscherSimpleProperty(propId, value));
+            opt.sortProperties();
+        }
+    }
+
+    /**
+     * Set an simple escher property for this shape.
+     *
+     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
+     * @param value     value of the property. If value = -1 then the property is removed.
+     */
+    public void setEscherProperty(short propId, int value){
+        EscherOptRecord opt = getEscherOptRecord();
+        setEscherProperty(opt, propId, value);
+    }
+
+    /**
+     * Get the value of a simple escher property for this shape.
+     *
+     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
+     */
+   public int getEscherProperty(short propId){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, propId);
+        return prop == null ? 0 : prop.getPropertyValue();
+    }
+
+    /**
+     * Get the value of a simple escher property for this shape.
+     *
+     * @param propId    The id of the property. One of the constants defined in EscherOptRecord.
+     */
+   public int getEscherProperty(short propId, int defaultValue){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, propId);
+        return prop == null ? defaultValue : prop.getPropertyValue();
+    }
+
+    /**
+     * @return  The shape container and it's children that can represent this
+     *          shape.
+     */
+    public EscherContainerRecord getSpContainer(){
+        return _escherContainer;
+    }
+
+    /**
+     * Event which fires when a shape is inserted in the sheet.
+     * In some cases we need to propagate changes to upper level containers.
+     * <br>
+     * Default implementation does nothing.
+     *
+     * @param sh - owning shape
+     */
+    protected void afterInsert(HSLFSheet sh){
+        if(_fill != null) {
+            _fill.afterInsert(sh);
+        }
+    }
+
+    /**
+     *  @return the <code>SlideShow</code> this shape belongs to
+     */
+    public HSLFSheet getSheet(){
+        return _sheet;
+    }
+
+    /**
+     * Assign the <code>SlideShow</code> this shape belongs to
+     *
+     * @param sheet owner of this shape
+     */
+    public void setSheet(HSLFSheet sheet){
+        _sheet = sheet;
+    }
+
+    Color getColor(short colorProperty, short opacityProperty, int defaultColor){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty p = getEscherProperty(opt, colorProperty);
+        if(p == null && defaultColor == -1) return null;
+
+        int val = (p == null) ? defaultColor : p.getPropertyValue();
+
+        EscherColorRef ecr = new EscherColorRef(val);
+        
+        boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
+        boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
+        boolean fSystemRGB = ecr.hasSystemRGBFlag();
+        boolean fSchemeIndex = ecr.hasSchemeIndexFlag();
+        boolean fSysIndex = ecr.hasSysIndexFlag();
+        
+        int rgb[] = ecr.getRGB();
+
+        HSLFSheet sheet = getSheet();
+        if (fSchemeIndex && sheet != null) {
+            //red is the index to the color scheme
+            ColorSchemeAtom ca = sheet.getColorScheme();
+            int schemeColor = ca.getColor(ecr.getSchemeIndex());
+
+            rgb[0] = (schemeColor >> 0) & 0xFF;
+            rgb[1] = (schemeColor >> 8) & 0xFF;
+            rgb[2] = (schemeColor >> 16) & 0xFF;
+        } else if (fPaletteIndex){
+            //TODO
+        } else if (fPaletteRGB){
+            //TODO
+        } else if (fSystemRGB){
+            //TODO
+        } else if (fSysIndex){
+            //TODO
+        }
+
+        double alpha = getAlpha(opacityProperty);
+        return new Color(rgb[0], rgb[1], rgb[2], (int)(alpha*255.0));
+    }
+
+    double getAlpha(short opacityProperty) {
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
+        int defaultOpacity = 0x00010000;
+        int opacity = (op == null) ? defaultOpacity : op.getPropertyValue();
+        return Units.fixedPointToDouble(opacity);
+    }
+    
+    Color toRGB(int val){
+        int a = (val >> 24) & 0xFF;
+        int b = (val >> 16) & 0xFF;
+        int g = (val >> 8) & 0xFF;
+        int r = (val >> 0) & 0xFF;
+
+        if(a == 0xFE){
+            // Color is an sRGB value specified by red, green, and blue fields.
+        } else if (a == 0xFF){
+            // Color is undefined.
+        } else {
+            // index in the color scheme
+            ColorSchemeAtom ca = getSheet().getColorScheme();
+            int schemeColor = ca.getColor(a);
+
+            r = (schemeColor >> 0) & 0xFF;
+            g = (schemeColor >> 8) & 0xFF;
+            b = (schemeColor >> 16) & 0xFF;
+        }
+        return new Color(r, g, b);
+    }
+
+    /**
+     * @return id for the shape.
+     */
+    public int getShapeId(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        return spRecord == null ? 0 : spRecord.getShapeId();
+    }
+
+    /**
+     * Sets shape ID
+     *
+     * @param id of the shape
+     */
+    public void setShapeId(int id){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        if(spRecord != null) spRecord.setShapeId(id);
+    }
+
+    /**
+     * Fill properties of this shape
+     *
+     * @return fill properties of this shape
+     */
+    public HSLFFill getFill(){
+        if(_fill == null) {
+            _fill = new HSLFFill(this);
+        }
+        return _fill;
+    }
+
+    public FillStyle getFillStyle() {
+        return getFill().getFillStyle();
+    }
+
+    /**
+     * Returns the hyperlink assigned to this shape
+     *
+     * @return the hyperlink assigned to this shape
+     * or <code>null</code> if not found.
+     */
+    public HSLFHyperlink getHyperlink(){
+        return HSLFHyperlink.find(this);
+    }
+
+    public void draw(Graphics2D graphics){
+        logger.log(POILogger.INFO, "Rendering " + getShapeName());
+    }
+
+    /**
+     * Return shape outline as a java.awt.Shape object
+     *
+     * @return the shape outline
+     */
+    public java.awt.Shape getOutline(){
+        return getLogicalAnchor2D();
+    }
+    
+    public EscherOptRecord getEscherOptRecord() {
+        return getEscherChild(EscherOptRecord.RECORD_ID);
+    }
+    
+    public boolean getFlipHorizontal(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
+    }
+     
+    public void setFlipHorizontal(boolean flip) {
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ;
+        spRecord.setFlags(flag);
+    }
+
+    public boolean getFlipVertical(){
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
+    }
+    
+    public void setFlipVertical(boolean flip) {
+        EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+        int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPVERT;
+        spRecord.setFlags(flag);
+    }
+
+    public double getRotation(){
+        int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
+        double angle = Units.fixedPointToDouble(rot) % 360.0;
+        return angle;
+    }
+    
+    public void setRotation(double theta){
+        int rot = Units.doubleToFixedPoint(theta % 360.0);
+        setEscherProperty(EscherProperties.TRANSFORM__ROTATION, rot);
+    }
+
+    public boolean isPlaceholder() {
+        return false;
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
new file mode 100644 (file)
index 0000000..0f9dd28
--- /dev/null
@@ -0,0 +1,159 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.ddf.EscherClientDataRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherProperty;
+import org.apache.poi.ddf.EscherPropertyFactory;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hslf.model.*;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.InteractiveInfoAtom;
+import org.apache.poi.hslf.record.OEShapeAtom;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Create a <code>Shape</code> object depending on its type
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFShapeFactory {
+    // For logging
+    protected static final POILogger logger = POILogFactory.getLogger(HSLFShapeFactory.class);
+
+    /**
+     * Create a new shape from the data provided.
+     */
+    public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
+        if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
+            return createShapeGroup(spContainer, parent);
+        }
+        return createSimpleShape(spContainer, parent);
+    }
+
+    public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
+        HSLFGroupShape group = null;
+        EscherRecord opt = HSLFShape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
+        if(opt != null){
+            try {
+                EscherPropertyFactory f = new EscherPropertyFactory();
+                List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
+                EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
+                if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
+                    group = new Table(spContainer, parent);
+                } else {
+                    group = new HSLFGroupShape(spContainer, parent);
+                }
+            } catch (Exception e){
+                logger.log(POILogger.WARN, e.getMessage());
+                group = new HSLFGroupShape(spContainer, parent);
+            }
+        }  else {
+            group = new HSLFGroupShape(spContainer, parent);
+        }
+
+        return group;
+     }
+
+    public static HSLFShape createSimpleShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
+        HSLFShape shape = null;
+        EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
+
+        ShapeType type = ShapeType.forId(spRecord.getShapeType(), false);
+        switch (type){
+            case TEXT_BOX:
+                shape = new HSLFTextBox(spContainer, parent);
+                break;
+            case HOST_CONTROL:
+            case FRAME: {
+                InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
+                OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
+                if(info != null && info.getInteractiveInfoAtom() != null){
+                    switch(info.getInteractiveInfoAtom().getAction()){
+                        case InteractiveInfoAtom.ACTION_OLE:
+                            shape = new OLEShape(spContainer, parent);
+                            break;
+                        case InteractiveInfoAtom.ACTION_MEDIA:
+                            shape = new MovieShape(spContainer, parent);
+                            break;
+                        default:
+                            break;
+                    }
+                } else if (oes != null){
+                    shape = new OLEShape(spContainer, parent);
+                }
+
+                if(shape == null) shape = new HSLFPictureShape(spContainer, parent);
+                break;
+            }
+            case LINE:
+                shape = new Line(spContainer, parent);
+                break;
+            case NOT_PRIMITIVE: {
+                EscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
+                EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
+                if(prop != null)
+                    shape = new HSLFFreeformShape(spContainer, parent);
+                else {
+
+                    logger.log(POILogger.WARN, "Creating AutoShape for a NotPrimitive shape");
+                    shape = new HSLFAutoShape(spContainer, parent);
+                }
+                break;
+            }
+            default:
+                shape = new HSLFAutoShape(spContainer, parent);
+                break;
+        }
+        return shape;
+
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
+        Record oep = null;
+        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
+            EscherRecord obj = it.next();
+            if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
+                byte[] data = obj.serialize();
+                Record[] records = Record.findChildRecords(data, 8, data.length - 8);
+                for (int j = 0; j < records.length; j++) {
+                    if (records[j].getRecordType() == recordType) {
+                        return (T)records[j];
+                    }
+                }
+            }
+        }
+        return (T)oep;
+    }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
new file mode 100644 (file)
index 0000000..e5b704b
--- /dev/null
@@ -0,0 +1,403 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.Graphics2D;
+import java.util.*;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.sl.usermodel.Sheet;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * This class defines the common format of "Sheets" in a powerpoint
+ * document. Such sheets could be Slides, Notes, Master etc
+ *
+ * @author Nick Burch
+ * @author Yegor Kozlov
+ */
+
+public abstract class HSLFSheet implements Sheet<HSLFShape,HSLFSlideShow> {
+       private static POILogger logger = POILogFactory.getLogger(HSLFSheet.class);
+
+    /**
+     * The <code>SlideShow</code> we belong to
+     */
+    private HSLFSlideShow _slideShow;
+
+    /**
+     * Sheet background
+     */
+    private HSLFBackground _background;
+
+    /**
+     * Record container that holds sheet data.
+     * For slides it is org.apache.poi.hslf.record.Slide,
+     * for notes it is org.apache.poi.hslf.record.Notes,
+     * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
+     */
+    private SheetContainer _container;
+
+    private int _sheetNo;
+
+    public HSLFSheet(SheetContainer container, int sheetNo) {
+        _container = container;
+        _sheetNo = sheetNo;
+    }
+
+    /**
+     * Returns an array of all the TextRuns in the sheet.
+     */
+    public abstract List<List<HSLFTextParagraph>> getTextParagraphs();
+
+    /**
+     * Returns the (internal, RefID based) sheet number, as used
+     * to in PersistPtr stuff.
+     */
+    public int _getSheetRefId() {
+        return _container.getSheetId();
+    }
+
+    /**
+     * Returns the (internal, SlideIdentifier based) sheet number, as used
+     * to reference this sheet from other records.
+     */
+    public int _getSheetNumber() {
+        return _sheetNo;
+    }
+
+    /**
+     * Fetch the PPDrawing from the underlying record
+     */
+    public PPDrawing getPPDrawing() {
+        return _container.getPPDrawing();
+    }
+
+    /**
+     * Fetch the SlideShow we're attached to
+     */
+    public HSLFSlideShow getSlideShow() {
+        return _slideShow;
+    }
+
+    /**
+     * Return record container for this sheet
+     */
+    public SheetContainer getSheetContainer() {
+        return _container;
+    }
+
+    /**
+     * Set the SlideShow we're attached to.
+     * Also passes it on to our child RichTextRuns
+     */
+    public void setSlideShow(HSLFSlideShow ss) {
+        _slideShow = ss;
+        List<List<HSLFTextParagraph>> trs = getTextParagraphs();
+        if (trs == null) return;
+        for (List<HSLFTextParagraph> ltp : trs) {
+            for (HSLFTextParagraph tp : ltp) {
+                tp.supplySheet(this);
+            }
+        }
+    }
+
+
+    /**
+     * Returns all shapes contained in this Sheet
+     *
+     * @return all shapes contained in this Sheet (Slide or Notes)
+     */
+    @Override
+    public List<HSLFShape> getShapes() {
+        return getShapeList();
+    }
+
+    /**
+     * Add a new Shape to this Slide
+     *
+     * @param shape - the Shape to add
+     */
+    public void addShape(HSLFShape shape) {
+        PPDrawing ppdrawing = getPPDrawing();
+
+        EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
+        EscherContainerRecord spgr = (EscherContainerRecord) HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
+        spgr.addChildRecord(shape.getSpContainer());
+
+        shape.setSheet(this);
+        shape.setShapeId(allocateShapeId());
+        shape.afterInsert(this);
+    }
+
+    /**
+     * Allocates new shape id for the new drawing group id.
+     *
+     * @return a new shape id.
+     */
+    public int allocateShapeId()
+    {
+        EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
+
+        dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
+
+        // Add to existing cluster if space available
+        for (int i = 0; i < dgg.getFileIdClusters().length; i++)
+        {
+            EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
+            if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
+            {
+                int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
+                c.incrementShapeId();
+                dg.setNumShapes( dg.getNumShapes() + 1 );
+                dg.setLastMSOSPID( result );
+                if (result >= dgg.getShapeIdMax())
+                    dgg.setShapeIdMax( result + 1 );
+                return result;
+            }
+        }
+
+        // Create new cluster
+        dgg.addCluster( dg.getDrawingGroupId(), 0, false );
+        dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
+        dg.setNumShapes( dg.getNumShapes() + 1 );
+        int result = (1024 * dgg.getFileIdClusters().length);
+        dg.setLastMSOSPID( result );
+        if (result >= dgg.getShapeIdMax())
+            dgg.setShapeIdMax( result + 1 );
+        return result;
+    }
+
+    /**
+     * Removes the specified shape from this sheet.
+     *
+     * @param shape shape to be removed from this sheet, if present.
+     * @return <tt>true</tt> if the shape was deleted.
+     */
+    public boolean removeShape(HSLFShape shape) {
+        PPDrawing ppdrawing = getPPDrawing();
+
+        EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
+        EscherContainerRecord spgr = null;
+
+        for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
+            EscherRecord rec = it.next();
+            if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
+                spgr = (EscherContainerRecord) rec;
+                break;
+            }
+        }
+        if(spgr == null) {
+            return false;
+        }
+
+        List<EscherRecord> lst = spgr.getChildRecords();
+        boolean result = lst.remove(shape.getSpContainer());
+        spgr.setChildRecords(lst);
+        return result;
+    }
+
+    /**
+     * Called by SlideShow ater a new sheet is created
+     */
+    public void onCreate(){
+
+    }
+
+    /**
+     * Return the master sheet .
+     */
+    public abstract HSLFMasterSheet getMasterSheet();
+
+    /**
+     * Color scheme for this sheet.
+     */
+    public ColorSchemeAtom getColorScheme() {
+        return _container.getColorScheme();
+    }
+
+    /**
+     * Returns the background shape for this sheet.
+     *
+     * @return the background shape for this sheet.
+     */
+    public HSLFBackground getBackground() {
+        if (_background == null) {
+            PPDrawing ppdrawing = getPPDrawing();
+
+            EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
+            EscherContainerRecord spContainer = null;
+
+            for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
+                EscherRecord rec = it.next();
+                if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
+                    spContainer = (EscherContainerRecord) rec;
+                    break;
+                }
+            }
+            _background = new HSLFBackground(spContainer, null);
+            _background.setSheet(this);
+        }
+        return _background;
+    }
+
+    public void draw(Graphics2D graphics){
+
+    }
+
+    /**
+     * Subclasses should call this method and update the array of text runs
+     * when a text shape is added
+     *
+     * @param shape
+     */
+    protected void onAddTextShape(HSLFTextShape shape) {
+
+    }
+
+    /**
+     * Return placeholder by text type
+     *
+     * @param type  type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom}
+     * @return  <code>TextShape</code> or <code>null</code>
+     */
+    public HSLFTextShape getPlaceholderByTextType(int type){
+        for (HSLFShape shape : getShapes()) {
+            if(shape instanceof HSLFTextShape){
+                HSLFTextShape tx = (HSLFTextShape)shape;
+                if (tx != null && tx.getRunType() == type) {
+                    return tx;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Search text placeholer by its type
+     *
+     * @param type  type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
+     * @return  <code>TextShape</code> or <code>null</code>
+     */
+    public HSLFTextShape getPlaceholder(int type){
+        for (HSLFShape shape : getShapes()) {
+            if(shape instanceof HSLFTextShape){
+                HSLFTextShape tx = (HSLFTextShape)shape;
+                int placeholderId = 0;
+                OEPlaceholderAtom oep = tx.getPlaceholderAtom();
+                if(oep != null) {
+                    placeholderId = oep.getPlaceholderId();
+                } else {
+                    //special case for files saved in Office 2007
+                    RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
+                    if(hldr != null) placeholderId = hldr.getPlaceholderId();
+                }
+                if(placeholderId == type){
+                    return tx;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return programmable tag associated with this sheet, e.g. <code>___PPT12</code>.
+     *
+     * @return programmable tag associated with this sheet.
+     */
+    public String getProgrammableTag(){
+        String tag = null;
+        RecordContainer progTags = (RecordContainer)
+                getSheetContainer().findFirstOfType(
+                            RecordTypes.ProgTags.typeID
+        );
+        if(progTags != null) {
+            RecordContainer progBinaryTag = (RecordContainer)
+                progTags.findFirstOfType(
+                        RecordTypes.ProgBinaryTag.typeID
+            );
+            if(progBinaryTag != null) {
+                CString binaryTag = (CString)
+                    progBinaryTag.findFirstOfType(
+                            RecordTypes.CString.typeID
+                );
+                if(binaryTag != null) tag = binaryTag.getText();
+            }
+        }
+
+        return tag;
+
+    }
+
+    public Iterator<HSLFShape> iterator() {
+        return getShapeList().iterator();
+    }
+
+
+    /**
+     * Returns all shapes contained in this Sheet
+     *
+     * @return all shapes contained in this Sheet (Slide or Notes)
+     */
+    protected List<HSLFShape> getShapeList() {
+        PPDrawing ppdrawing = getPPDrawing();
+
+        EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
+        EscherContainerRecord spgr = null;
+
+        for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
+            EscherRecord rec = it.next();
+            if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
+                spgr = (EscherContainerRecord) rec;
+                break;
+            }
+        }
+        if (spgr == null) {
+            throw new IllegalStateException("spgr not found");
+        }
+
+        List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
+        Iterator<EscherRecord> it = spgr.getChildIterator();
+        if (it.hasNext()) {
+            // skip first item
+            it.next();
+        }
+        for (; it.hasNext();) {
+            EscherContainerRecord sp = (EscherContainerRecord) it.next();
+            HSLFShape sh = HSLFShapeFactory.createShape(sp, null);
+            sh.setSheet(this);
+            shapeList.add(sh);
+        }
+
+        return shapeList;
+    }
+
+    /**
+     * @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
+     * Sheets that support the notion of master (slide, slideLayout) should override it and
+     * check this setting
+     */
+    public boolean getFollowMasterGraphics() {
+        return false;
+    }
+
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
new file mode 100644 (file)
index 0000000..6c053d4
--- /dev/null
@@ -0,0 +1,452 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.sl.draw.geom.*;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.Units;
+
+/**
+ *  An abstract simple (non-group) shape.
+ *  This is the parent class for all primitive shapes like Line, Rectangle, etc.
+ *
+ *  @author Yegor Kozlov
+ */
+public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
+
+    public final static double DEFAULT_LINE_WIDTH = 0.75;
+
+    /**
+     * Records stored in EscherClientDataRecord
+     */
+    protected Record[] _clientRecords;
+    protected EscherClientDataRecord _clientData;
+
+    /**
+     * Create a SimpleShape object and initialize it from the supplied Record container.
+     *
+     * @param escherRecord    <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent    the parent of the shape
+     */
+    protected HSLFSimpleShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+    }
+
+    /**
+     * Create a new Shape
+     *
+     * @param isChild   <code>true</code> if the Line is inside a group, <code>false</code> otherwise
+     * @return the record container which holds this shape
+     */
+    protected EscherContainerRecord createSpContainer(boolean isChild) {
+        _escherContainer = new EscherContainerRecord();
+        _escherContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
+        _escherContainer.setOptions((short)15);
+
+        EscherSpRecord sp = new EscherSpRecord();
+        int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE;
+        if (isChild) flags |= EscherSpRecord.FLAG_CHILD;
+        sp.setFlags(flags);
+        _escherContainer.addChildRecord(sp);
+
+        EscherOptRecord opt = new EscherOptRecord();
+        opt.setRecordId(EscherOptRecord.RECORD_ID);
+        _escherContainer.addChildRecord(opt);
+
+        EscherRecord anchor;
+        if(isChild) anchor = new EscherChildAnchorRecord();
+        else {
+            anchor = new EscherClientAnchorRecord();
+
+            //hack. internal variable EscherClientAnchorRecord.shortRecord can be
+            //initialized only in fillFields(). We need to set shortRecord=false;
+            byte[] header = new byte[16];
+            LittleEndian.putUShort(header, 0, 0);
+            LittleEndian.putUShort(header, 2, 0);
+            LittleEndian.putInt(header, 4, 8);
+            anchor.fillFields(header, 0, null);
+        }
+        _escherContainer.addChildRecord(anchor);
+
+        return _escherContainer;
+    }
+
+    /**
+     *  Returns width of the line in in points
+     */
+    public double getLineWidth(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
+        double width = (prop == null) ? DEFAULT_LINE_WIDTH : Units.toPoints(prop.getPropertyValue());
+        return width;
+    }
+
+    /**
+     *  Sets the width of line in in points
+     *  @param width  the width of line in in points
+     */
+    public void setLineWidth(double width){
+        EscherOptRecord opt = getEscherOptRecord();
+        setEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH, Units.toEMU(width));
+    }
+
+    /**
+     * Sets the color of line
+     *
+     * @param color new color of the line
+     */
+    public void setLineColor(Color color){
+        EscherOptRecord opt = getEscherOptRecord();
+        if (color == null) {
+            setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
+        } else {
+            int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
+            setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb);
+            setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, color == null ? 0x180010 : 0x180018);
+        }
+    }
+
+    /**
+     * @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
+     */
+    public Color getLineColor(){
+        EscherOptRecord opt = getEscherOptRecord();
+
+        EscherSimpleProperty p = getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
+        if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
+
+        Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
+        return clr == null ? Color.black : clr;
+    }
+
+    /**
+     * Gets line dashing.
+     *
+     * @return dashing of the line.
+     */
+    public LineDash getLineDashing(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
+        return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue());
+    }
+
+    /**
+     * Sets line dashing.
+     *
+     * @param pen new style of the line.
+     */
+    public void setLineDashing(LineDash pen){
+        EscherOptRecord opt = getEscherOptRecord();
+        setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId);
+    }
+
+    /**
+     * Gets the line compound style
+     *
+     * @return the compound style of the line.
+     */
+    public LineCompound getLineCompound() {
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE);
+        return (prop == null) ? LineCompound.SINGLE : LineCompound.fromNativeId(prop.getPropertyValue());
+    }
+    
+    /**
+     * Sets the line compound style
+     *
+     * @param style new compound style of the line.
+     */
+    public void setLineCompound(LineCompound style){
+        EscherOptRecord opt = getEscherOptRecord();
+        setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == LineCompound.SINGLE ? -1 : style.nativeId);
+    }
+
+    /**
+     * Returns line style. One of the constants defined in this class.
+     *
+     * @return style of the line.
+     */
+    public StrokeStyle getStrokeStyle(){
+        return new StrokeStyle() {
+            public PaintStyle getPaint() {
+                return null;
+            }
+
+            public LineCap getLineCap() {
+                return null;
+            }
+
+            public LineDash getLineDash() {
+                return null;
+            }
+
+            public LineCompound getLineCompound() {
+                return null;
+            }
+
+            public double getLineWidth() {
+                return 0;
+            }
+            
+        };
+    }
+
+    /**
+     * The color used to fill this shape.
+     */
+    public Color getFillColor(){
+        return getFill().getForegroundColor();
+    }
+
+    /**
+     * The color used to fill this shape.
+     *
+     * @param color the background color
+     */
+    public void setFillColor(Color color){
+        getFill().setForegroundColor(color);
+    }
+
+    /**
+     *
+     * @return 'absolute' anchor of this shape relative to the parent sheet
+     */
+    public Rectangle2D getLogicalAnchor2D(){
+        Rectangle2D anchor = getAnchor2D();
+
+        //if it is a groupped shape see if we need to transform the coordinates
+        if (getParent() != null){
+            ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
+            for (ShapeContainer<HSLFShape> parent=this.getParent();
+                parent instanceof HSLFGroupShape;
+                parent = ((HSLFGroupShape)parent).getParent()) {
+                lst.add(0, (HSLFGroupShape)parent);
+            }
+            
+            AffineTransform tx = new AffineTransform();
+            for(HSLFGroupShape prnt : lst) {
+                Rectangle2D exterior = prnt.getAnchor2D();
+                Rectangle2D interior = prnt.getCoordinates();
+
+                double scaleX =  exterior.getWidth() / interior.getWidth();
+                double scaleY = exterior.getHeight() / interior.getHeight();
+
+                tx.translate(exterior.getX(), exterior.getY());
+                tx.scale(scaleX, scaleY);
+                tx.translate(-interior.getX(), -interior.getY());
+                
+            }
+            anchor = tx.createTransformedShape(anchor).getBounds2D();
+        }
+
+        double angle = getRotation();
+        if(angle != 0.){
+            double centerX = anchor.getX() + anchor.getWidth()/2;
+            double centerY = anchor.getY() + anchor.getHeight()/2;
+
+            AffineTransform trans = new AffineTransform();
+            trans.translate(centerX, centerY);
+            trans.rotate(Math.toRadians(angle));
+            trans.translate(-centerX, -centerY);
+
+            Rectangle2D rect = trans.createTransformedShape(anchor).getBounds2D();
+            if((anchor.getWidth() < anchor.getHeight() && rect.getWidth() > rect.getHeight()) ||
+                (anchor.getWidth() > anchor.getHeight() && rect.getWidth() < rect.getHeight())    ){
+                trans = new AffineTransform();
+                trans.translate(centerX, centerY);
+                trans.rotate(Math.PI/2);
+                trans.translate(-centerX, -centerY);
+                anchor = trans.createTransformedShape(anchor).getBounds2D();
+            }
+        }
+        return anchor;
+    }
+
+    /**
+     *  Find a record in the underlying EscherClientDataRecord
+     *
+     * @param recordType type of the record to search
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Record> T getClientDataRecord(int recordType) {
+
+        Record[] records = getClientRecords();
+        if(records != null) for (int i = 0; i < records.length; i++) {
+            if(records[i].getRecordType() == recordType){
+                return (T)records[i];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Search for EscherClientDataRecord, if found, convert its contents into an array of HSLF records
+     *
+     * @return an array of HSLF records contained in the shape's EscherClientDataRecord or <code>null</code>
+     */
+    protected Record[] getClientRecords() {
+        if(_clientData == null){
+            EscherRecord r = getEscherChild(EscherClientDataRecord.RECORD_ID);
+            //ddf can return EscherContainerRecord with recordId=EscherClientDataRecord.RECORD_ID
+            //convert in to EscherClientDataRecord on the fly
+            if(r != null && !(r instanceof EscherClientDataRecord)){
+                byte[] data = r.serialize();
+                r = new EscherClientDataRecord();
+                r.fillFields(data, 0, new DefaultEscherRecordFactory());
+            }
+            _clientData = (EscherClientDataRecord)r;
+        }
+        if(_clientData != null && _clientRecords == null){
+            byte[] data = _clientData.getRemainingData();
+            _clientRecords = Record.findChildRecords(data, 0, data.length);
+        }
+        return _clientRecords;
+    }
+
+    protected void updateClientData() {
+        if(_clientData != null && _clientRecords != null){
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            try {
+                for (int i = 0; i < _clientRecords.length; i++) {
+                    _clientRecords[i].writeOut(out);
+                }
+            } catch(Exception e){
+                throw new HSLFException(e);
+            }
+            _clientData.setRemainingData(out.toByteArray());
+        }
+    }
+
+    public void setHyperlink(HSLFHyperlink link){
+        if(link.getId() == -1){
+            throw new HSLFException("You must call SlideShow.addHyperlink(Hyperlink link) first");
+        }
+
+        EscherClientDataRecord cldata = new EscherClientDataRecord();
+        cldata.setOptions((short)0xF);
+        getSpContainer().addChildRecord(cldata); // TODO - junit to prove getChildRecords().add is wrong
+
+        InteractiveInfo info = new InteractiveInfo();
+        InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
+
+        switch(link.getType()){
+            case HSLFHyperlink.LINK_FIRSTSLIDE:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_FIRSTSLIDE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_FirstSlide);
+                break;
+            case HSLFHyperlink.LINK_LASTSLIDE:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_LASTSLIDE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_LastSlide);
+                break;
+            case HSLFHyperlink.LINK_NEXTSLIDE:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_NEXTSLIDE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_NextSlide);
+                break;
+            case HSLFHyperlink.LINK_PREVIOUSSLIDE:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_JUMP);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_PREVIOUSSLIDE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_PreviousSlide);
+                break;
+            case HSLFHyperlink.LINK_URL:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_NONE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_Url);
+                break;
+            case HSLFHyperlink.LINK_SLIDENUMBER:
+                infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
+                infoAtom.setJump(InteractiveInfoAtom.JUMP_NONE);
+                infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_SlideNumber);
+                break;
+        }
+
+        infoAtom.setHyperlinkID(link.getId());
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            info.writeOut(out);
+        } catch(Exception e){
+            throw new HSLFException(e);
+        }
+        cldata.setRemainingData(out.toByteArray());
+
+    }
+
+    public Guide getAdjustValue(String name) {
+        if (name == null || !name.matches("adj([1-9]|10)")) {
+            throw new IllegalArgumentException("Adjust value '"+name+"' not supported.");
+        }
+        short escherProp;
+        switch (Integer.parseInt(name.substring(3))) {
+            case 1: escherProp = EscherProperties.GEOMETRY__ADJUSTVALUE; break;
+            case 2: escherProp = EscherProperties.GEOMETRY__ADJUST2VALUE; break;
+            case 3: escherProp = EscherProperties.GEOMETRY__ADJUST3VALUE; break;
+            case 4: escherProp = EscherProperties.GEOMETRY__ADJUST4VALUE; break;
+            case 5: escherProp = EscherProperties.GEOMETRY__ADJUST5VALUE; break;
+            case 6: escherProp = EscherProperties.GEOMETRY__ADJUST6VALUE; break;
+            case 7: escherProp = EscherProperties.GEOMETRY__ADJUST7VALUE; break;
+            case 8: escherProp = EscherProperties.GEOMETRY__ADJUST8VALUE; break;
+            case 9: escherProp = EscherProperties.GEOMETRY__ADJUST9VALUE; break;
+            case 10: escherProp = EscherProperties.GEOMETRY__ADJUST10VALUE; break;
+            default: throw new RuntimeException();
+        }
+        
+        int adjval = getEscherProperty(escherProp, -1);
+        return (adjval == -1) ? null : new Guide(name, "val "+adjval);
+    }
+
+    public LineDecoration getLineDecoration() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public CustomGeometry getGeometry() {
+        ShapeType st = getShapeType();
+        String name = st.getOoxmlName();
+        
+        PresetGeometries dict = PresetGeometries.getInstance();
+        CustomGeometry geom = dict.get(name);
+        if(geom == null) {
+            throw new IllegalStateException("Unknown shape geometry: " + name);
+        }
+        
+        return geom;
+    }
+
+    public Shadow getShadow() {
+        // TODO Auto-generated method stub
+        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
new file mode 100644 (file)
index 0000000..2fbd5c2
--- /dev/null
@@ -0,0 +1,480 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.model.*;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.Slide;
+
+/**
+ * This class represents a slide in a PowerPoint Document. It allows
+ *  access to the text within, and the layout. For now, it only does
+ *  the text side of things though
+ *
+ * @author Nick Burch
+ * @author Yegor Kozlov
+ */
+
+public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSlideShow,HSLFNotes> {
+       private int _slideNo;
+       private SlideAtomsSet _atomSet;
+       private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
+       private HSLFNotes _notes; // usermodel needs to set this
+
+       /**
+        * Constructs a Slide from the Slide record, and the SlideAtomsSet
+        *  containing the text.
+        * Initializes TextRuns, to provide easier access to the text
+        *
+        * @param slide the Slide record we're based on
+        * @param notes the Notes sheet attached to us
+        * @param atomSet the SlideAtomsSet to get the text from
+        */
+       public HSLFSlide(org.apache.poi.hslf.record.Slide slide, HSLFNotes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
+        super(slide, slideIdentifier);
+
+               _notes = notes;
+               _atomSet = atomSet;
+               _slideNo = slideNumber;
+
+               // For the text coming in from the SlideAtomsSet:
+               // Build up TextRuns from pairs of TextHeaderAtom and
+               //  one of TextBytesAtom or TextCharsAtom
+               if (_atomSet != null && _atomSet.getSlideRecords().length > 0) {
+                   List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_atomSet.getSlideRecords());
+                   _paragraphs.addAll(llhtp);
+               if (_paragraphs.isEmpty()) {
+                   throw new RuntimeException("No text records found for slide");
+               }
+               } else {
+                       // No text on the slide, must just be pictures
+               }
+
+               // Grab text from SlideListWithTexts entries
+               for(List<HSLFTextParagraph> ltp : _paragraphs) {
+                   for (HSLFTextParagraph tp : ltp) {
+                       tp.supplySheet(this);
+                   }
+               }
+
+        // Grab the TextRuns from the PPDrawing
+               List<List<HSLFTextParagraph>> llOtherRuns = HSLFTextParagraph.findTextParagraphs(getPPDrawing());
+               for (List<HSLFTextParagraph> otherRuns : llOtherRuns) {
+               // Grab text from slide's PPDrawing
+               for(HSLFTextParagraph tp : otherRuns) {
+                   tp.supplySheet(this);
+                   tp.setIndex(-1); // runs found in PPDrawing are not linked with SlideListWithTexts
+               }
+               }
+        _paragraphs.addAll(llOtherRuns);
+       }
+
+       /**
+       * Create a new Slide instance
+       * @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder
+       * @param slideNumber The user facing number of the sheet
+       */
+       public HSLFSlide(int sheetNumber, int sheetRefId, int slideNumber){
+               super(new org.apache.poi.hslf.record.Slide(), sheetNumber);
+               _slideNo = slideNumber;
+        getSheetContainer().setSheetId(sheetRefId);
+       }
+
+    /**
+     * Returns the Notes Sheet for this slide, or null if there isn't one
+     */
+    @Override
+    public HSLFNotes getNotes() {
+        return _notes;
+    }
+
+       /**
+        * Sets the Notes that are associated with this. Updates the
+        *  references in the records to point to the new ID
+        */
+       @Override
+       public void setNotes(HSLFNotes notes) {
+               _notes = notes;
+
+               // Update the Slide Atom's ID of where to point to
+               SlideAtom sa = getSlideRecord().getSlideAtom();
+
+               if(_notes == null) {
+                       // Set to 0
+                       sa.setNotesID(0);
+               } else {
+                       // Set to the value from the notes' sheet id
+                       sa.setNotesID(_notes._getSheetNumber());
+               }
+       }
+
+       /**
+       * Changes the Slide's (external facing) page number.
+       * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#reorderSlide(int, int)
+       */
+       public void setSlideNumber(int newSlideNumber) {
+               _slideNo = newSlideNumber;
+       }
+
+    /**
+     * Called by SlideShow ater a new slide is created.
+     * <p>
+     * For Slide we need to do the following:
+     *  <li> set id of the drawing group.
+     *  <li> set shapeId for the container descriptor and background
+     * </p>
+     */
+    public void onCreate(){
+        //initialize drawing group id
+        EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherContainerRecord dgContainer = (EscherContainerRecord)getSheetContainer().getPPDrawing().getEscherRecords()[0];
+        EscherDgRecord dg = (EscherDgRecord) HSLFShape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
+        int dgId = dgg.getMaxDrawingGroupId() + 1;
+        dg.setOptions((short)(dgId << 4));
+        dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
+        dgg.setMaxDrawingGroupId(dgId);
+
+        for (EscherContainerRecord c : dgContainer.getChildContainers()) {
+            EscherSpRecord spr = null;
+            switch(c.getRecordId()){
+                case EscherContainerRecord.SPGR_CONTAINER:
+                    EscherContainerRecord dc = (EscherContainerRecord)c.getChild(0);
+                    spr = dc.getChildById(EscherSpRecord.RECORD_ID);
+                    break;
+                case EscherContainerRecord.SP_CONTAINER:
+                    spr = c.getChildById(EscherSpRecord.RECORD_ID);
+                    break;
+            }
+            if(spr != null) spr.setShapeId(allocateShapeId());
+        }
+
+        //PPT doen't increment the number of saved shapes for group descriptor and background
+        dg.setNumShapes(1);
+    }
+
+       /**
+        * Create a <code>TextBox</code> object that represents the slide's title.
+        *
+        * @return <code>TextBox</code> object that represents the slide's title.
+        */
+       public HSLFTextBox addTitle() {
+               Placeholder pl = new Placeholder();
+               pl.setShapeType(ShapeType.RECT);
+               pl.setRunType(TextHeaderAtom.TITLE_TYPE);
+               pl.setText("Click to edit title");
+               pl.setAnchor(new java.awt.Rectangle(54, 48, 612, 90));
+               addShape(pl);
+               return pl;
+       }
+
+
+       // Complex Accesser methods follow
+
+       /**
+        * Return title of this slide or <code>null</code> if the slide does not have title.
+        * <p>
+        * The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
+        * <code>TextHeaderAtom.TITLE_TYPE</code>
+        * </p>
+        *
+        * @see TextHeaderAtom
+        *
+        * @return title of this slide
+        */
+       public String getTitle(){
+               for (List<HSLFTextParagraph> tp : getTextParagraphs()) {
+                   if (tp.isEmpty()) continue;
+                       int type = tp.get(0).getRunType();
+                       switch (type) {
+                       case TextHeaderAtom.CENTER_TITLE_TYPE:
+                       case TextHeaderAtom.TITLE_TYPE:
+                           String str = HSLFTextParagraph.getRawText(tp);
+                           return HSLFTextParagraph.toExternalString(str, type);
+                       }
+               }
+               return null;
+       }
+
+       // Simple Accesser methods follow
+
+       /**
+        * Returns an array of all the TextRuns found
+        */
+       public List<List<HSLFTextParagraph>> getTextParagraphs() { return _paragraphs; }
+
+       /**
+        * Returns the (public facing) page number of this slide
+        */
+       public int getSlideNumber() { return _slideNo; }
+
+       /**
+        * Returns the underlying slide record
+        */
+       public org.apache.poi.hslf.record.Slide getSlideRecord() {
+        return (org.apache.poi.hslf.record.Slide)getSheetContainer();
+    }
+
+       /**
+        * @return set of records inside <code>SlideListWithtext</code> container
+        *  which hold text data for this slide (typically for placeholders).
+        */
+       protected SlideAtomsSet getSlideAtomsSet() { return _atomSet;  }
+
+    /**
+     * Returns master sheet associated with this slide.
+     * It can be either SlideMaster or TitleMaster objects.
+     *
+     * @return the master sheet associated with this slide.
+     */
+     public HSLFMasterSheet getMasterSheet(){
+        int masterId = getSlideRecord().getSlideAtom().getMasterID();
+        for (HSLFSlideMaster sm : getSlideShow().getSlideMasters()) {
+            if (masterId == sm._getSheetNumber()) return sm;
+        }
+        for (HSLFTitleMaster tm : getSlideShow().getTitleMasters()) {
+            if (masterId == tm._getSheetNumber()) return tm;
+        }
+        return null;
+    }
+
+    /**
+     * Change Master of this slide.
+     */
+    public void setMasterSheet(HSLFMasterSheet master){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        int sheetNo = master._getSheetNumber();
+        sa.setMasterID(sheetNo);
+    }
+
+    /**
+     * Sets whether this slide follows master background
+     *
+     * @param flag  <code>true</code> if the slide follows master,
+     * <code>false</code> otherwise
+     */
+    public void setFollowMasterBackground(boolean flag){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        sa.setFollowMasterBackground(flag);
+    }
+
+    /**
+     * Whether this slide follows master sheet background
+     *
+     * @return <code>true</code> if the slide follows master background,
+     * <code>false</code> otherwise
+     */
+    public boolean getFollowMasterBackground(){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        return sa.getFollowMasterBackground();
+    }
+
+    /**
+     * Sets whether this slide draws master sheet objects
+     *
+     * @param flag  <code>true</code> if the slide draws master sheet objects,
+     * <code>false</code> otherwise
+     */
+    public void setFollowMasterObjects(boolean flag){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        sa.setFollowMasterObjects(flag);
+    }
+
+    /**
+     * Whether this slide follows master color scheme
+     *
+     * @return <code>true</code> if the slide follows master color scheme,
+     * <code>false</code> otherwise
+     */
+    public boolean getFollowMasterScheme(){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        return sa.getFollowMasterScheme();
+    }
+
+    /**
+     * Sets whether this slide draws master color scheme
+     *
+     * @param flag  <code>true</code> if the slide draws master color scheme,
+     * <code>false</code> otherwise
+     */
+    public void setFollowMasterScheme(boolean flag){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        sa.setFollowMasterScheme(flag);
+    }
+
+    /**
+     * Whether this slide draws master sheet objects
+     *
+     * @return <code>true</code> if the slide draws master sheet objects,
+     * <code>false</code> otherwise
+     */
+    public boolean getFollowMasterObjects(){
+        SlideAtom sa = getSlideRecord().getSlideAtom();
+        return sa.getFollowMasterObjects();
+    }
+
+    /**
+     * Background for this slide.
+     */
+     public HSLFBackground getBackground() {
+        if(getFollowMasterBackground()) {
+            return getMasterSheet().getBackground();
+        }
+        return super.getBackground();
+    }
+
+    /**
+     * Color scheme for this slide.
+     */
+    public ColorSchemeAtom getColorScheme() {
+        if(getFollowMasterScheme()){
+            return getMasterSheet().getColorScheme();
+        }
+        return super.getColorScheme();
+    }
+
+    /**
+     * Get the comment(s) for this slide.
+     * Note - for now, only works on PPT 2000 and
+     *  PPT 2003 files. Doesn't work for PPT 97
+     *  ones, as they do their comments oddly.
+     */
+    public Comment[] getComments() {
+       // If there are any, they're in
+       //  ProgTags -> ProgBinaryTag -> BinaryTagData
+       RecordContainer progTags = (RecordContainer)
+                       getSheetContainer().findFirstOfType(
+                                               RecordTypes.ProgTags.typeID
+       );
+       if(progTags != null) {
+               RecordContainer progBinaryTag = (RecordContainer)
+                       progTags.findFirstOfType(
+                                       RecordTypes.ProgBinaryTag.typeID
+               );
+               if(progBinaryTag != null) {
+                       RecordContainer binaryTags = (RecordContainer)
+                               progBinaryTag.findFirstOfType(
+                                               RecordTypes.BinaryTagData.typeID
+                       );
+                       if(binaryTags != null) {
+                               // This is where they'll be
+                               int count = 0;
+                               for(int i=0; i<binaryTags.getChildRecords().length; i++) {
+                                       if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
+                                               count++;
+                                       }
+                               }
+
+                               // Now build
+                               Comment[] comments = new Comment[count];
+                               count = 0;
+                               for(int i=0; i<binaryTags.getChildRecords().length; i++) {
+                                       if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
+                                               comments[i] = new Comment(
+                                                               (Comment2000)binaryTags.getChildRecords()[i]
+                                               );
+                                               count++;
+                                       }
+                               }
+
+                               return comments;
+                       }
+               }
+       }
+
+       // None found
+       return new Comment[0];
+    }
+
+    /**
+     * Header / Footer settings for this slide.
+     *
+     * @return Header / Footer settings for this slide
+     */
+     public HeadersFooters getHeadersFooters(){
+        HeadersFootersContainer hdd = null;
+        Record[] ch = getSheetContainer().getChildRecords();
+        boolean ppt2007 = false;
+        for (int i = 0; i < ch.length; i++) {
+            if(ch[i] instanceof HeadersFootersContainer){
+                hdd = (HeadersFootersContainer)ch[i];
+            } else if (ch[i].getRecordType() == RecordTypes.RoundTripContentMasterId.typeID){
+                ppt2007 = true;
+            }
+        }
+        boolean newRecord = false;
+        if(hdd == null && !ppt2007) {
+            return getSlideShow().getSlideHeadersFooters();
+        }
+        if(hdd == null) {
+            hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
+            newRecord = true;
+        }
+        return new HeadersFooters(hdd, this, newRecord, ppt2007);
+    }
+
+    protected void onAddTextShape(HSLFTextShape shape) {
+        List<HSLFTextParagraph> newParas = shape.getTextParagraphs();
+        _paragraphs.add(newParas);
+    }
+
+    /** This will return an atom per TextBox, so if the page has two text boxes the method should return two atoms. */
+    public StyleTextProp9Atom[] getNumberedListInfo() {
+       return this.getPPDrawing().getNumberedListInfo();
+    }
+
+       public EscherTextboxWrapper[] getTextboxWrappers() {
+               return this.getPPDrawing().getTextboxWrappers();
+       }
+
+       public void setHidden(boolean hidden) {
+               org.apache.poi.hslf.record.Slide cont = getSlideRecord();
+               
+               SSSlideInfoAtom slideInfo = 
+                       (SSSlideInfoAtom)cont.findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
+               if (slideInfo == null) {
+                       slideInfo = new SSSlideInfoAtom();
+                       cont.addChildAfter(slideInfo, cont.findFirstOfType(RecordTypes.SlideAtom.typeID));
+               }
+               
+               slideInfo.setEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT, hidden);
+       }
+       
+       public boolean getHidden() {
+               SSSlideInfoAtom slideInfo = 
+                       (SSSlideInfoAtom)getSlideRecord().findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
+               return (slideInfo == null)
+                       ? false
+                       : slideInfo.getEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT);
+       }
+
+    public boolean getFollowMasterColourScheme() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public void setFollowMasterColourScheme(boolean follow) {
+        // TODO Auto-generated method stub
+        
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
new file mode 100644 (file)
index 0000000..3626573
--- /dev/null
@@ -0,0 +1,147 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.record.*;
+
+/**
+ * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation.
+ * It stores information about default font styles, placeholder sizes and positions,
+ * background design, and color schemes.
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFSlideMaster extends HSLFMasterSheet {
+    private final List<List<HSLFTextParagraph>> _runs = new ArrayList<List<HSLFTextParagraph>>();
+
+    /**
+     * all TxMasterStyleAtoms available in this master
+     */
+    private TxMasterStyleAtom[] _txmaster;
+
+    /**
+     * Constructs a SlideMaster from the MainMaster record,
+     *
+     */
+    public HSLFSlideMaster(MainMaster record, int sheetNo) {
+        super(record, sheetNo);
+
+        _runs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing()));
+        for (List<HSLFTextParagraph> p : _runs) {
+            for (HSLFTextParagraph htp : p) {
+                htp.supplySheet(this);
+            }
+        }
+    }
+
+    /**
+     * Returns an array of all the TextRuns found
+     */
+    public List<List<HSLFTextParagraph>> getTextParagraphs() {
+        return _runs;
+    }
+
+    /**
+     * Returns <code>null</code> since SlideMasters doen't have master sheet.
+     */
+    public HSLFMasterSheet getMasterSheet() {
+        return null;
+    }
+
+    /**
+     * Pickup a style attribute from the master.
+     * This is the "workhorse" which returns the default style attrubutes.
+     */
+    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
+
+        TextProp prop = null;
+        for (int i = level; i >= 0; i--) {
+            TextPropCollection[] styles =
+                    isCharacter ? _txmaster[txtype].getCharacterStyles() : _txmaster[txtype].getParagraphStyles();
+            if (i < styles.length) prop = styles[i].findByName(name);
+            if (prop != null) break;
+        }
+        if (prop == null) {
+            if(isCharacter) {
+                switch (txtype) {
+                    case TextHeaderAtom.CENTRE_BODY_TYPE:
+                    case TextHeaderAtom.HALF_BODY_TYPE:
+                    case TextHeaderAtom.QUARTER_BODY_TYPE:
+                        txtype = TextHeaderAtom.BODY_TYPE;
+                        break;
+                    case TextHeaderAtom.CENTER_TITLE_TYPE:
+                        txtype = TextHeaderAtom.TITLE_TYPE;
+                        break;
+                    default:
+                        return null;
+                }
+            } else {
+                switch (txtype) {
+                    case TextHeaderAtom.CENTRE_BODY_TYPE:
+                    case TextHeaderAtom.HALF_BODY_TYPE:
+                    case TextHeaderAtom.QUARTER_BODY_TYPE:
+                        txtype = TextHeaderAtom.BODY_TYPE;
+                        break;
+                    case TextHeaderAtom.CENTER_TITLE_TYPE:
+                        txtype = TextHeaderAtom.TITLE_TYPE;
+                        break;
+                    default:
+                        return null;
+                }
+            }
+            prop = getStyleAttribute(txtype, level, name, isCharacter);
+        }
+        return prop;
+    }
+
+    /**
+     * Assign SlideShow for this slide master.
+     * (Used interanlly)
+     */
+    public void setSlideShow(HSLFSlideShow ss) {
+        super.setSlideShow(ss);
+
+        //after the slide show is assigned collect all available style records
+        if (_txmaster == null) {
+            _txmaster = new TxMasterStyleAtom[9];
+
+            TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom();
+            _txmaster[txdoc.getTextType()] = txdoc;
+
+            TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms();
+            for (int i = 0; i < txrec.length; i++) {
+                int txType = txrec[i].getTextType();
+                if(_txmaster[txType] == null) _txmaster[txType] = txrec[i];
+            }
+        }
+    }
+
+    protected void onAddTextShape(HSLFTextShape shape) {
+        List<HSLFTextParagraph> runs = shape.getTextParagraphs();
+        _runs.add(runs);
+    }
+
+    public TxMasterStyleAtom[] getTxMasterStyleAtoms(){
+        return _txmaster;
+    }
+}
index 1f9f6ca0277b05db7843d71dfdc7d6b5448a8931..cf91e5695394e18a9fe17a9571f9c5283cc3c593 100644 (file)
@@ -25,12 +25,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import org.apache.poi.ddf.EscherBSERecord;
 import org.apache.poi.ddf.EscherContainerRecord;
@@ -69,7 +64,7 @@ import org.apache.poi.hslf.record.SlidePersistAtom;
 import org.apache.poi.hslf.record.UserEditAtom;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.*;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -97,10 +92,10 @@ public final class HSLFSlideShow implements SlideShow {
        private Document _documentRecord;
 
        // Friendly objects for people to deal with
-       private SlideMaster[] _masters;
-       private TitleMaster[] _titleMasters;
-       private HSLFSlide[] _slides;
-       private HSLFNotes[] _notes;
+       private final List<HSLFSlideMaster> _masters = new ArrayList<HSLFSlideMaster>();
+       private final List<HSLFTitleMaster> _titleMasters = new ArrayList<HSLFTitleMaster>();
+       private final List<HSLFSlide> _slides = new ArrayList<HSLFSlide>();
+       private final List<HSLFNotes> _notes = new ArrayList<HSLFNotes>();
        private FontCollection _fonts;
 
        // For logging
@@ -310,27 +305,21 @@ public final class HSLFSlideShow implements SlideShow {
                if (masterSLWT != null) {
                        masterSets = masterSLWT.getSlideAtomsSets();
 
-                       ArrayList<SlideMaster> mmr = new ArrayList<SlideMaster>();
-                       ArrayList<TitleMaster> tmr = new ArrayList<TitleMaster>();
-
                        for (SlideAtomsSet sas : masterSets) {
                                Record r = getCoreRecordForSAS(sas);
                                int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
                                if (r instanceof org.apache.poi.hslf.record.Slide) {
-                                       TitleMaster master = new TitleMaster((org.apache.poi.hslf.record.Slide) r,
+                                       HSLFTitleMaster master = new HSLFTitleMaster((org.apache.poi.hslf.record.Slide) r,
                                                        sheetNo);
                                        master.setSlideShow(this);
-                                       tmr.add(master);
+                                       _titleMasters.add(master);
                                } else if (r instanceof org.apache.poi.hslf.record.MainMaster) {
-                                       SlideMaster master = new SlideMaster((org.apache.poi.hslf.record.MainMaster) r,
+                                       HSLFSlideMaster master = new HSLFSlideMaster((org.apache.poi.hslf.record.MainMaster) r,
                                                        sheetNo);
                                        master.setSlideShow(this);
-                                       mmr.add(master);
+                                       _masters.add(master);
                                }
                        }
-
-                       _masters = mmr.toArray(new SlideMaster[mmr.size()]);
-                       _titleMasters = tmr.toArray(new TitleMaster[tmr.size()]);
                }
 
                // Having sorted out the masters, that leaves the notes and slides
@@ -408,16 +397,14 @@ public final class HSLFSlideShow implements SlideShow {
 
                // Finally, generate model objects for everything
                // Notes first
-               _notes = new HSLFNotes[notesRecords.length];
-               for (int i = 0; i < _notes.length; i++) {
-                   if (notesRecords[i] != null) {
-                   _notes[i] = new HSLFNotes(notesRecords[i]);
-                       _notes[i].setSlideShow(this);
-                   }
+               for (org.apache.poi.hslf.record.Notes n : notesRecords) {
+                   if (n == null) continue;
+                   HSLFNotes hn = new HSLFNotes(n);
+                   hn.setSlideShow(this);
+                   _notes.add(hn);
                }
                // Then slides
-               _slides = new HSLFSlide[slidesRecords.length];
-               for (int i = 0; i < _slides.length; i++) {
+               for (int i = 0; i < slidesRecords.length; i++) {
                        SlideAtomsSet sas = slidesSets[i];
                        int slideIdentifier = sas.getSlidePersistAtom().getSlideIdentifier();
 
@@ -429,15 +416,16 @@ public final class HSLFSlideShow implements SlideShow {
                        if (noteId != 0) {
                                Integer notesPos = slideIdToNotes.get(noteId);
                                if (notesPos != null) {
-                                       notes = _notes[notesPos];
+                                       notes = _notes.get(notesPos);
                                } else {
                                        logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId);
                                }
                        }
 
                        // Now, build our slide
-                       _slides[i] = new HSLFSlide(slidesRecords[i], notes, sas, slideIdentifier, (i + 1));
-                       _slides[i].setSlideShow(this);
+                       HSLFSlide hs = new HSLFSlide(slidesRecords[i], notes, sas, slideIdentifier, (i + 1));
+                       hs.setSlideShow(this);
+                       _slides.add(hs);
                }
        }
 
@@ -472,28 +460,30 @@ public final class HSLFSlideShow implements SlideShow {
        /**
         * Returns an array of all the normal Slides found in the slideshow
         */
-       public HSLFSlide[] getSlides() {
+       @Override
+       public List<HSLFSlide> getSlides() {
                return _slides;
        }
 
        /**
         * Returns an array of all the normal Notes found in the slideshow
         */
-       public HSLFNotes[] getNotes() {
+       public List<HSLFNotes> getNotes() {
                return _notes;
        }
 
        /**
         * Returns an array of all the normal Slide Masters found in the slideshow
         */
-       public SlideMaster[] getSlidesMasters() {
+       @Override
+       public List<HSLFSlideMaster> getSlideMasters() {
                return _masters;
        }
-
+       
        /**
         * Returns an array of all the normal Title Masters found in the slideshow
         */
-       public TitleMaster[] getTitleMasters() {
+       public List<HSLFTitleMaster> getTitleMasters() {
                return _titleMasters;
        }
 
@@ -573,12 +563,16 @@ public final class HSLFSlideShow implements SlideShow {
                if (oldSlideNumber < 1 || newSlideNumber < 1) {
                        throw new IllegalArgumentException("Old and new slide numbers must be greater than 0");
                }
-               if (oldSlideNumber > _slides.length || newSlideNumber > _slides.length) {
+               if (oldSlideNumber > _slides.size() || newSlideNumber > _slides.size()) {
                        throw new IllegalArgumentException(
                                        "Old and new slide numbers must not exceed the number of slides ("
-                                                       + _slides.length + ")");
+                                                       + _slides.size() + ")");
                }
 
+               _slides.get(newSlideNumber).setSlideNumber(oldSlideNumber);
+               _slides.get(oldSlideNumber).setSlideNumber(newSlideNumber);
+               Collections.swap(_slides, oldSlideNumber-1, newSlideNumber-1);
+               
                // The order of slides is defined by the order of slide atom sets in the
                // SlideListWithText container.
                SlideListWithText slwt = _documentRecord.getSlideSlideListWithText();
@@ -589,13 +583,9 @@ public final class HSLFSlideShow implements SlideShow {
                sas[newSlideNumber - 1] = tmp;
 
                ArrayList<Record> lst = new ArrayList<Record>();
-               for (int i = 0; i < sas.length; i++) {
-                       lst.add(sas[i].getSlidePersistAtom());
-                       Record[] r = sas[i].getSlideRecords();
-                       for (int j = 0; j < r.length; j++) {
-                               lst.add(r[j]);
-                       }
-                       _slides[i].setSlideNumber(i + 1);
+               for (SlideAtomsSet s : sas) {
+                       lst.add(s.getSlidePersistAtom());
+                       lst.addAll(Arrays.asList(s.getSlideRecords()));
                }
                Record[] r = lst.toArray(new Record[lst.size()]);
                slwt.setChildRecord(r);
@@ -613,7 +603,7 @@ public final class HSLFSlideShow implements SlideShow {
         * @return the slide that was removed from the slide show.
         */
        public HSLFSlide removeSlide(int index) {
-               int lastSlideIdx = _slides.length - 1;
+               int lastSlideIdx = _slides.size() - 1;
                if (index < 0 || index > lastSlideIdx) {
                        throw new IllegalArgumentException("Slide index (" + index + ") is out of range (0.."
                                        + lastSlideIdx + ")");
@@ -622,26 +612,19 @@ public final class HSLFSlideShow implements SlideShow {
                SlideListWithText slwt = _documentRecord.getSlideSlideListWithText();
                SlideAtomsSet[] sas = slwt.getSlideAtomsSets();
 
-               HSLFSlide removedSlide = null;
-               ArrayList<Record> records = new ArrayList<Record>();
-               ArrayList<SlideAtomsSet> sa = new ArrayList<SlideAtomsSet>();
-               ArrayList<HSLFSlide> sl = new ArrayList<HSLFSlide>();
-
-               ArrayList<HSLFNotes> nt = new ArrayList<HSLFNotes>();
-               for (HSLFNotes notes : getNotes())
-                       nt.add(notes);
-
-               for (int i = 0, num = 0; i < _slides.length; i++) {
-                       if (i != index) {
-                               sl.add(_slides[i]);
-                               sa.add(sas[i]);
-                               _slides[i].setSlideNumber(num++);
-                               records.add(sas[i].getSlidePersistAtom());
-                               records.addAll(Arrays.asList(sas[i].getSlideRecords()));
-                       } else {
-                               removedSlide = _slides[i];
-                               nt.remove(_slides[i].getNotesSheet());
-                       }
+               List<Record> records = new ArrayList<Record>();
+               List<SlideAtomsSet> sa = Arrays.asList(sas);
+
+               HSLFSlide removedSlide = _slides.remove(index);
+               _notes.remove(removedSlide.getNotes());
+               sa.remove(index);
+               
+               int i=0;
+               for (HSLFSlide s : _slides) s.setSlideNumber(i++);
+               
+               for (SlideAtomsSet s : sa) {
+            records.add(s.getSlidePersistAtom());
+            records.addAll(Arrays.asList(s.getSlideRecords()));
                }
                if (sa.size() == 0) {
                        _documentRecord.removeSlideListWithText(slwt);
@@ -649,34 +632,29 @@ public final class HSLFSlideShow implements SlideShow {
                        slwt.setSlideAtomsSets(sa.toArray(new SlideAtomsSet[sa.size()]));
                        slwt.setChildRecord(records.toArray(new Record[records.size()]));
                }
-               _slides = sl.toArray(new HSLFSlide[sl.size()]);
 
                // if the removed slide had notes - remove references to them too
 
-               if (removedSlide != null) {
-                       int notesId = removedSlide.getSlideRecord().getSlideAtom().getNotesID();
-                       if (notesId != 0) {
-                               SlideListWithText nslwt = _documentRecord.getNotesSlideListWithText();
-                               records = new ArrayList<Record>();
-                               ArrayList<SlideAtomsSet> na = new ArrayList<SlideAtomsSet>();
-                               for (SlideAtomsSet ns : nslwt.getSlideAtomsSets()) {
-                                       if (ns.getSlidePersistAtom().getSlideIdentifier() != notesId) {
-                                               na.add(ns);
-                                               records.add(ns.getSlidePersistAtom());
-                                               if (ns.getSlideRecords() != null)
-                                                       records.addAll(Arrays.asList(ns.getSlideRecords()));
-                                       }
-                               }
-                               if (na.size() == 0) {
-                                       _documentRecord.removeSlideListWithText(nslwt);
-                               } else {
-                                       nslwt.setSlideAtomsSets(na.toArray(new SlideAtomsSet[na.size()]));
-                                       nslwt.setChildRecord(records.toArray(new Record[records.size()]));
+        int notesId = (removedSlide != null) ? removedSlide.getSlideRecord().getSlideAtom().getNotesID() : 0;
+               if (notesId != 0) {
+                       SlideListWithText nslwt = _documentRecord.getNotesSlideListWithText();
+                       records = new ArrayList<Record>();
+                       ArrayList<SlideAtomsSet> na = new ArrayList<SlideAtomsSet>();
+                       for (SlideAtomsSet ns : nslwt.getSlideAtomsSets()) {
+                               if (ns.getSlidePersistAtom().getSlideIdentifier() == notesId) continue;
+                               na.add(ns);
+                               records.add(ns.getSlidePersistAtom());
+                               if (ns.getSlideRecords() != null) {
+                                       records.addAll(Arrays.asList(ns.getSlideRecords()));
                                }
-
+                       }
+                       if (na.isEmpty()) {
+                               _documentRecord.removeSlideListWithText(nslwt);
+                       } else {
+                               nslwt.setSlideAtomsSets(na.toArray(new SlideAtomsSet[na.size()]));
+                               nslwt.setChildRecord(records.toArray(new Record[records.size()]));
                        }
                }
-               _notes = nt.toArray(new HSLFNotes[nt.size()]);
 
                return removedSlide;
        }
@@ -736,16 +714,13 @@ public final class HSLFSlideShow implements SlideShow {
                slist.addSlidePersistAtom(sp);
 
                // Create a new Slide
-               HSLFSlide slide = new HSLFSlide(sp.getSlideIdentifier(), sp.getRefID(), _slides.length + 1);
+               HSLFSlide slide = new HSLFSlide(sp.getSlideIdentifier(), sp.getRefID(), _slides.size() + 1);
                slide.setSlideShow(this);
                slide.onCreate();
 
                // Add in to the list of Slides
-               HSLFSlide[] s = new HSLFSlide[_slides.length + 1];
-               System.arraycopy(_slides, 0, s, 0, _slides.length);
-               s[_slides.length] = slide;
-               _slides = s;
-               logger.log(POILogger.INFO, "Added slide " + _slides.length + " with ref " + sp.getRefID()
+               _slides.add(slide);
+               logger.log(POILogger.INFO, "Added slide " + _slides.size() + " with ref " + sp.getRefID()
                                + " and identifier " + sp.getSlideIdentifier());
 
                // Add the core records for this new Slide to the record tree
@@ -754,7 +729,7 @@ public final class HSLFSlideShow implements SlideShow {
                sp.setRefID(psrId);
                slideRecord.setSheetId(psrId);
                
-               slide.setMasterSheet(_masters[0]);
+               slide.setMasterSheet(_masters.get(0));
                // All done and added
                return slide;
        }
@@ -901,7 +876,7 @@ public final class HSLFSlideShow implements SlideShow {
         */
        public HeadersFooters getSlideHeadersFooters() {
                // detect if this ppt was saved in Office2007
-               String tag = getSlidesMasters()[0].getProgrammableTag();
+               String tag = getSlideMasters().get(0).getProgrammableTag();
                boolean ppt2007 = "___PPT12".equals(tag);
 
                HeadersFootersContainer hdd = null;
@@ -927,7 +902,7 @@ public final class HSLFSlideShow implements SlideShow {
         */
        public HeadersFooters getNotesHeadersFooters() {
                // detect if this ppt was saved in Office2007
-               String tag = getSlidesMasters()[0].getProgrammableTag();
+               String tag = getSlideMasters().get(0).getProgrammableTag();
                boolean ppt2007 = "___PPT12".equals(tag);
 
                HeadersFootersContainer hdd = null;
@@ -943,8 +918,8 @@ public final class HSLFSlideShow implements SlideShow {
                        hdd = new HeadersFootersContainer(HeadersFootersContainer.NotesHeadersFootersContainer);
                        newRecord = true;
                }
-               if (ppt2007 && _notes.length > 0) {
-                       return new HeadersFooters(hdd, _notes[0], newRecord, ppt2007);
+               if (ppt2007 && !_notes.isEmpty()) {
+                       return new HeadersFooters(hdd, _notes.get(0), newRecord, ppt2007);
                }
                return new HeadersFooters(hdd, this, newRecord, ppt2007);
        }
@@ -1010,10 +985,10 @@ public final class HSLFSlideShow implements SlideShow {
         *
         * @return 0-based index of the hyperlink
         */
-       public int addHyperlink(Hyperlink link) {
+       public int addHyperlink(HSLFHyperlink link) {
                ExHyperlink ctrl = new ExHyperlink();
                ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
-        if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
+        if(link.getType() == HSLFHyperlink.LINK_SLIDENUMBER) {
             ctrl.setLinkURL(link.getAddress(), 0x30);
         } else {
             ctrl.setLinkURL(link.getAddress());
@@ -1160,4 +1135,15 @@ public final class HSLFSlideShow implements SlideShow {
 
                return psrId;
     }
+
+    public MasterSheet<? extends Shape, ? extends SlideShow> createMasterSheet()
+            throws IOException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Resources getResources() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java
new file mode 100644 (file)
index 0000000..30397bf
--- /dev/null
@@ -0,0 +1,494 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+
+import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
+import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
+import org.apache.poi.hslf.record.DocumentEncryptionAtom;
+import org.apache.poi.hslf.record.PersistPtrHolder;
+import org.apache.poi.hslf.record.PositionDependentRecord;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.UserEditAtom;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
+import org.apache.poi.poifs.crypt.Decryptor;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.crypt.Encryptor;
+import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor;
+import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * This class provides helper functions for encrypted PowerPoint documents.
+ */
+@Internal
+public class HSLFSlideShowEncrypted {
+    DocumentEncryptionAtom dea;
+    CryptoAPIEncryptor enc = null;
+    CryptoAPIDecryptor dec = null;
+    Cipher cipher = null;
+    CipherOutputStream cyos = null;
+
+    private static final BitField fieldRecInst = new BitField(0xFFF0);
+    
+    protected HSLFSlideShowEncrypted(DocumentEncryptionAtom dea) {
+        this.dea = dea;
+    }
+
+    protected HSLFSlideShowEncrypted(byte[] docstream, NavigableMap<Integer,Record> recordMap) {
+        // check for DocumentEncryptionAtom, which would be at the last offset
+        // need to ignore already set UserEdit and PersistAtoms
+        UserEditAtom userEditAtomWithEncryption = null;
+        for (Map.Entry<Integer, Record> me : recordMap.descendingMap().entrySet()) {
+            Record r = me.getValue();
+            if (!(r instanceof UserEditAtom)) continue;
+            UserEditAtom uea = (UserEditAtom)r;
+            if (uea.getEncryptSessionPersistIdRef() != -1) {
+                userEditAtomWithEncryption = uea;
+                break;
+            }
+        }
+
+        if (userEditAtomWithEncryption == null) {
+            dea = null;
+            return;
+        }
+
+        Record r = recordMap.get(userEditAtomWithEncryption.getPersistPointersOffset());
+        assert(r instanceof PersistPtrHolder);
+        PersistPtrHolder ptr = (PersistPtrHolder)r;
+        
+        Integer encOffset = ptr.getSlideLocationsLookup().get(userEditAtomWithEncryption.getEncryptSessionPersistIdRef());
+        assert(encOffset != null);
+        
+        r = recordMap.get(encOffset);
+        if (r == null) {
+            r = Record.buildRecordAtOffset(docstream, encOffset);
+            recordMap.put(encOffset, r);
+        }
+        assert(r instanceof DocumentEncryptionAtom);
+        this.dea = (DocumentEncryptionAtom)r;
+        
+        CryptoAPIDecryptor dec = (CryptoAPIDecryptor)dea.getEncryptionInfo().getDecryptor();
+        String pass = Biff8EncryptionKey.getCurrentUserPassword();
+        if(!dec.verifyPassword(pass != null ? pass : Decryptor.DEFAULT_PASSWORD)) {
+            throw new EncryptedPowerPointFileException("PowerPoint file is encrypted. The correct password needs to be set via Biff8EncryptionKey.setCurrentUserPassword()");
+        }
+     }
+
+    public DocumentEncryptionAtom getDocumentEncryptionAtom() {
+        return dea;
+    }
+    
+    protected void setPersistId(int persistId) {
+        if (enc != null && dec != null) {
+            throw new EncryptedPowerPointFileException("Use instance either for en- or decryption");
+        }
+        
+        try {
+            if (enc != null) cipher = enc.initCipherForBlock(cipher, persistId);
+            if (dec != null) cipher = dec.initCipherForBlock(cipher, persistId);
+        } catch (GeneralSecurityException e) {
+            throw new EncryptedPowerPointFileException(e);
+        }
+    }
+    
+    protected void decryptInit() {
+        if (dec != null) return;
+        EncryptionInfo ei = dea.getEncryptionInfo();
+        dec = (CryptoAPIDecryptor)ei.getDecryptor();
+    }
+    
+    protected void encryptInit() {
+        if (enc != null) return;
+        EncryptionInfo ei = dea.getEncryptionInfo();
+        enc = (CryptoAPIEncryptor)ei.getEncryptor();
+    }
+    
+
+    
+    protected OutputStream encryptRecord(OutputStream plainStream, int persistId, Record record) {
+        boolean isPlain = (dea == null 
+            || record instanceof UserEditAtom
+            || record instanceof PersistPtrHolder
+            || record instanceof DocumentEncryptionAtom
+        );
+        if (isPlain) return plainStream;
+
+        encryptInit();
+        setPersistId(persistId);
+        
+        if (cyos == null) {
+            cyos = new CipherOutputStream(plainStream, cipher);
+        }
+        return cyos;
+    }
+
+    protected void decryptRecord(byte[] docstream, int persistId, int offset) {
+        if (dea == null) return;
+
+        decryptInit();
+        setPersistId(persistId);
+        
+        try {
+            // decrypt header and read length to be decrypted
+            cipher.update(docstream, offset, 8, docstream, offset);
+            // decrypt the rest of the record
+            int rlen = (int)LittleEndian.getUInt(docstream, offset+4);
+            cipher.update(docstream, offset+8, rlen, docstream, offset+8);
+        } catch (GeneralSecurityException e) {
+            throw new CorruptPowerPointFileException(e);
+        }       
+    }        
+    
+    protected void decryptPicture(byte[] pictstream, int offset) {
+        if (dea == null) return;
+        
+        decryptInit();
+        setPersistId(0);
+        
+        try {
+            // decrypt header and read length to be decrypted
+            cipher.doFinal(pictstream, offset, 8, pictstream, offset);
+            int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
+            int recType = LittleEndian.getUShort(pictstream, offset+2);
+            int rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
+            offset += 8;
+            int endOffset = offset + rlen; 
+
+            if (recType == 0xF007) {
+                // TOOD: get a real example file ... to actual test the FBSE entry
+                // not sure where the foDelay block is
+                
+                // File BLIP Store Entry (FBSE)
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btWin32
+                offset++;
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btMacOS
+                offset++;
+                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid
+                offset += 16;
+                cipher.doFinal(pictstream, offset, 2, pictstream, offset); // tag
+                offset += 2;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // size
+                offset += 4;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // cRef
+                offset += 4;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // foDelay
+                offset += 4;
+                cipher.doFinal(pictstream, offset+0, 1, pictstream, offset+0); // unused1
+                cipher.doFinal(pictstream, offset+1, 1, pictstream, offset+1); // cbName
+                cipher.doFinal(pictstream, offset+2, 1, pictstream, offset+2); // unused2
+                cipher.doFinal(pictstream, offset+3, 1, pictstream, offset+3); // unused3
+                int cbName = LittleEndian.getUShort(pictstream, offset+1);
+                offset += 4;
+                if (cbName > 0) {
+                    cipher.doFinal(pictstream, offset, cbName, pictstream, offset); // nameData
+                    offset += cbName;
+                }
+                if (offset == endOffset) {
+                    return; // no embedded blip
+                }
+                // fall through, read embedded blip now
+
+                // update header data
+                cipher.doFinal(pictstream, offset, 8, pictstream, offset);
+                recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
+                recType = LittleEndian.getUShort(pictstream, offset+2);
+                rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
+                offset += 8;
+            }
+
+            int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 ||
+                recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1;
+            
+            for (int i=0; i<rgbUidCnt; i++) {
+                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid 1/2
+                offset += 16;
+            }
+            
+            if (recType == 0xF01A || recType == 0XF01B || recType == 0XF01C) {
+                cipher.doFinal(pictstream, offset, 34, pictstream, offset); // metafileHeader
+                offset += 34;
+            } else {
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // tag
+                offset += 1;
+            }
+            
+            int blipLen = endOffset - offset;
+            cipher.doFinal(pictstream, offset, blipLen, pictstream, offset);
+        } catch (GeneralSecurityException e) {
+            throw new CorruptPowerPointFileException(e);
+        }       
+    }
+
+    protected void encryptPicture(byte[] pictstream, int offset) {
+        if (dea == null) return;
+        
+        encryptInit();
+        setPersistId(0);
+
+        try {
+            int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
+            int recType = LittleEndian.getUShort(pictstream, offset+2);
+            int rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
+            cipher.doFinal(pictstream, offset, 8, pictstream, offset);
+            offset += 8;
+            int endOffset = offset + rlen; 
+
+            if (recType == 0xF007) {
+                // TOOD: get a real example file ... to actual test the FBSE entry
+                // not sure where the foDelay block is
+                
+                // File BLIP Store Entry (FBSE)
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btWin32
+                offset++;
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // btMacOS
+                offset++;
+                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid
+                offset += 16;
+                cipher.doFinal(pictstream, offset, 2, pictstream, offset); // tag
+                offset += 2;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // size
+                offset += 4;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // cRef
+                offset += 4;
+                cipher.doFinal(pictstream, offset, 4, pictstream, offset); // foDelay
+                offset += 4;
+                int cbName = LittleEndian.getUShort(pictstream, offset+1);
+                cipher.doFinal(pictstream, offset+0, 1, pictstream, offset+0); // unused1
+                cipher.doFinal(pictstream, offset+1, 1, pictstream, offset+1); // cbName
+                cipher.doFinal(pictstream, offset+2, 1, pictstream, offset+2); // unused2
+                cipher.doFinal(pictstream, offset+3, 1, pictstream, offset+3); // unused3
+                offset += 4;
+                if (cbName > 0) {
+                    cipher.doFinal(pictstream, offset, cbName, pictstream, offset); // nameData
+                    offset += cbName;
+                }
+                if (offset == endOffset) {
+                    return; // no embedded blip
+                }
+                // fall through, read embedded blip now
+
+                // update header data
+                recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
+                recType = LittleEndian.getUShort(pictstream, offset+2);
+                rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
+                cipher.doFinal(pictstream, offset, 8, pictstream, offset);
+                offset += 8;
+            }
+            
+            int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 ||
+                recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1;
+                
+            for (int i=0; i<rgbUidCnt; i++) {
+                cipher.doFinal(pictstream, offset, 16, pictstream, offset); // rgbUid 1/2
+                offset += 16;
+            }
+            
+            if (recType == 0xF01A || recType == 0XF01B || recType == 0XF01C) {
+                cipher.doFinal(pictstream, offset, 34, pictstream, offset); // metafileHeader
+                offset += 34;
+            } else {
+                cipher.doFinal(pictstream, offset, 1, pictstream, offset); // tag
+                offset += 1;
+            }
+            
+            int blipLen = endOffset - offset;
+            cipher.doFinal(pictstream, offset, blipLen, pictstream, offset);
+        } catch (GeneralSecurityException e) {
+            throw new CorruptPowerPointFileException(e);
+        }       
+    }
+
+    protected Record[] updateEncryptionRecord(Record records[]) {
+        String password = Biff8EncryptionKey.getCurrentUserPassword();
+        if (password == null) {
+            if (dea == null) {
+                // no password given, no encryption record exits -> done
+                return records;
+            } else {
+                // need to remove password data
+                dea = null;
+                return removeEncryptionRecord(records);
+            }
+        } else {
+            // create password record
+            if (dea == null) {
+                dea = new DocumentEncryptionAtom();
+            }
+            EncryptionInfo ei = dea.getEncryptionInfo();
+            byte salt[] = ei.getVerifier().getSalt();
+            Encryptor enc = ei.getEncryptor();
+            if (salt == null) {
+                enc.confirmPassword(password);
+            } else {
+                byte verifier[] = ei.getDecryptor().getVerifier();
+                enc.confirmPassword(password, null, null, verifier, salt, null);
+            }
+
+            // move EncryptionRecord to last slide position
+            records = normalizeRecords(records);
+            return addEncryptionRecord(records, dea);
+        }
+    }
+
+    /**
+     * remove duplicated UserEditAtoms and merge PersistPtrHolder.
+     * Before this method is called, make sure that the offsets are correct,
+     * i.e. call {@link HSLFSlideShowImpl#updateAndWriteDependantRecords(OutputStream, Map)}
+     */
+    protected static Record[] normalizeRecords(Record records[]) {
+        // http://msdn.microsoft.com/en-us/library/office/gg615594(v=office.14).aspx
+        // repeated slideIds can be overwritten, i.e. ignored
+        
+        UserEditAtom uea = null;
+        PersistPtrHolder pph = null;
+        TreeMap<Integer,Integer> slideLocations = new TreeMap<Integer,Integer>();
+        TreeMap<Integer,Record> recordMap = new TreeMap<Integer,Record>();
+        List<Integer> obsoleteOffsets = new ArrayList<Integer>();
+        int duplicatedCount = 0;
+        for (Record r : records) {
+            assert(r instanceof PositionDependentRecord);
+            PositionDependentRecord pdr = (PositionDependentRecord)r;
+            if (pdr instanceof UserEditAtom) {
+                uea = (UserEditAtom)pdr;
+                continue;
+            }
+            
+            if (pdr instanceof PersistPtrHolder) {
+                if (pph != null) {
+                    duplicatedCount++;
+                }
+                pph = (PersistPtrHolder)pdr;
+                for (Map.Entry<Integer,Integer> me : pph.getSlideLocationsLookup().entrySet()) {
+                    Integer oldOffset = slideLocations.put(me.getKey(), me.getValue());
+                    if (oldOffset != null) obsoleteOffsets.add(oldOffset);
+                }
+                continue;
+            }
+            
+            recordMap.put(pdr.getLastOnDiskOffset(), r);
+        }
+        recordMap.put(pph.getLastOnDiskOffset(), pph);
+        recordMap.put(uea.getLastOnDiskOffset(), uea);
+
+        assert(uea != null && pph != null && uea.getPersistPointersOffset() == pph.getLastOnDiskOffset());
+        
+        if (duplicatedCount == 0 && obsoleteOffsets.isEmpty()) {
+            return records;
+        }
+
+        uea.setLastUserEditAtomOffset(0);
+        pph.clear();
+        for (Map.Entry<Integer,Integer> me : slideLocations.entrySet()) {
+            pph.addSlideLookup(me.getKey(), me.getValue());
+        }
+        
+        for (Integer oldOffset : obsoleteOffsets) {
+            recordMap.remove(oldOffset);
+        }
+        
+        return recordMap.values().toArray(new Record[recordMap.size()]);
+    }
+     
+    
+    protected static Record[] removeEncryptionRecord(Record records[]) {
+        int deaSlideId = -1;
+        int deaOffset = -1;
+        PersistPtrHolder ptr = null;
+        UserEditAtom uea = null;
+        List<Record> recordList = new ArrayList<Record>();
+        for (Record r : records) {
+            if (r instanceof DocumentEncryptionAtom) {
+                deaOffset = ((DocumentEncryptionAtom)r).getLastOnDiskOffset();
+                continue;
+            } else if (r instanceof UserEditAtom) {
+                uea = (UserEditAtom)r;
+                deaSlideId = uea.getEncryptSessionPersistIdRef();
+                uea.setEncryptSessionPersistIdRef(-1);
+            } else if (r instanceof PersistPtrHolder) {
+                ptr = (PersistPtrHolder)r;
+            }
+            recordList.add(r);
+        }
+        
+        assert(ptr != null);
+        if (deaSlideId == -1 && deaOffset == -1) return records;
+        
+        TreeMap<Integer,Integer> tm = new TreeMap<Integer,Integer>(ptr.getSlideLocationsLookup());
+        ptr.clear();
+        int maxSlideId = -1;
+        for (Map.Entry<Integer,Integer> me : tm.entrySet()) {
+            if (me.getKey() == deaSlideId || me.getValue() == deaOffset) continue;
+            ptr.addSlideLookup(me.getKey(), me.getValue());
+            maxSlideId = Math.max(me.getKey(), maxSlideId);
+        }
+        
+        uea.setMaxPersistWritten(maxSlideId);
+
+        records = recordList.toArray(new Record[recordList.size()]);
+        
+        return records;
+    }
+
+
+    protected static Record[] addEncryptionRecord(Record records[], DocumentEncryptionAtom dea) {
+        assert(dea != null);
+        int ueaIdx = -1, ptrIdx = -1, deaIdx = -1, idx = -1;
+        for (Record r : records) {
+            idx++;
+            if (r instanceof UserEditAtom) ueaIdx = idx;
+            else if (r instanceof PersistPtrHolder) ptrIdx = idx;
+            else if (r instanceof DocumentEncryptionAtom) deaIdx = idx;
+        }
+        assert(ueaIdx != -1 && ptrIdx != -1 && ptrIdx < ueaIdx);
+        if (deaIdx != -1) {
+            DocumentEncryptionAtom deaOld = (DocumentEncryptionAtom)records[deaIdx];
+            dea.setLastOnDiskOffset(deaOld.getLastOnDiskOffset());
+            records[deaIdx] = dea;
+            return records;
+        } else {
+            PersistPtrHolder ptr = (PersistPtrHolder)records[ptrIdx];
+            UserEditAtom uea = ((UserEditAtom)records[ueaIdx]);
+            dea.setLastOnDiskOffset(ptr.getLastOnDiskOffset()-1);
+            int nextSlideId = uea.getMaxPersistWritten()+1;
+            ptr.addSlideLookup(nextSlideId, ptr.getLastOnDiskOffset()-1);
+            uea.setEncryptSessionPersistIdRef(nextSlideId);
+            uea.setMaxPersistWritten(nextSlideId);
+            
+            Record newRecords[] = new Record[records.length+1];
+            if (ptrIdx > 0) System.arraycopy(records, 0, newRecords, 0, ptrIdx);
+            if (ptrIdx < records.length-1) System.arraycopy(records, ptrIdx, newRecords, ptrIdx+1, records.length-ptrIdx);
+            newRecords[ptrIdx] = dea;
+            return newRecords;
+        }
+    }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
new file mode 100644 (file)
index 0000000..ec5f735
--- /dev/null
@@ -0,0 +1,806 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import org.apache.poi.POIDocument;
+import org.apache.poi.hpsf.PropertySet;
+import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.record.CurrentUserAtom;
+import org.apache.poi.hslf.record.DocumentEncryptionAtom;
+import org.apache.poi.hslf.record.ExOleObjStg;
+import org.apache.poi.hslf.record.PersistPtrHolder;
+import org.apache.poi.hslf.record.PersistRecord;
+import org.apache.poi.hslf.record.PositionDependentRecord;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.record.UserEditAtom;
+import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.DocumentEntry;
+import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.poifs.filesystem.EntryUtils;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * This class contains the main functionality for the Powerpoint file
+ * "reader". It is only a very basic class for now
+ *
+ * @author Nick Burch
+ */
+public final class HSLFSlideShowImpl extends POIDocument {
+    public static final int UNSET_OFFSET = -1;
+    
+    // For logging
+    private POILogger logger = POILogFactory.getLogger(this.getClass());
+
+       // Holds metadata on where things are in our document
+       private CurrentUserAtom currentUser;
+
+       // Low level contents of the file
+       private byte[] _docstream;
+
+       // Low level contents
+       private Record[] _records;
+
+       // Raw Pictures contained in the pictures stream
+       private List<HSLFPictureData> _pictures;
+
+    // Embedded objects stored in storage records in the document stream, lazily populated.
+    private HSLFObjectData[] _objects;
+    
+    /**
+        * Returns the underlying POIFSFileSystem for the document
+        *  that is open.
+        */
+       protected POIFSFileSystem getPOIFSFileSystem() {
+               return directory.getFileSystem();
+       }
+
+   /**
+    * Returns the directory in the underlying POIFSFileSystem for the 
+    *  document that is open.
+    */
+   protected DirectoryNode getPOIFSDirectory() {
+      return directory;
+   }
+
+       /**
+        * Constructs a Powerpoint document from fileName. Parses the document
+        * and places all the important stuff into data structures.
+        *
+        * @param fileName The name of the file to read.
+        * @throws IOException if there is a problem while parsing the document.
+        */
+       public HSLFSlideShowImpl(String fileName) throws IOException
+       {
+               this(new FileInputStream(fileName));
+       }
+
+       /**
+        * Constructs a Powerpoint document from an input stream. Parses the
+        * document and places all the important stuff into data structures.
+        *
+        * @param inputStream the source of the data
+        * @throws IOException if there is a problem while parsing the document.
+        */
+       public HSLFSlideShowImpl(InputStream inputStream) throws IOException {
+               //do Ole stuff
+               this(new POIFSFileSystem(inputStream));
+       }
+
+       /**
+        * Constructs a Powerpoint document from a POIFS Filesystem. Parses the
+        * document and places all the important stuff into data structures.
+        *
+        * @param filesystem the POIFS FileSystem to read from
+        * @throws IOException if there is a problem while parsing the document.
+        */
+       public HSLFSlideShowImpl(POIFSFileSystem filesystem) throws IOException
+       {
+               this(filesystem.getRoot());
+       }
+
+   /**
+    * Constructs a Powerpoint document from a POIFS Filesystem. Parses the
+    * document and places all the important stuff into data structures.
+    *
+    * @param filesystem the POIFS FileSystem to read from
+    * @throws IOException if there is a problem while parsing the document.
+    */
+   public HSLFSlideShowImpl(NPOIFSFileSystem filesystem) throws IOException
+   {
+      this(filesystem.getRoot());
+   }
+
+   /**
+    * Constructs a Powerpoint document from a specific point in a
+    *  POIFS Filesystem. Parses the document and places all the
+    *  important stuff into data structures.
+    *
+    * @deprecated Use {@link #HSLFSlideShow(DirectoryNode)} instead
+    * @param dir the POIFS directory to read from
+    * @param filesystem the POIFS FileSystem to read from
+    * @throws IOException if there is a problem while parsing the document.
+    */
+       @Deprecated
+   public HSLFSlideShowImpl(DirectoryNode dir, POIFSFileSystem filesystem) throws IOException
+   {
+      this(dir);
+   }
+   
+       /**
+        * Constructs a Powerpoint document from a specific point in a
+        *  POIFS Filesystem. Parses the document and places all the
+        *  important stuff into data structures.
+        *
+        * @param dir the POIFS directory to read from
+        * @throws IOException if there is a problem while parsing the document.
+        */
+       public HSLFSlideShowImpl(DirectoryNode dir) throws IOException {
+               super(handleDualStorage(dir));
+
+               // First up, grab the "Current User" stream
+               // We need this before we can detect Encrypted Documents
+               readCurrentUserStream();
+
+               // Next up, grab the data that makes up the
+               //  PowerPoint stream
+               readPowerPointStream();
+
+               // Now, build records based on the PowerPoint stream
+               buildRecords();
+
+               // Look for any other streams
+               readOtherStreams();
+       }
+       
+       private static DirectoryNode handleDualStorage(DirectoryNode dir) throws IOException {
+           // when there's a dual storage entry, use it, as the outer document can't be read quite probably ...
+           String dualName = "PP97_DUALSTORAGE";
+           if (!dir.hasEntry(dualName)) return dir;
+           dir = (DirectoryNode)dir.getEntry(dualName);
+           return dir;
+       }
+       
+       /**
+        * Constructs a new, empty, Powerpoint document.
+        */
+       public static final HSLFSlideShowImpl create() {
+               InputStream is = HSLFSlideShowImpl.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt");
+               if (is == null) {
+                       throw new RuntimeException("Missing resource 'empty.ppt'");
+               }
+               try {
+                       return new HSLFSlideShowImpl(is);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Extracts the main PowerPoint document stream from the
+        *  POI file, ready to be passed
+        *
+        * @throws IOException
+        */
+       private void readPowerPointStream() throws IOException
+       {
+               // Get the main document stream
+               DocumentEntry docProps =
+                       (DocumentEntry)directory.getEntry("PowerPoint Document");
+
+               // Grab the document stream
+               _docstream = new byte[docProps.getSize()];
+               directory.createDocumentInputStream("PowerPoint Document").read(_docstream);
+       }
+
+       /**
+        * Builds the list of records, based on the contents
+        *  of the PowerPoint stream
+        */
+       private void buildRecords()
+       {
+               // The format of records in a powerpoint file are:
+               //   <little endian 2 byte "info">
+               //   <little endian 2 byte "type">
+               //   <little endian 4 byte "length">
+               // If it has a zero length, following it will be another record
+               //              <xx xx yy yy 00 00 00 00> <xx xx yy yy zz zz zz zz>
+               // If it has a length, depending on its type it may have children or data
+               // If it has children, these will follow straight away
+               //              <xx xx yy yy zz zz zz zz <xx xx yy yy zz zz zz zz>>
+               // If it has data, this will come straigh after, and run for the length
+               //      <xx xx yy yy zz zz zz zz dd dd dd dd dd dd dd>
+               // All lengths given exclude the 8 byte record header
+               // (Data records are known as Atoms)
+
+               // Document should start with:
+               //   0F 00 E8 03 ## ## ## ##
+           //     (type 1000 = document, info 00 0f is normal, rest is document length)
+               //   01 00 E9 03 28 00 00 00
+               //     (type 1001 = document atom, info 00 01 normal, 28 bytes long)
+               //   80 16 00 00 E0 10 00 00 xx xx xx xx xx xx xx xx
+               //   05 00 00 00 0A 00 00 00 xx xx xx
+               //     (the contents of the document atom, not sure what it means yet)
+               //   (records then follow)
+
+               // When parsing a document, look to see if you know about that type
+               //  of the current record. If you know it's a type that has children,
+               //  process the record's data area looking for more records
+               // If you know about the type and it doesn't have children, either do
+               //  something with the data (eg TextRun) or skip over it
+               // If you don't know about the type, play safe and skip over it (using
+               //  its length to know where the next record will start)
+               //
+
+        _records = read(_docstream, (int)currentUser.getCurrentEditOffset());
+       }
+
+       private Record[] read(byte[] docstream, int usrOffset){
+        //sort found records by offset.
+        //(it is not necessary but SlideShow.findMostRecentCoreRecords() expects them sorted)
+           NavigableMap<Integer,Record> records = new TreeMap<Integer,Record>(); // offset -> record
+        Map<Integer,Integer> persistIds = new HashMap<Integer,Integer>(); // offset -> persistId
+        initRecordOffsets(docstream, usrOffset, records, persistIds);
+        HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(docstream, records);
+        
+        for (Map.Entry<Integer,Record> entry : records.entrySet()) {
+            Integer offset = entry.getKey();
+            Record record = entry.getValue();
+            Integer persistId = persistIds.get(offset);
+            if (record == null) {
+                // all plain records have been already added,
+                // only new records need to be decrypted (tbd #35897)
+                decryptData.decryptRecord(docstream, persistId, offset);
+                record = Record.buildRecordAtOffset(docstream, offset);
+                entry.setValue(record);
+            }
+            
+            if (record instanceof PersistRecord) {
+                ((PersistRecord)record).setPersistId(persistId);
+            }            
+        }
+        
+        return records.values().toArray(new Record[records.size()]);
+    }
+
+    private void initRecordOffsets(byte[] docstream, int usrOffset, NavigableMap<Integer,Record> recordMap, Map<Integer,Integer> offset2id) {
+        while (usrOffset != 0){
+            UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset);
+            recordMap.put(usrOffset, usr);
+            
+            int psrOffset = usr.getPersistPointersOffset();
+            PersistPtrHolder ptr = (PersistPtrHolder)Record.buildRecordAtOffset(docstream, psrOffset);
+            recordMap.put(psrOffset, ptr);
+            
+            for(Map.Entry<Integer,Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
+                Integer offset = entry.getValue();
+                Integer id = entry.getKey();
+                recordMap.put(offset, null); // reserve a slot for the record
+                offset2id.put(offset, id);
+            }
+            
+            usrOffset = usr.getLastUserEditAtomOffset();
+
+            // check for corrupted user edit atom and try to repair it
+            // if the next user edit atom offset is already known, we would go into an endless loop
+            if (usrOffset > 0 && recordMap.containsKey(usrOffset)) {
+                // a user edit atom is usually located 36 byte before the smallest known record offset 
+                usrOffset = recordMap.firstKey()-36;
+                // check that we really are located on a user edit atom
+                int ver_inst = LittleEndian.getUShort(docstream, usrOffset);
+                int type = LittleEndian.getUShort(docstream, usrOffset+2);
+                int len = LittleEndian.getInt(docstream, usrOffset+4);
+                if (ver_inst == 0 && type == 4085 && (len == 0x1C || len == 0x20)) {
+                    logger.log(POILogger.WARN, "Repairing invalid user edit atom");
+                    usr.setLastUserEditAtomOffset(usrOffset);
+                } else {
+                    throw new CorruptPowerPointFileException("Powerpoint document contains invalid user edit atom");
+                }
+            }
+        }       
+    }
+
+    public DocumentEncryptionAtom getDocumentEncryptionAtom() {
+        for (Record r : _records) {
+            if (r instanceof DocumentEncryptionAtom) {
+                return (DocumentEncryptionAtom)r;
+            }
+        }
+        return null;
+    }
+    
+    
+       /**
+        * Find the "Current User" stream, and load it
+        */
+       private void readCurrentUserStream() {
+               try {
+                       currentUser = new CurrentUserAtom(directory);
+               } catch(IOException ie) {
+                       logger.log(POILogger.ERROR, "Error finding Current User Atom:\n" + ie);
+                       currentUser = new CurrentUserAtom();
+               }
+       }
+
+       /**
+        * Find any other streams from the filesystem, and load them
+        */
+       private void readOtherStreams() {
+               // Currently, there aren't any
+       }
+       
+       /**
+        * Find and read in pictures contained in this presentation.
+        * This is lazily called as and when we want to touch pictures.
+        */
+    @SuppressWarnings("unused")
+       private void readPictures() throws IOException {
+        _pictures = new ArrayList<HSLFPictureData>();
+
+        // if the presentation doesn't contain pictures - will use a null set instead
+        if (!directory.hasEntry("Pictures")) return;
+
+        HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
+        
+               DocumentEntry entry = (DocumentEntry)directory.getEntry("Pictures");
+               byte[] pictstream = new byte[entry.getSize()];
+               DocumentInputStream is = directory.createDocumentInputStream(entry);
+               is.read(pictstream);
+               is.close();
+
+               
+        int pos = 0;
+               // An empty picture record (length 0) will take up 8 bytes
+        while (pos <= (pictstream.length-8)) {
+            int offset = pos;
+
+            decryptData.decryptPicture(pictstream, offset);
+            
+            // Image signature
+            int signature = LittleEndian.getUShort(pictstream, pos);
+            pos += LittleEndian.SHORT_SIZE;
+            // Image type + 0xF018
+            int type = LittleEndian.getUShort(pictstream, pos);
+            pos += LittleEndian.SHORT_SIZE;
+            // Image size (excluding the 8 byte header)
+            int imgsize = LittleEndian.getInt(pictstream, pos);
+            pos += LittleEndian.INT_SIZE;
+
+            // When parsing the BStoreDelay stream, [MS-ODRAW] says that we
+            //  should terminate if the type isn't 0xf007 or 0xf018->0xf117
+            if (!((type == 0xf007) || (type >= 0xf018 && type <= 0xf117)))
+                break;
+
+                       // The image size must be 0 or greater
+                       // (0 is allowed, but odd, since we do wind on by the header each
+                       //  time, so we won't get stuck)
+                       if(imgsize < 0) {
+                               throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
+                       }
+
+                       // If they type (including the bonus 0xF018) is 0, skip it
+                       if(type == 0) {
+                               logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
+                               logger.log(POILogger.ERROR, "" + pos);
+                       } else {
+                               // Build the PictureData object from the data
+                               try {
+                                       HSLFPictureData pict = HSLFPictureData.create(type - 0xF018);
+
+                    // Copy the data, ready to pass to PictureData
+                    byte[] imgdata = new byte[imgsize];
+                    System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
+                    pict.setRawData(imgdata);
+
+                    pict.setOffset(offset);
+                                       _pictures.add(pict);
+                               } catch(IllegalArgumentException e) {
+                                       logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
+                               }
+                       }
+
+            pos += imgsize;
+        }
+       }
+    
+    /**
+     * remove duplicated UserEditAtoms and merge PersistPtrHolder, i.e.
+     * remove document edit history
+     */
+    public void normalizeRecords() {
+        try {
+            updateAndWriteDependantRecords(null, null);
+        } catch (IOException e) {
+            throw new CorruptPowerPointFileException(e);
+        }
+        _records = HSLFSlideShowEncrypted.normalizeRecords(_records);
+    }
+   
+    
+       /**
+     * This is a helper functions, which is needed for adding new position dependent records
+     * or finally write the slideshow to a file.
+        *
+        * @param os the stream to write to, if null only the references are updated
+        * @param interestingRecords a map of interesting records (PersistPtrHolder and UserEditAtom)
+        *        referenced by their RecordType. Only the very last of each type will be saved to the map.
+        *        May be null, if not needed. 
+        * @throws IOException
+        */
+       public void updateAndWriteDependantRecords(OutputStream os, Map<RecordTypes.Type,PositionDependentRecord> interestingRecords)
+       throws IOException {
+        // For position dependent records, hold where they were and now are
+        // As we go along, update, and hand over, to any Position Dependent
+        //  records we happen across
+        Hashtable<Integer,Integer> oldToNewPositions = new Hashtable<Integer,Integer>();
+
+        // First pass - figure out where all the position dependent
+        //   records are going to end up, in the new scheme
+        // (Annoyingly, some powerpoint files have PersistPtrHolders
+        //  that reference slides after the PersistPtrHolder)
+        UserEditAtom usr = null;
+        PersistPtrHolder ptr = null;
+        CountingOS cos = new CountingOS();
+        for (Record record : _records) {
+            // all top level records are position dependent
+            assert(record instanceof PositionDependentRecord);
+            PositionDependentRecord pdr = (PositionDependentRecord)record;
+            int oldPos = pdr.getLastOnDiskOffset();
+            int newPos = cos.size();
+            pdr.setLastOnDiskOffset(newPos);
+            if (oldPos != UNSET_OFFSET) {
+                // new records don't need a mapping, as they aren't in a relation yet
+                oldToNewPositions.put(oldPos,newPos);
+            }
+
+            // Grab interesting records as they come past
+            // this will only save the very last record of each type
+            RecordTypes.Type saveme = null;
+            int recordType = (int)record.getRecordType();
+            if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
+                saveme = RecordTypes.PersistPtrIncrementalBlock;
+                ptr = (PersistPtrHolder)pdr;
+            } else if (recordType == RecordTypes.UserEditAtom.typeID) {
+                saveme = RecordTypes.UserEditAtom;
+                usr = (UserEditAtom)pdr;
+            }
+            if (interestingRecords != null && saveme != null) {
+                interestingRecords.put(saveme,pdr);
+            }
+            
+            // Dummy write out, so the position winds on properly
+            record.writeOut(cos);
+        }
+        
+        assert(usr != null && ptr != null);
+        
+        Map<Integer,Integer> persistIds = new HashMap<Integer,Integer>();
+        for (Map.Entry<Integer,Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
+            persistIds.put(oldToNewPositions.get(entry.getValue()), entry.getKey());
+        }
+        
+        HSLFSlideShowEncrypted encData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
+           
+           for (Record record : _records) {
+            assert(record instanceof PositionDependentRecord);
+            // We've already figured out their new location, and
+            // told them that
+            // Tell them of the positions of the other records though
+            PositionDependentRecord pdr = (PositionDependentRecord)record;
+            Integer persistId = persistIds.get(pdr.getLastOnDiskOffset());
+            if (persistId == null) persistId = 0;
+            
+            // For now, we're only handling PositionDependentRecord's that
+            // happen at the top level.
+            // In future, we'll need the handle them everywhere, but that's
+            // a bit trickier
+            pdr.updateOtherRecordReferences(oldToNewPositions);
+            
+            // Whatever happens, write out that record tree
+            if (os != null) {
+                record.writeOut(encData.encryptRecord(os, persistId, record));
+            }
+        }
+
+        // Update and write out the Current User atom
+        int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset();
+        Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos);
+        if(usr == null || newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) {
+            throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos);
+        }
+        currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset());
+       }
+
+    /**
+     * Writes out the slideshow file the is represented by an instance
+     *  of this class.
+     * It will write out the common OLE2 streams. If you require all
+     *  streams to be written out, pass in preserveNodes
+     * @param out The OutputStream to write to.
+     * @throws IOException If there is an unexpected IOException from
+     *           the passed in OutputStream
+     */
+    public void write(OutputStream out) throws IOException {
+        // Write out, but only the common streams
+        write(out,false);
+    }
+    /**
+     * Writes out the slideshow file the is represented by an instance
+     *  of this class.
+     * If you require all streams to be written out (eg Marcos, embeded
+     *  documents), then set preserveNodes to true
+     * @param out The OutputStream to write to.
+     * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones?
+     * @throws IOException If there is an unexpected IOException from
+     *           the passed in OutputStream
+     */
+    public void write(OutputStream out, boolean preserveNodes) throws IOException {
+        // read properties and pictures, with old encryption settings where appropriate 
+        if(_pictures == null) {
+           readPictures();
+        }
+        getDocumentSummaryInformation();
+
+        // set new encryption settings
+        HSLFSlideShowEncrypted encryptedSS = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
+        _records = encryptedSS.updateEncryptionRecord(_records);
+
+        // Get a new Filesystem to write into
+        POIFSFileSystem outFS = new POIFSFileSystem();
+
+        // The list of entries we've written out
+        List<String> writtenEntries = new ArrayList<String>(1);
+
+        // Write out the Property Streams
+        writeProperties(outFS, writtenEntries);
+        
+        BufAccessBAOS baos = new BufAccessBAOS();
+
+        // For position dependent records, hold where they were and now are
+        // As we go along, update, and hand over, to any Position Dependent
+        // records we happen across
+        updateAndWriteDependantRecords(baos, null);
+
+        // Update our cached copy of the bytes that make up the PPT stream
+        _docstream = new byte[baos.size()];
+        System.arraycopy(baos.getBuf(), 0, _docstream, 0, baos.size());
+
+        // Write the PPT stream into the POIFS layer
+        ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
+        outFS.createDocument(bais,"PowerPoint Document");
+        writtenEntries.add("PowerPoint Document");
+        
+        currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null);
+        currentUser.writeToFS(outFS);
+        writtenEntries.add("Current User");
+
+
+        if (_pictures.size() > 0) {
+            BufAccessBAOS pict = new BufAccessBAOS();
+            for (HSLFPictureData p : _pictures) {
+                int offset = pict.size();
+                p.write(pict);
+                encryptedSS.encryptPicture(pict.getBuf(), offset);
+            }
+            outFS.createDocument(
+                new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures"
+            );
+            writtenEntries.add("Pictures");
+        }
+
+        // If requested, write out any other streams we spot
+        if(preserveNodes) {
+            EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries);
+        }
+
+        // Send the POIFSFileSystem object out to the underlying stream
+        outFS.writeFilesystem(out);
+    }
+
+    /** 
+     * For a given named property entry, either return it or null if
+     *  if it wasn't found
+     *  
+     *  @param setName The property to read
+     *  @return The value of the given property or null if it wasn't found.
+     */
+    protected PropertySet getPropertySet(String setName) {
+        DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
+        return (dea == null)
+            ? super.getPropertySet(setName)
+            : super.getPropertySet(setName, dea.getEncryptionInfo());
+    }
+
+    /**
+     * Writes out the standard Documment Information Properties (HPSF)
+     * @param outFS the POIFSFileSystem to write the properties into
+     * @param writtenEntries a list of POIFS entries to add the property names too
+     * 
+     * @throws IOException if an error when writing to the 
+     *      {@link POIFSFileSystem} occurs
+     */
+    protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
+        super.writeProperties(outFS, writtenEntries);
+        DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
+        if (dea != null) {
+            CryptoAPIEncryptor enc = (CryptoAPIEncryptor)dea.getEncryptionInfo().getEncryptor();
+            try {
+                enc.getDataStream(outFS.getRoot()); // ignore OutputStream
+            } catch (IOException e) {
+                throw e;
+            } catch (GeneralSecurityException e) {
+                throw new IOException(e);
+            }
+        }
+    }
+    
+    /* ******************* adding methods follow ********************* */
+
+       /**
+        * Adds a new root level record, at the end, but before the last
+        *  PersistPtrIncrementalBlock.
+        */
+       public synchronized int appendRootLevelRecord(Record newRecord) {
+               int addedAt = -1;
+               Record[] r = new Record[_records.length+1];
+               boolean added = false;
+               for(int i=(_records.length-1); i>=0; i--) {
+                       if(added) {
+                               // Just copy over
+                               r[i] = _records[i];
+                       } else {
+                               r[(i+1)] = _records[i];
+                               if(_records[i] instanceof PersistPtrHolder) {
+                                       r[i] = newRecord;
+                                       added = true;
+                                       addedAt = i;
+                               }
+                       }
+               }
+               _records = r;
+               return addedAt;
+       }
+
+       /**
+        * Add a new picture to this presentation.
+     *
+     * @return offset of this picture in the Pictures stream
+        */
+       public int addPicture(HSLFPictureData img) {
+          // Process any existing pictures if we haven't yet
+          if(_pictures == null) {
+         try {
+            readPictures();
+         } catch(IOException e) {
+            throw new CorruptPowerPointFileException(e.getMessage());
+         }
+          }
+          
+          // Add the new picture in
+      int offset = 0;
+          if(_pictures.size() > 0) {
+             HSLFPictureData prev = _pictures.get(_pictures.size() - 1);
+             offset = prev.getOffset() + prev.getRawData().length + 8;
+          }
+          img.setOffset(offset);
+          _pictures.add(img);
+          return offset;
+   }
+
+       /* ******************* fetching methods follow ********************* */
+
+
+       /**
+        * Returns an array of all the records found in the slideshow
+        */
+       public Record[] getRecords() { return _records; }
+
+       /**
+        * Returns an array of the bytes of the file. Only correct after a
+        *  call to open or write - at all other times might be wrong!
+        */
+       public byte[] getUnderlyingBytes() { return _docstream; }
+
+       /**
+        * Fetch the Current User Atom of the document
+        */
+       public CurrentUserAtom getCurrentUserAtom() { return currentUser; }
+
+       /**
+        *  Return array of pictures contained in this presentation
+        *
+        *  @return array with the read pictures or <code>null</code> if the
+        *  presentation doesn't contain pictures.
+        */
+       public HSLFPictureData[] getPictures() {
+          if(_pictures == null) {
+             try {
+                readPictures();
+             } catch(IOException e) {
+                throw new CorruptPowerPointFileException(e.getMessage());
+             }
+          }
+          
+               return _pictures.toArray(new HSLFPictureData[_pictures.size()]);
+       }
+
+    /**
+     * Gets embedded object data from the slide show.
+     *
+     * @return the embedded objects.
+     */
+    public HSLFObjectData[] getEmbeddedObjects() {
+        if (_objects == null) {
+            List<HSLFObjectData> objects = new ArrayList<HSLFObjectData>();
+            for (Record r : _records) {
+                if (r instanceof ExOleObjStg) {
+                    objects.add(new HSLFObjectData((ExOleObjStg)r));
+                }
+            }
+            _objects = objects.toArray(new HSLFObjectData[objects.size()]);
+        }
+        return _objects;
+    }
+    
+    
+    private static class BufAccessBAOS extends ByteArrayOutputStream {
+        public byte[] getBuf() {
+            return buf;
+        }
+    }
+    
+    private static class CountingOS extends OutputStream {
+        int count = 0;
+        public void write(int b) throws IOException {
+            count++;
+        }
+
+        public void write(byte[] b) throws IOException {
+            count += b.length;
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            count += len;
+        }
+        
+        public int size() {
+            return count;
+        }
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java
new file mode 100644 (file)
index 0000000..b7895a6
--- /dev/null
@@ -0,0 +1,92 @@
+/* ====================================================================
+   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.usermodel;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.sl.usermodel.*;
+
+/**
+ * Represents a TextFrame shape in PowerPoint.
+ * <p>
+ * Contains the text in a text frame as well as the properties and methods
+ * that control alignment and anchoring of the text.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class HSLFTextBox extends HSLFTextShape {
+
+    /**
+     * Create a TextBox object and initialize it from the supplied Record container.
+     *
+     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent    the parent of the shape
+     */
+   protected HSLFTextBox(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     * @param parent    the parent of this Shape. For example, if this text box is a cell
+     * in a table then the parent is Table.
+     */
+    public HSLFTextBox(ShapeContainer<HSLFShape> parent){
+        super(parent);
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     */
+    public HSLFTextBox(){
+        this(null);
+    }
+
+    /**
+     * Create a new TextBox and initialize its internal structures
+     *
+     * @return the created <code>EscherContainerRecord</code> which holds shape data
+     */
+    protected EscherContainerRecord createSpContainer(boolean isChild){
+        _escherContainer = super.createSpContainer(isChild);
+
+        setShapeType(ShapeType.TEXT_BOX);
+
+        //set default properties for a TextBox
+        setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004);
+        setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
+        setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100000);
+        setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001);
+        setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
+        setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
+
+        // init paragraphs
+        getTextParagraphs();
+
+        return _escherContainer;
+    }
+
+    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
+        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
new file mode 100644 (file)
index 0000000..0b90f15
--- /dev/null
@@ -0,0 +1,1089 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hslf.usermodel;\r
+\r
+import java.awt.Color;\r
+import java.util.*;\r
+\r
+import org.apache.poi.hslf.model.textproperties.*;\r
+import org.apache.poi.hslf.record.*;\r
+import org.apache.poi.sl.usermodel.TextParagraph;\r
+import org.apache.poi.util.*;\r
+\r
+/**\r
+ * This class represents a run of text in a powerpoint document. That\r
+ *  run could be text on a sheet, or text in a note.\r
+ *  It is only a very basic class for now\r
+ *\r
+ * @author Nick Burch\r
+ */\r
+\r
+public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {\r
+    protected static POILogger logger = POILogFactory.getLogger(HSLFTextParagraph.class);\r
+    \r
+    /**\r
+     * How to align the text\r
+     */\r
+    /* package */ static final int AlignLeft = 0;\r
+    /* package */ static final int AlignCenter = 1;\r
+    /* package */ static final int AlignRight = 2;\r
+    /* package */ static final int AlignJustify = 3;\r
+    \r
+    \r
+    // Note: These fields are protected to help with unit testing\r
+       //   Other classes shouldn't really go playing with them!\r
+       private final TextHeaderAtom _headerAtom;\r
+       private final TextBytesAtom  _byteAtom;\r
+       private final TextCharsAtom  _charAtom;\r
+       private StyleTextPropAtom _styleAtom;\r
+       private TextPropCollection _paragraphStyle = new TextPropCollection(1);\r
+       \r
+    protected TextRulerAtom _ruler;\r
+       protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();\r
+       protected HSLFTextShape _parentShape;\r
+    private HSLFSheet _sheet;\r
+    private int shapeId;\r
+\r
+    /**\r
+     * all text run records that follow TextHeaderAtom.\r
+     * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)\r
+     */\r
+    private Record[] _records;\r
+       // private StyleTextPropAtom styleTextPropAtom;\r
+       private StyleTextProp9Atom styleTextProp9Atom;\r
+\r
+       /**\r
+    * Constructs a Text Run from a Unicode text block.\r
+    * Either a {@link TextCharsAtom} or a {@link TextBytesAtom} needs to be provided. \r
+    *\r
+    * @param tha the TextHeaderAtom that defines what's what\r
+    * @param tba the TextBytesAtom containing the text or null if {@link TextCharsAtom} is provided\r
+    * @param tca the TextCharsAtom containing the text or null if {@link TextBytesAtom} is provided\r
+    * @param sta the StyleTextPropAtom which defines the character stylings\r
+        */\r
+       /* package */ HSLFTextParagraph(\r
+        TextHeaderAtom tha,\r
+        TextBytesAtom tba,\r
+        TextCharsAtom tca,\r
+        StyleTextPropAtom sta\r
+    ) {\r
+               _headerAtom = tha;\r
+               _styleAtom = sta;\r
+        _byteAtom = tba;\r
+        _charAtom = tca;\r
+       }\r
+\r
+    /* package */ HSLFTextParagraph(HSLFTextParagraph other) {\r
+            _headerAtom = other._headerAtom;\r
+            _styleAtom = other._styleAtom;\r
+            _byteAtom = other._byteAtom;\r
+            _charAtom = other._charAtom;\r
+            _paragraphStyle = other._paragraphStyle;\r
+            _parentShape = other._parentShape;\r
+            _sheet = other._sheet;\r
+            _ruler = other._ruler; // ????\r
+            shapeId = other.shapeId;\r
+            _records = other._records;\r
+        }\r
+\r
+       public void addTextRun(HSLFTextRun run) {\r
+           _runs.add(run);\r
+       }\r
+       \r
+       /**\r
+        * Fetch the rich text runs (runs of text with the same styling) that\r
+        *  are contained within this block of text\r
+        */\r
+       public List<HSLFTextRun> getTextRuns() {\r
+               return  _runs;\r
+       }\r
+\r
+       public TextPropCollection getParagraphStyle() {\r
+           return _paragraphStyle;\r
+       }\r
+       \r
+       public void setParagraphStyle(TextPropCollection paragraphStyle) {\r
+           _paragraphStyle = paragraphStyle;\r
+       }\r
+       \r
+       /**\r
+     * Supply the Sheet we belong to, which might have an assigned SlideShow\r
+     * Also passes it on to our child RichTextRuns\r
+     */\r
+       public void supplySheet(HSLFSheet sheet){\r
+        this._sheet = sheet;\r
+\r
+        if (_runs == null) return;\r
+        for(HSLFTextRun rt : _runs) {\r
+            rt.updateSheet();\r
+        }\r
+       }\r
+\r
+    public HSLFSheet getSheet(){\r
+        return this._sheet;\r
+    }\r
+\r
+    /**\r
+     * @return  Shape ID\r
+     */\r
+    protected int getShapeId(){\r
+        return shapeId;\r
+    }\r
+\r
+    /**\r
+     *  @param id Shape ID\r
+     */\r
+    protected void setShapeId(int id){\r
+        shapeId = id;\r
+    }\r
+\r
+    /**\r
+     * @return  0-based index of the text run in the SLWT container\r
+     */\r
+    protected int getIndex(){\r
+        return (_headerAtom != null) ? _headerAtom.getIndex() : -1;\r
+    }\r
+\r
+    /**\r
+     * Sets the index of the paragraph in the SLWT container \r
+     *\r
+     * @param index\r
+     */\r
+    protected void setIndex(int index) {\r
+        if (_headerAtom != null) _headerAtom.setIndex(index);\r
+    }\r
+    \r
+    /**\r
+    * Returns the type of the text, from the TextHeaderAtom.\r
+    * Possible values can be seen from TextHeaderAtom\r
+    * @see org.apache.poi.hslf.record.TextHeaderAtom\r
+    */\r
+    public int getRunType() {\r
+        return (_headerAtom != null) ? _headerAtom.getTextType() : -1;\r
+    }\r
+    \r
+    /**\r
+     * Is this Text Run one from a {@link PPDrawing}, or is it\r
+     *  one from the {@link SlideListWithText}?\r
+     */\r
+    public boolean isDrawingBased() {\r
+        return (getIndex() == -1);\r
+    }\r
+\r
+    public TextRulerAtom getTextRuler(){\r
+        return _ruler;\r
+\r
+    }\r
+\r
+    public TextRulerAtom createTextRuler(){\r
+        _ruler = getTextRuler();\r
+        if (_ruler == null) {\r
+            _ruler = TextRulerAtom.getParagraphInstance();\r
+            _headerAtom.getParentRecord().appendChildRecord(_ruler);\r
+        }\r
+        return _ruler;\r
+    }\r
+\r
+    /**\r
+     * Returns records that make up this text run\r
+     *\r
+     * @return text run records\r
+     */\r
+    public Record[] getRecords(){\r
+        return _records;\r
+    }\r
+    \r
+    /** Numbered List info */\r
+       public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {\r
+               this.styleTextProp9Atom = styleTextProp9Atom;\r
+       }\r
+       \r
+    /** Numbered List info */\r
+       public StyleTextProp9Atom getStyleTextProp9Atom() {\r
+               return this.styleTextProp9Atom;\r
+       }\r
+\r
+    /** Characters covered */\r
+       public StyleTextPropAtom getStyleTextPropAtom() {\r
+               return this._styleAtom;         \r
+       }\r
+\r
+       /**\r
+     * Fetch the value of the given Paragraph related TextProp.\r
+     * Returns -1 if that TextProp isn't present.\r
+     * If the TextProp isn't present, the value from the appropriate\r
+     *  Master Sheet will apply.\r
+     */\r
+    private int getParaTextPropVal(String propName) {\r
+        TextProp prop = null;\r
+        boolean hardAttribute = false;\r
+        if (_paragraphStyle != null){\r
+            prop = _paragraphStyle.findByName(propName);\r
+\r
+            BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);\r
+            hardAttribute = maskProp != null && maskProp.getValue() == 0;\r
+        }\r
+        if (prop == null && !hardAttribute){\r
+            HSLFSheet sheet = _parentShape.getSheet();\r
+            int txtype = _parentShape.getRunType();\r
+            HSLFMasterSheet master = sheet.getMasterSheet();\r
+            if (master != null)\r
+                prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);\r
+        }\r
+\r
+        return prop == null ? -1 : prop.getValue();\r
+    }\r
+\r
+    /**\r
+     * Sets the value of the given Character TextProp, add if required\r
+     * @param propName The name of the Character TextProp\r
+     * @param val The value to set for the TextProp\r
+     */\r
+    public void setParaTextPropVal(String propName, int val) {\r
+        // Ensure we have the StyleTextProp atom we're going to need\r
+        if(_paragraphStyle == null) {\r
+            ensureStyleAtomPresent();\r
+            // paragraphStyle will now be defined\r
+        }\r
+\r
+        assert(_paragraphStyle!=null);\r
+        TextProp tp = fetchOrAddTextProp(_paragraphStyle, propName);\r
+        tp.setValue(val);\r
+    }\r
+       \r
+    /**\r
+     * Ensure a StyleTextPropAtom is present for this run,\r
+     *  by adding if required. Normally for internal TextRun use.\r
+     */\r
+    protected StyleTextPropAtom ensureStyleAtomPresent() {\r
+        if (_styleAtom != null) {\r
+            return _styleAtom;\r
+        }\r
+        \r
+        _styleAtom = ensureStyleAtomPresent(_headerAtom, _byteAtom, _charAtom);\r
+        _paragraphStyle = _styleAtom.getParagraphStyles().get(0);\r
+        \r
+        return _styleAtom;\r
+    }\r
+\r
+    protected static StyleTextPropAtom ensureStyleAtomPresent(TextHeaderAtom header, TextBytesAtom tbytes, TextCharsAtom tchars) {\r
+        RecordContainer wrapper = header.getParentRecord();\r
+        StyleTextPropAtom styleAtom = null;\r
+        \r
+        boolean afterHeader = false;\r
+        for (Record record : wrapper.getChildRecords()) {\r
+            if (afterHeader && record.getRecordType() == RecordTypes.TextHeaderAtom.typeID) break;\r
+            afterHeader |= (header == record);\r
+            if (afterHeader && record.getRecordType() == RecordTypes.StyleTextPropAtom.typeID) {\r
+                styleAtom = (StyleTextPropAtom)record;\r
+                break;\r
+            }\r
+        }\r
+        \r
+        if (styleAtom != null) return styleAtom;\r
+        \r
+        String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();\r
+        \r
+        // Create a new one at the right size\r
+        styleAtom = new StyleTextPropAtom(rawText.length()+1);\r
+\r
+        // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom\r
+        wrapper.addChildAfter(styleAtom, (tbytes == null ? tchars : tbytes));\r
+\r
+        return styleAtom;\r
+    }\r
+\r
+    @Override\r
+    public Iterator<HSLFTextRun> iterator() {\r
+        return _runs.iterator();\r
+    }\r
+\r
+    @Override\r
+    public double getLeftMargin() {\r
+        int val = getParaTextPropVal("text.offset");\r
+        return val*HSLFShape.POINT_DPI/((double)HSLFShape.MASTER_DPI);\r
+    }\r
+\r
+    @Override\r
+    public void setLeftMargin(double leftMargin) {\r
+        int val = (int)(leftMargin*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);\r
+        setParaTextPropVal("text.offset", val);\r
+    }\r
+    \r
+    @Override\r
+    public double getRightMargin() {\r
+        // TODO: find out, how to determine this value\r
+        return 0;\r
+    }\r
+\r
+    @Override\r
+    public void setRightMargin(double rightMargin) {\r
+        // TODO: find out, how to set this value\r
+    }\r
+    \r
+    @Override\r
+    public double getIndent() {\r
+        int val = getParaTextPropVal("bullet.offset");\r
+        return val*HSLFShape.POINT_DPI/((double)HSLFShape.MASTER_DPI);\r
+    }\r
+\r
+    @Override\r
+    public void setIndent(double intent) {\r
+        int val = (int)(intent*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);\r
+        setParaTextPropVal("bullet.offset", val);\r
+    }\r
+\r
+    @Override\r
+    public String getDefaultFontFamily() {\r
+        return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily());\r
+    }\r
+\r
+    @Override\r
+    public double getDefaultFontSize() {\r
+        return (_runs.isEmpty() ? 12 : _runs.get(0).getFontSize());\r
+    }\r
+\r
+    /**\r
+     * Sets the type of horizontal alignment for the paragraph.\r
+     *\r
+     * @param align - the type of alignment\r
+     */\r
+    public void setAlignment(org.apache.poi.sl.usermodel.TextParagraph.TextAlign align) {\r
+        int alignInt;\r
+        switch (align) {\r
+        default:\r
+        case LEFT: alignInt = AlignmentTextProp.LEFT; break;\r
+        case CENTER: alignInt = AlignmentTextProp.CENTER; break;\r
+        case RIGHT: alignInt = AlignmentTextProp.RIGHT; break;\r
+        case DIST: // TODO: DIST doesn't not exist within hslf, check mapping\r
+        case JUSTIFY: alignInt = AlignmentTextProp.JUSTIFY; break;\r
+        case JUSTIFY_LOW: alignInt = AlignmentTextProp.JUSTIFYLOW; break;\r
+        case THAI_DIST: alignInt = AlignmentTextProp.THAIDISTRIBUTED; break;\r
+        }\r
+        setParaTextPropVal("alignment", alignInt);\r
+    }\r
+    \r
+    @Override\r
+    public org.apache.poi.sl.usermodel.TextParagraph.TextAlign getTextAlign() {\r
+        switch (getParaTextPropVal("alignment")) {\r
+            default:\r
+            case AlignmentTextProp.LEFT: return TextAlign.LEFT;\r
+            case AlignmentTextProp.CENTER: return TextAlign.CENTER;\r
+            case AlignmentTextProp.RIGHT: return TextAlign.RIGHT;\r
+            case AlignmentTextProp.JUSTIFY: return TextAlign.JUSTIFY;\r
+            case AlignmentTextProp.JUSTIFYLOW: return TextAlign.JUSTIFY_LOW;\r
+            case AlignmentTextProp.THAIDISTRIBUTED: return TextAlign.THAI_DIST;\r
+        }\r
+    }\r
+\r
+    public org.apache.poi.sl.usermodel.TextParagraph.FontAlign getFontAlign() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+    public org.apache.poi.sl.usermodel.TextParagraph.BulletStyle getBulletStyle() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public HSLFTextShape getParentShape() {\r
+        return _parentShape;\r
+    }\r
+\r
+    public void setParentShape(HSLFTextShape parentShape) {\r
+        _parentShape = parentShape;\r
+    }\r
+\r
+       \r
+    /**\r
+    *\r
+    * @return indentation level\r
+    */\r
+   public int getIndentLevel() {\r
+       return _paragraphStyle == null ? 0 : _paragraphStyle.getReservedField();\r
+   }\r
+\r
+   /**\r
+    * Sets indentation level\r
+    *\r
+    * @param level indentation level. Must be in the range [0, 4]\r
+    */\r
+   public void setIndentLevel(int level) {\r
+       if( _paragraphStyle != null ) _paragraphStyle.setReservedField((short)level);\r
+   }\r
+\r
+   /**\r
+    * Sets whether this rich text run has bullets\r
+    */\r
+   public void setBullet(boolean flag) {\r
+       setFlag(ParagraphFlagsTextProp.BULLET_IDX, flag);\r
+   }\r
+\r
+   /**\r
+    * Returns whether this rich text run has bullets\r
+    */\r
+   public boolean isBullet() {\r
+       return getFlag(ParagraphFlagsTextProp.BULLET_IDX);\r
+   }\r
+\r
+   /**\r
+    * Returns whether this rich text run has bullets\r
+    */\r
+   public boolean isBulletHard() {\r
+       return getFlag(ParagraphFlagsTextProp.BULLET_IDX);\r
+   }\r
+\r
+   /**\r
+    * Sets the bullet character\r
+    */\r
+   public void setBulletChar(char c) {\r
+       setParaTextPropVal("bullet.char", c);\r
+   }\r
+\r
+   /**\r
+    * Returns the bullet character\r
+    */\r
+   public char getBulletChar() {\r
+       return (char)getParaTextPropVal("bullet.char");\r
+   }\r
+\r
+   /**\r
+    * Sets the bullet size\r
+    */\r
+   public void setBulletSize(int size) {\r
+       setParaTextPropVal("bullet.size", size);\r
+   }\r
+\r
+   /**\r
+    * Returns the bullet size\r
+    */\r
+   public int getBulletSize() {\r
+       return getParaTextPropVal("bullet.size");\r
+   }\r
+\r
+   /**\r
+    * Sets the bullet color\r
+    */\r
+   public void setBulletColor(Color color) {\r
+       int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();\r
+       setParaTextPropVal("bullet.color", rgb);\r
+   }\r
+\r
+   /**\r
+    * Returns the bullet color\r
+    */\r
+   public Color getBulletColor() {\r
+       int rgb = getParaTextPropVal("bullet.color");\r
+       if (rgb == -1) {\r
+           // if bullet color is undefined, return color of first run\r
+           if (_runs.isEmpty()) return null;\r
+           return _runs.get(0).getFontColor();\r
+       }\r
+\r
+       int cidx = rgb >> 24;\r
+       if (rgb % 0x1000000 == 0){\r
+           if (_sheet == null) return null;\r
+           ColorSchemeAtom ca = _sheet.getColorScheme();\r
+           if(cidx >= 0 && cidx <= 7) rgb = ca.getColor(cidx);\r
+       }\r
+       Color tmp = new Color(rgb, true);\r
+       return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());\r
+   }\r
+\r
+   /**\r
+    * Sets the bullet font\r
+    */\r
+   public void setBulletFont(int idx) {\r
+       setParaTextPropVal("bullet.font", idx);\r
+       setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true);\r
+   }\r
+\r
+   /**\r
+    * Returns the bullet font\r
+    */\r
+   public int getBulletFont() {\r
+       return getParaTextPropVal("bullet.font");\r
+   }\r
+\r
+   /**\r
+    * Sets the line spacing.\r
+    * <p>\r
+    * If linespacing >= 0, then linespacing is a percentage of normal line height.\r
+    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.\r
+    * </p>\r
+    */\r
+   public void setLineSpacing(int val) {\r
+       setParaTextPropVal("linespacing", val);\r
+   }\r
+\r
+   /**\r
+    * Returns the line spacing\r
+    * <p>\r
+    * If linespacing >= 0, then linespacing is a percentage of normal line height.\r
+    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.\r
+    * </p>\r
+    *\r
+    * @return the spacing between lines\r
+    */\r
+   @Override\r
+   public double getLineSpacing() {\r
+       int val = getParaTextPropVal("linespacing");\r
+       return val == -1 ? 0 : val;\r
+   }\r
+\r
+   /**\r
+    * Sets spacing before a paragraph.\r
+    * <p>\r
+    * If spacebefore >= 0, then spacebefore is a percentage of normal line height.\r
+    * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.\r
+    * </p>\r
+    */\r
+   public void setSpaceBefore(int val) {\r
+       setParaTextPropVal("spacebefore", val);\r
+   }\r
+\r
+   /**\r
+    * Returns spacing before a paragraph\r
+    * <p>\r
+    * If spacebefore >= 0, then spacebefore is a percentage of normal line height.\r
+    * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.\r
+    * </p>\r
+    *\r
+    * @return the spacing before a paragraph\r
+    */\r
+   @Override\r
+   public double getSpaceBefore() {\r
+       int val = getParaTextPropVal("spacebefore");\r
+       return val == -1 ? 0 : val;\r
+   }\r
+\r
+   /**\r
+    * Sets spacing after a paragraph.\r
+    * <p>\r
+    * If spaceafter >= 0, then spaceafter is a percentage of normal line height.\r
+    * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.\r
+    * </p>\r
+    */\r
+   public void setSpaceAfter(int val) {\r
+       setParaTextPropVal("spaceafter", val);\r
+   }\r
+\r
+   /**\r
+    * Returns spacing after a paragraph\r
+    * <p>\r
+    * If spaceafter >= 0, then spaceafter is a percentage of normal line height.\r
+    * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.\r
+    * </p>\r
+    *\r
+    * @return the spacing before a paragraph\r
+    */\r
+   @Override\r
+   public double getSpaceAfter() {\r
+       int val = getParaTextPropVal("spaceafter");\r
+       return val == -1 ? 0 : val;\r
+   }\r
+       \r
+   /**\r
+    * Returns the named TextProp, either by fetching it (if it exists) or adding it\r
+    *  (if it didn't)\r
+    * @param textPropCol The TextPropCollection to fetch from / add into\r
+    * @param textPropName The name of the TextProp to fetch/add\r
+    */\r
+    protected static TextProp fetchOrAddTextProp(TextPropCollection textPropCol, String textPropName) {\r
+        // Fetch / Add the TextProp\r
+        TextProp tp = textPropCol.findByName(textPropName);\r
+        if (tp == null) {\r
+            tp = textPropCol.addWithName(textPropName);\r
+        }\r
+        return tp;\r
+    }\r
+\r
+    protected boolean getFlag(int index) {\r
+        if (_paragraphStyle == null) return false;\r
+\r
+        BitMaskTextProp prop = (BitMaskTextProp) _paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);\r
+\r
+        if (prop == null) {\r
+            if (_sheet != null) {\r
+                int txtype = getParentShape().getRunType();\r
+                HSLFMasterSheet master = _sheet.getMasterSheet();\r
+                if (master != null) {\r
+                    prop = (BitMaskTextProp) master.getStyleAttribute(txtype, getIndentLevel(), ParagraphFlagsTextProp.NAME, false);\r
+                }\r
+            } else {\r
+                logger.log(POILogger.WARN, "MasterSheet is not available");\r
+            }\r
+        }\r
+\r
+        return prop == null ? false : prop.getSubValue(index);\r
+    }\r
+\r
+   protected void setFlag(int index, boolean value) {\r
+       // Ensure we have the StyleTextProp atom we're going to need\r
+       if(_paragraphStyle == null) {\r
+           _paragraphStyle = new TextPropCollection(1);\r
+       }\r
+\r
+       BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);\r
+       prop.setSubValue(value,index);\r
+   }\r
+\r
+   /**\r
+    * Saves the modified paragraphs/textrun to the records.\r
+    * Also updates the styles to the correct text length.\r
+    */\r
+   protected static void storeText(List<HSLFTextParagraph> paragraphs) {\r
+       String rawText = toInternalString(getRawText(paragraphs));\r
+\r
+       // Will it fit in a 8 bit atom?\r
+       boolean isUnicode = StringUtil.hasMultibyte(rawText);\r
+       \r
+       TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom;\r
+       TextBytesAtom byteAtom = paragraphs.get(0)._byteAtom;\r
+       TextCharsAtom charAtom = paragraphs.get(0)._charAtom;\r
+\r
+       // Store in the appropriate record\r
+       Record oldRecord = null, newRecord = null;\r
+       if (isUnicode) { \r
+           if (byteAtom != null) {\r
+               oldRecord = byteAtom;\r
+               newRecord = charAtom = new TextCharsAtom();\r
+           }\r
+           charAtom.setText(rawText);\r
+       } else {\r
+           if (charAtom != null) {\r
+               oldRecord = charAtom;\r
+               newRecord = byteAtom = new TextBytesAtom();\r
+           }\r
+           byte[] byteText = new byte[rawText.length()];\r
+           StringUtil.putCompressedUnicode(rawText,byteText,0);\r
+           byteAtom.setText(byteText);\r
+       }\r
+\r
+       RecordContainer _txtbox = headerAtom.getParentRecord();\r
+       \r
+       if (oldRecord != null) {\r
+           // swap not appropriated records\r
+           Record[] cr = _txtbox.getChildRecords();\r
+           int idx=0;\r
+           for (Record r : cr) {\r
+               if(r.equals(oldRecord)) break;\r
+               idx++;\r
+           }\r
+           if (idx >= cr.length) {\r
+               throw new RuntimeException("child record not found - malformed container record");\r
+           }\r
+           cr[idx] = newRecord;\r
+       }\r
+\r
+       // Ensure a StyleTextPropAtom is present, adding if required\r
+       StyleTextPropAtom styleAtom = ensureStyleAtomPresent(headerAtom, byteAtom, charAtom);\r
+\r
+       // Update the text length for its Paragraph and Character stylings\r
+       // If it's shared:\r
+       //   * calculate the new length based on the run's old text\r
+       //   * this should leave in any +1's for the end of block if needed\r
+       // If it isn't shared:\r
+       //   * reset the length, to the new string's length\r
+       //   * add on +1 if the last block\r
+       // The last run needs its stylings to be 1 longer than the raw\r
+       //  text is. This is to define the stylings that any new text\r
+       //  that is added will inherit\r
+       \r
+       styleAtom.clearStyles();\r
+       \r
+       TextPropCollection lastPTPC = null, lastRTPC = null;\r
+       for (HSLFTextParagraph para : paragraphs) {\r
+           TextPropCollection ptpc = para.getParagraphStyle();\r
+           ptpc.updateTextSize(0);\r
+           if (!ptpc.equals(lastPTPC)) {\r
+               lastPTPC = styleAtom.addParagraphTextPropCollection(0);\r
+               lastPTPC.copy(ptpc);\r
+           }\r
+           for (HSLFTextRun tr : para.getTextRuns()) {\r
+               TextPropCollection rtpc = tr.getCharacterStyle();\r
+               if (!rtpc.equals(lastRTPC)) {\r
+                   lastRTPC = styleAtom.addCharacterTextPropCollection(0);\r
+                   lastRTPC.copy(rtpc);\r
+               }\r
+               int len = tr.getLength();\r
+               ptpc.updateTextSize(ptpc.getCharactersCovered()+len);\r
+               rtpc.updateTextSize(len);\r
+               lastPTPC.updateTextSize(lastPTPC.getCharactersCovered()+len);\r
+               lastRTPC.updateTextSize(lastRTPC.getCharactersCovered()+len);\r
+           }\r
+       }\r
+       \r
+       assert(lastPTPC != null && lastRTPC != null);\r
+       lastPTPC.updateTextSize(lastPTPC.getCharactersCovered()+1);\r
+       lastRTPC.updateTextSize(lastRTPC.getCharactersCovered()+1);\r
+       \r
+       /**\r
+        * If TextSpecInfoAtom is present, we must update the text size in it,\r
+        * otherwise the ppt will be corrupted\r
+        */\r
+       TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_txtbox.findFirstOfType(RecordTypes.TextSpecInfoAtom.typeID);\r
+       int len = rawText.length() + 1;\r
+       if(specAtom != null && len != specAtom.getCharactersCovered()) {\r
+           specAtom.reset(len);\r
+       }\r
+   }\r
+\r
+   /**\r
+    * Adds the supplied text onto the end of the TextParagraphs,\r
+    * creating a new RichTextRun for it to sit in.\r
+    * \r
+    * @param text the text string used by this object.\r
+    */\r
+   protected static void appendText(List<HSLFTextParagraph> paragraphs, String text, boolean newParagraph) {\r
+       text = toInternalString(text);\r
+       \r
+       // init paragraphs\r
+       assert(!paragraphs.isEmpty());\r
+       \r
+       HSLFTextParagraph lastHTP = paragraphs.get(paragraphs.size()-1);\r
+       HSLFTextRun lastHTR = lastHTP.getTextRuns().get(lastHTP.getTextRuns().size()-1);\r
+       HSLFTextParagraph htp = (newParagraph) ? new HSLFTextParagraph(lastHTP) : lastHTP;\r
+       HSLFTextRun htr = new HSLFTextRun(htp);\r
+       htr.setText(text);\r
+       htr.getCharacterStyle().copy(lastHTR.getCharacterStyle());\r
+       htp.addTextRun(htr);\r
+   }\r
+   \r
+   /**\r
+    * Sets (overwrites) the current text.\r
+    * Uses the properties of the first paragraph / textrun\r
+    * \r
+    * @param text the text string used by this object.\r
+    */\r
+   public static void setText(List<HSLFTextParagraph> paragraphs, String text) {\r
+       text = HSLFTextParagraph.toInternalString(text);\r
+       \r
+       // init paragraphs\r
+       assert(!paragraphs.isEmpty());\r
+\r
+       Iterator<HSLFTextParagraph> paraIter = paragraphs.iterator();\r
+       HSLFTextParagraph firstHTP = paraIter.next(); // keep first\r
+       assert(firstHTP != null);\r
+       while (paraIter.hasNext()) {\r
+           paraIter.next();\r
+           paraIter.remove();\r
+       }\r
+       \r
+       Iterator<HSLFTextRun> runIter = firstHTP.getTextRuns().iterator();\r
+       HSLFTextRun firstHTR = runIter.next();\r
+       assert(firstHTR != null);\r
+       while (runIter.hasNext()) {\r
+           runIter.next();\r
+           runIter.remove();\r
+       }\r
+       \r
+       firstHTR.setText(text);\r
+   }\r
+   \r
+   public static String getRawText(List<HSLFTextParagraph> paragraphs) {\r
+       StringBuilder sb = new StringBuilder();\r
+       for (HSLFTextParagraph p : paragraphs) {\r
+           for (HSLFTextRun r : p.getTextRuns()) {\r
+               sb.append(r.getRawText());\r
+           }\r
+           sb.append("\r");\r
+       }\r
+       sb.deleteCharAt(sb.length()-1); // remove last line break\r
+       return sb.toString();        \r
+   }\r
+   \r
+   /**\r
+    * Returns a new string with line breaks converted into internal ppt\r
+    * representation\r
+    */\r
+   protected static String toInternalString(String s) {\r
+       String ns = s.replaceAll("\\r?\\n", "\r");\r
+       return ns;\r
+   }\r
+\r
+   /**\r
+    * Converts raw text from the text paragraphs to a formatted string,\r
+    * i.e. it converts certain control characters used in the raw txt\r
+    *\r
+    * @param rawText the raw text\r
+    * @param runType the run type of the shape, paragraph or headerAtom.\r
+    *        use -1 if unknown\r
+    * @return the formatted string\r
+    */\r
+   public static String toExternalString(String rawText, int runType) {\r
+       // PowerPoint seems to store files with \r as the line break\r
+       // The messes things up on everything but a Mac, so translate\r
+       // them to \n\r
+       String text = rawText.replace('\r', '\n');\r
+\r
+       switch (runType) {\r
+           // 0xB acts like cariage return in page titles and like blank in the\r
+           // others\r
+           case -1:\r
+           case org.apache.poi.hslf.record.TextHeaderAtom.TITLE_TYPE:\r
+           case org.apache.poi.hslf.record.TextHeaderAtom.CENTER_TITLE_TYPE:\r
+               text = text.replace((char) 0x0B, '\n');\r
+               break;\r
+           default:\r
+               text = text.replace((char) 0x0B, ' ');\r
+               break;\r
+       }\r
+\r
+       return text;\r
+   }\r
+\r
+   /**\r
+    * For a given PPDrawing, grab all the TextRuns\r
+    */\r
+   public static List<List<HSLFTextParagraph>> findTextParagraphs(PPDrawing ppdrawing) {\r
+       List<List<HSLFTextParagraph>> runsV = new ArrayList<List<HSLFTextParagraph>>();\r
+       for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) {\r
+           // propagate parents to parent-aware records\r
+           RecordContainer.handleParentAwareRecords(wrapper);\r
+           int shapeId = wrapper.getShapeId();\r
+           List<List<HSLFTextParagraph>> rv = findTextParagraphs(wrapper);\r
+           for (List<HSLFTextParagraph> htpList : rv) {\r
+               for (HSLFTextParagraph htp : htpList) {\r
+                   htp.setShapeId(shapeId);\r
+               }\r
+           }\r
+           runsV.addAll(rv);\r
+       }\r
+       return runsV;\r
+   }\r
+   /**\r
+    * Scans through the supplied record array, looking for\r
+    * a TextHeaderAtom followed by one of a TextBytesAtom or\r
+    * a TextCharsAtom. Builds up TextRuns from these\r
+    *\r
+    * @param records the records to build from\r
+    * @param found   vector to add any found to\r
+    */\r
+   protected static List<List<HSLFTextParagraph>> findTextParagraphs(final Record[] records) {\r
+       return findTextParagraphs(records, null); \r
+   }\r
+   /**\r
+    * Scans through the supplied record array, looking for\r
+    * a TextHeaderAtom followed by one of a TextBytesAtom or\r
+    * a TextCharsAtom. Builds up TextRuns from these\r
+    *\r
+    * @param wrapper an EscherTextboxWrapper\r
+    */\r
+   protected static List<List<HSLFTextParagraph>> findTextParagraphs(final EscherTextboxWrapper wrapper) {\r
+       return findTextParagraphs(wrapper.getChildRecords(), wrapper.getStyleTextProp9Atom());\r
+   }\r
+\r
+   /**\r
+    * Scans through the supplied record array, looking for\r
+    * a TextHeaderAtom followed by one of a TextBytesAtom or\r
+    * a TextCharsAtom. Builds up TextRuns from these\r
+    *\r
+    * @param records the records to build from\r
+    * @param styleTextProp9Atom an optional StyleTextProp9Atom with numbered lists info\r
+    */\r
+    protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records, StyleTextProp9Atom styleTextProp9Atom) {\r
+        List<List<HSLFTextParagraph>> paragraphCollection = new ArrayList<List<HSLFTextParagraph>>();\r
+        \r
+        if (records == null) {\r
+            throw new NullPointerException("records need to be filled.");\r
+        }\r
+        \r
+        int recordIdx;\r
+        for (recordIdx = 0; recordIdx < records.length; recordIdx++) {\r
+            if (records[recordIdx] instanceof TextHeaderAtom) break;\r
+        }\r
+        \r
+        if (recordIdx == records.length) {\r
+            logger.log(POILogger.INFO, "No text records found.");\r
+            return paragraphCollection;\r
+        }\r
+        \r
+        for (int slwtIndex = 0; recordIdx < records.length-2; slwtIndex++) {\r
+            List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();\r
+            paragraphCollection.add(paragraphs);\r
+            \r
+            TextHeaderAtom    header = (TextHeaderAtom)records[recordIdx++];\r
+            TextBytesAtom     tbytes = null;\r
+            TextCharsAtom     tchars = null;\r
+            StyleTextPropAtom styles = null;\r
+            TextRulerAtom     ruler  = null;\r
+            MasterTextPropAtom indents = null;\r
+            \r
+            List<Record> otherRecordList = new ArrayList<Record>();\r
+            \r
+            for (; recordIdx < records.length; recordIdx++) {\r
+                Record r = records[recordIdx];\r
+                long rt = r.getRecordType();\r
+                if (RecordTypes.TextHeaderAtom.typeID == rt) break;\r
+                else if (RecordTypes.TextBytesAtom.typeID == rt) tbytes = (TextBytesAtom)r;\r
+                else if (RecordTypes.TextCharsAtom.typeID == rt) tchars = (TextCharsAtom)r;\r
+                else if (RecordTypes.StyleTextPropAtom.typeID == rt) styles = (StyleTextPropAtom)r;\r
+                else if (RecordTypes.TextRulerAtom.typeID == rt) ruler = (TextRulerAtom)r;\r
+                else if (RecordTypes.MasterTextPropAtom.typeID == rt) {\r
+                    indents = (MasterTextPropAtom)r;\r
+                    otherRecordList.add(indents);\r
+                } else {\r
+                    otherRecordList.add(r);\r
+                }\r
+            }\r
+        \r
+            assert(header != null);\r
+            if (header.getIndex() == -1) {\r
+                header.setIndex(slwtIndex);\r
+            }\r
+            \r
+            Record otherRecords[] = otherRecordList.toArray(new Record[otherRecordList.size()]);\r
+            \r
+            if (tbytes == null && tchars == null) {\r
+                tbytes = new TextBytesAtom();\r
+                logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating dummy record for later saving.");\r
+            }\r
+        \r
+            String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();\r
+        \r
+            for (String para : rawText.split("\r")) {\r
+                HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, styles);\r
+                paragraphs.add(tpara);\r
+                tpara.setStyleTextProp9Atom(styleTextProp9Atom);\r
+                tpara._ruler = ruler;\r
+                tpara._records = otherRecords;\r
+                tpara.getParagraphStyle().updateTextSize(para.length());\r
+        \r
+                HSLFTextRun trun = new HSLFTextRun(tpara);\r
+                tpara.addTextRun(trun);\r
+                trun.setText(para);\r
+            }\r
+            \r
+            if (styles == null) {\r
+                styles = ensureStyleAtomPresent(header, tbytes, tchars);\r
+            } else {\r
+                styles.setParentTextSize(rawText.length());\r
+            }\r
+            \r
+            applyCharacterStyles(paragraphs, styles.getCharacterStyles());\r
+            applyParagraphStyles(paragraphs, styles.getParagraphStyles());\r
+            if (indents != null) {\r
+                applyParagraphIndents(paragraphs, indents.getIndents());\r
+            }\r
+        }\r
+        \r
+        return paragraphCollection;\r
+    }\r
+\r
+    protected static void applyCharacterStyles(List<HSLFTextParagraph> paragraphs, List<TextPropCollection> charStyles) {\r
+        int paraIdx = 0, runIdx = 0;\r
+        for (TextPropCollection p : charStyles) {\r
+            for (int ccRun = 0, ccStyle = p.getCharactersCovered(); ccRun < ccStyle; ) {\r
+                HSLFTextParagraph para = paragraphs.get(paraIdx);\r
+                List<HSLFTextRun> runs = para.getTextRuns();\r
+                HSLFTextRun trun = runs.get(runIdx);\r
+                int len = trun.getLength();\r
+                \r
+                if (runIdx+1 >= runs.size()) {\r
+                    // need to add +1 to the last run of the paragraph\r
+                    len++;\r
+                }\r
+                \r
+                TextPropCollection pCopy = new TextPropCollection(1);\r
+                pCopy.copy(p);\r
+                if (ccRun+len <= ccStyle) {\r
+                    trun.setCharacterStyle(pCopy);\r
+                    pCopy.updateTextSize(len);\r
+                    ccRun += len;\r
+                } else {\r
+                    String text = trun.getRawText();\r
+                    trun.setText(text.substring(0,ccStyle-ccRun));\r
+                    pCopy.updateTextSize(ccStyle-ccRun);\r
+                    trun.setCharacterStyle(pCopy);\r
+                    \r
+                    HSLFTextRun nextRun = new HSLFTextRun(para);\r
+                    nextRun.setText(text.substring(ccStyle-ccRun));\r
+                    runs.add(runIdx+1, nextRun);\r
+                    \r
+                    ccRun += ccStyle-ccRun;\r
+                }\r
+\r
+                // need to compare it again, in case a run has been added afer\r
+                if (++runIdx >= runs.size()) {\r
+                    paraIdx++;\r
+                    runIdx = 0;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+    protected static void applyParagraphStyles(List<HSLFTextParagraph> paragraphs, List<TextPropCollection> paraStyles) {\r
+        int paraIdx = 0;\r
+        for (TextPropCollection p : paraStyles) {\r
+            for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) {\r
+                HSLFTextParagraph para = paragraphs.get(paraIdx);\r
+                TextPropCollection pCopy = new TextPropCollection(1);\r
+                pCopy.copy(p);\r
+                int len = 0;\r
+                for (HSLFTextRun trun : para.getTextRuns()) {\r
+                    len += trun.getLength();\r
+                }\r
+                pCopy.updateTextSize(len+1);\r
+                para.setParagraphStyle(pCopy);\r
+                ccPara += len+1;\r
+            }\r
+        }\r
+    }\r
+    \r
+    protected static void applyParagraphIndents(List<HSLFTextParagraph> paragraphs, List<IndentProp> paraStyles) {\r
+        int paraIdx = 0;\r
+        for (IndentProp p : paraStyles) {\r
+            for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) {\r
+                HSLFTextParagraph para = paragraphs.get(paraIdx);\r
+                int len = 0;\r
+                for (HSLFTextRun trun : para.getTextRuns()) {\r
+                    len += trun.getLength();\r
+                }\r
+                para.setIndentLevel(p.getIndentLevel());\r
+                ccPara += len+1;\r
+            }\r
+        }\r
+    }\r
+    \r
+    protected static List<HSLFTextParagraph> createEmptyParagraph() {\r
+        EscherTextboxWrapper wrapper = new EscherTextboxWrapper();\r
+    \r
+        TextHeaderAtom tha = new TextHeaderAtom();\r
+        tha.setParentRecord(wrapper);\r
+        wrapper.appendChildRecord(tha);\r
+    \r
+        TextCharsAtom tca = new TextCharsAtom();\r
+        wrapper.appendChildRecord(tca);\r
+    \r
+        StyleTextPropAtom sta = new StyleTextPropAtom(0);\r
+        wrapper.appendChildRecord(sta);\r
+    \r
+        HSLFTextParagraph htp = new HSLFTextParagraph(tha, null, tca, sta);\r
+        htp._records = new Record[0];\r
+        HSLFTextRun htr = new HSLFTextRun(htp);\r
+        htp.addTextRun(htr);\r
+        \r
+        return Arrays.asList(htp);\r
+    }\r
+    \r
+    public EscherTextboxWrapper getTextboxWrapper() {\r
+        return (EscherTextboxWrapper)_headerAtom.getParentRecord();\r
+    }\r
+}\r
index 06980e9ff5689eee0e8a94e7a3828f4663d7eb49..9a10a9b125d311310f89ef0dd1e584e9f863b321 100644 (file)
 
 package org.apache.poi.hslf.usermodel;
 
+import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.fetchOrAddTextProp;
+
 import java.awt.Color;
 
-import org.apache.poi.hslf.model.*;
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.model.textproperties.*;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
 import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.POILogFactory;
@@ -40,70 +37,31 @@ public final class HSLFTextRun implements TextRun {
 
        /** The TextRun we belong to */
        private HSLFTextParagraph parentParagraph;
-       /** The SlideShow we belong to */
-       // private SlideShow slideShow;
-
-       /** Where in the parent TextRun we start from */
-       private int startPos;
-
-       /** How long a string (in the parent TextRun) we represent */
-       private int length;
-
+       private String _runText = "\r";
        private String _fontname;
+       
        /**
         * Our paragraph and character style.
         * Note - we may share these styles with other RichTextRuns
         */
-       private TextPropCollection paragraphStyle;
-       private TextPropCollection characterStyle;
-       private boolean sharingParagraphStyle;
-       private boolean sharingCharacterStyle;
+       private TextPropCollection characterStyle = new TextPropCollection(1);
 
        /**
-        * Create a new wrapper around a (currently not)
-        *  rich text string
-        * @param parent
-        * @param startAt
-        * @param len
+        * Create a new wrapper around a rich text string
+        * @param parent The parent paragraph
         */
-       public HSLFTextRun(HSLFTextParagraph parent, int startAt, int len) {
-               this(parent, startAt, len, null, null, false, false);
+       public HSLFTextRun(HSLFTextParagraph parentParagraph) {
+               this.parentParagraph = parentParagraph;
        }
-       /**
-        * Create a new wrapper around a rich text string
-        * @param parent The parent TextRun
-        * @param startAt The start position of this run
-        * @param len The length of this run
-        * @param pStyle The paragraph style property collection
-        * @param cStyle The character style property collection
-        * @param pShared The paragraph styles are shared with other runs
-        * @param cShared The character styles are shared with other runs
-        */
-       public HSLFTextRun(HSLFTextParagraph parent, int startAt, int len,
-       TextPropCollection pStyle,  TextPropCollection cStyle,
-       boolean pShared, boolean cShared) {
-               parentParagraph = parent;
-               startPos = startAt;
-               length = len;
-               paragraphStyle = pStyle;
-               characterStyle = cStyle;
-               sharingParagraphStyle = pShared;
-               sharingCharacterStyle = cShared;
-       }
-
-       /**
-        * Supply (normally default) textprops, and if they're shared,
-        *  when a run gets them
-        */
-       public void supplyTextProps(TextPropCollection pStyle,  TextPropCollection cStyle, boolean pShared, boolean cShared) {
-               if(paragraphStyle != null || characterStyle != null) {
-                       throw new IllegalStateException("Can't call supplyTextProps if run already has some");
-               }
-               paragraphStyle = pStyle;
-               characterStyle = cStyle;
-               sharingParagraphStyle = pShared;
-               sharingCharacterStyle = cShared;
+       
+       public TextPropCollection getCharacterStyle() {
+           return characterStyle;
+       }
+
+       public void setCharacterStyle(TextPropCollection characterStyle) {
+           this.characterStyle = characterStyle;
        }
+       
        /**
         * Supply the SlideShow we belong to
         */
@@ -118,65 +76,23 @@ public final class HSLFTextRun implements TextRun {
         * Get the length of the text
         */
        public int getLength() {
-               return length;
+               return _runText.length();
        }
 
-       /**
-        * The beginning index, inclusive.
-        *
-        * @return the beginning index, inclusive.
-        */
-       public int getStartIndex(){
-               return startPos;
-       }
-
-       /**
-        *  The ending index, exclusive.
-        *
-        * @return the ending index, exclusive.
-        */
-       public int getEndIndex(){
-               return startPos + length;
-       }
-
-       /**
-        * Fetch the text, in output suitable form
-        */
-       public String getText() {
-               return parentParagraph.getText().substring(startPos, startPos+length);
-       }
        /**
         * Fetch the text, in raw storage form
         */
        public String getRawText() {
-               return parentParagraph.getRawText().substring(startPos, startPos+length);
+               return _runText;
        }
 
        /**
         * Change the text
         */
        public void setText(String text) {
-               String s = parentParagraph.normalize(text);
-               setRawText(s);
+           _runText = text;
        }
 
-       /**
-        * Change the text
-        */
-       public void setRawText(String text) {
-               length = text.length();
-               parentParagraph.changeTextInRichTextRun(this,text);
-       }
-
-       /**
-        * Tells the RichTextRun its new position in the parent TextRun
-        * @param startAt
-        */
-       public void updateStartPosition(int startAt) {
-               startPos = startAt;
-       }
-
-
        // --------------- Internal helpers on rich text properties -------
 
        /**
@@ -185,31 +101,21 @@ public final class HSLFTextRun implements TextRun {
         *  text property won't be set if there's no CharFlagsTextProp.
         */
        private boolean isCharFlagsTextPropVal(int index) {
-               return getFlag(true, index);
-       }
-
-       private boolean getFlag(boolean isCharacter, int index) {
-               TextPropCollection props;
-               String propname;
-               if (isCharacter){
-                       props = characterStyle;
-                       propname = CharFlagsTextProp.NAME;
-               } else {
-                       props = paragraphStyle;
-                       propname = ParagraphFlagsTextProp.NAME;
-               }
+               return getFlag(index);
+       }
+
+       protected boolean getFlag(int index) {
+           if (characterStyle == null) return false;
+
+               BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME);
 
-               BitMaskTextProp prop = null;
-               if (props != null){
-                       prop = (BitMaskTextProp)props.findByName(propname);
-               }
                if (prop == null){
                        HSLFSheet sheet = parentParagraph.getSheet();
                        if(sheet != null){
-                               int txtype = parentParagraph.getRunType();
+                               int txtype = parentParagraph.getParentShape().getRunType();
                                HSLFMasterSheet master = sheet.getMasterSheet();
                                if (master != null){
-                                       prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
+                                       prop = (BitMaskTextProp)master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), CharFlagsTextProp.NAME, true);
                                }
                        } else {
                                logger.log(POILogger.WARN, "MasterSheet is not available");
@@ -224,43 +130,7 @@ public final class HSLFTextRun implements TextRun {
         *  it if required.
         */
        private void setCharFlagsTextPropVal(int index, boolean value) {
-               if(getFlag(true, index) != value) setFlag(true, index, value);
-       }
-
-       public void setFlag(boolean isCharacter, int index, boolean value) {
-               TextPropCollection props;
-               String propname;
-               if (isCharacter){
-                       props = characterStyle;
-                       propname = CharFlagsTextProp.NAME;
-               } else {
-                       props = paragraphStyle;
-                       propname = ParagraphFlagsTextProp.NAME;
-               }
-
-               // Ensure we have the StyleTextProp atom we're going to need
-               if(props == null) {
-                       parentParagraph.ensureStyleAtomPresent();
-                       props = isCharacter ? characterStyle : paragraphStyle;
-               }
-
-               BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(props, propname);
-               prop.setSubValue(value,index);
-       }
-
-       /**
-        * Returns the named TextProp, either by fetching it (if it exists) or adding it
-        *  (if it didn't)
-        * @param textPropCol The TextPropCollection to fetch from / add into
-        * @param textPropName The name of the TextProp to fetch/add
-        */
-       private TextProp fetchOrAddTextProp(TextPropCollection textPropCol, String textPropName) {
-               // Fetch / Add the TextProp
-               TextProp tp = textPropCol.findByName(textPropName);
-               if(tp == null) {
-                       tp = textPropCol.addWithName(textPropName);
-               }
-               return tp;
+               if(getFlag(index) != value) setFlag(index, value);
        }
 
        /**
@@ -277,55 +147,14 @@ public final class HSLFTextRun implements TextRun {
 
                if (prop == null){
                        HSLFSheet sheet = parentParagraph.getSheet();
-                       int txtype = parentParagraph.getRunType();
+                       int txtype = parentParagraph.getParentShape().getRunType();
                        HSLFMasterSheet master = sheet.getMasterSheet();
                        if (master != null)
-                               prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true);
+                               prop = master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), propName, true);
                }
                return prop == null ? -1 : prop.getValue();
        }
-       /**
-        * Fetch the value of the given Paragraph related TextProp.
-        * Returns -1 if that TextProp isn't present.
-        * If the TextProp isn't present, the value from the appropriate
-        *  Master Sheet will apply.
-        */
-       private int getParaTextPropVal(String propName) {
-               TextProp prop = null;
-               boolean hardAttribute = false;
-               if (paragraphStyle != null){
-                       prop = paragraphStyle.findByName(propName);
-
-                       BitMaskTextProp maskProp = (BitMaskTextProp)paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
-                       hardAttribute = maskProp != null && maskProp.getValue() == 0;
-               }
-               if (prop == null && !hardAttribute){
-                       HSLFSheet sheet = parentParagraph.getSheet();
-                       int txtype = parentParagraph.getRunType();
-                       HSLFMasterSheet master = sheet.getMasterSheet();
-                       if (master != null)
-                               prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);
-               }
-
-               return prop == null ? -1 : prop.getValue();
-       }
-
-       /**
-        * Sets the value of the given Character TextProp, add if required
-        * @param propName The name of the Character TextProp
-        * @param val The value to set for the TextProp
-        */
-       public void setParaTextPropVal(String propName, int val) {
-               // Ensure we have the StyleTextProp atom we're going to need
-               if(paragraphStyle == null) {
-                       parentParagraph.ensureStyleAtomPresent();
-                       // paragraphStyle will now be defined
-               }
-
-        assert(paragraphStyle!=null);
-               TextProp tp = fetchOrAddTextProp(paragraphStyle, propName);
-               tp.setValue(val);
-       }
+       
        /**
         * Sets the value of the given Paragraph TextProp, add if required
         * @param propName The name of the Paragraph TextProp
@@ -334,11 +163,10 @@ public final class HSLFTextRun implements TextRun {
        public void setCharTextPropVal(String propName, int val) {
                // Ensure we have the StyleTextProp atom we're going to need
                if(characterStyle == null) {
-                       parentParagraph.ensureStyleAtomPresent();
+                   characterStyle = new TextPropCollection(1);
                        // characterStyle will now be defined
                }
 
-               assert(characterStyle!=null);
                TextProp tp = fetchOrAddTextProp(characterStyle, propName);
                tp.setValue(val);
        }
@@ -377,14 +205,14 @@ public final class HSLFTextRun implements TextRun {
        /**
         * Is the text underlined?
         */
-       public boolean isUnderline() {
+       public boolean isUnderlined() {
                return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
        }
 
        /**
         * Is the text underlined?
         */
-       public void setUnderline(boolean underlined) {
+       public void setUnderlined(boolean underlined) {
                setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
        }
 
@@ -452,7 +280,7 @@ public final class HSLFTextRun implements TextRun {
        /**
         * Gets the font size
         */
-       public int getFontSize() {
+       public double getFontSize() {
                return getCharTextPropVal("font.size");
        }
 
@@ -484,7 +312,7 @@ public final class HSLFTextRun implements TextRun {
         */
        public void setFontName(String fontName) {
            HSLFSheet sheet = parentParagraph.getSheet();
-           HSLFSlideShowImpl slideShow = (sheet == null) ? null : sheet.getSlideShow();
+           HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
                if (sheet == null || slideShow == null) {
                        //we can't set font since slideshow is not assigned yet
                        _fontname = fontName;
@@ -498,9 +326,10 @@ public final class HSLFTextRun implements TextRun {
        /**
         * Gets the font name
         */
-       public String getFontName() {
+       @Override
+       public String getFontFamily() {
         HSLFSheet sheet = parentParagraph.getSheet();
-        HSLFSlideShowImpl slideShow = (sheet == null) ? null : sheet.getSlideShow();
+        HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
                if (sheet == null || slideShow == null) {
                        return _fontname;
                }
@@ -544,250 +373,29 @@ public final class HSLFTextRun implements TextRun {
                setFontColor(rgb);
        }
 
-       /**
-        * Sets the type of horizontal alignment for the text.
-        * One of the <code>Align*</code> constants defined in the <code>TextBox</code> class.
-        *
-        * @param align - the type of alignment
-        */
-       public void setAlignment(int align) {
-               setParaTextPropVal("alignment", align);
-       }
-       /**
-        * Returns the type of horizontal alignment for the text.
-        * One of the <code>Align*</code> constants defined in the <code>TextBox</class> class.
-        *
-        * @return the type of alignment
-        */
-       public int getAlignment() {
-               return getParaTextPropVal("alignment");
-       }
+    protected void setFlag(int index, boolean value) {
+        // Ensure we have the StyleTextProp atom we're going to need
+        if (characterStyle == null) {
+            characterStyle = new TextPropCollection(1);
+        }
 
-       /**
-        *
-        * @return indentation level
-        */
-       public int getIndentLevel() {
-               return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
-       }
+        BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(characterStyle, CharFlagsTextProp.NAME);
+        prop.setSubValue(value, index);
+    }
 
-       /**
-        * Sets indentation level
-        *
-        * @param level indentation level. Must be in the range [0, 4]
-        */
-       public void setIndentLevel(int level) {
-               if(paragraphStyle != null ) paragraphStyle.setReservedField((short)level);
-       }
+    public TextCap getTextCap() {
+        return TextCap.NONE;
+    }
 
-       /**
-        * Sets whether this rich text run has bullets
-        */
-       public void setBullet(boolean flag) {
-               setFlag(false, ParagraphFlagsTextProp.BULLET_IDX, flag);
-       }
+    public boolean isSubscript() {
+        return false;
+    }
 
-       /**
-        * Returns whether this rich text run has bullets
-        */
-       public boolean isBullet() {
-               return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
-       }
+    public boolean isSuperscript() {
+        return false;
+    }
 
-       /**
-        * Returns whether this rich text run has bullets
-        */
-       public boolean isBulletHard() {
-               return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
-       }
-
-       /**
-        * Sets the bullet character
-        */
-       public void setBulletChar(char c) {
-               setParaTextPropVal("bullet.char", c);
-       }
-
-       /**
-        * Returns the bullet character
-        */
-       public char getBulletChar() {
-               return (char)getParaTextPropVal("bullet.char");
-       }
-
-       /**
-        * Sets the bullet offset
-        */
-       public void setBulletOffset(int offset) {
-               setParaTextPropVal("bullet.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
-       }
-
-       /**
-        * Returns the bullet offset
-        */
-       public int getBulletOffset() {
-               return getParaTextPropVal("bullet.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-       }
-
-       /**
-        * Sets the text offset
-        */
-       public void setTextOffset(int offset) {
-               setParaTextPropVal("text.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
-       }
-
-       /**
-        * Returns the text offset
-        */
-       public int getTextOffset() {
-               return getParaTextPropVal("text.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-       }
-
-       /**
-        * Sets the bullet size
-        */
-       public void setBulletSize(int size) {
-               setParaTextPropVal("bullet.size", size);
-       }
-
-       /**
-        * Returns the bullet size
-        */
-       public int getBulletSize() {
-               return getParaTextPropVal("bullet.size");
-       }
-
-       /**
-        * Sets the bullet color
-        */
-       public void setBulletColor(Color color) {
-               int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();
-               setParaTextPropVal("bullet.color", rgb);
-       }
-
-       /**
-        * Returns the bullet color
-        */
-       public Color getBulletColor() {
-               int rgb = getParaTextPropVal("bullet.color");
-               if(rgb == -1) return getFontColor();
-
-               int cidx = rgb >> 24;
-               if (rgb % 0x1000000 == 0){
-                       ColorSchemeAtom ca = parentParagraph.getSheet().getColorScheme();
-                       if(cidx >= 0 && cidx <= 7) rgb = ca.getColor(cidx);
-               }
-               Color tmp = new Color(rgb, true);
-               return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
-       }
-
-       /**
-        * Sets the bullet font
-        */
-       public void setBulletFont(int idx) {
-               setParaTextPropVal("bullet.font", idx);
-               setFlag(false, ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true);
-       }
-
-       /**
-        * Returns the bullet font
-        */
-       public int getBulletFont() {
-               return getParaTextPropVal("bullet.font");
-       }
-
-       /**
-        * Sets the line spacing.
-        * <p>
-        * If linespacing >= 0, then linespacing is a percentage of normal line height.
-        * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-        * </p>
-        */
-       public void setLineSpacing(int val) {
-               setParaTextPropVal("linespacing", val);
-       }
-
-       /**
-        * Returns the line spacing
-        * <p>
-        * If linespacing >= 0, then linespacing is a percentage of normal line height.
-        * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-        * </p>
-        *
-        * @return the spacing between lines
-        */
-       public int getLineSpacing() {
-               int val = getParaTextPropVal("linespacing");
-               return val == -1 ? 0 : val;
-       }
-
-       /**
-        * Sets spacing before a paragraph.
-        * <p>
-        * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
-        * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
-        * </p>
-        */
-       public void setSpaceBefore(int val) {
-               setParaTextPropVal("spacebefore", val);
-       }
-
-       /**
-        * Returns spacing before a paragraph
-        * <p>
-        * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
-        * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
-        * </p>
-        *
-        * @return the spacing before a paragraph
-        */
-       public int getSpaceBefore() {
-               int val = getParaTextPropVal("spacebefore");
-               return val == -1 ? 0 : val;
-       }
-
-       /**
-        * Sets spacing after a paragraph.
-        * <p>
-        * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
-        * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
-        * </p>
-        */
-       public void setSpaceAfter(int val) {
-               setParaTextPropVal("spaceafter", val);
-       }
-
-       /**
-        * Returns spacing after a paragraph
-        * <p>
-        * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
-        * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
-        * </p>
-        *
-        * @return the spacing before a paragraph
-        */
-       public int getSpaceAfter() {
-               int val = getParaTextPropVal("spaceafter");
-               return val == -1 ? 0 : val;
-       }
-       // --------------- Internal HSLF methods, not intended for end-user use! -------
-
-       /**
-        * Internal Use Only - get the underlying paragraph style collection.
-        * For normal use, use the friendly setters and getters
-        */
-       public TextPropCollection _getRawParagraphStyle() { return paragraphStyle; }
-       /**
-        * Internal Use Only - get the underlying character style collection.
-        * For normal use, use the friendly setters and getters
-        */
-       public TextPropCollection _getRawCharacterStyle() { return characterStyle; }
-       /**
-        * Internal Use Only - are the Paragraph styles shared?
-        */
-       public boolean _isParagraphStyleShared() { return sharingParagraphStyle; }
-       /**
-        * Internal Use Only - are the Character styles shared?
-        */
-       public boolean _isCharacterStyleShared() { return sharingCharacterStyle; }
+    public byte getPitchAndFamily() {
+        return 0;
+    }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
new file mode 100644 (file)
index 0000000..2c4e73b
--- /dev/null
@@ -0,0 +1,754 @@
+/* ====================================================================
+   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.usermodel;
+
+import static org.apache.poi.hslf.record.RecordTypes.*;
+
+import java.awt.Rectangle;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Rectangle2D.Double;
+import java.io.IOException;
+import java.util.*;
+
+import org.apache.poi.POIXMLException;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.DrawTextShape;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.util.POILogger;
+
+/**
+ * A common superclass of all shapes that can hold text.
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape<HSLFTextParagraph> {
+
+    /**
+     * How to anchor the text
+     */
+    /* package */ static final int AnchorTop = 0;
+    /* package */ static final int AnchorMiddle = 1;
+    /* package */ static final int AnchorBottom = 2;
+    /* package */ static final int AnchorTopCentered = 3;
+    /* package */ static final int AnchorMiddleCentered = 4;
+    /* package */ static final int AnchorBottomCentered = 5;
+    /* package */ static final int AnchorTopBaseline = 6;
+    /* package */ static final int AnchorBottomBaseline = 7;
+    /* package */ static final int AnchorTopCenteredBaseline = 8;
+    /* package */ static final int AnchorBottomCenteredBaseline = 9;
+
+    /**
+     * How to wrap the text
+     */
+    public static final int WrapSquare = 0;
+    public static final int WrapByPoints = 1;
+    public static final int WrapNone = 2;
+    public static final int WrapTopBottom = 3;
+    public static final int WrapThrough = 4;
+
+    /**
+     * TextRun object which holds actual text and format data
+     */
+    protected List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>();
+
+    /**
+     * Escher container which holds text attributes such as
+     * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
+     */
+    protected EscherTextboxWrapper _txtbox;
+
+    /**
+     * This setting is used for supporting a deprecated alignment
+     * 
+     * @see <a href=""></a>
+     */
+    boolean alignToBaseline = false;
+    
+    /**
+     * Used to calculate text bounds
+     */
+    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
+
+    /**
+     * Create a TextBox object and initialize it from the supplied Record container.
+     *
+     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent    the parent of the shape
+     */
+   protected HSLFTextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+        super(escherRecord, parent);
+
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     * @param parent    the parent of this Shape. For example, if this text box is a cell
+     * in a table then the parent is Table.
+     */
+    public HSLFTextShape(ShapeContainer<HSLFShape> parent){
+        super(null, parent);
+        _escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     */
+    public HSLFTextShape(){
+        this(null);
+    }
+
+    /**
+     * Set default properties for the  TextRun.
+     * Depending on the text and shape type the defaults are different:
+     *   TextBox: align=left, valign=top
+     *   AutoShape: align=center, valign=middle
+     *
+     */
+    protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
+
+    }
+
+    /**
+     * When a textbox is added to  a sheet we need to tell upper-level
+     * <code>PPDrawing</code> about it.
+     *
+     * @param sh the sheet we are adding to
+     */
+    protected void afterInsert(HSLFSheet sh){
+        super.afterInsert(sh);
+
+        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
+        if(_txtbox != null){
+            PPDrawing ppdrawing = sh.getPPDrawing();
+            ppdrawing.addTextboxWrapper(_txtbox);
+            // Ensure the escher layer knows about the added records
+            try {
+                _txtbox.writeOut(null);
+            } catch (IOException e){
+                throw new HSLFException(e);
+            }
+            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
+        }
+        for (HSLFTextParagraph htp : _paragraphs) {
+            htp.setShapeId(getShapeId());
+        }
+        sh.onAddTextShape(this);
+    }
+
+    protected EscherTextboxWrapper getEscherTextboxWrapper(){
+        if(_txtbox == null){
+            EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
+            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
+        }
+        return _txtbox;
+    }
+
+    /**
+     * Adjust the size of the shape so it encompasses the text inside it.
+     *
+     * @return a <code>Rectangle2D</code> that is the bounds of this shape.
+     */
+    public Rectangle2D resizeToFitText(){
+        Rectangle2D anchor = getAnchor();
+        if(anchor.getWidth() == 0.) {
+            logger.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px");
+            anchor = new Rectangle2D.Double(anchor.getX(), anchor.getY(), 200, anchor.getHeight());
+            setAnchor(anchor);
+        }
+        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
+    * @see org.apache.poi.hslf.record.TextHeaderAtom
+    */
+    public int getRunType() {
+        getEscherTextboxWrapper();
+        if (_txtbox == null) return -1;
+        TextHeaderAtom headerAtom = (TextHeaderAtom)_txtbox.findFirstOfType(TextHeaderAtom.typeID);
+        assert(headerAtom != null);
+        return headerAtom.getTextType();
+    }
+
+    /**
+    * Changes the type of the text. Values should be taken
+    *  from TextHeaderAtom. No checking is done to ensure you
+    *  set this to a valid value!
+    * @see org.apache.poi.hslf.record.TextHeaderAtom
+    */
+    public void setRunType(int type) {
+        getEscherTextboxWrapper();
+        if (_txtbox == null) return;
+        TextHeaderAtom headerAtom = (TextHeaderAtom)_txtbox.findFirstOfType(TextHeaderAtom.typeID);
+        assert(headerAtom != null);
+        headerAtom.setTextType(type);
+    }
+    
+    /**
+     * Returns the type of vertical alignment for the text.
+     * One of the <code>Anchor*</code> constants defined in this class.
+     *
+     * @return the type of alignment
+     */
+    /* package */ int getAlignment(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
+        int align = HSLFTextShape.AnchorTop;
+        if (prop == null){
+            /**
+             * If vertical alignment was not found in the shape properties then try to
+             * fetch the master shape and search for the align property there.
+             */
+            int type = getRunType();
+            HSLFMasterSheet master = getSheet().getMasterSheet();
+            if(master != null){
+                HSLFTextShape masterShape = master.getPlaceholderByTextType(type);
+                if(masterShape != null) align = masterShape.getAlignment();
+            } else {
+                //not found in the master sheet. Use the hardcoded defaults.
+                switch (type){
+                     case org.apache.poi.hslf.record.TextHeaderAtom.TITLE_TYPE:
+                     case org.apache.poi.hslf.record.TextHeaderAtom.CENTER_TITLE_TYPE:
+                         align = HSLFTextShape.AnchorMiddle;
+                         break;
+                     default:
+                         align = HSLFTextShape.AnchorTop;
+                         break;
+                 }
+            }
+        } else {
+            align = prop.getPropertyValue();
+        }
+
+        alignToBaseline = (align == AnchorBottomBaseline || align == AnchorBottomCenteredBaseline
+            || align == AnchorTopBaseline || align == AnchorTopCenteredBaseline);
+        
+        return align;
+    }
+
+    /**
+     * Sets the type of alignment for the text.
+     * One of the <code>Anchor*</code> constants defined in this class.
+     *
+     * @param align - the type of alignment
+     */
+    /* package */ void setAlignment(Boolean isCentered, VerticalAlignment vAlign) {
+        int align[];
+        switch (vAlign) {
+        case TOP:
+            align = new int[]{AnchorTop, AnchorTopCentered, AnchorTopBaseline, AnchorTopCenteredBaseline};
+            break;
+        default:
+        case MIDDLE:
+            align = new int[]{AnchorMiddle, AnchorMiddleCentered, AnchorMiddle, AnchorMiddleCentered};
+            break;
+        case BOTTOM:
+            align = new int[]{AnchorBottom, AnchorBottomCentered, AnchorBottomBaseline, AnchorBottomCenteredBaseline};
+            break;
+        }
+        
+        int align2 = align[(isCentered ? 1 : 0)+(alignToBaseline ? 2 : 0)];
+        
+        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align2);
+    }
+    
+    @Override
+    public VerticalAlignment getVerticalAlignment() {
+        int va = getAlignment();
+        switch (va) {
+        case AnchorTop:
+        case AnchorTopCentered:
+        case AnchorTopBaseline:
+        case AnchorTopCenteredBaseline: return VerticalAlignment.TOP;
+        case AnchorBottom:
+        case AnchorBottomCentered:
+        case AnchorBottomBaseline:
+        case AnchorBottomCenteredBaseline: return VerticalAlignment.BOTTOM;
+        default:
+        case AnchorMiddle:
+        case AnchorMiddleCentered: return VerticalAlignment.MIDDLE;
+        }
+    }
+
+    /**
+     * @return true, if vertical alignment is relative to baseline
+     * this is only used for older versions less equals Office 2003 
+     */
+    public boolean isAlignToBaseline() {
+        getAlignment();
+        return alignToBaseline;
+    }
+
+    /**
+     * Sets the vertical alignment relative to the baseline
+     *
+     * @param alignToBaseline if true, vertical alignment is relative to baseline
+     */
+    public void setAlignToBaseline(boolean alignToBaseline) {
+        this.alignToBaseline = alignToBaseline;
+        setAlignment(isHorizontalCentered(), getVerticalAlignment());
+    }
+    
+    @Override
+    public boolean isHorizontalCentered() {
+        int va = getAlignment();
+        switch (va) {
+        case AnchorTopCentered:
+        case AnchorTopCenteredBaseline:
+        case AnchorBottomCentered:
+        case AnchorBottomCenteredBaseline:
+        case AnchorMiddleCentered:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
+    public void setVerticalAlignment(VerticalAlignment vAlign) {
+        setAlignment(isHorizontalCentered(), vAlign);
+    }
+
+    /**
+     * Sets if the paragraphs are horizontal centered
+     *
+     * @param isCentered true, if the paragraphs are horizontal centered
+     * A {@code null} values unsets this property.
+     * 
+     * @see TextShape#isHorizontalCentered()
+     */
+    public void setHorizontalCentered(Boolean isCentered){
+        setAlignment(isCentered, getVerticalAlignment());
+    }
+
+    /**
+     * Returns the distance (in points) between the bottom of the text frame
+     * and the bottom of the inscribed rectangle of the shape that contains the text.
+     * Default value is 1/20 inch.
+     *
+     * @return the botom margin
+     */
+    public double getBottomInset(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+        return val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the botom margin.
+     * @see #getBottomInset()
+     *
+     * @param margin    the bottom margin
+     */
+    public void setBottomInset(double margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) between the left edge of the text frame
+     *  and the left edge of the inscribed rectangle of the shape that contains
+     *  the text.
+     *  Default value is 1/10 inch.
+     *
+     * @return the left margin
+     */
+    public double getLeftInset(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT);
+        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+        return val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the left margin.
+     * @see #getLeftInset()
+     *
+     * @param margin    the left margin
+     */
+    public void setLeftInset(double margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) between the right edge of the
+     *  text frame and the right edge of the inscribed rectangle of the shape
+     *  that contains the text.
+     *  Default value is 1/10 inch.
+     *
+     * @return the right margin
+     */
+    public double getRightInset(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
+        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+        return val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the right margin.
+     * @see #getRightInset()
+     *
+     * @param margin    the right margin
+     */
+    public void setRightInset(double margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
+    }
+
+     /**
+     *  Returns the distance (in points) between the top of the text frame
+     *  and the top of the inscribed rectangle of the shape that contains the text.
+     *  Default value is 1/20 inch.
+     *
+     * @return the top margin
+     */
+    public double getTopInset(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
+        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+        return val/EMU_PER_POINT;
+    }
+
+   /**
+     * Sets the top margin.
+     * @see #getTopInset()
+     *
+     * @param margin    the top margin
+     */
+    public void setTopInset(double margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
+    }
+
+    @Override
+    public boolean getWordWrap(){
+        int ww = getWordWrapEx();
+        return (ww != WrapNone);
+    }
+
+    /**
+     * Returns the value indicating word wrap.
+     *
+     * @return the value indicating word wrap.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     *
+     * @see <a href="https://msdn.microsoft.com/en-us/library/dd948168(v=office.12).aspx">MSOWRAPMODE</a>
+     */
+    public int getWordWrapEx() {
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
+        return prop == null ? WrapSquare : prop.getPropertyValue();
+    }
+
+    /**
+     *  Specifies how the text should be wrapped
+     *
+     * @param wrap  the value indicating how the text should be wrapped.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     */
+    public void setWordWrap(int wrap){
+        setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
+    }
+
+    /**
+     * @return id for the text.
+     */
+    public int getTextId(){
+        EscherOptRecord opt = getEscherOptRecord();
+        EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
+        return prop == null ? 0 : prop.getPropertyValue();
+    }
+
+    /**
+     * Sets text ID
+     *
+     * @param id of the text
+     */
+    public void setTextId(int id){
+        setEscherProperty(EscherProperties.TEXT__TEXTID, id);
+    }
+
+    /**
+      * @return the TextRun object for this text box
+      */
+    public List<HSLFTextParagraph> getTextParagraphs(){
+        if (!_paragraphs.isEmpty()) return _paragraphs;
+        
+        _txtbox = getEscherTextboxWrapper();
+        if (_txtbox == null) {
+            _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
+            _txtbox = _paragraphs.get(0).getTextboxWrapper();
+        } else {
+            initParagraphsFromSheetRecords();
+            if (_paragraphs.isEmpty()) {
+                List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
+                if (!llhtp.isEmpty()) {
+                    _paragraphs.addAll(llhtp.get(0));
+                }
+            }
+        }
+
+        for (HSLFTextParagraph p : _paragraphs) {
+            p.setParentShape(this);
+        }
+        
+        return _paragraphs;
+    }
+
+    public void setSheet(HSLFSheet sheet) {
+        _sheet = sheet;
+
+        // Initialize _txtrun object.
+        // (We can't do it in the constructor because the sheet
+        //  is not assigned then, it's only built once we have
+        //  all the records)
+        for (HSLFTextParagraph htp : getTextParagraphs()) {
+            // Supply the sheet to our child RichTextRuns
+            htp.supplySheet(_sheet);
+        }
+    }
+
+    protected void initParagraphsFromSheetRecords(){
+        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
+        HSLFSheet sheet = getSheet();
+
+        if(sheet == null || txtbox == null) return;
+
+        OutlineTextRefAtom ota = null;
+
+        Record[] child = txtbox.getChildRecords();
+        for (int i = 0; i < child.length; i++) {
+            if (child[i] instanceof OutlineTextRefAtom) {
+                ota = (OutlineTextRefAtom)child[i];
+                break;
+            }
+        }
+
+        List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
+        _paragraphs.clear();
+        if (sheetRuns != null) {
+            if (ota != null) {
+                int idx = ota.getTextIndex();
+                for (List<HSLFTextParagraph> r : sheetRuns) {
+                    if (r.isEmpty()) continue;
+                    int ridx = r.get(0).getIndex();
+                    if (ridx > idx) break;
+                    if (ridx == idx) _paragraphs.addAll(r);
+                }
+                if(_paragraphs.isEmpty()) {
+                    logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
+                }
+            } else {
+                int shapeId = getShapeId();
+                for (List<HSLFTextParagraph> r : sheetRuns) {
+                    if (r.isEmpty()) continue;
+                    if (r.get(0).getShapeId() == shapeId) _paragraphs.addAll(r);
+                }
+            }
+        }
+
+        // ensure the same references child records of TextRun
+        // TODO: check the purpose of this ...
+//        if(_txtrun != null) {
+//            for (int i = 0; i < child.length; i++) {
+//                for (Record r : _txtrun.getRecords()) {
+//                    if (child[i].getRecordType() == r.getRecordType()) {
+//                        child[i] = r;
+//                    }
+//                }
+//            }
+//        }
+    }
+
+    /*
+        // 0xB acts like cariage return in page titles and like blank in the others
+        char replChr;
+        switch(tha == null ? -1 : tha.getTextType()) {
+            case -1:
+            case TextHeaderAtom.TITLE_TYPE:
+            case TextHeaderAtom.CENTER_TITLE_TYPE:
+                replChr = '\n';
+                break;
+            default:
+                replChr = ' ';
+                break;
+        }
+
+        // PowerPoint seems to store files with \r as the line break
+        // The messes things up on everything but a Mac, so translate
+        //  them to \n
+        String text = rawText.replace('\r','\n').replace('\u000b', replChr);
+     */
+    
+    /**
+     * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder.
+     *
+     * @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
+     */
+    public OEPlaceholderAtom getPlaceholderAtom(){
+        return getClientDataRecord(OEPlaceholderAtom.typeID);
+    }
+
+    /**
+     *
+     * Assigns a hyperlink to this text shape
+     *
+     * @param linkId    id of the hyperlink, @see org.apache.poi.hslf.usermodel.SlideShow#addHyperlink(Hyperlink)
+     * @param      beginIndex   the beginning index, inclusive.
+     * @param      endIndex     the ending index, exclusive.
+     * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#addHyperlink(HSLFHyperlink)
+     */
+    public void setHyperlink(int linkId, int beginIndex, int endIndex){
+        //TODO validate beginIndex and endIndex and throw IllegalArgumentException
+
+        InteractiveInfo info = new InteractiveInfo();
+        InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
+        infoAtom.setAction(org.apache.poi.hslf.record.InteractiveInfoAtom.ACTION_HYPERLINK);
+        infoAtom.setHyperlinkType(org.apache.poi.hslf.record.InteractiveInfoAtom.LINK_Url);
+        infoAtom.setHyperlinkID(linkId);
+
+        _txtbox.appendChildRecord(info);
+
+        TxInteractiveInfoAtom txiatom = new TxInteractiveInfoAtom();
+        txiatom.setStartIndex(beginIndex);
+        txiatom.setEndIndex(endIndex);
+        _txtbox.appendChildRecord(txiatom);
+
+    }
+
+    @Override
+    public boolean isPlaceholder() {
+        OEPlaceholderAtom oep = getPlaceholderAtom();
+        if (oep != null) return true;
+
+        //special case for files saved in Office 2007
+        RoundTripHFPlaceholder12 hldr = getClientDataRecord(RoundTripHFPlaceholder12.typeID);
+        if (hldr != null) return true;
+
+        return false;
+    }
+
+
+    @Override
+    public Iterator<HSLFTextParagraph> iterator() {
+        return _paragraphs.iterator();
+    }
+
+    @Override
+    public Insets2D getInsets() {
+        Insets2D insets = new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset());
+        return insets;
+    }
+
+    @Override
+    public double getTextHeight(){
+        DrawFactory drawFact = DrawFactory.getInstance(null);
+        DrawTextShape<HSLFTextShape> dts = drawFact.getDrawable(this);
+        return dts.getTextHeight();
+    }
+
+    @Override
+    public TextDirection getTextDirection() {
+        // TODO: determine vertical text setting
+        return TextDirection.HORIZONTAL;
+    }
+
+    /**
+     * Returns the raw text content of the shape. This hasn't had any
+     * changes applied to it, and so is probably unlikely to print
+     * out nicely.
+     */
+    public String getRawText() {
+        return HSLFTextParagraph.getRawText(getTextParagraphs());
+    }
+
+    /**
+     * Returns the text contained in this text frame, which has been made safe
+     * for printing and other use.
+     *
+     * @return the text string for this textbox.
+     */
+    public String getText() {
+        String rawText = getRawText();
+        TextHeaderAtom _headerAtom = (TextHeaderAtom)_txtbox.findFirstOfType(TextHeaderAtom.typeID);
+        int runType = (_headerAtom == null) ? -1 : _headerAtom.getTextType();
+
+        return HSLFTextParagraph.toExternalString(rawText, runType);
+    }
+
+    
+    // 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 void appendText(String text, boolean newParagraph) {
+          // init paragraphs
+          List<HSLFTextParagraph> paras = getTextParagraphs();
+          HSLFTextParagraph.appendText(paras, text, newParagraph);
+      }
+
+      /**
+       * Sets (overwrites) the current text.
+       * Uses the properties of the first paragraph / textrun
+       * 
+       * @param text the text string used by this object.
+       */
+      public void setText(String text) {
+          // init paragraphs
+          List<HSLFTextParagraph> paras = getTextParagraphs();
+          HSLFTextParagraph.setText(paras, text);
+          setTextId(text.hashCode());
+      }
+      
+      /**
+       * Saves the modified paragraphs/textrun to the records.
+       * Also updates the styles to the correct text length.
+       */
+      protected void storeText() {
+          HSLFTextParagraph.storeText(_paragraphs);
+      }
+      // Accesser methods follow
+
+    /**
+     * 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.
+     */
+    public HSLFHyperlink[] getHyperlinks() {
+        return HSLFHyperlink.find(this);
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
new file mode 100644 (file)
index 0000000..fc6131d
--- /dev/null
@@ -0,0 +1,71 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.record.SlideAtom;
+
+/**
+ * Title masters define the design template for slides with a Title Slide layout.
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFTitleMaster extends HSLFMasterSheet {
+    private final List<List<HSLFTextParagraph>> _runs = new ArrayList<List<HSLFTextParagraph>>();
+
+    /**
+     * Constructs a TitleMaster
+     *
+     */
+    public HSLFTitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
+        super(record, sheetNo);
+
+        _runs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing()));
+    }
+
+    /**
+     * Returns an array of all the TextRuns found
+     */
+    public List<List<HSLFTextParagraph>> getTextParagraphs() {
+        return _runs;
+    }
+
+    /**
+     * Delegate the call to the underlying slide master.
+     */
+    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
+        HSLFMasterSheet master = getMasterSheet();
+        return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
+    }
+
+    /**
+     * Returns the slide master for this title master.
+     */
+    public HSLFMasterSheet getMasterSheet(){
+        List<HSLFSlideMaster> master = getSlideShow().getSlideMasters();
+        SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
+        int masterId = sa.getMasterID();
+        for (HSLFSlideMaster sm : master) {
+            if (masterId == sm._getSheetNumber()) return sm;
+        }
+        return null;
+    }
+}
index bf82208cdc66fefe09cb6223739d4346cf988201..df4d635a69beb4a557b560148590aae98778604a 100644 (file)
@@ -76,7 +76,7 @@ public class DrawFactory {
         } else if (shape instanceof Background) {\r
             return getDrawable((Background)shape);\r
         } else if (shape instanceof Slide) {\r
-            return getDrawable((Slide<? extends Shape, ? extends SlideShow>)shape);\r
+            return getDrawable((Slide<? extends Shape, ? extends SlideShow, ? extends Notes<?,?>>)shape);\r
         } else if (shape instanceof MasterSheet) {\r
             return getDrawable((MasterSheet<? extends Shape, ? extends SlideShow>)shape);\r
         } else if (shape instanceof Sheet) {\r
@@ -86,7 +86,7 @@ public class DrawFactory {
         throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass());\r
     }\r
 \r
-    public <T extends Slide<? extends Shape, ? extends SlideShow>> DrawSlide<T> getDrawable(T sheet) {\r
+    public <T extends Slide<? extends Shape, ? extends SlideShow, ? extends Notes<?,?>>> DrawSlide<T> getDrawable(T sheet) {\r
         return new DrawSlide<T>(sheet);\r
     }\r
 \r
index cada314ece62d870324551615d61a0eb42af615e..4f5f631aee889607b442a7752e730260883ea286 100644 (file)
@@ -5,7 +5,7 @@ import java.awt.Graphics2D;
 import org.apache.poi.sl.usermodel.*;\r
 \r
 \r
-public class DrawSlide<T extends Slide<? extends Shape, ? extends SlideShow>> extends DrawSheet<T> {\r
+public class DrawSlide<T extends Slide<? extends Shape, ? extends SlideShow, ? extends Notes<?,?>>> extends DrawSheet<T> {\r
 \r
     public DrawSlide(T slide) {\r
         super(slide);\r
index 700edf0eb06b3da6b9edf7242528ba8631179825..3db3c6f6d023f5ec28ffdbc5844c84efb288ec6d 100644 (file)
@@ -237,7 +237,7 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
     protected String getRenderableText(TextRun tr) {\r
         StringBuilder buf = new StringBuilder();\r
         TextCap cap = tr.getTextCap();\r
-        for (char c : tr.getText().toCharArray()) {\r
+        for (char c : tr.getRawText().toCharArray()) {\r
             if(c == '\t') {\r
                 // TODO: finish support for tabs\r
                 buf.append("  ");\r
@@ -346,7 +346,7 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
             if(run.isItalic()) {\r
                 attList.add(new AttributedStringData(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, beginIndex, endIndex));\r
             }\r
-            if(run.isUnderline()) {\r
+            if(run.isUnderlined()) {\r
                 attList.add(new AttributedStringData(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, beginIndex, endIndex));\r
                 attList.add(new AttributedStringData(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, beginIndex, endIndex));\r
             }\r
index 736dc0d66877edc3b2be2a0c6224c4a61c11d980..e2caa084dd726e70a355bcd61f62f195bc453328 100644 (file)
@@ -19,8 +19,7 @@
 
 package org.apache.poi.sl.draw.geom;
 
-import java.io.*;
-import java.nio.charset.Charset;
+import java.io.InputStream;
 import java.util.LinkedHashMap;
 
 import javax.xml.bind.*;
index 630c37de45af6f37945ca0f490eb3661ad29bfd6..b06764e54d1f02a41f645303feaf32e5e9ad849f 100644 (file)
@@ -17,6 +17,6 @@
 
 package org.apache.poi.sl.usermodel;
 
-public interface Line extends AutoShape {
+public interface Line<T extends TextParagraph<? extends TextRun>> extends AutoShape<T> {
 
 }
index 08f023cd9fbb0af7f530b49ccaa1b56ae0a002ea..3e4b92472190dc95f282d3dcce1551982867356c 100644 (file)
@@ -20,5 +20,5 @@ package org.apache.poi.sl.usermodel;
 import java.util.List;
 
 public interface Notes<T extends Shape, SS extends SlideShow> extends Sheet<T,SS> {
-       List<? extends TextParagraph<? extends TextRun>> getTextParagraphs();
+       List<? extends List<? extends TextParagraph<? extends TextRun>>> getTextParagraphs();
 }
index 11a5039c665977af1853e11f7198a284fd2a3b67..1741a732d30b7334342e3e34cffe9e501ee764e3 100644 (file)
 
 package org.apache.poi.sl.usermodel;
 
+import java.util.List;
+
 
 public interface ShapeContainer<T extends Shape> extends Iterable<T> {
     /**
-     * Returns an array containing all of the elements in this container in proper
+     * Returns an list containing all of the elements in this container in proper
      * sequence (from first to last element).
      *
-     * @return an array containing all of the elements in this container in proper
+     * @return an list containing all of the elements in this container in proper
      *         sequence
      */
-       public T[] getShapes();
+       List<T> getShapes();
 
-       public void addShape(T shape);
+       void addShape(T shape);
 
     /**
      * Removes the specified shape from this sheet, if it is present
@@ -40,5 +42,5 @@ public interface ShapeContainer<T extends Shape> extends Iterable<T> {
      * @throws IllegalArgumentException if the type of the specified shape
      *         is incompatible with this sheet (optional)
      */
-       public boolean removeShape(T shape);
+       boolean removeShape(T shape);
 }
index 0c25f5be4c45e7c27f3f65bae393ac9d5381c683..f151e0c0822fc8969f52bd1659baf7fadf1b2bf0 100644 (file)
@@ -285,6 +285,25 @@ public enum ShapeType {
         this.nativeName = nativeName;
     }
 
+    /** name of the presetShapeDefinit(i)on entry */
+    public String getOoxmlName() {
+        if (this == SEAL) return STAR_16.getOoxmlName();
+        if (ooxmlId == -1) return null;
+        
+        StringBuilder sb = new StringBuilder();
+        boolean toLower = true;
+        for (char ch : name().toCharArray()) {
+            if (ch == '_') {
+                toLower = false;
+                continue;
+            }
+            sb.append(toLower ? Character.toLowerCase(ch) : Character.toUpperCase(ch));
+            toLower = true;
+        }
+        
+        return sb.toString();
+    }
+    
     public static ShapeType forId(int id, boolean isOoxmlId){
         for(ShapeType t : values()){
             if((isOoxmlId && t.ooxmlId == id) ||
index b2027c182c45f03bb558a6526f8c8952d14865eb..a9095c80ff349eaaa37c878bec903b75ad97fec1 100644 (file)
 
 package org.apache.poi.sl.usermodel;
 
-public interface Slide<T extends Shape, SS extends SlideShow> extends Sheet<T, SS> {
-       public Notes<T,SS> getNotes();
-       public void setNotes(Notes<T,SS> notes);
+public interface Slide<T extends Shape, SS extends SlideShow, N extends Notes<T,SS>> extends Sheet<T, SS> {
+       N getNotes();
+       void setNotes(N notes);
 
-       public boolean getFollowMasterBackground();
-       public void setFollowMasterBackground(boolean follow);
+       boolean getFollowMasterBackground();
+       void setFollowMasterBackground(boolean follow);
 
-       public boolean getFollowMasterColourScheme();
-       public void setFollowMasterColourScheme(boolean follow);
+       boolean getFollowMasterColourScheme();
+       void setFollowMasterColourScheme(boolean follow);
 
-       public boolean getFollowMasterObjects();
-       public void setFollowMasterObjects(boolean follow);
+       boolean getFollowMasterObjects();
+       void setFollowMasterObjects(boolean follow);
 }
index e3007f6c1780b2d576467c2e4605f523e7880b30..ca0ddf39182682b595d103f36df7c6c4aac5a780 100644 (file)
@@ -19,13 +19,20 @@ package org.apache.poi.sl.usermodel;
 
 import java.awt.Dimension;
 import java.io.IOException;
+import java.util.List;
 
 public interface SlideShow {
-       Slide<? extends Shape, ? extends SlideShow> createSlide() throws IOException;
-       MasterSheet<? extends Shape, ? extends SlideShow> createMasterSheet() throws IOException;
+       Slide<? extends Shape, ? extends SlideShow, ? extends Notes<?,?>> createSlide() throws IOException;
 
-       Slide<? extends Shape, ? extends SlideShow>[] getSlides();
-       MasterSheet<? extends Shape, ? extends SlideShow>[] getMasterSheet();
+       List<? extends Slide<? extends Shape, ? extends SlideShow, ? extends Notes<?,?>>> getSlides();
+
+    MasterSheet<? extends Shape, ? extends SlideShow> createMasterSheet() throws IOException;
+
+       /**
+     * Returns all slide masters.
+     * This doesn't include notes master and other arbitrary masters.
+     */
+       List<? extends MasterSheet<? extends Shape, ? extends SlideShow>> getSlideMasters();
 
        Resources getResources();
 
index 348cc703d60243c0590baa9d76c8e0e44210c46c..c4cf8bc57e90b131bf965fd524fba08b9b197fbe 100644 (file)
@@ -22,7 +22,7 @@ import java.awt.Color;
 \r
 public interface TextParagraph<T extends TextRun> extends Iterable<T> {\r
     /**\r
-     * Specified a list of text alignment types\r
+     * Specifies a list of text alignment types\r
      */\r
     public enum TextAlign {\r
         /**\r
@@ -50,6 +50,13 @@ public interface TextParagraph<T extends TextRun> extends Iterable<T> {
         THAI_DIST\r
     }\r
 \r
+    /**\r
+     * \r
+     */\r
+    public enum FontAlign {\r
+        AUTO, TOP, CENTER, BASELINE, BOTTOM; \r
+    }\r
+    \r
     public interface BulletStyle {\r
         String getBulletCharacter();\r
         String getBulletFont();\r
@@ -86,16 +93,32 @@ public interface TextParagraph<T extends TextRun> extends Iterable<T> {
      */\r
     double getLeftMargin();\r
 \r
+    /**\r
+     * @param leftMargin the left margin (in points) \r
+     */\r
+    void setLeftMargin(double leftMargin);\r
+    \r
+    \r
     /**\r
      * @return the right margin (in points) of the paragraph\r
      */\r
     double getRightMargin();\r
 \r
     /**\r
-     * @return the indent applied (in points) to the first line of text in the paragraph.\r
+     * @param rightMargin the right margin (in points) of the paragraph\r
+     */\r
+    void setRightMargin(double rightMargin);\r
+    \r
+    /**\r
+     * @return the indent (in points) applied to the first line of text in the paragraph.\r
      */\r
     double getIndent();\r
 \r
+    /**\r
+     * @param indent the indent (in points) applied to the first line of text in the paragraph\r
+     */\r
+    void setIndent(double indent);\r
+    \r
     /**\r
      * Returns the vertical line spacing that is to be used within a paragraph.\r
      * This may be specified in two different ways, percentage spacing and font point spacing:\r
@@ -123,6 +146,15 @@ public interface TextParagraph<T extends TextRun> extends Iterable<T> {
      */\r
     TextAlign getTextAlign();\r
     \r
+    \r
+    /**\r
+     * Returns the font alignment that is applied to the paragraph.\r
+     *\r
+     * If this attribute is omitted, then a value of auto (~ left) is implied.\r
+     * @return ??? alignment that is applied to the paragraph\r
+     */\r
+    FontAlign getFontAlign();\r
+    \r
     /**\r
      * @return the bullet style of the paragraph, if {@code null} then no bullets are used \r
      */\r
index 87758c105fe637abb04d70f699d2229bccf7f649..8ac40c18923ac662d640ec3f284b444283085c25 100644 (file)
@@ -31,7 +31,7 @@ public interface TextRun {
         ALL
     }
     
-    public String getText();
+    public String getRawText();
        public void setText(String text);
 
        TextCap getTextCap();
@@ -42,7 +42,7 @@ public interface TextRun {
        
        boolean isBold();
        boolean isItalic();
-       boolean isUnderline();
+       boolean isUnderlined();
        boolean isStrikethrough();
        boolean isSubscript();
        boolean isSuperscript();
index a6a53fe1bdd63e9111911b20ad178ab0f06f84db..927fdf1f9de31bb714625682bb1dc67ac4781cbe 100644 (file)
@@ -17,6 +17,8 @@
 \r
 package org.apache.poi.sl.usermodel;\r
 \r
+import org.apache.poi.ss.usermodel.HorizontalAlignment;\r
+\r
 \r
 \r
 public interface TextShape<T extends TextParagraph<? extends TextRun>> extends SimpleShape, Iterable<T>  {\r
@@ -104,6 +106,16 @@ public interface TextShape<T extends TextParagraph<? extends TextRun>> extends S
      */\r
     VerticalAlignment getVerticalAlignment();\r
     \r
+    /**\r
+     * Returns if the text is centered.\r
+     * If true and if the individual paragraph settings allow it,\r
+     * the whole text block will be displayed centered, i.e. its left and right\r
+     * margin will be maximized while still keeping the alignment of the paragraphs\r
+     *\r
+     * @return true, if the text anchor is horizontal centered \r
+     */\r
+    boolean isHorizontalCentered();\r
+    \r
     /**\r
      * @return whether to wrap words within the bounding rectangle\r
      */\r
index 134f3e8ac0188d9eeffba8124044961b39a8e1e7..652314c204fb900fce9625cdd1e9718aae8a514d 100644 (file)
@@ -25,7 +25,7 @@ import junit.framework.TestCase;
 
 import java.io.*;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.hwpf.HWPFTestDataSamples;
 import org.apache.poi.poifs.filesystem.*;
 
index 6207a4597d518fa4c0e4f06af2c4d2b7c009e92a..34d5aee93d318d1724cbdf1b64eabbab410ff89c 100644 (file)
@@ -24,8 +24,8 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 
 public class HSLFTestDataSamples {
 
index 3de6032ae55dbcacae844dc3a168b2a9e8abe145..ae4339427333c83d0efdab494a5d7361629c0e92 100644 (file)
@@ -21,7 +21,7 @@ package org.apache.poi.hslf;
 import junit.framework.TestCase;
 
 import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.POIDataSamples;
 
 /**
index ae64b3614d2fd81358b18cde3857bd9b24ed8d80..a742528e2129b204e000608c7a6a2b628a2e4e00 100644 (file)
@@ -25,8 +25,8 @@ import java.io.FileNotFoundException;
 import junit.framework.TestCase;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
index 31a80ae3068eb84d9dbbe4c6fc3aa016b3002682..50d2370d6a64e045432548165c75b6870dff732b 100644 (file)
@@ -23,8 +23,8 @@ import junit.framework.TestCase;
 import java.io.*;
 import java.util.*;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.poifs.filesystem.*;
 import org.apache.poi.POIDataSamples;
 
index 732f609381b80da7c52f3727460d0aca23869bfe..d40a1e643710bd8dec8b0dab31bf95f54e890c89 100644 (file)
@@ -20,8 +20,8 @@ package org.apache.poi.hslf;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.POIDataSamples;
 
 /**
index a00d75d03edc38a780a22ff2f6e55a46e1831c84..55a4ca8bbd025c39dfc765508af4a9c2591100fe 100644 (file)
@@ -23,9 +23,9 @@ import java.util.List;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.POITestCase;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.model.OLEShape;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
index 71cd5f570d3fab384c3af02a9f25fbd948c4b542..f43f168ee71269ce39c6f6427fd371ea075a4d50 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hslf.model;
 
+import org.apache.poi.hslf.usermodel.TestTextRun;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
index 0d1cfd9e09ab2d6242b27f872015adc4dd6da2e4..92eca1ae5ddc4f6644ab67fea941b8ce8ee1583b 100644 (file)
@@ -33,7 +33,7 @@ import org.apache.poi.ddf.EscherProperties;
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.ddf.EscherSimpleProperty;
 import org.apache.poi.hslf.record.Document;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.junit.Test;
 
@@ -53,7 +53,7 @@ public final class TestBackground {
     public void defaults() {
         HSLFSlideShow ppt = new HSLFSlideShow();
 
-        assertEquals(HSLFFill.FILL_SOLID, ppt.getSlidesMasters()[0].getBackground().getFill().getFillType());
+        assertEquals(HSLFFill.FILL_SOLID, ppt.getSlideMasters().get(0).getBackground().getFill().getFillType());
 
         HSLFSlide slide = ppt.createSlide();
         assertTrue(slide.getFollowMasterBackground());
@@ -72,26 +72,26 @@ public final class TestBackground {
         HSLFFill fill;
         HSLFShape shape;
 
-        HSLFSlide[] slide = ppt.getSlides();
+        List<HSLFSlide> slide = ppt.getSlides();
 
-        fill = slide[0].getBackground().getFill();
+        fill = slide.get(0).getBackground().getFill();
         assertEquals(HSLFFill.FILL_PICTURE, fill.getFillType());
-        shape = slide[0].getShapes()[0];
+        shape = slide.get(0).getShapes().get(0);
         assertEquals(HSLFFill.FILL_SOLID, shape.getFill().getFillType());
 
-        fill = slide[1].getBackground().getFill();
+        fill = slide.get(1).getBackground().getFill();
         assertEquals(HSLFFill.FILL_PATTERN, fill.getFillType());
-        shape = slide[1].getShapes()[0];
+        shape = slide.get(1).getShapes().get(0);
         assertEquals(HSLFFill.FILL_BACKGROUND, shape.getFill().getFillType());
 
-        fill = slide[2].getBackground().getFill();
+        fill = slide.get(2).getBackground().getFill();
         assertEquals(HSLFFill.FILL_TEXTURE, fill.getFillType());
-        shape = slide[2].getShapes()[0];
+        shape = slide.get(2).getShapes().get(0);
         assertEquals(HSLFFill.FILL_PICTURE, shape.getFill().getFillType());
 
-        fill = slide[3].getBackground().getFill();
+        fill = slide.get(3).getBackground().getFill();
         assertEquals(HSLFFill.FILL_SHADE_CENTER, fill.getFillType());
-        shape = slide[3].getShapes()[0];
+        shape = slide.get(3).getShapes().get(0);
         assertEquals(HSLFFill.FILL_SHADE, shape.getFill().getFillType());
     }
 
@@ -174,29 +174,29 @@ public final class TestBackground {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        HSLFSlide[] slides = ppt.getSlides();
+        List<HSLFSlide> slides = ppt.getSlides();
 
-        fill = slides[0].getBackground().getFill();
+        fill = slides.get(0).getBackground().getFill();
         assertEquals(HSLFFill.FILL_PICTURE, fill.getFillType());
-        assertEquals(3, getFillPictureRefCount(slides[0].getBackground(), fill));
-        shape = slides[0].getShapes()[0];
+        assertEquals(3, getFillPictureRefCount(slides.get(0).getBackground(), fill));
+        shape = slides.get(0).getShapes().get(0);
         assertEquals(HSLFFill.FILL_SOLID, shape.getFill().getFillType());
 
-        fill = slides[1].getBackground().getFill();
+        fill = slides.get(1).getBackground().getFill();
         assertEquals(HSLFFill.FILL_PATTERN, fill.getFillType());
-        shape = slides[1].getShapes()[0];
+        shape = slides.get(1).getShapes().get(0);
         assertEquals(HSLFFill.FILL_BACKGROUND, shape.getFill().getFillType());
 
-        fill = slides[2].getBackground().getFill();
+        fill = slides.get(2).getBackground().getFill();
         assertEquals(HSLFFill.FILL_TEXTURE, fill.getFillType());
-        assertEquals(3, getFillPictureRefCount(slides[2].getBackground(), fill));
-        shape = slides[2].getShapes()[0];
+        assertEquals(3, getFillPictureRefCount(slides.get(2).getBackground(), fill));
+        shape = slides.get(2).getShapes().get(0);
         assertEquals(HSLFFill.FILL_PICTURE, shape.getFill().getFillType());
         assertEquals(1, getFillPictureRefCount(shape, fill));
 
-        fill = slides[3].getBackground().getFill();
+        fill = slides.get(3).getBackground().getFill();
         assertEquals(HSLFFill.FILL_SHADE_CENTER, fill.getFillType());
-        shape = slides[3].getShapes()[0];
+        shape = slides.get(3).getShapes().get(0);
         assertEquals(HSLFFill.FILL_SHADE, shape.getFill().getFillType());
 
     }
index 6d1365efbe8b300f910809903725948fb7d51fee..cdbf28cb60d67a35c870d2379569c24a7cea2397 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import java.awt.geom.Area;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
-import junit.framework.TestCase;
+import java.awt.geom.*;
+
+import org.apache.poi.hslf.usermodel.HSLFFreeformShape;
+import org.junit.Test;
 
 /**
  * Test Freeform object.
@@ -32,8 +33,9 @@ import junit.framework.TestCase;
  *
  * @author Yegor Kozlov
  */
-public final class TestFreeform extends TestCase {
+public final class TestFreeform {
 
+    @Test
     public void testClosedPath() {
 
         GeneralPath path1 = new GeneralPath();
@@ -50,6 +52,7 @@ public final class TestFreeform extends TestCase {
         assertTrue(new Area(path1).equals(new Area(path2)));
     }
 
+    @Test
     public void testLine() {
 
         GeneralPath path1 = new GeneralPath(new Line2D.Double(100, 100, 200, 100));
@@ -61,6 +64,7 @@ public final class TestFreeform extends TestCase {
         assertTrue(new Area(path1).equals(new Area(path2)));
     }
 
+    @Test
     public void testRectangle() {
 
         GeneralPath path1 = new GeneralPath(new Rectangle2D.Double(100, 100, 200, 50));
@@ -76,6 +80,7 @@ public final class TestFreeform extends TestCase {
      * Avoid NPE in  Freeform.getOutline() if either GEOMETRY__VERTICES or
      * GEOMETRY__SEGMENTINFO is missing, see Bugzilla 54188
      */
+    @Test
     public void test54188() {
 
         HSLFFreeformShape p = new HSLFFreeformShape();
index 8239a359d51b7acbf9050dc564c26cda4114359f..6a503fde4a5d040d34071c1d141175329a91d478 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import java.io.*;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
 
-import junit.framework.TestCase;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.HSLFSlide;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.junit.Test;
 
 /**
  * Test {@link org.apache.poi.hslf.model.HeadersFooters} object
  */
-public final class TestHeadersFooters extends TestCase
+public final class TestHeadersFooters
 {
 
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
-    public void testRead() throws Exception
-    {
+    @Test
+    public void testRead() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("headers_footers.ppt"));
 
         HeadersFooters slideHdd = ppt.getSlideHeadersFooters();
@@ -53,9 +58,9 @@ public final class TestHeadersFooters extends TestCase
         assertTrue(notesHdd.isUserDateVisible());
         assertNull(notesHdd.getDateTimeText());
 
-        HSLFSlide[] slide = ppt.getSlides();
+        List<HSLFSlide> slide = ppt.getSlides();
         //the first slide uses presentation-scope headers / footers
-        HeadersFooters hd1 = slide[0].getHeadersFooters();
+        HeadersFooters hd1 = slide.get(0).getHeadersFooters();
         assertEquals(slideHdd.isFooterVisible(), hd1.isFooterVisible());
         assertEquals(slideHdd.getFooterText(), hd1.getFooterText());
         assertEquals(slideHdd.isSlideNumberVisible(), hd1.isSlideNumberVisible());
@@ -65,7 +70,7 @@ public final class TestHeadersFooters extends TestCase
         assertEquals(slideHdd.getDateTimeText(), hd1.getDateTimeText());
 
         //the first slide uses per-slide headers / footers
-        HeadersFooters hd2 = slide[1].getHeadersFooters();
+        HeadersFooters hd2 = slide.get(1).getHeadersFooters();
         assertEquals(true, hd2.isFooterVisible());
         assertEquals("per-slide footer", hd2.getFooterText());
         assertEquals(true, hd2.isUserDateVisible());
@@ -75,8 +80,8 @@ public final class TestHeadersFooters extends TestCase
     /**
      * If Headers / Footers are not set, all the getters should return <code>false</code> or <code>null</code>
      */
-    public void testReadNoHeadersFooters() throws Exception
-    {
+    @Test
+    public void testReadNoHeadersFooters() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
 
         HeadersFooters slideHdd = ppt.getSlideHeadersFooters();
@@ -97,9 +102,8 @@ public final class TestHeadersFooters extends TestCase
         assertFalse(notesHdd.isUserDateVisible());
         assertNull(notesHdd.getDateTimeText());
 
-        HSLFSlide[] slide = ppt.getSlides();
-        for(int i=0 ; i < slide.length; i++){
-            HeadersFooters hd1 = slide[i].getHeadersFooters();
+        for(HSLFSlide s : ppt.getSlides()) {
+            HeadersFooters hd1 = s.getHeadersFooters();
             assertFalse(hd1.isFooterVisible());
             assertNull(hd1.getFooterText());
             assertFalse(hd1.isHeaderVisible());
@@ -112,8 +116,8 @@ public final class TestHeadersFooters extends TestCase
     /**
      * Test extraction of headers / footers from PPTs saved in Office 2007
      */
-    public void testRead2007() throws Exception
-    {
+    @Test
+    public void testRead2007() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("headers_footers_2007.ppt"));
 
         HeadersFooters slideHdd = ppt.getSlideHeadersFooters();
@@ -137,9 +141,9 @@ public final class TestHeadersFooters extends TestCase
         //assertEquals("08/12/08", notesHdd.getDateTimeText());
 
         //per-slide headers / footers
-        HSLFSlide[] slide = ppt.getSlides();
+        List<HSLFSlide> slide = ppt.getSlides();
         //the first slide uses presentation-scope headers / footers
-        HeadersFooters hd1 = slide[0].getHeadersFooters();
+        HeadersFooters hd1 = slide.get(0).getHeadersFooters();
         assertTrue(hd1.isFooterVisible());
         assertEquals("THE FOOTER TEXT", hd1.getFooterText());
         assertTrue(hd1.isSlideNumberVisible());
@@ -150,7 +154,7 @@ public final class TestHeadersFooters extends TestCase
         assertEquals("Wednesday, August 06, 2008", hd1.getDateTimeText());
 
         //the second slide uses custom per-slide headers / footers
-        HeadersFooters hd2 = slide[1].getHeadersFooters();
+        HeadersFooters hd2 = slide.get(1).getHeadersFooters();
         assertTrue(hd2.isFooterVisible());
         assertEquals("THE FOOTER TEXT FOR SLIDE 2", hd2.getFooterText());
         assertTrue(hd2.isSlideNumberVisible());
@@ -161,7 +165,7 @@ public final class TestHeadersFooters extends TestCase
         assertEquals("August 06, 2008", hd2.getDateTimeText());
 
         //the third slide uses per-slide headers / footers
-        HeadersFooters hd3 = slide[2].getHeadersFooters();
+        HeadersFooters hd3 = slide.get(2).getHeadersFooters();
         assertTrue(hd3.isFooterVisible());
         assertEquals("THE FOOTER TEXT", hd3.getFooterText());
         assertTrue(hd3.isSlideNumberVisible());
@@ -172,8 +176,8 @@ public final class TestHeadersFooters extends TestCase
         assertEquals("Wednesday, August 06, 2008", hd3.getDateTimeText());
     }
 
-    public void testCreateSlideFooters() throws Exception
-    {
+    @Test
+    public void testCreateSlideFooters() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow();
         HeadersFooters hdd = ppt.getSlideHeadersFooters();
         hdd.setFootersText("My slide footer");
@@ -190,8 +194,8 @@ public final class TestHeadersFooters extends TestCase
         assertEquals("My slide footer", hdd2.getFooterText());
     }
 
-    public void testCreateNotesFooters() throws Exception
-    {
+    @Test
+    public void testCreateNotesFooters() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow();
         HeadersFooters hdd = ppt.getNotesHeadersFooters();
         hdd.setFootersText("My notes footer");
index 83e6ca65825fa75d719566c5d7745d38797cf365..5438ac8af94b4a7128cd293c3876b8a985c0d7b4 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.TestCase;
+import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getRawText;
+import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.toExternalString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test Hyperlink.
  *
  * @author Yegor Kozlov
  */
-public final class TestHyperlink extends TestCase {
+public final class TestHyperlink {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
+    @Test
     public void testTextRunHyperlinks() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("WithLinks.ppt"));
 
-        HSLFTextParagraph[] run;
-        HSLFSlide slide;
-        slide = ppt.getSlides()[0];
-        run = slide.getTextRuns();
-        for (int i = 0; i < run.length; i++) {
-            String text = run[i].getText();
-            if (text.equals(
-                    "This page has two links:\n" +
-                    "http://jakarta.apache.org/poi/\n" +
-                    "\n" +
-                    "http://slashdot.org/\n" +
-                    "\n" +
-                    "In addition, its notes has one link")){
-
-                Hyperlink[] links = run[i].getHyperlinks();
-                assertNotNull(links);
-                assertEquals(2, links.length);
-
-                assertEquals("http://jakarta.apache.org/poi/", links[0].getTitle());
-                assertEquals("http://jakarta.apache.org/poi/", links[0].getAddress());
-                assertEquals("http://jakarta.apache.org/poi/", text.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
-
-                assertEquals("http://slashdot.org/", links[1].getTitle());
-                assertEquals("http://slashdot.org/", links[1].getAddress());
-                assertEquals("http://slashdot.org/", text.substring(links[1].getStartIndex(), links[1].getEndIndex()-1));
-
-            }
-        }
-
-        slide = ppt.getSlides()[1];
-        run = slide.getTextRuns();
-        for (int i = 0; i < run.length; i++) {
-            String text = run[i].getText();
-            if (text.equals(
-                    "I have the one link:\n" +
-                    "Jakarta HSSF")){
-
-                Hyperlink[] links = run[i].getHyperlinks();
-                assertNotNull(links);
-                assertEquals(1, links.length);
-
-                assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getTitle());
-                assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getAddress());
-                assertEquals("Jakarta HSSF", text.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
-
-            }
-        }
-
+        HSLFSlide slide = ppt.getSlides().get(0);
+        List<HSLFTextParagraph> para = slide.getTextParagraphs().get(1);
+        
+        String rawText = toExternalString(getRawText(para), para.get(0).getRunType());
+        String expected =
+            "This page has two links:\n"+
+            "http://jakarta.apache.org/poi/\n"+
+            "\n"+
+            "http://slashdot.org/\n"+
+            "\n"+
+            "In addition, its notes has one link";
+        assertEquals(expected, rawText);
+        
+        HSLFHyperlink[] links = HSLFHyperlink.find(para.get(1));
+        assertNotNull(links);
+        assertEquals(2, links.length);
+
+        assertEquals("http://jakarta.apache.org/poi/", links[0].getTitle());
+        assertEquals("http://jakarta.apache.org/poi/", links[0].getAddress());
+        assertEquals("http://jakarta.apache.org/poi/", rawText.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
+
+        assertEquals("http://slashdot.org/", links[1].getTitle());
+        assertEquals("http://slashdot.org/", links[1].getAddress());
+        assertEquals("http://slashdot.org/", rawText.substring(links[1].getStartIndex(), links[1].getEndIndex()-1));
+
+        slide = ppt.getSlides().get(1);
+        para = slide.getTextParagraphs().get(1);
+        rawText = toExternalString(getRawText(para), para.get(0).getRunType());
+        expected = 
+            "I have the one link:\n" +
+            "Jakarta HSSF";
+        assertEquals(expected, rawText);
+
+        links = HSLFHyperlink.find(para.get(1));
+        assertNotNull(links);
+        assertEquals(1, links.length);
+
+        assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getTitle());
+        assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getAddress());
+        assertEquals("Jakarta HSSF", rawText.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
     }
-
 }
index 11a64f63794345dc052271ec69f74a383d91fb3d..963beeefbe660fb73c75705dd2745c043d8e25d1 100644 (file)
@@ -24,6 +24,7 @@ import junit.framework.TestCase;
 import org.apache.poi.hslf.blip.BitmapPainter;
 import org.apache.poi.hslf.blip.ImagePainter;
 import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
 
 /**
  * Test Picture shape.
index 413ff8ebe8d5ceb52f81d5a8bd63a42e0dc38f0d..5d58b2538325c9c7061ae814e974c05382cfa066 100644 (file)
@@ -19,17 +19,20 @@ package org.apache.poi.hslf.model;
 
 import java.awt.Color;
 
-import junit.framework.TestCase;
-
+import org.apache.poi.hslf.usermodel.HSLFSlide;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
+import org.junit.Test;
 
 /**
  * Test Line shape.
  *
  * @author Yegor Kozlov
  */
-public final class TestLine extends TestCase {
+public final class TestLine {
 
+    @Test
     public void testCreateLines() {
         HSLFSlideShow ppt = new HSLFSlideShow();
 
@@ -44,31 +47,31 @@ public final class TestLine extends TestCase {
          */
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 200, 300, 0));
-        line.setLineStyle(Line.LINE_SIMPLE);
+        line.setLineCompound(LineCompound.SINGLE);
         line.setLineColor(Color.blue);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 230, 300, 0));
-        line.setLineStyle(Line.LINE_DOUBLE);
+        line.setLineCompound(LineCompound.DOUBLE);
         line.setLineWidth(3.5);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 260, 300, 0));
-        line.setLineStyle(Line.LINE_TRIPLE);
+        line.setLineCompound(LineCompound.TRIPLE);
         line.setLineWidth(6);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 290, 300, 0));
-        line.setLineStyle(Line.LINE_THICKTHIN);
+        line.setLineCompound(LineCompound.THICK_THIN);
         line.setLineWidth(4.5);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 320, 300, 0));
-        line.setLineStyle(Line.LINE_THINTHICK);
+        line.setLineCompound(LineCompound.THIN_THICK);
         line.setLineWidth(5.5);
         slide.addShape(line);
 
@@ -77,27 +80,27 @@ public final class TestLine extends TestCase {
          */
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(450, 200, 300, 0));
-        line.setLineDashing(Line.PEN_SOLID);
+        line.setLineDashing(LineDash.SOLID);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(450, 230, 300, 0));
-        line.setLineDashing(Line.PEN_PS_DASH);
+        line.setLineDashing(LineDash.DASH);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(450, 260, 300, 0));
-        line.setLineDashing(Line.PEN_DOT);
+        line.setLineDashing(LineDash.DOT);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(450, 290, 300, 0));
-        line.setLineDashing(Line.PEN_DOTGEL);
+        line.setLineDashing(LineDash.DASH_DOT);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(450, 320, 300, 0));
-        line.setLineDashing(Line.PEN_LONGDASHDOTDOTGEL);
+        line.setLineDashing(LineDash.LG_DASH_DOT_DOT);
         slide.addShape(line);
 
         /**
@@ -105,22 +108,22 @@ public final class TestLine extends TestCase {
          */
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 400, 300, 0));
-        line.setLineDashing(Line.PEN_DASHDOT);
-        line.setLineStyle(Line.LINE_TRIPLE);
+        line.setLineDashing(LineDash.DASH_DOT);
+        line.setLineCompound(LineCompound.TRIPLE);
         line.setLineWidth(5.0);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 430, 300, 0));
-        line.setLineDashing(Line.PEN_DASH);
-        line.setLineStyle(Line.LINE_THICKTHIN);
+        line.setLineDashing(LineDash.DASH);
+        line.setLineCompound(LineCompound.THICK_THIN);
         line.setLineWidth(4.0);
         slide.addShape(line);
 
         line = new Line();
         line.setAnchor(new java.awt.Rectangle(75, 460, 300, 0));
-        line.setLineDashing(Line.PEN_DOT);
-        line.setLineStyle(Line.LINE_DOUBLE);
+        line.setLineDashing(LineDash.DOT);
+        line.setLineCompound(LineCompound.DOUBLE);
         line.setLineWidth(8.0);
         slide.addShape(line);
     }
index 1b5bbd32985e3cc28146c4188dc82226af1d19c5..a83d8201236c667a1a17178ad3699e339ce26365 100644 (file)
 
 package org.apache.poi.hslf.model;
 
+import static org.junit.Assert.*;
+
 import java.awt.geom.Rectangle2D;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
-import junit.framework.TestCase;
-
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test <code>MovieShape</code> object.
  *
  * @author Yegor Kozlov
  */
-public final class TestMovieShape extends TestCase {
+public final class TestMovieShape {
 
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
+    @Test
     public void testCreate() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow();
 
@@ -57,8 +59,8 @@ public final class TestMovieShape extends TestCase {
         ppt.write(out);
 
         ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        slide = ppt.getSlides()[0];
-        shape = (MovieShape)slide.getShapes()[0];
+        slide = ppt.getSlides().get(0);
+        shape = (MovieShape)slide.getShapes().get(0);
         assertEquals(path, shape.getPath());
         assertFalse(shape.isAutoPlay());
     }
index 410f48226ac891aae376ef760697e40a5e5d7365..f58949117f2d20c9236750ecd28ac49531528ce4 100644 (file)
 package org.apache.poi.hslf.model;
 
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
 
 import java.awt.geom.Rectangle2D;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-
-import junit.framework.TestCase;
+import java.io.*;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hslf.usermodel.HSLFObjectData;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.IOUtils;
+import org.junit.Test;
 
-public final class TestOleEmbedding extends TestCase {
+public final class TestOleEmbedding {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
     /**
      * Tests support for OLE objects.
      *
      * @throws Exception if an error occurs.
      */
+    @Test
     public void testOleEmbedding2003() throws Exception {
         HSLFSlideShowImpl slideShow = new HSLFSlideShowImpl(_slTests.openResourceAsStream("ole2-embedding-2003.ppt"));
         // Placeholder EMFs for clients that don't support the OLE components.
@@ -59,16 +55,16 @@ public final class TestOleEmbedding extends TestCase {
         //assertDigestEquals("Wrong data for object 2", "b323604b2003a7299c77c2693b641495", objects[1].getData());
     }
 
+    @Test
     public void testOLEShape() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("ole2-embedding-2003.ppt"));
 
-        HSLFSlide slide = ppt.getSlides()[0];
-        HSLFShape[] sh = slide.getShapes();
+        HSLFSlide slide = ppt.getSlides().get(0);
         int cnt = 0;
-        for (int i = 0; i < sh.length; i++) {
-            if(sh[i] instanceof OLEShape){
+        for (HSLFShape sh : slide.getShapes()) {
+            if(sh instanceof OLEShape){
                 cnt++;
-                OLEShape ole = (OLEShape)sh[i];
+                OLEShape ole = (OLEShape)sh;
                 HSLFObjectData data = ole.getObjectData();
                 if("Worksheet".equals(ole.getInstanceName())){
                     //Voila! we created a workbook from the embedded OLE data
@@ -80,6 +76,7 @@ public final class TestOleEmbedding extends TestCase {
                     assertEquals(2, sheet.getRow(2).getCell(0).getNumericCellValue(), 0);
                     assertEquals(3, sheet.getRow(3).getCell(0).getNumericCellValue(), 0);
                     assertEquals(8, sheet.getRow(5).getCell(0).getNumericCellValue(), 0);
+                    wb.close();
                 } else if ("Document".equals(ole.getInstanceName())){
                     //creating a HWPF document
                     HWPFDocument doc = new HWPFDocument(data.getData());
@@ -92,6 +89,7 @@ public final class TestOleEmbedding extends TestCase {
         assertEquals("Expected 2 OLE shapes", 2, cnt);
     }
     
+    @Test
     public void testEmbedding() throws Exception {
        HSLFSlideShowImpl _hslfSlideShow = HSLFSlideShowImpl.create();
        HSLFSlideShow ppt = new HSLFSlideShow(_hslfSlideShow);
@@ -129,7 +127,7 @@ public final class TestOleEmbedding extends TestCase {
        ppt.write(bos);
        
        ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
-       OLEShape comp = (OLEShape)ppt.getSlides()[0].getShapes()[0];
+       OLEShape comp = (OLEShape)ppt.getSlides().get(0).getShapes().get(0);
        byte compData[] = IOUtils.toByteArray(comp.getObjectData().getData());
        
        bos.reset();
index fb04ccf5dded1218c0b275d0ac96aa943545a75f..4c69862c3bf3a3cfe84d9614872f3367705da265 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.junit.Test;
+
 
 /**
  * Test adding fonts to the presenataion resources
  *
  * @author Yegor Kozlov
  */
-public final class TestPPFont extends TestCase{
+public final class TestPPFont {
 
+    @Test
     public void testCreate() {
         HSLFSlideShow ppt = new HSLFSlideShow();
         assertEquals(1, ppt.getNumberOfFonts());
index b71ce010359738a630fa951c559076a41d1899b1..4fb06ddcf3d67c57b1e1a0b99b518cedc15554fa 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.TestCase;
-
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.awt.*;
-import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * Test drawing shapes via Graphics2D
  *
  * @author Yegor Kozlov
  */
-public final class TestPPGraphics2D extends TestCase {
+public final class TestPPGraphics2D {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
     private HSLFSlideShow ppt;
 
+    @Before
     protected void setUp() throws Exception {
                ppt = new HSLFSlideShow(_slTests.openResourceAsStream("empty.ppt"));
     }
 
+    @Test
     public void testGraphics() throws Exception {
        // Starts off empty
-       assertEquals(0, ppt.getSlides().length);
+       assertTrue(ppt.getSlides().isEmpty());
 
        // Add a slide
         HSLFSlide slide = ppt.createSlide();
-       assertEquals(1, ppt.getSlides().length);
+       assertEquals(1, ppt.getSlides().size());
 
        // Add some stuff into it
         HSLFGroupShape group = new HSLFGroupShape();
@@ -73,17 +79,17 @@ public final class TestPPGraphics2D extends TestCase {
 
         // And read it back in
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertEquals(1, ppt.getSlides().length);
+        assertEquals(1, ppt.getSlides().size());
 
-        slide = ppt.getSlides()[0];
-        HSLFShape[] shape = slide.getShapes();
-        assertEquals(shape.length, 1); //group shape
+        slide = ppt.getSlides().get(0);
+        List<HSLFShape> shape = slide.getShapes();
+        assertEquals(shape.size(), 1); //group shape
 
-        assertTrue(shape[0] instanceof HSLFGroupShape); //group shape
+        assertTrue(shape.get(0) instanceof HSLFGroupShape); //group shape
 
-        group = (HSLFGroupShape)shape[0];
+        group = (HSLFGroupShape)shape.get(0);
         shape = group.getShapes();
-        assertEquals(shape.length, 3);
+        assertEquals(shape.size(), 3);
     }
 
 }
index 08077f0e0054927bf8ba37e7bba4afdda8be90ec..ff4e1c5a7a1af851af7dc207e51011c6029dab82 100644 (file)
@@ -36,8 +36,7 @@ import javax.imageio.ImageIO;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.hslf.usermodel.HSLFPictureData;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.util.JvmBugs;
 import org.junit.Ignore;
 import org.junit.Test;
index e1703626ca42871acb2d4b68b9d1e7ca8d5112e5..febf9e3b206cba2a98825ce26d40c1b610ad183a 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.*;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-
-import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test setting text properties of newly added TextBoxes
  *
  * @author Yegor Kozlov
  */
-public final class TestSetBoldItalic extends TestCase {
+public final class TestSetBoldItalic {
     /**
      * Verify that we can add TextBox shapes to a slide
      * and set some of the style attributes
      */
+    @Test
     public void testTextBoxWrite() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow();
         HSLFSlide sl = ppt.createSlide();
@@ -44,7 +45,7 @@ public final class TestSetBoldItalic extends TestCase {
 
         // Create a new textbox, and give it lots of properties
         HSLFTextBox txtbox = new HSLFTextBox();
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
         txtbox.setText(val);
         rt.setFontSize(42);
         rt.setBold(true);
@@ -53,9 +54,9 @@ public final class TestSetBoldItalic extends TestCase {
         sl.addShape(txtbox);
 
         // Check it before save
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
+        assertEquals(val, rt.getRawText());
+        assertEquals(42, rt.getFontSize(), 0);
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
 
@@ -65,14 +66,14 @@ public final class TestSetBoldItalic extends TestCase {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        sl = ppt.getSlides()[0];
+        sl = ppt.getSlides().get(0);
 
-        txtbox = (HSLFTextBox)sl.getShapes()[0];
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
+        txtbox = (HSLFTextBox)sl.getShapes().get(0);
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
 
         // Check after save
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
+        assertEquals(val, rt.getRawText());
+        assertEquals(42, rt.getFontSize(), 0);
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
index 9456c211f8627b71d430956bf3fa714cce44378b..d38a21ecab8d1b3741f0e5def7b73339d3f93941 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import static org.junit.Assert.*;
+
+import java.awt.*;
+import java.io.*;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -77,7 +65,7 @@ public final class TestShapes {
         java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60);
         line.setAnchor(lineAnchor);
         line.setLineWidth(3);
-        line.setLineStyle(Line.PEN_DASH);
+        line.setLineDashing(LineDash.DASH);
         line.setLineColor(Color.red);
         slide.addShape(line);
 
@@ -85,7 +73,7 @@ public final class TestShapes {
         java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111);
         ellipse.setAnchor(ellipseAnchor);
         ellipse.setLineWidth(2);
-        ellipse.setLineStyle(Line.PEN_SOLID);
+        ellipse.setLineDashing(LineDash.SOLID);
         ellipse.setLineColor(Color.green);
         ellipse.setFillColor(Color.lightGray);
         slide.addShape(ellipse);
@@ -97,17 +85,17 @@ public final class TestShapes {
         //read ppt from byte array
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertEquals(1, ppt.getSlides().length);
+        assertEquals(1, ppt.getSlides().size());
 
-        slide = ppt.getSlides()[0];
-        HSLFShape[] shape = slide.getShapes();
-        assertEquals(2, shape.length);
+        slide = ppt.getSlides().get(0);
+        List<HSLFShape> shape = slide.getShapes();
+        assertEquals(2, shape.size());
 
-        assertTrue(shape[0] instanceof Line); //group shape
-        assertEquals(lineAnchor, shape[0].getAnchor()); //group shape
+        assertTrue(shape.get(0) instanceof Line); //group shape
+        assertEquals(lineAnchor, shape.get(0).getAnchor()); //group shape
 
-        assertTrue(shape[1] instanceof HSLFAutoShape); //group shape
-        assertEquals(ellipseAnchor, shape[1].getAnchor()); //group shape
+        assertTrue(shape.get(1) instanceof HSLFAutoShape); //group shape
+        assertEquals(ellipseAnchor, shape.get(1).getAnchor()); //group shape
     }
 
     /**
@@ -117,31 +105,30 @@ public final class TestShapes {
     @Test
     public void textBoxRead() throws Exception {
         ppt = new HSLFSlideShow(_slTests.openResourceAsStream("with_textbox.ppt"));
-        HSLFSlide sl = ppt.getSlides()[0];
-        HSLFShape[] sh = sl.getShapes();
-        for (int i = 0; i < sh.length; i++) {
-            assertTrue(sh[i] instanceof HSLFTextBox);
-            HSLFTextBox txtbox = (HSLFTextBox)sh[i];
+        HSLFSlide sl = ppt.getSlides().get(0);
+        for (HSLFShape sh : sl.getShapes()) {
+            assertTrue(sh instanceof HSLFTextBox);
+            HSLFTextBox txtbox = (HSLFTextBox)sh;
             String text = txtbox.getText();
             assertNotNull(text);
 
-            assertEquals(txtbox.getTextParagraph().getRichTextRuns().length, 1);
-            HSLFTextRun rt = txtbox.getTextParagraph().getRichTextRuns()[0];
+            assertEquals(txtbox.getTextParagraphs().get(0).getTextRuns().size(), 1);
+            HSLFTextRun rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
 
             if (text.equals("Hello, World!!!")){
-                assertEquals(32, rt.getFontSize());
+                assertEquals(32, rt.getFontSize(), 0);
                 assertTrue(rt.isBold());
                 assertTrue(rt.isItalic());
             } else if (text.equals("I am just a poor boy")){
-                assertEquals(44, rt.getFontSize());
+                assertEquals(44, rt.getFontSize(), 0);
                 assertTrue(rt.isBold());
             } else if (text.equals("This is Times New Roman")){
-                assertEquals(16, rt.getFontSize());
+                assertEquals(16, rt.getFontSize(), 0);
                 assertTrue(rt.isBold());
                 assertTrue(rt.isItalic());
                 assertTrue(rt.isUnderlined());
             } else if (text.equals("Plain Text")){
-                assertEquals(18, rt.getFontSize());
+                assertEquals(18, rt.getFontSize(), 0);
             }
         }
     }
@@ -160,7 +147,7 @@ public final class TestShapes {
 
         // Create a new textbox, and give it lots of properties
         HSLFTextBox txtbox = new HSLFTextBox();
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
         txtbox.setText(val);
         rt.setFontName("Arial");
         rt.setFontSize(42);
@@ -171,13 +158,13 @@ public final class TestShapes {
         sl.addShape(txtbox);
 
         // Check it before save
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
+        assertEquals(val, rt.getRawText());
+        assertEquals(42, rt.getFontSize(), 0);
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
-        assertEquals("Arial", rt.getFontName());
+        assertEquals("Arial", rt.getFontFamily());
         assertEquals(Color.red, rt.getFontColor());
 
         // Serialize and read again
@@ -186,18 +173,18 @@ public final class TestShapes {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        sl = ppt.getSlides()[0];
+        sl = ppt.getSlides().get(0);
 
-        txtbox = (HSLFTextBox)sl.getShapes()[0];
-        rt = txtbox.getTextParagraph().getRichTextRuns()[0];
+        txtbox = (HSLFTextBox)sl.getShapes().get(0);
+        rt = txtbox.getTextParagraphs().get(0).getTextRuns().get(0);
 
         // Check after save
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
+        assertEquals(val, rt.getRawText());
+        assertEquals(42, rt.getFontSize(), 0);
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
-        assertEquals("Arial", rt.getFontName());
+        assertEquals("Arial", rt.getFontFamily());
         assertEquals(Color.red, rt.getFontColor());
     }
 
@@ -206,13 +193,13 @@ public final class TestShapes {
      */
     @Test
     public void emptyTextBox() {
-       assertEquals(2, pptB.getSlides().length);
-       HSLFSlide s1 = pptB.getSlides()[0];
-       HSLFSlide s2 = pptB.getSlides()[1];
+       assertEquals(2, pptB.getSlides().size());
+       HSLFSlide s1 = pptB.getSlides().get(0);
+       HSLFSlide s2 = pptB.getSlides().get(1);
 
        // Check we can get the shapes count
-       assertEquals(2, s1.getShapes().length);
-       assertEquals(2, s2.getShapes().length);
+       assertEquals(2, s1.getShapes().size());
+       assertEquals(2, s2.getShapes().size());
     }
 
     /**
@@ -231,19 +218,20 @@ public final class TestShapes {
 
     private void textBoxSet(String filename) throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(filename));
-        HSLFSlide[] sl = ppt.getSlides();
-        for (int k = 0; k < sl.length; k++) {
+        for (HSLFSlide sld : ppt.getSlides()) {
             ArrayList<String> lst1 = new ArrayList<String>();
-            HSLFTextParagraph[] txt = sl[k].getTextRuns();
-            for (int i = 0; i < txt.length; i++) {
-                lst1.add(txt[i].getText());
+            for (List<HSLFTextParagraph> txt : sld.getTextParagraphs()) {
+                for (HSLFTextParagraph p : txt) {
+                    for (HSLFTextRun r : p) {
+                        lst1.add(r.getRawText());
+                    }
+                }
             }
 
             ArrayList<String> lst2 = new ArrayList<String>();
-            HSLFShape[] sh = sl[k].getShapes();
-            for (int i = 0; i < sh.length; i++) {
-                if (sh[i] instanceof HSLFTextShape){
-                    HSLFTextShape tbox = (HSLFTextShape)sh[i];
+            for (HSLFShape sh : sld.getShapes()) {
+                if (sh instanceof HSLFTextShape){
+                    HSLFTextShape tbox = (HSLFTextShape)sh;
                     lst2.add(tbox.getText());
                 }
             }
@@ -285,22 +273,22 @@ public final class TestShapes {
         ppt = new HSLFSlideShow(is);
         is.close();
 
-        slide = ppt.getSlides()[0];
+        slide = ppt.getSlides().get(0);
 
-        HSLFShape[] shape = slide.getShapes();
-        assertEquals(1, shape.length);
-        assertTrue(shape[0] instanceof HSLFGroupShape);
+        List<HSLFShape> shape = slide.getShapes();
+        assertEquals(1, shape.size());
+        assertTrue(shape.get(0) instanceof HSLFGroupShape);
 
-        group = (HSLFGroupShape)shape[0];
-        HSLFShape[] grshape = group.getShapes();
-        assertEquals(2, grshape.length);
-        assertTrue(grshape[0] instanceof HSLFPictureShape);
-        assertTrue(grshape[1] instanceof Line);
+        group = (HSLFGroupShape)shape.get(0);
+        List<HSLFShape> grshape = group.getShapes();
+        assertEquals(2, grshape.size());
+        assertTrue(grshape.get(0) instanceof HSLFPictureShape);
+        assertTrue(grshape.get(1) instanceof Line);
 
-        pict = (HSLFPictureShape)grshape[0];
+        pict = (HSLFPictureShape)grshape.get(0);
         assertEquals(new Rectangle(0, 0, 200, 200), pict.getAnchor());
 
-        line = (Line)grshape[1];
+        line = (Line)grshape.get(1);
         assertEquals(new Rectangle(300, 300, 500, 0), line.getAnchor());
     }
 
@@ -311,16 +299,16 @@ public final class TestShapes {
     public void removeShapes() throws IOException {
         String file = "with_textbox.ppt";
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(file));
-        HSLFSlide sl = ppt.getSlides()[0];
-        HSLFShape[] sh = sl.getShapes();
-        assertEquals("expected four shaped in " + file, 4, sh.length);
+        HSLFSlide sl = ppt.getSlides().get(0);
+        List<HSLFShape> sh = sl.getShapes();
+        assertEquals("expected four shaped in " + file, 4, sh.size());
         //remove all
-        for (int i = 0; i < sh.length; i++) {
-            boolean ok = sl.removeShape(sh[i]);
+        for (int i = 0; i < sh.size(); i++) {
+            boolean ok = sl.removeShape(sh.get(i));
             assertTrue("Failed to delete shape #" + i, ok);
         }
         //now Slide.getShapes() should return an empty array
-        assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length);
+        assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().size());
 
         //serialize and read again. The file should be readable and contain no shapes
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -328,8 +316,8 @@ public final class TestShapes {
         out.close();
 
         ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        sl = ppt.getSlides()[0];
-        assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length);
+        sl = ppt.getSlides().get(0);
+        assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().size());
     }
 
     @Test
@@ -400,24 +388,24 @@ public final class TestShapes {
     @Test
     public void lineColor() throws IOException {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("51731.ppt"));
-        HSLFShape[] shape = ppt.getSlides()[0].getShapes();
+        List<HSLFShape> shape = ppt.getSlides().get(0).getShapes();
 
-        assertEquals(4, shape.length);
+        assertEquals(4, shape.size());
 
-        HSLFTextShape sh1 = (HSLFTextShape)shape[0];
+        HSLFTextShape sh1 = (HSLFTextShape)shape.get(0);
         assertEquals("Hello Apache POI", sh1.getText());
         assertNull(sh1.getLineColor());
 
-        HSLFTextShape sh2 = (HSLFTextShape)shape[1];
+        HSLFTextShape sh2 = (HSLFTextShape)shape.get(1);
         assertEquals("Why are you showing this border?", sh2.getText());
         assertNull(sh2.getLineColor());
 
-        HSLFTextShape sh3 = (HSLFTextShape)shape[2];
+        HSLFTextShape sh3 = (HSLFTextShape)shape.get(2);
         assertEquals("Text in a black border", sh3.getText());
         assertEquals(Color.black, sh3.getLineColor());
         assertEquals(0.75, sh3.getLineWidth(), 0);
 
-        HSLFTextShape sh4 = (HSLFTextShape)shape[3];
+        HSLFTextShape sh4 = (HSLFTextShape)shape.get(3);
         assertEquals("Border width is 5 pt", sh4.getText());
         assertEquals(Color.black, sh4.getLineColor());
         assertEquals(5.0, sh4.getLineWidth(), 0);
index 60b8ca42e2346990f224d68f24f53ab227d63404..330c832486a0dcbc07378c1cbed05991a8223ec5 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
+import java.util.List;
+
+import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
 import org.apache.poi.hslf.record.PPDrawing;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test common functionality of the <code>Sheet</code> object.
@@ -32,12 +35,13 @@ import org.apache.poi.POIDataSamples;
  *
  * @author Yegor Kozlov
  */
-public final class TestSheet extends TestCase {
+public final class TestSheet {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
     /**
      * For each ppt in the test directory check that all sheets are properly initialized
      */
+    @Test
     public void testSheet() throws Exception {
         String[] tests = {"SampleShow.ppt", "backgrounds.ppt", "text_shapes.ppt", "pictures.ppt"};
         for (String file : tests) {
@@ -51,14 +55,13 @@ public final class TestSheet extends TestCase {
     }
 
     private void doSlideShow(HSLFSlideShow ppt) {
-        HSLFSlide[] slide = ppt.getSlides();
-        for (int i = 0; i < slide.length; i++) {
-            verify(slide[i]);
+        for (HSLFSlide slide : ppt.getSlides()) {
+            verify(slide);
 
-            HSLFNotes notes = slide[i].getNotesSheet();
+            HSLFNotes notes = slide.getNotes();
             if(notes != null) verify(notes);
 
-            HSLFMasterSheet master = slide[i].getMasterSheet();
+            HSLFMasterSheet master = slide.getMasterSheet();
             assertNotNull(master);
             verify(master);
         }
@@ -79,23 +82,19 @@ public final class TestSheet extends TestCase {
         assertTrue(sheet._getSheetNumber() != 0);
         assertTrue(sheet._getSheetRefId() != 0);
 
-        HSLFTextParagraph[] txt = sheet.getTextRuns();
-        if (txt == null) {
-            throw new AssertionFailedError("no text runs");
-        }
-        for (int i = 0; i < txt.length; i++) {
-            assertNotNull(txt[i].getSheet());
+        List<HSLFTextParagraph> txt = sheet.getTextParagraphs();
+        assertTrue("no text runs", txt != null && !txt.isEmpty());
+        for (HSLFTextParagraph t : txt) {
+            assertNotNull(t.getSheet());
         }
 
-        HSLFShape[] shape = sheet.getShapes();
-        if (shape == null) {
-            throw new AssertionFailedError("no shapes");
-        }
-        for (int i = 0; i < shape.length; i++) {
-            assertNotNull(shape[i].getSpContainer());
-            assertNotNull(shape[i].getSheet());
-            assertNotNull(shape[i].getShapeName());
-            assertNotNull(shape[i].getAnchor());
+        List<HSLFShape> shape = sheet.getShapes();
+        assertTrue("no shapes", shape != null && !shape.isEmpty());
+        for (HSLFShape s : shape) {
+            assertNotNull(s.getSpContainer());
+            assertNotNull(s.getSheet());
+            assertNotNull(s.getShapeName());
+            assertNotNull(s.getAnchor());
         }
     }
 }
index 2d4fe151310e133a05f5afc827a47d53edb3d715..57f6f5adb9dc99313e6062c22ad07efead7c3f10 100644 (file)
 package org.apache.poi.hslf.model;
 
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
 
-import org.apache.poi.hslf.record.SlideAtom;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.record.SlideAtom;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * Tests that changing a slide's idea of what notes sheet is its works right
  *
  * @author Nick Burch (nick at torchbox dot com)
  */
-public final class TestSlideChangeNotes extends TestCase {
+public final class TestSlideChangeNotes {
        // SlideShow primed on the test data
        private HSLFSlideShow ss;
 
-       public TestSlideChangeNotes() throws Exception {
+       @Before
+       public void init() throws Exception {
         POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
                HSLFSlideShowImpl hss = new HSLFSlideShowImpl(_slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
                ss = new HSLFSlideShow(hss);
        }
 
+       @Test
        public void testSetToNone() {
-               HSLFSlide slideOne = ss.getSlides()[0];
+               HSLFSlide slideOne = ss.getSlides().get(0);
                SlideAtom sa = slideOne.getSlideRecord().getSlideAtom();
 
                slideOne.setNotes(null);
@@ -48,9 +52,10 @@ public final class TestSlideChangeNotes extends TestCase {
                assertEquals(0, sa.getNotesID());
        }
 
+       @Test
        public void testSetToSomething() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFNotes notesOne = ss.getNotes()[1];
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               HSLFNotes notesOne = ss.getNotes().get(1);
                SlideAtom sa = slideOne.getSlideRecord().getSlideAtom();
 
                slideOne.setNotes(notesOne);
index ffb6563da5b20fd8a39d0953628bc5dc9b32a20b..e6b24ce1b9c18385d145a4410128f8122729cc53 100644 (file)
 
 package org.apache.poi.hslf.model;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.util.List;
 
-import junit.framework.TestCase;
-
+import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
 import org.apache.poi.hslf.record.Environment;
 import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Tests for SlideMaster
  *
  * @author Yegor Kozlov
  */
-public final class TestSlideMaster extends TestCase{
+public final class TestSlideMaster {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
     /**
      * The reference ppt has two masters.
      * Check we can read their attributes.
      */
+    @Test
     public void testSlideMaster() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
 
         Environment env = ppt.getDocumentRecord().getEnvironment();
 
-        SlideMaster[] master = ppt.getSlidesMasters();
-        assertEquals(2, master.length);
+        List<HSLFSlideMaster> master = ppt.getSlideMasters();
+        assertEquals(2, master.size());
 
         //character attributes
-        assertEquals(40, master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
-        assertEquals(48, master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
+        assertEquals(40, master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
+        assertEquals(48, master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
 
-        int font1 = master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
-        int font2 = master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
+        int font1 = master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
+        int font2 = master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
         assertEquals("Arial", env.getFontCollection().getFontWithId(font1));
         assertEquals("Georgia", env.getFontCollection().getFontWithId(font2));
 
-        CharFlagsTextProp prop1 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
+        CharFlagsTextProp prop1 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
         assertEquals(false, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
         assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
         assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
 
-        CharFlagsTextProp prop2 = (CharFlagsTextProp)master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
+        CharFlagsTextProp prop2 = (CharFlagsTextProp)master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
         assertEquals(false, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
         assertEquals(true, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX));
         assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
 
         //now paragraph attributes
-        assertEquals(0x266B, master[0].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
-        assertEquals(0x2022, master[1].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
+        assertEquals(0x266B, master.get(0).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
+        assertEquals(0x2022, master.get(1).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
 
-        int b1 = master[0].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
-        int b2 = master[1].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
+        int b1 = master.get(0).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
+        int b2 = master.get(1).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
         assertEquals("Arial", env.getFontCollection().getFontWithId(b1));
         assertEquals("Georgia", env.getFontCollection().getFontWithId(b2));
     }
@@ -81,19 +84,20 @@ public final class TestSlideMaster extends TestCase{
     /**
      * Test we can read default text attributes for a title master sheet
      */
+    @Test
     public void testTitleMasterTextAttributes() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
-        TitleMaster[] master = ppt.getTitleMasters();
-        assertEquals(1, master.length);
+        List<HSLFTitleMaster> master = ppt.getTitleMasters();
+        assertEquals(1, master.size());
 
-        assertEquals(32, master[0].getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "font.size", true).getValue());
-        CharFlagsTextProp prop1 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "char_flags", true);
+        assertEquals(32, master.get(0).getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "font.size", true).getValue());
+        CharFlagsTextProp prop1 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "char_flags", true);
         assertEquals(true, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
         assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
         assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
 
-        assertEquals(20, master[0].getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "font.size", true).getValue());
-        CharFlagsTextProp prop2 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "char_flags", true);
+        assertEquals(20, master.get(0).getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "font.size", true).getValue());
+        CharFlagsTextProp prop2 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "char_flags", true);
         assertEquals(true, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
         assertEquals(false, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX));
         assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
@@ -102,25 +106,26 @@ public final class TestSlideMaster extends TestCase{
     /**
      * Slide 3 has title layout and follows the TitleMaster. Verify that.
      */
+    @Test
     public void testTitleMaster() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
-        HSLFSlide slide = ppt.getSlides()[2];
+        HSLFSlide slide = ppt.getSlides().get(2);
         HSLFMasterSheet masterSheet = slide.getMasterSheet();
-        assertTrue(masterSheet instanceof TitleMaster);
+        assertTrue(masterSheet instanceof HSLFTitleMaster);
 
-        HSLFTextParagraph[] txt = slide.getTextRuns();
-        for (int i = 0; i < txt.length; i++) {
-            HSLFTextRun rt = txt[i].getRichTextRuns()[0];
-            switch(txt[i].getRunType()){
+        List<HSLFTextParagraph> txt = slide.getTextParagraphs();
+        for (int i = 0; i < txt.size(); i++) {
+            HSLFTextRun rt = txt.get(i).getTextRuns().get(0);
+            switch(txt.get(i).getRunType()){
                 case TextHeaderAtom.CENTER_TITLE_TYPE:
-                    assertEquals("Arial", rt.getFontName());
-                    assertEquals(32, rt.getFontSize());
+                    assertEquals("Arial", rt.getFontFamily());
+                    assertEquals(32, rt.getFontSize(), 0);
                     assertEquals(true, rt.isBold());
                     assertEquals(true, rt.isUnderlined());
                     break;
                 case TextHeaderAtom.CENTRE_BODY_TYPE:
-                    assertEquals("Courier New", rt.getFontName());
-                    assertEquals(20, rt.getFontSize());
+                    assertEquals("Courier New", rt.getFontFamily());
+                    assertEquals(20, rt.getFontSize(), 0);
                     assertEquals(true, rt.isBold());
                     assertEquals(false, rt.isUnderlined());
                     break;
@@ -131,47 +136,44 @@ public final class TestSlideMaster extends TestCase{
     /**
      * If a style attribute is not set ensure it is read from the master
      */
+    @Test
     public void testMasterAttributes() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
-        HSLFSlide[] slide = ppt.getSlides();
-        assertEquals(3, slide.length);
-        HSLFTextParagraph[] trun;
-
-        trun = slide[0].getTextRuns();
-        for (int i = 0; i < trun.length; i++) {
-            if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){
-                HSLFTextRun rt = trun[i].getRichTextRuns()[0];
-                assertEquals(40, rt.getFontSize());
+        List<HSLFSlide> slide = ppt.getSlides();
+        assertEquals(3, slide.size());
+        for (HSLFTextParagraph trun : slide.get(0).getTextParagraphs()) {
+            if (trun.getRunType() == TextHeaderAtom.TITLE_TYPE){
+                HSLFTextRun rt = trun.getTextRuns().get(0);
+                assertEquals(40, rt.getFontSize(), 0);
                 assertEquals(true, rt.isUnderlined());
-                assertEquals("Arial", rt.getFontName());
-            } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){
-                HSLFTextRun rt;
-                rt = trun[i].getRichTextRuns()[0];
-                assertEquals(0, rt.getIndentLevel());
-                assertEquals(32, rt.getFontSize());
-                assertEquals("Arial", rt.getFontName());
-
-                rt = trun[i].getRichTextRuns()[1];
-                assertEquals(1, rt.getIndentLevel());
-                assertEquals(28, rt.getFontSize());
-                assertEquals("Arial", rt.getFontName());
+                assertEquals("Arial", rt.getFontFamily());
+            } else if (trun.getRunType() == TextHeaderAtom.BODY_TYPE){
+                HSLFTextRun rt = trun.getTextRuns().get(0);
+                assertEquals(0, trun.getIndentLevel());
+                assertEquals(32, rt.getFontSize(), 0);
+                assertEquals("Arial", rt.getFontFamily());
+
+                rt = trun.getTextRuns().get(1);
+                assertEquals(1, trun.getIndentLevel());
+                assertEquals(28, rt.getFontSize(), 0);
+                assertEquals("Arial", rt.getFontFamily());
 
             }
         }
 
-        trun = slide[1].getTextRuns();
-        for (int i = 0; i < trun.length; i++) {
-            if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){
-                HSLFTextRun rt = trun[i].getRichTextRuns()[0];
-                assertEquals(48, rt.getFontSize());
+        ;
+        for (HSLFTextParagraph trun : slide.get(1).getTextParagraphs()) {
+            if (trun.getRunType() == TextHeaderAtom.TITLE_TYPE){
+                HSLFTextRun rt = trun.getTextRuns().get(0);
+                assertEquals(48, rt.getFontSize(), 0);
                 assertEquals(true, rt.isItalic());
-                assertEquals("Georgia", rt.getFontName());
-            } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){
+                assertEquals("Georgia", rt.getFontFamily());
+            } else if (trun.getRunType() == TextHeaderAtom.BODY_TYPE){
                 HSLFTextRun rt;
-                rt = trun[i].getRichTextRuns()[0];
-                assertEquals(0, rt.getIndentLevel());
-                assertEquals(32, rt.getFontSize());
-                assertEquals("Courier New", rt.getFontName());
+                rt = trun.getTextRuns().get(0);
+                assertEquals(0, trun.getIndentLevel());
+                assertEquals(32, rt.getFontSize(), 0);
+                assertEquals("Courier New", rt.getFontFamily());
             }
         }
 
@@ -180,20 +182,21 @@ public final class TestSlideMaster extends TestCase{
     /**
      * Check we can dynamically assign a slide master to a slide.
      */
+    @Test
     public void testChangeSlideMaster() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
-        SlideMaster[] master = ppt.getSlidesMasters();
-        HSLFSlide[] slide = ppt.getSlides();
+        List<HSLFSlideMaster> master = ppt.getSlideMasters();
+        List<HSLFSlide> slide = ppt.getSlides();
         int sheetNo;
 
         //each slide uses its own master
-        assertEquals(slide[0].getMasterSheet()._getSheetNumber(), master[0]._getSheetNumber());
-        assertEquals(slide[1].getMasterSheet()._getSheetNumber(), master[1]._getSheetNumber());
+        assertEquals(slide.get(0).getMasterSheet()._getSheetNumber(), master.get(0)._getSheetNumber());
+        assertEquals(slide.get(1).getMasterSheet()._getSheetNumber(), master.get(1)._getSheetNumber());
 
         //all slides use the first master slide
-        sheetNo = master[0]._getSheetNumber();
-        for (int i = 0; i < slide.length; i++) {
-            slide[i].setMasterSheet(master[0]);
+        sheetNo = master.get(0)._getSheetNumber();
+        for (HSLFSlide s : slide) {
+            s.setMasterSheet(master.get(0));
         }
 
         ByteArrayOutputStream out;
@@ -203,10 +206,10 @@ public final class TestSlideMaster extends TestCase{
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        master = ppt.getSlidesMasters();
+        master = ppt.getSlideMasters();
         slide = ppt.getSlides();
-        for (int i = 0; i < slide.length; i++) {
-            assertEquals(sheetNo, slide[i].getMasterSheet()._getSheetNumber());
+        for (HSLFSlide s : slide) {
+            assertEquals(sheetNo, s.getMasterSheet()._getSheetNumber());
         }
     }
 
@@ -214,33 +217,22 @@ public final class TestSlideMaster extends TestCase{
      * Varify we can read attrubutes for different identtation levels.
      * (typical for the "bullted body" placeholder)
      */
+    @Test
     public void testIndentation() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
-        HSLFSlide slide = ppt.getSlides()[0];
-        HSLFTextParagraph[] trun;
-
-        trun = slide.getTextRuns();
-        for (int i = 0; i < trun.length; i++) {
-            if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){
-                HSLFTextRun rt = trun[i].getRichTextRuns()[0];
-                assertEquals(40, rt.getFontSize());
+        HSLFSlide slide = ppt.getSlides().get(0);
+        
+        for (HSLFTextParagraph trun : slide.getTextParagraphs()) {
+            if (trun.getRunType() == TextHeaderAtom.TITLE_TYPE){
+                HSLFTextRun rt = trun.getTextRuns().get(0);
+                assertEquals(40, rt.getFontSize(), 0);
                 assertEquals(true, rt.isUnderlined());
-                assertEquals("Arial", rt.getFontName());
-            } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){
-                HSLFTextRun[] rt = trun[i].getRichTextRuns();
-                for (int j = 0; j < rt.length; j++) {
-                    int indent = rt[j].getIndentLevel();
-                    switch (indent){
-                        case 0:
-                            assertEquals(32, rt[j].getFontSize());
-                            break;
-                        case 1:
-                            assertEquals(28, rt[j].getFontSize());
-                            break;
-                        case 2:
-                            assertEquals(24, rt[j].getFontSize());
-                            break;
-                    }
+                assertEquals("Arial", rt.getFontFamily());
+            } else if (trun.getRunType() == TextHeaderAtom.BODY_TYPE){
+                int indents[] = { 32, 28, 24 };
+                for (HSLFTextRun rt : trun.getTextRuns()) {
+                    int indent = trun.getIndentLevel();
+                    assertEquals(indents[indent], rt.getFontSize(), 0);
                 }
             }
         }
index f5e0abef594b63f6536df84fa5c649243ebe2a50..a84caefd68c8a09d4f1c8dc9ed081ebf50e7d102 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
-
-import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test adding new slides to a ppt.
@@ -32,18 +34,19 @@ import java.io.ByteArrayInputStream;
  *  stuff does
  * @author Yegor Kozlov
  */
-public final class TestSlides extends TestCase {
+public final class TestSlides {
 
     /**
      * Add 1 slide to an empty ppt.
      * @throws Exception
      */
+    @Test
     public void testAddSlides1() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") ));
-        assertTrue(ppt.getSlides().length == 0);
+        assertTrue(ppt.getSlides().isEmpty());
 
         HSLFSlide s1 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 1);
+        assertEquals(1, ppt.getSlides().size());
         assertEquals(3, s1._getSheetRefId());
         assertEquals(256, s1._getSheetNumber());
         assertEquals(1, s1.getSlideNumber());
@@ -54,60 +57,62 @@ public final class TestSlides extends TestCase {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getSlides().length == 1);
+        assertEquals(1, ppt.getSlides().size());
     }
 
     /**
      * Add 2 slides to an empty ppt
      * @throws Exception
      */
+    @Test
     public void testAddSlides2() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") ));
-        assertTrue(ppt.getSlides().length == 0);
+        assertTrue(ppt.getSlides().isEmpty());
 
         HSLFSlide s1 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 1);
+        assertEquals(1, ppt.getSlides().size());
         assertEquals(3, s1._getSheetRefId());
         assertEquals(256, s1._getSheetNumber());
         assertEquals(1, s1.getSlideNumber());
 
         HSLFSlide s2 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 2);
+        assertEquals(2, ppt.getSlides().size());
         assertEquals(4, s2._getSheetRefId());
         assertEquals(257, s2._getSheetNumber());
         assertEquals(2, s2.getSlideNumber());
 
         //serialize and read again
-         ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
         ppt.write(out);
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getSlides().length == 2);
+        assertEquals(2, ppt.getSlides().size());
     }
 
     /**
      * Add 3 slides to an empty ppt
      * @throws Exception
      */
+    @Test
     public void testAddSlides3() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") ));
-        assertTrue(ppt.getSlides().length == 0);
+        assertTrue(ppt.getSlides().isEmpty());
 
         HSLFSlide s1 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 1);
+        assertEquals(1, ppt.getSlides().size());
         assertEquals(3, s1._getSheetRefId());
         assertEquals(256, s1._getSheetNumber());
         assertEquals(1, s1.getSlideNumber());
 
         HSLFSlide s2 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 2);
+        assertEquals(2, ppt.getSlides().size());
         assertEquals(4, s2._getSheetRefId());
         assertEquals(257, s2._getSheetNumber());
         assertEquals(2, s2.getSlideNumber());
 
         HSLFSlide s3 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 3);
+        assertEquals(3, ppt.getSlides().size());
         assertEquals(5, s3._getSheetRefId());
         assertEquals(258, s3._getSheetNumber());
         assertEquals(3, s3.getSlideNumber());
@@ -119,17 +124,17 @@ public final class TestSlides extends TestCase {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getSlides().length == 3);
+        assertEquals(3, ppt.getSlides().size());
 
         // Check IDs are still right
-        s1 = ppt.getSlides()[0];
+        s1 = ppt.getSlides().get(0);
         assertEquals(256, s1._getSheetNumber());
         assertEquals(3, s1._getSheetRefId());
-        s2 = ppt.getSlides()[1];
+        s2 = ppt.getSlides().get(1);
         assertEquals(257, s2._getSheetNumber());
         assertEquals(4, s2._getSheetRefId());
-        s3 = ppt.getSlides()[2];;
-        assertTrue(ppt.getSlides().length == 3);
+        s3 = ppt.getSlides().get(2);;
+        assertEquals(3, ppt.getSlides().size());
         assertEquals(258, s3._getSheetNumber());
         assertEquals(5, s3._getSheetRefId());
     }
@@ -137,25 +142,26 @@ public final class TestSlides extends TestCase {
     /**
      * Add slides to ppt which already has two slides
      */
+    @Test
     public void testAddSlides2to3() throws Exception {
         POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
         HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
 
-        assertTrue(ppt.getSlides().length == 2);
+        assertEquals(2, ppt.getSlides().size());
 
         // First slide is 256 / 4
-        HSLFSlide s1 = ppt.getSlides()[0];
+        HSLFSlide s1 = ppt.getSlides().get(0);
         assertEquals(256, s1._getSheetNumber());
         assertEquals(4, s1._getSheetRefId());
 
         // Last slide is 257 / 6
-        HSLFSlide s2 = ppt.getSlides()[1];
+        HSLFSlide s2 = ppt.getSlides().get(1);
         assertEquals(257, s2._getSheetNumber());
         assertEquals(6, s2._getSheetRefId());
 
         // Add another slide, goes in at the end
         HSLFSlide s3 = ppt.createSlide();
-        assertTrue(ppt.getSlides().length == 3);
+        assertEquals(3, ppt.getSlides().size());
         assertEquals(258, s3._getSheetNumber());
         assertEquals(8, s3._getSheetRefId());
 
@@ -166,18 +172,18 @@ public final class TestSlides extends TestCase {
         out.close();
 
         ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getSlides().length == 3);
+        assertEquals(3, ppt.getSlides().size());
 
 
         // Check IDs are still right
-        s1 = ppt.getSlides()[0];
+        s1 = ppt.getSlides().get(0);
         assertEquals(256, s1._getSheetNumber());
         assertEquals(4, s1._getSheetRefId());
-        s2 = ppt.getSlides()[1];
+        s2 = ppt.getSlides().get(1);
         assertEquals(257, s2._getSheetNumber());
         assertEquals(6, s2._getSheetRefId());
-        s3 = ppt.getSlides()[2];;
-        assertTrue(ppt.getSlides().length == 3);
+        s3 = ppt.getSlides().get(2);
+        assertEquals(3, ppt.getSlides().size());
         assertEquals(258, s3._getSheetNumber());
         assertEquals(8, s3._getSheetRefId());
     }
index d3fb354063b18688de3cf01066ebbad1eb10f0cc..0c5fcb69bbd1bd75da843d6b0b02213c3792e1e4 100644 (file)
 
 package org.apache.poi.hslf.model;
 
+import static org.junit.Assert.*;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-
-import junit.framework.TestCase;
+import java.util.List;
 
 import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Test;
 
 /**
  * Test <code>Table</code> object.
  *
  * @author Yegor Kozlov
  */
-public final class TestTable extends TestCase {
+public final class TestTable {
 
     /**
      * Test that ShapeFactory works properly and returns <code>Table</code>
      */
+    @Test
     public void testShapeFactory() throws Exception {
         HSLFSlideShow ppt = new HSLFSlideShow();
 
@@ -45,10 +48,10 @@ public final class TestTable extends TestCase {
 
         TableCell cell = tbl.getCell(0, 0);
         //table cells have type=TextHeaderAtom.OTHER_TYPE, see bug #46033
-        assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraph().getRunType());
+        assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType());
 
-        assertTrue(slide.getShapes()[0] instanceof Table);
-        Table tbl2 = (Table)slide.getShapes()[0];
+        assertTrue(slide.getShapes().get(0) instanceof Table);
+        Table tbl2 = (Table)slide.getShapes().get(0);
         assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
         assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
 
@@ -57,9 +60,9 @@ public final class TestTable extends TestCase {
         out.close();
 
         ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        slide = ppt.getSlides()[0];
-        assertTrue(slide.getShapes()[0] instanceof Table);
-        Table tbl3 = (Table)slide.getShapes()[0];
+        slide = ppt.getSlides().get(0);
+        assertTrue(slide.getShapes().get(0) instanceof Table);
+        Table tbl3 = (Table)slide.getShapes().get(0);
         assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns());
         assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
     }
@@ -67,25 +70,27 @@ public final class TestTable extends TestCase {
     /**
      * Error constructing Table when rownum=1
      */
+    @Test
     public void test45889(){
         HSLFSlideShow ppt = new HSLFSlideShow();
         HSLFSlide slide = ppt.createSlide();
-        HSLFShape[] shapes;
+        List<HSLFShape> shapes;
         Table tbl1 = new Table(1, 5);
         assertEquals(5, tbl1.getNumberOfColumns());
         assertEquals(1, tbl1.getNumberOfRows());
         slide.addShape(tbl1);
 
         shapes = slide.getShapes();
-        assertEquals(1, shapes.length);
+        assertEquals(1, shapes.size());
 
-        Table tbl2 = (Table)shapes[0];
+        Table tbl2 = (Table)shapes.get(0);
         assertSame(tbl1.getSpContainer(), tbl2.getSpContainer());
 
         assertEquals(tbl1.getNumberOfColumns(), tbl2.getNumberOfColumns());
         assertEquals(tbl1.getNumberOfRows(), tbl2.getNumberOfRows());
     }
 
+    @Test
     public void testIllegalCOnstruction(){
         try {
             new Table(0, 5);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java
deleted file mode 100644 (file)
index 01ce6a0..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-/* ====================================================================
-   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.awt.*;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.TextBytesAtom;
-import org.apache.poi.hslf.record.TextCharsAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
-
-/**
- * Tests for TextRuns
- *
- * @author Nick Burch (nick at torchbox dot com)
- */
-public final class TestTextRun extends TestCase {
-    private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
-
-       // SlideShow primed on the test data
-       private HSLFSlideShow ss;
-       private HSLFSlideShow ssRich;
-
-       protected void setUp() throws IOException {
-
-               // Basic (non rich) test file
-               ss = new HSLFSlideShow(_slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
-
-               // Rich test file
-               ssRich = new HSLFSlideShow(_slTests.openResourceAsStream("Single_Coloured_Page.ppt"));
-       }
-
-       /**
-        * Test to ensure that getting the text works correctly
-        */
-       public void testGetText() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-
-               assertEquals(2, textRuns.length);
-
-               // Get text works with \n
-               assertEquals("This is a test title", textRuns[0].getText());
-               assertEquals("This is a test subtitle\nThis is on page 1", textRuns[1].getText());
-
-               // Raw text has \r instead
-               assertEquals("This is a test title", textRuns[0].getRawText());
-               assertEquals("This is a test subtitle\rThis is on page 1", textRuns[1].getRawText());
-
-
-               // Now check on a rich text run
-               HSLFSlide slideOneR = ssRich.getSlides()[0];
-               HSLFTextParagraph[] textRunsR = slideOneR.getTextRuns();
-
-               assertEquals(2, textRunsR.length);
-               assertEquals("This is a title, it\u2019s in black", textRunsR[0].getText());
-               assertEquals("This is the subtitle, in bold\nThis bit is blue and italic\nThis bit is red (normal)", textRunsR[1].getText());
-               assertEquals("This is a title, it\u2019s in black", textRunsR[0].getRawText());
-               assertEquals("This is the subtitle, in bold\rThis bit is blue and italic\rThis bit is red (normal)", textRunsR[1].getRawText());
-       }
-
-       /**
-        * Test to ensure changing non rich text bytes->bytes works correctly
-        */
-       public void testSetText() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextParagraph run = textRuns[0];
-
-               // Check current text
-               assertEquals("This is a test title", run.getText());
-
-               // Change
-               String changeTo = "New test title";
-               run.setText(changeTo);
-               assertEquals(changeTo, run.getText());
-
-               // Ensure trailing \n's are NOT stripped, it is legal to set a text with a trailing '\r'
-               run.setText(changeTo + "\n");
-               assertEquals(changeTo + "\n", run.getText());
-       }
-
-       /**
-        * Test to ensure that changing non rich text between bytes and
-        *  chars works correctly
-        */
-       public void testAdvancedSetText() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph run = slideOne.getTextRuns()[0];
-
-               TextHeaderAtom tha = run._headerAtom;
-               TextBytesAtom tba = run._byteAtom;
-               TextCharsAtom tca = run._charAtom;
-
-               // Bytes -> Bytes
-               assertNull(tca);
-               assertNotNull(tba);
-               assertFalse(run._isUnicode);
-               assertEquals("This is a test title", run.getText());
-
-               String changeBytesOnly = "New Test Title";
-               run.setText(changeBytesOnly);
-               tba = run._byteAtom;
-               tca = run._charAtom;
-
-               assertEquals(changeBytesOnly, run.getText());
-               assertFalse(run._isUnicode);
-               assertNull(tca);
-               assertNotNull(tba);
-
-               // Bytes -> Chars
-               assertNull(tca);
-               assertNotNull(tba);
-               assertFalse(run._isUnicode);
-               assertEquals(changeBytesOnly, run.getText());
-
-               String changeByteChar = "This is a test title with a '\u0121' g with a dot";
-               run.setText(changeByteChar);
-               tba = run._byteAtom;
-               tca = run._charAtom;
-
-               assertEquals(changeByteChar, run.getText());
-               assertTrue(run._isUnicode);
-               assertNotNull(tca);
-               assertNull(tba);
-
-               // Chars -> Chars
-               assertNull(tba);
-               assertNotNull(tca);
-               assertTrue(run._isUnicode);
-               assertEquals(changeByteChar, run.getText());
-
-               String changeCharChar = "This is a test title with a '\u0147' N with a hat";
-               run.setText(changeCharChar);
-               tba = run._byteAtom;
-               tca = run._charAtom;
-
-               assertEquals(changeCharChar, run.getText());
-               assertTrue(run._isUnicode);
-               assertNotNull(tca);
-               assertNull(tba);
-       }
-
-       /**
-        * Tests to ensure that non rich text has the right default rich text run
-        *  set up for it
-        */
-       public void testGetRichTextNonRich() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-
-               assertEquals(2, textRuns.length);
-
-               HSLFTextParagraph trA = textRuns[0];
-               HSLFTextParagraph trB = textRuns[1];
-
-               assertEquals(1, trA.getRichTextRuns().length);
-               assertEquals(1, trB.getRichTextRuns().length);
-
-               HSLFTextRun rtrA = trA.getRichTextRuns()[0];
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-
-               assertEquals(trA.getText(), rtrA.getText());
-               assertEquals(trB.getText(), rtrB.getText());
-
-               assertNull(rtrA._getRawCharacterStyle());
-               assertNull(rtrA._getRawParagraphStyle());
-               assertNull(rtrB._getRawCharacterStyle());
-               assertNull(rtrB._getRawParagraphStyle());
-       }
-
-       /**
-        * Tests to ensure that the rich text runs are built up correctly
-        */
-       public void testGetRichText() {
-               HSLFSlide slideOne = ssRich.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-
-               assertEquals(2, textRuns.length);
-
-               HSLFTextParagraph trA = textRuns[0];
-               HSLFTextParagraph trB = textRuns[1];
-
-               assertEquals(1, trA.getRichTextRuns().length);
-               assertEquals(3, trB.getRichTextRuns().length);
-
-               HSLFTextRun rtrA = trA.getRichTextRuns()[0];
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-               HSLFTextRun rtrC = trB.getRichTextRuns()[1];
-               HSLFTextRun rtrD = trB.getRichTextRuns()[2];
-
-               assertEquals(trA.getText(), rtrA.getText());
-
-               assertEquals(trB.getText().substring(0, 30), rtrB.getText());
-               assertEquals(trB.getText().substring(30,58), rtrC.getText());
-               assertEquals(trB.getText().substring(58,82), rtrD.getText());
-
-               assertNull(rtrA._getRawCharacterStyle());
-               assertNull(rtrA._getRawParagraphStyle());
-               assertNotNull(rtrB._getRawCharacterStyle());
-               assertNotNull(rtrB._getRawParagraphStyle());
-               assertNotNull(rtrC._getRawCharacterStyle());
-               assertNotNull(rtrC._getRawParagraphStyle());
-               assertNotNull(rtrD._getRawCharacterStyle());
-               assertNotNull(rtrD._getRawParagraphStyle());
-
-               // Same paragraph styles
-               assertEquals(rtrB._getRawParagraphStyle(), rtrC._getRawParagraphStyle());
-               assertEquals(rtrB._getRawParagraphStyle(), rtrD._getRawParagraphStyle());
-
-               // Different char styles
-               assertFalse( rtrB._getRawCharacterStyle().equals( rtrC._getRawCharacterStyle() ));
-               assertFalse( rtrB._getRawCharacterStyle().equals( rtrD._getRawCharacterStyle() ));
-               assertFalse( rtrC._getRawCharacterStyle().equals( rtrD._getRawCharacterStyle() ));
-       }
-
-       /**
-        * Tests to ensure that setting the text where the text isn't rich,
-        *  ensuring that everything stays with the same default styling
-        */
-       public void testSetTextWhereNotRich() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextParagraph trB = textRuns[1];
-               assertEquals(1, trB.getRichTextRuns().length);
-
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-               assertEquals(trB.getText(), rtrB.getText());
-               assertNull(rtrB._getRawCharacterStyle());
-               assertNull(rtrB._getRawParagraphStyle());
-
-               // Change text via normal
-               trB.setText("Test Foo Test");
-               rtrB = trB.getRichTextRuns()[0];
-               assertEquals("Test Foo Test", trB.getText());
-               assertEquals("Test Foo Test", rtrB.getText());
-               assertNull(rtrB._getRawCharacterStyle());
-               assertNull(rtrB._getRawParagraphStyle());
-       }
-
-       /**
-        * Tests to ensure that setting the text where the text is rich
-        *  sets everything to the same styling
-        */
-       public void testSetTextWhereRich() {
-               HSLFSlide slideOne = ssRich.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextParagraph trB = textRuns[1];
-               assertEquals(3, trB.getRichTextRuns().length);
-
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-               HSLFTextRun rtrC = trB.getRichTextRuns()[1];
-               HSLFTextRun rtrD = trB.getRichTextRuns()[2];
-               TextPropCollection tpBP = rtrB._getRawParagraphStyle();
-               TextPropCollection tpBC = rtrB._getRawCharacterStyle();
-               TextPropCollection tpCP = rtrC._getRawParagraphStyle();
-               TextPropCollection tpCC = rtrC._getRawCharacterStyle();
-               TextPropCollection tpDP = rtrD._getRawParagraphStyle();
-               TextPropCollection tpDC = rtrD._getRawCharacterStyle();
-
-               assertEquals(trB.getText().substring(0, 30), rtrB.getText());
-               assertNotNull(tpBP);
-               assertNotNull(tpBC);
-               assertNotNull(tpCP);
-               assertNotNull(tpCC);
-               assertNotNull(tpDP);
-               assertNotNull(tpDC);
-               assertTrue(tpBP.equals(tpCP));
-               assertTrue(tpBP.equals(tpDP));
-               assertTrue(tpCP.equals(tpDP));
-               assertFalse(tpBC.equals(tpCC));
-               assertFalse(tpBC.equals(tpDC));
-               assertFalse(tpCC.equals(tpDC));
-
-               // Change text via normal
-               trB.setText("Test Foo Test");
-
-               // Ensure now have first style
-               assertEquals(1, trB.getRichTextRuns().length);
-               rtrB = trB.getRichTextRuns()[0];
-               assertEquals("Test Foo Test", trB.getText());
-               assertEquals("Test Foo Test", rtrB.getText());
-               assertNotNull(rtrB._getRawCharacterStyle());
-               assertNotNull(rtrB._getRawParagraphStyle());
-               assertEquals( tpBP, rtrB._getRawParagraphStyle() );
-               assertEquals( tpBC, rtrB._getRawCharacterStyle() );
-       }
-
-       /**
-        * Test to ensure the right stuff happens if we change the text
-        *  in a rich text run, that doesn't happen to actually be rich
-        */
-       public void testChangeTextInRichTextRunNonRich() {
-               HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextParagraph trB = textRuns[1];
-               assertEquals(1, trB.getRichTextRuns().length);
-
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-               assertEquals(trB.getText(), rtrB.getText());
-               assertNull(rtrB._getRawCharacterStyle());
-               assertNull(rtrB._getRawParagraphStyle());
-
-               // Change text via rich
-               rtrB.setText("Test Test Test");
-               assertEquals("Test Test Test", trB.getText());
-               assertEquals("Test Test Test", rtrB.getText());
-
-               // Will now have dummy props
-               assertNotNull(rtrB._getRawCharacterStyle());
-               assertNotNull(rtrB._getRawParagraphStyle());
-       }
-
-       /**
-        * Tests to ensure changing the text within rich text runs works
-        *  correctly
-        */
-       public void testChangeTextInRichTextRun() {
-               HSLFSlide slideOne = ssRich.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextParagraph trB = textRuns[1];
-               assertEquals(3, trB.getRichTextRuns().length);
-
-               // We start with 3 text runs, each with their own set of styles,
-               //  but all sharing the same paragraph styles
-               HSLFTextRun rtrB = trB.getRichTextRuns()[0];
-               HSLFTextRun rtrC = trB.getRichTextRuns()[1];
-               HSLFTextRun rtrD = trB.getRichTextRuns()[2];
-               TextPropCollection tpBP = rtrB._getRawParagraphStyle();
-               TextPropCollection tpBC = rtrB._getRawCharacterStyle();
-               TextPropCollection tpCP = rtrC._getRawParagraphStyle();
-               TextPropCollection tpCC = rtrC._getRawCharacterStyle();
-               TextPropCollection tpDP = rtrD._getRawParagraphStyle();
-               TextPropCollection tpDC = rtrD._getRawCharacterStyle();
-
-               // Check text and stylings
-               assertEquals(trB.getText().substring(0, 30), rtrB.getText());
-               assertNotNull(tpBP);
-               assertNotNull(tpBC);
-               assertNotNull(tpCP);
-               assertNotNull(tpCC);
-               assertNotNull(tpDP);
-               assertNotNull(tpDC);
-               assertTrue(tpBP.equals(tpCP));
-               assertTrue(tpBP.equals(tpDP));
-               assertTrue(tpCP.equals(tpDP));
-               assertFalse(tpBC.equals(tpCC));
-               assertFalse(tpBC.equals(tpDC));
-               assertFalse(tpCC.equals(tpDC));
-
-               // Check text in the rich runs
-               assertEquals("This is the subtitle, in bold\n", rtrB.getText());
-               assertEquals("This bit is blue and italic\n", rtrC.getText());
-               assertEquals("This bit is red (normal)", rtrD.getText());
-
-               String newBText = "New Subtitle, will still be bold\n";
-               String newCText = "New blue and italic text\n";
-               String newDText = "Funky new normal red text";
-               rtrB.setText(newBText);
-               rtrC.setText(newCText);
-               rtrD.setText(newDText);
-               assertEquals(newBText, rtrB.getText());
-               assertEquals(newCText, rtrC.getText());
-               assertEquals(newDText, rtrD.getText());
-
-               assertEquals(newBText + newCText + newDText, trB.getText());
-
-               // The styles should have been updated for the new sizes
-               assertEquals(newBText.length(), tpBC.getCharactersCovered());
-               assertEquals(newCText.length(), tpCC.getCharactersCovered());
-               assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger
-
-               assertEquals(
-                               newBText.length() + newCText.length() + newDText.length(),
-                               tpBP.getCharactersCovered()
-               );
-
-               // Paragraph style should be sum of text length
-               assertEquals(newBText.length() + newCText.length() + newDText.length(), tpBP.getCharactersCovered());
-
-               // Check stylings still as expected
-               TextPropCollection ntpBC = rtrB._getRawCharacterStyle();
-               TextPropCollection ntpCC = rtrC._getRawCharacterStyle();
-               TextPropCollection ntpDC = rtrD._getRawCharacterStyle();
-               assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
-               assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
-               assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
-       }
-
-
-       /**
-        * Test case for Bug 41015.
-        *
-        * In some cases RichTextRun.getText() threw StringIndexOutOfBoundsException because
-        * of the wrong list of potential paragraph properties defined in StyleTextPropAtom.
-        *
-        */
-       public void testBug41015() throws IOException {
-               HSLFTextRun[] rt;
-
-               HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("bug-41015.ppt"));
-               HSLFSlide sl = ppt.getSlides()[0];
-               HSLFTextParagraph[] txt = sl.getTextRuns();
-               assertEquals(2, txt.length);
-
-               rt = txt[0].getRichTextRuns();
-               assertEquals(1, rt.length);
-               assertEquals(0, rt[0].getIndentLevel());
-               assertEquals("sdfsdfsdf", rt[0].getText());
-
-               rt = txt[1].getRichTextRuns();
-               assertEquals(2, rt.length);
-               assertEquals(0, rt[0].getIndentLevel());
-               assertEquals("Sdfsdfsdf\n" +
-                               "Dfgdfg\n" +
-                               "Dfgdfgdfg\n", rt[0].getText());
-               assertEquals(1, rt[1].getIndentLevel());
-               assertEquals("Sdfsdfs\n" +
-                               "Sdfsdf\n", rt[1].getText());
-       }
-
-       /**
-        * Test creation of TextRun objects.
-        */
-       public void testAddTextRun() {
-               HSLFSlideShow ppt = new HSLFSlideShow();
-               HSLFSlide slide = ppt.createSlide();
-
-               assertNull(slide.getTextRuns());
-
-               HSLFTextBox shape1 = new HSLFTextBox();
-               HSLFTextParagraph run1 = shape1.getTextParagraph();
-               assertSame(run1, shape1.createTextRun());
-               run1.setText("Text 1");
-               slide.addShape(shape1);
-
-               //The array of Slide's text runs must be updated when new text shapes are added.
-               HSLFTextParagraph[] runs = slide.getTextRuns();
-               assertNotNull(runs);
-               assertSame(run1, runs[0]);
-
-               HSLFTextBox shape2 = new HSLFTextBox();
-               HSLFTextParagraph run2 = shape2.getTextParagraph();
-               assertSame(run2, shape2.createTextRun());
-               run2.setText("Text 2");
-               slide.addShape(shape2);
-
-               runs = slide.getTextRuns();
-               assertEquals(2, runs.length);
-
-               assertSame(run1, runs[0]);
-               assertSame(run2, runs[1]);
-
-               //as getShapes()
-               HSLFShape[] sh = slide.getShapes();
-               assertEquals(2, sh.length);
-               assertTrue(sh[0] instanceof HSLFTextBox);
-               HSLFTextBox box1 = (HSLFTextBox)sh[0];
-               assertSame(run1, box1.getTextParagraph());
-               HSLFTextBox box2 = (HSLFTextBox)sh[1];
-               assertSame(run2, box2.getTextParagraph());
-
-               //test Table - a complex group of shapes containing text objects
-               HSLFSlide slide2 = ppt.createSlide();
-               assertNull(slide2.getTextRuns());
-               Table table = new Table(2, 2);
-               slide2.addShape(table);
-               runs = slide2.getTextRuns();
-               assertNotNull(runs);
-               assertEquals(4, runs.length);
-       }
-
-    public void test48916() throws IOException {
-        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
-        for(HSLFSlide slide : ppt.getSlides()){
-            for(HSLFShape sh : slide.getShapes()){
-                if(sh instanceof HSLFTextShape){
-                    HSLFTextShape tx = (HSLFTextShape)sh;
-                    HSLFTextParagraph run = tx.getTextParagraph();
-                    //verify that records cached in  TextRun and EscherTextboxWrapper are the same
-                    Record[] runChildren = run.getRecords();
-                    Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
-                    assertEquals(runChildren.length, txboxChildren.length);
-                    for(int i=0; i < txboxChildren.length; i++){
-                        assertSame(txboxChildren[i], runChildren[i]);
-                    }
-                    //caused NPE prior to fix of Bugzilla #48916 
-                    run.getRichTextRuns()[0].setBold(true);
-                    run.getRichTextRuns()[0].setFontColor(Color.RED);
-                }
-            }
-        }
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ppt.write(out);
-        ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        for(HSLFSlide slide : ppt.getSlides()){
-            for(HSLFShape sh : slide.getShapes()){
-                if(sh instanceof HSLFTextShape){
-                    HSLFTextShape tx = (HSLFTextShape)sh;
-                    HSLFTextParagraph run = tx.getTextParagraph();
-                    HSLFTextRun rt = run.getRichTextRuns()[0];
-                    assertTrue(rt.isBold());
-                    assertEquals(rt.getFontColor(), Color.RED);
-                }
-            }
-        }
-
-    }
-
-    public void test52244() throws IOException {
-        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("52244.ppt"));
-        HSLFSlide slide = ppt.getSlides()[0];
-        HSLFTextParagraph[] runs = slide.getTextRuns();
-
-        assertEquals("Arial", runs[0].getRichTextRuns()[0].getFontName());
-        assertEquals(36, runs[0].getRichTextRuns()[0].getFontSize());
-
-        assertEquals("Arial", runs[1].getRichTextRuns()[0].getFontName());
-        assertEquals(24, runs[1].getRichTextRuns()[0].getFontSize());
-
-        assertEquals("Arial", runs[2].getRichTextRuns()[0].getFontName());
-        assertEquals(32, runs[2].getRichTextRuns()[0].getFontSize());
-
-    }
-
-}
index c5a01341ae03a4cea8fd14d953e2bac2c9c309f3..8601f95ea5543c27aff5ba883d6c673d86e48a5e 100644 (file)
 
 package org.apache.poi.hslf.model;
 
+import static org.junit.Assert.assertEquals;
 
-import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 
-import java.io.*;
-
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.poifs.filesystem.*;
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.poifs.filesystem.DocumentEntry;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * Tests that if we load something up, get a TextRun, set the text
@@ -34,7 +36,7 @@ import org.apache.poi.POIDataSamples;
  *
  * @author Nick Burch (nick at torchbox dot com)
  */
-public final class TestTextRunReWrite extends TestCase {
+public final class TestTextRunReWrite {
        // HSLFSlideShow primed on the test data
        private HSLFSlideShowImpl hss;
        // HSLFSlideShow primed on the test data
@@ -45,6 +47,7 @@ public final class TestTextRunReWrite extends TestCase {
        /**
         * Load up a test PPT file with rich data
         */
+       @Before
     public void setUp() throws Exception {
         POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
                String filename = "Single_Coloured_Page_With_Fonts_and_Alignments.ppt";
@@ -53,35 +56,36 @@ public final class TestTextRunReWrite extends TestCase {
                ss = new HSLFSlideShow(hss);
     }
 
-    public void testWritesOutTheSameNonRich() throws Exception {
+    @Test
+       public void testWritesOutTheSameNonRich() throws Exception {
        // Grab the first text run on the first sheet
-       HSLFTextParagraph tr1 = ss.getSlides()[0].getTextRuns()[0];
-       HSLFTextParagraph tr2 = ss.getSlides()[0].getTextRuns()[1];
+       HSLFTextParagraph tr1 = ss.getSlides().get(0).getTextParagraphs().get(0);
+       HSLFTextParagraph tr2 = ss.getSlides().get(0).getTextParagraphs().get(1);
 
        // Ensure the text lengths are as we'd expect to start with
        assertEquals(1, ss.getSlides().length);
-       assertEquals(2, ss.getSlides()[0].getTextRuns().length);
-       assertEquals(30, tr1.getText().length());
-       assertEquals(179, tr2.getText().length());
+       assertEquals(2, ss.getSlides().get(0).getTextParagraphs().length);
+       assertEquals(30, tr1.getRawText().length());
+       assertEquals(179, tr2.getRawText().length());
 
-       assertEquals(1, tr1.getRichTextRuns().length);
-       assertEquals(30, tr1.getRichTextRuns()[0].getLength());
-       assertEquals(30, tr1.getRichTextRuns()[0].getText().length());
-       assertEquals(31, tr1.getRichTextRuns()[0]._getRawCharacterStyle().getCharactersCovered());
-       assertEquals(31, tr1.getRichTextRuns()[0]._getRawParagraphStyle().getCharactersCovered());
+       assertEquals(1, tr1.getTextRuns().length);
+       assertEquals(30, tr1.getTextRuns().get(0).getLength());
+       assertEquals(30, tr1.getTextRuns().get(0).getRawText().length());
+       assertEquals(31, tr1.getTextRuns().get(0)._getRawCharacterStyle().getCharactersCovered());
+       assertEquals(31, tr1.getTextRuns().get(0)._getRawParagraphStyle().getCharactersCovered());
 
        // Set the text to be as it is now
-       tr1.setText( tr1.getText() );
+       tr1.setText( tr1.getRawText() );
 
        // Check the text lengths are still right
-       assertEquals(30, tr1.getText().length());
-       assertEquals(179, tr2.getText().length());
+       assertEquals(30, tr1.getRawText().length());
+       assertEquals(179, tr2.getRawText().length());
 
-       assertEquals(1, tr1.getRichTextRuns().length);
-       assertEquals(30, tr1.getRichTextRuns()[0].getLength());
-       assertEquals(30, tr1.getRichTextRuns()[0].getText().length());
-       assertEquals(31, tr1.getRichTextRuns()[0]._getRawCharacterStyle().getCharactersCovered());
-       assertEquals(31, tr1.getRichTextRuns()[0]._getRawParagraphStyle().getCharactersCovered());
+       assertEquals(1, tr1.getTextRuns().length);
+       assertEquals(30, tr1.getTextRuns().get(0).getLength());
+       assertEquals(30, tr1.getTextRuns().get(0).getRawText().length());
+       assertEquals(31, tr1.getTextRuns().get(0)._getRawCharacterStyle().getCharactersCovered());
+       assertEquals(31, tr1.getTextRuns().get(0)._getRawParagraphStyle().getCharactersCovered());
 
 
                // Write the slideshow out to a byte array
@@ -110,33 +114,34 @@ public final class TestTextRunReWrite extends TestCase {
                }
        }
 
+    @Test
     public void testWritesOutTheSameRich() throws Exception {
        // Grab the first text run on the first sheet
-       HSLFTextParagraph tr1 = ss.getSlides()[0].getTextRuns()[0];
+       HSLFTextParagraph tr1 = ss.getSlides().get(0).getTextParagraphs().get(0);
 
        // Get the first rich text run
-       HSLFTextRun rtr1 = tr1.getRichTextRuns()[0];
+       HSLFTextRun rtr1 = tr1.getTextRuns().get(0);
 
 
        // Check that the text sizes are as expected
-       assertEquals(1, tr1.getRichTextRuns().length);
-       assertEquals(30, tr1.getText().length());
-       assertEquals(30, tr1.getRichTextRuns()[0].getText().length());
+       assertEquals(1, tr1.getTextRuns().length);
+       assertEquals(30, tr1.getRawText().length());
+       assertEquals(30, tr1.getTextRuns().get(0).getRawText().length());
        assertEquals(30, rtr1.getLength());
-       assertEquals(30, rtr1.getText().length());
+       assertEquals(30, rtr1.getRawText().length());
        assertEquals(31, rtr1._getRawCharacterStyle().getCharactersCovered());
        assertEquals(31, rtr1._getRawParagraphStyle().getCharactersCovered());
 
        // Set the text to be as it is now
-       rtr1.setText( rtr1.getText() );
-       rtr1 = tr1.getRichTextRuns()[0];
+       rtr1.setText( rtr1.getRawText() );
+       rtr1 = tr1.getTextRuns().get(0);
 
        // Check that the text sizes are still as expected
-       assertEquals(1, tr1.getRichTextRuns().length);
-       assertEquals(30, tr1.getText().length());
-       assertEquals(30, tr1.getRichTextRuns()[0].getText().length());
+       assertEquals(1, tr1.getTextRuns().length);
+       assertEquals(30, tr1.getRawText().length());
+       assertEquals(30, tr1.getTextRuns().get(0).getRawText().length());
        assertEquals(30, rtr1.getLength());
-       assertEquals(30, rtr1.getText().length());
+       assertEquals(30, rtr1.getRawText().length());
        assertEquals(31, rtr1._getRawCharacterStyle().getCharactersCovered());
        assertEquals(31, rtr1._getRawParagraphStyle().getCharactersCovered());
 
index 5666b8db0e133e7fa004f0c224bcdb111f5a4699..f57d1548bef2880f875195a97d7aebb688869e9e 100644 (file)
@@ -34,7 +34,7 @@ import java.util.Map;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.junit.Test;
 
@@ -49,13 +49,13 @@ public final class TestTextShape {
     @Test
     public void createAutoShape(){
         HSLFTextShape shape = new HSLFAutoShape(ShapeType.TRAPEZOID);
-        assertNull(shape.getTextParagraph());
+        assertNull(shape.getTextParagraphs());
         assertNull(shape.getText());
         assertNull(shape.getEscherTextboxWrapper());
 
         HSLFTextParagraph run = shape.createTextRun();
         assertNotNull(run);
-        assertNotNull(shape.getTextParagraph());
+        assertNotNull(shape.getTextParagraphs());
         assertNotNull(shape.getEscherTextboxWrapper());
         assertEquals("", shape.getText());
         assertSame(run, shape.createTextRun());
@@ -65,13 +65,13 @@ public final class TestTextShape {
     @Test
     public void createTextBox(){
         HSLFTextShape shape = new HSLFTextBox();
-        HSLFTextParagraph run = shape.getTextParagraph();
+        HSLFTextParagraph run = shape.getTextParagraphs();
         assertNotNull(run);
         assertNotNull(shape.getText());
         assertNotNull(shape.getEscherTextboxWrapper());
 
         assertSame(run, shape.createTextRun());
-        assertNotNull(shape.getTextParagraph());
+        assertNotNull(shape.getTextParagraphs());
         assertNotNull(shape.getEscherTextboxWrapper());
         assertEquals("", shape.getText());
 
@@ -93,41 +93,41 @@ public final class TestTextShape {
         for (int i = 0; i < shape.length; i++) {
             assertTrue("Expected TextShape but found " + shape[i].getClass().getName(), shape[i] instanceof HSLFTextShape);
             HSLFTextShape tx = (HSLFTextShape)shape[i];
-            HSLFTextParagraph run = tx.getTextParagraph();
+            HSLFTextParagraph run = tx.getTextParagraphs();
             assertNotNull(run);
             int runType = run.getRunType();
 
             ShapeType type = shape[i].getShapeType();
             switch (type){
                 case TEXT_BOX:
-                    assertEquals("Text in a TextBox", run.getText());
+                    assertEquals("Text in a TextBox", run.getRawText());
                     break;
                 case RECT:
                     if(runType == TextHeaderAtom.OTHER_TYPE)
-                        assertEquals("Rectangle", run.getText());
+                        assertEquals("Rectangle", run.getRawText());
                     else if(runType == TextHeaderAtom.TITLE_TYPE)
-                        assertEquals("Title Placeholder", run.getText());
+                        assertEquals("Title Placeholder", run.getRawText());
                     break;
                 case OCTAGON:
-                    assertEquals("Octagon", run.getText());
+                    assertEquals("Octagon", run.getRawText());
                     break;
                 case ELLIPSE:
-                    assertEquals("Ellipse", run.getText());
+                    assertEquals("Ellipse", run.getRawText());
                     break;
                 case ROUND_RECT:
-                    assertEquals("RoundRectangle", run.getText());
+                    assertEquals("RoundRectangle", run.getRawText());
                     break;
                 default:
                     fail("Unexpected shape: " + shape[i].getShapeName());
 
             }
-            lst1.add(run.getText());
+            lst1.add(run.getRawText());
         }
 
         List<String> lst2 = new ArrayList<String>();
-        HSLFTextParagraph[] run = slide.getTextRuns();
+        HSLFTextParagraph[] run = slide.getTextParagraphs();
         for (int i = 0; i < run.length; i++) {
-            lst2.add(run[i].getText());
+            lst2.add(run[i].getRawText());
         }
 
         assertTrue(lst1.containsAll(lst2));
@@ -162,12 +162,12 @@ public final class TestTextShape {
         assertTrue(shape[0] instanceof HSLFTextShape);
         shape1 = (HSLFTextShape)shape[0];
         assertEquals(ShapeType.TEXT_BOX, shape1.getShapeType());
-        assertEquals("Hello, World!", shape1.getTextParagraph().getText());
+        assertEquals("Hello, World!", shape1.getTextParagraphs().getRawText());
 
         assertTrue(shape[1] instanceof HSLFTextShape);
         shape1 = (HSLFTextShape)shape[1];
         assertEquals(ShapeType.RIGHT_ARROW, shape1.getShapeType());
-        assertEquals("Testing TextShape", shape1.getTextParagraph().getText());
+        assertEquals("Testing TextShape", shape1.getTextParagraphs().getRawText());
     }
 
     @Test
@@ -188,28 +188,28 @@ public final class TestTextShape {
         HSLFTextShape tx;
 
         tx = map.get("TEST1");
-        assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.39, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getLeftInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getRightInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.39, tx.getTopInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getBottomInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
 
         tx = map.get("TEST2");
-        assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.39, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getLeftInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getRightInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getTopInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.39, tx.getBottomInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
 
         tx = map.get("TEST3");
-        assertEquals(0.39, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.39, tx.getLeftInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getRightInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getTopInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getBottomInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
 
         tx = map.get("TEST4");
-        assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.39, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
-        assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.1, tx.getLeftInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.39, tx.getRightInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getTopInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+        assertEquals(0.05, tx.getBottomInset()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
     }
 
     @Test
@@ -222,14 +222,14 @@ public final class TestTextShape {
 
         HSLFTextShape sh0 = (HSLFTextShape)sh[0];
         assertEquals(null, sh0.getText());
-        assertEquals(null, sh0.getTextParagraph());
+        assertEquals(null, sh0.getTextParagraphs());
 
         HSLFTextShape sh1 = (HSLFTextShape)sh[1];
         assertEquals(null, sh1.getText());
-        assertEquals(null, sh1.getTextParagraph());
+        assertEquals(null, sh1.getTextParagraphs());
 
         HSLFTextShape sh2 = (HSLFTextShape)sh[2];
         assertEquals("this box should be shown just once", sh2.getText());
-        assertEquals(-1, sh2.getTextParagraph().getIndex());
+        assertEquals(-1, sh2.getTextParagraphs().getIndex());
     }
 }
index 7e37b47a439172b4e70b61693bcba49ad5fc7deb..f11d299c90b77aef71776cb2758d3a5d36b62aba 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.poi.hslf.model;
 import org.apache.poi.hslf.record.StyleTextPropAtom;
 import org.apache.poi.hslf.record.TextCharsAtom;
 import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.*;
 import org.apache.poi.hssf.usermodel.DummyGraphics2d;
 import org.junit.Test;
 
index 60aee0f49d951acdf6a926f05658655c083d2558..f7ee1f9262321607c39014141716d623c7198750 100644 (file)
@@ -25,7 +25,7 @@ import java.io.InputStream;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.junit.Test;
index d7de61c8777c9017656223fb728d93ef30191fe6..8018ba3b861d5e1fb58c427118a67765309d63fd 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.poi.hslf.record;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.poifs.filesystem.*;
 import org.apache.poi.POIDataSamples;
 
index 12c114b3444b8caa3e0e480b674f318b3cacbacc..4f23e4998bccd3c5b9f01118be04ae02e5fd0ef6 100644 (file)
@@ -34,10 +34,7 @@ import org.apache.poi.hpsf.PropertySet;
 import org.apache.poi.hpsf.PropertySetFactory;\r
 import org.apache.poi.hpsf.SummaryInformation;\r
 import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;\r
-import org.apache.poi.hslf.model.HSLFSlide;\r
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;\r
-import org.apache.poi.hslf.usermodel.HSLFPictureData;\r
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;\r
+import org.apache.poi.hslf.usermodel.*;\r
 import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;\r
 import org.apache.poi.poifs.crypt.CryptoFunctions;\r
 import org.apache.poi.poifs.crypt.EncryptionInfo;\r
@@ -147,7 +144,7 @@ public class TestDocumentEncryption {
         HSLFSlideShow ss = new HSLFSlideShow(hss);\r
         \r
         HSLFSlide slide = ss.getSlides()[0];\r
-        assertEquals("Dominic Salemno", slide.getTextRuns()[0].getText());\r
+        assertEquals("Dominic Salemno", slide.getTextParagraphs()[0].getRawText());\r
 \r
         String picCmp[][] = {\r
             {"0","nKsDTKqxTCR8LFkVVWlP9GSTvZ0="},\r
index f712e20a6d49824510e9ab8582f602ac63f1bb90..de5ee42b7cf8a3071e63f16934c79427459c3584 100644 (file)
@@ -25,8 +25,8 @@ import java.util.List;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.POIDataSamples;
 
 /**
index 836016666e620c98384918f8160f8772d4ba370a..bf596faed8d3679eacb9773f121558d1a8521d80 100644 (file)
@@ -20,8 +20,8 @@ package org.apache.poi.hslf.record;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.POIDataSamples;
 
 /**
index cecf3ee31981d1b888b1510831968cf5511ee7e9..67bbd0317559475a8c2ab5685c0337d79b746df9 100644 (file)
@@ -20,7 +20,7 @@ package org.apache.poi.hslf.record;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.POIDataSamples;
 
 /**
index 4b1ef6c9885bee88a67d881470795e80704ea09e..4dad61a6cb7cd2ac5d51f952839fecdd15e926d9 100644 (file)
@@ -78,7 +78,7 @@ public final class TestSlideAtom extends TestCase {
        
        public void testSSSlideInfoAtom() throws Exception {
                HSLFSlideShow ss = new HSLFSlideShow();
-               org.apache.poi.hslf.model.HSLFSlide     slide1 = ss.createSlide(), slide2 = ss.createSlide();
+               org.apache.poi.hslf.usermodel.HSLFSlide slide1 = ss.createSlide(), slide2 = ss.createSlide();
                slide2.setHidden(true);
 
                ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);
index 42fbf9113d672c18895653d490dd008c607e9bdc..1dcd58ca374cf659fff1b53fca3d3fd06ea81afd 100644 (file)
@@ -98,16 +98,16 @@ public final class TestBugs {
 
         notes = ppt.getSlides()[0].getNotesSheet();
         assertNotNull(notes);
-        txrun = notes.getTextRuns()[0];
+        txrun = notes.getTextParagraphs()[0];
         assertEquals("Notes-1", txrun.getRawText());
-        assertEquals(false, txrun.getRichTextRuns()[0].isBold());
+        assertEquals(false, txrun.getTextRuns()[0].isBold());
 
         //notes for the second slide are in bold
         notes = ppt.getSlides()[1].getNotesSheet();
         assertNotNull(notes);
-        txrun = notes.getTextRuns()[0];
+        txrun = notes.getTextParagraphs()[0];
         assertEquals("Notes-2", txrun.getRawText());
-        assertEquals(true, txrun.getRichTextRuns()[0].isBold());
+        assertEquals(true, txrun.getTextRuns()[0].isBold());
 
     }
 
@@ -134,7 +134,7 @@ public final class TestBugs {
             HSLFNotes notes = slide[i].getNotesSheet();
             if (notesMap.containsKey(slideNumber)){
                 assertNotNull(notes);
-                String text = notes.getTextRuns()[0].getRawText();
+                String text = notes.getTextParagraphs()[0].getRawText();
                 String startingPhrase = notesMap.get(slideNumber);
                 assertTrue("Notes for slide " + slideNumber + " must start with " +
                         startingPhrase , text.startsWith(startingPhrase));
@@ -158,7 +158,7 @@ public final class TestBugs {
                 for (int j = 0; j < sh.length; j++) {
                     if( sh[j] instanceof HSLFTextBox){
                         HSLFTextBox txt = (HSLFTextBox)sh[j];
-                        assertNotNull(txt.getTextParagraph());
+                        assertNotNull(txt.getTextParagraphs());
                     }
                 }
             }
@@ -202,8 +202,8 @@ public final class TestBugs {
         HSLFSlide[] slide = ppt.getSlides();
         for (int i = 0; i < slide.length; i++) {
             HSLFMasterSheet master = slide[i].getMasterSheet();
-            if (i == 0) assertTrue(master instanceof TitleMaster); //the first slide follows TitleMaster
-            else assertTrue(master instanceof SlideMaster);
+            if (i == 0) assertTrue(master instanceof HSLFTitleMaster); //the first slide follows TitleMaster
+            else assertTrue(master instanceof HSLFSlideMaster);
         }
     }
 
@@ -301,7 +301,7 @@ public final class TestBugs {
 
         HSLFSlide[] slide = ppt.getSlides();
         assertEquals(1, slide.length);
-        HSLFTextParagraph[] runs = slide[0].getTextRuns();
+        HSLFTextParagraph[] runs = slide[0].getTextParagraphs();
         assertEquals(4, runs.length);
 
         Set<String> txt = new HashSet<String>();
@@ -329,21 +329,21 @@ public final class TestBugs {
 
         // Check the first slide
         HSLFSlide slide = ppt.getSlides()[0];
-        HSLFTextParagraph[] slTr = slide.getTextRuns();
+        HSLFTextParagraph[] slTr = slide.getTextParagraphs();
         
         // Has two text runs, one from slide text, one from drawing
         assertEquals(2, slTr.length);
         assertEquals(false, slTr[0].isDrawingBased());
         assertEquals(true, slTr[1].isDrawingBased());
-        assertEquals("First run", slTr[0].getText());
-        assertEquals("Second run", slTr[1].getText());
+        assertEquals("First run", slTr[0].getRawText());
+        assertEquals("Second run", slTr[1].getRawText());
 
         // Check the shape based text runs
         List<HSLFTextParagraph> lst = new ArrayList<HSLFTextParagraph>();
         HSLFShape[] shape = slide.getShapes();
         for (int i = 0; i < shape.length; i++) {
             if( shape[i] instanceof HSLFTextShape){
-                HSLFTextParagraph textRun = ((HSLFTextShape)shape[i]).getTextParagraph();
+                HSLFTextParagraph textRun = ((HSLFTextShape)shape[i]).getTextParagraphs();
                 if(textRun != null) {
                     lst.add(textRun);
                 }
@@ -354,7 +354,7 @@ public final class TestBugs {
         assertEquals(1, lst.size());
         
         // And it should be the second one
-        assertEquals("Second run", lst.get(0).getText());
+        assertEquals("Second run", lst.get(0).getRawText());
     }
 
     /**
@@ -402,11 +402,11 @@ public final class TestBugs {
         assertEquals(1, sh.length);
         assertTrue(sh[0] instanceof HSLFTextShape);
         HSLFTextShape tx = (HSLFTextShape)sh[0];
-        assertEquals("Fundera, planera och involvera.", tx.getTextParagraph().getText());
+        assertEquals("Fundera, planera och involvera.", tx.getTextParagraphs().getRawText());
 
-        HSLFTextParagraph[] run = slide.getTextRuns();
+        HSLFTextParagraph[] run = slide.getTextParagraphs();
         assertEquals(1, run.length);
-        assertEquals("Fundera, planera och involvera.", run[0].getText());
+        assertEquals("Fundera, planera och involvera.", run[0].getRawText());
     }
 
     /**
@@ -429,7 +429,7 @@ public final class TestBugs {
     public void bug49648() throws Exception {
        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("49648.ppt"));
        for(HSLFSlide slide : ppt.getSlides()) {
-          for(HSLFTextParagraph run : slide.getTextRuns()) {
+          for(HSLFTextParagraph run : slide.getTextParagraphs()) {
              String text = run.getRawText();
              text.replace("{txtTot}", "With \u0123\u1234\u5678 unicode");
              run.setRawText(text);
@@ -487,7 +487,7 @@ public final class TestBugs {
                 str = str.replace("$$DATE$$", new Date().toString());
                 tb.setText(str);
                 
-                HSLFTextParagraph tr = tb.getTextParagraph();
+                HSLFTextParagraph tr = tb.getTextParagraphs();
                 assertEquals(str.length()+1,tr.getStyleTextPropAtom().getParagraphStyles().getFirst().getCharactersCovered());
                 assertEquals(str.length()+1,tr.getStyleTextPropAtom().getCharacterStyles().getFirst().getCharactersCovered());
             }
@@ -538,7 +538,7 @@ public final class TestBugs {
         // Check the number of text runs based on the slide (not textbox)
         // Will have skipped the empty one
         int str = 0;
-        for (HSLFTextParagraph tr : _slides[0].getTextRuns()) {
+        for (HSLFTextParagraph tr : _slides[0].getTextParagraphs()) {
             if (! tr.isDrawingBased()) str++;
         }
         assertEquals(1, str);
index 37b7bb696539e46500255c2c51535a5f658e07a7..3638bad82e2e1188577ef16475a37b74458472b3 100644 (file)
@@ -39,7 +39,6 @@ import java.util.Map;
 import javax.imageio.ImageIO;\r
 \r
 import org.apache.poi.POIDataSamples;\r
-import org.apache.poi.hslf.model.HSLFSlide;\r
 import org.apache.poi.hslf.model.TextPainter;\r
 import org.apache.poi.util.TempFile;\r
 import org.junit.Ignore;\r
index 088dbb0cee547e7f1e3b0a6842c01ad8cc853fbd..1cb9c7d9fd9391925616ef7fed41f3a5e859a4ee 100644 (file)
@@ -21,7 +21,6 @@ package org.apache.poi.hslf.usermodel;
 import junit.framework.TestCase;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.*;
 import org.apache.poi.POIDataSamples;
 
index 22b40a22e2c3853d08676156454d908a6b7bfb53..570fb5883ab6add08a5a067236a85bb3d869d5d9 100644 (file)
@@ -43,18 +43,18 @@ public final class TestNotesText extends TestCase {
                HSLFNotes notes = ss.getNotes()[0];
 
                String[] expectText = new String[] {"These are the notes for page 1"};
-               assertEquals(expectText.length, notes.getTextRuns().length);
+               assertEquals(expectText.length, notes.getTextParagraphs().length);
                for(int i=0; i<expectText.length; i++) {
-                       assertEquals(expectText[i], notes.getTextRuns()[i].getText());
+                       assertEquals(expectText[i], notes.getTextParagraphs()[i].getRawText());
                }
        }
 
        public void testNotesTwo() {
                HSLFNotes notes = ss.getNotes()[1];
                String[] expectText = new String[] {"These are the notes on page two, again lacking formatting"};
-               assertEquals(expectText.length, notes.getTextRuns().length);
+               assertEquals(expectText.length, notes.getTextParagraphs().length);
                for(int i=0; i<expectText.length; i++) {
-                       assertEquals(expectText[i], notes.getTextRuns()[i].getText());
+                       assertEquals(expectText[i], notes.getTextParagraphs()[i].getRawText());
                }
        }
 }
index 9f8d5f3ff281410d040649730f0b50c7f291184c..53079a3ac2fd635aa65d23de30660ff9b4e702e2 100644 (file)
@@ -23,8 +23,6 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlide;
-import org.apache.poi.hslf.model.HSLFTextParagraph;
 import org.apache.poi.hslf.model.textproperties.TextPFException9;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.EscherTextboxWrapper;
@@ -70,12 +68,12 @@ public final class TestNumberedList extends TestCase {
                assertNull(autoNumbers[1].getAutoNumberScheme());
                assertTrue(TextAutoNumberSchemeEnum.ANM_AlphaLcParenRight == autoNumbers[2].getAutoNumberScheme());
                        
-               HSLFTextParagraph[] textRuns = s.getTextRuns();
+               HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(2, textRuns.length);
 
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertEquals("titTe", textRun.getRawText());
-               assertEquals(1, textRuns[0].getRichTextRuns().length);
+               assertEquals(1, textRuns[0].getTextRuns().length);
                assertFalse(textRun.isBullet());
 
                assertEquals("This is a text placeholder that \rfollows the design pattern\rJust a test\rWithout any paragraph\rSecond paragraph first line c) ;\rSecond paragraph second line d) . \r", textRuns[1].getRawText());
@@ -106,12 +104,12 @@ public final class TestNumberedList extends TestCase {
                assertNull(autoNumbers[1].getAutoNumberScheme());
                assertTrue(TextAutoNumberSchemeEnum.ANM_AlphaUcPeriod == autoNumbers[2].getAutoNumberScheme());
 
-               final HSLFTextParagraph[] textRuns = s.getTextRuns();
+               final HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(2, textRuns.length);
 
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertEquals("Second Slide Title", textRun.getRawText());
-               assertEquals(1, textRuns[0].getRichTextRuns().length);
+               assertEquals(1, textRuns[0].getTextRuns().length);
                assertFalse(textRun.isBullet());
 
                assertEquals("This is a text placeholder that \rfollows the design pattern\rJust a test\rWithout any paragraph\rSecond paragraph first line c) ;\rSecond paragraph second line d) . \r", textRuns[1].getRawText());
index 60c0e908014ab0931be02bc0d54675715a7a300e..c0457f4d8c8fe0ba2d67dddd53bf1389787453cc 100644 (file)
@@ -23,8 +23,6 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlide;
-import org.apache.poi.hslf.model.HSLFTextParagraph;
 import org.apache.poi.hslf.model.textproperties.TextPFException9;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.EscherTextboxWrapper;
@@ -75,12 +73,12 @@ public final class TestNumberedList2 extends TestCase {
                assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox1[0].getAutoNumberScheme());
 
                
-               HSLFTextParagraph[] textRuns = s.getTextRuns();
+               HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(2, textRuns.length);
 
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertEquals("List Item One\rList Item Two\rList Item Three", textRun.getRawText());
-               assertEquals(1, textRuns[0].getRichTextRuns().length);
+               assertEquals(1, textRuns[0].getTextRuns().length);
                assertTrue(textRun.isBullet());
 
                assertEquals("A numbered list may start at any number \rThis would be used as a continuation list on another page\rThis list should start with #6", textRuns[1].getRawText());
@@ -101,12 +99,12 @@ public final class TestNumberedList2 extends TestCase {
                assertEquals(Short.valueOf((short)1), autoNumbersOfTextBox[0].getAutoNumberStartNumber());//Default value = 1 will be used 
                assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox[0].getAutoNumberScheme());
                        
-               HSLFTextParagraph[] textRuns = s.getTextRuns();
+               HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(3, textRuns.length);
 
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertEquals("Bulleted list\rMore bullets", textRun.getRawText());
-               assertEquals(1, textRuns[0].getRichTextRuns().length);
+               assertEquals(1, textRuns[0].getTextRuns().length);
                assertTrue(textRun.isBullet());
 
                assertEquals("Numbered list between two bulleted lists\rSecond numbered list item", textRuns[1].getRawText());
index e9a01459f3454c76a5b144a1e6d63e57023da909..eabbc4d58fd54278a777636a626db77fbbc31d85 100644 (file)
@@ -23,8 +23,6 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFSlide;
-import org.apache.poi.hslf.model.HSLFTextParagraph;
 import org.apache.poi.hslf.model.textproperties.TextPFException9;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.EscherTextboxWrapper;
@@ -68,14 +66,14 @@ public final class TestNumberedList3 extends TestCase {
                assertEquals(Short.valueOf((short)1), autoNumbersOfTextBox0[0].getAutoNumberStartNumber());//Default value = 1 will be used 
                assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox0[0].getAutoNumberScheme());
                
-               final HSLFTextParagraph[] textRuns = s.getTextRuns();
+               final HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(3, textRuns.length);
                assertEquals("Bulleted list\rMore bullets\rNo bullets here", textRuns[0].getRawText());
                assertEquals("Numbered list between two bulleted lists\rSecond numbered list item", textRuns[1].getRawText());
                assertEquals("Second bulleted list \u2013 should appear after numbered list\rMore bullets", textRuns[2].getRawText());
-               assertEquals(2, textRuns[0].getRichTextRuns().length);
-               assertEquals(1, textRuns[1].getRichTextRuns().length);
-               assertEquals(1, textRuns[2].getRichTextRuns().length);
+               assertEquals(2, textRuns[0].getTextRuns().length);
+               assertEquals(1, textRuns[1].getTextRuns().length);
+               assertEquals(1, textRuns[2].getTextRuns().length);
                assertNull(textRuns[0].getStyleTextProp9Atom());
                assertNotNull(textRuns[1].getStyleTextProp9Atom());
                assertNull(textRuns[2].getStyleTextProp9Atom());
@@ -91,7 +89,7 @@ public final class TestNumberedList3 extends TestCase {
                assertEquals(67, textProp.getCharactersCovered());
                
                
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertTrue(textRun.isBullet());
 
                
index c15bacd1f21a6b24d95c64fa371302e9de108fb6..4acda5beb9529818ac69df4b011c76cbf2fbd60e 100644 (file)
@@ -21,7 +21,6 @@ package org.apache.poi.hslf.usermodel;
 import junit.framework.TestCase;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.model.HSLFSlideShowImpl;
 import org.apache.poi.hslf.record.ParentAwareRecord;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.RecordContainer;
index 267e9ec7a431105f8ce8c71c4d83525ae8cc1caf..fca03441e915b983f1ca64ff9c24c57ef0fc0481 100644 (file)
@@ -78,8 +78,8 @@ public final class TestRichTextRun extends POITestCase {
         */
        public void testBoldNonRich() {
                HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextRun rtr = textRuns[0].getRichTextRuns()[0];
+               HSLFTextParagraph[] textRuns = slideOne.getTextParagraphs();
+               HSLFTextRun rtr = textRuns[0].getTextRuns()[0];
 
                assertNull(rtr._getRawCharacterStyle());
                assertNull(rtr._getRawParagraphStyle());
@@ -106,8 +106,8 @@ public final class TestRichTextRun extends POITestCase {
         */
        public void testBoldRich() {
                HSLFSlide slideOneR = ssRichA.getSlides()[0];
-               HSLFTextParagraph[] textRunsR = slideOneR.getTextRuns();
-               HSLFTextRun[] rtrs = textRunsR[1].getRichTextRuns();
+               HSLFTextParagraph[] textRunsR = slideOneR.getTextParagraphs();
+               HSLFTextRun[] rtrs = textRunsR[1].getTextRuns();
                assertEquals(3, rtrs.length);
 
                assertTrue(rtrs[0].isBold());
@@ -134,14 +134,14 @@ public final class TestRichTextRun extends POITestCase {
        public void testFontSize() {
 
                HSLFSlide slideOne = ss.getSlides()[0];
-               HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-               HSLFTextRun rtr = textRuns[0].getRichTextRuns()[0];
+               HSLFTextParagraph[] textRuns = slideOne.getTextParagraphs();
+               HSLFTextRun rtr = textRuns[0].getTextRuns()[0];
 
                HSLFSlide slideOneR = ssRichB.getSlides()[0];
-               HSLFTextParagraph[] textRunsR = slideOneR.getTextRuns();
-               HSLFTextRun rtrRa = textRunsR[0].getRichTextRuns()[0];
-               HSLFTextRun rtrRb = textRunsR[1].getRichTextRuns()[0];
-               HSLFTextRun rtrRc = textRunsR[1].getRichTextRuns()[3];
+               HSLFTextParagraph[] textRunsR = slideOneR.getTextParagraphs();
+               HSLFTextRun rtrRa = textRunsR[0].getTextRuns()[0];
+               HSLFTextRun rtrRb = textRunsR[1].getTextRuns()[0];
+               HSLFTextRun rtrRc = textRunsR[1].getTextRuns()[3];
 
                String defaultFont = "Arial";
 
@@ -198,8 +198,8 @@ public final class TestRichTextRun extends POITestCase {
                for(int i=0; i<h.length; i++) {
                        // Change
                        HSLFSlide slideOne = s[i];
-                       HSLFTextParagraph[] textRuns = slideOne.getTextRuns();
-                       HSLFTextRun rtr = textRuns[0].getRichTextRuns()[0];
+                       HSLFTextParagraph[] textRuns = slideOne.getTextParagraphs();
+                       HSLFTextRun rtr = textRuns[0].getTextRuns()[0];
 
                        rtr.setBold(true);
                        rtr.setFontSize(18);
@@ -232,8 +232,8 @@ public final class TestRichTextRun extends POITestCase {
                        // Now, look at the one we changed, wrote out, and read back in
                        // Ensure it does contain our original modifications
                        HSLFSlide slideOneRR = readS.getSlides()[0];
-                       HSLFTextParagraph[] textRunsRR = slideOneRR.getTextRuns();
-                       HSLFTextRun rtrRRa = textRunsRR[0].getRichTextRuns()[0];
+                       HSLFTextParagraph[] textRunsRR = slideOneRR.getTextParagraphs();
+                       HSLFTextRun rtrRRa = textRunsRR[0].getTextRuns()[0];
 
                        assertEquals(true, rtrRRa.isBold());
                        assertEquals(18, rtrRRa.getFontSize());
@@ -253,8 +253,8 @@ public final class TestRichTextRun extends POITestCase {
                // Check the number of text runs on interesting sheets
                HSLFSlide slideThreeC = ssRichC.getSlides()[2];
                HSLFSlide slideSevenC = ssRichC.getSlides()[6];
-               assertEquals(3, slideThreeC.getTextRuns().length);
-               assertEquals(5, slideSevenC.getTextRuns().length);
+               assertEquals(3, slideThreeC.getTextParagraphs().length);
+               assertEquals(5, slideSevenC.getTextParagraphs().length);
 
                // On slide three, we should have:
                // TR:
@@ -266,20 +266,20 @@ public final class TestRichTextRun extends POITestCase {
                //   Illustrative Example
                //   .
 
-               HSLFTextParagraph[] s3tr = slideThreeC.getTextRuns();
-               HSLFTextRun[] s3rtr0 = s3tr[0].getRichTextRuns();
-               HSLFTextRun[] s3rtr1 = s3tr[1].getRichTextRuns();
-               HSLFTextRun[] s3rtr2 = s3tr[2].getRichTextRuns();
+               HSLFTextParagraph[] s3tr = slideThreeC.getTextParagraphs();
+               HSLFTextRun[] s3rtr0 = s3tr[0].getTextRuns();
+               HSLFTextRun[] s3rtr1 = s3tr[1].getTextRuns();
+               HSLFTextRun[] s3rtr2 = s3tr[2].getTextRuns();
 
                assertEquals(2, s3rtr0.length);
                assertEquals(1, s3rtr1.length);
                assertEquals(2, s3rtr2.length);
 
-               assertEquals("You are an important supplier of various items that I need", s3rtr0[0].getText());
-               assertEquals("", s3rtr0[1].getText());
-               assertEquals("Source: Internal focus groups", s3rtr1[0].getText());
-               assertEquals("Illustrative Example", s3rtr2[0].getText());
-               assertEquals("", s3rtr2[1].getText());
+               assertEquals("You are an important supplier of various items that I need", s3rtr0[0].getRawText());
+               assertEquals("", s3rtr0[1].getRawText());
+               assertEquals("Source: Internal focus groups", s3rtr1[0].getRawText());
+               assertEquals("Illustrative Example", s3rtr2[0].getRawText());
+               assertEquals("", s3rtr2[1].getRawText());
 
                assertTrue(s3rtr0[0]._isParagraphStyleShared());
                assertTrue(s3rtr0[1]._isParagraphStyleShared());
@@ -300,10 +300,10 @@ public final class TestRichTextRun extends POITestCase {
                //  <ps>(text a)</ps><ps>(text a)(text b)</ps>
                // TR:
                //  (text)
-               HSLFTextParagraph[] s7tr = slideSevenC.getTextRuns();
-               HSLFTextRun[] s7rtr0 = s7tr[0].getRichTextRuns();
-               HSLFTextRun[] s7rtr1 = s7tr[1].getRichTextRuns();
-               HSLFTextRun[] s7rtr2 = s7tr[2].getRichTextRuns();
+               HSLFTextParagraph[] s7tr = slideSevenC.getTextParagraphs();
+               HSLFTextRun[] s7rtr0 = s7tr[0].getTextRuns();
+               HSLFTextRun[] s7rtr1 = s7tr[1].getTextRuns();
+               HSLFTextRun[] s7rtr2 = s7tr[2].getTextRuns();
 
                assertEquals(1, s7rtr0.length);
                assertEquals(3, s7rtr1.length);
@@ -332,10 +332,10 @@ public final class TestRichTextRun extends POITestCase {
                assertMatchesFileC(ssRichC);
 
                HSLFSlide slideSevenC = ssRichC.getSlides()[6];
-               HSLFTextParagraph[] s7tr = slideSevenC.getTextRuns();
-               HSLFTextRun[] s7rtr0 = s7tr[0].getRichTextRuns();
-               HSLFTextRun[] s7rtr1 = s7tr[1].getRichTextRuns();
-               HSLFTextRun[] s7rtr2 = s7tr[2].getRichTextRuns();
+               HSLFTextParagraph[] s7tr = slideSevenC.getTextParagraphs();
+               HSLFTextRun[] s7rtr0 = s7tr[0].getTextRuns();
+               HSLFTextRun[] s7rtr1 = s7tr[1].getTextRuns();
+               HSLFTextRun[] s7rtr2 = s7tr[2].getTextRuns();
 
                String oldText;
 
@@ -343,8 +343,8 @@ public final class TestRichTextRun extends POITestCase {
                // Need to ensure it's a run that really has styles!
                oldText = s7rtr2[0].getRawText();
                s7rtr2[0].setText( oldText );
-               assertEquals(oldText, s7rtr2[0].getText());
-               assertEquals(oldText, s7tr[2].getText());
+               assertEquals(oldText, s7rtr2[0].getRawText());
+               assertEquals(oldText, s7tr[2].getRawText());
                assertEquals(oldText.length() + 1, s7rtr2[0]._getRawCharacterStyle().getCharactersCovered());
                assertEquals(oldText.length() + 1, s7rtr2[0]._getRawParagraphStyle().getCharactersCovered());
                assertMatchesSLTWC(ssRichC);
@@ -353,7 +353,7 @@ public final class TestRichTextRun extends POITestCase {
                // Reset the text on a shared paragraph
                oldText = s7rtr1[2].getRawText();
                s7rtr1[2].setText( oldText );
-               assertEquals(oldText, s7rtr1[2].getText());
+               assertEquals(oldText, s7rtr1[2].getRawText());
                assertEquals(oldText.length() + 1, s7rtr1[2]._getRawCharacterStyle().getCharactersCovered());
                assertMatchesSLTWC(ssRichC);
                assertMatchesFileC(ssRichC);
@@ -450,9 +450,9 @@ if(false) {
                HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("ParagraphStylesShorterThanCharStyles.ppt"));
                HSLFSlide[] sl = ppt.getSlides();
                for (int i = 0; i < sl.length; i++) {
-                       HSLFTextParagraph[] txt = sl[i].getTextRuns();
+                       HSLFTextParagraph[] txt = sl[i].getTextParagraphs();
                        for (int j = 0; j < txt.length; j++) {
-                               HSLFTextRun[] rt = txt[j].getRichTextRuns();
+                               HSLFTextRun[] rt = txt[j].getTextRuns();
                                for (int k = 0; k < rt.length; k++) {
                                        int indent = rt[k].getIndentLevel();
                                        assertTrue(indent >= 0 && indent <= 4 );
@@ -471,12 +471,12 @@ if(false) {
                HSLFSlide[] slide = ppt.getSlides();
                assertEquals(2, slide.length);
 
-               txt = slide[0].getTextRuns();
+               txt = slide[0].getTextParagraphs();
                assertEquals(2, txt.length);
 
                assertEquals("Title text", txt[0].getRawText());
-               assertEquals(1, txt[0].getRichTextRuns().length);
-               rt = txt[0].getRichTextRuns()[0];
+               assertEquals(1, txt[0].getTextRuns().length);
+               rt = txt[0].getTextRuns()[0];
                assertFalse(rt.isBullet());
 
                assertEquals(
@@ -484,13 +484,13 @@ if(false) {
                                "follows the design pattern\r" +
                                "Defined in the slide master\r" +
                                "and has bullets by default", txt[1].getRawText());
-               assertEquals(1, txt[1].getRichTextRuns().length);
-               rt = txt[1].getRichTextRuns()[0];
+               assertEquals(1, txt[1].getTextRuns().length);
+               rt = txt[1].getTextRuns()[0];
                assertEquals('\u2022', rt.getBulletChar());
                assertTrue(rt.isBullet());
 
 
-               txt = slide[1].getTextRuns();
+               txt = slide[1].getTextParagraphs();
                assertEquals(2, txt.length);
 
                assertEquals(
@@ -498,16 +498,16 @@ if(false) {
                                "With bullets\r" +
                                "That follow the design pattern\r" +
                                "From the slide master", txt[0].getRawText());
-               assertEquals(1, txt[0].getRichTextRuns().length);
-               rt = txt[0].getRichTextRuns()[0];
+               assertEquals(1, txt[0].getTextRuns().length);
+               rt = txt[0].getTextRuns()[0];
                assertTrue(rt.isBullet());
                assertEquals('\u2022', rt.getBulletChar());
 
                assertEquals(
                                "I\u2019m a text box with user-defined\r" +
                                "bullet character", txt[1].getRawText());
-               assertEquals(1, txt[1].getRichTextRuns().length);
-               rt = txt[1].getRichTextRuns()[0];
+               assertEquals(1, txt[1].getTextRuns().length);
+               rt = txt[1].getTextRuns()[0];
                assertTrue(rt.isBullet());
                assertEquals('\u263A', rt.getBulletChar());
        }
@@ -518,7 +518,7 @@ if(false) {
                HSLFSlide slide = ppt.createSlide();
 
                HSLFTextBox shape = new HSLFTextBox();
-               HSLFTextRun rt = shape.getTextParagraph().getRichTextRuns()[0];
+               HSLFTextRun rt = shape.getTextParagraphs().getTextRuns()[0];
                shape.setText(
                                "Hello, World!\r" +
                                "This should be\r" +
@@ -547,7 +547,7 @@ if(false) {
                ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
                slide = ppt.getSlides()[0];
                shape = (HSLFTextBox)slide.getShapes()[0];
-               rt = shape.getTextParagraph().getRichTextRuns()[0];
+               rt = shape.getTextParagraphs().getTextRuns()[0];
                assertEquals(42, rt.getFontSize());
                assertEquals(true, rt.isBullet());
                assertEquals(50, rt.getTextOffset());
@@ -564,38 +564,38 @@ if(false) {
                HSLFSlide[] slides = ppt.getSlides();
 
                assertEquals(2, slides.length);
-               txt = slides[0].getTextRuns();
+               txt = slides[0].getTextParagraphs();
                assertEquals(2, txt.length);
 
                assertEquals("Title text", txt[0].getRawText());
-               assertEquals(1, txt[0].getRichTextRuns().length);
-               rt = txt[0].getRichTextRuns()[0];
+               assertEquals(1, txt[0].getTextRuns().length);
+               rt = txt[0].getTextRuns()[0];
                assertFalse(rt.isBullet());
 
                // Add some new text
                txt[0].appendText("Foo! I'm new!");
-               assertEquals(2, txt[0].getRichTextRuns().length);
+               assertEquals(2, txt[0].getTextRuns().length);
 
-               rt = txt[0].getRichTextRuns()[0];
+               rt = txt[0].getTextRuns()[0];
                assertFalse(rt.isBold());
-               assertEquals("Title text", rt.getText());
-               rt = txt[0].getRichTextRuns()[1];
+               assertEquals("Title text", rt.getRawText());
+               rt = txt[0].getTextRuns()[1];
                assertFalse(rt.isBold());
-               assertEquals("Foo! I'm new!", rt.getText());
+               assertEquals("Foo! I'm new!", rt.getRawText());
                rt.setBold(true);
 
                // And some more
                txt[0].appendText("Me too!");
-               assertEquals(3, txt[0].getRichTextRuns().length);
-               rt = txt[0].getRichTextRuns()[0];
+               assertEquals(3, txt[0].getTextRuns().length);
+               rt = txt[0].getTextRuns()[0];
                assertFalse(rt.isBold());
-               assertEquals("Title text", rt.getText());
-               rt = txt[0].getRichTextRuns()[1];
+               assertEquals("Title text", rt.getRawText());
+               rt = txt[0].getTextRuns()[1];
                assertTrue(rt.isBold());
-               assertEquals("Foo! I'm new!", rt.getText());
-               rt = txt[0].getRichTextRuns()[2];
+               assertEquals("Foo! I'm new!", rt.getRawText());
+               rt = txt[0].getTextRuns()[2];
                assertFalse(rt.isBold());
-               assertEquals("Me too!", rt.getText());
+               assertEquals("Me too!", rt.getRawText());
 
                // Save and re-open
                ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -607,18 +607,18 @@ if(false) {
 
                assertEquals(2, slides.length);
 
-               txt = slides[0].getTextRuns();
+               txt = slides[0].getTextParagraphs();
                assertEquals(2, txt.length);
-               assertEquals(3, txt[0].getRichTextRuns().length);
-               rt = txt[0].getRichTextRuns()[0];
+               assertEquals(3, txt[0].getTextRuns().length);
+               rt = txt[0].getTextRuns()[0];
                assertFalse(rt.isBold());
-               assertEquals("Title text", rt.getText());
-               rt = txt[0].getRichTextRuns()[1];
+               assertEquals("Title text", rt.getRawText());
+               rt = txt[0].getTextRuns()[1];
                assertTrue(rt.isBold());
-               assertEquals("Foo! I'm new!", rt.getText());
-               rt = txt[0].getRichTextRuns()[2];
+               assertEquals("Foo! I'm new!", rt.getRawText());
+               rt = txt[0].getTextRuns()[2];
                assertFalse(rt.isBold());
-               assertEquals("Me too!", rt.getText());
+               assertEquals("Me too!", rt.getRawText());
 
 //             FileOutputStream fout = new FileOutputStream("/tmp/foo.ppt");
 //             ppt.write(fout);
@@ -634,17 +634,17 @@ if(false) {
       assertEquals(1, slides.length);
       
       // One block of text within that
-      txt = slides[0].getTextRuns();
+      txt = slides[0].getTextParagraphs();
       assertEquals(1, txt.length);
       
       // One rich block of text in that - text is all the same style
       // TODO Is this completely correct?
-      rts = txt[0].getRichTextRuns();
+      rts = txt[0].getTextRuns();
       assertEquals(1, rts.length);
       rt = rts[0];
       
       // Check we can get the english text out of that
-      String text = rt.getText();
+      String text = rt.getRawText();
       assertContains(text, "Single byte");
       // And the chinese
       assertContains(text, "\uff8a\uff9d\uff76\uff78");
index fda2aba0d06260a9023db518ad1bd02b9432ed4d..000166b754b122d23f08989c9ebd05b3333c190a 100644 (file)
@@ -43,18 +43,18 @@ public final class TestSheetText extends TestCase {
                HSLFSheet slideOne = ss.getSlides()[0];
 
                String[] expectText = new String[] {"This is a test title","This is a test subtitle\nThis is on page 1"};
-               assertEquals(expectText.length, slideOne.getTextRuns().length);
+               assertEquals(expectText.length, slideOne.getTextParagraphs().length);
                for(int i=0; i<expectText.length; i++) {
-                       assertEquals(expectText[i], slideOne.getTextRuns()[i].getText());
+                       assertEquals(expectText[i], slideOne.getTextParagraphs()[i].getRawText());
                }
        }
 
        public void testSheetTwo() {
                HSLFSheet slideTwo = ss.getSlides()[1];
                String[] expectText = new String[] {"This is the title on page 2","This is page two\nIt has several blocks of text\nNone of them have formatting"};
-               assertEquals(expectText.length, slideTwo.getTextRuns().length);
+               assertEquals(expectText.length, slideTwo.getTextParagraphs().length);
                for(int i=0; i<expectText.length; i++) {
-                       assertEquals(expectText[i], slideTwo.getTextRuns()[i].getText());
+                       assertEquals(expectText[i], slideTwo.getTextParagraphs()[i].getRawText());
                }
        }
 
@@ -83,7 +83,7 @@ public final class TestSheetText extends TestCase {
                        "COP 11 \u2013 MOP 1\n" + // special long hyphen
                        "December 5, 2005\n";
 
-               assertEquals(1, s.getTextRuns().length);
-               assertEquals(exp, s.getTextRuns()[0].getText());
+               assertEquals(1, s.getTextParagraphs().length);
+               assertEquals(exp, s.getTextParagraphs()[0].getRawText());
        }
 }
index 35c2fdcdbcdf1621db48f6228646c28a00c21d61..0aaa8acb77a4d79a32dd9e99f920ffe2d308b898 100644 (file)
@@ -55,8 +55,8 @@ public final class TestSlideOrdering extends TestCase {
 
                String[] firstTRs = new String[] { "This is a test title", "This is the title on page 2" };
 
-               assertEquals(firstTRs[0], s1.getTextRuns()[0].getText());
-               assertEquals(firstTRs[1], s2.getTextRuns()[0].getText());
+               assertEquals(firstTRs[0], s1.getTextParagraphs()[0].getRawText());
+               assertEquals(firstTRs[1], s2.getTextParagraphs()[0].getRawText());
        }
 
        /**
@@ -71,9 +71,9 @@ public final class TestSlideOrdering extends TestCase {
 
                String[] firstTRs = new String[] { "Slide 1", "Slide 2", "Slide 3" };
 
-               assertEquals(firstTRs[0], s1.getTextRuns()[0].getText());
-               assertEquals(firstTRs[1], s2.getTextRuns()[0].getText());
-               assertEquals(firstTRs[2], s3.getTextRuns()[0].getText());
+               assertEquals(firstTRs[0], s1.getTextParagraphs()[0].getRawText());
+               assertEquals(firstTRs[1], s2.getTextParagraphs()[0].getRawText());
+               assertEquals(firstTRs[2], s3.getTextParagraphs()[0].getRawText());
        }
 
        /**
index 4f42af81daeb69c50affaa9aeca40c66346d4db7..4a456dc7710d3ed6fe46f52985744eb22d334a6a 100644 (file)
@@ -21,10 +21,7 @@ package org.apache.poi.hslf.usermodel;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hslf.model.HSLFShape;
-import org.apache.poi.hslf.model.HSLFSlide;
 import org.apache.poi.hslf.model.Table;
-import org.apache.poi.hslf.model.HSLFTextParagraph;
 import org.apache.poi.POIDataSamples;
 
 
@@ -48,12 +45,12 @@ public final class TestTable extends TestCase {
                checkSlide(slides[0]);
        }
        private void checkSlide(final HSLFSlide s) {
-               HSLFTextParagraph[] textRuns = s.getTextRuns();
+               HSLFTextParagraph[] textRuns = s.getTextParagraphs();
                assertEquals(2, textRuns.length);
 
-               HSLFTextRun textRun = textRuns[0].getRichTextRuns()[0];
+               HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
                assertEquals("Table sample", textRun.getRawText().trim());
-               assertEquals(1, textRuns[0].getRichTextRuns().length);
+               assertEquals(1, textRuns[0].getTextRuns().length);
                assertFalse(textRun.isBullet());
 
                assertEquals("Dummy text", textRuns[1].getRawText());
@@ -66,7 +63,7 @@ public final class TestTable extends TestCase {
                assertEquals(4, table.getNumberOfColumns());
                assertEquals(6, table.getNumberOfRows());
                for (int x = 0; x < 4; x ++) {
-                       assertEquals("TH Cell " + (x + 1), table.getCell(0, x).getTextParagraph().getRawText());
+                       assertEquals("TH Cell " + (x + 1), table.getCell(0, x).getTextParagraphs().getRawText());
                        for (int y = 1; y < 6; y++) {
                                assertEquals("Row " + y + ", Cell " + (x + 1), table.getCell(y, x).getText());
                        }
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
new file mode 100644 (file)
index 0000000..60676b6
--- /dev/null
@@ -0,0 +1,581 @@
+/* ====================================================================
+   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.usermodel;
+
+import static org.junit.Assert.*;
+
+import java.awt.Color;
+import java.io.*;
+import java.util.List;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.model.Table;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.*;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for TextRuns
+ *
+ * @author Nick Burch (nick at torchbox dot com)
+ */
+public final class TestTextRun {
+    private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
+
+       // SlideShow primed on the test data
+       private HSLFSlideShow ss;
+       private HSLFSlideShow ssRich;
+
+       @Before
+       public void setUp() throws IOException {
+
+               // Basic (non rich) test file
+               ss = new HSLFSlideShow(_slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
+
+               // Rich test file
+               ssRich = new HSLFSlideShow(_slTests.openResourceAsStream("Single_Coloured_Page.ppt"));
+       }
+
+       /**
+        * Test to ensure that getting the text works correctly
+        */
+       @Test
+       public void testGetText() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> textParas = slideOne.getTextParagraphs();
+
+               assertEquals(2, textParas.size());
+
+               // Get text works with \n
+               assertEquals("This is a test title", textParas.get(0).getTextRuns().get(0).getRawText());
+               assertEquals("This is a test subtitle\nThis is on page 1", textParas.get(1).getTextRuns().get(0).getRawText());
+
+               // Raw text has \r instead
+               assertEquals("This is a test title", textParas.get(0).getTextRuns().get(0).getRawText());
+               assertEquals("This is a test subtitle\rThis is on page 1", textParas.get(1).getTextRuns().get(0).getRawText());
+
+
+               // Now check on a rich text run
+               HSLFSlide slideOneR = ssRich.getSlides().get(0);
+               List<HSLFTextParagraph> textRunsR = slideOneR.getTextParagraphs();
+
+               assertEquals(2, textRunsR.size());
+               assertEquals("This is a title, it\u2019s in black", textRunsR.get(0).getTextRuns().get(0).getRawText());
+               assertEquals("This is the subtitle, in bold\nThis bit is blue and italic\nThis bit is red (normal)", textRunsR.get(1).getTextRuns().get(0).getRawText());
+               assertEquals("This is a title, it\u2019s in black", textRunsR.get(0).getTextRuns().get(0).getRawText());
+               assertEquals("This is the subtitle, in bold\rThis bit is blue and italic\rThis bit is red (normal)", textRunsR.get(1).getTextRuns().get(0).getRawText());
+       }
+
+       /**
+        * Test to ensure changing non rich text bytes->bytes works correctly
+        */
+       @Test
+       public void testSetText() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+               HSLFTextParagraph run = textRuns.get(0);
+               HSLFTextRun tr =  run.getTextRuns().get(0);
+
+               // Check current text
+               assertEquals("This is a test title", tr.getRawText());
+
+               // Change
+               String changeTo = "New test title";
+               tr.setText(changeTo);
+               assertEquals(changeTo, tr.getRawText());
+
+               // Ensure trailing \n's are NOT stripped, it is legal to set a text with a trailing '\r'
+               tr.setText(changeTo + "\n");
+               assertEquals(changeTo + "\n", tr.getRawText());
+       }
+
+       /**
+        * Test to ensure that changing non rich text between bytes and
+        *  chars works correctly
+        */
+       @Test
+       public void testAdvancedSetText() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> paras = slideOne.getTextParagraphs();
+               HSLFTextParagraph para = paras.get(0);
+               
+        TextHeaderAtom tha = null;
+        TextBytesAtom tba = null;
+        TextCharsAtom tca = null;
+               for (Record r : para.getRecords()) {
+                   if (r instanceof TextHeaderAtom) tha = (TextHeaderAtom)r;
+                   else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r;
+                   else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
+               }
+               
+
+               // Bytes -> Bytes
+               assertNull(tca);
+               assertNotNull(tba);
+               // assertFalse(run._isUnicode);
+               assertEquals("This is a test title", para.getTextRuns().get(0).getRawText());
+
+               String changeBytesOnly = "New Test Title";
+               HSLFTextParagraph.setText(paras, changeBytesOnly);
+               para = paras.get(0);
+               tha = null; tba = null; tca = null;
+        for (Record r : para.getRecords()) {
+            if (r instanceof TextHeaderAtom) tha = (TextHeaderAtom)r;
+            else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r;
+            else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
+        }
+               
+               assertEquals(changeBytesOnly, HSLFTextParagraph.getRawText(paras));
+               assertNull(tca);
+               assertNotNull(tba);
+
+               // Bytes -> Chars
+        assertNull(tca);
+        assertNotNull(tba);
+               assertEquals(changeBytesOnly, HSLFTextParagraph.getRawText(paras));
+
+               String changeByteChar = "This is a test title with a '\u0121' g with a dot";
+               HSLFTextParagraph.setText(paras, changeByteChar);
+               para = paras.get(0);
+        tha = null; tba = null; tca = null;
+        for (Record r : para.getRecords()) {
+            if (r instanceof TextHeaderAtom) tha = (TextHeaderAtom)r;
+            else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r;
+            else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
+        }              
+
+               assertEquals(changeByteChar, HSLFTextParagraph.getRawText(paras));
+               assertNotNull(tca);
+               assertNull(tba);
+
+               // Chars -> Chars
+               assertNull(tba);
+               assertNotNull(tca);
+               assertEquals(changeByteChar, HSLFTextParagraph.getRawText(paras));
+
+               String changeCharChar = "This is a test title with a '\u0147' N with a hat";
+               HSLFTextParagraph.setText(paras, changeCharChar);
+        para = paras.get(0);
+        tha = null; tba = null; tca = null;
+        for (Record r : para.getRecords()) {
+            if (r instanceof TextHeaderAtom) tha = (TextHeaderAtom)r;
+            else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r;
+            else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
+        }       
+
+               assertEquals(changeCharChar, HSLFTextParagraph.getRawText(paras));
+               assertNotNull(tca);
+               assertNull(tba);
+       }
+
+       /**
+        * Tests to ensure that non rich text has the right default rich text run
+        *  set up for it
+        */
+       @Test
+       public void testGetRichTextNonRich() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+
+               assertEquals(2, textRuns.size());
+
+               HSLFTextParagraph trA = textRuns.get(0);
+               HSLFTextParagraph trB = textRuns.get(1);
+
+               assertEquals(1, trA.getTextRuns().size());
+               assertEquals(1, trB.getTextRuns().size());
+
+               HSLFTextRun rtrA = trA.getTextRuns().get(0);
+               HSLFTextRun rtrB = trB.getTextRuns().get(0);
+
+               assertEquals(HSLFTextParagraph.getRawText(textRuns.subList(0, 0)), rtrA.getRawText());
+               assertEquals(HSLFTextParagraph.getRawText(textRuns.subList(1, 1)), rtrB.getRawText());
+
+//             assertNull(rtrA._getRawCharacterStyle());
+//             assertNull(rtrA._getRawParagraphStyle());
+//             assertNull(rtrB._getRawCharacterStyle());
+//             assertNull(rtrB._getRawParagraphStyle());
+       }
+
+       /**
+        * Tests to ensure that the rich text runs are built up correctly
+        */
+       @Test
+       public void testGetRichText() {
+               HSLFSlide slideOne = ssRich.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+
+               assertEquals(2, textRuns.size());
+
+               HSLFTextParagraph trA = textRuns.get(0);
+               HSLFTextParagraph trB = textRuns.get(1);
+
+               assertEquals(1, trA.getTextRuns().size());
+               assertEquals(3, trB.getTextRuns().size());
+
+               HSLFTextRun rtrA = trA.getTextRuns().get(0);
+               HSLFTextRun rtrB = trB.getTextRuns().get(0);
+               HSLFTextRun rtrC = trB.getTextRuns().get(1);
+               HSLFTextRun rtrD = trB.getTextRuns().get(2);
+
+               assertEquals(HSLFTextParagraph.getRawText(textRuns.subList(0, 0)), rtrA.getRawText());
+
+               String trBstr = HSLFTextParagraph.getRawText(textRuns.subList(1, 1));
+               assertEquals(trBstr.substring(0, 30), rtrB.getRawText());
+               assertEquals(trBstr.substring(30,58), rtrC.getRawText());
+               assertEquals(trBstr.substring(58,82), rtrD.getRawText());
+
+//             assertNull(rtrA._getRawCharacterStyle());
+//             assertNull(rtrA._getRawParagraphStyle());
+//             assertNotNull(rtrB._getRawCharacterStyle());
+//             assertNotNull(rtrB._getRawParagraphStyle());
+//             assertNotNull(rtrC._getRawCharacterStyle());
+//             assertNotNull(rtrC._getRawParagraphStyle());
+//             assertNotNull(rtrD._getRawCharacterStyle());
+//             assertNotNull(rtrD._getRawParagraphStyle());
+
+               // Same paragraph styles
+//             assertEquals(rtrB._getRawParagraphStyle(), rtrC._getRawParagraphStyle());
+//             assertEquals(rtrB._getRawParagraphStyle(), rtrD._getRawParagraphStyle());
+
+               // Different char styles
+//             assertFalse( rtrB._getRawCharacterStyle().equals( rtrC._getRawCharacterStyle() ));
+//             assertFalse( rtrB._getRawCharacterStyle().equals( rtrD._getRawCharacterStyle() ));
+//             assertFalse( rtrC._getRawCharacterStyle().equals( rtrD._getRawCharacterStyle() ));
+       }
+
+       /**
+        * Tests to ensure that setting the text where the text isn't rich,
+        *  ensuring that everything stays with the same default styling
+        */
+       @Test
+       public void testSetTextWhereNotRich() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+               HSLFTextParagraph trB = textRuns.get(1);
+//             assertEquals(1, trB.getTextRuns().length);
+
+               HSLFTextRun rtrB = trB.getTextRuns().get(0);
+//             assertEquals(trB.getRawText(), rtrB.getRawText());
+//             assertNull(rtrB._getRawCharacterStyle());
+//             assertNull(rtrB._getRawParagraphStyle());
+
+               // Change text via normal
+//             trB.setText("Test Foo Test");
+               rtrB = trB.getTextRuns().get(0);
+//             assertEquals("Test Foo Test", trB.getRawText());
+//             assertEquals("Test Foo Test", rtrB.getRawText());
+//             assertNull(rtrB._getRawCharacterStyle());
+//             assertNull(rtrB._getRawParagraphStyle());
+       }
+
+       /**
+        * Tests to ensure that setting the text where the text is rich
+        *  sets everything to the same styling
+        */
+       @Test
+       public void testSetTextWhereRich() {
+               HSLFSlide slideOne = ssRich.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+               HSLFTextParagraph trB = textRuns.get(1);
+               assertEquals(3, trB.getTextRuns().size());
+
+               HSLFTextRun rtrB = trB.getTextRuns().get(0);
+               HSLFTextRun rtrC = trB.getTextRuns().get(1);
+               HSLFTextRun rtrD = trB.getTextRuns().get(2);
+//             TextPropCollection tpBP = rtrB._getRawParagraphStyle();
+//             TextPropCollection tpBC = rtrB._getRawCharacterStyle();
+//             TextPropCollection tpCP = rtrC._getRawParagraphStyle();
+//             TextPropCollection tpCC = rtrC._getRawCharacterStyle();
+//             TextPropCollection tpDP = rtrD._getRawParagraphStyle();
+//             TextPropCollection tpDC = rtrD._getRawCharacterStyle();
+
+//             assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
+//             assertNotNull(tpBP);
+//             assertNotNull(tpBC);
+//             assertNotNull(tpCP);
+//             assertNotNull(tpCC);
+//             assertNotNull(tpDP);
+//             assertNotNull(tpDC);
+//             assertTrue(tpBP.equals(tpCP));
+//             assertTrue(tpBP.equals(tpDP));
+//             assertTrue(tpCP.equals(tpDP));
+//             assertFalse(tpBC.equals(tpCC));
+//             assertFalse(tpBC.equals(tpDC));
+//             assertFalse(tpCC.equals(tpDC));
+
+               // Change text via normal
+//             trB.setText("Test Foo Test");
+
+               // Ensure now have first style
+//             assertEquals(1, trB.getTextRuns().length);
+//             rtrB = trB.getTextRuns().get(0);
+//             assertEquals("Test Foo Test", trB.getRawText());
+//             assertEquals("Test Foo Test", rtrB.getRawText());
+//             assertNotNull(rtrB._getRawCharacterStyle());
+//             assertNotNull(rtrB._getRawParagraphStyle());
+//             assertEquals( tpBP, rtrB._getRawParagraphStyle() );
+//             assertEquals( tpBC, rtrB._getRawCharacterStyle() );
+       }
+
+       /**
+        * Test to ensure the right stuff happens if we change the text
+        *  in a rich text run, that doesn't happen to actually be rich
+        */
+       @Test
+       public void testChangeTextInRichTextRunNonRich() {
+               HSLFSlide slideOne = ss.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+               HSLFTextParagraph trB = textRuns.get(1);
+//             assertEquals(1, trB.getTextRuns().length);
+//
+//             HSLFTextRun rtrB = trB.getTextRuns().get(0);
+//             assertEquals(trB.getRawText(), rtrB.getRawText());
+//             assertNull(rtrB._getRawCharacterStyle());
+//             assertNull(rtrB._getRawParagraphStyle());
+
+               // Change text via rich
+//             rtrB.setText("Test Test Test");
+//             assertEquals("Test Test Test", trB.getRawText());
+//             assertEquals("Test Test Test", rtrB.getRawText());
+
+               // Will now have dummy props
+//             assertNotNull(rtrB._getRawCharacterStyle());
+//             assertNotNull(rtrB._getRawParagraphStyle());
+       }
+
+       /**
+        * Tests to ensure changing the text within rich text runs works
+        *  correctly
+        */
+       @Test
+       public void testChangeTextInRichTextRun() {
+               HSLFSlide slideOne = ssRich.getSlides().get(0);
+               List<HSLFTextParagraph> textRuns = slideOne.getTextParagraphs();
+               HSLFTextParagraph trB = textRuns.get(1);
+               assertEquals(3, trB.getTextRuns().size());
+
+               // We start with 3 text runs, each with their own set of styles,
+               //  but all sharing the same paragraph styles
+               HSLFTextRun rtrB = trB.getTextRuns().get(0);
+               HSLFTextRun rtrC = trB.getTextRuns().get(1);
+               HSLFTextRun rtrD = trB.getTextRuns().get(2);
+//             TextPropCollection tpBP = rtrB._getRawParagraphStyle();
+//             TextPropCollection tpBC = rtrB._getRawCharacterStyle();
+//             TextPropCollection tpCP = rtrC._getRawParagraphStyle();
+//             TextPropCollection tpCC = rtrC._getRawCharacterStyle();
+//             TextPropCollection tpDP = rtrD._getRawParagraphStyle();
+//             TextPropCollection tpDC = rtrD._getRawCharacterStyle();
+
+               // Check text and stylings
+//             assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
+//             assertNotNull(tpBP);
+//             assertNotNull(tpBC);
+//             assertNotNull(tpCP);
+//             assertNotNull(tpCC);
+//             assertNotNull(tpDP);
+//             assertNotNull(tpDC);
+//             assertTrue(tpBP.equals(tpCP));
+//             assertTrue(tpBP.equals(tpDP));
+//             assertTrue(tpCP.equals(tpDP));
+//             assertFalse(tpBC.equals(tpCC));
+//             assertFalse(tpBC.equals(tpDC));
+//             assertFalse(tpCC.equals(tpDC));
+
+               // Check text in the rich runs
+               assertEquals("This is the subtitle, in bold\n", rtrB.getRawText());
+               assertEquals("This bit is blue and italic\n", rtrC.getRawText());
+               assertEquals("This bit is red (normal)", rtrD.getRawText());
+
+               String newBText = "New Subtitle, will still be bold\n";
+               String newCText = "New blue and italic text\n";
+               String newDText = "Funky new normal red text";
+               rtrB.setText(newBText);
+               rtrC.setText(newCText);
+               rtrD.setText(newDText);
+               assertEquals(newBText, rtrB.getRawText());
+               assertEquals(newCText, rtrC.getRawText());
+               assertEquals(newDText, rtrD.getRawText());
+
+//             assertEquals(newBText + newCText + newDText, trB.getRawText());
+
+               // The styles should have been updated for the new sizes
+//             assertEquals(newBText.length(), tpBC.getCharactersCovered());
+//             assertEquals(newCText.length(), tpCC.getCharactersCovered());
+//             assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger
+
+//             assertEquals(
+//                             newBText.length() + newCText.length() + newDText.length(),
+//                             tpBP.getCharactersCovered()
+//             );
+
+               // Paragraph style should be sum of text length
+//             assertEquals(newBText.length() + newCText.length() + newDText.length(), tpBP.getCharactersCovered());
+
+               // Check stylings still as expected
+//             TextPropCollection ntpBC = rtrB._getRawCharacterStyle();
+//             TextPropCollection ntpCC = rtrC._getRawCharacterStyle();
+//             TextPropCollection ntpDC = rtrD._getRawCharacterStyle();
+//             assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
+//             assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
+//             assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
+       }
+
+
+       /**
+        * Test case for Bug 41015.
+        *
+        * In some cases RichTextRun.getText() threw StringIndexOutOfBoundsException because
+        * of the wrong list of potential paragraph properties defined in StyleTextPropAtom.
+        *
+        */
+       @Test
+       public void testBug41015() throws IOException {
+               List<HSLFTextRun> rt;
+
+               HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("bug-41015.ppt"));
+               HSLFSlide sl = ppt.getSlides().get(0);
+               List<HSLFTextParagraph> txt = sl.getTextParagraphs();
+               assertEquals(2, txt.size());
+
+               rt = txt.get(0).getTextRuns();
+               assertEquals(1, rt.size());
+               assertEquals(0, txt.get(0).getIndentLevel());
+               assertEquals("sdfsdfsdf", rt.get(0).getRawText());
+
+               rt = txt.get(1).getTextRuns();
+               assertEquals(2, rt.size());
+               assertEquals(0, txt.get(0).getIndentLevel());
+               assertEquals("Sdfsdfsdf\n" +
+                               "Dfgdfg\n" +
+                               "Dfgdfgdfg\n", rt.get(0).getRawText());
+               assertEquals(1, txt.get(1).getIndentLevel());
+               assertEquals("Sdfsdfs\n" +
+                               "Sdfsdf\n", rt.get(1).getRawText());
+       }
+
+       /**
+        * Test creation of TextRun objects.
+        */
+       @Test
+       public void testAddTextRun() {
+               HSLFSlideShow ppt = new HSLFSlideShow();
+               HSLFSlide slide = ppt.createSlide();
+
+               assertNull(slide.getTextParagraphs());
+
+               HSLFTextBox shape1 = new HSLFTextBox();
+//             HSLFTextParagraph run1 = shape1.getTextParagraphs();
+//             assertSame(run1, shape1.createTextRun());
+//             run1.setText("Text 1");
+               slide.addShape(shape1);
+
+               //The array of Slide's text runs must be updated when new text shapes are added.
+//             HSLFTextParagraph[] runs = slide.getTextParagraphs();
+//             assertNotNull(runs);
+//             assertSame(run1, runs.get(0));
+//
+//             HSLFTextBox shape2 = new HSLFTextBox();
+//             HSLFTextParagraph run2 = shape2.getTextParagraphs();
+//             assertSame(run2, shape2.createTextRun());
+//             run2.setText("Text 2");
+//             slide.addShape(shape2);
+//
+//             runs = slide.getTextParagraphs();
+//             assertEquals(2, runs.length);
+//
+//             assertSame(run1, runs.get(0));
+//             assertSame(run2, runs.get(1));
+//
+//             //as getShapes()
+//             HSLFShape[] sh = slide.getShapes();
+//             assertEquals(2, sh.length);
+//             assertTrue(sh.get(0) instanceof HSLFTextBox);
+//             HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
+//             assertSame(run1, box1.getTextParagraphs());
+//             HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
+//             assertSame(run2, box2.getTextParagraphs());
+//
+//             //test Table - a complex group of shapes containing text objects
+//             HSLFSlide slide2 = ppt.createSlide();
+//             assertNull(slide2.getTextParagraphs());
+//             Table table = new Table(2, 2);
+//             slide2.addShape(table);
+//             runs = slide2.getTextParagraphs();
+//             assertNotNull(runs);
+//             assertEquals(4, runs.length);
+       }
+
+       @Test
+       public void test48916() throws IOException {
+//        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
+//        for(HSLFSlide slide : ppt.getSlides()){
+//            for(HSLFShape sh : slide.getShapes()){
+//                if(sh instanceof HSLFTextShape){
+//                    HSLFTextShape tx = (HSLFTextShape)sh;
+//                    HSLFTextParagraph run = tx.getTextParagraphs();
+//                    //verify that records cached in  TextRun and EscherTextboxWrapper are the same
+//                    Record[] runChildren = run.getRecords();
+//                    Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
+//                    assertEquals(runChildren.length, txboxChildren.length);
+//                    for(int i=0; i < txboxChildren.length; i++){
+//                        assertSame(txboxChildren.get(i), runChildren.get(i));
+//                    }
+//                    //caused NPE prior to fix of Bugzilla #48916 
+//                    run.getTextRuns().get(0).setBold(true);
+//                    run.getTextRuns().get(0).setFontColor(Color.RED);
+//                }
+//            }
+//        }
+//        ByteArrayOutputStream out = new ByteArrayOutputStream();
+//        ppt.write(out);
+//        ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
+//        for(HSLFSlide slide : ppt.getSlides()){
+//            for(HSLFShape sh : slide.getShapes()){
+//                if(sh instanceof HSLFTextShape){
+//                    HSLFTextShape tx = (HSLFTextShape)sh;
+//                    HSLFTextParagraph run = tx.getTextParagraphs();
+//                    HSLFTextRun rt = run.getTextRuns().get(0);
+//                    assertTrue(rt.isBold());
+//                    assertEquals(rt.getFontColor(), Color.RED);
+//                }
+//            }
+//        }
+
+    }
+
+       @Test
+       public void test52244() throws IOException {
+        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("52244.ppt"));
+        HSLFSlide slide = ppt.getSlides().get(0);
+        List<HSLFTextParagraph> runs = slide.getTextParagraphs();
+
+        assertEquals("Arial", runs.get(0).getTextRuns().get(0).getFontFamily());
+        assertEquals(36, runs.get(0).getTextRuns().get(0).getFontSize(), 0);
+
+        assertEquals("Arial", runs.get(1).getTextRuns().get(0).getFontFamily());
+        assertEquals(24, runs.get(1).getTextRuns().get(0).getFontSize(), 0);
+
+        assertEquals("Arial", runs.get(2).getTextRuns().get(0).getFontFamily());
+        assertEquals(32, runs.get(2).getTextRuns().get(0).getFontSize(), 0);
+
+    }
+
+}