Fixed TextRun handling and various junit tests
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1684773 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d1f9035400
commit
4acc6a84a1
@ -146,10 +146,10 @@ public final class ApacheconEU08 {
|
||||
{"Note"},
|
||||
{"This presentation was created programmatically using POI HSLF"}
|
||||
};
|
||||
Table table1 = new Table(2, 1);
|
||||
HSLFTable table1 = new HSLFTable(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);
|
||||
HSLFTableCell cell = table1.getCell(i, j);
|
||||
cell.setText(txt1[i][j]);
|
||||
HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
|
||||
rt.setFontSize(10);
|
||||
|
@ -50,7 +50,7 @@ public final class Graphics2DDemo {
|
||||
//define position of the drawing in the slide
|
||||
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
|
||||
group.setAnchor(bounds);
|
||||
group.setCoordinates(new java.awt.Rectangle(0, 0, 100, 100));
|
||||
group.setInteriorAnchor(new java.awt.Rectangle(0, 0, 100, 100));
|
||||
slide.addShape(group);
|
||||
Graphics2D graphics = new PPGraphics2D(group);
|
||||
|
||||
@ -68,7 +68,7 @@ public final class Graphics2DDemo {
|
||||
}
|
||||
graphics.setColor(Color.black);
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, 14));
|
||||
graphics.draw(group.getCoordinates());
|
||||
graphics.draw(group.getInteriorAnchor());
|
||||
graphics.drawString("Performance", x + 30, y + 10);
|
||||
|
||||
FileOutputStream out = new FileOutputStream("hslf-graphics.ppt");
|
||||
|
@ -49,10 +49,10 @@ public final class TableDemo {
|
||||
HSLFSlide slide = ppt.createSlide();
|
||||
|
||||
//six rows, two columns
|
||||
Table table1 = new Table(6, 2);
|
||||
HSLFTable table1 = new HSLFTable(6, 2);
|
||||
for (int i = 0; i < txt1.length; i++) {
|
||||
for (int j = 0; j < txt1[i].length; j++) {
|
||||
TableCell cell = table1.getCell(i, j);
|
||||
HSLFTableCell cell = table1.getCell(i, j);
|
||||
HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
|
||||
rt.setFontFamily("Arial");
|
||||
rt.setFontSize(10);
|
||||
@ -88,10 +88,10 @@ public final class TableDemo {
|
||||
};
|
||||
|
||||
//two rows, one column
|
||||
Table table2 = new Table(2, 1);
|
||||
HSLFTable table2 = new HSLFTable(2, 1);
|
||||
for (int i = 0; i < txt2.length; i++) {
|
||||
for (int j = 0; j < txt2[i].length; j++) {
|
||||
TableCell cell = table2.getCell(i, j);
|
||||
HSLFTableCell cell = table2.getCell(i, j);
|
||||
HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
|
||||
rt.setFontSize(10);
|
||||
rt.setFontFamily("Arial");
|
||||
|
@ -40,13 +40,26 @@ public class EscherChildAnchorRecord
|
||||
private int field_4_dy2;
|
||||
|
||||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
/*int bytesRemaining =*/ readHeader( data, offset );
|
||||
int bytesRemaining = readHeader( data, offset );
|
||||
int pos = offset + 8;
|
||||
int size = 0;
|
||||
field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_2_dy1 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_4_dy2 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
switch (bytesRemaining) {
|
||||
case 16: // RectStruct
|
||||
field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_2_dy1 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
field_4_dy2 = LittleEndian.getInt( data, pos + size );size+=4;
|
||||
break;
|
||||
case 8: // SmallRectStruct
|
||||
field_1_dx1 = LittleEndian.getShort( data, pos + size );size+=2;
|
||||
field_2_dy1 = LittleEndian.getShort( data, pos + size );size+=2;
|
||||
field_3_dx2 = LittleEndian.getShort( data, pos + size );size+=2;
|
||||
field_4_dy2 = LittleEndian.getShort( data, pos + size );size+=2;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Invalid EscherChildAnchorRecord - neither 8 nor 16 bytes.");
|
||||
}
|
||||
|
||||
return 8 + size;
|
||||
}
|
||||
|
||||
@ -58,8 +71,8 @@ public class EscherChildAnchorRecord
|
||||
LittleEndian.putInt( data, pos, getRecordSize()-8 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_1_dx1 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_2_dy1 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_3_dx2 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_4_dy2 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_3_dx2 ); pos += 4;
|
||||
LittleEndian.putInt( data, pos, field_4_dy2 ); pos += 4;
|
||||
|
||||
listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this );
|
||||
return pos - offset;
|
||||
|
@ -507,7 +507,7 @@ public final class EscherProperties {
|
||||
addProp(m, SHADOWSTYLE__ORIGINX, "shadowstyle.originx");
|
||||
addProp(m, SHADOWSTYLE__ORIGINY, "shadowstyle.originy");
|
||||
addProp(m, SHADOWSTYLE__SHADOW, "shadowstyle.shadow");
|
||||
addProp(m, SHADOWSTYLE__SHADOWOBSURED, "shadowstyle.shadowobsured");
|
||||
addProp(m, SHADOWSTYLE__SHADOWOBSURED, "shadowstyle.shadowobscured");
|
||||
addProp(m, PERSPECTIVE__TYPE, "perspective.type");
|
||||
addProp(m, PERSPECTIVE__OFFSETX, "perspective.offsetx");
|
||||
addProp(m, PERSPECTIVE__OFFSETY, "perspective.offsety");
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.poi.ddf;
|
||||
|
||||
import org.apache.poi.hslf.record.RecordTypes;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
@ -32,7 +33,7 @@ import org.apache.poi.util.RecordFormatException;
|
||||
*/
|
||||
public class EscherTextboxRecord extends EscherRecord
|
||||
{
|
||||
public static final short RECORD_ID = (short)0xF00D;
|
||||
public static final short RECORD_ID = (short)RecordTypes.EscherClientTextbox;
|
||||
public static final String RECORD_DESCRIPTION = "msofbtClientTextbox";
|
||||
|
||||
private static final byte[] NO_BYTES = new byte[0];
|
||||
|
@ -28,6 +28,7 @@ import java.awt.image.ImageObserver;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.renderable.RenderableImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class DummyGraphics2d
|
||||
@ -262,7 +263,7 @@ public class DummyGraphics2d
|
||||
|
||||
public void setPaint( Paint paint )
|
||||
{
|
||||
System.out.println( "setPain(Paint):" );
|
||||
System.out.println( "setPaint(Paint):" );
|
||||
System.out.println( "paint = " + paint );
|
||||
g2D.setPaint( paint );
|
||||
}
|
||||
@ -285,7 +286,19 @@ public class DummyGraphics2d
|
||||
public void setStroke(Stroke s)
|
||||
{
|
||||
System.out.println( "setStroke(Stoke):" );
|
||||
System.out.println( "s = " + s );
|
||||
if (s instanceof BasicStroke) {
|
||||
BasicStroke bs = (BasicStroke)s;
|
||||
StringBuilder str = new StringBuilder("s = BasicStroke(");
|
||||
str.append("dash[]: "+Arrays.toString(bs.getDashArray())+", ");
|
||||
str.append("dashPhase: "+bs.getDashPhase()+", ");
|
||||
str.append("endCap: "+bs.getEndCap()+", ");
|
||||
str.append("lineJoin: "+bs.getLineJoin()+", ");
|
||||
str.append("width: "+bs.getLineWidth()+", ");
|
||||
str.append("miterLimit: "+bs.getMiterLimit()+")");
|
||||
System.out.println(str.toString());
|
||||
} else {
|
||||
System.out.println( "s = " + s );
|
||||
}
|
||||
g2D.setStroke( s );
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,7 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.*;
|
||||
import org.apache.poi.sl.usermodel.PlaceableShape;
|
||||
import org.apache.poi.sl.usermodel.ShapeGroup;
|
||||
import org.apache.poi.sl.usermodel.GroupShape;
|
||||
import org.apache.poi.util.*;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.*;
|
||||
@ -38,7 +37,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.*;
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
@Beta
|
||||
public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, ShapeGroup<XSLFShape> {
|
||||
public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, GroupShape<XSLFShape> {
|
||||
private static POILogger _logger = POILogFactory.getLogger(XSLFGroupShape.class);
|
||||
|
||||
private final List<XSLFShape> _shapes;
|
||||
@ -118,7 +117,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, Sha
|
||||
* used for calculations of grouping, scaling, and rotation
|
||||
* behavior of shapes placed within a group.
|
||||
*/
|
||||
public void setInteriorAnchor(Rectangle2D anchor){
|
||||
public void setInteriorAnchor(Rectangle2D anchor) {
|
||||
CTGroupTransform2D xfrm = getSafeXfrm();
|
||||
CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff();
|
||||
long x = Units.toEMU(anchor.getX());
|
||||
|
@ -169,6 +169,7 @@ public class XSLFPictureShape extends XSLFSimpleShape implements PictureShape {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getClipping(){
|
||||
CTPicture ct = (CTPicture)getXmlObject();
|
||||
CTRelativeRect r = ct.getBlipFill().getSrcRect();
|
||||
|
@ -481,6 +481,7 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeC
|
||||
*
|
||||
* @param graphics
|
||||
*/
|
||||
@Override
|
||||
public void draw(Graphics2D graphics){
|
||||
DrawFactory drawFact = DrawFactory.getInstance(graphics);
|
||||
Drawable draw = drawFact.getDrawable(this);
|
||||
|
@ -21,7 +21,6 @@ import java.io.IOException;
|
||||
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.Notes;
|
||||
import org.apache.poi.sl.usermodel.Slide;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
|
@ -1,95 +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.blip;
|
||||
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
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.
|
||||
==================================================================== */
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
/**
|
||||
* Creates BufferedImage using javax.imageio.ImageIO and draws it in the specified graphics.
|
||||
*
|
||||
* @author Yegor Kozlov.
|
||||
*/
|
||||
public final class BitmapPainter implements ImagePainter {
|
||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
||||
|
||||
public void paint(Graphics2D graphics, HSLFPictureData pict, HSLFPictureShape parent) {
|
||||
BufferedImage img;
|
||||
try {
|
||||
img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
|
||||
} catch (Exception e) {
|
||||
logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isClipped = true;
|
||||
Insets clip = parent.getBlipClip();
|
||||
if (clip == null) {
|
||||
isClipped = false;
|
||||
clip = new Insets(0,0,0,0);
|
||||
}
|
||||
|
||||
int iw = img.getWidth();
|
||||
int ih = img.getHeight();
|
||||
|
||||
Rectangle anchor = parent.getLogicalAnchor2D().getBounds();
|
||||
|
||||
double cw = (100000-clip.left-clip.right) / 100000.0;
|
||||
double ch = (100000-clip.top-clip.bottom) / 100000.0;
|
||||
double sx = anchor.getWidth()/(iw*cw);
|
||||
double sy = anchor.getHeight()/(ih*ch);
|
||||
double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
|
||||
double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
|
||||
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
||||
|
||||
Shape clipOld = graphics.getClip();
|
||||
if (isClipped) graphics.clip(anchor.getBounds2D());
|
||||
graphics.drawRenderedImage(img, at);
|
||||
graphics.setClip(clipOld);
|
||||
}
|
||||
|
||||
}
|
@ -1,72 +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.blip;
|
||||
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* A common interface for objects that can render ppt picture data.
|
||||
* <p>
|
||||
* Subclasses can redefine it and use third-party libraries for actual rendering,
|
||||
* for example, Bitmaps can be rendered using javax.imageio.* , WMF can be rendered using Apache Batik,
|
||||
* PICT can be rendered using Apple QuickTime API for Java, etc.
|
||||
* </p>
|
||||
*
|
||||
* A typical usage is as follows:
|
||||
* <code>
|
||||
* public WMFPaiter implements ImagePainter{
|
||||
* public void paint(Graphics2D graphics, PictureData pict, Picture parent){
|
||||
* DataInputStream is = new DataInputStream(new ByteArrayInputStream(pict.getData()));
|
||||
* org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore =
|
||||
* new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore();
|
||||
* try {
|
||||
* wmfStore.read(is);
|
||||
* } catch (IOException e){
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* Rectangle anchor = parent.getAnchor();
|
||||
* float scale = (float)anchor.width/wmfStore.getWidthPixels();
|
||||
*
|
||||
* org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter =
|
||||
* new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale);
|
||||
* graphics.translate(anchor.x, anchor.y);
|
||||
* painter.paint(graphics);
|
||||
* }
|
||||
* }
|
||||
* PictureData.setImagePainter(Picture.WMF, new WMFPaiter());
|
||||
* ...
|
||||
* </code>
|
||||
* Subsequent calls of Slide.draw(Graphics gr) will use WMFPaiter for WMF images.
|
||||
*
|
||||
* @author Yegor Kozlov.
|
||||
*/
|
||||
public interface ImagePainter {
|
||||
|
||||
/**
|
||||
* Paints the specified picture data
|
||||
*
|
||||
* @param graphics the graphics to paintb into
|
||||
* @param pict the data to paint
|
||||
* @param parent the shapes that owns the picture data
|
||||
*/
|
||||
public void paint(Graphics2D graphics, HSLFPictureData pict, HSLFPictureShape parent);
|
||||
}
|
@ -247,8 +247,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
|
||||
|
||||
// Table text
|
||||
for (HSLFShape shape : slide.getShapes()){
|
||||
if (shape instanceof Table){
|
||||
extractTableText(ret, (Table)shape);
|
||||
if (shape instanceof HSLFTable){
|
||||
extractTableText(ret, (HSLFTable)shape);
|
||||
}
|
||||
}
|
||||
// Slide footer, if set
|
||||
@ -305,10 +305,10 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
private void extractTableText(StringBuffer ret, Table table) {
|
||||
private void extractTableText(StringBuffer ret, HSLFTable table) {
|
||||
for (int row = 0; row < table.getNumberOfRows(); row++){
|
||||
for (int col = 0; col < table.getNumberOfColumns(); col++){
|
||||
TableCell cell = table.getCell(row, col);
|
||||
HSLFTableCell cell = table.getCell(row, col);
|
||||
//defensive null checks; don't know if they're necessary
|
||||
if (cell != null){
|
||||
String txt = cell.getText();
|
||||
|
@ -22,8 +22,8 @@ import org.apache.poi.hslf.usermodel.*;
|
||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||
import org.apache.poi.sl.usermodel.ShapeType;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents a line in a PowerPoint drawing
|
||||
@ -69,4 +69,63 @@ public final class Line extends HSLFSimpleShape {
|
||||
Rectangle2D anchor = getLogicalAnchor2D();
|
||||
return new Line2D.Double(anchor.getX(), anchor.getY(), anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return 'absolute' anchor of this shape relative to the parent sheet
|
||||
*
|
||||
* @deprecated TODO: remove the whole class, should work with preset geometries instead
|
||||
*/
|
||||
public Rectangle2D getLogicalAnchor2D(){
|
||||
Rectangle2D anchor = getAnchor2D();
|
||||
|
||||
//if it is a groupped shape see if we need to transform the coordinates
|
||||
if (getParent() != null){
|
||||
ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
|
||||
for (ShapeContainer<HSLFShape> parent=this.getParent();
|
||||
parent instanceof HSLFGroupShape;
|
||||
parent = ((HSLFGroupShape)parent).getParent()) {
|
||||
lst.add(0, (HSLFGroupShape)parent);
|
||||
}
|
||||
|
||||
AffineTransform tx = new AffineTransform();
|
||||
for(HSLFGroupShape prnt : lst) {
|
||||
Rectangle2D exterior = prnt.getAnchor2D();
|
||||
Rectangle2D interior = prnt.getInteriorAnchor();
|
||||
|
||||
double scaleX = exterior.getWidth() / interior.getWidth();
|
||||
double scaleY = exterior.getHeight() / interior.getHeight();
|
||||
|
||||
tx.translate(exterior.getX(), exterior.getY());
|
||||
tx.scale(scaleX, scaleY);
|
||||
tx.translate(-interior.getX(), -interior.getY());
|
||||
|
||||
}
|
||||
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
|
||||
double angle = getRotation();
|
||||
if(angle != 0.){
|
||||
double centerX = anchor.getX() + anchor.getWidth()/2;
|
||||
double centerY = anchor.getY() + anchor.getHeight()/2;
|
||||
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.rotate(Math.toRadians(angle));
|
||||
trans.translate(-centerX, -centerY);
|
||||
|
||||
Rectangle2D rect = trans.createTransformedShape(anchor).getBounds2D();
|
||||
if((anchor.getWidth() < anchor.getHeight() && rect.getWidth() > rect.getHeight()) ||
|
||||
(anchor.getWidth() > anchor.getHeight() && rect.getWidth() < rect.getHeight()) ){
|
||||
trans = new AffineTransform();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.rotate(Math.PI/2);
|
||||
trans.translate(-centerX, -centerY);
|
||||
anchor = trans.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
}
|
||||
return anchor;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -285,6 +285,7 @@ public class TextPropCollection {
|
||||
* Clones the given text properties
|
||||
*/
|
||||
public void copy(TextPropCollection other) {
|
||||
if (this == other) return;
|
||||
this.charactersCovered = other.charactersCovered;
|
||||
this.indentLevel = other.indentLevel;
|
||||
this.maskSpecial = other.maskSpecial;
|
||||
|
@ -87,9 +87,7 @@ public final class EscherTextboxWrapper extends RecordContainer {
|
||||
|
||||
// Grab the children's data
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for(int i=0; i<_children.length; i++) {
|
||||
_children[i].writeOut(baos);
|
||||
}
|
||||
for (Record r : _children) r.writeOut(baos);
|
||||
byte[] data = baos.toByteArray();
|
||||
|
||||
// Save in the escher layer
|
||||
|
@ -97,7 +97,7 @@ public final class PPDrawing extends RecordAtom {
|
||||
findEscherChildren(erf, contents, 8, len-8, escherChildren);
|
||||
this.childRecords = escherChildren.toArray(new EscherRecord[escherChildren.size()]);
|
||||
|
||||
if (1 == this.childRecords.length && (short)0xf002 == this.childRecords[0].getRecordId() && this.childRecords[0] instanceof EscherContainerRecord) {
|
||||
if (1 == this.childRecords.length && (short)RecordTypes.EscherDgContainer == this.childRecords[0].getRecordId() && this.childRecords[0] instanceof EscherContainerRecord) {
|
||||
this.textboxWrappers = findInDgContainer((EscherContainerRecord) this.childRecords[0]);
|
||||
} else {
|
||||
// Find and EscherTextboxRecord's, and wrap them up
|
||||
@ -106,37 +106,30 @@ public final class PPDrawing extends RecordAtom {
|
||||
this.textboxWrappers = textboxes.toArray(new EscherTextboxWrapper[textboxes.size()]);
|
||||
}
|
||||
}
|
||||
private EscherTextboxWrapper[] findInDgContainer(final EscherContainerRecord escherContainerF002) {
|
||||
private EscherTextboxWrapper[] findInDgContainer(final EscherContainerRecord dgContainer) {
|
||||
final List<EscherTextboxWrapper> found = new LinkedList<EscherTextboxWrapper>();
|
||||
final EscherContainerRecord SpgrContainer = findFirstEscherContainerRecordOfType((short)0xf003, escherContainerF002);
|
||||
final EscherContainerRecord[] escherContainersF004 = findAllEscherContainerRecordOfType((short)0xf004, SpgrContainer);
|
||||
for (EscherContainerRecord spContainer : escherContainersF004) {
|
||||
final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherSpgrContainer, dgContainer);
|
||||
final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType((short)RecordTypes.EscherSpContainer, spgrContainer);
|
||||
for (EscherContainerRecord spContainer : spContainers) {
|
||||
StyleTextProp9Atom nineAtom = findInSpContainer(spContainer);
|
||||
EscherSpRecord sp = null;
|
||||
final EscherRecord escherContainerF00A = findFirstEscherRecordOfType((short)0xf00a, spContainer);
|
||||
if (null != escherContainerF00A) {
|
||||
if (escherContainerF00A instanceof EscherSpRecord) {
|
||||
sp = (EscherSpRecord) escherContainerF00A;
|
||||
}
|
||||
}
|
||||
final EscherRecord escherContainerF00D = findFirstEscherRecordOfType((short)0xf00d, spContainer);
|
||||
if (null == escherContainerF00D) { continue; }
|
||||
if (escherContainerF00D instanceof EscherTextboxRecord) {
|
||||
EscherTextboxRecord tbr = (EscherTextboxRecord) escherContainerF00D;
|
||||
EscherTextboxWrapper w = new EscherTextboxWrapper(tbr);
|
||||
w.setStyleTextProp9Atom(nineAtom);
|
||||
if (null != sp) {
|
||||
w.setShapeId(sp.getShapeId());
|
||||
}
|
||||
found.add(w);
|
||||
EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherSp, spContainer);
|
||||
EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherClientTextbox, spContainer);
|
||||
if (null == clientTextbox) { continue; }
|
||||
|
||||
EscherTextboxWrapper w = new EscherTextboxWrapper(clientTextbox);
|
||||
w.setStyleTextProp9Atom(nineAtom);
|
||||
if (null != sp) {
|
||||
w.setShapeId(sp.getShapeId());
|
||||
}
|
||||
found.add(w);
|
||||
}
|
||||
return found.toArray(new EscherTextboxWrapper[found.size()]);
|
||||
}
|
||||
|
||||
private StyleTextProp9Atom findInSpContainer(final EscherContainerRecord spContainer) {
|
||||
final EscherContainerRecord escherContainerF011 = findFirstEscherContainerRecordOfType((short)0xf011, spContainer);
|
||||
if (null == escherContainerF011) { return null; }
|
||||
final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, escherContainerF011);
|
||||
EscherContainerRecord clientData = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherClientData, spContainer);
|
||||
if (null == clientData) { return null; }
|
||||
final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, clientData);
|
||||
if (null == escherContainer1388) { return null; }
|
||||
final EscherContainerRecord escherContainer138A = findFirstEscherContainerRecordOfType((short)0x138A, escherContainer1388);
|
||||
if (null == escherContainer138A) { return null; }
|
||||
|
@ -294,7 +294,7 @@ public abstract class RecordContainer extends Record
|
||||
// Write out our header, less the size
|
||||
mout.write(new byte[] {headerA,headerB});
|
||||
byte[] typeB = new byte[2];
|
||||
LittleEndian.putShort(typeB,(short)type);
|
||||
LittleEndian.putShort(typeB, 0, (short)type);
|
||||
mout.write(typeB);
|
||||
mout.write(new byte[4]);
|
||||
|
||||
@ -320,7 +320,7 @@ public abstract class RecordContainer extends Record
|
||||
// Write out our header, less the size
|
||||
baos.write(new byte[] {headerA,headerB});
|
||||
byte[] typeB = new byte[2];
|
||||
LittleEndian.putShort(typeB,(short)type);
|
||||
LittleEndian.putShort(typeB,0,(short)type);
|
||||
baos.write(typeB);
|
||||
baos.write(new byte[] {0,0,0,0});
|
||||
|
||||
|
@ -93,8 +93,6 @@ public final class SlideListWithText extends RecordContainer {
|
||||
}
|
||||
|
||||
int clen = endPos - i - 1;
|
||||
boolean emptySet = false;
|
||||
if(clen == 0) { emptySet = true; }
|
||||
|
||||
// Create a SlideAtomsSets, not caring if they're empty
|
||||
//if(emptySet) { continue; }
|
||||
@ -149,7 +147,7 @@ public final class SlideListWithText extends RecordContainer {
|
||||
}
|
||||
|
||||
public void setInstance(int inst){
|
||||
LittleEndian.putShort(_header, (short)((inst << 4) | 0xF));
|
||||
LittleEndian.putShort(_header, 0, (short)((inst << 4) | 0xF));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,9 +128,10 @@ public final class HSLFFill {
|
||||
};
|
||||
}
|
||||
case FILL_PICTURE: {
|
||||
return new TexturePaint() {
|
||||
final HSLFPictureData pd = getPictureData();
|
||||
final HSLFPictureData pd = getPictureData();
|
||||
if (pd == null) break;
|
||||
|
||||
return new TexturePaint() {
|
||||
public InputStream getImageData() {
|
||||
return new ByteArrayInputStream(pd.getData());
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||
import org.apache.poi.sl.usermodel.ShapeType;
|
||||
import org.apache.poi.sl.usermodel.*;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
@ -31,7 +30,7 @@ import org.apache.poi.util.POILogger;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShape> {
|
||||
public class HSLFGroupShape extends HSLFShape implements GroupShape<HSLFShape> {
|
||||
|
||||
/**
|
||||
* Create a new ShapeGroup. This constructor is used when a new shape is created.
|
||||
@ -87,13 +86,8 @@ public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShap
|
||||
spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the coordinate space of this group. All children are constrained
|
||||
* to these coordinates.
|
||||
*
|
||||
* @param anchor the coordinate space of this group
|
||||
*/
|
||||
public void setCoordinates(Rectangle2D anchor){
|
||||
@Override
|
||||
public void setInteriorAnchor(Rectangle2D anchor){
|
||||
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
|
||||
|
||||
int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
|
||||
@ -108,22 +102,14 @@ public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShap
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinate space of this group. All children are constrained
|
||||
* to these coordinates.
|
||||
*
|
||||
* @return the coordinate space of this group
|
||||
*/
|
||||
public Rectangle2D getCoordinates(){
|
||||
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
|
||||
|
||||
Rectangle2D.Float anchor = new Rectangle2D.Float();
|
||||
anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
|
||||
anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
|
||||
anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
|
||||
anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;
|
||||
|
||||
return anchor;
|
||||
@Override
|
||||
public Rectangle2D getInteriorAnchor(){
|
||||
EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID);
|
||||
double x = rec.getRectX1()*POINT_DPI/MASTER_DPI;
|
||||
double y = rec.getRectY1()*POINT_DPI/MASTER_DPI;
|
||||
double width = (rec.getRectX2()-rec.getRectX1())*POINT_DPI/MASTER_DPI;
|
||||
double height = (rec.getRectY2()-rec.getRectY1())*POINT_DPI/MASTER_DPI;
|
||||
return new Rectangle2D.Double(x,y,width,height);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,21 +185,21 @@ public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShap
|
||||
*/
|
||||
public Rectangle2D getAnchor2D(){
|
||||
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
|
||||
Rectangle2D.Float anchor = new Rectangle2D.Float();
|
||||
Rectangle2D anchor;
|
||||
if(clientAnchor == null){
|
||||
logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
|
||||
EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
|
||||
anchor = new Rectangle2D.Float(
|
||||
(float)rec.getDx1()*POINT_DPI/MASTER_DPI,
|
||||
(float)rec.getDy1()*POINT_DPI/MASTER_DPI,
|
||||
(float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
|
||||
(float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
|
||||
);
|
||||
double x = rec.getDx1()*POINT_DPI/MASTER_DPI;
|
||||
double y = rec.getDy1()*POINT_DPI/MASTER_DPI;
|
||||
double width = (rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI;
|
||||
double height = (rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI;
|
||||
anchor = new Rectangle2D.Double(x,y,width,height);
|
||||
} else {
|
||||
anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
|
||||
anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
|
||||
anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
|
||||
anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
|
||||
double x = clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
|
||||
double y = clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
|
||||
double width = (clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
|
||||
double height = (clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
|
||||
anchor = new Rectangle2D.Double(x,y,width,height);
|
||||
}
|
||||
|
||||
return anchor;
|
||||
|
@ -35,7 +35,7 @@ import org.apache.poi.util.POILogger;
|
||||
public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFSlideShow> {
|
||||
protected static POILogger logger = POILogFactory.getLogger(HSLFNotes.class);
|
||||
|
||||
private List<List<HSLFTextParagraph>> _runs;
|
||||
private List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
|
||||
|
||||
/**
|
||||
* Constructs a Notes Sheet from the given Notes record.
|
||||
@ -49,13 +49,16 @@ public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFS
|
||||
// Now, build up TextRuns from pairs of TextHeaderAtom and
|
||||
// one of TextBytesAtom or TextCharsAtom, found inside
|
||||
// EscherTextboxWrapper's in the PPDrawing
|
||||
_runs = HSLFTextParagraph.findTextParagraphs(getPPDrawing());
|
||||
if (_runs.isEmpty()) {
|
||||
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
|
||||
if (!_paragraphs.contains(l)) _paragraphs.add(l);
|
||||
}
|
||||
|
||||
if (_paragraphs.isEmpty()) {
|
||||
logger.log(POILogger.WARN, "No text records found for notes sheet");
|
||||
}
|
||||
|
||||
// Set the sheet on each TextRun
|
||||
for (List<HSLFTextParagraph> ltp : _runs) {
|
||||
for (List<HSLFTextParagraph> ltp : _paragraphs) {
|
||||
for (HSLFTextParagraph tp : ltp) {
|
||||
tp.supplySheet(this);
|
||||
}
|
||||
@ -67,7 +70,7 @@ public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFS
|
||||
*/
|
||||
@Override
|
||||
public List<List<HSLFTextParagraph>> getTextParagraphs() {
|
||||
return _runs;
|
||||
return _paragraphs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,31 +17,22 @@
|
||||
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import org.apache.poi.hslf.blip.BitmapPainter;
|
||||
import org.apache.poi.hslf.blip.DIB;
|
||||
import org.apache.poi.hslf.blip.EMF;
|
||||
import org.apache.poi.hslf.blip.ImagePainter;
|
||||
import org.apache.poi.hslf.blip.JPEG;
|
||||
import org.apache.poi.hslf.blip.PICT;
|
||||
import org.apache.poi.hslf.blip.PNG;
|
||||
import org.apache.poi.hslf.blip.WMF;
|
||||
import org.apache.poi.hslf.blip.*;
|
||||
import org.apache.poi.poifs.crypt.CryptoFunctions;
|
||||
import org.apache.poi.poifs.crypt.HashAlgorithm;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.sl.usermodel.PictureData;
|
||||
import org.apache.poi.util.*;
|
||||
|
||||
/**
|
||||
* A class that represents image data contained in a slide show.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public abstract class HSLFPictureData {
|
||||
public abstract class HSLFPictureData implements PictureData {
|
||||
|
||||
protected POILogger logger = POILogFactory.getLogger(this.getClass());
|
||||
|
||||
@ -91,13 +82,6 @@ public abstract class HSLFPictureData {
|
||||
*/
|
||||
protected abstract int getSignature();
|
||||
|
||||
protected static final ImagePainter[] painters = new ImagePainter[8];
|
||||
static {
|
||||
HSLFPictureData.setImagePainter(HSLFPictureShape.PNG, new BitmapPainter());
|
||||
HSLFPictureData.setImagePainter(HSLFPictureShape.JPEG, new BitmapPainter());
|
||||
HSLFPictureData.setImagePainter(HSLFPictureShape.DIB, new BitmapPainter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw binary data of this Picture excluding the first 8 bytes
|
||||
* which hold image signature and size of the image data.
|
||||
@ -233,31 +217,4 @@ public abstract class HSLFPictureData {
|
||||
public int getSize(){
|
||||
return getData().length;
|
||||
}
|
||||
|
||||
public void draw(Graphics2D graphics, HSLFPictureShape parent){
|
||||
ImagePainter painter = painters[getType()];
|
||||
if(painter != null) painter.paint(graphics, this, parent);
|
||||
else logger.log(POILogger.WARN, "Rendering is not supported: " + getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ImagePainter for the specified image type
|
||||
*
|
||||
* @param type image type, must be one of the static constants defined in the <code>Picture<code> class.
|
||||
* @param painter
|
||||
*/
|
||||
public static void setImagePainter(int type, ImagePainter painter){
|
||||
painters[type] = painter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ImagePainter for the specified image type
|
||||
*
|
||||
* @param type blip type, must be one of the static constants defined in the <code>Picture<code> class.
|
||||
* @return ImagePainter for the specified image type
|
||||
*/
|
||||
public static ImagePainter getImagePainter(int type){
|
||||
return painters[type];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ import javax.imageio.ImageIO;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hslf.blip.Bitmap;
|
||||
import org.apache.poi.hslf.record.Document;
|
||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||
import org.apache.poi.sl.usermodel.ShapeType;
|
||||
import org.apache.poi.sl.usermodel.*;
|
||||
import org.apache.poi.util.*;
|
||||
|
||||
|
||||
@ -38,7 +37,7 @@ import org.apache.poi.util.*;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class HSLFPictureShape extends HSLFSimpleShape {
|
||||
public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape {
|
||||
|
||||
/**
|
||||
* Windows Enhanced Metafile (EMF)
|
||||
@ -165,11 +164,7 @@ public class HSLFPictureShape extends HSLFSimpleShape {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the picture data for this picture.
|
||||
*
|
||||
* @return the picture data for this picture.
|
||||
*/
|
||||
@Override
|
||||
public HSLFPictureData getPictureData(){
|
||||
HSLFSlideShow ppt = getSheet().getSlideShow();
|
||||
HSLFPictureData[] pict = ppt.getPictureData();
|
||||
@ -247,13 +242,11 @@ public class HSLFPictureShape extends HSLFSimpleShape {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clipping values as percent ratio relatively to the image size.
|
||||
* The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size,
|
||||
* i.e. the size of the already clipped image
|
||||
*
|
||||
* @return the clipping as insets converted/scaled to 100000 (=100%)
|
||||
*/
|
||||
public Insets getBlipClip() {
|
||||
@Override
|
||||
public Insets getClipping() {
|
||||
EscherOptRecord opt = getEscherOptRecord();
|
||||
|
||||
double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP);
|
||||
|
@ -165,14 +165,12 @@ public abstract class HSLFShape implements Shape {
|
||||
public Rectangle2D getAnchor2D(){
|
||||
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
|
||||
int flags = spRecord.getFlags();
|
||||
Rectangle2D anchor=null;
|
||||
Rectangle2D anchor;
|
||||
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
|
||||
EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
|
||||
anchor = new java.awt.Rectangle();
|
||||
if(rec == null){
|
||||
logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
|
||||
EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
|
||||
anchor = new java.awt.Rectangle();
|
||||
anchor = new Rectangle2D.Float(
|
||||
(float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
|
||||
(float)clrec.getFlag()*POINT_DPI/MASTER_DPI,
|
||||
@ -187,10 +185,8 @@ public abstract class HSLFShape implements Shape {
|
||||
(float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
|
||||
anchor = new java.awt.Rectangle();
|
||||
anchor = new Rectangle2D.Float(
|
||||
(float)rec.getCol1()*POINT_DPI/MASTER_DPI,
|
||||
(float)rec.getFlag()*POINT_DPI/MASTER_DPI,
|
||||
@ -201,10 +197,6 @@ public abstract class HSLFShape implements Shape {
|
||||
return anchor;
|
||||
}
|
||||
|
||||
public Rectangle2D getLogicalAnchor2D(){
|
||||
return getAnchor2D();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the anchor (the bounding box rectangle) of this shape.
|
||||
* All coordinates should be expressed in points (72 dpi).
|
||||
@ -262,8 +254,9 @@ public abstract class HSLFShape implements Shape {
|
||||
* @return escher property or <code>null</code> if not found.
|
||||
*/
|
||||
public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
|
||||
return opt.lookup(propId);
|
||||
}
|
||||
if (opt == null) return null;
|
||||
return opt.lookup(propId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an escher property for this shape.
|
||||
@ -475,15 +468,6 @@ public abstract class HSLFShape implements Shape {
|
||||
logger.log(POILogger.INFO, "Rendering " + getShapeName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return shape outline as a java.awt.Shape object
|
||||
*
|
||||
* @return the shape outline
|
||||
*/
|
||||
public java.awt.Shape getOutline(){
|
||||
return getLogicalAnchor2D();
|
||||
}
|
||||
|
||||
public EscherOptRecord getEscherOptRecord() {
|
||||
EscherOptRecord opt = getEscherChild(EscherOptRecord.RECORD_ID);
|
||||
if (opt == null) {
|
||||
@ -516,8 +500,7 @@ public abstract class HSLFShape implements Shape {
|
||||
|
||||
public double getRotation(){
|
||||
int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
|
||||
double angle = Units.fixedPointToDouble(rot) % 360.0;
|
||||
return angle;
|
||||
return Units.fixedPointToDouble(rot);
|
||||
}
|
||||
|
||||
public void setRotation(double theta){
|
||||
|
@ -69,7 +69,7 @@ public final class HSLFShapeFactory {
|
||||
List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
|
||||
EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
|
||||
if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
|
||||
group = new Table(spContainer, parent);
|
||||
group = new HSLFTable(spContainer, parent);
|
||||
} else {
|
||||
group = new HSLFGroupShape(spContainer, parent);
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import java.util.*;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hslf.record.*;
|
||||
import org.apache.poi.sl.draw.DrawFactory;
|
||||
import org.apache.poi.sl.draw.Drawable;
|
||||
import org.apache.poi.sl.usermodel.Sheet;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
@ -288,8 +290,11 @@ public abstract class HSLFSheet implements Sheet<HSLFShape,HSLFSlideShow> {
|
||||
return _background;
|
||||
}
|
||||
|
||||
public void draw(Graphics2D graphics){
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D graphics) {
|
||||
DrawFactory drawFact = DrawFactory.getInstance(graphics);
|
||||
Drawable draw = drawFact.getDrawable(this);
|
||||
draw.draw(graphics);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,16 +18,15 @@
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||
import org.apache.poi.hslf.record.*;
|
||||
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.LineCompound;
|
||||
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
@ -196,7 +195,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
|
||||
public StrokeStyle getStrokeStyle(){
|
||||
return new StrokeStyle() {
|
||||
public PaintStyle getPaint() {
|
||||
return null;
|
||||
return DrawPaint.createSolidPaint(HSLFSimpleShape.this.getLineColor());
|
||||
}
|
||||
|
||||
public LineCap getLineCap() {
|
||||
@ -204,15 +203,15 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
|
||||
}
|
||||
|
||||
public LineDash getLineDash() {
|
||||
return null;
|
||||
return HSLFSimpleShape.this.getLineDashing();
|
||||
}
|
||||
|
||||
public LineCompound getLineCompound() {
|
||||
return null;
|
||||
return HSLFSimpleShape.this.getLineCompound();
|
||||
}
|
||||
|
||||
public double getLineWidth() {
|
||||
return 0;
|
||||
return HSLFSimpleShape.this.getLineWidth();
|
||||
}
|
||||
|
||||
};
|
||||
@ -234,61 +233,6 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
|
||||
getFill().setForegroundColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return 'absolute' anchor of this shape relative to the parent sheet
|
||||
*/
|
||||
public Rectangle2D getLogicalAnchor2D(){
|
||||
Rectangle2D anchor = getAnchor2D();
|
||||
|
||||
//if it is a groupped shape see if we need to transform the coordinates
|
||||
if (getParent() != null){
|
||||
ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
|
||||
for (ShapeContainer<HSLFShape> parent=this.getParent();
|
||||
parent instanceof HSLFGroupShape;
|
||||
parent = ((HSLFGroupShape)parent).getParent()) {
|
||||
lst.add(0, (HSLFGroupShape)parent);
|
||||
}
|
||||
|
||||
AffineTransform tx = new AffineTransform();
|
||||
for(HSLFGroupShape prnt : lst) {
|
||||
Rectangle2D exterior = prnt.getAnchor2D();
|
||||
Rectangle2D interior = prnt.getCoordinates();
|
||||
|
||||
double scaleX = exterior.getWidth() / interior.getWidth();
|
||||
double scaleY = exterior.getHeight() / interior.getHeight();
|
||||
|
||||
tx.translate(exterior.getX(), exterior.getY());
|
||||
tx.scale(scaleX, scaleY);
|
||||
tx.translate(-interior.getX(), -interior.getY());
|
||||
|
||||
}
|
||||
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
|
||||
double angle = getRotation();
|
||||
if(angle != 0.){
|
||||
double centerX = anchor.getX() + anchor.getWidth()/2;
|
||||
double centerY = anchor.getY() + anchor.getHeight()/2;
|
||||
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.rotate(Math.toRadians(angle));
|
||||
trans.translate(-centerX, -centerY);
|
||||
|
||||
Rectangle2D rect = trans.createTransformedShape(anchor).getBounds2D();
|
||||
if((anchor.getWidth() < anchor.getHeight() && rect.getWidth() > rect.getHeight()) ||
|
||||
(anchor.getWidth() > anchor.getHeight() && rect.getWidth() < rect.getHeight()) ){
|
||||
trans = new AffineTransform();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.rotate(Math.PI/2);
|
||||
trans.translate(-centerX, -centerY);
|
||||
anchor = trans.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
}
|
||||
return anchor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a record in the underlying EscherClientDataRecord
|
||||
*
|
||||
@ -424,11 +368,6 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
|
||||
return (adjval == -1) ? null : new Guide(name, "val "+adjval);
|
||||
}
|
||||
|
||||
public LineDecoration getLineDecoration() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public CustomGeometry getGeometry() {
|
||||
ShapeType st = getShapeType();
|
||||
String name = st.getOoxmlName();
|
||||
@ -442,11 +381,89 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
|
||||
return geom;
|
||||
}
|
||||
|
||||
public Shadow getShadow() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
||||
public double getShadowAngle() {
|
||||
EscherOptRecord opt = getEscherOptRecord();
|
||||
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX);
|
||||
int offX = (prop == null) ? 0 : prop.getPropertyValue();
|
||||
prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY);
|
||||
int offY = (prop == null) ? 0 : prop.getPropertyValue();
|
||||
return Math.toDegrees(Math.atan2(offY, offX));
|
||||
}
|
||||
|
||||
public double getShadowDistance() {
|
||||
EscherOptRecord opt = getEscherOptRecord();
|
||||
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX);
|
||||
int offX = (prop == null) ? 0 : prop.getPropertyValue();
|
||||
prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY);
|
||||
int offY = (prop == null) ? 0 : prop.getPropertyValue();
|
||||
return Units.toPoints((long)Math.hypot(offX, offY));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
|
||||
*/
|
||||
public Color getShadowColor(){
|
||||
Color clr = getColor(EscherProperties.SHADOWSTYLE__COLOR, EscherProperties.SHADOWSTYLE__OPACITY, -1);
|
||||
return clr == null ? Color.black : clr;
|
||||
}
|
||||
|
||||
public Shadow getShadow() {
|
||||
EscherOptRecord opt = getEscherOptRecord();
|
||||
EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE);
|
||||
if (shadowType == null) return null;
|
||||
|
||||
return new Shadow(){
|
||||
public SimpleShape getShadowParent() {
|
||||
return HSLFSimpleShape.this;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return getShadowDistance();
|
||||
}
|
||||
|
||||
public double getAngle() {
|
||||
return getShadowAngle();
|
||||
}
|
||||
|
||||
public double getBlur() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
public SolidPaint getFillStyle() {
|
||||
return DrawPaint.createSolidPaint(getShadowColor());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public LineDecoration getLineDecoration() {
|
||||
return new LineDecoration() {
|
||||
|
||||
public DecorationShape getHeadShape() {
|
||||
return DecorationShape.NONE;
|
||||
}
|
||||
|
||||
public DecorationSize getHeadWidth() {
|
||||
return DecorationSize.MEDIUM;
|
||||
}
|
||||
|
||||
public DecorationSize getHeadLength() {
|
||||
return DecorationSize.MEDIUM;
|
||||
}
|
||||
|
||||
public DecorationShape getTailShape() {
|
||||
return DecorationShape.NONE;
|
||||
}
|
||||
|
||||
public DecorationSize getTailWidth() {
|
||||
return DecorationSize.MEDIUM;
|
||||
}
|
||||
|
||||
public DecorationSize getTailLength() {
|
||||
return DecorationSize.MEDIUM;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,9 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSl
|
||||
}
|
||||
|
||||
// Grab text from slide's PPDrawing
|
||||
_paragraphs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing()));
|
||||
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
|
||||
if (!_paragraphs.contains(l)) _paragraphs.add(l);
|
||||
}
|
||||
|
||||
for(List<HSLFTextParagraph> ltp : _paragraphs) {
|
||||
for (HSLFTextParagraph tp : ltp) {
|
||||
|
@ -32,7 +32,7 @@ import org.apache.poi.hslf.record.*;
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class HSLFSlideMaster extends HSLFMasterSheet {
|
||||
private final List<List<HSLFTextParagraph>> _runs = new ArrayList<List<HSLFTextParagraph>>();
|
||||
private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
|
||||
|
||||
/**
|
||||
* all TxMasterStyleAtoms available in this master
|
||||
@ -46,8 +46,11 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
|
||||
public HSLFSlideMaster(MainMaster record, int sheetNo) {
|
||||
super(record, sheetNo);
|
||||
|
||||
_runs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing()));
|
||||
for (List<HSLFTextParagraph> p : _runs) {
|
||||
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
|
||||
if (!_paragraphs.contains(l)) _paragraphs.add(l);
|
||||
}
|
||||
|
||||
for (List<HSLFTextParagraph> p : _paragraphs) {
|
||||
for (HSLFTextParagraph htp : p) {
|
||||
htp.supplySheet(this);
|
||||
}
|
||||
@ -58,7 +61,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
|
||||
* Returns an array of all the TextRuns found
|
||||
*/
|
||||
public List<List<HSLFTextParagraph>> getTextParagraphs() {
|
||||
return _runs;
|
||||
return _paragraphs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,7 +141,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
|
||||
|
||||
protected void onAddTextShape(HSLFTextShape shape) {
|
||||
List<HSLFTextParagraph> runs = shape.getTextParagraphs();
|
||||
_runs.add(runs);
|
||||
_paragraphs.add(runs);
|
||||
}
|
||||
|
||||
public TxMasterStyleAtom[] getTxMasterStyleAtoms(){
|
||||
|
@ -15,9 +15,10 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hslf.model;
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hslf.model.Line;
|
||||
import org.apache.poi.hslf.usermodel.*;
|
||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
@ -31,7 +32,7 @@ import java.awt.*;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class Table extends HSLFGroupShape {
|
||||
public final class HSLFTable extends HSLFGroupShape {
|
||||
|
||||
protected static final int BORDER_TOP = 1;
|
||||
protected static final int BORDER_RIGHT = 2;
|
||||
@ -44,7 +45,7 @@ public final class Table extends HSLFGroupShape {
|
||||
protected static final int BORDERS_NONE = 8;
|
||||
|
||||
|
||||
protected TableCell[][] cells;
|
||||
protected HSLFTableCell[][] cells;
|
||||
|
||||
/**
|
||||
* Create a new Table of the given number of rows and columns
|
||||
@ -52,23 +53,23 @@ public final class Table extends HSLFGroupShape {
|
||||
* @param numrows the number of rows
|
||||
* @param numcols the number of columns
|
||||
*/
|
||||
public Table(int numrows, int numcols) {
|
||||
public HSLFTable(int numrows, int numcols) {
|
||||
super();
|
||||
|
||||
if(numrows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1");
|
||||
if(numcols < 1) throw new IllegalArgumentException("The number of columns must be greater than 1");
|
||||
|
||||
int x=0, y=0, tblWidth=0, tblHeight=0;
|
||||
cells = new TableCell[numrows][numcols];
|
||||
cells = new HSLFTableCell[numrows][numcols];
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
x = 0;
|
||||
for (int j = 0; j < cells[i].length; j++) {
|
||||
cells[i][j] = new TableCell(this);
|
||||
Rectangle anchor = new Rectangle(x, y, TableCell.DEFAULT_WIDTH, TableCell.DEFAULT_HEIGHT);
|
||||
cells[i][j] = new HSLFTableCell(this);
|
||||
Rectangle anchor = new Rectangle(x, y, HSLFTableCell.DEFAULT_WIDTH, HSLFTableCell.DEFAULT_HEIGHT);
|
||||
cells[i][j].setAnchor(anchor);
|
||||
x += TableCell.DEFAULT_WIDTH;
|
||||
x += HSLFTableCell.DEFAULT_WIDTH;
|
||||
}
|
||||
y += TableCell.DEFAULT_HEIGHT;
|
||||
y += HSLFTableCell.DEFAULT_HEIGHT;
|
||||
}
|
||||
tblWidth = x;
|
||||
tblHeight = y;
|
||||
@ -94,7 +95,7 @@ public final class Table extends HSLFGroupShape {
|
||||
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
|
||||
* @param parent the parent of the shape
|
||||
*/
|
||||
public Table(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
|
||||
public HSLFTable(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
|
||||
super(escherRecord, parent);
|
||||
}
|
||||
|
||||
@ -105,7 +106,7 @@ public final class Table extends HSLFGroupShape {
|
||||
* @param col the column index (0-based)
|
||||
* @return the cell
|
||||
*/
|
||||
public TableCell getCell(int row, int col) {
|
||||
public HSLFTableCell getCell(int row, int col) {
|
||||
return cells[row][col];
|
||||
}
|
||||
|
||||
@ -124,13 +125,13 @@ public final class Table extends HSLFGroupShape {
|
||||
EscherOptRecord opt = (EscherOptRecord)lst.get(lst.size()-2);
|
||||
EscherArrayProperty p = opt.lookup(0x3A0);
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
TableCell cell = cells[i][0];
|
||||
HSLFTableCell cell = cells[i][0];
|
||||
int rowHeight = cell.getAnchor().height*MASTER_DPI/POINT_DPI;
|
||||
byte[] val = new byte[4];
|
||||
LittleEndian.putInt(val, 0, rowHeight);
|
||||
p.setElement(i, val);
|
||||
for (int j = 0; j < cells[i].length; j++) {
|
||||
TableCell c = cells[i][j];
|
||||
HSLFTableCell c = cells[i][j];
|
||||
addShape(c);
|
||||
|
||||
Line bt = c.getBorderTop();
|
||||
@ -177,12 +178,12 @@ public final class Table extends HSLFGroupShape {
|
||||
maxrowlen = Math.max(maxrowlen, row.size());
|
||||
}
|
||||
}
|
||||
cells = new TableCell[lst.size()][maxrowlen];
|
||||
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 TableCell(tx.getSpContainer(), getParent());
|
||||
cells[i][j] = new HSLFTableCell(tx.getSpContainer(), getParent());
|
||||
cells[i][j].setSheet(tx.getSheet());
|
||||
}
|
||||
}
|
||||
@ -256,7 +257,7 @@ public final class Table extends HSLFGroupShape {
|
||||
public void setAllBorders(Line line){
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
for (int j = 0; j < cells[i].length; j++) {
|
||||
TableCell cell = cells[i][j];
|
||||
HSLFTableCell cell = cells[i][j];
|
||||
cell.setBorderTop(cloneBorder(line));
|
||||
cell.setBorderLeft(cloneBorder(line));
|
||||
if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
|
||||
@ -273,7 +274,7 @@ public final class Table extends HSLFGroupShape {
|
||||
public void setOutsideBorders(Line line){
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
for (int j = 0; j < cells[i].length; j++) {
|
||||
TableCell cell = cells[i][j];
|
||||
HSLFTableCell cell = cells[i][j];
|
||||
|
||||
if(j == 0) cell.setBorderLeft(cloneBorder(line));
|
||||
if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
|
||||
@ -300,7 +301,7 @@ public final class Table extends HSLFGroupShape {
|
||||
public void setInsideBorders(Line line){
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
for (int j = 0; j < cells[i].length; j++) {
|
||||
TableCell cell = cells[i][j];
|
||||
HSLFTableCell cell = cells[i][j];
|
||||
|
||||
if(j != cells[i].length - 1)
|
||||
cell.setBorderRight(cloneBorder(line));
|
@ -15,15 +15,14 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hslf.model;
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherOptRecord;
|
||||
import org.apache.poi.ddf.EscherProperties;
|
||||
import org.apache.poi.hslf.usermodel.HSLFShape;
|
||||
import org.apache.poi.hslf.usermodel.HSLFTextBox;
|
||||
import org.apache.poi.hslf.model.Line;
|
||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||
import org.apache.poi.sl.usermodel.ShapeType;
|
||||
|
||||
@ -32,7 +31,7 @@ import org.apache.poi.sl.usermodel.ShapeType;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class TableCell extends HSLFTextBox {
|
||||
public final class HSLFTableCell extends HSLFTextBox {
|
||||
protected static final int DEFAULT_WIDTH = 100;
|
||||
protected static final int DEFAULT_HEIGHT = 40;
|
||||
|
||||
@ -47,7 +46,7 @@ public final class TableCell extends HSLFTextBox {
|
||||
* @param escherRecord {@link EscherSpContainer} container which holds information about this shape
|
||||
* @param parent the parent of the shape
|
||||
*/
|
||||
protected TableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
|
||||
protected HSLFTableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
|
||||
super(escherRecord, parent);
|
||||
}
|
||||
|
||||
@ -57,7 +56,7 @@ public final class TableCell extends HSLFTextBox {
|
||||
* @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 TableCell(ShapeContainer<HSLFShape> parent){
|
||||
public HSLFTableCell(ShapeContainer<HSLFShape> parent){
|
||||
super(parent);
|
||||
|
||||
setShapeType(ShapeType.RECT);
|
||||
@ -81,25 +80,25 @@ public final class TableCell extends HSLFTextBox {
|
||||
Rectangle cellAnchor = getAnchor();
|
||||
Rectangle lineAnchor = new Rectangle();
|
||||
switch(type){
|
||||
case Table.BORDER_TOP:
|
||||
case HSLFTable.BORDER_TOP:
|
||||
lineAnchor.x = cellAnchor.x;
|
||||
lineAnchor.y = cellAnchor.y;
|
||||
lineAnchor.width = cellAnchor.width;
|
||||
lineAnchor.height = 0;
|
||||
break;
|
||||
case Table.BORDER_RIGHT:
|
||||
case HSLFTable.BORDER_RIGHT:
|
||||
lineAnchor.x = cellAnchor.x + cellAnchor.width;
|
||||
lineAnchor.y = cellAnchor.y;
|
||||
lineAnchor.width = 0;
|
||||
lineAnchor.height = cellAnchor.height;
|
||||
break;
|
||||
case Table.BORDER_BOTTOM:
|
||||
case HSLFTable.BORDER_BOTTOM:
|
||||
lineAnchor.x = cellAnchor.x;
|
||||
lineAnchor.y = cellAnchor.y + cellAnchor.height;
|
||||
lineAnchor.width = cellAnchor.width;
|
||||
lineAnchor.height = 0;
|
||||
break;
|
||||
case Table.BORDER_LEFT:
|
||||
case HSLFTable.BORDER_LEFT:
|
||||
lineAnchor.x = cellAnchor.x;
|
||||
lineAnchor.y = cellAnchor.y;
|
||||
lineAnchor.width = 0;
|
||||
@ -116,7 +115,7 @@ public final class TableCell extends HSLFTextBox {
|
||||
}
|
||||
|
||||
public void setBorderLeft(Line line) {
|
||||
if(line != null) anchorBorder(Table.BORDER_LEFT, line);
|
||||
if(line != null) anchorBorder(HSLFTable.BORDER_LEFT, line);
|
||||
this.borderLeft = line;
|
||||
}
|
||||
|
||||
@ -125,7 +124,7 @@ public final class TableCell extends HSLFTextBox {
|
||||
}
|
||||
|
||||
public void setBorderRight(Line line) {
|
||||
if(line != null) anchorBorder(Table.BORDER_RIGHT, line);
|
||||
if(line != null) anchorBorder(HSLFTable.BORDER_RIGHT, line);
|
||||
this.borderRight = line;
|
||||
}
|
||||
|
||||
@ -134,7 +133,7 @@ public final class TableCell extends HSLFTextBox {
|
||||
}
|
||||
|
||||
public void setBorderTop(Line line) {
|
||||
if(line != null) anchorBorder(Table.BORDER_TOP, line);
|
||||
if(line != null) anchorBorder(HSLFTable.BORDER_TOP, line);
|
||||
this.borderTop = line;
|
||||
}
|
||||
|
||||
@ -143,16 +142,16 @@ public final class TableCell extends HSLFTextBox {
|
||||
}
|
||||
|
||||
public void setBorderBottom(Line line) {
|
||||
if(line != null) anchorBorder(Table.BORDER_BOTTOM, line);
|
||||
if(line != null) anchorBorder(HSLFTable.BORDER_BOTTOM, line);
|
||||
this.borderBottom = line;
|
||||
}
|
||||
|
||||
public void setAnchor(Rectangle anchor){
|
||||
super.setAnchor(anchor);
|
||||
|
||||
if(borderTop != null) anchorBorder(Table.BORDER_TOP, borderTop);
|
||||
if(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight);
|
||||
if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom);
|
||||
if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft);
|
||||
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);
|
||||
}
|
||||
}
|
@ -17,7 +17,10 @@
|
||||
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import static org.apache.poi.hslf.record.RecordTypes.OutlineTextRefAtom;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.poi.hslf.model.PPFont;
|
||||
@ -52,8 +55,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
private final TextHeaderAtom _headerAtom;
|
||||
private TextBytesAtom _byteAtom;
|
||||
private TextCharsAtom _charAtom;
|
||||
private StyleTextPropAtom _styleAtom;
|
||||
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
|
||||
private final TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
|
||||
|
||||
protected TextRulerAtom _ruler;
|
||||
protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
|
||||
@ -61,11 +63,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
private HSLFSheet _sheet;
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* all text run records that follow TextHeaderAtom.
|
||||
* (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
|
||||
*/
|
||||
private Record[] _records;
|
||||
// private StyleTextPropAtom styleTextPropAtom;
|
||||
private StyleTextProp9Atom styleTextProp9Atom;
|
||||
|
||||
@ -76,32 +73,30 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
* @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
|
||||
* @param sta the StyleTextPropAtom which defines the character stylings
|
||||
*/
|
||||
/* package */ HSLFTextParagraph(
|
||||
TextHeaderAtom tha,
|
||||
TextBytesAtom tba,
|
||||
TextCharsAtom tca,
|
||||
StyleTextPropAtom sta
|
||||
TextCharsAtom tca
|
||||
) {
|
||||
if (tha == null) {
|
||||
throw new IllegalArgumentException("TextHeaderAtom must be set.");
|
||||
}
|
||||
_headerAtom = tha;
|
||||
_styleAtom = sta;
|
||||
_byteAtom = tba;
|
||||
_charAtom = tca;
|
||||
}
|
||||
|
||||
/* package */ HSLFTextParagraph(HSLFTextParagraph other) {
|
||||
_headerAtom = other._headerAtom;
|
||||
_styleAtom = other._styleAtom;
|
||||
_byteAtom = other._byteAtom;
|
||||
_charAtom = other._charAtom;
|
||||
_paragraphStyle = other._paragraphStyle;
|
||||
_parentShape = other._parentShape;
|
||||
_sheet = other._sheet;
|
||||
_ruler = other._ruler; // ????
|
||||
shapeId = other.shapeId;
|
||||
_records = other._records;
|
||||
}
|
||||
_headerAtom = other._headerAtom;
|
||||
_byteAtom = other._byteAtom;
|
||||
_charAtom = other._charAtom;
|
||||
_parentShape = other._parentShape;
|
||||
_sheet = other._sheet;
|
||||
_ruler = other._ruler;
|
||||
shapeId = other.shapeId;
|
||||
_paragraphStyle.copy(other._paragraphStyle);
|
||||
}
|
||||
|
||||
public void addTextRun(HSLFTextRun run) {
|
||||
_runs.add(run);
|
||||
@ -120,7 +115,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
}
|
||||
|
||||
public void setParagraphStyle(TextPropCollection paragraphStyle) {
|
||||
_paragraphStyle = paragraphStyle;
|
||||
_paragraphStyle.copy(paragraphStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,18 +191,50 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
_ruler = getTextRuler();
|
||||
if (_ruler == null) {
|
||||
_ruler = TextRulerAtom.getParagraphInstance();
|
||||
_headerAtom.getParentRecord().appendChildRecord(_ruler);
|
||||
Record childAfter = _byteAtom;
|
||||
if (childAfter == null) childAfter = _charAtom;
|
||||
if (childAfter == null) childAfter = _headerAtom;
|
||||
_headerAtom.getParentRecord().addChildAfter(_ruler, childAfter);
|
||||
}
|
||||
return _ruler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns records that make up this text run
|
||||
* 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(){
|
||||
return _records;
|
||||
Record r[] = _headerAtom.getParentRecord().getChildRecords();
|
||||
return getRecords(r, new int[]{0}, _headerAtom);
|
||||
}
|
||||
|
||||
private static Record[] getRecords(Record[] records, int[] startIdx, TextHeaderAtom headerAtom) {
|
||||
if (records == null) {
|
||||
throw new NullPointerException("records need to be set.");
|
||||
}
|
||||
|
||||
for (; startIdx[0] < records.length; startIdx[0]++) {
|
||||
Record r = records[startIdx[0]];
|
||||
if (r instanceof TextHeaderAtom && (headerAtom == null || r == headerAtom)) break;
|
||||
}
|
||||
|
||||
if (startIdx[0] >= records.length) {
|
||||
logger.log(POILogger.INFO, "header atom wasn't found - container might contain only an OutlineTextRefAtom");
|
||||
return new Record[0];
|
||||
}
|
||||
|
||||
int length;
|
||||
for (length = 1; startIdx[0]+length < records.length; length++) {
|
||||
if (records[startIdx[0]+length] instanceof TextHeaderAtom) break;
|
||||
}
|
||||
|
||||
Record result[] = new Record[length];
|
||||
System.arraycopy(records, startIdx[0], result, 0, length);
|
||||
startIdx[0] += length;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Numbered List info */
|
||||
@ -220,11 +247,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
return this.styleTextProp9Atom;
|
||||
}
|
||||
|
||||
/** Characters covered */
|
||||
public StyleTextPropAtom getStyleTextPropAtom() {
|
||||
return this._styleAtom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the value of the given Paragraph related TextProp.
|
||||
* Returns -1 if that TextProp isn't present.
|
||||
@ -232,14 +254,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
* Master Sheet will apply.
|
||||
*/
|
||||
private int getParaTextPropVal(String propName) {
|
||||
TextProp prop = null;
|
||||
boolean hardAttribute = false;
|
||||
if (_paragraphStyle != null){
|
||||
prop = _paragraphStyle.findByName(propName);
|
||||
|
||||
BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
|
||||
hardAttribute = maskProp != null && maskProp.getValue() == 0;
|
||||
}
|
||||
TextProp prop = _paragraphStyle.findByName(propName);
|
||||
BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
|
||||
boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
|
||||
if (prop == null && !hardAttribute){
|
||||
HSLFSheet sheet = getSheet();
|
||||
int txtype = getRunType();
|
||||
@ -258,11 +275,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
*/
|
||||
public void setParaTextPropVal(String propName, int val) {
|
||||
// Ensure we have the StyleTextProp atom we're going to need
|
||||
if(_paragraphStyle == null) {
|
||||
_styleAtom = findStyleAtomPresent(_headerAtom, -1);
|
||||
_paragraphStyle = _styleAtom.getParagraphStyles().get(0);
|
||||
}
|
||||
|
||||
assert(_paragraphStyle!=null);
|
||||
TextProp tp = fetchOrAddTextProp(_paragraphStyle, propName);
|
||||
tp.setValue(val);
|
||||
@ -615,10 +627,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
|
||||
protected void setFlag(int index, boolean value) {
|
||||
// Ensure we have the StyleTextProp atom we're going to need
|
||||
if(_paragraphStyle == null) {
|
||||
_paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
|
||||
}
|
||||
|
||||
assert(_paragraphStyle!=null);
|
||||
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);
|
||||
prop.setSubValue(value,index);
|
||||
}
|
||||
@ -653,12 +662,13 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
boolean afterHeader = false;
|
||||
StyleTextPropAtom style = null;
|
||||
for (Record record : header.getParentRecord().getChildRecords()) {
|
||||
if (afterHeader && record.getRecordType() == RecordTypes.TextHeaderAtom.typeID) {
|
||||
long rt = record.getRecordType();
|
||||
if (afterHeader && rt == RecordTypes.TextHeaderAtom.typeID) {
|
||||
// already on the next header, quit searching
|
||||
break;
|
||||
}
|
||||
afterHeader |= (header == record);
|
||||
if (afterHeader && record.getRecordType() == RecordTypes.StyleTextPropAtom.typeID) {
|
||||
if (afterHeader && rt == RecordTypes.StyleTextPropAtom.typeID) {
|
||||
// found it
|
||||
style = (StyleTextPropAtom)record;
|
||||
}
|
||||
@ -789,12 +799,20 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
* If TextSpecInfoAtom is present, we must update the text size in it,
|
||||
* otherwise the ppt will be corrupted
|
||||
*/
|
||||
for (Record r : paragraphs.get(0)._records) {
|
||||
for (Record r : paragraphs.get(0).getRecords()) {
|
||||
if (r instanceof TextSpecInfoAtom) {
|
||||
((TextSpecInfoAtom)r).setParentSize(rawText.length()+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_txtbox instanceof EscherTextboxWrapper) {
|
||||
try {
|
||||
((EscherTextboxWrapper)_txtbox).writeOut(null);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed dummy write", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -817,7 +835,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
if (!isFirst) {
|
||||
TextPropCollection tpc = htp.getParagraphStyle();
|
||||
HSLFTextParagraph prevHtp = htp;
|
||||
htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom, htp._styleAtom);
|
||||
htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom);
|
||||
htp.getParagraphStyle().copy(tpc);
|
||||
htp.setParentShape(prevHtp.getParentShape());
|
||||
htp.setShapeId(prevHtp.getShapeId());
|
||||
@ -930,24 +948,14 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
/**
|
||||
* For a given PPDrawing, grab all the TextRuns
|
||||
*/
|
||||
public static List<List<HSLFTextParagraph>> findTextParagraphs(PPDrawing ppdrawing) {
|
||||
public static List<List<HSLFTextParagraph>> findTextParagraphs(PPDrawing ppdrawing, HSLFSheet sheet) {
|
||||
List<List<HSLFTextParagraph>> runsV = new ArrayList<List<HSLFTextParagraph>>();
|
||||
for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) {
|
||||
runsV.addAll(findTextParagraphs(wrapper));
|
||||
runsV.add(findTextParagraphs(wrapper, sheet));
|
||||
}
|
||||
return runsV;
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
* @param found vector to add any found to
|
||||
*/
|
||||
protected static List<List<HSLFTextParagraph>> findTextParagraphs(final Record[] records) {
|
||||
return findTextParagraphs(records, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans through the supplied record array, looking for
|
||||
* a TextHeaderAtom followed by one of a TextBytesAtom or
|
||||
@ -955,14 +963,73 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
*
|
||||
* @param wrapper an EscherTextboxWrapper
|
||||
*/
|
||||
protected static List<List<HSLFTextParagraph>> findTextParagraphs(EscherTextboxWrapper wrapper) {
|
||||
protected static List<HSLFTextParagraph> findTextParagraphs(EscherTextboxWrapper wrapper, HSLFSheet sheet) {
|
||||
// propagate parents to parent-aware records
|
||||
RecordContainer.handleParentAwareRecords(wrapper);
|
||||
int shapeId = wrapper.getShapeId();
|
||||
List<List<HSLFTextParagraph>> rv = findTextParagraphs(wrapper.getChildRecords(), wrapper.getStyleTextProp9Atom());
|
||||
for (List<HSLFTextParagraph> htpList : rv) {
|
||||
for (HSLFTextParagraph htp : htpList) {
|
||||
List<HSLFTextParagraph> rv = null;
|
||||
|
||||
OutlineTextRefAtom ota = (OutlineTextRefAtom)wrapper.findFirstOfType(OutlineTextRefAtom.typeID);
|
||||
if (ota != null) {
|
||||
// if we are based on an outline, there are no further records to be parsed from the wrapper
|
||||
if (sheet == null) {
|
||||
throw new RuntimeException("Outline atom reference can't be solved without a sheet record");
|
||||
}
|
||||
|
||||
List<List<HSLFTextParagraph>> sheetRuns = sheet.getTextParagraphs();
|
||||
assert(sheetRuns != null);
|
||||
|
||||
int idx = ota.getTextIndex();
|
||||
for (List<HSLFTextParagraph> r : sheetRuns) {
|
||||
if (r.isEmpty()) continue;
|
||||
int ridx = r.get(0).getIndex();
|
||||
if (ridx > idx) break;
|
||||
if (ridx == idx) {
|
||||
if (rv == null) {
|
||||
rv = r;
|
||||
} else {
|
||||
// create a new container
|
||||
// TODO: ... is this case really happening?
|
||||
rv = new ArrayList<HSLFTextParagraph>(rv);
|
||||
rv.addAll(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(rv == null || rv.isEmpty()) {
|
||||
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
|
||||
}
|
||||
} else {
|
||||
if (sheet != null) {
|
||||
// check sheet runs first, so we get exactly the same paragraph list
|
||||
List<List<HSLFTextParagraph>> sheetRuns = sheet.getTextParagraphs();
|
||||
assert(sheetRuns != null);
|
||||
|
||||
for (List<HSLFTextParagraph> paras : sheetRuns) {
|
||||
if (!paras.isEmpty() && paras.get(0)._headerAtom.getParentRecord() == wrapper) {
|
||||
rv = paras;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == null) {
|
||||
// if we haven't found the wrapper in the sheet runs, create a new paragraph list from its record
|
||||
List<List<HSLFTextParagraph>> rvl = findTextParagraphs(wrapper.getChildRecords());
|
||||
switch (rvl.size()) {
|
||||
case 0: break; // nothing found
|
||||
case 1: rv = rvl.get(0); break; // normal case
|
||||
default:
|
||||
throw new RuntimeException("TextBox contains more than one list of paragraphs.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv != null) {
|
||||
StyleTextProp9Atom styleTextProp9Atom = wrapper.getStyleTextProp9Atom();
|
||||
|
||||
for (HSLFTextParagraph htp : rv) {
|
||||
htp.setShapeId(shapeId);
|
||||
htp.setStyleTextProp9Atom(styleTextProp9Atom);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
@ -974,77 +1041,59 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
* a TextCharsAtom. Builds up TextRuns from these
|
||||
*
|
||||
* @param records the records to build from
|
||||
* @param styleTextProp9Atom an optional StyleTextProp9Atom with numbered lists info
|
||||
*/
|
||||
protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records, StyleTextProp9Atom styleTextProp9Atom) {
|
||||
protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records) {
|
||||
List<List<HSLFTextParagraph>> paragraphCollection = new ArrayList<List<HSLFTextParagraph>>();
|
||||
|
||||
if (records == null) {
|
||||
throw new NullPointerException("records need to be filled.");
|
||||
}
|
||||
int[] recordIdx = {0};
|
||||
|
||||
int recordIdx;
|
||||
for (recordIdx = 0; recordIdx < records.length; recordIdx++) {
|
||||
if (records[recordIdx] instanceof TextHeaderAtom) break;
|
||||
}
|
||||
|
||||
if (recordIdx == records.length) {
|
||||
logger.log(POILogger.INFO, "No text records found.");
|
||||
return paragraphCollection;
|
||||
}
|
||||
|
||||
for (int slwtIndex = 0; recordIdx < records.length; slwtIndex++) {
|
||||
List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
|
||||
paragraphCollection.add(paragraphs);
|
||||
|
||||
TextHeaderAtom header = (TextHeaderAtom)records[recordIdx++];
|
||||
for (int slwtIndex = 0; recordIdx[0] < records.length; slwtIndex++) {
|
||||
TextHeaderAtom header = null;
|
||||
TextBytesAtom tbytes = null;
|
||||
TextCharsAtom tchars = null;
|
||||
TextRulerAtom ruler = null;
|
||||
MasterTextPropAtom indents = null;
|
||||
|
||||
List<Record> otherRecordList = new ArrayList<Record>();
|
||||
|
||||
for (; recordIdx < records.length; recordIdx++) {
|
||||
Record r = records[recordIdx];
|
||||
for (Record r : getRecords(records, recordIdx, null)) {
|
||||
long rt = r.getRecordType();
|
||||
if (RecordTypes.TextHeaderAtom.typeID == rt) break;
|
||||
else if (RecordTypes.TextBytesAtom.typeID == rt) tbytes = (TextBytesAtom)r;
|
||||
else if (RecordTypes.TextCharsAtom.typeID == rt) tchars = (TextCharsAtom)r;
|
||||
// don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below
|
||||
else if (RecordTypes.TextRulerAtom.typeID == rt) ruler = (TextRulerAtom)r;
|
||||
else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
|
||||
if (RecordTypes.TextHeaderAtom.typeID == rt) {
|
||||
header = (TextHeaderAtom)r;
|
||||
} else if (RecordTypes.TextBytesAtom.typeID == rt) {
|
||||
tbytes = (TextBytesAtom)r;
|
||||
} else if (RecordTypes.TextCharsAtom.typeID == rt) {
|
||||
tchars = (TextCharsAtom)r;
|
||||
} else if (RecordTypes.TextRulerAtom.typeID == rt) {
|
||||
ruler = (TextRulerAtom)r;
|
||||
} else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
|
||||
indents = (MasterTextPropAtom)r;
|
||||
otherRecordList.add(indents);
|
||||
} else {
|
||||
otherRecordList.add(r);
|
||||
}
|
||||
// don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below
|
||||
}
|
||||
|
||||
assert(header != null);
|
||||
if (header == null) break;
|
||||
|
||||
if (header.getParentRecord() instanceof SlideListWithText) {
|
||||
// runs found in PPDrawing are not linked with SlideListWithTexts
|
||||
header.setIndex(slwtIndex);
|
||||
}
|
||||
|
||||
Record otherRecords[] = otherRecordList.toArray(new Record[otherRecordList.size()]);
|
||||
|
||||
if (tbytes == null && tchars == null) {
|
||||
tbytes = new TextBytesAtom();
|
||||
// header.getParentRecord().addChildAfter(tbytes, header);
|
||||
// don't add record yet - set it in storeText
|
||||
logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating dummy record for later saving.");
|
||||
}
|
||||
|
||||
String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
|
||||
StyleTextPropAtom styles = findStyleAtomPresent(header, rawText.length());
|
||||
|
||||
List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
|
||||
paragraphCollection.add(paragraphs);
|
||||
|
||||
// split, but keep delimiter
|
||||
for (String para : rawText.split("(?<=\r)")) {
|
||||
HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, styles);
|
||||
HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars);
|
||||
paragraphs.add(tpara);
|
||||
tpara.setStyleTextProp9Atom(styleTextProp9Atom);
|
||||
tpara._ruler = ruler;
|
||||
tpara._records = otherRecords;
|
||||
tpara.getParagraphStyle().updateTextSize(para.length());
|
||||
|
||||
HSLFTextRun trun = new HSLFTextRun(tpara);
|
||||
@ -1059,6 +1108,10 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
}
|
||||
}
|
||||
|
||||
if (paragraphCollection.isEmpty()) {
|
||||
logger.log(POILogger.DEBUG, "No text records found.");
|
||||
}
|
||||
|
||||
return paragraphCollection;
|
||||
}
|
||||
|
||||
@ -1166,9 +1219,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
||||
TextPropCollection charStyle = sta.addCharacterTextPropCollection(1);
|
||||
wrapper.appendChildRecord(sta);
|
||||
|
||||
HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, sta);
|
||||
HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null);
|
||||
htp.setParagraphStyle(paraStyle);
|
||||
htp._records = new Record[0];
|
||||
|
||||
HSLFTextRun htr = new HSLFTextRun(htp);
|
||||
htr.setCharacterStyle(charStyle);
|
||||
|
@ -92,7 +92,7 @@ public final class HSLFTextRun implements TextRun {
|
||||
* Change the text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
_runText = text;
|
||||
_runText = HSLFTextParagraph.toInternalString(text);
|
||||
}
|
||||
|
||||
// --------------- Internal helpers on rich text properties -------
|
||||
|
@ -159,10 +159,29 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
|
||||
}
|
||||
|
||||
protected EscherTextboxWrapper getEscherTextboxWrapper(){
|
||||
if(_txtbox == null){
|
||||
EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
|
||||
if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
|
||||
if(_txtbox != null) return _txtbox;
|
||||
|
||||
EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
|
||||
if (textRecord == null) return null;
|
||||
|
||||
HSLFSheet sheet = getSheet();
|
||||
if (sheet != null) {
|
||||
PPDrawing drawing = sheet.getPPDrawing();
|
||||
if (drawing != null) {
|
||||
EscherTextboxWrapper wrappers[] = drawing.getTextboxWrappers();
|
||||
if (wrappers != null) {
|
||||
for (EscherTextboxWrapper w : wrappers) {
|
||||
// check for object identity
|
||||
if (textRecord == w.getEscherRecord()) {
|
||||
_txtbox = w;
|
||||
return _txtbox;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_txtbox = new EscherTextboxWrapper(textRecord);
|
||||
return _txtbox;
|
||||
}
|
||||
|
||||
@ -507,13 +526,17 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
|
||||
_paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
|
||||
_txtbox = _paragraphs.get(0).getTextboxWrapper();
|
||||
} else {
|
||||
initParagraphsFromSheetRecords();
|
||||
if (_paragraphs.isEmpty()) {
|
||||
List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
|
||||
if (!llhtp.isEmpty()) {
|
||||
_paragraphs.addAll(llhtp.get(0));
|
||||
}
|
||||
_paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
|
||||
if (_paragraphs == null || _paragraphs.isEmpty()) {
|
||||
throw new RuntimeException("TextRecord didn't contained any text lines");
|
||||
}
|
||||
// initParagraphsFromSheetRecords();
|
||||
// if (_paragraphs.isEmpty()) {
|
||||
// List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
|
||||
// if (!llhtp.isEmpty()) {
|
||||
// _paragraphs.addAll(llhtp.get(0));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
for (HSLFTextParagraph p : _paragraphs) {
|
||||
@ -536,57 +559,47 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
|
||||
}
|
||||
}
|
||||
|
||||
protected void initParagraphsFromSheetRecords(){
|
||||
EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
|
||||
HSLFSheet sheet = getSheet();
|
||||
|
||||
if(sheet == null || txtbox == null) return;
|
||||
|
||||
OutlineTextRefAtom ota = null;
|
||||
|
||||
Record[] child = txtbox.getChildRecords();
|
||||
for (int i = 0; i < child.length; i++) {
|
||||
if (child[i] instanceof OutlineTextRefAtom) {
|
||||
ota = (OutlineTextRefAtom)child[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
|
||||
_paragraphs.clear();
|
||||
if (sheetRuns != null) {
|
||||
if (ota != null) {
|
||||
int idx = ota.getTextIndex();
|
||||
for (List<HSLFTextParagraph> r : sheetRuns) {
|
||||
if (r.isEmpty()) continue;
|
||||
int ridx = r.get(0).getIndex();
|
||||
if (ridx > idx) break;
|
||||
if (ridx == idx) _paragraphs.addAll(r);
|
||||
}
|
||||
if(_paragraphs.isEmpty()) {
|
||||
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
|
||||
}
|
||||
} else {
|
||||
int shapeId = getShapeId();
|
||||
for (List<HSLFTextParagraph> r : sheetRuns) {
|
||||
if (r.isEmpty()) continue;
|
||||
if (r.get(0).getShapeId() == shapeId) _paragraphs.addAll(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure the same references child records of TextRun
|
||||
// TODO: check the purpose of this ...
|
||||
// if(_txtrun != null) {
|
||||
// for (int i = 0; i < child.length; i++) {
|
||||
// for (Record r : _txtrun.getRecords()) {
|
||||
// if (child[i].getRecordType() == r.getRecordType()) {
|
||||
// child[i] = r;
|
||||
// }
|
||||
// }
|
||||
// protected void initParagraphsFromSheetRecords(){
|
||||
// EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
|
||||
// HSLFSheet sheet = getSheet();
|
||||
//
|
||||
// if (sheet == null || txtbox == null) return;
|
||||
// List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
|
||||
// if (sheetRuns == null) return;
|
||||
//
|
||||
// _paragraphs.clear();
|
||||
// OutlineTextRefAtom ota = (OutlineTextRefAtom)txtbox.findFirstOfType(OutlineTextRefAtom.typeID);
|
||||
//
|
||||
// if (ota != null) {
|
||||
// int idx = ota.getTextIndex();
|
||||
// for (List<HSLFTextParagraph> r : sheetRuns) {
|
||||
// if (r.isEmpty()) continue;
|
||||
// int ridx = r.get(0).getIndex();
|
||||
// if (ridx > idx) break;
|
||||
// if (ridx == idx) _paragraphs.addAll(r);
|
||||
// }
|
||||
// if(_paragraphs.isEmpty()) {
|
||||
// logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
|
||||
// }
|
||||
// } else {
|
||||
// int shapeId = getShapeId();
|
||||
// for (List<HSLFTextParagraph> r : sheetRuns) {
|
||||
// if (r.isEmpty()) continue;
|
||||
// if (r.get(0).getShapeId() == shapeId) _paragraphs.addAll(r);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//
|
||||
// // ensure the same references child records of TextRun - see #48916
|
||||
//// if(_txtrun != null) {
|
||||
//// for (int i = 0; i < child.length; i++) {
|
||||
//// for (Record r : _txtrun.getRecords()) {
|
||||
//// if (child[i].getRecordType() == r.getRecordType()) {
|
||||
//// child[i] = r;
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
|
||||
/*
|
||||
// 0xB acts like cariage return in page titles and like blank in the others
|
||||
@ -740,7 +753,8 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
|
||||
* Also updates the styles to the correct text length.
|
||||
*/
|
||||
protected void storeText() {
|
||||
HSLFTextParagraph.storeText(_paragraphs);
|
||||
List<HSLFTextParagraph> paras = getTextParagraphs();
|
||||
HSLFTextParagraph.storeText(paras);
|
||||
}
|
||||
// Accesser methods follow
|
||||
|
||||
|
@ -29,7 +29,7 @@ import org.apache.poi.hslf.record.SlideAtom;
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class HSLFTitleMaster extends HSLFMasterSheet {
|
||||
private final List<List<HSLFTextParagraph>> _runs = new ArrayList<List<HSLFTextParagraph>>();
|
||||
private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
|
||||
|
||||
/**
|
||||
* Constructs a TitleMaster
|
||||
@ -38,14 +38,16 @@ public final class HSLFTitleMaster extends HSLFMasterSheet {
|
||||
public HSLFTitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
|
||||
super(record, sheetNo);
|
||||
|
||||
_runs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing()));
|
||||
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
|
||||
if (!_paragraphs.contains(l)) _paragraphs.add(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the TextRuns found
|
||||
*/
|
||||
public List<List<HSLFTextParagraph>> getTextParagraphs() {
|
||||
return _runs;
|
||||
return _paragraphs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,8 +69,8 @@ public class DrawFactory {
|
||||
return getDrawable((FreeformShape<? extends TextParagraph<? extends TextRun>>)shape);
|
||||
} else if (shape instanceof TextShape) {
|
||||
return getDrawable((TextShape<? extends TextParagraph<? extends TextRun>>)shape);
|
||||
} else if (shape instanceof ShapeGroup) {
|
||||
return getDrawable((ShapeGroup<? extends Shape>)shape);
|
||||
} else if (shape instanceof GroupShape) {
|
||||
return getDrawable((GroupShape<? extends Shape>)shape);
|
||||
} else if (shape instanceof PictureShape) {
|
||||
return getDrawable((PictureShape)shape);
|
||||
} else if (shape instanceof Background) {
|
||||
@ -110,8 +110,8 @@ public class DrawFactory {
|
||||
return new DrawTextShape<T>(shape);
|
||||
}
|
||||
|
||||
public <T extends ShapeGroup<? extends Shape>> DrawShapeGroup<T> getDrawable(T shape) {
|
||||
return new DrawShapeGroup<T>(shape);
|
||||
public <T extends GroupShape<? extends Shape>> DrawGroupShape<T> getDrawable(T shape) {
|
||||
return new DrawGroupShape<T>(shape);
|
||||
}
|
||||
|
||||
public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) {
|
||||
|
@ -7,9 +7,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import org.apache.poi.sl.usermodel.*;
|
||||
|
||||
|
||||
public class DrawShapeGroup<T extends ShapeGroup<? extends Shape>> extends DrawShape<T> implements Drawable {
|
||||
public class DrawGroupShape<T extends GroupShape<? extends Shape>> extends DrawShape<T> implements Drawable {
|
||||
|
||||
public DrawShapeGroup(T shape) {
|
||||
public DrawGroupShape(T shape) {
|
||||
super(shape);
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ public class DrawShapeGroup<T extends ShapeGroup<? extends Shape>> extends DrawS
|
||||
tx.translate(-interior.getX(), -interior.getY());
|
||||
|
||||
DrawFactory drawFact = DrawFactory.getInstance(graphics);
|
||||
AffineTransform at2 = graphics.getTransform();
|
||||
|
||||
for (Shape child : shape) {
|
||||
// remember the initial transform and restore it after we are done with the drawing
|
||||
@ -46,7 +47,7 @@ public class DrawShapeGroup<T extends ShapeGroup<? extends Shape>> extends DrawS
|
||||
graphics.setRenderingHint(Drawable.GRESTORE, true);
|
||||
}
|
||||
|
||||
graphics.setTransform(at2);
|
||||
graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0);
|
||||
|
||||
}
|
||||
}
|
@ -25,11 +25,10 @@ public class DrawShape<T extends Shape> implements Drawable {
|
||||
if (!(shape instanceof PlaceableShape)) return;
|
||||
|
||||
PlaceableShape ps = (PlaceableShape)shape;
|
||||
Rectangle2D anchor = ps.getAnchor();
|
||||
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
|
||||
if(tx != null) {
|
||||
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
final Rectangle2D anchor = (tx != null)
|
||||
? tx.createTransformedShape(ps.getAnchor()).getBounds2D()
|
||||
: ps.getAnchor();
|
||||
|
||||
// rotation
|
||||
double rotation = ps.getRotation();
|
||||
@ -39,7 +38,8 @@ public class DrawShape<T extends Shape> implements Drawable {
|
||||
double centerY = anchor.getCenterY();
|
||||
|
||||
// normalize rotation
|
||||
rotation = (360.+(rotation%360.))%360.;
|
||||
rotation %= 360.;
|
||||
if (rotation < 0) rotation += 360.;
|
||||
int quadrant = (((int)rotation+45)/90)%4;
|
||||
double scaleX = 1.0, scaleY = 1.0;
|
||||
|
||||
@ -53,26 +53,43 @@ public class DrawShape<T extends Shape> implements Drawable {
|
||||
// think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might
|
||||
// be already (differently) scaled, so you can paint the shape in its default orientation
|
||||
// and later on, turn it around again to compare it with its original size ...
|
||||
AffineTransform txg = new AffineTransform(); // graphics coordinate space
|
||||
AffineTransform txs = new AffineTransform(tx); // shape coordinate space
|
||||
|
||||
// graphics coordinate space
|
||||
AffineTransform txg = new AffineTransform();
|
||||
txg.translate(centerX, centerY);
|
||||
txg.rotate(Math.toRadians(quadrant*90));
|
||||
txg.rotate(Math.toRadians(90));
|
||||
txg.translate(-centerX, -centerY);
|
||||
txs.translate(centerX, centerY);
|
||||
txs.rotate(Math.toRadians(-quadrant*90));
|
||||
txs.translate(-centerX, -centerY);
|
||||
txg.concatenate(txs);
|
||||
Rectangle2D anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
|
||||
|
||||
boolean oldVariant = true;
|
||||
Rectangle2D anchor2;
|
||||
|
||||
if (oldVariant) {
|
||||
// shape coordinate space
|
||||
AffineTransform txs = new AffineTransform(tx);
|
||||
txs.translate(centerX, centerY);
|
||||
txs.rotate(Math.toRadians(90));
|
||||
txs.translate(-centerX, -centerY);
|
||||
txg.concatenate(txs);
|
||||
anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
|
||||
} else {
|
||||
anchor2 = txg.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
|
||||
scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();
|
||||
scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();
|
||||
}
|
||||
|
||||
graphics.translate(centerX, centerY);
|
||||
graphics.rotate(Math.toRadians(rotation-quadrant*90.));
|
||||
graphics.scale(scaleX, scaleY);
|
||||
graphics.rotate(Math.toRadians(quadrant*90));
|
||||
graphics.translate(-centerX, -centerY);
|
||||
} else {
|
||||
graphics.translate(centerX, centerY);
|
||||
graphics.rotate(Math.toRadians(rotation));
|
||||
graphics.scale(scaleX, scaleY);
|
||||
graphics.translate(-centerX, -centerY);
|
||||
}
|
||||
// transformation is applied reversed ...
|
||||
graphics.translate(centerX, centerY);
|
||||
graphics.rotate(Math.toRadians(rotation-quadrant*90.));
|
||||
graphics.scale(scaleX, scaleY);
|
||||
graphics.rotate(Math.toRadians(quadrant*90));
|
||||
graphics.translate(-centerX, -centerY);
|
||||
}
|
||||
|
||||
//flip horizontal
|
||||
|
@ -32,6 +32,23 @@ public interface Drawable {
|
||||
public boolean isCompatibleValue(Object val) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (intKey()) {
|
||||
case 1: return "DRAW_FACTORY";
|
||||
case 2: return "GROUP_TRANSFORM";
|
||||
case 3: return "IMAGE_RENDERER";
|
||||
case 4: return "TEXT_RENDERING_MODE";
|
||||
case 5: return "GRADIENT_SHAPE";
|
||||
case 6: return "PRESET_GEOMETRY_CACHE";
|
||||
case 7: return "FONT_HANDLER";
|
||||
case 8: return "FONT_FALLBACK";
|
||||
case 9: return "FONT_MAP";
|
||||
case 10: return "GSAVE";
|
||||
case 11: return "GRESTORE";
|
||||
default: return "UNKNOWN_ID "+intKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,18 +30,35 @@ import javax.imageio.ImageIO;
|
||||
/**
|
||||
* For now this class renders only images supported by the javax.imageio.ImageIO
|
||||
* framework. Subclasses can override this class to support other formats, for
|
||||
* example, Use Apache batik to render WMF:
|
||||
* example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* public class MyImageRendener extends ImageRendener {
|
||||
* InputStream data;
|
||||
*
|
||||
* public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
|
||||
* // draw image
|
||||
* DataInputStream is = new DataInputStream(data);
|
||||
* org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore =
|
||||
* new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore();
|
||||
* try {
|
||||
* wmfStore.read(is);
|
||||
* } catch (IOException e){
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* float scale = (float)anchor.width/wmfStore.getWidthPixels();
|
||||
*
|
||||
* org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter =
|
||||
* new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale);
|
||||
* graphics.translate(anchor.x, anchor.y);
|
||||
* painter.paint(graphics);
|
||||
* }
|
||||
*
|
||||
* public void loadImage(InputStream data, String contentType) throws IOException {
|
||||
* if ("image/wmf".equals(contentType)) {
|
||||
* this.data = data;
|
||||
* // use Apache Batik to handle WMF
|
||||
* } else {
|
||||
* super.loadImage(data,contentType);
|
||||
@ -147,12 +164,14 @@ public class ImageRenderer {
|
||||
int iw = img.getWidth();
|
||||
int ih = img.getHeight();
|
||||
|
||||
|
||||
double cw = (100000-clip.left-clip.right) / 100000.0;
|
||||
double ch = (100000-clip.top-clip.bottom) / 100000.0;
|
||||
double sx = anchor.getWidth()/(iw*cw);
|
||||
double sy = anchor.getHeight()/(ih*ch);
|
||||
double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
|
||||
double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
|
||||
|
||||
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
||||
|
||||
Shape clipOld = graphics.getClip();
|
||||
|
@ -19,6 +19,21 @@ package org.apache.poi.sl.usermodel;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
public interface ShapeGroup<T extends Shape> extends Shape, ShapeContainer<T>, PlaceableShape {
|
||||
public interface GroupShape<T extends Shape> extends Shape, ShapeContainer<T>, PlaceableShape {
|
||||
|
||||
/**
|
||||
* Gets the coordinate space of this group. All children are constrained
|
||||
* to these coordinates.
|
||||
*
|
||||
* @param anchor the coordinate space of this group
|
||||
*/
|
||||
Rectangle2D getInteriorAnchor();
|
||||
|
||||
/**
|
||||
* Sets the coordinate space of this group. All children are constrained
|
||||
* to these coordinates.
|
||||
*
|
||||
* @param anchor the coordinate space of this group
|
||||
*/
|
||||
void setInteriorAnchor(Rectangle2D anchor);
|
||||
}
|
@ -20,9 +20,17 @@ package org.apache.poi.sl.usermodel;
|
||||
import java.awt.Insets;
|
||||
|
||||
public interface PictureShape extends SimpleShape {
|
||||
PictureData getPictureData();
|
||||
/**
|
||||
* Returns the picture data for this picture.
|
||||
*
|
||||
* @return the picture data for this picture.
|
||||
*/
|
||||
PictureData getPictureData();
|
||||
|
||||
/**
|
||||
* Returns the clipping values as percent ratio relatively to the image size.
|
||||
* The clipping are returned as insets converted/scaled to 100000 (=100%).
|
||||
*
|
||||
* @return the clipping rectangle, which is given in percent in relation to the image width/height
|
||||
*/
|
||||
Insets getClipping();
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.poi.sl.usermodel;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
|
||||
/**
|
||||
* Common parent of Slides, Notes and Masters
|
||||
@ -34,4 +36,11 @@ public interface Sheet<T extends Shape, SS extends SlideShow> extends ShapeConta
|
||||
MasterSheet<T,SS> getMasterSheet();
|
||||
|
||||
Background getBackground();
|
||||
|
||||
/**
|
||||
* Convenience method to draw a sheet to a graphics context
|
||||
*
|
||||
* @param graphics
|
||||
*/
|
||||
void draw(Graphics2D graphics);
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import org.junit.runners.Suite;
|
||||
TestFreeform.class,
|
||||
TestHeadersFooters.class,
|
||||
TestHyperlink.class,
|
||||
TestImagePainter.class,
|
||||
TestLine.class,
|
||||
TestMovieShape.class,
|
||||
TestOleEmbedding.class,
|
||||
|
@ -1,55 +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 java.awt.Graphics2D;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hslf.blip.BitmapPainter;
|
||||
import org.apache.poi.hslf.blip.ImagePainter;
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
||||
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
||||
|
||||
/**
|
||||
* Test Picture shape.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class TestImagePainter extends TestCase {
|
||||
|
||||
private static class CustomImagePainter implements ImagePainter {
|
||||
public CustomImagePainter() {
|
||||
// no fields to initialise
|
||||
}
|
||||
public void paint(Graphics2D graphics, HSLFPictureData pict, HSLFPictureShape parent){
|
||||
//do noting
|
||||
}
|
||||
}
|
||||
|
||||
public void testImagePainter() {
|
||||
|
||||
ImagePainter pntr = HSLFPictureData.getImagePainter(HSLFPictureShape.PNG);
|
||||
assertTrue(HSLFPictureData.getImagePainter(HSLFPictureShape.PNG) instanceof BitmapPainter);
|
||||
assertTrue(HSLFPictureData.getImagePainter(HSLFPictureShape.JPEG) instanceof BitmapPainter);
|
||||
assertTrue(HSLFPictureData.getImagePainter(HSLFPictureShape.DIB) instanceof BitmapPainter);
|
||||
|
||||
HSLFPictureData.setImagePainter(HSLFPictureShape.WMF, new CustomImagePainter());
|
||||
assertTrue(HSLFPictureData.getImagePainter(HSLFPictureShape.WMF) instanceof CustomImagePainter);
|
||||
}
|
||||
}
|
@ -43,15 +43,15 @@ public final class TestTable {
|
||||
|
||||
HSLFSlide slide = ppt.createSlide();
|
||||
|
||||
Table tbl = new Table(2, 5);
|
||||
HSLFTable tbl = new HSLFTable(2, 5);
|
||||
slide.addShape(tbl);
|
||||
|
||||
TableCell cell = tbl.getCell(0, 0);
|
||||
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 Table);
|
||||
Table tbl2 = (Table)slide.getShapes().get(0);
|
||||
assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
|
||||
HSLFTable tbl2 = (HSLFTable)slide.getShapes().get(0);
|
||||
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
|
||||
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
|
||||
|
||||
@ -61,8 +61,8 @@ public final class TestTable {
|
||||
|
||||
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||
slide = ppt.getSlides().get(0);
|
||||
assertTrue(slide.getShapes().get(0) instanceof Table);
|
||||
Table tbl3 = (Table)slide.getShapes().get(0);
|
||||
assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
|
||||
HSLFTable tbl3 = (HSLFTable)slide.getShapes().get(0);
|
||||
assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns());
|
||||
assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
|
||||
}
|
||||
@ -75,7 +75,7 @@ public final class TestTable {
|
||||
HSLFSlideShow ppt = new HSLFSlideShow();
|
||||
HSLFSlide slide = ppt.createSlide();
|
||||
List<HSLFShape> shapes;
|
||||
Table tbl1 = new Table(1, 5);
|
||||
HSLFTable tbl1 = new HSLFTable(1, 5);
|
||||
assertEquals(5, tbl1.getNumberOfColumns());
|
||||
assertEquals(1, tbl1.getNumberOfRows());
|
||||
slide.addShape(tbl1);
|
||||
@ -83,7 +83,7 @@ public final class TestTable {
|
||||
shapes = slide.getShapes();
|
||||
assertEquals(1, shapes.size());
|
||||
|
||||
Table tbl2 = (Table)shapes.get(0);
|
||||
HSLFTable tbl2 = (HSLFTable)shapes.get(0);
|
||||
assertSame(tbl1.getSpContainer(), tbl2.getSpContainer());
|
||||
|
||||
assertEquals(tbl1.getNumberOfColumns(), tbl2.getNumberOfColumns());
|
||||
@ -93,13 +93,13 @@ public final class TestTable {
|
||||
@Test
|
||||
public void testIllegalCOnstruction(){
|
||||
try {
|
||||
new Table(0, 5);
|
||||
new HSLFTable(0, 5);
|
||||
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
|
||||
} catch (IllegalArgumentException e){
|
||||
|
||||
}
|
||||
try {
|
||||
new Table(5, 0);
|
||||
new HSLFTable(5, 0);
|
||||
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
|
||||
} catch (IllegalArgumentException e){
|
||||
|
||||
|
@ -281,7 +281,7 @@ public final class TestAddingSlides extends TestCase {
|
||||
assertEquals(14, doc.getNotesSlideListWithText().getSlideAtomsSets().length);
|
||||
|
||||
//remove all slides, corresponding notes should be removed too
|
||||
for (int i = 0; i < slides.size(); i++) {
|
||||
for (int i = slides.size(); i > 0; i--) {
|
||||
ppt.removeSlide(0);
|
||||
}
|
||||
assertEquals(0, ppt.getSlides().size());
|
||||
|
@ -18,14 +18,10 @@
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@ -44,14 +40,14 @@ import org.apache.poi.ddf.EscherProperties;
|
||||
import org.apache.poi.hslf.HSLFTestDataSamples;
|
||||
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
|
||||
import org.apache.poi.hslf.model.*;
|
||||
import org.apache.poi.hslf.record.Document;
|
||||
import org.apache.poi.hslf.record.Record;
|
||||
import org.apache.poi.hslf.record.SlideListWithText;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||
import org.apache.poi.hslf.record.*;
|
||||
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
|
||||
import org.apache.poi.hslf.record.TextHeaderAtom;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.util.*;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@ -527,7 +523,7 @@ public final class TestBugs {
|
||||
for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) {
|
||||
if (! tr.get(0).isDrawingBased()) str++;
|
||||
}
|
||||
assertEquals(1, str);
|
||||
assertEquals(2, str);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -17,29 +17,22 @@
|
||||
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.hslf.model.TextPainter;
|
||||
import org.apache.poi.sl.draw.Drawable;
|
||||
import org.apache.poi.util.TempFile;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@ -50,7 +43,7 @@ import org.junit.Test;
|
||||
public class TestFontRendering {
|
||||
private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
|
||||
|
||||
@Ignore("This fails on some systems because fonts are rendered slightly different")
|
||||
// @Ignore2("This fails on some systems because fonts are rendered slightly different")
|
||||
@Test
|
||||
public void bug55902mixedFontWithChineseCharacters() throws Exception {
|
||||
// font files need to be downloaded first via
|
||||
@ -86,7 +79,7 @@ public class TestFontRendering {
|
||||
|
||||
Dimension pgsize = ss.getPageSize();
|
||||
|
||||
HSLFSlide slide = ss.getSlides()[0];
|
||||
HSLFSlide slide = ss.getSlides().get(0);
|
||||
|
||||
// render it
|
||||
double zoom = 1;
|
||||
@ -95,8 +88,8 @@ public class TestFontRendering {
|
||||
|
||||
BufferedImage imgActual = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_3BYTE_BGR);
|
||||
Graphics2D graphics = imgActual.createGraphics();
|
||||
graphics.setRenderingHint(TextPainter.KEY_FONTFALLBACK, fallbackMap);
|
||||
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap);
|
||||
graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
|
||||
graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
@ -116,7 +109,7 @@ public class TestFontRendering {
|
||||
if(!Arrays.equals(expectedData, actualData)) {
|
||||
ImageIO.write(imgActual, "PNG", TempFile.createTempFile("TestFontRendering", ".png"));
|
||||
}
|
||||
assertTrue("Expected to have matching raster-arrays, but found differences, size " + expectedData.length + " and " + actualData.length,
|
||||
Arrays.equals(expectedData, actualData));
|
||||
|
||||
assertArrayEquals("Expected to have matching raster-arrays, but found differences", expectedData, actualData);
|
||||
}
|
||||
}
|
||||
|
@ -79,10 +79,14 @@ public final class TestNumberedList3 {
|
||||
assertEquals(Short.valueOf((short)1), autoNumbers[0].getAutoNumberStartNumber());//Default value = 1 will be used
|
||||
assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox0[0].getAutoNumberScheme());
|
||||
|
||||
final List<TextPropCollection> textProps = textParass.get(1).get(0).getStyleTextPropAtom().getCharacterStyles();
|
||||
assertEquals(1, textProps.size());
|
||||
final TextPropCollection textProp = textProps.get(0);
|
||||
assertEquals(67, textProp.getCharactersCovered());
|
||||
int chCovered = 0;
|
||||
for (HSLFTextParagraph htp : textParass.get(1)) {
|
||||
for (HSLFTextRun htr : htp.getTextRuns()) {
|
||||
TextPropCollection textProp = htr.getCharacterStyle();
|
||||
chCovered += textProp.getCharactersCovered();
|
||||
}
|
||||
}
|
||||
assertEquals(67, chCovered);
|
||||
|
||||
assertTrue(textParass.get(0).get(0).isBullet());
|
||||
|
||||
|
@ -17,18 +17,11 @@
|
||||
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
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.*;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -36,8 +29,12 @@ import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.hslf.usermodel.*;
|
||||
import org.apache.poi.hssf.usermodel.DummyGraphics2d;
|
||||
import org.apache.poi.sl.draw.Drawable;
|
||||
import org.apache.poi.sl.usermodel.Slide;
|
||||
import org.apache.poi.sl.usermodel.SlideShow;
|
||||
import org.apache.poi.util.JvmBugs;
|
||||
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -143,45 +140,42 @@ public final class TestPicture {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Just for visual validation - antialiasing is different on various systems")
|
||||
// @Ignore("Just for visual validation - antialiasing is different on various systems")
|
||||
public void bug54541() throws Exception {
|
||||
// InputStream xis = _slTests.openResourceAsStream("54542_cropped_bitmap.pptx");
|
||||
// XMLSlideShow xss = new XMLSlideShow(xis);
|
||||
// xis.close();
|
||||
//
|
||||
// Dimension xpg = xss.getPageSize();
|
||||
// for(XSLFSlide slide : xss.getSlides()) {
|
||||
// BufferedImage img = new BufferedImage(xpg.width, xpg.height, BufferedImage.TYPE_INT_RGB);
|
||||
// Graphics2D graphics = img.createGraphics();
|
||||
// fixFonts(graphics);
|
||||
// slide.draw(graphics);
|
||||
// ImageIO.write(img, "PNG", new File("testx.png"));
|
||||
// }
|
||||
//
|
||||
// System.out.println("########################");
|
||||
|
||||
InputStream is = _slTests.openResourceAsStream("54541_cropped_bitmap.ppt");
|
||||
HSLFSlideShow ss = new HSLFSlideShow(is);
|
||||
String file = new String[]{
|
||||
"54542_cropped_bitmap.pptx",
|
||||
"54541_cropped_bitmap.ppt",
|
||||
"54541_cropped_bitmap2.ppt",
|
||||
"sample_pptx_grouping_issues.pptx"
|
||||
}[3];
|
||||
InputStream is = _slTests.openResourceAsStream(file);
|
||||
SlideShow ss = file.endsWith("pptx") ? new XMLSlideShow(is) : new HSLFSlideShow(is);
|
||||
is.close();
|
||||
|
||||
boolean debugOut = false;
|
||||
Dimension pg = ss.getPageSize();
|
||||
int i=1;
|
||||
for(HSLFSlide slide : ss.getSlides()) {
|
||||
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D graphics = img.createGraphics();
|
||||
fixFonts(graphics);
|
||||
slide.draw(graphics);
|
||||
ImageIO.write(img, "PNG", new File("test"+(i++)+".png"));
|
||||
for(Slide<?,?,?> slide : ss.getSlides()) {
|
||||
if (debugOut) {
|
||||
DummyGraphics2d graphics = new DummyGraphics2d();
|
||||
slide.draw(graphics);
|
||||
} else {
|
||||
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D graphics = img.createGraphics();
|
||||
fixFonts(graphics);
|
||||
slide.draw(graphics);
|
||||
ImageIO.write(img, "PNG", new File("test"+(i++)+"hslf.png"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fixFonts(Graphics2D graphics) {
|
||||
if (!JvmBugs.hasLineBreakMeasurerBug()) return;
|
||||
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);
|
||||
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
|
||||
if (fontMap == null) fontMap = new HashMap<String,String>();
|
||||
fontMap.put("Calibri", "Lucida Sans");
|
||||
fontMap.put("Cambria", "Lucida Bright");
|
||||
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap);
|
||||
graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
|
||||
}
|
||||
}
|
||||
|
@ -22,17 +22,12 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.hslf.blip.DIB;
|
||||
import org.apache.poi.hslf.blip.EMF;
|
||||
import org.apache.poi.hslf.blip.JPEG;
|
||||
import org.apache.poi.hslf.blip.PICT;
|
||||
import org.apache.poi.hslf.blip.PNG;
|
||||
import org.apache.poi.hslf.blip.WMF;
|
||||
import org.apache.poi.hslf.model.*;
|
||||
import org.apache.poi.hslf.blip.*;
|
||||
|
||||
/**
|
||||
* Test adding/reading pictures
|
||||
@ -65,9 +60,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can read this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -110,9 +105,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can read this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -156,9 +151,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can get this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -195,9 +190,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can read this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -235,9 +230,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can read this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -274,9 +269,9 @@ public final class TestPictures extends TestCase{
|
||||
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
//make sure we can read this picture shape and it refers to the correct picture data
|
||||
HSLFShape[] sh = ppt.getSlides()[0].getShapes();
|
||||
assertEquals(1, sh.length);
|
||||
pict = (HSLFPictureShape)sh[0];
|
||||
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
|
||||
assertEquals(1, sh.size());
|
||||
pict = (HSLFPictureShape)sh.get(0);
|
||||
assertEquals(idx, pict.getPictureIndex());
|
||||
|
||||
//check picture data
|
||||
@ -302,11 +297,11 @@ public final class TestPictures extends TestCase{
|
||||
HSLFPictureData pdata;
|
||||
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("pictures.ppt"));
|
||||
HSLFSlide[] slides = ppt.getSlides();
|
||||
List<HSLFSlide> slides = ppt.getSlides();
|
||||
HSLFPictureData[] pictures = ppt.getPictureData();
|
||||
assertEquals(5, pictures.length);
|
||||
|
||||
pict = (HSLFPictureShape)slides[0].getShapes()[0]; //the first slide contains JPEG
|
||||
pict = (HSLFPictureShape)slides.get(0).getShapes().get(0); //the first slide contains JPEG
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof JPEG);
|
||||
assertEquals(HSLFPictureShape.JPEG, pdata.getType());
|
||||
@ -314,7 +309,7 @@ public final class TestPictures extends TestCase{
|
||||
ppt_bytes = slTests.readFile("clock.jpg");
|
||||
assertArrayEquals(src_bytes, ppt_bytes);
|
||||
|
||||
pict = (HSLFPictureShape)slides[1].getShapes()[0]; //the second slide contains PNG
|
||||
pict = (HSLFPictureShape)slides.get(1).getShapes().get(0); //the second slide contains PNG
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof PNG);
|
||||
assertEquals(HSLFPictureShape.PNG, pdata.getType());
|
||||
@ -322,7 +317,7 @@ public final class TestPictures extends TestCase{
|
||||
ppt_bytes = slTests.readFile("tomcat.png");
|
||||
assertArrayEquals(src_bytes, ppt_bytes);
|
||||
|
||||
pict = (HSLFPictureShape)slides[2].getShapes()[0]; //the third slide contains WMF
|
||||
pict = (HSLFPictureShape)slides.get(2).getShapes().get(0); //the third slide contains WMF
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof WMF);
|
||||
assertEquals(HSLFPictureShape.WMF, pdata.getType());
|
||||
@ -336,7 +331,7 @@ public final class TestPictures extends TestCase{
|
||||
System.arraycopy(ppt_bytes, 22, b2, 0, b2.length);
|
||||
assertArrayEquals(b1, b2);
|
||||
|
||||
pict = (HSLFPictureShape)slides[3].getShapes()[0]; //the forth slide contains PICT
|
||||
pict = (HSLFPictureShape)slides.get(3).getShapes().get(0); //the forth slide contains PICT
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof PICT);
|
||||
assertEquals(HSLFPictureShape.PICT, pdata.getType());
|
||||
@ -350,7 +345,7 @@ public final class TestPictures extends TestCase{
|
||||
System.arraycopy(ppt_bytes, 512, b2, 0, b2.length);
|
||||
assertArrayEquals(b1, b2);
|
||||
|
||||
pict = (HSLFPictureShape)slides[4].getShapes()[0]; //the fifth slide contains EMF
|
||||
pict = (HSLFPictureShape)slides.get(4).getShapes().get(0); //the fifth slide contains EMF
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof EMF);
|
||||
assertEquals(HSLFPictureShape.EMF, pdata.getType());
|
||||
@ -375,20 +370,20 @@ public final class TestPictures extends TestCase{
|
||||
|
||||
// Now test what happens when we use the SlideShow interface
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(hslf);
|
||||
HSLFSlide[] slides = ppt.getSlides();
|
||||
List<HSLFSlide> slides = ppt.getSlides();
|
||||
HSLFPictureData[] pictures = ppt.getPictureData();
|
||||
assertEquals(12, slides.length);
|
||||
assertEquals(12, slides.size());
|
||||
assertEquals(2, pictures.length);
|
||||
|
||||
HSLFPictureShape pict;
|
||||
HSLFPictureData pdata;
|
||||
|
||||
pict = (HSLFPictureShape)slides[0].getShapes()[1]; // 2nd object on 1st slide
|
||||
pict = (HSLFPictureShape)slides.get(0).getShapes().get(1); // 2nd object on 1st slide
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof WMF);
|
||||
assertEquals(HSLFPictureShape.WMF, pdata.getType());
|
||||
|
||||
pict = (HSLFPictureShape)slides[0].getShapes()[2]; // 3rd object on 1st slide
|
||||
pict = (HSLFPictureShape)slides.get(0).getShapes().get(2); // 3rd object on 1st slide
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof WMF);
|
||||
assertEquals(HSLFPictureShape.WMF, pdata.getType());
|
||||
@ -411,20 +406,20 @@ public final class TestPictures extends TestCase{
|
||||
|
||||
// Now test what happens when we use the SlideShow interface
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(hslf);
|
||||
HSLFSlide[] slides = ppt.getSlides();
|
||||
List<HSLFSlide> slides = ppt.getSlides();
|
||||
HSLFPictureData[] pictures = ppt.getPictureData();
|
||||
assertEquals(27, slides.length);
|
||||
assertEquals(27, slides.size());
|
||||
assertEquals(2, pictures.length);
|
||||
|
||||
HSLFPictureShape pict;
|
||||
HSLFPictureData pdata;
|
||||
|
||||
pict = (HSLFPictureShape)slides[6].getShapes()[13];
|
||||
pict = (HSLFPictureShape)slides.get(6).getShapes().get(13);
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof WMF);
|
||||
assertEquals(HSLFPictureShape.WMF, pdata.getType());
|
||||
|
||||
pict = (HSLFPictureShape)slides[7].getShapes()[13];
|
||||
pict = (HSLFPictureShape)slides.get(7).getShapes().get(13);
|
||||
pdata = pict.getPictureData();
|
||||
assertTrue(pdata instanceof WMF);
|
||||
assertEquals(HSLFPictureShape.WMF, pdata.getType());
|
||||
@ -446,9 +441,9 @@ public final class TestPictures extends TestCase{
|
||||
|
||||
public void testGetPictureName() throws Exception {
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("ppt_with_png.ppt"));
|
||||
HSLFSlide slide = ppt.getSlides()[0];
|
||||
HSLFSlide slide = ppt.getSlides().get(0);
|
||||
|
||||
HSLFPictureShape p = (HSLFPictureShape)slide.getShapes()[0]; //the first slide contains JPEG
|
||||
HSLFPictureShape p = (HSLFPictureShape)slide.getShapes().get(0); //the first slide contains JPEG
|
||||
assertEquals("test", p.getPictureName());
|
||||
}
|
||||
|
||||
@ -469,7 +464,7 @@ public final class TestPictures extends TestCase{
|
||||
|
||||
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||
|
||||
HSLFPictureShape p = (HSLFPictureShape)ppt.getSlides()[0].getShapes()[0];
|
||||
HSLFPictureShape p = (HSLFPictureShape)ppt.getSlides().get(0).getShapes().get(0);
|
||||
assertEquals("tomcat.png", p.getPictureName());
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hslf.model.Table;
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
@ -30,40 +32,39 @@ import org.apache.poi.POIDataSamples;
|
||||
*
|
||||
* @author Alex Nikiforov [mailto:anikif@gmail.com]
|
||||
*/
|
||||
public final class TestTable extends TestCase {
|
||||
public class TestTable {
|
||||
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
}
|
||||
|
||||
public void testTable() throws Exception {
|
||||
@Test
|
||||
public void testTable() throws Exception {
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt"));
|
||||
assertTrue("No Exceptions while reading file", true);
|
||||
|
||||
final HSLFSlide[] slides = ppt.getSlides();
|
||||
assertEquals(1, slides.length);
|
||||
checkSlide(slides[0]);
|
||||
List<HSLFSlide> slides = ppt.getSlides();
|
||||
assertEquals(1, slides.size());
|
||||
checkSlide(slides.get(0));
|
||||
}
|
||||
|
||||
private void checkSlide(final HSLFSlide s) {
|
||||
HSLFTextParagraph[] textRuns = s.getTextParagraphs();
|
||||
assertEquals(2, textRuns.length);
|
||||
List<List<HSLFTextParagraph>> textRuns = s.getTextParagraphs();
|
||||
assertEquals(2, textRuns.size());
|
||||
|
||||
HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
|
||||
HSLFTextRun textRun = textRuns.get(0).get(0).getTextRuns().get(0);
|
||||
assertEquals("Table sample", textRun.getRawText().trim());
|
||||
assertEquals(1, textRuns[0].getTextRuns().length);
|
||||
assertFalse(textRun.isBullet());
|
||||
assertEquals(1, textRuns.get(0).get(0).getTextRuns().size());
|
||||
assertFalse(textRun.getTextParagraph().isBullet());
|
||||
|
||||
assertEquals("Dummy text", textRuns[1].getRawText());
|
||||
assertEquals("Dummy text", HSLFTextParagraph.getRawText(textRuns.get(1)));
|
||||
|
||||
final HSLFShape[] shapes = s.getShapes();
|
||||
List<HSLFShape> shapes = s.getShapes();
|
||||
assertNotNull(shapes);
|
||||
assertEquals(3, shapes.length);
|
||||
assertTrue(shapes[2] instanceof Table);
|
||||
final Table table = (Table) shapes[2];
|
||||
assertEquals(3, shapes.size());
|
||||
assertTrue(shapes.get(2) instanceof HSLFTable);
|
||||
final HSLFTable table = (HSLFTable) shapes.get(2);
|
||||
assertEquals(4, table.getNumberOfColumns());
|
||||
assertEquals(6, table.getNumberOfRows());
|
||||
for (int x = 0; x < 4; x ++) {
|
||||
assertEquals("TH Cell " + (x + 1), table.getCell(0, x).getTextParagraphs().getRawText());
|
||||
assertEquals("TH Cell " + (x + 1), HSLFTextParagraph.getRawText(table.getCell(0, x).getTextParagraphs()));
|
||||
for (int y = 1; y < 6; y++) {
|
||||
assertEquals("Row " + y + ", Cell " + (x + 1), table.getCell(y, x).getText());
|
||||
}
|
||||
|
@ -19,10 +19,12 @@ package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.awt.Color;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||
import org.apache.poi.hslf.record.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -99,7 +101,7 @@ public final class TestTextRun {
|
||||
|
||||
// Ensure trailing \n's are NOT stripped, it is legal to set a text with a trailing '\r'
|
||||
tr.setText(changeTo + "\n");
|
||||
assertEquals(changeTo + "\n", tr.getRawText());
|
||||
assertEquals(changeTo + "\r", tr.getRawText());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,7 +124,6 @@ public final class TestTextRun {
|
||||
else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
|
||||
}
|
||||
|
||||
|
||||
// Bytes -> Bytes
|
||||
assertNull(tca);
|
||||
assertNotNull(tba);
|
||||
@ -197,18 +198,13 @@ public final class TestTextRun {
|
||||
List<HSLFTextParagraph> trB = textParass.get(1);
|
||||
|
||||
assertEquals(1, trA.size());
|
||||
assertEquals(1, trB.size());
|
||||
assertEquals(2, trB.size());
|
||||
|
||||
HSLFTextRun rtrA = trA.get(0).getTextRuns().get(0);
|
||||
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
|
||||
|
||||
assertEquals(HSLFTextParagraph.getRawText(trA), rtrA.getRawText());
|
||||
assertEquals(HSLFTextParagraph.getRawText(trB), rtrB.getRawText());
|
||||
|
||||
// assertNull(rtrA._getRawCharacterStyle());
|
||||
// assertNull(rtrA._getRawParagraphStyle());
|
||||
// assertNull(rtrB._getRawCharacterStyle());
|
||||
// assertNull(rtrB._getRawParagraphStyle());
|
||||
assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,39 +280,39 @@ public final class TestTextRun {
|
||||
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
|
||||
HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0);
|
||||
HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0);
|
||||
// TextPropCollection tpBP = rtrB._getRawParagraphStyle();
|
||||
// TextPropCollection tpBC = rtrB._getRawCharacterStyle();
|
||||
// TextPropCollection tpCP = rtrC._getRawParagraphStyle();
|
||||
// TextPropCollection tpCC = rtrC._getRawCharacterStyle();
|
||||
// TextPropCollection tpDP = rtrD._getRawParagraphStyle();
|
||||
// TextPropCollection tpDC = rtrD._getRawCharacterStyle();
|
||||
TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpBC = rtrB.getCharacterStyle();
|
||||
TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpCC = rtrC.getCharacterStyle();
|
||||
TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpDC = rtrD.getCharacterStyle();
|
||||
|
||||
// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
|
||||
// assertNotNull(tpBP);
|
||||
// assertNotNull(tpBC);
|
||||
// assertNotNull(tpCP);
|
||||
// assertNotNull(tpCC);
|
||||
// assertNotNull(tpDP);
|
||||
// assertNotNull(tpDC);
|
||||
// assertTrue(tpBP.equals(tpCP));
|
||||
// assertTrue(tpBP.equals(tpDP));
|
||||
// assertTrue(tpCP.equals(tpDP));
|
||||
// assertFalse(tpBC.equals(tpCC));
|
||||
// assertFalse(tpBC.equals(tpDC));
|
||||
// assertFalse(tpCC.equals(tpDC));
|
||||
assertNotNull(tpBP);
|
||||
assertNotNull(tpBC);
|
||||
assertNotNull(tpCP);
|
||||
assertNotNull(tpCC);
|
||||
assertNotNull(tpDP);
|
||||
assertNotNull(tpDC);
|
||||
assertEquals(tpBP,tpCP);
|
||||
assertEquals(tpBP,tpDP);
|
||||
assertEquals(tpCP,tpDP);
|
||||
assertNotEquals(tpBC,tpCC);
|
||||
assertNotEquals(tpBC,tpDC);
|
||||
assertNotEquals(tpCC,tpDC);
|
||||
|
||||
// Change text via normal
|
||||
// trB.setText("Test Foo Test");
|
||||
HSLFTextParagraph.setText(trB, "Test Foo Test");
|
||||
|
||||
// Ensure now have first style
|
||||
// assertEquals(1, trB.getTextRuns().length);
|
||||
// rtrB = trB.getTextRuns().get(0);
|
||||
// assertEquals("Test Foo Test", trB.getRawText());
|
||||
// assertEquals("Test Foo Test", rtrB.getRawText());
|
||||
// assertNotNull(rtrB._getRawCharacterStyle());
|
||||
// assertNotNull(rtrB._getRawParagraphStyle());
|
||||
// assertEquals( tpBP, rtrB._getRawParagraphStyle() );
|
||||
// assertEquals( tpBC, rtrB._getRawCharacterStyle() );
|
||||
assertEquals(1, trB.get(0).getTextRuns().size());
|
||||
rtrB = trB.get(0).getTextRuns().get(0);
|
||||
assertEquals("Test Foo Test", HSLFTextParagraph.getRawText(trB));
|
||||
assertEquals("Test Foo Test", rtrB.getRawText());
|
||||
assertNotNull(rtrB.getCharacterStyle());
|
||||
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
|
||||
assertEquals( tpBP, rtrB.getTextParagraph().getParagraphStyle() );
|
||||
assertEquals( tpBC, rtrB.getCharacterStyle() );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,21 +324,21 @@ public final class TestTextRun {
|
||||
HSLFSlide slideOne = ss.getSlides().get(0);
|
||||
List<List<HSLFTextParagraph>> textRuns = slideOne.getTextParagraphs();
|
||||
List<HSLFTextParagraph> trB = textRuns.get(1);
|
||||
// assertEquals(1, trB.getTextRuns().length);
|
||||
//
|
||||
// HSLFTextRun rtrB = trB.getTextRuns().get(0);
|
||||
// assertEquals(trB.getRawText(), rtrB.getRawText());
|
||||
// assertNull(rtrB._getRawCharacterStyle());
|
||||
// assertNull(rtrB._getRawParagraphStyle());
|
||||
assertEquals(1, trB.get(0).getTextRuns().size());
|
||||
|
||||
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
|
||||
assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
|
||||
assertNotNull(rtrB.getCharacterStyle());
|
||||
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
|
||||
|
||||
// Change text via rich
|
||||
// rtrB.setText("Test Test Test");
|
||||
// assertEquals("Test Test Test", trB.getRawText());
|
||||
// assertEquals("Test Test Test", rtrB.getRawText());
|
||||
rtrB.setText("Test Test Test");
|
||||
assertEquals("Test Test Test", HSLFTextParagraph.getRawText(trB.subList(0, 1)));
|
||||
assertEquals("Test Test Test", rtrB.getRawText());
|
||||
|
||||
// Will now have dummy props
|
||||
// assertNotNull(rtrB._getRawCharacterStyle());
|
||||
// assertNotNull(rtrB._getRawParagraphStyle());
|
||||
assertNotNull(rtrB.getCharacterStyle());
|
||||
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,31 +353,31 @@ public final class TestTextRun {
|
||||
assertEquals(3, trB.size());
|
||||
|
||||
// We start with 3 text runs, each with their own set of styles,
|
||||
// but all sharing the same paragraph styles
|
||||
// but all sharing the same paragraph styles
|
||||
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
|
||||
HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0);
|
||||
HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0);
|
||||
// TextPropCollection tpBP = rtrB._getRawParagraphStyle();
|
||||
// TextPropCollection tpBC = rtrB._getRawCharacterStyle();
|
||||
// TextPropCollection tpCP = rtrC._getRawParagraphStyle();
|
||||
// TextPropCollection tpCC = rtrC._getRawCharacterStyle();
|
||||
// TextPropCollection tpDP = rtrD._getRawParagraphStyle();
|
||||
// TextPropCollection tpDC = rtrD._getRawCharacterStyle();
|
||||
TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpBC = rtrB.getCharacterStyle();
|
||||
TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpCC = rtrC.getCharacterStyle();
|
||||
TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
|
||||
TextPropCollection tpDC = rtrD.getCharacterStyle();
|
||||
|
||||
// Check text and stylings
|
||||
// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
|
||||
// assertNotNull(tpBP);
|
||||
// assertNotNull(tpBC);
|
||||
// assertNotNull(tpCP);
|
||||
// assertNotNull(tpCC);
|
||||
// assertNotNull(tpDP);
|
||||
// assertNotNull(tpDC);
|
||||
// assertTrue(tpBP.equals(tpCP));
|
||||
// assertTrue(tpBP.equals(tpDP));
|
||||
// assertTrue(tpCP.equals(tpDP));
|
||||
// assertFalse(tpBC.equals(tpCC));
|
||||
// assertFalse(tpBC.equals(tpDC));
|
||||
// assertFalse(tpCC.equals(tpDC));
|
||||
assertEquals(HSLFTextParagraph.getRawText(trB).substring(0, 30), rtrB.getRawText());
|
||||
assertNotNull(tpBP);
|
||||
assertNotNull(tpBC);
|
||||
assertNotNull(tpCP);
|
||||
assertNotNull(tpCC);
|
||||
assertNotNull(tpDP);
|
||||
assertNotNull(tpDC);
|
||||
assertEquals(tpBP, tpCP);
|
||||
assertEquals(tpBP, tpDP);
|
||||
assertEquals(tpCP, tpDP);
|
||||
assertNotEquals(tpBC, tpCC);
|
||||
assertNotEquals(tpBC, tpDC);
|
||||
assertNotEquals(tpCC, tpDC);
|
||||
|
||||
// Check text in the rich runs
|
||||
assertEquals("This is the subtitle, in bold\r", rtrB.getRawText());
|
||||
@ -394,32 +390,32 @@ public final class TestTextRun {
|
||||
rtrB.setText(newBText);
|
||||
rtrC.setText(newCText);
|
||||
rtrD.setText(newDText);
|
||||
assertEquals(newBText, rtrB.getRawText());
|
||||
assertEquals(newCText, rtrC.getRawText());
|
||||
assertEquals(newDText, rtrD.getRawText());
|
||||
HSLFTextParagraph.storeText(trB);
|
||||
|
||||
// assertEquals(newBText + newCText + newDText, trB.getRawText());
|
||||
assertEquals(newBText.replace('\n','\r'), rtrB.getRawText());
|
||||
assertEquals(newCText.replace('\n','\r'), rtrC.getRawText());
|
||||
assertEquals(newDText.replace('\n','\r'), rtrD.getRawText());
|
||||
|
||||
assertEquals(newBText.replace('\n','\r') + newCText.replace('\n','\r') + newDText.replace('\n','\r'), HSLFTextParagraph.getRawText(trB));
|
||||
|
||||
// The styles should have been updated for the new sizes
|
||||
// assertEquals(newBText.length(), tpBC.getCharactersCovered());
|
||||
// assertEquals(newCText.length(), tpCC.getCharactersCovered());
|
||||
// assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger
|
||||
assertEquals(newBText.length(), tpBC.getCharactersCovered());
|
||||
assertEquals(newCText.length(), tpCC.getCharactersCovered());
|
||||
assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger
|
||||
|
||||
// assertEquals(
|
||||
// newBText.length() + newCText.length() + newDText.length(),
|
||||
// tpBP.getCharactersCovered()
|
||||
// );
|
||||
|
||||
// Paragraph style should be sum of text length
|
||||
// assertEquals(newBText.length() + newCText.length() + newDText.length(), tpBP.getCharactersCovered());
|
||||
// Paragraph style should be sum of text length
|
||||
assertEquals(
|
||||
newBText.length() + newCText.length() + newDText.length() +1,
|
||||
tpBP.getCharactersCovered() + tpCP.getCharactersCovered() + tpDP.getCharactersCovered()
|
||||
);
|
||||
|
||||
// Check stylings still as expected
|
||||
// TextPropCollection ntpBC = rtrB._getRawCharacterStyle();
|
||||
// TextPropCollection ntpCC = rtrC._getRawCharacterStyle();
|
||||
// TextPropCollection ntpDC = rtrD._getRawCharacterStyle();
|
||||
// assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
|
||||
// assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
|
||||
// assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
|
||||
TextPropCollection ntpBC = rtrB.getCharacterStyle();
|
||||
TextPropCollection ntpCC = rtrC.getCharacterStyle();
|
||||
TextPropCollection ntpDC = rtrD.getCharacterStyle();
|
||||
assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
|
||||
assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
|
||||
assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
|
||||
}
|
||||
|
||||
|
||||
@ -467,82 +463,86 @@ public final class TestTextRun {
|
||||
assertEquals(0, slide.getTextParagraphs().size());
|
||||
|
||||
HSLFTextBox shape1 = new HSLFTextBox();
|
||||
// HSLFTextParagraph run1 = shape1.getTextParagraphs();
|
||||
// assertSame(run1, shape1.createTextRun());
|
||||
// run1.setText("Text 1");
|
||||
List<HSLFTextParagraph> run1 = shape1.getTextParagraphs();
|
||||
shape1.setText("Text 1");
|
||||
slide.addShape(shape1);
|
||||
|
||||
//The array of Slide's text runs must be updated when new text shapes are added.
|
||||
// HSLFTextParagraph[] runs = slide.getTextParagraphs();
|
||||
// assertNotNull(runs);
|
||||
// assertSame(run1, runs.get(0));
|
||||
//
|
||||
// HSLFTextBox shape2 = new HSLFTextBox();
|
||||
// HSLFTextParagraph run2 = shape2.getTextParagraphs();
|
||||
// assertSame(run2, shape2.createTextRun());
|
||||
// run2.setText("Text 2");
|
||||
// slide.addShape(shape2);
|
||||
//
|
||||
// runs = slide.getTextParagraphs();
|
||||
// assertEquals(2, runs.length);
|
||||
//
|
||||
// assertSame(run1, runs.get(0));
|
||||
// assertSame(run2, runs.get(1));
|
||||
//
|
||||
// //as getShapes()
|
||||
// HSLFShape[] sh = slide.getShapes();
|
||||
// assertEquals(2, sh.length);
|
||||
// assertTrue(sh.get(0) instanceof HSLFTextBox);
|
||||
// HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
|
||||
// assertSame(run1, box1.getTextParagraphs());
|
||||
// HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
|
||||
// assertSame(run2, box2.getTextParagraphs());
|
||||
//
|
||||
// //test Table - a complex group of shapes containing text objects
|
||||
// HSLFSlide slide2 = ppt.createSlide();
|
||||
// assertNull(slide2.getTextParagraphs());
|
||||
// Table table = new Table(2, 2);
|
||||
// slide2.addShape(table);
|
||||
// runs = slide2.getTextParagraphs();
|
||||
// assertNotNull(runs);
|
||||
// assertEquals(4, runs.length);
|
||||
List<List<HSLFTextParagraph>> runs = slide.getTextParagraphs();
|
||||
assertNotNull(runs);
|
||||
assertSame(run1, runs.get(0));
|
||||
|
||||
HSLFTextBox shape2 = new HSLFTextBox();
|
||||
List<HSLFTextParagraph> run2 = shape2.getTextParagraphs();
|
||||
shape2.setText("Text 2");
|
||||
slide.addShape(shape2);
|
||||
|
||||
runs = slide.getTextParagraphs();
|
||||
assertEquals(2, runs.size());
|
||||
|
||||
assertSame(run1, runs.get(0));
|
||||
assertSame(run2, runs.get(1));
|
||||
|
||||
// as getShapes()
|
||||
List<HSLFShape> sh = slide.getShapes();
|
||||
assertEquals(2, sh.size());
|
||||
assertTrue(sh.get(0) instanceof HSLFTextBox);
|
||||
HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
|
||||
assertSame(run1, box1.getTextParagraphs());
|
||||
HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
|
||||
assertSame(run2, box2.getTextParagraphs());
|
||||
|
||||
// test Table - a complex group of shapes containing text objects
|
||||
HSLFSlide slide2 = ppt.createSlide();
|
||||
assertTrue(slide2.getTextParagraphs().isEmpty());
|
||||
HSLFTable table = new HSLFTable(2, 2);
|
||||
slide2.addShape(table);
|
||||
runs = slide2.getTextParagraphs();
|
||||
assertNotNull(runs);
|
||||
assertEquals(4, runs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test48916() throws IOException {
|
||||
// HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
|
||||
// for(HSLFSlide slide : ppt.getSlides()){
|
||||
// for(HSLFShape sh : slide.getShapes()){
|
||||
// if(sh instanceof HSLFTextShape){
|
||||
// HSLFTextShape tx = (HSLFTextShape)sh;
|
||||
// HSLFTextParagraph run = tx.getTextParagraphs();
|
||||
// //verify that records cached in TextRun and EscherTextboxWrapper are the same
|
||||
// Record[] runChildren = run.getRecords();
|
||||
// Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
|
||||
// assertEquals(runChildren.length, txboxChildren.length);
|
||||
// for(int i=0; i < txboxChildren.length; i++){
|
||||
// assertSame(txboxChildren.get(i), runChildren.get(i));
|
||||
// }
|
||||
// //caused NPE prior to fix of Bugzilla #48916
|
||||
// run.getTextRuns().get(0).setBold(true);
|
||||
// run.getTextRuns().get(0).setFontColor(Color.RED);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// ppt.write(out);
|
||||
// ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||
// for(HSLFSlide slide : ppt.getSlides()){
|
||||
// for(HSLFShape sh : slide.getShapes()){
|
||||
// if(sh instanceof HSLFTextShape){
|
||||
// HSLFTextShape tx = (HSLFTextShape)sh;
|
||||
// HSLFTextParagraph run = tx.getTextParagraphs();
|
||||
// HSLFTextRun rt = run.getTextRuns().get(0);
|
||||
// assertTrue(rt.isBold());
|
||||
// assertEquals(rt.getFontColor(), Color.RED);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
|
||||
List<HSLFSlide> slides = ppt.getSlides();
|
||||
for(HSLFSlide slide : slides){
|
||||
for(HSLFShape sh : slide.getShapes()){
|
||||
if (!(sh instanceof HSLFTextShape)) continue;
|
||||
HSLFTextShape tx = (HSLFTextShape)sh;
|
||||
List<HSLFTextParagraph> paras = tx.getTextParagraphs();
|
||||
//verify that records cached in TextRun and EscherTextboxWrapper are the same
|
||||
Record[] runChildren = paras.get(0).getRecords();
|
||||
Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
|
||||
assertEquals(runChildren.length, txboxChildren.length);
|
||||
for(int i=0; i < txboxChildren.length; i++){
|
||||
assertSame(txboxChildren[i], runChildren[i]);
|
||||
}
|
||||
// caused NPE prior to fix of Bugzilla #48916
|
||||
for (HSLFTextParagraph p : paras) {
|
||||
for (HSLFTextRun rt : p.getTextRuns()) {
|
||||
rt.setBold(true);
|
||||
rt.setFontColor(Color.RED);
|
||||
}
|
||||
}
|
||||
tx.storeText();
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ppt.write(out);
|
||||
|
||||
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||
for(HSLFSlide slide : ppt.getSlides()){
|
||||
for(HSLFShape sh : slide.getShapes()){
|
||||
if(sh instanceof HSLFTextShape){
|
||||
HSLFTextShape tx = (HSLFTextShape)sh;
|
||||
List<HSLFTextParagraph> run = tx.getTextParagraphs();
|
||||
HSLFTextRun rt = run.get(0).getTextRuns().get(0);
|
||||
assertTrue(rt.isBold());
|
||||
assertEquals(rt.getFontColor(), Color.RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
BIN
test-data/slideshow/54541_cropped_bitmap2.ppt
Normal file
BIN
test-data/slideshow/54541_cropped_bitmap2.ppt
Normal file
Binary file not shown.
BIN
test-data/slideshow/sample_pptx_grouping_issues.pptx
Normal file
BIN
test-data/slideshow/sample_pptx_grouping_issues.pptx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user