mirror of https://github.com/apache/poi.git
improved rendering of groupped shapes in xslf
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1210089 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b8e52ae6ff
commit
99bd60879a
|
@ -102,7 +102,6 @@ class RenderableShape {
|
||||||
*/
|
*/
|
||||||
public Paint selectPaint(Graphics2D graphics, XmlObject obj, CTSchemeColor phClr, PackagePart parentPart) {
|
public Paint selectPaint(Graphics2D graphics, XmlObject obj, CTSchemeColor phClr, PackagePart parentPart) {
|
||||||
XSLFTheme theme = _shape.getSheet().getTheme();
|
XSLFTheme theme = _shape.getSheet().getTheme();
|
||||||
Rectangle2D anchor = _shape.getAnchor();
|
|
||||||
|
|
||||||
Paint paint = null;
|
Paint paint = null;
|
||||||
if (obj instanceof CTNoFillProperties) {
|
if (obj instanceof CTNoFillProperties) {
|
||||||
|
@ -119,6 +118,7 @@ class RenderableShape {
|
||||||
paint = createTexturePaint(blipFill, graphics, parentPart);
|
paint = createTexturePaint(blipFill, graphics, parentPart);
|
||||||
}
|
}
|
||||||
else if (obj instanceof CTGradientFillProperties) {
|
else if (obj instanceof CTGradientFillProperties) {
|
||||||
|
Rectangle2D anchor = getAnchor(graphics);
|
||||||
CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;
|
CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;
|
||||||
if (gradFill.isSetLin()) {
|
if (gradFill.isSetLin()) {
|
||||||
paint = createLinearGradientPaint(graphics, gradFill, anchor, theme, phClr);
|
paint = createLinearGradientPaint(graphics, gradFill, anchor, theme, phClr);
|
||||||
|
@ -477,8 +477,6 @@ class RenderableShape {
|
||||||
|
|
||||||
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
|
if(lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt
|
||||||
Number fontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.GROUP_SCALE);
|
|
||||||
if(fontScale != null) lineWidth *= fontScale.floatValue();
|
|
||||||
|
|
||||||
LineDash lineDash = _shape.getLineDash();
|
LineDash lineDash = _shape.getLineDash();
|
||||||
float[] dash = null;
|
float[] dash = null;
|
||||||
|
@ -512,7 +510,7 @@ class RenderableShape {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Graphics2D graphics){
|
public void render(Graphics2D graphics){
|
||||||
Collection<Outline> elems = computeOutlines();
|
Collection<Outline> elems = computeOutlines(graphics);
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
XSLFShadow shadow = _shape.getShadow();
|
XSLFShadow shadow = _shape.getShadow();
|
||||||
|
@ -549,7 +547,7 @@ class RenderableShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<Outline> computeOutlines() {
|
private Collection<Outline> computeOutlines(Graphics2D graphics) {
|
||||||
|
|
||||||
Collection<Outline> lst = new ArrayList<Outline>();
|
Collection<Outline> lst = new ArrayList<Outline>();
|
||||||
CustomGeometry geom = _shape.getGeometry();
|
CustomGeometry geom = _shape.getGeometry();
|
||||||
|
@ -557,7 +555,7 @@ class RenderableShape {
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle2D anchor = _shape.getAnchor();
|
Rectangle2D anchor = getAnchor(graphics);
|
||||||
for (Path p : geom) {
|
for (Path p : geom) {
|
||||||
|
|
||||||
double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW();
|
double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW();
|
||||||
|
@ -615,4 +613,16 @@ class RenderableShape {
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rectangle2D getAnchor(Graphics2D graphics) {
|
||||||
|
Rectangle2D anchor = _shape.getAnchor();
|
||||||
|
if(graphics == null) {
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);
|
||||||
|
if(tx != null) {
|
||||||
|
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||||
|
}
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,16 +282,15 @@ public class XSLFGroupShape extends XSLFShape {
|
||||||
// anchor of this group relative to the parent shape
|
// anchor of this group relative to the parent shape
|
||||||
Rectangle2D exterior = getAnchor();
|
Rectangle2D exterior = getAnchor();
|
||||||
|
|
||||||
graphics.translate(exterior.getX(), exterior.getY());
|
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);
|
||||||
double scaleX = exterior.getWidth() / interior.getWidth();
|
AffineTransform tx0 = new AffineTransform(tx);
|
||||||
double scaleY = exterior.getHeight() / interior.getHeight();
|
|
||||||
|
|
||||||
// group transform scales shapes but not fonts
|
double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth();
|
||||||
Number prevFontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.GROUP_SCALE);
|
double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight();
|
||||||
graphics.setRenderingHint(XSLFRenderingHint.GROUP_SCALE, Math.abs(1/scaleY));
|
|
||||||
|
|
||||||
graphics.scale(scaleX, scaleY);
|
tx.translate(exterior.getX(), exterior.getY());
|
||||||
graphics.translate(-interior.getX(), -interior.getY());
|
tx.scale(scaleX, scaleY);
|
||||||
|
tx.translate(-interior.getX(), -interior.getY());
|
||||||
|
|
||||||
for (XSLFShape shape : getShapes()) {
|
for (XSLFShape shape : getShapes()) {
|
||||||
// remember the initial transform and restore it after we are done with the drawing
|
// remember the initial transform and restore it after we are done with the drawing
|
||||||
|
@ -306,7 +305,7 @@ public class XSLFGroupShape extends XSLFShape {
|
||||||
graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
|
graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.setRenderingHint(XSLFRenderingHint.GROUP_SCALE, prevFontScale);
|
graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, tx0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,19 +80,14 @@ public class XSLFImageRendener {
|
||||||
Rectangle2D anchor) {
|
Rectangle2D anchor) {
|
||||||
try {
|
try {
|
||||||
BufferedImage img = ImageIO.read(data.getPackagePart().getInputStream());
|
BufferedImage img = ImageIO.read(data.getPackagePart().getInputStream());
|
||||||
Number groupScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.GROUP_SCALE);
|
double sx = anchor.getWidth()/img.getWidth();
|
||||||
if(groupScale != null) {
|
double sy = anchor.getHeight()/img.getHeight();
|
||||||
double sx = anchor.getWidth()/img.getWidth();
|
double tx = anchor.getX();
|
||||||
double sy = anchor.getHeight()/img.getHeight();
|
double ty = anchor.getY();
|
||||||
double tx = anchor.getX();
|
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
||||||
double ty = anchor.getY();
|
|
||||||
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
graphics.drawRenderedImage(img, at);
|
||||||
graphics.drawRenderedImage(img, at);
|
|
||||||
} else {
|
|
||||||
graphics.drawImage(img,
|
|
||||||
(int) anchor.getX(), (int) anchor.getY(),
|
|
||||||
(int) anchor.getWidth(), (int) anchor.getHeight(), null);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLDocumentPart;
|
||||||
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.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
|
@ -77,7 +78,12 @@ public final class XSLFNotes extends XSLFSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XSLFSheet getMasterSheet() {
|
public XSLFNotesMaster getMasterSheet() {
|
||||||
|
for (POIXMLDocumentPart p : getRelations()) {
|
||||||
|
if (p instanceof XSLFNotesMaster){
|
||||||
|
return (XSLFNotesMaster)p;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,10 @@ public class XSLFPictureShape extends XSLFSimpleShape {
|
||||||
XSLFImageRendener renderer = (XSLFImageRendener)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);
|
XSLFImageRendener renderer = (XSLFImageRendener)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);
|
||||||
if(renderer == null) renderer = new XSLFImageRendener();
|
if(renderer == null) renderer = new XSLFImageRendener();
|
||||||
|
|
||||||
renderer.drawImage(graphics, data, getAnchor());
|
RenderableShape rShape = new RenderableShape(this);
|
||||||
|
Rectangle2D anchor = rShape.getAnchor(graphics);
|
||||||
|
|
||||||
|
renderer.drawImage(graphics, data, anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class XSLFRenderingHint extends RenderingHints.Key {
|
||||||
public static final int TEXT_AS_SHAPES = 2;
|
public static final int TEXT_AS_SHAPES = 2;
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
static final XSLFRenderingHint GROUP_SCALE = new XSLFRenderingHint(5);
|
static final XSLFRenderingHint GROUP_TRANSFORM = new XSLFRenderingHint(5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this object to resolve unknown / missing fonts when rendering slides
|
* Use this object to resolve unknown / missing fonts when rendering slides
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.poi.util.Internal;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,6 +132,10 @@ public abstract class XSLFShape {
|
||||||
*/
|
*/
|
||||||
protected void applyTransform(Graphics2D graphics) {
|
protected void applyTransform(Graphics2D graphics) {
|
||||||
Rectangle2D anchor = getAnchor();
|
Rectangle2D anchor = getAnchor();
|
||||||
|
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);
|
||||||
|
if(tx != null) {
|
||||||
|
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||||
|
}
|
||||||
|
|
||||||
// rotation
|
// rotation
|
||||||
double rotation = getRotation();
|
double rotation = getRotation();
|
||||||
|
|
|
@ -430,6 +430,7 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements Iterable<X
|
||||||
XSLFSheet master = getMasterSheet();
|
XSLFSheet master = getMasterSheet();
|
||||||
if(getFollowMasterGraphics() && master != null) master.draw(graphics);
|
if(getFollowMasterGraphics() && master != null) master.draw(graphics);
|
||||||
|
|
||||||
|
graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, new AffineTransform());
|
||||||
for(XSLFShape shape : getShapeList()) {
|
for(XSLFShape shape : getShapeList()) {
|
||||||
if(!canDraw(shape)) continue;
|
if(!canDraw(shape)) continue;
|
||||||
|
|
||||||
|
|
|
@ -544,7 +544,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
||||||
Color lineColor = getLineColor();
|
Color lineColor = getLineColor();
|
||||||
if(lineColor != null) {
|
if(lineColor != null) {
|
||||||
graphics.setPaint(lineColor);
|
graphics.setPaint(lineColor);
|
||||||
for(Outline o : getDecorationOutlines()){
|
for(Outline o : getDecorationOutlines(graphics)){
|
||||||
if(o.getPath().isFilled()){
|
if(o.getPath().isFilled()){
|
||||||
graphics.fill(o.getOutline());
|
graphics.fill(o.getOutline());
|
||||||
}
|
}
|
||||||
|
@ -820,13 +820,13 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
||||||
return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
|
return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Outline getTailDecoration() {
|
Outline getTailDecoration(Graphics2D graphics) {
|
||||||
LineEndLength tailLength = getLineTailLength();
|
LineEndLength tailLength = getLineTailLength();
|
||||||
LineEndWidth tailWidth = getLineTailWidth();
|
LineEndWidth tailWidth = getLineTailWidth();
|
||||||
|
|
||||||
double lineWidth = Math.max(2.5, getLineWidth());
|
double lineWidth = Math.max(2.5, getLineWidth());
|
||||||
|
|
||||||
Rectangle2D anchor = getAnchor();
|
Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
|
||||||
double x2 = anchor.getX() + anchor.getWidth(),
|
double x2 = anchor.getX() + anchor.getWidth(),
|
||||||
y2 = anchor.getY() + anchor.getHeight();
|
y2 = anchor.getY() + anchor.getHeight();
|
||||||
|
|
||||||
|
@ -879,12 +879,13 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
||||||
return shape == null ? null : new Outline(shape, p);
|
return shape == null ? null : new Outline(shape, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
Outline getHeadDecoration() {
|
Outline getHeadDecoration(Graphics2D graphics) {
|
||||||
LineEndLength headLength = getLineHeadLength();
|
LineEndLength headLength = getLineHeadLength();
|
||||||
LineEndWidth headWidth = getLineHeadWidth();
|
LineEndWidth headWidth = getLineHeadWidth();
|
||||||
|
|
||||||
double lineWidth = Math.max(2.5, getLineWidth());
|
double lineWidth = Math.max(2.5, getLineWidth());
|
||||||
Rectangle2D anchor = getAnchor();
|
|
||||||
|
Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
|
||||||
double x1 = anchor.getX(),
|
double x1 = anchor.getX(),
|
||||||
y1 = anchor.getY();
|
y1 = anchor.getY();
|
||||||
|
|
||||||
|
@ -938,13 +939,13 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
||||||
return shape == null ? null : new Outline(shape, p);
|
return shape == null ? null : new Outline(shape, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Outline> getDecorationOutlines(){
|
private List<Outline> getDecorationOutlines(Graphics2D graphics){
|
||||||
List<Outline> lst = new ArrayList<Outline>();
|
List<Outline> lst = new ArrayList<Outline>();
|
||||||
|
|
||||||
Outline head = getHeadDecoration();
|
Outline head = getHeadDecoration(graphics);
|
||||||
if(head != null) lst.add(head);
|
if(head != null) lst.add(head);
|
||||||
|
|
||||||
Outline tail = getTailDecoration();
|
Outline tail = getTailDecoration(graphics);
|
||||||
if(tail != null) lst.add(tail);
|
if(tail != null) lst.add(tail);
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,14 @@
|
||||||
|
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLException;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
|
import org.apache.xmlbeans.XmlException;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
|
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDTable;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
|
||||||
|
@ -50,13 +54,23 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
||||||
/*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
/*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
||||||
super(shape, sheet);
|
super(shape, sheet);
|
||||||
|
|
||||||
for(XmlObject obj : shape.getGraphic().getGraphicData().selectPath("*")){
|
XmlObject[] rs = shape.getGraphic().getGraphicData()
|
||||||
if(obj instanceof CTTable){
|
.selectPath("declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' ./a:tbl");
|
||||||
_table = (CTTable)obj;
|
if (rs.length == 0) {
|
||||||
|
throw new IllegalStateException("a:tbl element was not found in\n " + shape.getGraphic().getGraphicData());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pesky XmlBeans bug - see Bugzilla #49934
|
||||||
|
// it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas
|
||||||
|
if(rs[0] instanceof XmlAnyTypeImpl){
|
||||||
|
try {
|
||||||
|
rs[0] = CTTable.Factory.parse(rs[0].toString());
|
||||||
|
}catch (XmlException e){
|
||||||
|
throw new POIXMLException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(_table == null) throw new IllegalStateException("CTTable element was not found");
|
|
||||||
|
|
||||||
|
_table = (CTTable) rs[0];
|
||||||
_rows = new ArrayList<XSLFTableRow>(_table.sizeOfTrArray());
|
_rows = new ArrayList<XSLFTableRow>(_table.sizeOfTrArray());
|
||||||
for(CTTableRow row : _table.getTrList()) _rows.add(new XSLFTableRow(row, this));
|
for(CTTableRow row : _table.getTrList()) _rows.add(new XSLFTableRow(row, this));
|
||||||
}
|
}
|
||||||
|
|
|
@ -633,12 +633,13 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
*
|
*
|
||||||
* @return wrapping width in points
|
* @return wrapping width in points
|
||||||
*/
|
*/
|
||||||
double getWrappingWidth(boolean firstLine){
|
double getWrappingWidth(boolean firstLine, Graphics2D graphics){
|
||||||
// internal margins for the text box
|
// internal margins for the text box
|
||||||
double leftInset = _shape.getLeftInset();
|
double leftInset = _shape.getLeftInset();
|
||||||
double rightInset = _shape.getRightInset();
|
double rightInset = _shape.getRightInset();
|
||||||
|
|
||||||
Rectangle2D anchor = _shape.getAnchor();
|
RenderableShape rShape = new RenderableShape(_shape);
|
||||||
|
Rectangle2D anchor = rShape.getAnchor(graphics);
|
||||||
|
|
||||||
double leftMargin = getLeftMargin();
|
double leftMargin = getLeftMargin();
|
||||||
double indent = getIndent();
|
double indent = getIndent();
|
||||||
|
@ -667,7 +668,8 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
public double draw(Graphics2D graphics, double x, double y){
|
public double draw(Graphics2D graphics, double x, double y){
|
||||||
double leftInset = _shape.getLeftInset();
|
double leftInset = _shape.getLeftInset();
|
||||||
double rightInset = _shape.getRightInset();
|
double rightInset = _shape.getRightInset();
|
||||||
Rectangle2D anchor = _shape.getAnchor();
|
RenderableShape rShape = new RenderableShape(_shape);
|
||||||
|
Rectangle2D anchor = rShape.getAnchor(graphics);
|
||||||
double penY = y;
|
double penY = y;
|
||||||
|
|
||||||
double leftMargin = getLeftMargin();
|
double leftMargin = getLeftMargin();
|
||||||
|
@ -758,10 +760,8 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
string.addAttribute(TextAttribute.FAMILY, fontFamily, startIndex, endIndex);
|
string.addAttribute(TextAttribute.FAMILY, fontFamily, startIndex, endIndex);
|
||||||
|
|
||||||
float fontSz = (float)run.getFontSize();
|
float fontSz = (float)run.getFontSize();
|
||||||
Number fontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.GROUP_SCALE);
|
|
||||||
if(fontScale != null) fontSz *= fontScale.floatValue();
|
|
||||||
|
|
||||||
string.addAttribute(TextAttribute.SIZE, fontSz , startIndex, endIndex);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -827,7 +827,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
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, graphics) + 1; // add a pixel to compensate rounding errors
|
||||||
// shape width can be smaller that the sum of insets (this was proved by a test file)
|
// shape width can be smaller that the sum of insets (this was proved by a test file)
|
||||||
if(wrappingWidth < 0) wrappingWidth = 1;
|
if(wrappingWidth < 0) wrappingWidth = 1;
|
||||||
|
|
||||||
|
@ -901,21 +901,23 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
CTTextParagraphProperties getDefaultMasterStyle(){
|
CTTextParagraphProperties getDefaultMasterStyle(){
|
||||||
CTPlaceholder ph = _shape.getCTPlaceholder();
|
CTPlaceholder ph = _shape.getCTPlaceholder();
|
||||||
String defaultStyleSelector;
|
String defaultStyleSelector;
|
||||||
switch(ph.getType().intValue()){
|
if(ph == null) defaultStyleSelector = "otherStyle"; // no placeholder means plain text box
|
||||||
case STPlaceholderType.INT_TITLE:
|
else {
|
||||||
case STPlaceholderType.INT_CTR_TITLE:
|
switch(ph.getType().intValue()){
|
||||||
defaultStyleSelector = "titleStyle";
|
case STPlaceholderType.INT_TITLE:
|
||||||
break;
|
case STPlaceholderType.INT_CTR_TITLE:
|
||||||
case STPlaceholderType.INT_FTR:
|
defaultStyleSelector = "titleStyle";
|
||||||
case STPlaceholderType.INT_SLD_NUM:
|
break;
|
||||||
case STPlaceholderType.INT_DT:
|
case STPlaceholderType.INT_FTR:
|
||||||
defaultStyleSelector = "otherStyle";
|
case STPlaceholderType.INT_SLD_NUM:
|
||||||
break;
|
case STPlaceholderType.INT_DT:
|
||||||
default:
|
defaultStyleSelector = "otherStyle";
|
||||||
defaultStyleSelector = "bodyStyle";
|
break;
|
||||||
break;
|
default:
|
||||||
|
defaultStyleSelector = "bodyStyle";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int level = getLevel();
|
int level = getLevel();
|
||||||
|
|
||||||
// wind up and find the root master sheet which must be slide master
|
// wind up and find the root master sheet which must be slide master
|
||||||
|
@ -951,7 +953,9 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||||
XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();
|
XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();
|
||||||
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getLevel());
|
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getLevel());
|
||||||
if(themeProps != null) ok = visitor.fetch(themeProps);
|
if(themeProps != null) ok = visitor.fetch(themeProps);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
if(defaultProps != null) ok = visitor.fetch(defaultProps);
|
if(defaultProps != null) ok = visitor.fetch(defaultProps);
|
||||||
|
|
|
@ -478,8 +478,8 @@ public class XSLFTextRun {
|
||||||
fetcher.isFetchingFromMaster = true;
|
fetcher.isFetchingFromMaster = true;
|
||||||
ok = fetcher.fetch(themeProps);
|
ok = fetcher.fetch(themeProps);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// defaults for placeholders are defined in the slide master
|
if (!ok) {
|
||||||
CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
|
CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
|
||||||
if(defaultProps != null) {
|
if(defaultProps != null) {
|
||||||
fetcher.isFetchingFromMaster = true;
|
fetcher.isFetchingFromMaster = true;
|
||||||
|
|
|
@ -469,7 +469,8 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable<
|
||||||
public void drawContent(Graphics2D graphics) {
|
public void drawContent(Graphics2D graphics) {
|
||||||
breakText(graphics);
|
breakText(graphics);
|
||||||
|
|
||||||
Rectangle2D anchor = getAnchor();
|
RenderableShape rShape = new RenderableShape(this);
|
||||||
|
Rectangle2D anchor = rShape.getAnchor(graphics);
|
||||||
double x = anchor.getX() + getLeftInset();
|
double x = anchor.getX() + getLeftInset();
|
||||||
double y = anchor.getY();
|
double y = anchor.getY();
|
||||||
|
|
||||||
|
|
|
@ -62,5 +62,18 @@ public class TestXSLFTextBox extends TestCase {
|
||||||
pPr.getLatin().setTypeface("Arial");
|
pPr.getLatin().setTypeface("Arial");
|
||||||
assertEquals(9.0, r.getFontSize());
|
assertEquals(9.0, r.getFontSize());
|
||||||
assertEquals("Arial", r.getFontFamily());
|
assertEquals("Arial", r.getFontFamily());
|
||||||
|
|
||||||
|
// unset font size in presentation.xml. The value should be taken from master slide
|
||||||
|
// from /p:sldMaster/p:txStyles/p:otherStyle/a:lvl1pPr/a:defRPr
|
||||||
|
ppt.getCTPresentation().getDefaultTextStyle().getLvl1PPr().getDefRPr().unsetSz();
|
||||||
|
pPr = slide.getSlideMaster().getXmlObject().getTxStyles().getOtherStyle().getLvl1PPr().getDefRPr();
|
||||||
|
assertEquals(1800, pPr.getSz());
|
||||||
|
assertEquals(18.0, r.getFontSize());
|
||||||
|
pPr.setSz(2000);
|
||||||
|
assertEquals(20.0, r.getFontSize());
|
||||||
|
|
||||||
|
pPr.unsetSz(); // Should never be
|
||||||
|
assertEquals(-1.0, r.getFontSize());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -51,16 +51,16 @@ public class TestXSLFTextParagraph extends TestCase {
|
||||||
// Case 1: bullet=false, leftMargin=0, indent=0.
|
// Case 1: bullet=false, leftMargin=0, indent=0.
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(285.6, expectedWidth); // 300 - 7.2 - 7.2 - 0
|
assertEquals(285.6, expectedWidth); // 300 - 7.2 - 7.2 - 0
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(true));
|
assertEquals(expectedWidth, p.getWrappingWidth(true, null));
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(false));
|
assertEquals(expectedWidth, p.getWrappingWidth(false, null));
|
||||||
|
|
||||||
p.setLeftMargin(36); // 0.5"
|
p.setLeftMargin(36); // 0.5"
|
||||||
leftMargin = p.getLeftMargin();
|
leftMargin = p.getLeftMargin();
|
||||||
assertEquals(36.0, leftMargin);
|
assertEquals(36.0, leftMargin);
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(249.6, expectedWidth, 1E-5); // 300 - 7.2 - 7.2 - 36
|
assertEquals(249.6, expectedWidth, 1E-5); // 300 - 7.2 - 7.2 - 36
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(true));
|
assertEquals(expectedWidth, p.getWrappingWidth(true, null));
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(false));
|
assertEquals(expectedWidth, p.getWrappingWidth(false, null));
|
||||||
|
|
||||||
// increase insets, the wrapping width should get smaller
|
// increase insets, the wrapping width should get smaller
|
||||||
sh.setLeftInset(10);
|
sh.setLeftInset(10);
|
||||||
|
@ -71,8 +71,8 @@ public class TestXSLFTextParagraph extends TestCase {
|
||||||
assertEquals(10.0, rightInset);
|
assertEquals(10.0, rightInset);
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(true));
|
assertEquals(expectedWidth, p.getWrappingWidth(true, null));
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(false));
|
assertEquals(expectedWidth, p.getWrappingWidth(false, null));
|
||||||
|
|
||||||
// set a positive indent of a 0.5 inch. This means "First Line" indentation:
|
// set a positive indent of a 0.5 inch. This means "First Line" indentation:
|
||||||
// |<--- indent -->|Here goes first line of the text
|
// |<--- indent -->|Here goes first line of the text
|
||||||
|
@ -83,11 +83,11 @@ public class TestXSLFTextParagraph extends TestCase {
|
||||||
assertEquals(36.0, indent);
|
assertEquals(36.0, indent);
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin - indent;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin - indent;
|
||||||
assertEquals(208.0, expectedWidth); // 300 - 10 - 10 - 36 - 6.4
|
assertEquals(208.0, expectedWidth); // 300 - 10 - 10 - 36 - 6.4
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(true)); // first line is indented
|
assertEquals(expectedWidth, p.getWrappingWidth(true, null)); // first line is indented
|
||||||
// other lines are not indented
|
// other lines are not indented
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(false));
|
assertEquals(expectedWidth, p.getWrappingWidth(false, null));
|
||||||
|
|
||||||
// set a negative indent of a 1 inch. This means "Hanging" indentation:
|
// set a negative indent of a 1 inch. This means "Hanging" indentation:
|
||||||
// Here goes first line of the text
|
// Here goes first line of the text
|
||||||
|
@ -97,11 +97,11 @@ public class TestXSLFTextParagraph extends TestCase {
|
||||||
assertEquals(-72.0, indent);
|
assertEquals(-72.0, indent);
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset;
|
||||||
assertEquals(280.0, expectedWidth); // 300 - 10 - 10
|
assertEquals(280.0, expectedWidth); // 300 - 10 - 10
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(true)); // first line is NOT indented
|
assertEquals(expectedWidth, p.getWrappingWidth(true, null)); // first line is NOT indented
|
||||||
// other lines are indented by leftMargin (the value of indent is not used)
|
// other lines are indented by leftMargin (the value of indent is not used)
|
||||||
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
|
||||||
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
assertEquals(244.0, expectedWidth); // 300 - 10 - 10 - 36
|
||||||
assertEquals(expectedWidth, p.getWrappingWidth(false));
|
assertEquals(expectedWidth, p.getWrappingWidth(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue