git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1681389 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_13_FINAL
@@ -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); | |||
} |