fix table font handling with base font's notorious illegal argument exception, fix other table font bugs

This commit is contained in:
Jörg Prante 2023-08-28 17:55:45 +02:00
parent b62aacfe59
commit 1df6a1ea16
10 changed files with 107 additions and 17 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib.graphics
name = graphics
version = 4.5.6
version = 4.5.7
org.gradle.warning.mode = ALL

View file

@ -236,6 +236,10 @@ public class Document implements Element, Closeable, RenderListener {
return false;
}
}
public String toString() {
return name;
}
});
}

View file

@ -40,7 +40,7 @@ public abstract class AbstractTextCell extends AbstractCell {
if (this.textHeight != null) {
return this.textHeight;
}
this.textHeight = PdfUtil.getFontHeight(getText(), getFontDescriptor());
this.textHeight = PdfUtil.getFontHeight(getFontDescriptor());
if (parameters.isWordBreak()) {
final int size = PdfUtil.getOptimalTextBreakLines(getText(), getFontDescriptor(), getMaxWidth()).size();
final float heightOfTextLines = size * this.textHeight;

View file

@ -13,6 +13,9 @@ public abstract class AbstractCellRenderer<T extends Cell> implements Renderer {
protected T cell;
public AbstractCellRenderer() {
}
public AbstractCellRenderer<T> withCell(T cell) {
this.cell = cell;
return this;

View file

@ -30,7 +30,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
final List<String> lines = calculateAndGetLines(fontDescriptor, cell.getMaxWidth());
for (int i = 0; i < lines.size(); i++) {
final String line = lines.get(i);
yOffset -= calculateYOffset(line, fontDescriptor, i);
yOffset -= calculateYOffset(fontDescriptor, i);
final float textWidth = PdfUtil.getStringWidth(line, fontDescriptor);
if (cell.isHorizontallyAligned(RIGHT)) {
xOffset = startX + (cell.getWidth() - (textWidth + cell.getPaddingRight()));
@ -54,9 +54,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return cell.getTextHeight();
}
private float calculateYOffset(String text, FontDescriptor fontDescriptor, int lineIndex) {
return PdfUtil.getFontHeight(text, fontDescriptor) +
(lineIndex > 0 ? PdfUtil.getFontHeight(text, fontDescriptor) * cell.getLineSpacing() : 0f);
private float calculateYOffset(FontDescriptor fontDescriptor, int lineIndex) {
return PdfUtil.getFontHeight(fontDescriptor) +
(lineIndex > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f);
}
private static boolean isNotLastLine(List<String> lines, int i) {

View file

@ -43,7 +43,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
float xOffset = startX + cell.getPaddingLeft(); /* - PdfUtil.getFontHeight(currentFont, currentFontSize)*/;
for (int i = 0; i < lines.size(); i++) {
final String line = lines.get(i);
xOffset += (PdfUtil.getFontHeight(line, fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(line, fontDescriptor) * cell.getLineSpacing() : 0f));
xOffset += (PdfUtil.getFontHeight(fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f));
drawText(line, fontDescriptor, currentTextColor, xOffset, yOffset, tableRenderContext.getContentStream());
}
}

View file

@ -61,6 +61,9 @@ public final class PdfUtil {
}
found = true;
}
if (found) {
break;
}
}
if (!found) {
throw new IllegalArgumentException("unable to get width of string " + codepoint);
@ -75,13 +78,11 @@ public final class PdfUtil {
* @param fontDescriptor font
* @return height of font
*/
public static float getFontHeight(String text, FontDescriptor fontDescriptor) {
public static float getFontHeight(FontDescriptor fontDescriptor) {
for (Font font : fontDescriptor.getFonts()) {
if (font.canWrite(text)) {
return font.getRegularFont().getFontDescriptor().getCapHeight() * fontDescriptor.getSize() / 1000F;
}
return font.getRegularFont().getFontDescriptor().getCapHeight() * fontDescriptor.getSize() / 1000F;
}
throw new IllegalArgumentException("unable to get font height for text " + text + ", fonts = " + fontDescriptor.getFonts());
throw new IllegalArgumentException("unable to get font height, fonts = " + fontDescriptor.getFonts());
}
/**

View file

@ -10,26 +10,40 @@ import org.xbib.graphics.pdfbox.layout.table.render.PositionedStyledText;
import java.awt.Color;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RenderUtil {
private static final Logger logger = Logger.getLogger(RenderUtil.class.getName());
private RenderUtil() {
}
public static void drawText(PDPageContentStream contentStream, PositionedStyledText styledText) {
for (Font font : styledText.getFontDescriptor().getFonts()) {
boolean isBeginText = false;
if (font.canWrite(styledText.getText())) {
try {
contentStream.beginText();
isBeginText = true;
contentStream.setNonStrokingColor(styledText.getColor());
// TODO select correct font style
contentStream.setFont(font.getRegularFont(), styledText.getFontDescriptor().getSize());
contentStream.newLineAtOffset(styledText.getX(), styledText.getY());
contentStream.showText(styledText.getText());
contentStream.endText();
isBeginText = false;
contentStream.setCharacterSpacing(0);
} catch (IOException e) {
throw new UncheckedIOException(e);
break;
} catch (IllegalArgumentException | IOException e) {
logger.log(Level.WARNING, e.getMessage());
if (isBeginText) {
try {
contentStream.endText();
} catch (IOException ex) {
// ignore
}
}
}
}
}

View file

@ -112,7 +112,7 @@ public class TableTest {
.add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build())
.build())
.build();
final float actualFontHeight = PdfUtil.getFontHeight("test", table.getSettings().getFontDescriptor());
final float actualFontHeight = PdfUtil.getFontHeight(table.getSettings().getFontDescriptor());
assertThat(table.getHeight(), equalTo(50 + actualFontHeight));
}

View file

@ -3,7 +3,7 @@
"margin": "0 0 0 0",
"author": "Jörg Prante",
"font": [
"helvetica"
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"elements": [
{
@ -147,6 +147,74 @@
]
}
]
},
{
"type": "table",
"padding": "10 10 10 10",
"columnwidths": "40 150",
"elements": [
{
"type": "row",
"elements": [
{
"type": "cell",
"text": "Demotext",
"font": [
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"fontsize": 11
},
{
"type": "cell",
"text": "This is a demo text This is a demo text This is a demo text This is a demo text This is a demo text This is a demo text",
"font": [
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"fontsize": 11
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"text": "Demotext",
"font": [
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"fontsize": 11
},
{
"type": "cell",
"text": "Short text",
"font": [
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"fontsize": 11
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"text": "Demotext",
"font": "helvetica",
"fontsize": 11
},
{
"type": "cell",
"text": "Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text ",
"font": [
"helvetica", "sourcesans", "notosans", "notosanscjksc"
],
"fontsize": 11
}
]
}
]
}
]
}