mirror of https://github.com/apache/poi.git
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647740 via svnmerge from
https://svn.apache.org:443/repos/asf/poi/trunk ........ r647712 | yegor | 2008-04-14 10:20:20 +0100 (Mon, 14 Apr 2008) | 1 line use commons logging throughout the code ........ r647713 | yegor | 2008-04-14 10:21:57 +0100 (Mon, 14 Apr 2008) | 1 line misc usermodel improvements. Also added the source code for the ApacheconEU08 FFT presentation ........ r647738 | nick | 2008-04-14 12:47:47 +0100 (Mon, 14 Apr 2008) | 1 line Switch to using our own logger, rather than the commons one ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@647743 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
74de0fb90e
commit
3864fc28f8
|
@ -44,6 +44,7 @@
|
||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">Fix the logger used by POIFSFileSystem, so that commons-logging isn't required when not used</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents</action>
|
<action dev="POI-DEVELOPERS" type="add">Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Improve how POIFS works with directory entries, and update HWPFDocument to support reading an embeded word document</action>
|
<action dev="POI-DEVELOPERS" type="add">Improve how POIFS works with directory entries, and update HWPFDocument to support reading an embeded word document</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Initial support for getting and changing chart and series titles</action>
|
<action dev="POI-DEVELOPERS" type="add">Initial support for getting and changing chart and series titles</action>
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">Fix the logger used by POIFSFileSystem, so that commons-logging isn't required when not used</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents</action>
|
<action dev="POI-DEVELOPERS" type="add">Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Improve how POIFS works with directory entries, and update HWPFDocument to support reading an embeded word document</action>
|
<action dev="POI-DEVELOPERS" type="add">Improve how POIFS works with directory entries, and update HWPFDocument to support reading an embeded word document</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Initial support for getting and changing chart and series titles</action>
|
<action dev="POI-DEVELOPERS" type="add">Initial support for getting and changing chart and series titles</action>
|
||||||
|
|
|
@ -31,8 +31,6 @@ import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.apache.poi.poifs.common.POIFSConstants;
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
import org.apache.poi.poifs.dev.POIFSViewable;
|
import org.apache.poi.poifs.dev.POIFSViewable;
|
||||||
import org.apache.poi.poifs.property.DirectoryProperty;
|
import org.apache.poi.poifs.property.DirectoryProperty;
|
||||||
|
@ -51,6 +49,8 @@ import org.apache.poi.poifs.storage.SmallBlockTableReader;
|
||||||
import org.apache.poi.poifs.storage.SmallBlockTableWriter;
|
import org.apache.poi.poifs.storage.SmallBlockTableWriter;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
import org.apache.poi.util.LongField;
|
import org.apache.poi.util.LongField;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the main class of the POIFS system; it manages the entire
|
* This is the main class of the POIFS system; it manages the entire
|
||||||
|
@ -62,7 +62,8 @@ import org.apache.poi.util.LongField;
|
||||||
public class POIFSFileSystem
|
public class POIFSFileSystem
|
||||||
implements POIFSViewable
|
implements POIFSViewable
|
||||||
{
|
{
|
||||||
private static final Log _logger = LogFactory.getLog(POIFSFileSystem.class);
|
private static final POILogger _logger =
|
||||||
|
POILogFactory.getLogger(POIFSFileSystem.class);
|
||||||
|
|
||||||
private static final class CloseIgnoringInputStream extends InputStream {
|
private static final class CloseIgnoringInputStream extends InputStream {
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ public class POIFSFileSystem
|
||||||
+ "This will be a problem for the caller if the stream will still be used. "
|
+ "This will be a problem for the caller if the stream will still be used. "
|
||||||
+ "If that is the case the caller should wrap the input stream to avoid this close logic. "
|
+ "If that is the case the caller should wrap the input stream to avoid this close logic. "
|
||||||
+ "This warning is only temporary and will not be present in future versions of POI.";
|
+ "This warning is only temporary and will not be present in future versions of POI.";
|
||||||
_logger.warn(msg);
|
_logger.log(POILogger.WARN, msg);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
stream.close();
|
stream.close();
|
||||||
|
|
|
@ -0,0 +1,515 @@
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.examples;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.usermodel.*;
|
||||||
|
import org.apache.poi.hslf.model.*;
|
||||||
|
import org.apache.poi.hslf.record.TextHeaderAtom;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presentation for Fast Feather Track on ApacheconEU 2008
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ApacheconEU08 {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
SlideShow ppt = new SlideShow();
|
||||||
|
ppt.setPageSize(new Dimension(720, 540));
|
||||||
|
|
||||||
|
slide1(ppt);
|
||||||
|
slide2(ppt);
|
||||||
|
slide3(ppt);
|
||||||
|
slide4(ppt);
|
||||||
|
slide5(ppt);
|
||||||
|
slide6(ppt);
|
||||||
|
slide7(ppt);
|
||||||
|
slide8(ppt);
|
||||||
|
slide9(ppt);
|
||||||
|
slide10(ppt);
|
||||||
|
slide11(ppt);
|
||||||
|
slide12(ppt);
|
||||||
|
|
||||||
|
FileOutputStream out = new FileOutputStream("apachecon_eu_08.ppt");
|
||||||
|
ppt.write(out);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide1(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
|
||||||
|
tr1.setText("POI-HSLF");
|
||||||
|
box1.setAnchor(new Rectangle(54, 78, 612, 115));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
|
||||||
|
tr2.setText("Java API To Access Microsoft PowerPoint Format Files");
|
||||||
|
box2.setAnchor(new Rectangle(108, 204, 504, 138));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
TextRun tr3 = box3.getTextRun();
|
||||||
|
tr3.getRichTextRuns()[0].setFontSize(32);
|
||||||
|
box3.setHorizontalAlignment(TextBox.AlignCenter);
|
||||||
|
tr3.setText(
|
||||||
|
"Yegor Kozlov\r" +
|
||||||
|
"yegor - apache - org");
|
||||||
|
box3.setAnchor(new Rectangle(206, 348, 310, 84));
|
||||||
|
slide.addShape(box3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide2(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("What is HSLF?");
|
||||||
|
box1.setAnchor(new Rectangle(36, 21, 648, 90));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " +
|
||||||
|
"of the Powerpoint binary file format. \r" +
|
||||||
|
"POI sub-project since 2005\r" +
|
||||||
|
"Started by Nick Birch, Yegor Kozlov joined soon after");
|
||||||
|
box2.setAnchor(new Rectangle(36, 126, 648, 356));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide3(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("HSLF in a Nutshell");
|
||||||
|
box1.setAnchor(new Rectangle(36, 15, 648, 65));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr2.setText(
|
||||||
|
"HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
|
||||||
|
"Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
|
||||||
|
"Comprehensive support of PowerPoint objects");
|
||||||
|
tr2.getRichTextRuns()[0].setFontSize(28);
|
||||||
|
box2.setAnchor(new Rectangle(36, 80, 648, 200));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
TextRun tr3 = box3.getTextRun();
|
||||||
|
tr3.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr3.setText(
|
||||||
|
"Rich text\r" +
|
||||||
|
"Tables\r" +
|
||||||
|
"Shapes\r" +
|
||||||
|
"Pictures\r" +
|
||||||
|
"Master slides");
|
||||||
|
tr3.getRichTextRuns()[0].setFontSize(24);
|
||||||
|
tr3.getRichTextRuns()[0].setIndentLevel(1);
|
||||||
|
box3.setAnchor(new Rectangle(36, 265, 648, 150));
|
||||||
|
slide.addShape(box3);
|
||||||
|
|
||||||
|
TextBox box4 = new TextBox();
|
||||||
|
TextRun tr4 = box4.getTextRun();
|
||||||
|
tr4.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr4.setText("Access to low level data structures");
|
||||||
|
box4.setAnchor(new Rectangle(36, 430, 648, 50));
|
||||||
|
slide.addShape(box4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide4(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
String[][] txt1 = {
|
||||||
|
{"Note"},
|
||||||
|
{"This presentation was created programmatically using POI HSLF"}
|
||||||
|
};
|
||||||
|
Table table1 = new Table(2, 1);
|
||||||
|
for (int i = 0; i < txt1.length; i++) {
|
||||||
|
for (int j = 0; j < txt1[i].length; j++) {
|
||||||
|
TableCell cell = table1.getCell(i, j);
|
||||||
|
cell.setText(txt1[i][j]);
|
||||||
|
cell.getTextRun().getRichTextRuns()[0].setFontSize(10);
|
||||||
|
RichTextRun rt = cell.getTextRun().getRichTextRuns()[0];
|
||||||
|
rt.setFontName("Arial");
|
||||||
|
rt.setBold(true);
|
||||||
|
if(i == 0){
|
||||||
|
rt.setFontSize(32);
|
||||||
|
rt.setFontColor(Color.white);
|
||||||
|
cell.getFill().setForegroundColor(new Color(0, 153, 204));
|
||||||
|
} else {
|
||||||
|
rt.setFontSize(28);
|
||||||
|
cell.getFill().setForegroundColor(new Color(235, 239, 241));
|
||||||
|
}
|
||||||
|
cell.setVerticalAlignment(TextBox.AnchorMiddle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Line border1 = table1.createBorder();
|
||||||
|
border1.setLineColor(Color.black);
|
||||||
|
border1.setLineWidth(1.0);
|
||||||
|
table1.setAllBorders(border1);
|
||||||
|
|
||||||
|
Line border2 = table1.createBorder();
|
||||||
|
border2.setLineColor(Color.black);
|
||||||
|
border2.setLineWidth(2.0);
|
||||||
|
table1.setOutsideBorders(border2);
|
||||||
|
|
||||||
|
table1.setColumnWidth(0, 510);
|
||||||
|
table1.setRowHeight(0, 60);
|
||||||
|
table1.setRowHeight(1, 100);
|
||||||
|
slide.addShape(table1);
|
||||||
|
|
||||||
|
table1.moveTo(100, 100);
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
box1.setHorizontalAlignment(TextBox.AlignCenter);
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setText("The source code is available at\r" +
|
||||||
|
"http://people.apache.org/~yegor/apachecon_eu08/");
|
||||||
|
RichTextRun rt = tr1.getRichTextRuns()[0];
|
||||||
|
rt.setFontSize(24);
|
||||||
|
box1.setAnchor(new Rectangle(80, 356, 553, 65));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide5(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("HSLF in Action - 1\rData Extraction");
|
||||||
|
box1.setAnchor(new Rectangle(36, 21, 648, 100));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr2.setText(
|
||||||
|
"Text from slides and notes\r" +
|
||||||
|
"Images\r" +
|
||||||
|
"Shapes and their properties (type, position in the slide, color, font, etc.)");
|
||||||
|
box2.setAnchor(new Rectangle(36, 150, 648, 300));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide6(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("HSLF in Action - 2");
|
||||||
|
box1.setAnchor(new Rectangle(36, 20, 648, 90));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.getRichTextRuns()[0].setFontSize(18);
|
||||||
|
tr2.setText("Creating a simple presentation from scratch");
|
||||||
|
box2.setAnchor(new Rectangle(170, 100, 364, 30));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
TextRun tr3 = box3.getTextRun();
|
||||||
|
RichTextRun rt3 = tr3.getRichTextRuns()[0];
|
||||||
|
rt3.setFontName("Courier New");
|
||||||
|
rt3.setFontSize(8);
|
||||||
|
tr3.setText(
|
||||||
|
" SlideShow ppt = new SlideShow();\r" +
|
||||||
|
" Slide slide = ppt.createSlide();\r" +
|
||||||
|
"\r" +
|
||||||
|
" TextBox box2 = new TextBox();\r" +
|
||||||
|
" box2.setHorizontalAlignment(TextBox.AlignCenter);\r" +
|
||||||
|
" box2.setVerticalAlignment(TextBox.AnchorMiddle);\r" +
|
||||||
|
" box2.getTextRun().setText(\"Java Code\");\r" +
|
||||||
|
" box2.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||||
|
" box2.setLineColor(Color.black);\r" +
|
||||||
|
" box2.setLineWidth(0.75);\r" +
|
||||||
|
" box2.setAnchor(new Rectangle(66, 243, 170, 170));\r" +
|
||||||
|
" slide.addShape(box2);\r" +
|
||||||
|
"\r" +
|
||||||
|
" TextBox box3 = new TextBox();\r" +
|
||||||
|
" box3.setHorizontalAlignment(TextBox.AlignCenter);\r" +
|
||||||
|
" box3.setVerticalAlignment(TextBox.AnchorMiddle);\r" +
|
||||||
|
" box3.getTextRun().setText(\"*.ppt file\");\r" +
|
||||||
|
" box3.setLineWidth(0.75);\r" +
|
||||||
|
" box3.setLineColor(Color.black);\r" +
|
||||||
|
" box3.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||||
|
" box3.setAnchor(new Rectangle(473, 243, 170, 170));\r" +
|
||||||
|
" slide.addShape(box3);\r" +
|
||||||
|
"\r" +
|
||||||
|
" AutoShape box4 = new AutoShape(ShapeTypes.Arrow);\r" +
|
||||||
|
" box4.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||||
|
" box4.setLineWidth(0.75);\r" +
|
||||||
|
" box4.setLineColor(Color.black);\r" +
|
||||||
|
" box4.setAnchor(new Rectangle(253, 288, 198, 85));\r" +
|
||||||
|
" slide.addShape(box4);\r" +
|
||||||
|
"\r" +
|
||||||
|
" FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" +
|
||||||
|
" ppt.write(out);\r" +
|
||||||
|
" out.close();");
|
||||||
|
box3.setAnchor(new Rectangle(30, 150, 618, 411));
|
||||||
|
slide.addShape(box3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide7(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
box2.setHorizontalAlignment(TextBox.AlignCenter);
|
||||||
|
box2.setVerticalAlignment(TextBox.AnchorMiddle);
|
||||||
|
box2.getTextRun().setText("Java Code");
|
||||||
|
box2.getFill().setForegroundColor(new Color(187, 224, 227));
|
||||||
|
box2.setLineColor(Color.black);
|
||||||
|
box2.setLineWidth(0.75);
|
||||||
|
box2.setAnchor(new Rectangle(66, 243, 170, 170));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
box3.setHorizontalAlignment(TextBox.AlignCenter);
|
||||||
|
box3.setVerticalAlignment(TextBox.AnchorMiddle);
|
||||||
|
box3.getTextRun().setText("*.ppt file");
|
||||||
|
box3.setLineWidth(0.75);
|
||||||
|
box3.setLineColor(Color.black);
|
||||||
|
box3.getFill().setForegroundColor(new Color(187, 224, 227));
|
||||||
|
box3.setAnchor(new Rectangle(473, 243, 170, 170));
|
||||||
|
slide.addShape(box3);
|
||||||
|
|
||||||
|
AutoShape box4 = new AutoShape(ShapeTypes.Arrow);
|
||||||
|
box4.getFill().setForegroundColor(new Color(187, 224, 227));
|
||||||
|
box4.setLineWidth(0.75);
|
||||||
|
box4.setLineColor(Color.black);
|
||||||
|
box4.setAnchor(new Rectangle(253, 288, 198, 85));
|
||||||
|
slide.addShape(box4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide8(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("Wait, there is more!");
|
||||||
|
box1.setAnchor(new Rectangle(36, 21, 648, 90));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr2.setText(
|
||||||
|
"Rich text\r" +
|
||||||
|
"Tables\r" +
|
||||||
|
"Pictures (JPEG, PNG, BMP, WMF, PICT)\r" +
|
||||||
|
"Comprehensive formatting features");
|
||||||
|
box2.setAnchor(new Rectangle(36, 126, 648, 356));
|
||||||
|
slide.addShape(box2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide9(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("HSLF in Action - 3");
|
||||||
|
box1.setAnchor(new Rectangle(36, 20, 648, 50));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.getRichTextRuns()[0].setFontSize(18);
|
||||||
|
tr2.setText("PPGraphics2D: PowerPoint Graphics2D driver");
|
||||||
|
box2.setAnchor(new Rectangle(178, 70, 387, 30));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
TextRun tr3 = box3.getTextRun();
|
||||||
|
RichTextRun rt3 = tr3.getRichTextRuns()[0];
|
||||||
|
rt3.setFontName("Courier New");
|
||||||
|
rt3.setFontSize(8);
|
||||||
|
tr3.setText(
|
||||||
|
" //bar chart data. The first value is the bar color, the second is the width\r" +
|
||||||
|
" Object[] def = new Object[]{\r" +
|
||||||
|
" Color.yellow, new Integer(100),\r" +
|
||||||
|
" Color.green, new Integer(150),\r" +
|
||||||
|
" Color.gray, new Integer(75),\r" +
|
||||||
|
" Color.red, new Integer(200),\r" +
|
||||||
|
" };\r" +
|
||||||
|
"\r" +
|
||||||
|
" SlideShow ppt = new SlideShow();\r" +
|
||||||
|
" Slide slide = ppt.createSlide();\r" +
|
||||||
|
"\r" +
|
||||||
|
" ShapeGroup group = new ShapeGroup();\r" +
|
||||||
|
" //define position of the drawing in the slide\r" +
|
||||||
|
" Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);\r" +
|
||||||
|
" group.setAnchor(bounds);\r" +
|
||||||
|
" slide.addShape(group);\r" +
|
||||||
|
" Graphics2D graphics = new PPGraphics2D(group);\r" +
|
||||||
|
"\r" +
|
||||||
|
" //draw a simple bar graph\r" +
|
||||||
|
" int x = bounds.x + 50, y = bounds.y + 50;\r" +
|
||||||
|
" graphics.setFont(new Font(\"Arial\", Font.BOLD, 10));\r" +
|
||||||
|
" for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {\r" +
|
||||||
|
" graphics.setColor(Color.black);\r" +
|
||||||
|
" int width = ((Integer)def[i+1]).intValue();\r" +
|
||||||
|
" graphics.drawString(\"Q\" + idx, x-20, y+20);\r" +
|
||||||
|
" graphics.drawString(width + \"%\", x + width + 10, y + 20);\r" +
|
||||||
|
" graphics.setColor((Color)def[i]);\r" +
|
||||||
|
" graphics.fill(new Rectangle(x, y, width, 30));\r" +
|
||||||
|
" y += 40;\r" +
|
||||||
|
" }\r" +
|
||||||
|
" graphics.setColor(Color.black);\r" +
|
||||||
|
" graphics.setFont(new Font(\"Arial\", Font.BOLD, 14));\r" +
|
||||||
|
" graphics.draw(bounds);\r" +
|
||||||
|
" graphics.drawString(\"Performance\", x + 70, y + 40);\r" +
|
||||||
|
"\r" +
|
||||||
|
" FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" +
|
||||||
|
" ppt.write(out);\r" +
|
||||||
|
" out.close();");
|
||||||
|
box3.setAnchor(new Rectangle(96, 110, 499, 378));
|
||||||
|
slide.addShape(box3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide10(SlideShow ppt) throws IOException {
|
||||||
|
//bar chart data. The first value is the bar color, the second is the width
|
||||||
|
Object[] def = new Object[]{
|
||||||
|
Color.yellow, new Integer(100),
|
||||||
|
Color.green, new Integer(150),
|
||||||
|
Color.gray, new Integer(75),
|
||||||
|
Color.red, new Integer(200),
|
||||||
|
};
|
||||||
|
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
ShapeGroup group = new ShapeGroup();
|
||||||
|
//define position of the drawing in the slide
|
||||||
|
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
|
||||||
|
group.setAnchor(bounds);
|
||||||
|
slide.addShape(group);
|
||||||
|
Graphics2D graphics = new PPGraphics2D(group);
|
||||||
|
|
||||||
|
//draw a simple bar graph
|
||||||
|
int x = bounds.x + 50, y = bounds.y + 50;
|
||||||
|
graphics.setFont(new Font("Arial", Font.BOLD, 10));
|
||||||
|
for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {
|
||||||
|
graphics.setColor(Color.black);
|
||||||
|
int width = ((Integer)def[i+1]).intValue();
|
||||||
|
graphics.drawString("Q" + idx, x-20, y+20);
|
||||||
|
graphics.drawString(width + "%", x + width + 10, y + 20);
|
||||||
|
graphics.setColor((Color)def[i]);
|
||||||
|
graphics.fill(new Rectangle(x, y, width, 30));
|
||||||
|
y += 40;
|
||||||
|
}
|
||||||
|
graphics.setColor(Color.black);
|
||||||
|
graphics.setFont(new Font("Arial", Font.BOLD, 14));
|
||||||
|
graphics.draw(bounds);
|
||||||
|
graphics.drawString("Performance", x + 70, y + 40);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide11(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.TITLE_TYPE);
|
||||||
|
tr1.setText("HSLF Development Plans");
|
||||||
|
box1.setAnchor(new Rectangle(36, 21, 648, 90));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr2.setText(
|
||||||
|
"Support for more PowerPoint functionality\r" +
|
||||||
|
"Rendering slides into java.awt.Graphics2D");
|
||||||
|
box2.setAnchor(new Rectangle(36, 126, 648, 100));
|
||||||
|
slide.addShape(box2);
|
||||||
|
|
||||||
|
TextBox box3 = new TextBox();
|
||||||
|
TextRun tr3 = box3.getTextRun();
|
||||||
|
tr3.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr3.getRichTextRuns()[0].setIndentLevel(1);
|
||||||
|
tr3.setText(
|
||||||
|
"A way to export slides into images or other formats");
|
||||||
|
box3.setAnchor(new Rectangle(36, 220, 648, 70));
|
||||||
|
slide.addShape(box3);
|
||||||
|
|
||||||
|
TextBox box4 = new TextBox();
|
||||||
|
TextRun tr4 = box4.getTextRun();
|
||||||
|
tr4.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr4.setText(
|
||||||
|
"Integration with Apache FOP - Formatting Objects Processor");
|
||||||
|
box4.setAnchor(new Rectangle(36, 290, 648, 90));
|
||||||
|
slide.addShape(box4);
|
||||||
|
|
||||||
|
TextBox box5 = new TextBox();
|
||||||
|
TextRun tr5 = box5.getTextRun();
|
||||||
|
tr5.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||||
|
tr5.getRichTextRuns()[0].setIndentLevel(1);
|
||||||
|
tr5.setText(
|
||||||
|
"Transformation of XSL-FO into PPT\r" +
|
||||||
|
"PPT2PDF transcoder");
|
||||||
|
box5.setAnchor(new Rectangle(36, 380, 648, 100));
|
||||||
|
slide.addShape(box5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void slide12(SlideShow ppt) throws IOException {
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox box1 = new TextBox();
|
||||||
|
TextRun tr1 = box1.getTextRun();
|
||||||
|
tr1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE);
|
||||||
|
tr1.setText("Questions?");
|
||||||
|
box1.setAnchor(new Rectangle(54, 167, 612, 115));
|
||||||
|
slide.addShape(box1);
|
||||||
|
|
||||||
|
TextBox box2 = new TextBox();
|
||||||
|
TextRun tr2 = box2.getTextRun();
|
||||||
|
tr2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE);
|
||||||
|
tr2.setText(
|
||||||
|
"http://poi.apache.org/hslf/\r" +
|
||||||
|
"http://people.apache.org/~yegor");
|
||||||
|
box2.setAnchor(new Rectangle(108, 306, 504, 138));
|
||||||
|
slide.addShape(box2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,13 +45,15 @@ import org.apache.poi.hslf.record.Record;
|
||||||
import org.apache.poi.hslf.record.UserEditAtom;
|
import org.apache.poi.hslf.record.UserEditAtom;
|
||||||
import org.apache.poi.hslf.usermodel.ObjectData;
|
import org.apache.poi.hslf.usermodel.ObjectData;
|
||||||
import org.apache.poi.hslf.usermodel.PictureData;
|
import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
|
import org.apache.poi.hslf.model.Shape;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the main functionality for the Powerpoint file
|
* This class contains the main functionality for the Powerpoint file
|
||||||
|
@ -63,7 +65,7 @@ import org.apache.poi.util.POILogger;
|
||||||
public class HSLFSlideShow extends POIDocument
|
public class HSLFSlideShow extends POIDocument
|
||||||
{
|
{
|
||||||
// For logging
|
// For logging
|
||||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
private static final Log logger = LogFactory.getLog(HSLFSlideShow.class);
|
||||||
|
|
||||||
private InputStream istream;
|
private InputStream istream;
|
||||||
|
|
||||||
|
@ -289,7 +291,7 @@ public class HSLFSlideShow extends POIDocument
|
||||||
try {
|
try {
|
||||||
currentUser = new CurrentUserAtom(directory);
|
currentUser = new CurrentUserAtom(directory);
|
||||||
} catch(IOException ie) {
|
} catch(IOException ie) {
|
||||||
logger.log(POILogger.ERROR, "Error finding Current User Atom:\n" + ie);
|
logger.error("Error finding Current User Atom:\n" + ie);
|
||||||
currentUser = new CurrentUserAtom();
|
currentUser = new CurrentUserAtom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,8 +346,8 @@ public class HSLFSlideShow extends POIDocument
|
||||||
|
|
||||||
// If they type (including the bonus 0xF018) is 0, skip it
|
// If they type (including the bonus 0xF018) is 0, skip it
|
||||||
if(type == 0) {
|
if(type == 0) {
|
||||||
logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
|
logger.error("Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
|
||||||
logger.log(POILogger.ERROR, "" + pos);
|
logger.error("" + pos);
|
||||||
} else {
|
} else {
|
||||||
// Copy the data, ready to pass to PictureData
|
// Copy the data, ready to pass to PictureData
|
||||||
byte[] imgdata = new byte[imgsize];
|
byte[] imgdata = new byte[imgsize];
|
||||||
|
@ -360,7 +362,7 @@ public class HSLFSlideShow extends POIDocument
|
||||||
pict.setOffset(offset);
|
pict.setOffset(offset);
|
||||||
p.add(pict);
|
p.add(pict);
|
||||||
} catch(IllegalArgumentException e) {
|
} catch(IllegalArgumentException e) {
|
||||||
logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
|
logger.error("Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ import org.apache.poi.hslf.record.*;
|
||||||
import org.apache.poi.hslf.usermodel.PictureData;
|
import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -36,7 +36,7 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
public class Fill {
|
public class Fill {
|
||||||
// For logging
|
// For logging
|
||||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
protected Log log = LogFactory.getLog(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill with a solid color
|
* Fill with a solid color
|
||||||
|
@ -154,8 +154,7 @@ public class Fill {
|
||||||
public void setForegroundColor(Color color){
|
public void setForegroundColor(Color color){
|
||||||
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
|
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1);
|
Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
|
||||||
Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150010);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
||||||
|
@ -214,7 +213,7 @@ public class Fill {
|
||||||
java.util.List lst = bstore.getChildRecords();
|
java.util.List lst = bstore.getChildRecords();
|
||||||
int idx = p.getPropertyValue();
|
int idx = p.getPropertyValue();
|
||||||
if (idx == 0){
|
if (idx == 0){
|
||||||
logger.log(POILogger.ERROR, "no reference to picture data found ");
|
log.error("no reference to picture data found ");
|
||||||
} else {
|
} else {
|
||||||
EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1);
|
EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1);
|
||||||
for ( int i = 0; i < pict.length; i++ ) {
|
for ( int i = 0; i < pict.length; i++ ) {
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
import java.awt.geom.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A "Freeform" shape.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections
|
||||||
|
* and straight-line segments in the straight sections. This object closely corresponds to <code>java.awt.geom.GeneralPath</code>.
|
||||||
|
* </p>
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class Freeform extends AutoShape {
|
||||||
|
/**
|
||||||
|
* Create a Freeform object and initialize it from the supplied Record container.
|
||||||
|
*
|
||||||
|
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
|
||||||
|
* @param parent the parent of the shape
|
||||||
|
*/
|
||||||
|
protected Freeform(EscherContainerRecord escherRecord, Shape parent){
|
||||||
|
super(escherRecord, parent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Freeform. This constructor is used when a new shape is created.
|
||||||
|
*
|
||||||
|
* @param parent the parent of this Shape. For example, if this text box is a cell
|
||||||
|
* in a table then the parent is Table.
|
||||||
|
*/
|
||||||
|
public Freeform(Shape parent){
|
||||||
|
super(null, parent);
|
||||||
|
_escherContainer = createSpContainer(ShapeTypes.NotPrimitive, parent instanceof ShapeGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Freeform. This constructor is used when a new shape is created.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public Freeform(){
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the shape path
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
|
public void setPath(GeneralPath path)
|
||||||
|
{
|
||||||
|
Rectangle2D bounds = path.getBounds2D();
|
||||||
|
PathIterator it = path.getPathIterator(new AffineTransform());
|
||||||
|
|
||||||
|
ArrayList segInfo = new ArrayList();
|
||||||
|
ArrayList pntInfo = new ArrayList();
|
||||||
|
boolean isClosed = false;
|
||||||
|
while (!it.isDone()) {
|
||||||
|
double[] vals = new double[6];
|
||||||
|
int type = it.currentSegment(vals);
|
||||||
|
switch (type) {
|
||||||
|
case PathIterator.SEG_MOVETO:
|
||||||
|
pntInfo.add(new Point2D.Double(vals[0], vals[1]));
|
||||||
|
segInfo.add(new byte[]{0x00, 0x40});
|
||||||
|
break;
|
||||||
|
case PathIterator.SEG_LINETO:
|
||||||
|
pntInfo.add(new Point2D.Double(vals[0], vals[1]));
|
||||||
|
segInfo.add(new byte[]{0x00, (byte)0xAC});
|
||||||
|
segInfo.add(new byte[]{0x01, 0x00 });
|
||||||
|
break;
|
||||||
|
case PathIterator.SEG_CUBICTO:
|
||||||
|
pntInfo.add(new Point2D.Double(vals[0], vals[1]));
|
||||||
|
pntInfo.add(new Point2D.Double(vals[2], vals[3]));
|
||||||
|
pntInfo.add(new Point2D.Double(vals[4], vals[5]));
|
||||||
|
segInfo.add(new byte[]{0x00, (byte)0xAD});
|
||||||
|
segInfo.add(new byte[]{0x01, 0x20 });
|
||||||
|
break;
|
||||||
|
case PathIterator.SEG_QUADTO:
|
||||||
|
System.err.println("SEG_QUADTO is not supported");
|
||||||
|
break;
|
||||||
|
case PathIterator.SEG_CLOSE:
|
||||||
|
pntInfo.add(pntInfo.get(0));
|
||||||
|
segInfo.add(new byte[]{0x00, (byte)0xAC});
|
||||||
|
segInfo.add(new byte[]{0x01, 0x00 });
|
||||||
|
segInfo.add(new byte[]{0x00, (byte)0xAC});
|
||||||
|
segInfo.add(new byte[]{0x01, (byte)0x60});
|
||||||
|
isClosed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.next();
|
||||||
|
}
|
||||||
|
if(!isClosed) segInfo.add(new byte[]{0x00, (byte)0xAC});
|
||||||
|
segInfo.add(new byte[]{0x00, (byte)0x80});
|
||||||
|
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
|
||||||
|
|
||||||
|
EscherArrayProperty verticesProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__VERTICES + 0x4000), false, null);
|
||||||
|
verticesProp.setNumberOfElementsInArray(pntInfo.size());
|
||||||
|
verticesProp.setNumberOfElementsInMemory(pntInfo.size());
|
||||||
|
verticesProp.setSizeOfElements(0xFFF0);
|
||||||
|
for (int i = 0; i < pntInfo.size(); i++) {
|
||||||
|
Point2D.Double pnt = (Point2D.Double)pntInfo.get(i);
|
||||||
|
byte[] data = new byte[4];
|
||||||
|
LittleEndian.putShort(data, 0, (short)((pnt.getX() - bounds.getX())*MASTER_DPI/POINT_DPI));
|
||||||
|
LittleEndian.putShort(data, 2, (short)((pnt.getY() - bounds.getY())*MASTER_DPI/POINT_DPI));
|
||||||
|
verticesProp.setElement(i, data);
|
||||||
|
}
|
||||||
|
opt.addEscherProperty(verticesProp);
|
||||||
|
|
||||||
|
EscherArrayProperty segmentsProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000), false, null);
|
||||||
|
segmentsProp.setNumberOfElementsInArray(segInfo.size());
|
||||||
|
segmentsProp.setNumberOfElementsInMemory(segInfo.size());
|
||||||
|
segmentsProp.setSizeOfElements(0x2);
|
||||||
|
for (int i = 0; i < segInfo.size(); i++) {
|
||||||
|
byte[] seg = (byte[])segInfo.get(i);
|
||||||
|
segmentsProp.setElement(i, seg);
|
||||||
|
}
|
||||||
|
opt.addEscherProperty(segmentsProp);
|
||||||
|
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, (int)(bounds.getWidth()*MASTER_DPI/POINT_DPI)));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, (int)(bounds.getHeight()*MASTER_DPI/POINT_DPI)));
|
||||||
|
|
||||||
|
opt.sortProperties();
|
||||||
|
|
||||||
|
setAnchor(bounds);
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,11 +53,6 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
private Color background;
|
private Color background;
|
||||||
private RenderingHints hints;
|
private RenderingHints hints;
|
||||||
|
|
||||||
/**
|
|
||||||
* the maximum distance that the line segments used to approximate the curved segments
|
|
||||||
*/
|
|
||||||
public static final float FLATNESS = 0.1f;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct Java Graphics object which translates graphic calls in ppt drawing layer.
|
* Construct Java Graphics object which translates graphic calls in ppt drawing layer.
|
||||||
*
|
*
|
||||||
|
@ -218,29 +213,12 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see #setComposite
|
* @see #setComposite
|
||||||
*/
|
*/
|
||||||
public void draw(Shape shape){
|
public void draw(Shape shape){
|
||||||
|
GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
|
||||||
PathIterator it = shape.getPathIterator(transform, FLATNESS);
|
Freeform p = new Freeform(group);
|
||||||
double[] prev = null;
|
p.setPath(path);
|
||||||
double[] coords = new double[6];
|
p.getFill().setForegroundColor(null);
|
||||||
double[] first = new double[6];
|
applyStroke(p);
|
||||||
if(!it.isDone()) it.currentSegment(first); //first point
|
group.addShape(p);
|
||||||
while(!it.isDone()){
|
|
||||||
int type = it.currentSegment(coords);
|
|
||||||
if (prev != null ){
|
|
||||||
Line line = new Line(group);
|
|
||||||
applyPaint(line);
|
|
||||||
applyStroke(line);
|
|
||||||
if (type == PathIterator.SEG_LINETO) {
|
|
||||||
line.setAnchor(new Rectangle2D.Double(prev[0], prev[1], (coords[0] - prev[0]), (coords[1] - prev[1])));
|
|
||||||
} else if (type == PathIterator.SEG_CLOSE){
|
|
||||||
line.setAnchor(new Rectangle2D.Double(coords[0], coords[1], (first[0] - coords[0]), (first[1] - coords[1])));
|
|
||||||
}
|
|
||||||
group.addShape(line);
|
|
||||||
}
|
|
||||||
prev = new double[]{coords[0], coords[1]};
|
|
||||||
it.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,7 +277,7 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* Even if top and bottom margins are set to 0 PowerPoint
|
* Even if top and bottom margins are set to 0 PowerPoint
|
||||||
* always sets extra space between the text and its bounding box.
|
* always sets extra space between the text and its bounding box.
|
||||||
*
|
*
|
||||||
* Approximation height = ascent*2 works good enough in most cases
|
* The approximation height = ascent*2 works good enough in most cases
|
||||||
*/
|
*/
|
||||||
float height = ascent * 2;
|
float height = ascent * 2;
|
||||||
|
|
||||||
|
@ -335,29 +313,13 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see #setClip
|
* @see #setClip
|
||||||
*/
|
*/
|
||||||
public void fill(Shape shape){
|
public void fill(Shape shape){
|
||||||
PathIterator it = shape.getPathIterator(transform, FLATNESS);
|
GeneralPath path = new GeneralPath(transform.createTransformedShape(shape));
|
||||||
ArrayList pnt = new ArrayList();
|
Freeform p = new Freeform(group);
|
||||||
double[] coords = new double[6];
|
p.setPath(path);
|
||||||
while(!it.isDone()){
|
|
||||||
int type = it.currentSegment(coords);
|
|
||||||
if (type != PathIterator.SEG_CLOSE) {
|
|
||||||
pnt.add(new Point2D.Double(coords[0], coords[1]));
|
|
||||||
}
|
|
||||||
it.next();
|
|
||||||
}
|
|
||||||
if(pnt.size() > 0){
|
|
||||||
Point2D[] points = (Point2D[])pnt.toArray(new Point2D[pnt.size()]);
|
|
||||||
Polygon p = new Polygon(group);
|
|
||||||
p.setPoints(points);
|
|
||||||
applyPaint(p);
|
applyPaint(p);
|
||||||
|
|
||||||
p.setLineColor(null); //Fills must be "No Line"
|
p.setLineColor(null); //Fills must be "No Line"
|
||||||
|
|
||||||
Rectangle2D bounds = transform.createTransformedShape(shape).getBounds2D();
|
|
||||||
p.setAnchor(bounds);
|
|
||||||
group.addShape(p);
|
group.addShape(p);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates the origin of the graphics context to the point
|
* Translates the origin of the graphics context to the point
|
||||||
|
@ -459,11 +421,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void drawRoundRect(int x, int y, int width, int height,
|
public void drawRoundRect(int x, int y, int width, int height,
|
||||||
int arcWidth, int arcHeight){
|
int arcWidth, int arcHeight){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group);
|
RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
|
||||||
shape.setFillColor(null);
|
draw(rect);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -493,11 +452,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see java.awt.Graphics#drawOval
|
* @see java.awt.Graphics#drawOval
|
||||||
*/
|
*/
|
||||||
public void fillOval(int x, int y, int width, int height){
|
public void fillOval(int x, int y, int width, int height){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group);
|
Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
|
||||||
applyPaint(shape);
|
fill(oval);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -518,11 +474,9 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void fillRoundRect(int x, int y, int width, int height,
|
public void fillRoundRect(int x, int y, int width, int height,
|
||||||
int arcWidth, int arcHeight){
|
int arcWidth, int arcHeight){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.RoundRectangle, group);
|
|
||||||
applyPaint(shape);
|
RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
|
||||||
applyStroke(shape);
|
fill(rect);
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -563,11 +517,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void fillArc(int x, int y, int width, int height,
|
public void fillArc(int x, int y, int width, int height,
|
||||||
int startAngle, int arcAngle){
|
int startAngle, int arcAngle){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Arc, group);
|
Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
|
||||||
applyPaint(shape);
|
fill(arc);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -609,11 +560,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void drawArc(int x, int y, int width, int height,
|
public void drawArc(int x, int y, int width, int height,
|
||||||
int startAngle, int arcAngle) {
|
int startAngle, int arcAngle) {
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Arc, group);
|
Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
|
||||||
shape.setFillColor(null);
|
draw(arc);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -659,11 +607,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see java.awt.Graphics#fillOval
|
* @see java.awt.Graphics#fillOval
|
||||||
*/
|
*/
|
||||||
public void drawOval(int x, int y, int width, int height){
|
public void drawOval(int x, int y, int width, int height){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Ellipse, group);
|
Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
|
||||||
shape.setFillColor(null);
|
draw(oval);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -998,11 +943,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see java.awt.Graphics#drawRect
|
* @see java.awt.Graphics#drawRect
|
||||||
*/
|
*/
|
||||||
public void fillRect(int x, int y, int width, int height){
|
public void fillRect(int x, int y, int width, int height){
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group);
|
Rectangle rect = new Rectangle(x, y, width, height);
|
||||||
applyPaint(shape);
|
fill(rect);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1022,12 +964,8 @@ public class PPGraphics2D extends Graphics2D implements Cloneable {
|
||||||
* @see java.awt.Graphics#clearRect
|
* @see java.awt.Graphics#clearRect
|
||||||
*/
|
*/
|
||||||
public void drawRect(int x, int y, int width, int height) {
|
public void drawRect(int x, int y, int width, int height) {
|
||||||
AutoShape shape = new AutoShape(ShapeTypes.Rectangle, group);
|
Rectangle rect = new Rectangle(x, y, width, height);
|
||||||
shape.setFillColor(null);
|
draw(rect);
|
||||||
applyStroke(shape);
|
|
||||||
shape.setAnchor(new Rectangle2D.Double(x, y, width, height));
|
|
||||||
group.addShape(shape);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,6 @@ import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
import org.apache.poi.hslf.record.Document;
|
import org.apache.poi.hslf.record.Document;
|
||||||
import org.apache.poi.hslf.blip.Bitmap;
|
import org.apache.poi.hslf.blip.Bitmap;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
@ -179,7 +178,7 @@ public class Picture extends SimpleShape {
|
||||||
List lst = bstore.getChildRecords();
|
List lst = bstore.getChildRecords();
|
||||||
int idx = getPictureIndex();
|
int idx = getPictureIndex();
|
||||||
if (idx == 0){
|
if (idx == 0){
|
||||||
logger.log(POILogger.ERROR, "no reference to picture data found ");
|
log.error("no reference to picture data found ");
|
||||||
} else {
|
} else {
|
||||||
EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
|
EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
|
||||||
for ( int i = 0; i < pict.length; i++ ) {
|
for ( int i = 0; i < pict.length; i++ ) {
|
||||||
|
@ -187,7 +186,7 @@ public class Picture extends SimpleShape {
|
||||||
return pict[i];
|
return pict[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.log(POILogger.ERROR, "no picture found for our BSE offset " + bse.getOffset());
|
log.error("no picture found for our BSE offset " + bse.getOffset());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ package org.apache.poi.hslf.model;
|
||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hslf.model.ShapeTypes;
|
import org.apache.poi.hslf.model.ShapeTypes;
|
||||||
import org.apache.poi.hslf.record.ColorSchemeAtom;
|
import org.apache.poi.hslf.record.ColorSchemeAtom;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -45,7 +45,7 @@ import java.awt.geom.Rectangle2D;
|
||||||
public abstract class Shape {
|
public abstract class Shape {
|
||||||
|
|
||||||
// For logging
|
// For logging
|
||||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
protected Log log = LogFactory.getLog(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In Escher absolute distances are specified in
|
* In Escher absolute distances are specified in
|
||||||
|
@ -89,6 +89,11 @@ public abstract class Shape {
|
||||||
*/
|
*/
|
||||||
protected Sheet _sheet;
|
protected Sheet _sheet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill
|
||||||
|
*/
|
||||||
|
protected Fill _fill;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
|
* Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
|
||||||
*
|
*
|
||||||
|
@ -344,7 +349,8 @@ public abstract class Shape {
|
||||||
* @return fill properties of this shape
|
* @return fill properties of this shape
|
||||||
*/
|
*/
|
||||||
public Fill getFill(){
|
public Fill getFill(){
|
||||||
return new Fill(this);
|
if(_fill == null) _fill = new Fill(this);
|
||||||
|
return _fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -71,7 +70,7 @@ public class ShapeGroup extends Shape{
|
||||||
} else {
|
} else {
|
||||||
// Should we do anything special with these non
|
// Should we do anything special with these non
|
||||||
// Container records?
|
// Container records?
|
||||||
logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName());
|
log.error("Shape contained non container escher record, was " + r.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,26 +187,7 @@ public class SimpleShape extends Shape {
|
||||||
* The color used to fill this shape.
|
* The color used to fill this shape.
|
||||||
*/
|
*/
|
||||||
public Color getFillColor(){
|
public Color getFillColor(){
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
return getFill().getForegroundColor();
|
||||||
EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR);
|
|
||||||
EscherSimpleProperty p2= (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
|
|
||||||
|
|
||||||
int p2val = p2 == null ? 0 : p2.getPropertyValue();
|
|
||||||
|
|
||||||
Color clr = null;
|
|
||||||
if (p1 != null && (p2val & 0x10) != 0){
|
|
||||||
int rgb = p1.getPropertyValue();
|
|
||||||
if (rgb >= 0x8000000) {
|
|
||||||
int idx = rgb % 0x8000000;
|
|
||||||
if(getSheet() != null) {
|
|
||||||
ColorSchemeAtom ca = getSheet().getColorScheme();
|
|
||||||
rgb = ca.getColor(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Color tmp = new Color(rgb, true);
|
|
||||||
clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
|
|
||||||
}
|
|
||||||
return clr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,14 +196,7 @@ public class SimpleShape extends Shape {
|
||||||
* @param color the background color
|
* @param color the background color
|
||||||
*/
|
*/
|
||||||
public void setFillColor(Color color){
|
public void setFillColor(Color color){
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
getFill().setForegroundColor(color);
|
||||||
if(color == null) {
|
|
||||||
setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
|
|
||||||
} else {
|
|
||||||
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
|
||||||
setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
|
|
||||||
setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hslf.record.*;
|
import org.apache.poi.hslf.record.*;
|
||||||
import org.apache.poi.hslf.usermodel.RichTextRun;
|
import org.apache.poi.hslf.usermodel.RichTextRun;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.font.FontRenderContext;
|
import java.awt.font.FontRenderContext;
|
||||||
|
@ -480,7 +479,7 @@ public class TextBox extends SimpleShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(_txtrun == null) {
|
if(_txtrun == null) {
|
||||||
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
|
log.warn("text run not found for OutlineTextRefAtom.TextIndex=" + idx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
|
int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
package org.apache.poi.hslf.record;
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
@ -134,10 +132,10 @@ public class Document extends PositionDependentRecordContainer
|
||||||
// (normally it's 2, or 3 if you have notes)
|
// (normally it's 2, or 3 if you have notes)
|
||||||
// Complain if it's not
|
// Complain if it's not
|
||||||
if(slwtcount == 0) {
|
if(slwtcount == 0) {
|
||||||
logger.log(POILogger.WARN, "No SlideListWithText's found - there should normally be at least one!");
|
logger.warn("No SlideListWithText's found - there should normally be at least one!");
|
||||||
}
|
}
|
||||||
if(slwtcount > 3) {
|
if(slwtcount > 3) {
|
||||||
logger.log(POILogger.WARN, "Found " + slwtcount + " SlideListWithTexts - normally there should only be three!");
|
logger.warn("Found " + slwtcount + " SlideListWithTexts - normally there should only be three!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now grab all the SLWTs
|
// Now grab all the SLWTs
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.io.OutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This data represents an embedded object in the document.
|
* This data represents an embedded object in the document.
|
||||||
|
@ -94,14 +93,14 @@ public class ExEmbed extends RecordContainer {
|
||||||
if(_children[0] instanceof ExEmbedAtom) {
|
if(_children[0] instanceof ExEmbedAtom) {
|
||||||
embedAtom = (ExEmbedAtom)_children[0];
|
embedAtom = (ExEmbedAtom)_children[0];
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
|
logger.error("First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second child should be the ExOleObjAtom
|
// Second child should be the ExOleObjAtom
|
||||||
if (_children[1] instanceof ExOleObjAtom) {
|
if (_children[1] instanceof ExOleObjAtom) {
|
||||||
oleObjAtom = (ExOleObjAtom)_children[1];
|
oleObjAtom = (ExOleObjAtom)_children[1];
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "Second child record wasn't a ExOleObjAtom, was of type " + _children[1].getRecordType());
|
logger.error("Second child record wasn't a ExOleObjAtom, was of type " + _children[1].getRecordType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 2; i < _children.length; i++) {
|
for (int i = 2; i < _children.length; i++) {
|
||||||
|
@ -110,15 +109,15 @@ public class ExEmbed extends RecordContainer {
|
||||||
else if (progId == null) progId = (CString)_children[i];
|
else if (progId == null) progId = (CString)_children[i];
|
||||||
else if (clipboardName == null) clipboardName = (CString)_children[i];
|
else if (clipboardName == null) clipboardName = (CString)_children[i];
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "Record after atoms wasn't a CString, was of type " + _children[i].getRecordType());
|
logger.error("Record after atoms wasn't a CString, was of type " + _children[i].getRecordType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@code ExEmbedAtom}.
|
* Gets the {@link ExEmbedAtom}.
|
||||||
*
|
*
|
||||||
* @return the {@code ExEmbedAtom}.
|
* @return the {@link ExEmbedAtom}.
|
||||||
*/
|
*/
|
||||||
public ExEmbedAtom getExEmbedAtom()
|
public ExEmbedAtom getExEmbedAtom()
|
||||||
{
|
{
|
||||||
|
@ -126,9 +125,9 @@ public class ExEmbed extends RecordContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@code ExOleObjAtom}.
|
* Gets the {@link ExOleObjAtom}.
|
||||||
*
|
*
|
||||||
* @return the {@code ExOleObjAtom}.
|
* @return the {@link ExOleObjAtom}.
|
||||||
*/
|
*/
|
||||||
public ExOleObjAtom getExOleObjAtom()
|
public ExOleObjAtom getExOleObjAtom()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents the data of a link in the document.
|
* This class represents the data of a link in the document.
|
||||||
|
@ -108,7 +107,7 @@ public class ExHyperlink extends RecordContainer {
|
||||||
if(_children[0] instanceof ExHyperlinkAtom) {
|
if(_children[0] instanceof ExHyperlinkAtom) {
|
||||||
linkAtom = (ExHyperlinkAtom)_children[0];
|
linkAtom = (ExHyperlinkAtom)_children[0];
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "First child record wasn't a ExHyperlinkAtom, was of type " + _children[0].getRecordType());
|
logger.error("First child record wasn't a ExHyperlinkAtom, was of type " + _children[0].getRecordType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < _children.length; i++) {
|
for (int i = 1; i < _children.length; i++) {
|
||||||
|
@ -116,7 +115,7 @@ public class ExHyperlink extends RecordContainer {
|
||||||
if ( linkDetailsA == null) linkDetailsA = (CString)_children[i];
|
if ( linkDetailsA == null) linkDetailsA = (CString)_children[i];
|
||||||
else linkDetailsB = (CString)_children[i];
|
else linkDetailsB = (CString)_children[i];
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "Record after ExHyperlinkAtom wasn't a CString, was of type " + _children[1].getRecordType());
|
logger.error("Record after ExHyperlinkAtom wasn't a CString, was of type " + _children[1].getRecordType());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
package org.apache.poi.hslf.record;
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -49,7 +46,7 @@ public class FontCollection extends RecordContainer {
|
||||||
FontEntityAtom atom = (FontEntityAtom)_children[i];
|
FontEntityAtom atom = (FontEntityAtom)_children[i];
|
||||||
fonts.add(atom.getFontName());
|
fonts.add(atom.getFontName());
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.WARN, "Warning: FontCollection child wasn't a FontEntityAtom, was " + _children[i]);
|
logger.warn("Warning: FontCollection child wasn't a FontEntityAtom, was " + _children[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.apache.poi.hslf.record;
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hslf.model.ShapeTypes;
|
import org.apache.poi.hslf.model.ShapeTypes;
|
||||||
|
@ -132,7 +131,7 @@ public class PPDrawing extends RecordAtom
|
||||||
// Wind on
|
// Wind on
|
||||||
int size = r.getRecordSize();
|
int size = r.getRecordSize();
|
||||||
if(size < 8) {
|
if(size < 8) {
|
||||||
logger.log(POILogger.WARN, "Hit short DDF record at " + startPos + " - " + size);
|
logger.warn("Hit short DDF record at " + startPos + " - " + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,7 +141,7 @@ public class PPDrawing extends RecordAtom
|
||||||
* Sometimes it is not so, see an example in bug #44770. Most likely reason is that one of ddf records calculates wrong size.
|
* Sometimes it is not so, see an example in bug #44770. Most likely reason is that one of ddf records calculates wrong size.
|
||||||
*/
|
*/
|
||||||
if(size != escherBytes){
|
if(size != escherBytes){
|
||||||
logger.log(POILogger.WARN, "Record length=" + escherBytes + " but getRecordSize() returned " + r.getRecordSize() + "; record: " + r.getClass());
|
logger.warn("Record length=" + escherBytes + " but getRecordSize() returned " + r.getRecordSize() + "; record: " + r.getClass());
|
||||||
size = escherBytes;
|
size = escherBytes;
|
||||||
}
|
}
|
||||||
startPos += size;
|
startPos += size;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.apache.poi.hslf.record;
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -195,8 +194,8 @@ public class PersistPtrHolder extends PositionDependentRecordAtom
|
||||||
Integer newPos = (Integer)oldToNewReferencesLookup.get(oldPos);
|
Integer newPos = (Integer)oldToNewReferencesLookup.get(oldPos);
|
||||||
|
|
||||||
if(newPos == null) {
|
if(newPos == null) {
|
||||||
logger.log(POILogger.WARN, "Couldn't find the new location of the \"slide\" with id " + id + " that used to be at " + oldPos);
|
logger.warn("Couldn't find the new location of the \"slide\" with id " + id + " that used to be at " + oldPos);
|
||||||
logger.log(POILogger.WARN, "Not updating the position of it, you probably won't be able to find it any more (if you ever could!)");
|
logger.warn("Not updating the position of it, you probably won't be able to find it any more (if you ever could!)");
|
||||||
newPos = oldPos;
|
newPos = oldPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
import org.apache.poi.util.POILogFactory;
|
|
||||||
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +40,7 @@ import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
||||||
public abstract class Record
|
public abstract class Record
|
||||||
{
|
{
|
||||||
// For logging
|
// For logging
|
||||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
protected Log logger = LogFactory.getLog(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this record type an Atom record (only has data),
|
* Is this record type an Atom record (only has data),
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
|
||||||
import org.apache.poi.hslf.model.textproperties.TextProp;
|
import org.apache.poi.hslf.model.textproperties.TextProp;
|
||||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A StyleTextPropAtom (type 4001). Holds basic character properties
|
* A StyleTextPropAtom (type 4001). Holds basic character properties
|
||||||
|
@ -293,7 +292,7 @@ public class StyleTextPropAtom extends RecordAtom
|
||||||
|
|
||||||
}
|
}
|
||||||
if (rawContents.length > 0 && textHandled != (size+1)){
|
if (rawContents.length > 0 && textHandled != (size+1)){
|
||||||
logger.log(POILogger.WARN, "Problem reading paragraph style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1));
|
logger.warn("Problem reading paragraph style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now do the character stylings
|
// Now do the character stylings
|
||||||
|
@ -328,7 +327,7 @@ public class StyleTextPropAtom extends RecordAtom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rawContents.length > 0 && textHandled != (size+1)){
|
if (rawContents.length > 0 && textHandled != (size+1)){
|
||||||
logger.log(POILogger.WARN, "Problem reading character style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1));
|
logger.warn("Problem reading character style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle anything left over
|
// Handle anything left over
|
||||||
|
|
|
@ -37,8 +37,8 @@ import org.apache.poi.hslf.record.*;
|
||||||
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
import org.apache.poi.util.ArrayUtil;
|
import org.apache.poi.util.ArrayUtil;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a friendly wrapper on top of the more scary HSLFSlideShow.
|
* This class is a friendly wrapper on top of the more scary HSLFSlideShow.
|
||||||
|
@ -80,7 +80,7 @@ public class SlideShow
|
||||||
private FontCollection _fonts;
|
private FontCollection _fonts;
|
||||||
|
|
||||||
// For logging
|
// For logging
|
||||||
private POILogger logger = POILogFactory.getLogger(this.getClass());
|
private static final Log logger = LogFactory.getLog(SlideShow.class);
|
||||||
|
|
||||||
|
|
||||||
/* ===============================================================
|
/* ===============================================================
|
||||||
|
@ -275,7 +275,7 @@ public class SlideShow
|
||||||
Record r = _mostRecentCoreRecords[coreRecordId.intValue()];
|
Record r = _mostRecentCoreRecords[coreRecordId.intValue()];
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "We tried to look up a reference to a core record, but there was no core ID for reference ID " + refID);
|
logger.error("We tried to look up a reference to a core record, but there was no core ID for reference ID " + refID);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ public class SlideShow
|
||||||
Integer slideId = new Integer(spa.getSlideIdentifier());
|
Integer slideId = new Integer(spa.getSlideIdentifier());
|
||||||
slideIdToNotes.put(slideId, new Integer(i));
|
slideIdToNotes.put(slideId, new Integer(i));
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "A Notes SlideAtomSet at " + i + " said its record was at refID " + notesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
|
logger.error("A Notes SlideAtomSet at " + i + " said its record was at refID " + notesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notesRecords = new org.apache.poi.hslf.record.Notes[notesRecordsL.size()];
|
notesRecords = new org.apache.poi.hslf.record.Notes[notesRecordsL.size()];
|
||||||
|
@ -404,7 +404,7 @@ public class SlideShow
|
||||||
if(r instanceof org.apache.poi.hslf.record.Slide) {
|
if(r instanceof org.apache.poi.hslf.record.Slide) {
|
||||||
slidesRecords[i] = (org.apache.poi.hslf.record.Slide)r;
|
slidesRecords[i] = (org.apache.poi.hslf.record.Slide)r;
|
||||||
} else {
|
} else {
|
||||||
logger.log(POILogger.ERROR, "A Slide SlideAtomSet at " + i + " said its record was at refID " + slidesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
|
logger.error("A Slide SlideAtomSet at " + i + " said its record was at refID " + slidesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ public class SlideShow
|
||||||
if (noteId != 0){
|
if (noteId != 0){
|
||||||
Integer notesPos = (Integer)slideIdToNotes.get(new Integer(noteId));
|
Integer notesPos = (Integer)slideIdToNotes.get(new Integer(noteId));
|
||||||
if (notesPos != null) notes = _notes[notesPos.intValue()];
|
if (notesPos != null) notes = _notes[notesPos.intValue()];
|
||||||
else logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId);
|
else logger.error("Notes not found for noteId=" + noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, build our slide
|
// Now, build our slide
|
||||||
|
@ -622,7 +622,7 @@ public class SlideShow
|
||||||
System.arraycopy(_slides, 0, s, 0, _slides.length);
|
System.arraycopy(_slides, 0, s, 0, _slides.length);
|
||||||
s[_slides.length] = slide;
|
s[_slides.length] = slide;
|
||||||
_slides = s;
|
_slides = s;
|
||||||
logger.log(POILogger.INFO, "Added slide " + _slides.length + " with ref " + sp.getRefID() + " and identifier " + sp.getSlideIdentifier());
|
logger.info("Added slide " + _slides.length + " with ref " + sp.getRefID() + " and identifier " + sp.getSlideIdentifier());
|
||||||
|
|
||||||
// Add the core records for this new Slide to the record tree
|
// Add the core records for this new Slide to the record tree
|
||||||
org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
|
org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
|
||||||
|
@ -658,7 +658,7 @@ public class SlideShow
|
||||||
// (Also need to tell it where it is)
|
// (Also need to tell it where it is)
|
||||||
slideRecord.setLastOnDiskOffset(slideOffset);
|
slideRecord.setLastOnDiskOffset(slideOffset);
|
||||||
ptr.addSlideLookup(sp.getRefID(), slideOffset);
|
ptr.addSlideLookup(sp.getRefID(), slideOffset);
|
||||||
logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
|
logger.info("New slide ended up at " + slideOffset);
|
||||||
|
|
||||||
// Last view is now of the slide
|
// Last view is now of the slide
|
||||||
usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
|
usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class TestPPGraphics2D extends TestCase {
|
||||||
|
|
||||||
group = (ShapeGroup)shape[0];
|
group = (ShapeGroup)shape[0];
|
||||||
shape = group.getShapes();
|
shape = group.getShapes();
|
||||||
assertEquals(shape.length, 7);
|
assertEquals(shape.length, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue