misc usermodel improvements. Also added the source code for the ApacheconEU08 FFT presentation

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@647713 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-04-14 09:21:57 +00:00
parent 874b349c58
commit 7bf8c0afbe
10 changed files with 716 additions and 138 deletions

View File

@ -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);
}
}

View File

@ -23,8 +23,8 @@ import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.usermodel.PictureData; import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.util.POILogger; import org.apache.commons.logging.Log;
import org.apache.poi.util.POILogFactory; import org.apache.commons.logging.LogFactory;
import java.awt.*; import java.awt.*;
import java.util.*; import java.util.*;
@ -36,7 +36,7 @@ import java.util.*;
*/ */
public class Fill { public class Fill {
// For logging // For logging
protected POILogger logger = POILogFactory.getLogger(this.getClass()); protected Log log = LogFactory.getLog(this.getClass());
/** /**
* Fill with a solid color * Fill with a solid color
@ -154,8 +154,7 @@ public class Fill {
public void setForegroundColor(Color color){ public void setForegroundColor(Color color){
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
if (color == null) { if (color == null) {
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1); Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150010);
} }
else { else {
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); 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(); java.util.List lst = bstore.getChildRecords();
int idx = p.getPropertyValue(); int idx = p.getPropertyValue();
if (idx == 0){ if (idx == 0){
logger.log(POILogger.ERROR, "no reference to picture data found "); log.error("no reference to picture data found ");
} else { } else {
EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1); EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1);
for ( int i = 0; i < pict.length; i++ ) { for ( int i = 0; i < pict.length; i++ ) {

View File

@ -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);
}
}

View File

@ -53,11 +53,6 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
private Color background; private Color background;
private RenderingHints hints; 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. * 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 * @see #setComposite
*/ */
public void draw(Shape shape){ public void draw(Shape shape){
GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
PathIterator it = shape.getPathIterator(transform, FLATNESS); Freeform p = new Freeform(group);
double[] prev = null; p.setPath(path);
double[] coords = new double[6]; p.getFill().setForegroundColor(null);
double[] first = new double[6]; applyStroke(p);
if(!it.isDone()) it.currentSegment(first); //first point group.addShape(p);
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();
}
} }
/** /**
@ -299,7 +277,7 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* Even if top and bottom margins are set to 0 PowerPoint * Even if top and bottom margins are set to 0 PowerPoint
* always sets extra space between the text and its bounding box. * 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; float height = ascent * 2;
@ -335,28 +313,12 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see #setClip * @see #setClip
*/ */
public void fill(Shape shape){ public void fill(Shape shape){
PathIterator it = shape.getPathIterator(transform, FLATNESS); GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
ArrayList pnt = new ArrayList(); Freeform p = new Freeform(group);
double[] coords = new double[6]; p.setPath(path);
while(!it.isDone()){ applyPaint(p);
int type = it.currentSegment(coords); p.setLineColor(null); //Fills must be "No Line"
if (type != PathIterator.SEG_CLOSE) { group.addShape(p);
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);
}
} }
/** /**
@ -459,11 +421,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/ */
public void drawRoundRect(int x, int y, int width, int height, public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){ int arcWidth, int arcHeight){
AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group); RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
shape.setFillColor(null); draw(rect);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -493,11 +452,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#drawOval * @see java.awt.Graphics#drawOval
*/ */
public void fillOval(int x, int y, int width, int height){ public void fillOval(int x, int y, int width, int height){
AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group); Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
applyPaint(shape); fill(oval);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -518,11 +474,9 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/ */
public void fillRoundRect(int x, int y, int width, int height, public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){ int arcWidth, int arcHeight){
AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group);
applyPaint(shape); RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
applyStroke(shape); fill(rect);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -563,11 +517,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/ */
public void fillArc(int x, int y, int width, int height, public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle){ int startAngle, int arcAngle){
AutoShape shape = new AutoShape(ShapeTypes.Arc, group); Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
applyPaint(shape); fill(arc);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -609,11 +560,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
*/ */
public void drawArc(int x, int y, int width, int height, public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle) { int startAngle, int arcAngle) {
AutoShape shape = new AutoShape(ShapeTypes.Arc, group); Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
shape.setFillColor(null); draw(arc);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
@ -659,11 +607,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#fillOval * @see java.awt.Graphics#fillOval
*/ */
public void drawOval(int x, int y, int width, int height){ public void drawOval(int x, int y, int width, int height){
AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group); Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
shape.setFillColor(null); draw(oval);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -998,11 +943,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#drawRect * @see java.awt.Graphics#drawRect
*/ */
public void fillRect(int x, int y, int width, int height){ public void fillRect(int x, int y, int width, int height){
AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group); Rectangle rect = new Rectangle(x, y, width, height);
applyPaint(shape); fill(rect);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**
@ -1022,12 +964,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
* @see java.awt.Graphics#clearRect * @see java.awt.Graphics#clearRect
*/ */
public void drawRect(int x, int y, int width, int height) { public void drawRect(int x, int y, int width, int height) {
AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group); Rectangle rect = new Rectangle(x, y, width, height);
shape.setFillColor(null); draw(rect);
applyStroke(shape);
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
group.addShape(shape);
} }
/** /**

View File

@ -21,7 +21,6 @@ import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.blip.Bitmap; import org.apache.poi.hslf.blip.Bitmap;
import org.apache.poi.util.POILogger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -179,7 +178,7 @@ public class Picture extends SimpleShape {
List lst = bstore.getChildRecords(); List lst = bstore.getChildRecords();
int idx = getPictureIndex(); int idx = getPictureIndex();
if (idx == 0){ if (idx == 0){
logger.log(POILogger.ERROR, "no reference to picture data found "); log.error("no reference to picture data found ");
} else { } else {
EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1); EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
for ( int i = 0; i < pict.length; i++ ) { for ( int i = 0; i < pict.length; i++ ) {
@ -187,7 +186,7 @@ public class Picture extends SimpleShape {
return pict[i]; 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; return null;
} }

View File

@ -19,8 +19,8 @@ package org.apache.poi.hslf.model;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hslf.model.ShapeTypes; import org.apache.poi.hslf.model.ShapeTypes;
import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.util.POILogger; import org.apache.commons.logging.Log;
import org.apache.poi.util.POILogFactory; import org.apache.commons.logging.LogFactory;
import java.util.Iterator; import java.util.Iterator;
import java.awt.*; import java.awt.*;
@ -45,7 +45,7 @@ import java.awt.geom.Rectangle2D;
public abstract class Shape { public abstract class Shape {
// For logging // For logging
protected POILogger logger = POILogFactory.getLogger(this.getClass()); protected Log log = LogFactory.getLog(this.getClass());
/** /**
* In Escher absolute distances are specified in * In Escher absolute distances are specified in
@ -89,6 +89,11 @@ public abstract class Shape {
*/ */
protected Sheet _sheet; 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. * 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 * @return fill properties of this shape
*/ */
public Fill getFill(){ public Fill getFill(){
return new Fill(this); if(_fill == null) _fill = new Fill(this);
return _fill;
} }

View File

@ -18,7 +18,6 @@ package org.apache.poi.hslf.model;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -71,7 +70,7 @@ public class ShapeGroup extends Shape{
} else { } else {
// Should we do anything special with these non // Should we do anything special with these non
// Container records? // 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());
} }
} }

View File

@ -187,26 +187,7 @@ public class SimpleShape extends Shape {
* The color used to fill this shape. * The color used to fill this shape.
*/ */
public Color getFillColor(){ public Color getFillColor(){
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); return getFill().getForegroundColor();
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;
} }
/** /**
@ -215,14 +196,7 @@ public class SimpleShape extends Shape {
* @param color the background color * @param color the background color
*/ */
public void setFillColor(Color color){ public void setFillColor(Color color){
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); getFill().setForegroundColor(color);
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);
}
} }
} }

View File

@ -22,7 +22,6 @@ import org.apache.poi.ddf.*;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.usermodel.RichTextRun; import org.apache.poi.hslf.usermodel.RichTextRun;
import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.util.POILogger;
import java.awt.*; import java.awt.*;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
@ -480,7 +479,7 @@ public class TextBox extends SimpleShape {
} }
} }
if(_txtrun == null) { 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 { } else {
int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId(); int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();

View File

@ -83,7 +83,7 @@ public class TestPPGraphics2D extends TestCase {
group = (ShapeGroup)shape[0]; group = (ShapeGroup)shape[0];
shape = group.getShapes(); shape = group.getShapes();
assertEquals(shape.length, 7); assertEquals(shape.length, 3);
} }
} }