fix table font handling with base font's notorious illegal argument exception, fix other table font bugs
This commit is contained in:
parent
b62aacfe59
commit
1df6a1ea16
10 changed files with 107 additions and 17 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib.graphics
|
group = org.xbib.graphics
|
||||||
name = graphics
|
name = graphics
|
||||||
version = 4.5.6
|
version = 4.5.7
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -236,6 +236,10 @@ public class Document implements Element, Closeable, RenderListener {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public abstract class AbstractTextCell extends AbstractCell {
|
||||||
if (this.textHeight != null) {
|
if (this.textHeight != null) {
|
||||||
return this.textHeight;
|
return this.textHeight;
|
||||||
}
|
}
|
||||||
this.textHeight = PdfUtil.getFontHeight(getText(), getFontDescriptor());
|
this.textHeight = PdfUtil.getFontHeight(getFontDescriptor());
|
||||||
if (parameters.isWordBreak()) {
|
if (parameters.isWordBreak()) {
|
||||||
final int size = PdfUtil.getOptimalTextBreakLines(getText(), getFontDescriptor(), getMaxWidth()).size();
|
final int size = PdfUtil.getOptimalTextBreakLines(getText(), getFontDescriptor(), getMaxWidth()).size();
|
||||||
final float heightOfTextLines = size * this.textHeight;
|
final float heightOfTextLines = size * this.textHeight;
|
||||||
|
|
|
@ -13,6 +13,9 @@ public abstract class AbstractCellRenderer<T extends Cell> implements Renderer {
|
||||||
|
|
||||||
protected T cell;
|
protected T cell;
|
||||||
|
|
||||||
|
public AbstractCellRenderer() {
|
||||||
|
}
|
||||||
|
|
||||||
public AbstractCellRenderer<T> withCell(T cell) {
|
public AbstractCellRenderer<T> withCell(T cell) {
|
||||||
this.cell = cell;
|
this.cell = cell;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
|
||||||
final List<String> lines = calculateAndGetLines(fontDescriptor, cell.getMaxWidth());
|
final List<String> lines = calculateAndGetLines(fontDescriptor, cell.getMaxWidth());
|
||||||
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);
|
||||||
yOffset -= calculateYOffset(line, fontDescriptor, i);
|
yOffset -= calculateYOffset(fontDescriptor, i);
|
||||||
final float textWidth = PdfUtil.getStringWidth(line, fontDescriptor);
|
final float textWidth = PdfUtil.getStringWidth(line, fontDescriptor);
|
||||||
if (cell.isHorizontallyAligned(RIGHT)) {
|
if (cell.isHorizontallyAligned(RIGHT)) {
|
||||||
xOffset = startX + (cell.getWidth() - (textWidth + cell.getPaddingRight()));
|
xOffset = startX + (cell.getWidth() - (textWidth + cell.getPaddingRight()));
|
||||||
|
@ -54,9 +54,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
|
||||||
return cell.getTextHeight();
|
return cell.getTextHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float calculateYOffset(String text, FontDescriptor fontDescriptor, int lineIndex) {
|
private float calculateYOffset(FontDescriptor fontDescriptor, int lineIndex) {
|
||||||
return PdfUtil.getFontHeight(text, fontDescriptor) +
|
return PdfUtil.getFontHeight(fontDescriptor) +
|
||||||
(lineIndex > 0 ? PdfUtil.getFontHeight(text, fontDescriptor) * cell.getLineSpacing() : 0f);
|
(lineIndex > 0 ? PdfUtil.getFontHeight(fontDescriptor) * cell.getLineSpacing() : 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNotLastLine(List<String> lines, int i) {
|
private static boolean isNotLastLine(List<String> lines, int i) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
|
||||||
float xOffset = startX + cell.getPaddingLeft(); /* - PdfUtil.getFontHeight(currentFont, currentFontSize)*/;
|
float xOffset = startX + cell.getPaddingLeft(); /* - PdfUtil.getFontHeight(currentFont, currentFontSize)*/;
|
||||||
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(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());
|
drawText(line, fontDescriptor, currentTextColor, xOffset, yOffset, tableRenderContext.getContentStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,9 @@ public final class PdfUtil {
|
||||||
}
|
}
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
throw new IllegalArgumentException("unable to get width of string " + codepoint);
|
throw new IllegalArgumentException("unable to get width of string " + codepoint);
|
||||||
|
@ -75,13 +78,11 @@ public final class PdfUtil {
|
||||||
* @param fontDescriptor font
|
* @param fontDescriptor font
|
||||||
* @return height of font
|
* @return height of font
|
||||||
*/
|
*/
|
||||||
public static float getFontHeight(String text, FontDescriptor fontDescriptor) {
|
public static float getFontHeight(FontDescriptor fontDescriptor) {
|
||||||
for (Font font : fontDescriptor.getFonts()) {
|
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, fonts = " + fontDescriptor.getFonts());
|
||||||
throw new IllegalArgumentException("unable to get font height for text " + text + ", fonts = " + fontDescriptor.getFonts());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,26 +10,40 @@ import org.xbib.graphics.pdfbox.layout.table.render.PositionedStyledText;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class RenderUtil {
|
public class RenderUtil {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(RenderUtil.class.getName());
|
||||||
|
|
||||||
private RenderUtil() {
|
private RenderUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawText(PDPageContentStream contentStream, PositionedStyledText styledText) {
|
public static void drawText(PDPageContentStream contentStream, PositionedStyledText styledText) {
|
||||||
for (Font font : styledText.getFontDescriptor().getFonts()) {
|
for (Font font : styledText.getFontDescriptor().getFonts()) {
|
||||||
|
boolean isBeginText = false;
|
||||||
if (font.canWrite(styledText.getText())) {
|
if (font.canWrite(styledText.getText())) {
|
||||||
try {
|
try {
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
|
isBeginText = true;
|
||||||
contentStream.setNonStrokingColor(styledText.getColor());
|
contentStream.setNonStrokingColor(styledText.getColor());
|
||||||
// TODO select correct font style
|
|
||||||
contentStream.setFont(font.getRegularFont(), styledText.getFontDescriptor().getSize());
|
contentStream.setFont(font.getRegularFont(), styledText.getFontDescriptor().getSize());
|
||||||
contentStream.newLineAtOffset(styledText.getX(), styledText.getY());
|
contentStream.newLineAtOffset(styledText.getX(), styledText.getY());
|
||||||
contentStream.showText(styledText.getText());
|
contentStream.showText(styledText.getText());
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
|
isBeginText = false;
|
||||||
contentStream.setCharacterSpacing(0);
|
contentStream.setCharacterSpacing(0);
|
||||||
} catch (IOException e) {
|
break;
|
||||||
throw new UncheckedIOException(e);
|
} catch (IllegalArgumentException | IOException e) {
|
||||||
|
logger.log(Level.WARNING, e.getMessage());
|
||||||
|
if (isBeginText) {
|
||||||
|
try {
|
||||||
|
contentStream.endText();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class TableTest {
|
||||||
.add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build())
|
.add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build())
|
||||||
.build())
|
.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));
|
assertThat(table.getHeight(), equalTo(50 + actualFontHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"margin": "0 0 0 0",
|
"margin": "0 0 0 0",
|
||||||
"author": "Jörg Prante",
|
"author": "Jörg Prante",
|
||||||
"font": [
|
"font": [
|
||||||
"helvetica"
|
"helvetica", "sourcesans", "notosans", "notosanscjksc"
|
||||||
],
|
],
|
||||||
"elements": [
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue