diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2020-06-04 23:17:44 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2020-06-04 23:17:44 +0000 |
commit | 5a18307eb051603509c8b8147f4dfdf0e8fe56b2 (patch) | |
tree | 70a5e2c1ff908c4a98a614b92f5992c8c2891060 /src/java/org/apache/poi/sl/draw | |
parent | 84330c6aa3a96fff4bbd5593b7173209187ec474 (diff) | |
download | poi-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')
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 * |