mirror of https://github.com/apache/poi.git
Creating a new slideshow and manipulating existing ones works again :)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1681389 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fd637ce0ed
commit
d49b2b6b51
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.examples;
|
|||
import java.awt.*;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hslf.model.*;
|
||||
import org.apache.poi.hslf.record.TextHeaderAtom;
|
||||
|
@ -113,33 +114,29 @@ public final class ApacheconEU08 {
|
|||
slide.addShape(box1);
|
||||
|
||||
HSLFTextBox box2 = new HSLFTextBox();
|
||||
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(28);
|
||||
box2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box2.setText(
|
||||
"HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
|
||||
"Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
|
||||
"Comprehensive support of PowerPoint objects");
|
||||
box2.setAnchor(new Rectangle(36, 80, 648, 200));
|
||||
slide.addShape(box2);
|
||||
|
||||
HSLFTextBox box3 = new HSLFTextBox();
|
||||
box2.getTextParagraphs().get(0).setIndentLevel(1);
|
||||
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(24);
|
||||
box3.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box3.setText(
|
||||
"HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
|
||||
"Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
|
||||
"Comprehensive support of PowerPoint objects\r" +
|
||||
"Rich text\r" +
|
||||
"Tables\r" +
|
||||
"Shapes\r" +
|
||||
"Pictures\r" +
|
||||
"Master slides");
|
||||
box3.setAnchor(new Rectangle(36, 265, 648, 150));
|
||||
slide.addShape(box3);
|
||||
"Master slides\r" +
|
||||
"Access to low level data structures"
|
||||
);
|
||||
|
||||
HSLFTextBox box4 = new HSLFTextBox();
|
||||
box4.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box4.setText("Access to low level data structures");
|
||||
box4.setAnchor(new Rectangle(36, 430, 648, 50));
|
||||
slide.addShape(box4);
|
||||
List<HSLFTextParagraph> tp = box2.getTextParagraphs();
|
||||
for (int i : new byte[]{0,1,2,8}) {
|
||||
tp.get(i).getTextRuns().get(0).setFontSize(28);
|
||||
}
|
||||
for (int i : new byte[]{3,4,5,6,7}) {
|
||||
tp.get(i).getTextRuns().get(0).setFontSize(24);
|
||||
tp.get(i).setIndentLevel(1);
|
||||
}
|
||||
box2.setAnchor(new Rectangle(36, 80, 648, 400));
|
||||
slide.addShape(box2);
|
||||
}
|
||||
|
||||
public static void slide4(HSLFSlideShow ppt) throws IOException {
|
||||
|
@ -238,40 +235,41 @@ public final class ApacheconEU08 {
|
|||
rt3.setFontName("Courier New");
|
||||
rt3.setFontSize(8);
|
||||
box3.setText(
|
||||
" SlideShow ppt = new SlideShow();\r" +
|
||||
" Slide slide = ppt.createSlide();\r" +
|
||||
"\r" +
|
||||
" TextBox box2 = new TextBox();\r" +
|
||||
" box2.setHorizontalAlignment(TextBox.AlignCenter);\r" +
|
||||
" box2.setVerticalAlignment(TextBox.AnchorMiddle);\r" +
|
||||
" box2.getTextRun().setText(\"Java Code\");\r" +
|
||||
" box2.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||
" box2.setLineColor(Color.black);\r" +
|
||||
" box2.setLineWidth(0.75);\r" +
|
||||
" box2.setAnchor(new Rectangle(66, 243, 170, 170));\r" +
|
||||
" slide.addShape(box2);\r" +
|
||||
"\r" +
|
||||
" TextBox box3 = new TextBox();\r" +
|
||||
" box3.setHorizontalAlignment(TextBox.AlignCenter);\r" +
|
||||
" box3.setVerticalAlignment(TextBox.AnchorMiddle);\r" +
|
||||
" box3.getTextRun().setText(\"*.ppt file\");\r" +
|
||||
" box3.setLineWidth(0.75);\r" +
|
||||
" box3.setLineColor(Color.black);\r" +
|
||||
" box3.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||
" box3.setAnchor(new Rectangle(473, 243, 170, 170));\r" +
|
||||
" slide.addShape(box3);\r" +
|
||||
"\r" +
|
||||
" AutoShape box4 = new AutoShape(ShapeTypes.Arrow);\r" +
|
||||
" box4.getFill().setForegroundColor(new Color(187, 224, 227));\r" +
|
||||
" box4.setLineWidth(0.75);\r" +
|
||||
" box4.setLineColor(Color.black);\r" +
|
||||
" box4.setAnchor(new Rectangle(253, 288, 198, 85));\r" +
|
||||
" slide.addShape(box4);\r" +
|
||||
"\r" +
|
||||
" FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" +
|
||||
" ppt.write(out);\r" +
|
||||
" out.close();");
|
||||
"SlideShow ppt = new SlideShow();\u000b" +
|
||||
"Slide slide = ppt.createSlide();\u000b" +
|
||||
"\u000b" +
|
||||
"TextBox box2 = new TextBox();\u000b" +
|
||||
"box2.setHorizontalAlignment(TextBox.AlignCenter);\u000b" +
|
||||
"box2.setVerticalAlignment(TextBox.AnchorMiddle);\u000b" +
|
||||
"box2.getTextRun().setText(\"Java Code\");\u000b" +
|
||||
"box2.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" +
|
||||
"box2.setLineColor(Color.black);\u000b" +
|
||||
"box2.setLineWidth(0.75);\u000b" +
|
||||
"box2.setAnchor(new Rectangle(66, 243, 170, 170));\u000b" +
|
||||
"slide.addShape(box2);\u000b" +
|
||||
"\u000b" +
|
||||
"TextBox box3 = new TextBox();\u000b" +
|
||||
"box3.setHorizontalAlignment(TextBox.AlignCenter);\u000b" +
|
||||
"box3.setVerticalAlignment(TextBox.AnchorMiddle);\u000b" +
|
||||
"box3.getTextRun().setText(\"*.ppt file\");\u000b" +
|
||||
"box3.setLineWidth(0.75);\u000b" +
|
||||
"box3.setLineColor(Color.black);\u000b" +
|
||||
"box3.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" +
|
||||
"box3.setAnchor(new Rectangle(473, 243, 170, 170));\u000b" +
|
||||
"slide.addShape(box3);\u000b" +
|
||||
"\u000b" +
|
||||
"AutoShape box4 = new AutoShape(ShapeTypes.Arrow);\u000b" +
|
||||
"box4.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" +
|
||||
"box4.setLineWidth(0.75);\u000b" +
|
||||
"box4.setLineColor(Color.black);\u000b" +
|
||||
"box4.setAnchor(new Rectangle(253, 288, 198, 85));\u000b" +
|
||||
"slide.addShape(box4);\u000b" +
|
||||
"\u000b" +
|
||||
"FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\u000b" +
|
||||
"ppt.write(out);\u000b" +
|
||||
"out.close();");
|
||||
box3.setAnchor(new Rectangle(30, 150, 618, 411));
|
||||
box3.setHorizontalCentered(true);
|
||||
slide.addShape(box3);
|
||||
}
|
||||
|
||||
|
@ -346,45 +344,46 @@ public final class ApacheconEU08 {
|
|||
rt3.setFontName("Courier New");
|
||||
rt3.setFontSize(8);
|
||||
box3.setText(
|
||||
" //bar chart data. The first value is the bar color, the second is the width\r" +
|
||||
" Object[] def = new Object[]{\r" +
|
||||
" Color.yellow, new Integer(100),\r" +
|
||||
" Color.green, new Integer(150),\r" +
|
||||
" Color.gray, new Integer(75),\r" +
|
||||
" Color.red, new Integer(200),\r" +
|
||||
" };\r" +
|
||||
"\r" +
|
||||
" SlideShow ppt = new SlideShow();\r" +
|
||||
" Slide slide = ppt.createSlide();\r" +
|
||||
"\r" +
|
||||
" ShapeGroup group = new ShapeGroup();\r" +
|
||||
" //define position of the drawing in the slide\r" +
|
||||
" Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);\r" +
|
||||
" group.setAnchor(bounds);\r" +
|
||||
" slide.addShape(group);\r" +
|
||||
" Graphics2D graphics = new PPGraphics2D(group);\r" +
|
||||
"\r" +
|
||||
" //draw a simple bar graph\r" +
|
||||
" int x = bounds.x + 50, y = bounds.y + 50;\r" +
|
||||
" graphics.setFont(new Font(\"Arial\", Font.BOLD, 10));\r" +
|
||||
" for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {\r" +
|
||||
" graphics.setColor(Color.black);\r" +
|
||||
" int width = ((Integer)def[i+1]).intValue();\r" +
|
||||
" graphics.drawString(\"Q\" + idx, x-20, y+20);\r" +
|
||||
" graphics.drawString(width + \"%\", x + width + 10, y + 20);\r" +
|
||||
" graphics.setColor((Color)def[i]);\r" +
|
||||
" graphics.fill(new Rectangle(x, y, width, 30));\r" +
|
||||
" y += 40;\r" +
|
||||
" }\r" +
|
||||
" graphics.setColor(Color.black);\r" +
|
||||
" graphics.setFont(new Font(\"Arial\", Font.BOLD, 14));\r" +
|
||||
" graphics.draw(bounds);\r" +
|
||||
" graphics.drawString(\"Performance\", x + 70, y + 40);\r" +
|
||||
"\r" +
|
||||
" FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\r" +
|
||||
" ppt.write(out);\r" +
|
||||
" out.close();");
|
||||
"//bar chart data. The first value is the bar color, the second is the width\u000b" +
|
||||
"Object[] def = new Object[]{\u000b" +
|
||||
" Color.yellow, new Integer(100),\u000b" +
|
||||
" Color.green, new Integer(150),\u000b" +
|
||||
" Color.gray, new Integer(75),\u000b" +
|
||||
" Color.red, new Integer(200),\u000b" +
|
||||
"};\u000b" +
|
||||
"\u000b" +
|
||||
"SlideShow ppt = new SlideShow();\u000b" +
|
||||
"Slide slide = ppt.createSlide();\u000b" +
|
||||
"\u000b" +
|
||||
"ShapeGroup group = new ShapeGroup();\u000b" +
|
||||
"//define position of the drawing in the slide\u000b" +
|
||||
"Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);\u000b" +
|
||||
"group.setAnchor(bounds);\u000b" +
|
||||
"slide.addShape(group);\u000b" +
|
||||
"Graphics2D graphics = new PPGraphics2D(group);\u000b" +
|
||||
"\u000b" +
|
||||
"//draw a simple bar graph\u000b" +
|
||||
"int x = bounds.x + 50, y = bounds.y + 50;\u000b" +
|
||||
"graphics.setFont(new Font(\"Arial\", Font.BOLD, 10));\u000b" +
|
||||
"for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {\u000b" +
|
||||
" graphics.setColor(Color.black);\u000b" +
|
||||
" int width = ((Integer)def[i+1]).intValue();\u000b" +
|
||||
" graphics.drawString(\"Q\" + idx, x-20, y+20);\u000b" +
|
||||
" graphics.drawString(width + \"%\", x + width + 10, y + 20);\u000b" +
|
||||
" graphics.setColor((Color)def[i]);\u000b" +
|
||||
" graphics.fill(new Rectangle(x, y, width, 30));\u000b" +
|
||||
" y += 40;\u000b" +
|
||||
"}\u000b" +
|
||||
"graphics.setColor(Color.black);\u000b" +
|
||||
"graphics.setFont(new Font(\"Arial\", Font.BOLD, 14));\u000b" +
|
||||
"graphics.draw(bounds);\u000b" +
|
||||
"graphics.drawString(\"Performance\", x + 70, y + 40);\u000b" +
|
||||
"\u000b" +
|
||||
"FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\u000b" +
|
||||
"ppt.write(out);\u000b" +
|
||||
"out.close();");
|
||||
box3.setAnchor(new Rectangle(96, 110, 499, 378));
|
||||
box3.setHorizontalCentered(true);
|
||||
slide.addShape(box3);
|
||||
}
|
||||
|
||||
|
@ -435,38 +434,27 @@ public final class ApacheconEU08 {
|
|||
slide.addShape(box1);
|
||||
|
||||
HSLFTextBox box2 = new HSLFTextBox();
|
||||
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32);
|
||||
box2.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box2.setText(
|
||||
"Support for more PowerPoint functionality\r" +
|
||||
"Rendering slides into java.awt.Graphics2D");
|
||||
box2.setAnchor(new Rectangle(36, 126, 648, 100));
|
||||
slide.addShape(box2);
|
||||
|
||||
HSLFTextBox box3 = new HSLFTextBox();
|
||||
box3.getTextParagraphs().get(0).setIndentLevel(1);
|
||||
box3.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box3.setText(
|
||||
"A way to export slides into images or other formats");
|
||||
box3.setAnchor(new Rectangle(36, 220, 648, 70));
|
||||
slide.addShape(box3);
|
||||
|
||||
HSLFTextBox box4 = new HSLFTextBox();
|
||||
box4.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32);
|
||||
box4.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box4.setText(
|
||||
"Integration with Apache FOP - Formatting Objects Processor");
|
||||
box4.setAnchor(new Rectangle(36, 290, 648, 90));
|
||||
slide.addShape(box4);
|
||||
|
||||
HSLFTextBox box5 = new HSLFTextBox();
|
||||
box5.getTextParagraphs().get(0).setIndentLevel(1);
|
||||
box5.setRunType(TextHeaderAtom.BODY_TYPE);
|
||||
box5.setText(
|
||||
"Support for more PowerPoint functionality\r" +
|
||||
"Rendering slides into java.awt.Graphics2D\r" +
|
||||
"A way to export slides into images or other formats\r" +
|
||||
"Integration with Apache FOP - Formatting Objects Processor\r" +
|
||||
"Transformation of XSL-FO into PPT\r" +
|
||||
"PPT2PDF transcoder");
|
||||
box5.setAnchor(new Rectangle(36, 380, 648, 100));
|
||||
slide.addShape(box5);
|
||||
"PPT2PDF transcoder"
|
||||
);
|
||||
|
||||
List<HSLFTextParagraph> tp = box2.getTextParagraphs();
|
||||
for (int i : new byte[]{0,1,3}) {
|
||||
tp.get(i).getTextRuns().get(0).setFontSize(28);
|
||||
}
|
||||
for (int i : new byte[]{2,4,5}) {
|
||||
tp.get(i).getTextRuns().get(0).setFontSize(24);
|
||||
tp.get(i).setIndentLevel(1);
|
||||
}
|
||||
|
||||
box2.setAnchor(new Rectangle(36, 126, 648, 400));
|
||||
slide.addShape(box2);
|
||||
}
|
||||
|
||||
public static void slide12(HSLFSlideShow ppt) throws IOException {
|
||||
|
|
|
@ -48,26 +48,42 @@ public abstract class BitMaskTextProp extends TextProp implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* As we're purely mask based, just set flags for stuff
|
||||
* that is set
|
||||
* Calculate mask from the subPropMatches.
|
||||
*/
|
||||
public int getWriteMask() {
|
||||
return dataValue;
|
||||
/*
|
||||
* The dataValue can't be taken as a mask, as sometimes certain properties
|
||||
* are explicitly set to false, i.e. the mask says the property is defined
|
||||
* but in the actually nibble the property is set to false
|
||||
*/
|
||||
int mask = 0, i = 0;
|
||||
for (int subMask : subPropMasks) {
|
||||
if (subPropMatches[i++]) mask |= subMask;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
public void setWriteMask(int containsField) {
|
||||
int i = 0;
|
||||
for (int subMask : subPropMasks) {
|
||||
if ((containsField & subMask) != 0) subPropMatches[i] = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the text property, and recompute the sub
|
||||
* properties based on it
|
||||
* properties based on it, i.e. all unset subvalues won't be saved.
|
||||
* Use {@link #setSubValue(boolean, int)} to explicitly set subvalues to {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(int val) {
|
||||
dataValue = val;
|
||||
|
||||
// Figure out the values of the sub properties
|
||||
for(int i=0; i< subPropMatches.length; i++) {
|
||||
subPropMatches[i] = false;
|
||||
if((dataValue & subPropMasks[i]) != 0) {
|
||||
subPropMatches[i] = true;
|
||||
}
|
||||
int i = 0;
|
||||
for(int mask : subPropMasks) {
|
||||
subPropMatches[i++] = ((val & mask) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,16 +91,19 @@ public abstract class BitMaskTextProp extends TextProp implements Cloneable {
|
|||
* Fetch the true/false status of the subproperty with the given index
|
||||
*/
|
||||
public boolean getSubValue(int idx) {
|
||||
return subPropMatches[idx];
|
||||
return (dataValue & subPropMasks[idx]) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the true/false status of the subproperty with the given index
|
||||
*/
|
||||
public void setSubValue(boolean value, int idx) {
|
||||
if (subPropMatches[idx] == value) return;
|
||||
subPropMatches[idx] = value;
|
||||
dataValue ^= subPropMasks[idx];
|
||||
subPropMatches[idx] = true;
|
||||
if (value) {
|
||||
dataValue |= subPropMasks[idx];
|
||||
} else {
|
||||
dataValue &= ~subPropMasks[idx];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,20 +34,23 @@ public class CharFlagsTextProp extends BitMaskTextProp {
|
|||
|
||||
public static final String NAME = "char_flags";
|
||||
public CharFlagsTextProp() {
|
||||
super(2,0xffff, NAME, new String[] {
|
||||
super(2, 0xffff, NAME, new String[] {
|
||||
"bold", // 0x0001 A bit that specifies whether the characters are bold.
|
||||
"italic", // 0x0002 A bit that specifies whether the characters are italicized.
|
||||
"underline", // 0x0004 A bit that specifies whether the characters are underlined.
|
||||
"char_unknown_1", // 0x0008 Undefined and MUST be ignored.
|
||||
"unused1", // 0x0008 Undefined and MUST be ignored.
|
||||
"shadow", // 0x0010 A bit that specifies whether the characters have a shadow effect.
|
||||
"fehint", // 0x0020 A bit that specifies whether characters originated from double-byte input.
|
||||
"char_unknown_2", // 0x0040 Undefined and MUST be ignored.
|
||||
"unused2", // 0x0040 Undefined and MUST be ignored.
|
||||
"kumi", // 0x0080 A bit that specifies whether Kumimoji are used for vertical text.
|
||||
"strikethrough", // 0x0100 Undefined and MUST be ignored.
|
||||
"emboss", // 0x0200 A bit that specifies whether the characters are embossed.
|
||||
"char_unknown_3", // 0x0400 Undefined and MUST be ignored.
|
||||
"char_unknown_4", // 0x0800 Undefined and MUST be ignored.
|
||||
"char_unknown_5", // 0x1000 Undefined and MUST be ignored.
|
||||
"pp9rt_1", // 0x0400 An unsigned integer that specifies the run grouping of additional text properties in StyleTextProp9Atom record.
|
||||
"pp9rt_2", // 0x0800
|
||||
"pp9rt_3", // 0x1000
|
||||
"pp9rt_4", // 0x2000
|
||||
"unused4_1", // 0x4000 Undefined and MUST be ignored.
|
||||
"unused4_2", // 0x8000 Undefined and MUST be ignored.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,15 +28,128 @@ import org.apache.poi.util.LittleEndian;
|
|||
* For a given run of characters, holds the properties (which could
|
||||
* be paragraph properties or character properties).
|
||||
* Used to hold the number of characters affected, the list of active
|
||||
* properties, and the random reserved field if required.
|
||||
* properties, and the indent level if required.
|
||||
*/
|
||||
public class TextPropCollection {
|
||||
private int charactersCovered;
|
||||
private short reservedField;
|
||||
/*
|
||||
private static TextProp paragraphSpecialPropTypes[] = {
|
||||
new ParagraphFlagsTextProp(),
|
||||
new TextProp(2, 0x80, "bullet.char"),
|
||||
new TextProp(2, 0x10, "bullet.font"),
|
||||
new TextProp(2, 0x40, "bullet.size"),
|
||||
new TextProp(4, 0x20, "bullet.color"),
|
||||
new TextProp(2, 0xD00, "alignment"),
|
||||
new TextProp(2, 0x1000, "linespacing"),
|
||||
new TextProp(2, 0x2000, "spacebefore"),
|
||||
new TextProp(2, 0x4000, "spaceafter"),
|
||||
new TextProp(2, 0x8000, "text.offset"),
|
||||
new TextProp(2, 0x10000, "bullet.offset"),
|
||||
new TextProp(2, 0x20000, "defaulttab"),
|
||||
new TextProp(2, 0x40000, "para_unknown_2"),
|
||||
new TextProp(2, 0x80000, "para_unknown_3"),
|
||||
new TextProp(2, 0x100000, "para_unknown_4"),
|
||||
new TextProp(2, 0x200000, "para_unknown_5")
|
||||
};
|
||||
|
||||
private static TextProp characterSpecialPropTypes[] = {
|
||||
new CharFlagsTextProp(),
|
||||
new TextProp(2, 0x10000, "font.index"),
|
||||
new TextProp(2, 0x20000, "char_unknown_1"),
|
||||
new TextProp(4, 0x40000, "char_unknown_2"),
|
||||
new TextProp(2, 0x80000, "font.size"),
|
||||
new TextProp(2, 0x100000, "char_unknown_3"),
|
||||
new TextProp(4, 0x200000, "font.color"),
|
||||
new TextProp(2, 0x800000, "char_unknown_4")
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
/** All the different kinds of paragraph properties we might handle */
|
||||
public static final TextProp[] paragraphTextPropTypes = {
|
||||
// TextProp order is according to 2.9.20 TextPFException,
|
||||
// bitmask order can be different
|
||||
// new TextProp(0, 0x1, "hasBullet"),
|
||||
// new TextProp(0, 0x2, "hasBulletFont"),
|
||||
// new TextProp(0, 0x4, "hasBulletColor"),
|
||||
// new TextProp(0, 0x8, "hasBulletSize"),
|
||||
new ParagraphFlagsTextProp(),
|
||||
new TextProp(2, 0x80, "bullet.char"),
|
||||
new TextProp(2, 0x10, "bullet.font"),
|
||||
new TextProp(2, 0x40, "bullet.size"),
|
||||
new TextProp(4, 0x20, "bullet.color"),
|
||||
new TextAlignmentProp(),
|
||||
new TextProp(2, 0x1000, "linespacing"),
|
||||
new TextProp(2, 0x2000, "spacebefore"),
|
||||
new TextProp(2, 0x4000, "spaceafter"),
|
||||
new TextProp(2, 0x100, "text.offset"), // left margin
|
||||
// 0x200 - Undefined and MUST be ignored
|
||||
new TextProp(2, 0x400, "bullet.offset"), // indent
|
||||
new TextProp(2, 0x8000, "defaultTabSize"),
|
||||
new TabStopPropCollection(), // tabstops size is variable!
|
||||
new FontAlignmentProp(),
|
||||
new TextProp(2, 0xE0000, "wrapFlags"), // charWrap | wordWrap | overflow
|
||||
new TextProp(2, 0x200000, "textDirection"),
|
||||
// 0x400000 MUST be zero and MUST be ignored
|
||||
new TextProp(0, 0x800000, "bullet.blip"), // TODO: check size
|
||||
new TextProp(0, 0x1000000, "bullet.scheme"), // TODO: check size
|
||||
new TextProp(0, 0x2000000, "hasBulletScheme"), // TODO: check size
|
||||
// 0xFC000000 MUST be zero and MUST be ignored
|
||||
};
|
||||
/** All the different kinds of character properties we might handle */
|
||||
public static final TextProp[] characterTextPropTypes = new TextProp[] {
|
||||
// new TextProp(0, 0x1, "bold"),
|
||||
// new TextProp(0, 0x2, "italic"),
|
||||
// new TextProp(0, 0x4, "underline"),
|
||||
// new TextProp(0, 0x8, "unused1"),
|
||||
// new TextProp(0, 0x10, "shadow"),
|
||||
// new TextProp(0, 0x20, "fehint"),
|
||||
// new TextProp(0, 0x40, "unused2"),
|
||||
// new TextProp(0, 0x80, "kumi"),
|
||||
// new TextProp(0, 0x100, "strikethrough"),
|
||||
// new TextProp(0, 0x200, "emboss"),
|
||||
// new TextProp(0, 0x400, "nibble1"),
|
||||
// new TextProp(0, 0x800, "nibble2"),
|
||||
// new TextProp(0, 0x1000, "nibble3"),
|
||||
// new TextProp(0, 0x2000, "nibble4"),
|
||||
// new TextProp(0, 0x4000, "unused4"),
|
||||
// new TextProp(0, 0x8000, "unused5"),
|
||||
new TextProp(0, 0x100000, "pp10ext"),
|
||||
new TextProp(0, 0x1000000, "newAsian.font.index"), // A bit that specifies whether the newEAFontRef field of the TextCFException10 structure that contains this CFMasks exists.
|
||||
new TextProp(0, 0x2000000, "cs.font.index"), // A bit that specifies whether the csFontRef field of the TextCFException10 structure that contains this CFMasks exists.
|
||||
new TextProp(0, 0x4000000, "pp11ext"), // A bit that specifies whether the pp11ext field of the TextCFException10 structure that contains this CFMasks exists.
|
||||
new CharFlagsTextProp(),
|
||||
new TextProp(2, 0x10000, "font.index"),
|
||||
new TextProp(2, 0x200000, "asian.font.index"),
|
||||
new TextProp(2, 0x400000, "ansi.font.index"),
|
||||
new TextProp(2, 0x800000, "symbol.font.index"),
|
||||
new TextProp(2, 0x20000, "font.size"),
|
||||
new TextProp(4, 0x40000, "font.color"),
|
||||
new TextProp(2, 0x80000, "superscript")
|
||||
};
|
||||
|
||||
public enum TextPropType {
|
||||
paragraph, character;
|
||||
}
|
||||
|
||||
private int charactersCovered;
|
||||
|
||||
// indentLevel is only valid for paragraph collection
|
||||
// if it's set to -1, it must be omitted - see 2.9.36 TextMasterStyleLevel
|
||||
private short indentLevel = 0;
|
||||
private final List<TextProp> textPropList = new ArrayList<TextProp>();
|
||||
private int maskSpecial = 0;
|
||||
private final TextProp[] potentialPropList;
|
||||
private final TextPropType textPropType;
|
||||
|
||||
/**
|
||||
* Create a new collection of text properties (be they paragraph
|
||||
* or character) which will be groked via a subsequent call to
|
||||
* buildTextPropList().
|
||||
*/
|
||||
public TextPropCollection(int charactersCovered, TextPropType textPropType) {
|
||||
this.charactersCovered = charactersCovered;
|
||||
this.textPropType = textPropType;
|
||||
}
|
||||
|
||||
public int getSpecialMask() { return maskSpecial; }
|
||||
|
||||
/** Fetch the number of characters this styling applies to */
|
||||
|
@ -61,7 +174,7 @@ public class TextPropCollection {
|
|||
if (existing != null) return existing;
|
||||
|
||||
TextProp base = null;
|
||||
for (TextProp tp : potentialPropList) {
|
||||
for (TextProp tp : getPotentialProperties()) {
|
||||
if (tp.getName().equals(name)) {
|
||||
base = tp;
|
||||
break;
|
||||
|
@ -78,6 +191,10 @@ public class TextPropCollection {
|
|||
addProp(textProp);
|
||||
return textProp;
|
||||
}
|
||||
|
||||
private TextProp[] getPotentialProperties() {
|
||||
return (textPropType == TextPropType.paragraph) ? paragraphTextPropTypes : characterTextPropTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the property at the correct position. Replaces an existing property with the same name.
|
||||
|
@ -89,7 +206,7 @@ public class TextPropCollection {
|
|||
|
||||
int pos = 0;
|
||||
boolean found = false;
|
||||
for (TextProp curProp : potentialPropList) {
|
||||
for (TextProp curProp : getPotentialProperties()) {
|
||||
String potName = curProp.getName();
|
||||
if (pos == textPropList.size() || potName.equals(textProp.getName())) {
|
||||
if (textPropList.size() > pos && potName.equals(textPropList.get(pos).getName())) {
|
||||
|
@ -123,7 +240,7 @@ public class TextPropCollection {
|
|||
|
||||
// For each possible entry, see if we match the mask
|
||||
// If we do, decode that, save it, and shuffle on
|
||||
for(TextProp tp : potentialPropList) {
|
||||
for(TextProp tp : getPotentialProperties()) {
|
||||
// Check there's still data left to read
|
||||
|
||||
// Check if this property is found in the mask
|
||||
|
@ -150,6 +267,9 @@ public class TextPropCollection {
|
|||
continue;
|
||||
}
|
||||
prop.setValue(val);
|
||||
if (prop instanceof BitMaskTextProp) {
|
||||
((BitMaskTextProp)prop).setWriteMask(containsField);
|
||||
}
|
||||
bytesPassed += prop.getSize();
|
||||
addProp(prop);
|
||||
}
|
||||
|
@ -159,31 +279,12 @@ public class TextPropCollection {
|
|||
return bytesPassed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new collection of text properties (be they paragraph
|
||||
* or character) which will be groked via a subsequent call to
|
||||
* buildTextPropList().
|
||||
*/
|
||||
public TextPropCollection(int charactersCovered, short reservedField, TextProp[] potentialPropList) {
|
||||
this.charactersCovered = charactersCovered;
|
||||
this.reservedField = reservedField;
|
||||
this.potentialPropList = potentialPropList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new collection of text properties (be they paragraph
|
||||
* or character) for a run of text without any
|
||||
*/
|
||||
public TextPropCollection(int textSize, TextProp[] potentialPropList) {
|
||||
this(textSize, (short)-1, potentialPropList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the given text properties
|
||||
*/
|
||||
public void copy(TextPropCollection other) {
|
||||
this.charactersCovered = other.charactersCovered;
|
||||
this.reservedField = other.reservedField;
|
||||
this.indentLevel = other.indentLevel;
|
||||
this.maskSpecial = other.maskSpecial;
|
||||
this.textPropList.clear();
|
||||
for (TextProp tp : other.textPropList) {
|
||||
|
@ -209,17 +310,17 @@ public class TextPropCollection {
|
|||
// First goes the number of characters we affect
|
||||
StyleTextPropAtom.writeLittleEndian(charactersCovered,o);
|
||||
|
||||
// Then we have the reserved field if required
|
||||
if(reservedField > -1) {
|
||||
StyleTextPropAtom.writeLittleEndian(reservedField,o);
|
||||
// Then we have the indentLevel field if it's a paragraph collection
|
||||
if (textPropType == TextPropType.paragraph && indentLevel > -1) {
|
||||
StyleTextPropAtom.writeLittleEndian(indentLevel, o);
|
||||
}
|
||||
|
||||
// Then the mask field
|
||||
int mask = maskSpecial;
|
||||
for(TextProp textProp : textPropList) {
|
||||
//sometimes header indicates that the bitmask is present but its value is 0
|
||||
for (TextProp textProp : textPropList) {
|
||||
// sometimes header indicates that the bitmask is present but its value is 0
|
||||
if (textProp instanceof BitMaskTextProp) {
|
||||
if(mask == 0) mask |= textProp.getWriteMask();
|
||||
if (mask == 0) mask |= textProp.getWriteMask();
|
||||
}
|
||||
else {
|
||||
mask |= textProp.getWriteMask();
|
||||
|
@ -228,17 +329,12 @@ public class TextPropCollection {
|
|||
StyleTextPropAtom.writeLittleEndian(mask,o);
|
||||
|
||||
// Then the contents of all the properties
|
||||
for (TextProp potProp : potentialPropList) {
|
||||
for (TextProp potProp : getPotentialProperties()) {
|
||||
for(TextProp textProp : textPropList) {
|
||||
if (!textProp.getName().equals(potProp.getName())) continue;
|
||||
int val = textProp.getValue();
|
||||
if (textProp instanceof BitMaskTextProp && val == 0
|
||||
&& !(textProp instanceof ParagraphFlagsTextProp)
|
||||
// && !(textProp instanceof CharFlagsTextProp)
|
||||
) {
|
||||
if (textProp instanceof BitMaskTextProp && textProp.getWriteMask() == 0) {
|
||||
// don't add empty properties, as they can't be recognized while reading
|
||||
// strangely this doesn't apply for ParagraphFlagsTextProp in contrast
|
||||
// to the documentation in 2.9.20 TextPFException
|
||||
continue;
|
||||
} else if (textProp.getSize() == 2) {
|
||||
StyleTextPropAtom.writeLittleEndian((short)val,o);
|
||||
|
@ -249,12 +345,15 @@ public class TextPropCollection {
|
|||
}
|
||||
}
|
||||
|
||||
public short getReservedField(){
|
||||
return reservedField;
|
||||
public short getIndentLevel(){
|
||||
return indentLevel;
|
||||
}
|
||||
|
||||
public void setReservedField(short val){
|
||||
reservedField = val;
|
||||
public void setIndentLevel(short indentLevel) {
|
||||
if (textPropType == TextPropType.character) {
|
||||
throw new RuntimeException("trying to set an indent on a character collection.");
|
||||
}
|
||||
this.indentLevel = indentLevel;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
@ -262,7 +361,7 @@ public class TextPropCollection {
|
|||
int result = 1;
|
||||
result = prime * result + charactersCovered;
|
||||
result = prime * result + maskSpecial;
|
||||
result = prime * result + reservedField;
|
||||
result = prime * result + indentLevel;
|
||||
result = prime * result + ((textPropList == null) ? 0 : textPropList.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
@ -275,7 +374,7 @@ public class TextPropCollection {
|
|||
if (getClass() != other.getClass()) return false;
|
||||
|
||||
TextPropCollection o = (TextPropCollection)other;
|
||||
if (o.maskSpecial != this.maskSpecial || o.reservedField != this.reservedField) {
|
||||
if (o.maskSpecial != this.maskSpecial || o.indentLevel != this.indentLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -303,6 +402,16 @@ public class TextPropCollection {
|
|||
for(TextProp p : getTextPropList()) {
|
||||
out.append(" " + p.getName() + " = " + p.getValue() );
|
||||
out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
|
||||
if (p instanceof BitMaskTextProp) {
|
||||
BitMaskTextProp bm = (BitMaskTextProp)p;
|
||||
int i = 0;
|
||||
for (String s : bm.getSubPropNames()) {
|
||||
if (bm.getSubPropMatches()[i]) {
|
||||
out.append(" " + s + " = " + bm.getSubValue(i) + "\n");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.append(" bytes that would be written: \n");
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hslf.model.textproperties.*;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||
import org.apache.poi.util.*;
|
||||
|
||||
/**
|
||||
|
@ -110,66 +111,6 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
return length;
|
||||
}
|
||||
|
||||
/** All the different kinds of paragraph properties we might handle */
|
||||
public static final TextProp[] paragraphTextPropTypes = {
|
||||
// TextProp order is according to 2.9.20 TextPFException,
|
||||
// bitmask order can be different
|
||||
new TextProp(0, 0x1, "hasBullet"),
|
||||
new TextProp(0, 0x2, "hasBulletFont"),
|
||||
new TextProp(0, 0x4, "hasBulletColor"),
|
||||
new TextProp(0, 0x8, "hasBulletSize"),
|
||||
new ParagraphFlagsTextProp(),
|
||||
new TextProp(2, 0x80, "bullet.char"),
|
||||
new TextProp(2, 0x10, "bullet.font"),
|
||||
new TextProp(2, 0x40, "bullet.size"),
|
||||
new TextProp(4, 0x20, "bullet.color"),
|
||||
new TextAlignmentProp(),
|
||||
new TextProp(2, 0x1000, "linespacing"),
|
||||
new TextProp(2, 0x2000, "spacebefore"),
|
||||
new TextProp(2, 0x4000, "spaceafter"),
|
||||
new TextProp(2, 0x100, "text.offset"), // left margin
|
||||
// 0x200 - Undefined and MUST be ignored
|
||||
new TextProp(2, 0x400, "bullet.offset"), // indent
|
||||
new TextProp(2, 0x8000, "defaultTabSize"),
|
||||
new TabStopPropCollection(), // tabstops size is variable!
|
||||
new FontAlignmentProp(),
|
||||
new TextProp(2, 0xE0000, "wrapFlags"), // charWrap | wordWrap | overflow
|
||||
new TextProp(2, 0x200000, "textDirection"),
|
||||
// 0x400000 MUST be zero and MUST be ignored
|
||||
new TextProp(0, 0x800000, "bullet.blip"), // TODO: check size
|
||||
new TextProp(0, 0x1000000, "bullet.scheme"), // TODO: check size
|
||||
new TextProp(0, 0x2000000, "hasBulletScheme"), // TODO: check size
|
||||
// 0xFC000000 MUST be zero and MUST be ignored
|
||||
};
|
||||
/** All the different kinds of character properties we might handle */
|
||||
public static final TextProp[] characterTextPropTypes = new TextProp[] {
|
||||
new TextProp(0, 0x1, "bold"),
|
||||
new TextProp(0, 0x2, "italic"),
|
||||
new TextProp(0, 0x4, "underline"),
|
||||
new TextProp(0, 0x8, "unused1"),
|
||||
new TextProp(0, 0x10, "shadow"),
|
||||
new TextProp(0, 0x20, "fehint"),
|
||||
new TextProp(0, 0x40, "unused2"),
|
||||
new TextProp(0, 0x80, "kumi"),
|
||||
new TextProp(0, 0x100, "unused3"),
|
||||
new TextProp(0, 0x200, "emboss"),
|
||||
new TextProp(0, 0x400, "nibble1"),
|
||||
new TextProp(0, 0x800, "nibble2"),
|
||||
new TextProp(0, 0x1000, "nibble3"),
|
||||
new TextProp(0, 0x2000, "nibble4"),
|
||||
new TextProp(0, 0x4000, "unused4"),
|
||||
new TextProp(0, 0x8000, "unused5"),
|
||||
new CharFlagsTextProp(),
|
||||
new TextProp(2, 0x10000, "font.index"),
|
||||
new TextProp(0, 0x100000, "pp10ext"),
|
||||
new TextProp(2, 0x200000, "asian.font.index"),
|
||||
new TextProp(2, 0x400000, "ansi.font.index"),
|
||||
new TextProp(2, 0x800000, "symbol.font.index"),
|
||||
new TextProp(2, 0x20000, "font.size"),
|
||||
new TextProp(4, 0x40000, "font.color"),
|
||||
new TextProp(2, 0x80000, "superscript")
|
||||
};
|
||||
|
||||
/* *************** record code follows ********************** */
|
||||
|
||||
/**
|
||||
|
@ -217,15 +158,8 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
paragraphStyles = new ArrayList<TextPropCollection>();
|
||||
charStyles = new ArrayList<TextPropCollection>();
|
||||
|
||||
TextPropCollection defaultParagraphTextProps =
|
||||
new TextPropCollection(parentTextSize, (short)0, paragraphTextPropTypes);
|
||||
defaultParagraphTextProps.addWithName("paragraph_flags");
|
||||
paragraphStyles.add(defaultParagraphTextProps);
|
||||
|
||||
TextPropCollection defaultCharacterTextProps =
|
||||
new TextPropCollection(parentTextSize, characterTextPropTypes);
|
||||
defaultCharacterTextProps.addWithName("char_flags");
|
||||
charStyles.add(defaultCharacterTextProps);
|
||||
addParagraphTextPropCollection(parentTextSize);
|
||||
addCharacterTextPropCollection(parentTextSize);
|
||||
|
||||
// Set us as now initialised
|
||||
initialised = true;
|
||||
|
@ -269,7 +203,7 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
* contains, so we can go ahead and initialise ourselves.
|
||||
*/
|
||||
public void setParentTextSize(int size) {
|
||||
// if (initialised) return;
|
||||
if (initialised) return;
|
||||
|
||||
int pos = 0;
|
||||
int textHandled = 0;
|
||||
|
@ -295,7 +229,8 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
pos += 4;
|
||||
|
||||
// Now make sense of those properties
|
||||
TextPropCollection thisCollection = new TextPropCollection(textLen, indent, paragraphTextPropTypes);
|
||||
TextPropCollection thisCollection = new TextPropCollection(textLen, TextPropType.paragraph);
|
||||
thisCollection.setIndentLevel(indent);
|
||||
int plSize = thisCollection.buildTextPropList(paraFlags, rawContents, pos);
|
||||
pos += plSize;
|
||||
|
||||
|
@ -322,16 +257,13 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
textHandled += textLen;
|
||||
pos += 4;
|
||||
|
||||
// There is no 2 byte value
|
||||
short no_val = -1;
|
||||
|
||||
// Grab the 4 byte value that tells us what properties follow
|
||||
int charFlags = LittleEndian.getInt(rawContents,pos);
|
||||
pos += 4;
|
||||
|
||||
// Now make sense of those properties
|
||||
// (Assuming we actually have some)
|
||||
TextPropCollection thisCollection = new TextPropCollection(textLen, no_val, characterTextPropTypes);
|
||||
TextPropCollection thisCollection = new TextPropCollection(textLen, TextPropType.character);
|
||||
int chSize = thisCollection.buildTextPropList(charFlags, rawContents, pos);
|
||||
pos += chSize;
|
||||
|
||||
|
@ -386,7 +318,7 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
// Now, we do the character ones
|
||||
for(TextPropCollection tpc : charStyles) {
|
||||
// ditto for the char flags
|
||||
tpc.addWithName(CharFlagsTextProp.NAME);
|
||||
// tpc.addWithName(CharFlagsTextProp.NAME);
|
||||
tpc.writeOut(baos);
|
||||
}
|
||||
|
||||
|
@ -414,7 +346,7 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
* @return the new TextPropCollection, which will then be in the list
|
||||
*/
|
||||
public TextPropCollection addParagraphTextPropCollection(int charactersCovered) {
|
||||
TextPropCollection tpc = new TextPropCollection(charactersCovered, (short)0, paragraphTextPropTypes);
|
||||
TextPropCollection tpc = new TextPropCollection(charactersCovered, TextPropType.paragraph);
|
||||
paragraphStyles.add(tpc);
|
||||
return tpc;
|
||||
}
|
||||
|
@ -424,7 +356,7 @@ public final class StyleTextPropAtom extends RecordAtom
|
|||
* @return the new TextPropCollection, which will then be in the list
|
||||
*/
|
||||
public TextPropCollection addCharacterTextPropCollection(int charactersCovered) {
|
||||
TextPropCollection tpc = new TextPropCollection(charactersCovered, characterTextPropTypes);
|
||||
TextPropCollection tpc = new TextPropCollection(charactersCovered, TextPropType.character);
|
||||
charStyles.add(tpc);
|
||||
return tpc;
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
|
||||
import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
|
||||
import org.apache.poi.hslf.model.textproperties.TextProp;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
|
@ -48,43 +48,12 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
*/
|
||||
public static final int MAX_INDENT = 5;
|
||||
|
||||
/*
|
||||
private static TextProp paragraphSpecialPropTypes[] = {
|
||||
new ParagraphFlagsTextProp(),
|
||||
new TextProp(2, 0x80, "bullet.char"),
|
||||
new TextProp(2, 0x10, "bullet.font"),
|
||||
new TextProp(2, 0x40, "bullet.size"),
|
||||
new TextProp(4, 0x20, "bullet.color"),
|
||||
new TextProp(2, 0xD00, "alignment"),
|
||||
new TextProp(2, 0x1000, "linespacing"),
|
||||
new TextProp(2, 0x2000, "spacebefore"),
|
||||
new TextProp(2, 0x4000, "spaceafter"),
|
||||
new TextProp(2, 0x8000, "text.offset"),
|
||||
new TextProp(2, 0x10000, "bullet.offset"),
|
||||
new TextProp(2, 0x20000, "defaulttab"),
|
||||
new TextProp(2, 0x40000, "para_unknown_2"),
|
||||
new TextProp(2, 0x80000, "para_unknown_3"),
|
||||
new TextProp(2, 0x100000, "para_unknown_4"),
|
||||
new TextProp(2, 0x200000, "para_unknown_5")
|
||||
};
|
||||
|
||||
private static TextProp characterSpecialPropTypes[] = {
|
||||
new CharFlagsTextProp(),
|
||||
new TextProp(2, 0x10000, "font.index"),
|
||||
new TextProp(2, 0x20000, "char_unknown_1"),
|
||||
new TextProp(4, 0x40000, "char_unknown_2"),
|
||||
new TextProp(2, 0x80000, "font.size"),
|
||||
new TextProp(2, 0x100000, "char_unknown_3"),
|
||||
new TextProp(4, 0x200000, "font.color"),
|
||||
new TextProp(2, 0x800000, "char_unknown_4")
|
||||
};
|
||||
*/
|
||||
private byte[] _header;
|
||||
private static long _type = 4003;
|
||||
private byte[] _data;
|
||||
|
||||
private TextPropCollection[] prstyles;
|
||||
private TextPropCollection[] chstyles;
|
||||
private List<TextPropCollection> paragraphStyles;
|
||||
private List<TextPropCollection> charStylesyles;
|
||||
|
||||
protected TxMasterStyleAtom(byte[] source, int start, int len) {
|
||||
_header = new byte[8];
|
||||
|
@ -129,8 +98,8 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
*
|
||||
* @return character styles defined in this record
|
||||
*/
|
||||
public TextPropCollection[] getCharacterStyles(){
|
||||
return chstyles;
|
||||
public List<TextPropCollection> getCharacterStyles(){
|
||||
return charStylesyles;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,8 +107,8 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
*
|
||||
* @return paragraph styles defined in this record
|
||||
*/
|
||||
public TextPropCollection[] getParagraphStyles(){
|
||||
return prstyles;
|
||||
public List<TextPropCollection> getParagraphStyles(){
|
||||
return paragraphStyles;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +126,6 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
/**
|
||||
* parse the record data and initialize styles
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void init(){
|
||||
//type of the text
|
||||
int type = getTextType();
|
||||
|
@ -169,28 +137,31 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
short levels = LittleEndian.getShort(_data, 0);
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
|
||||
prstyles = new TextPropCollection[levels];
|
||||
chstyles = new TextPropCollection[levels];
|
||||
paragraphStyles = new ArrayList<TextPropCollection>(levels);
|
||||
charStylesyles = new ArrayList<TextPropCollection>(levels);
|
||||
|
||||
for(short j = 0; j < levels; j++) {
|
||||
|
||||
TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); // getParagraphProps(type, j)
|
||||
if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) {
|
||||
// Fetch the 2 byte value, that is safe to ignore for some types of text
|
||||
short val = LittleEndian.getShort(_data, pos);
|
||||
short indentLevel = LittleEndian.getShort(_data, pos);
|
||||
prprops.setIndentLevel(indentLevel);
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
} else {
|
||||
prprops.setIndentLevel((short)-1);
|
||||
}
|
||||
|
||||
head = LittleEndian.getInt(_data, pos);
|
||||
pos += LittleEndian.INT_SIZE;
|
||||
TextPropCollection prprops = new TextPropCollection(0, getParagraphProps(type, j));
|
||||
|
||||
pos += prprops.buildTextPropList( head, _data, pos);
|
||||
prstyles[j] = prprops;
|
||||
paragraphStyles.add(prprops);
|
||||
|
||||
head = LittleEndian.getInt(_data, pos);
|
||||
pos += LittleEndian.INT_SIZE;
|
||||
TextPropCollection chprops = new TextPropCollection(0, getCharacterProps(type, j));
|
||||
TextPropCollection chprops = new TextPropCollection(0, TextPropType.character); // getCharacterProps(type, j)
|
||||
pos += chprops.buildTextPropList( head, _data, pos);
|
||||
chstyles[j] = chprops;
|
||||
charStylesyles.add(chprops);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -201,12 +172,12 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
* Depending on the level and type, it may be our special
|
||||
* ones, or the standard StyleTextPropAtom ones
|
||||
*/
|
||||
protected TextProp[] getParagraphProps(int type, int level){
|
||||
return StyleTextPropAtom.paragraphTextPropTypes;
|
||||
// protected TextProp[] getParagraphProps(int type, int level){
|
||||
// return StyleTextPropAtom.paragraphTextPropTypes;
|
||||
// return (level != 0 || type >= MAX_INDENT)
|
||||
// ? StyleTextPropAtom.paragraphTextPropTypes
|
||||
// : paragraphSpecialPropTypes;
|
||||
}
|
||||
// }
|
||||
|
||||
/**
|
||||
* Character properties for the specified text type and
|
||||
|
@ -214,10 +185,10 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||
* Depending on the level and type, it may be our special
|
||||
* ones, or the standard StyleTextPropAtom ones
|
||||
*/
|
||||
protected TextProp[] getCharacterProps(int type, int level){
|
||||
return StyleTextPropAtom.characterTextPropTypes;
|
||||
// protected TextProp[] getCharacterProps(int type, int level){
|
||||
// return StyleTextPropAtom.characterTextPropTypes;
|
||||
// return (level != 0 || type >= MAX_INDENT)
|
||||
// ? StyleTextPropAtom.characterTextPropTypes
|
||||
// : characterSpecialPropTypes;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -76,9 +76,9 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
|
|||
|
||||
TextProp prop = null;
|
||||
for (int i = level; i >= 0; i--) {
|
||||
TextPropCollection[] styles =
|
||||
List<TextPropCollection> styles =
|
||||
isCharacter ? _txmaster[txtype].getCharacterStyles() : _txmaster[txtype].getParagraphStyles();
|
||||
if (i < styles.length) prop = styles[i].findByName(name);
|
||||
if (i < styles.size()) prop = styles.get(i).findByName(name);
|
||||
if (prop != null) break;
|
||||
}
|
||||
if (prop == null) {
|
||||
|
|
|
@ -18,12 +18,11 @@
|
|||
package org.apache.poi.hslf.usermodel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.poi.hslf.model.PPFont;
|
||||
import org.apache.poi.hslf.model.textproperties.*;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||
import org.apache.poi.hslf.record.*;
|
||||
import org.apache.poi.sl.usermodel.TextParagraph;
|
||||
import org.apache.poi.util.*;
|
||||
|
@ -54,7 +53,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
private TextBytesAtom _byteAtom;
|
||||
private TextCharsAtom _charAtom;
|
||||
private StyleTextPropAtom _styleAtom;
|
||||
private TextPropCollection _paragraphStyle = new TextPropCollection(1, StyleTextPropAtom.paragraphTextPropTypes);
|
||||
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
|
||||
|
||||
protected TextRulerAtom _ruler;
|
||||
protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
|
||||
|
@ -407,7 +406,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
* @return indentation level
|
||||
*/
|
||||
public int getIndentLevel() {
|
||||
return _paragraphStyle == null ? 0 : _paragraphStyle.getReservedField();
|
||||
return _paragraphStyle == null ? 0 : _paragraphStyle.getIndentLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -416,7 +415,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
* @param level indentation level. Must be in the range [0, 4]
|
||||
*/
|
||||
public void setIndentLevel(int level) {
|
||||
if( _paragraphStyle != null ) _paragraphStyle.setReservedField((short)level);
|
||||
if( _paragraphStyle != null ) _paragraphStyle.setIndentLevel((short)level);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -591,11 +590,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
*/
|
||||
protected static TextProp fetchOrAddTextProp(TextPropCollection textPropCol, String textPropName) {
|
||||
// Fetch / Add the TextProp
|
||||
TextProp tp = textPropCol.findByName(textPropName);
|
||||
if (tp == null) {
|
||||
tp = textPropCol.addWithName(textPropName);
|
||||
}
|
||||
return tp;
|
||||
return textPropCol.addWithName(textPropName);
|
||||
}
|
||||
|
||||
protected boolean getFlag(int index) {
|
||||
|
@ -621,7 +616,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
protected void setFlag(int index, boolean value) {
|
||||
// Ensure we have the StyleTextProp atom we're going to need
|
||||
if(_paragraphStyle == null) {
|
||||
_paragraphStyle = new TextPropCollection(1, StyleTextPropAtom.paragraphTextPropTypes);
|
||||
_paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
|
||||
}
|
||||
|
||||
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);
|
||||
|
@ -747,9 +742,11 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
|
||||
for (HSLFTextParagraph p : paragraphs) {
|
||||
if (newRecord == byteAtom) {
|
||||
p._byteAtom = byteAtom;
|
||||
p._charAtom = null;
|
||||
} else {
|
||||
p._byteAtom = null;
|
||||
p._charAtom = charAtom;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,8 +822,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
htp.setShapeId(prevHtp.getShapeId());
|
||||
htp.supplySheet(prevHtp.getSheet());
|
||||
paragraphs.add(htp);
|
||||
isFirst = false;
|
||||
}
|
||||
isFirst = false;
|
||||
|
||||
TextPropCollection tpc = htr.getCharacterStyle();
|
||||
// special case, last text run is empty, we will reuse it
|
||||
|
@ -1083,7 +1080,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
ccRun += ccStyle-ccRun;
|
||||
}
|
||||
|
||||
TextPropCollection pCopy = new TextPropCollection(0, StyleTextPropAtom.characterTextPropTypes);
|
||||
TextPropCollection pCopy = new TextPropCollection(0, TextPropType.character);
|
||||
pCopy.copy(p);
|
||||
trun.setCharacterStyle(pCopy);
|
||||
|
||||
|
@ -1117,7 +1114,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) {
|
||||
if (paraIdx >= paragraphs.size() || ccPara >= ccStyle-1) return;
|
||||
HSLFTextParagraph htp = paragraphs.get(paraIdx);
|
||||
TextPropCollection pCopy = new TextPropCollection(0, StyleTextPropAtom.paragraphTextPropTypes);
|
||||
TextPropCollection pCopy = new TextPropCollection(0, TextPropType.paragraph);
|
||||
pCopy.copy(p);
|
||||
htp.setParagraphStyle(pCopy);
|
||||
int len = 0;
|
||||
|
@ -1165,16 +1162,16 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||
HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, sta);
|
||||
htp.setParagraphStyle(paraStyle);
|
||||
htp._records = new Record[0];
|
||||
htp.setBullet(false);
|
||||
htp.setLineSpacing(100);
|
||||
htp.setLeftMargin(0);
|
||||
htp.setIndent(0);
|
||||
// htp.setBullet(false);
|
||||
// htp.setLineSpacing(100);
|
||||
// htp.setLeftMargin(0);
|
||||
// htp.setIndent(0);
|
||||
// set wrap flags
|
||||
|
||||
HSLFTextRun htr = new HSLFTextRun(htp);
|
||||
htr.setCharacterStyle(charStyle);
|
||||
htr.setText("\r");
|
||||
htr.setFontColor(Color.black);
|
||||
// htr.setFontColor(Color.black);
|
||||
htp.addTextRun(htr);
|
||||
|
||||
return Arrays.asList(htp);
|
||||
|
|
|
@ -22,8 +22,8 @@ import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.fetchOrAddTextProp
|
|||
import java.awt.Color;
|
||||
|
||||
import org.apache.poi.hslf.model.textproperties.*;
|
||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||
import org.apache.poi.hslf.record.ColorSchemeAtom;
|
||||
import org.apache.poi.hslf.record.StyleTextPropAtom;
|
||||
import org.apache.poi.sl.usermodel.TextRun;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -45,7 +45,7 @@ public final class HSLFTextRun implements TextRun {
|
|||
* Our paragraph and character style.
|
||||
* Note - we may share these styles with other RichTextRuns
|
||||
*/
|
||||
private TextPropCollection characterStyle = new TextPropCollection(0, StyleTextPropAtom.characterTextPropTypes);
|
||||
private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character);
|
||||
|
||||
/**
|
||||
* Create a new wrapper around a rich text string
|
||||
|
@ -60,6 +60,7 @@ public final class HSLFTextRun implements TextRun {
|
|||
}
|
||||
|
||||
public void setCharacterStyle(TextPropCollection characterStyle) {
|
||||
assert(characterStyle != null);
|
||||
this.characterStyle = characterStyle;
|
||||
}
|
||||
|
||||
|
@ -162,12 +163,6 @@ public final class HSLFTextRun implements TextRun {
|
|||
* @param val The value to set for the TextProp
|
||||
*/
|
||||
public void setCharTextPropVal(String propName, int val) {
|
||||
// Ensure we have the StyleTextProp atom we're going to need
|
||||
if(characterStyle == null) {
|
||||
characterStyle = new TextPropCollection(1, StyleTextPropAtom.characterTextPropTypes);
|
||||
// characterStyle will now be defined
|
||||
}
|
||||
|
||||
TextProp tp = fetchOrAddTextProp(characterStyle, propName);
|
||||
tp.setValue(val);
|
||||
}
|
||||
|
@ -375,11 +370,6 @@ public final class HSLFTextRun implements TextRun {
|
|||
}
|
||||
|
||||
protected void setFlag(int index, boolean value) {
|
||||
// Ensure we have the StyleTextProp atom we're going to need
|
||||
if (characterStyle == null) {
|
||||
characterStyle = new TextPropCollection(1, StyleTextPropAtom.characterTextPropTypes);
|
||||
}
|
||||
|
||||
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(characterStyle, CharFlagsTextProp.NAME);
|
||||
prop.setSubValue(value, index);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue