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]

Reply via email to