catch IllegalArgumentException in StyledText when font is selected
This commit is contained in:
parent
1df6a1ea16
commit
0162464b0f
18 changed files with 98 additions and 37 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib.graphics
|
group = org.xbib.graphics
|
||||||
name = graphics
|
name = graphics
|
||||||
version = 4.5.7
|
version = 4.5.8
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -22,6 +22,9 @@ public class Paragraph extends TextFlow implements Drawable, Element, WidthRespe
|
||||||
|
|
||||||
private Alignment alignment = Alignment.LEFT;
|
private Alignment alignment = Alignment.LEFT;
|
||||||
|
|
||||||
|
public Paragraph() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position getAbsolutePosition() {
|
public Position getAbsolutePosition() {
|
||||||
return absolutePosition;
|
return absolutePosition;
|
||||||
|
|
|
@ -28,6 +28,9 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
|
||||||
|
|
||||||
public class CellCommand implements Command {
|
public class CellCommand implements Command {
|
||||||
|
|
||||||
|
public CellCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
||||||
if (settings.containsSetting("text")) {
|
if (settings.containsSetting("text")) {
|
||||||
|
|
|
@ -13,12 +13,14 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
|
||||||
|
|
||||||
public class IndentCommand implements Command {
|
public class IndentCommand implements Command {
|
||||||
|
|
||||||
|
public IndentCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
||||||
float value = settings.getAsFloat("value", 0.0f);
|
float value = settings.getAsFloat("value", 0.0f);
|
||||||
Element element = state.getElements().peek();
|
Element element = state.getElements().peek();
|
||||||
if (element instanceof Paragraph) {
|
if (element instanceof Paragraph paragraph) {
|
||||||
Paragraph paragraph = (Paragraph) element;
|
|
||||||
paragraph.add(new Indent(mmToPt(value), SpaceUnit.pt));
|
paragraph.add(new Indent(mmToPt(value), SpaceUnit.pt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
|
||||||
|
|
||||||
public class MarkupCommand implements Command {
|
public class MarkupCommand implements Command {
|
||||||
|
|
||||||
|
public MarkupCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Engine engine, State state, Settings settings) {
|
public void execute(Engine engine, State state, Settings settings) {
|
||||||
String text = settings.get("text");
|
String text = settings.get("text");
|
||||||
|
|
|
@ -15,6 +15,9 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
|
||||||
|
|
||||||
public class ParagraphCommand implements Command {
|
public class ParagraphCommand implements Command {
|
||||||
|
|
||||||
|
public ParagraphCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
public void execute(Engine engine, State state, Settings settings) throws IOException {
|
||||||
Paragraph paragraph = new Paragraph();
|
Paragraph paragraph = new Paragraph();
|
||||||
|
|
|
@ -20,6 +20,9 @@ public class Hyperlink implements ParagraphProcessor {
|
||||||
|
|
||||||
private float baselineOffset = 1f;
|
private float baselineOffset = 1f;
|
||||||
|
|
||||||
|
public Hyperlink() {
|
||||||
|
}
|
||||||
|
|
||||||
public void setFontDescriptor(FontDescriptor fontDescriptor) {
|
public void setFontDescriptor(FontDescriptor fontDescriptor) {
|
||||||
this.fontDescriptor = fontDescriptor;
|
this.fontDescriptor = fontDescriptor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ public class Markup implements ParagraphProcessor {
|
||||||
|
|
||||||
private FontDescriptor fontDescriptor;
|
private FontDescriptor fontDescriptor;
|
||||||
|
|
||||||
|
public Markup() {
|
||||||
|
}
|
||||||
|
|
||||||
public Markup setValue(String value) {
|
public Markup setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -15,6 +15,9 @@ public class ParagraphCell extends AbstractCell {
|
||||||
|
|
||||||
private CellParagraph cellParagraph;
|
private CellParagraph cellParagraph;
|
||||||
|
|
||||||
|
public ParagraphCell() {
|
||||||
|
}
|
||||||
|
|
||||||
public void setLineSpacing(float lineSpacing) {
|
public void setLineSpacing(float lineSpacing) {
|
||||||
this.lineSpacing = lineSpacing;
|
this.lineSpacing = lineSpacing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ public class StyledText implements ParagraphProcessor {
|
||||||
|
|
||||||
private Color color;
|
private Color color;
|
||||||
|
|
||||||
|
public StyledText() {
|
||||||
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setText(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
|
||||||
final List<String> lines = cell.isWordBreak()
|
final List<String> lines = cell.isWordBreak()
|
||||||
? PdfUtil.getOptimalTextBreakLines(cell.getText(), fontDescriptor, (height - cell.getVerticalPadding()))
|
? PdfUtil.getOptimalTextBreakLines(cell.getText(), fontDescriptor, (height - cell.getVerticalPadding()))
|
||||||
: Collections.singletonList(cell.getText());
|
: Collections.singletonList(cell.getText());
|
||||||
float xOffset = startX + cell.getPaddingLeft(); /* - PdfUtil.getFontHeight(currentFont, currentFontSize)*/;
|
float xOffset = startX + cell.getPaddingLeft() - PdfUtil.getFontHeight(fontDescriptor);
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
final String line = lines.get(i);
|
final String line = lines.get(i);
|
||||||
xOffset += (PdfUtil.getFontHeight(fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f));
|
xOffset += (PdfUtil.getFontHeight(fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f));
|
||||||
|
|
|
@ -188,7 +188,7 @@ public class StyledText implements TextFragment {
|
||||||
try {
|
try {
|
||||||
return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(text).getStringWidth(text) / 1000;
|
return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(text).getStringWidth(text) / 1000;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.WARNING, e.getMessage(), e);
|
logger.log(Level.WARNING, "text = " + text + " " + e.getMessage(), e);
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ public class TextFlow implements TextSequence, WidthRespecting {
|
||||||
|
|
||||||
private boolean applyLineSpacingToFirstLine = true;
|
private boolean applyLineSpacingToFirstLine = true;
|
||||||
|
|
||||||
|
public TextFlow() {
|
||||||
|
}
|
||||||
|
|
||||||
private void clearCache() {
|
private void clearCache() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@ import java.util.regex.Matcher;
|
||||||
|
|
||||||
public class TextFlowUtil {
|
public class TextFlowUtil {
|
||||||
|
|
||||||
|
private TextFlowUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
public static TextFlow createTextFlow(String text, FontDescriptor descriptor,
|
public static TextFlow createTextFlow(String text, FontDescriptor descriptor,
|
||||||
float linespacing, float rotation) {
|
float linespacing, float rotation) {
|
||||||
return createTextFlow(fromPlainText(text), descriptor, linespacing, rotation);
|
return createTextFlow(fromPlainText(text), descriptor, linespacing, rotation);
|
||||||
|
|
|
@ -8,13 +8,14 @@ import org.xbib.graphics.pdfbox.layout.position.Position;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text of line containing only {@link StyledText}s. It may be terminated by a
|
* A text of line containing only {@link StyledText}s. It may be terminated by a
|
||||||
|
@ -22,6 +23,8 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class TextLine implements TextSequence {
|
public class TextLine implements TextSequence {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(TextLine.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The font ascent.
|
* The font ascent.
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +44,9 @@ public class TextLine implements TextSequence {
|
||||||
|
|
||||||
private final Map<String, Object> cache = new HashMap<>();
|
private final Map<String, Object> cache = new HashMap<>();
|
||||||
|
|
||||||
|
public TextLine() {
|
||||||
|
}
|
||||||
|
|
||||||
private void clearCache() {
|
private void clearCache() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
@ -170,6 +176,7 @@ public class TextLine implements TextSequence {
|
||||||
Alignment alignment,
|
Alignment alignment,
|
||||||
float availableLineWidth,
|
float availableLineWidth,
|
||||||
DrawListener drawListener) {
|
DrawListener drawListener) {
|
||||||
|
boolean beginText = false;
|
||||||
try {
|
try {
|
||||||
contentStream.saveGraphicsState();
|
contentStream.saveGraphicsState();
|
||||||
float x = upperLeft.getX();
|
float x = upperLeft.getX();
|
||||||
|
@ -205,17 +212,17 @@ public class TextLine implements TextSequence {
|
||||||
}
|
}
|
||||||
if (!styledText.getText().isEmpty()) {
|
if (!styledText.getText().isEmpty()) {
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
|
beginText = true;
|
||||||
contentStream.setTextMatrix(matrix);
|
contentStream.setTextMatrix(matrix);
|
||||||
if (!styledText.getFontDescriptor().equals(lastFontDesc)) {
|
lastFontDesc = styledText.getFontDescriptor();
|
||||||
lastFontDesc = styledText.getFontDescriptor();
|
contentStream.setFont(lastFontDesc.getSelectedFont(styledText.getText()), lastFontDesc.getSize());
|
||||||
contentStream.setFont(lastFontDesc.getSelectedFont(styledText.getText()), lastFontDesc.getSize());
|
|
||||||
}
|
|
||||||
if (!styledText.getColor().equals(lastColor)) {
|
if (!styledText.getColor().equals(lastColor)) {
|
||||||
lastColor = styledText.getColor();
|
lastColor = styledText.getColor();
|
||||||
contentStream.setNonStrokingColor(lastColor);
|
contentStream.setNonStrokingColor(lastColor);
|
||||||
}
|
}
|
||||||
contentStream.showText(styledText.getText());
|
contentStream.showText(styledText.getText());
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
|
beginText = false;
|
||||||
}
|
}
|
||||||
if (drawListener != null) {
|
if (drawListener != null) {
|
||||||
drawListener.drawn(styledText,
|
drawListener.drawn(styledText,
|
||||||
|
@ -230,8 +237,20 @@ public class TextLine implements TextSequence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentStream.restoreGraphicsState();
|
contentStream.restoreGraphicsState();
|
||||||
} catch (IOException e) {
|
} catch (IllegalArgumentException | IOException e) {
|
||||||
throw new UncheckedIOException(e);
|
logger.log(Level.WARNING, e.getMessage(), e);
|
||||||
|
if (beginText) {
|
||||||
|
try {
|
||||||
|
contentStream.endText();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
contentStream.restoreGraphicsState();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class TextSequenceUtil {
|
public class TextSequenceUtil {
|
||||||
|
|
||||||
|
private TextSequenceUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dissects the given sequence into {@link TextLine}s.
|
* Dissects the given sequence into {@link TextLine}s.
|
||||||
*
|
*
|
||||||
|
@ -419,14 +422,11 @@ public class TextSequenceUtil {
|
||||||
*/
|
*/
|
||||||
public static float getOffset(final TextSequence textLine,
|
public static float getOffset(final TextSequence textLine,
|
||||||
final float targetWidth, final Alignment alignment) {
|
final float targetWidth, final Alignment alignment) {
|
||||||
switch (alignment) {
|
return switch (alignment) {
|
||||||
case RIGHT:
|
case RIGHT -> targetWidth - textLine.getWidth();
|
||||||
return targetWidth - textLine.getWidth();
|
case CENTER -> (targetWidth - textLine.getWidth()) / 2f;
|
||||||
case CENTER:
|
default -> 0;
|
||||||
return (targetWidth - textLine.getWidth()) / 2f;
|
};
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,9 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class WordBreakerFactory {
|
public class WordBreakerFactory {
|
||||||
|
|
||||||
|
private WordBreakerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constant for the system property <code>pdfbox.layout.word.breaker</code>.
|
* constant for the system property <code>pdfbox.layout.word.breaker</code>.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,18 +11,24 @@ import java.util.regex.Pattern;
|
||||||
*/
|
*/
|
||||||
public class WordBreakers {
|
public class WordBreakers {
|
||||||
|
|
||||||
|
private WordBreakers() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* May by used for legacy compatibility, does not break at all.
|
* May by used for legacy compatibility, does not break at all.
|
||||||
*/
|
*/
|
||||||
public static class NonBreakingWordBreaker implements WordBreaker {
|
public static class NonBreakingWordBreaker implements WordBreaker {
|
||||||
|
|
||||||
|
public NonBreakingWordBreaker() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String> breakWord(String word,
|
public Pair<String> breakWord(String word,
|
||||||
FontDescriptor fontDescriptor, float maxWidth,
|
FontDescriptor fontDescriptor,
|
||||||
|
float maxWidth,
|
||||||
boolean breakHardIfNecessary) {
|
boolean breakHardIfNecessary) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,10 +39,14 @@ public class WordBreakers {
|
||||||
*/
|
*/
|
||||||
public static abstract class AbstractWordBreaker implements WordBreaker {
|
public static abstract class AbstractWordBreaker implements WordBreaker {
|
||||||
|
|
||||||
|
public AbstractWordBreaker() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String> breakWord(final String word,
|
public Pair<String> breakWord(String word,
|
||||||
final FontDescriptor fontDescriptor, final float maxWidth,
|
FontDescriptor fontDescriptor,
|
||||||
final boolean breakHardIfNecessary) {
|
float maxWidth,
|
||||||
|
boolean breakHardIfNecessary) {
|
||||||
|
|
||||||
Pair<String> brokenWord = breakWordSoft(word, fontDescriptor,
|
Pair<String> brokenWord = breakWordSoft(word, fontDescriptor,
|
||||||
maxWidth);
|
maxWidth);
|
||||||
|
@ -87,11 +97,8 @@ public class WordBreakers {
|
||||||
}
|
}
|
||||||
--cutIndex;
|
--cutIndex;
|
||||||
}
|
}
|
||||||
|
return new Pair<>(word.substring(0, cutIndex), word.substring(cutIndex));
|
||||||
return new Pair<String>(word.substring(0, cutIndex),
|
|
||||||
word.substring(cutIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,12 +117,16 @@ public class WordBreakers {
|
||||||
* A letter followed by either <code>-</code>, <code>.</code>,
|
* A letter followed by either <code>-</code>, <code>.</code>,
|
||||||
* <code>,</code> or <code>/</code>.
|
* <code>,</code> or <code>/</code>.
|
||||||
*/
|
*/
|
||||||
private final Pattern breakPattern =
|
private static final Pattern breakPattern =
|
||||||
Pattern.compile("[A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]([\\-\\.\\,/])");
|
Pattern.compile("[A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]([\\-\\.\\,/])");
|
||||||
|
|
||||||
|
public DefaultWordBreaker() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Pair<String> breakWordSoft(final String word,
|
protected Pair<String> breakWordSoft(String word,
|
||||||
final FontDescriptor fontDescriptor, final float maxWidth) {
|
FontDescriptor fontDescriptor,
|
||||||
|
float maxWidth) {
|
||||||
Matcher matcher = breakPattern.matcher(word);
|
Matcher matcher = breakPattern.matcher(word);
|
||||||
int breakIndex = -1;
|
int breakIndex = -1;
|
||||||
boolean maxWidthExceeded = false;
|
boolean maxWidthExceeded = false;
|
||||||
|
@ -130,14 +141,10 @@ public class WordBreakers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakIndex < 0) {
|
if (breakIndex < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new Pair<>(word.substring(0, breakIndex),
|
return new Pair<>(word.substring(0, breakIndex), word.substring(breakIndex));
|
||||||
word.substring(breakIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue