more progress with PPTX2PNG

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1201687 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2011-11-14 13:00:13 +00:00
parent dd654d9870
commit 14ee39dde1
32 changed files with 244 additions and 159 deletions

View File

@ -27,6 +27,7 @@ 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);

View File

@ -430,6 +430,8 @@ class RenderableShape {
public Stroke applyStroke(Graphics2D graphics) { public Stroke applyStroke(Graphics2D graphics) {
float lineWidth = (float) _shape.getLineWidth(); float lineWidth = (float) _shape.getLineWidth();
if(lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt
LineDash lineDash = _shape.getLineDash(); LineDash lineDash = _shape.getLineDash();
float[] dash = null; float[] dash = null;
float dash_phase = 0; float dash_phase = 0;
@ -559,8 +561,6 @@ class RenderableShape {
lst.add(new Outline(canvasShape, p)); lst.add(new Outline(canvasShape, p));
} }
// add any shape-specific stuff here (line decorations, etc.)
lst.addAll(_shape.getCustomOutlines());
return lst; return lst;
} }

View File

@ -35,12 +35,13 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual; import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual;
import java.awt.Shape; import java.awt.Shape;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D; import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -206,7 +207,8 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
LineEndLength tailLength = getLineTailLength(); LineEndLength tailLength = getLineTailLength();
LineEndWidth tailWidth = getLineTailWidth(); LineEndWidth tailWidth = getLineTailWidth();
double lineWidth = getLineWidth(); double lineWidth = Math.max(2.5, getLineWidth());
Rectangle2D anchor = getAnchor(); Rectangle2D anchor = getAnchor();
double x2 = anchor.getX() + anchor.getWidth(), double x2 = anchor.getX() + anchor.getWidth(),
y2 = anchor.getY() + anchor.getHeight(); y2 = anchor.getY() + anchor.getHeight();
@ -264,7 +266,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
LineEndLength headLength = getLineHeadLength(); LineEndLength headLength = getLineHeadLength();
LineEndWidth headWidth = getLineHeadWidth(); LineEndWidth headWidth = getLineHeadWidth();
double lineWidth = getLineWidth(); double lineWidth = Math.max(2.5, getLineWidth());
Rectangle2D anchor = getAnchor(); Rectangle2D anchor = getAnchor();
double x1 = anchor.getX(), double x1 = anchor.getX(),
y1 = anchor.getY(); y1 = anchor.getY();
@ -287,7 +289,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
break; break;
case STEALTH: case STEALTH:
case ARROW: case ARROW:
p = new Path(); p = new Path(false, true);
GeneralPath arrow = new GeneralPath(); GeneralPath arrow = new GeneralPath();
arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2)); arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));
arrow.lineTo(0, 0); arrow.lineTo(0, 0);
@ -319,8 +321,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
return shape == null ? null : new Outline(shape, p); return shape == null ? null : new Outline(shape, p);
} }
@Override private List<Outline> getDecorationOutlines(){
List<Outline> getCustomOutlines(){
List<Outline> lst = new ArrayList<Outline>(); List<Outline> lst = new ArrayList<Outline>();
Outline head = getHeadDecoration(); Outline head = getHeadDecoration();
@ -339,4 +340,23 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
public XSLFShadow getShadow() { public XSLFShadow getShadow() {
return null; return null;
} }
@Override
public void draw(Graphics2D graphics){
super.draw(graphics);
// draw line decorations
Color lineColor = getLineColor();
if(lineColor != null) {
graphics.setPaint(lineColor);
for(Outline o : getDecorationOutlines()){
if(o.getPath().isFilled()){
graphics.fill(o.getOutline());
}
if(o.getPath().isStroked()){
graphics.draw(o.getOutline());
}
}
}
}
} }

View File

@ -281,6 +281,11 @@ public class XSLFGroupShape extends XSLFShape {
graphics.translate(exterior.getX(), exterior.getY()); graphics.translate(exterior.getX(), exterior.getY());
double scaleX = exterior.getWidth() / interior.getWidth(); double scaleX = exterior.getWidth() / interior.getWidth();
double scaleY = exterior.getHeight() / interior.getHeight(); double scaleY = exterior.getHeight() / interior.getHeight();
// group transform scales shapes but not fonts
Number prevFontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.FONT_SCALE);
graphics.setRenderingHint(XSLFRenderingHint.FONT_SCALE, Math.abs(1/scaleY));
graphics.scale(scaleX, scaleY); graphics.scale(scaleX, scaleY);
graphics.translate(-interior.getX(), -interior.getY()); graphics.translate(-interior.getX(), -interior.getY());
@ -296,6 +301,9 @@ public class XSLFGroupShape extends XSLFShape {
graphics.setTransform(at); graphics.setTransform(at);
graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true); graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
} }
graphics.setRenderingHint(XSLFRenderingHint.FONT_SCALE, prevFontScale);
} }
} }

View File

@ -19,6 +19,8 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import org.apache.poi.util.Internal;
import java.awt.RenderingHints; import java.awt.RenderingHints;
/** /**
@ -71,4 +73,7 @@ public class XSLFRenderingHint extends RenderingHints.Key {
* draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)} * draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}
*/ */
public static final int TEXT_MODE_GLYPHS = 2; public static final int TEXT_MODE_GLYPHS = 2;
@Internal
public static final XSLFRenderingHint FONT_SCALE = new XSLFRenderingHint(5);
} }

View File

@ -642,14 +642,6 @@ public abstract class XSLFSimpleShape extends XSLFShape {
} }
/**
* @return any shape-specific geometry that is not included in presetShapeDefinitions.xml
* (line decorations, etc)
*/
List<Outline> getCustomOutlines(){
return Collections.emptyList();
}
/** /**
* draw any content within this shape (image, text, etc.). * draw any content within this shape (image, text, etc.).
* *

View File

@ -26,6 +26,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;
@ -33,6 +35,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
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;
@ -242,7 +246,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
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) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});
} }
public double getBulletFontSize(){ public double getBulletFontSize(){
@ -333,7 +337,45 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
}; };
fetchParagraphProperty(fetcher); fetchParagraphProperty(fetcher);
// 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
return fetcher.getValue() == null ? Units.toPoints(347663) : fetcher.getValue(); return fetcher.getValue() == null ? 0 : fetcher.getValue();
}
/**
*
* @return the default size for a tab character within this paragraph
*/
public double getDefaultTabSize(){
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
public boolean fetch(CTTextParagraphProperties props){
if(props.isSetDefTabSz()){
double val = Units.toPoints(props.getDefTabSz());
setValue(val);
return true;
}
return false;
}
};
fetchParagraphProperty(fetcher);
return fetcher.getValue() == null ? 0 : fetcher.getValue();
}
public double getTabStop(final int idx){
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
public boolean fetch(CTTextParagraphProperties props){
if(props.isSetTabLst()){
CTTextTabStopList tabStops = props.getTabLst();
if(idx < tabStops.sizeOfTabArray() ) {
CTTextTabStop ts = tabStops.getTabArray(idx);
double val = Units.toPoints(ts.getPos());
setValue(val);
return true;
}
}
return false;
}
};
fetchParagraphProperty(fetcher);
return fetcher.getValue() == null ? getDefaultTabSize() : fetcher.getValue();
} }
/** /**
@ -389,7 +431,18 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
} }
}; };
fetchParagraphProperty(fetcher); fetchParagraphProperty(fetcher);
return fetcher.getValue() == null ? 100 : fetcher.getValue();
double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue();
if(lnSpc > 0) {
// check if the percentage value is scaled
CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit();
if(normAutofit != null) {
double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000;
lnSpc *= scale;
}
}
return lnSpc;
} }
/** /**
@ -443,7 +496,9 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
} }
}; };
fetchParagraphProperty(fetcher); fetchParagraphProperty(fetcher);
return fetcher.getValue() == null ? 0 : fetcher.getValue();
double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue();
return spcBef;
} }
/** /**
@ -535,7 +590,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
setValue(false); setValue(false);
return true; return true;
} }
if(props.isSetBuFont()){ if(props.isSetBuFont() || props.isSetBuChar()){
setValue(true); setValue(true);
return true; return true;
} }
@ -596,7 +651,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
width = anchor.getWidth() - leftInset - rightInset - leftMargin; width = anchor.getWidth() - leftInset - rightInset - leftMargin;
if(firstLine) { if(firstLine) {
if(isBullet()){ if(isBullet()){
width -= Math.abs(indent); if(indent > 0) width -= indent;
} else { } else {
if(indent > 0) width -= indent; // first line indentation if(indent > 0) width -= indent; // first line indentation
else if (indent < 0) { // hanging indentation: the first line start at the left margin else if (indent < 0) { // hanging indentation: the first line start at the left margin
@ -618,28 +673,25 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
double leftMargin = getLeftMargin(); double leftMargin = getLeftMargin();
boolean firstLine = true; boolean firstLine = true;
double indent = getIndent(); double indent = getIndent();
//The vertical line spacing
double spacing = getLineSpacing();
for(TextFragment line : _lines){ for(TextFragment line : _lines){
double penX = x; double penX = x + leftMargin;
if(firstLine) { if(firstLine) {
if(_bullet != null){ if(_bullet != null){
if(indent < 0) { if(indent < 0) {
// a negative value means "Hanging" indentation and // a negative value means "Hanging" indentation and
// indicates the position of the actual bullet character. // indicates the position of the actual bullet character.
// (the bullet is shifted to right relative to the text) // (the bullet is shifted to right relative to the text)
_bullet.draw(graphics, penX, penY); _bullet.draw(graphics, penX + indent, penY);
penX -= indent;
} else if(indent > 0){ } else if(indent > 0){
penX += leftMargin;
// a positive value means the "First Line" indentation: // a positive value means the "First Line" indentation:
// the first line is indented and other lines start at the bullet ofset // the first line is indented and other lines start at the bullet ofset
_bullet.draw(graphics, penX, penY); _bullet.draw(graphics, penX, penY);
penX += indent; penX += indent;
} else { } else {
// no special indent. The first line behaves like all others
penX += leftMargin;
// a zero indent means that the bullet and text have the same offset // a zero indent means that the bullet and text have the same offset
_bullet.draw(graphics, penX, penY); _bullet.draw(graphics, penX, penY);
@ -647,19 +699,8 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
penX += _bullet._layout.getAdvance() + 1; penX += _bullet._layout.getAdvance() + 1;
} }
} else { } else {
if(indent < 0) { penX += indent;
// if bullet=false and indentation=hanging then the first line
// starts at the left offset (penX is not incremented)
} else if(indent > 0) {
// first line indent shifts penX
penX += indent + leftMargin;
} else {
// no special indent. The first line behaves like all others
penX += leftMargin;
}
} }
} else {
penX += leftMargin;
} }
@ -671,14 +712,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset); penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);
break; break;
default: default:
//penX += leftInset;
break; break;
} }
line.draw(graphics, penX, penY); line.draw(graphics, penX, penY);
//The vertical line spacing
double spacing = getLineSpacing();
if(spacing > 0) { if(spacing > 0) {
// If linespacing >= 0, then linespacing is a percentage of normal line height. // If linespacing >= 0, then linespacing is a percentage of normal line height.
penY += spacing*0.01* _maxLineHeight; penY += spacing*0.01* _maxLineHeight;
@ -689,6 +727,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
firstLine = false; firstLine = false;
} }
return penY - y; return penY - y;
} }
@ -722,6 +761,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
} }
AttributedString getAttributedString(Graphics2D graphics){ AttributedString getAttributedString(Graphics2D graphics){
String text = getRenderableText(); String text = getRenderableText();
AttributedString string = new AttributedString(text); AttributedString string = new AttributedString(text);
@ -740,7 +780,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
// user can pass an object to convert fonts via a rendering hint // user can pass an object to convert fonts via a rendering hint
string.addAttribute(TextAttribute.FAMILY, run.getFontFamily(), startIndex, endIndex); string.addAttribute(TextAttribute.FAMILY, run.getFontFamily(), startIndex, endIndex);
string.addAttribute(TextAttribute.SIZE, (float)run.getFontSize(), startIndex, endIndex); float fontSz = (float)run.getFontSize();
Number fontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.FONT_SCALE);
if(fontScale != null) fontSz *= fontScale.floatValue();
string.addAttribute(TextAttribute.SIZE, fontSz , startIndex, endIndex);
if(run.isBold()) { if(run.isBold()) {
string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex); string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex);
} }
@ -768,30 +812,48 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
return string; return string;
} }
/**
* ensure that the paragraph contains at least one character
*/
private void ensureNotEmpty(){
XSLFTextRun r = addNewTextRun();
r.setText(" ");
CTTextCharacterProperties endPr = _p.getEndParaRPr();
if(endPr != null) {
if(endPr.isSetSz()) r.setFontSize(endPr.getSz() / 100);
}
}
void breakText(Graphics2D graphics){ void breakText(Graphics2D graphics){
_lines = new ArrayList<TextFragment>(); _lines = new ArrayList<TextFragment>();
// does this paragraph contain text?
boolean emptyParagraph = _runs.size() == 0;
// ensure that the paragraph contains at least one character
if(_runs.size() == 0) ensureNotEmpty();
String text = getRenderableText(); String text = getRenderableText();
if(text.length() == 0) return;
AttributedString at = getAttributedString(graphics); AttributedString at = getAttributedString(graphics);
AttributedCharacterIterator it = at.getIterator(); AttributedCharacterIterator it = at.getIterator();
if(it.getBeginIndex() == it.getEndIndex()) {
return;
}
LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext()); LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext());
for (;;) { for (;;) {
int startIndex = measurer.getPosition(); int startIndex = measurer.getPosition();
double wrappingWidth = getWrappingWidth(_lines.size() == 0) + 1; // add a pixel to compensate rounding errors double wrappingWidth = getWrappingWidth(_lines.size() == 0) + 1; // add a pixel to compensate rounding errors
// shape width can be smaller that the sum of insets (proved by a test file)
if(wrappingWidth < 0) wrappingWidth = 1;
int nextBreak = text.indexOf('\n', startIndex + 1); int nextBreak = text.indexOf('\n', startIndex + 1);
if(nextBreak == -1) nextBreak = it.getEndIndex(); if(nextBreak == -1) nextBreak = it.getEndIndex();
TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true); TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);
if (layout == null) { if (layout == null) {
// layout can be null if the entire word at the current position // layout can be null if the entire word at the current position
// does not fit within the wrapping width. Try with requireNextWord=false. // does not fit within the wrapping width. Try with requireNextWord=false.
layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false); layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false);
} }
int endIndex = measurer.getPosition(); int endIndex = measurer.getPosition();
@ -809,9 +871,10 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
if(endIndex == it.getEndIndex()) break; if(endIndex == it.getEndIndex()) break;
} }
if(isBullet()) { if(isBullet() && !emptyParagraph) {
String buCharacter = getBulletCharacter(); String buCharacter = getBulletCharacter();
String buFont = getBulletFont(); String buFont = getBulletFont();
if(buFont == null) buFont = getTextRuns().get(0).getFontFamily();
if(buCharacter != null && buFont != null && _lines.size() > 0) { if(buCharacter != null && buFont != null && _lines.size() > 0) {
AttributedString str = new AttributedString(buCharacter); AttributedString str = new AttributedString(buCharacter);
@ -954,4 +1017,5 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
r2.copy(r1); r2.copy(r1);
} }
} }
} }

View File

@ -29,8 +29,13 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import java.awt.Color; import java.awt.Color;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
/** /**
* Represents a run of text within the containing text body. The run element is the * Represents a run of text within the containing text body. The run element is the
@ -58,21 +63,54 @@ public class XSLFTextRun {
String getRenderableText(){ String getRenderableText(){
String txt = _r.getT(); String txt = _r.getT();
switch (getTextCap()){
case ALL: StringBuffer buf = new StringBuffer();
txt = txt.toUpperCase(); for(int i = 0; i < txt.length(); i++) {
break; char c = txt.charAt(i);
case SMALL: if(c == '\t') {
txt = txt.toLowerCase(); // replace tab with the effective number of white spaces
break; buf.append(" ");
} else {
switch (getTextCap()){
case ALL:
buf.append(Character.toUpperCase(c));
break;
case SMALL:
buf.append(Character.toLowerCase(c));
break;
default:
buf.append(c);
}
}
} }
// TODO-1 is is the place to convert wingdings to unicode
return buf.toString();
// TODO-2 this is a temporary hack. Rendering text with tabs is not yet supported.
// for now tabs are replaced with some number of spaces.
return txt.replace("\t", " ");
} }
/**
* Replace a tab with the effective number of white spaces.
*
* @return
*/
private String tab2space(){
AttributedString string = new AttributedString(" ");
// user can pass an object to convert fonts via a rendering hint
string.addAttribute(TextAttribute.FAMILY, getFontFamily());
string.addAttribute(TextAttribute.SIZE, (float)getFontSize());
TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true));
double wspace = l.getAdvance();
double tabSz = _p.getDefaultTabSize();
int numSpaces = (int)Math.ceil(tabSz / wspace);
StringBuffer buf = new StringBuffer();
for(int i = 0; i < numSpaces; i++) {
buf.append(' ');
}
return buf.toString();
}
public void setText(String text){ public void setText(String text){
_r.setT(text); _r.setT(text);
} }
@ -98,13 +136,16 @@ public class XSLFTextRun {
public Color getFontColor(){ public Color getFontColor(){
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
CTShapeStyle style = _p.getParentShape().getSpStyle(); CTShapeStyle style = _p.getParentShape().getSpStyle();
final CTSchemeColor shapeStyle = style == null ? null : style.getFontRef().getSchemeClr(); final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();
CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){ CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
CTSolidColorFillProperties solidFill = props.getSolidFill(); CTSolidColorFillProperties solidFill = props.getSolidFill();
if(solidFill != null) { if(solidFill != null) {
Color c = new XSLFColor(solidFill, theme, shapeStyle).getColor(); boolean useCtxColor =
(solidFill.isSetSchemeClr() && solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)
|| isFetchingFromMaster;
Color c = new XSLFColor(solidFill, theme, useCtxColor ? phClr : null).getColor();
setValue(c); setValue(c);
return true; return true;
} }
@ -410,7 +451,10 @@ public class XSLFTextRun {
ok = shape.fetchShapeProperty(fetcher); ok = shape.fetchShapeProperty(fetcher);
if(!ok) { if(!ok) {
CTTextParagraphProperties defaultProps = _p.getDefaultStyle(); CTTextParagraphProperties defaultProps = _p.getDefaultStyle();
if(defaultProps != null) ok = fetcher.fetch(defaultProps); if(defaultProps != null) {
fetcher.isFetchingFromMaster = true;
ok = fetcher.fetch(defaultProps);
}
} }
} }

View File

@ -16,11 +16,7 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xslf; package org.apache.poi.xslf;
import java.net.URI;
import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow;
@ -28,6 +24,9 @@ import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.poi.xslf.usermodel.XSLFSlide; import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFSlideLayout; import org.apache.poi.xslf.usermodel.XSLFSlideLayout;
import java.net.URI;
import java.util.List;
public class TestXSLFBugs extends TestCase { public class TestXSLFBugs extends TestCase {
public void test51187() throws Exception { public void test51187() throws Exception {

View File

@ -17,7 +17,6 @@
package org.apache.poi.xslf; package org.apache.poi.xslf;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;

View File

@ -16,14 +16,14 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xslf; package org.apache.poi.xslf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -16,12 +16,11 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xslf.extractor; package org.apache.poi.xslf.extractor;
import junit.framework.TestCase;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xslf.XSLFSlideShow; import org.apache.poi.xslf.XSLFSlideShow;
import junit.framework.TestCase;
/** /**
* Tests for HXFPowerPointExtractor * Tests for HXFPowerPointExtractor
*/ */

View File

@ -19,7 +19,10 @@
package org.apache.poi.xslf.geom; package org.apache.poi.xslf.geom;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.model.geom.*; import org.apache.poi.xslf.model.geom.Context;
import org.apache.poi.xslf.model.geom.CustomGeometry;
import org.apache.poi.xslf.model.geom.Formula;
import org.apache.poi.xslf.model.geom.Guide;
import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
/** /**

View File

@ -19,7 +19,12 @@
package org.apache.poi.xslf.geom; package org.apache.poi.xslf.geom;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.model.geom.*; import org.apache.poi.xslf.model.geom.Context;
import org.apache.poi.xslf.model.geom.CustomGeometry;
import org.apache.poi.xslf.model.geom.Guide;
import org.apache.poi.xslf.model.geom.IAdjustableShape;
import org.apache.poi.xslf.model.geom.Path;
import org.apache.poi.xslf.model.geom.PresetGeometries;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;

View File

@ -17,12 +17,9 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdListEntry; import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdListEntry;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;

View File

@ -17,10 +17,9 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,15 +17,13 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal; import org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import java.awt.*; import java.awt.Color;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,17 +17,9 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.usermodel.LineCap;
import org.apache.poi.xslf.usermodel.LineDash;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType; import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
import java.awt.*;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -18,7 +18,7 @@ package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*; import java.awt.Rectangle;
import java.awt.geom.Ellipse2D; import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;

View File

@ -18,7 +18,7 @@ package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*; import java.awt.Dimension;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
/** /**

View File

@ -17,18 +17,11 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.*;
import java.util.List;
import java.net.URI;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.xslf.XSLFTestDataSamples;
import java.net.URI;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,15 +17,11 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.*;
import java.util.List;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import java.util.Arrays;
import java.util.List;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -17,7 +17,6 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;

View File

@ -17,7 +17,6 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
/** /**

View File

@ -17,16 +17,13 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.poi.xslf.usermodel.LineCap;
import org.apache.poi.xslf.usermodel.LineDash;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import java.awt.*; import java.awt.Color;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,14 +17,10 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.apache.poi.openxml4j.opc.PackagePart;
import java.awt.Color; import java.awt.Color;
import java.util.List;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Pattern;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,13 +17,12 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.xslf.XSLFTestDataSamples;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.List; import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.xslf.XSLFTestDataSamples;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -17,16 +17,12 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.*;
import java.util.List;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
import java.awt.Color;
import java.util.List;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -18,15 +18,6 @@ package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.*;
import java.util.List;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -2,13 +2,9 @@ package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.awt.Rectangle;
import java.awt.Color; import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.FileOutputStream;
import org.apache.poi.xssf.dev.XSSFDump;
import org.apache.poi.xslf.util.PPTX2PNG;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.

View File

@ -18,11 +18,11 @@ package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
import java.awt.*; import java.awt.Color;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -17,8 +17,6 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import java.awt.Color; import java.awt.Color;