diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java index 5e4083ad7..1686d36da 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java @@ -45,17 +45,15 @@ public class AutoShape extends SimpleShape { short type = (short)((shapeType << 4) | 0x2); spRecord.setOptions(type); - //set default properties for a line + //set default properties for an autoshape EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLCOLOR, 134217732)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLBACKCOLOR, 134217728)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__NOFILLHITTEST, 1048592)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__COLOR, 134217729)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524296)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHADOWSTYLE__COLOR, 134217730)); - - opt.sortProperties(); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002)); return spcont; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java index 140797698..938a6a06c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java @@ -27,66 +27,69 @@ public class Line extends SimpleShape { /** * Solid (continuous) pen */ - public static final int LineSolid = 1; + public static final int PEN_SOLID = 1; /** * PS_DASH system dash style */ - public static final int LineDashSys = 2; + public static final int PEN_PS_DASH = 2; /** * PS_DOT system dash style */ - public static final int LineDotSys = 3; + public static final int PEN_DOT = 3; /** * PS_DASHDOT system dash style */ - public static final int LineDashDotSys = 4; - + public static final int PEN_DASHDOT = 4; /** * PS_DASHDOTDOT system dash style */ - public static final int LineDashDotDotSys = 5; + public static final int PEN_DASHDOTDOT = 5; /** * square dot style */ - public static final int LineDotGEL = 6; + public static final int PEN_DOTGEL = 6; /** * dash style */ - public static final int LineDashGEL = 7; + public static final int PEN_DASH = 7; /** * long dash style */ - public static final int LineLongDashGEL = 8; + public static final int PEN_LONGDASHGEL = 8; /** * dash short dash */ - public static final int LineDashDotGEL = 9; + public static final int PEN_DASHDOTGEL = 9; /** * long dash short dash */ - public static final int LineLongDashDotGEL = 10; + public static final int PEN_LONGDASHDOTGEL = 10; /** * long dash short dash short dash */ - public static final int LineLongDashDotDotGEL = 11; + public static final int PEN_LONGDASHDOTDOTGEL = 11; /** - * Decoration of the end of line, - * reserved in API but not supported. + * Single line (of width lineWidth) */ + public static final int LINE_SIMPLE = 0; + /** + * Double lines of equal width + */ + public static final int LINE_DOUBLE = 1; + /** + * Double lines, one thick, one thin + */ + public static final int LINE_THICKTHIN = 2; + /** + * Double lines, reverse order + */ + public static final int LINE_THINTHICK = 3; + /** + * Three lines, thin, thick, thin + */ + public static final int LINE_TRIPLE = 4; - /** - * Line ends at end point - */ - public static final int EndCapFlat = 0; - /** - * Rounded ends - the default - */ - public static final int EndCapRound = 1; - /** - * Square protrudes by half line width - */ - public static final int EndCapSquare = 2; protected Line(EscherContainerRecord escherRecord, Shape parent){ super(escherRecord, parent); @@ -111,7 +114,13 @@ public class Line extends SimpleShape { //set default properties for a line EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - opt.sortProperties(); + //default line properties + setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, 4); + setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, 0x10000); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); + setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0xA0008); + setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); return spcont; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java new file mode 100644 index 000000000..599a8d521 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java @@ -0,0 +1,12 @@ +package org.apache.poi.hslf.model; + +/** + * The superclass of all master sheets - Slide masters, Notes masters, etc. + * + * For now it's empty. When we understand more about masters in ppt we will add the common functionality here. + * + * @author Yegor Kozlov + */ +public abstract class MasterSheet extends Sheet { + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java index f7cf9f85a..5e1463a75 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java @@ -26,8 +26,10 @@ import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.text.AttributedCharacterIterator; import java.util.Map; +import java.util.ArrayList; import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.hslf.usermodel.RichTextRun; /** * Translates Graphics2D calls into PowerPoint. @@ -45,9 +47,9 @@ public class PPGraphics2D extends Graphics2D { private Color foreground; private Color background = Color.white; private Shape clip; - + int count = 0; /** - * Construct an powerpoint Graphics object. + * Construct Java Graphics object which translates graphic calls in ppt drawing layer. * * @param group The shape group to write the graphics calls into. */ @@ -106,8 +108,11 @@ public class PPGraphics2D extends Graphics2D { public void draw(Shape shape){ if(clip != null) { - if (!clip.getBounds().contains(transform.createTransformedShape(shape).getBounds())) { - //return; + java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); + if (bounds.width == 0) bounds.width = 1; + if (bounds.height == 0) bounds.height = 1; + if (!clip.getBounds().contains(bounds)) { + return; } } @@ -123,6 +128,8 @@ public class PPGraphics2D extends Graphics2D { if (stroke instanceof BasicStroke){ BasicStroke bs = (BasicStroke)stroke; line.setLineWidth(bs.getLineWidth()); + float[] dash = bs.getDashArray(); + if (dash != null) line.setLineDashing(Line.PEN_DASH); } if(getColor() != null) line.setLineColor(getColor()); if (type == PathIterator.SEG_LINETO) { @@ -139,24 +146,26 @@ public class PPGraphics2D extends Graphics2D { } public void drawString(String string, float x, float y){ - TextBox txt = new TextBox(group); + txt.getTextRun().supplySlideShow(group.getSheet().getSlideShow()); + txt.getTextRun().setSheet(group.getSheet()); + txt.setText(string); + + RichTextRun rt = txt.getTextRun().getRichTextRuns()[0]; + rt.setFontSize(font.getSize()); + rt.setFontName(font.getFamily()); + + if(getColor() != null) rt.setFontColor(getColor()); + if (font.isBold()) rt.setBold(true); + if (font.isItalic()) rt.setItalic(true); + txt.setMarginBottom(0); txt.setMarginTop(0); txt.setMarginLeft(0); txt.setMarginRight(0); - txt.setText(string); txt.setWordWrap(TextBox.WrapNone); - - if (font != null){ - txt.setFontSize(font.getSize()); - txt.setFontName(font.getName()); - if(getColor() != null) txt.setFontColor(getColor()); - if (font.isBold()) txt.setBold(true); - if (font.isItalic()) txt.setItalic(true); - } - txt.resizeToFitText(); + if (!"".equals(string)) txt.resizeToFitText(); int height = (int)txt.getAnchor().getHeight(); /* @@ -166,15 +175,57 @@ public class PPGraphics2D extends Graphics2D { */ txt.moveTo((int)x, (int)(y - height)); - group.addShape(txt); + if(clip != null) { + if (!clip.getBounds().contains(txt.getAnchor())) { + ;//return; + } + } + group.addShape(txt); } public void fill(Shape shape){ - if (paint instanceof Color){ - Color color = (Color)paint; + if(clip != null) { + java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); + if (bounds.width == 0) bounds.width = 1; + if (bounds.height == 0) bounds.height = 1; + if (!clip.getBounds().contains(bounds)) { + return; + } + } + PathIterator it = shape.getPathIterator(transform); + ArrayList pnt = new ArrayList(); + double[] coords = new double[6]; + while(!it.isDone()){ + int type = it.currentSegment(coords); + if (type != PathIterator.SEG_CLOSE) { + pnt.add(new Point((int)coords[0], (int)coords[1])); + } + it.next(); + } + int[] xPoints= new int[pnt.size()]; + int[] yPoints= new int[pnt.size()]; + for (int i = 0; i < pnt.size(); i++) { + Point p = (Point)pnt.get(i); + xPoints[i] = p.x; + yPoints[i] = p.y; } - throw new RuntimeException("Not implemented"); + AutoShape r = new AutoShape(ShapeTypes.Rectangle); + if (paint instanceof Color){ + Color color = (Color)paint; + r.setFillColor(color); + } + if(getColor() != null) r.setLineColor(getColor()); + if (stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)stroke; + r.setLineWidth(bs.getLineWidth()); + float[] dash = bs.getDashArray(); + if (dash != null) r.setLineDashing(Line.PEN_DASH); + } + + java.awt.Rectangle bounds = transform.createTransformedShape(shape).getBounds(); + r.setAnchor(bounds); + group.addShape(r); } public void translate(int x, int y) { @@ -458,5 +509,4 @@ public class PPGraphics2D extends Graphics2D { public void drawRenderableImage(RenderableImage renderableimage, AffineTransform affinetransform) { throw new RuntimeException("Not implemented"); } - } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index f8a86a196..f7108ce85 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -37,19 +37,16 @@ public class ShapeFactory { int type = spRecord.getOptions() >> 4; switch (type){ - case ShapeTypes.Rectangle: - EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID); - if (txtbox == null) shape = new AutoShape(spContainer, parent); - else{ - if(Shape.getEscherChild(spContainer, EscherClientDataRecord.RECORD_ID) != null ) - shape = new Placeholder(spContainer, parent); - else - shape = new TextBox(spContainer, parent); - } - break; case ShapeTypes.TextBox: shape = new TextBox(spContainer, parent); break; + case ShapeTypes.Rectangle: + EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID); + if (txtbox == null) + shape = new AutoShape(spContainer, parent); + else + shape = new TextBox(spContainer, parent); + break; case ShapeTypes.PictureFrame: shape = new Picture(spContainer, parent); break; @@ -57,7 +54,10 @@ public class ShapeFactory { shape = new Line(spContainer, parent); break; case ShapeTypes.NotPrimitive: - shape = new ShapeGroup(spContainer, parent); + if ((spRecord.getFlags() & EscherSpRecord.FLAG_GROUP) != 0) + shape = new ShapeGroup(spContainer, parent); + else + shape = new AutoShape(spContainer, parent); break; default: shape = new AutoShape(spContainer, parent); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java index 11fafdb4b..0a23d27e9 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java @@ -95,17 +95,17 @@ public class ShapeGroup extends Shape{ LittleEndian.putInt(header, 4, 8); clientAnchor.fillFields(header, 0, null); - clientAnchor.setFlag((short)anchor.y); - clientAnchor.setCol1((short)anchor.x); - clientAnchor.setDx1((short)(anchor.width + anchor.x)); - clientAnchor.setRow1((short)(anchor.height + anchor.y)); + clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI)); + clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI)); + clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI)); + clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI)); EscherSpgrRecord spgr = (EscherSpgrRecord)getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID); - spgr.setRectX1(anchor.x); - spgr.setRectY1(anchor.y); - spgr.setRectX2(anchor.x + anchor.width); - spgr.setRectY2(anchor.y + anchor.height); + spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI); + spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI); + spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI); + spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI); } /** @@ -145,6 +145,15 @@ public class ShapeGroup extends Shape{ */ public void addShape(Shape shape){ _escherContainer.addChildRecord(shape.getSpContainer()); + + Sheet sheet = getSheet(); + shape.setSheet(sheet); + shape.afterInsert(sheet); + + if(shape instanceof TextBox) { + TextBox tbox = (TextBox)shape; + getSheet().getPPDrawing().addTextboxWrapper(tbox._txtbox); + } } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index 57efcb0df..1187452f4 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -209,4 +209,18 @@ public abstract class Sheet ppdrawing.addTextboxWrapper(tbox._txtbox); } } -} + + /** + * Return the master sheet . + */ + public MasterSheet getMasterSheet(){ + return null; + } + + /** + * Color scheme for this sheet. + */ + public ColorSchemeAtom getColorScheme(){ + return null; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java index 038f00e5b..7fc1ba4ae 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java @@ -18,6 +18,7 @@ package org.apache.poi.hslf.model; import org.apache.poi.ddf.*; import org.apache.poi.util.LittleEndian; +import org.apache.poi.hslf.record.ColorSchemeAtom; import java.awt.*; @@ -105,6 +106,7 @@ public class SimpleShape extends Shape { EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, color == null ? 0x180010 : 0x180018); } /** @@ -112,13 +114,45 @@ public class SimpleShape extends Shape { */ public Color getLineColor(){ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherRGBProperty prop = (EscherRGBProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR); - Color color = Color.black; - if (prop != null){ - Color swp = new Color(prop.getRgbColor()); - color = new Color(swp.getBlue(), swp.getGreen(), swp.getRed()); + + EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR); + EscherSimpleProperty p2 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH); + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + Color clr = null; + if (p1 != null && (p2val & 0x8) != 0){ + int rgb = p1.getPropertyValue(); + if (rgb >= 0x8000000) { + int idx = rgb % 0x8000000; + ColorSchemeAtom ca = getSheet().getColorScheme(); + if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); + } + Color tmp = new Color(rgb, true); + clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); } - return color; + return clr; + } + + /** + * Gets line dashing. One of the PEN_* constants defined in this class. + * + * @return dashing of the line. + */ + public int getLineDashing(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); + return prop == null ? Line.PEN_SOLID : prop.getPropertyValue(); + } + + /** + * Sets line dashing. One of the PEN_* constants defined in this class. + * + * @param pen new style of the line. + */ + public void setLineDashing(int pen){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + + setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == Line.PEN_SOLID ? -1 : pen); } /** @@ -128,7 +162,7 @@ public class SimpleShape extends Shape { */ public void setLineStyle(int style){ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, style == Line.LineSolid ? -1 : style); + setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == Line.LINE_SIMPLE ? -1 : style); } /** @@ -138,8 +172,34 @@ public class SimpleShape extends Shape { */ public int getLineStyle(){ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); - return prop == null ? Line.LineSolid : prop.getPropertyValue(); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE); + return prop == null ? Line.LINE_SIMPLE : prop.getPropertyValue(); + } + + /** + * The color used to fill this shape. + * + * @param color the background color + */ + public Color getFillColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR); + EscherSimpleProperty p2= (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); + + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + + Color clr = null; + if (p1 != null && (p2val & 0x10) != 0){ + int rgb = p1.getPropertyValue(); + if (rgb >= 0x8000000) { + int idx = rgb % 0x8000000; + ColorSchemeAtom ca = getSheet().getColorScheme(); + rgb = ca.getColor(idx); + } + Color tmp = new Color(rgb, true); + clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); + } + return clr; } /** @@ -151,8 +211,7 @@ public class SimpleShape extends Shape { EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 1376273); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, color == null ? 0x150010 : 0x150011); } - } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java b/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java index 72f0f102e..eab57d8a0 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java @@ -24,6 +24,7 @@ import java.util.Vector; import org.apache.poi.hslf.record.PPDrawing; import org.apache.poi.hslf.record.SlideAtom; import org.apache.poi.hslf.record.TextHeaderAtom; +import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; /** @@ -81,10 +82,12 @@ public class Slide extends Sheet int i=0; for(i=0; i= 0; i--) { + TextPropCollection[] styles = + isCharacter ? _txmaster[txtype].getCharacterStyles() : _txmaster[txtype].getParagraphStyles(); + if (i < styles.length) prop = styles[i].findByName(name); + if (prop != null) break; + } + if (prop == null) { + switch (txtype) { + case TextHeaderAtom.CENTRE_BODY_TYPE: + case TextHeaderAtom.HALF_BODY_TYPE: + case TextHeaderAtom.QUARTER_BODY_TYPE: + txtype = TextHeaderAtom.BODY_TYPE; + break; + case TextHeaderAtom.CENTER_TITLE_TYPE: + txtype = TextHeaderAtom.TITLE_TYPE; + break; + default: + return null; + } + prop = getStyleAttribute(txtype, level, name, isCharacter); + } + return prop; + } + + /** + * Assign SlideShow for this slide master. + * (Used interanlly) + */ + public void setSlideShow(SlideShow ss) { + super.setSlideShow(ss); + + //after the slide show is assigned collect all available style records + if (_txmaster == null) { + _txmaster = new TxMasterStyleAtom[9]; + + TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); + _txmaster[txdoc.getTextType()] = txdoc; + + TxMasterStyleAtom[] txrec = _master.getTxMasterStyleAtoms(); + for (int i = 0; i < txrec.length; i++) { + _txmaster[txrec[i].getTextType()] = txrec[i]; + } + } + } + + /** + * Returns the ColorSchemeAtom associated with this slide master + */ + public ColorSchemeAtom getColorScheme(){ + return _master.getColorScheme(); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java index 44cee7c0e..da8098fac 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java @@ -69,11 +69,6 @@ public class TextBox extends SimpleShape { public static final int AlignRight = 2; public static final int AlignJustify = 3; - /** - * Default font size - */ - public static final int DefaultFontSize = 24; - /** * Low-level object which holds actual text and format data */ @@ -139,14 +134,12 @@ public class TextBox extends SimpleShape { EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0); - setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, 134217732); - setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 134217728); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 1048576); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 134217729); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524288); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 134217730); - - opt.sortProperties(); + setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, 0x8000004); + setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 0x8000000); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); + setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); + setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); //create EscherTextboxWrapper _txtbox = new EscherTextboxWrapper(); @@ -155,13 +148,13 @@ public class TextBox extends SimpleShape { tha.setParentRecord(_txtbox); // TextHeaderAtom is parent aware _txtbox.appendChildRecord(tha); - TextBytesAtom tba = new TextBytesAtom(); - _txtbox.appendChildRecord(tba); + TextCharsAtom tca = new TextCharsAtom(); + _txtbox.appendChildRecord(tca); StyleTextPropAtom sta = new StyleTextPropAtom(0); _txtbox.appendChildRecord(sta); - _txtrun = new TextRun(tha,tba,sta); + _txtrun = new TextRun(tha,tca,sta); _txtrun.setText(""); spcont.addChildRecord(_txtbox.getEscherRecord()); @@ -205,40 +198,31 @@ public class TextBox extends SimpleShape { } /** - * Returns the bounds of this TextFrame. - * Note, this is very primitive estimation, the precision is poor. - * - * @return the bounds of this TextFrame. + * Adjust the size of the TextBox so it encompasses the text inside it. */ - protected Dimension getTextDimensions(){ + public void resizeToFitText(){ + try{ FontRenderContext frc = new FontRenderContext(null, true, true); RichTextRun rt = _txtrun.getRichTextRuns()[0]; int size = rt.getFontSize(); - if (size == -1) size = TextBox.DefaultFontSize; int style = 0; if (rt.isBold()) style |= Font.BOLD; if (rt.isItalic()) style |= Font.ITALIC; String fntname = rt.getFontName(); - if (fntname == null) //get the default font from Document.Environment.FontCollection - fntname = getSheet().getSlideShow().getDocumentRecord().getEnvironment().getFontCollection().getFontWithId(0); Font font = new Font(fntname, style, size); TextLayout layout = new TextLayout(getText(), font, frc); int width = Math.round(layout.getAdvance()); - width += getMarginLeft() + getMarginRight() + 2; int height = Math.round(layout.getAscent()); - height += getMarginTop() + getMarginBottom() + 12; - return new Dimension(width, height); - } - /** - * Adjust the size of the TextBox so it encompasses the text inside it. - */ - public void resizeToFitText(){ - Dimension size = getTextDimensions(); + Dimension txsize = new Dimension(width, height); java.awt.Rectangle anchor = getAnchor(); - anchor.setSize(size); + anchor.setSize(txsize); setAnchor(anchor); + } catch (Exception e){ + e.printStackTrace(); + + } } /** @@ -250,7 +234,22 @@ public class TextBox extends SimpleShape { public int getVerticalAlignment(){ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT); - return prop == null ? AlignCenter : prop.getPropertyValue(); + int valign; + if (prop == null){ + int type = getTextRun().getRunType(); + switch (type){ + case TextHeaderAtom.TITLE_TYPE: + case TextHeaderAtom.CENTER_TITLE_TYPE: + valign = TextBox.AnchorMiddle; + break; + default: + valign = TextBox.AnchorTop; + break; + } + } else { + valign = prop.getPropertyValue(); + } + return valign; } /** @@ -425,129 +424,7 @@ public class TextBox extends SimpleShape { return _txtrun; } - /** - * @return array of RichTextRun objects which control text formatting in this text box - */ - public RichTextRun[] getRichTextRuns(){ - return _txtrun.getRichTextRuns(); - } - - /** - * Sets the Font object for this text frame - * - * @param size the size of the font - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setFontSize(int size){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setFontSize(size); - } - - /** - * - * @return the size of the font applied to this text shape - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public int getFontSize(){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - return rt.getFontSize(); - } - - /** - * - * @return the size of the font applied to this text shape - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public Color getFontColor(){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - Color color = new Color(rt.getFontColor()); - //in PowerPont RGB bytes are swapped, - return new Color(color.getBlue(), color.getGreen(), color.getRed(), 255); - } - - /** - * Set whether to use bold or not - * - * @param bold true if the text should be bold, false otherwise - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setBold(boolean bold){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setBold(bold); - } - - /** - * Set whether to use italic or not - * - * @param italic true if the text should be italic, false otherwise - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setItalic(boolean italic){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setItalic(italic); - } - - /** - * Set whether to use underline or not - * - * @param underline true if the text should be underlined, false otherwise - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setUnderline(boolean underline){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setUnderlined(underline); - } - - /** - * Sets the font of this text shape - * - * @param name the name of the font to be applied to this text shape - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setFontName(String name){ - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setFontName(name); - } - - /** - * Sets the font color - * @param color the font color - * - * @deprecated Use RichTextRun to work with the text format. - *

This method will be permanently removed in a future version of the POI HSLF API.

- */ - public void setFontColor(Color color){ - //in PowerPont RGB bytes are swapped, - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB(); - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - rt.setFontColor(rgb); - } - - /** - * Set type of the text. - * Must be one of the static constants defined in TextHeaderAtom - * - * @param type type of the text - */ - public void setTextType(int type){ - _txtrun._headerAtom.setTextType(type); - } - - public void setSheet(Sheet sheet){ + public void setSheet(Sheet sheet){ _sheet = sheet; // Initialize _txtrun object. @@ -564,6 +441,7 @@ public class TextBox extends SimpleShape { } // Supply the sheet to our child RichTextRuns + _txtrun.setSheet(sheet); RichTextRun[] rt = _txtrun.getRichTextRuns(); for (int i = 0; i < rt.length; i++) { rt[i].supplySlideShow(_sheet.getSlideShow()); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java index 4d45197a2..8a9d6c1f8 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java @@ -47,6 +47,7 @@ public class TextRun protected boolean _isUnicode; protected RichTextRun[] _rtRuns; private SlideShow slideShow; + private Sheet sheet; /** * Constructs a Text Run from a Unicode text block @@ -378,10 +379,12 @@ public class TextRun public synchronized void setText(String s) { // Save the new text to the atoms storeText(s); - + RichTextRun fst = _rtRuns[0]; + // Finally, zap and re-do the RichTextRuns for(int i=0; i<_rtRuns.length; i++) { _rtRuns[i] = null; } _rtRuns = new RichTextRun[1]; + _rtRuns[0] = fst; // Now handle record stylings: // If there isn't styling @@ -395,17 +398,7 @@ public class TextRun LinkedList cStyles = _styleAtom.getCharacterStyles(); while(cStyles.size() > 1) { cStyles.removeLast(); } - // Note - TextPropCollection's idea of the text length must - // be one larger than it actually is! - // (This indicates that new text added to the end should - // get the same styling as the current text) - TextPropCollection pCol = (TextPropCollection)pStyles.getFirst(); - TextPropCollection cCol = (TextPropCollection)cStyles.getFirst(); - pCol.updateTextSize(s.length()+1); - cCol.updateTextSize(s.length()+1); - - // Recreate rich text run with first styling - _rtRuns[0] = new RichTextRun(this,0,s.length(), pCol, cCol, false, false); + _rtRuns[0].setText(s); } else { // Recreate rich text run with no styling _rtRuns[0] = new RichTextRun(this,0,s.length()); @@ -515,4 +508,12 @@ public class TextRun } } } -} + + public void setSheet(Sheet sheet){ + this.sheet = sheet; + } + + public Sheet getSheet(){ + return this.sheet; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java index c0b9bf4ec..848c5d2f4 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java @@ -205,4 +205,17 @@ public class ColorSchemeAtom extends RecordAtom writeLittleEndian(accentAndHyperlinkColourRGB,out); writeLittleEndian(accentAndFollowingHyperlinkColourRGB,out); } + + /** + * Returns color by its index + * + * @param idx 0-based color index + * @return color by its index + */ + public int getColor(int idx){ + int[] clr = {backgroundColourRGB, textAndLinesColourRGB, shadowsColourRGB, titleTextColourRGB, + fillsColourRGB, accentColourRGB, accentAndHyperlinkColourRGB, accentAndFollowingHyperlinkColourRGB}; + return clr[idx]; + } + } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java b/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java index 831e9857f..cbda5e73a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java @@ -34,6 +34,8 @@ public class Environment extends PositionDependentRecordContainer // Links to our more interesting children private FontCollection fontCollection; + //master style for text with type=TextHeaderAtom.OTHER_TYPE + private TxMasterStyleAtom txmaster; /** * Returns the FontCollection of this Environment @@ -56,7 +58,9 @@ public class Environment extends PositionDependentRecordContainer for(int i=0; i<_children.length; i++) { if(_children[i] instanceof FontCollection) { fontCollection = (FontCollection)_children[i]; - } + } else if (_children[i] instanceof TxMasterStyleAtom){ + txmaster = (TxMasterStyleAtom)_children[i]; + } } if(fontCollection == null) { @@ -64,6 +68,9 @@ public class Environment extends PositionDependentRecordContainer } } + public TxMasterStyleAtom getTxMasterStyleAtom(){ + return txmaster; + } /** * We are of type 1010 diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java b/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java new file mode 100644 index 000000000..6c23f4522 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java @@ -0,0 +1,111 @@ + +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +package org.apache.poi.hslf.record; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + +import org.apache.poi.util.LittleEndian; + +/** + * Master slide + * + * @author Yegor Kozlov + */ + +public class MainMaster extends PositionDependentRecordContainer +{ + private byte[] _header; + private static long _type = 1016; + + // Links to our more interesting children + private SlideAtom slideAtom; + private PPDrawing ppDrawing; + private TxMasterStyleAtom[] txmasters; + private ColorSchemeAtom[] clrscheme; + private ColorSchemeAtom _colorScheme; + + /** + * Returns the SlideAtom of this Slide + */ + public SlideAtom getSlideAtom() { return slideAtom; } + + /** + * Returns the PPDrawing of this Slide, which has all the + * interesting data in it + */ + public PPDrawing getPPDrawing() { return ppDrawing; } + + public TxMasterStyleAtom[] getTxMasterStyleAtoms() { return txmasters; } + + public ColorSchemeAtom[] getColorSchemeAtoms() { return clrscheme; } + + /** + * Set things up, and find our more interesting children + */ + protected MainMaster(byte[] source, int start, int len) { + // Grab the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Find our children + _children = Record.findChildRecords(source,start+8,len-8); + + ArrayList tx = new ArrayList(); + ArrayList clr = new ArrayList(); + // Find the interesting ones in there + for(int i=0; i<_children.length; i++) { + if(_children[i] instanceof SlideAtom) { + slideAtom = (SlideAtom)_children[i]; + } else if(_children[i] instanceof PPDrawing) { + ppDrawing = (PPDrawing)_children[i]; + } else if(_children[i] instanceof TxMasterStyleAtom) { + tx.add(_children[i]); + } else if(_children[i] instanceof ColorSchemeAtom) { + clr.add(_children[i]); + } + + if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) { + _colorScheme = (ColorSchemeAtom)_children[i]; + } + + } + txmasters = (TxMasterStyleAtom[])tx.toArray(new TxMasterStyleAtom[tx.size()]); + clrscheme = (ColorSchemeAtom[])clr.toArray(new ColorSchemeAtom[clr.size()]); + } + + /** + * We are of type 1016 + */ + public long getRecordType() { return _type; } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0],_header[1],_type,_children,out); + } + + public ColorSchemeAtom getColorScheme(){ + return _colorScheme; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index ebb03446e..ea4c6f267 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -44,7 +44,7 @@ public class RecordTypes { public static final Type Environment = new Type(1010,Environment.class); public static final Type SlidePersistAtom = new Type(1011,SlidePersistAtom.class); public static final Type SSlideLayoutAtom = new Type(1015,null); - public static final Type MainMaster = new Type(1016,DummyPositionSensitiveRecordWithChildren.class); + public static final Type MainMaster = new Type(1016,MainMaster.class); public static final Type SSSlideInfoAtom = new Type(1017,null); public static final Type SlideViewInfo = new Type(1018,null); public static final Type GuideAtom = new Type(1019,null); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java b/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java index 27d811305..332d7708c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java @@ -38,6 +38,7 @@ public class Slide extends PositionDependentRecordContainer // Links to our more interesting children private SlideAtom slideAtom; private PPDrawing ppDrawing; + private ColorSchemeAtom _colorScheme; /** * Returns the SlideAtom of this Slide @@ -67,9 +68,13 @@ public class Slide extends PositionDependentRecordContainer if(_children[i] instanceof SlideAtom) { slideAtom = (SlideAtom)_children[i]; } - if(_children[i] instanceof PPDrawing) { + else if(_children[i] instanceof PPDrawing) { ppDrawing = (PPDrawing)_children[i]; } + + if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) { + _colorScheme = (ColorSchemeAtom)_children[i]; + } } } @@ -107,4 +112,8 @@ public class Slide extends PositionDependentRecordContainer public void writeOut(OutputStream out) throws IOException { writeOut(_header[0],_header[1],_type,_children,out); } + + public ColorSchemeAtom getColorScheme(){ + return _colorScheme; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java index f1c4bcb68..2e432776e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java @@ -49,6 +49,8 @@ public class SlideAtom extends RecordAtom /** Get the ID of the master slide used. 0 if this is a master slide, otherwise -2147483648 */ public int getMasterID() { return masterID; } + /** Change slide master. */ + public void setMasterID(int id) { masterID = id; } /** Get the ID of the notes for this slide. 0 if doesn't have one */ public int getNotesID() { return notesID; } /** Get the embeded SSlideLayoutAtom */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java index 082b03f33..0c3a72bbf 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java @@ -20,9 +20,12 @@ package org.apache.poi.hslf.usermodel; import org.apache.poi.hslf.model.TextRun; +import org.apache.poi.hslf.model.Sheet; +import org.apache.poi.hslf.model.SlideMaster; import org.apache.poi.hslf.record.StyleTextPropAtom.CharFlagsTextProp; import org.apache.poi.hslf.record.StyleTextPropAtom.TextProp; import org.apache.poi.hslf.record.StyleTextPropAtom.TextPropCollection; +import org.apache.poi.hslf.record.ColorSchemeAtom; import java.awt.*; @@ -47,7 +50,8 @@ public class RichTextRun /** How long a string (in the parent TextRun) we represent */ private int length; - /** + private String _fontname; + /** * Our paragraph and character style. * Note - we may share these styles with other RichTextRuns */ @@ -56,7 +60,6 @@ public class RichTextRun private boolean sharingParagraphStyle; private boolean sharingCharacterStyle; - private String _fontname; /** * Create a new wrapper around a (currently not) * rich text string @@ -158,14 +161,20 @@ public class RichTextRun * text property won't be set if there's no CharFlagsTextProp. */ private boolean isCharFlagsTextPropVal(int index) { - if(characterStyle == null) { return false; } - - CharFlagsTextProp cftp = (CharFlagsTextProp) - characterStyle.findByName("char_flags"); - - if(cftp == null) { return false; } - return cftp.getSubValue(index); + CharFlagsTextProp cftp = null; + if (characterStyle != null){ + cftp = (CharFlagsTextProp)characterStyle.findByName("char_flags"); + } + if (cftp == null){ + Sheet sheet = parentRun.getSheet(); + int txtype = parentRun.getRunType(); + SlideMaster master = (SlideMaster)sheet.getMasterSheet(); + cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true); + } + + return cftp == null ? false : cftp.getSubValue(index); } + /** * Set the value of the given flag in the CharFlagsTextProp, adding * it if required. @@ -204,24 +213,38 @@ public class RichTextRun * Master Sheet will apply. */ private int getCharTextPropVal(String propName) { - if(characterStyle == null) { return -1; } - - TextProp cTextProp = characterStyle.findByName(propName); - if(cTextProp == null) { return -1; } - return cTextProp.getValue(); + TextProp prop = null; + if (characterStyle != null){ + prop = characterStyle.findByName(propName); + } + + if (prop == null){ + Sheet sheet = parentRun.getSheet(); + int txtype = parentRun.getRunType(); + SlideMaster master = (SlideMaster)sheet.getMasterSheet(); + prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true); + } + return prop == null ? -1 : prop.getValue(); } /** - * Fetch the value of the given Paragraph related TextProp. - * Returns -1 if that TextProp isn't present. - * If the TextProp isn't present, the value from the appropriate + * Fetch the value of the given Paragraph related TextProp. + * Returns -1 if that TextProp isn't present. + * If the TextProp isn't present, the value from the appropriate * Master Sheet will apply. */ private int getParaTextPropVal(String propName) { - if(paragraphStyle == null) { return -1; } - - TextProp pTextProp = paragraphStyle.findByName(propName); - if(pTextProp == null) { return -1; } - return pTextProp.getValue(); + TextProp prop = null; + if (paragraphStyle != null){ + prop = paragraphStyle.findByName(propName); + } + if (prop == null){ + Sheet sheet = parentRun.getSheet(); + int txtype = parentRun.getRunType(); + SlideMaster master = (SlideMaster)sheet.getMasterSheet(); + prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false); + } + + return prop == null ? -1 : prop.getValue(); } /** @@ -290,27 +313,40 @@ public class RichTextRun if (slideShow == null) { //we can't set font since slideshow is not assigned yet _fontname = fontName; - } else{ - // Get the index for this font (adding if needed) - int fontIdx = slideShow.getFontCollection().addFont(fontName); - setCharTextPropVal("font.index", fontIdx); - } + } else { + // Get the index for this font (adding if needed) + int fontIdx = slideShow.getFontCollection().addFont(fontName); + setCharTextPropVal("font.index", fontIdx); + } } public String getFontName() { - int fontIdx = getCharTextPropVal("font.index"); - if(fontIdx == -1) { return null; } - return slideShow.getFontCollection().getFontWithId(fontIdx); + if (slideShow == null) { + return _fontname; + } else { + int fontIdx = getCharTextPropVal("font.index"); + if(fontIdx == -1) { return null; } + return slideShow.getFontCollection().getFontWithId(fontIdx); + } } /** * @return font color as RGB value * @see java.awt.Color */ - public int getFontColor() { - return getCharTextPropVal("font.color"); + public Color getFontColor() { + int rgb = getCharTextPropVal("font.color"); + if (rgb >= 0x8000000) { + int idx = rgb % 0x8000000; + ColorSchemeAtom ca = parentRun.getSheet().getColorScheme(); + if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); + } + + Color tmp = new Color(rgb, true); + return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); } + /** - * Sets color of the text, as a RGB value + * Sets color of the text, as a int rgb * @see java.awt.Color */ public void setFontColor(int rgb) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java index f12b0cfdb..449ba5c01 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -80,11 +80,10 @@ public class SlideShow private Document _documentRecord; // Friendly objects for people to deal with + private SlideMaster[] _masters; private Slide[] _slides; private Notes[] _notes; private FontCollection _fonts; - // MetaSheets (eg masters) not yet supported - // private MetaSheets[] _msheets; /* =============================================================== @@ -305,6 +304,18 @@ public class SlideShow SlideListWithText slidesSLWT = _documentRecord.getSlideSlideListWithText(); SlideListWithText notesSLWT = _documentRecord.getNotesSlideListWithText(); + //find master slides + SlideAtomsSet[] masterSets = new SlideAtomsSet[0]; + org.apache.poi.hslf.record.MainMaster[] masterRecords = null; + if (masterSLWT != null){ + + masterSets = masterSLWT.getSlideAtomsSets(); + masterRecords = new org.apache.poi.hslf.record.MainMaster[masterSets.length]; + for(int i=0; i