This is an automated email from the ASF dual-hosted git repository.
fanningpj pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new 0a17fa9e22 Delay initialization of `fontRenderContext` field & co. by
moving it into own inner class (#909)
0a17fa9e22 is described below
commit 0a17fa9e22810a3aa3861b86dcf03a4788dc4efc
Author: Jaroslav Tulach <[email protected]>
AuthorDate: Tue Sep 30 10:44:47 2025 +0200
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 <[email protected]>
Co-authored-by: Jaroslav Tulach <[email protected]>
---
.../java/org/apache/poi/ss/util/SheetUtil.java | 153 ++++++++++++---------
1 file changed, 86 insertions(+), 67 deletions(-)
diff --git a/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
b/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
index 633a785b93..312913a84d 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
@@ -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,56 +233,87 @@ 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;
}
- /**
- * Calculate the best-fit width for a cell
- * If a merged cell spans multiple columns, evenly distribute the column
width among those columns
- *
- * @param defaultCharWidth the width of a character using the default font
in a workbook
- * @param colspan the number of columns that is spanned by the cell (1 if
the cell is not part of a merged region)
- * @param style the cell style, which contains text rotation and indention
information needed to compute the cell width
- * @param minWidth the minimum best-fit width. This algorithm will only
return values greater than or equal to the minimum width.
- * @param str the text contained in the cell
- * @return the best fit cell width
- */
- private static double getCellWidth(float defaultCharWidth, final int
colspan,
- final CellStyle style, final double minWidth, final
AttributedString str) {
- TextLayout layout;
- try {
- layout = new TextLayout(str.getIterator(), fontRenderContext);
- } catch (Throwable t) {
- if (shouldIgnoreMissingFontSystem(t)) {
- return FAILOVER_FUNCTION.apply(defaultCharWidth, colspan,
style, minWidth, str);
+ 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
+ *
+ * @param defaultCharWidth the width of a character using the default
font in a workbook
+ * @param colspan the number of columns that is spanned by the cell (1
if the cell is not part of a merged region)
+ * @param style the cell style, which contains text rotation and
indention information needed to compute the cell width
+ * @param minWidth the minimum best-fit width. This algorithm will
only return values greater than or equal to the minimum width.
+ * @param str the text contained in the cell
+ * @return the best fit cell width
+ */
+ private static double getCellWidth(float defaultCharWidth, final int
colspan,
+ final CellStyle style, final double minWidth, final
AttributedString str) {
+ TextLayout layout;
+ try {
+ layout = new TextLayout(str.getIterator(), fontRenderContext);
+ } catch (Throwable t) {
+ if (shouldIgnoreMissingFontSystem(t)) {
+ return FAILOVER_FUNCTION.apply(defaultCharWidth, colspan,
style, minWidth, str);
+ }
+ throw t;
}
- throw t;
+ final Rectangle2D bounds;
+ if (style.getRotation() != 0) {
+ /*
+ * Transform the text using a scale so that its height is
increased by a multiple of the leading,
+ * and then rotate the text before computing the bounds. The
scale results in some whitespace around
+ * the unrotated top and bottom of the text that normally
wouldn't be present if unscaled, but
+ * is added by the standard Excel autosize.
+ */
+ AffineTransform trans = new AffineTransform();
+
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
+ trans.concatenate(
+ AffineTransform.getScaleInstance(1, fontHeightMultiple)
+ );
+ bounds = layout.getOutline(trans).getBounds();
+ } else {
+ bounds = layout.getBounds();
+ }
+ // frameWidth accounts for leading spaces which is excluded from
bounds.getWidth()
+ final double frameWidth = bounds.getX() + bounds.getWidth();
+ return Math.max(minWidth, ((frameWidth / colspan) /
defaultCharWidth) + style.getIndention());
}
- final Rectangle2D bounds;
- if (style.getRotation() != 0) {
- /*
- * Transform the text using a scale so that its height is
increased by a multiple of the leading,
- * and then rotate the text before computing the bounds. The scale
results in some whitespace around
- * the unrotated top and bottom of the text that normally wouldn't
be present if unscaled, but
- * is added by the standard Excel autosize.
- */
- AffineTransform trans = new AffineTransform();
-
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
- trans.concatenate(
- AffineTransform.getScaleInstance(1, fontHeightMultiple)
- );
- bounds = layout.getOutline(trans).getBounds();
- } else {
- bounds = layout.getBounds();
+
+ 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);
}
- // frameWidth accounts for leading spaces which is excluded from
bounds.getWidth()
- final double frameWidth = bounds.getX() + bounds.getWidth();
- return Math.max(minWidth, ((frameWidth / colspan) / defaultCharWidth)
+ style.getIndention());
+
+ 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);
+ }
+
}
/**
@@ -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() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]