From: Andreas Beeker Date: Sat, 23 May 2015 22:07:05 +0000 (+0000) Subject: Creating a new slideshow and manipulating existing ones works again :) X-Git-Tag: REL_3_13_FINAL~207^2~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d49b2b6b512fa42fe82fd98eb9e58b5eeec1a94e;p=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 --- diff --git a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java index 384da258e7..3397278737 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java +++ b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java @@ -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 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 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 { diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java index e688f9959d..15fdc1991f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java @@ -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 diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java index 1afd6b1810..54f1cbf382 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java @@ -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. } ); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java index a5af73b3d3..2c8fd1dbf1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java @@ -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 textPropList = new ArrayList(); 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"); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java index e2f765723b..7441ae91c0 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java @@ -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(); charStyles = new ArrayList(); - 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; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java index 8d6626dc2b..54e7529d5d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java @@ -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 paragraphStyles; + private List 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 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 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(levels); + charStylesyles = new ArrayList(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; - } +// } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java index 36265735b8..1c6518e5e0 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java @@ -76,9 +76,9 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { TextProp prop = null; for (int i = level; i >= 0; i--) { - TextPropCollection[] styles = + List 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) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java index a6d6e5b49b..4b1e3767a7 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java @@ -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 { 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 _runs = new ArrayList(); @@ -407,7 +406,7 @@ public final class HSLFTextParagraph implements TextParagraph { * @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 { * @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 { */ 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 { 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 { 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 { 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 { 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 { 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 { 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); diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java index b4da12c4dc..9096573c7e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java @@ -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); }