瀏覽代碼

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
tags/REL_3_13_FINAL
Andreas Beeker 9 年之前
父節點
當前提交
b00e544e9b
共有 58 個檔案被更改,包括 978 行新增1038 行删除
  1. 2
    2
      src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
  2. 2
    2
      src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java
  3. 4
    4
      src/examples/src/org/apache/poi/hslf/examples/TableDemo.java
  4. 20
    7
      src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java
  5. 1
    1
      src/java/org/apache/poi/ddf/EscherProperties.java
  6. 2
    1
      src/java/org/apache/poi/ddf/EscherTextboxRecord.java
  7. 15
    2
      src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java
  8. 3
    4
      src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
  9. 1
    0
      src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
  10. 1
    0
      src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
  11. 0
    1
      src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
  12. 0
    95
      src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java
  13. 0
    72
      src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java
  14. 4
    4
      src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
  15. 61
    2
      src/scratchpad/src/org/apache/poi/hslf/model/Line.java
  16. 1
    0
      src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
  17. 1
    3
      src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java
  18. 18
    25
      src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
  19. 2
    2
      src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java
  20. 1
    3
      src/scratchpad/src/org/apache/poi/hslf/record/SlideListWithText.java
  21. 3
    2
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
  22. 23
    37
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
  23. 8
    5
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java
  24. 4
    47
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
  25. 5
    12
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
  26. 6
    23
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
  27. 1
    1
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
  28. 7
    2
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
  29. 88
    71
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
  30. 3
    1
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
  31. 8
    5
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
  32. 19
    18
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
  33. 17
    18
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java
  34. 164
    112
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
  35. 1
    1
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
  36. 73
    59
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
  37. 5
    3
      src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
  38. 4
    4
      src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java
  39. 4
    3
      src/scratchpad/src/org/apache/poi/sl/draw/DrawGroupShape.java
  40. 36
    19
      src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java
  41. 17
    0
      src/scratchpad/src/org/apache/poi/sl/draw/Drawable.java
  42. 20
    1
      src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java
  43. 16
    1
      src/scratchpad/src/org/apache/poi/sl/usermodel/GroupShape.java
  44. 9
    1
      src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java
  45. 9
    0
      src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java
  46. 0
    1
      src/scratchpad/testcases/org/apache/poi/hslf/model/AllHSLFModelTests.java
  47. 0
    55
      src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java
  48. 10
    10
      src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
  49. 1
    1
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java
  50. 12
    16
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
  51. 10
    17
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java
  52. 8
    4
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList3.java
  53. 32
    38
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
  54. 37
    42
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
  55. 22
    21
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java
  56. 157
    157
      src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
  57. 二進制
      test-data/slideshow/54541_cropped_bitmap2.ppt
  58. 二進制
      test-data/slideshow/sample_pptx_grouping_issues.pptx

+ 2
- 2
src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java 查看文件

{"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);

+ 2
- 2
src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java 查看文件

//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);


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

+ 4
- 4
src/examples/src/org/apache/poi/hslf/examples/TableDemo.java 查看文件

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


//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");

+ 20
- 7
src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java 查看文件

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;
field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4;
field_2_dy1 = LittleEndian.getInt( data, pos + size );size+=4;
field_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4;
field_4_dy2 = LittleEndian.getInt( data, pos + size );size+=4;
switch (bytesRemaining) {
case 16: // RectStruct
field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4;
field_2_dy1 = LittleEndian.getInt( data, pos + size );size+=4;
field_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4;
field_4_dy2 = LittleEndian.getInt( data, pos + size );size+=4;
break;
case 8: // SmallRectStruct
field_1_dx1 = LittleEndian.getShort( data, pos + size );size+=2;
field_2_dy1 = LittleEndian.getShort( data, pos + size );size+=2;
field_3_dx2 = LittleEndian.getShort( data, pos + size );size+=2;
field_4_dy2 = LittleEndian.getShort( data, pos + size );size+=2;
break;
default:
throw new RuntimeException("Invalid EscherChildAnchorRecord - neither 8 nor 16 bytes.");
}
return 8 + size; return 8 + size;
} }


LittleEndian.putInt( data, pos, getRecordSize()-8 ); pos += 4; LittleEndian.putInt( data, pos, getRecordSize()-8 ); pos += 4;
LittleEndian.putInt( data, pos, field_1_dx1 ); pos += 4; LittleEndian.putInt( data, pos, field_1_dx1 ); pos += 4;
LittleEndian.putInt( data, pos, field_2_dy1 ); pos += 4; LittleEndian.putInt( data, pos, field_2_dy1 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_dx2 ); pos += 4;
LittleEndian.putInt( data, pos, field_4_dy2 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_dx2 ); pos += 4;
LittleEndian.putInt( data, pos, field_4_dy2 ); pos += 4;


listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this );
return pos - offset; return pos - offset;

+ 1
- 1
src/java/org/apache/poi/ddf/EscherProperties.java 查看文件

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");

+ 2
- 1
src/java/org/apache/poi/ddf/EscherTextboxRecord.java 查看文件



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;
*/ */
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];

+ 15
- 2
src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java 查看文件

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
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 );
} }
public void setStroke(Stroke s) public void setStroke(Stroke s)
{ {
System.out.println( "setStroke(Stoke):" ); System.out.println( "setStroke(Stoke):" );
System.out.println( "s = " + s );
if (s instanceof BasicStroke) {
BasicStroke bs = (BasicStroke)s;
StringBuilder str = new StringBuilder("s = BasicStroke(");
str.append("dash[]: "+Arrays.toString(bs.getDashArray())+", ");
str.append("dashPhase: "+bs.getDashPhase()+", ");
str.append("endCap: "+bs.getEndCap()+", ");
str.append("lineJoin: "+bs.getLineJoin()+", ");
str.append("width: "+bs.getLineWidth()+", ");
str.append("miterLimit: "+bs.getMiterLimit()+")");
System.out.println(str.toString());
} else {
System.out.println( "s = " + s );
}
g2D.setStroke( s ); g2D.setStroke( s );
} }

+ 3
- 4
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java 查看文件

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.ShapeGroup;
import org.apache.poi.sl.usermodel.GroupShape;
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.*;
* @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;
* used for calculations of grouping, scaling, and rotation * used for calculations of grouping, scaling, and rotation
* behavior of shapes placed within a group. * behavior of shapes placed within a group.
*/ */
public void setInteriorAnchor(Rectangle2D anchor){
public void setInteriorAnchor(Rectangle2D anchor) {
CTGroupTransform2D xfrm = getSafeXfrm(); CTGroupTransform2D xfrm = getSafeXfrm();
CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff(); CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff();
long x = Units.toEMU(anchor.getX()); long x = Units.toEMU(anchor.getX());

+ 1
- 0
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java 查看文件

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();

+ 1
- 0
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java 查看文件

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

+ 0
- 1
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java 查看文件

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;

+ 0
- 95
src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java 查看文件

/* ====================================================================
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);
}

}

+ 0
- 72
src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java 查看文件

/* ====================================================================
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);
}

+ 4
- 4
src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java 查看文件



// Table text // Table text
for (HSLFShape shape : slide.getShapes()){ for (HSLFShape shape : slide.getShapes()){
if (shape instanceof Table){
extractTableText(ret, (Table)shape);
if (shape instanceof HSLFTable){
extractTableText(ret, (HSLFTable)shape);
} }
} }
// Slide footer, if set // Slide footer, if set
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();

+ 61
- 2
src/scratchpad/src/org/apache/poi/hslf/model/Line.java 查看文件

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.Line2D;
import java.awt.geom.*;
import java.util.ArrayList;


/** /**
* Represents a line in a PowerPoint drawing * Represents a line in a PowerPoint drawing
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;
}


} }

+ 1
- 0
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java 查看文件

* 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;

+ 1
- 3
src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java 查看文件



// 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++) {
_children[i].writeOut(baos);
}
for (Record r : _children) r.writeOut(baos);
byte[] data = baos.toByteArray(); byte[] data = baos.toByteArray();


// Save in the escher layer // Save in the escher layer

+ 18
- 25
src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java 查看文件

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
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[] escherContainersF004 = findAllEscherContainerRecordOfType((short)0xf004, SpgrContainer);
for (EscherContainerRecord spContainer : escherContainersF004) {
final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherSpgrContainer, dgContainer);
final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType((short)RecordTypes.EscherSpContainer, spgrContainer);
for (EscherContainerRecord spContainer : spContainers) {
StyleTextProp9Atom nineAtom = findInSpContainer(spContainer); StyleTextProp9Atom nineAtom = findInSpContainer(spContainer);
EscherSpRecord sp = null;
final EscherRecord escherContainerF00A = findFirstEscherRecordOfType((short)0xf00a, spContainer);
if (null != escherContainerF00A) {
if (escherContainerF00A instanceof EscherSpRecord) {
sp = (EscherSpRecord) escherContainerF00A;
}
}
final EscherRecord escherContainerF00D = findFirstEscherRecordOfType((short)0xf00d, spContainer);
if (null == escherContainerF00D) { continue; }
if (escherContainerF00D instanceof EscherTextboxRecord) {
EscherTextboxRecord tbr = (EscherTextboxRecord) escherContainerF00D;
EscherTextboxWrapper w = new EscherTextboxWrapper(tbr);
w.setStyleTextProp9Atom(nineAtom);
if (null != sp) {
w.setShapeId(sp.getShapeId());
}
found.add(w);
EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherSp, spContainer);
EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherClientTextbox, spContainer);
if (null == clientTextbox) { continue; }

EscherTextboxWrapper w = new EscherTextboxWrapper(clientTextbox);
w.setStyleTextProp9Atom(nineAtom);
if (null != sp) {
w.setShapeId(sp.getShapeId());
} }
found.add(w);
} }
return found.toArray(new EscherTextboxWrapper[found.size()]); 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);
if (null == escherContainerF011) { return null; }
final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, escherContainerF011);
EscherContainerRecord clientData = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherClientData, spContainer);
if (null == clientData) { return null; }
final EscherContainerRecord escherContainer1388 = findFirstEscherContainerRecordOfType((short)0x1388, clientData);
if (null == escherContainer1388) { return null; } 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; }

+ 2
- 2
src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java 查看文件

// 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]);


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



+ 1
- 3
src/scratchpad/src/org/apache/poi/hslf/record/SlideListWithText.java 查看文件

} }


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


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


/** /**

+ 3
- 2
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java 查看文件

}; };
} }
case FILL_PICTURE: { case FILL_PICTURE: {
final HSLFPictureData pd = getPictureData();
if (pd == null) break;
return new TexturePaint() { return new TexturePaint() {
final HSLFPictureData pd = getPictureData();
public InputStream getImageData() { public InputStream getImageData() {
return new ByteArrayInputStream(pd.getData()); return new ByteArrayInputStream(pd.getData());
} }

+ 23
- 37
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java 查看文件

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.ShapeType;
import org.apache.poi.sl.usermodel.*;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger; 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.
spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI); spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
} }


/**
* Sets the coordinate space of this group. All children are constrained
* to these coordinates.
*
* @param anchor the coordinate space of this group
*/
public void setCoordinates(Rectangle2D anchor){
@Override
public void setInteriorAnchor(Rectangle2D anchor){
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID); 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);


} }


/**
* Gets the coordinate space of this group. All children are constrained
* to these coordinates.
*
* @return the coordinate space of this group
*/
public Rectangle2D getCoordinates(){
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);

Rectangle2D.Float anchor = new Rectangle2D.Float();
anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;

return anchor;
@Override
public Rectangle2D getInteriorAnchor(){
EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID);
double x = rec.getRectX1()*POINT_DPI/MASTER_DPI;
double y = rec.getRectY1()*POINT_DPI/MASTER_DPI;
double width = (rec.getRectX2()-rec.getRectX1())*POINT_DPI/MASTER_DPI;
double height = (rec.getRectY2()-rec.getRectY1())*POINT_DPI/MASTER_DPI;
return new Rectangle2D.Double(x,y,width,height);
} }


/** /**
*/ */
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(
(float)rec.getDx1()*POINT_DPI/MASTER_DPI,
(float)rec.getDy1()*POINT_DPI/MASTER_DPI,
(float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
(float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
);
double x = rec.getDx1()*POINT_DPI/MASTER_DPI;
double y = rec.getDy1()*POINT_DPI/MASTER_DPI;
double width = (rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI;
double height = (rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI;
anchor = new Rectangle2D.Double(x,y,width,height);
} else { } else {
anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
double x = clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
double y = clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
double width = (clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
double height = (clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
anchor = new Rectangle2D.Double(x,y,width,height);
} }


return anchor; return anchor;

+ 8
- 5
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java 查看文件

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.
// 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());
if (_runs.isEmpty()) {
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
if (!_paragraphs.contains(l)) _paragraphs.add(l);
}
if (_paragraphs.isEmpty()) {
logger.log(POILogger.WARN, "No text records found for notes sheet"); 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);
} }
*/ */
@Override @Override
public List<List<HSLFTextParagraph>> getTextParagraphs() { public List<List<HSLFTextParagraph>> getTextParagraphs() {
return _runs;
return _paragraphs;
} }


/** /**

+ 4
- 47
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java 查看文件



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.DIB;
import org.apache.poi.hslf.blip.EMF;
import org.apache.poi.hslf.blip.ImagePainter;
import org.apache.poi.hslf.blip.JPEG;
import org.apache.poi.hslf.blip.PICT;
import org.apache.poi.hslf.blip.PNG;
import org.apache.poi.hslf.blip.WMF;
import org.apache.poi.hslf.blip.*;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.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.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.util.*;


/** /**
* A class that represents image data contained in a slide show. * 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());


*/ */
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.
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];
}

} }

+ 5
- 12
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java 查看文件

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.ShapeType;
import org.apache.poi.sl.usermodel.*;
import org.apache.poi.util.*; 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)
} }
} }


/**
* Returns the picture data for this picture.
*
* @return the picture data for this picture.
*/
@Override
public HSLFPictureData getPictureData(){ public HSLFPictureData getPictureData(){
HSLFSlideShow ppt = getSheet().getSlideShow(); HSLFSlideShow ppt = getSheet().getSlideShow();
HSLFPictureData[] pict = ppt.getPictureData(); HSLFPictureData[] pict = ppt.getPictureData();
} }


/** /**
* 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);

+ 6
- 23
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java 查看文件

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,
(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,
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).
* @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){
return opt.lookup(propId);
}
if (opt == null) return null;
return opt.lookup(propId);
}


/** /**
* Set an escher property for this shape. * Set an escher property for this 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) {


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 angle;
return Units.fixedPointToDouble(rot);
} }
public void setRotation(double theta){ public void setRotation(double theta){

+ 1
- 1
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java 查看文件

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

+ 7
- 2
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java 查看文件



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;
return _background; return _background;
} }


public void draw(Graphics2D graphics){

@Override
public void draw(Graphics2D graphics) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
Drawable draw = drawFact.getDrawable(this);
draw.draw(graphics);
} }


/** /**

+ 88
- 71
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java 查看文件

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;
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() {
} }


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();
} }
}; };
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
* *
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();
return geom; return geom;
} }


public Shadow getShadow() {
// TODO Auto-generated method stub
return null;
}


public double getShadowAngle() {
EscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX);
int offX = (prop == null) ? 0 : prop.getPropertyValue();
prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY);
int offY = (prop == null) ? 0 : prop.getPropertyValue();
return Math.toDegrees(Math.atan2(offY, offX));
}
public double getShadowDistance() {
EscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX);
int offX = (prop == null) ? 0 : prop.getPropertyValue();
prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY);
int offY = (prop == null) ? 0 : prop.getPropertyValue();
return Units.toPoints((long)Math.hypot(offX, offY));
}

/**
* @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
*/
public Color getShadowColor(){
Color clr = getColor(EscherProperties.SHADOWSTYLE__COLOR, EscherProperties.SHADOWSTYLE__OPACITY, -1);
return clr == null ? Color.black : clr;
}
public Shadow getShadow() {
EscherOptRecord opt = getEscherOptRecord();
EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE);
if (shadowType == null) return null;
return new Shadow(){
public SimpleShape getShadowParent() {
return HSLFSimpleShape.this;
}

public double getDistance() {
return getShadowDistance();
}

public double getAngle() {
return getShadowAngle();
}

public double getBlur() {
// TODO Auto-generated method stub
return 0;
}

public SolidPaint getFillStyle() {
return DrawPaint.createSolidPaint(getShadowColor());
}
};
}

public LineDecoration getLineDecoration() {
return new LineDecoration() {

public DecorationShape getHeadShape() {
return DecorationShape.NONE;
}

public DecorationSize getHeadWidth() {
return DecorationSize.MEDIUM;
}

public DecorationSize getHeadLength() {
return DecorationSize.MEDIUM;
}

public DecorationShape getTailShape() {
return DecorationShape.NONE;
}

public DecorationSize getTailWidth() {
return DecorationSize.MEDIUM;
}

public DecorationSize getTailLength() {
return DecorationSize.MEDIUM;
}
};
}
} }

+ 3
- 1
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java 查看文件

} }


// 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) {

+ 8
- 5
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java 查看文件

* @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
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> p : _runs) {
for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
if (!_paragraphs.contains(l)) _paragraphs.add(l);
}

for (List<HSLFTextParagraph> p : _paragraphs) {
for (HSLFTextParagraph htp : p) { for (HSLFTextParagraph htp : p) {
htp.supplySheet(this); htp.supplySheet(this);
} }
* 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;
} }


/** /**


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(){

src/scratchpad/src/org/apache/poi/hslf/model/Table.java → src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java 查看文件

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;
* *
* @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;
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
* @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);
Rectangle anchor = new Rectangle(x, y, TableCell.DEFAULT_WIDTH, TableCell.DEFAULT_HEIGHT);
cells[i][j] = new HSLFTableCell(this);
Rectangle anchor = new Rectangle(x, y, HSLFTableCell.DEFAULT_WIDTH, HSLFTableCell.DEFAULT_HEIGHT);
cells[i][j].setAnchor(anchor); 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;
* @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);
} }


* @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];
} }


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

src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java → src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java 查看文件

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.usermodel.HSLFTextBox;
import org.apache.poi.hslf.model.Line;
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;


* *
* @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;


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


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


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


} }


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


} }


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


} }


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(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight);
if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom);
if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft);
if(borderTop != null) anchorBorder(HSLFTable.BORDER_TOP, borderTop);
if(borderRight != null) anchorBorder(HSLFTable.BORDER_RIGHT, borderRight);
if(borderBottom != null) anchorBorder(HSLFTable.BORDER_BOTTOM, borderBottom);
if(borderLeft != null) anchorBorder(HSLFTable.BORDER_LEFT, borderLeft);
} }
} }

+ 164
- 112
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java 查看文件

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;
private final TextHeaderAtom _headerAtom; private final TextHeaderAtom _headerAtom;
private TextBytesAtom _byteAtom; private TextBytesAtom _byteAtom;
private TextCharsAtom _charAtom; private TextCharsAtom _charAtom;
private StyleTextPropAtom _styleAtom;
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
private final TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
protected TextRulerAtom _ruler; protected TextRulerAtom _ruler;
protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>(); protected List<HSLFTextRun> _runs = new ArrayList<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;
* @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,
StyleTextPropAtom sta
TextCharsAtom tca
) { ) {
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;
_styleAtom = other._styleAtom;
_byteAtom = other._byteAtom;
_charAtom = other._charAtom;
_paragraphStyle = other._paragraphStyle;
_parentShape = other._parentShape;
_sheet = other._sheet;
_ruler = other._ruler; // ????
shapeId = other.shapeId;
_records = other._records;
}
_headerAtom = other._headerAtom;
_byteAtom = other._byteAtom;
_charAtom = other._charAtom;
_parentShape = other._parentShape;
_sheet = other._sheet;
_ruler = other._ruler;
shapeId = other.shapeId;
_paragraphStyle.copy(other._paragraphStyle);
}
public void addTextRun(HSLFTextRun run) { public void addTextRun(HSLFTextRun run) {
_runs.add(run); _runs.add(run);
} }
public void setParagraphStyle(TextPropCollection paragraphStyle) { public void setParagraphStyle(TextPropCollection paragraphStyle) {
_paragraphStyle = paragraphStyle;
_paragraphStyle.copy(paragraphStyle);
} }
/** /**
_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 */
public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) { public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {
this.styleTextProp9Atom = styleTextProp9Atom; this.styleTextProp9Atom = styleTextProp9Atom;
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.
* Master Sheet will apply. * Master Sheet will apply.
*/ */
private int getParaTextPropVal(String propName) { private int getParaTextPropVal(String propName) {
TextProp prop = null;
boolean hardAttribute = false;
if (_paragraphStyle != null){
prop = _paragraphStyle.findByName(propName);
BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
hardAttribute = maskProp != null && maskProp.getValue() == 0;
}
TextProp prop = _paragraphStyle.findByName(propName);
BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
if (prop == null && !hardAttribute){ if (prop == null && !hardAttribute){
HSLFSheet sheet = getSheet(); HSLFSheet sheet = getSheet();
int txtype = getRunType(); int txtype = getRunType();
*/ */
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);
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) {
_paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
}
assert(_paragraphStyle!=null);
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME); BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);
prop.setSubValue(value,index); prop.setSubValue(value,index);
} }
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;
} }
* 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);
}
}
} }
/** /**
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());
/** /**
* 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
* *
* @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());
for (List<HSLFTextParagraph> htpList : rv) {
for (HSLFTextParagraph htp : htpList) {
List<HSLFTextParagraph> rv = null;
OutlineTextRefAtom ota = (OutlineTextRefAtom)wrapper.findFirstOfType(OutlineTextRefAtom.typeID);
if (ota != null) {
// if we are based on an outline, there are no further records to be parsed from the wrapper
if (sheet == null) {
throw new RuntimeException("Outline atom reference can't be solved without a sheet record");
}
List<List<HSLFTextParagraph>> sheetRuns = sheet.getTextParagraphs();
assert(sheetRuns != null);
int idx = ota.getTextIndex();
for (List<HSLFTextParagraph> r : sheetRuns) {
if (r.isEmpty()) continue;
int ridx = r.get(0).getIndex();
if (ridx > idx) break;
if (ridx == idx) {
if (rv == null) {
rv = r;
} else {
// create a new container
// TODO: ... is this case really happening?
rv = new ArrayList<HSLFTextParagraph>(rv);
rv.addAll(r);
}
}
}
if(rv == null || rv.isEmpty()) {
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
}
} else {
if (sheet != null) {
// check sheet runs first, so we get exactly the same paragraph list
List<List<HSLFTextParagraph>> sheetRuns = sheet.getTextParagraphs();
assert(sheetRuns != null);
for (List<HSLFTextParagraph> paras : sheetRuns) {
if (!paras.isEmpty() && paras.get(0)._headerAtom.getParentRecord() == wrapper) {
rv = paras;
break;
}
}
}
if (rv == null) {
// if we haven't found the wrapper in the sheet runs, create a new paragraph list from its record
List<List<HSLFTextParagraph>> rvl = findTextParagraphs(wrapper.getChildRecords());
switch (rvl.size()) {
case 0: break; // nothing found
case 1: rv = rvl.get(0); break; // normal case
default:
throw new RuntimeException("TextBox contains more than one list of paragraphs.");
}
}
}
if (rv != null) {
StyleTextProp9Atom styleTextProp9Atom = wrapper.getStyleTextProp9Atom();
for (HSLFTextParagraph htp : rv) {
htp.setShapeId(shapeId); htp.setShapeId(shapeId);
htp.setStyleTextProp9Atom(styleTextProp9Atom);
} }
} }
return rv; return rv;
* 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) {
throw new NullPointerException("records need to be filled.");
}
int recordIdx;
for (recordIdx = 0; recordIdx < records.length; recordIdx++) {
if (records[recordIdx] instanceof TextHeaderAtom) break;
}
if (recordIdx == records.length) {
logger.log(POILogger.INFO, "No text records found.");
return paragraphCollection;
}
for (int slwtIndex = 0; recordIdx < records.length; slwtIndex++) {
List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
paragraphCollection.add(paragraphs);
TextHeaderAtom header = (TextHeaderAtom)records[recordIdx++];
int[] recordIdx = {0};
for (int slwtIndex = 0; recordIdx[0] < records.length; slwtIndex++) {
TextHeaderAtom header = null;
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 (; recordIdx < records.length; recordIdx++) {
Record r = records[recordIdx];
for (Record r : getRecords(records, recordIdx, null)) {
long rt = r.getRecordType(); long rt = r.getRecordType();
if (RecordTypes.TextHeaderAtom.typeID == rt) break;
else if (RecordTypes.TextBytesAtom.typeID == rt) tbytes = (TextBytesAtom)r;
else if (RecordTypes.TextCharsAtom.typeID == rt) tchars = (TextCharsAtom)r;
// don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below
else if (RecordTypes.TextRulerAtom.typeID == rt) ruler = (TextRulerAtom)r;
else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
if (RecordTypes.TextHeaderAtom.typeID == rt) {
header = (TextHeaderAtom)r;
} else if (RecordTypes.TextBytesAtom.typeID == rt) {
tbytes = (TextBytesAtom)r;
} else if (RecordTypes.TextCharsAtom.typeID == rt) {
tchars = (TextCharsAtom)r;
} else if (RecordTypes.TextRulerAtom.typeID == rt) {
ruler = (TextRulerAtom)r;
} else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
indents = (MasterTextPropAtom)r; 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);
} }
} }
if (paragraphCollection.isEmpty()) {
logger.log(POILogger.DEBUG, "No text records found.");
}
return paragraphCollection; return paragraphCollection;
} }
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);

+ 1
- 1
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java 查看文件

* 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 -------

+ 73
- 59
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java 查看文件

} }


protected EscherTextboxWrapper getEscherTextboxWrapper(){ protected EscherTextboxWrapper getEscherTextboxWrapper(){
if(_txtbox == null){
EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
if(_txtbox != null) return _txtbox;
EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
if (textRecord == null) return null;
HSLFSheet sheet = getSheet();
if (sheet != null) {
PPDrawing drawing = sheet.getPPDrawing();
if (drawing != null) {
EscherTextboxWrapper wrappers[] = drawing.getTextboxWrappers();
if (wrappers != null) {
for (EscherTextboxWrapper w : wrappers) {
// check for object identity
if (textRecord == w.getEscherRecord()) {
_txtbox = w;
return _txtbox;
}
}
}
}
} }
_txtbox = new EscherTextboxWrapper(textRecord);
return _txtbox; return _txtbox;
} }


_paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph()); _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
_txtbox = _paragraphs.get(0).getTextboxWrapper(); _txtbox = _paragraphs.get(0).getTextboxWrapper();
} else { } else {
initParagraphsFromSheetRecords();
if (_paragraphs.isEmpty()) {
List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
if (!llhtp.isEmpty()) {
_paragraphs.addAll(llhtp.get(0));
}
_paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
if (_paragraphs == null || _paragraphs.isEmpty()) {
throw new RuntimeException("TextRecord didn't contained any text lines");
} }
// initParagraphsFromSheetRecords();
// if (_paragraphs.isEmpty()) {
// List<List<HSLFTextParagraph>> llhtp = HSLFTextParagraph.findTextParagraphs(_txtbox);
// if (!llhtp.isEmpty()) {
// _paragraphs.addAll(llhtp.get(0));
// }
// }
} }


for (HSLFTextParagraph p : _paragraphs) { for (HSLFTextParagraph p : _paragraphs) {
} }
} }


protected void initParagraphsFromSheetRecords(){
EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
HSLFSheet sheet = getSheet();

if(sheet == null || txtbox == null) return;

OutlineTextRefAtom ota = null;

Record[] child = txtbox.getChildRecords();
for (int i = 0; i < child.length; i++) {
if (child[i] instanceof OutlineTextRefAtom) {
ota = (OutlineTextRefAtom)child[i];
break;
}
}

List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
_paragraphs.clear();
if (sheetRuns != null) {
if (ota != null) {
int idx = ota.getTextIndex();
for (List<HSLFTextParagraph> r : sheetRuns) {
if (r.isEmpty()) continue;
int ridx = r.get(0).getIndex();
if (ridx > idx) break;
if (ridx == idx) _paragraphs.addAll(r);
}
if(_paragraphs.isEmpty()) {
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
}
} else {
int shapeId = getShapeId();
for (List<HSLFTextParagraph> r : sheetRuns) {
if (r.isEmpty()) continue;
if (r.get(0).getShapeId() == shapeId) _paragraphs.addAll(r);
}
}
}

// ensure the same references child records of TextRun
// TODO: check the purpose of this ...
// if(_txtrun != null) {
// for (int i = 0; i < child.length; i++) {
// for (Record r : _txtrun.getRecords()) {
// if (child[i].getRecordType() == r.getRecordType()) {
// child[i] = r;
// }
// }
// protected void initParagraphsFromSheetRecords(){
// EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
// HSLFSheet sheet = getSheet();
//
// if (sheet == null || txtbox == null) return;
// List<List<HSLFTextParagraph>> sheetRuns = _sheet.getTextParagraphs();
// if (sheetRuns == null) return;
//
// _paragraphs.clear();
// OutlineTextRefAtom ota = (OutlineTextRefAtom)txtbox.findFirstOfType(OutlineTextRefAtom.typeID);
//
// if (ota != null) {
// int idx = ota.getTextIndex();
// for (List<HSLFTextParagraph> r : sheetRuns) {
// if (r.isEmpty()) continue;
// int ridx = r.get(0).getIndex();
// if (ridx > idx) break;
// if (ridx == idx) _paragraphs.addAll(r);
// }
// if(_paragraphs.isEmpty()) {
// logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
// }
// } else {
// int shapeId = getShapeId();
// for (List<HSLFTextParagraph> r : sheetRuns) {
// if (r.isEmpty()) continue;
// if (r.get(0).getShapeId() == shapeId) _paragraphs.addAll(r);
// } // }
// } // }
}
//
// // ensure the same references child records of TextRun - see #48916
//// if(_txtrun != null) {
//// for (int i = 0; i < child.length; i++) {
//// for (Record r : _txtrun.getRecords()) {
//// if (child[i].getRecordType() == r.getRecordType()) {
//// child[i] = r;
//// }
//// }
//// }
//// }
// }


/* /*
// 0xB acts like cariage return in page titles and like blank in the others // 0xB acts like cariage return in page titles and like blank in the others
* 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



+ 5
- 3
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java 查看文件

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


/** /**

+ 4
- 4
src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java 查看文件

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) {
return getDrawable((ShapeGroup<? extends Shape>)shape);
} else if (shape instanceof GroupShape) {
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) {
return new DrawTextShape<T>(shape); return new DrawTextShape<T>(shape);
} }
public <T extends ShapeGroup<? extends Shape>> DrawShapeGroup<T> getDrawable(T shape) {
return new DrawShapeGroup<T>(shape);
public <T extends GroupShape<? extends Shape>> DrawGroupShape<T> getDrawable(T shape) {
return new DrawGroupShape<T>(shape);
} }
public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) { public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) {

src/scratchpad/src/org/apache/poi/sl/draw/DrawShapeGroup.java → src/scratchpad/src/org/apache/poi/sl/draw/DrawGroupShape.java 查看文件

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

+ 36
- 19
src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java 查看文件

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) {
anchor = tx.createTransformedShape(anchor).getBounds2D();
}
final Rectangle2D anchor = (tx != null)
? tx.createTransformedShape(ps.getAnchor()).getBounds2D()
: ps.getAnchor();
// rotation // rotation
double rotation = ps.getRotation(); double rotation = ps.getRotation();
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;
// 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);
txs.translate(centerX, centerY);
txs.rotate(Math.toRadians(-quadrant*90));
txs.translate(-centerX, -centerY);
txg.concatenate(txs);
Rectangle2D anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
boolean oldVariant = true;
Rectangle2D anchor2;
if (oldVariant) {
// shape coordinate space
AffineTransform txs = new AffineTransform(tx);
txs.translate(centerX, centerY);
txs.rotate(Math.toRadians(90));
txs.translate(-centerX, -centerY);
txg.concatenate(txs);
anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
} else {
anchor2 = txg.createTransformedShape(anchor).getBounds2D();
}
scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth(); scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();
scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight(); scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();
graphics.translate(centerX, centerY);
graphics.rotate(Math.toRadians(rotation-quadrant*90.));
graphics.scale(scaleX, scaleY);
graphics.rotate(Math.toRadians(quadrant*90));
graphics.translate(-centerX, -centerY);
} else {
graphics.translate(centerX, centerY);
graphics.rotate(Math.toRadians(rotation));
graphics.scale(scaleX, scaleY);
graphics.translate(-centerX, -centerY);
} }
// transformation is applied reversed ... // transformation is applied reversed ...
graphics.translate(centerX, centerY);
graphics.rotate(Math.toRadians(rotation-quadrant*90.));
graphics.scale(scaleX, scaleY);
graphics.rotate(Math.toRadians(quadrant*90));
graphics.translate(-centerX, -centerY);
} }
//flip horizontal //flip horizontal

+ 17
- 0
src/scratchpad/src/org/apache/poi/sl/draw/Drawable.java 查看文件

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();
}
}
} }
/** /**

+ 20
- 1
src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java 查看文件

/** /**
* 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);
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();

src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeGroup.java → src/scratchpad/src/org/apache/poi/sl/usermodel/GroupShape.java 查看文件



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

+ 9
- 1
src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java 查看文件

import java.awt.Insets; import java.awt.Insets;


public interface PictureShape extends SimpleShape { public interface PictureShape extends SimpleShape {
PictureData getPictureData();
/**
* Returns the picture data for this picture.
*
* @return the picture data for this picture.
*/
PictureData getPictureData();


/** /**
* Returns the clipping values as percent ratio relatively to the image size.
* The clipping are returned as insets converted/scaled to 100000 (=100%).
*
* @return the clipping rectangle, which is given in percent in relation to the image width/height * @return the clipping rectangle, which is given in percent in relation to the image width/height
*/ */
Insets getClipping(); Insets getClipping();

+ 9
- 0
src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java 查看文件



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

+ 0
- 1
src/scratchpad/testcases/org/apache/poi/hslf/model/AllHSLFModelTests.java 查看文件

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,

+ 0
- 55
src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java 查看文件

/* ====================================================================
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);
}
}

+ 10
- 10
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java 查看文件



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);
Table tbl2 = (Table)slide.getShapes().get(0);
assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
HSLFTable tbl2 = (HSLFTable)slide.getShapes().get(0);
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns()); assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows()); assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());




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);
Table tbl3 = (Table)slide.getShapes().get(0);
assertTrue(slide.getShapes().get(0) instanceof HSLFTable);
HSLFTable tbl3 = (HSLFTable)slide.getShapes().get(0);
assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns()); assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows()); assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
} }
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);
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());
@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){



+ 1
- 1
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java 查看文件

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());

+ 12
- 16
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java 查看文件

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.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.awt.Color;
import java.awt.Rectangle;
import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
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.record.Record;
import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.Units;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.*;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;


/** /**
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

+ 10
- 17
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java 查看文件

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.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.*;
import java.awt.geom.AffineTransform; import java.awt.geom.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.HashMap;
import java.util.Map;
import java.util.*;
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;
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
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;
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(TextPainter.KEY_FONTMAP, fontMap);
graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_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);
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);
} }
} }

+ 8
- 4
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList3.java 查看文件

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();
assertEquals(1, textProps.size());
final TextPropCollection textProp = textProps.get(0);
assertEquals(67, textProp.getCharactersCovered());
int chCovered = 0;
for (HSLFTextParagraph htp : textParass.get(1)) {
for (HSLFTextRun htr : htp.getTextRuns()) {
TextPropCollection textProp = htr.getCharacterStyle();
chCovered += textProp.getCharactersCovered();
}
}
assertEquals(67, chCovered);
assertTrue(textParass.get(0).get(0).isBullet()); assertTrue(textParass.get(0).get(0).isBullet());

+ 32
- 38
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java 查看文件



package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import static org.junit.Assert.*;

import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;




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;


} }


@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");
// XMLSlideShow xss = new XMLSlideShow(xis);
// xis.close();
//
// Dimension xpg = xss.getPageSize();
// for(XSLFSlide slide : xss.getSlides()) {
// BufferedImage img = new BufferedImage(xpg.width, xpg.height, BufferedImage.TYPE_INT_RGB);
// Graphics2D graphics = img.createGraphics();
// fixFonts(graphics);
// slide.draw(graphics);
// ImageIO.write(img, "PNG", new File("testx.png"));
// }
//
// System.out.println("########################");
InputStream is = _slTests.openResourceAsStream("54541_cropped_bitmap.ppt");
HSLFSlideShow ss = new HSLFSlideShow(is);
String file = new String[]{
"54542_cropped_bitmap.pptx",
"54541_cropped_bitmap.ppt",
"54541_cropped_bitmap2.ppt",
"sample_pptx_grouping_issues.pptx"
}[3];
InputStream is = _slTests.openResourceAsStream(file);
SlideShow ss = file.endsWith("pptx") ? new XMLSlideShow(is) : new HSLFSlideShow(is);
is.close(); is.close();
boolean debugOut = false;
Dimension pg = ss.getPageSize(); Dimension pg = ss.getPageSize();
int i=1; int i=1;
for(HSLFSlide slide : ss.getSlides()) {
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
fixFonts(graphics);
slide.draw(graphics);
ImageIO.write(img, "PNG", new File("test"+(i++)+".png"));
for(Slide<?,?,?> slide : ss.getSlides()) {
if (debugOut) {
DummyGraphics2d graphics = new DummyGraphics2d();
slide.draw(graphics);
} else {
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
fixFonts(graphics);
slide.draw(graphics);
ImageIO.write(img, "PNG", new File("test"+(i++)+"hslf.png"));
}
} }
} }
@SuppressWarnings("unchecked") @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);
} }
} }

+ 37
- 42
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java 查看文件

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.EMF;
import org.apache.poi.hslf.blip.JPEG;
import org.apache.poi.hslf.blip.PICT;
import org.apache.poi.hslf.blip.PNG;
import org.apache.poi.hslf.blip.WMF;
import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.blip.*;


/** /**
* Test adding/reading pictures * Test adding/reading pictures
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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();
assertEquals(1, sh.length);
pict = (HSLFPictureShape)sh[0];
List<HSLFShape> sh = ppt.getSlides().get(0).getShapes();
assertEquals(1, sh.size());
pict = (HSLFPictureShape)sh.get(0);
assertEquals(idx, pict.getPictureIndex()); assertEquals(idx, pict.getPictureIndex());


//check picture data //check picture data
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());
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());
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());
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());
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());


// 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());


// 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());


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




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

+ 22
- 21
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java 查看文件



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;




/** /**
* *
* @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 {
}

public void testTable() throws Exception {
@Test
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();
assertEquals(1, slides.length);
checkSlide(slides[0]);
List<HSLFSlide> slides = ppt.getSlides();
assertEquals(1, slides.size());
checkSlide(slides.get(0));
} }
private void checkSlide(final HSLFSlide s) { private void checkSlide(final HSLFSlide s) {
HSLFTextParagraph[] textRuns = s.getTextParagraphs();
assertEquals(2, textRuns.length);
List<List<HSLFTextParagraph>> textRuns = s.getTextParagraphs();
assertEquals(2, textRuns.size());


HSLFTextRun textRun = textRuns[0].getTextRuns()[0];
HSLFTextRun textRun = textRuns.get(0).get(0).getTextRuns().get(0);
assertEquals("Table sample", textRun.getRawText().trim()); assertEquals("Table sample", textRun.getRawText().trim());
assertEquals(1, textRuns[0].getTextRuns().length);
assertFalse(textRun.isBullet());
assertEquals(1, textRuns.get(0).get(0).getTextRuns().size());
assertFalse(textRun.getTextParagraph().isBullet());


assertEquals("Dummy text", textRuns[1].getRawText());
assertEquals("Dummy text", HSLFTextParagraph.getRawText(textRuns.get(1)));
final HSLFShape[] shapes = s.getShapes();
List<HSLFShape> shapes = s.getShapes();
assertNotNull(shapes); assertNotNull(shapes);
assertEquals(3, shapes.length);
assertTrue(shapes[2] instanceof Table);
final Table table = (Table) shapes[2];
assertEquals(3, shapes.size());
assertTrue(shapes.get(2) instanceof HSLFTable);
final HSLFTable table = (HSLFTable) shapes.get(2);
assertEquals(4, table.getNumberOfColumns()); assertEquals(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());
} }

+ 157
- 157
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java 查看文件



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;


// 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());
} }


/** /**
else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r; else if (r instanceof TextBytesAtom) tba = (TextBytesAtom)r;
else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r; else if (r instanceof TextCharsAtom) tca = (TextCharsAtom)r;
} }


// Bytes -> Bytes // Bytes -> Bytes
assertNull(tca); assertNull(tca);
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());

// assertNull(rtrA._getRawCharacterStyle());
// assertNull(rtrA._getRawParagraphStyle());
// assertNull(rtrB._getRawCharacterStyle());
// assertNull(rtrB._getRawParagraphStyle());
assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
} }


/** /**
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 tpBC = rtrB._getRawCharacterStyle();
// TextPropCollection tpCP = rtrC._getRawParagraphStyle();
// TextPropCollection tpCC = rtrC._getRawCharacterStyle();
// TextPropCollection tpDP = rtrD._getRawParagraphStyle();
// TextPropCollection tpDC = rtrD._getRawCharacterStyle();
TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
TextPropCollection tpBC = rtrB.getCharacterStyle();
TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
TextPropCollection tpCC = rtrC.getCharacterStyle();
TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
TextPropCollection tpDC = rtrD.getCharacterStyle();


// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText()); // assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
// assertNotNull(tpBP);
// assertNotNull(tpBC);
// assertNotNull(tpCP);
// assertNotNull(tpCC);
// assertNotNull(tpDP);
// assertNotNull(tpDC);
// assertTrue(tpBP.equals(tpCP));
// assertTrue(tpBP.equals(tpDP));
// assertTrue(tpCP.equals(tpDP));
// assertFalse(tpBC.equals(tpCC));
// assertFalse(tpBC.equals(tpDC));
// assertFalse(tpCC.equals(tpDC));
assertNotNull(tpBP);
assertNotNull(tpBC);
assertNotNull(tpCP);
assertNotNull(tpCC);
assertNotNull(tpDP);
assertNotNull(tpDC);
assertEquals(tpBP,tpCP);
assertEquals(tpBP,tpDP);
assertEquals(tpCP,tpDP);
assertNotEquals(tpBC,tpCC);
assertNotEquals(tpBC,tpDC);
assertNotEquals(tpCC,tpDC);


// Change text via normal // 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);
// rtrB = trB.getTextRuns().get(0);
// assertEquals("Test Foo Test", trB.getRawText());
// assertEquals("Test Foo Test", rtrB.getRawText());
// assertNotNull(rtrB._getRawCharacterStyle());
// assertNotNull(rtrB._getRawParagraphStyle());
// assertEquals( tpBP, rtrB._getRawParagraphStyle() );
// assertEquals( tpBC, rtrB._getRawCharacterStyle() );
assertEquals(1, trB.get(0).getTextRuns().size());
rtrB = trB.get(0).getTextRuns().get(0);
assertEquals("Test Foo Test", HSLFTextParagraph.getRawText(trB));
assertEquals("Test Foo Test", rtrB.getRawText());
assertNotNull(rtrB.getCharacterStyle());
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
assertEquals( tpBP, rtrB.getTextParagraph().getParagraphStyle() );
assertEquals( tpBC, rtrB.getCharacterStyle() );
} }


/** /**
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);
//
// HSLFTextRun rtrB = trB.getTextRuns().get(0);
// assertEquals(trB.getRawText(), rtrB.getRawText());
// assertNull(rtrB._getRawCharacterStyle());
// assertNull(rtrB._getRawParagraphStyle());
assertEquals(1, trB.get(0).getTextRuns().size());
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0);
assertEquals(HSLFTextParagraph.getRawText(trB.subList(0, 1)), rtrB.getRawText());
assertNotNull(rtrB.getCharacterStyle());
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());


// Change text via rich // Change text via rich
// rtrB.setText("Test Test Test");
// assertEquals("Test Test Test", trB.getRawText());
// assertEquals("Test Test Test", rtrB.getRawText());
rtrB.setText("Test Test Test");
assertEquals("Test Test Test", HSLFTextParagraph.getRawText(trB.subList(0, 1)));
assertEquals("Test Test Test", rtrB.getRawText());


// Will now have dummy props // Will now have dummy props
// assertNotNull(rtrB._getRawCharacterStyle());
// assertNotNull(rtrB._getRawParagraphStyle());
assertNotNull(rtrB.getCharacterStyle());
assertNotNull(rtrB.getTextParagraph().getParagraphStyle());
} }


/** /**
assertEquals(3, trB.size()); assertEquals(3, trB.size());


// We start with 3 text runs, each with their own set of styles, // We start with 3 text runs, each with their own set of styles,
// but all sharing the same paragraph styles
// but all sharing the same paragraph styles
HSLFTextRun rtrB = trB.get(0).getTextRuns().get(0); HSLFTextRun 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 tpBC = rtrB._getRawCharacterStyle();
// TextPropCollection tpCP = rtrC._getRawParagraphStyle();
// TextPropCollection tpCC = rtrC._getRawCharacterStyle();
// TextPropCollection tpDP = rtrD._getRawParagraphStyle();
// TextPropCollection tpDC = rtrD._getRawCharacterStyle();
TextPropCollection tpBP = rtrB.getTextParagraph().getParagraphStyle();
TextPropCollection tpBC = rtrB.getCharacterStyle();
TextPropCollection tpCP = rtrC.getTextParagraph().getParagraphStyle();
TextPropCollection tpCC = rtrC.getCharacterStyle();
TextPropCollection tpDP = rtrD.getTextParagraph().getParagraphStyle();
TextPropCollection tpDC = rtrD.getCharacterStyle();


// Check text and stylings // Check text and stylings
// assertEquals(trB.getRawText().substring(0, 30), rtrB.getRawText());
// assertNotNull(tpBP);
// assertNotNull(tpBC);
// assertNotNull(tpCP);
// assertNotNull(tpCC);
// assertNotNull(tpDP);
// assertNotNull(tpDC);
// assertTrue(tpBP.equals(tpCP));
// assertTrue(tpBP.equals(tpDP));
// assertTrue(tpCP.equals(tpDP));
// assertFalse(tpBC.equals(tpCC));
// assertFalse(tpBC.equals(tpDC));
// assertFalse(tpCC.equals(tpDC));
assertEquals(HSLFTextParagraph.getRawText(trB).substring(0, 30), rtrB.getRawText());
assertNotNull(tpBP);
assertNotNull(tpBC);
assertNotNull(tpCP);
assertNotNull(tpCC);
assertNotNull(tpDP);
assertNotNull(tpDC);
assertEquals(tpBP, tpCP);
assertEquals(tpBP, tpDP);
assertEquals(tpCP, tpDP);
assertNotEquals(tpBC, tpCC);
assertNotEquals(tpBC, tpDC);
assertNotEquals(tpCC, tpDC);


// Check text in the rich runs // 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());
rtrB.setText(newBText); rtrB.setText(newBText);
rtrC.setText(newCText); rtrC.setText(newCText);
rtrD.setText(newDText); rtrD.setText(newDText);
assertEquals(newBText, rtrB.getRawText());
assertEquals(newCText, rtrC.getRawText());
assertEquals(newDText, rtrD.getRawText());
HSLFTextParagraph.storeText(trB);


// assertEquals(newBText + newCText + newDText, trB.getRawText());
assertEquals(newBText.replace('\n','\r'), rtrB.getRawText());
assertEquals(newCText.replace('\n','\r'), rtrC.getRawText());
assertEquals(newDText.replace('\n','\r'), rtrD.getRawText());


// The styles should have been updated for the new sizes
// assertEquals(newBText.length(), tpBC.getCharactersCovered());
// assertEquals(newCText.length(), tpCC.getCharactersCovered());
// assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger
assertEquals(newBText.replace('\n','\r') + newCText.replace('\n','\r') + newDText.replace('\n','\r'), HSLFTextParagraph.getRawText(trB));


// assertEquals(
// newBText.length() + newCText.length() + newDText.length(),
// tpBP.getCharactersCovered()
// );
// The styles should have been updated for the new sizes
assertEquals(newBText.length(), tpBC.getCharactersCovered());
assertEquals(newCText.length(), tpCC.getCharactersCovered());
assertEquals(newDText.length()+1, tpDC.getCharactersCovered()); // Last one is always one larger


// Paragraph style should be sum of text length
// assertEquals(newBText.length() + newCText.length() + newDText.length(), tpBP.getCharactersCovered());
// Paragraph style should be sum of text length
assertEquals(
newBText.length() + newCText.length() + newDText.length() +1,
tpBP.getCharactersCovered() + tpCP.getCharactersCovered() + tpDP.getCharactersCovered()
);


// Check stylings still as expected // Check stylings still as expected
// TextPropCollection ntpBC = rtrB._getRawCharacterStyle();
// TextPropCollection ntpCC = rtrC._getRawCharacterStyle();
// TextPropCollection ntpDC = rtrD._getRawCharacterStyle();
// assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
// assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
// assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
TextPropCollection ntpBC = rtrB.getCharacterStyle();
TextPropCollection ntpCC = rtrC.getCharacterStyle();
TextPropCollection ntpDC = rtrD.getCharacterStyle();
assertEquals(tpBC.getTextPropList(), ntpBC.getTextPropList());
assertEquals(tpCC.getTextPropList(), ntpCC.getTextPropList());
assertEquals(tpDC.getTextPropList(), ntpDC.getTextPropList());
} }




assertEquals(0, slide.getTextParagraphs().size()); assertEquals(0, slide.getTextParagraphs().size());


HSLFTextBox shape1 = new HSLFTextBox(); HSLFTextBox shape1 = new HSLFTextBox();
// HSLFTextParagraph run1 = shape1.getTextParagraphs();
// assertSame(run1, shape1.createTextRun());
// run1.setText("Text 1");
List<HSLFTextParagraph> run1 = shape1.getTextParagraphs();
shape1.setText("Text 1");
slide.addShape(shape1); 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();
// assertNotNull(runs);
// assertSame(run1, runs.get(0));
//
// HSLFTextBox shape2 = new HSLFTextBox();
// HSLFTextParagraph run2 = shape2.getTextParagraphs();
// assertSame(run2, shape2.createTextRun());
// run2.setText("Text 2");
// slide.addShape(shape2);
//
// runs = slide.getTextParagraphs();
// assertEquals(2, runs.length);
//
// assertSame(run1, runs.get(0));
// assertSame(run2, runs.get(1));
//
// //as getShapes()
// HSLFShape[] sh = slide.getShapes();
// assertEquals(2, sh.length);
// assertTrue(sh.get(0) instanceof HSLFTextBox);
// HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
// assertSame(run1, box1.getTextParagraphs());
// HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
// assertSame(run2, box2.getTextParagraphs());
//
// //test Table - a complex group of shapes containing text objects
// HSLFSlide slide2 = ppt.createSlide();
// assertNull(slide2.getTextParagraphs());
// Table table = new Table(2, 2);
// slide2.addShape(table);
// runs = slide2.getTextParagraphs();
// assertNotNull(runs);
// assertEquals(4, runs.length);
List<List<HSLFTextParagraph>> runs = slide.getTextParagraphs();
assertNotNull(runs);
assertSame(run1, runs.get(0));

HSLFTextBox shape2 = new HSLFTextBox();
List<HSLFTextParagraph> run2 = shape2.getTextParagraphs();
shape2.setText("Text 2");
slide.addShape(shape2);

runs = slide.getTextParagraphs();
assertEquals(2, runs.size());

assertSame(run1, runs.get(0));
assertSame(run2, runs.get(1));

// as getShapes()
List<HSLFShape> sh = slide.getShapes();
assertEquals(2, sh.size());
assertTrue(sh.get(0) instanceof HSLFTextBox);
HSLFTextBox box1 = (HSLFTextBox)sh.get(0);
assertSame(run1, box1.getTextParagraphs());
HSLFTextBox box2 = (HSLFTextBox)sh.get(1);
assertSame(run2, box2.getTextParagraphs());

// test Table - a complex group of shapes containing text objects
HSLFSlide slide2 = ppt.createSlide();
assertTrue(slide2.getTextParagraphs().isEmpty());
HSLFTable table = new HSLFTable(2, 2);
slide2.addShape(table);
runs = slide2.getTextParagraphs();
assertNotNull(runs);
assertEquals(4, runs.size());
} }


@Test @Test
public void test48916() throws IOException { public void test48916() throws IOException {
// HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
// for(HSLFSlide slide : ppt.getSlides()){
// for(HSLFShape sh : slide.getShapes()){
// if(sh instanceof HSLFTextShape){
// HSLFTextShape tx = (HSLFTextShape)sh;
// HSLFTextParagraph run = tx.getTextParagraphs();
// //verify that records cached in TextRun and EscherTextboxWrapper are the same
// Record[] runChildren = run.getRecords();
// Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
// assertEquals(runChildren.length, txboxChildren.length);
// for(int i=0; i < txboxChildren.length; i++){
// assertSame(txboxChildren.get(i), runChildren.get(i));
// }
// //caused NPE prior to fix of Bugzilla #48916
// run.getTextRuns().get(0).setBold(true);
// run.getTextRuns().get(0).setFontColor(Color.RED);
// }
// }
// }
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// ppt.write(out);
// ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
// for(HSLFSlide slide : ppt.getSlides()){
// for(HSLFShape sh : slide.getShapes()){
// if(sh instanceof HSLFTextShape){
// HSLFTextShape tx = (HSLFTextShape)sh;
// HSLFTextParagraph run = tx.getTextParagraphs();
// HSLFTextRun rt = run.getTextRuns().get(0);
// assertTrue(rt.isBold());
// assertEquals(rt.getFontColor(), Color.RED);
// }
// }
// }
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
List<HSLFSlide> slides = ppt.getSlides();
for(HSLFSlide slide : slides){
for(HSLFShape sh : slide.getShapes()){
if (!(sh instanceof HSLFTextShape)) continue;
HSLFTextShape tx = (HSLFTextShape)sh;
List<HSLFTextParagraph> paras = tx.getTextParagraphs();
//verify that records cached in TextRun and EscherTextboxWrapper are the same
Record[] runChildren = paras.get(0).getRecords();
Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords();
assertEquals(runChildren.length, txboxChildren.length);
for(int i=0; i < txboxChildren.length; i++){
assertSame(txboxChildren[i], runChildren[i]);
}
// caused NPE prior to fix of Bugzilla #48916
for (HSLFTextParagraph p : paras) {
for (HSLFTextRun rt : p.getTextRuns()) {
rt.setBold(true);
rt.setFontColor(Color.RED);
}
}
tx.storeText();
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ppt.write(out);
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
for(HSLFSlide slide : ppt.getSlides()){
for(HSLFShape sh : slide.getShapes()){
if(sh instanceof HSLFTextShape){
HSLFTextShape tx = (HSLFTextShape)sh;
List<HSLFTextParagraph> run = tx.getTextParagraphs();
HSLFTextRun rt = run.get(0).getTextRuns().get(0);
assertTrue(rt.isBold());
assertEquals(rt.getFontColor(), Color.RED);
}
}
}


} }



二進制
test-data/slideshow/54541_cropped_bitmap2.ppt 查看文件


二進制
test-data/slideshow/sample_pptx_grouping_issues.pptx 查看文件


Loading…
取消
儲存