aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/poi/sl/draw
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2020-06-04 23:17:44 +0000
committerAndreas Beeker <kiwiwings@apache.org>2020-06-04 23:17:44 +0000
commit5a18307eb051603509c8b8147f4dfdf0e8fe56b2 (patch)
tree70a5e2c1ff908c4a98a614b92f5992c8c2891060 /src/java/org/apache/poi/sl/draw
parent84330c6aa3a96fff4bbd5593b7173209187ec474 (diff)
downloadpoi-5a18307eb051603509c8b8147f4dfdf0e8fe56b2.tar.gz
poi-5a18307eb051603509c8b8147f4dfdf0e8fe56b2.zip
63290 - PPTX To Png changes font sizes and colors
various fixes to HSLF moved line spacing to the following line refactored PropertyFetcher with lambdas git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1878492 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/poi/sl/draw')
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawFontManagerDefault.java1
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawTextFragment.java19
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawTextParagraph.java143
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawTextShape.java22
4 files changed, 98 insertions, 87 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawFontManagerDefault.java b/src/java/org/apache/poi/sl/draw/DrawFontManagerDefault.java
index e5b5f51349..a5acccd023 100644
--- a/src/java/org/apache/poi/sl/draw/DrawFontManagerDefault.java
+++ b/src/java/org/apache/poi/sl/draw/DrawFontManagerDefault.java
@@ -44,6 +44,7 @@ public class DrawFontManagerDefault implements DrawFontManager {
public DrawFontManagerDefault() {
knownSymbolFonts.add("Wingdings");
knownSymbolFonts.add("Symbol");
+ // knownSymbolFonts.add("Monotype Sorts");
}
@Override
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextFragment.java b/src/java/org/apache/poi/sl/draw/DrawTextFragment.java
index 898ac51bd4..cb2ef66df9 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTextFragment.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTextFragment.java
@@ -19,13 +19,15 @@ package org.apache.poi.sl.draw;
import java.awt.Graphics2D;
import java.awt.font.TextLayout;
-import java.text.*;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.CharacterIterator;
public class DrawTextFragment implements Drawable {
final TextLayout layout;
final AttributedString str;
double x, y;
-
+
public DrawTextFragment(TextLayout layout, AttributedString str) {
this.layout = layout;
this.str = str;
@@ -57,7 +59,7 @@ public class DrawTextFragment implements Drawable {
public void drawContent(Graphics2D graphics) {
}
-
+
public TextLayout getLayout() {
return layout;
}
@@ -65,12 +67,12 @@ public class DrawTextFragment implements Drawable {
public AttributedString getAttributedString() {
return str;
}
-
+
/**
* @return full height of this text run which is sum of ascent, descent and leading
*/
- public float getHeight(){
- double h = layout.getAscent() + layout.getDescent() + getLeading();
+ public float getHeight(){
+ double h = layout.getAscent() + layout.getDescent();
return (float)h;
}
@@ -80,6 +82,7 @@ public class DrawTextFragment implements Drawable {
public float getLeading() {
// fix invalid leadings (leading == 0)
double l = layout.getLeading();
+
if (l == 0) {
// see https://stackoverflow.com/questions/925147
// we use a 115% value instead of the 120% proposed one, as this seems to be closer to LO/OO
@@ -87,7 +90,7 @@ public class DrawTextFragment implements Drawable {
}
return (float)l;
}
-
+
/**
*
* @return width if this text run
@@ -115,5 +118,5 @@ public class DrawTextFragment implements Drawable {
public String toString(){
return "[" + getClass().getSimpleName() + "] " + getString();
}
-
+
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
index c68eb44e0e..4019855854 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
@@ -72,11 +72,7 @@ public class DrawTextParagraph implements Drawable {
protected String rawText;
protected DrawTextFragment bullet;
protected int autoNbrIdx;
-
- /**
- * the highest line in this paragraph. Used for line spacing.
- */
- protected double maxLineHeight;
+ protected boolean firstParagraph = true;
/**
* Defines an attribute used for storing the hyperlink associated with
@@ -132,9 +128,10 @@ public class DrawTextParagraph implements Drawable {
return;
}
+ final boolean isHSLF = isHSLF();
+
double penY = y;
- boolean firstLine = true;
int indentLevel = paragraph.getIndentLevel();
Double leftMargin = paragraph.getLeftMargin();
if (leftMargin == null) {
@@ -145,10 +142,6 @@ public class DrawTextParagraph implements Drawable {
if (indent == null) {
indent = Units.toPoints(347663L*indentLevel);
}
- if (isHSLF()) {
- // special handling for HSLF
- indent -= leftMargin;
- }
// Double rightMargin = paragraph.getRightMargin();
// if (rightMargin == null) {
@@ -161,26 +154,41 @@ public class DrawTextParagraph implements Drawable {
spacing = 100d;
}
+ DrawTextFragment lastLine = null;
for(DrawTextFragment line : lines){
double penX;
- if(firstLine) {
+
+ if (!(isFirstParagraph() && lastLine == null)) {
+ // penY is now on descent line of the last text fragment
+ // need to substract descent height to get back to the baseline of the last fragment
+ // then add a multiple of the line height of the current text height
+ penY -= line.getLeading() + ((lastLine == null) ? 0 : lastLine.getLayout().getDescent());
+
+ if(spacing > 0) {
+ // If linespacing >= 0, then linespacing is a percentage of normal line height.
+ penY += (spacing*0.01) * line.getHeight(); // + (isHSLF ? line.getLayout().getLeading() : 0));
+ } else {
+ // negative value means absolute spacing in points
+ penY += -spacing;
+ }
+ penY -= line.getLayout().getAscent();
+ }
+
+ penX = x + (isHSLF ? leftMargin : leftMargin);
+ if (lastLine == null) {
if (!isEmptyParagraph()) {
// TODO: find out character style for empty, but bulleted/numbered lines
bullet = getBullet(graphics, line.getAttributedString().getIterator());
}
- if (bullet != null){
- bullet.setPosition(x+leftMargin+indent, penY);
+ if (bullet != null) {
+ bullet.setPosition(isHSLF ? x+indent : x+leftMargin+indent, penY);
bullet.draw(graphics);
// don't let text overlay the bullet and advance by the bullet width
double bulletWidth = bullet.getLayout().getAdvance() + 1;
- penX = x + Math.max(leftMargin, leftMargin+indent+bulletWidth);
- } else {
- penX = x + leftMargin;
+ penX = x + (isHSLF ? leftMargin : Math.max(leftMargin, leftMargin+indent+bulletWidth));
}
- } else {
- penX = x + leftMargin;
}
Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape());
@@ -207,16 +215,9 @@ public class DrawTextParagraph implements Drawable {
line.setPosition(penX, penY);
line.draw(graphics);
+ penY += line.getHeight();
- if(spacing > 0) {
- // If linespacing >= 0, then linespacing is a percentage of normal line height.
- penY += spacing*0.01* line.getHeight();
- } else {
- // negative value means absolute spacing in points
- penY += -spacing;
- }
-
- firstLine = false;
+ lastLine = line;
}
y = penY - y;
@@ -257,7 +258,6 @@ public class DrawTextParagraph implements Drawable {
DrawFactory fact = DrawFactory.getInstance(graphics);
StringBuilder text = new StringBuilder();
AttributedString at = getAttributedString(graphics, text);
- boolean emptyParagraph = text.toString().trim().isEmpty();
AttributedCharacterIterator it = at.getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext());
@@ -271,42 +271,47 @@ public class DrawTextParagraph implements Drawable {
wrappingWidth = 1;
}
- int nextBreak = text.indexOf("\n", startIndex + 1);
- if (nextBreak == -1) {
- nextBreak = it.getEndIndex();
- }
+ // usually "\n" is added after a line, if it occurs before it - only possible as first char -
+ // we need to add an empty line
+ TextLayout layout;
+ int endIndex;
+ if (startIndex == 0 && text.toString().startsWith("\n")) {
+ layout = measurer.nextLayout((float) wrappingWidth, 1, false);
+ endIndex = 1;
+ } else {
+ int nextBreak = text.indexOf("\n", startIndex + 1);
+ if (nextBreak == -1) {
+ nextBreak = it.getEndIndex();
+ }
- TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);
- if (layout == null) {
- // layout can be null if the entire word at the current position
- // does not fit within the wrapping width. Try with requireNextWord=false.
- layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false);
- }
+ layout = measurer.nextLayout((float) wrappingWidth, nextBreak, true);
+ if (layout == null) {
+ // layout can be null if the entire word at the current position
+ // does not fit within the wrapping width. Try with requireNextWord=false.
+ layout = measurer.nextLayout((float) wrappingWidth, nextBreak, false);
+ }
- if(layout == null) {
- // exit if can't break any more
- break;
- }
+ if (layout == null) {
+ // exit if can't break any more
+ break;
+ }
- int endIndex = measurer.getPosition();
- // skip over new line breaks (we paint 'clear' text runs not starting or ending with \n)
- if(endIndex < it.getEndIndex() && text.charAt(endIndex) == '\n'){
- measurer.setPosition(endIndex + 1);
- }
+ endIndex = measurer.getPosition();
+ // skip over new line breaks (we paint 'clear' text runs not starting or ending with \n)
+ if (endIndex < it.getEndIndex() && text.charAt(endIndex) == '\n') {
+ measurer.setPosition(endIndex + 1);
+ }
- TextAlign hAlign = paragraph.getTextAlign();
- if(hAlign == TextAlign.JUSTIFY || hAlign == TextAlign.JUSTIFY_LOW) {
- layout = layout.getJustifiedLayout((float)wrappingWidth);
+ TextAlign hAlign = paragraph.getTextAlign();
+ if (hAlign == TextAlign.JUSTIFY || hAlign == TextAlign.JUSTIFY_LOW) {
+ layout = layout.getJustifiedLayout((float) wrappingWidth);
+ }
}
- AttributedString str = (emptyParagraph)
- ? null // we will not paint empty paragraphs
- : new AttributedString(it, startIndex, endIndex);
+ AttributedString str = new AttributedString(it, startIndex, endIndex);
DrawTextFragment line = fact.getTextFragment(layout, str);
lines.add(line);
- maxLineHeight = Math.max(maxLineHeight, line.getHeight());
-
if(endIndex == it.getEndIndex()) {
break;
}
@@ -450,6 +455,7 @@ public class DrawTextParagraph implements Drawable {
* @return wrapping width in points
*/
protected double getWrappingWidth(boolean firstLine, Graphics2D graphics){
+ final long TAB_SIZE = 347663L;
TextShape<?,?> ts = paragraph.getParentShape();
// internal margins for the text box
@@ -465,11 +471,11 @@ public class DrawTextParagraph implements Drawable {
Double leftMargin = paragraph.getLeftMargin();
if (leftMargin == null) {
// if the marL attribute is omitted, then a value of 347663 is implied
- leftMargin = Units.toPoints(347663L*(indentLevel+1));
+ leftMargin = Units.toPoints(TAB_SIZE * indentLevel);
}
Double indent = paragraph.getIndent();
if (indent == null) {
- indent = Units.toPoints(347663L*indentLevel);
+ indent = 0.;
}
Double rightMargin = paragraph.getRightMargin();
if (rightMargin == null) {
@@ -503,18 +509,9 @@ public class DrawTextParagraph implements Drawable {
width = anchor.getHeight() - leftInset - rightInset - leftMargin - rightMargin;
break;
}
- if (firstLine && !isHSLF()) {
- if (bullet != null){
- if (indent > 0) {
- width -= indent;
- }
- } else {
- if (indent > 0) {
- width -= indent; // first line indentation
- } else if (indent < 0) { // hanging indentation: the first line start at the left margin
- width += leftMargin;
- }
- }
+ if (firstLine && bullet == null) {
+ // indent is usually negative in XSLF
+ width += isHSLF() ? (leftMargin - indent) : -indent;
}
}
@@ -727,4 +724,12 @@ public class DrawTextParagraph implements Drawable {
protected boolean isHSLF() {
return DrawShape.isHSLF(paragraph.getParentShape());
}
+
+ protected boolean isFirstParagraph() {
+ return firstParagraph;
+ }
+
+ protected void setFirstParagraph(boolean firstParagraph) {
+ this.firstParagraph = firstParagraph;
+ }
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java
index c4dd65bb75..d8d23b5676 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTextShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTextShape.java
@@ -41,7 +41,7 @@ public class DrawTextShape extends DrawSimpleShape {
@Override
public void drawContent(Graphics2D graphics) {
TextShape<?,?> s = getShape();
-
+
Rectangle2D anchor = DrawShape.getAnchor(graphics, s);
if(anchor == null) {
return;
@@ -53,7 +53,7 @@ public class DrawTextShape extends DrawSimpleShape {
// remember the initial transform
AffineTransform tx = graphics.getTransform();
-
+
// Transform of text in flipped shapes is special.
// At this point the flip and rotation transform is already applied
// (see DrawShape#applyTransform ), but we need to restore it to avoid painting "upside down".
@@ -68,7 +68,7 @@ public class DrawTextShape extends DrawSimpleShape {
horzFlip ^= ps.getFlipHorizontal();
sc = ps.getParent();
}
-
+
// Horizontal flipping applies only to shape outline and not to the text in the shape.
// Applying flip second time restores the original not-flipped transform
if (horzFlip ^ vertFlip) {
@@ -87,7 +87,7 @@ public class DrawTextShape extends DrawSimpleShape {
graphics.rotate(Math.toRadians(textRot));
graphics.translate(-cx, -cy);
}
-
+
// first dry-run to calculate the total height of the text
double textHeight;
@@ -115,7 +115,7 @@ public class DrawTextShape extends DrawSimpleShape {
graphics.translate(cx, cy);
graphics.rotate(Math.toRadians(deg));
graphics.translate(-cx, -cy);
-
+
// old top/left edge is now bottom/left or top/right - as we operate on the already
// rotated drawing context, both verticals can be moved in the same direction
final double w = anchor.getWidth();
@@ -140,7 +140,7 @@ public class DrawTextShape extends DrawSimpleShape {
double y0 = y;
Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs = getShape().iterator();
-
+
boolean isFirstLine = true;
for (int autoNbrIdx=0; paragraphs.hasNext(); autoNbrIdx++){
TextParagraph<?,?,? extends TextRun> p = paragraphs.next();
@@ -172,9 +172,11 @@ public class DrawTextShape extends DrawSimpleShape {
y += -spaceBefore;
}
}
- isFirstLine = false;
-
+
dp.setPosition(x, y);
+ dp.setFirstParagraph(isFirstLine);
+ isFirstLine = false;
+
dp.draw(graphics);
y += dp.getY();
@@ -196,13 +198,13 @@ public class DrawTextShape extends DrawSimpleShape {
/**
* Compute the cumulative height occupied by the text
- *
+ *
* @return the height in points
*/
public double getTextHeight() {
return getTextHeight(null);
}
-
+
/**
* Compute the cumulative height occupied by the text
*