git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@647713 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_0_3_BETA1
@@ -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); | |||
} | |||
} |
@@ -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++ ) { |
@@ -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. | |||
* | |||
* <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 class Freeform extends AutoShape { | |||
/** | |||
* 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 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); | |||
} | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
@@ -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()); | |||
} | |||
} | |||
@@ -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); | |||
} | |||
} |
@@ -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(); |
@@ -83,7 +83,7 @@ public class TestPPGraphics2D extends TestCase { | |||
group = (ShapeGroup)shape[0]; | |||
shape = group.getShapes(); | |||
assertEquals(shape.length, 7); | |||
assertEquals(shape.length, 3); | |||
} | |||
} |