catch IllegalArgumentException in StyledText when font is selected

This commit is contained in:
Jörg Prante 2023-08-31 17:57:34 +02:00
parent 1df6a1ea16
commit 0162464b0f
18 changed files with 98 additions and 37 deletions

View file

@ -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

View file

@ -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;

View file

@ -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")) {

View file

@ -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));
} }
} }

View file

@ -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");

View file

@ -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();

View file

@ -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;
} }

View file

@ -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;

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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));

View file

@ -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;
} }
} }

View file

@ -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();
} }

View file

@ -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);

View file

@ -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
}
} }
} }

View file

@ -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;
}
} }
/** /**

View file

@ -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>.
*/ */

View file

@ -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));
} }
} }
} }