initial support for embedded movies and controls.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690262 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1b99ca6b52
commit
e2b7f90cd7
@ -47,6 +47,7 @@
|
|||||||
<li><link href="#Graphics2D">Shapes and Graphics2D</link></li>
|
<li><link href="#Graphics2D">Shapes and Graphics2D</link></li>
|
||||||
<li><link href="#Render">How to convert slides into images</link></li>
|
<li><link href="#Render">How to convert slides into images</link></li>
|
||||||
<li><link href="#HeadersFooters">Headers / Footers</link></li>
|
<li><link href="#HeadersFooters">Headers / Footers</link></li>
|
||||||
|
<li><link href="#Movies">How to embed movies</link></li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section><title>Features</title>
|
<section><title>Features</title>
|
||||||
@ -662,6 +663,28 @@
|
|||||||
hdd.setFootersText("Created by POI-HSLF");
|
hdd.setFootersText("Created by POI-HSLF");
|
||||||
</source>
|
</source>
|
||||||
</section>
|
</section>
|
||||||
|
<anchor id="Movies"/>
|
||||||
|
<section><title>How to embed movies</title>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
SlideShow ppt = new SlideShow();
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
//UNC or local Returns UNC or local path to a video file
|
||||||
|
String moviePath = "card.mpg";
|
||||||
|
int movieIdx = ppt.addMovie(moviePath, MovieShape.MOVIE_MPEG);
|
||||||
|
|
||||||
|
String thumbnailPath = "card.png";
|
||||||
|
int thumbnailIdx = ppt.addPicture(new File(thumbnailPath), Picture.PNG);
|
||||||
|
MovieShape shape = new MovieShape(movieIdx, thumbnailIdx);
|
||||||
|
shape.setAnchor(new Rectangle2D.Float(300,225,120,90));
|
||||||
|
slide.addShape(shape);
|
||||||
|
|
||||||
|
FileOutputStream out = new FileOutputStream("hslf-movie.ppt");
|
||||||
|
ppt.write(out);
|
||||||
|
out.close();
|
||||||
|
</source>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package org.apache.poi.hslf.blip;
|
package org.apache.poi.hslf.blip;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.hslf.model.Picture;
|
import org.apache.poi.hslf.model.Picture;
|
||||||
import org.apache.poi.hslf.model.Shape;
|
import org.apache.poi.hslf.model.Shape;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
@ -76,7 +77,7 @@ public class WMF extends Metafile {
|
|||||||
Header header = new Header();
|
Header header = new Header();
|
||||||
header.wmfsize = data.length - aldus.getSize();
|
header.wmfsize = data.length - aldus.getSize();
|
||||||
header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top);
|
header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top);
|
||||||
//coefficiaent to translate from WMF dpi to 96pdi
|
//coefficient to translate from WMF dpi to 96pdi
|
||||||
int coeff = 96*Shape.EMU_PER_POINT/aldus.inch;
|
int coeff = 96*Shape.EMU_PER_POINT/aldus.inch;
|
||||||
header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff);
|
header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff);
|
||||||
header.zipsize = compressed.length;
|
header.zipsize = compressed.length;
|
||||||
@ -119,7 +120,7 @@ public class WMF extends Metafile {
|
|||||||
* <li>short Checksum; Checksum value for previous 10 shorts
|
* <li>short Checksum; Checksum value for previous 10 shorts
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public static class AldusHeader{
|
public class AldusHeader{
|
||||||
public static final int APMHEADER_KEY = 0x9AC6CDD7;
|
public static final int APMHEADER_KEY = 0x9AC6CDD7;
|
||||||
|
|
||||||
public int handle;
|
public int handle;
|
||||||
@ -143,8 +144,9 @@ public class WMF extends Metafile {
|
|||||||
reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
|
reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
|
||||||
|
|
||||||
checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE;
|
checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE;
|
||||||
if (checksum != getChecksum())
|
if (checksum != getChecksum()){
|
||||||
throw new HSLFException("WMF checksum does not match the header data");
|
logger.log(POILogger.WARN, "WMF checksum does not match the header data");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,7 +125,7 @@ public class PPTXMLDump {
|
|||||||
dump(data, pos, size, padding);
|
dump(data, pos, size, padding);
|
||||||
} else {
|
} else {
|
||||||
//dump first 100 bytes of the atom data
|
//dump first 100 bytes of the atom data
|
||||||
dump(out, data, pos, Math.min(size, 100), padding, true);
|
dump(out, data, pos, size, padding, true);
|
||||||
}
|
}
|
||||||
padding--;
|
padding--;
|
||||||
write(out, "</"+recname + ">" + CR, padding);
|
write(out, "</"+recname + ">" + CR, padding);
|
||||||
|
152
src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
Executable file
152
src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
Executable file
@ -0,0 +1,152 @@
|
|||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.hslf.record.*;
|
||||||
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an ActiveX control in a PowerPoint document.
|
||||||
|
*
|
||||||
|
* TODO: finish
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ActiveXShape extends Picture {
|
||||||
|
public static final int DEFAULT_ACTIVEX_THUMBNAIL = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new <code>Picture</code>
|
||||||
|
*
|
||||||
|
* @param pictureIdx the index of the picture
|
||||||
|
*/
|
||||||
|
public ActiveXShape(int movieIdx, int pictureIdx){
|
||||||
|
super(pictureIdx, null);
|
||||||
|
setActiveXIndex(movieIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <code>Picture</code> object
|
||||||
|
*
|
||||||
|
* @param escherRecord the <code>EscherSpContainer</code> record which holds information about
|
||||||
|
* this picture in the <code>Slide</code>
|
||||||
|
* @param parent the parent shape of this picture
|
||||||
|
*/
|
||||||
|
protected ActiveXShape(EscherContainerRecord escherRecord, Shape parent){
|
||||||
|
super(escherRecord, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Placeholder and initialize internal structures
|
||||||
|
*
|
||||||
|
* @return the created <code>EscherContainerRecord</code> which holds shape data
|
||||||
|
*/
|
||||||
|
protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
|
||||||
|
_escherContainer = super.createSpContainer(idx, isChild);
|
||||||
|
|
||||||
|
EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
|
spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE | EscherSpRecord.FLAG_OLESHAPE);
|
||||||
|
|
||||||
|
setShapeType(ShapeTypes.HostControl);
|
||||||
|
setEscherProperty(EscherProperties.BLIP__PICTUREID, idx);
|
||||||
|
setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001);
|
||||||
|
setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008);
|
||||||
|
setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
|
||||||
|
setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, -1);
|
||||||
|
|
||||||
|
EscherClientDataRecord cldata = new EscherClientDataRecord();
|
||||||
|
cldata.setOptions((short)0xF);
|
||||||
|
_escherContainer.getChildRecords().add(cldata);
|
||||||
|
|
||||||
|
OEShapeAtom oe = new OEShapeAtom();
|
||||||
|
|
||||||
|
//convert hslf into ddf
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
oe.writeOut(out);
|
||||||
|
} catch(Exception e){
|
||||||
|
throw new HSLFException(e);
|
||||||
|
}
|
||||||
|
cldata.setRemainingData(out.toByteArray());
|
||||||
|
|
||||||
|
return _escherContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a control to this shape
|
||||||
|
*
|
||||||
|
* @see {@link org.apache.poi.hslf.usermodel.SlideShow#addMovie(String, int)}
|
||||||
|
* @param idx the index of the movie
|
||||||
|
*/
|
||||||
|
public void setActiveXIndex(int idx){
|
||||||
|
EscherContainerRecord spContainer = getSpContainer();
|
||||||
|
for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
|
||||||
|
EscherRecord obj = (EscherRecord) it.next();
|
||||||
|
if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
|
||||||
|
EscherClientDataRecord clientRecord = (EscherClientDataRecord)obj;
|
||||||
|
byte[] recdata = clientRecord.getRemainingData();
|
||||||
|
LittleEndian.putInt(recdata, 8, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getControlIndex(){
|
||||||
|
int idx = -1;
|
||||||
|
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
|
||||||
|
if(oe != null) idx = oe.getOptions();
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a property of this ActiveX control
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public void setProperty(String key, String value){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Document-level container that specifies information about an ActiveX control
|
||||||
|
*
|
||||||
|
* @return container that specifies information about an ActiveX control
|
||||||
|
*/
|
||||||
|
public ExControl getExControl(){
|
||||||
|
int idx = getControlIndex();
|
||||||
|
ExControl ctrl = null;
|
||||||
|
Document doc = getSheet().getSlideShow().getDocumentRecord();
|
||||||
|
ExObjList lst = (ExObjList)doc.findFirstOfType(RecordTypes.ExObjList.typeID);
|
||||||
|
if(lst != null){
|
||||||
|
Record[] ch = lst.getChildRecords();
|
||||||
|
for (int i = 0; i < ch.length; i++) {
|
||||||
|
if(ch[i] instanceof ExControl){
|
||||||
|
ExControl c = (ExControl)ch[i];
|
||||||
|
if(c.getExOleObjAtom().getObjID() == idx){
|
||||||
|
ctrl = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void afterInsert(Sheet sheet){
|
||||||
|
ExControl ctrl = getExControl();
|
||||||
|
ctrl.getExControlAtom().setSlideId(sheet._getSheetNumber());
|
||||||
|
|
||||||
|
try {
|
||||||
|
String name = ctrl.getProgId() + "-" + getControlIndex();
|
||||||
|
byte[] data = (name + '\u0000').getBytes("UTF-16LE");
|
||||||
|
EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.GROUPSHAPE__SHAPENAME, false, data);
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
opt.addEscherProperty(prop);
|
||||||
|
} catch (UnsupportedEncodingException e){
|
||||||
|
throw new HSLFException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
159
src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
Executable file
159
src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
Executable file
@ -0,0 +1,159 @@
|
|||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.hslf.record.*;
|
||||||
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a movie in a PowerPoint document.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class MovieShape extends Picture {
|
||||||
|
public static final int DEFAULT_MOVIE_THUMBNAIL = -1;
|
||||||
|
|
||||||
|
public static final int MOVIE_MPEG = 1;
|
||||||
|
public static final int MOVIE_AVI = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new <code>Picture</code>
|
||||||
|
*
|
||||||
|
* @param pictureIdx the index of the picture
|
||||||
|
*/
|
||||||
|
public MovieShape(int movieIdx, int pictureIdx){
|
||||||
|
super(pictureIdx, null);
|
||||||
|
setMovieIndex(movieIdx);
|
||||||
|
setAutoPlay(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new <code>Picture</code>
|
||||||
|
*
|
||||||
|
* @param idx the index of the picture
|
||||||
|
* @param parent the parent shape
|
||||||
|
*/
|
||||||
|
public MovieShape(int movieIdx, int idx, Shape parent) {
|
||||||
|
super(idx, parent);
|
||||||
|
setMovieIndex(movieIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <code>Picture</code> object
|
||||||
|
*
|
||||||
|
* @param escherRecord the <code>EscherSpContainer</code> record which holds information about
|
||||||
|
* this picture in the <code>Slide</code>
|
||||||
|
* @param parent the parent shape of this picture
|
||||||
|
*/
|
||||||
|
protected MovieShape(EscherContainerRecord escherRecord, Shape parent){
|
||||||
|
super(escherRecord, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Placeholder and initialize internal structures
|
||||||
|
*
|
||||||
|
* @return the created <code>EscherContainerRecord</code> which holds shape data
|
||||||
|
*/
|
||||||
|
protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
|
||||||
|
_escherContainer = super.createSpContainer(idx, isChild);
|
||||||
|
|
||||||
|
setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100);
|
||||||
|
setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x10001);
|
||||||
|
|
||||||
|
EscherClientDataRecord cldata = new EscherClientDataRecord();
|
||||||
|
cldata.setOptions((short)0xF);
|
||||||
|
_escherContainer.getChildRecords().add(cldata);
|
||||||
|
|
||||||
|
OEShapeAtom oe = new OEShapeAtom();
|
||||||
|
InteractiveInfo info = new InteractiveInfo();
|
||||||
|
InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
|
||||||
|
infoAtom.setAction(InteractiveInfoAtom.ACTION_MEDIA);
|
||||||
|
infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_NULL);
|
||||||
|
|
||||||
|
AnimationInfo an = new AnimationInfo();
|
||||||
|
AnimationInfoAtom anAtom = an.getAnimationInfoAtom();
|
||||||
|
anAtom.setFlag(AnimationInfoAtom.Automatic, true);
|
||||||
|
|
||||||
|
//convert hslf into ddf
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
oe.writeOut(out);
|
||||||
|
an.writeOut(out);
|
||||||
|
info.writeOut(out);
|
||||||
|
} catch(Exception e){
|
||||||
|
throw new HSLFException(e);
|
||||||
|
}
|
||||||
|
cldata.setRemainingData(out.toByteArray());
|
||||||
|
|
||||||
|
return _escherContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a movie to this shape
|
||||||
|
*
|
||||||
|
* @see {@link org.apache.poi.hslf.usermodel.SlideShow#addMovie(String, int)}
|
||||||
|
* @param idx the index of the movie
|
||||||
|
*/
|
||||||
|
public void setMovieIndex(int idx){
|
||||||
|
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
|
||||||
|
oe.setOptions(idx);
|
||||||
|
|
||||||
|
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
|
||||||
|
if(an != null) {
|
||||||
|
AnimationInfoAtom ai = an.getAnimationInfoAtom();
|
||||||
|
ai.setDimColor(0x07000000);
|
||||||
|
ai.setFlag(AnimationInfoAtom.Automatic, true);
|
||||||
|
ai.setFlag(AnimationInfoAtom.Play, true);
|
||||||
|
ai.setFlag(AnimationInfoAtom.Synchronous, true);
|
||||||
|
ai.setOrderID(idx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoPlay(boolean flag){
|
||||||
|
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
|
||||||
|
if(an != null){
|
||||||
|
an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag);
|
||||||
|
updateClientData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoPlay(){
|
||||||
|
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
|
||||||
|
if(an != null){
|
||||||
|
return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns UNC or local path to a video file
|
||||||
|
*
|
||||||
|
* @return UNC or local path to a video file
|
||||||
|
*/
|
||||||
|
public String getPath(){
|
||||||
|
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
|
||||||
|
int idx = oe.getOptions();
|
||||||
|
|
||||||
|
SlideShow ppt = getSheet().getSlideShow();
|
||||||
|
ExObjList lst = (ExObjList)ppt.getDocumentRecord().findFirstOfType(RecordTypes.ExObjList.typeID);
|
||||||
|
if(lst == null) return null;
|
||||||
|
|
||||||
|
Record[] r = lst.getChildRecords();
|
||||||
|
for (int i = 0; i < r.length; i++) {
|
||||||
|
if(r[i] instanceof ExMCIMovie){
|
||||||
|
ExMCIMovie mci = (ExMCIMovie)r[i];
|
||||||
|
ExVideoContainer exVideo = mci.getExVideo();
|
||||||
|
int objectId = exVideo.getExMediaAtom().getObjectId();
|
||||||
|
if(objectId == idx){
|
||||||
|
return exVideo.getPathAtom().getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -19,8 +19,10 @@ package org.apache.poi.hslf.model;
|
|||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.hslf.record.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a <code>Shape</code> object depending on its type
|
* Create a <code>Shape</code> object depending on its type
|
||||||
@ -45,14 +47,14 @@ public class ShapeFactory {
|
|||||||
|
|
||||||
public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, Shape parent){
|
public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, Shape parent){
|
||||||
ShapeGroup group = null;
|
ShapeGroup group = null;
|
||||||
UnknownEscherRecord opt = (UnknownEscherRecord)Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
|
EscherRecord opt = Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
|
||||||
if(opt != null){
|
if(opt != null){
|
||||||
try {
|
try {
|
||||||
EscherPropertyFactory f = new EscherPropertyFactory();
|
EscherPropertyFactory f = new EscherPropertyFactory();
|
||||||
List props = f.createProperties( opt.getData(), 0, opt.getInstance() );
|
List 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 ShapeGroup(spContainer, parent);
|
group = new Table(spContainer, parent);
|
||||||
} else {
|
} else {
|
||||||
group = new ShapeGroup(spContainer, parent);
|
group = new ShapeGroup(spContainer, parent);
|
||||||
}
|
}
|
||||||
@ -68,7 +70,7 @@ public class ShapeFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Shape createSimpeShape(EscherContainerRecord spContainer, Shape parent){
|
public static Shape createSimpeShape(EscherContainerRecord spContainer, Shape parent){
|
||||||
Shape shape;
|
Shape shape = null;
|
||||||
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
|
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
|
|
||||||
int type = spRecord.getOptions() >> 4;
|
int type = spRecord.getOptions() >> 4;
|
||||||
@ -76,14 +78,26 @@ public class ShapeFactory {
|
|||||||
case ShapeTypes.TextBox:
|
case ShapeTypes.TextBox:
|
||||||
shape = new TextBox(spContainer, parent);
|
shape = new TextBox(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
case ShapeTypes.HostControl:
|
case ShapeTypes.HostControl:
|
||||||
case ShapeTypes.PictureFrame: {
|
case ShapeTypes.PictureFrame: {
|
||||||
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
|
InteractiveInfo info = (InteractiveInfo)getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
|
||||||
EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID);
|
OEShapeAtom oes = (OEShapeAtom)getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
|
||||||
if(prop != null)
|
if(info != null && info.getInteractiveInfoAtom() != null){
|
||||||
shape = new OLEShape(spContainer, parent); //presence of BLIP__PICTUREID indicates it is an embedded object
|
switch(info.getInteractiveInfoAtom().getAction()){
|
||||||
else
|
case InteractiveInfoAtom.ACTION_OLE:
|
||||||
shape = new Picture(spContainer, parent);
|
shape = new OLEShape(spContainer, parent);
|
||||||
|
break;
|
||||||
|
case InteractiveInfoAtom.ACTION_MEDIA:
|
||||||
|
shape = new MovieShape(spContainer, parent);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (oes != null){
|
||||||
|
shape = new OLEShape(spContainer, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shape == null) shape = new Picture(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShapeTypes.Line:
|
case ShapeTypes.Line:
|
||||||
@ -108,4 +122,22 @@ public class ShapeFactory {
|
|||||||
return shape;
|
return shape;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Record getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
|
||||||
|
Record oep = null;
|
||||||
|
for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
|
||||||
|
EscherRecord obj = (EscherRecord) it.next();
|
||||||
|
if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
|
||||||
|
byte[] data = obj.serialize();
|
||||||
|
Record[] records = Record.findChildRecords(data, 8, data.length - 8);
|
||||||
|
for (int j = 0; j < records.length; j++) {
|
||||||
|
if (records[j].getRecordType() == recordType) {
|
||||||
|
return records[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oep;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,13 @@ import org.apache.poi.ddf.*;
|
|||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.hslf.record.ColorSchemeAtom;
|
import org.apache.poi.hslf.record.ColorSchemeAtom;
|
||||||
import org.apache.poi.hslf.record.Record;
|
import org.apache.poi.hslf.record.Record;
|
||||||
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
|
|
||||||
import java.awt.*;
|
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.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract simple (non-group) shape.
|
* An abstract simple (non-group) shape.
|
||||||
@ -35,6 +37,12 @@ import java.util.Iterator;
|
|||||||
*/
|
*/
|
||||||
public class SimpleShape extends Shape {
|
public class SimpleShape extends Shape {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records stored in EscherClientDataRecord
|
||||||
|
*/
|
||||||
|
protected Record[] _clientRecords;
|
||||||
|
protected EscherClientDataRecord _clientData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a SimpleShape object and initialize it from the supplied Record container.
|
* Create a SimpleShape object and initialize it from the supplied Record container.
|
||||||
*
|
*
|
||||||
@ -293,21 +301,46 @@ public class SimpleShape extends Shape {
|
|||||||
* @param recordType type of the record to search
|
* @param recordType type of the record to search
|
||||||
*/
|
*/
|
||||||
protected Record getClientDataRecord(int recordType) {
|
protected Record getClientDataRecord(int recordType) {
|
||||||
Record oep = null;
|
|
||||||
EscherContainerRecord spContainer = getSpContainer();
|
Record[] records = getClientRecords();
|
||||||
for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
|
if(records != null) for (int i = 0; i < records.length; i++) {
|
||||||
EscherRecord obj = (EscherRecord) it.next();
|
if(records[i].getRecordType() == recordType){
|
||||||
if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
|
return records[i];
|
||||||
byte[] data = obj.serialize();
|
|
||||||
Record[] records = Record.findChildRecords(data, 8, data.length - 8);
|
|
||||||
for (int j = 0; j < records.length; j++) {
|
|
||||||
if (records[j].getRecordType() == recordType) {
|
|
||||||
return records[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return oep;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Record[] getClientRecords() {
|
||||||
|
if(_clientData == null){
|
||||||
|
EscherRecord r = Shape.getEscherChild(getSpContainer(), EscherClientDataRecord.RECORD_ID);
|
||||||
|
//ddf can return EscherContainerRecord with recordId=EscherClientDataRecord.RECORD_ID
|
||||||
|
//convert in to EscherClientDataRecord on the fly
|
||||||
|
if(!(r instanceof EscherClientDataRecord)){
|
||||||
|
byte[] data = r.serialize();
|
||||||
|
r = new EscherClientDataRecord();
|
||||||
|
r.fillFields(data, 0, new DefaultEscherRecordFactory());
|
||||||
|
}
|
||||||
|
_clientData = (EscherClientDataRecord)r;
|
||||||
|
}
|
||||||
|
if(_clientData != null && _clientRecords == null){
|
||||||
|
byte[] data = _clientData.getRemainingData();
|
||||||
|
_clientRecords = Record.findChildRecords(data, 0, data.length);
|
||||||
|
}
|
||||||
|
return _clientRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateClientData() {
|
||||||
|
if(_clientData != null && _clientRecords != null){
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < _clientRecords.length; i++) {
|
||||||
|
_clientRecords[i].writeOut(out);
|
||||||
|
}
|
||||||
|
} catch(Exception e){
|
||||||
|
throw new HSLFException(e);
|
||||||
|
}
|
||||||
|
_clientData.setRemainingData(out.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ public class Table extends ShapeGroup {
|
|||||||
* @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
|
||||||
*/
|
*/
|
||||||
protected Table(EscherContainerRecord escherRecord, Shape parent) {
|
public Table(EscherContainerRecord escherRecord, Shape parent) {
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,11 @@ import org.apache.poi.util.POILogFactory;
|
|||||||
|
|
||||||
import java.text.AttributedString;
|
import java.text.AttributedString;
|
||||||
import java.text.AttributedCharacterIterator;
|
import java.text.AttributedCharacterIterator;
|
||||||
|
import java.text.BreakIterator;
|
||||||
import java.awt.font.TextAttribute;
|
import java.awt.font.TextAttribute;
|
||||||
import java.awt.font.LineBreakMeasurer;
|
import java.awt.font.LineBreakMeasurer;
|
||||||
import java.awt.font.TextLayout;
|
import java.awt.font.TextLayout;
|
||||||
|
import java.awt.font.FontRenderContext;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
@ -89,11 +91,69 @@ public class TextPainter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void paint(Graphics2D graphics){
|
public void paint(Graphics2D graphics){
|
||||||
|
Rectangle2D anchor = _shape.getLogicalAnchor2D();
|
||||||
|
TextElement[] elem = getTextElements((float)anchor.getWidth(), graphics.getFontRenderContext());
|
||||||
|
if(elem == null) return;
|
||||||
|
|
||||||
|
float textHeight = 0;
|
||||||
|
for (int i = 0; i < elem.length; i++) {
|
||||||
|
textHeight += elem[i].ascent + elem[i].descent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int valign = _shape.getVerticalAlignment();
|
||||||
|
double y0 = anchor.getY();
|
||||||
|
switch (valign){
|
||||||
|
case TextShape.AnchorTopBaseline:
|
||||||
|
case TextShape.AnchorTop:
|
||||||
|
y0 += _shape.getMarginTop();
|
||||||
|
break;
|
||||||
|
case TextShape.AnchorBottom:
|
||||||
|
y0 += anchor.getHeight() - textHeight - _shape.getMarginBottom();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case TextShape.AnchorMiddle:
|
||||||
|
float delta = (float)anchor.getHeight() - textHeight - _shape.getMarginTop() - _shape.getMarginBottom();
|
||||||
|
y0 += _shape.getMarginTop() + delta/2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//finally draw the text fragments
|
||||||
|
for (int i = 0; i < elem.length; i++) {
|
||||||
|
y0 += elem[i].ascent;
|
||||||
|
|
||||||
|
Point2D.Double pen = new Point2D.Double();
|
||||||
|
pen.y = y0;
|
||||||
|
switch (elem[i]._align) {
|
||||||
|
default:
|
||||||
|
case TextShape.AlignLeft:
|
||||||
|
pen.x = anchor.getX() + _shape.getMarginLeft();
|
||||||
|
break;
|
||||||
|
case TextShape.AlignCenter:
|
||||||
|
pen.x = anchor.getX() + _shape.getMarginLeft() +
|
||||||
|
(anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
|
||||||
|
break;
|
||||||
|
case TextShape.AlignRight:
|
||||||
|
pen.x = anchor.getX() + _shape.getMarginLeft() +
|
||||||
|
(anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(elem[i]._bullet != null){
|
||||||
|
graphics.drawString(elem[i]._bullet.getIterator(), (float)(pen.x + elem[i]._bulletOffset), (float)pen.y);
|
||||||
|
}
|
||||||
|
AttributedCharacterIterator chIt = elem[i]._text.getIterator();
|
||||||
|
if(chIt.getEndIndex() > chIt.getBeginIndex()) {
|
||||||
|
graphics.drawString(chIt, (float)(pen.x + elem[i]._textOffset), (float)pen.y);
|
||||||
|
}
|
||||||
|
y0 += elem[i].descent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextElement[] getTextElements(float textWidth, FontRenderContext frc){
|
||||||
TextRun run = _shape.getTextRun();
|
TextRun run = _shape.getTextRun();
|
||||||
if (run == null) return;
|
if (run == null) return null;
|
||||||
|
|
||||||
String text = run.getText();
|
String text = run.getText();
|
||||||
if (text == null || text.equals("")) return;
|
if (text == null || text.equals("")) return null;
|
||||||
|
|
||||||
AttributedString at = getAttributedString(run);
|
AttributedString at = getAttributedString(run);
|
||||||
|
|
||||||
@ -101,11 +161,8 @@ public class TextPainter {
|
|||||||
int paragraphStart = it.getBeginIndex();
|
int paragraphStart = it.getBeginIndex();
|
||||||
int paragraphEnd = it.getEndIndex();
|
int paragraphEnd = it.getEndIndex();
|
||||||
|
|
||||||
Rectangle2D anchor = _shape.getLogicalAnchor2D();
|
|
||||||
|
|
||||||
float textHeight = 0;
|
|
||||||
ArrayList lines = new ArrayList();
|
ArrayList lines = new ArrayList();
|
||||||
LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext());
|
LineBreakMeasurer measurer = new LineBreakMeasurer(it, frc);
|
||||||
measurer.setPosition(paragraphStart);
|
measurer.setPosition(paragraphStart);
|
||||||
while (measurer.getPosition() < paragraphEnd) {
|
while (measurer.getPosition() < paragraphEnd) {
|
||||||
int startIndex = measurer.getPosition();
|
int startIndex = measurer.getPosition();
|
||||||
@ -120,7 +177,7 @@ public class TextPainter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float wrappingWidth = (float)anchor.getWidth() - _shape.getMarginLeft() - _shape.getMarginRight();
|
float wrappingWidth = textWidth - _shape.getMarginLeft() - _shape.getMarginRight();
|
||||||
int bulletOffset = rt.getBulletOffset();
|
int bulletOffset = rt.getBulletOffset();
|
||||||
int textOffset = rt.getTextOffset();
|
int textOffset = rt.getTextOffset();
|
||||||
int indent = rt.getIndentLevel();
|
int indent = rt.getIndentLevel();
|
||||||
@ -138,7 +195,7 @@ public class TextPainter {
|
|||||||
if(text_val != 0) textOffset = text_val;
|
if(text_val != 0) textOffset = text_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappingWidth -= textOffset;
|
if(bulletOffset > 0 || prStart || startIndex == 0) wrappingWidth -= textOffset;
|
||||||
|
|
||||||
if (_shape.getWordWrap() == TextShape.WrapNone) {
|
if (_shape.getWordWrap() == TextShape.WrapNone) {
|
||||||
wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
|
wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
|
||||||
@ -147,7 +204,7 @@ public class TextPainter {
|
|||||||
TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
|
TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
|
||||||
nextBreak == -1 ? paragraphEnd : nextBreak, true);
|
nextBreak == -1 ? paragraphEnd : nextBreak, true);
|
||||||
if (textLayout == null) {
|
if (textLayout == null) {
|
||||||
textLayout = measurer.nextLayout((float)anchor.getWidth(),
|
textLayout = measurer.nextLayout(textWidth,
|
||||||
nextBreak == -1 ? paragraphEnd : nextBreak, false);
|
nextBreak == -1 ? paragraphEnd : nextBreak, false);
|
||||||
}
|
}
|
||||||
if(textLayout == null){
|
if(textLayout == null){
|
||||||
@ -173,6 +230,8 @@ public class TextPainter {
|
|||||||
el.advance = textLayout.getAdvance();
|
el.advance = textLayout.getAdvance();
|
||||||
el._textOffset = textOffset;
|
el._textOffset = textOffset;
|
||||||
el._text = new AttributedString(it, startIndex, endIndex);
|
el._text = new AttributedString(it, startIndex, endIndex);
|
||||||
|
el.textStartIndex = startIndex;
|
||||||
|
el.textEndIndex = endIndex;
|
||||||
|
|
||||||
if (prStart){
|
if (prStart){
|
||||||
int sp = rt.getSpaceBefore();
|
int sp = rt.getSpaceBefore();
|
||||||
@ -203,8 +262,6 @@ public class TextPainter {
|
|||||||
}
|
}
|
||||||
el.descent = descent;
|
el.descent = descent;
|
||||||
|
|
||||||
textHeight += el.ascent + el.descent;
|
|
||||||
|
|
||||||
if(rt.isBullet() && (prStart || startIndex == 0)){
|
if(rt.isBullet() && (prStart || startIndex == 0)){
|
||||||
it.setIndex(startIndex);
|
it.setIndex(startIndex);
|
||||||
|
|
||||||
@ -236,56 +293,11 @@ public class TextPainter {
|
|||||||
lines.add(el);
|
lines.add(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
int valign = _shape.getVerticalAlignment();
|
|
||||||
double y0 = anchor.getY();
|
|
||||||
switch (valign){
|
|
||||||
case TextShape.AnchorTopBaseline:
|
|
||||||
case TextShape.AnchorTop:
|
|
||||||
y0 += _shape.getMarginTop();
|
|
||||||
break;
|
|
||||||
case TextShape.AnchorBottom:
|
|
||||||
y0 += anchor.getHeight() - textHeight - _shape.getMarginBottom();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case TextShape.AnchorMiddle:
|
|
||||||
float delta = (float)anchor.getHeight() - textHeight - _shape.getMarginTop() - _shape.getMarginBottom();
|
|
||||||
y0 += _shape.getMarginTop() + delta/2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//finally draw the text fragments
|
//finally draw the text fragments
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
TextElement[] elems = new TextElement[lines.size()];
|
||||||
TextElement elem = (TextElement)lines.get(i);
|
return (TextElement[])lines.toArray(elems);
|
||||||
y0 += elem.ascent;
|
|
||||||
|
|
||||||
Point2D.Double pen = new Point2D.Double();
|
|
||||||
pen.y = y0;
|
|
||||||
switch (elem._align) {
|
|
||||||
default:
|
|
||||||
case TextShape.AlignLeft:
|
|
||||||
pen.x = anchor.getX() + _shape.getMarginLeft();
|
|
||||||
break;
|
|
||||||
case TextShape.AlignCenter:
|
|
||||||
pen.x = anchor.getX() + _shape.getMarginLeft() +
|
|
||||||
(anchor.getWidth() - elem.advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
|
|
||||||
break;
|
|
||||||
case TextShape.AlignRight:
|
|
||||||
pen.x = anchor.getX() + _shape.getMarginLeft() +
|
|
||||||
(anchor.getWidth() - elem.advance - _shape.getMarginLeft() - _shape.getMarginRight());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(elem._bullet != null){
|
|
||||||
graphics.drawString(elem._bullet.getIterator(), (float)(pen.x + elem._bulletOffset), (float)pen.y);
|
|
||||||
}
|
|
||||||
AttributedCharacterIterator chIt = elem._text.getIterator();
|
|
||||||
if(chIt.getEndIndex() > chIt.getBeginIndex()) {
|
|
||||||
graphics.drawString(chIt, (float)(pen.x + elem._textOffset), (float)pen.y);
|
|
||||||
}
|
|
||||||
y0 += elem.descent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class TextElement {
|
public static class TextElement {
|
||||||
public AttributedString _text;
|
public AttributedString _text;
|
||||||
public int _textOffset;
|
public int _textOffset;
|
||||||
@ -294,5 +306,6 @@ public class TextPainter {
|
|||||||
public int _align;
|
public int _align;
|
||||||
public float ascent, descent;
|
public float ascent, descent;
|
||||||
public float advance;
|
public float advance;
|
||||||
|
public int textStartIndex, textEndIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package org.apache.poi.hslf.model;
|
|||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||||
import org.apache.poi.hslf.record.*;
|
import org.apache.poi.hslf.record.*;
|
||||||
@ -45,7 +46,8 @@ public class TextRun
|
|||||||
protected TextBytesAtom _byteAtom;
|
protected TextBytesAtom _byteAtom;
|
||||||
protected TextCharsAtom _charAtom;
|
protected TextCharsAtom _charAtom;
|
||||||
protected StyleTextPropAtom _styleAtom;
|
protected StyleTextPropAtom _styleAtom;
|
||||||
protected boolean _isUnicode;
|
protected TextRulerAtom _ruler;
|
||||||
|
protected boolean _isUnicode;
|
||||||
protected RichTextRun[] _rtRuns;
|
protected RichTextRun[] _rtRuns;
|
||||||
private SlideShow slideShow;
|
private SlideShow slideShow;
|
||||||
private Sheet sheet;
|
private Sheet sheet;
|
||||||
@ -103,155 +105,159 @@ public class TextRun
|
|||||||
pStyles = _styleAtom.getParagraphStyles();
|
pStyles = _styleAtom.getParagraphStyles();
|
||||||
cStyles = _styleAtom.getCharacterStyles();
|
cStyles = _styleAtom.getCharacterStyles();
|
||||||
}
|
}
|
||||||
|
buildRichTextRuns(pStyles, cStyles, runRawText);
|
||||||
// Handle case of no current style, with a default
|
|
||||||
if(pStyles.size() == 0 || cStyles.size() == 0) {
|
|
||||||
_rtRuns = new RichTextRun[1];
|
|
||||||
_rtRuns[0] = new RichTextRun(this, 0, runRawText.length());
|
|
||||||
} else {
|
|
||||||
// Build up Rich Text Runs, one for each
|
|
||||||
// character/paragraph style pair
|
|
||||||
Vector rtrs = new Vector();
|
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
int curP = 0;
|
|
||||||
int curC = 0;
|
|
||||||
int pLenRemain = -1;
|
|
||||||
int cLenRemain = -1;
|
|
||||||
|
|
||||||
// Build one for each run with the same style
|
|
||||||
while(pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) {
|
|
||||||
// Get the Props to use
|
|
||||||
TextPropCollection pProps = (TextPropCollection)pStyles.get(curP);
|
|
||||||
TextPropCollection cProps = (TextPropCollection)cStyles.get(curC);
|
|
||||||
|
|
||||||
int pLen = pProps.getCharactersCovered();
|
|
||||||
int cLen = cProps.getCharactersCovered();
|
|
||||||
|
|
||||||
// Handle new pass
|
|
||||||
boolean freshSet = false;
|
|
||||||
if(pLenRemain == -1 && cLenRemain == -1) { freshSet = true; }
|
|
||||||
if(pLenRemain == -1) { pLenRemain = pLen; }
|
|
||||||
if(cLenRemain == -1) { cLenRemain = cLen; }
|
|
||||||
|
|
||||||
// So we know how to build the eventual run
|
|
||||||
int runLen = -1;
|
|
||||||
boolean pShared = false;
|
|
||||||
boolean cShared = false;
|
|
||||||
|
|
||||||
// Same size, new styles - neither shared
|
|
||||||
if(pLen == cLen && freshSet) {
|
|
||||||
runLen = cLen;
|
|
||||||
pShared = false;
|
|
||||||
cShared = false;
|
|
||||||
curP++;
|
|
||||||
curC++;
|
|
||||||
pLenRemain = -1;
|
|
||||||
cLenRemain = -1;
|
|
||||||
} else {
|
|
||||||
// Some sharing
|
|
||||||
|
|
||||||
// See if we are already in a shared block
|
|
||||||
if(pLenRemain < pLen) {
|
|
||||||
// Existing shared p block
|
|
||||||
pShared = true;
|
|
||||||
|
|
||||||
// Do we end with the c block, or either side of it?
|
|
||||||
if(pLenRemain == cLenRemain) {
|
|
||||||
// We end at the same time
|
|
||||||
cShared = false;
|
|
||||||
runLen = pLenRemain;
|
|
||||||
curP++;
|
|
||||||
curC++;
|
|
||||||
pLenRemain = -1;
|
|
||||||
cLenRemain = -1;
|
|
||||||
} else if(pLenRemain < cLenRemain) {
|
|
||||||
// We end before the c block
|
|
||||||
cShared = true;
|
|
||||||
runLen = pLenRemain;
|
|
||||||
curP++;
|
|
||||||
cLenRemain -= pLenRemain;
|
|
||||||
pLenRemain = -1;
|
|
||||||
} else {
|
|
||||||
// We end after the c block
|
|
||||||
cShared = false;
|
|
||||||
runLen = cLenRemain;
|
|
||||||
curC++;
|
|
||||||
pLenRemain -= cLenRemain;
|
|
||||||
cLenRemain = -1;
|
|
||||||
}
|
|
||||||
} else if(cLenRemain < cLen) {
|
|
||||||
// Existing shared c block
|
|
||||||
cShared = true;
|
|
||||||
|
|
||||||
// Do we end with the p block, or either side of it?
|
|
||||||
if(pLenRemain == cLenRemain) {
|
|
||||||
// We end at the same time
|
|
||||||
pShared = false;
|
|
||||||
runLen = cLenRemain;
|
|
||||||
curP++;
|
|
||||||
curC++;
|
|
||||||
pLenRemain = -1;
|
|
||||||
cLenRemain = -1;
|
|
||||||
} else if(cLenRemain < pLenRemain) {
|
|
||||||
// We end before the p block
|
|
||||||
pShared = true;
|
|
||||||
runLen = cLenRemain;
|
|
||||||
curC++;
|
|
||||||
pLenRemain -= cLenRemain;
|
|
||||||
cLenRemain = -1;
|
|
||||||
} else {
|
|
||||||
// We end after the p block
|
|
||||||
pShared = false;
|
|
||||||
runLen = pLenRemain;
|
|
||||||
curP++;
|
|
||||||
cLenRemain -= pLenRemain;
|
|
||||||
pLenRemain = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Start of a shared block
|
|
||||||
if(pLenRemain < cLenRemain) {
|
|
||||||
// Shared c block
|
|
||||||
pShared = false;
|
|
||||||
cShared = true;
|
|
||||||
runLen = pLenRemain;
|
|
||||||
curP++;
|
|
||||||
cLenRemain -= pLenRemain;
|
|
||||||
pLenRemain = -1;
|
|
||||||
} else {
|
|
||||||
// Shared p block
|
|
||||||
pShared = true;
|
|
||||||
cShared = false;
|
|
||||||
runLen = cLenRemain;
|
|
||||||
curC++;
|
|
||||||
pLenRemain -= cLenRemain;
|
|
||||||
cLenRemain = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wind on
|
|
||||||
int prevPos = pos;
|
|
||||||
pos += runLen;
|
|
||||||
// Adjust for end-of-run extra 1 length
|
|
||||||
if(pos > runRawText.length()) {
|
|
||||||
runLen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save
|
|
||||||
RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared, cShared);
|
|
||||||
rtrs.add(rtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the array
|
|
||||||
_rtRuns = new RichTextRun[rtrs.size()];
|
|
||||||
rtrs.copyInto(_rtRuns);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText){
|
||||||
// Update methods follow
|
|
||||||
|
// Handle case of no current style, with a default
|
||||||
|
if(pStyles.size() == 0 || cStyles.size() == 0) {
|
||||||
|
_rtRuns = new RichTextRun[1];
|
||||||
|
_rtRuns[0] = new RichTextRun(this, 0, runRawText.length());
|
||||||
|
} else {
|
||||||
|
// Build up Rich Text Runs, one for each
|
||||||
|
// character/paragraph style pair
|
||||||
|
Vector rtrs = new Vector();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
int curP = 0;
|
||||||
|
int curC = 0;
|
||||||
|
int pLenRemain = -1;
|
||||||
|
int cLenRemain = -1;
|
||||||
|
|
||||||
|
// Build one for each run with the same style
|
||||||
|
while(pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) {
|
||||||
|
// Get the Props to use
|
||||||
|
TextPropCollection pProps = (TextPropCollection)pStyles.get(curP);
|
||||||
|
TextPropCollection cProps = (TextPropCollection)cStyles.get(curC);
|
||||||
|
|
||||||
|
int pLen = pProps.getCharactersCovered();
|
||||||
|
int cLen = cProps.getCharactersCovered();
|
||||||
|
|
||||||
|
// Handle new pass
|
||||||
|
boolean freshSet = false;
|
||||||
|
if(pLenRemain == -1 && cLenRemain == -1) { freshSet = true; }
|
||||||
|
if(pLenRemain == -1) { pLenRemain = pLen; }
|
||||||
|
if(cLenRemain == -1) { cLenRemain = cLen; }
|
||||||
|
|
||||||
|
// So we know how to build the eventual run
|
||||||
|
int runLen = -1;
|
||||||
|
boolean pShared = false;
|
||||||
|
boolean cShared = false;
|
||||||
|
|
||||||
|
// Same size, new styles - neither shared
|
||||||
|
if(pLen == cLen && freshSet) {
|
||||||
|
runLen = cLen;
|
||||||
|
pShared = false;
|
||||||
|
cShared = false;
|
||||||
|
curP++;
|
||||||
|
curC++;
|
||||||
|
pLenRemain = -1;
|
||||||
|
cLenRemain = -1;
|
||||||
|
} else {
|
||||||
|
// Some sharing
|
||||||
|
|
||||||
|
// See if we are already in a shared block
|
||||||
|
if(pLenRemain < pLen) {
|
||||||
|
// Existing shared p block
|
||||||
|
pShared = true;
|
||||||
|
|
||||||
|
// Do we end with the c block, or either side of it?
|
||||||
|
if(pLenRemain == cLenRemain) {
|
||||||
|
// We end at the same time
|
||||||
|
cShared = false;
|
||||||
|
runLen = pLenRemain;
|
||||||
|
curP++;
|
||||||
|
curC++;
|
||||||
|
pLenRemain = -1;
|
||||||
|
cLenRemain = -1;
|
||||||
|
} else if(pLenRemain < cLenRemain) {
|
||||||
|
// We end before the c block
|
||||||
|
cShared = true;
|
||||||
|
runLen = pLenRemain;
|
||||||
|
curP++;
|
||||||
|
cLenRemain -= pLenRemain;
|
||||||
|
pLenRemain = -1;
|
||||||
|
} else {
|
||||||
|
// We end after the c block
|
||||||
|
cShared = false;
|
||||||
|
runLen = cLenRemain;
|
||||||
|
curC++;
|
||||||
|
pLenRemain -= cLenRemain;
|
||||||
|
cLenRemain = -1;
|
||||||
|
}
|
||||||
|
} else if(cLenRemain < cLen) {
|
||||||
|
// Existing shared c block
|
||||||
|
cShared = true;
|
||||||
|
|
||||||
|
// Do we end with the p block, or either side of it?
|
||||||
|
if(pLenRemain == cLenRemain) {
|
||||||
|
// We end at the same time
|
||||||
|
pShared = false;
|
||||||
|
runLen = cLenRemain;
|
||||||
|
curP++;
|
||||||
|
curC++;
|
||||||
|
pLenRemain = -1;
|
||||||
|
cLenRemain = -1;
|
||||||
|
} else if(cLenRemain < pLenRemain) {
|
||||||
|
// We end before the p block
|
||||||
|
pShared = true;
|
||||||
|
runLen = cLenRemain;
|
||||||
|
curC++;
|
||||||
|
pLenRemain -= cLenRemain;
|
||||||
|
cLenRemain = -1;
|
||||||
|
} else {
|
||||||
|
// We end after the p block
|
||||||
|
pShared = false;
|
||||||
|
runLen = pLenRemain;
|
||||||
|
curP++;
|
||||||
|
cLenRemain -= pLenRemain;
|
||||||
|
pLenRemain = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Start of a shared block
|
||||||
|
if(pLenRemain < cLenRemain) {
|
||||||
|
// Shared c block
|
||||||
|
pShared = false;
|
||||||
|
cShared = true;
|
||||||
|
runLen = pLenRemain;
|
||||||
|
curP++;
|
||||||
|
cLenRemain -= pLenRemain;
|
||||||
|
pLenRemain = -1;
|
||||||
|
} else {
|
||||||
|
// Shared p block
|
||||||
|
pShared = true;
|
||||||
|
cShared = false;
|
||||||
|
runLen = cLenRemain;
|
||||||
|
curC++;
|
||||||
|
pLenRemain -= cLenRemain;
|
||||||
|
cLenRemain = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wind on
|
||||||
|
int prevPos = pos;
|
||||||
|
pos += runLen;
|
||||||
|
// Adjust for end-of-run extra 1 length
|
||||||
|
if(pos > runRawText.length()) {
|
||||||
|
runLen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save
|
||||||
|
RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared, cShared);
|
||||||
|
rtrs.add(rtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the array
|
||||||
|
_rtRuns = new RichTextRun[rtrs.size()];
|
||||||
|
rtrs.copyInto(_rtRuns);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update methods follow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the supplied text onto the end of the TextRun,
|
* Adds the supplied text onto the end of the TextRun,
|
||||||
@ -379,7 +385,7 @@ public class TextRun
|
|||||||
* @param run
|
* @param run
|
||||||
* @param s
|
* @param s
|
||||||
*/
|
*/
|
||||||
public synchronized void changeTextInRichTextRun(RichTextRun run, String s) {
|
public void changeTextInRichTextRun(RichTextRun run, String s) {
|
||||||
// Figure out which run it is
|
// Figure out which run it is
|
||||||
int runID = -1;
|
int runID = -1;
|
||||||
for(int i=0; i<_rtRuns.length; i++) {
|
for(int i=0; i<_rtRuns.length; i++) {
|
||||||
@ -457,7 +463,7 @@ public class TextRun
|
|||||||
* as the the first character has.
|
* as the the first character has.
|
||||||
* If you care about styling, do setText on a RichTextRun instead
|
* If you care about styling, do setText on a RichTextRun instead
|
||||||
*/
|
*/
|
||||||
public synchronized void setRawText(String s) {
|
public void setRawText(String s) {
|
||||||
// Save the new text to the atoms
|
// Save the new text to the atoms
|
||||||
storeText(s);
|
storeText(s);
|
||||||
RichTextRun fst = _rtRuns[0];
|
RichTextRun fst = _rtRuns[0];
|
||||||
@ -491,7 +497,7 @@ public class TextRun
|
|||||||
* Changes the text.
|
* Changes the text.
|
||||||
* Converts '\r' into '\n'
|
* Converts '\r' into '\n'
|
||||||
*/
|
*/
|
||||||
public synchronized void setText(String s) {
|
public void setText(String s) {
|
||||||
String text = normalize(s);
|
String text = normalize(s);
|
||||||
setRawText(text);
|
setRawText(text);
|
||||||
}
|
}
|
||||||
@ -500,7 +506,7 @@ public class TextRun
|
|||||||
* Ensure a StyleTextPropAtom is present for this run,
|
* Ensure a StyleTextPropAtom is present for this run,
|
||||||
* by adding if required. Normally for internal TextRun use.
|
* by adding if required. Normally for internal TextRun use.
|
||||||
*/
|
*/
|
||||||
public synchronized void ensureStyleAtomPresent() {
|
public void ensureStyleAtomPresent() {
|
||||||
if(_styleAtom != null) {
|
if(_styleAtom != null) {
|
||||||
// All there
|
// All there
|
||||||
return;
|
return;
|
||||||
@ -669,11 +675,26 @@ public class TextRun
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TextRulerAtom getTextRuler(){
|
public TextRulerAtom getTextRuler(){
|
||||||
for (int i = 0; i < _records.length; i++) {
|
if(_ruler == null){
|
||||||
if(_records[i] instanceof TextRulerAtom) return (TextRulerAtom)_records[i];
|
if(_records != null) for (int i = 0; i < _records.length; i++) {
|
||||||
}
|
if(_records[i] instanceof TextRulerAtom) {
|
||||||
return null;
|
_ruler = (TextRulerAtom)_records[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return _ruler;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextRulerAtom createTextRuler(){
|
||||||
|
_ruler = getTextRuler();
|
||||||
|
if(_ruler == null){
|
||||||
|
_ruler = TextRulerAtom.getParagraphInstance();
|
||||||
|
_headerAtom.getParentRecord().appendChildRecord(_ruler);
|
||||||
|
}
|
||||||
|
return _ruler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -692,4 +713,5 @@ public class TextRun
|
|||||||
public Record[] getRecords(){
|
public Record[] getRecords(){
|
||||||
return _records;
|
return _records;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ public abstract class TextShape extends SimpleShape {
|
|||||||
_txtbox.appendChildRecord(sta);
|
_txtbox.appendChildRecord(sta);
|
||||||
|
|
||||||
_txtrun = new TextRun(tha,tca,sta);
|
_txtrun = new TextRun(tha,tca,sta);
|
||||||
|
_txtrun._records = new Record[]{tha, tca, sta};
|
||||||
_txtrun.setText("");
|
_txtrun.setText("");
|
||||||
|
|
||||||
_escherContainer.addChildRecord(_txtbox.getEscherRecord());
|
_escherContainer.addChildRecord(_txtbox.getEscherRecord());
|
||||||
|
97
src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java
Executable file
97
src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container record that specifies information about animation information for a shape.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class AnimationInfo extends RecordContainer {
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
// Links to our more interesting children
|
||||||
|
private AnimationInfoAtom animationAtom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set things up, and find our more interesting children
|
||||||
|
*/
|
||||||
|
protected AnimationInfo(byte[] source, int start, int len) {
|
||||||
|
// Grab the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Find our children
|
||||||
|
_children = Record.findChildRecords(source,start+8,len-8);
|
||||||
|
findInterestingChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through our child records, picking out the ones that are
|
||||||
|
* interesting, and saving those for use by the easy helper
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
private void findInterestingChildren() {
|
||||||
|
|
||||||
|
// First child should be the ExMediaAtom
|
||||||
|
if(_children[0] instanceof AnimationInfoAtom) {
|
||||||
|
animationAtom = (AnimationInfoAtom)_children[0];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "First child record wasn't a AnimationInfoAtom, was of type " + _children[0].getRecordType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new AnimationInfo, with blank fields
|
||||||
|
*/
|
||||||
|
public AnimationInfo() {
|
||||||
|
// Setup our header block
|
||||||
|
_header = new byte[8];
|
||||||
|
_header[0] = 0x0f; // We are a container record
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
|
||||||
|
_children = new Record[1];
|
||||||
|
_children[0] = animationAtom = new AnimationInfoAtom();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are of type 4103
|
||||||
|
*/
|
||||||
|
public long getRecordType() { return RecordTypes.AnimationInfo.typeID; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the AnimationInfo
|
||||||
|
*/
|
||||||
|
public AnimationInfoAtom getAnimationInfoAtom() {
|
||||||
|
return animationAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
278
src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java
Executable file
278
src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java
Executable file
@ -0,0 +1,278 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.util.SystemTimeUtils;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An atom record that specifies the animation information for a shape.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class AnimationInfoAtom extends RecordAtom
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether the animation plays in the reverse direction
|
||||||
|
*/
|
||||||
|
public static final int Reverse = 1;
|
||||||
|
/**
|
||||||
|
* whether the animation starts automatically
|
||||||
|
*/
|
||||||
|
public static final int Automatic = 4;
|
||||||
|
/**
|
||||||
|
* whether the animation has an associated sound
|
||||||
|
*/
|
||||||
|
public static final int Sound = 16;
|
||||||
|
/**
|
||||||
|
* whether all playing sounds are stopped when this animation begins
|
||||||
|
*/
|
||||||
|
public static final int StopSound = 64;
|
||||||
|
/**
|
||||||
|
* whether an associated sound, media or action verb is activated when the shape is clicked.
|
||||||
|
*/
|
||||||
|
public static final int Play = 256;
|
||||||
|
/**
|
||||||
|
* specifies that the animation, while playing, stops other slide show actions.
|
||||||
|
*/
|
||||||
|
public static final int Synchronous = 1024;
|
||||||
|
/**
|
||||||
|
* whether the shape is hidden while the animation is not playing
|
||||||
|
*/
|
||||||
|
public static final int Hide = 4096;
|
||||||
|
/**
|
||||||
|
* whether the background of the shape is animated
|
||||||
|
*/
|
||||||
|
public static final int AnimateBg = 16384;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* record data
|
||||||
|
*/
|
||||||
|
private byte[] _recdata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a brand new link related atom record.
|
||||||
|
*/
|
||||||
|
protected AnimationInfoAtom() {
|
||||||
|
_recdata = new byte[28];
|
||||||
|
|
||||||
|
_header = new byte[8];
|
||||||
|
LittleEndian.putShort(_header, 0, (short)0x01);
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _recdata.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the link related atom record from its
|
||||||
|
* source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected AnimationInfoAtom(byte[] source, int start, int len) {
|
||||||
|
// Get the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Grab the record data
|
||||||
|
_recdata = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the record type.
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.AnimationInfoAtom.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*
|
||||||
|
* @param out the output stream to write to.
|
||||||
|
* @throws java.io.IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_recdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A rgb structure that specifies a color for the dim effect after the animation is complete.
|
||||||
|
*
|
||||||
|
* @return color for the dim effect after the animation is complete
|
||||||
|
*/
|
||||||
|
public int getDimColor(){
|
||||||
|
return LittleEndian.getInt(_recdata, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A rgb structure that specifies a color for the dim effect after the animation is complete.
|
||||||
|
*
|
||||||
|
* @param rgb color for the dim effect after the animation is complete
|
||||||
|
*/
|
||||||
|
public void setDimColor(int rgb){
|
||||||
|
LittleEndian.putInt(_recdata, 0, rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit mask specifying options for displaying headers and footers
|
||||||
|
*
|
||||||
|
* @return A bit mask specifying options for displaying headers and footers
|
||||||
|
*/
|
||||||
|
public int getMask(){
|
||||||
|
return LittleEndian.getInt(_recdata, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit mask specifying options for displaying video
|
||||||
|
*
|
||||||
|
* @param mask A bit mask specifying options for displaying video
|
||||||
|
*/
|
||||||
|
public void setMask(int mask){
|
||||||
|
LittleEndian.putInt(_recdata, 4, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bit the bit to check
|
||||||
|
* @return whether the specified flag is set
|
||||||
|
*/
|
||||||
|
public boolean getFlag(int bit){
|
||||||
|
return (getMask() & bit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bit the bit to set
|
||||||
|
* @param value whether the specified bit is set
|
||||||
|
*/
|
||||||
|
public void setFlag(int bit, boolean value){
|
||||||
|
int mask = getMask();
|
||||||
|
if(value) mask |= bit;
|
||||||
|
else mask &= ~bit;
|
||||||
|
setMask(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 4-byte unsigned integer that specifies a reference to a sound
|
||||||
|
* in the SoundCollectionContainer record to locate the embedded audio
|
||||||
|
*
|
||||||
|
* @return reference to a sound
|
||||||
|
*/
|
||||||
|
public int getSoundIdRef(){
|
||||||
|
return LittleEndian.getInt(_recdata, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 4-byte unsigned integer that specifies a reference to a sound
|
||||||
|
* in the SoundCollectionContainer record to locate the embedded audio
|
||||||
|
*
|
||||||
|
* @param id reference to a sound
|
||||||
|
*/
|
||||||
|
public void setSoundIdRef(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 8, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
|
||||||
|
* If {@link Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
|
||||||
|
*/
|
||||||
|
public int getDelayTime(){
|
||||||
|
return LittleEndian.getInt(_recdata, 12);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
|
||||||
|
* If {@link Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
|
||||||
|
*/
|
||||||
|
public void setDelayTime(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 12, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A signed integer that specifies the order of the animation in the slide.
|
||||||
|
* It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
|
||||||
|
* the corresponding placeholder shape on the main master slide or title master slide.
|
||||||
|
* The value -1 SHOULD NOT <105> be used.
|
||||||
|
*/
|
||||||
|
public int getOrderID(){
|
||||||
|
return LittleEndian.getInt(_recdata, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A signed integer that specifies the order of the animation in the slide.
|
||||||
|
* It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
|
||||||
|
* the corresponding placeholder shape on the main master slide or title master slide.
|
||||||
|
* The value -1 SHOULD NOT <105> be used.
|
||||||
|
*/
|
||||||
|
public void setOrderID(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 16, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unsigned integer that specifies the number of slides that this animation continues playing.
|
||||||
|
* This field is utilized only in conjunction with media.
|
||||||
|
* The value 0xFFFFFFFF specifies that the animation plays for one slide.
|
||||||
|
*/
|
||||||
|
public int getSlideCount(){
|
||||||
|
return LittleEndian.getInt(_recdata, 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unsigned integer that specifies the number of slides that this animation continues playing.
|
||||||
|
* This field is utilized only in conjunction with media.
|
||||||
|
* The value 0xFFFFFFFF specifies that the animation plays for one slide.
|
||||||
|
*/
|
||||||
|
public void setSlideCount(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 18, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
buf.append("AnimationInfoAtom\n");
|
||||||
|
buf.append("\tDimColor: " + getDimColor() + "\n");
|
||||||
|
int mask = getMask();
|
||||||
|
buf.append("\tMask: " + mask + ", 0x"+Integer.toHexString(mask)+"\n");
|
||||||
|
buf.append("\t Reverse: " + getFlag(Reverse)+"\n");
|
||||||
|
buf.append("\t Automatic: " + getFlag(Automatic)+"\n");
|
||||||
|
buf.append("\t Sound: " + getFlag(Sound)+"\n");
|
||||||
|
buf.append("\t StopSound: " + getFlag(StopSound)+"\n");
|
||||||
|
buf.append("\t Play: " + getFlag(Play)+"\n");
|
||||||
|
buf.append("\t Synchronous: " + getFlag(Synchronous)+"\n");
|
||||||
|
buf.append("\t Hide: " + getFlag(Hide)+"\n");
|
||||||
|
buf.append("\t AnimateBg: " + getFlag(AnimateBg)+"\n");
|
||||||
|
buf.append("\tSoundIdRef: " + getSoundIdRef() + "\n");
|
||||||
|
buf.append("\tDelayTime: " + getDelayTime() + "\n");
|
||||||
|
buf.append("\tOrderID: " + getOrderID() + "\n");
|
||||||
|
buf.append("\tSlideCount: " + getSlideCount() + "\n");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
53
src/scratchpad/src/org/apache/poi/hslf/record/ExAviMovie.java
Executable file
53
src/scratchpad/src/org/apache/poi/hslf/record/ExAviMovie.java
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container record that specifies information about a movie stored externally.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ExAviMovie extends ExMCIMovie {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set things up, and find our more interesting children
|
||||||
|
*/
|
||||||
|
protected ExAviMovie(byte[] source, int start, int len) {
|
||||||
|
super(source, start, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ExAviMovie, with blank fields
|
||||||
|
*/
|
||||||
|
public ExAviMovie() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* We are of type 4102
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExAviMovie.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,7 +24,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for OLE Control object. It contains:
|
* A container record that specifies information about an ActiveX control. It contains:
|
||||||
* <p>
|
* <p>
|
||||||
* 1. ExControlAtom (4091)
|
* 1. ExControlAtom (4091)
|
||||||
* 2. ExOleObjAtom (4035)
|
* 2. ExOleObjAtom (4035)
|
||||||
@ -40,9 +40,6 @@ import org.apache.poi.util.POILogger;
|
|||||||
*/
|
*/
|
||||||
public class ExControl extends ExEmbed {
|
public class ExControl extends ExEmbed {
|
||||||
|
|
||||||
// Links to our more interesting children
|
|
||||||
private ExControlAtom ctrlAtom;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set things up, and find our more interesting children
|
* Set things up, and find our more interesting children
|
||||||
*
|
*
|
||||||
@ -60,7 +57,7 @@ public class ExControl extends ExEmbed {
|
|||||||
public ExControl() {
|
public ExControl() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
_children[0] = ctrlAtom = new ExControlAtom();
|
_children[0] = embedAtom = new ExControlAtom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,7 +67,7 @@ public class ExControl extends ExEmbed {
|
|||||||
*/
|
*/
|
||||||
public ExControlAtom getExControlAtom()
|
public ExControlAtom getExControlAtom()
|
||||||
{
|
{
|
||||||
return ctrlAtom;
|
return (ExControlAtom)_children[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,14 +79,4 @@ public class ExControl extends ExEmbed {
|
|||||||
public long getRecordType() {
|
public long getRecordType() {
|
||||||
return RecordTypes.ExControl.typeID;
|
return RecordTypes.ExControl.typeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RecordAtom getEmbedAtom(Record[] children){
|
|
||||||
RecordAtom atom = null;
|
|
||||||
if(_children[0] instanceof ExControlAtom) {
|
|
||||||
atom = (ExControlAtom)_children[0];
|
|
||||||
} else {
|
|
||||||
logger.log(POILogger.ERROR, "First child record wasn't a ExControlAtom, was of type " + _children[0].getRecordType());
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@ import java.io.OutputStream;
|
|||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a long integer, slideID, which stores the unique slide identifier of the slide
|
* An atom record that specifies an ActiveX control.
|
||||||
* where this control resides.
|
|
||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
@ -67,10 +66,32 @@ public class ExControlAtom extends RecordAtom {
|
|||||||
_id = LittleEndian.getInt(source, start + 8);
|
_id = LittleEndian.getInt(source, start + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An integer that specifies which presentation slide is associated with the ActiveX control.
|
||||||
|
* <p>
|
||||||
|
* It MUST be 0x00000000 or equal to the value of the slideId field of a SlidePersistAtom record.
|
||||||
|
* The value 0x00000000 specifies a null reference.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return an integer that specifies which presentation slide is associated with the ActiveX control
|
||||||
|
*/
|
||||||
public int getSlideId() {
|
public int getSlideId() {
|
||||||
return _id;
|
return _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which presentation slide is associated with the ActiveX control.
|
||||||
|
*
|
||||||
|
* @param id an integer that specifies which presentation slide is associated with the ActiveX control
|
||||||
|
* <p>
|
||||||
|
* It MUST be 0x00000000 or equal to the value of the slideId field of a SlidePersistAtom record.
|
||||||
|
* The value 0x00000000 specifies a null reference.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void setSlideId(int id) {
|
||||||
|
_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the record type.
|
* Gets the record type.
|
||||||
* @return the record type.
|
* @return the record type.
|
||||||
|
@ -36,7 +36,7 @@ public class ExEmbed extends RecordContainer {
|
|||||||
private byte[] _header;
|
private byte[] _header;
|
||||||
|
|
||||||
// Links to our more interesting children
|
// Links to our more interesting children
|
||||||
private RecordAtom embedAtom;
|
protected RecordAtom embedAtom;
|
||||||
private ExOleObjAtom oleObjAtom;
|
private ExOleObjAtom oleObjAtom;
|
||||||
private CString menuName;
|
private CString menuName;
|
||||||
private CString progId;
|
private CString progId;
|
||||||
@ -72,10 +72,11 @@ public class ExEmbed extends RecordContainer {
|
|||||||
|
|
||||||
// Setup our child records
|
// Setup our child records
|
||||||
CString cs1 = new CString();
|
CString cs1 = new CString();
|
||||||
|
cs1.setOptions(0x1 << 4);
|
||||||
CString cs2 = new CString();
|
CString cs2 = new CString();
|
||||||
|
cs2.setOptions(0x2 << 4);
|
||||||
CString cs3 = new CString();
|
CString cs3 = new CString();
|
||||||
// cs1.setOptions(0x00);
|
cs3.setOptions(0x3 << 4);
|
||||||
// cs2.setOptions(0x10);
|
|
||||||
_children[0] = new ExEmbedAtom();
|
_children[0] = new ExEmbedAtom();
|
||||||
_children[1] = new ExOleObjAtom();
|
_children[1] = new ExOleObjAtom();
|
||||||
_children[2] = cs1;
|
_children[2] = cs1;
|
||||||
@ -91,7 +92,11 @@ public class ExEmbed extends RecordContainer {
|
|||||||
private void findInterestingChildren() {
|
private void findInterestingChildren() {
|
||||||
|
|
||||||
// First child should be the ExHyperlinkAtom
|
// First child should be the ExHyperlinkAtom
|
||||||
embedAtom = getEmbedAtom(_children);
|
if(_children[0] instanceof ExEmbedAtom) {
|
||||||
|
embedAtom = (ExEmbedAtom)_children[0];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
|
||||||
|
}
|
||||||
|
|
||||||
// Second child should be the ExOleObjAtom
|
// Second child should be the ExOleObjAtom
|
||||||
if (_children[1] instanceof ExOleObjAtom) {
|
if (_children[1] instanceof ExOleObjAtom) {
|
||||||
@ -102,25 +107,17 @@ public class ExEmbed extends RecordContainer {
|
|||||||
|
|
||||||
for (int i = 2; i < _children.length; i++) {
|
for (int i = 2; i < _children.length; i++) {
|
||||||
if (_children[i] instanceof CString){
|
if (_children[i] instanceof CString){
|
||||||
if (menuName == null) menuName = (CString)_children[i];
|
CString cs = (CString)_children[i];
|
||||||
else if (progId == null) progId = (CString)_children[i];
|
int opts = cs.getOptions() >> 4;
|
||||||
else if (clipboardName == null) clipboardName = (CString)_children[i];
|
switch(opts){
|
||||||
} else {
|
case 0x1: menuName = cs; break;
|
||||||
logger.log(POILogger.ERROR, "Record after atoms wasn't a CString, was of type " + _children[i].getRecordType());
|
case 0x2: progId = cs; break;
|
||||||
|
case 0x3: clipboardName = cs; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RecordAtom getEmbedAtom(Record[] children){
|
|
||||||
RecordAtom atom = null;
|
|
||||||
if(_children[0] instanceof ExEmbedAtom) {
|
|
||||||
atom = (ExEmbedAtom)_children[0];
|
|
||||||
} else {
|
|
||||||
logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link ExEmbedAtom}.
|
* Gets the {@link ExEmbedAtom}.
|
||||||
*
|
*
|
||||||
@ -151,6 +148,11 @@ public class ExEmbed extends RecordContainer {
|
|||||||
return menuName == null ? null : menuName.getText();
|
return menuName == null ? null : menuName.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMenuName(String s)
|
||||||
|
{
|
||||||
|
if(menuName != null) menuName.setText(s);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the OLE Programmatic Identifier.
|
* Gets the OLE Programmatic Identifier.
|
||||||
*
|
*
|
||||||
@ -161,6 +163,10 @@ public class ExEmbed extends RecordContainer {
|
|||||||
return progId == null ? null : progId.getText();
|
return progId == null ? null : progId.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProgId(String s)
|
||||||
|
{
|
||||||
|
if(progId != null) progId.setText(s);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Gets the name that appears in the paste special dialog.
|
* Gets the name that appears in the paste special dialog.
|
||||||
*
|
*
|
||||||
@ -171,6 +177,10 @@ public class ExEmbed extends RecordContainer {
|
|||||||
return clipboardName == null ? null : clipboardName.getText();
|
return clipboardName == null ? null : clipboardName.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setClipboardName(String s)
|
||||||
|
{
|
||||||
|
if(clipboardName != null) clipboardName.setText(s);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns the type (held as a little endian in bytes 3 and 4)
|
* Returns the type (held as a little endian in bytes 3 and 4)
|
||||||
* that this class handles.
|
* that this class handles.
|
||||||
|
100
src/scratchpad/src/org/apache/poi/hslf/record/ExMCIMovie.java
Executable file
100
src/scratchpad/src/org/apache/poi/hslf/record/ExMCIMovie.java
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* 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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container record that specifies information about a movie stored externally.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ExMCIMovie extends RecordContainer {
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
//An ExVideoContainer record that specifies information about the MCI movie
|
||||||
|
private ExVideoContainer exVideo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set things up, and find our more interesting children
|
||||||
|
*/
|
||||||
|
protected ExMCIMovie(byte[] source, int start, int len) {
|
||||||
|
// Grab the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source, start, _header, 0, 8);
|
||||||
|
|
||||||
|
// Find our children
|
||||||
|
_children = Record.findChildRecords(source, start + 8, len - 8);
|
||||||
|
findInterestingChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ExMCIMovie, with blank fields
|
||||||
|
*/
|
||||||
|
public ExMCIMovie() {
|
||||||
|
_header = new byte[8];
|
||||||
|
// Setup our header block
|
||||||
|
_header[0] = 0x0f; // We are a container record
|
||||||
|
LittleEndian.putShort(_header, 2, (short) getRecordType());
|
||||||
|
|
||||||
|
exVideo = new ExVideoContainer();
|
||||||
|
_children = new Record[]{exVideo};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through our child records, picking out the ones that are
|
||||||
|
* interesting, and saving those for use by the easy helper
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
private void findInterestingChildren() {
|
||||||
|
|
||||||
|
// First child should be the ExVideoContainer
|
||||||
|
if (_children[0] instanceof ExVideoContainer) {
|
||||||
|
exVideo = (ExVideoContainer) _children[0];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "First child record wasn't a ExVideoContainer, was of type " + _children[0].getRecordType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are of type 4103
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExMCIMovie.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
writeOut(_header[0], _header[1], getRecordType(), _children, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ExVideoContainer that specifies information about the MCI movie
|
||||||
|
*/
|
||||||
|
public ExVideoContainer getExVideo() {
|
||||||
|
return exVideo; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
172
src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java
Executable file
172
src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java
Executable file
@ -0,0 +1,172 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.util.SystemTimeUtils;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An atom record that specifies information about external audio or video data.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ExMediaAtom extends RecordAtom
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit that specifies whether the audio or video data is repeated continuously during playback.
|
||||||
|
*/
|
||||||
|
public static final int fLoop = 1;
|
||||||
|
/**
|
||||||
|
* A bit that specifies whether the audio or video data is rewound after playing.
|
||||||
|
*/
|
||||||
|
public static final int fRewind = 2;
|
||||||
|
/**
|
||||||
|
* A bit that specifies whether the audio data is recorded narration for the slide show. It MUST be FALSE if this ExMediaAtom record is contained by an ExVideoContainer record.
|
||||||
|
*/
|
||||||
|
public static final int fNarration = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* record data
|
||||||
|
*/
|
||||||
|
private byte[] _recdata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a brand new link related atom record.
|
||||||
|
*/
|
||||||
|
protected ExMediaAtom() {
|
||||||
|
_recdata = new byte[8];
|
||||||
|
|
||||||
|
_header = new byte[8];
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _recdata.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the link related atom record from its
|
||||||
|
* source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected ExMediaAtom(byte[] source, int start, int len) {
|
||||||
|
// Get the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Grab the record data
|
||||||
|
_recdata = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the record type.
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() { return RecordTypes.ExMediaAtom.typeID; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*
|
||||||
|
* @param out the output stream to write to.
|
||||||
|
* @throws java.io.IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_recdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 4-byte unsigned integer that specifies an ID for an external object.
|
||||||
|
*
|
||||||
|
* @return A 4-byte unsigned integer that specifies an ID for an external object.
|
||||||
|
*/
|
||||||
|
public int getObjectId(){
|
||||||
|
return LittleEndian.getInt(_recdata, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 4-byte unsigned integer that specifies an ID for an external object.
|
||||||
|
*
|
||||||
|
* @param id A 4-byte unsigned integer that specifies an ID for an external object.
|
||||||
|
*/
|
||||||
|
public void setObjectId(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 0, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit mask specifying options for displaying headers and footers
|
||||||
|
*
|
||||||
|
* @return A bit mask specifying options for displaying headers and footers
|
||||||
|
*/
|
||||||
|
public int getMask(){
|
||||||
|
return LittleEndian.getInt(_recdata, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit mask specifying options for displaying video
|
||||||
|
*
|
||||||
|
* @param mask A bit mask specifying options for displaying video
|
||||||
|
*/
|
||||||
|
public void setMask(int mask){
|
||||||
|
LittleEndian.putInt(_recdata, 4, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bit the bit to check
|
||||||
|
* @return whether the specified flag is set
|
||||||
|
*/
|
||||||
|
public boolean getFlag(int bit){
|
||||||
|
return (getMask() & bit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bit the bit to set
|
||||||
|
* @param value whether the specified bit is set
|
||||||
|
*/
|
||||||
|
public void setFlag(int bit, boolean value){
|
||||||
|
int mask = getMask();
|
||||||
|
if(value) mask |= bit;
|
||||||
|
else mask &= ~bit;
|
||||||
|
setMask(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
buf.append("ExMediaAtom\n");
|
||||||
|
buf.append("\tObjectId: " + getObjectId() + "\n");
|
||||||
|
buf.append("\tMask : " + getMask() + "\n");
|
||||||
|
buf.append("\t fLoop : " + getFlag(fLoop) + "\n");
|
||||||
|
buf.append("\t fRewind : " + getFlag(fRewind) + "\n");
|
||||||
|
buf.append("\t fNarration : " + getFlag(fNarration) + "\n");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -65,11 +65,35 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
*/
|
*/
|
||||||
public class ExOleObjAtom extends RecordAtom {
|
public class ExOleObjAtom extends RecordAtom {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object) is displayed as an embedded object inside of a container,
|
||||||
|
*/
|
||||||
public static final int DRAW_ASPECT_VISIBLE = 1;
|
public static final int DRAW_ASPECT_VISIBLE = 1;
|
||||||
|
/**
|
||||||
|
* The object is displayed as a thumbnail image.
|
||||||
|
*/
|
||||||
|
public static final int DRAW_ASPECT_THUMBNAIL = 2;
|
||||||
|
/**
|
||||||
|
* The object is displayed as an icon.
|
||||||
|
*/
|
||||||
public static final int DRAW_ASPECT_ICON = 4;
|
public static final int DRAW_ASPECT_ICON = 4;
|
||||||
|
/**
|
||||||
|
* The object is displayed on the screen as though it were printed to a printer.
|
||||||
|
*/
|
||||||
|
public static final int DRAW_ASPECT_DOCPRINT = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An embedded OLE object; the object is serialized and saved within the file.
|
||||||
|
*/
|
||||||
public static final int TYPE_EMBEDDED = 0;
|
public static final int TYPE_EMBEDDED = 0;
|
||||||
|
/**
|
||||||
|
* A linked OLE object; the object is saved outside of the file.
|
||||||
|
*/
|
||||||
public static final int TYPE_LINKED = 1;
|
public static final int TYPE_LINKED = 1;
|
||||||
|
/**
|
||||||
|
* The OLE object is an ActiveX control.
|
||||||
|
*/
|
||||||
|
public static final int TYPE_CONTROL = 2;
|
||||||
|
|
||||||
public static final int SUBTYPE_DEFAULT = 0;
|
public static final int SUBTYPE_DEFAULT = 0;
|
||||||
public static final int SUBTYPE_CLIPART_GALLERY = 1;
|
public static final int SUBTYPE_CLIPART_GALLERY = 1;
|
||||||
@ -101,14 +125,13 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
/**
|
/**
|
||||||
* Constructs a brand new link related atom record.
|
* Constructs a brand new link related atom record.
|
||||||
*/
|
*/
|
||||||
protected ExOleObjAtom() {
|
public ExOleObjAtom() {
|
||||||
_header = new byte[8];
|
_header = new byte[8];
|
||||||
_data = new byte[18];
|
_data = new byte[24];
|
||||||
|
|
||||||
|
LittleEndian.putShort(_header, 0, (short)1); //MUST be 0x1
|
||||||
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
LittleEndian.putInt(_header, 4, _data.length);
|
LittleEndian.putInt(_header, 4, _data.length);
|
||||||
|
|
||||||
// I hope it is fine for the other values to be zero.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,6 +167,16 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 0);
|
return LittleEndian.getInt(_data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the object can be completely seen, or if only the
|
||||||
|
* icon is visible.
|
||||||
|
*
|
||||||
|
* @param aspect the draw aspect, one of the {@code DRAW_ASPECT_*} constants.
|
||||||
|
*/
|
||||||
|
public void setDrawAspect(int aspect) {
|
||||||
|
LittleEndian.putInt(_data, 0, aspect);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the object is embedded or linked.
|
* Gets whether the object is embedded or linked.
|
||||||
*
|
*
|
||||||
@ -153,6 +186,15 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 4);
|
return LittleEndian.getInt(_data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the object is embedded or linked.
|
||||||
|
*
|
||||||
|
* @param type the type, one of the {@code TYPE_EMBEDDED_*} constants.
|
||||||
|
*/
|
||||||
|
public void setType(int type) {
|
||||||
|
LittleEndian.putInt(_data, 4, type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the unique identifier for the OLE object.
|
* Gets the unique identifier for the OLE object.
|
||||||
*
|
*
|
||||||
@ -162,6 +204,15 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 8);
|
return LittleEndian.getInt(_data, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unique identifier for the OLE object.
|
||||||
|
*
|
||||||
|
* @param id the object ID.
|
||||||
|
*/
|
||||||
|
public void setObjID(int id) {
|
||||||
|
LittleEndian.putInt(_data, 8, id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of OLE object.
|
* Gets the type of OLE object.
|
||||||
*
|
*
|
||||||
@ -171,6 +222,15 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 12);
|
return LittleEndian.getInt(_data, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of OLE object.
|
||||||
|
*
|
||||||
|
* @param type the sub-type, one of the {@code SUBTYPE_*} constants.
|
||||||
|
*/
|
||||||
|
public void setSubType(int type) {
|
||||||
|
LittleEndian.putInt(_data, 12, type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the reference to the persistent object
|
* Gets the reference to the persistent object
|
||||||
*
|
*
|
||||||
@ -181,6 +241,16 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 16);
|
return LittleEndian.getInt(_data, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the reference to the persistent object
|
||||||
|
*
|
||||||
|
* @param ref the reference to the persistent object, corresponds with an
|
||||||
|
* {@code ExOleObjStg} storage container.
|
||||||
|
*/
|
||||||
|
public void setObjStgDataRef(int ref) {
|
||||||
|
LittleEndian.putInt(_data, 16, ref);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the object's image is blank.
|
* Gets whether the object's image is blank.
|
||||||
*
|
*
|
||||||
@ -191,6 +261,24 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
return LittleEndian.getInt(_data, 20) != 0;
|
return LittleEndian.getInt(_data, 20) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets misc options (the last four bytes in the atom).
|
||||||
|
*
|
||||||
|
* @return {@code true} if the object's image is blank.
|
||||||
|
*/
|
||||||
|
public int getOptions() {
|
||||||
|
// Even though this is a mere boolean, KOffice's code says it's an int.
|
||||||
|
return LittleEndian.getInt(_data, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets misc options (the last four bytes in the atom).
|
||||||
|
*/
|
||||||
|
public void setOptions(int opts) {
|
||||||
|
// Even though this is a mere boolean, KOffice's code says it's an int.
|
||||||
|
LittleEndian.putInt(_data, 20, opts);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type (held as a little endian in bytes 3 and 4)
|
* Returns the type (held as a little endian in bytes 3 and 4)
|
||||||
* that this class handles.
|
* that this class handles.
|
||||||
@ -210,4 +298,16 @@ public class ExOleObjAtom extends RecordAtom {
|
|||||||
out.write(_header);
|
out.write(_header);
|
||||||
out.write(_data);
|
out.write(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
buf.append("ExOleObjAtom\n");
|
||||||
|
buf.append(" drawAspect: " + getDrawAspect() + "\n");
|
||||||
|
buf.append(" type: " + getType() + "\n");
|
||||||
|
buf.append(" objID: " + getObjID() + "\n");
|
||||||
|
buf.append(" subType: " + getSubType() + "\n");
|
||||||
|
buf.append(" objStgDataRef: " + getObjStgDataRef() + "\n");
|
||||||
|
buf.append(" options: " + getOptions() + "\n");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
*
|
*
|
||||||
* @author Daniel Noll
|
* @author Daniel Noll
|
||||||
*/
|
*/
|
||||||
public class ExOleObjStg extends RecordAtom implements PersistRecord {
|
public class ExOleObjStg extends RecordAtom implements PositionDependentRecord, PersistRecord {
|
||||||
|
|
||||||
private int _persistId; // Found from PersistPtrHolder
|
private int _persistId; // Found from PersistPtrHolder
|
||||||
|
|
||||||
@ -45,10 +46,11 @@ public class ExOleObjStg extends RecordAtom implements PersistRecord {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new empty storage container.
|
* Constructs a new empty storage container.
|
||||||
*/
|
*/
|
||||||
protected ExOleObjStg() {
|
public ExOleObjStg() {
|
||||||
_header = new byte[8];
|
_header = new byte[8];
|
||||||
_data = new byte[0];
|
_data = new byte[0];
|
||||||
|
|
||||||
|
LittleEndian.putShort(_header, 0, (short)0x10);
|
||||||
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
LittleEndian.putInt(_header, 4, _data.length);
|
LittleEndian.putInt(_header, 4, _data.length);
|
||||||
}
|
}
|
||||||
@ -90,6 +92,10 @@ public class ExOleObjStg extends RecordAtom implements PersistRecord {
|
|||||||
return new InflaterInputStream(compressedStream);
|
return new InflaterInputStream(compressedStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getRawData() {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the embedded data.
|
* Sets the embedded data.
|
||||||
*
|
*
|
||||||
@ -144,4 +150,23 @@ public class ExOleObjStg extends RecordAtom implements PersistRecord {
|
|||||||
public void setPersistId(int id) {
|
public void setPersistId(int id) {
|
||||||
_persistId = id;
|
_persistId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Our location on the disk, as of the last write out */
|
||||||
|
protected int myLastOnDiskOffset;
|
||||||
|
|
||||||
|
/** Fetch our location on the disk, as of the last write out */
|
||||||
|
public int getLastOnDiskOffset() { return myLastOnDiskOffset; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the Record's idea of where on disk it lives, after a write out.
|
||||||
|
* Use with care...
|
||||||
|
*/
|
||||||
|
public void setLastOnDiskOffset(int offset) {
|
||||||
|
myLastOnDiskOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateOtherRecordReferences(Hashtable oldToNewReferencesLookup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
108
src/scratchpad/src/org/apache/poi/hslf/record/ExVideoContainer.java
Executable file
108
src/scratchpad/src/org/apache/poi/hslf/record/ExVideoContainer.java
Executable file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* 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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container record that specifies information about external video data.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class ExVideoContainer extends RecordContainer {
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
// Links to our more interesting children
|
||||||
|
private ExMediaAtom mediaAtom;
|
||||||
|
//the UNC or local path to a video file.
|
||||||
|
private CString pathAtom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set things up, and find our more interesting children
|
||||||
|
*/
|
||||||
|
protected ExVideoContainer(byte[] source, int start, int len) {
|
||||||
|
// Grab the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Find our children
|
||||||
|
_children = Record.findChildRecords(source,start+8,len-8);
|
||||||
|
findInterestingChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through our child records, picking out the ones that are
|
||||||
|
* interesting, and saving those for use by the easy helper
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
private void findInterestingChildren() {
|
||||||
|
|
||||||
|
// First child should be the ExMediaAtom
|
||||||
|
if(_children[0] instanceof ExMediaAtom) {
|
||||||
|
mediaAtom = (ExMediaAtom)_children[0];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "First child record wasn't a ExMediaAtom, was of type " + _children[0].getRecordType());
|
||||||
|
}
|
||||||
|
if(_children[1] instanceof CString) {
|
||||||
|
pathAtom = (CString)_children[1];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "Second child record wasn't a CString, was of type " + _children[1].getRecordType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ExVideoContainer, with blank fields
|
||||||
|
*/
|
||||||
|
public ExVideoContainer() {
|
||||||
|
// Setup our header block
|
||||||
|
_header = new byte[8];
|
||||||
|
_header[0] = 0x0f; // We are a container record
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
|
||||||
|
_children = new Record[2];
|
||||||
|
_children[0] = mediaAtom = new ExMediaAtom();
|
||||||
|
_children[1] = pathAtom = new CString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are of type 4103
|
||||||
|
*/
|
||||||
|
public long getRecordType() { return RecordTypes.ExVideoContainer.typeID; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ExMediaAtom of this link
|
||||||
|
*/
|
||||||
|
public ExMediaAtom getExMediaAtom() { return mediaAtom; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Path Atom (CString) of this link
|
||||||
|
*/
|
||||||
|
public CString getPathAtom() { return pathAtom; }
|
||||||
|
|
||||||
|
}
|
@ -39,27 +39,39 @@ public class InteractiveInfoAtom extends RecordAtom
|
|||||||
/**
|
/**
|
||||||
* Action Table
|
* Action Table
|
||||||
*/
|
*/
|
||||||
public static final int ACTION_NONE = 0;
|
public static final byte ACTION_NONE = 0;
|
||||||
public static final int ACTION_MACRO = 1;
|
public static final byte ACTION_MACRO = 1;
|
||||||
public static final int ACTION_RUNPROGRAM = 2;
|
public static final byte ACTION_RUNPROGRAM = 2;
|
||||||
public static final int ACTION_JUMP = 3;
|
public static final byte ACTION_JUMP = 3;
|
||||||
public static final int ACTION_HYPERLINK = 4;
|
public static final byte ACTION_HYPERLINK = 4;
|
||||||
public static final int ACTION_OLE = 5;
|
public static final byte ACTION_OLE = 5;
|
||||||
public static final int ACTION_MEDIA = 6;
|
public static final byte ACTION_MEDIA = 6;
|
||||||
public static final int ACTION_CUSTOMSHOW = 7;
|
public static final byte ACTION_CUSTOMSHOW = 7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jump Table
|
* Jump Table
|
||||||
*/
|
*/
|
||||||
public static final int JUMP_NONE = 0;
|
public static final byte JUMP_NONE = 0;
|
||||||
public static final int JUMP_NEXTSLIDE = 1;
|
public static final byte JUMP_NEXTSLIDE = 1;
|
||||||
public static final int JUMP_PREVIOUSSLIDE = 2;
|
public static final byte JUMP_PREVIOUSSLIDE = 2;
|
||||||
public static final int JUMP_FIRSTSLIDE = 3;
|
public static final byte JUMP_FIRSTSLIDE = 3;
|
||||||
public static final int JUMP_LASTSLIDE = 4;
|
public static final byte JUMP_LASTSLIDE = 4;
|
||||||
public static final int JUMP_LASTSLIDEVIEWED = 5;
|
public static final byte JUMP_LASTSLIDEVIEWED = 5;
|
||||||
public static final int JUMP_ENDSHOW = 6;
|
public static final byte JUMP_ENDSHOW = 6;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of hyperlinks
|
||||||
|
*/
|
||||||
|
public static final byte LINK_NextSlide = 0x00;
|
||||||
|
public static final byte LINK_PreviousSlide = 0x01;
|
||||||
|
public static final byte LINK_FirstSlide = 0x02;
|
||||||
|
public static final byte LINK_LastSlide = 0x03;
|
||||||
|
public static final byte LINK_CustomShow = 0x06;
|
||||||
|
public static final byte LINK_SlideNumber = 0x07;
|
||||||
|
public static final byte LINK_Url = 0x08;
|
||||||
|
public static final byte LINK_OtherPresentation = 0x09;
|
||||||
|
public static final byte LINK_OtherFile = 0x0A;
|
||||||
|
public static final byte LINK_NULL = (byte)0xFF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record header.
|
* Record header.
|
||||||
|
110
src/scratchpad/src/org/apache/poi/hslf/record/OEShapeAtom.java
Executable file
110
src/scratchpad/src/org/apache/poi/hslf/record/OEShapeAtom.java
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.util.SystemTimeUtils;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atom that contains information that describes shape client data.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class OEShapeAtom extends RecordAtom
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* record data
|
||||||
|
*/
|
||||||
|
private byte[] _recdata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a brand new link related atom record.
|
||||||
|
*/
|
||||||
|
public OEShapeAtom() {
|
||||||
|
_recdata = new byte[4];
|
||||||
|
|
||||||
|
_header = new byte[8];
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _recdata.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the link related atom record from its
|
||||||
|
* source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected OEShapeAtom(byte[] source, int start, int len) {
|
||||||
|
// Get the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Grab the record data
|
||||||
|
_recdata = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the record type.
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() { return RecordTypes.OEShapeAtom.typeID; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*
|
||||||
|
* @param out the output stream to write to.
|
||||||
|
* @throws java.io.IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_recdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shape flags.
|
||||||
|
*
|
||||||
|
* @return shape flags.
|
||||||
|
*/
|
||||||
|
public int getOptions(){
|
||||||
|
return LittleEndian.getInt(_recdata, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shape flags.
|
||||||
|
*
|
||||||
|
* @param id shape flags.
|
||||||
|
*/
|
||||||
|
public void setOptions(int id){
|
||||||
|
LittleEndian.putInt(_recdata, 0, id);
|
||||||
|
}
|
||||||
|
}
|
@ -77,7 +77,7 @@ public class RecordTypes {
|
|||||||
public static final Type BookmarkSeedAtom = new Type(2025,null);
|
public static final Type BookmarkSeedAtom = new Type(2025,null);
|
||||||
public static final Type ColorSchemeAtom = new Type(2032,ColorSchemeAtom.class);
|
public static final Type ColorSchemeAtom = new Type(2032,ColorSchemeAtom.class);
|
||||||
public static final Type ExObjRefAtom = new Type(3009,null);
|
public static final Type ExObjRefAtom = new Type(3009,null);
|
||||||
public static final Type OEShapeAtom = new Type(3009,null);
|
public static final Type OEShapeAtom = new Type(3009,OEShapeAtom.class);
|
||||||
public static final Type OEPlaceholderAtom = new Type(3011,OEPlaceholderAtom.class);
|
public static final Type OEPlaceholderAtom = new Type(3011,OEPlaceholderAtom.class);
|
||||||
public static final Type GPopublicintAtom = new Type(3024,null);
|
public static final Type GPopublicintAtom = new Type(3024,null);
|
||||||
public static final Type GRatioAtom = new Type(3031,null);
|
public static final Type GRatioAtom = new Type(3031,null);
|
||||||
@ -128,11 +128,11 @@ public class RecordTypes {
|
|||||||
public static final Type DateTimeMCAtom = new Type(4087,null);
|
public static final Type DateTimeMCAtom = new Type(4087,null);
|
||||||
public static final Type GenericDateMCAtom = new Type(4088,null);
|
public static final Type GenericDateMCAtom = new Type(4088,null);
|
||||||
public static final Type FooterMCAtom = new Type(4090,null);
|
public static final Type FooterMCAtom = new Type(4090,null);
|
||||||
public static final Type ExControlAtom = new Type(4091,null);
|
public static final Type ExControlAtom = new Type(4091,ExControlAtom.class);
|
||||||
public static final Type ExMediaAtom = new Type(4100,null);
|
public static final Type ExMediaAtom = new Type(4100,ExMediaAtom.class);
|
||||||
public static final Type ExVideo = new Type(4101,null);
|
public static final Type ExVideoContainer = new Type(4101,ExVideoContainer.class);
|
||||||
public static final Type ExAviMovie = new Type(4102,null);
|
public static final Type ExAviMovie = new Type(4102,ExAviMovie.class);
|
||||||
public static final Type ExMCIMovie = new Type(4103,null);
|
public static final Type ExMCIMovie = new Type(4103,ExMCIMovie.class);
|
||||||
public static final Type ExMIDIAudio = new Type(4109,null);
|
public static final Type ExMIDIAudio = new Type(4109,null);
|
||||||
public static final Type ExCDAudio = new Type(4110,null);
|
public static final Type ExCDAudio = new Type(4110,null);
|
||||||
public static final Type ExWAVAudioEmbedded = new Type(4111,null);
|
public static final Type ExWAVAudioEmbedded = new Type(4111,null);
|
||||||
@ -140,7 +140,8 @@ public class RecordTypes {
|
|||||||
public static final Type ExOleObjStg = new Type(4113,ExOleObjStg.class);
|
public static final Type ExOleObjStg = new Type(4113,ExOleObjStg.class);
|
||||||
public static final Type ExCDAudioAtom = new Type(4114,null);
|
public static final Type ExCDAudioAtom = new Type(4114,null);
|
||||||
public static final Type ExWAVAudioEmbeddedAtom = new Type(4115,null);
|
public static final Type ExWAVAudioEmbeddedAtom = new Type(4115,null);
|
||||||
public static final Type AnimationInfoAtom = new Type(4116,null);
|
public static final Type AnimationInfo = new Type(4116,AnimationInfo.class);
|
||||||
|
public static final Type AnimationInfoAtom = new Type(4081,AnimationInfoAtom.class);
|
||||||
public static final Type RTFDateTimeMCAtom = new Type(4117,null);
|
public static final Type RTFDateTimeMCAtom = new Type(4117,null);
|
||||||
public static final Type ProgTags = new Type(5000,DummyPositionSensitiveRecordWithChildren.class);
|
public static final Type ProgTags = new Type(5000,DummyPositionSensitiveRecordWithChildren.class);
|
||||||
public static final Type ProgStringTag = new Type(5001,null);
|
public static final Type ProgStringTag = new Type(5001,null);
|
||||||
|
@ -367,8 +367,14 @@ public class StyleTextPropAtom extends RecordAtom
|
|||||||
|
|
||||||
rawContents = baos.toByteArray();
|
rawContents = baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setRawContents(byte[] bytes) {
|
||||||
|
rawContents = bytes;
|
||||||
|
reserved = new byte[0];
|
||||||
|
initialised = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Create a new Paragraph TextPropCollection, and add it to the list
|
* Create a new Paragraph TextPropCollection, and add it to the list
|
||||||
* @param charactersCovered The number of characters this TextPropCollection will cover
|
* @param charactersCovered The number of characters this TextPropCollection will cover
|
||||||
* @return the new TextPropCollection, which will then be in the list
|
* @return the new TextPropCollection, which will then be in the list
|
||||||
|
@ -53,7 +53,7 @@ public class TextRulerAtom extends RecordAtom {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new empty ruler atom.
|
* Constructs a new empty ruler atom.
|
||||||
*/
|
*/
|
||||||
protected TextRulerAtom() {
|
public TextRulerAtom() {
|
||||||
_header = new byte[8];
|
_header = new byte[8];
|
||||||
_data = new byte[0];
|
_data = new byte[0];
|
||||||
|
|
||||||
@ -191,4 +191,19 @@ public class TextRulerAtom extends RecordAtom {
|
|||||||
public int[] getBulletOffsets(){
|
public int[] getBulletOffsets(){
|
||||||
return bulletOffsets;
|
return bulletOffsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TextRulerAtom getParagraphInstance(){
|
||||||
|
byte[] data = new byte[] {
|
||||||
|
0x00, 0x00, (byte)0xA6, 0x0F, 0x0A, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01
|
||||||
|
};
|
||||||
|
TextRulerAtom ruler = new TextRulerAtom(data, 0, data.length);
|
||||||
|
return ruler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParagraphIndent(short tetxOffset, short bulletOffset){
|
||||||
|
LittleEndian.putShort(_data, 4, tetxOffset);
|
||||||
|
LittleEndian.putShort(_data, 6, bulletOffset);
|
||||||
|
LittleEndian.putShort(_data, 8, bulletOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,6 +687,7 @@ public class RichTextRun {
|
|||||||
*/
|
*/
|
||||||
public void setBulletFont(int idx) {
|
public void setBulletFont(int idx) {
|
||||||
setParaTextPropVal("bullet.font", idx);
|
setParaTextPropVal("bullet.font", idx);
|
||||||
|
setFlag(false, ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,11 +24,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherBSERecord;
|
import org.apache.poi.ddf.EscherBSERecord;
|
||||||
import org.apache.poi.ddf.EscherContainerRecord;
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
@ -38,21 +34,9 @@ import org.apache.poi.hslf.HSLFSlideShow;
|
|||||||
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
import org.apache.poi.hslf.model.*;
|
import org.apache.poi.hslf.model.*;
|
||||||
import org.apache.poi.hslf.record.Document;
|
import org.apache.poi.hslf.model.Notes;
|
||||||
import org.apache.poi.hslf.record.DocumentAtom;
|
import org.apache.poi.hslf.model.Slide;
|
||||||
import org.apache.poi.hslf.record.FontCollection;
|
import org.apache.poi.hslf.record.*;
|
||||||
import org.apache.poi.hslf.record.FontEntityAtom;
|
|
||||||
import org.apache.poi.hslf.record.HeadersFootersContainer;
|
|
||||||
import org.apache.poi.hslf.record.ParentAwareRecord;
|
|
||||||
import org.apache.poi.hslf.record.PersistPtrHolder;
|
|
||||||
import org.apache.poi.hslf.record.PositionDependentRecord;
|
|
||||||
import org.apache.poi.hslf.record.PositionDependentRecordContainer;
|
|
||||||
import org.apache.poi.hslf.record.Record;
|
|
||||||
import org.apache.poi.hslf.record.RecordContainer;
|
|
||||||
import org.apache.poi.hslf.record.RecordTypes;
|
|
||||||
import org.apache.poi.hslf.record.SlideListWithText;
|
|
||||||
import org.apache.poi.hslf.record.SlidePersistAtom;
|
|
||||||
import org.apache.poi.hslf.record.UserEditAtom;
|
|
||||||
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
|
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
|
||||||
import org.apache.poi.util.ArrayUtil;
|
import org.apache.poi.util.ArrayUtil;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
@ -590,9 +574,8 @@ public final class SlideShow {
|
|||||||
* Create a blank <code>Slide</code>.
|
* Create a blank <code>Slide</code>.
|
||||||
*
|
*
|
||||||
* @return the created <code>Slide</code>
|
* @return the created <code>Slide</code>
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public Slide createSlide() throws IOException {
|
public Slide createSlide() {
|
||||||
SlideListWithText slist = null;
|
SlideListWithText slist = null;
|
||||||
|
|
||||||
// We need to add the records to the SLWT that deals
|
// We need to add the records to the SLWT that deals
|
||||||
@ -660,9 +643,13 @@ public final class SlideShow {
|
|||||||
for (int i = 0; i < _records.length; i++) {
|
for (int i = 0; i < _records.length; i++) {
|
||||||
Record record = _records[i];
|
Record record = _records[i];
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
record.writeOut(out);
|
try {
|
||||||
|
record.writeOut(out);
|
||||||
|
} catch (IOException e){
|
||||||
|
throw new HSLFException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// Grab interesting records as they come past
|
// Grab interesting records as they come past
|
||||||
if(_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID){
|
if(_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID){
|
||||||
ptr = (PersistPtrHolder)_records[i];
|
ptr = (PersistPtrHolder)_records[i];
|
||||||
}
|
}
|
||||||
@ -888,4 +875,72 @@ public final class SlideShow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a movie in this presentation
|
||||||
|
*
|
||||||
|
* @param path the path or url to the movie
|
||||||
|
* @return 0-based index of the movie
|
||||||
|
*/
|
||||||
|
public int addMovie(String path, int type) {
|
||||||
|
ExObjList lst = (ExObjList)_documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
|
||||||
|
if(lst == null){
|
||||||
|
lst = new ExObjList();
|
||||||
|
_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
|
||||||
|
}
|
||||||
|
|
||||||
|
ExObjListAtom objAtom = lst.getExObjListAtom();
|
||||||
|
//increment the object ID seed
|
||||||
|
int objectId = (int)objAtom.getObjectIDSeed() + 1;
|
||||||
|
objAtom.setObjectIDSeed(objectId);
|
||||||
|
ExMCIMovie mci;
|
||||||
|
switch (type){
|
||||||
|
case MovieShape.MOVIE_MPEG:
|
||||||
|
mci = new ExMCIMovie();
|
||||||
|
break;
|
||||||
|
case MovieShape.MOVIE_AVI:
|
||||||
|
mci = new ExAviMovie();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported Movie: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
lst.appendChildRecord(mci);
|
||||||
|
ExVideoContainer exVideo = mci.getExVideo();
|
||||||
|
exVideo.getExMediaAtom().setObjectId(objectId);
|
||||||
|
exVideo.getExMediaAtom().setMask(0xE80000);
|
||||||
|
exVideo.getPathAtom().setText(path);
|
||||||
|
return objectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a control in this presentation
|
||||||
|
*
|
||||||
|
* @param name name of the control, e.g. "Shockwave Flash Object"
|
||||||
|
* @param progId OLE Programmatic Identifier, e.g. "ShockwaveFlash.ShockwaveFlash.9"
|
||||||
|
* @return 0-based index of the control
|
||||||
|
*/
|
||||||
|
public int addControl(String name, String progId) {
|
||||||
|
ExObjList lst = _documentRecord.getExObjList();
|
||||||
|
if (lst == null) {
|
||||||
|
lst = new ExObjList();
|
||||||
|
_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
|
||||||
|
}
|
||||||
|
ExObjListAtom objAtom = lst.getExObjListAtom();
|
||||||
|
//increment the object ID seed
|
||||||
|
int objectId = (int) objAtom.getObjectIDSeed() + 1;
|
||||||
|
objAtom.setObjectIDSeed(objectId);
|
||||||
|
ExControl ctrl = new ExControl();
|
||||||
|
ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
|
||||||
|
oleObj.setObjID(objectId);
|
||||||
|
oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
|
||||||
|
oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
|
||||||
|
oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
|
||||||
|
|
||||||
|
ctrl.setProgId(progId);
|
||||||
|
ctrl.setMenuName(name);
|
||||||
|
ctrl.setClipboardName(name);
|
||||||
|
lst.addChildAfter(ctrl, objAtom);
|
||||||
|
|
||||||
|
return objectId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
66
src/scratchpad/testcases/org/apache/poi/hslf/model/TestMovieShape.java
Executable file
66
src/scratchpad/testcases/org/apache/poi/hslf/model/TestMovieShape.java
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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 junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.hslf.HSLFSlideShow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test <code>MovieShape</code> object.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestMovieShape extends TestCase {
|
||||||
|
|
||||||
|
protected String cwd = System.getProperty("HSLF.testdata.path");
|
||||||
|
|
||||||
|
public void testCreate() throws Exception {
|
||||||
|
SlideShow ppt = new SlideShow();
|
||||||
|
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
String path = cwd + "/test-movie.mpg";
|
||||||
|
int movieIdx = ppt.addMovie(path, MovieShape.MOVIE_MPEG);
|
||||||
|
int thumbnailIdx = ppt.addPicture(new File(cwd, "tomcat.png"), Picture.PNG);
|
||||||
|
|
||||||
|
MovieShape shape = new MovieShape(movieIdx, thumbnailIdx);
|
||||||
|
shape.setAnchor(new Rectangle2D.Float(300,225,120,90));
|
||||||
|
slide.addShape(shape);
|
||||||
|
|
||||||
|
assertEquals(path, shape.getPath());
|
||||||
|
assertTrue(shape.isAutoPlay());
|
||||||
|
shape.setAutoPlay(false);
|
||||||
|
assertFalse(shape.isAutoPlay());
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ppt.write(out);
|
||||||
|
|
||||||
|
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||||
|
slide = ppt.getSlides()[0];
|
||||||
|
shape = (MovieShape)slide.getShapes()[0];
|
||||||
|
assertEquals(path, shape.getPath());
|
||||||
|
assertFalse(shape.isAutoPlay());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
Executable file
63
src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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 junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.hslf.HSLFSlideShow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test <code>Table</code> object.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestTable extends TestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that ShapeFactory works properly and returns <code>Table</code>
|
||||||
|
*/
|
||||||
|
public void testShapeFactory() throws Exception {
|
||||||
|
SlideShow ppt = new SlideShow();
|
||||||
|
|
||||||
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
|
Table tbl = new Table(2, 5);
|
||||||
|
slide.addShape(tbl);
|
||||||
|
|
||||||
|
assertTrue(slide.getShapes()[0] instanceof Table);
|
||||||
|
Table tbl2 = (Table)slide.getShapes()[0];
|
||||||
|
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
|
||||||
|
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ppt.write(out);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||||
|
slide = ppt.getSlides()[0];
|
||||||
|
assertTrue(slide.getShapes()[0] instanceof Table);
|
||||||
|
Table tbl3 = (Table)slide.getShapes()[0];
|
||||||
|
assertEquals(tbl.getNumberOfColumns(), tbl3.getNumberOfColumns());
|
||||||
|
assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.apache.poi.util.HexDump;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link HeadersFootersAtom} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestAnimationInfoAtom extends TestCase {
|
||||||
|
// From a real file
|
||||||
|
/*
|
||||||
|
<AnimationInfoAtom info="1" type="4081" size="28" offset="4015" header="01 00 F1 0F 1C 00 00 00 ">
|
||||||
|
00 00 00 07 04 05 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00
|
||||||
|
</AnimationInfoAtom>
|
||||||
|
*/
|
||||||
|
private byte[] data = new byte[] {
|
||||||
|
0x01, 0x00, (byte)0xF1, 0x0F, 0x1C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
AnimationInfoAtom record = new AnimationInfoAtom(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.AnimationInfoAtom.typeID, record.getRecordType());
|
||||||
|
assertTrue(record.getFlag(AnimationInfoAtom.Automatic));
|
||||||
|
assertTrue(record.getFlag(AnimationInfoAtom.Play));
|
||||||
|
assertTrue(record.getFlag(AnimationInfoAtom.Synchronous));
|
||||||
|
assertFalse(record.getFlag(AnimationInfoAtom.Reverse));
|
||||||
|
assertFalse(record.getFlag(AnimationInfoAtom.Sound));
|
||||||
|
assertFalse(record.getFlag(AnimationInfoAtom.StopSound));
|
||||||
|
assertFalse(record.getFlag(AnimationInfoAtom.Hide));
|
||||||
|
assertFalse(record.getFlag(AnimationInfoAtom.AnimateBg));
|
||||||
|
assertEquals(0x07000000, record.getDimColor());
|
||||||
|
assertEquals(0, record.getSoundIdRef());
|
||||||
|
assertEquals(0, record.getDelayTime());
|
||||||
|
assertEquals(2, record.getOrderID());
|
||||||
|
assertEquals(0, record.getSlideCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
AnimationInfoAtom record = new AnimationInfoAtom(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
AnimationInfoAtom record = new AnimationInfoAtom();
|
||||||
|
record.setDimColor(0x07000000);
|
||||||
|
record.setOrderID(2);
|
||||||
|
record.setFlag(AnimationInfoAtom.Automatic, true);
|
||||||
|
record.setFlag(AnimationInfoAtom.Play, true);
|
||||||
|
record.setFlag(AnimationInfoAtom.Synchronous, true);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
127
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExControl.java
Executable file
127
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExControl.java
Executable file
@ -0,0 +1,127 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link org.apache.poi.hslf.record.ExControl} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestExControl extends TestCase {
|
||||||
|
|
||||||
|
// From a real file (embedded SWF control)
|
||||||
|
/*
|
||||||
|
<ExControl info="15" type="4078" size="218" offset="76" header="0F 00 EE 0F DA 00 00 00 ">
|
||||||
|
<ExControlAtom info="0" type="4091" size="4" offset="84" header="00 00 FB 0F 04 00 00 00 ">
|
||||||
|
00 01 00 00
|
||||||
|
</ExControlAtom>
|
||||||
|
<ExOleObjAtom info="1" type="4035" size="24" offset="96" header="01 00 C3 0F 18 00 00 00 ">
|
||||||
|
01 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 96 13 00
|
||||||
|
</ExOleObjAtom>
|
||||||
|
<CString info="16" type="4026" size="44" offset="128" header="10 00 BA 0F 2C 00 00 00 ">
|
||||||
|
53 00 68 00 6F 00 63 00 6B 00 77 00 61 00 76 00 65 00 20 00 46 00 6C 00 61
|
||||||
|
00 73 00 68 00 20 00 4F 00 62 00 6A 00 65 00 63 00 74 00
|
||||||
|
</CString>
|
||||||
|
<CString info="32" type="4026" size="62" offset="180" header="20 00 BA 0F 3E 00 00 00 ">
|
||||||
|
53 00 68 00 6F 00 63 00 6B 00 77 00 61 00 76 00 65 00 46 00 6C 00 61 00 73
|
||||||
|
00 68 00 2E 00 53 00 68 00 6F 00 63 00 6B 00 77 00 61 00 76 00 65 00 46 00
|
||||||
|
6C 00 61 00 73 00 68 00 2E 00 39 00
|
||||||
|
</CString>
|
||||||
|
<CString info="48" type="4026" size="44" offset="250" header="30 00 BA 0F 2C 00 00 00 ">
|
||||||
|
53 00 68 00 6F 00 63 00 6B 00 77 00 61 00 76 00 65 00 20 00 46 00 6C 00 61
|
||||||
|
00 73 00 68 00 20 00 4F 00 62 00 6A 00 65 00 63 00 74 00
|
||||||
|
</CString>
|
||||||
|
</ExControl>
|
||||||
|
*/
|
||||||
|
private byte[] data = new byte[] {
|
||||||
|
0x0F, 0x00, (byte)0xEE, 0x0F, (byte)0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xFB, 0x0F, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, (byte)0xC3, 0x0F, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte)0x96, 0x13, 0x00,
|
||||||
|
0x10, 0x00, (byte)0xBA, 0x0F, 0x2C, 0x00, 0x00, 0x00, 0x53, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x6B, 0x00,
|
||||||
|
0x77, 0x00, 0x61, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68,
|
||||||
|
0x00, 0x20, 0x00, 0x4F, 0x00, 0x62, 0x00, 0x6A, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, (byte)0xBA,
|
||||||
|
0x0F, 0x3E, 0x00, 0x00, 0x00, 0x53, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x77, 0x00, 0x61, 0x00,
|
||||||
|
0x76, 0x00, 0x65, 0x00, 0x46, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x2E, 0x00, 0x53, 0x00, 0x68,
|
||||||
|
0x00, 0x6F, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x77, 0x00, 0x61, 0x00, 0x76, 0x00, 0x65, 0x00, 0x46, 0x00, 0x6C, 0x00,
|
||||||
|
0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x2E, 0x00, 0x39, 0x00, 0x30, 0x00, (byte)0xBA, 0x0F, 0x2C, 0x00, 0x00, 0x00,
|
||||||
|
0x53, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x77, 0x00, 0x61, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20,
|
||||||
|
0x00, 0x46, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x20, 0x00, 0x4F, 0x00, 0x62, 0x00, 0x6A, 0x00,
|
||||||
|
0x65, 0x00, 0x63, 0x00, 0x74, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
ExControl record = new ExControl(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.ExControl.typeID, record.getRecordType());
|
||||||
|
|
||||||
|
assertNotNull(record.getExControlAtom());
|
||||||
|
assertEquals(256, record.getExControlAtom().getSlideId());
|
||||||
|
|
||||||
|
ExOleObjAtom oleObj = record.getExOleObjAtom();
|
||||||
|
assertNotNull(oleObj);
|
||||||
|
assertEquals(oleObj.getDrawAspect(), ExOleObjAtom.DRAW_ASPECT_VISIBLE);
|
||||||
|
assertEquals(oleObj.getType(), ExOleObjAtom.TYPE_CONTROL);
|
||||||
|
assertEquals(oleObj.getSubType(), ExOleObjAtom.SUBTYPE_DEFAULT);
|
||||||
|
|
||||||
|
assertEquals("Shockwave Flash Object", record.getMenuName());
|
||||||
|
assertEquals("ShockwaveFlash.ShockwaveFlash.9", record.getProgId());
|
||||||
|
assertEquals("Shockwave Flash Object", record.getClipboardName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
ExControl record = new ExControl(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
ExControl record = new ExControl();
|
||||||
|
ExControlAtom ctrl = record.getExControlAtom();
|
||||||
|
ctrl.setSlideId(256);
|
||||||
|
|
||||||
|
ExOleObjAtom oleObj = record.getExOleObjAtom();
|
||||||
|
oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
|
||||||
|
oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
|
||||||
|
oleObj.setObjID(1);
|
||||||
|
oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
|
||||||
|
oleObj.setObjStgDataRef(2);
|
||||||
|
oleObj.setOptions(1283584);
|
||||||
|
|
||||||
|
record.setMenuName("Shockwave Flash Object");
|
||||||
|
record.setProgId("ShockwaveFlash.ShockwaveFlash.9");
|
||||||
|
record.setClipboardName("Shockwave Flash Object");
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertEquals(data.length, b.length);
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
94
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExMediaAtom.java
Executable file
94
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExMediaAtom.java
Executable file
@ -0,0 +1,94 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link org.apache.poi.hslf.record.HeadersFootersAtom} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestExMediaAtom extends TestCase {
|
||||||
|
// From a real file
|
||||||
|
private byte[] data = new byte[] {
|
||||||
|
0x00, 0x00, (byte)0x04, 0x10, 0x08, 0x00, 0x00, 00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
ExMediaAtom record = new ExMediaAtom(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.ExMediaAtom.typeID, record.getRecordType());
|
||||||
|
|
||||||
|
assertEquals(1, record.getObjectId());
|
||||||
|
assertFalse(record.getFlag(ExMediaAtom.fLoop));
|
||||||
|
assertFalse(record.getFlag(ExMediaAtom.fNarration));
|
||||||
|
assertFalse(record.getFlag(ExMediaAtom.fRewind));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
ExMediaAtom record = new ExMediaAtom(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
ExMediaAtom ref = new ExMediaAtom(data, 0, data.length);
|
||||||
|
System.out.println(ref.getMask());
|
||||||
|
|
||||||
|
ExMediaAtom record = new ExMediaAtom();
|
||||||
|
record.setObjectId(1);
|
||||||
|
record.setFlag(HeadersFootersAtom.fHasDate, false);
|
||||||
|
record.setFlag(HeadersFootersAtom.fHasTodayDate, false);
|
||||||
|
record.setFlag(HeadersFootersAtom.fHasFooter, false);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFlags() throws Exception {
|
||||||
|
ExMediaAtom record = new ExMediaAtom();
|
||||||
|
|
||||||
|
//in a new record all the bits are 0
|
||||||
|
for(int i = 0; i < 3; i++) assertFalse(record.getFlag(1 << i));
|
||||||
|
|
||||||
|
record.setFlag(ExMediaAtom.fLoop, true);
|
||||||
|
assertTrue(record.getFlag(ExMediaAtom.fLoop));
|
||||||
|
|
||||||
|
record.setFlag(ExMediaAtom.fNarration, true);
|
||||||
|
assertTrue(record.getFlag(ExMediaAtom.fNarration));
|
||||||
|
|
||||||
|
record.setFlag(ExMediaAtom.fNarration, false);
|
||||||
|
assertFalse(record.getFlag(ExMediaAtom.fNarration));
|
||||||
|
|
||||||
|
record.setFlag(ExMediaAtom.fNarration, false);
|
||||||
|
assertFalse(record.getFlag(ExMediaAtom.fNarration));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
78
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExOleObjAtom.java
Executable file
78
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExOleObjAtom.java
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link ExOleObjAtom} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestExOleObjAtom extends TestCase {
|
||||||
|
// From a real file (embedded SWF control)
|
||||||
|
private byte[] data = new byte[] {
|
||||||
|
0x01, 0x00, (byte)0xC3, 0x0F, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte)0x96, 0x13, 0x00 };
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
ExOleObjAtom record = new ExOleObjAtom(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.ExOleObjAtom.typeID, record.getRecordType());
|
||||||
|
System.out.println(record);
|
||||||
|
|
||||||
|
assertEquals(record.getDrawAspect(), ExOleObjAtom.DRAW_ASPECT_VISIBLE);
|
||||||
|
assertEquals(record.getType(), ExOleObjAtom.TYPE_CONTROL);
|
||||||
|
assertEquals(record.getObjID(), 1);
|
||||||
|
assertEquals(record.getSubType(), ExOleObjAtom.SUBTYPE_DEFAULT);
|
||||||
|
assertEquals(record.getObjStgDataRef(), 2);
|
||||||
|
assertEquals(record.getOptions(), 1283584); //ther meaning is unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
ExOleObjAtom record = new ExOleObjAtom(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
ExOleObjAtom record = new ExOleObjAtom();
|
||||||
|
record.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
|
||||||
|
record.setType(ExOleObjAtom.TYPE_CONTROL);
|
||||||
|
record.setObjID(1);
|
||||||
|
record.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
|
||||||
|
record.setObjStgDataRef(2);
|
||||||
|
record.setOptions(1283584);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
144
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExOleObjStg.java
Executable file
144
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExOleObjStg.java
Executable file
@ -0,0 +1,144 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link ExOleObjStg} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestExOleObjStg extends TestCase {
|
||||||
|
|
||||||
|
// From a real file (embedded SWF control)
|
||||||
|
/*
|
||||||
|
<ExOleObjStg info="16" type="4113" size="347" offset="4322" header="10 00 11 10 5B 01 00 00 ">
|
||||||
|
00 0E 00 00 78 9C BB 70 5E F0 C1 C2 8D 52 0F 19 D0 80 1D 03 33 C3 BF FF 9C
|
||||||
|
0C 6C 48 62 8C 40 CC 04 E3 08 30 30 B0 40 C5 FE FD FF FF 1F 24 C4 0C C4 FF
|
||||||
|
47 C1 90 02 41 0C F9 40 58 C2 A0 C0 E0 CA 90 07 A4 8B 18 2A D1 93 02 5E 20
|
||||||
|
C6 C0 0A 8F 73 50 5A C8 BB 5D 73 29 77 DD 79 C1 69 3B 5C 5C 83 43 50 D5 06
|
||||||
|
BC 48 2F 2B 66 38 C9 C8 0E 64 3B 30 42 C4 9C 81 B6 83 EC 4D 05 93 C5 24 D9
|
||||||
|
0D 02 42 0C 4C 8C C8 FE 21 56 9F 02 23 C9 56 E1 04 E4 D8 4F 4D 40 89 FD A0
|
||||||
|
BC FB 17 4B BA F8 07 C5 A3 60 78 03 7A E6 FF 09 67 59 1B 41 F9 9F 95 61 34
|
||||||
|
FF 53 13 50 62 3F 4C 1F AC 1C 18 CD F7 23 0B C0 DA 74 A0 B6 1B A8 3D 37 1A
|
||||||
|
F7 23 0B A4 87 A6 85 0A 00 1B 64 6F 38 21 98 03 DA C2 E7 60 90 01 92 69 0C
|
||||||
|
39 0C 65 0C 05 40 32 11 58 2F A4 02 6B 07 3D 60 19 5D 0E 14 27 4E 05 1F 90
|
||||||
|
0C 67 C8 04 96 ED 29 C0 72 BE 1C C8 E3 06 E3 FF FF 39 18 B8 80 2C 0F A0 5C
|
||||||
|
3A 43 06 58 2D A8 A7 E1 C3 10 02 97 87 B8 02 E6 1A 60 77 83 21 18 A8 12 64
|
||||||
|
8A 23 D0 B6 1C B8 59 C8 AA 90 F5 F0 62 94 75 DC C0 DE 0A 37 5C 1D 33 54 35
|
||||||
|
88 97 08 35 91 83 81 07 EC 27 10 BF 18 E8 9B E1 0F 00 BD 65 3D D4
|
||||||
|
</ExOleObjStg>
|
||||||
|
*/
|
||||||
|
private byte[] data = new byte[] {
|
||||||
|
0x10, 0x00, 0x11, 0x10, 0x5B, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x78, (byte)0x9C, (byte)0xBB, 0x70,
|
||||||
|
0x5E, (byte)0xF0, (byte)0xC1, (byte)0xC2, (byte)0x8D, 0x52, 0x0F, 0x19, (byte)0xD0, (byte)0x80, 0x1D, 0x03,
|
||||||
|
0x33, (byte)0xC3, (byte)0xBF, (byte)0xFF, (byte)0x9C, 0x0C, 0x6C, 0x48, 0x62, (byte)0x8C, 0x40, (byte)0xCC,
|
||||||
|
0x04, (byte)0xE3, 0x08, 0x30, 0x30, (byte)0xB0, 0x40, (byte)0xC5, (byte)0xFE, (byte)0xFD, (byte)0xFF, (byte)0xFF,
|
||||||
|
0x1F, 0x24, (byte)0xC4, (byte)0x0C, (byte)0xC4, (byte)0xFF, 0x47, (byte)0xC1, (byte)0x90, 0x02, 0x41, 0x0C,
|
||||||
|
(byte)0xF9, 0x40, 0x58, (byte)0xC2, (byte)0xA0, (byte)0xC0, (byte)0xE0, (byte)0xCA, (byte)0x90, 0x07, (byte)0xA4,
|
||||||
|
(byte)0x8B, 0x18, 0x2A, (byte)0xD1, (byte)0x93, 0x02, 0x5E, 0x20, (byte)0xC6, (byte)0xC0, 0x0A, (byte)0x8F,
|
||||||
|
0x73, 0x50, 0x5A, (byte)0xC8, (byte)0xBB, 0x5D, 0x73, 0x29, 0x77, (byte)0xDD, 0x79, (byte)0xC1, 0x69, 0x3B,
|
||||||
|
0x5C, 0x5C, (byte)0x83, 0x43, 0x50, (byte)0xD5, 0x06, (byte)0xBC, 0x48, 0x2F, 0x2B, 0x66, 0x38, (byte)0xC9,
|
||||||
|
(byte)0xC8, 0x0E, 0x64, 0x3B, 0x30, 0x42, (byte)0xC4, (byte)0x9C, (byte)0x81, (byte)0xB6, (byte)0x83, (byte)0xEC,
|
||||||
|
0x4D, 0x05, (byte)0x93, (byte)0xC5, 0x24, (byte)0xD9, 0x0D, 0x02, 0x42, 0x0C, 0x4C, (byte)0x8C, (byte)0xC8,
|
||||||
|
(byte)0xFE, 0x21, 0x56, (byte)0x9F, 0x02, 0x23, (byte)0xC9, 0x56, (byte)0xE1, 0x04, (byte)0xE4, (byte)0xD8,
|
||||||
|
0x4F, 0x4D, 0x40, (byte)0x89, (byte)0xFD, (byte)0xA0, (byte)0xBC, (byte)0xFB, 0x17, 0x4B, (byte)0xBA, (byte)0xF8,
|
||||||
|
0x07, (byte)0xC5, (byte)0xA3, 0x60, 0x78, 0x03, 0x7A, (byte)0xE6, (byte)0xFF, 0x09, 0x67, 0x59, 0x1B, 0x41,
|
||||||
|
(byte)0xF9, (byte)0x9F, (byte)0x95, 0x61, 0x34, (byte)0xFF, 0x53, 0x13, 0x50, 0x62, 0x3F, 0x4C, 0x1F, (byte)0xAC,
|
||||||
|
0x1C, 0x18, (byte)0xCD, (byte)0xF7, 0x23, 0x0B, (byte)0xC0, (byte)0xDA, 0x74, (byte)0xA0, (byte)0xB6, 0x1B,
|
||||||
|
(byte)0xA8, 0x3D, 0x37, 0x1A, (byte)0xF7, 0x23, 0x0B, (byte)0xA4, (byte)0x87, (byte)0xA6, (byte)0x85, 0x0A,
|
||||||
|
0x00, 0x1B, 0x64, 0x6F, 0x38, 0x21, (byte)0x98, 0x03, (byte)0xDA, (byte)0xC2, (byte)0xE7, 0x60, (byte)0x90,
|
||||||
|
0x01, (byte)0x92, 0x69, 0x0C, 0x39, 0x0C, 0x65, 0x0C, 0x05, 0x40, 0x32, 0x11, 0x58, 0x2F, (byte)0xA4, 0x02,
|
||||||
|
0x6B, 0x07, 0x3D, 0x60, 0x19, 0x5D, 0x0E, 0x14, 0x27, 0x4E, 0x05, 0x1F, (byte)0x90, 0x0C, 0x67, (byte)0xC8,
|
||||||
|
0x04, (byte)0x96, (byte)0xED, 0x29, (byte)0xC0, 0x72, (byte)0xBE, 0x1C, (byte)0xC8, (byte)0xE3, 0x06, (byte)0xE3,
|
||||||
|
(byte)0xFF, (byte)0xFF, 0x39, 0x18, (byte)0xB8, (byte)0x80, 0x2C, 0x0F, (byte)0xA0, 0x5C, 0x3A, 0x43, 0x06, 0x58,
|
||||||
|
0x2D, (byte)0xA8, (byte)0xA7, (byte)0xE1, (byte)0xC3, 0x10, 0x02, (byte)0x97, (byte)0x87, (byte)0xB8, 0x02,
|
||||||
|
(byte)0xE6, 0x1A, 0x60, 0x77, (byte)0x83, 0x21, 0x18, (byte)0xA8, 0x12, 0x64, (byte)0x8A, 0x23, (byte)0xD0,
|
||||||
|
(byte)0xB6, 0x1C, (byte)0xB8, 0x59, (byte)0xC8, (byte)0xAA, (byte)0x90, (byte)0xF5, (byte)0xF0, 0x62, (byte)0x94,
|
||||||
|
0x75, (byte)0xDC, (byte)0xC0, (byte)0xDE, 0x0A, 0x37, 0x5C, 0x1D, 0x33, 0x54, 0x35, (byte)0x88, (byte)0x97, 0x08,
|
||||||
|
0x35, (byte)0x91, (byte)0x83, (byte)0x81, 0x07, (byte)0xEC, 0x27, 0x10, (byte)0xBF, 0x18, (byte)0xE8, (byte)0x9B,
|
||||||
|
(byte)0xE1, 0x0F, 0x00, (byte)0xBD, 0x65, 0x3D, (byte)0xD4
|
||||||
|
};
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
ExOleObjStg record = new ExOleObjStg(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.ExOleObjStg.typeID, record.getRecordType());
|
||||||
|
|
||||||
|
int len = record.getDataLength();
|
||||||
|
byte[] oledata = readAll(record.getData());
|
||||||
|
assertEquals(len, oledata.length);
|
||||||
|
|
||||||
|
POIFSFileSystem fs = new POIFSFileSystem(record.getData());
|
||||||
|
assertTrue("Constructed POIFS from ExOleObjStg data", true);
|
||||||
|
DocumentEntry doc = (DocumentEntry)fs.getRoot().getEntry("Contents");
|
||||||
|
assertNotNull(doc);
|
||||||
|
assertTrue("Fetched the Contents stream containing OLE properties", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
ExOleObjStg record = new ExOleObjStg(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
ExOleObjStg src = new ExOleObjStg(data, 0, data.length);
|
||||||
|
byte[] oledata = readAll(src.getData());
|
||||||
|
|
||||||
|
ExOleObjStg tgt = new ExOleObjStg();
|
||||||
|
tgt.setData(oledata);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(src.getDataLength(), tgt.getDataLength());
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
tgt.writeOut(out);
|
||||||
|
byte[] b = out.toByteArray();
|
||||||
|
|
||||||
|
assertEquals(data.length, b.length);
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] readAll(InputStream is) throws IOException {
|
||||||
|
int pos;
|
||||||
|
byte[] chunk = new byte[1024];
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
while((pos = is.read(chunk)) > 0){
|
||||||
|
out.write(chunk, 0, pos);
|
||||||
|
}
|
||||||
|
return out.toByteArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.record;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link HeadersFootersAtom} works properly
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestExVideoContainer extends TestCase {
|
||||||
|
|
||||||
|
// From a real file
|
||||||
|
private byte[] data = new byte[]{
|
||||||
|
0x0F, 0x00, 0x05, 0x10, (byte) 0x9E, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x04, 0x10, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, (byte)0xBA, 0x0F, (byte)0x86, 0x00, 0x00, 0x00,
|
||||||
|
0x44, 0x00, 0x3A, 0x00, 0x5C, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x6A, 0x00, 0x65, 0x00,
|
||||||
|
0x63, 0x00, 0x74, 0x00, 0x73, 0x00, 0x5C, 0x00, 0x53, 0x00, 0x63, 0x00, 0x68, 0x00, 0x75, 0x00,
|
||||||
|
0x6C, 0x00, 0x65, 0x00, 0x72, 0x00, 0x41, 0x00, 0x47, 0x00, 0x5C, 0x00, 0x6D, 0x00, 0x63, 0x00,
|
||||||
|
0x6F, 0x00, 0x6D, 0x00, 0x5F, 0x00, 0x76, 0x00, 0x5F, 0x00, 0x31, 0x00, 0x5F, 0x00, 0x30, 0x00,
|
||||||
|
0x5F, 0x00, 0x34, 0x00, 0x5C, 0x00, 0x76, 0x00, 0x69, 0x00, 0x65, 0x00, 0x77, 0x00, 0x5C, 0x00,
|
||||||
|
0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x61, 0x00, 0x5C, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,
|
||||||
|
0x74, 0x00, 0x73, 0x00, 0x5C, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00,
|
||||||
|
0x73, 0x00, 0x5C, 0x00, 0x63, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x73, 0x00, 0x2E, 0x00,
|
||||||
|
0x6D, 0x00, 0x70, 0x00, 0x67, 0x00};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
ExVideoContainer record = new ExVideoContainer(data, 0, data.length);
|
||||||
|
assertEquals(RecordTypes.ExVideoContainer.typeID, record.getRecordType());
|
||||||
|
|
||||||
|
ExMediaAtom exMedia = record.getExMediaAtom();
|
||||||
|
assertEquals(1, exMedia.getObjectId());
|
||||||
|
assertNotNull(exMedia);
|
||||||
|
assertFalse(exMedia.getFlag(ExMediaAtom.fLoop));
|
||||||
|
assertFalse(exMedia.getFlag(ExMediaAtom.fNarration));
|
||||||
|
assertFalse(exMedia.getFlag(ExMediaAtom.fRewind));
|
||||||
|
|
||||||
|
CString path = record.getPathAtom();
|
||||||
|
assertNotNull(exMedia);
|
||||||
|
assertEquals("D:\\projects\\SchulerAG\\mcom_v_1_0_4\\view\\data\\tests\\images\\cards.mpg", path.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrite() throws Exception {
|
||||||
|
ExVideoContainer record = new ExVideoContainer(data, 0, data.length);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewRecord() throws Exception {
|
||||||
|
ExVideoContainer record = new ExVideoContainer();
|
||||||
|
record.getExMediaAtom().setObjectId(1);
|
||||||
|
record.getPathAtom().setText("D:\\projects\\SchulerAG\\mcom_v_1_0_4\\view\\data\\tests\\images\\cards.mpg");
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
record.writeOut(baos);
|
||||||
|
byte[] b = baos.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(data, b));
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,10 @@ public class TestTextRulerAtom extends TestCase {
|
|||||||
0x03, 0x69, 0x04, (byte)0xF6, 0x05, (byte)0xF6, 0x05
|
0x03, 0x69, 0x04, (byte)0xF6, 0x05, (byte)0xF6, 0x05
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private byte[] data_2 = new byte[] {
|
||||||
|
0x00, 0x00, (byte)0xA6, 0x0F, 0x0A, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
public void testReadRuler() throws Exception {
|
public void testReadRuler() throws Exception {
|
||||||
TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
|
TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
|
||||||
@ -73,4 +77,16 @@ public class TestTextRulerAtom extends TestCase {
|
|||||||
byte[] result = out.toByteArray();
|
byte[] result = out.toByteArray();
|
||||||
assertTrue(Arrays.equals(result, data_1));
|
assertTrue(Arrays.equals(result, data_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRead2() throws Exception {
|
||||||
|
TextRulerAtom ruler = TextRulerAtom.getParagraphInstance();
|
||||||
|
ruler.setParagraphIndent((short)249, (short)321);
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ruler.writeOut(out);
|
||||||
|
|
||||||
|
byte[] result = out.toByteArray();
|
||||||
|
assertTrue(Arrays.equals(result, data_2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user