aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2015-10-29 01:05:27 +0000
committerAndreas Beeker <kiwiwings@apache.org>2015-10-29 01:05:27 +0000
commiteb1e1a28e8fe4815851b283789a2552bbac9afcb (patch)
tree40273b56cb9179d7341c57f19eac18a13995e02a /src
parent8f0093e4648f0e9598d26847984eee060535f951 (diff)
downloadpoi-eb1e1a28e8fe4815851b283789a2552bbac9afcb.tar.gz
poi-eb1e1a28e8fe4815851b283789a2552bbac9afcb.zip
Common sl unification - copy first paragraph / textrun properties on XSLFTextShape.setText()
Common sl unification - converted ApacheconEU08 example to common sl - added missing functionality Common sl unification - return null instead of default values for missing borders X/HSLFTable Common sl unification - use points in HSLFTable.setColumnWidth() Fix appending text to empty HSLFTextParagraph git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1711171 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java253
-rw-r--r--src/examples/src/org/apache/poi/hslf/examples/TableDemo.java18
-rw-r--r--src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java2
-rw-r--r--src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java5
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawTableShape.java112
-rw-r--r--src/java/org/apache/poi/sl/draw/SLGraphics.java1831
-rw-r--r--src/java/org/apache/poi/sl/usermodel/SimpleShape.java57
-rw-r--r--src/java/org/apache/poi/sl/usermodel/SlideShow.java7
-rw-r--r--src/java/org/apache/poi/sl/usermodel/StrokeStyle.java38
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TableCell.java61
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TableShape.java22
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TextBox.java7
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TextParagraph.java6
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TextRun.java143
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TextShape.java82
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java41
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java13
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java21
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java1
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java1
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java118
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java15
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java261
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java3
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java22
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java60
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java132
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java2
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java15
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java8
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java57
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java11
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java5
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java4
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java96
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java85
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java55
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java12
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java96
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java185
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java3
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java11
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java427
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java323
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java88
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java48
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java203
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java16
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java4
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java17
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java35
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java9
57 files changed, 4028 insertions, 1129 deletions
diff --git a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
index c911424726..8101c71f63 100644
--- a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
+++ b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
@@ -26,19 +26,20 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
-import org.apache.poi.hslf.model.PPGraphics2D;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.HSLFAutoShape;
-import org.apache.poi.hslf.usermodel.HSLFGroupShape;
-import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFTable;
-import org.apache.poi.hslf.usermodel.HSLFTableCell;
-import org.apache.poi.hslf.usermodel.HSLFTextBox;
-import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFLine;
+import org.apache.poi.sl.draw.DrawTableShape;
+import org.apache.poi.sl.draw.SLGraphics;
+import org.apache.poi.sl.usermodel.AutoShape;
+import org.apache.poi.sl.usermodel.GroupShape;
import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.TableCell;
+import org.apache.poi.sl.usermodel.TableShape;
+import org.apache.poi.sl.usermodel.TextBox;
+import org.apache.poi.sl.usermodel.TextParagraph;
+import org.apache.poi.sl.usermodel.TextRun;
+import org.apache.poi.sl.usermodel.TextShape.TextPlaceholder;
import org.apache.poi.sl.usermodel.VerticalAlignment;
/**
@@ -49,7 +50,8 @@ import org.apache.poi.sl.usermodel.VerticalAlignment;
public final class ApacheconEU08 {
public static void main(String[] args) throws IOException {
- HSLFSlideShow ppt = new HSLFSlideShow();
+ SlideShow<?,?> ppt = new HSLFSlideShow();
+ // SlideShow<?,?> ppt = new XMLSlideShow();
ppt.setPageSize(new Dimension(720, 540));
slide1(ppt);
@@ -65,69 +67,62 @@ public final class ApacheconEU08 {
slide11(ppt);
slide12(ppt);
- FileOutputStream out = new FileOutputStream("apachecon_eu_08.ppt");
+ String ext = ppt.getClass().getName().contains("HSLF") ? "ppt" : "pptx";
+ FileOutputStream out = new FileOutputStream("apachecon_eu_08."+ext);
ppt.write(out);
out.close();
}
- public static void slide1(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide1(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE);
box1.setText("POI-HSLF");
box1.setAnchor(new Rectangle(54, 78, 612, 115));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY);
box2.setText("Java API To Access Microsoft PowerPoint Format Files");
box2.setAnchor(new Rectangle(108, 204, 504, 138));
- slide.addShape(box2);
- HSLFTextBox box3 = new HSLFTextBox();
+ TextBox<?,?> box3 = slide.createTextBox();
box3.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32d);
box3.setText(
"Yegor Kozlov\r" +
"yegor - apache - org");
box3.setHorizontalCentered(true);
box3.setAnchor(new Rectangle(206, 348, 310, 84));
- slide.addShape(box3);
}
- public static void slide2(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide2(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("What is HSLF?");
box1.setAnchor(new Rectangle(36, 21, 648, 90));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.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");
+ "Started by Nick Burch, Yegor Kozlov joined soon after");
box2.setAnchor(new Rectangle(36, 126, 648, 356));
- slide.addShape(box2);
-
-
}
- public static void slide3(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide3(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in a Nutshell");
box1.setAnchor(new Rectangle(36, 15, 648, 65));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.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" +
@@ -140,7 +135,7 @@ public final class ApacheconEU08 {
"Access to low level data structures"
);
- List<HSLFTextParagraph> tp = box2.getTextParagraphs();
+ List<? extends TextParagraph<?,?,?>> tp = box2.getTextParagraphs();
for (int i : new byte[]{0,1,2,8}) {
tp.get(i).getTextRuns().get(0).setFontSize(28d);
}
@@ -149,102 +144,88 @@ public final class ApacheconEU08 {
tp.get(i).setIndentLevel(1);
}
box2.setAnchor(new Rectangle(36, 80, 648, 400));
- slide.addShape(box2);
}
- public static void slide4(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide4(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
String[][] txt1 = {
{"Note"},
{"This presentation was created programmatically using POI HSLF"}
};
- HSLFTable table1 = new HSLFTable(2, 1);
+ TableShape<?,?> table1 = slide.createTable(2, 1);
for (int i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) {
- HSLFTableCell cell = table1.getCell(i, j);
+ TableCell<?,?> cell = table1.getCell(i, j);
cell.setText(txt1[i][j]);
- HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
+ TextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
rt.setFontSize(10d);
rt.setFontFamily("Arial");
rt.setBold(true);
if(i == 0){
rt.setFontSize(32d);
rt.setFontColor(Color.white);
- cell.getFill().setForegroundColor(new Color(0, 153, 204));
+ cell.setFillColor(new Color(0, 153, 204));
} else {
rt.setFontSize(28d);
- cell.getFill().setForegroundColor(new Color(235, 239, 241));
+ cell.setFillColor(new Color(235, 239, 241));
}
cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
}
}
- HSLFLine border1 = table1.createBorder();
- border1.setLineColor(Color.black);
- border1.setLineWidth(1.0);
- table1.setAllBorders(border1);
-
- HSLFLine border2 = table1.createBorder();
- border2.setLineColor(Color.black);
- border2.setLineWidth(2.0);
- table1.setOutsideBorders(border2);
+ DrawTableShape dts = new DrawTableShape(table1);
+ dts.setAllBorders(1.0, Color.black);
+ dts.setOutsideBorders(4.0);
- table1.setColumnWidth(0, 510);
- table1.setRowHeight(0, 60);
- table1.setRowHeight(1, 100);
- slide.addShape(table1);
+ table1.setColumnWidth(0, 450);
+ table1.setRowHeight(0, 50);
+ table1.setRowHeight(1, 80);
- table1.moveTo(100, 100);
+ Dimension dim = ppt.getPageSize();
+ Rectangle oldAnchor = table1.getAnchor();
+ table1.setAnchor(new Rectangle((dim.width-450)/2, 100, oldAnchor.width, oldAnchor.height));
- HSLFTextBox box1 = new HSLFTextBox();
+ TextBox<?,?> box1 = slide.createTextBox();
box1.setHorizontalCentered(true);
box1.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(24d);
box1.setText("The source code is available at\r" +
"http://people.apache.org/~yegor/apachecon_eu08/");
box1.setAnchor(new Rectangle(80, 356, 553, 65));
- slide.addShape(box1);
-
}
- public static void slide5(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide5(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 1\rData Extraction");
box1.setAnchor(new Rectangle(36, 21, 648, 100));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.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(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide6(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 2");
box1.setAnchor(new Rectangle(36, 20, 648, 90));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
+ TextBox<?,?> box2 = slide.createTextBox();
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d);
box2.setText("Creating a simple presentation from scratch");
box2.setAnchor(new Rectangle(170, 100, 364, 30));
- slide.addShape(box2);
- HSLFTextBox box3 = new HSLFTextBox();
- HSLFTextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
+ TextBox<?,?> box3 = slide.createTextBox();
+ TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
rt3.setFontFamily("Courier New");
rt3.setFontSize(8d);
box3.setText(
@@ -283,77 +264,67 @@ public final class ApacheconEU08 {
"out.close();");
box3.setAnchor(new Rectangle(30, 150, 618, 411));
box3.setHorizontalCentered(true);
- slide.addShape(box3);
}
- public static void slide7(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide7(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box2 = new HSLFTextBox();
+ TextBox<?,?> box2 = slide.createTextBox();
box2.setHorizontalCentered(true);
box2.setVerticalAlignment(VerticalAlignment.MIDDLE);
box2.setText("Java Code");
- box2.getFill().setForegroundColor(new Color(187, 224, 227));
- box2.setLineColor(Color.black);
- box2.setLineWidth(0.75);
+ box2.setFillColor(new Color(187, 224, 227));
+ box2.setStrokeStyle(0.75, Color.black);
box2.setAnchor(new Rectangle(66, 243, 170, 170));
- slide.addShape(box2);
- HSLFTextBox box3 = new HSLFTextBox();
+ TextBox<?,?> box3 = slide.createTextBox();
box3.setHorizontalCentered(true);
box3.setVerticalAlignment(VerticalAlignment.MIDDLE);
box3.setText("*.ppt file");
- box3.setLineWidth(0.75);
- box3.setLineColor(Color.black);
- box3.getFill().setForegroundColor(new Color(187, 224, 227));
+ box3.setFillColor(new Color(187, 224, 227));
+ box3.setStrokeStyle(0.75, Color.black);
box3.setAnchor(new Rectangle(473, 243, 170, 170));
- slide.addShape(box3);
- HSLFAutoShape box4 = new HSLFAutoShape(ShapeType.RIGHT_ARROW);
- box4.getFill().setForegroundColor(new Color(187, 224, 227));
- box4.setLineWidth(0.75);
- box4.setLineColor(Color.black);
+ AutoShape<?,?> box4 = slide.createAutoShape();
+ box4.setShapeType(ShapeType.RIGHT_ARROW);
+ box4.setFillColor(new Color(187, 224, 227));
+ box4.setStrokeStyle(0.75, Color.black);
box4.setAnchor(new Rectangle(253, 288, 198, 85));
- slide.addShape(box4);
}
- public static void slide8(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide8(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("Wait, there is more!");
box1.setAnchor(new Rectangle(36, 21, 648, 90));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.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(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide9(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 3");
box1.setAnchor(new Rectangle(36, 20, 648, 50));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
+ TextBox<?,?> box2 = slide.createTextBox();
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d);
box2.setText("PPGraphics2D: PowerPoint Graphics2D driver");
box2.setAnchor(new Rectangle(178, 70, 387, 30));
- slide.addShape(box2);
- HSLFTextBox box3 = new HSLFTextBox();
- HSLFTextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
+ TextBox<?,?> box3 = slide.createTextBox();
+ TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
rt3.setFontFamily("Courier New");
rt3.setFontSize(8d);
box3.setText(
@@ -397,10 +368,9 @@ public final class ApacheconEU08 {
"out.close();");
box3.setAnchor(new Rectangle(96, 110, 499, 378));
box3.setHorizontalCentered(true);
- slide.addShape(box3);
}
- public static void slide10(HSLFSlideShow ppt) throws IOException {
+ 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),
@@ -409,14 +379,13 @@ public final class ApacheconEU08 {
Color.red, new Integer(200),
};
- HSLFSlide slide = ppt.createSlide();
+ Slide<?,?> slide = ppt.createSlide();
- HSLFGroupShape group = new HSLFGroupShape();
+ GroupShape<?,?> group = slide.createGroup();
//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);
+ Graphics2D graphics = new SLGraphics(group);
//draw a simple bar graph
int x = bounds.x + 50, y = bounds.y + 50;
@@ -437,17 +406,16 @@ public final class ApacheconEU08 {
}
- public static void slide11(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide11(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF Development Plans");
box1.setAnchor(new Rectangle(36, 21, 648, 90));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText(
"Support for more PowerPoint functionality\r" +
"Rendering slides into java.awt.Graphics2D\r" +
@@ -457,7 +425,7 @@ public final class ApacheconEU08 {
"PPT2PDF transcoder"
);
- List<HSLFTextParagraph> tp = box2.getTextParagraphs();
+ List<? extends TextParagraph<?,?,?>> tp = box2.getTextParagraphs();
for (int i : new byte[]{0,1,3}) {
tp.get(i).getTextRuns().get(0).setFontSize(28d);
}
@@ -467,24 +435,21 @@ public final class ApacheconEU08 {
}
box2.setAnchor(new Rectangle(36, 126, 648, 400));
- slide.addShape(box2);
}
- public static void slide12(HSLFSlideShow ppt) throws IOException {
- HSLFSlide slide = ppt.createSlide();
+ public static void slide12(SlideShow<?,?> ppt) throws IOException {
+ Slide<?,?> slide = ppt.createSlide();
- HSLFTextBox box1 = new HSLFTextBox();
- box1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
+ TextBox<?,?> box1 = slide.createTextBox();
+ box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE);
box1.setText("Questions?");
box1.setAnchor(new Rectangle(54, 167, 612, 115));
- slide.addShape(box1);
- HSLFTextBox box2 = new HSLFTextBox();
- box2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
+ TextBox<?,?> box2 = slide.createTextBox();
+ box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY);
box2.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/examples/src/org/apache/poi/hslf/examples/TableDemo.java b/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java
index d50855e619..c8a1395902 100644
--- a/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java
+++ b/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java
@@ -25,7 +25,7 @@ import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTable;
import org.apache.poi.hslf.usermodel.HSLFTableCell;
import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFLine;
+import org.apache.poi.sl.draw.DrawTableShape;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
@@ -53,7 +53,7 @@ public final class TableDemo {
HSLFSlide slide = ppt.createSlide();
//six rows, two columns
- HSLFTable table1 = new HSLFTable(6, 2);
+ HSLFTable table1 = slide.createTable(6, 2);
for (int i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) {
HSLFTableCell cell = table1.getCell(i, j);
@@ -71,15 +71,12 @@ public final class TableDemo {
}
}
- HSLFLine border1 = table1.createBorder();
- border1.setLineColor(Color.black);
- border1.setLineWidth(1.0);
- table1.setAllBorders(border1);
+ DrawTableShape dts1 = new DrawTableShape(table1);
+ dts1.setAllBorders(1.0, Color.black);
table1.setColumnWidth(0, 300);
table1.setColumnWidth(1, 150);
- slide.addShape(table1);
int pgWidth = ppt.getPageSize().width;
table1.moveTo((pgWidth - table1.getAnchor().width)/2, 100);
@@ -92,7 +89,7 @@ public final class TableDemo {
};
//two rows, one column
- HSLFTable table2 = new HSLFTable(2, 1);
+ HSLFTable table2 = slide.createTable(2, 1);
for (int i = 0; i < txt2.length; i++) {
for (int j = 0; j < txt2[i].length; j++) {
HSLFTableCell cell = table2.getCell(i, j);
@@ -119,10 +116,9 @@ public final class TableDemo {
table2.setRowHeight(0, 30);
table2.setRowHeight(1, 70);
- HSLFLine border2 = table2.createBorder();
- table2.setOutsideBorders(border2);
+ DrawTableShape dts2 = new DrawTableShape(table2);
+ dts2.setOutsideBorders(Color.black, 1.0);
- slide.addShape(table2);
table2.moveTo(200, 400);
FileOutputStream out = new FileOutputStream("hslf-table.ppt");
diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
index 54347b4c32..28c1fa3f12 100644
--- a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
+++ b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
@@ -23,6 +23,8 @@ import java.awt.Rectangle;
import java.io.FileOutputStream;
import java.io.IOException;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+
/**
* How to set slide title
*
diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java
index ecfc986670..94082a2ef9 100644
--- a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java
+++ b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java
@@ -24,6 +24,7 @@ import java.awt.Rectangle;
import java.io.FileOutputStream;
import java.io.IOException;
+import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
/**
@@ -56,8 +57,8 @@ public class Tutorial4 {
r.setBold(true);
r.setFontColor(Color.white);
th.setFillColor(new Color(79, 129, 189));
- th.setBorderBottom(2);
- th.setBorderBottomColor(Color.white);
+ th.setBorderWidth(BorderEdge.bottom, 2.0);
+ th.setBorderColor(BorderEdge.bottom, Color.white);
tbl.setColumnWidth(i, 150); // all columns are equally sized
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawTableShape.java b/src/java/org/apache/poi/sl/draw/DrawTableShape.java
index b252ddfda9..ec44d17d6b 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTableShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTableShape.java
@@ -17,9 +17,15 @@
package org.apache.poi.sl.draw;
+import java.awt.Color;
import java.awt.Graphics2D;
import org.apache.poi.sl.usermodel.GroupShape;
+import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
+import org.apache.poi.sl.usermodel.TableCell;
+import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.TableShape;
public class DrawTableShape extends DrawShape {
@@ -57,5 +63,111 @@ public class DrawTableShape extends DrawShape {
}
}
+ @Override
+ protected TableShape<?,?> getShape() {
+ return (TableShape<?,?>)shape;
+ }
+
+ /**
+ * Format the table and apply the specified Line to all cell boundaries,
+ * both outside and inside.
+ * An empty args parameter removes the affected border.
+ *
+ * @param args a varargs array possible containing {@link Double} (width),
+ * {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
+ */
+ public void setAllBorders(Object... args) {
+ TableShape<?,?> table = getShape();
+ final int rows = table.getNumberOfRows();
+ final int cols = table.getNumberOfColumns();
+
+ BorderEdge edges[] = { BorderEdge.top, BorderEdge.left, null, null };
+ for (int row = 0; row < rows; row++) {
+ for (int col = 0; col < cols; col++) {
+ edges[2] = (col == cols - 1) ? BorderEdge.right : null;
+ edges[3] = (row == rows - 1) ? BorderEdge.bottom : null;
+ setEdges(table.getCell(row, col), edges, args);
+ }
+ }
+ }
+
+ /**
+ * Format the outside border using the specified Line object
+ * An empty args parameter removes the affected border.
+ *
+ * @param args a varargs array possible containing {@link Double} (width),
+ * {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
+ */
+ public void setOutsideBorders(Object... args){
+ if (args.length == 0) return;
+
+ TableShape<?,?> table = getShape();
+ final int rows = table.getNumberOfRows();
+ final int cols = table.getNumberOfColumns();
+
+ BorderEdge edges[] = new BorderEdge[4];
+ for (int row = 0; row < rows; row++) {
+ for (int col = 0; col < cols; col++) {
+ edges[0] = (col == 0) ? BorderEdge.left : null;
+ edges[1] = (col == cols - 1) ? BorderEdge.right : null;
+ edges[2] = (row == 0) ? BorderEdge.top : null;
+ edges[3] = (row == rows - 1) ? BorderEdge.bottom : null;
+ setEdges(table.getCell(row, col), edges, args);
+ }
+ }
+ }
+
+ /**
+ * Format the inside border using the specified Line object
+ * An empty args parameter removes the affected border.
+ *
+ * @param args a varargs array possible containing {@link Double} (width),
+ * {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
+ */
+ public void setInsideBorders(Object... args) {
+ if (args.length == 0) return;
+
+ TableShape<?,?> table = getShape();
+ final int rows = table.getNumberOfRows();
+ final int cols = table.getNumberOfColumns();
+
+ BorderEdge edges[] = new BorderEdge[2];
+ for (int row = 0; row < rows; row++) {
+ for (int col = 0; col < cols; col++) {
+ edges[0] = (col > 0 && col < cols - 1) ? BorderEdge.right : null;
+ edges[1] = (row > 0 && row < rows - 1) ? BorderEdge.bottom : null;
+ setEdges(table.getCell(row, col), edges, args);
+ }
+ }
+ }
+
+ /**
+ * Apply the border attributes (args) to the given cell and edges
+ *
+ * @param cell the cell
+ * @param edges the border edges
+ * @param args the border attributes
+ */
+ private static void setEdges(TableCell<?,?> cell, BorderEdge edges[], Object... args) {
+ for (BorderEdge be : edges) {
+ if (be != null) {
+ if (args.length == 0) {
+ cell.removeBorder(be);
+ } else {
+ for (Object o : args) {
+ if (o instanceof Double) {
+ cell.setBorderWidth(be, (Double)o);
+ } else if (o instanceof Color) {
+ cell.setBorderColor(be, (Color)o);
+ } else if (o instanceof LineDash) {
+ cell.setBorderDash(be, (LineDash)o);
+ } else if (o instanceof LineCompound) {
+ cell.setBorderCompound(be, (LineCompound)o);
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/java/org/apache/poi/sl/draw/SLGraphics.java b/src/java/org/apache/poi/sl/draw/SLGraphics.java
new file mode 100644
index 0000000000..2a6d884ca1
--- /dev/null
+++ b/src/java/org/apache/poi/sl/draw/SLGraphics.java
@@ -0,0 +1,1831 @@
+/* ====================================================================
+ 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.sl.draw;
+
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.poi.sl.usermodel.FreeformShape;
+import org.apache.poi.sl.usermodel.GroupShape;
+import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.SimpleShape;
+import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.TextBox;
+import org.apache.poi.sl.usermodel.TextRun;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.SuppressForbidden;
+
+/**
+ * Translates Graphics2D calls into PowerPoint.
+ *
+ * @author Yegor Kozlov
+ */
+public final class SLGraphics extends Graphics2D implements Cloneable {
+
+ protected POILogger log = POILogFactory.getLogger(this.getClass());
+
+ //The ppt object to write into.
+ private GroupShape<?,?> _group;
+
+ private AffineTransform _transform;
+ private Stroke _stroke;
+ private Paint _paint;
+ private Font _font;
+ private Color _foreground;
+ private Color _background;
+ private RenderingHints _hints;
+
+ /**
+ * Construct Java Graphics object which translates graphic calls in ppt drawing layer.
+ *
+ * @param group The shape group to write the graphics calls into.
+ */
+ public SLGraphics(GroupShape<?,?> group){
+ this._group = group;
+
+ _transform = new AffineTransform();
+ _stroke = new BasicStroke();
+ _paint = Color.black;
+ _font = new Font("Arial", Font.PLAIN, 12);
+ _background = Color.black;
+ _foreground = Color.white;
+ _hints = new RenderingHints(null);
+ }
+
+ /**
+ * @return the shape group being used for drawing
+ */
+ public GroupShape<?,?> getShapeGroup(){
+ return _group;
+ }
+
+ /**
+ * Gets the current font.
+ * @return this graphics context's current font.
+ * @see java.awt.Font
+ * @see java.awt.Graphics#setFont(Font)
+ */
+ public Font getFont(){
+ return _font;
+ }
+
+ /**
+ * Sets this graphics context's font to the specified font.
+ * All subsequent text operations using this graphics context
+ * use this font.
+ * @param font the font.
+ * @see java.awt.Graphics#getFont
+ * @see java.awt.Graphics#drawString(java.lang.String, int, int)
+ * @see java.awt.Graphics#drawBytes(byte[], int, int, int, int)
+ * @see java.awt.Graphics#drawChars(char[], int, int, int, int)
+ */
+ public void setFont(Font font){
+ this._font = font;
+ }
+
+ /**
+ * Gets this graphics context's current color.
+ * @return this graphics context's current color.
+ * @see java.awt.Color
+ * @see java.awt.Graphics#setColor
+ */
+ public Color getColor(){
+ return _foreground;
+ }
+
+ /**
+ * Sets this graphics context's current color to the specified
+ * color. All subsequent graphics operations using this graphics
+ * context use this specified color.
+ * @param c the new rendering color.
+ * @see java.awt.Color
+ * @see java.awt.Graphics#getColor
+ */
+ public void setColor(Color c) {
+ setPaint(c);
+ }
+
+ /**
+ * Returns the current <code>Stroke</code> in the
+ * <code>Graphics2D</code> context.
+ * @return the current <code>Graphics2D</code> <code>Stroke</code>,
+ * which defines the line style.
+ * @see #setStroke
+ */
+ public Stroke getStroke(){
+ return _stroke;
+ }
+
+ /**
+ * Sets the <code>Stroke</code> for the <code>Graphics2D</code> context.
+ * @param s the <code>Stroke</code> object to be used to stroke a
+ * <code>Shape</code> during the rendering process
+ */
+ public void setStroke(Stroke s){
+ this._stroke = s;
+ }
+
+ /**
+ * Returns the current <code>Paint</code> of the
+ * <code>Graphics2D</code> context.
+ * @return the current <code>Graphics2D</code> <code>Paint</code>,
+ * which defines a color or pattern.
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ */
+ public Paint getPaint(){
+ return _paint;
+ }
+
+ /**
+ * Sets the <code>Paint</code> attribute for the
+ * <code>Graphics2D</code> context. Calling this method
+ * with a <code>null</code> <code>Paint</code> object does
+ * not have any effect on the current <code>Paint</code> attribute
+ * of this <code>Graphics2D</code>.
+ * @param paint the <code>Paint</code> object to be used to generate
+ * color during the rendering process, or <code>null</code>
+ * @see java.awt.Graphics#setColor
+ */
+ public void setPaint(Paint paint){
+ if(paint == null) return;
+
+ this._paint = paint;
+ if (paint instanceof Color) _foreground = (Color)paint;
+ }
+
+ /**
+ * Returns a copy of the current <code>Transform</code> in the
+ * <code>Graphics2D</code> context.
+ * @return the current <code>AffineTransform</code> in the
+ * <code>Graphics2D</code> context.
+ * @see #_transform
+ * @see #setTransform
+ */
+ public AffineTransform getTransform(){
+ return new AffineTransform(_transform);
+ }
+
+ /**
+ * Sets the <code>Transform</code> in the <code>Graphics2D</code>
+ * context.
+ * @param Tx the <code>AffineTransform</code> object to be used in the
+ * rendering process
+ * @see #_transform
+ * @see AffineTransform
+ */
+ public void setTransform(AffineTransform Tx) {
+ _transform = new AffineTransform(Tx);
+ }
+
+ /**
+ * Strokes the outline of a <code>Shape</code> using the settings of the
+ * current <code>Graphics2D</code> context. The rendering attributes
+ * applied include the <code>Clip</code>, <code>Transform</code>,
+ * <code>Paint</code>, <code>Composite</code> and
+ * <code>Stroke</code> attributes.
+ * @param shape the <code>Shape</code> to be rendered
+ * @see #setStroke
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ * @see #_transform
+ * @see #setTransform
+ * @see #clip
+ * @see #setClip
+ * @see #setComposite
+ */
+ public void draw(Shape shape){
+ GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ FreeformShape<?,?> p = _group.createFreeform();
+ p.setPath(path);
+ p.setFillColor(null);
+ applyStroke(p);
+ if (_paint instanceof Color) {
+ p.setStrokeStyle((Color)_paint);
+ }
+ }
+
+ /**
+ * Renders the text specified by the specified <code>String</code>,
+ * using the current text attribute state in the <code>Graphics2D</code> context.
+ * The baseline of the first character is at position
+ * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
+ * <code>Composite</code> attributes. For characters in script systems
+ * such as Hebrew and Arabic, the glyphs can be rendered from right to
+ * left, in which case the coordinate supplied is the location of the
+ * leftmost character on the baseline.
+ * @param s the <code>String</code> to be rendered
+ * @param x the x coordinate of the location where the
+ * <code>String</code> should be rendered
+ * @param y the y coordinate of the location where the
+ * <code>String</code> should be rendered
+ * @throws NullPointerException if <code>str</code> is
+ * <code>null</code>
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ * @see java.awt.Graphics#setFont
+ * @see #setTransform
+ * @see #setComposite
+ * @see #setClip
+ */
+ public void drawString(String s, float x, float y) {
+ TextBox<?,?> txt = _group.createTextBox();
+
+ TextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0);
+ rt.setFontSize((double)_font.getSize());
+ rt.setFontFamily(_font.getFamily());
+
+ if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor()));
+ if (_font.isBold()) rt.setBold(true);
+ if (_font.isItalic()) rt.setItalic(true);
+
+ txt.setText(s);
+
+ txt.setInsets(new Insets2D(0,0,0,0));
+ txt.setWordWrap(false);
+ txt.setHorizontalCentered(false);
+ txt.setVerticalAlignment(VerticalAlignment.MIDDLE);
+
+
+ TextLayout layout = new TextLayout(s, _font, getFontRenderContext());
+ float ascent = layout.getAscent();
+
+ float width = (float) Math.floor(layout.getAdvance());
+ /**
+ * Even if top and bottom margins are set to 0 PowerPoint
+ * always sets extra space between the text and its bounding box.
+ *
+ * The approximation height = ascent*2 works good enough in most cases
+ */
+ float height = ascent * 2;
+
+ /*
+ In powerpoint anchor of a shape is its top left corner.
+ Java graphics sets string coordinates by the baseline of the first character
+ so we need to shift up by the height of the textbox
+ */
+ y -= height / 2 + ascent / 2;
+
+ /*
+ In powerpoint anchor of a shape is its top left corner.
+ Java graphics sets string coordinates by the baseline of the first character
+ so we need to shift down by the height of the textbox
+ */
+ txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height));
+ }
+
+ /**
+ * Fills the interior of a <code>Shape</code> using the settings of the
+ * <code>Graphics2D</code> context. The rendering attributes applied
+ * include the <code>Clip</code>, <code>Transform</code>,
+ * <code>Paint</code>, and <code>Composite</code>.
+ * @param shape the <code>Shape</code> to be filled
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ * @see #_transform
+ * @see #setTransform
+ * @see #setComposite
+ * @see #clip
+ * @see #setClip
+ */
+ public void fill(Shape shape){
+ GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ FreeformShape<?,?> p = _group.createFreeform();
+ p.setPath(path);
+ applyPaint(p);
+ p.setStrokeStyle(); //Fills must be "No Line"
+ }
+
+ /**
+ * Translates the origin of the graphics context to the point
+ * (<i>x</i>,&nbsp;<i>y</i>) in the current coordinate system.
+ * Modifies this graphics context so that its new origin corresponds
+ * to the point (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's
+ * original coordinate system. All coordinates used in subsequent
+ * rendering operations on this graphics context will be relative
+ * to this new origin.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ */
+ public void translate(int x, int y){
+ _transform.translate(x, y);
+ }
+
+ /**
+ * Intersects the current <code>Clip</code> with the interior of the
+ * specified <code>Shape</code> and sets the <code>Clip</code> to the
+ * resulting intersection. The specified <code>Shape</code> is
+ * transformed with the current <code>Graphics2D</code>
+ * <code>Transform</code> before being intersected with the current
+ * <code>Clip</code>. This method is used to make the current
+ * <code>Clip</code> smaller.
+ * To make the <code>Clip</code> larger, use <code>setClip</code>.
+ * The <i>user clip</i> modified by this method is independent of the
+ * clipping associated with device bounds and visibility. If no clip has
+ * previously been set, or if the clip has been cleared using
+ * {@link java.awt.Graphics#setClip(Shape) setClip} with a
+ * <code>null</code> argument, the specified <code>Shape</code> becomes
+ * the new user clip.
+ * @param s the <code>Shape</code> to be intersected with the current
+ * <code>Clip</code>. If <code>s</code> is <code>null</code>,
+ * this method clears the current <code>Clip</code>.
+ */
+ public void clip(Shape s){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Gets the current clipping area.
+ * This method returns the user clip, which is independent of the
+ * clipping associated with device bounds and window visibility.
+ * If no clip has previously been set, or if the clip has been
+ * cleared using <code>setClip(null)</code>, this method returns
+ * <code>null</code>.
+ * @return a <code>Shape</code> object representing the
+ * current clipping area, or <code>null</code> if
+ * no clip is set.
+ * @see java.awt.Graphics#getClipBounds()
+ * @see java.awt.Graphics#clipRect
+ * @see java.awt.Graphics#setClip(int, int, int, int)
+ * @see java.awt.Graphics#setClip(Shape)
+ * @since JDK1.1
+ */
+ public Shape getClip(){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return null;
+ }
+
+ /**
+ * Concatenates the current <code>Graphics2D</code>
+ * <code>Transform</code> with a scaling transformation
+ * Subsequent rendering is resized according to the specified scaling
+ * factors relative to the previous scaling.
+ * This is equivalent to calling <code>transform(S)</code>, where S is an
+ * <code>AffineTransform</code> represented by the following matrix:
+ * <pre>
+ * [ sx 0 0 ]
+ * [ 0 sy 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ * @param sx the amount by which X coordinates in subsequent
+ * rendering operations are multiplied relative to previous
+ * rendering operations.
+ * @param sy the amount by which Y coordinates in subsequent
+ * rendering operations are multiplied relative to previous
+ * rendering operations.
+ */
+ public void scale(double sx, double sy){
+ _transform.scale(sx, sy);
+ }
+
+ /**
+ * Draws an outlined round-cornered rectangle using this graphics
+ * context's current color. The left and right edges of the rectangle
+ * are at <code>x</code> and <code>x&nbsp;+&nbsp;width</code>,
+ * respectively. The top and bottom edges of the rectangle are at
+ * <code>y</code> and <code>y&nbsp;+&nbsp;height</code>.
+ * @param x the <i>x</i> coordinate of the rectangle to be drawn.
+ * @param y the <i>y</i> coordinate of the rectangle to be drawn.
+ * @param width the width of the rectangle to be drawn.
+ * @param height the height of the rectangle to be drawn.
+ * @param arcWidth the horizontal diameter of the arc
+ * at the four corners.
+ * @param arcHeight the vertical diameter of the arc
+ * at the four corners.
+ * @see java.awt.Graphics#fillRoundRect
+ */
+ public void drawRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight){
+ RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ draw(rect);
+ }
+
+ /**
+ * Draws the text given by the specified string, using this
+ * graphics context's current font and color. The baseline of the
+ * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
+ * graphics context's coordinate system.
+ * @param str the string to be drawn.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @see java.awt.Graphics#drawBytes
+ * @see java.awt.Graphics#drawChars
+ */
+ public void drawString(String str, int x, int y){
+ drawString(str, (float)x, (float)y);
+ }
+
+ /**
+ * Fills an oval bounded by the specified rectangle with the
+ * current color.
+ * @param x the <i>x</i> coordinate of the upper left corner
+ * of the oval to be filled.
+ * @param y the <i>y</i> coordinate of the upper left corner
+ * of the oval to be filled.
+ * @param width the width of the oval to be filled.
+ * @param height the height of the oval to be filled.
+ * @see java.awt.Graphics#drawOval
+ */
+ public void fillOval(int x, int y, int width, int height){
+ Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ fill(oval);
+ }
+
+ /**
+ * Fills the specified rounded corner rectangle with the current color.
+ * The left and right edges of the rectangle
+ * are at <code>x</code> and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>,
+ * respectively. The top and bottom edges of the rectangle are at
+ * <code>y</code> and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
+ * @param x the <i>x</i> coordinate of the rectangle to be filled.
+ * @param y the <i>y</i> coordinate of the rectangle to be filled.
+ * @param width the width of the rectangle to be filled.
+ * @param height the height of the rectangle to be filled.
+ * @param arcWidth the horizontal diameter
+ * of the arc at the four corners.
+ * @param arcHeight the vertical diameter
+ * of the arc at the four corners.
+ * @see java.awt.Graphics#drawRoundRect
+ */
+ public void fillRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight){
+
+ RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ fill(rect);
+ }
+
+ /**
+ * Fills a circular or elliptical arc covering the specified rectangle.
+ * <p>
+ * The resulting arc begins at <code>startAngle</code> and extends
+ * for <code>arcAngle</code> degrees.
+ * Angles are interpreted such that 0&nbsp;degrees
+ * is at the 3&nbsp;o'clock position.
+ * A positive value indicates a counter-clockwise rotation
+ * while a negative value indicates a clockwise rotation.
+ * <p>
+ * The center of the arc is the center of the rectangle whose origin
+ * is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
+ * <code>width</code> and <code>height</code> arguments.
+ * <p>
+ * The resulting arc covers an area
+ * <code>width&nbsp;+&nbsp;1</code> pixels wide
+ * by <code>height&nbsp;+&nbsp;1</code> pixels tall.
+ * <p>
+ * The angles are specified relative to the non-square extents of
+ * the bounding rectangle such that 45 degrees always falls on the
+ * line from the center of the ellipse to the upper right corner of
+ * the bounding rectangle. As a result, if the bounding rectangle is
+ * noticeably longer in one axis than the other, the angles to the
+ * start and end of the arc segment will be skewed farther along the
+ * longer axis of the bounds.
+ * @param x the <i>x</i> coordinate of the
+ * upper-left corner of the arc to be filled.
+ * @param y the <i>y</i> coordinate of the
+ * upper-left corner of the arc to be filled.
+ * @param width the width of the arc to be filled.
+ * @param height the height of the arc to be filled.
+ * @param startAngle the beginning angle.
+ * @param arcAngle the angular extent of the arc,
+ * relative to the start angle.
+ * @see java.awt.Graphics#drawArc
+ */
+ public void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle){
+ Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
+ fill(arc);
+ }
+
+ /**
+ * Draws the outline of a circular or elliptical arc
+ * covering the specified rectangle.
+ * <p>
+ * The resulting arc begins at <code>startAngle</code> and extends
+ * for <code>arcAngle</code> degrees, using the current color.
+ * Angles are interpreted such that 0&nbsp;degrees
+ * is at the 3&nbsp;o'clock position.
+ * A positive value indicates a counter-clockwise rotation
+ * while a negative value indicates a clockwise rotation.
+ * <p>
+ * The center of the arc is the center of the rectangle whose origin
+ * is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
+ * <code>width</code> and <code>height</code> arguments.
+ * <p>
+ * The resulting arc covers an area
+ * <code>width&nbsp;+&nbsp;1</code> pixels wide
+ * by <code>height&nbsp;+&nbsp;1</code> pixels tall.
+ * <p>
+ * The angles are specified relative to the non-square extents of
+ * the bounding rectangle such that 45 degrees always falls on the
+ * line from the center of the ellipse to the upper right corner of
+ * the bounding rectangle. As a result, if the bounding rectangle is
+ * noticeably longer in one axis than the other, the angles to the
+ * start and end of the arc segment will be skewed farther along the
+ * longer axis of the bounds.
+ * @param x the <i>x</i> coordinate of the
+ * upper-left corner of the arc to be drawn.
+ * @param y the <i>y</i> coordinate of the
+ * upper-left corner of the arc to be drawn.
+ * @param width the width of the arc to be drawn.
+ * @param height the height of the arc to be drawn.
+ * @param startAngle the beginning angle.
+ * @param arcAngle the angular extent of the arc,
+ * relative to the start angle.
+ * @see java.awt.Graphics#fillArc
+ */
+ public void drawArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle) {
+ Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
+ draw(arc);
+ }
+
+
+ /**
+ * Draws a sequence of connected lines defined by
+ * arrays of <i>x</i> and <i>y</i> coordinates.
+ * Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
+ * The figure is not closed if the first point
+ * differs from the last point.
+ * @param xPoints an array of <i>x</i> points
+ * @param yPoints an array of <i>y</i> points
+ * @param nPoints the total number of points
+ * @see java.awt.Graphics#drawPolygon(int[], int[], int)
+ * @since JDK1.1
+ */
+ public void drawPolyline(int[] xPoints, int[] yPoints,
+ int nPoints){
+ if(nPoints > 0){
+ GeneralPath path = new GeneralPath();
+ path.moveTo(xPoints[0], yPoints[0]);
+ for(int i=1; i<nPoints; i++)
+ path.lineTo(xPoints[i], yPoints[i]);
+
+ draw(path);
+ }
+ }
+
+ /**
+ * Draws the outline of an oval.
+ * The result is a circle or ellipse that fits within the
+ * rectangle specified by the <code>x</code>, <code>y</code>,
+ * <code>width</code>, and <code>height</code> arguments.
+ * <p>
+ * The oval covers an area that is
+ * <code>width&nbsp;+&nbsp;1</code> pixels wide
+ * and <code>height&nbsp;+&nbsp;1</code> pixels tall.
+ * @param x the <i>x</i> coordinate of the upper left
+ * corner of the oval to be drawn.
+ * @param y the <i>y</i> coordinate of the upper left
+ * corner of the oval to be drawn.
+ * @param width the width of the oval to be drawn.
+ * @param height the height of the oval to be drawn.
+ * @see java.awt.Graphics#fillOval
+ */
+ public void drawOval(int x, int y, int width, int height){
+ Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ draw(oval);
+ }
+
+ /**
+ * Draws as much of the specified image as is currently available.
+ * The image is drawn with its top-left corner at
+ * (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
+ * space. Transparent pixels are drawn in the specified
+ * background color.
+ * <p>
+ * This operation is equivalent to filling a rectangle of the
+ * width and height of the specified image with the given color and then
+ * drawing the image on top of it, but possibly more efficient.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * complete image has not yet been loaded, and it has not been dithered
+ * and converted for the current output device.
+ * <p>
+ * If the image has not yet been completely loaded, then
+ * <code>drawImage</code> returns <code>false</code>. As more of
+ * the image becomes available, the process that draws the image notifies
+ * the specified image observer.
+ * @param img the specified image to be drawn.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @param bgcolor the background color to paint under the
+ * non-opaque portions of the image.
+ * @param observer object to be notified as more of
+ * the image is converted.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ */
+ public boolean drawImage(Image img, int x, int y,
+ Color bgcolor,
+ ImageObserver observer){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+
+ return false;
+ }
+
+ /**
+ * Draws as much of the specified image as has already been scaled
+ * to fit inside the specified rectangle.
+ * <p>
+ * The image is drawn inside the specified rectangle of this
+ * graphics context's coordinate space, and is scaled if
+ * necessary. Transparent pixels are drawn in the specified
+ * background color.
+ * This operation is equivalent to filling a rectangle of the
+ * width and height of the specified image with the given color and then
+ * drawing the image on top of it, but possibly more efficient.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * entire image has not yet been scaled, dithered, and converted
+ * for the current output device.
+ * If the current output representation is not yet complete then
+ * <code>drawImage</code> returns <code>false</code>. As more of
+ * the image becomes available, the process that draws the image notifies
+ * the specified image observer.
+ * <p>
+ * A scaled version of an image will not necessarily be
+ * available immediately just because an unscaled version of the
+ * image has been constructed for this output device. Each size of
+ * the image may be cached separately and generated from the original
+ * data in a separate image production sequence.
+ * @param img the specified image to be drawn.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @param width the width of the rectangle.
+ * @param height the height of the rectangle.
+ * @param bgcolor the background color to paint under the
+ * non-opaque portions of the image.
+ * @param observer object to be notified as more of
+ * the image is converted.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ */
+ public boolean drawImage(Image img, int x, int y,
+ int width, int height,
+ Color bgcolor,
+ ImageObserver observer){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Draws as much of the specified area of the specified image as is
+ * currently available, scaling it on the fly to fit inside the
+ * specified area of the destination drawable surface. Transparent pixels
+ * do not affect whatever pixels are already there.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * image area to be drawn has not yet been scaled, dithered, and converted
+ * for the current output device.
+ * If the current output representation is not yet complete then
+ * <code>drawImage</code> returns <code>false</code>. As more of
+ * the image becomes available, the process that draws the image notifies
+ * the specified image observer.
+ * <p>
+ * This method always uses the unscaled version of the image
+ * to render the scaled rectangle and performs the required
+ * scaling on the fly. It does not use a cached, scaled version
+ * of the image for this operation. Scaling of the image from source
+ * to destination is performed such that the first coordinate
+ * of the source rectangle is mapped to the first coordinate of
+ * the destination rectangle, and the second source coordinate is
+ * mapped to the second destination coordinate. The subimage is
+ * scaled and flipped as needed to preserve those mappings.
+ * @param img the specified image to be drawn
+ * @param dx1 the <i>x</i> coordinate of the first corner of the
+ * destination rectangle.
+ * @param dy1 the <i>y</i> coordinate of the first corner of the
+ * destination rectangle.
+ * @param dx2 the <i>x</i> coordinate of the second corner of the
+ * destination rectangle.
+ * @param dy2 the <i>y</i> coordinate of the second corner of the
+ * destination rectangle.
+ * @param sx1 the <i>x</i> coordinate of the first corner of the
+ * source rectangle.
+ * @param sy1 the <i>y</i> coordinate of the first corner of the
+ * source rectangle.
+ * @param sx2 the <i>x</i> coordinate of the second corner of the
+ * source rectangle.
+ * @param sy2 the <i>y</i> coordinate of the second corner of the
+ * source rectangle.
+ * @param observer object to be notified as more of the image is
+ * scaled and converted.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ * @since JDK1.1
+ */
+ public boolean drawImage(Image img,
+ int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return false;
+ }
+
+ /**
+ * Draws as much of the specified area of the specified image as is
+ * currently available, scaling it on the fly to fit inside the
+ * specified area of the destination drawable surface.
+ * <p>
+ * Transparent pixels are drawn in the specified background color.
+ * This operation is equivalent to filling a rectangle of the
+ * width and height of the specified image with the given color and then
+ * drawing the image on top of it, but possibly more efficient.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * image area to be drawn has not yet been scaled, dithered, and converted
+ * for the current output device.
+ * If the current output representation is not yet complete then
+ * <code>drawImage</code> returns <code>false</code>. As more of
+ * the image becomes available, the process that draws the image notifies
+ * the specified image observer.
+ * <p>
+ * This method always uses the unscaled version of the image
+ * to render the scaled rectangle and performs the required
+ * scaling on the fly. It does not use a cached, scaled version
+ * of the image for this operation. Scaling of the image from source
+ * to destination is performed such that the first coordinate
+ * of the source rectangle is mapped to the first coordinate of
+ * the destination rectangle, and the second source coordinate is
+ * mapped to the second destination coordinate. The subimage is
+ * scaled and flipped as needed to preserve those mappings.
+ * @param img the specified image to be drawn
+ * @param dx1 the <i>x</i> coordinate of the first corner of the
+ * destination rectangle.
+ * @param dy1 the <i>y</i> coordinate of the first corner of the
+ * destination rectangle.
+ * @param dx2 the <i>x</i> coordinate of the second corner of the
+ * destination rectangle.
+ * @param dy2 the <i>y</i> coordinate of the second corner of the
+ * destination rectangle.
+ * @param sx1 the <i>x</i> coordinate of the first corner of the
+ * source rectangle.
+ * @param sy1 the <i>y</i> coordinate of the first corner of the
+ * source rectangle.
+ * @param sx2 the <i>x</i> coordinate of the second corner of the
+ * source rectangle.
+ * @param sy2 the <i>y</i> coordinate of the second corner of the
+ * source rectangle.
+ * @param bgcolor the background color to paint under the
+ * non-opaque portions of the image.
+ * @param observer object to be notified as more of the image is
+ * scaled and converted.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ * @since JDK1.1
+ */
+ public boolean drawImage(Image img,
+ int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgcolor,
+ ImageObserver observer){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return false;
+ }
+
+ /**
+ * Draws as much of the specified image as is currently available.
+ * The image is drawn with its top-left corner at
+ * (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
+ * space. Transparent pixels in the image do not affect whatever
+ * pixels are already there.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * complete image has not yet been loaded, and it has not been dithered
+ * and converted for the current output device.
+ * <p>
+ * If the image has completely loaded and its pixels are
+ * no longer being changed, then
+ * <code>drawImage</code> returns <code>true</code>.
+ * Otherwise, <code>drawImage</code> returns <code>false</code>
+ * and as more of
+ * the image becomes available
+ * or it is time to draw another frame of animation,
+ * the process that loads the image notifies
+ * the specified image observer.
+ * @param img the specified image to be drawn. This method does
+ * nothing if <code>img</code> is null.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @param observer object to be notified as more of
+ * the image is converted.
+ * @return <code>false</code> if the image pixels are still changing;
+ * <code>true</code> otherwise.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ */
+ public boolean drawImage(Image img, int x, int y,
+ ImageObserver observer) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return false;
+ }
+
+ /**
+ * Disposes of this graphics context and releases
+ * any system resources that it is using.
+ * A <code>Graphics</code> object cannot be used after
+ * <code>dispose</code>has been called.
+ * <p>
+ * When a Java program runs, a large number of <code>Graphics</code>
+ * objects can be created within a short time frame.
+ * Although the finalization process of the garbage collector
+ * also disposes of the same system resources, it is preferable
+ * to manually free the associated resources by calling this
+ * method rather than to rely on a finalization process which
+ * may not run to completion for a long period of time.
+ * <p>
+ * Graphics objects which are provided as arguments to the
+ * <code>paint</code> and <code>update</code> methods
+ * of components are automatically released by the system when
+ * those methods return. For efficiency, programmers should
+ * call <code>dispose</code> when finished using
+ * a <code>Graphics</code> object only if it was created
+ * directly from a component or another <code>Graphics</code> object.
+ * @see java.awt.Graphics#finalize
+ * @see java.awt.Component#paint
+ * @see java.awt.Component#update
+ * @see java.awt.Component#getGraphics
+ * @see java.awt.Graphics#create
+ */
+ public void dispose() {
+ ;
+ }
+
+ /**
+ * Draws a line, using the current color, between the points
+ * <code>(x1,&nbsp;y1)</code> and <code>(x2,&nbsp;y2)</code>
+ * in this graphics context's coordinate system.
+ * @param x1 the first point's <i>x</i> coordinate.
+ * @param y1 the first point's <i>y</i> coordinate.
+ * @param x2 the second point's <i>x</i> coordinate.
+ * @param y2 the second point's <i>y</i> coordinate.
+ */
+ public void drawLine(int x1, int y1, int x2, int y2){
+ Line2D line = new Line2D.Float(x1, y1, x2, y2);
+ draw(line);
+ }
+
+ /**
+ * Fills a closed polygon defined by
+ * arrays of <i>x</i> and <i>y</i> coordinates.
+ * <p>
+ * This method draws the polygon defined by <code>nPoint</code> line
+ * segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
+ * line segments are line segments from
+ * <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
+ * to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
+ * 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;<code>nPoints</code>.
+ * The figure is automatically closed by drawing a line connecting
+ * the final point to the first point, if those points are different.
+ * <p>
+ * The area inside the polygon is defined using an
+ * even-odd fill rule, also known as the alternating rule.
+ * @param xPoints a an array of <code>x</code> coordinates.
+ * @param yPoints a an array of <code>y</code> coordinates.
+ * @param nPoints a the total number of points.
+ * @see java.awt.Graphics#drawPolygon(int[], int[], int)
+ */
+ public void fillPolygon(int[] xPoints, int[] yPoints,
+ int nPoints){
+ java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints);
+ fill(polygon);
+ }
+
+ /**
+ * Fills the specified rectangle.
+ * The left and right edges of the rectangle are at
+ * <code>x</code> and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>.
+ * The top and bottom edges are at
+ * <code>y</code> and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
+ * The resulting rectangle covers an area
+ * <code>width</code> pixels wide by
+ * <code>height</code> pixels tall.
+ * The rectangle is filled using the graphics context's current color.
+ * @param x the <i>x</i> coordinate
+ * of the rectangle to be filled.
+ * @param y the <i>y</i> coordinate
+ * of the rectangle to be filled.
+ * @param width the width of the rectangle to be filled.
+ * @param height the height of the rectangle to be filled.
+ * @see java.awt.Graphics#clearRect
+ * @see java.awt.Graphics#drawRect
+ */
+ public void fillRect(int x, int y, int width, int height){
+ Rectangle rect = new Rectangle(x, y, width, height);
+ fill(rect);
+ }
+
+ /**
+ * Draws the outline of the specified rectangle.
+ * The left and right edges of the rectangle are at
+ * <code>x</code> and <code>x&nbsp;+&nbsp;width</code>.
+ * The top and bottom edges are at
+ * <code>y</code> and <code>y&nbsp;+&nbsp;height</code>.
+ * The rectangle is drawn using the graphics context's current color.
+ * @param x the <i>x</i> coordinate
+ * of the rectangle to be drawn.
+ * @param y the <i>y</i> coordinate
+ * of the rectangle to be drawn.
+ * @param width the width of the rectangle to be drawn.
+ * @param height the height of the rectangle to be drawn.
+ * @see java.awt.Graphics#fillRect
+ * @see java.awt.Graphics#clearRect
+ */
+ public void drawRect(int x, int y, int width, int height) {
+ Rectangle rect = new Rectangle(x, y, width, height);
+ draw(rect);
+ }
+
+ /**
+ * Draws a closed polygon defined by
+ * arrays of <i>x</i> and <i>y</i> coordinates.
+ * Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
+ * <p>
+ * This method draws the polygon defined by <code>nPoint</code> line
+ * segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
+ * line segments are line segments from
+ * <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
+ * to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
+ * 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;<code>nPoints</code>.
+ * The figure is automatically closed by drawing a line connecting
+ * the final point to the first point, if those points are different.
+ * @param xPoints a an array of <code>x</code> coordinates.
+ * @param yPoints a an array of <code>y</code> coordinates.
+ * @param nPoints a the total number of points.
+ * @see java.awt.Graphics#fillPolygon(int[],int[],int)
+ * @see java.awt.Graphics#drawPolyline
+ */
+ public void drawPolygon(int[] xPoints, int[] yPoints,
+ int nPoints){
+ java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints);
+ draw(polygon);
+ }
+
+ /**
+ * Intersects the current clip with the specified rectangle.
+ * The resulting clipping area is the intersection of the current
+ * clipping area and the specified rectangle. If there is no
+ * current clipping area, either because the clip has never been
+ * set, or the clip has been cleared using <code>setClip(null)</code>,
+ * the specified rectangle becomes the new clip.
+ * This method sets the user clip, which is independent of the
+ * clipping associated with device bounds and window visibility.
+ * This method can only be used to make the current clip smaller.
+ * To set the current clip larger, use any of the setClip methods.
+ * Rendering operations have no effect outside of the clipping area.
+ * @param x the x coordinate of the rectangle to intersect the clip with
+ * @param y the y coordinate of the rectangle to intersect the clip with
+ * @param width the width of the rectangle to intersect the clip with
+ * @param height the height of the rectangle to intersect the clip with
+ * @see #setClip(int, int, int, int)
+ * @see #setClip(Shape)
+ */
+ public void clipRect(int x, int y, int width, int height){
+ clip(new Rectangle(x, y, width, height));
+ }
+
+ /**
+ * Sets the current clipping area to an arbitrary clip shape.
+ * Not all objects that implement the <code>Shape</code>
+ * interface can be used to set the clip. The only
+ * <code>Shape</code> objects that are guaranteed to be
+ * supported are <code>Shape</code> objects that are
+ * obtained via the <code>getClip</code> method and via
+ * <code>Rectangle</code> objects. This method sets the
+ * user clip, which is independent of the clipping associated
+ * with device bounds and window visibility.
+ * @param clip the <code>Shape</code> to use to set the clip
+ * @see java.awt.Graphics#getClip()
+ * @see java.awt.Graphics#clipRect
+ * @see java.awt.Graphics#setClip(int, int, int, int)
+ * @since JDK1.1
+ */
+ public void setClip(Shape clip) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Returns the bounding rectangle of the current clipping area.
+ * This method refers to the user clip, which is independent of the
+ * clipping associated with device bounds and window visibility.
+ * If no clip has previously been set, or if the clip has been
+ * cleared using <code>setClip(null)</code>, this method returns
+ * <code>null</code>.
+ * The coordinates in the rectangle are relative to the coordinate
+ * system origin of this graphics context.
+ * @return the bounding rectangle of the current clipping area,
+ * or <code>null</code> if no clip is set.
+ * @see java.awt.Graphics#getClip
+ * @see java.awt.Graphics#clipRect
+ * @see java.awt.Graphics#setClip(int, int, int, int)
+ * @see java.awt.Graphics#setClip(Shape)
+ * @since JDK1.1
+ */
+ public Rectangle getClipBounds(){
+ Shape c = getClip();
+ if (c==null) {
+ return null;
+ }
+ return c.getBounds();
+ }
+
+ /**
+ * Draws the text given by the specified iterator, using this
+ * graphics context's current color. The iterator has to specify a font
+ * for each character. The baseline of the
+ * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
+ * graphics context's coordinate system.
+ * @param iterator the iterator whose text is to be drawn
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @see java.awt.Graphics#drawBytes
+ * @see java.awt.Graphics#drawChars
+ */
+ public void drawString(AttributedCharacterIterator iterator,
+ int x, int y){
+ drawString(iterator, (float)x, (float)y);
+ }
+
+ /**
+ * Clears the specified rectangle by filling it with the background
+ * color of the current drawing surface. This operation does not
+ * use the current paint mode.
+ * <p>
+ * Beginning with Java&nbsp;1.1, the background color
+ * of offscreen images may be system dependent. Applications should
+ * use <code>setColor</code> followed by <code>fillRect</code> to
+ * ensure that an offscreen image is cleared to a specific color.
+ * @param x the <i>x</i> coordinate of the rectangle to clear.
+ * @param y the <i>y</i> coordinate of the rectangle to clear.
+ * @param width the width of the rectangle to clear.
+ * @param height the height of the rectangle to clear.
+ * @see java.awt.Graphics#fillRect(int, int, int, int)
+ * @see java.awt.Graphics#drawRect
+ * @see java.awt.Graphics#setColor(java.awt.Color)
+ * @see java.awt.Graphics#setPaintMode
+ * @see java.awt.Graphics#setXORMode(java.awt.Color)
+ */
+ public void clearRect(int x, int y, int width, int height) {
+ Paint paint = getPaint();
+ setColor(getBackground());
+ fillRect(x, y, width, height);
+ setPaint(paint);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+ ;
+ }
+
+ /**
+ * Sets the current clip to the rectangle specified by the given
+ * coordinates. This method sets the user clip, which is
+ * independent of the clipping associated with device bounds
+ * and window visibility.
+ * Rendering operations have no effect outside of the clipping area.
+ * @param x the <i>x</i> coordinate of the new clip rectangle.
+ * @param y the <i>y</i> coordinate of the new clip rectangle.
+ * @param width the width of the new clip rectangle.
+ * @param height the height of the new clip rectangle.
+ * @see java.awt.Graphics#clipRect
+ * @see java.awt.Graphics#setClip(Shape)
+ * @since JDK1.1
+ */
+ public void setClip(int x, int y, int width, int height){
+ setClip(new Rectangle(x, y, width, height));
+ }
+
+ /**
+ * Concatenates the current <code>Graphics2D</code>
+ * <code>Transform</code> with a rotation transform.
+ * Subsequent rendering is rotated by the specified radians relative
+ * to the previous origin.
+ * This is equivalent to calling <code>transform(R)</code>, where R is an
+ * <code>AffineTransform</code> represented by the following matrix:
+ * <pre>
+ * [ cos(theta) -sin(theta) 0 ]
+ * [ sin(theta) cos(theta) 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ * Rotating with a positive angle theta rotates points on the positive
+ * x axis toward the positive y axis.
+ * @param theta the angle of rotation in radians
+ */
+ public void rotate(double theta){
+ _transform.rotate(theta);
+ }
+
+ /**
+ * Concatenates the current <code>Graphics2D</code>
+ * <code>Transform</code> with a translated rotation
+ * transform. Subsequent rendering is transformed by a transform
+ * which is constructed by translating to the specified location,
+ * rotating by the specified radians, and translating back by the same
+ * amount as the original translation. This is equivalent to the
+ * following sequence of calls:
+ * <pre>
+ * translate(x, y);
+ * rotate(theta);
+ * translate(-x, -y);
+ * </pre>
+ * Rotating with a positive angle theta rotates points on the positive
+ * x axis toward the positive y axis.
+ * @param theta the angle of rotation in radians
+ * @param x x coordinate of the origin of the rotation
+ * @param y y coordinate of the origin of the rotation
+ */
+ public void rotate(double theta, double x, double y){
+ _transform.rotate(theta, x, y);
+ }
+
+ /**
+ * Concatenates the current <code>Graphics2D</code>
+ * <code>Transform</code> with a shearing transform.
+ * Subsequent renderings are sheared by the specified
+ * multiplier relative to the previous position.
+ * This is equivalent to calling <code>transform(SH)</code>, where SH
+ * is an <code>AffineTransform</code> represented by the following
+ * matrix:
+ * <pre>
+ * [ 1 shx 0 ]
+ * [ shy 1 0 ]
+ * [ 0 0 1 ]
+ * </pre>
+ * @param shx the multiplier by which coordinates are shifted in
+ * the positive X axis direction as a function of their Y coordinate
+ * @param shy the multiplier by which coordinates are shifted in
+ * the positive Y axis direction as a function of their X coordinate
+ */
+ public void shear(double shx, double shy){
+ _transform.shear(shx, shy);
+ }
+
+ /**
+ * Get the rendering context of the <code>Font</code> within this
+ * <code>Graphics2D</code> context.
+ * The {@link FontRenderContext}
+ * encapsulates application hints such as anti-aliasing and
+ * fractional metrics, as well as target device specific information
+ * such as dots-per-inch. This information should be provided by the
+ * application when using objects that perform typographical
+ * formatting, such as <code>Font</code> and
+ * <code>TextLayout</code>. This information should also be provided
+ * by applications that perform their own layout and need accurate
+ * measurements of various characteristics of glyphs such as advance
+ * and line height when various rendering hints have been applied to
+ * the text rendering.
+ *
+ * @return a reference to an instance of FontRenderContext.
+ * @see java.awt.font.FontRenderContext
+ * @see java.awt.Font#createGlyphVector(FontRenderContext,char[])
+ * @see java.awt.font.TextLayout
+ * @since JDK1.2
+ */
+ public FontRenderContext getFontRenderContext() {
+ boolean isAntiAliased = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(
+ getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));
+ boolean usesFractionalMetrics = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(
+ getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS));
+
+
+ return new FontRenderContext(new AffineTransform(), isAntiAliased, usesFractionalMetrics);
+ }
+
+ /**
+ * Composes an <code>AffineTransform</code> object with the
+ * <code>Transform</code> in this <code>Graphics2D</code> according
+ * to the rule last-specified-first-applied. If the current
+ * <code>Transform</code> is Cx, the result of composition
+ * with Tx is a new <code>Transform</code> Cx'. Cx' becomes the
+ * current <code>Transform</code> for this <code>Graphics2D</code>.
+ * Transforming a point p by the updated <code>Transform</code> Cx' is
+ * equivalent to first transforming p by Tx and then transforming
+ * the result by the original <code>Transform</code> Cx. In other
+ * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary,
+ * so further modifications to Tx do not affect rendering.
+ * @param Tx the <code>AffineTransform</code> object to be composed with
+ * the current <code>Transform</code>
+ * @see #setTransform
+ * @see AffineTransform
+ */
+ public void transform(AffineTransform Tx) {
+ _transform.concatenate(Tx);
+ }
+
+ /**
+ * Renders a <code>BufferedImage</code> that is
+ * filtered with a
+ * {@link BufferedImageOp}.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>
+ * and <code>Composite</code> attributes. This is equivalent to:
+ * <pre>
+ * img1 = op.filter(img, null);
+ * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
+ * </pre>
+ * @param img the <code>BufferedImage</code> to be rendered
+ * @param op the filter to be applied to the image before rendering
+ * @param x the x coordinate in user space where the image is rendered
+ * @param y the y coordinate in user space where the image is rendered
+ * @see #_transform
+ * @see #setTransform
+ * @see #setComposite
+ * @see #clip
+ * @see #setClip(Shape)
+ */
+ public void drawImage(BufferedImage img,
+ BufferedImageOp op,
+ int x,
+ int y){
+ img = op.filter(img, null);
+ drawImage(img, x, y, null);
+ }
+
+ /**
+ * Sets the background color for the <code>Graphics2D</code> context.
+ * The background color is used for clearing a region.
+ * When a <code>Graphics2D</code> is constructed for a
+ * <code>Component</code>, the background color is
+ * inherited from the <code>Component</code>. Setting the background color
+ * in the <code>Graphics2D</code> context only affects the subsequent
+ * <code>clearRect</code> calls and not the background color of the
+ * <code>Component</code>. To change the background
+ * of the <code>Component</code>, use appropriate methods of
+ * the <code>Component</code>.
+ * @param color the background color that isused in
+ * subsequent calls to <code>clearRect</code>
+ * @see #getBackground
+ * @see java.awt.Graphics#clearRect
+ */
+ public void setBackground(Color color) {
+ if(color == null)
+ return;
+
+ _background = color;
+ }
+
+ /**
+ * Returns the background color used for clearing a region.
+ * @return the current <code>Graphics2D</code> <code>Color</code>,
+ * which defines the background color.
+ * @see #setBackground
+ */
+ public Color getBackground(){
+ return _background;
+ }
+
+ /**
+ * Sets the <code>Composite</code> for the <code>Graphics2D</code> context.
+ * The <code>Composite</code> is used in all drawing methods such as
+ * <code>drawImage</code>, <code>drawString</code>, <code>draw</code>,
+ * and <code>fill</code>. It specifies how new pixels are to be combined
+ * with the existing pixels on the graphics device during the rendering
+ * process.
+ * <p>If this <code>Graphics2D</code> context is drawing to a
+ * <code>Component</code> on the display screen and the
+ * <code>Composite</code> is a custom object rather than an
+ * instance of the <code>AlphaComposite</code> class, and if
+ * there is a security manager, its <code>checkPermission</code>
+ * method is called with an <code>AWTPermission("readDisplayPixels")</code>
+ * permission.
+ *
+ * @param comp the <code>Composite</code> object to be used for rendering
+ * @throws SecurityException
+ * if a custom <code>Composite</code> object is being
+ * used to render to the screen and a security manager
+ * is set and its <code>checkPermission</code> method
+ * does not allow the operation.
+ * @see java.awt.Graphics#setXORMode
+ * @see java.awt.Graphics#setPaintMode
+ * @see java.awt.AlphaComposite
+ */
+ public void setComposite(Composite comp){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Returns the current <code>Composite</code> in the
+ * <code>Graphics2D</code> context.
+ * @return the current <code>Graphics2D</code> <code>Composite</code>,
+ * which defines a compositing style.
+ * @see #setComposite
+ */
+ public Composite getComposite(){
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return null;
+ }
+
+ /**
+ * Returns the value of a single preference for the rendering algorithms.
+ * Hint categories include controls for rendering quality and overall
+ * time/quality trade-off in the rendering process. Refer to the
+ * <code>RenderingHints</code> class for definitions of some common
+ * keys and values.
+ * @param hintKey the key corresponding to the hint to get.
+ * @return an object representing the value for the specified hint key.
+ * Some of the keys and their associated values are defined in the
+ * <code>RenderingHints</code> class.
+ * @see RenderingHints
+ */
+ public Object getRenderingHint(RenderingHints.Key hintKey){
+ return _hints.get(hintKey);
+ }
+
+ /**
+ * Sets the value of a single preference for the rendering algorithms.
+ * Hint categories include controls for rendering quality and overall
+ * time/quality trade-off in the rendering process. Refer to the
+ * <code>RenderingHints</code> class for definitions of some common
+ * keys and values.
+ * @param hintKey the key of the hint to be set.
+ * @param hintValue the value indicating preferences for the specified
+ * hint category.
+ * @see RenderingHints
+ */
+ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue){
+ _hints.put(hintKey, hintValue);
+ }
+
+
+ /**
+ * Renders the text of the specified
+ * {@link GlyphVector} using
+ * the <code>Graphics2D</code> context's rendering attributes.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, <code>Paint</code>, and
+ * <code>Composite</code> attributes. The <code>GlyphVector</code>
+ * specifies individual glyphs from a {@link Font}.
+ * The <code>GlyphVector</code> can also contain the glyph positions.
+ * This is the fastest way to render a set of characters to the
+ * screen.
+ *
+ * @param g the <code>GlyphVector</code> to be rendered
+ * @param x the x position in user space where the glyphs should be
+ * rendered
+ * @param y the y position in user space where the glyphs should be
+ * rendered
+ *
+ * @see java.awt.Font#createGlyphVector(FontRenderContext, char[])
+ * @see java.awt.font.GlyphVector
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ * @see #setTransform
+ * @see #setComposite
+ * @see #setClip(Shape)
+ */
+ public void drawGlyphVector(GlyphVector g, float x, float y) {
+ Shape glyphOutline = g.getOutline(x, y);
+ fill(glyphOutline);
+ }
+
+ /**
+ * Returns the device configuration associated with this
+ * <code>Graphics2D</code>.
+ * @return the device configuration
+ */
+ public GraphicsConfiguration getDeviceConfiguration() {
+ return GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ }
+
+ /**
+ * Sets the values of an arbitrary number of preferences for the
+ * rendering algorithms.
+ * Only values for the rendering hints that are present in the
+ * specified <code>Map</code> object are modified.
+ * All other preferences not present in the specified
+ * object are left unmodified.
+ * Hint categories include controls for rendering quality and
+ * overall time/quality trade-off in the rendering process.
+ * Refer to the <code>RenderingHints</code> class for definitions of
+ * some common keys and values.
+ * @param hints the rendering hints to be set
+ * @see RenderingHints
+ */
+ public void addRenderingHints(Map<?,?> hints){
+ this._hints.putAll(hints);
+ }
+
+ /**
+ * Concatenates the current
+ * <code>Graphics2D</code> <code>Transform</code>
+ * with a translation transform.
+ * Subsequent rendering is translated by the specified
+ * distance relative to the previous position.
+ * This is equivalent to calling transform(T), where T is an
+ * <code>AffineTransform</code> represented by the following matrix:
+ * <pre>
+ * [ 1 0 tx ]
+ * [ 0 1 ty ]
+ * [ 0 0 1 ]
+ * </pre>
+ * @param tx the distance to translate along the x-axis
+ * @param ty the distance to translate along the y-axis
+ */
+ public void translate(double tx, double ty){
+ _transform.translate(tx, ty);
+ }
+
+ /**
+ * Renders the text of the specified iterator, using the
+ * <code>Graphics2D</code> context's current <code>Paint</code>. The
+ * iterator must specify a font
+ * for each character. The baseline of the
+ * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in the
+ * User Space.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, <code>Paint</code>, and
+ * <code>Composite</code> attributes.
+ * For characters in script systems such as Hebrew and Arabic,
+ * the glyphs can be rendered from right to left, in which case the
+ * coordinate supplied is the location of the leftmost character
+ * on the baseline.
+ * @param iterator the iterator whose text is to be rendered
+ * @param x the x coordinate where the iterator's text is to be
+ * rendered
+ * @param y the y coordinate where the iterator's text is to be
+ * rendered
+ * @see #setPaint
+ * @see java.awt.Graphics#setColor
+ * @see #setTransform
+ * @see #setComposite
+ * @see #setClip
+ */
+ public void drawString(AttributedCharacterIterator iterator, float x, float y) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Checks whether or not the specified <code>Shape</code> intersects
+ * the specified {@link Rectangle}, which is in device
+ * space. If <code>onStroke</code> is false, this method checks
+ * whether or not the interior of the specified <code>Shape</code>
+ * intersects the specified <code>Rectangle</code>. If
+ * <code>onStroke</code> is <code>true</code>, this method checks
+ * whether or not the <code>Stroke</code> of the specified
+ * <code>Shape</code> outline intersects the specified
+ * <code>Rectangle</code>.
+ * The rendering attributes taken into account include the
+ * <code>Clip</code>, <code>Transform</code>, and <code>Stroke</code>
+ * attributes.
+ * @param rect the area in device space to check for a hit
+ * @param s the <code>Shape</code> to check for a hit
+ * @param onStroke flag used to choose between testing the
+ * stroked or the filled shape. If the flag is <code>true</code>, the
+ * <code>Stroke</code> oultine is tested. If the flag is
+ * <code>false</code>, the filled <code>Shape</code> is tested.
+ * @return <code>true</code> if there is a hit; <code>false</code>
+ * otherwise.
+ * @see #setStroke
+ * @see #fill(Shape)
+ * @see #draw(Shape)
+ * @see #_transform
+ * @see #setTransform
+ * @see #clip
+ * @see #setClip(Shape)
+ */
+ public boolean hit(Rectangle rect,
+ Shape s,
+ boolean onStroke){
+ if (onStroke) {
+ s = getStroke().createStrokedShape(s);
+ }
+
+ s = getTransform().createTransformedShape(s);
+
+ return s.intersects(rect);
+ }
+
+ /**
+ * Gets the preferences for the rendering algorithms. Hint categories
+ * include controls for rendering quality and overall time/quality
+ * trade-off in the rendering process.
+ * Returns all of the hint key/value pairs that were ever specified in
+ * one operation. Refer to the
+ * <code>RenderingHints</code> class for definitions of some common
+ * keys and values.
+ * @return a reference to an instance of <code>RenderingHints</code>
+ * that contains the current preferences.
+ * @see RenderingHints
+ */
+ public RenderingHints getRenderingHints(){
+ return _hints;
+ }
+
+ /**
+ * Replaces the values of all preferences for the rendering
+ * algorithms with the specified <code>hints</code>.
+ * The existing values for all rendering hints are discarded and
+ * the new set of known hints and values are initialized from the
+ * specified {@link Map} object.
+ * Hint categories include controls for rendering quality and
+ * overall time/quality trade-off in the rendering process.
+ * Refer to the <code>RenderingHints</code> class for definitions of
+ * some common keys and values.
+ * @param hints the rendering hints to be set
+ * @see RenderingHints
+ */
+ public void setRenderingHints(Map<?,?> hints){
+ this._hints = new RenderingHints(null);
+ this._hints.putAll(hints);
+ }
+
+ /**
+ * Renders an image, applying a transform from image space into user space
+ * before drawing.
+ * The transformation from user space into device space is done with
+ * the current <code>Transform</code> in the <code>Graphics2D</code>.
+ * The specified transformation is applied to the image before the
+ * transform attribute in the <code>Graphics2D</code> context is applied.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, and <code>Composite</code> attributes.
+ * Note that no rendering is done if the specified transform is
+ * noninvertible.
+ * @param img the <code>Image</code> to be rendered
+ * @param xform the transformation from image space into user space
+ * @param obs the {@link ImageObserver}
+ * to be notified as more of the <code>Image</code>
+ * is converted
+ * @return <code>true</code> if the <code>Image</code> is
+ * fully loaded and completely rendered;
+ * <code>false</code> if the <code>Image</code> is still being loaded.
+ * @see #_transform
+ * @see #setTransform
+ * @see #setComposite
+ * @see #clip
+ * @see #setClip(Shape)
+ */
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return false;
+ }
+
+ /**
+ * Draws as much of the specified image as has already been scaled
+ * to fit inside the specified rectangle.
+ * <p>
+ * The image is drawn inside the specified rectangle of this
+ * graphics context's coordinate space, and is scaled if
+ * necessary. Transparent pixels do not affect whatever pixels
+ * are already there.
+ * <p>
+ * This method returns immediately in all cases, even if the
+ * entire image has not yet been scaled, dithered, and converted
+ * for the current output device.
+ * If the current output representation is not yet complete, then
+ * <code>drawImage</code> returns <code>false</code>. As more of
+ * the image becomes available, the process that loads the image notifies
+ * the image observer by calling its <code>imageUpdate</code> method.
+ * <p>
+ * A scaled version of an image will not necessarily be
+ * available immediately just because an unscaled version of the
+ * image has been constructed for this output device. Each size of
+ * the image may be cached separately and generated from the original
+ * data in a separate image production sequence.
+ * @param img the specified image to be drawn. This method does
+ * nothing if <code>img</code> is null.
+ * @param x the <i>x</i> coordinate.
+ * @param y the <i>y</i> coordinate.
+ * @param width the width of the rectangle.
+ * @param height the height of the rectangle.
+ * @param observer object to be notified as more of
+ * the image is converted.
+ * @return <code>false</code> if the image pixels are still changing;
+ * <code>true</code> otherwise.
+ * @see java.awt.Image
+ * @see java.awt.image.ImageObserver
+ * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
+ */
+ public boolean drawImage(Image img, int x, int y,
+ int width, int height,
+ ImageObserver observer) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ return false;
+ }
+
+ /**
+ * Creates a new <code>Graphics</code> object that is
+ * a copy of this <code>Graphics</code> object.
+ * @return a new graphics context that is a copy of
+ * this graphics context.
+ */
+ public Graphics create() {
+ try {
+ return (Graphics)clone();
+ } catch (CloneNotSupportedException e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Gets the font metrics for the specified font.
+ * @return the font metrics for the specified font.
+ * @param f the specified font
+ * @see java.awt.Graphics#getFont
+ * @see java.awt.FontMetrics
+ * @see java.awt.Graphics#getFontMetrics()
+ */
+ @SuppressWarnings("deprecation")
+ @SuppressForbidden
+ public FontMetrics getFontMetrics(Font f) {
+ return Toolkit.getDefaultToolkit().getFontMetrics(f);
+ }
+
+ /**
+ * Sets the paint mode of this graphics context to alternate between
+ * this graphics context's current color and the new specified color.
+ * This specifies that logical pixel operations are performed in the
+ * XOR mode, which alternates pixels between the current color and
+ * a specified XOR color.
+ * <p>
+ * When drawing operations are performed, pixels which are the
+ * current color are changed to the specified color, and vice versa.
+ * <p>
+ * Pixels that are of colors other than those two colors are changed
+ * in an unpredictable but reversible manner; if the same figure is
+ * drawn twice, then all pixels are restored to their original values.
+ * @param c1 the XOR alternation color
+ */
+ public void setXORMode(Color c1) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Sets the paint mode of this graphics context to overwrite the
+ * destination with this graphics context's current color.
+ * This sets the logical pixel operation function to the paint or
+ * overwrite mode. All subsequent rendering operations will
+ * overwrite the destination with the current color.
+ */
+ public void setPaintMode() {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Renders a
+ * {@link RenderableImage},
+ * applying a transform from image space into user space before drawing.
+ * The transformation from user space into device space is done with
+ * the current <code>Transform</code> in the <code>Graphics2D</code>.
+ * The specified transformation is applied to the image before the
+ * transform attribute in the <code>Graphics2D</code> context is applied.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, and <code>Composite</code> attributes. Note
+ * that no rendering is done if the specified transform is
+ * noninvertible.
+ *<p>
+ * Rendering hints set on the <code>Graphics2D</code> object might
+ * be used in rendering the <code>RenderableImage</code>.
+ * If explicit control is required over specific hints recognized by a
+ * specific <code>RenderableImage</code>, or if knowledge of which hints
+ * are used is required, then a <code>RenderedImage</code> should be
+ * obtained directly from the <code>RenderableImage</code>
+ * and rendered using
+ *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}.
+ * @param img the image to be rendered. This method does
+ * nothing if <code>img</code> is null.
+ * @param xform the transformation from image space into user space
+ * @see #_transform
+ * @see #setTransform
+ * @see #setComposite
+ * @see #clip
+ * @see #setClip
+ * @see #drawRenderedImage
+ */
+ public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ /**
+ * Renders a {@link RenderedImage},
+ * applying a transform from image
+ * space into user space before drawing.
+ * The transformation from user space into device space is done with
+ * the current <code>Transform</code> in the <code>Graphics2D</code>.
+ * The specified transformation is applied to the image before the
+ * transform attribute in the <code>Graphics2D</code> context is applied.
+ * The rendering attributes applied include the <code>Clip</code>,
+ * <code>Transform</code>, and <code>Composite</code> attributes. Note
+ * that no rendering is done if the specified transform is
+ * noninvertible.
+ * @param img the image to be rendered. This method does
+ * nothing if <code>img</code> is null.
+ * @param xform the transformation from image space into user space
+ * @see #_transform
+ * @see #setTransform
+ * @see #setComposite
+ * @see #clip
+ * @see #setClip
+ */
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+ if (log.check(POILogger.WARN)) {
+ log.log(POILogger.WARN, "Not implemented");
+ }
+ }
+
+ protected void applyStroke(SimpleShape<?,?> shape) {
+ if (_stroke instanceof BasicStroke){
+ BasicStroke bs = (BasicStroke)_stroke;
+ shape.setStrokeStyle((double)bs.getLineWidth());
+ float[] dash = bs.getDashArray();
+ if (dash != null) {
+ //TODO: implement more dashing styles
+ shape.setStrokeStyle(StrokeStyle.LineDash.DASH);
+ }
+ }
+ }
+
+ protected void applyPaint(SimpleShape<?,?> shape) {
+ if (_paint instanceof Color) {
+ shape.setFillColor((Color)_paint);
+ }
+ }
+}
diff --git a/src/java/org/apache/poi/sl/usermodel/SimpleShape.java b/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
index ceed729e09..8ed151b496 100644
--- a/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
@@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel;
+import java.awt.Color;
+
import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.IAdjustableShape;
@@ -25,15 +27,66 @@ public interface SimpleShape<
S extends Shape<S,P>,
P extends TextParagraph<S,P,?>
> extends Shape<S,P>, IAdjustableShape, PlaceableShape<S,P> {
+
+ enum Placeholder {
+ TITLE,
+ BODY,
+ CENTERED_TITLE,
+ SUBTITLE,
+ DATETIME,
+ SLIDE_NUMBER,
+ FOOTER,
+ HEADER,
+ CONTENT,
+ CHART,
+ TABLE,
+ CLIP_ART,
+ DGM,
+ MEDIA,
+ SLIDE_IMAGE,
+ PICTURE
+ }
+
FillStyle getFillStyle();
+
LineDecoration getLineDecoration();
+
StrokeStyle getStrokeStyle();
+
+ /**
+ * Sets the line attributes.
+ * Possible attributes are Double (width), LineCap, LineDash, LineCompound, Color
+ * (implementations of PaintStyle aren't yet supported ...)
+ *
+ * If no styles are given, the line will be hidden
+ *
+ * @param styles the line attributes
+ */
+ void setStrokeStyle(Object... styles);
CustomGeometry getGeometry();
-
+
ShapeType getShapeType();
+ void setShapeType(ShapeType type);
boolean isPlaceholder();
-
+
Shadow<S,P> getShadow();
+
+ /**
+ * Returns the solid color fill.
+ *
+ * @return solid fill color of null if not set or fill color
+ * is not solid (pattern or gradient)
+ */
+ Color getFillColor();
+
+ /**
+ * Specifies a solid color fill. The shape is filled entirely with the
+ * specified color.
+ *
+ * @param color the solid color fill. The value of <code>null</code> unsets
+ * the solid fill attribute from the underlying implementation
+ */
+ void setFillColor(Color color);
}
diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShow.java b/src/java/org/apache/poi/sl/usermodel/SlideShow.java
index 53449e76d5..968911b95f 100644
--- a/src/java/org/apache/poi/sl/usermodel/SlideShow.java
+++ b/src/java/org/apache/poi/sl/usermodel/SlideShow.java
@@ -48,6 +48,13 @@ public interface SlideShow<
* @return the page size
*/
Dimension getPageSize();
+
+ /**
+ * Change the current page size
+ *
+ * @param pgsize page size (in points)
+ */
+ void setPageSize(Dimension pgsize);
/**
* Returns all Pictures of this slideshow.
diff --git a/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java b/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java
index 244173fed4..be93a994de 100644
--- a/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java
+++ b/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java
@@ -20,18 +20,27 @@ package org.apache.poi.sl.usermodel;
public interface StrokeStyle {
enum LineCap {
/** Rounded ends */
- ROUND(1),
+ ROUND(0,1),
/** Square protrudes by half line width */
- SQUARE(2),
+ SQUARE(1,2),
/** Line ends at end point*/
- FLAT(3);
+ FLAT(2,3);
+ public final int nativeId;
public final int ooxmlId;
- LineCap(int ooxmlId) {
+ LineCap(int nativeId, int ooxmlId) {
+ this.nativeId = nativeId;
this.ooxmlId = ooxmlId;
}
+ public static LineCap fromNativeId(int nativeId) {
+ for (LineCap ld : values()) {
+ if (ld.nativeId == nativeId) return ld;
+ }
+ return null;
+ }
+
public static LineCap fromOoxmlId(int ooxmlId) {
for (LineCap lc : values()) {
if (lc.ooxmlId == ooxmlId) return lc;
@@ -96,20 +105,22 @@ public interface StrokeStyle {
enum LineCompound {
/** Single line (of width lineWidth) - native 0 / ooxml default */
- SINGLE(0),
+ SINGLE(0, 1),
/** Double lines of equal width - native 1 / ooxml "dbl" */
- DOUBLE(1),
+ DOUBLE(1, 2),
/** Double lines, one thick, one thin - native 2 / ooxml "thickThin" */
- THICK_THIN(2),
+ THICK_THIN(2, 3),
/** Double lines, reverse order - native 3 / ooxml "thinThick" */
- THIN_THICK(3),
+ THIN_THICK(3, 4),
/** Three lines, thin, thick, thin - native 4 / ooxml "tri" */
- TRIPLE(4);
+ TRIPLE(4, 5);
public final int nativeId;
+ public final int ooxmlId;
- LineCompound(int nativeId) {
+ LineCompound(int nativeId, int ooxmlId) {
this.nativeId = nativeId;
+ this.ooxmlId = ooxmlId;
}
public static LineCompound fromNativeId(int nativeId) {
@@ -118,6 +129,13 @@ public interface StrokeStyle {
}
return null;
}
+
+ public static LineCompound fromOoxmlId(int ooxmlId) {
+ for (LineCompound lc : values()) {
+ if (lc.ooxmlId == ooxmlId) return lc;
+ }
+ return null;
+ }
}
diff --git a/src/java/org/apache/poi/sl/usermodel/TableCell.java b/src/java/org/apache/poi/sl/usermodel/TableCell.java
index 278573bab5..5ad4c4c296 100644
--- a/src/java/org/apache/poi/sl/usermodel/TableCell.java
+++ b/src/java/org/apache/poi/sl/usermodel/TableCell.java
@@ -17,9 +17,70 @@
package org.apache.poi.sl.usermodel;
+import java.awt.Color;
+
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
+
public interface TableCell<
S extends Shape<S,P>,
P extends TextParagraph<S,P,?>
> extends TextShape<S,P> {
+ enum BorderEdge { bottom, left, top, right };
+
+ /**
+ * Return line style of given edge or {@code null} if border is not defined
+ *
+ * @param edge the border edge
+ * @return line style of given edge or {@code null} if border is not defined
+ */
+ StrokeStyle getBorderStyle(BorderEdge edge);
+
+ /**
+ * Sets the {@link StrokeStyle} of the given border edge.
+ * A {@code null} property of the style is ignored.
+ *
+ * @param edge border edge
+ * @param style the new stroke style
+ */
+ void setBorderStyle(BorderEdge edge, StrokeStyle style);
+
+ /**
+ * Convenience method for setting the border width.
+ *
+ * @param edge border edge
+ * @param width the new border width
+ */
+ void setBorderWidth(BorderEdge edge, double width);
+
+ /**
+ * Convenience method for setting the border color.
+ *
+ * @param edge border edge
+ * @param color the new border color
+ */
+ void setBorderColor(BorderEdge edge, Color color);
+
+ /**
+ * Convenience method for setting the border line compound.
+ *
+ * @param edge border edge
+ * @param compound the new border line compound
+ */
+ void setBorderCompound(BorderEdge edge, LineCompound compound);
+ /**
+ * Convenience method for setting the border line dash.
+ *
+ * @param edge border edge
+ * @param dash the new border line dash
+ */
+ void setBorderDash(BorderEdge edge, LineDash dash);
+
+ /**
+ * Remove all line attributes of the given border edge
+ *
+ * @param edge the border edge to be cleared
+ */
+ void removeBorder(BorderEdge edge);
}
diff --git a/src/java/org/apache/poi/sl/usermodel/TableShape.java b/src/java/org/apache/poi/sl/usermodel/TableShape.java
index 29342e7d94..5614484467 100644
--- a/src/java/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/TableShape.java
@@ -21,5 +21,25 @@ public interface TableShape<
S extends Shape<S,P>,
P extends TextParagraph<S,P,?>
> extends Shape<S,P>, PlaceableShape<S,P> {
- // to be defined ...
+ int getNumberOfColumns();
+
+ int getNumberOfRows();
+
+ TableCell<S,P> getCell(int row, int col);
+
+ /**
+ * Sets the width (in points) of the n-th column
+ *
+ * @param idx the column index (0-based)
+ * @param width the width (in points)
+ */
+ void setColumnWidth(int idx, double width);
+
+ /**
+ * Sets the row height.
+ *
+ * @param row the row index (0-based)
+ * @param height the height to set (in points)
+ */
+ void setRowHeight(int row, double height);
}
diff --git a/src/java/org/apache/poi/sl/usermodel/TextBox.java b/src/java/org/apache/poi/sl/usermodel/TextBox.java
index 8fa997c89e..bc6951103a 100644
--- a/src/java/org/apache/poi/sl/usermodel/TextBox.java
+++ b/src/java/org/apache/poi/sl/usermodel/TextBox.java
@@ -17,6 +17,13 @@
package org.apache.poi.sl.usermodel;
+/**
+ * Represents a TextFrame shape in PowerPoint.
+ * <p>
+ * Contains the text in a text frame as well as the properties and methods
+ * that control alignment and anchoring of the text.
+ * </p>
+ */
public interface TextBox<
S extends Shape<S,P>,
P extends TextParagraph<S,P,?>
diff --git a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
index 00a016058d..b35d323e1a 100644
--- a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
+++ b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
@@ -18,6 +18,7 @@
package org.apache.poi.sl.usermodel;
import java.awt.Color;
+import java.util.List;
@@ -339,4 +340,9 @@ public interface TextParagraph<
TextShape<S,P> getParentShape();
+
+ /**
+ * Fetch the text runs that are contained within this block of text
+ */
+ List<T> getTextRuns();
}
diff --git a/src/java/org/apache/poi/sl/usermodel/TextRun.java b/src/java/org/apache/poi/sl/usermodel/TextRun.java
index bd0164c275..9eb27b616e 100644
--- a/src/java/org/apache/poi/sl/usermodel/TextRun.java
+++ b/src/java/org/apache/poi/sl/usermodel/TextRun.java
@@ -30,23 +30,23 @@ public interface TextRun {
SMALL,
ALL
}
-
+
String getRawText();
- void setText(String text);
-
- TextCap getTextCap();
-
- /**
- * Returns the font color.
- * This usually returns a {@link SolidPaint}, but but also other classes are possible
- *
- * @return the font color/paint
- *
+ void setText(String text);
+
+ TextCap getTextCap();
+
+ /**
+ * Returns the font color.
+ * This usually returns a {@link SolidPaint}, but but also other classes are possible
+ *
+ * @return the font color/paint
+ *
* @see org.apache.poi.sl.draw.DrawPaint#getPaint(java.awt.Graphics2D, PaintStyle)
* @see SolidPaint#getSolidColor()
- * @see org.apache.poi.sl.draw.DrawPaint#applyColorTransform(ColorStyle)
- */
- PaintStyle getFontColor();
+ * @see org.apache.poi.sl.draw.DrawPaint#applyColorTransform(ColorStyle)
+ */
+ PaintStyle getFontColor();
/**
* Sets the (solid) font color - convenience function
@@ -56,41 +56,104 @@ public interface TextRun {
void setFontColor(Color color);
/**
- * Sets the font color
- *
- * @param color the color
- *
- * @see org.apache.poi.sl.draw.DrawPaint#createSolidPaint(Color)
- */
- void setFontColor(PaintStyle color);
-
-
+ * Sets the font color
+ *
+ * @param color the color
+ *
+ * @see org.apache.poi.sl.draw.DrawPaint#createSolidPaint(Color)
+ */
+ void setFontColor(PaintStyle color);
+
+
/**
* Returns the font size which is either set directly on this text run or
* given from the slide layout
- *
+ *
* @return font size in points or null if font size is not set.
*/
- Double getFontSize();
+ Double getFontSize();
/**
* Sets the font size directly on this text run, if null is given, the
* font size defaults to the values given from the slide layout
- *
+ *
* @param fontSize font size in points, if null the underlying fontsize will be unset
*/
- void setFontSize(Double fontSize);
- String getFontFamily();
-
- boolean isBold();
- boolean isItalic();
- boolean isUnderlined();
- boolean isStrikethrough();
- boolean isSubscript();
- boolean isSuperscript();
-
- /**
- * @return the pitch and family id or -1 if not applicable
- */
- byte getPitchAndFamily();
+ void setFontSize(Double fontSize);
+
+ /**
+ * @return font family or null if not set
+ */
+ String getFontFamily();
+
+ /**
+ * Specifies the typeface, or name of the font that is to be used for this text run.
+ *
+ * @param typeface the font to apply to this text run.
+ * The value of <code>null</code> unsets the Typeface attrubute from the underlying xml.
+ */
+ void setFontFamily(String typeface);
+
+ /**
+ * @return true, if text is bold
+ */
+ boolean isBold();
+
+ /**
+ * Sets the bold state
+ *
+ * @param bold set to true for bold text, false for normal weight
+ */
+ void setBold(boolean bold);
+
+ /**
+ * @return true, if text is italic
+ */
+ boolean isItalic();
+
+ /**
+ * Sets the italic state
+ *
+ * @param italic set to true for italic text, false for non-italics
+ */
+ void setItalic(boolean italic);
+
+ /**
+ * @return true, if text is underlined
+ */
+ boolean isUnderlined();
+
+ /**
+ * Sets the underlined state
+ *
+ * @param underlined set to true for underlined text, false for no underlining
+ */
+ void setUnderlined(boolean underlined);
+
+ /**
+ * @return true, if text is stroked
+ */
+ boolean isStrikethrough();
+
+ /**
+ * Sets the strikethrough state
+ *
+ * @param stroked set to true for stroked text, false for no stroking
+ */
+ void setStrikethrough(boolean stroked);
+
+ /**
+ * @return true, if text is sub scripted
+ */
+ boolean isSubscript();
+
+ /**
+ * @return true, if text is super scripted
+ */
+ boolean isSuperscript();
+
+ /**
+ * @return the pitch and family id or -1 if not applicable
+ */
+ byte getPitchAndFamily();
}
diff --git a/src/java/org/apache/poi/sl/usermodel/TextShape.java b/src/java/org/apache/poi/sl/usermodel/TextShape.java
index f487c108a4..0ec2ddfb91 100644
--- a/src/java/org/apache/poi/sl/usermodel/TextShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/TextShape.java
@@ -26,7 +26,7 @@ public interface TextShape<
/**
* Vertical Text Types
*/
- public enum TextDirection {
+ enum TextDirection {
/**
* Horizontal text. This should be default.
*/
@@ -59,7 +59,7 @@ public interface TextShape<
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside
* </p>
*/
- public enum TextAutofit {
+ enum TextAutofit {
/**
* Specifies that text within the text body should not be auto-fit to the bounding box.
* Auto-fitting is when text within a text box is scaled in order to remain inside
@@ -89,6 +89,46 @@ public interface TextShape<
*/
SHAPE
}
+
+ /**
+ * This enum represents a compromise for the handling of
+ * HSLF run types (see org.apache.poi.hslf.record.TextHeaderAtom) and
+ * XSLF placeholders (see org.apache.poi.xslf.usermodel.Placeholder).
+ * When a shape is considered a placeholder by the generating application
+ * it can have special properties to alert the user that they may enter content into the shape.
+ *
+ * This enum and the handling around it may change significantly in future releases
+ */
+ enum TextPlaceholder {
+ /** Title placeholder shape text */
+ TITLE,
+ /** Body placeholder shape text */
+ BODY,
+ /** Center title placeholder shape text */
+ CENTER_TITLE,
+ /** Center body placeholder shape text */
+ CENTER_BODY,
+ /** Half-sized body placeholder shape text */
+ HALF_BODY,
+ /** Quarter-sized body placeholder shape text */
+ QUARTER_BODY,
+ /** Notes placeholder shape text */
+ NOTES,
+ /** Any other text */
+ OTHER
+ }
+
+ /**
+ * Sets (overwrites) the current text.
+ * Uses the properties of the first paragraph / textrun.
+ * Text paragraphs are split by \\r or \\n.
+ * New lines within text run are split by \\u000b
+ *
+ * @param text the text string used by this object.
+ *
+ * @return the last text run of the - potential split - text
+ */
+ TextRun setText(String text);
/**
* @return the TextParagraphs for this text box
@@ -99,6 +139,13 @@ public interface TextShape<
* @return text shape margin
*/
Insets2D getInsets();
+
+ /**
+ * Sets the shape margins
+ *
+ * @param insets the new shape margins
+ */
+ void setInsets(Insets2D insets);
/**
* Compute the cumulative height occupied by the text
@@ -113,6 +160,14 @@ public interface TextShape<
VerticalAlignment getVerticalAlignment();
/**
+ * Sets the type of vertical alignment for the text.
+ *
+ * @param vAlign - the type of alignment.
+ * A {@code null} values unsets this property.
+ */
+ void setVerticalAlignment(VerticalAlignment vAlign);
+
+ /**
* Returns if the text is centered.
* If true and if the individual paragraph settings allow it,
* the whole text block will be displayed centered, i.e. its left and right
@@ -123,12 +178,35 @@ public interface TextShape<
boolean isHorizontalCentered();
/**
+ * Sets if the paragraphs are horizontal centered
+ *
+ * @param isCentered true, if the paragraphs are horizontal centered
+ * A {@code null} values unsets this property.
+ */
+ void setHorizontalCentered(Boolean isCentered);
+
+ /**
* @return whether to wrap words within the bounding rectangle
*/
boolean getWordWrap();
/**
+ * @param wrap whether to wrap words within the bounding rectangle
+ */
+ void setWordWrap(boolean wrap);
+
+ /**
* @return vertical orientation of the text
*/
TextDirection getTextDirection();
+
+ /**
+ * Sets the text placeholder
+ */
+ void setTextPlaceholder(TextPlaceholder placeholder);
+
+ /**
+ * @return the text placeholder
+ */
+ TextPlaceholder getTextPlaceholder();
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java
deleted file mode 100644
index 087b28c054..0000000000
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- */
-package org.apache.poi.xslf.usermodel;
-
-/**
- * @author Yegor Kozlov
- */
-public enum Placeholder {
- TITLE,
- BODY,
- CENTERED_TITLE,
- SUBTITLE,
- DATETIME,
- SLIDE_NUMBER,
- FOOTER,
- HEADER,
- CONTENT,
- CHART,
- TABLE,
- CLIP_ART,
- DGM,
- MEDIA,
- SLIDE_IMAGE,
- PICTURE
-}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
index e896420e93..bd150811a2 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
@@ -41,7 +41,6 @@ import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.Resources;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.util.Beta;
-import org.apache.poi.util.DocumentHelper;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
@@ -404,11 +403,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
return slide;
}
- /**
- * Returns the current page size
- *
- * @return the page size
- */
+ @Override
public Dimension getPageSize(){
CTSlideSize sz = _presentation.getSldSz();
int cx = sz.getCx();
@@ -416,11 +411,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy));
}
- /**
- * Sets the page size to the given <code>Dimension</code> object.
- *
- * @param pgSize page size
- */
+ @Override
public void setPageSize(Dimension pgSize){
CTSlideSize sz = CTSlideSize.Factory.newInstance();
sz.setCx(Units.toEMU(pgSize.getWidth()));
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
index b9e4004488..e45df5ee29 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
@@ -25,7 +25,12 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
@@ -71,14 +76,26 @@ public class XSLFAutoShape extends XSLFTextShape
prst.addNewAvLst();
return ct;
}
+
+ protected static void initTextBody(CTTextBody txBody) {
+ CTTextBodyProperties bodypr = txBody.addNewBodyPr();
+ bodypr.setAnchor(STTextAnchoringType.T);
+ bodypr.setRtlCol(false);
+ CTTextParagraph p = txBody.addNewP();
+ p.addNewPPr().setAlgn(STTextAlignType.L);
+ CTTextCharacterProperties endPr = p.addNewEndParaRPr();
+ endPr.setLang("en-US");
+ endPr.setSz(1100);
+ p.addNewR().setT("");
+ txBody.addNewLstStyle();
+ }
protected CTTextBody getTextBody(boolean create){
CTShape shape = (CTShape)getXmlObject();
CTTextBody txBody = shape.getTxBody();
if (txBody == null && create) {
txBody = shape.addNewTxBody();
- txBody.addNewBodyPr();
- txBody.addNewLstStyle();
+ initTextBody(txBody);
}
return txBody;
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
index 37dbc33a22..dc1ef5af2c 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
@@ -33,6 +33,7 @@ import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
index f5d0207b78..daca97131d 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
@@ -39,6 +39,7 @@ import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawPictureShape;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
index 821cb07dff..28c98889cb 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
@@ -88,25 +88,23 @@ public abstract class XSLFSimpleShape extends XSLFShape
super(shape,sheet);
}
- /**
- *
- * @param type
- */
- public void setShapeType(ShapeType type){
+ @Override
+ public void setShapeType(ShapeType type) {
STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId);
getSpPr().getPrstGeom().setPrst(geom);
}
+ @Override
public ShapeType getShapeType(){
STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst();
return ShapeType.forId(geom.intValue(), true);
}
-
+
protected CTTransform2D getSafeXfrm() {
CTTransform2D xfrm = getXfrm();
return (xfrm == null ? getSpPr().addNewXfrm() : xfrm);
}
-
+
protected CTTransform2D getXfrm() {
PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
public boolean fetch(XSLFShape shape) {
@@ -151,7 +149,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
ext.setCx(cx);
ext.setCy(cy);
}
-
+
@Override
public void setRotation(double theta) {
getSafeXfrm().setRot((int) (theta * 60000));
@@ -185,7 +183,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV();
}
-
+
/**
* Get default line properties defined in the theme (if any).
* Used internally to resolve shape properties.
@@ -199,7 +197,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
if (lnRef == null) return null;
// 1-based index of a line style within the style matrix
int idx = (int)lnRef.getIdx();
-
+
XSLFTheme theme = getSheet().getTheme();
if (theme == null) return null;
CTBaseStyles styles = theme.getXmlObject().getThemeElements();
@@ -208,7 +206,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
if (styleMatrix == null) return null;
CTLineStyleList lineStyles = styleMatrix.getLnStyleLst();
if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) return null;
-
+
return lineStyles.getLnArray(idx - 1);
}
@@ -262,7 +260,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
setValue(null); // use it as 'nofill' value
return true;
}
-
+
PaintStyle paint = null;
PackagePart pp = getSheet().getPackagePart();
for (XmlObject obj : spPr.selectPath("*")) {
@@ -290,11 +288,11 @@ public abstract class XSLFSimpleShape extends XSLFShape
PaintStyle paint = fetcher.getValue();
if (paint != null) return paint;
-
+
// line color was not found, check if it is defined in the theme
CTShapeStyle style = getSpStyle();
if (style == null) return null;
-
+
// get a reference to a line style within the style matrix.
CTStyleMatrixReference lnRef = style.getLnRef();
int idx = (int)lnRef.getIdx();
@@ -308,7 +306,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
return paint;
}
-
+
/**
*
* @param width line width in points. <code>0</code> means no line
@@ -362,6 +360,40 @@ public abstract class XSLFSimpleShape extends XSLFShape
return lineWidth;
}
+
+ /**
+ * @param compound set the line compound style
+ */
+ public void setLineCompound(LineCompound compound) {
+ CTShapeProperties spPr = getSpPr();
+ if (compound == null) {
+ if (spPr.isSetLn() && spPr.getLn().isSetCmpd())
+ spPr.getLn().unsetCmpd();
+ } else {
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+ STCompoundLine.Enum xCmpd;
+ switch (compound) {
+ default:
+ case SINGLE:
+ xCmpd = STCompoundLine.SNG;
+ break;
+ case DOUBLE:
+ xCmpd = STCompoundLine.DBL;
+ break;
+ case THICK_THIN:
+ xCmpd = STCompoundLine.THICK_THIN;
+ break;
+ case THIN_THICK:
+ xCmpd = STCompoundLine.THIN_THICK;
+ break;
+ case TRIPLE:
+ xCmpd = STCompoundLine.TRI;
+ break;
+ }
+ ln.setCmpd(xCmpd);
+ }
+ }
+
/**
* @return the line compound
*/
@@ -392,7 +424,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
}
}
-
+
if (cmpd == null) return null;
switch (cmpd) {
@@ -417,15 +449,12 @@ public abstract class XSLFSimpleShape extends XSLFShape
public void setLineDash(LineDash dash) {
CTShapeProperties spPr = getSpPr();
if (dash == null) {
- if (spPr.isSetLn() && spPr.getLn().isSetPrstDash())
+ if (spPr.isSetLn() && spPr.getLn().isSetPrstDash())
spPr.getLn().unsetPrstDash();
} else {
- CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory
- .newInstance();
- val.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
- CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
- .addNewLn();
- ln.setPrstDash(val);
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+ CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash();
+ ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
}
}
@@ -513,13 +542,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
return cap;
}
- /**
- * Specifies a solid color fill. The shape is filled entirely with the
- * specified color.
- *
- * @param color the solid color fill. The value of <code>null</code> unsets
- * the solidFIll attribute from the underlying xml
- */
+ @Override
public void setFillColor(Color color) {
CTShapeProperties spPr = getSpPr();
if (color == null) {
@@ -545,10 +568,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
}
- /**
- * @return solid fill color of null if not set or fill color
- * is not solid (pattern or gradient)
- */
+ @Override
public Color getFillColor() {
PaintStyle ps = getFillPaint();
if (ps instanceof SolidPaint) {
@@ -615,7 +635,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
return geom;
}
-
+
@Override
void copy(XSLFShape sh){
super.copy(sh);
@@ -635,7 +655,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
String relId = getSheet().importBlip(blipId, s.getSheet().getPackagePart());
blip.setEmbed(relId);
}
-
+
Color srcLineColor = s.getLineColor();
Color tgtLineColor = getLineColor();
if(srcLineColor != null && !srcLineColor.equals(tgtLineColor)) {
@@ -871,7 +891,31 @@ public abstract class XSLFSimpleShape extends XSLFShape
public LineCompound getLineCompound() {
return XSLFSimpleShape.this.getLineCompound();
}
-
+
};
}
+
+ @Override
+ public void setStrokeStyle(Object... styles) {
+ if (styles.length == 0) {
+ // remove stroke
+ setLineColor(null);
+ return;
+ }
+
+ // TODO: handle PaintStyle
+ for (Object st : styles) {
+ if (st instanceof Number) {
+ setLineWidth(((Number)st).doubleValue());
+ } else if (st instanceof LineCap) {
+ setLineCap((LineCap)st);
+ } else if (st instanceof LineDash) {
+ setLineDash((LineDash)st);
+ } else if (st instanceof LineCompound) {
+ setLineCompound((LineCompound)st);
+ } else if (st instanceof Color) {
+ setLineColor((Color)st);
+ }
+ }
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
index cba6f3e614..1d0d854bda 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
@@ -25,9 +25,9 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Notes;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta;
-import org.apache.poi.util.DocumentHelper;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
index c728197083..329ebf8994 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
@@ -22,8 +22,8 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.util.Beta;
-import org.apache.poi.util.DocumentHelper;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
index e6f37386b0..302e064b6a 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
@@ -25,8 +25,8 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.util.Beta;
-import org.apache.poi.util.DocumentHelper;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
index 7469e25d42..b30b3ba269 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
@@ -80,15 +80,22 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this));
}
+ @Override
+ public XSLFTableCell getCell(int row, int col) {
+ return getRows().get(row).getCells().get(col);
+ }
+
@Internal
public CTTable getCTTable(){
return _table;
}
+ @Override
public int getNumberOfColumns() {
return _table.getTblGrid().sizeOfGridColArray();
}
+ @Override
public int getNumberOfRows() {
return _table.sizeOfTrArray();
}
@@ -98,10 +105,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
_table.getTblGrid().getGridColArray(idx).getW());
}
- public void setColumnWidth(int idx, double width){
+ @Override
+ public void setColumnWidth(int idx, double width) {
_table.getTblGrid().getGridColArray(idx).setW(Units.toEMU(width));
}
+ @Override
+ public void setRowHeight(int row, double height) {
+ _table.getTrArray(row).setH(Units.toEMU(height));
+ }
+
public Iterator<XSLFTableRow> iterator(){
return _rows.iterator();
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
index 29f373929e..b5dcc8e0f5 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
@@ -21,6 +21,12 @@ package org.apache.poi.xslf.usermodel;
import java.awt.Color;
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Units;
@@ -44,7 +50,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
* Represents a cell of a table in a .pptx presentation
*/
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> {
- static double defaultBorderWidth = 1.0;
private CTTableCellProperties _tcPr = null;
/*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){
@@ -57,8 +62,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
CTTextBody txBody = cell.getTxBody();
if (txBody == null && create) {
txBody = cell.addNewTxBody();
- txBody.addNewBodyPr();
- txBody.addNewLstStyle();
+ XSLFAutoShape.initTextBody(txBody);
}
return txBody;
}
@@ -83,7 +87,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
return _tcPr;
}
-
+
@Override
public void setLeftInset(double margin){
CTTableCellProperties pr = getCellProperties(true);
@@ -108,67 +112,174 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
pr.setMarB(Units.toEMU(margin));
}
- private CTLineProperties getCTLine(char bltr, boolean create) {
+ private CTLineProperties getCTLine(BorderEdge edge, boolean create) {
+ if (edge == null) {
+ throw new IllegalArgumentException("BorderEdge needs to be specified.");
+ }
+
CTTableCellProperties pr = getCellProperties(create);
if (pr == null) return null;
-
- switch (bltr) {
- case 'b':
+
+ switch (edge) {
+ case bottom:
return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null);
- case 'l':
+ case left:
return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null);
- case 't':
+ case top:
return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null);
- case 'r':
+ case right:
return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null);
default:
return null;
}
}
+
+ @Override
+ public void removeBorder(BorderEdge edge) {
+ CTTableCellProperties pr = getCellProperties(false);
+ if (pr == null) return;
+ switch (edge) {
+ case bottom:
+ if (pr.isSetLnB()) {
+ pr.unsetLnB();
+ }
+ break;
+ case left:
+ if (pr.isSetLnL()) {
+ pr.unsetLnL();
+ }
+ break;
+ case top:
+ if (pr.isSetLnT()) {
+ pr.unsetLnT();
+ }
+ break;
+ case right:
+ if (pr.isSetLnR()) {
+ pr.unsetLnB();
+ }
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public StrokeStyle getBorderStyle(final BorderEdge edge) {
+ final Double width = getBorderWidth(edge);
+ return (width == null) ? null : new StrokeStyle() {
+ public PaintStyle getPaint() {
+ return DrawPaint.createSolidPaint(getBorderColor(edge));
+ }
+
+ public LineCap getLineCap() {
+ return getBorderCap(edge);
+ }
+
+ public LineDash getLineDash() {
+ return getBorderDash(edge);
+ }
+
+ public LineCompound getLineCompound() {
+ return getBorderCompound(edge);
+ }
+
+ public double getLineWidth() {
+ return width;
+ }
+ };
+ }
- private void setBorderWidth(char bltr, double width) {
- CTLineProperties ln = getCTLine(bltr, true);
- ln.setW(Units.toEMU(width));
+ @Override
+ public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
+ if (style == null) {
+ throw new IllegalArgumentException("StrokeStyle needs to be specified.");
+ }
+
+ LineCap cap = style.getLineCap();
+ if (cap != null) {
+ setBorderCap(edge, cap);
+ }
+
+ LineCompound compound = style.getLineCompound();
+ if (compound != null) {
+ setBorderCompound(edge, compound);
+ }
+
+ LineDash dash = style.getLineDash();
+ if (dash != null) {
+ setBorderDash(edge, dash);
+ }
+
+ double width = style.getLineWidth();
+ setBorderWidth(edge, width);
}
- private double getBorderWidth(char bltr) {
- CTLineProperties ln = getCTLine(bltr, false);
- return (ln == null || !ln.isSetW()) ? defaultBorderWidth : Units.toPoints(ln.getW());
+ public Double getBorderWidth(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, false);
+ return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW());
}
- private void setBorderColor(char bltr, Color color) {
- CTLineProperties ln = getCTLine(bltr, true);
+ @Override
+ public void setBorderWidth(BorderEdge edge, double width) {
+ CTLineProperties ln = getCTLine(edge, true);
+ ln.setW(Units.toEMU(width));
+ }
- if(color == null){
- ln.addNewNoFill();
- if(ln.isSetSolidFill()) ln.unsetSolidFill();
- } else {
- if(ln.isSetNoFill()) ln.unsetNoFill();
+ private CTLineProperties setBorderDefaults(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, true);
+ if (ln.isSetNoFill()) {
+ ln.unsetNoFill();
+ }
- if(!ln.isSetPrstDash()) ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
+ if(!ln.isSetPrstDash()) {
+ ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
+ }
+ if (!ln.isSetCmpd()) {
ln.setCmpd(STCompoundLine.SNG);
+ }
+ if (!ln.isSetAlgn()) {
ln.setAlgn(STPenAlignment.CTR);
+ }
+ if (!ln.isSetCap()) {
ln.setCap(STLineCap.FLAT);
+ }
+ if (!ln.isSetRound()) {
ln.addNewRound();
+ }
+ if (!ln.isSetHeadEnd()) {
CTLineEndProperties hd = ln.addNewHeadEnd();
hd.setType(STLineEndType.NONE);
hd.setW(STLineEndWidth.MED);
hd.setLen(STLineEndLength.MED);
+ }
+ if (!ln.isSetTailEnd()) {
CTLineEndProperties tl = ln.addNewTailEnd();
tl.setType(STLineEndType.NONE);
tl.setW(STLineEndWidth.MED);
tl.setLen(STLineEndLength.MED);
+ }
- CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
- rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
- ln.addNewSolidFill().setSrgbClr(rgb);
+ return ln;
+ }
+
+ @Override
+ public void setBorderColor(BorderEdge edge, Color color) {
+ if (color == null) {
+ throw new IllegalArgumentException("Colors need to be specified.");
}
- }
-
- private Color getBorderColor(char bltr) {
- CTLineProperties ln = getCTLine(bltr,false);
+
+ CTLineProperties ln = setBorderDefaults(edge);
+
+ CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
+ rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
+ ln.addNewSolidFill().setSrgbClr(rgb);
+ }
+
+ public Color getBorderColor(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
CTSolidColorFillProperties fill = ln.getSolidFill();
@@ -178,71 +289,65 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
byte[] val = fill.getSrgbClr().getVal();
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
- }
-
- public void setBorderLeft(double width) {
- setBorderWidth('l', width);
}
- public double getBorderLeft() {
- return getBorderWidth('l');
- }
-
- public void setBorderLeftColor(Color color) {
- setBorderColor('l', color);
- }
-
- public Color getBorderLeftColor() {
- return getBorderColor('l');
- }
+ public LineCompound getBorderCompound(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, false);
+ if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) {
+ return null;
+ }
- public void setBorderRight(double width) {
- setBorderWidth('r', width);
+ return LineCompound.fromOoxmlId(ln.getCmpd().intValue());
}
- public double getBorderRight() {
- return getBorderWidth('r');
- }
+ @Override
+ public void setBorderCompound(BorderEdge edge, LineCompound compound) {
+ if (compound == null) {
+ throw new IllegalArgumentException("LineCompound need to be specified.");
+ }
- public void setBorderRightColor(Color color) {
- setBorderColor('r', color);
+ CTLineProperties ln = setBorderDefaults(edge);
+ ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId));
}
- public Color getBorderRightColor() {
- return getBorderColor('r');
- }
+ public LineDash getBorderDash(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, false);
+ if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) {
+ return null;
+ }
- public void setBorderTop(double width) {
- setBorderWidth('t', width);
+ return LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue());
}
- public double getBorderTop() {
- return getBorderWidth('t');
- }
+ @Override
+ public void setBorderDash(BorderEdge edge, LineDash dash) {
+ if (dash == null) {
+ throw new IllegalArgumentException("LineDash need to be specified.");
+ }
- public void setBorderTopColor(Color color) {
- setBorderColor('t', color);
+ CTLineProperties ln = setBorderDefaults(edge);
+ ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
}
- public Color getBorderTopColor() {
- return getBorderColor('t');
+ public LineCap getBorderCap(BorderEdge edge) {
+ CTLineProperties ln = getCTLine(edge, false);
+ if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) {
+ return null;
+ }
+
+ return LineCap.fromOoxmlId(ln.getCap().intValue());
}
- public void setBorderBottom(double width) {
- setBorderWidth('b', width);
- }
+ public void setBorderCap(BorderEdge edge, LineCap cap) {
+ if (cap == null) {
+ throw new IllegalArgumentException("LineCap need to be specified.");
+ }
- public double getBorderBottom() {
- return getBorderWidth('b');
+ CTLineProperties ln = setBorderDefaults(edge);
+ ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
}
- public void setBorderBottomColor(Color color) {
- setBorderColor('b', color);
- }
- public Color getBorderBottomColor(){
- return getBorderColor('b');
- }
/**
* Specifies a solid color fill. The shape is filled entirely with the specified color.
@@ -299,7 +404,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
void setVMerge(boolean merge_) {
((CTTableCell)getXmlObject()).setVMerge(merge_);
}
-
+
@Override
public void setVerticalAlignment(VerticalAlignment anchor){
CTTableCellProperties cellProps = getCellProperties(true);
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
index 65635c4d3c..bb5bd42ae5 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
@@ -54,8 +54,7 @@ public class XSLFTextBox extends XSLFAutoShape
prst.setPrst(STShapeType.RECT);
prst.addNewAvLst();
CTTextBody txBody = ct.addNewTxBody();
- txBody.addNewBodyPr();
- txBody.addNewLstStyle();
+ XSLFAutoShape.initTextBody(txBody);
return ct;
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
index 68d7438d4e..cc12a63426 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
@@ -32,7 +32,26 @@ import org.apache.poi.util.Units;
import org.apache.poi.xslf.model.ParagraphPropertyFetcher;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.*;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextFontAlignType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
@@ -100,6 +119,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
}
+ @Override
public List<XSLFTextRun> getTextRuns(){
return _runs;
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
index fd0f44d75a..8ce7c5241e 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
@@ -206,12 +206,7 @@ public class XSLFTextRun implements TextRun {
}
}
- /**
- * Specifies the typeface, or name of the font that is to be used for this text run.
- *
- * @param typeface the font to apply to this text run.
- * The value of <code>null</code> unsets the Typeface attrubute from the underlying xml.
- */
+ @Override
public void setFontFamily(String typeface){
setFontFamily(typeface, (byte)-1, (byte)-1, false);
}
@@ -236,9 +231,7 @@ public class XSLFTextRun implements TextRun {
}
}
- /**
- * @return font family or null if not set
- */
+ @Override
public String getFontFamily(){
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
@@ -281,18 +274,12 @@ public class XSLFTextRun implements TextRun {
return visitor.getValue() == null ? 0 : visitor.getValue();
}
- /**
- * Specifies whether a run of text will be formatted as strikethrough text.
- *
- * @param strike whether a run of text will be formatted as strikethrough text.
- */
+ @Override
public void setStrikethrough(boolean strike) {
getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
}
- /**
- * @return whether a run of text will be formatted as strikethrough text. Default is false.
- */
+ @Override
public boolean isStrikethrough() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -307,9 +294,7 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue();
}
- /**
- * @return whether a run of text will be formatted as a superscript text. Default is false.
- */
+ @Override
public boolean isSuperscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -357,9 +342,7 @@ public class XSLFTextRun implements TextRun {
setBaselineOffset(flag ? -25.0 : 0.);
}
- /**
- * @return whether a run of text will be formatted as a superscript text. Default is false.
- */
+ @Override
public boolean isSubscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -392,18 +375,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? TextCap.NONE : fetcher.getValue();
}
- /**
- * Specifies whether this run of text will be formatted as bold text
- *
- * @param bold whether this run of text will be formatted as bold text
- */
+ @Override
public void setBold(boolean bold){
getRPr().setB(bold);
}
- /**
- * @return whether this run of text is formatted as bold text
- */
+ @Override
public boolean isBold(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -418,16 +395,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue();
}
- /**
- * @param italic whether this run of text is formatted as italic text
- */
+ @Override
public void setItalic(boolean italic){
getRPr().setI(italic);
}
- /**
- * @return whether this run of text is formatted as italic text
- */
+ @Override
public boolean isItalic(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -442,16 +415,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue();
}
- /**
- * @param underline whether this run of text is formatted as underlined text
- */
- public void setUnderline(boolean underline) {
+ @Override
+ public void setUnderlined(boolean underline) {
getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
}
- /**
- * @return whether this run of text is formatted as underlined text
- */
+ @Override
public boolean isUnderlined(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -501,6 +470,7 @@ public class XSLFTextRun implements TextRun {
CTPlaceholder ph = shape.getCTPlaceholder();
if (ph == null){
// if it is a plain text box then take defaults from presentation.xml
+ @SuppressWarnings("resource")
XMLSlideShow ppt = sheet.getSlideShow();
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
if (themeProps != null) {
@@ -543,7 +513,7 @@ public class XSLFTextRun implements TextRun {
if(italic != isItalic()) setItalic(italic);
boolean underline = r.isUnderlined();
- if(underline != isUnderlined()) setUnderline(underline);
+ if(underline != isUnderlined()) setUnderlined(underline);
boolean strike = r.isStrikethrough();
if(strike != isStrikethrough()) setStrikethrough(strike);
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
index 8cc90f979f..8a4a935209 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
@@ -37,8 +37,10 @@ import org.apache.poi.xslf.model.TextBodyPropertyFetcher;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
@@ -91,10 +93,52 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
txBody.setPArray(null); // remove any existing paragraphs
}
- public void setText(String text){
- clearText();
+ @Override
+ public XSLFTextRun setText(String text) {
+ // copy properties from first paragraph / textrun
+ CTTextParagraphProperties pPr = null;
+ CTTextCharacterProperties rPr = null;
+ if (!_paragraphs.isEmpty()) {
+ XSLFTextParagraph p0 = _paragraphs.get(0);
+ pPr = p0.getXmlObject().getPPr();
+ if (!p0.getTextRuns().isEmpty()) {
+ XSLFTextRun r0 = p0.getTextRuns().get(0);
+ rPr = r0.getXmlObject().getRPr();
+ }
+ }
- addNewTextParagraph().addNewTextRun().setText(text);
+ // can't call clearText otherwise we receive a XmlValueDisconnectedException
+ _paragraphs.clear();
+ CTTextBody txBody = getTextBody(true);
+ int cntPs = txBody.sizeOfPArray();
+
+ // split text by paragraph and new line char
+ XSLFTextRun r = null;
+ for (String paraText : text.split("\\r\\n?|\\n")) {
+ XSLFTextParagraph para = addNewTextParagraph();
+ if (pPr != null) {
+ para.getXmlObject().setPPr(pPr);
+ }
+ boolean first = true;
+ for (String runText : paraText.split("[\u000b]")) {
+ if (!first) {
+ para.addLineBreak();
+ }
+ r = para.addNewTextRun();
+ r.setText(runText);
+ if (rPr != null) {
+ r.getXmlObject().setRPr(rPr);
+ }
+ first = false;
+ }
+ }
+
+ // simply setting a new pArray leads to XmlValueDisconnectedException
+ for (int i = cntPs-1; i >= 0; i--) {
+ txBody.removeP(i);
+ }
+
+ return r;
}
@Override
@@ -115,13 +159,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return paragraph;
}
-
- /**
- * Sets the type of vertical alignment for the text.
- *
- * @param anchor - the type of alignment.
- * A {@code null} values unsets this property.
- */
+ @Override
public void setVerticalAlignment(VerticalAlignment anchor){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
@@ -133,11 +171,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
}
- /**
- * Returns the type of vertical alignment for the text.
- *
- * @return the type of vertical alignment
- */
+ @Override
public VerticalAlignment getVerticalAlignment(){
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
public boolean fetch(CTTextBodyProperties props){
@@ -153,14 +187,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue();
}
- /**
- * Sets if the paragraphs are horizontal centered
- *
- * @param isCentered true, if the paragraphs are horizontal centered
- * A {@code null} values unsets this property.
- *
- * @see TextShape#isHorizontalCentered()
- */
+ @Override
public void setHorizontalCentered(Boolean isCentered){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
@@ -369,10 +396,15 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return insets;
}
-
- /**
- * @return whether to wrap words within the bounding rectangle
- */
+ @Override
+ public void setInsets(Insets2D insets) {
+ setTopInset(insets.top);
+ setLeftInset(insets.left);
+ setBottomInset(insets.bottom);
+ setRightInset(insets.right);
+ }
+
+ @Override
public boolean getWordWrap(){
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
public boolean fetch(CTTextBodyProperties props){
@@ -387,10 +419,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return fetcher.getValue() == null ? true : fetcher.getValue();
}
- /**
- *
- * @param wrap whether to wrap words within the bounding rectangle
- */
+ @Override
public void setWordWrap(boolean wrap){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
@@ -532,4 +561,45 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
tgtP.copy(srcP);
}
}
+
+ @Override
+ public void setTextPlaceholder(TextPlaceholder placeholder) {
+ switch (placeholder) {
+ default:
+ case NOTES:
+ case HALF_BODY:
+ case QUARTER_BODY:
+ case BODY:
+ setPlaceholder(Placeholder.BODY);
+ break;
+ case TITLE:
+ setPlaceholder(Placeholder.TITLE);
+ break;
+ case CENTER_BODY:
+ setPlaceholder(Placeholder.BODY);
+ setHorizontalCentered(true);
+ break;
+ case CENTER_TITLE:
+ setPlaceholder(Placeholder.CENTERED_TITLE);
+ break;
+ case OTHER:
+ setPlaceholder(Placeholder.CONTENT);
+ break;
+ }
+ }
+
+ @Override
+ public TextPlaceholder getTextPlaceholder() {
+ Placeholder ph = getTextType();
+ if (ph == null) return TextPlaceholder.BODY;
+ switch (ph) {
+ case BODY: return TextPlaceholder.BODY;
+ case TITLE: return TextPlaceholder.TITLE;
+ case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE;
+ default:
+ case CONTENT: return TextPlaceholder.OTHER;
+ }
+ }
+
+
} \ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
index 3350149751..525f55ef7b 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
@@ -268,7 +268,7 @@ public class TestXSLFAutoShape {
assertFalse(r.isUnderlined());
assertFalse(r.getXmlObject().getRPr().isSetU());
- r.setUnderline(true);
+ r.setUnderlined(true);
assertTrue(r.isUnderlined());
assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU());
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
index 0eb075acaf..02fac93bc8 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
@@ -20,13 +20,16 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import java.io.IOException;
+
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test;
public class TestXSLFNotes {
@Test
- public void createNewNote() {
+ public void createNewNote() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide1 = ppt.createSlide();
@@ -48,10 +51,12 @@ public class TestXSLFNotes {
}
assertNotNull(note);
assertEquals("New Note", note);
+
+ ppt.close();
}
@Test
- public void addNote() {
+ public void addNote() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx");
@@ -69,10 +74,12 @@ public class TestXSLFNotes {
}
assertNotNull(note);
assertEquals("New Note", note);
+
+ ppt.close();
}
@Test
- public void replaceNotes() {
+ public void replaceNotes() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx");
@@ -93,5 +100,7 @@ public class TestXSLFNotes {
assertNotNull(note);
assertEquals("New Note", note);
}
+
+ ppt.close();
}
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
index db2c9833f7..452f22ebcb 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
@@ -28,6 +28,7 @@ import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.draw.geom.TestPresetGeometries;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Units;
@@ -168,7 +169,7 @@ public class TestXSLFSimpleShape {
}
@Test
- public void testDefaultProperties() {
+ public void testDefaultProperties() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
XSLFSlide slide6 = ppt.getSlides().get(5);
@@ -234,10 +235,12 @@ public class TestXSLFSimpleShape {
assertEquals(50000, ref5.getLumModArray(0).getVal());
assertEquals("accent1", ref5.getVal().toString());
assertEquals(new Color(79, 129, 189), s5.getFillColor());
+
+ ppt.close();
}
@Test
- public void testAnchor(){
+ public void testAnchor() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
List<XSLFSlide> slide = ppt.getSlides();
@@ -267,6 +270,7 @@ public class TestXSLFSimpleShape {
assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm());
assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor());
+ ppt.close();
}
@SuppressWarnings({ "deprecation", "unused" })
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
index 3b7c5cbcc2..cf535b5650 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
@@ -16,23 +16,29 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import java.awt.Color;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
-import java.awt.Color;
-import java.util.List;
-
/**
* @author Yegor Kozlov
*/
public class TestXSLFTable {
@Test
- public void testRead(){
+ public void testRead() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
XSLFSlide slide = ppt.getSlides().get(3);
@@ -69,10 +75,12 @@ public class TestXSLFTable {
assertEquals("A1", cells1.get(0).getText());
assertEquals("B1", cells1.get(1).getText());
assertEquals("C1", cells1.get(2).getText());
+
+ ppt.close();
}
@Test
- public void testCreate() {
+ public void testCreate() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
@@ -121,38 +129,21 @@ public class TestXSLFTable {
cell1.addNewTextParagraph().addNewTextRun().setText("Apache");
assertEquals("Apache", cell1.getText());
- assertEquals(1.0, cell1.getBorderBottom(), 0);
- cell1.setBorderBottom(2.0);
- assertEquals(2.0, cell1.getBorderBottom(), 0);
- assertNull(cell1.getBorderBottomColor());
- cell1.setBorderBottomColor(Color.yellow);
- assertEquals(Color.yellow, cell1.getBorderBottomColor());
-
- assertEquals(1.0, cell1.getBorderTop(), 0);
- cell1.setBorderTop(2.0);
- assertEquals(2.0, cell1.getBorderTop(), 0);
- assertNull(cell1.getBorderTopColor());
- cell1.setBorderTopColor(Color.yellow);
- assertEquals(Color.yellow, cell1.getBorderTopColor());
-
- assertEquals(1.0, cell1.getBorderLeft(), 0);
- cell1.setBorderLeft(2.0);
- assertEquals(2.0, cell1.getBorderLeft(), 0);
- assertNull(cell1.getBorderLeftColor());
- cell1.setBorderLeftColor(Color.yellow);
- assertEquals(Color.yellow, cell1.getBorderLeftColor());
-
- assertEquals(1.0, cell1.getBorderRight(), 0);
- cell1.setBorderRight(2.0);
- assertEquals(2.0, cell1.getBorderRight(), 0);
- assertNull(cell1.getBorderRightColor());
- cell1.setBorderRightColor(Color.yellow);
- assertEquals(Color.yellow, cell1.getBorderRightColor());
+ for (BorderEdge edge : BorderEdge.values()) {
+ assertNull(cell1.getBorderWidth(edge));
+ cell1.setBorderWidth(edge, 2.0);
+ assertEquals(2.0, cell1.getBorderWidth(edge), 0);
+ assertNull(cell1.getBorderColor(edge));
+ cell1.setBorderColor(edge, Color.yellow);
+ assertEquals(Color.yellow, cell1.getBorderColor(edge));
+ }
assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment());
cell1.setVerticalAlignment(VerticalAlignment.MIDDLE);
assertEquals(VerticalAlignment.MIDDLE, cell1.getVerticalAlignment());
cell1.setVerticalAlignment(null);
assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment());
+
+ ppt.close();
}
} \ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
index 59b0dca95c..cee11e541a 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
@@ -19,6 +19,9 @@ package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import java.io.IOException;
+
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
@@ -28,7 +31,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties
public class TestXSLFTextBox {
@Test
- public void testPlaceholder() {
+ public void testPlaceholder() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
@@ -39,13 +42,15 @@ public class TestXSLFTextBox {
shape.setPlaceholder(null);
assertNull(shape.getTextType());
shape.setText("Apache POI");
+
+ ppt.close();
}
/**
* text box inherits default text proeprties from presentation.xml
*/
@Test
- public void testDefaultTextStyle() {
+ public void testDefaultTextStyle() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
@@ -79,5 +84,7 @@ public class TestXSLFTextBox {
pPr.unsetSz(); // Should never be
assertNull(r.getFontSize());
+
+ ppt.close();
}
} \ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
index e0c4f9dd96..18632ffbf0 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
@@ -28,6 +28,7 @@ import java.awt.Color;
import java.io.IOException;
import java.util.List;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples;
@@ -45,7 +46,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
public class TestXSLFTextShape {
@Test
- public void testLayouts(){
+ public void testLayouts() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx");
List<XSLFSlide> slide = ppt.getSlides();
@@ -57,6 +58,8 @@ public class TestXSLFTextShape {
verifySlide7(slide.get(6));
verifySlide8(slide.get(7));
verifySlide10(slide.get(9));
+
+ ppt.close();
}
void verifySlide1(XSLFSlide slide){
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 834dea5ff0..0022822b82 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
@@ -297,7 +297,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
txt.setTopInset(0);
txt.setLeftInset(0);
txt.setRightInset(0);
- txt.setWordWrap(HSLFTextBox.WrapNone);
+ txt.setWordWrap(false);
txt.setHorizontalCentered(false);
txt.setVerticalAlignment(VerticalAlignment.MIDDLE);
@@ -1826,7 +1826,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
float[] dash = bs.getDashArray();
if (dash != null) {
//TODO: implement more dashing styles
- shape.setLineDashing(StrokeStyle.LineDash.DASH);
+ shape.setLineDash(StrokeStyle.LineDash.DASH);
}
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java b/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
deleted file mode 100644
index 1e632b8dcc..0000000000
--- a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hslf.model;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.OEPlaceholderAtom;
-import org.apache.poi.hslf.usermodel.HSLFShape;
-import org.apache.poi.hslf.usermodel.HSLFTextBox;
-import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
-import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-
-import java.io.ByteArrayOutputStream;
-
-/**
- * Represents a Placeholder in PowerPoint.
- *
- * @author Yegor Kozlov
- */
-public final class Placeholder extends HSLFTextBox {
-
- protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
- super(escherRecord, parent);
- }
-
- public Placeholder(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
- super(parent);
- }
-
- public Placeholder(){
- super();
- }
-
- /**
- * Create a new Placeholder and initialize internal structures
- *
- * @return the created <code>EscherContainerRecord</code> which holds shape data
- */
- protected EscherContainerRecord createSpContainer(boolean isChild){
- _escherContainer = super.createSpContainer(isChild);
-
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
- spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER);
-
- EscherClientDataRecord cldata = new EscherClientDataRecord();
- cldata.setOptions((short)15);
-
- AbstractEscherOptRecord opt = getEscherOptRecord();
-
- //Placeholders can't be grouped
- setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
-
- //OEPlaceholderAtom tells powerpoint that this shape is a placeholder
- //
- OEPlaceholderAtom oep = new OEPlaceholderAtom();
- /**
- * Extarct from MSDN:
- *
- * There is a special case when the placeholder does not have a position in the layout.
- * This occurs when the user has moved the placeholder from its original position.
- * In this case the placeholder ID is -1.
- */
- oep.setPlacementId(-1);
-
- oep.setPlaceholderId(OEPlaceholderAtom.Body);
-
- //convert hslf into ddf record
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try {
- oep.writeOut(out);
- } catch(Exception e){
- throw new HSLFException(e);
- }
- cldata.setRemainingData(out.toByteArray());
-
- //append placeholder container before EscherTextboxRecord
- _escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
-
- return _escherContainer;
- }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
index 21c07010ca..329f78f423 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
@@ -67,7 +67,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
setVerticalAlignment(VerticalAlignment.MIDDLE);
setHorizontalCentered(true);
- setWordWrap(HSLFTextBox.WrapNone);
+ setWordWrap(false);
}
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
index 22317fb62a..bbfe93f97c 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
@@ -43,7 +43,6 @@ import org.apache.poi.util.Units;
*/
public class HSLFGroupShape extends HSLFShape
implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
-
/**
* Create a new ShapeGroup. This constructor is used when a new shape is created.
*
@@ -73,34 +72,16 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
super(escherRecord, parent);
}
- /**
- * Sets the anchor (the bounding box rectangle) of this shape.
- * All coordinates should be expressed in Master units (576 dpi).
- *
- * @param anchor new anchor
- */
- public void setAnchor(java.awt.Rectangle anchor){
-
+ @Override
+ public void setAnchor(Rectangle anchor) {
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- //hack. internal variable EscherClientAnchorRecord.shortRecord can be
- //initialized only in fillFields(). We need to set shortRecord=false;
- byte[] header = new byte[16];
- LittleEndian.putUShort(header, 0, 0);
- LittleEndian.putUShort(header, 2, 0);
- LittleEndian.putInt(header, 4, 8);
- clientAnchor.fillFields(header, 0, null);
-
- clientAnchor.setFlag((short)Units.pointsToMaster(anchor.y));
- clientAnchor.setCol1((short)Units.pointsToMaster(anchor.x));
- clientAnchor.setDx1((short)Units.pointsToMaster(anchor.width + anchor.x));
- clientAnchor.setRow1((short)Units.pointsToMaster(anchor.height + anchor.y));
-
- EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
- spgr.setRectX1(Units.pointsToMaster(anchor.x));
- spgr.setRectY1(Units.pointsToMaster(anchor.y));
- spgr.setRectX2(Units.pointsToMaster(anchor.x + anchor.width));
- spgr.setRectY2(Units.pointsToMaster(anchor.y + anchor.height));
+ boolean isInitialized = !(clientAnchor.getDx1() == 0 && clientAnchor.getRow1() == 0);
+
+ if (isInitialized) {
+ moveAndScale(anchor);
+ } else {
+ setExteriorAnchor(anchor);
+ }
}
@Override
@@ -116,7 +97,6 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
spgr.setRectY1(y1);
spgr.setRectX2(x2);
spgr.setRectY2(y2);
-
}
@Override
@@ -129,6 +109,27 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
return new Rectangle(x1,y1,x2-x1,y2-y1);
}
+ protected void setExteriorAnchor(Rectangle anchor) {
+ EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+
+ //hack. internal variable EscherClientAnchorRecord.shortRecord can be
+ //initialized only in fillFields(). We need to set shortRecord=false;
+ byte[] header = new byte[16];
+ LittleEndian.putUShort(header, 0, 0);
+ LittleEndian.putUShort(header, 2, 0);
+ LittleEndian.putInt(header, 4, 8);
+ clientAnchor.fillFields(header, 0, null);
+
+ // All coordinates need to be converted to Master units (576 dpi)
+ clientAnchor.setFlag((short)Units.pointsToMaster(anchor.y));
+ clientAnchor.setCol1((short)Units.pointsToMaster(anchor.x));
+ clientAnchor.setDx1((short)Units.pointsToMaster(anchor.width + anchor.x));
+ clientAnchor.setRow1((short)Units.pointsToMaster(anchor.height + anchor.y));
+
+ // TODO: does this make sense?
+ setInteriorAnchor(anchor);
+ }
+
/**
* Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
*/
@@ -174,23 +175,22 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
}
/**
- * Moves this <code>ShapeGroup</code> to the specified location.
- * <p>
- * @param x the x coordinate of the top left corner of the shape in new location
- * @param y the y coordinate of the top left corner of the shape in new location
+ * Moves and scales this <code>ShapeGroup</code> to the specified anchor.
*/
- public void moveTo(int x, int y){
- Rectangle anchor = getAnchor();
- int dx = x - anchor.x;
- int dy = y - anchor.y;
- anchor.translate(dx, dy);
- setAnchor(anchor);
+ protected void moveAndScale(Rectangle anchorDest){
+ Rectangle anchorSrc = getAnchor();
+ double scaleX = (anchorSrc.width == 0) ? 0 : anchorDest.width / (double)anchorSrc.width;
+ double scaleY = (anchorSrc.height == 0) ? 0 : anchorDest.height / (double)anchorSrc.height;
+ setExteriorAnchor(anchorDest);
for (HSLFShape shape : getShapes()) {
Rectangle chanchor = shape.getAnchor();
- chanchor.translate(dx, dy);
- shape.setAnchor(chanchor);
+ int x = (int)Math.rint(anchorDest.x+(chanchor.x-anchorSrc.x)*scaleX);
+ int y = (int)Math.rint(anchorDest.y+(chanchor.y-anchorSrc.y)*scaleY);
+ int width = (int)Math.rint(chanchor.width*scaleX);
+ int height = (int)Math.rint(chanchor.height*scaleY);
+ shape.setAnchor(new Rectangle(x, y, width, height));
}
}
@@ -262,9 +262,6 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
throw new UnsupportedOperationException();
}
- /**
- * @return the shapes contained in this group container
- */
@Override
public List<HSLFShape> getShapes() {
// Out escher container record should contain several
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java
new file mode 100644
index 0000000000..c0a7aef69e
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java
@@ -0,0 +1,55 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hslf.usermodel;
+
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+
+/**
+ * Represents a Placeholder in PowerPoint.
+ *
+ * @author Yegor Kozlov
+ */
+public final class HSLFPlaceholder extends HSLFTextBox {
+
+ protected HSLFPlaceholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
+ super(escherRecord, parent);
+ }
+
+ public HSLFPlaceholder(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
+ super(parent);
+ }
+
+ public HSLFPlaceholder(){
+ super();
+ }
+
+ /**
+ * Create a new Placeholder and initialize internal structures
+ *
+ * @return the created <code>EscherContainerRecord</code> which holds shape data
+ */
+ protected EscherContainerRecord createSpContainer(boolean isChild){
+ _escherContainer = super.createSpContainer(isChild);
+
+ setPlaceholder(Placeholder.BODY);
+
+ return _escherContainer;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
index 85f3a906ea..81679c02df 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
@@ -116,19 +116,11 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
return getShapeType().nativeName;
}
- /**
- * @return type of the shape.
- * @see org.apache.poi.hslf.record.RecordTypes
- */
public ShapeType getShapeType(){
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
return ShapeType.forId(spRecord.getShapeType(), false);
}
- /**
- * @param type type of the shape.
- * @see org.apache.poi.hslf.record.RecordTypes
- */
public void setShapeType(ShapeType type){
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
spRecord.setShapeType( (short) type.nativeId );
@@ -209,7 +201,9 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
* @param x the x coordinate of the top left corner of the shape
* @param y the y coordinate of the top left corner of the shape
*/
- public void moveTo(float x, float y){
+ public final void moveTo(float x, float y) {
+ // This convenience method should be implemented via setAnchor in subclasses
+ // see HSLFGroupShape.setAnchor() for a reference
Rectangle anchor = getAnchor();
anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
setAnchor(anchor);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
index f2aac4da25..4fe197782e 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
@@ -56,7 +56,7 @@ public final class HSLFShapeFactory {
EscherPropertyFactory f = new EscherPropertyFactory();
List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
for (EscherProperty ep : props) {
- if (ep.getPropertyNumber() == 0x39F
+ if (ep.getPropertyNumber() == EscherProperties.GROUPSHAPE__TABLEPROPERTIES
&& ep instanceof EscherSimpleProperty
&& ((EscherSimpleProperty)ep).getPropertyValue() == 1) {
isTable = true;
@@ -65,9 +65,13 @@ public final class HSLFShapeFactory {
}
}
- HSLFGroupShape group = (isTable)
- ? new HSLFTable(spContainer, parent)
- : new HSLFGroupShape(spContainer, parent);
+ HSLFGroupShape group;
+ if (isTable) {
+ group = new HSLFTable(spContainer, parent);
+
+ } else {
+ group = new HSLFGroupShape(spContainer, parent);
+ }
return group;
}
@@ -82,65 +86,73 @@ public final class HSLFShapeFactory {
shape = new HSLFTextBox(spContainer, parent);
break;
case HOST_CONTROL:
- case FRAME: {
- InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
- OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
- if(info != null && info.getInteractiveInfoAtom() != null){
- switch(info.getInteractiveInfoAtom().getAction()){
- case InteractiveInfoAtom.ACTION_OLE:
- shape = new OLEShape(spContainer, parent);
- break;
- case InteractiveInfoAtom.ACTION_MEDIA:
- shape = new MovieShape(spContainer, parent);
- break;
- default:
- break;
- }
- } else if (oes != null){
- shape = new OLEShape(spContainer, parent);
- }
-
- if(shape == null) shape = new HSLFPictureShape(spContainer, parent);
+ case FRAME:
+ shape = createFrame(spContainer, parent);
break;
- }
case LINE:
shape = new HSLFLine(spContainer, parent);
break;
- case NOT_PRIMITIVE: {
- AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
- EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
- if(prop != null)
- shape = new HSLFFreeformShape(spContainer, parent);
- else {
- logger.log(POILogger.INFO, "Creating AutoShape for a NotPrimitive shape");
- shape = new HSLFAutoShape(spContainer, parent);
- }
+ case NOT_PRIMITIVE:
+ shape = createNonPrimitive(spContainer, parent);
break;
- }
default:
- shape = new HSLFAutoShape(spContainer, parent);
+ EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID);
+ if (parent instanceof HSLFTable && etr != null) {
+ shape = new HSLFTableCell(spContainer, (HSLFTable)parent);
+ } else {
+ shape = new HSLFAutoShape(spContainer, parent);
+ }
break;
}
return shape;
-
}
+ private static HSLFShape createFrame(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
+ InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
+ if(info != null && info.getInteractiveInfoAtom() != null){
+ switch(info.getInteractiveInfoAtom().getAction()){
+ case InteractiveInfoAtom.ACTION_OLE:
+ return new OLEShape(spContainer, parent);
+ case InteractiveInfoAtom.ACTION_MEDIA:
+ return new MovieShape(spContainer, parent);
+ default:
+ break;
+ }
+ }
+
+ OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
+ if (oes != null){
+ return new OLEShape(spContainer, parent);
+ }
+
+ return new HSLFPictureShape(spContainer, parent);
+ }
+
+ private static HSLFShape createNonPrimitive(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
+ AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
+ EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
+ if(prop != null) {
+ return new HSLFFreeformShape(spContainer, parent);
+ }
+
+ logger.log(POILogger.INFO, "Creating AutoShape for a NotPrimitive shape");
+ return new HSLFAutoShape(spContainer, parent);
+ }
+
@SuppressWarnings("unchecked")
protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
- Record oep = null;
for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
EscherRecord obj = it.next();
if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
byte[] data = obj.serialize();
- Record[] records = Record.findChildRecords(data, 8, data.length - 8);
- for (int j = 0; j < records.length; j++) {
- if (records[j].getRecordType() == recordType) {
- return (T)records[j];
+ for (Record r : Record.findChildRecords(data, 8, data.length - 8)) {
+ if (r.getRecordType() == recordType) {
+ return (T)r;
}
}
}
}
- return (T)oep;
+ return null;
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
index 139840c548..1a46a5e175 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
@@ -458,7 +458,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
throw new IllegalArgumentException("numRows and numCols must be greater than 0");
}
HSLFTable s = new HSLFTable(numRows,numCols);
- s.setAnchor(new Rectangle(0, 0, 100, 100));
+ // anchor is set in constructor based on numRows/numCols
addShape(s);
return s;
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
index d75aebf007..74761e49ca 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
@@ -27,6 +27,7 @@ import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.draw.geom.*;
import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.LittleEndian;
@@ -147,11 +148,32 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
}
/**
+ * Gets line cap.
+ *
+ * @return cap of the line.
+ */
+ public LineCap getLineCap(){
+ AbstractEscherOptRecord opt = getEscherOptRecord();
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE);
+ return (prop == null) ? LineCap.FLAT : LineCap.fromNativeId(prop.getPropertyValue());
+ }
+
+ /**
+ * Sets line cap.
+ *
+ * @param pen new style of the line.
+ */
+ public void setLineCap(LineCap pen){
+ AbstractEscherOptRecord opt = getEscherOptRecord();
+ setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId);
+ }
+
+ /**
* Gets line dashing.
*
* @return dashing of the line.
*/
- public LineDash getLineDashing(){
+ public LineDash getLineDash(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue());
@@ -162,7 +184,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
*
* @param pen new style of the line.
*/
- public void setLineDashing(LineDash pen){
+ public void setLineDash(LineDash pen){
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId);
}
@@ -177,7 +199,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE);
return (prop == null) ? LineCompound.SINGLE : LineCompound.fromNativeId(prop.getPropertyValue());
}
-
+
/**
* Sets the line compound style
*
@@ -204,7 +226,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
}
public LineDash getLineDash() {
- return HSLFSimpleShape.this.getLineDashing();
+ return HSLFSimpleShape.this.getLineDash();
}
public LineCompound getLineCompound() {
@@ -214,23 +236,17 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public double getLineWidth() {
return HSLFSimpleShape.this.getLineWidth();
}
-
+
};
}
- /**
- * The color used to fill this shape.
- */
- public Color getFillColor(){
+ @Override
+ public Color getFillColor() {
return getFill().getForegroundColor();
}
- /**
- * The color used to fill this shape.
- *
- * @param color the background color
- */
- public void setFillColor(Color color){
+ @Override
+ public void setFillColor(Color color) {
getFill().setForegroundColor(color);
}
@@ -353,10 +369,10 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
if (name == null || !name.matches("adj([1-9]|10)?")) {
throw new IllegalArgumentException("Adjust value '"+name+"' not supported.");
}
-
+
name = name.replace("adj", "");
if ("".equals(name)) name = "1";
-
+
short escherProp;
switch (Integer.parseInt(name)) {
case 1: escherProp = EscherProperties.GEOMETRY__ADJUSTVALUE; break;
@@ -371,7 +387,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
case 10: escherProp = EscherProperties.GEOMETRY__ADJUST10VALUE; break;
default: throw new RuntimeException();
}
-
+
int adjval = getEscherProperty(escherProp, -1);
return (adjval == -1) ? null : new Guide(name, "val "+adjval);
}
@@ -386,7 +402,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
logger.log(POILogger.WARN, "No preset shape definition for shapeType: "+name);
return null;
}
-
+
return geom;
}
@@ -399,7 +415,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
int offY = (prop == null) ? 0 : prop.getPropertyValue();
return Math.toDegrees(Math.atan2(offY, offX));
}
-
+
public double getShadowDistance() {
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX);
@@ -415,13 +431,13 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public Color getShadowColor(){
Color clr = getColor(EscherProperties.SHADOWSTYLE__COLOR, EscherProperties.SHADOWSTYLE__OPACITY, -1);
return clr == null ? Color.black : clr;
- }
-
+ }
+
public Shadow<HSLFShape,HSLFTextParagraph> getShadow() {
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE);
if (shadowType == null) return null;
-
+
return new Shadow<HSLFShape,HSLFTextParagraph>(){
public SimpleShape<HSLFShape,HSLFTextParagraph> getShadowParent() {
return HSLFSimpleShape.this;
@@ -443,7 +459,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public SolidPaint getFillStyle() {
return DrawPaint.createSolidPaint(getShadowColor());
}
-
+
};
}
@@ -475,4 +491,123 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
}
};
}
-}
+
+ protected void setPlaceholder(Placeholder placeholder) {
+ EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ int flags = spRecord.getFlags();
+ flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
+ spRecord.setFlags(flags);
+
+ EscherClientDataRecord cldata = _escherContainer.getChildById(EscherClientDataRecord.RECORD_ID);
+ if (cldata == null) {
+ cldata = new EscherClientDataRecord();
+ // append placeholder container before EscherTextboxRecord
+ _escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
+ }
+ cldata.setOptions((short)15);
+
+ AbstractEscherOptRecord opt = getEscherOptRecord();
+
+ // Placeholders can't be grouped
+ setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
+
+ // OEPlaceholderAtom tells powerpoint that this shape is a placeholder
+ OEPlaceholderAtom oep = new OEPlaceholderAtom();
+
+ /**
+ * Extarct from MSDN:
+ *
+ * There is a special case when the placeholder does not have a position in the layout.
+ * This occurs when the user has moved the placeholder from its original position.
+ * In this case the placeholder ID is -1.
+ */
+ oep.setPlacementId(-1);
+
+ boolean isMaster = (getSheet() instanceof HSLFSlideMaster);
+ boolean isNotes = (getSheet() instanceof HSLFNotes);
+ byte phId;
+ switch (placeholder) {
+ case TITLE:
+ phId = (isMaster) ? OEPlaceholderAtom.MasterTitle : OEPlaceholderAtom.Title;
+ break;
+ case BODY:
+ phId = (isMaster) ? OEPlaceholderAtom.MasterBody :
+ ((isNotes) ? OEPlaceholderAtom.NotesBody : OEPlaceholderAtom.Body);
+ break;
+ case CENTERED_TITLE:
+ phId = (isMaster) ? OEPlaceholderAtom.MasterCenteredTitle : OEPlaceholderAtom.CenteredTitle;
+ break;
+ case SUBTITLE:
+ phId = (isMaster) ? OEPlaceholderAtom.MasterSubTitle : OEPlaceholderAtom.Subtitle;
+ break;
+ case DATETIME:
+ phId = OEPlaceholderAtom.MasterDate;
+ break;
+ case SLIDE_NUMBER:
+ phId = OEPlaceholderAtom.MasterSlideNumber;
+ break;
+ case FOOTER:
+ phId = OEPlaceholderAtom.MasterFooter;
+ break;
+ case HEADER:
+ phId = OEPlaceholderAtom.MasterHeader;
+ break;
+ case DGM:
+ case CHART:
+ phId = OEPlaceholderAtom.Graph;
+ break;
+ case TABLE:
+ phId = OEPlaceholderAtom.Table;
+ break;
+ case PICTURE:
+ case CLIP_ART:
+ phId = OEPlaceholderAtom.ClipArt;
+ break;
+ case MEDIA:
+ phId = OEPlaceholderAtom.MediaClip;
+ break;
+ case SLIDE_IMAGE:
+ phId = (isMaster) ? OEPlaceholderAtom.MasterNotesSlideImage : OEPlaceholderAtom.NotesSlideImage;
+ break;
+ default:
+ case CONTENT:
+ phId = OEPlaceholderAtom.Object;
+ break;
+ }
+ oep.setPlaceholderId(phId);
+
+ //convert hslf into ddf record
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ oep.writeOut(out);
+ } catch(Exception e){
+ throw new HSLFException(e);
+ }
+ cldata.setRemainingData(out.toByteArray());
+ }
+
+
+ @Override
+ public void setStrokeStyle(Object... styles) {
+ if (styles.length == 0) {
+ // remove stroke
+ setLineColor(null);
+ return;
+ }
+
+ // TODO: handle PaintStyle
+ for (Object st : styles) {
+ if (st instanceof Number) {
+ setLineWidth(((Number)st).doubleValue());
+ } else if (st instanceof LineCap) {
+ setLineCap((LineCap)st);
+ } else if (st instanceof LineDash) {
+ setLineDash((LineDash)st);
+ } else if (st instanceof LineCompound) {
+ setLineCompound((LineCompound)st);
+ } else if (st instanceof Color) {
+ setLineColor((Color)st);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
index b4dd77144f..8e94421c5d 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
@@ -27,7 +27,6 @@ import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hslf.model.Comment;
import org.apache.poi.hslf.model.HeadersFooters;
-import org.apache.poi.hslf.model.Placeholder;
import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.Comment2000;
import org.apache.poi.hslf.record.EscherTextboxWrapper;
@@ -196,7 +195,7 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTe
* @return <code>TextBox</code> object that represents the slide's title.
*/
public HSLFTextBox addTitle() {
- Placeholder pl = new Placeholder();
+ HSLFPlaceholder pl = new HSLFPlaceholder();
pl.setShapeType(ShapeType.RECT);
pl.setRunType(TextHeaderAtom.TITLE_TYPE);
pl.setText("Click to edit title");
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
index 7064a862bf..46a356fec9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
@@ -531,9 +531,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
return HSLFSoundData.find(_documentRecord);
}
- /**
- * Return the current page size
- */
+ @Override
public Dimension getPageSize() {
DocumentAtom docatom = _documentRecord.getDocumentAtom();
int pgx = (int)Units.masterToPoints((int)docatom.getSlideSizeX());
@@ -541,12 +539,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
return new Dimension(pgx, pgy);
}
- /**
- * Change the current page size
- *
- * @param pgsize
- * page size (in points)
- */
+ @Override
public void setPageSize(Dimension pgsize) {
DocumentAtom docatom = _documentRecord.getDocumentAtom();
docatom.setSlideSizeX(Units.pointsToMaster(pgsize.width));
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
index 2f785c433b..6bbd345f45 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
@@ -21,17 +21,16 @@ import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Iterator;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.TableShape;
@@ -46,11 +45,6 @@ import org.apache.poi.util.Units;
public final class HSLFTable extends HSLFGroupShape
implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
- protected static final int BORDER_TOP = 1;
- protected static final int BORDER_RIGHT = 2;
- protected static final int BORDER_BOTTOM = 3;
- protected static final int BORDER_LEFT = 4;
-
protected static final int BORDERS_ALL = 5;
protected static final int BORDERS_OUTSIDE = 6;
protected static final int BORDERS_INSIDE = 7;
@@ -65,10 +59,10 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
* @param numRows the number of rows
* @param numCols the number of columns
*/
- public HSLFTable(int numRows, int numCols) {
+ protected HSLFTable(int numRows, int numCols) {
this(numRows, numCols, null);
}
-
+
/**
* Create a new Table of the given number of rows and columns
*
@@ -76,7 +70,7 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
* @param numCols the number of columns
* @param parent the parent shape, or null if table is added to sheet
*/
- public HSLFTable(int numRows, int numCols, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
+ protected HSLFTable(int numRows, int numCols, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
super(parent);
if(numRows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1");
@@ -96,13 +90,13 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
}
tblWidth = x;
tblHeight = y;
- setAnchor(new Rectangle(0, 0, tblWidth, tblHeight));
+ setExteriorAnchor(new Rectangle(0, 0, tblWidth, tblHeight));
EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);
AbstractEscherOptRecord opt = new EscherOptRecord();
opt.setRecordId((short)RecordTypes.EscherUserDefined);
- opt.addEscherProperty(new EscherSimpleProperty((short)0x39F, 1));
- EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | 0x3A0), false, null);
+ opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__TABLEPROPERTIES, 1));
+ EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES), false, null);
p.setSizeOfElements(0x0004);
p.setNumberOfElementsInArray(numRows);
p.setNumberOfElementsInMemory(numRows);
@@ -111,12 +105,12 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
}
/**
- * Create a Table object and initilize it from the supplied Record container.
+ * Create a Table 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
*/
- public HSLFTable(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
+ protected HSLFTable(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
super(escherRecord, parent);
}
@@ -131,9 +125,12 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
return cells[row][col];
}
+ @Override
public int getNumberOfColumns() {
return cells[0].length;
}
+
+ @Override
public int getNumberOfRows() {
return cells.length;
}
@@ -141,90 +138,171 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
protected void afterInsert(HSLFSheet sh){
super.afterInsert(sh);
- EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);
- List<EscherRecord> lst = spCont.getChildRecords();
- AbstractEscherOptRecord opt = (AbstractEscherOptRecord)lst.get(lst.size()-2);
- EscherArrayProperty p = opt.lookup(0x3A0);
- for (int i = 0; i < cells.length; i++) {
- HSLFTableCell cell = cells[i][0];
- int rowHeight = Units.pointsToMaster(cell.getAnchor().height);
- byte[] val = new byte[4];
- LittleEndian.putInt(val, 0, rowHeight);
- p.setElement(i, val);
- for (int j = 0; j < cells[i].length; j++) {
- HSLFTableCell c = cells[i][j];
+ Set<HSLFLine> lineSet = new HashSet<HSLFLine>();
+ for (HSLFTableCell row[] : cells) {
+ for (HSLFTableCell c : row) {
addShape(c);
+ for (HSLFLine bt : new HSLFLine[]{ c.borderTop, c.borderRight, c.borderBottom, c.borderLeft }) {
+ if (bt != null) {
+ lineSet.add(bt);
+ }
+ }
+ }
+ }
+
+ for (HSLFLine l : lineSet) {
+ addShape(l);
+ }
- HSLFLine bt = c.getBorderTop();
- if(bt != null) addShape(bt);
+ updateRowHeightsProperty();
+ }
+
+ private static class TableCellComparator implements Comparator<HSLFShape> {
+ public int compare( HSLFShape o1, HSLFShape o2 ) {
+ Rectangle anchor1 = o1.getAnchor();
+ Rectangle anchor2 = o2.getAnchor();
+ int delta = anchor1.y - anchor2.y;
+ if (delta == 0) delta = anchor1.x - anchor2.x;
+ // descending size
+ if (delta == 0) delta = (anchor2.width*anchor2.height)-(anchor1.width*anchor1.height);
+ return delta;
+ }
+ }
- HSLFLine br = c.getBorderRight();
- if(br != null) addShape(br);
+ private void cellListToArray() {
+ List<HSLFTableCell> htc = new ArrayList<HSLFTableCell>();
+ for (HSLFShape h : getShapes()) {
+ if (h instanceof HSLFTableCell) {
+ htc.add((HSLFTableCell)h);
+ }
+ }
+
+ if (htc.isEmpty()) {
+ throw new IllegalStateException("HSLFTable without HSLFTableCells");
+ }
- HSLFLine bb = c.getBorderBottom();
- if(bb != null) addShape(bb);
+ Collections.sort(htc, new TableCellComparator());
- HSLFLine bl = c.getBorderLeft();
- if(bl != null) addShape(bl);
+ List<HSLFTableCell[]> lst = new ArrayList<HSLFTableCell[]>();
+ List<HSLFTableCell> row = new ArrayList<HSLFTableCell>();
+ int y0 = htc.get(0).getAnchor().y;
+ for (HSLFTableCell sh : htc) {
+ Rectangle anchor = sh.getAnchor();
+ boolean isNextRow = (anchor.y > y0);
+ if (isNextRow) {
+ y0 = anchor.y;
+ lst.add(row.toArray(new HSLFTableCell[row.size()]));
+ row.clear();
}
+ row.add(sh);
}
+ lst.add(row.toArray(new HSLFTableCell[row.size()]));
+ cells = lst.toArray(new HSLFTableCell[lst.size()][]);
}
- protected void initTable(){
- List<HSLFShape> shapeList = getShapes();
-
- Iterator<HSLFShape> shapeIter = shapeList.iterator();
- while (shapeIter.hasNext()) {
- HSLFShape shape = shapeIter.next();
- if (shape instanceof HSLFAutoShape) {
- HSLFAutoShape autoShape = (HSLFAutoShape)shape;
- EscherTextboxRecord etr = autoShape.getEscherChild(EscherTextboxRecord.RECORD_ID);
- if (etr != null) continue;
- }
- shapeIter.remove();
- }
-
- Collections.sort(shapeList, new Comparator<HSLFShape>(){
- public int compare( HSLFShape o1, HSLFShape o2 ) {
- Rectangle anchor1 = o1.getAnchor();
- Rectangle anchor2 = o2.getAnchor();
- int delta = anchor1.y - anchor2.y;
- if (delta == 0) delta = anchor1.x - anchor2.x;
- // descending size
- if (delta == 0) delta = (anchor2.width*anchor2.height)-(anchor1.width*anchor1.height);
- return delta;
- }
- });
-
- int y0 = (shapeList.isEmpty()) ? -1 : shapeList.get(0).getAnchor().y - 1;
- int maxrowlen = 0;
- List<List<HSLFShape>> lst = new ArrayList<List<HSLFShape>>();
- List<HSLFShape> row = null;
- for (HSLFShape sh : shapeList) {
- if(sh instanceof HSLFTextShape){
- Rectangle anchor = sh.getAnchor();
- if(anchor.y != y0){
- y0 = anchor.y;
- row = new ArrayList<HSLFShape>();
- lst.add(row);
- }
- row.add(sh);
- maxrowlen = Math.max(maxrowlen, row.size());
+ static class LineRect {
+ final HSLFLine l;
+ final double lx1, lx2, ly1, ly2;
+ LineRect(HSLFLine l) {
+ this.l = l;
+ Rectangle r = l.getAnchor();
+ lx1 = r.getMinX();
+ lx2 = r.getMaxX();
+ ly1 = r.getMinY();
+ ly2 = r.getMaxY();
+ }
+ int leftFit(double x1, double x2, double y1, double y2) {
+ return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x1-lx2)+Math.abs(y2-ly2));
+ }
+ int topFit(double x1, double x2, double y1, double y2) {
+ return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y1-ly2));
+ }
+ int rightFit(double x1, double x2, double y1, double y2) {
+ return (int)(Math.abs(x2-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2));
+ }
+ int bottomFit(double x1, double x2, double y1, double y2) {
+ return (int)(Math.abs(x1-lx1)+Math.abs(y2-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2));
+ }
+ }
+
+ private void fitLinesToCells() {
+ List<LineRect> lines = new ArrayList<LineRect>();
+ for (HSLFShape h : getShapes()) {
+ if (h instanceof HSLFLine) {
+ lines.add(new LineRect((HSLFLine)h));
}
}
- cells = new HSLFTableCell[lst.size()][maxrowlen];
- for (int i = 0; i < lst.size(); i++) {
- row = lst.get(i);
- for (int j = 0; j < row.size(); j++) {
- HSLFTextShape tx = (HSLFTextShape)row.get(j);
- cells[i][j] = new HSLFTableCell(tx.getSpContainer(), getParent());
- cells[i][j].setSheet(tx.getSheet());
+
+ final int threshold = 5;
+
+ // TODO: this only works for non-rotated tables
+ for (HSLFTableCell[] tca : cells) {
+ for (HSLFTableCell tc : tca) {
+ final Rectangle cellAnchor = tc.getAnchor();
+
+ /**
+ * x1/y1 --------+
+ * | |
+ * +---------x2/y2
+ */
+ final double x1 = cellAnchor.getMinX();
+ final double x2 = cellAnchor.getMaxX();
+ final double y1 = cellAnchor.getMinY();
+ final double y2 = cellAnchor.getMaxY();
+
+ LineRect lline = null, tline = null, rline = null, bline = null;
+ int lfit = Integer.MAX_VALUE, tfit = Integer.MAX_VALUE, rfit = Integer.MAX_VALUE, bfit = Integer.MAX_VALUE;
+
+ for (LineRect lr : lines) {
+ // calculate border fit
+ int lfitx = lr.leftFit(x1, x2, y1, y2);
+ if (lfitx < lfit) {
+ lfit = lfitx;
+ lline = lr;
+ }
+
+ int tfitx = lr.topFit(x1, x2, y1, y2);
+ if (tfitx < tfit) {
+ tfit = tfitx;
+ tline = lr;
+ }
+
+ int rfitx = lr.rightFit(x1, x2, y1, y2);
+ if (rfitx < rfit) {
+ rfit = rfitx;
+ rline = lr;
+ }
+
+ int bfitx = lr.bottomFit(x1, x2, y1, y2);
+ if (bfitx < bfit) {
+ bfit = bfitx;
+ bline = lr;
+ }
+ }
+
+ if (lfit < threshold) {
+ tc.borderLeft = lline.l;
+ }
+ if (tfit < threshold) {
+ tc.borderTop = tline.l;
+ }
+ if (rfit < threshold) {
+ tc.borderRight = rline.l;
+ }
+ if (bfit < threshold) {
+ tc.borderBottom = bline.l;
+ }
}
}
}
+ protected void initTable(){
+ cellListToArray();
+ fitLinesToCells();
+ }
+
/**
* Assign the <code>SlideShow</code> this shape belongs to
*
@@ -232,151 +310,102 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
*/
public void setSheet(HSLFSheet sheet){
super.setSheet(sheet);
- if(cells == null) initTable();
+ if (cells == null) {
+ initTable();
+ } else {
+ for (HSLFTableCell cols[] : cells) {
+ for (HSLFTableCell col : cols) {
+ col.setSheet(sheet);
+ }
+ }
+ }
}
- /**
- * Sets the row height.
- *
- * @param row the row index (0-based)
- * @param height the height to set (in pixels)
- */
- public void setRowHeight(int row, int height){
+ @Override
+ public void setRowHeight(int row, double height) {
+ int pxHeight = Units.pointsToPixel(height);
int currentHeight = cells[row][0].getAnchor().height;
- int dy = height - currentHeight;
+ int dy = pxHeight - currentHeight;
for (int i = row; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
Rectangle anchor = cells[i][j].getAnchor();
- if(i == row) anchor.height = height;
- else anchor.y += dy;
+ if(i == row) {
+ anchor.height = pxHeight;
+ } else {
+ anchor.y += dy;
+ }
cells[i][j].setAnchor(anchor);
}
}
Rectangle tblanchor = getAnchor();
tblanchor.height += dy;
- setAnchor(tblanchor);
+ setExteriorAnchor(tblanchor);
}
- /**
- * Sets the column width.
- *
- * @param col the column index (0-based)
- * @param width the width to set (in pixels)
- */
- public void setColumnWidth(int col, int width){
- int currentWidth = cells[0][col].getAnchor().width;
- int dx = width - currentWidth;
- for (int i = 0; i < cells.length; i++) {
- Rectangle anchor = cells[i][col].getAnchor();
- anchor.width = width;
- cells[i][col].setAnchor(anchor);
-
- if(col < cells[i].length - 1) for (int j = col+1; j < cells[i].length; j++) {
- anchor = cells[i][j].getAnchor();
- anchor.x += dx;
- cells[i][j].setAnchor(anchor);
+ @Override
+ public void setColumnWidth(int col, final double width){
+ if (col < 0 || col >= cells[0].length) {
+ throw new IllegalArgumentException("Column index '"+col+"' is not within range [0-"+(cells[0].length-1)+"]");
+ }
+ double currentWidth = cells[0][col].getAnchor().getWidth();
+ double dx = width - currentWidth;
+ for (HSLFTableCell cols[] : cells) {
+ Rectangle anchor = cols[col].getAnchor();
+ anchor.width = (int)Math.rint(width);
+ cols[col].setAnchor(anchor);
+
+ if (col < cols.length - 1) {
+ for (int j = col+1; j < cols.length; j++) {
+ anchor = cols[j].getAnchor();
+ anchor.x += dx;
+ cols[j].setAnchor(anchor);
+ }
}
}
Rectangle tblanchor = getAnchor();
tblanchor.width += dx;
- setAnchor(tblanchor);
+ setExteriorAnchor(tblanchor);
}
- /**
- * Format the table and apply the specified Line to all cell boundaries,
- * both outside and inside
- *
- * @param line the border line
- */
- public void setAllBorders(HSLFLine line){
- for (int i = 0; i < cells.length; i++) {
- for (int j = 0; j < cells[i].length; j++) {
- HSLFTableCell cell = cells[i][j];
- cell.setBorderTop(cloneBorder(line));
- cell.setBorderLeft(cloneBorder(line));
- if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
- if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line));
- }
- }
- }
-
- /**
- * Format the outside border using the specified Line object
- *
- * @param line the border line
- */
- public void setOutsideBorders(HSLFLine line){
- for (int i = 0; i < cells.length; i++) {
- for (int j = 0; j < cells[i].length; j++) {
- HSLFTableCell cell = cells[i][j];
-
- if(j == 0) cell.setBorderLeft(cloneBorder(line));
- if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
- else {
- cell.setBorderLeft(null);
- cell.setBorderLeft(null);
- }
-
- if(i == 0) cell.setBorderTop(cloneBorder(line));
- else if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line));
- else {
- cell.setBorderTop(null);
- cell.setBorderBottom(null);
+ protected HSLFTableCell getRelativeCell(HSLFTableCell origin, int row, int col) {
+ int thisRow = 0, thisCol = 0;
+ boolean found = false;
+ outer: for (HSLFTableCell[] tca : cells) {
+ thisCol = 0;
+ for (HSLFTableCell tc : tca) {
+ if (tc == origin) {
+ found = true;
+ break outer;
}
+ thisCol++;
}
+ thisRow++;
}
- }
-
- /**
- * Format the inside border using the specified Line object
- *
- * @param line the border line
- */
- public void setInsideBorders(HSLFLine line){
- for (int i = 0; i < cells.length; i++) {
- for (int j = 0; j < cells[i].length; j++) {
- HSLFTableCell cell = cells[i][j];
- if(j != cells[i].length - 1)
- cell.setBorderRight(cloneBorder(line));
- else {
- cell.setBorderLeft(null);
- cell.setBorderLeft(null);
- }
- if(i != cells.length - 1) cell.setBorderBottom(cloneBorder(line));
- else {
- cell.setBorderTop(null);
- cell.setBorderBottom(null);
- }
- }
- }
+ int otherRow = thisRow + row;
+ int otherCol = thisCol + col;
+ return (found
+ && 0 <= otherRow && otherRow < cells.length
+ && 0 <= otherCol && otherCol < cells[otherRow].length)
+ ? cells[otherRow][otherCol] : null;
}
- private HSLFLine cloneBorder(HSLFLine line){
- HSLFLine border = createBorder();
- border.setLineWidth(line.getLineWidth());
- border.setLineDashing(line.getLineDashing());
- border.setLineColor(line.getLineColor());
- border.setLineCompound(line.getLineCompound());
- return border;
+ @Override
+ protected void moveAndScale(Rectangle anchorDest){
+ super.moveAndScale(anchorDest);
+ updateRowHeightsProperty();
}
- /**
- * Create a border to format this table
- *
- * @return the created border
- */
- public HSLFLine createBorder(){
- HSLFLine line = new HSLFLine(this);
-
+ private void updateRowHeightsProperty() {
AbstractEscherOptRecord opt = getEscherOptRecord();
- setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1);
- setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1);
- setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
- setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000);
-
- return line;
+ EscherArrayProperty p = opt.lookup(EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES);
+ byte[] val = new byte[4];
+ for (int rowIdx = 0; rowIdx < cells.length; rowIdx++) {
+ int rowHeight = Units.pointsToMaster(cells[rowIdx][0].getAnchor().height);
+ LittleEndian.putInt(val, 0, rowHeight);
+ p.setElement(rowIdx, val);
+ }
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java
index e3737e5e18..80341aa354 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java
@@ -17,13 +17,18 @@
package org.apache.poi.hslf.usermodel;
+import java.awt.Color;
import java.awt.Rectangle;
import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell;
/**
@@ -35,10 +40,10 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
protected static final int DEFAULT_WIDTH = 100;
protected static final int DEFAULT_HEIGHT = 40;
- private HSLFLine borderLeft;
- private HSLFLine borderRight;
- private HSLFLine borderTop;
- private HSLFLine borderBottom;
+ /* package */ HSLFLine borderLeft;
+ /* package */ HSLFLine borderRight;
+ /* package */ HSLFLine borderTop;
+ /* package */ HSLFLine borderBottom;
/**
* Create a TableCell object and initialize it from the supplied Record container.
@@ -46,7 +51,7 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
* @param escherRecord EscherSpContainer which holds information about this shape
* @param parent the parent of the shape
*/
- protected HSLFTableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
+ protected HSLFTableCell(EscherContainerRecord escherRecord, HSLFTable parent){
super(escherRecord, parent);
}
@@ -56,7 +61,7 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
* @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 HSLFTableCell(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
+ public HSLFTableCell(HSLFTable parent){
super(parent);
setShapeType(ShapeType.RECT);
@@ -76,82 +81,320 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
return _escherContainer;
}
- protected void anchorBorder(int type, HSLFLine line){
+ private void anchorBorder(BorderEdge edge, final HSLFLine line) {
+ if (line == null) {
+ return;
+ }
Rectangle cellAnchor = getAnchor();
Rectangle lineAnchor = new Rectangle();
- switch(type){
- case HSLFTable.BORDER_TOP:
+ switch(edge){
+ case top:
lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y;
lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0;
break;
- case HSLFTable.BORDER_RIGHT:
+ case right:
lineAnchor.x = cellAnchor.x + cellAnchor.width;
lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0;
lineAnchor.height = cellAnchor.height;
break;
- case HSLFTable.BORDER_BOTTOM:
+ case bottom:
lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y + cellAnchor.height;
lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0;
break;
- case HSLFTable.BORDER_LEFT:
+ case left:
lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0;
lineAnchor.height = cellAnchor.height;
break;
default:
- throw new IllegalArgumentException("Unknown border type: " + type);
+ throw new IllegalArgumentException();
}
line.setAnchor(lineAnchor);
}
- public HSLFLine getBorderLeft() {
- return borderLeft;
+ public void setAnchor(Rectangle anchor){
+ super.setAnchor(anchor);
+
+ anchorBorder(BorderEdge.top, borderTop);
+ anchorBorder(BorderEdge.right, borderRight);
+ anchorBorder(BorderEdge.bottom, borderBottom);
+ anchorBorder(BorderEdge.left, borderLeft);
}
- public void setBorderLeft(HSLFLine line) {
- if(line != null) anchorBorder(HSLFTable.BORDER_LEFT, line);
- this.borderLeft = line;
+ @Override
+ public StrokeStyle getBorderStyle(final BorderEdge edge) {
+ final Double width = getBorderWidth(edge);
+ return (width == null) ? null : new StrokeStyle() {
+ public PaintStyle getPaint() {
+ return DrawPaint.createSolidPaint(getBorderColor(edge));
+ }
+
+ public LineCap getLineCap() {
+ return null;
+ }
+
+ public LineDash getLineDash() {
+ return getBorderDash(edge);
+ }
+
+ public LineCompound getLineCompound() {
+ return getBorderCompound(edge);
+ }
+
+ public double getLineWidth() {
+ return width;
+ }
+ };
}
- public HSLFLine getBorderRight() {
- return borderRight;
+ @Override
+ public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
+ if (style == null) {
+ throw new IllegalArgumentException("StrokeStyle needs to be specified.");
+ }
+
+ // setting the line cap is not implemented, as the border lines aren't connected
+
+ LineCompound compound = style.getLineCompound();
+ if (compound != null) {
+ setBorderCompound(edge, compound);
+ }
+
+ LineDash dash = style.getLineDash();
+ if (dash != null) {
+ setBorderDash(edge, dash);
+ }
+
+ double width = style.getLineWidth();
+ setBorderWidth(edge, width);
}
- public void setBorderRight(HSLFLine line) {
- if(line != null) anchorBorder(HSLFTable.BORDER_RIGHT, line);
- this.borderRight = line;
+
+ public Double getBorderWidth(BorderEdge edge) {
+ HSLFLine l;
+ switch (edge) {
+ case bottom: l = borderBottom; break;
+ case top: l = borderTop; break;
+ case right: l = borderRight; break;
+ case left: l = borderLeft; break;
+ default: throw new IllegalArgumentException();
+ }
+ return (l == null) ? null : l.getLineWidth();
+ }
+
+ @Override
+ public void setBorderWidth(BorderEdge edge, double width) {
+ HSLFLine l = addLine(edge);
+ l.setLineWidth(width);
}
- public HSLFLine getBorderTop() {
- return borderTop;
+ public Color getBorderColor(BorderEdge edge) {
+ HSLFLine l;
+ switch (edge) {
+ case bottom: l = borderBottom; break;
+ case top: l = borderTop; break;
+ case right: l = borderRight; break;
+ case left: l = borderLeft; break;
+ default: throw new IllegalArgumentException();
+ }
+ return (l == null) ? null : l.getLineColor();
}
- public void setBorderTop(HSLFLine line) {
- if(line != null) anchorBorder(HSLFTable.BORDER_TOP, line);
- this.borderTop = line;
+ @Override
+ public void setBorderColor(BorderEdge edge, Color color) {
+ if (edge == null || color == null) {
+ throw new IllegalArgumentException("BorderEdge and/or Color need to be specified.");
+ }
+
+ HSLFLine l = addLine(edge);
+ l.setLineColor(color);
}
- public HSLFLine getBorderBottom() {
- return borderBottom;
+ public LineDash getBorderDash(BorderEdge edge) {
+ HSLFLine l;
+ switch (edge) {
+ case bottom: l = borderBottom; break;
+ case top: l = borderTop; break;
+ case right: l = borderRight; break;
+ case left: l = borderLeft; break;
+ default: throw new IllegalArgumentException();
+ }
+ return (l == null) ? null : l.getLineDash();
+ }
+
+ @Override
+ public void setBorderDash(BorderEdge edge, LineDash dash) {
+ if (edge == null || dash == null) {
+ throw new IllegalArgumentException("BorderEdge and/or LineDash need to be specified.");
+ }
+
+ HSLFLine l = addLine(edge);
+ l.setLineDash(dash);
}
- public void setBorderBottom(HSLFLine line) {
- if(line != null) anchorBorder(HSLFTable.BORDER_BOTTOM, line);
- this.borderBottom = line;
+ public LineCompound getBorderCompound(BorderEdge edge) {
+ HSLFLine l;
+ switch (edge) {
+ case bottom: l = borderBottom; break;
+ case top: l = borderTop; break;
+ case right: l = borderRight; break;
+ case left: l = borderLeft; break;
+ default: throw new IllegalArgumentException();
+ }
+ return (l == null) ? null : l.getLineCompound();
+ }
+
+ @Override
+ public void setBorderCompound(BorderEdge edge, LineCompound compound) {
+ if (edge == null || compound == null) {
+ throw new IllegalArgumentException("BorderEdge and/or LineCompound need to be specified.");
+ }
+
+ HSLFLine l = addLine(edge);
+ l.setLineCompound(compound);
}
- public void setAnchor(Rectangle anchor){
- super.setAnchor(anchor);
- if(borderTop != null) anchorBorder(HSLFTable.BORDER_TOP, borderTop);
- if(borderRight != null) anchorBorder(HSLFTable.BORDER_RIGHT, borderRight);
- if(borderBottom != null) anchorBorder(HSLFTable.BORDER_BOTTOM, borderBottom);
- if(borderLeft != null) anchorBorder(HSLFTable.BORDER_LEFT, borderLeft);
+ protected HSLFLine addLine(BorderEdge edge) {
+ switch (edge) {
+ case bottom: {
+ if (borderBottom == null) {
+ borderBottom = createBorder(edge);
+ HSLFTableCell c = getSiblingCell(1,0);
+ if (c != null) {
+ assert(c.borderTop == null);
+ c.borderTop = borderBottom;
+ }
+ }
+ return borderBottom;
+ }
+ case top: {
+ if (borderTop == null) {
+ borderTop = createBorder(edge);
+ HSLFTableCell c = getSiblingCell(-1,0);
+ if (c != null) {
+ assert(c.borderBottom == null);
+ c.borderBottom = borderTop;
+ }
+ }
+ return borderTop;
+ }
+ case right: {
+ if (borderRight == null) {
+ borderRight = createBorder(edge);
+ HSLFTableCell c = getSiblingCell(0,1);
+ if (c != null) {
+ assert(c.borderLeft == null);
+ c.borderLeft = borderRight;
+ }
+ }
+ return borderRight;
+ }
+ case left: {
+ if (borderLeft == null) {
+ borderLeft = createBorder(edge);
+ HSLFTableCell c = getSiblingCell(0,-1);
+ if (c != null) {
+ assert(c.borderRight == null);
+ c.borderRight = borderLeft;
+ }
+ }
+ return borderLeft;
+ }
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void removeBorder(BorderEdge edge) {
+ switch (edge) {
+ case bottom: {
+ if (borderBottom == null) break;
+ getParent().removeShape(borderBottom);
+ borderBottom = null;
+ HSLFTableCell c = getSiblingCell(1,0);
+ if (c != null) {
+ c.borderTop = null;
+ }
+ break;
+ }
+ case top: {
+ if (borderTop == null) break;
+ getParent().removeShape(borderTop);
+ borderTop = null;
+ HSLFTableCell c = getSiblingCell(-1,0);
+ if (c != null) {
+ c.borderBottom = null;
+ }
+ break;
+ }
+ case right: {
+ if (borderRight == null) break;
+ getParent().removeShape(borderRight);
+ borderRight = null;
+ HSLFTableCell c = getSiblingCell(0,1);
+ if (c != null) {
+ c.borderLeft = null;
+ }
+ break;
+ }
+ case left: {
+ if (borderLeft == null) break;
+ getParent().removeShape(borderLeft);
+ borderLeft = null;
+ HSLFTableCell c = getSiblingCell(0,-1);
+ if (c != null) {
+ c.borderRight = null;
+ }
+ break;
+ }
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ protected HSLFTableCell getSiblingCell(int row, int col) {
+ return getParent().getRelativeCell(this, row, col);
+ }
+
+ /**
+ * Create a border to format this table
+ *
+ * @return the created border
+ */
+ private HSLFLine createBorder(BorderEdge edge) {
+ HSLFTable table = getParent();
+ HSLFLine line = new HSLFLine(table);
+ table.addShape(line);
+
+ AbstractEscherOptRecord opt = getEscherOptRecord();
+ setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1);
+ setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1);
+ setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
+ setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000);
+
+ anchorBorder(edge, line);
+
+ return line;
+ }
+
+ protected void applyLineProperties(BorderEdge edge, HSLFLine other) {
+ HSLFLine line = addLine(edge);
+ line.setLineWidth(other.getLineWidth());
+ line.setLineColor(other.getLineColor());
+ // line.setLineCompound(other.getLineCompound());
+ // line.setLineDashing(other.getLineDashing());
+ }
+
+ @Override
+ public HSLFTable getParent() {
+ return (HSLFTable)super.getParent();
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
index 39fe74c2a9..76969a4713 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
@@ -69,7 +69,7 @@ import org.apache.poi.util.Units;
* This class represents a run of text in a powerpoint document. That
* run could be text on a sheet, or text in a note.
* It is only a very basic class for now
- *
+ *
* @author Nick Burch
*/
@@ -98,18 +98,18 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
private int shapeId;
private StyleTextProp9Atom styleTextProp9Atom;
-
+
private boolean _dirty = false;
/**
* Constructs a Text Run from a Unicode text block.
* Either a {@link TextCharsAtom} or a {@link TextBytesAtom} needs to be provided.
- *
+ *
* @param tha the TextHeaderAtom that defines what's what
* @param tba the TextBytesAtom containing the text or null if {@link TextCharsAtom} is provided
* @param tca the TextCharsAtom containing the text or null if {@link TextBytesAtom} is provided
*/
- /* package */ HSLFTextParagraph(
+ /* package */ HSLFTextParagraph(
TextHeaderAtom tha,
TextBytesAtom tba,
TextCharsAtom tca
@@ -137,10 +137,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
_runs.add(run);
}
- /**
- * Fetch the rich text runs (runs of text with the same styling) that
- * are contained within this block of text
- */
+ @Override
public List<HSLFTextRun> getTextRuns() {
return _runs;
}
@@ -193,7 +190,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Sets the index of the paragraph in the SLWT container
- *
+ *
* @param index
*/
protected void setIndex(int index) {
@@ -241,7 +238,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Returns records that make up the list of text paragraphs
* (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
- *
+ *
* @return text run records
*/
public Record[] getRecords() {
@@ -278,7 +275,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
}
/** Numbered List info */
- public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {
+ public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {
this.styleTextProp9Atom = styleTextProp9Atom;
}
@@ -286,7 +283,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
public StyleTextProp9Atom getStyleTextProp9Atom() {
return this.styleTextProp9Atom;
}
-
+
@Override
public Iterator<HSLFTextRun> iterator() {
return _runs.iterator();
@@ -342,13 +339,13 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
if (!_runs.isEmpty()) {
d = _runs.get(0).getFontSize();
}
-
+
return (d != null) ? d : 12d;
}
/**
* Sets the type of horizontal alignment for the paragraph.
- *
+ *
* @param align - the type of alignment
*/
public void setAlignment(org.apache.poi.sl.usermodel.TextParagraph.TextAlign align) {
@@ -386,7 +383,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
public FontAlign getFontAlign() {
TextProp tp = getPropVal(_paragraphStyle, FontAlignmentProp.NAME, this);
if (tp == null) return null;
-
+
switch (tp.getValue()) {
case FontAlignmentProp.BASELINE: return FontAlign.BASELINE;
case FontAlignmentProp.TOP: return FontAlign.TOP;
@@ -413,8 +410,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
assert(startAt != null);
return startAt.intValue();
}
-
-
+
+
@Override
public BulletStyle getBulletStyle() {
if (!isBullet() && getAutoNumberingScheme() == null) return null;
@@ -440,7 +437,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
public void setBulletFontColor(Color color) {
setBulletFontColor(DrawPaint.createSolidPaint(color));
}
-
+
@Override
public void setBulletFontColor(PaintStyle color) {
if (!(color instanceof SolidPaint)) {
@@ -450,7 +447,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
Color col = DrawPaint.applyColorTransform(sp.getSolidColor());
HSLFTextParagraph.this.setBulletColor(col);
}
-
+
@Override
public PaintStyle getBulletFontColor() {
Color col = HSLFTextParagraph.this.getBulletColor();
@@ -617,7 +614,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
// TODO: implement
return null;
}
-
+
private Double getPctOrPoints(String propName) {
TextProp tp = getPropVal(_paragraphStyle, propName, this);
if (tp == null) return null;
@@ -632,7 +629,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
}
setParagraphTextPropVal(propName, ival);
}
-
+
private boolean getFlag(int index) {
BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, ParagraphFlagsTextProp.NAME, this);
return (tp == null) ? false : tp.getSubValue(index);
@@ -672,7 +669,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Returns the named TextProp, either by fetching it (if it exists) or
* adding it (if it didn't)
- *
+ *
* @param props the TextPropCollection to fetch from / add into
* @param name the name of the TextProp to fetch/add
* @param val the value, null if unset
@@ -682,15 +679,15 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
props.removeByName(name);
return;
}
-
+
// Fetch / Add the TextProp
TextProp tp = props.addWithName(name);
tp.setValue(val);
}
-
+
/**
* Check and add linebreaks to text runs leading other paragraphs
- *
+ *
* @param paragraphs
*/
protected static void fixLineEndings(List<HSLFTextParagraph> paragraphs) {
@@ -710,7 +707,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Search for a StyleTextPropAtom is for this text header (list of paragraphs)
- *
+ *
* @param header the header
* @param textLen the length of the rawtext, or -1 if the length is not known
*/
@@ -868,7 +865,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
throw new RuntimeException("failed dummy write", e);
}
}
-
+
for (HSLFTextParagraph p : paragraphs) {
p._dirty = false;
}
@@ -877,7 +874,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Adds the supplied text onto the end of the TextParagraphs,
* creating a new RichTextRun for it to sit in.
- *
+ *
* @param text the text string used by this object.
*/
protected static HSLFTextRun appendText(List<HSLFTextParagraph> paragraphs, String text, boolean newParagraph) {
@@ -889,9 +886,13 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
HSLFTextParagraph htp = paragraphs.get(paragraphs.size() - 1);
HSLFTextRun htr = htp.getTextRuns().get(htp.getTextRuns().size() - 1);
- boolean isFirst = !newParagraph;
+ boolean addParagraph = newParagraph;
for (String rawText : text.split("(?<=\r)")) {
- if (!isFirst) {
+ // special case, if last text paragraph or run is empty, we will reuse it
+ boolean lastRunEmpty = (htr.getLength() == 0);
+ boolean lastParaEmpty = lastRunEmpty && (htp.getTextRuns().size() == 1);
+
+ if (addParagraph && !lastParaEmpty) {
TextPropCollection tpc = htp.getParagraphStyle();
HSLFTextParagraph prevHtp = htp;
htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom);
@@ -901,11 +902,10 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
htp.supplySheet(prevHtp.getSheet());
paragraphs.add(htp);
}
- isFirst = false;
+ addParagraph = true;
- TextPropCollection tpc = htr.getCharacterStyle();
- // special case, last text run is empty, we will reuse it
- if (htr.getLength() > 0) {
+ if (!lastRunEmpty) {
+ TextPropCollection tpc = htr.getCharacterStyle();
htr = new HSLFTextRun(htp);
htr.getCharacterStyle().copy(tpc);
htp.addTextRun(htr);
@@ -921,7 +921,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Sets (overwrites) the current text.
* Uses the properties of the first paragraph / textrun
- *
+ *
* @param text the text string used by this object.
*/
public static HSLFTextRun setText(List<HSLFTextParagraph> paragraphs, String text) {
@@ -980,7 +980,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
/**
* Converts raw text from the text paragraphs to a formatted string,
* i.e. it converts certain control characters used in the raw txt
- *
+ *
* @param rawText the raw text
* @param runType the run type of the shape, paragraph or headerAtom.
* use -1 if unknown
@@ -1024,7 +1024,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or
* a TextCharsAtom. Builds up TextRuns from these
- *
+ *
* @param wrapper an EscherTextboxWrapper
*/
protected static List<HSLFTextParagraph> findTextParagraphs(EscherTextboxWrapper wrapper, HSLFSheet sheet) {
@@ -1103,7 +1103,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or
* a TextCharsAtom. Builds up TextRuns from these
- *
+ *
* @param records the records to build from
*/
protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records) {
@@ -1272,7 +1272,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
EscherTextboxWrapper wrapper = new EscherTextboxWrapper();
return createEmptyParagraph(wrapper);
}
-
+
protected static List<HSLFTextParagraph> createEmptyParagraph(EscherTextboxWrapper wrapper) {
TextHeaderAtom tha = new TextHeaderAtom();
tha.setParentRecord(wrapper);
@@ -1301,10 +1301,10 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
public EscherTextboxWrapper getTextboxWrapper() {
return (EscherTextboxWrapper) _headerAtom.getParentRecord();
}
-
+
protected static Color getColorFromColorIndexStruct(int rgb, HSLFSheet sheet) {
int cidx = rgb >>> 24;
- Color tmp;
+ Color tmp;
switch (cidx) {
// Background ... Accent 3 color
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
@@ -1333,15 +1333,15 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
setPropVal(_paragraphStyle, propName, val);
setDirty();
}
-
+
/**
* marks this paragraph dirty, so its records will be renewed on save
*/
public void setDirty() {
_dirty = true;
}
-
+
public boolean isDirty() {
return _dirty;
}
-}
+} \ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
index fbb908c1c7..a636d346c3 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
@@ -157,44 +157,32 @@ public final class HSLFTextRun implements TextRun {
// --------------- Friendly getters / setters on rich text properties -------
- /**
- * Is the text bold?
- */
+ @Override
public boolean isBold() {
return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX);
}
- /**
- * Is the text bold?
- */
+ @Override
public void setBold(boolean bold) {
setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold);
}
- /**
- * Is the text italic?
- */
+ @Override
public boolean isItalic() {
return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX);
}
- /**
- * Is the text italic?
- */
+ @Override
public void setItalic(boolean italic) {
setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic);
}
- /**
- * Is the text underlined?
- */
+ @Override
public boolean isUnderlined() {
return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
}
- /**
- * Is the text underlined?
- */
+ @Override
public void setUnderlined(boolean underlined) {
setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
}
@@ -227,16 +215,12 @@ public final class HSLFTextRun implements TextRun {
setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag);
}
- /**
- * Gets the strikethrough flag
- */
+ @Override
public boolean isStrikethrough() {
return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX);
}
- /**
- * Sets the strikethrough flag
- */
+ @Override
public void setStrikethrough(boolean flag) {
setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag);
}
@@ -288,10 +272,7 @@ public final class HSLFTextRun implements TextRun {
setCharTextPropVal("font.index", idx);
}
-
- /**
- * Sets the font name to use
- */
+ @Override
public void setFontFamily(String fontFamily) {
HSLFSheet sheet = parentParagraph.getSheet();
HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
@@ -301,13 +282,10 @@ public final class HSLFTextRun implements TextRun {
return;
}
// Get the index for this font (adding if needed)
- int fontIdx = slideShow.getFontCollection().addFont(fontFamily);
+ Integer fontIdx = (fontFamily == null) ? null : slideShow.getFontCollection().addFont(fontFamily);
setCharTextPropVal("font.index", fontIdx);
}
- /**
- * Gets the font name
- */
@Override
public String getFontFamily() {
HSLFSheet sheet = parentParagraph.getSheet();
@@ -373,12 +351,14 @@ public final class HSLFTextRun implements TextRun {
return TextCap.NONE;
}
+ @Override
public boolean isSubscript() {
- return false;
+ return getSuperscript() < 0;
}
+ @Override
public boolean isSuperscript() {
- return false;
+ return getSuperscript() > 0;
}
public byte getPitchAndFamily() {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
index 1b5bbb83fd..f24173e204 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
@@ -17,20 +17,37 @@
package org.apache.poi.hslf.usermodel;
-import static org.apache.poi.hslf.record.RecordTypes.*;
+import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom;
+import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
-import java.util.*;
-
-import org.apache.poi.ddf.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.EscherTextboxWrapper;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.InteractiveInfoAtom;
+import org.apache.poi.hslf.record.OEPlaceholderAtom;
+import org.apache.poi.hslf.record.PPDrawing;
+import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
+import org.apache.poi.hslf.record.TextHeaderAtom;
+import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawTextShape;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.TextShape;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
@@ -57,14 +74,35 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/* package */ static final int AnchorBottomCenteredBaseline = 9;
/**
- * How to wrap the text
+ * Specifies that a line of text will continue on subsequent lines instead
+ * of extending into or beyond a margin.
+ * Office Excel 2007, Excel 2010, PowerPoint 97, and PowerPoint 2010 read
+ * and use this value properly but do not write it.
*/
public static final int WrapSquare = 0;
+ /**
+ * Specifies a wrapping rule that is equivalent to that of WrapSquare
+ * Excel 97, Excel 2000, Excel 2002, and Office Excel 2003 use this value.
+ * All other product versions listed at the beginning of this appendix ignore this value.
+ */
public static final int WrapByPoints = 1;
+ /**
+ * Specifies that a line of text will extend into or beyond a margin instead
+ * of continuing on subsequent lines.
+ * Excel 97, Word 97, Excel 2000, Word 2000, Excel 2002,
+ * and Office Excel 2003 do not use this value.
+ */
public static final int WrapNone = 2;
+ /**
+ * Specifies a wrapping rule that is undefined and MUST be ignored.
+ */
public static final int WrapTopBottom = 3;
+ /**
+ * Specifies a wrapping rule that is undefined and MUST be ignored.
+ */
public static final int WrapThrough = 4;
+
/**
* TextRun object which holds actual text and format data
*/
@@ -302,24 +340,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align2);
}
- @Override
- public VerticalAlignment getVerticalAlignment() {
- int va = getAlignment();
- switch (va) {
- case AnchorTop:
- case AnchorTopCentered:
- case AnchorTopBaseline:
- case AnchorTopCenteredBaseline: return VerticalAlignment.TOP;
- case AnchorBottom:
- case AnchorBottomCentered:
- case AnchorBottomBaseline:
- case AnchorBottomCenteredBaseline: return VerticalAlignment.BOTTOM;
- default:
- case AnchorMiddle:
- case AnchorMiddleCentered: return VerticalAlignment.MIDDLE;
- }
- }
-
/**
* @return true, if vertical alignment is relative to baseline
* this is only used for older versions less equals Office 2003
@@ -353,21 +373,33 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return false;
}
}
+
+ @Override
+ public void setHorizontalCentered(Boolean isCentered) {
+ setAlignment(isCentered, getVerticalAlignment());
+ }
- public void setVerticalAlignment(VerticalAlignment vAlign) {
- setAlignment(isHorizontalCentered(), vAlign);
+ @Override
+ public VerticalAlignment getVerticalAlignment() {
+ int va = getAlignment();
+ switch (va) {
+ case AnchorTop:
+ case AnchorTopCentered:
+ case AnchorTopBaseline:
+ case AnchorTopCenteredBaseline: return VerticalAlignment.TOP;
+ case AnchorBottom:
+ case AnchorBottomCentered:
+ case AnchorBottomBaseline:
+ case AnchorBottomCenteredBaseline: return VerticalAlignment.BOTTOM;
+ default:
+ case AnchorMiddle:
+ case AnchorMiddleCentered: return VerticalAlignment.MIDDLE;
+ }
}
- /**
- * Sets if the paragraphs are horizontal centered
- *
- * @param isCentered true, if the paragraphs are horizontal centered
- * A {@code null} values unsets this property.
- *
- * @see TextShape#isHorizontalCentered()
- */
- public void setHorizontalCentered(Boolean isCentered){
- setAlignment(isCentered, getVerticalAlignment());
+ @Override
+ public void setVerticalAlignment(VerticalAlignment vAlign) {
+ setAlignment(isHorizontalCentered(), vAlign);
}
/**
@@ -479,12 +511,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
setEscherProperty(propId, Units.toEMU(margin));
}
- @Override
- public boolean getWordWrap(){
- int ww = getWordWrapEx();
- return (ww != WrapNone);
- }
-
/**
* Returns the value indicating word wrap.
*
@@ -498,17 +524,28 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
return prop == null ? WrapSquare : prop.getPropertyValue();
}
-
+
/**
* Specifies how the text should be wrapped
*
* @param wrap the value indicating how the text should be wrapped.
* Must be one of the <code>Wrap*</code> constants defined in this class.
*/
- public void setWordWrap(int wrap){
+ public void setWordWrapEx(int wrap){
setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
}
+ @Override
+ public boolean getWordWrap(){
+ int ww = getWordWrapEx();
+ return (ww != WrapNone);
+ }
+
+ @Override
+ public void setWordWrap(boolean wrap) {
+ setWordWrapEx(wrap ? WrapSquare : WrapNone);
+ }
+
/**
* @return id for the text.
*/
@@ -700,6 +737,14 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
}
@Override
+ public void setInsets(Insets2D insets) {
+ setTopInset(insets.top);
+ setLeftInset(insets.left);
+ setBottomInset(insets.bottom);
+ setRightInset(insets.right);
+ }
+
+ @Override
public double getTextHeight(){
DrawFactory drawFact = DrawFactory.getInstance(null);
DrawTextShape dts = drawFact.getDrawable(this);
@@ -747,14 +792,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return HSLFTextParagraph.appendText(paras, text, newParagraph);
}
- /**
- * Sets (overwrites) the current text.
- * Uses the properties of the first paragraph / textrun
- *
- * @param text the text string used by this object.
- *
- * @return the last text run of the splitted text
- */
+ @Override
public HSLFTextRun setText(String text) {
// init paragraphs
List<HSLFTextParagraph> paras = getTextParagraphs();
@@ -783,5 +821,64 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return HSLFHyperlink.find(this);
}
+ @Override
+ public void setTextPlaceholder(TextPlaceholder placeholder) {
+ // TOOD: check for correct placeholder handling - see org.apache.poi.hslf.model.Placeholder
+ Placeholder ph = null;
+ int runType;
+ switch (placeholder) {
+ default:
+ case BODY:
+ runType = TextHeaderAtom.BODY_TYPE;
+ ph = Placeholder.BODY;
+ break;
+ case TITLE:
+ runType = TextHeaderAtom.TITLE_TYPE;
+ ph = Placeholder.TITLE;
+ break;
+ case CENTER_BODY:
+ runType = TextHeaderAtom.CENTRE_BODY_TYPE;
+ ph = Placeholder.BODY;
+ break;
+ case CENTER_TITLE:
+ runType = TextHeaderAtom.CENTER_TITLE_TYPE;
+ ph = Placeholder.TITLE;
+ break;
+ case HALF_BODY:
+ runType = TextHeaderAtom.HALF_BODY_TYPE;
+ ph = Placeholder.BODY;
+ break;
+ case QUARTER_BODY:
+ runType = TextHeaderAtom.QUARTER_BODY_TYPE;
+ ph = Placeholder.BODY;
+ break;
+ case NOTES:
+ runType = TextHeaderAtom.NOTES_TYPE;
+ break;
+ case OTHER:
+ runType = TextHeaderAtom.OTHER_TYPE;
+ break;
+ }
+ setRunType(runType);
+ if (ph != null) {
+ setPlaceholder(ph);
+ }
+ }
+ @Override
+ public TextPlaceholder getTextPlaceholder() {
+ switch (getRunType()) {
+ default:
+ case TextHeaderAtom.BODY_TYPE: return TextPlaceholder.BODY;
+ case TextHeaderAtom.TITLE_TYPE: return TextPlaceholder.TITLE;
+ case TextHeaderAtom.NOTES_TYPE: return TextPlaceholder.NOTES;
+ case TextHeaderAtom.OTHER_TYPE: return TextPlaceholder.OTHER;
+ case TextHeaderAtom.CENTRE_BODY_TYPE: return TextPlaceholder.CENTER_BODY;
+ case TextHeaderAtom.CENTER_TITLE_TYPE: return TextPlaceholder.CENTER_TITLE;
+ case TextHeaderAtom.HALF_BODY_TYPE: return TextPlaceholder.HALF_BODY;
+ case TextHeaderAtom.QUARTER_BODY_TYPE: return TextPlaceholder.QUARTER_BODY;
+ }
+ }
+
+
} \ No newline at end of file
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java
index b26e10215f..c601ca04b7 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java
@@ -81,27 +81,27 @@ public final class TestLine {
*/
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 200, 300, 0));
- line.setLineDashing(LineDash.SOLID);
+ line.setLineDash(LineDash.SOLID);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 230, 300, 0));
- line.setLineDashing(LineDash.DASH);
+ line.setLineDash(LineDash.DASH);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 260, 300, 0));
- line.setLineDashing(LineDash.DOT);
+ line.setLineDash(LineDash.DOT);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 290, 300, 0));
- line.setLineDashing(LineDash.DASH_DOT);
+ line.setLineDash(LineDash.DASH_DOT);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 320, 300, 0));
- line.setLineDashing(LineDash.LG_DASH_DOT_DOT);
+ line.setLineDash(LineDash.LG_DASH_DOT_DOT);
slide.addShape(line);
/**
@@ -109,21 +109,21 @@ public final class TestLine {
*/
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 400, 300, 0));
- line.setLineDashing(LineDash.DASH_DOT);
+ line.setLineDash(LineDash.DASH_DOT);
line.setLineCompound(LineCompound.TRIPLE);
line.setLineWidth(5.0);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 430, 300, 0));
- line.setLineDashing(LineDash.DASH);
+ line.setLineDash(LineDash.DASH);
line.setLineCompound(LineCompound.THICK_THIN);
line.setLineWidth(4.0);
slide.addShape(line);
line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 460, 300, 0));
- line.setLineDashing(LineDash.DOT);
+ line.setLineDash(LineDash.DOT);
line.setLineCompound(LineCompound.DOUBLE);
line.setLineWidth(8.0);
slide.addShape(line);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
index f7fe4c43f4..3ce7a71b99 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
@@ -91,7 +91,7 @@ public final class TestShapes {
java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60);
line.setAnchor(lineAnchor);
line.setLineWidth(3);
- line.setLineDashing(LineDash.DASH);
+ line.setLineDash(LineDash.DASH);
line.setLineColor(Color.red);
slide.addShape(line);
@@ -99,7 +99,7 @@ public final class TestShapes {
java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111);
ellipse.setAnchor(ellipseAnchor);
ellipse.setLineWidth(2);
- ellipse.setLineDashing(LineDash.SOLID);
+ ellipse.setLineDash(LineDash.SOLID);
ellipse.setLineColor(Color.green);
ellipse.setFillColor(Color.lightGray);
slide.addShape(ellipse);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
index 8032d2da3e..9b11555b1a 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
@@ -57,15 +57,15 @@ public final class TestTable {
HSLFSlide slide = ppt.createSlide();
- HSLFTable tbl = new HSLFTable(2, 5);
- slide.addShape(tbl);
+ HSLFTable tbl = slide.createTable(2, 5);
HSLFTableCell cell = tbl.getCell(0, 0);
//table cells have type=TextHeaderAtom.OTHER_TYPE, see bug #46033
assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType());
- assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
- HSLFTable tbl2 = (HSLFTable)slide.getShapes().get(0);
+ HSLFShape tblSh = slide.getShapes().get(0);
+ assertTrue(tblSh instanceof HSLFTable);
+ HSLFTable tbl2 = (HSLFTable)tblSh;
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
@@ -89,10 +89,9 @@ public final class TestTable {
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide();
List<HSLFShape> shapes;
- HSLFTable tbl1 = new HSLFTable(1, 5);
+ HSLFTable tbl1 = slide.createTable(1, 5);
assertEquals(5, tbl1.getNumberOfColumns());
assertEquals(1, tbl1.getNumberOfRows());
- slide.addShape(tbl1);
shapes = slide.getShapes();
assertEquals(1, shapes.size());
@@ -106,14 +105,16 @@ public final class TestTable {
@Test
public void testIllegalCOnstruction(){
+ HSLFSlideShow ppt = new HSLFSlideShow();
+ HSLFSlide slide = ppt.createSlide();
try {
- new HSLFTable(0, 5);
+ slide.createTable(0, 5);
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){
}
try {
- new HSLFTable(5, 0);
+ slide.createTable(5, 0);
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java
index 2270cd420f..d32114a7f8 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java
@@ -19,23 +19,50 @@
package org.apache.poi.hslf.usermodel;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.awt.Color;
+import java.awt.Rectangle;
import java.util.List;
import org.apache.poi.POIDataSamples;
+import org.apache.poi.sl.draw.DrawTableShape;
+import org.apache.poi.sl.usermodel.StrokeStyle;
import org.junit.Test;
/**
- * Test that checks numbered list functionality.
- *
- * @author Alex Nikiforov [mailto:anikif@gmail.com]
+ * Table related tests
*/
public class TestTable {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@Test
+ public void moveTable() throws Exception {
+ HSLFSlideShow ppt = new HSLFSlideShow();
+ HSLFSlide slide = ppt.createSlide();
+ int rows = 3, cols = 5;
+ HSLFTable table = slide.createTable(rows, cols);
+ for (int row=0; row<rows; row++) {
+ for (int col=0; col<cols; col++) {
+ HSLFTableCell c = table.getCell(row, col);
+ c.setText("r"+row+"c"+col);
+ }
+ }
+
+ new DrawTableShape(table).setAllBorders(1.0, Color.black, StrokeStyle.LineDash.DASH_DOT);
+
+ table.setAnchor(new Rectangle(100, 100, 400, 400));
+
+ Rectangle rectExp = new Rectangle(420,367,80,133);
+ Rectangle rectAct = table.getCell(rows-1, cols-1).getAnchor();
+ assertEquals(rectExp, rectAct);
+ }
+
+ @Test
public void testTable() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt"));
assertTrue("No Exceptions while reading file", true);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
index 1cbf238de6..f7db8f5a80 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
@@ -571,4 +571,13 @@ public final class TestTextRun {
}
}
+ @Test
+ public void testAppendEmpty() throws IOException {
+ HSLFSlideShow ppt = new HSLFSlideShow();
+ HSLFSlide s = ppt.createSlide();
+ HSLFTextBox title = s.addTitle();
+ title.setText("");
+ title.appendText("\n", true);
+ title.appendText("para", true);
+ }
}