#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
This commit is contained in:
parent
bdb00633a3
commit
750558d8d9
@ -17,25 +17,31 @@
|
|||||||
|
|
||||||
package org.apache.poi.sl.draw;
|
package org.apache.poi.sl.draw;
|
||||||
|
|
||||||
import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.*;
|
import java.awt.LinearGradientPaint;
|
||||||
import java.awt.MultipleGradientPaint.ColorSpaceType;
|
import java.awt.MultipleGradientPaint.ColorSpaceType;
|
||||||
import java.awt.MultipleGradientPaint.CycleMethod;
|
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.IOException;
|
||||||
import java.io.InputStream;
|
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.GradientPaint;
|
||||||
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
|
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
|
||||||
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
|
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.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
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>
|
* @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;
|
this.shape = shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SolidPaint createSolidPaint(final Color color) {
|
private static class SimpleSolidPaint implements SolidPaint {
|
||||||
return new SolidPaint() {
|
private final ColorStyle solidColor;
|
||||||
public ColorStyle getSolidColor() {
|
|
||||||
return new ColorStyle(){
|
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 Color getColor() { return color; }
|
||||||
public int getAlpha() { return -1; }
|
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 getLumOff() { return -1; }
|
||||||
public int getLumMod() { return -1; }
|
public int getLumMod() { return -1; }
|
||||||
public int getShade() { return -1; }
|
public int getShade() { return -1; }
|
||||||
public int getTint() { 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) {
|
public Paint getPaint(Graphics2D graphics, PaintStyle paint) {
|
||||||
@ -95,26 +127,26 @@ public class DrawPaint {
|
|||||||
|
|
||||||
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
|
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
|
||||||
InputStream is = fill.getImageData();
|
InputStream is = fill.getImageData();
|
||||||
if (is == null) return TRANSPARENT_PAINT.getSolidColor().getColor();
|
if (is == null) return null;
|
||||||
assert(graphics != null);
|
assert(graphics != null);
|
||||||
|
|
||||||
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
|
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
|
||||||
if (renderer == null) renderer = new ImageRenderer();
|
if (renderer == null) renderer = new ImageRenderer();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
renderer.loadImage(fill.getImageData(), fill.getContentType());
|
renderer.loadImage(is, fill.getContentType());
|
||||||
|
is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", 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();
|
int alpha = fill.getAlpha();
|
||||||
if (alpha != -1) {
|
if (0 <= alpha && alpha < 100000) {
|
||||||
renderer.setAlpha(alpha/100000.f);
|
renderer.setAlpha(alpha/100000.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dimension dim = renderer.getDimension();
|
Rectangle2D textAnchor = shape.getAnchor();
|
||||||
Rectangle2D textAnchor = new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight());
|
|
||||||
Paint paint = new java.awt.TexturePaint(renderer.getImage(), textAnchor);
|
Paint paint = new java.awt.TexturePaint(renderer.getImage(), textAnchor);
|
||||||
|
|
||||||
return paint;
|
return paint;
|
||||||
@ -122,106 +154,102 @@ public class DrawPaint {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert color transformations in {@link ColorStyle} to a {@link Color} instance
|
* 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){
|
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();
|
Color result = color.getColor();
|
||||||
|
if (result == null) return null;
|
||||||
|
|
||||||
if (result == null || color.getAlpha() == 100) {
|
double alpha = getAlpha(result, color);
|
||||||
return TRANSPARENT_PAINT.getSolidColor().getColor();
|
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 = applyAlpha(result, color);
|
result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha);
|
||||||
result = applyLuminance(result, color);
|
|
||||||
result = applyShade(result, color);
|
|
||||||
result = applyTint(result, color);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Color applyAlpha(Color c, ColorStyle fc) {
|
private static double getAlpha(Color c, ColorStyle fc) {
|
||||||
int alpha = c.getAlpha();
|
double alpha = c.getAlpha()/255d;
|
||||||
return (alpha == 255) ? c : new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
|
int fcAlpha = fc.getAlpha();
|
||||||
|
if (fcAlpha != -1) {
|
||||||
|
alpha *= fcAlpha/100000d;
|
||||||
|
}
|
||||||
|
return Math.min(1, Math.max(0, alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply lumMod / lumOff adjustments
|
* Apply the modulation and offset adjustments to the given HSL part
|
||||||
*
|
*
|
||||||
* @param c the color to modify
|
* Example for lumMod/lumOff:
|
||||||
* @param fc the color style containing the lumMod / lumOff adjustments
|
* The lumMod value is the percent luminance. A lumMod value of "60000",
|
||||||
* @return modified color
|
* 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) {
|
private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {
|
||||||
int lumMod = fc.getLumMod();
|
if (mod == -1) mod = 100000;
|
||||||
if (lumMod == -1) lumMod = 100000;
|
if (off == -1) off = 0;
|
||||||
|
if (!(mod == 100000 && off == 0)) {
|
||||||
int lumOff = fc.getLumOff();
|
double fOff = off / 1000d;
|
||||||
if (lumOff == -1) lumOff = 0;
|
double fMod = mod / 100000d;
|
||||||
|
hsl[hslPart] = hsl[hslPart]*fMod+fOff;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This algorithm returns result different from PowerPoint.
|
* Apply the shade
|
||||||
* TODO: revisit and improve
|
*
|
||||||
|
* 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();
|
int shade = fc.getShade();
|
||||||
if (shade == -1) return c;
|
if (shade == -1) return;
|
||||||
|
|
||||||
float fshade = shade / 100000.f;
|
double fshade = shade / 100000.d;
|
||||||
|
|
||||||
float red = c.getRed() * fshade;
|
hsl[2] *= fshade;
|
||||||
float green = c.getGreen() * fshade;
|
|
||||||
float blue = c.getGreen() * fshade;
|
|
||||||
|
|
||||||
return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This algorithm returns result different from PowerPoint.
|
* Apply the tint
|
||||||
* TODO: revisit and improve
|
*
|
||||||
|
* 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();
|
int tint = fc.getTint();
|
||||||
if (tint == -1) return c;
|
if (tint == -1) return;
|
||||||
|
|
||||||
float ftint = tint / 100000.f;
|
double ftint = tint / 100000.f;
|
||||||
|
|
||||||
float red = ftint * c.getRed() + (1.f - ftint) * 255.f;
|
hsl[2] = hsl[2] * ftint + (100 - ftint*100.);
|
||||||
float green = ftint * c.getGreen() + (1.f - ftint) * 255.f;
|
|
||||||
float blue = ftint * c.getBlue() + (1.f - ftint) * 255.f;
|
|
||||||
|
|
||||||
return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,9 +47,6 @@ public class DrawSimpleShape<T extends SimpleShape> extends DrawShape<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Graphics2D graphics) {
|
public void draw(Graphics2D graphics) {
|
||||||
// RenderableShape rShape = new RenderableShape(this);
|
|
||||||
// rShape.render(graphics);
|
|
||||||
|
|
||||||
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(shape);
|
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(shape);
|
||||||
Paint fill = drawPaint.getPaint(graphics, shape.getFillStyle().getPaint());
|
Paint fill = drawPaint.getPaint(graphics, shape.getFillStyle().getPaint());
|
||||||
Paint line = drawPaint.getPaint(graphics, shape.getStrokeStyle().getPaint());
|
Paint line = drawPaint.getPaint(graphics, shape.getStrokeStyle().getPaint());
|
||||||
|
@ -17,18 +17,32 @@
|
|||||||
|
|
||||||
package org.apache.poi.sl.draw;
|
package org.apache.poi.sl.draw;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Graphics2D;
|
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.awt.geom.Rectangle2D;
|
||||||
import java.text.*;
|
import java.text.AttributedCharacterIterator;
|
||||||
import java.text.AttributedCharacterIterator.Attribute;
|
import java.text.AttributedCharacterIterator.Attribute;
|
||||||
import java.util.*;
|
import java.text.AttributedString;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.poi.sl.usermodel.*;
|
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.BulletStyle;
|
||||||
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
|
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.TextRun.TextCap;
|
||||||
|
import org.apache.poi.sl.usermodel.TextShape;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
|
|
||||||
public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
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){
|
public void draw(Graphics2D graphics){
|
||||||
if (lines.isEmpty()) return;
|
if (lines.isEmpty()) return;
|
||||||
|
|
||||||
Insets2D insets = paragraph.getParentShape().getInsets();
|
|
||||||
double leftInset = insets.left;
|
|
||||||
double rightInset = insets.right;
|
|
||||||
double penY = y;
|
double penY = y;
|
||||||
|
|
||||||
boolean firstLine = true;
|
boolean firstLine = true;
|
||||||
@ -79,12 +90,17 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
|||||||
Double leftMargin = paragraph.getLeftMargin();
|
Double leftMargin = paragraph.getLeftMargin();
|
||||||
if (leftMargin == null) {
|
if (leftMargin == null) {
|
||||||
// if the marL attribute is omitted, then a value of 347663 is implied
|
// 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();
|
Double indent = paragraph.getIndent();
|
||||||
if (indent == null) {
|
if (indent == null) {
|
||||||
indent = Units.toPoints(347663*indentLevel);
|
indent = Units.toPoints(347663*indentLevel);
|
||||||
}
|
}
|
||||||
|
if (paragraph.getClass().getName().contains("HSLF")) {
|
||||||
|
// special handling for HSLF
|
||||||
|
indent -= leftMargin;
|
||||||
|
}
|
||||||
|
|
||||||
Double rightMargin = paragraph.getRightMargin();
|
Double rightMargin = paragraph.getRightMargin();
|
||||||
if (rightMargin == null) {
|
if (rightMargin == null) {
|
||||||
rightMargin = 0d;
|
rightMargin = 0d;
|
||||||
@ -104,25 +120,30 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bullet != null){
|
if (bullet != null){
|
||||||
bullet.setPosition(x + indent, penY);
|
bullet.setPosition(x+leftMargin+indent, penY);
|
||||||
bullet.draw(graphics);
|
bullet.draw(graphics);
|
||||||
// don't let text overlay the bullet and advance by the bullet width
|
// don't let text overlay the bullet and advance by the bullet width
|
||||||
double bulletWidth = bullet.getLayout().getAdvance() + 1;
|
double bulletWidth = bullet.getLayout().getAdvance() + 1;
|
||||||
penX = x + Math.max(leftMargin, indent+bulletWidth);
|
penX = x + Math.max(leftMargin, leftMargin+indent+bulletWidth);
|
||||||
} else {
|
} else {
|
||||||
penX = x + indent;
|
penX = x + leftMargin;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
penX = x + leftMargin;
|
penX = x + leftMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape());
|
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();
|
TextAlign ta = paragraph.getTextAlign();
|
||||||
if (ta == null) ta = TextAlign.LEFT;
|
if (ta == null) ta = TextAlign.LEFT;
|
||||||
switch (ta) {
|
switch (ta) {
|
||||||
case CENTER:
|
case CENTER:
|
||||||
penX += (anchor.getWidth() - leftMargin - line.getWidth() - leftInset - rightInset) / 2;
|
penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;
|
||||||
break;
|
break;
|
||||||
case RIGHT:
|
case RIGHT:
|
||||||
penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);
|
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();
|
if (buFont == null) buFont = paragraph.getDefaultFontFamily();
|
||||||
assert(buFont != null);
|
assert(buFont != null);
|
||||||
|
|
||||||
Color buColor = bulletStyle.getBulletFontColor();
|
PlaceableShape ps = getParagraphShape();
|
||||||
if (buColor == null) buColor = (Color)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);
|
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);
|
float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);
|
||||||
Double buSz = bulletStyle.getBulletFontSize();
|
Double buSz = bulletStyle.getBulletFontSize();
|
||||||
@ -256,7 +283,7 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
|||||||
|
|
||||||
|
|
||||||
AttributedString str = new AttributedString(buCharacter);
|
AttributedString str = new AttributedString(buCharacter);
|
||||||
str.addAttribute(TextAttribute.FOREGROUND, buColor);
|
str.addAttribute(TextAttribute.FOREGROUND, fgPaint);
|
||||||
str.addAttribute(TextAttribute.FAMILY, buFont);
|
str.addAttribute(TextAttribute.FAMILY, buFont);
|
||||||
str.addAttribute(TextAttribute.SIZE, fontSize);
|
str.addAttribute(TextAttribute.SIZE, fontSize);
|
||||||
|
|
||||||
@ -383,10 +410,30 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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){
|
protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){
|
||||||
List<AttributedStringData> attList = new ArrayList<AttributedStringData>();
|
List<AttributedStringData> attList = new ArrayList<AttributedStringData>();
|
||||||
if (text == null) text = new StringBuilder();
|
if (text == null) text = new StringBuilder();
|
||||||
|
|
||||||
|
PlaceableShape ps = getParagraphShape();
|
||||||
|
|
||||||
DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);
|
DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);
|
||||||
|
|
||||||
for (TextRun run : paragraph){
|
for (TextRun run : paragraph){
|
||||||
@ -398,9 +445,9 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
|
|||||||
text.append(runText);
|
text.append(runText);
|
||||||
int endIndex = text.length();
|
int endIndex = text.length();
|
||||||
|
|
||||||
Color fgColor = run.getFontColor();
|
PaintStyle fgPaintStyle = run.getFontColor();
|
||||||
if (fgColor == null) fgColor = Color.BLACK;
|
Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);
|
||||||
attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgColor, beginIndex, endIndex));
|
attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex));
|
||||||
|
|
||||||
// user can pass an custom object to convert fonts
|
// user can pass an custom object to convert fonts
|
||||||
String fontFamily = run.getFontFamily();
|
String fontFamily = run.getFontFamily();
|
||||||
|
@ -102,7 +102,6 @@ public class DrawTextShape<T extends TextShape<? extends TextParagraph<? extends
|
|||||||
*/
|
*/
|
||||||
public double drawParagraphs(Graphics2D graphics, double x, double y) {
|
public double drawParagraphs(Graphics2D graphics, double x, double y) {
|
||||||
DrawFactory fact = DrawFactory.getInstance(graphics);
|
DrawFactory fact = DrawFactory.getInstance(graphics);
|
||||||
Insets2D shapePadding = shape.getInsets();
|
|
||||||
|
|
||||||
double y0 = y;
|
double y0 = y;
|
||||||
Iterator<? extends TextParagraph<? extends TextRun>> paragraphs = shape.iterator();
|
Iterator<? extends TextParagraph<? extends TextRun>> paragraphs = shape.iterator();
|
||||||
|
@ -32,17 +32,55 @@ public interface ColorStyle {
|
|||||||
int getAlpha();
|
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 luminance shift in percents in the range [0..100000]
|
* @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] (usually ...)
|
||||||
* or -1 if the value is not set
|
* or -1 if the value is not set
|
||||||
*/
|
*/
|
||||||
int getLumOff();
|
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
|
* or -1 if the value is not set
|
||||||
*/
|
*/
|
||||||
int getLumMod();
|
int getLumMod();
|
||||||
@ -50,8 +88,9 @@ public interface ColorStyle {
|
|||||||
/**
|
/**
|
||||||
* specifies a darker version of its input color.
|
* specifies a darker version of its input color.
|
||||||
* A 10% shade is 10% of the input color combined with 90% black.
|
* 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
|
* with 0% indicating minimal shade and 100% indicating maximum
|
||||||
* or -1 if the value is not set
|
* or -1 if the value is not set
|
||||||
*/
|
*/
|
||||||
@ -60,8 +99,9 @@ public interface ColorStyle {
|
|||||||
/**
|
/**
|
||||||
* specifies a lighter version of its input color.
|
* specifies a lighter version of its input color.
|
||||||
* A 10% tint is 10% of the input color combined with 90% white.
|
* 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
|
* with 0% indicating minimal tint and 100% indicating maximum
|
||||||
* or -1 if the value is not set
|
* or -1 if the value is not set
|
||||||
*/
|
*/
|
||||||
|
@ -17,14 +17,12 @@
|
|||||||
|
|
||||||
package org.apache.poi.sl.usermodel;
|
package org.apache.poi.sl.usermodel;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.apache.poi.sl.draw.DrawPaint;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface PaintStyle {
|
public interface PaintStyle {
|
||||||
|
|
||||||
public interface SolidPaint extends PaintStyle {
|
public interface SolidPaint extends PaintStyle {
|
||||||
ColorStyle getSolidColor();
|
ColorStyle getSolidColor();
|
||||||
}
|
}
|
||||||
@ -58,6 +56,4 @@ public interface PaintStyle {
|
|||||||
*/
|
*/
|
||||||
int getAlpha();
|
int getAlpha();
|
||||||
}
|
}
|
||||||
|
|
||||||
SolidPaint TRANSPARENT_PAINT = DrawPaint.createSolidPaint(new Color(0xFF, 0xFF, 0xFF, 0));
|
|
||||||
}
|
}
|
||||||
|
@ -34,4 +34,10 @@ public interface Slide<T extends Shape, SS extends SlideShow, N extends Notes<T,
|
|||||||
* @return the 1-based slide no.
|
* @return the 1-based slide no.
|
||||||
*/
|
*/
|
||||||
int getSlideNumber();
|
int getSlideNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return title of this slide or null if title is not set
|
||||||
|
*/
|
||||||
|
String getTitle();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import java.awt.Dimension;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.sl.usermodel.PictureData;
|
|
||||||
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
|
|
||||||
public interface SlideShow {
|
public interface SlideShow {
|
||||||
|
@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface TextParagraph<T extends TextRun> extends Iterable<T> {
|
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
|
* @return the bullet point font size
|
||||||
*/
|
*/
|
||||||
Double getBulletFontSize();
|
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();
|
AutoNumberingScheme getAutoNumberingScheme();
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,8 @@ package org.apache.poi.sl.usermodel;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some text.
|
* Some text.
|
||||||
*/
|
*/
|
||||||
@ -34,9 +36,34 @@ public interface TextRun {
|
|||||||
|
|
||||||
TextCap getTextCap();
|
TextCap getTextCap();
|
||||||
|
|
||||||
Color getFontColor();
|
/**
|
||||||
|
* 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);
|
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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return font size in points or null if font size is not set.
|
* @return font size in points or null if font size is not set.
|
||||||
|
298
src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java
Normal file
298
src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,8 +27,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties
|
|||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {
|
public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {
|
||||||
public boolean isFetchingFromMaster = false;
|
|
||||||
|
|
||||||
public CharacterPropertyFetcher(int level) {
|
public CharacterPropertyFetcher(int level) {
|
||||||
super(level);
|
super(level);
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,22 @@ public class XSLFColor {
|
|||||||
return getRawValue("alpha");
|
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() {
|
public int getLumOff() {
|
||||||
return getRawValue("lumOff");
|
return getRawValue("lumOff");
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,14 @@ public class XSLFDrawing {
|
|||||||
XmlObject[] cNvPr = sheet.getSpTree().selectPath(
|
XmlObject[] cNvPr = sheet.getSpTree().selectPath(
|
||||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
|
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
|
||||||
for(XmlObject o : cNvPr) {
|
for(XmlObject o : cNvPr) {
|
||||||
|
// powerpoint generates AlternateContent elements which cNvPr elements aren't recognized
|
||||||
|
// ignore them for now
|
||||||
|
if (o instanceof CTNonVisualDrawingProps) {
|
||||||
CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
|
CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
|
||||||
_shapeId = (int)Math.max(_shapeId, p.getId());
|
_shapeId = (int)Math.max(_shapeId, p.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public XSLFAutoShape createAutoShape(){
|
public XSLFAutoShape createAutoShape(){
|
||||||
CTShape sp = _spTree.addNewSp();
|
CTShape sp = _spTree.addNewSp();
|
||||||
|
@ -21,8 +21,6 @@ import java.awt.Color;
|
|||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
import org.apache.poi.sl.draw.DrawPaint;
|
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.PaintStyle.SolidPaint;
|
||||||
import org.apache.poi.sl.usermodel.Shadow;
|
import org.apache.poi.sl.usermodel.Shadow;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
@ -90,7 +88,7 @@ public class XSLFShadow extends XSLFShape implements Shadow {
|
|||||||
*/
|
*/
|
||||||
public Color getFillColor() {
|
public Color getFillColor() {
|
||||||
SolidPaint ps = getFillStyle();
|
SolidPaint ps = getFillStyle();
|
||||||
if (ps == PaintStyle.TRANSPARENT_PAINT) return null;
|
if (ps == null) return null;
|
||||||
Color col = DrawPaint.applyColorTransform(ps.getSolidColor());
|
Color col = DrawPaint.applyColorTransform(ps.getSolidColor());
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
@ -99,14 +97,10 @@ public class XSLFShadow extends XSLFShape implements Shadow {
|
|||||||
public SolidPaint getFillStyle() {
|
public SolidPaint getFillStyle() {
|
||||||
XSLFTheme theme = getSheet().getTheme();
|
XSLFTheme theme = getSheet().getTheme();
|
||||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
||||||
if(ct == null) return PaintStyle.TRANSPARENT_PAINT;
|
if(ct == null) return null;
|
||||||
|
|
||||||
CTSchemeColor phClr = ct.getSchemeClr();
|
CTSchemeColor phClr = ct.getSchemeClr();
|
||||||
final XSLFColor xc = new XSLFColor(ct, theme, phClr);
|
final XSLFColor xc = new XSLFColor(ct, theme, phClr);
|
||||||
return new SolidPaint(){
|
return DrawPaint.createSolidPaint(xc.getColorStyle());
|
||||||
public ColorStyle getSolidColor() {
|
|
||||||
return xc.getColorStyle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,10 +27,10 @@ import java.util.Comparator;
|
|||||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
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.ColorStyle;
|
||||||
import org.apache.poi.sl.usermodel.PaintStyle;
|
import org.apache.poi.sl.usermodel.PaintStyle;
|
||||||
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
|
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.PaintStyle.TexturePaint;
|
||||||
import org.apache.poi.sl.usermodel.PlaceableShape;
|
import org.apache.poi.sl.usermodel.PlaceableShape;
|
||||||
import org.apache.poi.sl.usermodel.Shape;
|
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.util.Internal;
|
||||||
import org.apache.poi.xslf.model.PropertyFetcher;
|
import org.apache.poi.xslf.model.PropertyFetcher;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
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.CTApplicationNonVisualDrawingProps;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
|
||||||
@ -139,7 +152,7 @@ public abstract class XSLFShape implements Shape {
|
|||||||
try {
|
try {
|
||||||
pr = shape.getSpPr();
|
pr = shape.getSpPr();
|
||||||
if (((CTShapeProperties)pr).isSetNoFill()) {
|
if (((CTShapeProperties)pr).isSetNoFill()) {
|
||||||
setValue(PaintStyle.TRANSPARENT_PAINT);
|
setValue(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException e) {}
|
} catch (IllegalStateException e) {}
|
||||||
@ -156,21 +169,19 @@ public abstract class XSLFShape implements Shape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr == null) {
|
if (pr == null) return false;
|
||||||
setValue(PaintStyle.TRANSPARENT_PAINT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PaintStyle paint = null;
|
PaintStyle paint = null;
|
||||||
|
PackagePart pp = getSheet().getPackagePart();
|
||||||
for (XmlObject obj : pr.selectPath("*")) {
|
for (XmlObject obj : pr.selectPath("*")) {
|
||||||
paint = selectPaint(obj, null, getSheet().getPackagePart());
|
paint = selectPaint(obj, null, pp);
|
||||||
if (paint != null) break;
|
if (paint != null) {
|
||||||
}
|
|
||||||
|
|
||||||
if (paint == null) return false;
|
|
||||||
|
|
||||||
setValue(paint);
|
setValue(paint);
|
||||||
return true;
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetchShapeProperty(fetcher);
|
fetchShapeProperty(fetcher);
|
||||||
@ -190,7 +201,7 @@ public abstract class XSLFShape implements Shape {
|
|||||||
}
|
}
|
||||||
paint = selectPaint(fillRef);
|
paint = selectPaint(fillRef);
|
||||||
|
|
||||||
return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
|
return paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CTBackgroundProperties getBgPr() {
|
protected CTBackgroundProperties getBgPr() {
|
||||||
@ -347,7 +358,7 @@ public abstract class XSLFShape implements Shape {
|
|||||||
paint = selectPaint(obj, phClr, pp);
|
paint = selectPaint(obj, phClr, pp);
|
||||||
if(paint != null) break;
|
if(paint != null) break;
|
||||||
}
|
}
|
||||||
return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
|
return paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -371,13 +382,13 @@ public abstract class XSLFShape implements Shape {
|
|||||||
*/
|
*/
|
||||||
protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {
|
protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {
|
||||||
if (obj instanceof CTNoFillProperties) {
|
if (obj instanceof CTNoFillProperties) {
|
||||||
return PaintStyle.TRANSPARENT_PAINT;
|
return null;
|
||||||
} else if (obj instanceof CTSolidColorFillProperties) {
|
} else if (obj instanceof CTSolidColorFillProperties) {
|
||||||
return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart);
|
return selectPaint((CTSolidColorFillProperties)obj, phClr);
|
||||||
} else if (obj instanceof CTBlipFillProperties) {
|
} else if (obj instanceof CTBlipFillProperties) {
|
||||||
return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);
|
return selectPaint((CTBlipFillProperties)obj, parentPart);
|
||||||
} else if (obj instanceof CTGradientFillProperties) {
|
} else if (obj instanceof CTGradientFillProperties) {
|
||||||
return selectPaint((CTGradientFillProperties) obj, phClr, parentPart);
|
return selectPaint((CTGradientFillProperties) obj, phClr);
|
||||||
} else if (obj instanceof CTStyleMatrixReference) {
|
} else if (obj instanceof CTStyleMatrixReference) {
|
||||||
return selectPaint((CTStyleMatrixReference)obj);
|
return selectPaint((CTStyleMatrixReference)obj);
|
||||||
} else {
|
} 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();
|
final XSLFTheme theme = getSheet().getTheme();
|
||||||
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
|
if (phClr == null && solidFill.isSetSchemeClr()) {
|
||||||
return new SolidPaint() {
|
phClr = solidFill.getSchemeClr();
|
||||||
public ColorStyle getSolidColor() {
|
|
||||||
return c.getColorStyle();
|
|
||||||
}
|
}
|
||||||
};
|
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
|
||||||
|
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();
|
final CTBlip blip = blipFill.getBlip();
|
||||||
return new TexturePaint() {
|
return new TexturePaint() {
|
||||||
private PackagePart getPart() {
|
private PackagePart getPart() {
|
||||||
@ -424,12 +434,12 @@ public abstract class XSLFShape implements Shape {
|
|||||||
public int getAlpha() {
|
public int getAlpha() {
|
||||||
return (blip.sizeOfAlphaModFixArray() > 0)
|
return (blip.sizeOfAlphaModFixArray() > 0)
|
||||||
? blip.getAlphaModFixArray(0).getAmt()
|
? 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")
|
@SuppressWarnings("deprecation")
|
||||||
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
|
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
|
||||||
@ -448,7 +458,11 @@ public abstract class XSLFShape implements Shape {
|
|||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
for (CTGradientStop cgs : gs) {
|
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;
|
fractions[i] = cgs.getPos() / 100000.f;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.geom.Rectangle2D;
|
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.CustomGeometry;
|
||||||
import org.apache.poi.sl.draw.geom.Guide;
|
import org.apache.poi.sl.draw.geom.Guide;
|
||||||
import org.apache.poi.sl.draw.geom.PresetGeometries;
|
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.DecorationShape;
|
||||||
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
|
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.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.LineCap;
|
||||||
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
|
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
|
||||||
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
|
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
|
||||||
@ -219,7 +222,6 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
|
|||||||
*/
|
*/
|
||||||
public Color getLineColor() {
|
public Color getLineColor() {
|
||||||
PaintStyle ps = getLinePaint();
|
PaintStyle ps = getLinePaint();
|
||||||
if (ps == null || ps == TRANSPARENT_PAINT) return null;
|
|
||||||
if (ps instanceof SolidPaint) {
|
if (ps instanceof SolidPaint) {
|
||||||
return ((SolidPaint)ps).getSolidColor().getColor();
|
return ((SolidPaint)ps).getSolidColor().getColor();
|
||||||
}
|
}
|
||||||
@ -232,7 +234,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
|
|||||||
CTLineProperties spPr = shape.getSpPr().getLn();
|
CTLineProperties spPr = shape.getSpPr().getLn();
|
||||||
if (spPr != null) {
|
if (spPr != null) {
|
||||||
if (spPr.isSetNoFill()) {
|
if (spPr.isSetNoFill()) {
|
||||||
setValue(TRANSPARENT_PAINT); // use it as 'nofill' value
|
setValue(null); // use it as 'nofill' value
|
||||||
return true;
|
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
|
// line color was not found, check if it is defined in the theme
|
||||||
CTShapeStyle style = getSpStyle();
|
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.
|
// get a reference to a line style within the style matrix.
|
||||||
CTStyleMatrixReference lnRef = style.getLnRef();
|
CTStyleMatrixReference lnRef = style.getLnRef();
|
||||||
@ -279,7 +281,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
|
|||||||
paint = getPaint(lnProps, phClr);
|
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() {
|
public Color getFillColor() {
|
||||||
PaintStyle ps = getFillPaint();
|
PaintStyle ps = getFillPaint();
|
||||||
if (ps == null || ps == TRANSPARENT_PAINT) return null;
|
|
||||||
if (ps instanceof SolidPaint) {
|
if (ps instanceof SolidPaint) {
|
||||||
return ((SolidPaint)ps).getSolidColor().getColor();
|
return ((SolidPaint)ps).getSolidColor().getColor();
|
||||||
}
|
}
|
||||||
|
@ -168,13 +168,10 @@ public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSl
|
|||||||
return _notes;
|
return _notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
*
|
|
||||||
* @return title of this slide or empty string if title is not set
|
|
||||||
*/
|
|
||||||
public String getTitle(){
|
public String getTitle(){
|
||||||
XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE);
|
XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE);
|
||||||
return txt == null ? "" : txt.getText();
|
return txt == null ? null : txt.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,7 +21,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.sl.draw.DrawPaint;
|
||||||
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
|
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.sl.usermodel.TextParagraph;
|
||||||
import org.apache.poi.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.util.Internal;
|
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.
|
* @return the color of bullet characters within a given paragraph.
|
||||||
* A <code>null</code> value means to use the text font color.
|
* A <code>null</code> value means to use the text font color.
|
||||||
*/
|
*/
|
||||||
public Color getBulletFontColor(){
|
public PaintStyle getBulletFontColor(){
|
||||||
final XSLFTheme theme = getParentShape().getSheet().getTheme();
|
final XSLFTheme theme = getParentShape().getSheet().getTheme();
|
||||||
ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getIndentLevel()){
|
ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getIndentLevel()){
|
||||||
public boolean fetch(CTTextParagraphProperties props){
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
@ -277,19 +280,33 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetchParagraphProperty(fetcher);
|
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.
|
* Set the color to be used on bullet characters within a given paragraph.
|
||||||
*
|
*
|
||||||
* @param color the bullet color
|
* @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();
|
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
|
||||||
CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();
|
CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();
|
||||||
CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr();
|
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();
|
XSLFSheet masterSheet = _shape.getSheet();
|
||||||
for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
|
for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
|
||||||
masterSheet = m;
|
masterSheet = m;
|
||||||
|
|
||||||
XmlObject xo = masterSheet.getXmlObject();
|
XmlObject xo = masterSheet.getXmlObject();
|
||||||
for (String xpath : xpaths) {
|
for (String xpath : xpaths) {
|
||||||
XmlObject[] o = xo.selectPath(xpath);
|
XmlObject[] o = xo.selectPath(xpath);
|
||||||
@ -767,32 +783,35 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
|
|||||||
|
|
||||||
private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){
|
private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
|
XSLFTextShape shape = getParentShape();
|
||||||
|
XSLFSheet sheet = shape.getSheet();
|
||||||
|
|
||||||
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
|
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
|
||||||
|
if (ok) return true;
|
||||||
|
|
||||||
if(!ok) {
|
|
||||||
XSLFTextShape shape = getParentShape();
|
|
||||||
ok = shape.fetchShapeProperty(visitor);
|
ok = shape.fetchShapeProperty(visitor);
|
||||||
if(!ok){
|
if (ok) return true;
|
||||||
|
|
||||||
|
|
||||||
CTPlaceholder ph = shape.getCTPlaceholder();
|
CTPlaceholder ph = shape.getCTPlaceholder();
|
||||||
if(ph == null){
|
if(ph == null){
|
||||||
// if it is a plain text box then take defaults from presentation.xml
|
// if it is a plain text box then take defaults from presentation.xml
|
||||||
XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();
|
XMLSlideShow ppt = sheet.getSlideShow();
|
||||||
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
|
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
|
||||||
if (themeProps != null) ok = visitor.fetch(themeProps);
|
if (themeProps != null) ok = visitor.fetch(themeProps);
|
||||||
}
|
}
|
||||||
|
if (ok) return true;
|
||||||
|
|
||||||
if(!ok){
|
|
||||||
// defaults for placeholders are defined in the slide master
|
// defaults for placeholders are defined in the slide master
|
||||||
CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
|
CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
|
||||||
|
// TODO: determine master shape
|
||||||
if(defaultProps != null) ok = visitor.fetch(defaultProps);
|
if(defaultProps != null) ok = visitor.fetch(defaultProps);
|
||||||
}
|
if (ok) return true;
|
||||||
}
|
|
||||||
}
|
return false;
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
void copy(XSLFTextParagraph other){
|
void copy(XSLFTextParagraph other){
|
||||||
if (other == this) return;
|
if (other == this) return;
|
||||||
|
|
||||||
@ -848,7 +867,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
|
|||||||
if(buChar != null && !buChar.equals(getBulletCharacter())){
|
if(buChar != null && !buChar.equals(getBulletCharacter())){
|
||||||
setBulletCharacter(buChar);
|
setBulletCharacter(buChar);
|
||||||
}
|
}
|
||||||
Color buColor = other.getBulletFontColor();
|
PaintStyle buColor = other.getBulletFontColor();
|
||||||
if(buColor != null && !buColor.equals(getBulletFontColor())){
|
if(buColor != null && !buColor.equals(getBulletFontColor())){
|
||||||
setBulletFontColor(buColor);
|
setBulletFontColor(buColor);
|
||||||
}
|
}
|
||||||
@ -920,10 +939,20 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getBulletFontColor() {
|
public PaintStyle getBulletFontColor() {
|
||||||
return XSLFTextParagraph.this.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
|
@Override
|
||||||
public AutoNumberingScheme getAutoNumberingScheme() {
|
public AutoNumberingScheme getAutoNumberingScheme() {
|
||||||
return XSLFTextParagraph.this.getAutoNumberingScheme();
|
return XSLFTextParagraph.this.getAutoNumberingScheme();
|
||||||
|
@ -18,6 +18,9 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
|
|
||||||
import java.awt.Color;
|
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.sl.usermodel.TextRun;
|
||||||
import org.apache.poi.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.xslf.model.CharacterPropertyFetcher;
|
import org.apache.poi.xslf.model.CharacterPropertyFetcher;
|
||||||
@ -84,10 +87,21 @@ public class XSLFTextRun implements TextRun {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFontColor(Color color) {
|
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();
|
CTTextCharacterProperties rPr = getRPr();
|
||||||
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
|
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
|
||||||
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
|
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.isSetHslClr()) fill.unsetHslClr();
|
||||||
if(fill.isSetPrstClr()) fill.unsetPrstClr();
|
if(fill.isSetPrstClr()) fill.unsetPrstClr();
|
||||||
@ -98,22 +112,22 @@ public class XSLFTextRun implements TextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getFontColor(){
|
public PaintStyle getFontColor(){
|
||||||
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
|
CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
|
||||||
CTShapeStyle style = _p.getParentShape().getSpStyle();
|
|
||||||
final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();
|
|
||||||
|
|
||||||
CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getIndentLevel()){
|
|
||||||
public boolean fetch(CTTextCharacterProperties props){
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
CTSolidColorFillProperties solidFill = props.getSolidFill();
|
XSLFShape shape = _p.getParentShape();
|
||||||
if(solidFill != null) {
|
CTShapeStyle style = shape.getSpStyle();
|
||||||
boolean useCtxColor =
|
CTSchemeColor phClr = null;
|
||||||
(solidFill.isSetSchemeClr() && solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)
|
if (style != null && style.getFontRef() != null) {
|
||||||
|| isFetchingFromMaster;
|
phClr = style.getFontRef().getSchemeClr();
|
||||||
Color c = new XSLFColor(solidFill, theme, useCtxColor ? phClr : null).getColor();
|
}
|
||||||
setValue(c);
|
|
||||||
|
PaintStyle ps = shape.getPaint(props, phClr);
|
||||||
|
if (ps != null) {
|
||||||
|
setValue(ps);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -250,7 +264,7 @@ public class XSLFTextRun implements TextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte getPitchAndFamily(){
|
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()){
|
CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
|
||||||
public boolean fetch(CTTextCharacterProperties props){
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
@ -474,35 +488,36 @@ public class XSLFTextRun implements TextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
|
private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
|
||||||
|
XSLFTextShape shape = _p.getParentShape();
|
||||||
|
XSLFSheet sheet = shape.getSheet();
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
|
|
||||||
if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());
|
if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());
|
||||||
|
if (ok) return true;
|
||||||
|
|
||||||
if(!ok) {
|
|
||||||
XSLFTextShape shape = _p.getParentShape();
|
|
||||||
ok = shape.fetchShapeProperty(fetcher);
|
ok = shape.fetchShapeProperty(fetcher);
|
||||||
if(!ok){
|
if (ok) return true;
|
||||||
|
|
||||||
CTPlaceholder ph = shape.getCTPlaceholder();
|
CTPlaceholder ph = shape.getCTPlaceholder();
|
||||||
if (ph == null){
|
if (ph == null){
|
||||||
// if it is a plain text box then take defaults from presentation.xml
|
// if it is a plain text box then take defaults from presentation.xml
|
||||||
XMLSlideShow ppt = shape.getSheet().getSlideShow();
|
XMLSlideShow ppt = sheet.getSlideShow();
|
||||||
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
|
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
|
||||||
if (themeProps != null) {
|
if (themeProps != null) {
|
||||||
fetcher.isFetchingFromMaster = true;
|
// TODO: determine master shape
|
||||||
ok = fetcher.fetch(themeProps);
|
ok = fetcher.fetch(themeProps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (ok) return true;
|
||||||
|
|
||||||
CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
|
CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
|
||||||
if(defaultProps != null) {
|
if(defaultProps != null) {
|
||||||
fetcher.isFetchingFromMaster = true;
|
// TODO: determine master shape
|
||||||
ok = fetcher.fetch(defaultProps);
|
ok = fetcher.fetch(defaultProps);
|
||||||
}
|
}
|
||||||
}
|
if (ok) return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy(XSLFTextRun r){
|
void copy(XSLFTextRun r){
|
||||||
@ -511,7 +526,7 @@ public class XSLFTextRun implements TextRun {
|
|||||||
setFontFamily(srcFontFamily);
|
setFontFamily(srcFontFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color srcFontColor = r.getFontColor();
|
PaintStyle srcFontColor = r.getFontColor();
|
||||||
if(srcFontColor != null && !srcFontColor.equals(getFontColor())){
|
if(srcFontColor != null && !srcFontColor.equals(getFontColor())){
|
||||||
setFontColor(srcFontColor);
|
setFontColor(srcFontColor);
|
||||||
}
|
}
|
||||||
|
@ -19,19 +19,22 @@
|
|||||||
|
|
||||||
package org.apache.poi.xslf.util;
|
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.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.FileOutputStream;
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
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
|
* 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 {
|
public class PPTX2PNG {
|
||||||
|
|
||||||
static void usage(){
|
static void usage(String error){
|
||||||
System.out.println("Usage: PPTX2PNG [options] <pptx file>");
|
String msg =
|
||||||
System.out.println("Options:");
|
"Usage: PPTX2PNG [options] <ppt or pptx file>\n" +
|
||||||
System.out.println(" -scale <float> scale factor");
|
(error == null ? "" : ("Error: "+error+"\n")) +
|
||||||
System.out.println(" -slide <integer> 1-based index of a slide to render");
|
"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 {
|
public static void main(String[] args) throws Exception {
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
usage();
|
usage(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slidenum = -1;
|
int slidenum = -1;
|
||||||
float scale = 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++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
if (args[i].startsWith("-")) {
|
if (args[i].startsWith("-")) {
|
||||||
@ -63,33 +77,69 @@ public class PPTX2PNG {
|
|||||||
scale = Float.parseFloat(args[++i]);
|
scale = Float.parseFloat(args[++i]);
|
||||||
} else if ("-slide".equals(args[i])) {
|
} else if ("-slide".equals(args[i])) {
|
||||||
slidenum = Integer.parseInt(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 {
|
} else {
|
||||||
file = args[i];
|
file = new File(args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file == null){
|
if (file == null || !file.exists()) {
|
||||||
usage();
|
usage("File not specified or it doesn't exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Processing " + file);
|
if (outdir == null) {
|
||||||
XMLSlideShow ppt = new XMLSlideShow(OPCPackage.open(file));
|
outdir = file.getParentFile();
|
||||||
|
}
|
||||||
|
|
||||||
Dimension pgsize = ppt.getPageSize();
|
if (outdir == null || !outdir.exists() || !outdir.isDirectory()) {
|
||||||
|
usage("Output directory doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
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 width = (int) (pgsize.width * scale);
|
||||||
int height = (int) (pgsize.height * scale);
|
int height = (int) (pgsize.height * scale);
|
||||||
|
|
||||||
List<XSLFSlide> slide = ppt.getSlides();
|
int slideNo=1;
|
||||||
for (int i = 0; i < slide.size(); i++) {
|
for(Slide<?,?,?> slide : slides) {
|
||||||
if (slidenum != -1 && slidenum != (i + 1)) continue;
|
if (slidenum == -1 || slideNo == slidenum) {
|
||||||
|
String title = slide.getTitle();
|
||||||
|
if (!quite) {
|
||||||
|
System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
|
||||||
|
}
|
||||||
|
|
||||||
String title = slide.get(i).getTitle();
|
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title));
|
|
||||||
|
|
||||||
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
||||||
Graphics2D graphics = img.createGraphics();
|
Graphics2D graphics = img.createGraphics();
|
||||||
|
fixFonts(graphics);
|
||||||
|
|
||||||
// default rendering options
|
// default rendering options
|
||||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
@ -97,21 +147,34 @@ public class PPTX2PNG {
|
|||||||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||||
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||||
|
|
||||||
graphics.setColor(Color.white);
|
|
||||||
graphics.clearRect(0, 0, width, height);
|
|
||||||
|
|
||||||
graphics.scale(scale, scale);
|
graphics.scale(scale, scale);
|
||||||
|
|
||||||
// draw stuff
|
// draw stuff
|
||||||
slide.get(i).draw(graphics);
|
slide.draw(graphics);
|
||||||
|
|
||||||
// save the result
|
// save the result
|
||||||
int sep = file.lastIndexOf(".");
|
if (!"null".equals(format)) {
|
||||||
String fname = file.substring(0, sep == -1 ? file.length() : sep) + "-" + (i + 1) +".png";
|
String outname = file.getName().replaceFirst(".pptx?", "");
|
||||||
FileOutputStream out = new FileOutputStream(fname);
|
outname = String.format("%1$s-%2$04d.%3$s", outname, slideNo, format);
|
||||||
ImageIO.write(img, "png", out);
|
File outfile = new File(outdir, outname);
|
||||||
out.close();
|
ImageIO.write(img, format, outfile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
slideNo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!quite) {
|
||||||
System.out.println("Done");
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,16 +19,11 @@
|
|||||||
|
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.io.File;
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.poi.sl.draw.Drawable;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.util.JvmBugs;
|
import org.apache.poi.xslf.util.PPTX2PNG;
|
||||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -44,7 +39,6 @@ public class TestPPTX2PNG {
|
|||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void activateJaxpDebug() {
|
public static void activateJaxpDebug() {
|
||||||
jaxpDebugEnable = setDebugFld(true);
|
jaxpDebugEnable = setDebugFld(true);
|
||||||
// setXmlInputFactory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
@ -67,47 +61,25 @@ public class TestPPTX2PNG {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
@Test
|
||||||
public void render() throws Exception {
|
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){
|
for(String sampleFile : testFiles){
|
||||||
|
args[args.length-1] = samples.getFile(sampleFile).getCanonicalPath();
|
||||||
try {
|
try {
|
||||||
XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument(sampleFile);
|
PPTX2PNG.main(args);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
throw new IllegalStateException("While reading file " + sampleFile, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,12 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
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.awt.Color;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -16,9 +16,15 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
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.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
import org.apache.poi.xslf.XSLFTestDataSamples;
|
||||||
@ -98,7 +104,7 @@ public class TestXSLFSlide {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateSlide(){
|
public void testCreateSlide() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
assertEquals(0, ppt.getSlides().size());
|
assertEquals(0, ppt.getSlides().size());
|
||||||
|
|
||||||
@ -108,10 +114,12 @@ public class TestXSLFSlide {
|
|||||||
assertFalse(slide.getFollowMasterGraphics());
|
assertFalse(slide.getFollowMasterGraphics());
|
||||||
slide.setFollowMasterGraphics(true);
|
slide.setFollowMasterGraphics(true);
|
||||||
assertTrue(slide.getFollowMasterGraphics());
|
assertTrue(slide.getFollowMasterGraphics());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImportContent(){
|
public void testImportContent() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
|
|
||||||
XMLSlideShow src = XSLFTestDataSamples.openSampleDocument("themes.pptx");
|
XMLSlideShow src = XSLFTestDataSamples.openSampleDocument("themes.pptx");
|
||||||
@ -128,7 +136,7 @@ public class TestXSLFSlide {
|
|||||||
assertEquals(40.0, r1.getFontSize(), 0);
|
assertEquals(40.0, r1.getFontSize(), 0);
|
||||||
assertTrue(r1.isBold());
|
assertTrue(r1.isBold());
|
||||||
assertTrue(r1.isItalic());
|
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.getFillColor());
|
||||||
assertNull(sh1.getLineColor());
|
assertNull(sh1.getLineColor());
|
||||||
|
|
||||||
@ -141,7 +149,7 @@ public class TestXSLFSlide {
|
|||||||
assertEquals(18.0, r2.getFontSize(), 0);
|
assertEquals(18.0, r2.getFontSize(), 0);
|
||||||
assertFalse(r2.isBold());
|
assertFalse(r2.isBold());
|
||||||
assertFalse(r2.isItalic());
|
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.getFillColor());
|
||||||
assertEquals(new Color(148, 198, 0), sh2.getLineColor()); // slightly different from PowerPoint!
|
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());
|
//assertEquals(32.4.0, r3.getFontSize());
|
||||||
assertTrue(r3.isBold());
|
assertTrue(r3.isBold());
|
||||||
assertTrue(r3.isItalic());
|
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.getFillColor());
|
||||||
assertNull(sh3.getLineColor());
|
assertNull(sh3.getLineColor());
|
||||||
|
|
||||||
XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);
|
XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);
|
||||||
XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);
|
XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);
|
||||||
assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());
|
assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMergeSlides(){
|
public void testMergeSlides() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"};
|
String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"};
|
||||||
|
|
||||||
@ -179,5 +189,7 @@ public class TestXSLFSlide {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals(30, ppt.getSlides().size());
|
assertEquals(30, ppt.getSlides().size());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,19 +16,24 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
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.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.sl.draw.DrawTextFragment;
|
import org.apache.poi.sl.draw.DrawTextFragment;
|
||||||
import org.apache.poi.sl.draw.DrawTextParagraph;
|
import org.apache.poi.sl.draw.DrawTextParagraph;
|
||||||
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
|
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
|
||||||
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
|
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.apache.poi.xslf.XSLFTestDataSamples;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -37,7 +42,7 @@ import org.junit.Test;
|
|||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public class TestXSLFTextParagraph {
|
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> {
|
static class DrawTextParagraphProxy extends DrawTextParagraph<XSLFTextRun> {
|
||||||
DrawTextParagraphProxy(XSLFTextParagraph p) {
|
DrawTextParagraphProxy(XSLFTextParagraph p) {
|
||||||
@ -58,7 +63,7 @@ public class TestXSLFTextParagraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWrappingWidth() throws Exception {
|
public void testWrappingWidth() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
XSLFSlide slide = ppt.createSlide();
|
XSLFSlide slide = ppt.createSlide();
|
||||||
XSLFTextShape sh = slide.createAutoShape();
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
@ -142,6 +147,8 @@ public class TestXSLFTextParagraph {
|
|||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36
|
assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36
|
||||||
assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0);
|
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
|
* This test requires that the Arial font is available and will run only on windows
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBreakLines(){
|
public void testBreakLines() throws IOException {
|
||||||
String os = System.getProperty("os.name");
|
String os = System.getProperty("os.name");
|
||||||
Assume.assumeTrue("Skipping testBreakLines(), it is executed only on Windows machines", (os != null && os.contains("Windows")));
|
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
|
// the first line is at least two times higher than the second
|
||||||
assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2);
|
assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2);
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThemeInheritance(){
|
public void testThemeInheritance() throws IOException {
|
||||||
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");
|
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");
|
||||||
List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
|
List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
|
||||||
XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0);
|
XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0);
|
||||||
@ -252,10 +260,11 @@ public class TestXSLFTextParagraph {
|
|||||||
XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2);
|
XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2);
|
||||||
assertEquals("Foundation", sh3.getText());
|
assertEquals("Foundation", sh3.getText());
|
||||||
assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());
|
assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParagraphProperties(){
|
public void testParagraphProperties() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
XSLFSlide slide = ppt.createSlide();
|
XSLFSlide slide = ppt.createSlide();
|
||||||
XSLFTextShape sh = slide.createAutoShape();
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
@ -275,7 +284,7 @@ public class TestXSLFTextParagraph {
|
|||||||
|
|
||||||
assertEquals(null, p.getBulletFontColor());
|
assertEquals(null, p.getBulletFontColor());
|
||||||
p.setBulletFontColor(Color.red);
|
p.setBulletFontColor(Color.red);
|
||||||
assertEquals(Color.red, p.getBulletFontColor());
|
assertTrue(sameColor(Color.red, p.getBulletFontColor()));
|
||||||
|
|
||||||
assertNull(p.getBulletFontSize());
|
assertNull(p.getBulletFontSize());
|
||||||
p.setBulletFontSize(200.);
|
p.setBulletFontSize(200.);
|
||||||
@ -342,11 +351,13 @@ public class TestXSLFTextParagraph {
|
|||||||
|
|
||||||
assertEquals(72.0, p.getDefaultTabSize(), 0);
|
assertEquals(72.0, p.getDefaultTabSize(), 0);
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalStateException.class)
|
||||||
public void testLineBreak(){
|
public void testLineBreak() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
|
try {
|
||||||
XSLFSlide slide = ppt.createSlide();
|
XSLFSlide slide = ppt.createSlide();
|
||||||
XSLFTextShape sh = slide.createAutoShape();
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
|
|
||||||
@ -365,11 +376,10 @@ public class TestXSLFTextParagraph {
|
|||||||
|
|
||||||
assertEquals("Hello,\nWorld!\n",sh.getText());
|
assertEquals("Hello,\nWorld!\n",sh.getText());
|
||||||
|
|
||||||
try {
|
// "You cannot change text of a line break, it is always '\\n'"
|
||||||
r2.setText("aaa");
|
r2.setText("aaa");
|
||||||
fail("Expected IllegalStateException");
|
} finally {
|
||||||
} catch (IllegalStateException e){
|
ppt.close();
|
||||||
assertEquals("You cannot change text of a line break, it is always '\\n'", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.poi.xslf.usermodel;
|
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
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public class TestXSLFTextRun extends TestCase {
|
public class TestXSLFTextRun {
|
||||||
|
|
||||||
public void testRunProperties(){
|
@Test
|
||||||
|
public void testRunProperties() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
XSLFSlide slide = ppt.createSlide();
|
XSLFSlide slide = ppt.createSlide();
|
||||||
XSLFTextShape sh = slide.createAutoShape();
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
@ -35,26 +42,26 @@ public class TestXSLFTextRun extends TestCase {
|
|||||||
XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();
|
XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();
|
||||||
assertEquals("en-US", r.getRPr().getLang());
|
assertEquals("en-US", r.getRPr().getLang());
|
||||||
|
|
||||||
assertEquals(0., r.getCharacterSpacing());
|
assertEquals(0., r.getCharacterSpacing(), 0);
|
||||||
r.setCharacterSpacing(3);
|
r.setCharacterSpacing(3);
|
||||||
assertEquals(3., r.getCharacterSpacing());
|
assertEquals(3., r.getCharacterSpacing(), 0);
|
||||||
r.setCharacterSpacing(-3);
|
r.setCharacterSpacing(-3);
|
||||||
assertEquals(-3., r.getCharacterSpacing());
|
assertEquals(-3., r.getCharacterSpacing(), 0);
|
||||||
r.setCharacterSpacing(0);
|
r.setCharacterSpacing(0);
|
||||||
assertEquals(0., r.getCharacterSpacing());
|
assertEquals(0., r.getCharacterSpacing(), 0);
|
||||||
assertFalse(r.getRPr().isSetSpc());
|
assertFalse(r.getRPr().isSetSpc());
|
||||||
|
|
||||||
assertEquals(Color.black, r.getFontColor());
|
assertTrue(sameColor(Color.black, r.getFontColor()));
|
||||||
r.setFontColor(Color.red);
|
r.setFontColor(Color.red);
|
||||||
assertEquals(Color.red, r.getFontColor());
|
assertTrue(sameColor(Color.red, r.getFontColor()));
|
||||||
|
|
||||||
assertEquals("Calibri", r.getFontFamily());
|
assertEquals("Calibri", r.getFontFamily());
|
||||||
r.setFontFamily("Arial");
|
r.setFontFamily("Arial");
|
||||||
assertEquals("Arial", r.getFontFamily());
|
assertEquals("Arial", r.getFontFamily());
|
||||||
|
|
||||||
assertEquals(18.0, r.getFontSize());
|
assertEquals(18.0, r.getFontSize(), 0);
|
||||||
r.setFontSize(13.0);
|
r.setFontSize(13.0);
|
||||||
assertEquals(13.0, r.getFontSize());
|
assertEquals(13.0, r.getFontSize(), 0);
|
||||||
|
|
||||||
assertEquals(false, r.isSuperscript());
|
assertEquals(false, r.isSuperscript());
|
||||||
r.setSuperscript(true);
|
r.setSuperscript(true);
|
||||||
@ -67,5 +74,7 @@ public class TestXSLFTextRun extends TestCase {
|
|||||||
assertEquals(true, r.isSubscript());
|
assertEquals(true, r.isSubscript());
|
||||||
r.setSubscript(false);
|
r.setSubscript(false);
|
||||||
assertEquals(false, r.isSubscript());
|
assertEquals(false, r.isSubscript());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,26 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
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.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
|
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
|
||||||
import org.apache.poi.sl.usermodel.VerticalAlignment;
|
import org.apache.poi.sl.usermodel.VerticalAlignment;
|
||||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
import org.apache.poi.xslf.XSLFTestDataSamples;
|
||||||
import org.junit.Test;
|
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.CTPlaceholder;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
|
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
|
||||||
|
|
||||||
@ -82,7 +92,7 @@ public class TestXSLFTextShape {
|
|||||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
|
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(44.0, r1.getFontSize(), 0);
|
assertEquals(44.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
|
|
||||||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
||||||
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
||||||
@ -151,7 +161,7 @@ public class TestXSLFTextShape {
|
|||||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
|
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(44.0, r1.getFontSize(), 0);
|
assertEquals(44.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
|
|
||||||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
||||||
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
||||||
@ -262,7 +272,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
|
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(40.0, r1.getFontSize(), 0);
|
assertEquals(40.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
assertTrue(r1.isBold());
|
assertTrue(r1.isBold());
|
||||||
assertFalse(r1.isItalic());
|
assertFalse(r1.isItalic());
|
||||||
assertFalse(r1.isUnderlined());
|
assertFalse(r1.isUnderlined());
|
||||||
@ -336,7 +346,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
|
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(44.0, r1.getFontSize(), 0);
|
assertEquals(44.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
|
|
||||||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
||||||
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
CTPlaceholder ph2 = shape2.getCTPlaceholder();
|
||||||
@ -404,7 +414,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals(0, pr5.getParentParagraph().getIndentLevel());
|
assertEquals(0, pr5.getParentParagraph().getIndentLevel());
|
||||||
assertEquals("Right", pr5.getRawText());
|
assertEquals("Right", pr5.getRawText());
|
||||||
assertEquals("Calibri", pr5.getFontFamily());
|
assertEquals("Calibri", pr5.getFontFamily());
|
||||||
assertEquals(Color.black, pr5.getFontColor());
|
assertTrue(sameColor(Color.black, pr5.getFontColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -444,7 +454,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
|
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(44.0, r1.getFontSize(), 0);
|
assertEquals(44.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
assertFalse(r1.isBold());
|
assertFalse(r1.isBold());
|
||||||
|
|
||||||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
||||||
@ -517,7 +527,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
|
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());
|
||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(20.0, r1.getFontSize(), 0);
|
assertEquals(20.0, r1.getFontSize(), 0);
|
||||||
assertEquals(Color.black, r1.getFontColor());
|
assertTrue(sameColor(Color.black, r1.getFontColor()));
|
||||||
assertTrue(r1.isBold());
|
assertTrue(r1.isBold());
|
||||||
|
|
||||||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
|
||||||
@ -605,7 +615,7 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals("Calibri", r1.getFontFamily());
|
assertEquals("Calibri", r1.getFontFamily());
|
||||||
assertEquals(12.0, r1.getFontSize(), 0);
|
assertEquals(12.0, r1.getFontSize(), 0);
|
||||||
// TODO calculation of tint is incorrect
|
// 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);
|
XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT);
|
||||||
assertEquals("Friday, October 21, 2011", dt.getText());
|
assertEquals("Friday, October 21, 2011", dt.getText());
|
||||||
@ -615,7 +625,7 @@ public class TestXSLFTextShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTitleStyles(){
|
public void testTitleStyles() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
|
|
||||||
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
|
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
|
||||||
@ -693,10 +703,12 @@ public class TestXSLFTextShape {
|
|||||||
assertEquals("Calibri", textRun.getFontFamily());
|
assertEquals("Calibri", textRun.getFontFamily());
|
||||||
lv5PPr.setAlgn(STTextAlignType.CTR);
|
lv5PPr.setAlgn(STTextAlignType.CTR);
|
||||||
assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
|
assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBodyStyles(){
|
public void testBodyStyles() throws IOException {
|
||||||
XMLSlideShow ppt = new XMLSlideShow();
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
|
|
||||||
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
|
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
|
||||||
@ -896,6 +908,6 @@ public class TestXSLFTextShape {
|
|||||||
lv3PPr.setAlgn(STTextAlignType.CTR);
|
lv3PPr.setAlgn(STTextAlignType.CTR);
|
||||||
assertEquals(TextAlign.CENTER, p3.getTextAlign());
|
assertEquals(TextAlign.CENTER, p3.getTextAlign());
|
||||||
|
|
||||||
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,6 +16,7 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
|
import static org.apache.poi.sl.TestCommonSL.sameColor;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@ -66,7 +67,7 @@ public class TestXSLFTheme {
|
|||||||
|
|
||||||
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3");
|
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3");
|
||||||
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
|
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());
|
assertEquals(new Color(79, 129, 189), sh1.getFillColor());
|
||||||
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
|
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
|
||||||
|
|
||||||
@ -89,13 +90,13 @@ public class TestXSLFTheme {
|
|||||||
|
|
||||||
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4");
|
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4");
|
||||||
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
|
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());
|
assertEquals(new Color(148, 198, 0), sh1.getFillColor());
|
||||||
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
|
assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill
|
||||||
|
|
||||||
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3");
|
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3");
|
||||||
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh2.getFillColor()); // no fill
|
||||||
|
|
||||||
assertTrue(slide.getSlideLayout().getFollowMasterGraphics());
|
assertTrue(slide.getSlideLayout().getFollowMasterGraphics());
|
||||||
@ -107,7 +108,7 @@ public class TestXSLFTheme {
|
|||||||
|
|
||||||
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1");
|
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1");
|
||||||
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh2.getFillColor()); // no fill
|
||||||
// font size is 40pt and scale factor is 90%
|
// font size is 40pt and scale factor is 90%
|
||||||
assertEquals(36.0, run2.getFontSize(), 0);
|
assertEquals(36.0, run2.getFontSize(), 0);
|
||||||
@ -119,12 +120,12 @@ public class TestXSLFTheme {
|
|||||||
|
|
||||||
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Subtitle 3");
|
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Subtitle 3");
|
||||||
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh1.getFillColor()); // no fill
|
||||||
|
|
||||||
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 2");
|
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 2");
|
||||||
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh2.getFillColor()); // no fill
|
||||||
|
|
||||||
assertFalse(slide.getSlideLayout().getFollowMasterGraphics());
|
assertFalse(slide.getSlideLayout().getFollowMasterGraphics());
|
||||||
@ -154,12 +155,12 @@ public class TestXSLFTheme {
|
|||||||
|
|
||||||
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3");
|
XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3");
|
||||||
XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh1.getFillColor()); // no fill
|
||||||
|
|
||||||
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Subtitle 4");
|
XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Subtitle 4");
|
||||||
XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);
|
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
|
assertNull(sh2.getFillColor()); // no fill
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,14 @@
|
|||||||
|
|
||||||
package org.apache.poi.hslf.model;
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
import org.apache.poi.hslf.usermodel.*;
|
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.ShapeContainer;
|
||||||
import org.apache.poi.sl.usermodel.ShapeType;
|
import org.apache.poi.sl.usermodel.ShapeType;
|
||||||
|
|
||||||
@ -27,7 +33,7 @@ import org.apache.poi.sl.usermodel.ShapeType;
|
|||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @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){
|
public Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
@ -64,23 +70,23 @@ public final class Line extends HSLFSimpleShape {
|
|||||||
return _escherContainer;
|
return _escherContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Sets the orientation of the line, if inverse is false, then line goes
|
// * Sets the orientation of the line, if inverse is false, then line goes
|
||||||
* from top-left to bottom-right, otherwise use inverse equals true
|
// * from top-left to bottom-right, otherwise use inverse equals true
|
||||||
*
|
// *
|
||||||
* @param inverse the orientation of the line
|
// * @param inverse the orientation of the line
|
||||||
*/
|
// */
|
||||||
public void setInverse(boolean inverse) {
|
// public void setInverse(boolean inverse) {
|
||||||
setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE);
|
// setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* Gets the orientation of the line, if inverse is false, then line goes
|
// * Gets the orientation of the line, if inverse is false, then line goes
|
||||||
* from top-left to bottom-right, otherwise inverse equals true
|
// * from top-left to bottom-right, otherwise inverse equals true
|
||||||
*
|
// *
|
||||||
* @return inverse the orientation of the line
|
// * @return inverse the orientation of the line
|
||||||
*/
|
// */
|
||||||
public boolean isInverse() {
|
// public boolean isInverse() {
|
||||||
return (getShapeType() == ShapeType.LINE_INV);
|
// return (getShapeType() == ShapeType.LINE_INV);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,49 @@
|
|||||||
package org.apache.poi.hslf.model;
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.font.*;
|
import java.awt.Color;
|
||||||
import java.awt.geom.*;
|
import java.awt.Composite;
|
||||||
import java.awt.image.*;
|
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.awt.image.renderable.RenderableImage;
|
||||||
import java.text.AttributedCharacterIterator;
|
import java.text.AttributedCharacterIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
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.StrokeStyle;
|
||||||
import org.apache.poi.sl.usermodel.VerticalAlignment;
|
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.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
@ -259,7 +289,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
|
|||||||
rt.setFontSize((double)_font.getSize());
|
rt.setFontSize((double)_font.getSize());
|
||||||
rt.setFontFamily(_font.getFamily());
|
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.isBold()) rt.setBold(true);
|
||||||
if (_font.isItalic()) rt.setItalic(true);
|
if (_font.isItalic()) rt.setItalic(true);
|
||||||
|
|
||||||
|
@ -22,10 +22,16 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
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.hslf.record.Document;
|
||||||
import org.apache.poi.sl.usermodel.*;
|
import org.apache.poi.sl.draw.DrawPaint;
|
||||||
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
|
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.sl.usermodel.PaintStyle.TexturePaint;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
@ -113,20 +119,8 @@ public final class HSLFFill {
|
|||||||
return new FillStyle() {
|
return new FillStyle() {
|
||||||
public PaintStyle getPaint() {
|
public PaintStyle getPaint() {
|
||||||
switch (getFillType()) {
|
switch (getFillType()) {
|
||||||
case FILL_SOLID: {
|
case FILL_SOLID:
|
||||||
return new SolidPaint() {
|
return DrawPaint.createSolidPaint(getForegroundColor());
|
||||||
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_PICTURE: {
|
case FILL_PICTURE: {
|
||||||
final HSLFPictureData pd = getPictureData();
|
final HSLFPictureData pd = getPictureData();
|
||||||
if (pd == null) break;
|
if (pd == null) break;
|
||||||
@ -149,7 +143,7 @@ public final class HSLFFill {
|
|||||||
logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
|
logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return PaintStyle.TRANSPARENT_PAINT;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -188,16 +188,14 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSl
|
|||||||
// Complex Accesser methods follow
|
// Complex Accesser methods follow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return title of this slide or <code>null</code> if the slide does not have title.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
|
* The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
|
||||||
* <code>TextHeaderAtom.TITLE_TYPE</code>
|
* <code>TextHeaderAtom.TITLE_TYPE</code>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @see TextHeaderAtom
|
* @see TextHeaderAtom
|
||||||
*
|
|
||||||
* @return title of this slide
|
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getTitle(){
|
public String getTitle(){
|
||||||
for (List<HSLFTextParagraph> tp : getTextParagraphs()) {
|
for (List<HSLFTextParagraph> tp : getTextParagraphs()) {
|
||||||
if (tp.isEmpty()) continue;
|
if (tp.isEmpty()) continue;
|
||||||
|
@ -132,6 +132,20 @@ public final class HSLFSlideShow implements SlideShow {
|
|||||||
this(new HSLFSlideShowImpl(inputStream));
|
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"
|
* 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
|
* version of all the core records (Document, Notes, Slide etc), and save a
|
||||||
|
@ -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.*;
|
||||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
|
||||||
import org.apache.poi.hslf.record.*;
|
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.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.sl.usermodel.TextParagraph;
|
||||||
import org.apache.poi.util.*;
|
import org.apache.poi.util.*;
|
||||||
|
|
||||||
@ -403,8 +406,24 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getBulletFontColor() {
|
public void setBulletFontColor(Color color) {
|
||||||
return HSLFTextParagraph.this.getBulletColor();
|
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
|
@Override
|
||||||
@ -497,7 +516,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
|
|||||||
TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);
|
TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);
|
||||||
if (tp == null) {
|
if (tp == null) {
|
||||||
// if bullet color is undefined, return color of first run
|
// 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);
|
return getColorFromColorIndexStruct(tp.getValue(), _sheet);
|
||||||
|
@ -21,8 +21,14 @@ import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal;
|
|||||||
|
|
||||||
import java.awt.Color;
|
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.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.sl.usermodel.TextRun;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
@ -315,13 +321,15 @@ public final class HSLFTextRun implements TextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return font color as RGB value
|
* @return font color as PaintStyle
|
||||||
* @see java.awt.Color
|
|
||||||
*/
|
*/
|
||||||
public Color getFontColor() {
|
@Override
|
||||||
|
public SolidPaint getFontColor() {
|
||||||
TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph);
|
TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph);
|
||||||
return (tp == null) ? null
|
if (tp == null) return null;
|
||||||
: HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet());
|
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);
|
setCharTextPropVal("font.color", bgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets color of the text, as a java.awt.Color
|
@Override
|
||||||
*/
|
|
||||||
public void setFontColor(Color color) {
|
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
|
// 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);
|
setFontColor(rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.poi.hslf.model;
|
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.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
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.HSLFTextParagraph;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTextRun;
|
import org.apache.poi.hslf.usermodel.HSLFTextRun;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTextShape;
|
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.ShapeType;
|
||||||
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
|
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
|
||||||
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -189,16 +190,16 @@ public final class TestShapes {
|
|||||||
List<HSLFTextParagraph> para = tb.getTextParagraphs();
|
List<HSLFTextParagraph> para = tb.getTextParagraphs();
|
||||||
HSLFTextRun tr = para.get(0).getTextRuns().get(0);
|
HSLFTextRun tr = para.get(0).getTextRuns().get(0);
|
||||||
assertEquals("para 1 run 1. ", tr.getRawText());
|
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);
|
tr = para.get(0).getTextRuns().get(1);
|
||||||
assertEquals("para 1 run 2.\r", tr.getRawText());
|
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);
|
tr = para.get(1).getTextRuns().get(0);
|
||||||
assertEquals("para 2 run 1. ", tr.getRawText());
|
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);
|
tr = para.get(1).getTextRuns().get(1);
|
||||||
assertEquals("para 2 run 2. para 2 run 3.", tr.getRawText());
|
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());
|
assertTrue(tr.isStrikethrough());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +236,7 @@ public final class TestShapes {
|
|||||||
assertTrue(rt.isItalic());
|
assertTrue(rt.isItalic());
|
||||||
assertFalse(rt.isUnderlined());
|
assertFalse(rt.isUnderlined());
|
||||||
assertEquals("Arial", rt.getFontFamily());
|
assertEquals("Arial", rt.getFontFamily());
|
||||||
assertEquals(Color.red, rt.getFontColor());
|
assertTrue(sameColor(Color.red, rt.getFontColor()));
|
||||||
|
|
||||||
// Serialize and read again
|
// Serialize and read again
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
@ -255,7 +256,7 @@ public final class TestShapes {
|
|||||||
assertTrue(rt.isItalic());
|
assertTrue(rt.isItalic());
|
||||||
assertFalse(rt.isUnderlined());
|
assertFalse(rt.isUnderlined());
|
||||||
assertEquals("Arial", rt.getFontFamily());
|
assertEquals("Arial", rt.getFontFamily());
|
||||||
assertEquals(Color.red, rt.getFontColor());
|
assertTrue(sameColor(Color.red, rt.getFontColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,15 +17,26 @@
|
|||||||
|
|
||||||
package org.apache.poi.hslf.usermodel;
|
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.awt.Color;
|
||||||
import java.io.*;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -539,7 +550,7 @@ public final class TestTextRun {
|
|||||||
List<HSLFTextParagraph> run = tx.getTextParagraphs();
|
List<HSLFTextParagraph> run = tx.getTextParagraphs();
|
||||||
HSLFTextRun rt = run.get(0).getTextRuns().get(0);
|
HSLFTextRun rt = run.get(0).getTextRuns().get(0);
|
||||||
assertTrue(rt.isBold());
|
assertTrue(rt.isBold());
|
||||||
assertEquals(rt.getFontColor(), Color.RED);
|
assertTrue(sameColor(Color.RED, rt.getFontColor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
src/testcases/org/apache/poi/sl/TestCommonSL.java
Normal file
38
src/testcases/org/apache/poi/sl/TestCommonSL.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
test-data/slideshow/KEY02.pptx
Normal file
BIN
test-data/slideshow/KEY02.pptx
Normal file
Binary file not shown.
BIN
test-data/slideshow/alterman_security.pptx
Normal file
BIN
test-data/slideshow/alterman_security.pptx
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user