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
name = graphics
version = 4.5.7
version = 4.5.8
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;
public Paragraph() {
}
@Override
public Position getAbsolutePosition() {
return absolutePosition;

View file

@ -28,6 +28,9 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class CellCommand implements Command {
public CellCommand() {
}
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
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 IndentCommand() {
}
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
float value = settings.getAsFloat("value", 0.0f);
Element element = state.getElements().peek();
if (element instanceof Paragraph) {
Paragraph paragraph = (Paragraph) element;
if (element instanceof Paragraph paragraph) {
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 MarkupCommand() {
}
@Override
public void execute(Engine engine, State state, Settings settings) {
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 ParagraphCommand() {
}
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Paragraph paragraph = new Paragraph();

View file

@ -20,6 +20,9 @@ public class Hyperlink implements ParagraphProcessor {
private float baselineOffset = 1f;
public Hyperlink() {
}
public void setFontDescriptor(FontDescriptor fontDescriptor) {
this.fontDescriptor = fontDescriptor;
}

View file

@ -9,6 +9,9 @@ public class Markup implements ParagraphProcessor {
private FontDescriptor fontDescriptor;
public Markup() {
}
public Markup setValue(String value) {
this.value = value;
return this;

View file

@ -15,6 +15,9 @@ public class ParagraphCell extends AbstractCell {
private CellParagraph cellParagraph;
public ParagraphCell() {
}
public void setLineSpacing(float lineSpacing) {
this.lineSpacing = lineSpacing;
}

View file

@ -14,6 +14,9 @@ public class StyledText implements ParagraphProcessor {
private Color color;
public StyledText() {
}
public void setText(String text) {
this.text = text;
}

View file

@ -40,7 +40,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
final List<String> lines = cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), fontDescriptor, (height - cell.getVerticalPadding()))
: 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++) {
final String line = lines.get(i);
xOffset += (PdfUtil.getFontHeight(fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f));

View file

@ -188,7 +188,7 @@ public class StyledText implements TextFragment {
try {
return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(text).getStringWidth(text) / 1000;
} catch (Exception e) {
logger.log(Level.WARNING, e.getMessage(), e);
logger.log(Level.WARNING, "text = " + text + " " + e.getMessage(), e);
return 0f;
}
}

View file

@ -60,6 +60,9 @@ public class TextFlow implements TextSequence, WidthRespecting {
private boolean applyLineSpacingToFirstLine = true;
public TextFlow() {
}
private void clearCache() {
cache.clear();
}

View file

@ -15,6 +15,9 @@ import java.util.regex.Matcher;
public class TextFlowUtil {
private TextFlowUtil() {
}
public static TextFlow createTextFlow(String text, FontDescriptor descriptor,
float linespacing, float 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.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
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
@ -22,6 +23,8 @@ import java.util.Map;
*/
public class TextLine implements TextSequence {
private static final Logger logger = Logger.getLogger(TextLine.class.getName());
/**
* The font ascent.
*/
@ -41,6 +44,9 @@ public class TextLine implements TextSequence {
private final Map<String, Object> cache = new HashMap<>();
public TextLine() {
}
private void clearCache() {
cache.clear();
}
@ -170,6 +176,7 @@ public class TextLine implements TextSequence {
Alignment alignment,
float availableLineWidth,
DrawListener drawListener) {
boolean beginText = false;
try {
contentStream.saveGraphicsState();
float x = upperLeft.getX();
@ -205,17 +212,17 @@ public class TextLine implements TextSequence {
}
if (!styledText.getText().isEmpty()) {
contentStream.beginText();
beginText = true;
contentStream.setTextMatrix(matrix);
if (!styledText.getFontDescriptor().equals(lastFontDesc)) {
lastFontDesc = styledText.getFontDescriptor();
contentStream.setFont(lastFontDesc.getSelectedFont(styledText.getText()), lastFontDesc.getSize());
}
lastFontDesc = styledText.getFontDescriptor();
contentStream.setFont(lastFontDesc.getSelectedFont(styledText.getText()), lastFontDesc.getSize());
if (!styledText.getColor().equals(lastColor)) {
lastColor = styledText.getColor();
contentStream.setNonStrokingColor(lastColor);
}
contentStream.showText(styledText.getText());
contentStream.endText();
beginText = false;
}
if (drawListener != null) {
drawListener.drawn(styledText,
@ -230,8 +237,20 @@ public class TextLine implements TextSequence {
}
}
contentStream.restoreGraphicsState();
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (IllegalArgumentException | IOException 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 {
private TextSequenceUtil() {
}
/**
* Dissects the given sequence into {@link TextLine}s.
*
@ -419,14 +422,11 @@ public class TextSequenceUtil {
*/
public static float getOffset(final TextSequence textLine,
final float targetWidth, final Alignment alignment) {
switch (alignment) {
case RIGHT:
return targetWidth - textLine.getWidth();
case CENTER:
return (targetWidth - textLine.getWidth()) / 2f;
default:
return 0;
}
return switch (alignment) {
case RIGHT -> targetWidth - textLine.getWidth();
case CENTER -> (targetWidth - textLine.getWidth()) / 2f;
default -> 0;
};
}
/**

View file

@ -16,6 +16,9 @@ import java.util.Map;
*/
public class WordBreakerFactory {
private WordBreakerFactory() {
}
/**
* 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 {
private WordBreakers() {
}
/**
* May by used for legacy compatibility, does not break at all.
*/
public static class NonBreakingWordBreaker implements WordBreaker {
public NonBreakingWordBreaker() {
}
@Override
public Pair<String> breakWord(String word,
FontDescriptor fontDescriptor, float maxWidth,
FontDescriptor fontDescriptor,
float maxWidth,
boolean breakHardIfNecessary) {
return null;
}
}
/**
@ -33,10 +39,14 @@ public class WordBreakers {
*/
public static abstract class AbstractWordBreaker implements WordBreaker {
public AbstractWordBreaker() {
}
@Override
public Pair<String> breakWord(final String word,
final FontDescriptor fontDescriptor, final float maxWidth,
final boolean breakHardIfNecessary) {
public Pair<String> breakWord(String word,
FontDescriptor fontDescriptor,
float maxWidth,
boolean breakHardIfNecessary) {
Pair<String> brokenWord = breakWordSoft(word, fontDescriptor,
maxWidth);
@ -87,11 +97,8 @@ public class WordBreakers {
}
--cutIndex;
}
return new Pair<String>(word.substring(0, cutIndex),
word.substring(cutIndex));
return new Pair<>(word.substring(0, cutIndex), word.substring(cutIndex));
}
}
/**
@ -110,12 +117,16 @@ public class WordBreakers {
* A letter followed by either <code>-</code>, <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]([\\-\\.\\,/])");
public DefaultWordBreaker() {
}
@Override
protected Pair<String> breakWordSoft(final String word,
final FontDescriptor fontDescriptor, final float maxWidth) {
protected Pair<String> breakWordSoft(String word,
FontDescriptor fontDescriptor,
float maxWidth) {
Matcher matcher = breakPattern.matcher(word);
int breakIndex = -1;
boolean maxWidthExceeded = false;
@ -130,14 +141,10 @@ public class WordBreakers {
}
}
}
if (breakIndex < 0) {
return null;
}
return new Pair<>(word.substring(0, breakIndex),
word.substring(breakIndex));
return new Pair<>(word.substring(0, breakIndex), word.substring(breakIndex));
}
}
}