diff --git a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java new file mode 100755 index 000000000..0f28c2a8c --- /dev/null +++ b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java @@ -0,0 +1,515 @@ + +/* ==================================================================== + 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.examples; + +import org.apache.poi.hslf.usermodel.*; +import org.apache.poi.hslf.model.*; +import org.apache.poi.hslf.record.TextHeaderAtom; + +import java.io.IOException; +import java.io.FileOutputStream; +import java.io.File; +import java.awt.*; + +/** + * Presentation for Fast Feather Track on ApacheconEU 2008 + * + * @author Yegor Kozlov + */ +public class ApacheconEU08 { + + public static void main(String[] args) throws IOException { + SlideShow ppt = new SlideShow(); + ppt.setPageSize(new Dimension(720, 540)); + + slide1(ppt); + slide2(ppt); + slide3(ppt); + slide4(ppt); + slide5(ppt); + slide6(ppt); + slide7(ppt); + slide8(ppt); + slide9(ppt); + slide10(ppt); + slide11(ppt); + slide12(ppt); + + FileOutputStream out = new FileOutputStream("apachecon_eu_08.ppt"); + ppt.write(out); + out.close(); + + } + + public static void slide1(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE); + tr1.setText("POI-HSLF"); + box1.setAnchor(new Rectangle(54, 78, 612, 115)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + 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); + + TextBox box3 = new TextBox(); + TextRun tr3 = box3.getTextRun(); + tr3.getRichTextRuns()[0].setFontSize(32); + box3.setHorizontalAlignment(TextBox.AlignCenter); + tr3.setText( + "Yegor Kozlov\r" + + "yegor - apache - org"); + box3.setAnchor(new Rectangle(206, 348, 310, 84)); + slide.addShape(box3); + } + + public static void slide2(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("What is HSLF?"); + box1.setAnchor(new Rectangle(36, 21, 648, 90)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.setRunType(TextHeaderAtom.BODY_TYPE); + tr2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " + + "of the Powerpoint binary file format. \r" + + "POI sub-project since 2005\r" + + "Started by Nick Birch, Yegor Kozlov joined soon after"); + box2.setAnchor(new Rectangle(36, 126, 648, 356)); + slide.addShape(box2); + + + } + + public static void slide3(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("HSLF in a Nutshell"); + box1.setAnchor(new Rectangle(36, 15, 648, 65)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + 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); + box2.setAnchor(new Rectangle(36, 80, 648, 200)); + slide.addShape(box2); + + TextBox box3 = new TextBox(); + TextRun tr3 = box3.getTextRun(); + tr3.setRunType(TextHeaderAtom.BODY_TYPE); + tr3.setText( + "Rich text\r" + + "Tables\r" + + "Shapes\r" + + "Pictures\r" + + "Master slides"); + tr3.getRichTextRuns()[0].setFontSize(24); + tr3.getRichTextRuns()[0].setIndentLevel(1); + box3.setAnchor(new Rectangle(36, 265, 648, 150)); + slide.addShape(box3); + + TextBox box4 = new TextBox(); + TextRun tr4 = box4.getTextRun(); + tr4.setRunType(TextHeaderAtom.BODY_TYPE); + tr4.setText("Access to low level data structures"); + box4.setAnchor(new Rectangle(36, 430, 648, 50)); + slide.addShape(box4); + } + + public static void slide4(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + String[][] txt1 = { + {"Note"}, + {"This presentation was created programmatically using POI HSLF"} + }; + Table table1 = new Table(2, 1); + for (int i = 0; i < txt1.length; i++) { + for (int j = 0; j < txt1[i].length; j++) { + TableCell cell = table1.getCell(i, j); + cell.setText(txt1[i][j]); + cell.getTextRun().getRichTextRuns()[0].setFontSize(10); + RichTextRun rt = cell.getTextRun().getRichTextRuns()[0]; + rt.setFontName("Arial"); + rt.setBold(true); + if(i == 0){ + rt.setFontSize(32); + rt.setFontColor(Color.white); + cell.getFill().setForegroundColor(new Color(0, 153, 204)); + } else { + rt.setFontSize(28); + cell.getFill().setForegroundColor(new Color(235, 239, 241)); + } + cell.setVerticalAlignment(TextBox.AnchorMiddle); + } + } + + Line border1 = table1.createBorder(); + border1.setLineColor(Color.black); + border1.setLineWidth(1.0); + table1.setAllBorders(border1); + + Line border2 = table1.createBorder(); + border2.setLineColor(Color.black); + border2.setLineWidth(2.0); + table1.setOutsideBorders(border2); + + table1.setColumnWidth(0, 510); + table1.setRowHeight(0, 60); + table1.setRowHeight(1, 100); + slide.addShape(table1); + + table1.moveTo(100, 100); + + TextBox box1 = new TextBox(); + box1.setHorizontalAlignment(TextBox.AlignCenter); + TextRun tr1 = box1.getTextRun(); + tr1.setText("The source code is available at\r" + + "http://people.apache.org/~yegor/apachecon_eu08/"); + RichTextRun rt = tr1.getRichTextRuns()[0]; + rt.setFontSize(24); + box1.setAnchor(new Rectangle(80, 356, 553, 65)); + slide.addShape(box1); + + } + + public static void slide5(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("HSLF in Action - 1\rData Extraction"); + box1.setAnchor(new Rectangle(36, 21, 648, 100)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.setRunType(TextHeaderAtom.BODY_TYPE); + tr2.setText( + "Text from slides and notes\r" + + "Images\r" + + "Shapes and their properties (type, position in the slide, color, font, etc.)"); + box2.setAnchor(new Rectangle(36, 150, 648, 300)); + slide.addShape(box2); + + + } + + public static void slide6(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("HSLF in Action - 2"); + box1.setAnchor(new Rectangle(36, 20, 648, 90)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.getRichTextRuns()[0].setFontSize(18); + tr2.setText("Creating a simple presentation from scratch"); + box2.setAnchor(new Rectangle(170, 100, 364, 30)); + slide.addShape(box2); + + TextBox box3 = new TextBox(); + TextRun tr3 = box3.getTextRun(); + RichTextRun rt3 = tr3.getRichTextRuns()[0]; + rt3.setFontName("Courier New"); + rt3.setFontSize(8); + tr3.setText( + " SlideShow ppt = new SlideShow();\r" + + " Slide slide = ppt.createSlide();\r" + + "\r" + + " TextBox box2 = new TextBox();\r" + + " box2.setHorizontalAlignment(TextBox.AlignCenter);\r" + + " box2.setVerticalAlignment(TextBox.AnchorMiddle);\r" + + " box2.getTextRun().setText(\"Java Code\");\r" + + " box2.getFill().setForegroundColor(new Color(187, 224, 227));\r" + + " box2.setLineColor(Color.black);\r" + + " box2.setLineWidth(0.75);\r" + + " box2.setAnchor(new Rectangle(66, 243, 170, 170));\r" + + " slide.addShape(box2);\r" + + "\r" + + " TextBox box3 = new TextBox();\r" + + " box3.setHorizontalAlignment(TextBox.AlignCenter);\r" + + " box3.setVerticalAlignment(TextBox.AnchorMiddle);\r" + + " box3.getTextRun().setText(\"*.ppt file\");\r" + + " box3.setLineWidth(0.75);\r" + + " box3.setLineColor(Color.black);\r" + + " box3.getFill().setForegroundColor(new Color(187, 224, 227));\r" + + " box3.setAnchor(new Rectangle(473, 243, 170, 170));\r" + + " slide.addShape(box3);\r" + + "\r" + + " AutoShape box4 = new AutoShape(ShapeTypes.Arrow);\r" + + " box4.getFill().setForegroundColor(new Color(187, 224, 227));\r" + + " box4.setLineWidth(0.75);\r" + + " box4.setLineColor(Color.black);\r" + + " box4.setAnchor(new Rectangle(253, 288, 198, 85));\r" + + " slide.addShape(box4);\r" + + "\r" + + " FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" + + " ppt.write(out);\r" + + " out.close();"); + box3.setAnchor(new Rectangle(30, 150, 618, 411)); + slide.addShape(box3); + } + + public static void slide7(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box2 = new TextBox(); + box2.setHorizontalAlignment(TextBox.AlignCenter); + box2.setVerticalAlignment(TextBox.AnchorMiddle); + box2.getTextRun().setText("Java Code"); + box2.getFill().setForegroundColor(new Color(187, 224, 227)); + box2.setLineColor(Color.black); + box2.setLineWidth(0.75); + box2.setAnchor(new Rectangle(66, 243, 170, 170)); + slide.addShape(box2); + + TextBox box3 = new TextBox(); + box3.setHorizontalAlignment(TextBox.AlignCenter); + box3.setVerticalAlignment(TextBox.AnchorMiddle); + box3.getTextRun().setText("*.ppt file"); + box3.setLineWidth(0.75); + box3.setLineColor(Color.black); + box3.getFill().setForegroundColor(new Color(187, 224, 227)); + box3.setAnchor(new Rectangle(473, 243, 170, 170)); + slide.addShape(box3); + + AutoShape box4 = new AutoShape(ShapeTypes.Arrow); + box4.getFill().setForegroundColor(new Color(187, 224, 227)); + box4.setLineWidth(0.75); + box4.setLineColor(Color.black); + box4.setAnchor(new Rectangle(253, 288, 198, 85)); + slide.addShape(box4); + } + + public static void slide8(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("Wait, there is more!"); + box1.setAnchor(new Rectangle(36, 21, 648, 90)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.setRunType(TextHeaderAtom.BODY_TYPE); + tr2.setText( + "Rich text\r" + + "Tables\r" + + "Pictures (JPEG, PNG, BMP, WMF, PICT)\r" + + "Comprehensive formatting features"); + box2.setAnchor(new Rectangle(36, 126, 648, 356)); + slide.addShape(box2); + } + + public static void slide9(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("HSLF in Action - 3"); + box1.setAnchor(new Rectangle(36, 20, 648, 50)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.getRichTextRuns()[0].setFontSize(18); + tr2.setText("PPGraphics2D: PowerPoint Graphics2D driver"); + box2.setAnchor(new Rectangle(178, 70, 387, 30)); + slide.addShape(box2); + + TextBox box3 = new TextBox(); + TextRun tr3 = box3.getTextRun(); + RichTextRun rt3 = tr3.getRichTextRuns()[0]; + rt3.setFontName("Courier New"); + rt3.setFontSize(8); + tr3.setText( + " //bar chart data. The first value is the bar color, the second is the width\r" + + " Object[] def = new Object[]{\r" + + " Color.yellow, new Integer(100),\r" + + " Color.green, new Integer(150),\r" + + " Color.gray, new Integer(75),\r" + + " Color.red, new Integer(200),\r" + + " };\r" + + "\r" + + " SlideShow ppt = new SlideShow();\r" + + " Slide slide = ppt.createSlide();\r" + + "\r" + + " ShapeGroup group = new ShapeGroup();\r" + + " //define position of the drawing in the slide\r" + + " Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);\r" + + " group.setAnchor(bounds);\r" + + " slide.addShape(group);\r" + + " Graphics2D graphics = new PPGraphics2D(group);\r" + + "\r" + + " //draw a simple bar graph\r" + + " int x = bounds.x + 50, y = bounds.y + 50;\r" + + " graphics.setFont(new Font(\"Arial\", Font.BOLD, 10));\r" + + " for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {\r" + + " graphics.setColor(Color.black);\r" + + " int width = ((Integer)def[i+1]).intValue();\r" + + " graphics.drawString(\"Q\" + idx, x-20, y+20);\r" + + " graphics.drawString(width + \"%\", x + width + 10, y + 20);\r" + + " graphics.setColor((Color)def[i]);\r" + + " graphics.fill(new Rectangle(x, y, width, 30));\r" + + " y += 40;\r" + + " }\r" + + " graphics.setColor(Color.black);\r" + + " graphics.setFont(new Font(\"Arial\", Font.BOLD, 14));\r" + + " graphics.draw(bounds);\r" + + " graphics.drawString(\"Performance\", x + 70, y + 40);\r" + + "\r" + + " FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" + + " ppt.write(out);\r" + + " out.close();"); + box3.setAnchor(new Rectangle(96, 110, 499, 378)); + slide.addShape(box3); + } + + public static void slide10(SlideShow ppt) throws IOException { + //bar chart data. The first value is the bar color, the second is the width + Object[] def = new Object[]{ + Color.yellow, new Integer(100), + Color.green, new Integer(150), + Color.gray, new Integer(75), + Color.red, new Integer(200), + }; + + Slide slide = ppt.createSlide(); + + ShapeGroup group = new ShapeGroup(); + //define position of the drawing in the slide + Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300); + group.setAnchor(bounds); + slide.addShape(group); + Graphics2D graphics = new PPGraphics2D(group); + + //draw a simple bar graph + int x = bounds.x + 50, y = bounds.y + 50; + graphics.setFont(new Font("Arial", Font.BOLD, 10)); + for (int i = 0, idx = 1; i < def.length; i+=2, idx++) { + graphics.setColor(Color.black); + int width = ((Integer)def[i+1]).intValue(); + graphics.drawString("Q" + idx, x-20, y+20); + graphics.drawString(width + "%", x + width + 10, y + 20); + graphics.setColor((Color)def[i]); + graphics.fill(new Rectangle(x, y, width, 30)); + y += 40; + } + graphics.setColor(Color.black); + graphics.setFont(new Font("Arial", Font.BOLD, 14)); + graphics.draw(bounds); + graphics.drawString("Performance", x + 70, y + 40); + + } + + public static void slide11(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.TITLE_TYPE); + tr1.setText("HSLF Development Plans"); + box1.setAnchor(new Rectangle(36, 21, 648, 90)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.setRunType(TextHeaderAtom.BODY_TYPE); + tr2.setText( + "Support for more PowerPoint functionality\r" + + "Rendering slides into java.awt.Graphics2D"); + box2.setAnchor(new Rectangle(36, 126, 648, 100)); + slide.addShape(box2); + + TextBox box3 = new TextBox(); + TextRun tr3 = box3.getTextRun(); + tr3.setRunType(TextHeaderAtom.BODY_TYPE); + tr3.getRichTextRuns()[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); + + TextBox box4 = new TextBox(); + TextRun tr4 = box4.getTextRun(); + tr4.setRunType(TextHeaderAtom.BODY_TYPE); + tr4.setText( + "Integration with Apache FOP - Formatting Objects Processor"); + box4.setAnchor(new Rectangle(36, 290, 648, 90)); + slide.addShape(box4); + + TextBox box5 = new TextBox(); + TextRun tr5 = box5.getTextRun(); + tr5.setRunType(TextHeaderAtom.BODY_TYPE); + tr5.getRichTextRuns()[0].setIndentLevel(1); + tr5.setText( + "Transformation of XSL-FO into PPT\r" + + "PPT2PDF transcoder"); + box5.setAnchor(new Rectangle(36, 380, 648, 100)); + slide.addShape(box5); + } + + public static void slide12(SlideShow ppt) throws IOException { + Slide slide = ppt.createSlide(); + + TextBox box1 = new TextBox(); + TextRun tr1 = box1.getTextRun(); + tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE); + tr1.setText("Questions?"); + box1.setAnchor(new Rectangle(54, 167, 612, 115)); + slide.addShape(box1); + + TextBox box2 = new TextBox(); + TextRun tr2 = box2.getTextRun(); + tr2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE); + tr2.setText( + "http://poi.apache.org/hslf/\r" + + "http://people.apache.org/~yegor"); + box2.setAnchor(new Rectangle(108, 306, 504, 138)); + slide.addShape(box2); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java index f9cc43a7e..436b5188f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java @@ -23,8 +23,8 @@ import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.usermodel.PictureData; import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.POILogFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import java.awt.*; import java.util.*; @@ -36,7 +36,7 @@ import java.util.*; */ public class Fill { // For logging - protected POILogger logger = POILogFactory.getLogger(this.getClass()); + protected Log log = LogFactory.getLog(this.getClass()); /** * Fill with a solid color @@ -154,8 +154,7 @@ public class Fill { public void setForegroundColor(Color color){ EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); if (color == null) { - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1); - Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150010); + Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000); } else { int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); @@ -214,7 +213,7 @@ public class Fill { java.util.List lst = bstore.getChildRecords(); int idx = p.getPropertyValue(); if (idx == 0){ - logger.log(POILogger.ERROR, "no reference to picture data found "); + log.error("no reference to picture data found "); } else { EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1); for ( int i = 0; i < pict.length; i++ ) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java b/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java new file mode 100755 index 000000000..502363346 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java @@ -0,0 +1,149 @@ +/* ==================================================================== + 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.util.LittleEndian; + +import java.awt.geom.*; +import java.util.ArrayList; + +/** + * A "Freeform" shape. + * + *
+ * 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 java.awt.geom.GeneralPath
.
+ *
EscherSpContainer
container which holds information about this shape
+ * @param parent the parent of the shape
+ */
+ protected Freeform(EscherContainerRecord escherRecord, Shape 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 Freeform(Shape parent){
+ super(null, parent);
+ _escherContainer = createSpContainer(ShapeTypes.NotPrimitive, parent instanceof ShapeGroup);
+ }
+
+ /**
+ * Create a new Freeform. This constructor is used when a new shape is created.
+ *
+ */
+ public Freeform(){
+ this(null);
+ }
+
+ /**
+ * Set the shape path
+ *
+ * @param path
+ */
+ public void setPath(GeneralPath path)
+ {
+ Rectangle2D bounds = path.getBounds2D();
+ PathIterator it = path.getPathIterator(new AffineTransform());
+
+ ArrayList segInfo = new ArrayList();
+ ArrayList pntInfo = new ArrayList();
+ 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(new byte[]{0x00, 0x40});
+ break;
+ case PathIterator.SEG_LINETO:
+ pntInfo.add(new Point2D.Double(vals[0], vals[1]));
+ segInfo.add(new byte[]{0x00, (byte)0xAC});
+ segInfo.add(new byte[]{0x01, 0x00 });
+ 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(new byte[]{0x00, (byte)0xAD});
+ segInfo.add(new byte[]{0x01, 0x20 });
+ break;
+ case PathIterator.SEG_QUADTO:
+ System.err.println("SEG_QUADTO is not supported");
+ break;
+ case PathIterator.SEG_CLOSE:
+ pntInfo.add(pntInfo.get(0));
+ segInfo.add(new byte[]{0x00, (byte)0xAC});
+ segInfo.add(new byte[]{0x01, 0x00 });
+ segInfo.add(new byte[]{0x00, (byte)0xAC});
+ segInfo.add(new byte[]{0x01, (byte)0x60});
+ isClosed = true;
+ break;
+ }
+
+ it.next();
+ }
+ if(!isClosed) segInfo.add(new byte[]{0x00, (byte)0xAC});
+ segInfo.add(new byte[]{0x00, (byte)0x80});
+
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ 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 = (Point2D.Double)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 = (byte[])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);
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
index 4aad44d75..cb001ccf9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
@@ -53,11 +53,6 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
private Color background;
private RenderingHints hints;
- /**
- * the maximum distance that the line segments used to approximate the curved segments
- */
- public static final float FLATNESS = 0.1f;
-
/**
* Construct Java Graphics object which translates graphic calls in ppt drawing layer.
*
@@ -218,29 +213,12 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see #setComposite
*/
public void draw(Shape shape){
-
- PathIterator it = shape.getPathIterator(transform, FLATNESS);
- double[] prev = null;
- double[] coords = new double[6];
- double[] first = new double[6];
- if(!it.isDone()) it.currentSegment(first); //first point
- while(!it.isDone()){
- int type = it.currentSegment(coords);
- if (prev != null ){
- Line line = new Line(group);
- applyPaint(line);
- applyStroke(line);
- if (type == PathIterator.SEG_LINETO) {
- line.setAnchor(new Rectangle2D.Double(prev[0], prev[1], (coords[0] - prev[0]), (coords[1] - prev[1])));
- } else if (type == PathIterator.SEG_CLOSE){
- line.setAnchor(new Rectangle2D.Double(coords[0], coords[1], (first[0] - coords[0]), (first[1] - coords[1])));
- }
- group.addShape(line);
- }
- prev = new double[]{coords[0], coords[1]};
- it.next();
- }
-
+ GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
+ Freeform p = new Freeform(group);
+ p.setPath(path);
+ p.getFill().setForegroundColor(null);
+ applyStroke(p);
+ group.addShape(p);
}
/**
@@ -299,7 +277,7 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* Even if top and bottom margins are set to 0 PowerPoint
* always sets extra space between the text and its bounding box.
*
- * Approximation height = ascent*2 works good enough in most cases
+ * The approximation height = ascent*2 works good enough in most cases
*/
float height = ascent * 2;
@@ -335,28 +313,12 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see #setClip
*/
public void fill(Shape shape){
- PathIterator it = shape.getPathIterator(transform, FLATNESS);
- ArrayList pnt = new ArrayList();
- double[] coords = new double[6];
- while(!it.isDone()){
- int type = it.currentSegment(coords);
- if (type != PathIterator.SEG_CLOSE) {
- pnt.add(new Point2D.Double(coords[0], coords[1]));
- }
- it.next();
- }
- if(pnt.size() > 0){
- Point2D[] points = (Point2D[])pnt.toArray(new Point2D[pnt.size()]);
- Polygon p = new Polygon(group);
- p.setPoints(points);
- applyPaint(p);
-
- p.setLineColor(null); //Fills must be "No Line"
-
- Rectangle2D bounds = transform.createTransformedShape(shape).getBounds2D();
- p.setAnchor(bounds);
- group.addShape(p);
- }
+ GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
+ Freeform p = new Freeform(group);
+ p.setPath(path);
+ applyPaint(p);
+ p.setLineColor(null); //Fills must be "No Line"
+ group.addShape(p);
}
/**
@@ -459,11 +421,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){
- AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group);
- shape.setFillColor(null);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ draw(rect);
}
/**
@@ -493,11 +452,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#drawOval
*/
public void fillOval(int x, int y, int width, int height){
- AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group);
- applyPaint(shape);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ fill(oval);
}
/**
@@ -518,11 +474,9 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){
- AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group);
- applyPaint(shape);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+
+ RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ fill(rect);
}
/**
@@ -563,11 +517,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle){
- AutoShape shape = new AutoShape(ShapeTypes.Arc, group);
- applyPaint(shape);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
+ fill(arc);
}
/**
@@ -609,11 +560,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle) {
- AutoShape shape = new AutoShape(ShapeTypes.Arc, group);
- shape.setFillColor(null);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
+ draw(arc);
}
@@ -659,11 +607,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#fillOval
*/
public void drawOval(int x, int y, int width, int height){
- AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group);
- shape.setFillColor(null);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ draw(oval);
}
/**
@@ -998,11 +943,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#drawRect
*/
public void fillRect(int x, int y, int width, int height){
- AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group);
- applyPaint(shape);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
+ Rectangle rect = new Rectangle(x, y, width, height);
+ fill(rect);
}
/**
@@ -1022,12 +964,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#clearRect
*/
public void drawRect(int x, int y, int width, int height) {
- AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group);
- shape.setFillColor(null);
- applyStroke(shape);
- shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
- group.addShape(shape);
-
+ Rectangle rect = new Rectangle(x, y, width, height);
+ draw(rect);
}
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
index 90efd5f3e..4866779b9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
@@ -21,7 +21,6 @@ import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.blip.Bitmap;
-import org.apache.poi.util.POILogger;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -179,7 +178,7 @@ public class Picture extends SimpleShape {
List lst = bstore.getChildRecords();
int idx = getPictureIndex();
if (idx == 0){
- logger.log(POILogger.ERROR, "no reference to picture data found ");
+ log.error("no reference to picture data found ");
} else {
EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
for ( int i = 0; i < pict.length; i++ ) {
@@ -187,7 +186,7 @@ public class Picture extends SimpleShape {
return pict[i];
}
}
- logger.log(POILogger.ERROR, "no picture found for our BSE offset " + bse.getOffset());
+ log.error("no picture found for our BSE offset " + bse.getOffset());
}
return null;
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
index 2e23c5926..220a512dc 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
@@ -19,8 +19,8 @@ package org.apache.poi.hslf.model;
import org.apache.poi.ddf.*;
import org.apache.poi.hslf.model.ShapeTypes;
import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import java.util.Iterator;
import java.awt.*;
@@ -45,7 +45,7 @@ import java.awt.geom.Rectangle2D;
public abstract class Shape {
// For logging
- protected POILogger logger = POILogFactory.getLogger(this.getClass());
+ protected Log log = LogFactory.getLog(this.getClass());
/**
* In Escher absolute distances are specified in
@@ -89,6 +89,11 @@ public abstract class Shape {
*/
protected Sheet _sheet;
+ /**
+ * Fill
+ */
+ protected Fill _fill;
+
/**
* Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
*
@@ -344,7 +349,8 @@ public abstract class Shape {
* @return fill properties of this shape
*/
public Fill getFill(){
- return new Fill(this);
+ if(_fill == null) _fill = new Fill(this);
+ return _fill;
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
index dbcc8069c..7b79ebad9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
@@ -18,7 +18,6 @@ package org.apache.poi.hslf.model;
import org.apache.poi.ddf.*;
import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
import java.util.ArrayList;
import java.util.List;
@@ -71,7 +70,7 @@ public class ShapeGroup extends 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());
+ log.error("Shape contained non container escher record, was " + r.getClass().getName());
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
index 58fc33305..85d672fe8 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
@@ -187,26 +187,7 @@ public class SimpleShape extends Shape {
* The color used to fill this shape.
*/
public Color getFillColor(){
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
- EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR);
- EscherSimpleProperty p2= (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
-
- int p2val = p2 == null ? 0 : p2.getPropertyValue();
-
- Color clr = null;
- if (p1 != null && (p2val & 0x10) != 0){
- int rgb = p1.getPropertyValue();
- if (rgb >= 0x8000000) {
- int idx = rgb % 0x8000000;
- if(getSheet() != null) {
- ColorSchemeAtom ca = getSheet().getColorScheme();
- rgb = ca.getColor(idx);
- }
- }
- Color tmp = new Color(rgb, true);
- clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
- }
- return clr;
+ return getFill().getForegroundColor();
}
/**
@@ -215,14 +196,7 @@ public class SimpleShape extends Shape {
* @param color the background color
*/
public void setFillColor(Color color){
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
- if(color == null) {
- setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
- } else {
- int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
- setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
- setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
- }
+ getFill().setForegroundColor(color);
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
index 1f9a489a7..8a54e079c 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
@@ -22,7 +22,6 @@ import org.apache.poi.ddf.*;
import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.usermodel.RichTextRun;
import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.util.POILogger;
import java.awt.*;
import java.awt.font.FontRenderContext;
@@ -480,7 +479,7 @@ public class TextBox extends SimpleShape {
}
}
if(_txtrun == null) {
- logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
+ log.warn("text run not found for OutlineTextRefAtom.TextIndex=" + idx);
}
} else {
int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java
index 12aca6fa3..7efe956e2 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java
@@ -83,7 +83,7 @@ public class TestPPGraphics2D extends TestCase {
group = (ShapeGroup)shape[0];
shape = group.getShapes();
- assertEquals(shape.length, 7);
+ assertEquals(shape.length, 3);
}
}