Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix auto size columns #1130

Merged
merged 18 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion main/HSSF/UserModel/EscherGraphics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public class EscherGraphics : IDisposable
private Font font;
private static POILogger Logger = POILogFactory.GetLogger(typeof(EscherGraphics));

// Default dpi
private static int dpi = 96;

/**
* Construct an escher graphics object.
*
Expand Down Expand Up @@ -289,7 +292,8 @@ public void DrawString(String str, int x, int y)
Font excelFont = new Font(SystemFonts.Get(font.Name.Equals("SansSerif") ? "Arial" : font.Name),
(int)(font.Size / verticalPixelsPerPoint), font.FontMetrics.Description.Style);
{
int width = (int)((TextMeasurer.Measure(str, new TextOptions(excelFont)).Width * 8) + 12);
var textOptions = new TextOptions(excelFont) { Dpi = dpi };
int width = (int)((TextMeasurer.MeasureSize(str, textOptions).Width * 8) + 12);
int height = (int)((font.Size / verticalPixelsPerPoint) + 6) * 2;
y -= Convert.ToInt32((font.Size / verticalPixelsPerPoint) + 2 * verticalPixelsPerPoint); // we want to Draw the shape from the top-left
HSSFTextbox textbox = escherGroup.CreateTextbox(new HSSFChildAnchor(x, y, x + width, y + height));
Expand Down
2 changes: 1 addition & 1 deletion main/NPOI.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.2.1" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta19" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.4" />
</ItemGroup>

Expand Down
47 changes: 20 additions & 27 deletions main/SS/Util/SheetUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class SheetUtil
// */
private static char defaultChar = '0';

// Default dpi
private static int dpi = 96;

// /**
// * This is the multiple that the font height is scaled by when determining the
// * boundary of rotated text.
Expand Down Expand Up @@ -269,19 +272,19 @@ public static IRow CopyRow(ISheet sheet, int sourceRowIndex, int targetRowIndex)

public static double GetRowHeight(IRow row, bool useMergedCells, int firstColumnIdx, int lastColumnIdx)
{
double width = -1;
double height = -1;

for (int cellIdx = firstColumnIdx; cellIdx <= lastColumnIdx; ++cellIdx)
{
ICell cell = row.GetCell(cellIdx);
if (row != null && cell != null)
{
double cellWidth = GetCellHeight(cell, useMergedCells);
width = Math.Max(width, cellWidth);
double cellHeight = GetCellHeight(cell, useMergedCells);
height = Math.Max(height, cellHeight);
}
}

return width;
return height;
}

public static double GetRowHeight(ISheet sheet, int rowIdx, bool useMergedCells, int firstColumnIdx, int lastColumnIdx)
Expand Down Expand Up @@ -366,8 +369,7 @@ private static int GetNumberOfRowsInMergedRegion(ICell cell)

private static double GetCellConetntHeight(double actualHeight, int numberOfRowsInMergedRegion)
{
var correction = 1.1;
return Math.Max(-1, actualHeight / numberOfRowsInMergedRegion * correction);
return Math.Max(-1, actualHeight / numberOfRowsInMergedRegion);
}

private static string GetCellStringValue(ICell cell)
Expand Down Expand Up @@ -416,7 +418,7 @@ private static Font GetWindowsFont(ICell cell)
private static double GetRotatedContentHeight(ICell cell, string stringValue, Font windowsFont)
{
var angle = cell.CellStyle.Rotation * 2.0 * Math.PI / 360.0;
var measureResult = TextMeasurer.Measure(stringValue, new TextOptions(windowsFont));
var measureResult = TextMeasurer.MeasureAdvance(stringValue, new TextOptions(windowsFont) { Dpi = dpi });

var x1 = Math.Abs(measureResult.Height * Math.Cos(angle));
var x2 = Math.Abs(measureResult.Width * Math.Sin(angle));
Expand All @@ -426,7 +428,7 @@ private static double GetRotatedContentHeight(ICell cell, string stringValue, Fo

private static double GetContentHeight(string stringValue, Font windowsFont)
{
var measureResult = TextMeasurer.Measure(stringValue, new TextOptions(windowsFont));
var measureResult = TextMeasurer.MeasureAdvance(stringValue, new TextOptions(windowsFont) { Dpi = dpi });

return Math.Round(measureResult.Height, 0, MidpointRounding.ToEven);
}
Expand Down Expand Up @@ -480,7 +482,7 @@ public static double GetCellWidth(ICell cell, int defaultCharWidth, DataFormatte
String[] lines = rt.String.Split("\n".ToCharArray());
for (int i = 0; i < lines.Length; i++)
{
String txt = lines[i] + defaultChar;
String txt = lines[i];

//AttributedString str = new AttributedString(txt);
//copyAttributes(font, str, 0, txt.length());
Expand Down Expand Up @@ -514,7 +516,7 @@ public static double GetCellWidth(ICell cell, int defaultCharWidth, DataFormatte
}
if (sval != null)
{
String txt = sval + defaultChar;
String txt = sval;
//str = new AttributedString(txt);
//copyAttributes(font, str, 0, txt.length());
windowsFont = IFont2Font(font);
Expand All @@ -530,25 +532,20 @@ private static double GetCellWidth(int defaultCharWidth, int colspan,
{
//Rectangle bounds;
double actualWidth;
FontRectangle sf = TextMeasurer.Measure(str, new TextOptions(windowsFont));
FontRectangle sf = TextMeasurer.MeasureSize(str, new TextOptions(windowsFont) { Dpi = dpi });
if (style.Rotation != 0)
{
double angle = style.Rotation * 2.0 * Math.PI / 360.0;
double x1 = Math.Abs(sf.Height * Math.Sin(angle));
double x2 = Math.Abs(sf.Width * Math.Cos(angle));
actualWidth = Math.Round(x1 + x2, 0, MidpointRounding.ToEven);
//bounds = layout.getOutline(trans).getBounds();
}
else
{
//bounds = layout.getBounds();
actualWidth = Math.Round(sf.Width, 0, MidpointRounding.ToEven);
}
// entireWidth accounts for leading spaces which is excluded from bounds.getWidth()
//double frameWidth = bounds.getX() + bounds.getWidth();
//width = Math.max(width, ((frameWidth / colspan) / defaultCharWidth) + style.getIndention());
var correction = 1.1;
width = Math.Max(width, (actualWidth / colspan / defaultCharWidth * correction) + cell.CellStyle.Indention);
actualWidth = Math.Round(sf.Width, 0, MidpointRounding.ToEven);

int padding = 5;
double correction = 1.05;
width = Math.Max(width, ((actualWidth + padding) / colspan / defaultCharWidth * correction) + cell.CellStyle.Indention);
return width;
}

Expand Down Expand Up @@ -610,13 +607,9 @@ public static double GetColumnWidth(ISheet sheet, int column, bool useMergedCell
public static int GetDefaultCharWidth(IWorkbook wb)
{
IFont defaultFont = wb.GetFontAt((short)0);

//AttributedString str = new AttributedString(String.valueOf(defaultChar));
//copyAttributes(defaultFont, str, 0, 1);
//TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
//int defaultCharWidth = (int)layout.getAdvance();
Font font = IFont2Font(defaultFont);
return (int)Math.Ceiling(TextMeasurer.Measure(new string(defaultChar, 1), new TextOptions(font)).Width);

return (int)Math.Ceiling(TextMeasurer.MeasureSize(new string(defaultChar, 1), new TextOptions(font) { Dpi = dpi }).Width);
}

/**
Expand Down
5 changes: 1 addition & 4 deletions testcases/main/HSSF/UserModel/TestHSSFSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -854,10 +854,7 @@ public void TestAutoSizeRow()
sheet.AutoSizeRow(row.RowNum);

Assert.AreNotEqual(100, row.Height);

// there's slight difference due to fonts
var expectedRowHeight = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 506 : 528;
Assert.AreEqual(expectedRowHeight, row.Height);
Assert.AreEqual(540, row.Height);

workbook.Close();
}
Expand Down
15 changes: 10 additions & 5 deletions testcases/main/SS/UserModel/BaseTestBugzillaIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public abstract class BaseTestBugzillaIssues
{

private ITestDataProvider _testDataProvider;
private static int dpi = 96;

protected BaseTestBugzillaIssues(ITestDataProvider TestDataProvider)
{
Expand Down Expand Up @@ -445,12 +446,14 @@ public void Bug51622_testAutoSizeShouldRecognizeLeadingSpaces()
// if the default font or margins change.
double expectedRatioThreshold = 1.2f;
double leadingWhitespaceRatio = ((double)leadingWhitespaceColWidth) / noWhitespaceColWidth;
double trailingWhitespaceRatio = ((double)leadingWhitespaceColWidth) / noWhitespaceColWidth;
double trailingWhitespaceRatio = ((double)trailingWhitespaceColWidth) / noWhitespaceColWidth;

assertGreaterThan("leading whitespace is longer than no whitespace", leadingWhitespaceRatio, expectedRatioThreshold);
assertGreaterThan("trailing whitespace is longer than no whitespace", trailingWhitespaceRatio, expectedRatioThreshold);
Assert.AreEqual(leadingWhitespaceColWidth, trailingWhitespaceColWidth,
"cells with equal leading and trailing whitespace have equal width");

//This is not correct https://github.com/SixLabors/Fonts/discussions/349
//Assert.AreEqual(leadingWhitespaceColWidth, trailingWhitespaceColWidth,
//"cells with equal leading and trailing whitespace have equal width");

wb.Close();
}
Expand Down Expand Up @@ -487,15 +490,17 @@ private double ComputeCellWidthManually(ICell cell0, IFont font)
//TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
//width = ((layout.getBounds().getWidth() / 1) / 8);
Font wfont = SheetUtil.IFont2Font(font);
width = (double)TextMeasurer.Measure(txt, new TextOptions(wfont)).Width;
var textOptions = new TextOptions(wfont) { Dpi = dpi };
width = (double)TextMeasurer.MeasureSize(txt, textOptions).Width;
return width;
}

private double ComputeCellWidthFixed(IFont font, String txt)
{
double width;
Font wfont = SheetUtil.IFont2Font(font);
width = (double)TextMeasurer.Measure(txt, new TextOptions(wfont)).Width;
var textOptions = new TextOptions(wfont) { Dpi = dpi };
width = (double)TextMeasurer.MeasureSize(txt, textOptions).Width;
return width;
}

Expand Down
2 changes: 1 addition & 1 deletion testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public void TestAutoSizeRow()
sheet.AutoSizeRow(row.RowNum);

Assert.AreNotEqual(100, row.Height);
Assert.AreEqual(550, row.Height);
Assert.AreEqual(540, row.Height);

workbook.Close();
}
Expand Down