Delay initialization of fontRenderContext field & co. by moving it into own inner class (#909)

* git-svn-id: https://svn.apache.org/repos/asf/poi/tags/REL_5_2_3@1904113 13f79535-47bb-0310-9956-ffa450edef68

* Delay loading AWT classes by moving the methods into own class

* Set default value of ignoreMissingFontSystem to true when java.desktop module isn't available

---------

Co-authored-by: PJ Fanning <fanningpj@apache.org>
Co-authored-by: Jaroslav Tulach <jaroslav.tulach@apidesign.org>
This commit is contained in:
Jaroslav Tulach 2025-09-30 10:44:47 +02:00 committed by GitHub
parent 444a8a7214
commit 0a17fa9e22
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -93,11 +93,6 @@ public class SheetUtil {
public CellType evaluateFormulaCell(Cell cell) { return cell.getCachedFormulaResultType(); }
};
/**
* drawing context to measure text
*/
private static FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);
/**
* A system property which can be enabled to not fail when the
* font-system is not available on the current machine.
@ -214,13 +209,13 @@ public class SheetUtil {
String txt = line + defaultChar;
AttributedString str = new AttributedString(txt);
copyAttributes(font, str, 0, txt.length());
WithJavaDesktop.copyAttributes(font, str, 0, txt.length());
/*if (rt.numFormattingRuns() > 0) {
// TODO: support rich text fragments
}*/
width = getCellWidth(defaultCharWidth, colspan, style, width, str);
width = WithJavaDesktop.getCellWidth(defaultCharWidth, colspan, style, width, str);
}
}
} else {
@ -238,14 +233,20 @@ public class SheetUtil {
if(sval != null) {
String txt = sval + defaultChar;
AttributedString str = new AttributedString(txt);
copyAttributes(font, str, 0, txt.length());
WithJavaDesktop.copyAttributes(font, str, 0, txt.length());
width = getCellWidth(defaultCharWidth, colspan, style, width, str);
width = WithJavaDesktop.getCellWidth(defaultCharWidth, colspan, style, width, str);
}
}
return width;
}
private static final class WithJavaDesktop {
/**
* drawing context to measure text
*/
private static FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);
/**
* Calculate the best-fit width for a cell
* If a merged cell spans multiple columns, evenly distribute the column width among those columns
@ -290,6 +291,31 @@ public class SheetUtil {
return Math.max(minWidth, ((frameWidth / colspan) / defaultCharWidth) + style.getIndention());
}
private static float getDefaultCharWidthAsFloat(AttributedString str) {
TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
return layout.getAdvance();
}
/**
* Copy text attributes from the supplied Font to Java2D AttributedString
*/
private static void copyAttributes(Font font, AttributedString str, @SuppressWarnings("SameParameterValue") int startIdx, int endIdx) {
str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
if (font.getBold()) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
}
private static boolean canComputeColumnWidth(Font font, AttributedString str) {
copyAttributes(font, str, 0, "1w".length());
TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
return (layout.getBounds().getWidth() > 0);
}
}
/**
* Compute width of a column and return the result.
* Note that this fall can fail if you do not have the right fonts installed in your OS.
@ -356,10 +382,9 @@ public class SheetUtil {
Font defaultFont = wb.getFontAt( 0);
AttributedString str = new AttributedString(String.valueOf(defaultChar));
copyAttributes(defaultFont, str, 0, 1);
try {
TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
return layout.getAdvance();
WithJavaDesktop.copyAttributes(defaultFont, str, 0, 1);
return WithJavaDesktop.getDefaultCharWidthAsFloat(str);
} catch (Throwable t) {
if (shouldIgnoreMissingFontSystem(t)) {
return DEFAULT_CHAR_WIDTH;
@ -456,22 +481,16 @@ public class SheetUtil {
public static boolean canComputeColumnWidth(Font font) {
// not sure what is the best value sample-here, only "1" did not work on some platforms...
AttributedString str = new AttributedString("1w");
copyAttributes(font, str, 0, "1w".length());
TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
return (layout.getBounds().getWidth() > 0);
try {
return WithJavaDesktop.canComputeColumnWidth(font, str);
} catch (Throwable t) {
if (shouldIgnoreMissingFontSystem(t)) {
return false;
}
throw t;
}
}
/**
* Copy text attributes from the supplied Font to Java2D AttributedString
*/
private static void copyAttributes(Font font, AttributedString str, @SuppressWarnings("SameParameterValue") int startIdx, int endIdx) {
str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
if (font.getBold()) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
}
/**
* Return the cell, without taking account of merged regions.
@ -543,11 +562,11 @@ public class SheetUtil {
}
protected static FontRenderContext getFontRenderContext() {
return fontRenderContext;
return WithJavaDesktop.fontRenderContext;
}
protected static void setFontRenderContext(FontRenderContext fontRenderContext) {
SheetUtil.fontRenderContext = fontRenderContext;
WithJavaDesktop.fontRenderContext = fontRenderContext;
}
private static boolean initIgnoreMissingFontSystemFlag() {