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:
Andreas Beeker 2015-06-10 22:23:47 +00:00
parent d1f9035400
commit 4acc6a84a1
58 changed files with 976 additions and 1036 deletions

View File

@ -146,10 +146,10 @@ public final class ApacheconEU08 {
{"Note"}, {"Note"},
{"This presentation was created programmatically using POI HSLF"} {"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 i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) { 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]); cell.setText(txt1[i][j]);
HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0); HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
rt.setFontSize(10); rt.setFontSize(10);

View File

@ -50,7 +50,7 @@ public final class Graphics2DDemo {
//define position of the drawing in the slide //define position of the drawing in the slide
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300); Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
group.setAnchor(bounds); 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); slide.addShape(group);
Graphics2D graphics = new PPGraphics2D(group); Graphics2D graphics = new PPGraphics2D(group);
@ -68,7 +68,7 @@ public final class Graphics2DDemo {
} }
graphics.setColor(Color.black); graphics.setColor(Color.black);
graphics.setFont(new Font("Arial", Font.BOLD, 14)); graphics.setFont(new Font("Arial", Font.BOLD, 14));
graphics.draw(group.getCoordinates()); graphics.draw(group.getInteriorAnchor());
graphics.drawString("Performance", x + 30, y + 10); graphics.drawString("Performance", x + 30, y + 10);
FileOutputStream out = new FileOutputStream("hslf-graphics.ppt"); FileOutputStream out = new FileOutputStream("hslf-graphics.ppt");

View File

@ -49,10 +49,10 @@ public final class TableDemo {
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
//six rows, two columns //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 i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) { 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); HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
rt.setFontFamily("Arial"); rt.setFontFamily("Arial");
rt.setFontSize(10); rt.setFontSize(10);
@ -88,10 +88,10 @@ public final class TableDemo {
}; };
//two rows, one column //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 i = 0; i < txt2.length; i++) {
for (int j = 0; j < txt2[i].length; j++) { 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); HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
rt.setFontSize(10); rt.setFontSize(10);
rt.setFontFamily("Arial"); rt.setFontFamily("Arial");

View File

@ -40,13 +40,26 @@ public class EscherChildAnchorRecord
private int field_4_dy2; private int field_4_dy2;
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
/*int bytesRemaining =*/ readHeader( data, offset ); int bytesRemaining = readHeader( data, offset );
int pos = offset + 8; int pos = offset + 8;
int size = 0; int size = 0;
switch (bytesRemaining) {
case 16: // RectStruct
field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4; field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4;
field_2_dy1 = 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_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4;
field_4_dy2 = 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; return 8 + size;
} }

View File

@ -507,7 +507,7 @@ public final class EscherProperties {
addProp(m, SHADOWSTYLE__ORIGINX, "shadowstyle.originx"); addProp(m, SHADOWSTYLE__ORIGINX, "shadowstyle.originx");
addProp(m, SHADOWSTYLE__ORIGINY, "shadowstyle.originy"); addProp(m, SHADOWSTYLE__ORIGINY, "shadowstyle.originy");
addProp(m, SHADOWSTYLE__SHADOW, "shadowstyle.shadow"); 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__TYPE, "perspective.type");
addProp(m, PERSPECTIVE__OFFSETX, "perspective.offsetx"); addProp(m, PERSPECTIVE__OFFSETX, "perspective.offsetx");
addProp(m, PERSPECTIVE__OFFSETY, "perspective.offsety"); addProp(m, PERSPECTIVE__OFFSETY, "perspective.offsety");

View File

@ -17,6 +17,7 @@
package org.apache.poi.ddf; package org.apache.poi.ddf;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.util.HexDump; import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.RecordFormatException; import org.apache.poi.util.RecordFormatException;
@ -32,7 +33,7 @@ import org.apache.poi.util.RecordFormatException;
*/ */
public class EscherTextboxRecord extends EscherRecord 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"; public static final String RECORD_DESCRIPTION = "msofbtClientTextbox";
private static final byte[] NO_BYTES = new byte[0]; private static final byte[] NO_BYTES = new byte[0];

View File

@ -28,6 +28,7 @@ import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage; import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
public class DummyGraphics2d public class DummyGraphics2d
@ -262,7 +263,7 @@ public class DummyGraphics2d
public void setPaint( Paint paint ) public void setPaint( Paint paint )
{ {
System.out.println( "setPain(Paint):" ); System.out.println( "setPaint(Paint):" );
System.out.println( "paint = " + paint ); System.out.println( "paint = " + paint );
g2D.setPaint( paint ); g2D.setPaint( paint );
} }
@ -285,7 +286,19 @@ public class DummyGraphics2d
public void setStroke(Stroke s) public void setStroke(Stroke s)
{ {
System.out.println( "setStroke(Stoke):" ); System.out.println( "setStroke(Stoke):" );
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 ); System.out.println( "s = " + s );
}
g2D.setStroke( s ); g2D.setStroke( s );
} }

View File

@ -25,8 +25,7 @@ import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.poi.openxml4j.opc.*; import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.sl.usermodel.PlaceableShape; import org.apache.poi.sl.usermodel.GroupShape;
import org.apache.poi.sl.usermodel.ShapeGroup;
import org.apache.poi.util.*; import org.apache.poi.util.*;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.*; import org.openxmlformats.schemas.drawingml.x2006.main.*;
@ -38,7 +37,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.*;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
@Beta @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 static POILogger _logger = POILogFactory.getLogger(XSLFGroupShape.class);
private final List<XSLFShape> _shapes; private final List<XSLFShape> _shapes;

View File

@ -169,6 +169,7 @@ public class XSLFPictureShape extends XSLFSimpleShape implements PictureShape {
return id; return id;
} }
@Override
public Insets getClipping(){ public Insets getClipping(){
CTPicture ct = (CTPicture)getXmlObject(); CTPicture ct = (CTPicture)getXmlObject();
CTRelativeRect r = ct.getBlipFill().getSrcRect(); CTRelativeRect r = ct.getBlipFill().getSrcRect();

View File

@ -481,6 +481,7 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeC
* *
* @param graphics * @param graphics
*/ */
@Override
public void draw(Graphics2D graphics){ public void draw(Graphics2D graphics){
DrawFactory drawFact = DrawFactory.getInstance(graphics); DrawFactory drawFact = DrawFactory.getInstance(graphics);
Drawable draw = drawFact.getDrawable(this); Drawable draw = drawFact.getDrawable(this);

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; 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.sl.usermodel.Slide;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;

View File

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

View File

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

View File

@ -247,8 +247,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
// Table text // Table text
for (HSLFShape shape : slide.getShapes()){ for (HSLFShape shape : slide.getShapes()){
if (shape instanceof Table){ if (shape instanceof HSLFTable){
extractTableText(ret, (Table)shape); extractTableText(ret, (HSLFTable)shape);
} }
} }
// Slide footer, if set // Slide footer, if set
@ -305,10 +305,10 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
return ret.toString(); 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 row = 0; row < table.getNumberOfRows(); row++){
for (int col = 0; col < table.getNumberOfColumns(); col++){ 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 //defensive null checks; don't know if they're necessary
if (cell != null){ if (cell != null){
String txt = cell.getText(); String txt = cell.getText();

View File

@ -22,8 +22,8 @@ import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.ShapeType;
import java.awt.geom.Rectangle2D; import java.awt.geom.*;
import java.awt.geom.Line2D; import java.util.ArrayList;
/** /**
* Represents a line in a PowerPoint drawing * Represents a line in a PowerPoint drawing
@ -69,4 +69,63 @@ public final class Line extends HSLFSimpleShape {
Rectangle2D anchor = getLogicalAnchor2D(); Rectangle2D anchor = getLogicalAnchor2D();
return new Line2D.Double(anchor.getX(), anchor.getY(), anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight()); 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;
}
} }

View File

@ -285,6 +285,7 @@ public class TextPropCollection {
* Clones the given text properties * Clones the given text properties
*/ */
public void copy(TextPropCollection other) { public void copy(TextPropCollection other) {
if (this == other) return;
this.charactersCovered = other.charactersCovered; this.charactersCovered = other.charactersCovered;
this.indentLevel = other.indentLevel; this.indentLevel = other.indentLevel;
this.maskSpecial = other.maskSpecial; this.maskSpecial = other.maskSpecial;

View File

@ -87,9 +87,7 @@ public final class EscherTextboxWrapper extends RecordContainer {
// Grab the children's data // Grab the children's data
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i=0; i<_children.length; i++) { for (Record r : _children) r.writeOut(baos);
_children[i].writeOut(baos);
}
byte[] data = baos.toByteArray(); byte[] data = baos.toByteArray();
// Save in the escher layer // Save in the escher layer

View File

@ -97,7 +97,7 @@ public final class PPDrawing extends RecordAtom {
findEscherChildren(erf, contents, 8, len-8, escherChildren); findEscherChildren(erf, contents, 8, len-8, escherChildren);
this.childRecords = escherChildren.toArray(new EscherRecord[escherChildren.size()]); 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]); this.textboxWrappers = findInDgContainer((EscherContainerRecord) this.childRecords[0]);
} else { } else {
// Find and EscherTextboxRecord's, and wrap them up // 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()]); 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 List<EscherTextboxWrapper> found = new LinkedList<EscherTextboxWrapper>();
final EscherContainerRecord SpgrContainer = findFirstEscherContainerRecordOfType((short)0xf003, escherContainerF002); final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherSpgrContainer, dgContainer);
final EscherContainerRecord[] escherContainersF004 = findAllEscherContainerRecordOfType((short)0xf004, SpgrContainer); final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType((short)RecordTypes.EscherSpContainer, spgrContainer);
for (EscherContainerRecord spContainer : escherContainersF004) { for (EscherContainerRecord spContainer : spContainers) {
StyleTextProp9Atom nineAtom = findInSpContainer(spContainer); StyleTextProp9Atom nineAtom = findInSpContainer(spContainer);
EscherSpRecord sp = null; EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherSp, spContainer);
final EscherRecord escherContainerF00A = findFirstEscherRecordOfType((short)0xf00a, spContainer); EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherClientTextbox, spContainer);
if (null != escherContainerF00A) { if (null == clientTextbox) { continue; }
if (escherContainerF00A instanceof EscherSpRecord) {
sp = (EscherSpRecord) escherContainerF00A; EscherTextboxWrapper w = new EscherTextboxWrapper(clientTextbox);
}
}
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); w.setStyleTextProp9Atom(nineAtom);
if (null != sp) { if (null != sp) {
w.setShapeId(sp.getShapeId()); w.setShapeId(sp.getShapeId());
} }
found.add(w); found.add(w);
} }
}
return found.toArray(new EscherTextboxWrapper[found.size()]); return found.toArray(new EscherTextboxWrapper[found.size()]);
} }
private StyleTextProp9Atom findInSpContainer(final EscherContainerRecord spContainer) { private StyleTextProp9Atom findInSpContainer(final EscherContainerRecord spContainer) {
final EscherContainerRecord escherContainerF011 = findFirstEscherContainerRecordOfType((short)0xf011, spContainer); EscherContainerRecord clientData = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherClientData, spContainer);
if (null == escherContainerF011) { return null; } if (null == clientData) { return null; }
final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, escherContainerF011); final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, clientData);
if (null == escherContainer1388) { return null; } if (null == escherContainer1388) { return null; }
final EscherContainerRecord escherContainer138A = findFirstEscherContainerRecordOfType((short)0x138A, escherContainer1388); final EscherContainerRecord escherContainer138A = findFirstEscherContainerRecordOfType((short)0x138A, escherContainer1388);
if (null == escherContainer138A) { return null; } if (null == escherContainer138A) { return null; }

View File

@ -294,7 +294,7 @@ public abstract class RecordContainer extends Record
// Write out our header, less the size // Write out our header, less the size
mout.write(new byte[] {headerA,headerB}); mout.write(new byte[] {headerA,headerB});
byte[] typeB = new byte[2]; byte[] typeB = new byte[2];
LittleEndian.putShort(typeB,(short)type); LittleEndian.putShort(typeB, 0, (short)type);
mout.write(typeB); mout.write(typeB);
mout.write(new byte[4]); mout.write(new byte[4]);
@ -320,7 +320,7 @@ public abstract class RecordContainer extends Record
// Write out our header, less the size // Write out our header, less the size
baos.write(new byte[] {headerA,headerB}); baos.write(new byte[] {headerA,headerB});
byte[] typeB = new byte[2]; byte[] typeB = new byte[2];
LittleEndian.putShort(typeB,(short)type); LittleEndian.putShort(typeB,0,(short)type);
baos.write(typeB); baos.write(typeB);
baos.write(new byte[] {0,0,0,0}); baos.write(new byte[] {0,0,0,0});

View File

@ -93,8 +93,6 @@ public final class SlideListWithText extends RecordContainer {
} }
int clen = endPos - i - 1; int clen = endPos - i - 1;
boolean emptySet = false;
if(clen == 0) { emptySet = true; }
// Create a SlideAtomsSets, not caring if they're empty // Create a SlideAtomsSets, not caring if they're empty
//if(emptySet) { continue; } //if(emptySet) { continue; }
@ -149,7 +147,7 @@ public final class SlideListWithText extends RecordContainer {
} }
public void setInstance(int inst){ public void setInstance(int inst){
LittleEndian.putShort(_header, (short)((inst << 4) | 0xF)); LittleEndian.putShort(_header, 0, (short)((inst << 4) | 0xF));
} }
/** /**

View File

@ -128,9 +128,10 @@ public final class HSLFFill {
}; };
} }
case FILL_PICTURE: { case FILL_PICTURE: {
return new TexturePaint() {
final HSLFPictureData pd = getPictureData(); final HSLFPictureData pd = getPictureData();
if (pd == null) break;
return new TexturePaint() {
public InputStream getImageData() { public InputStream getImageData() {
return new ByteArrayInputStream(pd.getData()); return new ByteArrayInputStream(pd.getData());
} }

View File

@ -21,8 +21,7 @@ import java.awt.geom.Rectangle2D;
import java.util.*; import java.util.*;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -31,7 +30,7 @@ import org.apache.poi.util.POILogger;
* *
* @author Yegor Kozlov * @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. * 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); spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
} }
/** @Override
* Sets the coordinate space of this group. All children are constrained public void setInteriorAnchor(Rectangle2D anchor){
* to these coordinates.
*
* @param anchor the coordinate space of this group
*/
public void setCoordinates(Rectangle2D anchor){
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID); EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI); int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
@ -108,22 +102,14 @@ public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShap
} }
/** @Override
* Gets the coordinate space of this group. All children are constrained public Rectangle2D getInteriorAnchor(){
* to these coordinates. EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID);
* double x = rec.getRectX1()*POINT_DPI/MASTER_DPI;
* @return the coordinate space of this group double y = rec.getRectY1()*POINT_DPI/MASTER_DPI;
*/ double width = (rec.getRectX2()-rec.getRectX1())*POINT_DPI/MASTER_DPI;
public Rectangle2D getCoordinates(){ double height = (rec.getRectY2()-rec.getRectY1())*POINT_DPI/MASTER_DPI;
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID); return new Rectangle2D.Double(x,y,width,height);
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;
} }
/** /**
@ -199,21 +185,21 @@ public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShap
*/ */
public Rectangle2D getAnchor2D(){ public Rectangle2D getAnchor2D(){
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
Rectangle2D.Float anchor = new Rectangle2D.Float(); Rectangle2D anchor;
if(clientAnchor == null){ if(clientAnchor == null){
logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord."); logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID); EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
anchor = new Rectangle2D.Float( double x = rec.getDx1()*POINT_DPI/MASTER_DPI;
(float)rec.getDx1()*POINT_DPI/MASTER_DPI, double y = rec.getDy1()*POINT_DPI/MASTER_DPI;
(float)rec.getDy1()*POINT_DPI/MASTER_DPI, double width = (rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI;
(float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI, double height = (rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI;
(float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI anchor = new Rectangle2D.Double(x,y,width,height);
);
} else { } else {
anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI; double x = clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI; double y = clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ; double width = (clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI; double height = (clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
anchor = new Rectangle2D.Double(x,y,width,height);
} }
return anchor; return anchor;

View File

@ -35,7 +35,7 @@ import org.apache.poi.util.POILogger;
public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFSlideShow> { public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFSlideShow> {
protected static POILogger logger = POILogFactory.getLogger(HSLFNotes.class); 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. * 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 // Now, build up TextRuns from pairs of TextHeaderAtom and
// one of TextBytesAtom or TextCharsAtom, found inside // one of TextBytesAtom or TextCharsAtom, found inside
// EscherTextboxWrapper's in the PPDrawing // EscherTextboxWrapper's in the PPDrawing
_runs = HSLFTextParagraph.findTextParagraphs(getPPDrawing()); for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
if (_runs.isEmpty()) { if (!_paragraphs.contains(l)) _paragraphs.add(l);
}
if (_paragraphs.isEmpty()) {
logger.log(POILogger.WARN, "No text records found for notes sheet"); logger.log(POILogger.WARN, "No text records found for notes sheet");
} }
// Set the sheet on each TextRun // Set the sheet on each TextRun
for (List<HSLFTextParagraph> ltp : _runs) { for (List<HSLFTextParagraph> ltp : _paragraphs) {
for (HSLFTextParagraph tp : ltp) { for (HSLFTextParagraph tp : ltp) {
tp.supplySheet(this); tp.supplySheet(this);
} }
@ -67,7 +70,7 @@ public final class HSLFNotes extends HSLFSheet implements Notes<HSLFShape, HSLFS
*/ */
@Override @Override
public List<List<HSLFTextParagraph>> getTextParagraphs() { public List<List<HSLFTextParagraph>> getTextParagraphs() {
return _runs; return _paragraphs;
} }
/** /**

View File

@ -17,31 +17,22 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import java.awt.Graphics2D;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import org.apache.poi.hslf.blip.BitmapPainter; import org.apache.poi.hslf.blip.*;
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.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.util.LittleEndian; import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.*;
import org.apache.poi.util.POILogger;
/** /**
* A class that represents image data contained in a slide show. * A class that represents image data contained in a slide show.
* *
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public abstract class HSLFPictureData { public abstract class HSLFPictureData implements PictureData {
protected POILogger logger = POILogFactory.getLogger(this.getClass()); protected POILogger logger = POILogFactory.getLogger(this.getClass());
@ -91,13 +82,6 @@ public abstract class HSLFPictureData {
*/ */
protected abstract int getSignature(); 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 * Returns the raw binary data of this Picture excluding the first 8 bytes
* which hold image signature and size of the image data. * which hold image signature and size of the image data.
@ -233,31 +217,4 @@ public abstract class HSLFPictureData {
public int getSize(){ public int getSize(){
return getData().length; 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];
}
} }

View File

@ -28,8 +28,7 @@ import javax.imageio.ImageIO;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hslf.blip.Bitmap; import org.apache.poi.hslf.blip.Bitmap;
import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.record.Document;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.util.*; import org.apache.poi.util.*;
@ -38,7 +37,7 @@ import org.apache.poi.util.*;
* *
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class HSLFPictureShape extends HSLFSimpleShape { public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape {
/** /**
* Windows Enhanced Metafile (EMF) * Windows Enhanced Metafile (EMF)
@ -165,11 +164,7 @@ public class HSLFPictureShape extends HSLFSimpleShape {
} }
} }
/** @Override
* Returns the picture data for this picture.
*
* @return the picture data for this picture.
*/
public HSLFPictureData getPictureData(){ public HSLFPictureData getPictureData(){
HSLFSlideShow ppt = getSheet().getSlideShow(); HSLFSlideShow ppt = getSheet().getSlideShow();
HSLFPictureData[] pict = ppt.getPictureData(); 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, * The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size,
* i.e. the size of the already clipped image * 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(); EscherOptRecord opt = getEscherOptRecord();
double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP); double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP);

View File

@ -165,14 +165,12 @@ public abstract class HSLFShape implements Shape {
public Rectangle2D getAnchor2D(){ public Rectangle2D getAnchor2D(){
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags(); int flags = spRecord.getFlags();
Rectangle2D anchor=null; Rectangle2D anchor;
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID); EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
if(rec == null){ if(rec == null){
logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found"); logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID); EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
anchor = new Rectangle2D.Float( anchor = new Rectangle2D.Float(
(float)clrec.getCol1()*POINT_DPI/MASTER_DPI, (float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
(float)clrec.getFlag()*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 (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
); );
} }
} } else {
else {
EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID); EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
anchor = new Rectangle2D.Float( anchor = new Rectangle2D.Float(
(float)rec.getCol1()*POINT_DPI/MASTER_DPI, (float)rec.getCol1()*POINT_DPI/MASTER_DPI,
(float)rec.getFlag()*POINT_DPI/MASTER_DPI, (float)rec.getFlag()*POINT_DPI/MASTER_DPI,
@ -201,10 +197,6 @@ public abstract class HSLFShape implements Shape {
return anchor; return anchor;
} }
public Rectangle2D getLogicalAnchor2D(){
return getAnchor2D();
}
/** /**
* Sets the anchor (the bounding box rectangle) of this shape. * Sets the anchor (the bounding box rectangle) of this shape.
* All coordinates should be expressed in points (72 dpi). * All coordinates should be expressed in points (72 dpi).
@ -262,6 +254,7 @@ public abstract class HSLFShape implements Shape {
* @return escher property or <code>null</code> if not found. * @return escher property or <code>null</code> if not found.
*/ */
public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){ public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
if (opt == null) return null;
return opt.lookup(propId); return opt.lookup(propId);
} }
@ -475,15 +468,6 @@ public abstract class HSLFShape implements Shape {
logger.log(POILogger.INFO, "Rendering " + getShapeName()); 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() { public EscherOptRecord getEscherOptRecord() {
EscherOptRecord opt = getEscherChild(EscherOptRecord.RECORD_ID); EscherOptRecord opt = getEscherChild(EscherOptRecord.RECORD_ID);
if (opt == null) { if (opt == null) {
@ -516,8 +500,7 @@ public abstract class HSLFShape implements Shape {
public double getRotation(){ public double getRotation(){
int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION); int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
double angle = Units.fixedPointToDouble(rot) % 360.0; return Units.fixedPointToDouble(rot);
return angle;
} }
public void setRotation(double theta){ public void setRotation(double theta){

View File

@ -69,7 +69,7 @@ public final class HSLFShapeFactory {
List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() ); List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
EscherSimpleProperty p = (EscherSimpleProperty)props.get(0); EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){ if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
group = new Table(spContainer, parent); group = new HSLFTable(spContainer, parent);
} else { } else {
group = new HSLFGroupShape(spContainer, parent); group = new HSLFGroupShape(spContainer, parent);
} }

View File

@ -22,6 +22,8 @@ import java.util.*;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hslf.record.*; 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.sl.usermodel.Sheet;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -288,8 +290,11 @@ public abstract class HSLFSheet implements Sheet<HSLFShape,HSLFSlideShow> {
return _background; return _background;
} }
@Override
public void draw(Graphics2D graphics) { public void draw(Graphics2D graphics) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
Drawable draw = drawFact.getDrawable(this);
draw.draw(graphics);
} }
/** /**

View File

@ -18,16 +18,15 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import java.awt.Color; import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.record.*; 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.draw.geom.*;
import org.apache.poi.sl.usermodel.*; 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.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -196,7 +195,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
public StrokeStyle getStrokeStyle(){ public StrokeStyle getStrokeStyle(){
return new StrokeStyle() { return new StrokeStyle() {
public PaintStyle getPaint() { public PaintStyle getPaint() {
return null; return DrawPaint.createSolidPaint(HSLFSimpleShape.this.getLineColor());
} }
public LineCap getLineCap() { public LineCap getLineCap() {
@ -204,15 +203,15 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
} }
public LineDash getLineDash() { public LineDash getLineDash() {
return null; return HSLFSimpleShape.this.getLineDashing();
} }
public LineCompound getLineCompound() { public LineCompound getLineCompound() {
return null; return HSLFSimpleShape.this.getLineCompound();
} }
public double getLineWidth() { public double getLineWidth() {
return 0; return HSLFSimpleShape.this.getLineWidth();
} }
}; };
@ -234,61 +233,6 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
getFill().setForegroundColor(color); 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 * 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); return (adjval == -1) ? null : new Guide(name, "val "+adjval);
} }
public LineDecoration getLineDecoration() {
// TODO Auto-generated method stub
return null;
}
public CustomGeometry getGeometry() { public CustomGeometry getGeometry() {
ShapeType st = getShapeType(); ShapeType st = getShapeType();
String name = st.getOoxmlName(); String name = st.getOoxmlName();
@ -442,11 +381,89 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape {
return geom; return geom;
} }
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() { 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 // TODO Auto-generated method stub
return null; 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;
}
};
}
} }

View File

@ -72,7 +72,9 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSl
} }
// Grab text from slide's PPDrawing // 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(List<HSLFTextParagraph> ltp : _paragraphs) {
for (HSLFTextParagraph tp : ltp) { for (HSLFTextParagraph tp : ltp) {

View File

@ -32,7 +32,7 @@ import org.apache.poi.hslf.record.*;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public final class HSLFSlideMaster extends HSLFMasterSheet { 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 * all TxMasterStyleAtoms available in this master
@ -46,8 +46,11 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
public HSLFSlideMaster(MainMaster record, int sheetNo) { public HSLFSlideMaster(MainMaster record, int sheetNo) {
super(record, sheetNo); super(record, sheetNo);
_runs.addAll(HSLFTextParagraph.findTextParagraphs(getPPDrawing())); for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
for (List<HSLFTextParagraph> p : _runs) { if (!_paragraphs.contains(l)) _paragraphs.add(l);
}
for (List<HSLFTextParagraph> p : _paragraphs) {
for (HSLFTextParagraph htp : p) { for (HSLFTextParagraph htp : p) {
htp.supplySheet(this); htp.supplySheet(this);
} }
@ -58,7 +61,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
* Returns an array of all the TextRuns found * Returns an array of all the TextRuns found
*/ */
public List<List<HSLFTextParagraph>> getTextParagraphs() { public List<List<HSLFTextParagraph>> getTextParagraphs() {
return _runs; return _paragraphs;
} }
/** /**
@ -138,7 +141,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
protected void onAddTextShape(HSLFTextShape shape) { protected void onAddTextShape(HSLFTextShape shape) {
List<HSLFTextParagraph> runs = shape.getTextParagraphs(); List<HSLFTextParagraph> runs = shape.getTextParagraphs();
_runs.add(runs); _paragraphs.add(runs);
} }
public TxMasterStyleAtom[] getTxMasterStyleAtoms(){ public TxMasterStyleAtom[] getTxMasterStyleAtoms(){

View File

@ -15,9 +15,10 @@
limitations under the License. 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.ddf.*;
import org.apache.poi.hslf.model.Line;
import org.apache.poi.hslf.usermodel.*; import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -31,7 +32,7 @@ import java.awt.*;
* *
* @author Yegor Kozlov * @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_TOP = 1;
protected static final int BORDER_RIGHT = 2; 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 static final int BORDERS_NONE = 8;
protected TableCell[][] cells; protected HSLFTableCell[][] cells;
/** /**
* Create a new Table of the given number of rows and columns * 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 numrows the number of rows
* @param numcols the number of columns * @param numcols the number of columns
*/ */
public Table(int numrows, int numcols) { public HSLFTable(int numrows, int numcols) {
super(); super();
if(numrows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1"); 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"); if(numcols < 1) throw new IllegalArgumentException("The number of columns must be greater than 1");
int x=0, y=0, tblWidth=0, tblHeight=0; 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++) { for (int i = 0; i < cells.length; i++) {
x = 0; x = 0;
for (int j = 0; j < cells[i].length; j++) { for (int j = 0; j < cells[i].length; j++) {
cells[i][j] = new TableCell(this); cells[i][j] = new HSLFTableCell(this);
Rectangle anchor = new Rectangle(x, y, TableCell.DEFAULT_WIDTH, TableCell.DEFAULT_HEIGHT); Rectangle anchor = new Rectangle(x, y, HSLFTableCell.DEFAULT_WIDTH, HSLFTableCell.DEFAULT_HEIGHT);
cells[i][j].setAnchor(anchor); cells[i][j].setAnchor(anchor);
x += TableCell.DEFAULT_WIDTH; x += HSLFTableCell.DEFAULT_WIDTH;
} }
y += TableCell.DEFAULT_HEIGHT; y += HSLFTableCell.DEFAULT_HEIGHT;
} }
tblWidth = x; tblWidth = x;
tblHeight = y; 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 escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the 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); super(escherRecord, parent);
} }
@ -105,7 +106,7 @@ public final class Table extends HSLFGroupShape {
* @param col the column index (0-based) * @param col the column index (0-based)
* @return the cell * @return the cell
*/ */
public TableCell getCell(int row, int col) { public HSLFTableCell getCell(int row, int col) {
return cells[row][col]; return cells[row][col];
} }
@ -124,13 +125,13 @@ public final class Table extends HSLFGroupShape {
EscherOptRecord opt = (EscherOptRecord)lst.get(lst.size()-2); EscherOptRecord opt = (EscherOptRecord)lst.get(lst.size()-2);
EscherArrayProperty p = opt.lookup(0x3A0); EscherArrayProperty p = opt.lookup(0x3A0);
for (int i = 0; i < cells.length; i++) { 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; int rowHeight = cell.getAnchor().height*MASTER_DPI/POINT_DPI;
byte[] val = new byte[4]; byte[] val = new byte[4];
LittleEndian.putInt(val, 0, rowHeight); LittleEndian.putInt(val, 0, rowHeight);
p.setElement(i, val); p.setElement(i, val);
for (int j = 0; j < cells[i].length; j++) { for (int j = 0; j < cells[i].length; j++) {
TableCell c = cells[i][j]; HSLFTableCell c = cells[i][j];
addShape(c); addShape(c);
Line bt = c.getBorderTop(); Line bt = c.getBorderTop();
@ -177,12 +178,12 @@ public final class Table extends HSLFGroupShape {
maxrowlen = Math.max(maxrowlen, row.size()); 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++) { for (int i = 0; i < lst.size(); i++) {
row = lst.get(i); row = lst.get(i);
for (int j = 0; j < row.size(); j++) { for (int j = 0; j < row.size(); j++) {
HSLFTextShape tx = (HSLFTextShape)row.get(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()); cells[i][j].setSheet(tx.getSheet());
} }
} }
@ -256,7 +257,7 @@ public final class Table extends HSLFGroupShape {
public void setAllBorders(Line line){ public void setAllBorders(Line line){
for (int i = 0; i < cells.length; i++) { for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) { for (int j = 0; j < cells[i].length; j++) {
TableCell cell = cells[i][j]; HSLFTableCell cell = cells[i][j];
cell.setBorderTop(cloneBorder(line)); cell.setBorderTop(cloneBorder(line));
cell.setBorderLeft(cloneBorder(line)); cell.setBorderLeft(cloneBorder(line));
if(j == cells[i].length - 1) cell.setBorderRight(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){ public void setOutsideBorders(Line line){
for (int i = 0; i < cells.length; i++) { for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) { 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 == 0) cell.setBorderLeft(cloneBorder(line));
if(j == cells[i].length - 1) cell.setBorderRight(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){ public void setInsideBorders(Line line){
for (int i = 0; i < cells.length; i++) { for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) { 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) if(j != cells[i].length - 1)
cell.setBorderRight(cloneBorder(line)); cell.setBorderRight(cloneBorder(line));

View File

@ -15,15 +15,14 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hslf.model; package org.apache.poi.hslf.usermodel;
import java.awt.Rectangle; import java.awt.Rectangle;
import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord; import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties; import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.hslf.usermodel.HSLFShape; import org.apache.poi.hslf.model.Line;
import org.apache.poi.hslf.usermodel.HSLFTextBox;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.ShapeType;
@ -32,7 +31,7 @@ import org.apache.poi.sl.usermodel.ShapeType;
* *
* @author Yegor Kozlov * @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_WIDTH = 100;
protected static final int DEFAULT_HEIGHT = 40; 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 escherRecord {@link EscherSpContainer} container which holds information about this shape
* @param parent the parent of the 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); 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 * @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table. * in a table then the parent is Table.
*/ */
public TableCell(ShapeContainer<HSLFShape> parent){ public HSLFTableCell(ShapeContainer<HSLFShape> parent){
super(parent); super(parent);
setShapeType(ShapeType.RECT); setShapeType(ShapeType.RECT);
@ -81,25 +80,25 @@ public final class TableCell extends HSLFTextBox {
Rectangle cellAnchor = getAnchor(); Rectangle cellAnchor = getAnchor();
Rectangle lineAnchor = new Rectangle(); Rectangle lineAnchor = new Rectangle();
switch(type){ switch(type){
case Table.BORDER_TOP: case HSLFTable.BORDER_TOP:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = cellAnchor.width; lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0; lineAnchor.height = 0;
break; break;
case Table.BORDER_RIGHT: case HSLFTable.BORDER_RIGHT:
lineAnchor.x = cellAnchor.x + cellAnchor.width; lineAnchor.x = cellAnchor.x + cellAnchor.width;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0; lineAnchor.width = 0;
lineAnchor.height = cellAnchor.height; lineAnchor.height = cellAnchor.height;
break; break;
case Table.BORDER_BOTTOM: case HSLFTable.BORDER_BOTTOM:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y + cellAnchor.height; lineAnchor.y = cellAnchor.y + cellAnchor.height;
lineAnchor.width = cellAnchor.width; lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0; lineAnchor.height = 0;
break; break;
case Table.BORDER_LEFT: case HSLFTable.BORDER_LEFT:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0; lineAnchor.width = 0;
@ -116,7 +115,7 @@ public final class TableCell extends HSLFTextBox {
} }
public void setBorderLeft(Line line) { public void setBorderLeft(Line line) {
if(line != null) anchorBorder(Table.BORDER_LEFT, line); if(line != null) anchorBorder(HSLFTable.BORDER_LEFT, line);
this.borderLeft = line; this.borderLeft = line;
} }
@ -125,7 +124,7 @@ public final class TableCell extends HSLFTextBox {
} }
public void setBorderRight(Line line) { public void setBorderRight(Line line) {
if(line != null) anchorBorder(Table.BORDER_RIGHT, line); if(line != null) anchorBorder(HSLFTable.BORDER_RIGHT, line);
this.borderRight = line; this.borderRight = line;
} }
@ -134,7 +133,7 @@ public final class TableCell extends HSLFTextBox {
} }
public void setBorderTop(Line line) { public void setBorderTop(Line line) {
if(line != null) anchorBorder(Table.BORDER_TOP, line); if(line != null) anchorBorder(HSLFTable.BORDER_TOP, line);
this.borderTop = line; this.borderTop = line;
} }
@ -143,16 +142,16 @@ public final class TableCell extends HSLFTextBox {
} }
public void setBorderBottom(Line line) { public void setBorderBottom(Line line) {
if(line != null) anchorBorder(Table.BORDER_BOTTOM, line); if(line != null) anchorBorder(HSLFTable.BORDER_BOTTOM, line);
this.borderBottom = line; this.borderBottom = line;
} }
public void setAnchor(Rectangle anchor){ public void setAnchor(Rectangle anchor){
super.setAnchor(anchor); super.setAnchor(anchor);
if(borderTop != null) anchorBorder(Table.BORDER_TOP, borderTop); if(borderTop != null) anchorBorder(HSLFTable.BORDER_TOP, borderTop);
if(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight); if(borderRight != null) anchorBorder(HSLFTable.BORDER_RIGHT, borderRight);
if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom); if(borderBottom != null) anchorBorder(HSLFTable.BORDER_BOTTOM, borderBottom);
if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft); if(borderLeft != null) anchorBorder(HSLFTable.BORDER_LEFT, borderLeft);
} }
} }

View File

@ -17,7 +17,10 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.apache.poi.hslf.record.RecordTypes.OutlineTextRefAtom;
import java.awt.Color; import java.awt.Color;
import java.io.IOException;
import java.util.*; import java.util.*;
import org.apache.poi.hslf.model.PPFont; import org.apache.poi.hslf.model.PPFont;
@ -52,8 +55,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
private final TextHeaderAtom _headerAtom; private final TextHeaderAtom _headerAtom;
private TextBytesAtom _byteAtom; private TextBytesAtom _byteAtom;
private TextCharsAtom _charAtom; private TextCharsAtom _charAtom;
private StyleTextPropAtom _styleAtom; private final TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
protected TextRulerAtom _ruler; protected TextRulerAtom _ruler;
protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>(); protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
@ -61,11 +63,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
private HSLFSheet _sheet; private HSLFSheet _sheet;
private int shapeId; 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 StyleTextPropAtom styleTextPropAtom;
private StyleTextProp9Atom styleTextProp9Atom; private StyleTextProp9Atom styleTextProp9Atom;
@ -76,31 +73,29 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
* @param tha the TextHeaderAtom that defines what's what * @param tha the TextHeaderAtom that defines what's what
* @param tba the TextBytesAtom containing the text or null if {@link TextCharsAtom} is provided * @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 tca the TextCharsAtom containing the text or null if {@link TextBytesAtom} is provided
* @param sta the StyleTextPropAtom which defines the character stylings
*/ */
/* package */ HSLFTextParagraph( /* package */ HSLFTextParagraph(
TextHeaderAtom tha, TextHeaderAtom tha,
TextBytesAtom tba, TextBytesAtom tba,
TextCharsAtom tca, TextCharsAtom tca
StyleTextPropAtom sta
) { ) {
if (tha == null) {
throw new IllegalArgumentException("TextHeaderAtom must be set.");
}
_headerAtom = tha; _headerAtom = tha;
_styleAtom = sta;
_byteAtom = tba; _byteAtom = tba;
_charAtom = tca; _charAtom = tca;
} }
/* package */ HSLFTextParagraph(HSLFTextParagraph other) { /* package */ HSLFTextParagraph(HSLFTextParagraph other) {
_headerAtom = other._headerAtom; _headerAtom = other._headerAtom;
_styleAtom = other._styleAtom;
_byteAtom = other._byteAtom; _byteAtom = other._byteAtom;
_charAtom = other._charAtom; _charAtom = other._charAtom;
_paragraphStyle = other._paragraphStyle;
_parentShape = other._parentShape; _parentShape = other._parentShape;
_sheet = other._sheet; _sheet = other._sheet;
_ruler = other._ruler; // ???? _ruler = other._ruler;
shapeId = other.shapeId; shapeId = other.shapeId;
_records = other._records; _paragraphStyle.copy(other._paragraphStyle);
} }
public void addTextRun(HSLFTextRun run) { public void addTextRun(HSLFTextRun run) {
@ -120,7 +115,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
} }
public void setParagraphStyle(TextPropCollection paragraphStyle) { public void setParagraphStyle(TextPropCollection paragraphStyle) {
_paragraphStyle = paragraphStyle; _paragraphStyle.copy(paragraphStyle);
} }
/** /**
@ -196,18 +191,50 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
_ruler = getTextRuler(); _ruler = getTextRuler();
if (_ruler == null) { if (_ruler == null) {
_ruler = TextRulerAtom.getParagraphInstance(); _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; 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 * @return text run records
*/ */
public Record[] getRecords(){ 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 */ /** Numbered List info */
@ -220,11 +247,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
return this.styleTextProp9Atom; return this.styleTextProp9Atom;
} }
/** Characters covered */
public StyleTextPropAtom getStyleTextPropAtom() {
return this._styleAtom;
}
/** /**
* Fetch the value of the given Paragraph related TextProp. * Fetch the value of the given Paragraph related TextProp.
* Returns -1 if that TextProp isn't present. * Returns -1 if that TextProp isn't present.
@ -232,14 +254,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
* Master Sheet will apply. * Master Sheet will apply.
*/ */
private int getParaTextPropVal(String propName) { private int getParaTextPropVal(String propName) {
TextProp prop = null; TextProp prop = _paragraphStyle.findByName(propName);
boolean hardAttribute = false;
if (_paragraphStyle != null){
prop = _paragraphStyle.findByName(propName);
BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME); BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
hardAttribute = maskProp != null && maskProp.getValue() == 0; boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
}
if (prop == null && !hardAttribute){ if (prop == null && !hardAttribute){
HSLFSheet sheet = getSheet(); HSLFSheet sheet = getSheet();
int txtype = getRunType(); int txtype = getRunType();
@ -258,11 +275,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
*/ */
public void setParaTextPropVal(String propName, int val) { public void setParaTextPropVal(String propName, int val) {
// Ensure we have the StyleTextProp atom we're going to need // 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); assert(_paragraphStyle!=null);
TextProp tp = fetchOrAddTextProp(_paragraphStyle, propName); TextProp tp = fetchOrAddTextProp(_paragraphStyle, propName);
tp.setValue(val); tp.setValue(val);
@ -615,10 +627,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
protected void setFlag(int index, boolean value) { protected void setFlag(int index, boolean value) {
// Ensure we have the StyleTextProp atom we're going to need // Ensure we have the StyleTextProp atom we're going to need
if(_paragraphStyle == null) { assert(_paragraphStyle!=null);
_paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
}
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME); BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);
prop.setSubValue(value,index); prop.setSubValue(value,index);
} }
@ -653,12 +662,13 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
boolean afterHeader = false; boolean afterHeader = false;
StyleTextPropAtom style = null; StyleTextPropAtom style = null;
for (Record record : header.getParentRecord().getChildRecords()) { 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 // already on the next header, quit searching
break; break;
} }
afterHeader |= (header == record); afterHeader |= (header == record);
if (afterHeader && record.getRecordType() == RecordTypes.StyleTextPropAtom.typeID) { if (afterHeader && rt == RecordTypes.StyleTextPropAtom.typeID) {
// found it // found it
style = (StyleTextPropAtom)record; 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, * If TextSpecInfoAtom is present, we must update the text size in it,
* otherwise the ppt will be corrupted * otherwise the ppt will be corrupted
*/ */
for (Record r : paragraphs.get(0)._records) { for (Record r : paragraphs.get(0).getRecords()) {
if (r instanceof TextSpecInfoAtom) { if (r instanceof TextSpecInfoAtom) {
((TextSpecInfoAtom)r).setParentSize(rawText.length()+1); ((TextSpecInfoAtom)r).setParentSize(rawText.length()+1);
break; 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) { if (!isFirst) {
TextPropCollection tpc = htp.getParagraphStyle(); TextPropCollection tpc = htp.getParagraphStyle();
HSLFTextParagraph prevHtp = htp; 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.getParagraphStyle().copy(tpc);
htp.setParentShape(prevHtp.getParentShape()); htp.setParentShape(prevHtp.getParentShape());
htp.setShapeId(prevHtp.getShapeId()); htp.setShapeId(prevHtp.getShapeId());
@ -930,24 +948,14 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
/** /**
* For a given PPDrawing, grab all the TextRuns * 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>>(); List<List<HSLFTextParagraph>> runsV = new ArrayList<List<HSLFTextParagraph>>();
for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) { for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) {
runsV.addAll(findTextParagraphs(wrapper)); runsV.add(findTextParagraphs(wrapper, sheet));
} }
return runsV; 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 * Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or * a TextHeaderAtom followed by one of a TextBytesAtom or
@ -955,14 +963,73 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
* *
* @param wrapper an EscherTextboxWrapper * @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 // propagate parents to parent-aware records
RecordContainer.handleParentAwareRecords(wrapper); RecordContainer.handleParentAwareRecords(wrapper);
int shapeId = wrapper.getShapeId(); int shapeId = wrapper.getShapeId();
List<List<HSLFTextParagraph>> rv = findTextParagraphs(wrapper.getChildRecords(), wrapper.getStyleTextProp9Atom()); List<HSLFTextParagraph> rv = null;
for (List<HSLFTextParagraph> htpList : rv) {
for (HSLFTextParagraph htp : htpList) { 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.setShapeId(shapeId);
htp.setStyleTextProp9Atom(styleTextProp9Atom);
} }
} }
return rv; return rv;
@ -974,77 +1041,59 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
* a TextCharsAtom. Builds up TextRuns from these * a TextCharsAtom. Builds up TextRuns from these
* *
* @param records the records to build from * @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>>(); List<List<HSLFTextParagraph>> paragraphCollection = new ArrayList<List<HSLFTextParagraph>>();
if (records == null) { int[] recordIdx = {0};
throw new NullPointerException("records need to be filled.");
}
int recordIdx; for (int slwtIndex = 0; recordIdx[0] < records.length; slwtIndex++) {
for (recordIdx = 0; recordIdx < records.length; recordIdx++) { TextHeaderAtom header = null;
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++];
TextBytesAtom tbytes = null; TextBytesAtom tbytes = null;
TextCharsAtom tchars = null; TextCharsAtom tchars = null;
TextRulerAtom ruler = null; TextRulerAtom ruler = null;
MasterTextPropAtom indents = null; MasterTextPropAtom indents = null;
List<Record> otherRecordList = new ArrayList<Record>(); for (Record r : getRecords(records, recordIdx, null)) {
for (; recordIdx < records.length; recordIdx++) {
Record r = records[recordIdx];
long rt = r.getRecordType(); long rt = r.getRecordType();
if (RecordTypes.TextHeaderAtom.typeID == rt) break; if (RecordTypes.TextHeaderAtom.typeID == rt) {
else if (RecordTypes.TextBytesAtom.typeID == rt) tbytes = (TextBytesAtom)r; header = (TextHeaderAtom)r;
else if (RecordTypes.TextCharsAtom.typeID == rt) tchars = (TextCharsAtom)r; } else if (RecordTypes.TextBytesAtom.typeID == rt) {
// don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below tbytes = (TextBytesAtom)r;
else if (RecordTypes.TextRulerAtom.typeID == rt) ruler = (TextRulerAtom)r; } else if (RecordTypes.TextCharsAtom.typeID == rt) {
else if (RecordTypes.MasterTextPropAtom.typeID == rt) { tchars = (TextCharsAtom)r;
} else if (RecordTypes.TextRulerAtom.typeID == rt) {
ruler = (TextRulerAtom)r;
} else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
indents = (MasterTextPropAtom)r; 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) { if (header.getParentRecord() instanceof SlideListWithText) {
// runs found in PPDrawing are not linked with SlideListWithTexts // runs found in PPDrawing are not linked with SlideListWithTexts
header.setIndex(slwtIndex); header.setIndex(slwtIndex);
} }
Record otherRecords[] = otherRecordList.toArray(new Record[otherRecordList.size()]);
if (tbytes == null && tchars == null) { if (tbytes == null && tchars == null) {
tbytes = new TextBytesAtom(); 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."); 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(); String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
StyleTextPropAtom styles = findStyleAtomPresent(header, rawText.length()); StyleTextPropAtom styles = findStyleAtomPresent(header, rawText.length());
List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
paragraphCollection.add(paragraphs);
// split, but keep delimiter // split, but keep delimiter
for (String para : rawText.split("(?<=\r)")) { for (String para : rawText.split("(?<=\r)")) {
HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, styles); HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars);
paragraphs.add(tpara); paragraphs.add(tpara);
tpara.setStyleTextProp9Atom(styleTextProp9Atom);
tpara._ruler = ruler; tpara._ruler = ruler;
tpara._records = otherRecords;
tpara.getParagraphStyle().updateTextSize(para.length()); tpara.getParagraphStyle().updateTextSize(para.length());
HSLFTextRun trun = new HSLFTextRun(tpara); 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; return paragraphCollection;
} }
@ -1166,9 +1219,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
TextPropCollection charStyle = sta.addCharacterTextPropCollection(1); TextPropCollection charStyle = sta.addCharacterTextPropCollection(1);
wrapper.appendChildRecord(sta); wrapper.appendChildRecord(sta);
HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, sta); HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null);
htp.setParagraphStyle(paraStyle); htp.setParagraphStyle(paraStyle);
htp._records = new Record[0];
HSLFTextRun htr = new HSLFTextRun(htp); HSLFTextRun htr = new HSLFTextRun(htp);
htr.setCharacterStyle(charStyle); htr.setCharacterStyle(charStyle);

View File

@ -92,7 +92,7 @@ public final class HSLFTextRun implements TextRun {
* Change the text * Change the text
*/ */
public void setText(String text) { public void setText(String text) {
_runText = text; _runText = HSLFTextParagraph.toInternalString(text);
} }
// --------------- Internal helpers on rich text properties ------- // --------------- Internal helpers on rich text properties -------

View File

@ -159,10 +159,29 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
} }
protected EscherTextboxWrapper getEscherTextboxWrapper(){ protected EscherTextboxWrapper getEscherTextboxWrapper(){
if(_txtbox == null){ if(_txtbox != null) return _txtbox;
EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID); EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord); 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; return _txtbox;
} }
@ -507,13 +526,17 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
_paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph()); _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
_txtbox = _paragraphs.get(0).getTextboxWrapper(); _txtbox = _paragraphs.get(0).getTextboxWrapper();
} else { } else {
initParagraphsFromSheetRecords(); _paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
if (_paragraphs.isEmpty()) { if (_paragraphs == null || _paragraphs.isEmpty()) {
List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox); throw new RuntimeException("TextRecord didn't contained any text lines");
if (!llhtp.isEmpty()) {
_paragraphs.addAll(llhtp.get(0));
}
} }
// initParagraphsFromSheetRecords();
// if (_paragraphs.isEmpty()) {
// List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
// if (!llhtp.isEmpty()) {
// _paragraphs.addAll(llhtp.get(0));
// }
// }
} }
for (HSLFTextParagraph p : _paragraphs) { for (HSLFTextParagraph p : _paragraphs) {
@ -536,57 +559,47 @@ public abstract class HSLFTextShape extends HSLFSimpleShape implements TextShape
} }
} }
protected void initParagraphsFromSheetRecords(){ // protected void initParagraphsFromSheetRecords(){
EscherTextboxWrapper txtbox = getEscherTextboxWrapper(); // EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
HSLFSheet sheet = getSheet(); // HSLFSheet sheet = getSheet();
//
if(sheet == null || txtbox == null) return; // if (sheet == null || txtbox == null) return;
// List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
OutlineTextRefAtom ota = null; // if (sheetRuns == null) return;
//
Record[] child = txtbox.getChildRecords(); // _paragraphs.clear();
for (int i = 0; i < child.length; i++) { // OutlineTextRefAtom ota = (OutlineTextRefAtom)txtbox.findFirstOfType(OutlineTextRefAtom.typeID);
if (child[i] instanceof OutlineTextRefAtom) { //
ota = (OutlineTextRefAtom)child[i]; // if (ota != null) {
break; // int idx = ota.getTextIndex();
} // for (List<HSLFTextParagraph> r : sheetRuns) {
} // if (r.isEmpty()) continue;
// int ridx = r.get(0).getIndex();
List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs(); // if (ridx > idx) break;
_paragraphs.clear(); // if (ridx == idx) _paragraphs.addAll(r);
if (sheetRuns != null) { // }
if (ota != null) { // if(_paragraphs.isEmpty()) {
int idx = ota.getTextIndex(); // logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
for (List<HSLFTextParagraph> r : sheetRuns) { // }
if (r.isEmpty()) continue; // } else {
int ridx = r.get(0).getIndex(); // int shapeId = getShapeId();
if (ridx > idx) break; // for (List<HSLFTextParagraph> r : sheetRuns) {
if (ridx == idx) _paragraphs.addAll(r); // if (r.isEmpty()) continue;
} // if (r.get(0).getShapeId() == shapeId) _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;
// } // }
// } // }
//
// // 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 // 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. * Also updates the styles to the correct text length.
*/ */
protected void storeText() { protected void storeText() {
HSLFTextParagraph.storeText(_paragraphs); List<HSLFTextParagraph> paras = getTextParagraphs();
HSLFTextParagraph.storeText(paras);
} }
// Accesser methods follow // Accesser methods follow

View File

@ -29,7 +29,7 @@ import org.apache.poi.hslf.record.SlideAtom;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public final class HSLFTitleMaster extends HSLFMasterSheet { 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 * Constructs a TitleMaster
@ -38,14 +38,16 @@ public final class HSLFTitleMaster extends HSLFMasterSheet {
public HSLFTitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) { public HSLFTitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
super(record, 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 * Returns an array of all the TextRuns found
*/ */
public List<List<HSLFTextParagraph>> getTextParagraphs() { public List<List<HSLFTextParagraph>> getTextParagraphs() {
return _runs; return _paragraphs;
} }
/** /**

View File

@ -69,8 +69,8 @@ public class DrawFactory {
return getDrawable((FreeformShape<? extends TextParagraph<? extends TextRun>>)shape); return getDrawable((FreeformShape<? extends TextParagraph<? extends TextRun>>)shape);
} else if (shape instanceof TextShape) { } else if (shape instanceof TextShape) {
return getDrawable((TextShape<? extends TextParagraph<? extends TextRun>>)shape); return getDrawable((TextShape<? extends TextParagraph<? extends TextRun>>)shape);
} else if (shape instanceof ShapeGroup) { } else if (shape instanceof GroupShape) {
return getDrawable((ShapeGroup<? extends Shape>)shape); return getDrawable((GroupShape<? extends Shape>)shape);
} else if (shape instanceof PictureShape) { } else if (shape instanceof PictureShape) {
return getDrawable((PictureShape)shape); return getDrawable((PictureShape)shape);
} else if (shape instanceof Background) { } else if (shape instanceof Background) {
@ -110,8 +110,8 @@ public class DrawFactory {
return new DrawTextShape<T>(shape); return new DrawTextShape<T>(shape);
} }
public <T extends ShapeGroup<? extends Shape>> DrawShapeGroup<T> getDrawable(T shape) { public <T extends GroupShape<? extends Shape>> DrawGroupShape<T> getDrawable(T shape) {
return new DrawShapeGroup<T>(shape); return new DrawGroupShape<T>(shape);
} }
public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) { public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) {

View File

@ -7,9 +7,9 @@ import java.awt.geom.Rectangle2D;
import org.apache.poi.sl.usermodel.*; 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); super(shape);
} }
@ -31,6 +31,7 @@ public class DrawShapeGroup<T extends ShapeGroup<? extends Shape>> extends DrawS
tx.translate(-interior.getX(), -interior.getY()); tx.translate(-interior.getX(), -interior.getY());
DrawFactory drawFact = DrawFactory.getInstance(graphics); DrawFactory drawFact = DrawFactory.getInstance(graphics);
AffineTransform at2 = graphics.getTransform();
for (Shape child : shape) { for (Shape child : shape) {
// remember the initial transform and restore it after we are done with the drawing // 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.setRenderingHint(Drawable.GRESTORE, true);
} }
graphics.setTransform(at2);
graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0); graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0);
} }
} }

View File

@ -25,11 +25,10 @@ public class DrawShape<T extends Shape> implements Drawable {
if (!(shape instanceof PlaceableShape)) return; if (!(shape instanceof PlaceableShape)) return;
PlaceableShape ps = (PlaceableShape)shape; PlaceableShape ps = (PlaceableShape)shape;
Rectangle2D anchor = ps.getAnchor();
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
if(tx != null) { final Rectangle2D anchor = (tx != null)
anchor = tx.createTransformedShape(anchor).getBounds2D(); ? tx.createTransformedShape(ps.getAnchor()).getBounds2D()
} : ps.getAnchor();
// rotation // rotation
double rotation = ps.getRotation(); double rotation = ps.getRotation();
@ -39,7 +38,8 @@ public class DrawShape<T extends Shape> implements Drawable {
double centerY = anchor.getCenterY(); double centerY = anchor.getCenterY();
// normalize rotation // normalize rotation
rotation = (360.+(rotation%360.))%360.; rotation %= 360.;
if (rotation < 0) rotation += 360.;
int quadrant = (((int)rotation+45)/90)%4; int quadrant = (((int)rotation+45)/90)%4;
double scaleX = 1.0, scaleY = 1.0; 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 // 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 // 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 ... // 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.translate(centerX, centerY);
txg.rotate(Math.toRadians(quadrant*90)); txg.rotate(Math.toRadians(90));
txg.translate(-centerX, -centerY); txg.translate(-centerX, -centerY);
boolean oldVariant = true;
Rectangle2D anchor2;
if (oldVariant) {
// shape coordinate space
AffineTransform txs = new AffineTransform(tx);
txs.translate(centerX, centerY); txs.translate(centerX, centerY);
txs.rotate(Math.toRadians(-quadrant*90)); txs.rotate(Math.toRadians(90));
txs.translate(-centerX, -centerY); txs.translate(-centerX, -centerY);
txg.concatenate(txs); txg.concatenate(txs);
Rectangle2D anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D(); anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth(); } else {
scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight(); anchor2 = txg.createTransformedShape(anchor).getBounds2D();
} }
// transformation is applied reversed ... 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.translate(centerX, centerY);
graphics.rotate(Math.toRadians(rotation-quadrant*90.)); graphics.rotate(Math.toRadians(rotation-quadrant*90.));
graphics.scale(scaleX, scaleY); graphics.scale(scaleX, scaleY);
graphics.rotate(Math.toRadians(quadrant*90)); graphics.rotate(Math.toRadians(quadrant*90));
graphics.translate(-centerX, -centerY); 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 ...
} }
//flip horizontal //flip horizontal

View File

@ -32,6 +32,23 @@ public interface Drawable {
public boolean isCompatibleValue(Object val) { public boolean isCompatibleValue(Object val) {
return true; 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();
}
}
} }
/** /**

View File

@ -30,18 +30,35 @@ import javax.imageio.ImageIO;
/** /**
* For now this class renders only images supported by the 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 * 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> * <pre>
* <code> * <code>
* public class MyImageRendener extends ImageRendener { * public class MyImageRendener extends ImageRendener {
* InputStream data;
* *
* public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) { * public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
* // draw image * // 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 { * public void loadImage(InputStream data, String contentType) throws IOException {
* if ("image/wmf".equals(contentType)) { * if ("image/wmf".equals(contentType)) {
* this.data = data;
* // use Apache Batik to handle WMF * // use Apache Batik to handle WMF
* } else { * } else {
* super.loadImage(data,contentType); * super.loadImage(data,contentType);
@ -147,12 +164,14 @@ public class ImageRenderer {
int iw = img.getWidth(); int iw = img.getWidth();
int ih = img.getHeight(); int ih = img.getHeight();
double cw = (100000-clip.left-clip.right) / 100000.0; double cw = (100000-clip.left-clip.right) / 100000.0;
double ch = (100000-clip.top-clip.bottom) / 100000.0; double ch = (100000-clip.top-clip.bottom) / 100000.0;
double sx = anchor.getWidth()/(iw*cw); double sx = anchor.getWidth()/(iw*cw);
double sy = anchor.getHeight()/(ih*ch); double sy = anchor.getHeight()/(ih*ch);
double tx = anchor.getX()-(iw*sx*clip.left/100000.0); double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
double ty = anchor.getY()-(ih*sy*clip.top/100000.0); double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ; AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
Shape clipOld = graphics.getClip(); Shape clipOld = graphics.getClip();

View File

@ -19,6 +19,21 @@ package org.apache.poi.sl.usermodel;
import java.awt.geom.Rectangle2D; 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(); 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);
} }

View File

@ -20,9 +20,17 @@ package org.apache.poi.sl.usermodel;
import java.awt.Insets; import java.awt.Insets;
public interface PictureShape extends SimpleShape { public interface PictureShape extends SimpleShape {
/**
* Returns the picture data for this picture.
*
* @return the picture data for this picture.
*/
PictureData getPictureData(); 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 * @return the clipping rectangle, which is given in percent in relation to the image width/height
*/ */
Insets getClipping(); Insets getClipping();

View File

@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
import java.awt.Graphics2D;
/** /**
* Common parent of Slides, Notes and Masters * 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(); MasterSheet<T,SS> getMasterSheet();
Background getBackground(); Background getBackground();
/**
* Convenience method to draw a sheet to a graphics context
*
* @param graphics
*/
void draw(Graphics2D graphics);
} }

View File

@ -29,7 +29,6 @@ import org.junit.runners.Suite;
TestFreeform.class, TestFreeform.class,
TestHeadersFooters.class, TestHeadersFooters.class,
TestHyperlink.class, TestHyperlink.class,
TestImagePainter.class,
TestLine.class, TestLine.class,
TestMovieShape.class, TestMovieShape.class,
TestOleEmbedding.class, TestOleEmbedding.class,

View File

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

View File

@ -43,15 +43,15 @@ public final class TestTable {
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
Table tbl = new Table(2, 5); HSLFTable tbl = new HSLFTable(2, 5);
slide.addShape(tbl); 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 //table cells have type=TextHeaderAtom.OTHER_TYPE, see bug #46033
assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType()); assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType());
assertTrue(slide.getShapes().get(0) instanceof Table); assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
Table tbl2 = (Table)slide.getShapes().get(0); HSLFTable tbl2 = (HSLFTable)slide.getShapes().get(0);
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns()); assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows()); assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
@ -61,8 +61,8 @@ public final class TestTable {
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())); ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
slide = ppt.getSlides().get(0); slide = ppt.getSlides().get(0);
assertTrue(slide.getShapes().get(0) instanceof Table); assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
Table tbl3 = (Table)slide.getShapes().get(0); HSLFTable tbl3 = (HSLFTable)slide.getShapes().get(0);
assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns()); assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows()); assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
} }
@ -75,7 +75,7 @@ public final class TestTable {
HSLFSlideShow ppt = new HSLFSlideShow(); HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
List<HSLFShape> shapes; List<HSLFShape> shapes;
Table tbl1 = new Table(1, 5); HSLFTable tbl1 = new HSLFTable(1, 5);
assertEquals(5, tbl1.getNumberOfColumns()); assertEquals(5, tbl1.getNumberOfColumns());
assertEquals(1, tbl1.getNumberOfRows()); assertEquals(1, tbl1.getNumberOfRows());
slide.addShape(tbl1); slide.addShape(tbl1);
@ -83,7 +83,7 @@ public final class TestTable {
shapes = slide.getShapes(); shapes = slide.getShapes();
assertEquals(1, shapes.size()); assertEquals(1, shapes.size());
Table tbl2 = (Table)shapes.get(0); HSLFTable tbl2 = (HSLFTable)shapes.get(0);
assertSame(tbl1.getSpContainer(), tbl2.getSpContainer()); assertSame(tbl1.getSpContainer(), tbl2.getSpContainer());
assertEquals(tbl1.getNumberOfColumns(), tbl2.getNumberOfColumns()); assertEquals(tbl1.getNumberOfColumns(), tbl2.getNumberOfColumns());
@ -93,13 +93,13 @@ public final class TestTable {
@Test @Test
public void testIllegalCOnstruction(){ public void testIllegalCOnstruction(){
try { 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"); fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){ } catch (IllegalArgumentException e){
} }
try { 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"); fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){ } catch (IllegalArgumentException e){

View File

@ -281,7 +281,7 @@ public final class TestAddingSlides extends TestCase {
assertEquals(14, doc.getNotesSlideListWithText().getSlideAtomsSets().length); assertEquals(14, doc.getNotesSlideListWithText().getSlideAtomsSets().length);
//remove all slides, corresponding notes should be removed too //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); ppt.removeSlide(0);
} }
assertEquals(0, ppt.getSlides().size()); assertEquals(0, ppt.getSlides().size());

View File

@ -18,14 +18,10 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream; import java.awt.Color;
import java.io.File; import java.awt.Rectangle;
import java.io.FileInputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; 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.HSLFTestDataSamples;
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
import org.apache.poi.hslf.model.*; import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.hslf.record.SlideListWithText; import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.hslf.record.TextHeaderAtom; import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.util.LittleEndian; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.StringUtil; import org.apache.poi.util.*;
import org.apache.poi.util.Units; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
/** /**
@ -527,7 +523,7 @@ public final class TestBugs {
for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) { for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) {
if (! tr.get(0).isDrawingBased()) str++; if (! tr.get(0).isDrawingBased()) str++;
} }
assertEquals(1, str); assertEquals(2, str);
} }
@Test @Test

View File

@ -17,29 +17,22 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
import java.awt.Color; import java.awt.*;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte; import java.awt.image.DataBufferByte;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.apache.poi.POIDataSamples; 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.apache.poi.util.TempFile;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -50,7 +43,7 @@ import org.junit.Test;
public class TestFontRendering { public class TestFontRendering {
private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); 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 @Test
public void bug55902mixedFontWithChineseCharacters() throws Exception { public void bug55902mixedFontWithChineseCharacters() throws Exception {
// font files need to be downloaded first via // font files need to be downloaded first via
@ -86,7 +79,7 @@ public class TestFontRendering {
Dimension pgsize = ss.getPageSize(); Dimension pgsize = ss.getPageSize();
HSLFSlide slide = ss.getSlides()[0]; HSLFSlide slide = ss.getSlides().get(0);
// render it // render it
double zoom = 1; 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); BufferedImage imgActual = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D graphics = imgActual.createGraphics(); Graphics2D graphics = imgActual.createGraphics();
graphics.setRenderingHint(TextPainter.KEY_FONTFALLBACK, fallbackMap); graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap); graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
@ -116,7 +109,7 @@ public class TestFontRendering {
if(!Arrays.equals(expectedData, actualData)) { if(!Arrays.equals(expectedData, actualData)) {
ImageIO.write(imgActual, "PNG", TempFile.createTempFile("TestFontRendering", ".png")); 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);
} }
} }

View File

@ -79,10 +79,14 @@ public final class TestNumberedList3 {
assertEquals(Short.valueOf((short)1), autoNumbers[0].getAutoNumberStartNumber());//Default value = 1 will be used assertEquals(Short.valueOf((short)1), autoNumbers[0].getAutoNumberStartNumber());//Default value = 1 will be used
assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox0[0].getAutoNumberScheme()); assertTrue(TextAutoNumberSchemeEnum.ANM_ArabicPeriod == autoNumbersOfTextBox0[0].getAutoNumberScheme());
final List<TextPropCollection> textProps = textParass.get(1).get(0).getStyleTextPropAtom().getCharacterStyles(); int chCovered = 0;
assertEquals(1, textProps.size()); for (HSLFTextParagraph htp : textParass.get(1)) {
final TextPropCollection textProp = textProps.get(0); for (HSLFTextRun htr : htp.getTextRuns()) {
assertEquals(67, textProp.getCharactersCovered()); TextPropCollection textProp = htr.getCharacterStyle();
chCovered += textProp.getCharactersCovered();
}
}
assertEquals(67, chCovered);
assertTrue(textParass.get(0).get(0).isBullet()); assertTrue(textParass.get(0).get(0).isBullet());

View File

@ -17,18 +17,11 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import java.awt.Dimension; import java.awt.*;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.*;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -36,8 +29,12 @@ import javax.imageio.ImageIO;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.ddf.EscherBSERecord; 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.util.JvmBugs;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -143,45 +140,42 @@ public final class TestPicture {
} }
@Test @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 { public void bug54541() throws Exception {
// InputStream xis = _slTests.openResourceAsStream("54542_cropped_bitmap.pptx"); String file = new String[]{
// XMLSlideShow xss = new XMLSlideShow(xis); "54542_cropped_bitmap.pptx",
// xis.close(); "54541_cropped_bitmap.ppt",
// "54541_cropped_bitmap2.ppt",
// Dimension xpg = xss.getPageSize(); "sample_pptx_grouping_issues.pptx"
// for(XSLFSlide slide : xss.getSlides()) { }[3];
// BufferedImage img = new BufferedImage(xpg.width, xpg.height, BufferedImage.TYPE_INT_RGB); InputStream is = _slTests.openResourceAsStream(file);
// Graphics2D graphics = img.createGraphics(); SlideShow ss = file.endsWith("pptx") ? new XMLSlideShow(is) : new HSLFSlideShow(is);
// 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);
is.close(); is.close();
boolean debugOut = false;
Dimension pg = ss.getPageSize(); Dimension pg = ss.getPageSize();
int i=1; int i=1;
for(HSLFSlide slide : ss.getSlides()) { 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); BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics(); Graphics2D graphics = img.createGraphics();
fixFonts(graphics); fixFonts(graphics);
slide.draw(graphics); slide.draw(graphics);
ImageIO.write(img, "PNG", new File("test"+(i++)+".png")); ImageIO.write(img, "PNG", new File("test"+(i++)+"hslf.png"));
}
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void fixFonts(Graphics2D graphics) { private void fixFonts(Graphics2D graphics) {
if (!JvmBugs.hasLineBreakMeasurerBug()) return; 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>(); if (fontMap == null) fontMap = new HashMap<String,String>();
fontMap.put("Calibri", "Lucida Sans"); fontMap.put("Calibri", "Lucida Sans");
fontMap.put("Cambria", "Lucida Bright"); fontMap.put("Cambria", "Lucida Bright");
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap); graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
} }
} }

View File

@ -22,17 +22,12 @@ import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.net.URL; import java.net.URL;
import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.blip.DIB; import org.apache.poi.hslf.blip.*;
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.*;
/** /**
* Test adding/reading pictures * Test adding/reading pictures
@ -65,9 +60,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can read this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -110,9 +105,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can read this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -156,9 +151,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can get this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -195,9 +190,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can read this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -235,9 +230,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can read this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -274,9 +269,9 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new HSLFSlideShowImpl(new ByteArrayInputStream(out.toByteArray()))); 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 //make sure we can read this picture shape and it refers to the correct picture data
HSLFShape[] sh = ppt.getSlides()[0].getShapes(); List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.length); assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh[0]; pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());
//check picture data //check picture data
@ -302,11 +297,11 @@ public final class TestPictures extends TestCase{
HSLFPictureData pdata; HSLFPictureData pdata;
HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("pictures.ppt")); HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("pictures.ppt"));
HSLFSlide[] slides = ppt.getSlides(); List<HSLFSlide> slides = ppt.getSlides();
HSLFPictureData[] pictures = ppt.getPictureData(); HSLFPictureData[] pictures = ppt.getPictureData();
assertEquals(5, pictures.length); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof JPEG); assertTrue(pdata instanceof JPEG);
assertEquals(HSLFPictureShape.JPEG, pdata.getType()); assertEquals(HSLFPictureShape.JPEG, pdata.getType());
@ -314,7 +309,7 @@ public final class TestPictures extends TestCase{
ppt_bytes = slTests.readFile("clock.jpg"); ppt_bytes = slTests.readFile("clock.jpg");
assertArrayEquals(src_bytes, ppt_bytes); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof PNG); assertTrue(pdata instanceof PNG);
assertEquals(HSLFPictureShape.PNG, pdata.getType()); assertEquals(HSLFPictureShape.PNG, pdata.getType());
@ -322,7 +317,7 @@ public final class TestPictures extends TestCase{
ppt_bytes = slTests.readFile("tomcat.png"); ppt_bytes = slTests.readFile("tomcat.png");
assertArrayEquals(src_bytes, ppt_bytes); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF); assertTrue(pdata instanceof WMF);
assertEquals(HSLFPictureShape.WMF, pdata.getType()); assertEquals(HSLFPictureShape.WMF, pdata.getType());
@ -336,7 +331,7 @@ public final class TestPictures extends TestCase{
System.arraycopy(ppt_bytes, 22, b2, 0, b2.length); System.arraycopy(ppt_bytes, 22, b2, 0, b2.length);
assertArrayEquals(b1, b2); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof PICT); assertTrue(pdata instanceof PICT);
assertEquals(HSLFPictureShape.PICT, pdata.getType()); assertEquals(HSLFPictureShape.PICT, pdata.getType());
@ -350,7 +345,7 @@ public final class TestPictures extends TestCase{
System.arraycopy(ppt_bytes, 512, b2, 0, b2.length); System.arraycopy(ppt_bytes, 512, b2, 0, b2.length);
assertArrayEquals(b1, b2); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof EMF); assertTrue(pdata instanceof EMF);
assertEquals(HSLFPictureShape.EMF, pdata.getType()); 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 // Now test what happens when we use the SlideShow interface
HSLFSlideShow ppt = new HSLFSlideShow(hslf); HSLFSlideShow ppt = new HSLFSlideShow(hslf);
HSLFSlide[] slides = ppt.getSlides(); List<HSLFSlide> slides = ppt.getSlides();
HSLFPictureData[] pictures = ppt.getPictureData(); HSLFPictureData[] pictures = ppt.getPictureData();
assertEquals(12, slides.length); assertEquals(12, slides.size());
assertEquals(2, pictures.length); assertEquals(2, pictures.length);
HSLFPictureShape pict; HSLFPictureShape pict;
HSLFPictureData pdata; 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF); assertTrue(pdata instanceof WMF);
assertEquals(HSLFPictureShape.WMF, pdata.getType()); 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(); pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF); assertTrue(pdata instanceof WMF);
assertEquals(HSLFPictureShape.WMF, pdata.getType()); 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 // Now test what happens when we use the SlideShow interface
HSLFSlideShow ppt = new HSLFSlideShow(hslf); HSLFSlideShow ppt = new HSLFSlideShow(hslf);
HSLFSlide[] slides = ppt.getSlides(); List<HSLFSlide> slides = ppt.getSlides();
HSLFPictureData[] pictures = ppt.getPictureData(); HSLFPictureData[] pictures = ppt.getPictureData();
assertEquals(27, slides.length); assertEquals(27, slides.size());
assertEquals(2, pictures.length); assertEquals(2, pictures.length);
HSLFPictureShape pict; HSLFPictureShape pict;
HSLFPictureData pdata; HSLFPictureData pdata;
pict = (HSLFPictureShape)slides[6].getShapes()[13]; pict = (HSLFPictureShape)slides.get(6).getShapes().get(13);
pdata = pict.getPictureData(); pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF); assertTrue(pdata instanceof WMF);
assertEquals(HSLFPictureShape.WMF, pdata.getType()); assertEquals(HSLFPictureShape.WMF, pdata.getType());
pict = (HSLFPictureShape)slides[7].getShapes()[13]; pict = (HSLFPictureShape)slides.get(7).getShapes().get(13);
pdata = pict.getPictureData(); pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF); assertTrue(pdata instanceof WMF);
assertEquals(HSLFPictureShape.WMF, pdata.getType()); assertEquals(HSLFPictureShape.WMF, pdata.getType());
@ -446,9 +441,9 @@ public final class TestPictures extends TestCase{
public void testGetPictureName() throws Exception { public void testGetPictureName() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow(slTests.openResourceAsStream("ppt_with_png.ppt")); 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()); assertEquals("test", p.getPictureName());
} }
@ -469,7 +464,7 @@ public final class TestPictures extends TestCase{
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())); 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()); assertEquals("tomcat.png", p.getPictureName());
} }
} }

View File

@ -19,10 +19,12 @@
package org.apache.poi.hslf.usermodel; 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.apache.poi.POIDataSamples;
import org.junit.Test;
/** /**
@ -30,40 +32,39 @@ import org.apache.poi.POIDataSamples;
* *
* @author Alex Nikiforov [mailto:anikif@gmail.com] * @author Alex Nikiforov [mailto:anikif@gmail.com]
*/ */
public final class TestTable extends TestCase { public class TestTable {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
protected void setUp() throws Exception { @Test
}
public void testTable() throws Exception { public void testTable() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt")); HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt"));
assertTrue("No Exceptions while reading file", true); assertTrue("No Exceptions while reading file", true);
final HSLFSlide[] slides = ppt.getSlides(); List<HSLFSlide> slides = ppt.getSlides();
assertEquals(1, slides.length); assertEquals(1, slides.size());
checkSlide(slides[0]); checkSlide(slides.get(0));
} }
private void checkSlide(final HSLFSlide s) { private void checkSlide(final HSLFSlide s) {
HSLFTextParagraph[] textRuns = s.getTextParagraphs(); List<List<HSLFTextParagraph>> textRuns = s.getTextParagraphs();
assertEquals(2, textRuns.length); 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("Table sample", textRun.getRawText().trim());
assertEquals(1, textRuns[0].getTextRuns().length); assertEquals(1, textRuns.get(0).get(0).getTextRuns().size());
assertFalse(textRun.isBullet()); 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); assertNotNull(shapes);
assertEquals(3, shapes.length); assertEquals(3, shapes.size());
assertTrue(shapes[2] instanceof Table); assertTrue(shapes.get(2) instanceof HSLFTable);
final Table table = (Table) shapes[2]; final HSLFTable table = (HSLFTable) shapes.get(2);
assertEquals(4, table.getNumberOfColumns()); assertEquals(4, table.getNumberOfColumns());
assertEquals(6, table.getNumberOfRows()); assertEquals(6, table.getNumberOfRows());
for (int x = 0; x < 4; x ++) { 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++) { for (int y = 1; y < 6; y++) {
assertEquals("Row " + y + ", Cell " + (x + 1), table.getCell(y, x).getText()); assertEquals("Row " + y + ", Cell " + (x + 1), table.getCell(y, x).getText());
} }

View File

@ -19,10 +19,12 @@ package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.IOException; import java.awt.Color;
import java.io.*;
import java.util.List; import java.util.List;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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' // Ensure trailing \n's are NOT stripped, it is legal to set a text with a trailing '\r'
tr.setText(changeTo + "\n"); 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; else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
} }
// Bytes -> Bytes // Bytes -> Bytes
assertNull(tca); assertNull(tca);
assertNotNull(tba); assertNotNull(tba);
@ -197,18 +198,13 @@ public final class TestTextRun {
List<HSLFTextParagraph> trB = textParass.get(1); List<HSLFTextParagraph> trB = textParass.get(1);
assertEquals(1, trA.size()); assertEquals(1, trA.size());
assertEquals(1, trB.size()); assertEquals(2, trB.size());
HSLFTextRun rtrA = trA.get(0).getTextRuns().get(0); HSLFTextRun rtrA = trA.get(0).getTextRuns().get(0);
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0); HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
assertEquals(HSLFTextParagraph.getRawText(trA), rtrA.getRawText()); assertEquals(HSLFTextParagraph.getRawText(trA), rtrA.getRawText());
assertEquals(HSLFTextParagraph.getRawText(trB), rtrB.getRawText()); assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
// assertNull(rtrA._getRawCharacterStyle());
// assertNull(rtrA._getRawParagraphStyle());
// assertNull(rtrB._getRawCharacterStyle());
// assertNull(rtrB._getRawParagraphStyle());
} }
/** /**
@ -284,39 +280,39 @@ public final class TestTextRun {
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0); HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0); HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0);
HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0); HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0);
// TextPropCollection tpBP = rtrB._getRawParagraphStyle(); TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
// TextPropCollection tpBC = rtrB._getRawCharacterStyle(); TextPropCollection tpBC = rtrB.getCharacterStyle();
// TextPropCollection tpCP = rtrC._getRawParagraphStyle(); TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
// TextPropCollection tpCC = rtrC._getRawCharacterStyle(); TextPropCollection tpCC = rtrC.getCharacterStyle();
// TextPropCollection tpDP = rtrD._getRawParagraphStyle(); TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
// TextPropCollection tpDC = rtrD._getRawCharacterStyle(); TextPropCollection tpDC = rtrD.getCharacterStyle();
// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText()); // assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
// assertNotNull(tpBP); assertNotNull(tpBP);
// assertNotNull(tpBC); assertNotNull(tpBC);
// assertNotNull(tpCP); assertNotNull(tpCP);
// assertNotNull(tpCC); assertNotNull(tpCC);
// assertNotNull(tpDP); assertNotNull(tpDP);
// assertNotNull(tpDC); assertNotNull(tpDC);
// assertTrue(tpBP.equals(tpCP)); assertEquals(tpBP,tpCP);
// assertTrue(tpBP.equals(tpDP)); assertEquals(tpBP,tpDP);
// assertTrue(tpCP.equals(tpDP)); assertEquals(tpCP,tpDP);
// assertFalse(tpBC.equals(tpCC)); assertNotEquals(tpBC,tpCC);
// assertFalse(tpBC.equals(tpDC)); assertNotEquals(tpBC,tpDC);
// assertFalse(tpCC.equals(tpDC)); assertNotEquals(tpCC,tpDC);
// Change text via normal // Change text via normal
// trB.setText("Test Foo Test"); HSLFTextParagraph.setText(trB, "Test Foo Test");
// Ensure now have first style // Ensure now have first style
// assertEquals(1, trB.getTextRuns().length); assertEquals(1, trB.get(0).getTextRuns().size());
// rtrB = trB.getTextRuns().get(0); rtrB = trB.get(0).getTextRuns().get(0);
// assertEquals("Test Foo Test", trB.getRawText()); assertEquals("Test Foo Test", HSLFTextParagraph.getRawText(trB));
// assertEquals("Test Foo Test", rtrB.getRawText()); assertEquals("Test Foo Test", rtrB.getRawText());
// assertNotNull(rtrB._getRawCharacterStyle()); assertNotNull(rtrB.getCharacterStyle());
// assertNotNull(rtrB._getRawParagraphStyle()); assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
// assertEquals( tpBP, rtrB._getRawParagraphStyle() ); assertEquals( tpBP, rtrB.getTextParagraph().getParagraphStyle() );
// assertEquals( tpBC, rtrB._getRawCharacterStyle() ); assertEquals( tpBC, rtrB.getCharacterStyle() );
} }
/** /**
@ -328,21 +324,21 @@ public final class TestTextRun {
HSLFSlide slideOne = ss.getSlides().get(0); HSLFSlide slideOne = ss.getSlides().get(0);
List<List<HSLFTextParagraph>> textRuns = slideOne.getTextParagraphs(); List<List<HSLFTextParagraph>> textRuns = slideOne.getTextParagraphs();
List<HSLFTextParagraph> trB = textRuns.get(1); List<HSLFTextParagraph> trB = textRuns.get(1);
// assertEquals(1, trB.getTextRuns().length); assertEquals(1, trB.get(0).getTextRuns().size());
//
// HSLFTextRun rtrB = trB.getTextRuns().get(0); HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
// assertEquals(trB.getRawText(), rtrB.getRawText()); assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
// assertNull(rtrB._getRawCharacterStyle()); assertNotNull(rtrB.getCharacterStyle());
// assertNull(rtrB._getRawParagraphStyle()); assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
// Change text via rich // Change text via rich
// rtrB.setText("Test Test Test"); rtrB.setText("Test Test Test");
// assertEquals("Test Test Test", trB.getRawText()); assertEquals("Test Test Test", HSLFTextParagraph.getRawText(trB.subList(0, 1)));
// assertEquals("Test Test Test", rtrB.getRawText()); assertEquals("Test Test Test", rtrB.getRawText());
// Will now have dummy props // Will now have dummy props
// assertNotNull(rtrB._getRawCharacterStyle()); assertNotNull(rtrB.getCharacterStyle());
// assertNotNull(rtrB._getRawParagraphStyle()); assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
} }
/** /**
@ -361,27 +357,27 @@ public final class TestTextRun {
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0); HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0); HSLFTextRun rtrC = trB.get(1).getTextRuns().get(0);
HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0); HSLFTextRun rtrD = trB.get(2).getTextRuns().get(0);
// TextPropCollection tpBP = rtrB._getRawParagraphStyle(); TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
// TextPropCollection tpBC = rtrB._getRawCharacterStyle(); TextPropCollection tpBC = rtrB.getCharacterStyle();
// TextPropCollection tpCP = rtrC._getRawParagraphStyle(); TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
// TextPropCollection tpCC = rtrC._getRawCharacterStyle(); TextPropCollection tpCC = rtrC.getCharacterStyle();
// TextPropCollection tpDP = rtrD._getRawParagraphStyle(); TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
// TextPropCollection tpDC = rtrD._getRawCharacterStyle(); TextPropCollection tpDC = rtrD.getCharacterStyle();
// Check text and stylings // Check text and stylings
// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText()); assertEquals(HSLFTextParagraph.getRawText(trB).substring(0, 30), rtrB.getRawText());
// assertNotNull(tpBP); assertNotNull(tpBP);
// assertNotNull(tpBC); assertNotNull(tpBC);
// assertNotNull(tpCP); assertNotNull(tpCP);
// assertNotNull(tpCC); assertNotNull(tpCC);
// assertNotNull(tpDP); assertNotNull(tpDP);
// assertNotNull(tpDC); assertNotNull(tpDC);
// assertTrue(tpBP.equals(tpCP)); assertEquals(tpBP, tpCP);
// assertTrue(tpBP.equals(tpDP)); assertEquals(tpBP, tpDP);
// assertTrue(tpCP.equals(tpDP)); assertEquals(tpCP, tpDP);
// assertFalse(tpBC.equals(tpCC)); assertNotEquals(tpBC, tpCC);
// assertFalse(tpBC.equals(tpDC)); assertNotEquals(tpBC, tpDC);
// assertFalse(tpCC.equals(tpDC)); assertNotEquals(tpCC, tpDC);
// Check text in the rich runs // Check text in the rich runs
assertEquals("This is the subtitle, in bold\r", rtrB.getRawText()); assertEquals("This is the subtitle, in bold\r", rtrB.getRawText());
@ -394,32 +390,32 @@ public final class TestTextRun {
rtrB.setText(newBText); rtrB.setText(newBText);
rtrC.setText(newCText); rtrC.setText(newCText);
rtrD.setText(newDText); rtrD.setText(newDText);
assertEquals(newBText, rtrB.getRawText()); HSLFTextParagraph.storeText(trB);
assertEquals(newCText, rtrC.getRawText());
assertEquals(newDText, rtrD.getRawText());
// 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 // The styles should have been updated for the new sizes
// assertEquals(newBText.length(), tpBC.getCharactersCovered()); assertEquals(newBText.length(), tpBC.getCharactersCovered());
// assertEquals(newCText.length(), tpCC.getCharactersCovered()); assertEquals(newCText.length(), tpCC.getCharactersCovered());
// assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger 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 // Paragraph style should be sum of text length
// assertEquals(newBText.length() + newCText.length() + newDText.length(), tpBP.getCharactersCovered()); assertEquals(
newBText.length() + newCText.length() + newDText.length() +1,
tpBP.getCharactersCovered() + tpCP.getCharactersCovered() + tpDP.getCharactersCovered()
);
// Check stylings still as expected // Check stylings still as expected
// TextPropCollection ntpBC = rtrB._getRawCharacterStyle(); TextPropCollection ntpBC = rtrB.getCharacterStyle();
// TextPropCollection ntpCC = rtrC._getRawCharacterStyle(); TextPropCollection ntpCC = rtrC.getCharacterStyle();
// TextPropCollection ntpDC = rtrD._getRawCharacterStyle(); TextPropCollection ntpDC = rtrD.getCharacterStyle();
// assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList()); assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
// assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList()); assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
// assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList()); assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
} }
@ -467,82 +463,86 @@ public final class TestTextRun {
assertEquals(0, slide.getTextParagraphs().size()); assertEquals(0, slide.getTextParagraphs().size());
HSLFTextBox shape1 = new HSLFTextBox(); HSLFTextBox shape1 = new HSLFTextBox();
// HSLFTextParagraph run1 = shape1.getTextParagraphs(); List<HSLFTextParagraph> run1 = shape1.getTextParagraphs();
// assertSame(run1, shape1.createTextRun()); shape1.setText("Text 1");
// run1.setText("Text 1");
slide.addShape(shape1); slide.addShape(shape1);
//The array of Slide's text runs must be updated when new text shapes are added. //The array of Slide's text runs must be updated when new text shapes are added.
// HSLFTextParagraph[] runs = slide.getTextParagraphs(); List<List<HSLFTextParagraph>> runs = slide.getTextParagraphs();
// assertNotNull(runs); assertNotNull(runs);
// assertSame(run1, runs.get(0)); assertSame(run1, runs.get(0));
//
// HSLFTextBox shape2 = new HSLFTextBox(); HSLFTextBox shape2 = new HSLFTextBox();
// HSLFTextParagraph run2 = shape2.getTextParagraphs(); List<HSLFTextParagraph> run2 = shape2.getTextParagraphs();
// assertSame(run2, shape2.createTextRun()); shape2.setText("Text 2");
// run2.setText("Text 2"); slide.addShape(shape2);
// slide.addShape(shape2);
// runs = slide.getTextParagraphs();
// runs = slide.getTextParagraphs(); assertEquals(2, runs.size());
// assertEquals(2, runs.length);
// assertSame(run1, runs.get(0));
// assertSame(run1, runs.get(0)); assertSame(run2, runs.get(1));
// assertSame(run2, runs.get(1));
// // as getShapes()
// //as getShapes() List<HSLFShape> sh = slide.getShapes();
// HSLFShape[] sh = slide.getShapes(); assertEquals(2, sh.size());
// assertEquals(2, sh.length); assertTrue(sh.get(0) instanceof HSLFTextBox);
// assertTrue(sh.get(0) instanceof HSLFTextBox); HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
// HSLFTextBox box1 = (HSLFTextBox)sh.get(0); assertSame(run1, box1.getTextParagraphs());
// assertSame(run1, box1.getTextParagraphs()); HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
// HSLFTextBox box2 = (HSLFTextBox)sh.get(1); assertSame(run2, box2.getTextParagraphs());
// assertSame(run2, box2.getTextParagraphs());
// // test Table - a complex group of shapes containing text objects
// //test Table - a complex group of shapes containing text objects HSLFSlide slide2 = ppt.createSlide();
// HSLFSlide slide2 = ppt.createSlide(); assertTrue(slide2.getTextParagraphs().isEmpty());
// assertNull(slide2.getTextParagraphs()); HSLFTable table = new HSLFTable(2, 2);
// Table table = new Table(2, 2); slide2.addShape(table);
// slide2.addShape(table); runs = slide2.getTextParagraphs();
// runs = slide2.getTextParagraphs(); assertNotNull(runs);
// assertNotNull(runs); assertEquals(4, runs.size());
// assertEquals(4, runs.length);
} }
@Test @Test
public void test48916() throws IOException { public void test48916() throws IOException {
// HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt")); HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
// for(HSLFSlide slide : ppt.getSlides()){ List<HSLFSlide> slides = ppt.getSlides();
// for(HSLFShape sh : slide.getShapes()){ for(HSLFSlide slide : slides){
// if(sh instanceof HSLFTextShape){ for(HSLFShape sh : slide.getShapes()){
// HSLFTextShape tx = (HSLFTextShape)sh; if (!(sh instanceof HSLFTextShape)) continue;
// HSLFTextParagraph run = tx.getTextParagraphs(); HSLFTextShape tx = (HSLFTextShape)sh;
// //verify that records cached in TextRun and EscherTextboxWrapper are the same List<HSLFTextParagraph> paras = tx.getTextParagraphs();
// Record[] runChildren = run.getRecords(); //verify that records cached in TextRun and EscherTextboxWrapper are the same
// Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords(); Record[] runChildren = paras.get(0).getRecords();
// assertEquals(runChildren.length, txboxChildren.length); Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
// for(int i=0; i < txboxChildren.length; i++){ assertEquals(runChildren.length, txboxChildren.length);
// assertSame(txboxChildren.get(i), runChildren.get(i)); for(int i=0; i < txboxChildren.length; i++){
// } assertSame(txboxChildren[i], runChildren[i]);
// //caused NPE prior to fix of Bugzilla #48916 }
// run.getTextRuns().get(0).setBold(true); // caused NPE prior to fix of Bugzilla #48916
// run.getTextRuns().get(0).setFontColor(Color.RED); for (HSLFTextParagraph p : paras) {
// } for (HSLFTextRun rt : p.getTextRuns()) {
// } rt.setBold(true);
// } rt.setFontColor(Color.RED);
// ByteArrayOutputStream out = new ByteArrayOutputStream(); }
// ppt.write(out); }
// ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())); tx.storeText();
// for(HSLFSlide slide : ppt.getSlides()){ }
// for(HSLFShape sh : slide.getShapes()){ }
// if(sh instanceof HSLFTextShape){ ByteArrayOutputStream out = new ByteArrayOutputStream();
// HSLFTextShape tx = (HSLFTextShape)sh; ppt.write(out);
// HSLFTextParagraph run = tx.getTextParagraphs();
// HSLFTextRun rt = run.getTextRuns().get(0); ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
// assertTrue(rt.isBold()); for(HSLFSlide slide : ppt.getSlides()){
// assertEquals(rt.getFontColor(), Color.RED); 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);
}
}
}
} }

Binary file not shown.

Binary file not shown.