From 5f167f01b2eddfdb4afce8326503714e3dd46674 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 17 Oct 2006 18:01:19 +0000 Subject: [PATCH] Support for Master Sheets from Yegor (bug 40753) git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@464982 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hslf/model/AutoShape.java | 16 +- .../src/org/apache/poi/hslf/model/Line.java | 63 +++--- .../apache/poi/hslf/model/MasterSheet.java | 12 ++ .../apache/poi/hslf/model/PPGraphics2D.java | 90 ++++++-- .../apache/poi/hslf/model/ShapeFactory.java | 22 +- .../org/apache/poi/hslf/model/ShapeGroup.java | 25 ++- .../src/org/apache/poi/hslf/model/Sheet.java | 16 +- .../apache/poi/hslf/model/SimpleShape.java | 81 ++++++- .../src/org/apache/poi/hslf/model/Slide.java | 37 +++- .../apache/poi/hslf/model/SlideMaster.java | 146 +++++++++++++ .../org/apache/poi/hslf/model/TextBox.java | 194 ++++------------- .../org/apache/poi/hslf/model/TextRun.java | 27 +-- .../poi/hslf/record/ColorSchemeAtom.java | 13 ++ .../apache/poi/hslf/record/Environment.java | 9 +- .../apache/poi/hslf/record/MainMaster.java | 111 ++++++++++ .../apache/poi/hslf/record/RecordTypes.java | 2 +- .../src/org/apache/poi/hslf/record/Slide.java | 11 +- .../org/apache/poi/hslf/record/SlideAtom.java | 2 + .../poi/hslf/usermodel/RichTextRun.java | 102 ++++++--- .../apache/poi/hslf/usermodel/SlideShow.java | 28 ++- .../org/apache/poi/hslf/data/slide_master.ppt | Bin 0 -> 15872 bytes .../org/apache/poi/hslf/model/TestLine.java | 133 ++++++++++++ .../poi/hslf/model/TestSetBoldItalic.java | 13 +- .../org/apache/poi/hslf/model/TestShapes.java | 30 +-- .../poi/hslf/model/TestSlideMaster.java | 201 ++++++++++++++++++ .../poi/hslf/usermodel/TestRichTextRun.java | 19 +- 26 files changed, 1074 insertions(+), 329 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java create mode 100644 src/scratchpad/testcases/org/apache/poi/hslf/data/slide_master.ppt create mode 100644 src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java create mode 100644 src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java 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; iK^CTOS?X+VPc z!?|3}7K$MGemI3R@E&-biNSLLVL%yxV_pG>04f1hfNDSuU=m<5APRs9NFAUaKpP-T zL3%1+8elr$G{EVA8GthYe!EjhMgOl^y-HH}%ZQPWOA>LPY{V#)9;U)#d zDjw!b$O)mE_DepBw;Ziu`v+&+e3`6OI=#}SvR?{%ouJ+a+HIhmKsq_vbzF+{Id6O& zjB8M&pplaZp=_M26XRzo==-!wmH!VxH$x>LMCB#-a!hnbUUugrKZwb@9}}CvG}i;p ze?M@H5uB*}#{DKT7s%cy*M&v$M3j19eN>*RcoDJ4_oJ)udl9smfHr%O?h_+dVpIo^ zuKn(iG(FcKb9WEPrk^)R2Vlda)r+|9FtBX?FD5O*iZrLz!*wzGa&)>BqZ|vadgI|* z2~7RU8}09y__|Q!fhhGeD6ROlBk*5!ZTMaAU)DD4Wf=e-q( z=NOR=!~zS}m}!aWD6v;A_o|lIvF3`as>bjb$581yRI!ll!C`B4TRADTd@wu+njD$x za3fk{_0HC4uk!3pl!q?2yE*Y{L&TQv(Y#+Cj7flbvdNezOX-JZ+Md?M_Qc~Eq{d_O zH%oOEW+0n6*CIEQOyrh}@GB2Fwb+ODI4FudtR*=of}P6=0bgX1oPLnjIeZ`|!?|G@ zULq2cGY`VJNk76~Z1)C?ah7DGONmlmbGbrUuVMfVXGvq2 zJDtdsF!B83_T8_`&|M$-M#UYEGA650dE4#MHiuoMgED!~{Q!P11#|@B;DlI@3E_vU zv6KEitbsk(%R8<=Y1Sj*=UErS&OJ+VDiT-?QyqRl9(4`jWm;hAlXej92F+& zN_^vj(*PV5c{paH5pno&DLA5XYXj9El`Rb%YA7zsVY*)bnz22!$c0#DM84d>a=0R4 zm3a@6fEDtLH|>6|3(+K*2VB``m+IFJ8_kV@a&s7LxL4cT^sXo!oV7iPj<~s^EuD$? zrLk8;IgYI0xL1a)og)d$vz;xjUC~)cG^YmQea)#vGGo^F#nbU*rY)05CDW$8Eor*j zHpESDe@`Z{z6S|Q!AxrDj+^y8ZSC=1G&gO@4%3ut+q63H%;>NJ`7jTw_#_vv_h z#^PBQH|^bR$*y>ZNhM7p*^$_g=;&|jF=?`%HUo)Fcd8$#Iy=#aSTZ1C>499z^rkuz zog2-%w)Pvk`cnO%=%Xj~Kyh0#0Y)G|li8T+2k+^OiFYJ20fbFvpgYmt?Ga0xww@6_ z5=qmRrv|Ku_eDPp)zQ{%NFlNcya_3e&1fy_bfpNhPCZf#`h(G{k(mRq{b&bchlXXg zmcMpU;?Qx?wdJJb_u4d4>Q8?()u8;?4#)>>WoNVrC2O&*C1CAwF>(bqxip*xZYOEv z=fjDi`;d{-OoyC{*4C8hAp4Yk)MHI)JKA^_XgcCB#NI@*bR%gB4xu-)O=?($hStQ@ zOwzPE6WmHWQWL(9kOE>JK30aciwrYwtMIKwUXP>sjE7oaqWD3JBG3P z1C}fqmTz_CM%q31`a#9x<0BupKLTDlL3CFT-!s~7V1Ql=`F%r{3=d1Lxf%3F+X?tr zS^oHwh*8n8PI^<1vIAhW-Js&g$+fdYo_}Jy^8YUzTeZ(mzjoRPe^7wMw*)c*#}e|j zo9yKz_e&?xjwD#WLtgk5WP4Y~A{2GI-A}$qjeP z%g_E`1Yalc5a06U*J|8)&F7@EGl#JNUC8B+$5qSE*7^lziafvPcDe0y>*XugUm(NZ z6S?i4osjbW=yLoz<9r-Pw+B=q#B_#ng3`y~v;%E~`K)xg#@-*zAZb0N3c2BIySdP; zI)p3p(|~*|DDbctCTW0J`=4|SQX!s0k=qwypAb)}$Ys@A3K1W2wPk}k{|#st_tMTJ zZUo}7OH96(R>NYCwo%&11A9y<+jOhawdujIrP>UtSJ@(QFptU=2?`MVc}ha={k-MD z9m%&sb6h$7dW*Rgn8}rPW&?!vDB~!BF)vUD zXEyf4MZOlL^s}`;HxQmSn6o29$)+OdOXeC>p^5J?`;r}ac_`0&KAKEfmoha($I3*i zAy1}zkoLDk%grve+rl!@g;9~xlh(%DQ}8l+u+{Xy_eu2m>D8(JzD&1Qu{zP|r>OwHmfEq};Y_J; z?1(ob?Q4g;iR_HB{ye~a>QVahiW+4I>CM`k0e95O!&<9f$}@zVFHf04rhq)F4oy^^ z-4**LkC%tDy)tCw;fhpT9=bH1JTQGHPolRcAQ5MIA&D+|W1B*#lki0~B^ZgjW_)8`iRZwU8^;r(Sx**}Zf7;|7N>-rBCj z{Rkb}6mG+KD;GyDfxDL^sJ!V;hvmKRC^UfBbXCWVNj`2K1Op;v&c@%|eN6Zg9LI z{<<4NId_t=KHjFs=DDT&cnvb=ApNh0xD|q{QarwS@B~k;$2S+&?#t51df)sekHtE-dc4L%)^uB?c3m;dzmq&t#t zXr()OzF|W9NtFxeoz9JQDqNT)i78VV%bZ z23_ZQpCWS4$cccQ1}RgDLX@vvI+n6)h{^6SM_PX;7oZI0RY!Rz4^YmxC*<+<4Ej0Y zCy#APe@nxc5FhE&O+xEOPa9h|z51spIv-oBhFP-e;72ue&Ou{~MsAC|ETW`-^R7oK zDjz+_`+%79v4b3U-gluebUq@)#f=cQFvvEAjBruV2&WUz1dR}V3K}8G3zWYd+a(9(A_;s^&rPRC63Y^4GPT;zMsh}h|2WhtScR4M1Bf#kdC;F)GzZ%d6 zcjt1n_g{Q##`PDUKEwbZq<+Xd3-MgQJiyt2a{%=I&jp+Z;CyZZEC4J7Tmazd@j}32 zz!Ja*0Dl1BjqZm4O96au#?Or(0W1S>ZCMUj0f+%E0(=a>cB{PDo+^Joeh=p`=K6vP z!UqEFV*j7t`w}1&Tath zXD@(8{v?35bO^xrgtT_kke+kk_5i4HwV71YdxBa z;Ojfv2GhiSO}q==HZMzkwkNeg@Kv5|=wmFtP*P0OZm&qR_odRQ&WstQBB`X>N$cvF z=TW8@zz;D$ftcyowl(^`jd(dTmq#HX z+w!}IANHW*J}7~DWQ&NlK!LunWXV}t62=S5mMfc^8zqDLXU>RRZjH{!D{y0HRPStE zrLCyfLwd(Jijy2t`z&eHR$+_|^{Bc;%(bDKq%~C&+85g6vMlUS!yNf{QOny+YYz+1 zkve-jR5pTxcCx^6)LvLmxn`EnmMo;CtfM`Be5w$yeMsZ%2wt|g!Q!==qXbhuO>&+1 z3b?96pC2J6Kddj;dPm=+zN0dEi2UfSg99<7JHu7wk;fb4A0BvZ;9mh|(QgMfx}D1` zJy$hR$^MWLE1+Ux%DzhEI0m`77+jE>jetVjuxD{>RwF>6!EzAxG~=lLXN2#RZSG90 zjJDS5i+V1EnY+?Ep~qlv3|lSYn9RATFVWV6lD`R8ZP@#8G1<$!u_&&Cg$`$|)drFC z4e;WsURj~`lK;r&EZAC&%*00M*qv7j>eHugk z@Cun~Kx(ts#_EZ7YJ=@j9?%c9JR^Lg+#E`SQ_DS@`?ziF>-!6#ZSJlSeV31n2Kxm^ zk{nolKUGxUpK+_czO$&lD?ELd1$g!4+^p6&R^Oaki>rPnAJ*BoLQFwj7UGm;W3h1; zCARByzaCv7^PcwvUOCOgYDSo>zg0-pVAW@SI#%21_+zdHE5LNDWmAzFEoGkdmXG|g zFO^?i7DjQK&jX%ayP*;WD8k93#jdjhIvJLZ7c&67jQ!tXmQH_%0vz1F#qFzYUgcKj@ zmHNPr5|B^JV*_Fd!q7ap%tEr;Id;;Jk(!}HWJJpF93(#%l4$#Xq;rffDf19?heWvbAW zOa)ZGhb)NcPv zoFALs`sON>m5nJ|goXz|nw~N_xD`MywgPw>*#)4Mz6apF#18?~%D)5X1@f#xIi3XY zZ22r;8sJ3$&zJ`Q#C-@rkKkPZ->QT`jHec!J!=r(hL}A2XHC*xlU$H)?~BKiW^H#0 zPd`V_l_)2V{2wC5roMl+%@X zBbA8vnJeQ1`d(-yUSy|w&8m1h(ZzQexR;N2w&97nU&LGYd}o^q$}2JR@gOVn)sAze z2J}grvXaNuC{LSDq~jeb62)Q_Rca}kmUu6ou4m#SDquZTYbmtwEn9k|k~ZM$#vl!~ z>%9$i2b0!3)0FyZyuQc7^O133Keo>guSe&ipb>EWo^3DOf-$MV+1AAywcwebHgXNV zS9IYm3;);WGQ^+7cZ-y4$Vc~kmg5VbKK$ALvorDuyzt@k^-{y>7#-eO_@R`3E76E{ TaH4`woAHUlIT1XkGX4JppuT)# literal 0 HcmV?d00001 diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java new file mode 100644 index 000000000..0ea78ac40 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestLine.java @@ -0,0 +1,133 @@ +/* ==================================================================== + 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.model; + +import junit.framework.*; + +import java.io.FileOutputStream; +import java.awt.*; + +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.HSLFSlideShow; + +/** + * Test Line shape. + * + * @author Yegor Kozlov + */ +public class TestLine extends TestCase { + + public void setUp() throws Exception { + + } + + public void testCreateLines() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + + slide.addTitle().setText("Lines tester"); + + Line line; + + /** + * line styles + */ + line = new Line(); + line.setAnchor(new Rectangle(75, 200, 300, 0)); + line.setLineStyle(Line.LINE_SIMPLE); + line.setLineColor(Color.blue); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 230, 300, 0)); + line.setLineStyle(Line.LINE_DOUBLE); + line.setLineWidth(3.5); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 260, 300, 0)); + line.setLineStyle(Line.LINE_TRIPLE); + line.setLineWidth(6); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 290, 300, 0)); + line.setLineStyle(Line.LINE_THICKTHIN); + line.setLineWidth(4.5); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 320, 300, 0)); + line.setLineStyle(Line.LINE_THINTHICK); + line.setLineWidth(5.5); + slide.addShape(line); + + /** + * line dashing + */ + line = new Line(); + line.setAnchor(new java.awt.Rectangle(450, 200, 300, 0)); + line.setLineDashing(Line.PEN_SOLID); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(450, 230, 300, 0)); + line.setLineDashing(Line.PEN_PS_DASH); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(450, 260, 300, 0)); + line.setLineDashing(Line.PEN_DOT); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(450, 290, 300, 0)); + line.setLineDashing(Line.PEN_DOTGEL); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(450, 320, 300, 0)); + line.setLineDashing(Line.PEN_LONGDASHDOTDOTGEL); + slide.addShape(line); + + /** + * Combinations + */ + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 400, 300, 0)); + line.setLineDashing(Line.PEN_DASHDOT); + line.setLineStyle(Line.LINE_TRIPLE); + line.setLineWidth(5.0); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 430, 300, 0)); + line.setLineDashing(Line.PEN_DASH); + line.setLineStyle(Line.LINE_THICKTHIN); + line.setLineWidth(4.0); + slide.addShape(line); + + line = new Line(); + line.setAnchor(new java.awt.Rectangle(75, 460, 300, 0)); + line.setLineDashing(Line.PEN_DOT); + line.setLineStyle(Line.LINE_DOUBLE); + line.setLineWidth(8.0); + slide.addShape(line); + + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java index 28362c685..7e53ebc22 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java @@ -46,15 +46,16 @@ public class TestSetBoldItalic extends TestCase { // Create a new textbox, and give it lots of properties TextBox txtbox = new TextBox(); + rt = txtbox.getTextRun().getRichTextRuns()[0]; txtbox.setText(val); - txtbox.setFontSize(42); - txtbox.setBold(true); - txtbox.setItalic(true); - txtbox.setUnderline(false); + rt.setFontSize(42); + rt.setBold(true); + rt.setItalic(true); + rt.setUnderlined(false); sl.addShape(txtbox); // Check it before save - rt = txtbox.getRichTextRuns()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; assertEquals(val, rt.getText()); assertEquals(42, rt.getFontSize()); assertTrue(rt.isBold()); @@ -69,7 +70,7 @@ public class TestSetBoldItalic extends TestCase { sl = ppt.getSlides()[0]; txtbox = (TextBox)sl.getShapes()[0]; - rt = txtbox.getRichTextRuns()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; // Check after save assertEquals(val, rt.getText()); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java index 6d2f1fcc3..2c3a6d189 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java @@ -50,9 +50,8 @@ public class TestShapes extends TestCase { Line line = new Line(); java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60); line.setAnchor(lineAnchor); - System.out.println(line.getAnchor()); line.setLineWidth(3); - line.setLineStyle(Line.LineDashSys); + line.setLineStyle(Line.PEN_DASH); line.setLineColor(Color.red); slide.addShape(line); @@ -60,7 +59,7 @@ public class TestShapes extends TestCase { java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111); ellipse.setAnchor(ellipseAnchor); ellipse.setLineWidth(2); - ellipse.setLineStyle(Line.LineSolid); + ellipse.setLineStyle(Line.PEN_SOLID); ellipse.setLineColor(Color.green); ellipse.setFillColor(Color.lightGray); slide.addShape(ellipse); @@ -101,8 +100,8 @@ public class TestShapes extends TestCase { String text = txtbox.getText(); assertNotNull(text); - assertEquals(txtbox.getRichTextRuns().length, 1); - RichTextRun rt = txtbox.getRichTextRuns()[0]; + assertEquals(txtbox.getTextRun().getRichTextRuns().length, 1); + RichTextRun rt = txtbox.getTextRun().getRichTextRuns()[0]; if (text.equals("Hello, World!!!")){ assertEquals(32, rt.getFontSize()); @@ -135,24 +134,25 @@ public class TestShapes extends TestCase { // Create a new textbox, and give it lots of properties TextBox txtbox = new TextBox(); + rt = txtbox.getTextRun().getRichTextRuns()[0]; txtbox.setText(val); - txtbox.setFontName("Arial"); - txtbox.setFontSize(42); - txtbox.setBold(true); - txtbox.setItalic(true); - txtbox.setUnderline(false); - txtbox.setFontColor(Color.red); + rt.setFontName("Arial"); + rt.setFontSize(42); + rt.setBold(true); + rt.setItalic(true); + rt.setUnderlined(false); + rt.setFontColor(Color.red); sl.addShape(txtbox); // Check it before save - rt = txtbox.getRichTextRuns()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; assertEquals(val, rt.getText()); assertEquals(42, rt.getFontSize()); assertTrue(rt.isBold()); assertTrue(rt.isItalic()); assertFalse(rt.isUnderlined()); assertEquals("Arial", rt.getFontName()); - assertEquals(Color.red, txtbox.getFontColor()); + assertEquals(Color.red, rt.getFontColor()); // Serialize and read again ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -162,7 +162,7 @@ public class TestShapes extends TestCase { ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); txtbox = (TextBox)sl.getShapes()[0]; - rt = txtbox.getRichTextRuns()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; // Check after save assertEquals(val, rt.getText()); @@ -171,7 +171,7 @@ public class TestShapes extends TestCase { assertTrue(rt.isItalic()); assertFalse(rt.isUnderlined()); assertEquals("Arial", rt.getFontName()); - assertEquals(Color.red, txtbox.getFontColor()); + assertEquals(Color.red, rt.getFontColor()); } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java new file mode 100644 index 000000000..666ddbf94 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java @@ -0,0 +1,201 @@ +/* ==================================================================== + 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.model; + +import junit.framework.TestCase; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.usermodel.RichTextRun; +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.record.StyleTextPropAtom.*; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + +/** + * Tests for SlideMaster + * + * @author Yegor Kozlov + */ +public class TestSlideMaster extends TestCase{ + String home; + + public void setUp() throws Exception { + home = System.getProperty("HSLF.testdata.path"); + } + + /** + * The reference ppt has two masters. + * Check we can read their attributes. + */ + public void testSlideMaster() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt")); + + Environment env = ppt.getDocumentRecord().getEnvironment(); + + SlideMaster[] master = ppt.getSlidesMasters(); + assertEquals(2, master.length); + + //character attributes + assertEquals(40, master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue()); + assertEquals(48, master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue()); + + int font1 = master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue(); + int font2 = master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue(); + assertEquals("Arial", env.getFontCollection().getFontWithId(font1)); + assertEquals("Georgia", env.getFontCollection().getFontWithId(font2)); + + CharFlagsTextProp prop1 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true); + assertEquals(false, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX)); + assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX)); + assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX)); + + CharFlagsTextProp prop2 = (CharFlagsTextProp)master[1].getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true); + assertEquals(false, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX)); + assertEquals(true, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX)); + assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX)); + + //now paragraph attributes + assertEquals(0x266B, master[0].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue()); + assertEquals(0x2022, master[1].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue()); + + int b1 = master[0].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue(); + int b2 = master[1].getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue(); + assertEquals("Arial", env.getFontCollection().getFontWithId(b1)); + assertEquals("Georgia", env.getFontCollection().getFontWithId(b2)); + } + + /** + * If a style attribute is not set ensure it is read from the master + */ + public void testMasterAttributes() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt")); + Slide[] slide = ppt.getSlides(); + assertEquals(2, slide.length); + TextRun[] trun; + + trun = slide[0].getTextRuns(); + for (int i = 0; i < trun.length; i++) { + if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){ + RichTextRun rt = trun[i].getRichTextRuns()[0]; + assertEquals(40, rt.getFontSize()); + assertEquals(true, rt.isUnderlined()); + assertEquals("Arial", rt.getFontName()); + } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){ + RichTextRun rt; + rt = trun[i].getRichTextRuns()[0]; + assertEquals(0, rt.getIndentLevel()); + assertEquals(32, rt.getFontSize()); + assertEquals("Arial", rt.getFontName()); + + rt = trun[i].getRichTextRuns()[1]; + assertEquals(1, rt.getIndentLevel()); + assertEquals(28, rt.getFontSize()); + assertEquals("Arial", rt.getFontName()); + + } + } + + trun = slide[1].getTextRuns(); + for (int i = 0; i < trun.length; i++) { + if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){ + RichTextRun rt = trun[i].getRichTextRuns()[0]; + assertEquals(48, rt.getFontSize()); + assertEquals(true, rt.isItalic()); + assertEquals("Georgia", rt.getFontName()); + } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){ + RichTextRun rt; + rt = trun[i].getRichTextRuns()[0]; + assertEquals(0, rt.getIndentLevel()); + assertEquals(32, rt.getFontSize()); + assertEquals("Courier New", rt.getFontName()); + } + } + + } + + /** + * Check we can dynamically assign a slide master to a slide. + */ + public void testChangeSlideMaster() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt")); + SlideMaster[] master = ppt.getSlidesMasters(); + Slide[] slide = ppt.getSlides(); + int sheetNo; + + //each slide uses its own master + assertEquals(slide[0].getMasterSheet()._getSheetNumber(), master[0]._getSheetNumber()); + assertEquals(slide[1].getMasterSheet()._getSheetNumber(), master[1]._getSheetNumber()); + + //all slides use the first master slide + sheetNo = master[0]._getSheetNumber(); + for (int i = 0; i < slide.length; i++) { + slide[i].setMasterSheet(master[0]); + } + + ByteArrayOutputStream out; + + out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + master = ppt.getSlidesMasters(); + slide = ppt.getSlides(); + for (int i = 0; i < slide.length; i++) { + assertEquals(sheetNo, slide[i].getMasterSheet()._getSheetNumber()); + } + } + + /** + * Varify we can read attrubutes for different identtation levels. + * (typical for the "bullted body" placeholder) + */ + public void testIndentation() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt")); + Slide slide = ppt.getSlides()[0]; + TextRun[] trun; + + trun = slide.getTextRuns(); + for (int i = 0; i < trun.length; i++) { + if (trun[i].getRunType() == TextHeaderAtom.TITLE_TYPE){ + RichTextRun rt = trun[i].getRichTextRuns()[0]; + assertEquals(40, rt.getFontSize()); + assertEquals(true, rt.isUnderlined()); + assertEquals("Arial", rt.getFontName()); + } else if (trun[i].getRunType() == TextHeaderAtom.BODY_TYPE){ + RichTextRun[] rt = trun[i].getRichTextRuns(); + for (int j = 0; j < rt.length; j++) { + int indent = rt[j].getIndentLevel(); + switch (indent){ + case 0: + assertEquals(32, rt[j].getFontSize()); + break; + case 1: + assertEquals(28, rt[j].getFontSize()); + break; + case 2: + assertEquals(24, rt[j].getFontSize()); + break; + } + } + } + } + + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java index d5f788349..ff21cac18 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java @@ -8,6 +8,7 @@ import java.io.File; import org.apache.poi.hslf.HSLFSlideShow; import org.apache.poi.hslf.model.Slide; import org.apache.poi.hslf.model.TextRun; +import org.apache.poi.hslf.model.SlideMaster; import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.SlideListWithText; @@ -114,7 +115,8 @@ public class TestRichTextRun extends TestCase { * rich text runs */ public void testFontSize() throws Exception { - Slide slideOne = ss.getSlides()[0]; + SlideMaster master; + Slide slideOne = ss.getSlides()[0]; TextRun[] textRuns = slideOne.getTextRuns(); RichTextRun rtr = textRuns[0].getRichTextRuns()[0]; @@ -124,13 +126,16 @@ public class TestRichTextRun extends TestCase { RichTextRun rtrRb = textRunsR[1].getRichTextRuns()[0]; RichTextRun rtrRc = textRunsR[1].getRichTextRuns()[3]; + String defaultFont = "Arial"; + // Start off with rich one // First run has defaults - assertEquals(-1, rtrRa.getFontSize()); - assertEquals(null, rtrRa.getFontName()); + assertEquals(44, rtrRa.getFontSize()); + assertEquals(defaultFont, rtrRa.getFontName()); + // Second is size 20, default font assertEquals(20, rtrRb.getFontSize()); - assertEquals(null, rtrRb.getFontName()); + assertEquals(defaultFont, rtrRb.getFontName()); // Third is size 24, alt font assertEquals(24, rtrRc.getFontSize()); assertEquals("Times New Roman", rtrRc.getFontName()); @@ -145,8 +150,8 @@ public class TestRichTextRun extends TestCase { // Now do non rich one - assertEquals(-1, rtr.getFontSize()); - assertEquals(null, rtr.getFontName()); + assertEquals(44, rtr.getFontSize()); + assertEquals(defaultFont, rtr.getFontName()); assertEquals(1, ss.getFontCollection().getChildRecords().length); // Default assertNull(rtr._getRawCharacterStyle()); assertNull(rtr._getRawParagraphStyle()); @@ -154,7 +159,7 @@ public class TestRichTextRun extends TestCase { // Change Font size rtr.setFontSize(99); assertEquals(99, rtr.getFontSize()); - assertEquals(null, rtr.getFontName()); + assertEquals(defaultFont, rtr.getFontName()); assertNotNull(rtr._getRawCharacterStyle()); assertNotNull(rtr._getRawParagraphStyle()); assertEquals(1, ss.getFontCollection().getChildRecords().length); // Default