diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2015-08-09 22:44:13 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2015-08-09 22:44:13 +0000 |
commit | c619525118f6db2f94c188dda2997c3d5d40e1d2 (patch) | |
tree | 79e5deb8dfa93d1bce65bb9a484a0c428ae7e816 /src | |
parent | 19e8f76d906454cbbaca56417ee1ce324ad172dc (diff) | |
download | poi-c619525118f6db2f94c188dda2997c3d5d40e1d2.tar.gz poi-c619525118f6db2f94c188dda2997c3d5d40e1d2.zip |
#56519 - XSLFSlide.draw is not working with text embeded in PPTX
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1694925 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
38 files changed, 1242 insertions, 509 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java index 26a94ed347..2221c2f2f6 100644 --- a/src/java/org/apache/poi/sl/draw/DrawPaint.java +++ b/src/java/org/apache/poi/sl/draw/DrawPaint.java @@ -17,25 +17,31 @@ package org.apache.poi.sl.draw;
-import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
-
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
-import java.awt.geom.*;
+import java.awt.Paint;
+import java.awt.RadialGradientPaint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.ColorStyle;
+import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
+import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/**
- * This class handles color transformations
+ * This class handles color transformations.
*
* @see <a href="https://tips4java.wordpress.com/2009/07/05/hsl-color/">HSL code taken from Java Tips Weblog</a>
*/
@@ -50,19 +56,45 @@ public class DrawPaint { this.shape = shape;
}
- public static SolidPaint createSolidPaint(final Color color) {
- return new SolidPaint() {
- public ColorStyle getSolidColor() {
- return new ColorStyle(){
+ private static class SimpleSolidPaint implements SolidPaint {
+ private final ColorStyle solidColor;
+
+ SimpleSolidPaint(final Color color) {
+ if (color == null) {
+ throw new NullPointerException("Color needs to be specified");
+ }
+ this.solidColor = new ColorStyle(){
public Color getColor() { return color; }
public int getAlpha() { return -1; }
+ public int getHueOff() { return -1; }
+ public int getHueMod() { return -1; }
+ public int getSatOff() { return -1; }
+ public int getSatMod() { return -1; }
public int getLumOff() { return -1; }
public int getLumMod() { return -1; }
public int getShade() { return -1; }
public int getTint() { return -1; }
};
+ }
+
+ SimpleSolidPaint(ColorStyle color) {
+ if (color == null) {
+ throw new NullPointerException("Color needs to be specified");
}
- };
+ this.solidColor = color;
+ }
+
+ public ColorStyle getSolidColor() {
+ return solidColor;
+ }
+ }
+
+ public static SolidPaint createSolidPaint(final Color color) {
+ return (color == null) ? null : new SimpleSolidPaint(color);
+ }
+
+ public static SolidPaint createSolidPaint(final ColorStyle color) {
+ return (color == null) ? null : new SimpleSolidPaint(color);
}
public Paint getPaint(Graphics2D graphics, PaintStyle paint) {
@@ -95,26 +127,26 @@ public class DrawPaint { protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
InputStream is = fill.getImageData();
- if (is == null) return TRANSPARENT_PAINT.getSolidColor().getColor();
+ if (is == null) return null;
assert(graphics != null);
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
if (renderer == null) renderer = new ImageRenderer();
try {
- renderer.loadImage(fill.getImageData(), fill.getContentType());
+ renderer.loadImage(is, fill.getContentType());
+ is.close();
} catch (IOException e) {
LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e);
- return TRANSPARENT_PAINT.getSolidColor().getColor();
+ return null;
}
int alpha = fill.getAlpha();
- if (alpha != -1) {
+ if (0 <= alpha && alpha < 100000) {
renderer.setAlpha(alpha/100000.f);
}
- Dimension dim = renderer.getDimension();
- Rectangle2D textAnchor = new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight());
+ Rectangle2D textAnchor = shape.getAnchor();
Paint paint = new java.awt.TexturePaint(renderer.getImage(), textAnchor);
return paint;
@@ -122,106 +154,102 @@ public class DrawPaint { /**
* Convert color transformations in {@link ColorStyle} to a {@link Color} instance
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/dd560821%28v=office.12%29.aspx">Using Office Open XML to Customize Document Formatting in the 2007 Office System</a>
+ * @see <a href="https://social.msdn.microsoft.com/Forums/office/en-US/040e0a1f-dbfe-4ce5-826b-38b4b6f6d3f7/saturation-modulation-satmod">saturation modulation (satMod)</a>
+ * @see <a href="http://stackoverflow.com/questions/6754127/office-open-xml-satmod-results-in-more-than-100-saturation">Office Open XML satMod results in more than 100% saturation</a>
*/
public static Color applyColorTransform(ColorStyle color){
+ // TODO: The colors don't match 100% the results of Powerpoint, maybe because we still
+ // operate in sRGB and not scRGB ... work in progress ...
+
Color result = color.getColor();
+ if (result == null) return null;
- if (result == null || color.getAlpha() == 100) {
- return TRANSPARENT_PAINT.getSolidColor().getColor();
- }
-
- result = applyAlpha(result, color);
- result = applyLuminance(result, color);
- result = applyShade(result, color);
- result = applyTint(result, color);
+ double alpha = getAlpha(result, color);
+ double hsl[] = RGB2HSL(result); // values are in the range [0..100] (usually ...)
+ applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff());
+ applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff());
+ applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());
+ applyShade(hsl, color);
+ applyTint(hsl, color);
+ result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha);
+
return result;
}
- protected static Color applyAlpha(Color c, ColorStyle fc) {
- int alpha = c.getAlpha();
- return (alpha == 255) ? c : new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
+ private static double getAlpha(Color c, ColorStyle fc) {
+ double alpha = c.getAlpha()/255d;
+ int fcAlpha = fc.getAlpha();
+ if (fcAlpha != -1) {
+ alpha *= fcAlpha/100000d;
+ }
+ return Math.min(1, Math.max(0, alpha));
}
/**
- * Apply lumMod / lumOff adjustments
- *
- * @param c the color to modify
- * @param fc the color style containing the lumMod / lumOff adjustments
- * @return modified color
+ * Apply the modulation and offset adjustments to the given HSL part
+ *
+ * Example for lumMod/lumOff:
+ * The lumMod value is the percent luminance. A lumMod value of "60000",
+ * is 60% of the luminance of the original color.
+ * When the color is a shade of the original theme color, the lumMod
+ * attribute is the only one of the tags shown here that appears.
+ * The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a
+ * tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation
+ *
+ * Despite having different ways to display the tint and shade percentages,
+ * all of the programs use the same method to calculate the resulting color.
+ * Convert the original RGB value to HSL ... and then adjust the luminance (L)
+ * with one of the following equations before converting the HSL value back to RGB.
+ * (The % tint in the following equations refers to the tint, themetint, themeshade,
+ * or lumMod values, as applicable.)
+ *
+ * @param hsl the hsl values
+ * @param hslPart the hsl part to modify [0..2]
+ * @param mod the modulation adjustment
+ * @param off the offset adjustment
+ * @return the modified hsl value
*
- * @see <a href="https://msdn.microsoft.com/en-us/library/dd560821%28v=office.12%29.aspx">Using Office Open XML to Customize Document Formatting in the 2007 Office System</a>
*/
- protected static Color applyLuminance(Color c, ColorStyle fc) {
- int lumMod = fc.getLumMod();
- if (lumMod == -1) lumMod = 100000;
-
- int lumOff = fc.getLumOff();
- if (lumOff == -1) lumOff = 0;
-
- if (lumMod == 100000 && lumOff == 0) return c;
-
- // The lumMod value is the percent luminance. A lumMod value of "60000",
- // is 60% of the luminance of the original color.
- // When the color is a shade of the original theme color, the lumMod
- // attribute is the only one of the tags shown here that appears.
- // The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a
- // tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation
- //
- // Despite having different ways to display the tint and shade percentages,
- // all of the programs use the same method to calculate the resulting color.
- // Convert the original RGB value to HSL ... and then adjust the luminance (L)
- // with one of the following equations before converting the HSL value back to RGB.
- // (The % tint in the following equations refers to the tint, themetint, themeshade,
- // or lumMod values, as applicable.)
- //
- // For a shade, the equation is luminance * %tint.
- //
- // For a tint, the equation is luminance * %tint + (1-%tint).
- // (Note that 1-%tint is equal to the lumOff value in DrawingML.)
-
- double fLumOff = lumOff / 100000d;
- double fLumMod = lumMod / 100000d;
-
- double hsl[] = RGB2HSL(c);
- hsl[2] = hsl[2]*fLumMod+fLumOff;
-
- Color c2 = HSL2RGB(hsl[0], hsl[1], hsl[2], c.getAlpha()/255d);
- return c2;
+ private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {
+ if (mod == -1) mod = 100000;
+ if (off == -1) off = 0;
+ if (!(mod == 100000 && off == 0)) {
+ double fOff = off / 1000d;
+ double fMod = mod / 100000d;
+ hsl[hslPart] = hsl[hslPart]*fMod+fOff;
+ }
}
/**
- * This algorithm returns result different from PowerPoint.
- * TODO: revisit and improve
+ * Apply the shade
+ *
+ * For a shade, the equation is luminance * %tint.
*/
- protected static Color applyShade(Color c, ColorStyle fc) {
+ private static void applyShade(double hsl[], ColorStyle fc) {
int shade = fc.getShade();
- if (shade == -1) return c;
+ if (shade == -1) return;
- float fshade = shade / 100000.f;
-
- float red = c.getRed() * fshade;
- float green = c.getGreen() * fshade;
- float blue = c.getGreen() * fshade;
+ double fshade = shade / 100000.d;
- return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());
+ hsl[2] *= fshade;
}
/**
- * This algorithm returns result different from PowerPoint.
- * TODO: revisit and improve
+ * Apply the tint
+ *
+ * For a tint, the equation is luminance * %tint + (1-%tint).
+ * (Note that 1-%tint is equal to the lumOff value in DrawingML.)
*/
- protected static Color applyTint(Color c, ColorStyle fc) {
+ private static void applyTint(double hsl[], ColorStyle fc) {
int tint = fc.getTint();
- if (tint == -1) return c;
+ if (tint == -1) return;
- float ftint = tint / 100000.f;
-
- float red = ftint * c.getRed() + (1.f - ftint) * 255.f;
- float green = ftint * c.getGreen() + (1.f - ftint) * 255.f;
- float blue = ftint * c.getBlue() + (1.f - ftint) * 255.f;
+ double ftint = tint / 100000.f;
- return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());
+ hsl[2] = hsl[2] * ftint + (100 - ftint*100.);
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java index d62b93006d..8ffc57e606 100644 --- a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java @@ -47,9 +47,6 @@ public class DrawSimpleShape<T extends SimpleShape> extends DrawShape<T> { @Override
public void draw(Graphics2D graphics) {
-// RenderableShape rShape = new RenderableShape(this);
-// rShape.render(graphics);
-
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(shape);
Paint fill = drawPaint.getPaint(graphics, shape.getFillStyle().getPaint());
Paint line = drawPaint.getPaint(graphics, shape.getStrokeStyle().getPaint());
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java index e4ce1d760a..1a40372be0 100644 --- a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java +++ b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java @@ -17,18 +17,32 @@ package org.apache.poi.sl.draw;
-import java.awt.Color;
import java.awt.Graphics2D;
-import java.awt.font.*;
+import java.awt.Paint;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
-import java.text.*;
+import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
-import java.util.*;
-
-import org.apache.poi.sl.usermodel.*;
+import java.text.AttributedString;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
+import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextRun.TextCap;
+import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.util.Units;
public class DrawTextParagraph<T extends TextRun> implements Drawable {
@@ -69,9 +83,6 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { public void draw(Graphics2D graphics){
if (lines.isEmpty()) return;
- Insets2D insets = paragraph.getParentShape().getInsets();
- double leftInset = insets.left;
- double rightInset = insets.right;
double penY = y;
boolean firstLine = true;
@@ -79,12 +90,17 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { Double leftMargin = paragraph.getLeftMargin();
if (leftMargin == null) {
// if the marL attribute is omitted, then a value of 347663 is implied
- leftMargin = Units.toPoints(347663*(indentLevel+1));
+ leftMargin = Units.toPoints(347663*indentLevel);
}
Double indent = paragraph.getIndent();
if (indent == null) {
indent = Units.toPoints(347663*indentLevel);
}
+ if (paragraph.getClass().getName().contains("HSLF")) {
+ // special handling for HSLF
+ indent -= leftMargin;
+ }
+
Double rightMargin = paragraph.getRightMargin();
if (rightMargin == null) {
rightMargin = 0d;
@@ -104,25 +120,30 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { }
if (bullet != null){
- bullet.setPosition(x + indent, penY);
+ bullet.setPosition(x+leftMargin+indent, penY);
bullet.draw(graphics);
// don't let text overlay the bullet and advance by the bullet width
double bulletWidth = bullet.getLayout().getAdvance() + 1;
- penX = x + Math.max(leftMargin, indent+bulletWidth);
+ penX = x + Math.max(leftMargin, leftMargin+indent+bulletWidth);
} else {
- penX = x + indent;
+ penX = x + leftMargin;
}
} else {
penX = x + leftMargin;
}
Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape());
+ // Insets are already applied on DrawTextShape.drawContent
+ // but (outer) anchor need to be adjusted
+ Insets2D insets = paragraph.getParentShape().getInsets();
+ double leftInset = insets.left;
+ double rightInset = insets.right;
TextAlign ta = paragraph.getTextAlign();
if (ta == null) ta = TextAlign.LEFT;
switch (ta) {
case CENTER:
- penX += (anchor.getWidth() - leftMargin - line.getWidth() - leftInset - rightInset) / 2;
+ penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;
break;
case RIGHT:
penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);
@@ -245,8 +266,14 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { if (buFont == null) buFont = paragraph.getDefaultFontFamily();
assert(buFont != null);
- Color buColor = bulletStyle.getBulletFontColor();
- if (buColor == null) buColor = (Color)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);
+ PlaceableShape ps = getParagraphShape();
+ PaintStyle fgPaintStyle = bulletStyle.getBulletFontColor();
+ Paint fgPaint;
+ if (fgPaintStyle == null) {
+ fgPaint = (Paint)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);
+ } else {
+ fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);
+ }
float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);
Double buSz = bulletStyle.getBulletFontSize();
@@ -256,7 +283,7 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { AttributedString str = new AttributedString(buCharacter);
- str.addAttribute(TextAttribute.FOREGROUND, buColor);
+ str.addAttribute(TextAttribute.FOREGROUND, fgPaint);
str.addAttribute(TextAttribute.FAMILY, buFont);
str.addAttribute(TextAttribute.SIZE, fontSize);
@@ -382,11 +409,31 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { this.endIndex = endIndex;
}
}
+
+ /**
+ * Helper method for paint style relative to bounds, e.g. gradient paint
+ */
+ private PlaceableShape getParagraphShape() {
+ PlaceableShape ps = new PlaceableShape(){
+ public ShapeContainer<? extends Shape> getParent() { return null; }
+ public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); }
+ public void setAnchor(Rectangle2D anchor) {}
+ public double getRotation() { return 0; }
+ public void setRotation(double theta) {}
+ public void setFlipHorizontal(boolean flip) {}
+ public void setFlipVertical(boolean flip) {}
+ public boolean getFlipHorizontal() { return false; }
+ public boolean getFlipVertical() { return false; }
+ };
+ return ps;
+ }
protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){
List<AttributedStringData> attList = new ArrayList<AttributedStringData>();
if (text == null) text = new StringBuilder();
+ PlaceableShape ps = getParagraphShape();
+
DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);
for (TextRun run : paragraph){
@@ -398,9 +445,9 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable { text.append(runText);
int endIndex = text.length();
- Color fgColor = run.getFontColor();
- if (fgColor == null) fgColor = Color.BLACK;
- attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgColor, beginIndex, endIndex));
+ PaintStyle fgPaintStyle = run.getFontColor();
+ Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);
+ attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex));
// user can pass an custom object to convert fonts
String fontFamily = run.getFontFamily();
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java index 3be880ec02..36896ba688 100644 --- a/src/java/org/apache/poi/sl/draw/DrawTextShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawTextShape.java @@ -102,7 +102,6 @@ public class DrawTextShape<T extends TextShape<? extends TextParagraph<? extends */
public double drawParagraphs(Graphics2D graphics, double x, double y) {
DrawFactory fact = DrawFactory.getInstance(graphics);
- Insets2D shapePadding = shape.getInsets();
double y0 = y;
Iterator<? extends TextParagraph<? extends TextRun>> paragraphs = shape.iterator();
diff --git a/src/java/org/apache/poi/sl/usermodel/ColorStyle.java b/src/java/org/apache/poi/sl/usermodel/ColorStyle.java index 9be847b36c..fba7f5eae0 100644 --- a/src/java/org/apache/poi/sl/usermodel/ColorStyle.java +++ b/src/java/org/apache/poi/sl/usermodel/ColorStyle.java @@ -32,17 +32,55 @@ public interface ColorStyle { int getAlpha();
/**
- * the luminance shift as expressed by a percentage relative to the input color
+ * the hue shift as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%
+ *
+ * @return hue shift in percents in the range [0..100000] (usually ...)
+ * or -1 if the value is not set
+ */
+ int getHueOff();
+
+ /**
+ * the hue as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%
+ *
+ * @return hue in percents in the range [0..100000] (usually ...)
+ * or -1 if the value is not set
+ */
+ int getHueMod();
+
+ /**
+ * the saturation shift as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%
+ *
+ * @return saturation shift in percents in the range [0..100000] (usually ...)
+ * or -1 if the value is not set
+ */
+ int getSatOff();
+
+ /**
+ * the saturation as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%
+ *
+ * @return saturation in percents in the range [0..100000] (usually ...)
+ * or -1 if the value is not set
+ */
+ int getSatMod();
+
+ /**
+ * the luminance shift as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%
*
- * @return luminance shift in percents in the range [0..100000]
+ * @return luminance shift in percents in the range [0..100000] (usually ...)
* or -1 if the value is not set
*/
int getLumOff();
/**
- * the luminance as expressed by a percentage relative to the input color
+ * the luminance as expressed by a percentage relative to the input color.
+ * Be aware that OOXML also returns values greater than 100%.
*
- * @return luminance in percents in the range [0..100000]
+ * @return luminance in percents in the range [0..100000] (usually ...)
* or -1 if the value is not set
*/
int getLumMod();
@@ -50,8 +88,9 @@ public interface ColorStyle { /**
* specifies a darker version of its input color.
* A 10% shade is 10% of the input color combined with 90% black.
+ * Be aware that OOXML also returns values greater than 100%.
*
- * @return the value of the shade specified as percents in the range [0..100000]
+ * @return the value of the shade specified as percents in the range [0..100000] (usually ...)
* with 0% indicating minimal shade and 100% indicating maximum
* or -1 if the value is not set
*/
@@ -60,8 +99,9 @@ public interface ColorStyle { /**
* specifies a lighter version of its input color.
* A 10% tint is 10% of the input color combined with 90% white.
+ * Be aware that OOXML also returns values greater than 100%
*
- * @return the value of the tint specified as percents in the range [0..100000]
+ * @return the value of the tint specified as percents in the range [0..100000] (usually ...)
* with 0% indicating minimal tint and 100% indicating maximum
* or -1 if the value is not set
*/
diff --git a/src/java/org/apache/poi/sl/usermodel/PaintStyle.java b/src/java/org/apache/poi/sl/usermodel/PaintStyle.java index 2551201692..25651043b7 100644 --- a/src/java/org/apache/poi/sl/usermodel/PaintStyle.java +++ b/src/java/org/apache/poi/sl/usermodel/PaintStyle.java @@ -17,14 +17,12 @@ package org.apache.poi.sl.usermodel; -import java.awt.Color; import java.io.InputStream; -import org.apache.poi.sl.draw.DrawPaint; - public interface PaintStyle { + public interface SolidPaint extends PaintStyle { ColorStyle getSolidColor(); } @@ -58,6 +56,4 @@ public interface PaintStyle { */ int getAlpha(); } - - SolidPaint TRANSPARENT_PAINT = DrawPaint.createSolidPaint(new Color(0xFF, 0xFF, 0xFF, 0)); } diff --git a/src/java/org/apache/poi/sl/usermodel/Slide.java b/src/java/org/apache/poi/sl/usermodel/Slide.java index 7b238de176..b992a5e3c6 100644 --- a/src/java/org/apache/poi/sl/usermodel/Slide.java +++ b/src/java/org/apache/poi/sl/usermodel/Slide.java @@ -18,20 +18,26 @@ package org.apache.poi.sl.usermodel; public interface Slide<T extends Shape, SS extends SlideShow, N extends Notes<T,SS>> extends Sheet<T, SS> { - N getNotes(); - void setNotes(N notes); + N getNotes(); + void setNotes(N notes); - boolean getFollowMasterBackground(); - void setFollowMasterBackground(boolean follow); + boolean getFollowMasterBackground(); + void setFollowMasterBackground(boolean follow); - boolean getFollowMasterColourScheme(); - void setFollowMasterColourScheme(boolean follow); + boolean getFollowMasterColourScheme(); + void setFollowMasterColourScheme(boolean follow); - boolean getFollowMasterObjects(); - void setFollowMasterObjects(boolean follow); + boolean getFollowMasterObjects(); + void setFollowMasterObjects(boolean follow); + + /** + * @return the 1-based slide no. + */ + int getSlideNumber(); + + /** + * @return title of this slide or null if title is not set + */ + String getTitle(); - /** - * @return the 1-based slide no. - */ - int getSlideNumber(); } diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShow.java b/src/java/org/apache/poi/sl/usermodel/SlideShow.java index 5ced5b21e2..e8f442821a 100644 --- a/src/java/org/apache/poi/sl/usermodel/SlideShow.java +++ b/src/java/org/apache/poi/sl/usermodel/SlideShow.java @@ -21,7 +21,6 @@ import java.awt.Dimension; import java.io.IOException; import java.util.List; -import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureData.PictureType; public interface SlideShow { diff --git a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java index 0b2eb062c2..97296bb0bc 100644 --- a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java +++ b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java @@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel; import java.awt.Color;
+
public interface TextParagraph<T extends TextRun> extends Iterable<T> {
/**
@@ -113,7 +114,20 @@ public interface TextParagraph<T extends TextRun> extends Iterable<T> { * @return the bullet point font size
*/
Double getBulletFontSize();
- Color getBulletFontColor();
+
+ /**
+ * Convenience function to set a solid color
+ */
+ void setBulletFontColor(Color color);
+
+ void setBulletFontColor(PaintStyle color);
+
+ /**
+ *
+ * @return the color of bullet characters within a given paragraph.
+ * A {@code null} value means to use the text font color.
+ */
+ PaintStyle getBulletFontColor();
AutoNumberingScheme getAutoNumberingScheme();
/**
diff --git a/src/java/org/apache/poi/sl/usermodel/TextRun.java b/src/java/org/apache/poi/sl/usermodel/TextRun.java index 946bfc3217..ff76a98e08 100644 --- a/src/java/org/apache/poi/sl/usermodel/TextRun.java +++ b/src/java/org/apache/poi/sl/usermodel/TextRun.java @@ -19,6 +19,8 @@ package org.apache.poi.sl.usermodel; import java.awt.Color; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; + /** * Some text. */ @@ -34,8 +36,33 @@ public interface TextRun { TextCap getTextCap(); - Color getFontColor(); - void setFontColor(Color color); + /** + * Returns the font color. + * This usually returns a {@link SolidPaint}, but but also other classes are possible + * + * @return the font color/paint + * + * @see org.apache.poi.sl.draw.DrawPaint#getPaint(java.awt.Graphics2D, PaintStyle) + * @see SolidPaint#getSolidColor() + * @see org.apache.poi.sl.draw.DrawPaint#applyColorTransform(ColorStyle) + */ + PaintStyle getFontColor(); + + /** + * Sets the (solid) font color - convenience function + * + * @param color the color + */ + void setFontColor(Color color); + + /** + * Sets the font color + * + * @param color the color + * + * @see org.apache.poi.sl.draw.DrawPaint#createSolidPaint(Color) + */ + void setFontColor(PaintStyle color); /** diff --git a/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java b/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java new file mode 100644 index 0000000000..19446c98c0 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java @@ -0,0 +1,298 @@ +/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.sl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.security.GeneralSecurityException;
+
+import org.apache.poi.EmptyFileException;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageAccess;
+import org.apache.poi.poifs.crypt.Decryptor;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+
+public class SlideShowFactory {
+ /**
+ * Creates a HSLFSlideShow from the given POIFSFileSystem
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.
+ */
+ public static SlideShow create(POIFSFileSystem fs) throws IOException {
+ return new HSLFSlideShow(fs);
+ }
+
+ /**
+ * Creates a HSLFSlideShow from the given NPOIFSFileSystem
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.
+ */
+ public static SlideShow create(NPOIFSFileSystem fs) throws IOException {
+ try {
+ return create(fs, null);
+ } catch (InvalidFormatException e) {
+ // Special case of OOXML-in-POIFS which is broken
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Creates a SlideShow from the given NPOIFSFileSystem, which may
+ * be password protected
+ *
+ * @param fs The {@link NPOIFSFileSystem} to read the document from
+ * @param password The password that should be used or null if no password is necessary.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ */
+ private static SlideShow create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException {
+ DirectoryNode root = fs.getRoot();
+
+ // Encrypted OOXML files go inside OLE2 containers, is this one?
+ if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
+ EncryptionInfo info = new EncryptionInfo(fs);
+ Decryptor d = Decryptor.getInstance(info);
+
+ boolean passwordCorrect = false;
+ InputStream stream = null;
+ try {
+ if (password != null && d.verifyPassword(password)) {
+ passwordCorrect = true;
+ }
+ if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
+ passwordCorrect = true;
+ }
+ if (passwordCorrect) {
+ stream = d.getDataStream(root);
+ }
+ } catch (GeneralSecurityException e) {
+ throw new IOException(e);
+ }
+
+ if (! passwordCorrect) {
+ if (password != null)
+ throw new EncryptedDocumentException("Password incorrect");
+ else
+ throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied");
+ }
+
+ OPCPackage pkg = OPCPackage.open(stream);
+ return create(pkg);
+ }
+
+ // If we get here, it isn't an encrypted PPTX file
+ // So, treat it as a regular HSLF PPT one
+ if (password != null) {
+ Biff8EncryptionKey.setCurrentUserPassword(password);
+ }
+ SlideShow wb = new HSLFSlideShow(root);
+ Biff8EncryptionKey.setCurrentUserPassword(null);
+ return wb;
+ }
+
+ /**
+ * Creates a XMLSlideShow from the given OOXML Package
+ *
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.</p>
+ *
+ * @param pkg The {@link OPCPackage} opened for reading data.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ */
+ public static SlideShow create(OPCPackage pkg) throws IOException {
+ return new XMLSlideShow(pkg);
+ }
+
+ /**
+ * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * the given InputStream.
+ *
+ * <p>Your input stream MUST either support mark/reset, or
+ * be wrapped as a {@link PushbackInputStream}! Note that
+ * using an {@link InputStream} has a higher memory footprint
+ * than using a {@link File}.</p>
+ *
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use. Note also that loading
+ * from an InputStream requires more memory than loading
+ * from a File, so prefer {@link #create(File)} where possible.
+ *
+ * @param inp The {@link InputStream} to read data from.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ * @throws EncryptedDocumentException If the SlideShow given is password protected
+ */
+ public static SlideShow create(InputStream inp) throws IOException, InvalidFormatException, EncryptedDocumentException {
+ return create(inp, null);
+ }
+
+ /**
+ * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * the given InputStream, which may be password protected.
+ * <p>Your input stream MUST either support mark/reset, or
+ * be wrapped as a {@link PushbackInputStream}! Note that
+ * using an {@link InputStream} has a higher memory footprint
+ * than using a {@link File}.</p>
+ *
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use. Note also that loading
+ * from an InputStream requires more memory than loading
+ * from a File, so prefer {@link #create(File)} where possible.</p>
+ *
+ * @param inp The {@link InputStream} to read data from.
+ * @param password The password that should be used or null if no password is necessary.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ * @throws EncryptedDocumentException If the wrong password is given for a protected file
+ * @throws EmptyFileException If an empty stream is given
+ */
+ public static SlideShow create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
+ // If clearly doesn't do mark/reset, wrap up
+ if (! inp.markSupported()) {
+ inp = new PushbackInputStream(inp, 8);
+ }
+
+ // Ensure that there is at least some data there
+ byte[] header8 = IOUtils.peekFirst8Bytes(inp);
+
+ // Try to create
+ if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
+ NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
+ return create(fs, password);
+ }
+ if (POIXMLDocument.hasOOXMLHeader(inp)) {
+ return new XMLSlideShow(OPCPackage.open(inp));
+ }
+ throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
+ }
+
+ /**
+ * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * the given File, which must exist and be readable.
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.
+ *
+ * @param file The file to read data from.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ * @throws EncryptedDocumentException If the SlideShow given is password protected
+ */
+ public static SlideShow create(File file) throws IOException, InvalidFormatException, EncryptedDocumentException {
+ return create(file, null);
+ }
+
+ /**
+ * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * the given File, which must exist and be readable, and
+ * may be password protected
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.
+ *
+ * @param file The file to read data from.
+ * @param password The password that should be used or null if no password is necessary.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ * @throws EncryptedDocumentException If the wrong password is given for a protected file
+ * @throws EmptyFileException If an empty stream is given
+ */
+ public static SlideShow create(File file, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
+ return create(file, password, false);
+ }
+
+ /**
+ * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * the given File, which must exist and be readable, and
+ * may be password protected
+ * <p>Note that in order to properly release resources the
+ * SlideShow should be closed after use.
+ *
+ * @param file The file to read data from.
+ * @param password The password that should be used or null if no password is necessary.
+ * @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back
+ * changes when the document is closed.
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while reading the data
+ * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}
+ * @throws EncryptedDocumentException If the wrong password is given for a protected file
+ * @throws EmptyFileException If an empty stream is given
+ */
+ public static SlideShow create(File file, String password, boolean readOnly) throws IOException, InvalidFormatException, EncryptedDocumentException {
+ if (! file.exists()) {
+ throw new FileNotFoundException(file.toString());
+ }
+
+ try {
+ NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly);
+ return create(fs, password);
+ } catch(OfficeXmlFileException e) {
+ // opening as .ppt failed => try opening as .pptx
+ OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);
+ try {
+ return new XMLSlideShow(pkg);
+// } catch (IOException ioe) {
+// // ensure that file handles are closed (use revert() to not re-write the file)
+// pkg.revert();
+// //pkg.close();
+//
+// // rethrow exception
+// throw ioe;
+ } catch (IllegalArgumentException ioe) {
+ // ensure that file handles are closed (use revert() to not re-write the file)
+ pkg.revert();
+ //pkg.close();
+
+ // rethrow exception
+ throw ioe;
+ }
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java b/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java index ced941ccb3..c20f94259b 100644 --- a/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java +++ b/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java @@ -27,8 +27,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties * @author Yegor Kozlov
*/
public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {
- public boolean isFetchingFromMaster = false;
-
public CharacterPropertyFetcher(int level) {
super(level);
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java index 09e05d9648..67a41faec2 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java @@ -78,6 +78,22 @@ public class XSLFColor { return getRawValue("alpha");
}
+ public int getHueOff() {
+ return getRawValue("hueOff");
+ }
+
+ public int getHueMod() {
+ return getRawValue("hueMod");
+ }
+
+ public int getSatOff() {
+ return getRawValue("satOff");
+ }
+
+ public int getSatMod() {
+ return getRawValue("satMod");
+ }
+
public int getLumOff() {
return getRawValue("lumOff");
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java index c3b0b1a511..f312145b9b 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java @@ -44,8 +44,12 @@ public class XSLFDrawing { XmlObject[] cNvPr = sheet.getSpTree().selectPath(
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
for(XmlObject o : cNvPr) {
- CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
- _shapeId = (int)Math.max(_shapeId, p.getId());
+ // powerpoint generates AlternateContent elements which cNvPr elements aren't recognized
+ // ignore them for now
+ if (o instanceof CTNonVisualDrawingProps) {
+ CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
+ _shapeId = (int)Math.max(_shapeId, p.getId());
+ }
}
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java index 85e85b6a46..fd42bc2d76 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java @@ -21,8 +21,6 @@ import java.awt.Color; import java.awt.geom.Rectangle2D;
import org.apache.poi.sl.draw.DrawPaint;
-import org.apache.poi.sl.usermodel.ColorStyle;
-import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.Shadow;
import org.apache.poi.util.Units;
@@ -90,7 +88,7 @@ public class XSLFShadow extends XSLFShape implements Shadow { */
public Color getFillColor() {
SolidPaint ps = getFillStyle();
- if (ps == PaintStyle.TRANSPARENT_PAINT) return null;
+ if (ps == null) return null;
Color col = DrawPaint.applyColorTransform(ps.getSolidColor());
return col;
}
@@ -99,14 +97,10 @@ public class XSLFShadow extends XSLFShape implements Shadow { public SolidPaint getFillStyle() {
XSLFTheme theme = getSheet().getTheme();
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
- if(ct == null) return PaintStyle.TRANSPARENT_PAINT;
+ if(ct == null) return null;
CTSchemeColor phClr = ct.getSchemeClr();
final XSLFColor xc = new XSLFColor(ct, theme, phClr);
- return new SolidPaint(){
- public ColorStyle getSolidColor() {
- return xc.getColorStyle();
- }
- };
+ return DrawPaint.createSolidPaint(xc.getColorStyle());
}
}
\ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java index 3ea1d3a7ca..d0c5123825 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -27,10 +27,10 @@ import java.util.Comparator; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
-import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.Shape;
@@ -38,7 +38,20 @@ import org.apache.poi.util.Beta; import org.apache.poi.util.Internal;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.*;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
+import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
@@ -139,7 +152,7 @@ public abstract class XSLFShape implements Shape { try {
pr = shape.getSpPr();
if (((CTShapeProperties)pr).isSetNoFill()) {
- setValue(PaintStyle.TRANSPARENT_PAINT);
+ setValue(null);
return true;
}
} catch (IllegalStateException e) {}
@@ -156,21 +169,19 @@ public abstract class XSLFShape implements Shape { }
}
- if (pr == null) {
- setValue(PaintStyle.TRANSPARENT_PAINT);
- return true;
- }
+ if (pr == null) return false;
PaintStyle paint = null;
+ PackagePart pp = getSheet().getPackagePart();
for (XmlObject obj : pr.selectPath("*")) {
- paint = selectPaint(obj, null, getSheet().getPackagePart());
- if (paint != null) break;
+ paint = selectPaint(obj, null, pp);
+ if (paint != null) {
+ setValue(paint);
+ return true;
+ };
}
- if (paint == null) return false;
-
- setValue(paint);
- return true;
+ return false;
}
};
fetchShapeProperty(fetcher);
@@ -190,7 +201,7 @@ public abstract class XSLFShape implements Shape { }
paint = selectPaint(fillRef);
- return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
+ return paint;
}
protected CTBackgroundProperties getBgPr() {
@@ -347,8 +358,8 @@ public abstract class XSLFShape implements Shape { paint = selectPaint(obj, phClr, pp);
if(paint != null) break;
}
- return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
- }
+ return paint;
+ }
/**
* Convert shape fill into java.awt.Paint. The result is either Color or
@@ -371,13 +382,13 @@ public abstract class XSLFShape implements Shape { */
protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {
if (obj instanceof CTNoFillProperties) {
- return PaintStyle.TRANSPARENT_PAINT;
+ return null;
} else if (obj instanceof CTSolidColorFillProperties) {
- return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart);
+ return selectPaint((CTSolidColorFillProperties)obj, phClr);
} else if (obj instanceof CTBlipFillProperties) {
- return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);
+ return selectPaint((CTBlipFillProperties)obj, parentPart);
} else if (obj instanceof CTGradientFillProperties) {
- return selectPaint((CTGradientFillProperties) obj, phClr, parentPart);
+ return selectPaint((CTGradientFillProperties) obj, phClr);
} else if (obj instanceof CTStyleMatrixReference) {
return selectPaint((CTStyleMatrixReference)obj);
} else {
@@ -385,17 +396,16 @@ public abstract class XSLFShape implements Shape { }
}
- protected PaintStyle selectPaint(final CTSolidColorFillProperties solidFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+ protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr) {
final XSLFTheme theme = getSheet().getTheme();
+ if (phClr == null && solidFill.isSetSchemeClr()) {
+ phClr = solidFill.getSchemeClr();
+ }
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
- return new SolidPaint() {
- public ColorStyle getSolidColor() {
- return c.getColorStyle();
- }
- };
+ return DrawPaint.createSolidPaint(c.getColorStyle());
}
- protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+ protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
final CTBlip blip = blipFill.getBlip();
return new TexturePaint() {
private PackagePart getPart() {
@@ -424,12 +434,12 @@ public abstract class XSLFShape implements Shape { public int getAlpha() {
return (blip.sizeOfAlphaModFixArray() > 0)
? blip.getAlphaModFixArray(0).getAmt()
- : 0;
+ : 100000;
}
};
}
- protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+ protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr) {
@SuppressWarnings("deprecation")
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
@@ -448,7 +458,11 @@ public abstract class XSLFShape implements Shape { int i=0;
for (CTGradientStop cgs : gs) {
- cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();
+ CTSchemeColor phClrCgs = phClr;
+ if (phClrCgs == null && cgs.isSetSchemeClr()) {
+ phClrCgs = cgs.getSchemeClr();
+ }
+ cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle();
fractions[i] = cgs.getPos() / 100000.f;
i++;
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java index bd29667c8c..3b08748762 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java @@ -19,8 +19,6 @@ package org.apache.poi.xslf.usermodel;
-import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
-
import java.awt.Color;
import java.awt.geom.Rectangle2D;
@@ -31,10 +29,15 @@ import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.Guide;
import org.apache.poi.sl.draw.geom.PresetGeometries;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.FillStyle;
+import org.apache.poi.sl.usermodel.LineDecoration;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
+import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.SimpleShape;
+import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
@@ -219,7 +222,6 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { */
public Color getLineColor() {
PaintStyle ps = getLinePaint();
- if (ps == null || ps == TRANSPARENT_PAINT) return null;
if (ps instanceof SolidPaint) {
return ((SolidPaint)ps).getSolidColor().getColor();
}
@@ -232,7 +234,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { CTLineProperties spPr = shape.getSpPr().getLn();
if (spPr != null) {
if (spPr.isSetNoFill()) {
- setValue(TRANSPARENT_PAINT); // use it as 'nofill' value
+ setValue(null); // use it as 'nofill' value
return true;
}
@@ -266,7 +268,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { // line color was not found, check if it is defined in the theme
CTShapeStyle style = getSpStyle();
- if (style == null) return TRANSPARENT_PAINT;
+ if (style == null) return null;
// get a reference to a line style within the style matrix.
CTStyleMatrixReference lnRef = style.getLnRef();
@@ -279,7 +281,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { paint = getPaint(lnProps, phClr);
}
- return paint == null ? TRANSPARENT_PAINT : paint;
+ return paint;
}
/**
@@ -524,7 +526,6 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { */
public Color getFillColor() {
PaintStyle ps = getFillPaint();
- if (ps == null || ps == TRANSPARENT_PAINT) return null;
if (ps instanceof SolidPaint) {
return ((SolidPaint)ps).getSolidColor().getColor();
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java index 83024ee2ef..83453573cd 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java @@ -168,13 +168,10 @@ public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSl return _notes; } - /** - * - * @return title of this slide or empty string if title is not set - */ + @Override public String getTitle(){ XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE); - return txt == null ? "" : txt.getText(); + return txt == null ? null : txt.getText(); } @Override diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index f9bad78be2..6cffd94701 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -21,7 +21,10 @@ import java.util.ArrayList; import java.util.Iterator;
import java.util.List;
+import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
@@ -264,7 +267,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { * @return the color of bullet characters within a given paragraph.
* A <code>null</code> value means to use the text font color.
*/
- public Color getBulletFontColor(){
+ public PaintStyle getBulletFontColor(){
final XSLFTheme theme = getParentShape().getSheet().getTheme();
ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getIndentLevel()){
public boolean fetch(CTTextParagraphProperties props){
@@ -277,19 +280,33 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { }
};
fetchParagraphProperty(fetcher);
- return fetcher.getValue();
+ Color col = fetcher.getValue();
+ return (col == null) ? null : DrawPaint.createSolidPaint(col);
}
+ public void setBulletFontColor(Color color) {
+ setBulletFontColor(DrawPaint.createSolidPaint(color));
+ }
+
+
/**
* Set the color to be used on bullet characters within a given paragraph.
*
* @param color the bullet color
*/
- public void setBulletFontColor(Color color){
+ public void setBulletFontColor(PaintStyle color) {
+ if (!(color instanceof SolidPaint)) {
+ throw new IllegalArgumentException("Currently XSLF only supports SolidPaint");
+ }
+
+ // TODO: implement setting bullet color to null
+ SolidPaint sp = (SolidPaint)color;
+ Color col = DrawPaint.applyColorTransform(sp.getSolidColor());
+
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();
CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr();
- clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});
+ clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), (byte) col.getBlue()});
}
/**
@@ -729,7 +746,6 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { XSLFSheet masterSheet = _shape.getSheet();
for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
masterSheet = m;
-
XmlObject xo = masterSheet.getXmlObject();
for (String xpath : xpaths) {
XmlObject[] o = xo.selectPath(xpath);
@@ -767,32 +783,35 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){
boolean ok = false;
-
+ XSLFTextShape shape = getParentShape();
+ XSLFSheet sheet = shape.getSheet();
+
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
+ if (ok) return true;
- if(!ok) {
- XSLFTextShape shape = getParentShape();
- ok = shape.fetchShapeProperty(visitor);
- if(!ok){
- CTPlaceholder ph = shape.getCTPlaceholder();
- if(ph == null){
- // if it is a plain text box then take defaults from presentation.xml
- XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();
- CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
- if(themeProps != null) ok = visitor.fetch(themeProps);
- }
-
- if(!ok){
- // defaults for placeholders are defined in the slide master
- CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
- if(defaultProps != null) ok = visitor.fetch(defaultProps);
- }
- }
+ ok = shape.fetchShapeProperty(visitor);
+ if (ok) return true;
+
+
+ CTPlaceholder ph = shape.getCTPlaceholder();
+ if(ph == null){
+ // if it is a plain text box then take defaults from presentation.xml
+ XMLSlideShow ppt = sheet.getSlideShow();
+ CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
+ if (themeProps != null) ok = visitor.fetch(themeProps);
}
+ if (ok) return true;
+
+ // defaults for placeholders are defined in the slide master
+ CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
+ // TODO: determine master shape
+ if(defaultProps != null) ok = visitor.fetch(defaultProps);
+ if (ok) return true;
- return ok;
+ return false;
}
+ @SuppressWarnings("deprecation")
void copy(XSLFTextParagraph other){
if (other == this) return;
@@ -848,7 +867,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { if(buChar != null && !buChar.equals(getBulletCharacter())){
setBulletCharacter(buChar);
}
- Color buColor = other.getBulletFontColor();
+ PaintStyle buColor = other.getBulletFontColor();
if(buColor != null && !buColor.equals(getBulletFontColor())){
setBulletFontColor(buColor);
}
@@ -920,11 +939,21 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> { }
@Override
- public Color getBulletFontColor() {
+ public PaintStyle getBulletFontColor() {
return XSLFTextParagraph.this.getBulletFontColor();
}
@Override
+ public void setBulletFontColor(Color color) {
+ setBulletFontColor(DrawPaint.createSolidPaint(color));
+ }
+
+ @Override
+ public void setBulletFontColor(PaintStyle color) {
+ XSLFTextParagraph.this.setBulletFontColor(color);
+ }
+
+ @Override
public AutoNumberingScheme getAutoNumberingScheme() {
return XSLFTextParagraph.this.getAutoNumberingScheme();
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java index 7a5c78b198..fd0f44d75a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java @@ -18,6 +18,9 @@ package org.apache.poi.xslf.usermodel; import java.awt.Color;
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.util.Beta;
import org.apache.poi.xslf.model.CharacterPropertyFetcher;
@@ -84,10 +87,21 @@ public class XSLFTextRun implements TextRun { @Override
public void setFontColor(Color color) {
+ setFontColor(DrawPaint.createSolidPaint(color));
+ }
+
+ @Override
+ public void setFontColor(PaintStyle color) {
+ if (!(color instanceof SolidPaint)) {
+ throw new IllegalArgumentException("Currently only SolidPaint is supported!");
+ }
+ SolidPaint sp = (SolidPaint)color;
+
CTTextCharacterProperties rPr = getRPr();
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
- clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
+ Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
+ clr.setVal(new byte[]{(byte)c.getRed(), (byte)c.getGreen(), (byte)c.getBlue()});
if(fill.isSetHslClr()) fill.unsetHslClr();
if(fill.isSetPrstClr()) fill.unsetPrstClr();
@@ -98,22 +112,22 @@ public class XSLFTextRun implements TextRun { }
@Override
- public Color getFontColor(){
- final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
- CTShapeStyle style = _p.getParentShape().getSpStyle();
- final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();
-
- CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getIndentLevel()){
+ public PaintStyle getFontColor(){
+ CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
- CTSolidColorFillProperties solidFill = props.getSolidFill();
- if(solidFill != null) {
- boolean useCtxColor =
- (solidFill.isSetSchemeClr() && solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)
- || isFetchingFromMaster;
- Color c = new XSLFColor(solidFill, theme, useCtxColor ? phClr : null).getColor();
- setValue(c);
+ XSLFShape shape = _p.getParentShape();
+ CTShapeStyle style = shape.getSpStyle();
+ CTSchemeColor phClr = null;
+ if (style != null && style.getFontRef() != null) {
+ phClr = style.getFontRef().getSchemeClr();
+ }
+
+ PaintStyle ps = shape.getPaint(props, phClr);
+ if (ps != null) {
+ setValue(ps);
return true;
}
+
return false;
}
};
@@ -250,7 +264,7 @@ public class XSLFTextRun implements TextRun { }
public byte getPitchAndFamily(){
- final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
+ // final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
@@ -474,35 +488,36 @@ public class XSLFTextRun implements TextRun { }
private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
+ XSLFTextShape shape = _p.getParentShape();
+ XSLFSheet sheet = shape.getSheet();
boolean ok = false;
- if(_r.isSetRPr()) ok = fetcher.fetch(getRPr());
-
- if(!ok) {
- XSLFTextShape shape = _p.getParentShape();
- ok = shape.fetchShapeProperty(fetcher);
- if(!ok){
- CTPlaceholder ph = shape.getCTPlaceholder();
- if(ph == null){
- // if it is a plain text box then take defaults from presentation.xml
- XMLSlideShow ppt = shape.getSheet().getSlideShow();
- CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
- if(themeProps != null) {
- fetcher.isFetchingFromMaster = true;
- ok = fetcher.fetch(themeProps);
- }
- }
- if (!ok) {
- CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
- if(defaultProps != null) {
- fetcher.isFetchingFromMaster = true;
- ok = fetcher.fetch(defaultProps);
- }
- }
+ if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());
+ if (ok) return true;
+
+ ok = shape.fetchShapeProperty(fetcher);
+ if (ok) return true;
+
+ CTPlaceholder ph = shape.getCTPlaceholder();
+ if (ph == null){
+ // if it is a plain text box then take defaults from presentation.xml
+ XMLSlideShow ppt = sheet.getSlideShow();
+ CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
+ if (themeProps != null) {
+ // TODO: determine master shape
+ ok = fetcher.fetch(themeProps);
}
}
+ if (ok) return true;
+
+ CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
+ if(defaultProps != null) {
+ // TODO: determine master shape
+ ok = fetcher.fetch(defaultProps);
+ }
+ if (ok) return true;
- return ok;
+ return false;
}
void copy(XSLFTextRun r){
@@ -511,7 +526,7 @@ public class XSLFTextRun implements TextRun { setFontFamily(srcFontFamily);
}
- Color srcFontColor = r.getFontColor();
+ PaintStyle srcFontColor = r.getFontColor();
if(srcFontColor != null && !srcFontColor.equals(getFontColor())){
setFontColor(srcFontColor);
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java b/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java index 400c637ca8..43fefedf54 100644 --- a/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java +++ b/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java @@ -19,19 +19,22 @@ package org.apache.poi.xslf.util;
-import org.apache.poi.openxml4j.opc.OPCPackage;
-import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.apache.poi.xslf.usermodel.XSLFSlide;
-
-import javax.imageio.ImageIO;
-
-import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
-import java.io.FileOutputStream;
+import java.io.File;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+import org.apache.poi.sl.SlideShowFactory;
+import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.util.JvmBugs;
/**
* An utulity to convert slides of a .pptx slide show to a PNG image
@@ -40,22 +43,33 @@ import java.util.List; */
public class PPTX2PNG {
- static void usage(){
- System.out.println("Usage: PPTX2PNG [options] <pptx file>");
- System.out.println("Options:");
- System.out.println(" -scale <float> scale factor");
- System.out.println(" -slide <integer> 1-based index of a slide to render");
+ static void usage(String error){
+ String msg =
+ "Usage: PPTX2PNG [options] <ppt or pptx file>\n" +
+ (error == null ? "" : ("Error: "+error+"\n")) +
+ "Options:\n" +
+ " -scale <float> scale factor\n" +
+ " -slide <integer> 1-based index of a slide to render\n" +
+ " -format <type> png,gif,jpg (,null for testing)" +
+ " -outdir <dir> output directory, defaults to origin of the ppt/pptx file" +
+ " -quite do not write to console (for normal processing)";
+
+ System.out.println(msg);
+ // no System.exit here, as we also run in junit tests!
}
public static void main(String[] args) throws Exception {
if (args.length == 0) {
- usage();
+ usage(null);
return;
}
int slidenum = -1;
float scale = 1;
- String file = null;
+ File file = null;
+ String format = "png";
+ File outdir = null;
+ boolean quite = false;
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
@@ -63,55 +77,104 @@ public class PPTX2PNG { scale = Float.parseFloat(args[++i]);
} else if ("-slide".equals(args[i])) {
slidenum = Integer.parseInt(args[++i]);
+ } else if ("-format".equals(args[i])) {
+ format = args[++i];
+ } else if ("-outdir".equals(args[i])) {
+ outdir = new File(args[++i]);
+ } else if ("-quite".equals(args[i])) {
+ quite = true;
}
} else {
- file = args[i];
+ file = new File(args[i]);
}
}
- if(file == null){
- usage();
+ if (file == null || !file.exists()) {
+ usage("File not specified or it doesn't exist");
+ return;
+ }
+
+ if (outdir == null) {
+ outdir = file.getParentFile();
+ }
+
+ if (outdir == null || !outdir.exists() || !outdir.isDirectory()) {
+ usage("Output directory doesn't exist");
return;
}
- System.out.println("Processing " + file);
- XMLSlideShow ppt = new XMLSlideShow(OPCPackage.open(file));
+ if (scale < 0) {
+ usage("Invalid scale given");
+ return;
+ }
+
+ if (format == null || !format.matches("^(png|gif|jpg|null)$")) {
+ usage("Invalid format given");
+ return;
+ }
+
+ if (!quite) {
+ System.out.println("Processing " + file);
+ }
+ SlideShow ss = SlideShowFactory.create(file, null, true);
+ List<? extends Slide<?,?,?>> slides = ss.getSlides();
- Dimension pgsize = ppt.getPageSize();
+
+ if (slidenum < -1 || slidenum == 0 || slidenum > slides.size()) {
+ usage("slidenum must be either -1 (for all) or within range: [1.."+slides.size()+"] for "+file);
+ return;
+ }
+
+ Dimension pgsize = ss.getPageSize();
int width = (int) (pgsize.width * scale);
int height = (int) (pgsize.height * scale);
- List<XSLFSlide> slide = ppt.getSlides();
- for (int i = 0; i < slide.size(); i++) {
- if (slidenum != -1 && slidenum != (i + 1)) continue;
-
- String title = slide.get(i).getTitle();
- System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title));
-
- BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics2D graphics = img.createGraphics();
-
- // default rendering options
- graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
- graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
- graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-
- graphics.setColor(Color.white);
- graphics.clearRect(0, 0, width, height);
-
- graphics.scale(scale, scale);
-
- // draw stuff
- slide.get(i).draw(graphics);
+ int slideNo=1;
+ for(Slide<?,?,?> slide : slides) {
+ if (slidenum == -1 || slideNo == slidenum) {
+ String title = slide.getTitle();
+ if (!quite) {
+ System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
+ }
- // save the result
- int sep = file.lastIndexOf(".");
- String fname = file.substring(0, sep == -1 ? file.length() : sep) + "-" + (i + 1) +".png";
- FileOutputStream out = new FileOutputStream(fname);
- ImageIO.write(img, "png", out);
- out.close();
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = img.createGraphics();
+ fixFonts(graphics);
+
+ // default rendering options
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ graphics.scale(scale, scale);
+
+ // draw stuff
+ slide.draw(graphics);
+
+ // save the result
+ if (!"null".equals(format)) {
+ String outname = file.getName().replaceFirst(".pptx?", "");
+ outname = String.format("%1$s-%2$04d.%3$s", outname, slideNo, format);
+ File outfile = new File(outdir, outname);
+ ImageIO.write(img, format, outfile);
+ }
+ }
+ slideNo++;
}
- System.out.println("Done");
+
+ if (!quite) {
+ System.out.println("Done");
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void fixFonts(Graphics2D graphics) {
+ if (!JvmBugs.hasLineBreakMeasurerBug()) return;
+ Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
+ if (fontMap == null) fontMap = new HashMap<String,String>();
+ fontMap.put("Calibri", "Lucida Sans");
+ fontMap.put("Cambria", "Lucida Bright");
+ graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
}
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java index a0a937aee8..2c72f0a447 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java @@ -19,16 +19,11 @@ package org.apache.poi.xslf.usermodel;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
+import java.io.File;
import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.poi.sl.draw.Drawable;
-import org.apache.poi.util.JvmBugs;
-import org.apache.poi.xslf.XSLFTestDataSamples;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.xslf.util.PPTX2PNG;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -44,7 +39,6 @@ public class TestPPTX2PNG { @BeforeClass
public static void activateJaxpDebug() {
jaxpDebugEnable = setDebugFld(true);
-// setXmlInputFactory();
}
@AfterClass
@@ -66,48 +60,26 @@ public class TestPPTX2PNG { return false;
}
}
-
-// private static void setXmlInputFactory() {
-// String propName = "javax.xml.stream.XMLInputFactory";
-// String propVal = "com.sun.xml.internal.stream.XMLInputFactoryImpl";
-// try {
-// Class.forName(propVal);
-// System.setProperty(propName, propVal);
-// } catch (Exception e){
-// // ignore
-// }
-// }
-
@Test
public void render() throws Exception {
- String[] testFiles = {"backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx", "themes.pptx",};
+ POIDataSamples samples = POIDataSamples.getSlideShowInstance();
+
+ String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
+ String[] args = {
+ "-format", "null", // png,gif,jpg or null for test
+ "-slide", "-1", // -1 for all
+ "-outdir", new File("build/tmp/").getCanonicalPath(),
+ "-quite",
+ "dummyfile"
+ };
for(String sampleFile : testFiles){
+ args[args.length-1] = samples.getFile(sampleFile).getCanonicalPath();
try {
- XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument(sampleFile);
- Dimension pg = pptx.getPageSize();
- //int slideNo=1;
- for(XSLFSlide slide : pptx.getSlides()){
- BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D graphics = img.createGraphics();
- fixFonts(graphics);
- slide.draw(graphics);
- // ImageIO.write(img, "PNG", new File("build/tmp/"+sampleFile.replaceFirst(".pptx?", "-")+slideNo+".png"));
- //slideNo++;
- }
+ PPTX2PNG.main(args);
} catch (IllegalStateException e) {
throw new IllegalStateException("While reading file " + sampleFile, e);
}
}
}
-
- @SuppressWarnings("unchecked")
- private void fixFonts(Graphics2D graphics) {
- if (!JvmBugs.hasLineBreakMeasurerBug()) return;
- Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
- if (fontMap == null) fontMap = new HashMap<String,String>();
- fontMap.put("Calibri", "Lucida Sans");
- fontMap.put("Cambria", "Lucida Bright");
- graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
- }
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java index 6088eeee71..db2c9833f7 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java @@ -16,7 +16,12 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.awt.Color;
import java.io.IOException;
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java index 3314855c70..691d9941ad 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java @@ -16,9 +16,15 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.awt.Color;
+import java.io.IOException;
import java.util.List;
import org.apache.poi.xslf.XSLFTestDataSamples;
@@ -98,7 +104,7 @@ public class TestXSLFSlide { }
@Test
- public void testCreateSlide(){
+ public void testCreateSlide() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
assertEquals(0, ppt.getSlides().size());
@@ -108,10 +114,12 @@ public class TestXSLFSlide { assertFalse(slide.getFollowMasterGraphics());
slide.setFollowMasterGraphics(true);
assertTrue(slide.getFollowMasterGraphics());
+
+ ppt.close();
}
@Test
- public void testImportContent(){
+ public void testImportContent() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XMLSlideShow src = XSLFTestDataSamples.openSampleDocument("themes.pptx");
@@ -128,7 +136,7 @@ public class TestXSLFSlide { assertEquals(40.0, r1.getFontSize(), 0);
assertTrue(r1.isBold());
assertTrue(r1.isItalic());
- assertEquals(new Color(148, 198, 0), r1.getFontColor());
+ assertTrue(sameColor(new Color(148, 198, 0), r1.getFontColor()));
assertNull(sh1.getFillColor());
assertNull(sh1.getLineColor());
@@ -141,7 +149,7 @@ public class TestXSLFSlide { assertEquals(18.0, r2.getFontSize(), 0);
assertFalse(r2.isBold());
assertFalse(r2.isItalic());
- assertEquals(Color.white, r2.getFontColor());
+ assertTrue(sameColor(Color.white, r2.getFontColor()));
assertEquals(new Color(148, 198, 0), sh2.getFillColor());
assertEquals(new Color(148, 198, 0), sh2.getLineColor()); // slightly different from PowerPoint!
@@ -157,17 +165,19 @@ public class TestXSLFSlide { //assertEquals(32.4.0, r3.getFontSize());
assertTrue(r3.isBold());
assertTrue(r3.isItalic());
- assertEquals(new Color(148, 198, 0), r3.getFontColor());
+ assertTrue(sameColor(new Color(148, 198, 0), r3.getFontColor()));
assertNull(sh3.getFillColor());
assertNull(sh3.getLineColor());
XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);
XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);
assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());
+
+ ppt.close();
}
@Test
- public void testMergeSlides(){
+ public void testMergeSlides() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"};
@@ -179,5 +189,7 @@ public class TestXSLFSlide { }
}
assertEquals(30, ppt.getSlides().size());
+
+ ppt.close();
}
}
\ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java index e71cf2419f..1ad525011c 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java @@ -16,19 +16,24 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
-
-import java.awt.*;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
+import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.draw.DrawTextFragment;
import org.apache.poi.sl.draw.DrawTextParagraph;
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Assume;
import org.junit.Test;
@@ -37,7 +42,7 @@ import org.junit.Test; * @author Yegor Kozlov
*/
public class TestXSLFTextParagraph {
- private static POILogger _logger = POILogFactory.getLogger(XSLFTextParagraph.class);
+ // private static POILogger _logger = POILogFactory.getLogger(XSLFTextParagraph.class);
static class DrawTextParagraphProxy extends DrawTextParagraph<XSLFTextRun> {
DrawTextParagraphProxy(XSLFTextParagraph p) {
@@ -58,7 +63,7 @@ public class TestXSLFTextParagraph { }
@Test
- public void testWrappingWidth() throws Exception {
+ public void testWrappingWidth() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFTextShape sh = slide.createAutoShape();
@@ -142,6 +147,8 @@ public class TestXSLFTextParagraph { expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36
assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0);
+
+ ppt.close();
}
/**
@@ -149,7 +156,7 @@ public class TestXSLFTextParagraph { * This test requires that the Arial font is available and will run only on windows
*/
@Test
- public void testBreakLines(){
+ public void testBreakLines() throws IOException {
String os = System.getProperty("os.name");
Assume.assumeTrue("Skipping testBreakLines(), it is executed only on Windows machines", (os != null && os.contains("Windows")));
@@ -237,10 +244,11 @@ public class TestXSLFTextParagraph { // the first line is at least two times higher than the second
assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2);
+ ppt.close();
}
@Test
- public void testThemeInheritance(){
+ public void testThemeInheritance() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");
List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0);
@@ -252,10 +260,11 @@ public class TestXSLFTextParagraph { XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2);
assertEquals("Foundation", sh3.getText());
assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());
+ ppt.close();
}
@Test
- public void testParagraphProperties(){
+ public void testParagraphProperties() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFTextShape sh = slide.createAutoShape();
@@ -275,7 +284,7 @@ public class TestXSLFTextParagraph { assertEquals(null, p.getBulletFontColor());
p.setBulletFontColor(Color.red);
- assertEquals(Color.red, p.getBulletFontColor());
+ assertTrue(sameColor(Color.red, p.getBulletFontColor()));
assertNull(p.getBulletFontSize());
p.setBulletFontSize(200.);
@@ -342,34 +351,35 @@ public class TestXSLFTextParagraph { assertEquals(72.0, p.getDefaultTabSize(), 0);
+ ppt.close();
}
- @Test
- public void testLineBreak(){
+ @Test(expected = IllegalStateException.class)
+ public void testLineBreak() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
- XSLFSlide slide = ppt.createSlide();
- XSLFTextShape sh = slide.createAutoShape();
-
- XSLFTextParagraph p = sh.addNewTextParagraph();
- XSLFTextRun r1 = p.addNewTextRun();
- r1.setText("Hello,");
- XSLFTextRun r2 = p.addLineBreak();
- assertEquals("\n", r2.getRawText());
- r2.setFontSize(10.0);
- assertEquals(10.0, r2.getFontSize(), 0);
- XSLFTextRun r3 = p.addNewTextRun();
- r3.setText("World!");
- r3.setFontSize(20.0);
- XSLFTextRun r4 = p.addLineBreak();
- assertEquals(20.0, r4.getFontSize(), 0);
-
- assertEquals("Hello,\nWorld!\n",sh.getText());
-
try {
+ XSLFSlide slide = ppt.createSlide();
+ XSLFTextShape sh = slide.createAutoShape();
+
+ XSLFTextParagraph p = sh.addNewTextParagraph();
+ XSLFTextRun r1 = p.addNewTextRun();
+ r1.setText("Hello,");
+ XSLFTextRun r2 = p.addLineBreak();
+ assertEquals("\n", r2.getRawText());
+ r2.setFontSize(10.0);
+ assertEquals(10.0, r2.getFontSize(), 0);
+ XSLFTextRun r3 = p.addNewTextRun();
+ r3.setText("World!");
+ r3.setFontSize(20.0);
+ XSLFTextRun r4 = p.addLineBreak();
+ assertEquals(20.0, r4.getFontSize(), 0);
+
+ assertEquals("Hello,\nWorld!\n",sh.getText());
+
+ // "You cannot change text of a line break, it is always '\\n'"
r2.setText("aaa");
- fail("Expected IllegalStateException");
- } catch (IllegalStateException e){
- assertEquals("You cannot change text of a line break, it is always '\\n'", e.getMessage());
+ } finally {
+ ppt.close();
}
}
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java index eb7553ecc4..a3d2c50e88 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java @@ -18,16 +18,23 @@ */
package org.apache.poi.xslf.usermodel;
-import junit.framework.TestCase;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-import java.awt.*;
+import java.awt.Color;
+import java.io.IOException;
+
+import org.junit.Test;
/**
* @author Yegor Kozlov
*/
-public class TestXSLFTextRun extends TestCase {
+public class TestXSLFTextRun {
- public void testRunProperties(){
+ @Test
+ public void testRunProperties() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFTextShape sh = slide.createAutoShape();
@@ -35,26 +42,26 @@ public class TestXSLFTextRun extends TestCase { XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();
assertEquals("en-US", r.getRPr().getLang());
- assertEquals(0., r.getCharacterSpacing());
+ assertEquals(0., r.getCharacterSpacing(), 0);
r.setCharacterSpacing(3);
- assertEquals(3., r.getCharacterSpacing());
+ assertEquals(3., r.getCharacterSpacing(), 0);
r.setCharacterSpacing(-3);
- assertEquals(-3., r.getCharacterSpacing());
+ assertEquals(-3., r.getCharacterSpacing(), 0);
r.setCharacterSpacing(0);
- assertEquals(0., r.getCharacterSpacing());
+ assertEquals(0., r.getCharacterSpacing(), 0);
assertFalse(r.getRPr().isSetSpc());
- assertEquals(Color.black, r.getFontColor());
+ assertTrue(sameColor(Color.black, r.getFontColor()));
r.setFontColor(Color.red);
- assertEquals(Color.red, r.getFontColor());
+ assertTrue(sameColor(Color.red, r.getFontColor()));
assertEquals("Calibri", r.getFontFamily());
r.setFontFamily("Arial");
assertEquals("Arial", r.getFontFamily());
- assertEquals(18.0, r.getFontSize());
+ assertEquals(18.0, r.getFontSize(), 0);
r.setFontSize(13.0);
- assertEquals(13.0, r.getFontSize());
+ assertEquals(13.0, r.getFontSize(), 0);
assertEquals(false, r.isSuperscript());
r.setSuperscript(true);
@@ -67,5 +74,7 @@ public class TestXSLFTextRun extends TestCase { assertEquals(true, r.isSubscript());
r.setSubscript(false);
assertEquals(false, r.isSubscript());
+
+ ppt.close();
}
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java index de0d1a36a4..e0c4f9dd96 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -16,16 +16,26 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import java.awt.Color;
+import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test;
-import org.openxmlformats.schemas.drawingml.x2006.main.*;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
@@ -82,7 +92,7 @@ public class TestXSLFTextShape { XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
assertEquals("Calibri", r1.getFontFamily());
assertEquals(44.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
CTPlaceholder ph2 = shape2.getCTPlaceholder();
@@ -151,7 +161,7 @@ public class TestXSLFTextShape { XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
assertEquals("Calibri", r1.getFontFamily());
assertEquals(44.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
CTPlaceholder ph2 = shape2.getCTPlaceholder();
@@ -262,7 +272,7 @@ public class TestXSLFTextShape { assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
assertEquals("Calibri", r1.getFontFamily());
assertEquals(40.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
assertTrue(r1.isBold());
assertFalse(r1.isItalic());
assertFalse(r1.isUnderlined());
@@ -336,7 +346,7 @@ public class TestXSLFTextShape { assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
assertEquals("Calibri", r1.getFontFamily());
assertEquals(44.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
CTPlaceholder ph2 = shape2.getCTPlaceholder();
@@ -404,7 +414,7 @@ public class TestXSLFTextShape { assertEquals(0, pr5.getParentParagraph().getIndentLevel());
assertEquals("Right", pr5.getRawText());
assertEquals("Calibri", pr5.getFontFamily());
- assertEquals(Color.black, pr5.getFontColor());
+ assertTrue(sameColor(Color.black, pr5.getFontColor()));
}
@SuppressWarnings("unused")
@@ -444,7 +454,7 @@ public class TestXSLFTextShape { assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
assertEquals("Calibri", r1.getFontFamily());
assertEquals(44.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
assertFalse(r1.isBold());
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
@@ -517,7 +527,7 @@ public class TestXSLFTextShape { assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
assertEquals("Calibri", r1.getFontFamily());
assertEquals(20.0, r1.getFontSize(), 0);
- assertEquals(Color.black, r1.getFontColor());
+ assertTrue(sameColor(Color.black, r1.getFontColor()));
assertTrue(r1.isBold());
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
@@ -605,7 +615,7 @@ public class TestXSLFTextShape { assertEquals("Calibri", r1.getFontFamily());
assertEquals(12.0, r1.getFontSize(), 0);
// TODO calculation of tint is incorrect
- assertEquals(new Color(64,64,64), r1.getFontColor());
+ assertTrue(sameColor(new Color(64,64,64), r1.getFontColor()));
XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT);
assertEquals("Friday, October 21, 2011", dt.getText());
@@ -615,7 +625,7 @@ public class TestXSLFTextShape { }
@Test
- public void testTitleStyles(){
+ public void testTitleStyles() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
@@ -693,10 +703,12 @@ public class TestXSLFTextShape { assertEquals("Calibri", textRun.getFontFamily());
lv5PPr.setAlgn(STTextAlignType.CTR);
assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
+
+ ppt.close();
}
@Test
- public void testBodyStyles(){
+ public void testBodyStyles() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
@@ -895,7 +907,7 @@ public class TestXSLFTextShape { assertEquals("Calibri", r3.getFontFamily());
lv3PPr.setAlgn(STTextAlignType.CTR);
assertEquals(TextAlign.CENTER, p3.getTextAlign());
-
+
+ ppt.close();
}
-
}
\ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java index f928124c42..ee95e771d4 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java @@ -16,6 +16,7 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
import static org.junit.Assert.*;
import java.awt.Color;
@@ -66,7 +67,7 @@ public class TestXSLFTheme { XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3");
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(Color.white, run1.getFontColor());
+ assertTrue(sameColor(Color.white, run1.getFontColor()));
assertEquals(new Color(79, 129, 189), sh1.getFillColor());
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
@@ -89,13 +90,13 @@ public class TestXSLFTheme { XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4");
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(Color.white, run1.getFontColor());
+ assertTrue(sameColor(Color.white, run1.getFontColor()));
assertEquals(new Color(148, 198, 0), sh1.getFillColor());
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3");
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(new Color(148, 198, 0), run2.getFontColor());
+ assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));
assertNull(sh2.getFillColor()); // no fill
assertTrue(slide.getSlideLayout().getFollowMasterGraphics());
@@ -107,7 +108,7 @@ public class TestXSLFTheme { XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1");
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(new Color(148, 198, 0), run2.getFontColor());
+ assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));
assertNull(sh2.getFillColor()); // no fill
// font size is 40pt and scale factor is 90%
assertEquals(36.0, run2.getFontSize(), 0);
@@ -119,12 +120,12 @@ public class TestXSLFTheme { XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Subtitle 3");
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(new Color(66, 66, 66), run1.getFontColor());
+ assertTrue(sameColor(new Color(66, 66, 66), run1.getFontColor()));
assertNull(sh1.getFillColor()); // no fill
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 2");
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(new Color(148, 198, 0), run2.getFontColor());
+ assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));
assertNull(sh2.getFillColor()); // no fill
assertFalse(slide.getSlideLayout().getFollowMasterGraphics());
@@ -154,12 +155,12 @@ public class TestXSLFTheme { XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3");
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(Color.white, run1.getFontColor());
+ assertTrue(sameColor(Color.white, run1.getFontColor()));
assertNull(sh1.getFillColor()); // no fill
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Subtitle 4");
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
- assertEquals(Color.white, run2.getFontColor());
+ assertTrue(sameColor(Color.white, run2.getFontColor()));
assertNull(sh2.getFillColor()); // no fill
}
}
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 67b12be8b4..c71395980b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java @@ -17,8 +17,14 @@ package org.apache.poi.hslf.model; -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.usermodel.*; +import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.EscherOptRecord; +import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.ddf.EscherSpRecord; +import org.apache.poi.hslf.usermodel.HSLFGroupShape; +import org.apache.poi.hslf.usermodel.HSLFShape; +import org.apache.poi.hslf.usermodel.HSLFTextParagraph; +import org.apache.poi.hslf.usermodel.HSLFTextShape; import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.ShapeType; @@ -27,7 +33,7 @@ import org.apache.poi.sl.usermodel.ShapeType; * * @author Yegor Kozlov */ -public final class Line extends HSLFSimpleShape { +public final class Line extends HSLFTextShape implements org.apache.poi.sl.usermodel.Line<HSLFTextParagraph> { public Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){ super(escherRecord, parent); } @@ -64,23 +70,23 @@ public final class Line extends HSLFSimpleShape { return _escherContainer; } - /** - * Sets the orientation of the line, if inverse is false, then line goes - * from top-left to bottom-right, otherwise use inverse equals true - * - * @param inverse the orientation of the line - */ - public void setInverse(boolean inverse) { - setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE); - } - - /** - * Gets the orientation of the line, if inverse is false, then line goes - * from top-left to bottom-right, otherwise inverse equals true - * - * @return inverse the orientation of the line - */ - public boolean isInverse() { - return (getShapeType() == ShapeType.LINE_INV); - } +// /** +// * Sets the orientation of the line, if inverse is false, then line goes +// * from top-left to bottom-right, otherwise use inverse equals true +// * +// * @param inverse the orientation of the line +// */ +// public void setInverse(boolean inverse) { +// setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE); +// } +// +// /** +// * Gets the orientation of the line, if inverse is false, then line goes +// * from top-left to bottom-right, otherwise inverse equals true +// * +// * @return inverse the orientation of the line +// */ +// public boolean isInverse() { +// return (getShapeType() == ShapeType.LINE_INV); +// } } 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 3b22227b99..02cb9154fa 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java @@ -18,19 +18,49 @@ package org.apache.poi.hslf.model; -import java.awt.*; -import java.awt.font.*; -import java.awt.geom.*; -import java.awt.image.*; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.text.AttributedCharacterIterator; import java.util.Map; import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.usermodel.*; +import org.apache.poi.hslf.usermodel.HSLFFreeformShape; +import org.apache.poi.hslf.usermodel.HSLFGroupShape; +import org.apache.poi.hslf.usermodel.HSLFSimpleShape; +import org.apache.poi.hslf.usermodel.HSLFTextBox; +import org.apache.poi.hslf.usermodel.HSLFTextRun; +import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.usermodel.StrokeStyle; import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -259,7 +289,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { rt.setFontSize((double)_font.getSize()); rt.setFontFamily(_font.getFamily()); - if (getColor() != null) rt.setFontColor(getColor()); + if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor())); if (_font.isBold()) rt.setBold(true); if (_font.isItalic()) rt.setItalic(true); diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java index 77cb18e21e..e0b0567147 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java @@ -22,10 +22,16 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; -import org.apache.poi.ddf.*; +import org.apache.poi.ddf.EscherBSERecord; +import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.EscherOptRecord; +import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.ddf.EscherRecord; +import org.apache.poi.ddf.EscherSimpleProperty; import org.apache.poi.hslf.record.Document; -import org.apache.poi.sl.usermodel.*; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.FillStyle; +import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -113,20 +119,8 @@ public final class HSLFFill { return new FillStyle() { public PaintStyle getPaint() { switch (getFillType()) { - case FILL_SOLID: { - return new SolidPaint() { - public ColorStyle getSolidColor() { - return new ColorStyle() { - public Color getColor() { return getForegroundColor(); } - public int getAlpha() { return -1; } - public int getLumOff() { return -1; } - public int getLumMod() { return -1; } - public int getShade() { return -1; } - public int getTint() { return -1; } - }; - } - }; - } + case FILL_SOLID: + return DrawPaint.createSolidPaint(getForegroundColor()); case FILL_PICTURE: { final HSLFPictureData pd = getPictureData(); if (pd == null) break; @@ -149,7 +143,7 @@ public final class HSLFFill { logger.log(POILogger.WARN, "unsuported fill type: " + getFillType()); break; } - return PaintStyle.TRANSPARENT_PAINT; + return null; } }; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java index 8feee2312b..bbffdc5e1b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java @@ -188,16 +188,14 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSl // Complex Accesser methods follow /** - * Return title of this slide or <code>null</code> if the slide does not have title. * <p> * The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or * <code>TextHeaderAtom.TITLE_TYPE</code> * </p> * * @see TextHeaderAtom - * - * @return title of this slide */ + @Override public String getTitle(){ for (List<HSLFTextParagraph> tp : getTextParagraphs()) { if (tp.isEmpty()) continue; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index 9f4d311982..86604bf09b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -132,6 +132,20 @@ public final class HSLFSlideShow implements SlideShow { this(new HSLFSlideShowImpl(inputStream)); } + /** + * Constructs a Powerpoint document from an POIFSFileSystem. + */ + public HSLFSlideShow(POIFSFileSystem inputStream) throws IOException { + this(new HSLFSlideShowImpl(inputStream)); + } + + /** + * Constructs a Powerpoint document from an DirectoryNode. + */ + public HSLFSlideShow(DirectoryNode root) throws IOException { + this(new HSLFSlideShowImpl(root)); + } + /** * Use the PersistPtrHolder entries to figure out what is the "most recent" * version of all the core records (Document, Notes, Slide etc), and save a diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java index 0dc8de65f4..529d733163 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java @@ -27,7 +27,10 @@ import org.apache.poi.hslf.model.PPFont; import org.apache.poi.hslf.model.textproperties.*;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.hslf.record.*;
+import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.util.*;
@@ -403,8 +406,24 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> { }
@Override
- public Color getBulletFontColor() {
- return HSLFTextParagraph.this.getBulletColor();
+ public void setBulletFontColor(Color color) {
+ setBulletFontColor(DrawPaint.createSolidPaint(color));
+ }
+
+ @Override
+ public void setBulletFontColor(PaintStyle color) {
+ if (!(color instanceof SolidPaint)) {
+ throw new IllegalArgumentException("HSLF only supports SolidPaint");
+ }
+ SolidPaint sp = (SolidPaint)color;
+ Color col = DrawPaint.applyColorTransform(sp.getSolidColor());
+ HSLFTextParagraph.this.setBulletColor(col);
+ }
+
+ @Override
+ public PaintStyle getBulletFontColor() {
+ Color col = HSLFTextParagraph.this.getBulletColor();
+ return DrawPaint.createSolidPaint(col);
}
@Override
@@ -497,7 +516,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> { TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);
if (tp == null) {
// if bullet color is undefined, return color of first run
- return (_runs.isEmpty()) ? null : _runs.get(0).getFontColor();
+ if (_runs.isEmpty()) return null;
+ SolidPaint sp = _runs.get(0).getFontColor();
+ return DrawPaint.applyColorTransform(sp.getSolidColor());
}
return getColorFromColorIndexStruct(tp.getValue(), _sheet);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java index 08565e3da6..fbb908c1c7 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java @@ -21,8 +21,14 @@ import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal; import java.awt.Color; -import org.apache.poi.hslf.model.textproperties.*; +import org.apache.poi.hslf.model.textproperties.BitMaskTextProp; +import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp; +import org.apache.poi.hslf.model.textproperties.TextProp; +import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; +import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.PaintStyle; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -315,13 +321,15 @@ public final class HSLFTextRun implements TextRun { } /** - * @return font color as RGB value - * @see java.awt.Color + * @return font color as PaintStyle */ - public Color getFontColor() { + @Override + public SolidPaint getFontColor() { TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph); - return (tp == null) ? null - : HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet()); + if (tp == null) return null; + Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet()); + SolidPaint ps = DrawPaint.createSolidPaint(color); + return ps; } /** @@ -334,12 +342,21 @@ public final class HSLFTextRun implements TextRun { setCharTextPropVal("font.color", bgr); } - /** - * Sets color of the text, as a java.awt.Color - */ - public void setFontColor(Color color) { + + @Override + public void setFontColor(Color color) { + setFontColor(DrawPaint.createSolidPaint(color)); + } + + @Override + public void setFontColor(PaintStyle color) { + if (!(color instanceof SolidPaint)) { + throw new IllegalArgumentException("HSLF only supports solid paint"); + } // In PowerPont RGB bytes are swapped, as BGR - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB(); + SolidPaint sp = (SolidPaint)color; + Color c = DrawPaint.applyColorTransform(sp.getSolidColor()); + int rgb = new Color(c.getBlue(), c.getGreen(), c.getRed(), 254).getRGB(); setFontColor(rgb); } 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 ed9ca3819d..8141650fe7 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java @@ -17,6 +17,7 @@ package org.apache.poi.hslf.model; +import static org.apache.poi.sl.TestCommonSL.sameColor; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -53,9 +54,9 @@ import org.apache.poi.hslf.usermodel.HSLFTextBox; import org.apache.poi.hslf.usermodel.HSLFTextParagraph; import org.apache.poi.hslf.usermodel.HSLFTextRun; import org.apache.poi.hslf.usermodel.HSLFTextShape; +import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.junit.Before; import org.junit.Test; @@ -189,16 +190,16 @@ public final class TestShapes { List<HSLFTextParagraph> para = tb.getTextParagraphs(); HSLFTextRun tr = para.get(0).getTextRuns().get(0); assertEquals("para 1 run 1. ", tr.getRawText()); - assertEquals(Color.black, tr.getFontColor()); + assertTrue(sameColor(Color.black, tr.getFontColor())); tr = para.get(0).getTextRuns().get(1); assertEquals("para 1 run 2.\r", tr.getRawText()); - assertEquals(Color.red, tr.getFontColor()); + assertTrue(sameColor(Color.red, tr.getFontColor())); tr = para.get(1).getTextRuns().get(0); assertEquals("para 2 run 1. ", tr.getRawText()); - assertEquals(Color.yellow, tr.getFontColor()); + assertTrue(sameColor(Color.yellow, tr.getFontColor())); tr = para.get(1).getTextRuns().get(1); assertEquals("para 2 run 2. para 2 run 3.", tr.getRawText()); - assertEquals(Color.black, tr.getFontColor()); + assertTrue(sameColor(Color.black, tr.getFontColor())); assertTrue(tr.isStrikethrough()); } @@ -235,7 +236,7 @@ public final class TestShapes { assertTrue(rt.isItalic()); assertFalse(rt.isUnderlined()); assertEquals("Arial", rt.getFontFamily()); - assertEquals(Color.red, rt.getFontColor()); + assertTrue(sameColor(Color.red, rt.getFontColor())); // Serialize and read again ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -255,7 +256,7 @@ public final class TestShapes { assertTrue(rt.isItalic()); assertFalse(rt.isUnderlined()); assertEquals("Arial", rt.getFontFamily()); - assertEquals(Color.red, rt.getFontColor()); + assertTrue(sameColor(Color.red, rt.getFontColor())); } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java index aa0c307f93..1cbf238de6 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java @@ -17,15 +17,26 @@ package org.apache.poi.hslf.usermodel; -import static org.junit.Assert.*; +import static org.apache.poi.sl.TestCommonSL.sameColor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import java.awt.Color; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.List; import org.apache.poi.POIDataSamples; import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.record.TextBytesAtom; +import org.apache.poi.hslf.record.TextCharsAtom; +import org.apache.poi.hslf.record.TextHeaderAtom; import org.junit.Before; import org.junit.Test; @@ -539,7 +550,7 @@ public final class TestTextRun { List<HSLFTextParagraph> run = tx.getTextParagraphs(); HSLFTextRun rt = run.get(0).getTextRuns().get(0); assertTrue(rt.isBold()); - assertEquals(rt.getFontColor(), Color.RED); + assertTrue(sameColor(Color.RED, rt.getFontColor())); } } } diff --git a/src/testcases/org/apache/poi/sl/TestCommonSL.java b/src/testcases/org/apache/poi/sl/TestCommonSL.java new file mode 100644 index 0000000000..ab27ca42e1 --- /dev/null +++ b/src/testcases/org/apache/poi/sl/TestCommonSL.java @@ -0,0 +1,38 @@ +/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.sl;
+
+import java.awt.Color;
+
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.junit.Ignore;
+
+/**
+ * Currently only contains helper methods
+ */
+@Ignore
+public class TestCommonSL {
+
+ public static boolean sameColor(Color colorExpected, PaintStyle paintActual) {
+ if (!(paintActual instanceof SolidPaint)) return false;
+ Color thisC = DrawPaint.applyColorTransform(((SolidPaint)paintActual).getSolidColor());
+ return thisC.equals(colorExpected);
+ }
+
+}
|