Skip to content

Commit 8bc9d8b

Browse files
committed
Removed old references created class wrapper
1 parent c447e55 commit 8bc9d8b

9 files changed

Lines changed: 245 additions & 93 deletions

File tree

src/EPPlus.Export.ImageRenderer.Test/TestFontMeasurer.cs

Lines changed: 60 additions & 27 deletions
Large diffs are not rendered by default.

src/EPPlus.Export.ImageRenderer.Test/TextRenderTests.cs

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using EPPlus.Export.ImageRenderer.RenderItems.SvgItem;
22
using EPPlus.Fonts.OpenType;
3-
using EPPlus.Fonts.OpenType.TextShaping.DataHolders;
4-
using EPPlus.Fonts.OpenType.TrueTypeMeasurer;
53
using EPPlus.Fonts.OpenType.Utils;
4+
using EPPlus.Fonts.OpenType.Integration;
65
using EPPlus.Graphics;
76
using EPPlusImageRenderer;
87
using EPPlusImageRenderer.Svg;
@@ -59,48 +58,44 @@ private void SetFillColor(ExcelDrawingFillBasic fill, string color)
5958
}
6059
}
6160

62-
TextFragmentCollection GenerateTextFragments(ExcelDrawingTextRunCollection runs)
63-
{
64-
List<string> runContents = new List<string>();
65-
List<float> fontSizes = new List<float>();
61+
//TextFragmentCollectionSimple GenerateTextFragments(ExcelDrawingTextRunCollection runs)
62+
//{
63+
// List<string> runContents = new List<string>();
64+
// List<float> fontSizes = new List<float>();
65+
// List<MeasurementFont> fonts = new List<MeasurementFont>();
6666

67-
for (int i = 0; i < runs.Count(); i++)
68-
{
69-
var txtRun = runs[i];
70-
var runFont = txtRun.GetMeasurementFont();
67+
// for (int i = 0; i < runs.Count(); i++)
68+
// {
69+
// var txtRun = runs[i];
70+
// var runFont = txtRun.GetMeasurementFont();
7171

72-
runContents.Add(txtRun.Text);
73-
fontSizes.Add(runFont.Size);
74-
}
72+
// fonts.Add(runFont);
7573

76-
return new TextFragmentCollection(runContents, fontSizes);
77-
}
74+
// runContents.Add(txtRun.Text);
75+
// fontSizes.Add(runFont.Size);
76+
// }
7877

79-
List<TextLineSimple> GetWrappedText(ExcelDrawingTextRunCollection runs, TextFragmentCollection fragments)
80-
{
81-
FontMeasurerTrueType ttMeasurer = new();
82-
List<MeasurementFont> fonts = new List<MeasurementFont>();
78+
79+
// return new TextFragmentCollectionSimple(fonts, runContents);
80+
//}
8381

84-
for (int i = 0; i < runs.Count(); i++)
85-
{
86-
var txtRun = runs[i];
87-
var runFont = txtRun.GetMeasurementFont();
88-
fonts.Add(runFont);
89-
}
82+
//List<TextLineSimple> GetWrappedText(ExcelDrawingTextRunCollection runs, TextFragmentCollectionSimple fragments)
83+
//{
84+
85+
// List<MeasurementFont> fonts = new List<MeasurementFont>();
9086

91-
var maxSizePoints = Math.Round(300d, 0, MidpointRounding.AwayFromZero).PixelToPoint();
92-
return ttMeasurer.WrapMultipleTextFragmentsToTextLines(fragments, fonts, maxSizePoints);
93-
}
94-
95-
[TestMethod]
96-
public void TextFragmentHandlesEndLines()
97-
{
98-
string strWEndLines = "TextBodySvg\r\na";
87+
// for (int i = 0; i < runs.Count(); i++)
88+
// {
89+
// var txtRun = runs[i];
90+
// var runFont = txtRun.GetMeasurementFont();
91+
// fonts.Add(runFont);
92+
// }
9993

100-
List<string> inputFrags = new List<string>() { strWEndLines };
101-
var textFragments = new TextFragmentCollection(inputFrags);
94+
// var maxSizePoints = Math.Round(300d, 0, MidpointRounding.AwayFromZero).PixelToPoint();
95+
// TextHandler handler = new TextHandler(fonts[0]);
10296

103-
}
97+
// return handler.WrapMultipleTextFragmentsToTextLines(fragments, fonts, maxSizePoints);
98+
//}
10499

105100
[TestMethod]
106101
public void MeasureWrappedWidths()
@@ -153,11 +148,11 @@ public void MeasureWrappedWidths()
153148
List<MeasurementFont> fonts = new() { /*font1,*/ font2, font3, font4, font5, font6};
154149

155150
var maxSizePoints = Math.Round(300d, 0, MidpointRounding.AwayFromZero).PixelToPoint();
156-
var ttMeasurer = new FontMeasurerTrueType(font2);
151+
var ttMeasurer = OpenTypeFonts.GetTextLayoutEngineForFont(font2);
157152

158-
var textFragments = new TextFragmentCollection(lstOfRichText);
153+
var textFragments = new TextFragmentCollectionSimple(fonts, lstOfRichText);
159154

160-
var wrappedLines = ttMeasurer.WrapMultipleTextFragmentsToTextLines(textFragments, fonts, maxSizePoints);
155+
var wrappedLines = ttMeasurer.WrapRichTextLines(textFragments, maxSizePoints);
161156

162157
//Assert.AreEqual(wrappedLines[0].r)
163158

src/EPPlus.Export.ImageRenderer/DrawingBase.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ internal DrawingBase(ExcelDrawing drawing)
3737
var wb = drawing._drawings.Worksheet.Workbook;
3838
Theme = wb.ThemeManager.GetOrCreateTheme();
3939

40-
//Theme.FontScheme.MajorFont[0].Typeface
41-
//var shaper = OpenTypeFonts.GetTextShaper(
42-
//Theme.FontScheme.MajorFont[0].Typeface, Theme.FontScheme.MinorFont[0].Typeface)
43-
TextMeasurer = new OpenTypeFontTextMeasurer();
40+
var shaper = OpenTypeFonts.GetTextShaper(Theme.FontScheme.MajorFont[0].Typeface);
41+
TextMeasurer = new OpenTypeFontTextMeasurer(shaper);
4442
}
4543

4644

src/EPPlus.Export.ImageRenderer/RenderItems/Shared/ParagraphItem.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,11 @@ private void AddLinesAndTextRuns(ExcelDrawingParagraph p, string textIfEmpty)
379379

380380
if (p.TextRuns.Count == 0 && string.IsNullOrEmpty(textIfEmpty) == false)
381381
{
382-
var measurer = new FontMeasurerTrueType();
382+
var font = p.DefaultRunProperties.GetMeasureFont();
383+
var measurer = OpenTypeFonts.GetTextLayoutEngineForFont(font);
383384
var maxWidth = ParentTextBody.MaxWidth + 0.001; //TODO: fix for equal width issue;
384-
lines = measurer.MeasureAndWrapTextLines_New(textIfEmpty, p.DefaultRunProperties.GetMeasureFont(), maxWidth);
385+
386+
lines = measurer.WrapRichTextLines(textIfEmpty, font, maxWidth);
385387

386388
//Bounds.Width = maxWidth;
387389
if (HorizontalAlignment != eTextAlignment.Center)
@@ -485,13 +487,15 @@ private void AddLinesAndTextRuns(ExcelDrawingParagraph p, string textIfEmpty)
485487

486488
List<TextLineSimple> WrapToSimpleTextLines(ExcelDrawingParagraph p)
487489
{
488-
var ttMeasurer = (FontMeasurerTrueType)_layout;
489-
490490
if (_newTextFragments.Count > 0)
491491
{
492-
ttMeasurer.SetFont(_newTextFragments[0].Font);
492+
if(_layout == null)
493+
{
494+
_layout = OpenTypeFonts.GetTextLayoutEngineForFont((_newTextFragments[0].Font));
495+
}
496+
493497
var maxWidthPoints = Math.Round(ParentTextBody.MaxWidth, 0, MidpointRounding.AwayFromZero);
494-
return ttMeasurer.WrapMultipleTextFragmentsToTextLines_New(_newTextFragments, maxWidthPoints);
498+
return _layout.WrapRichTextLines(_newTextFragments, maxWidthPoints);
495499
}
496500
return new List<TextLineSimple>();
497501
}

src/EPPlus.Export.ImageRenderer/Svg/Chart/SvgChartAxis.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Date Author Change
1414
using EPPlus.Export.ImageRenderer.RenderItems;
1515
using EPPlus.Export.ImageRenderer.RenderItems.SvgItem;
1616
using EPPlus.Export.ImageRenderer.Svg.Chart.Util;
17+
using EPPlus.Fonts.OpenType;
18+
using EPPlus.Fonts.OpenType.Integration;
1719
using EPPlus.Fonts.OpenType.Utils;
1820
using EPPlus.Graphics;
1921
using EPPlusImageRenderer.RenderItems;
@@ -180,10 +182,12 @@ private double GetTextHeight(SvgChart sc, ExcelChartAxisStandard ax)
180182

181183
private double GetTextWidest(SvgChart sc, ExcelChartAxisStandard ax)
182184
{
183-
var tm = sc.Chart.WorkSheet._package.Settings.TextSettings.GenericTextMeasurerTrueType;
185+
var mf = ax.Font.GetMeasureFont();
186+
var shaper = OpenTypeFonts.GetShaperForFont(mf);
187+
var tm = new OpenTypeFontTextMeasurer(shaper);
184188

185189
var widest = 0f;
186-
var mf = ax.Font.GetMeasureFont();
190+
187191
foreach(var s in AxisValues)
188192
{
189193
var m= tm.MeasureText(s, mf);
@@ -313,8 +317,11 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
313317
var ret = new List<SvgTextBox>();
314318
if (Axis.LabelPosition == eTickLabelPosition.None) return ret;
315319

316-
var tm = Chart.WorkSheet._package.Settings.TextSettings.GenericTextMeasurerTrueType;
317320
var mf = Axis.Font.GetMeasureFont();
321+
322+
var shaper = OpenTypeFonts.GetShaperForFont(mf);
323+
var tm = new OpenTypeFontTextMeasurer(shaper);
324+
318325
var axisStyle = GetAxisStyleEntry();
319326
double maxWidth, maxHeight;
320327
if(Axis.AxisPosition==eAxisPosition.Left || Axis.AxisPosition == eAxisPosition.Right)

src/EPPlus.Export.ImageRenderer/Svg/Chart/SvgChartLegend.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Date Author Change
1313
using EPPlus.Export.ImageRenderer.RenderItems.Shared;
1414
using EPPlus.Export.ImageRenderer.RenderItems.SvgItem;
1515
using EPPlus.Export.ImageRenderer.Svg;
16+
using EPPlus.Fonts.OpenType;
17+
using EPPlus.Fonts.OpenType.Integration;
1618
using EPPlusImageRenderer.RenderItems;
1719
using OfficeOpenXml;
1820
using OfficeOpenXml.ConditionalFormatting;
@@ -41,7 +43,10 @@ internal class SvgChartLegend : SvgChartObject
4143
double _maxWidth, _maxHeight;
4244
internal SvgChartLegend(SvgChart sc, bool isDataLabelLegend = false) : base(sc)
4345
{
44-
_ttMeasurer = sc.Chart.WorkSheet._package.Settings.TextSettings.GenericTextMeasurerTrueType;
46+
var mf = sc.Chart.Font.GetMeasureFont();
47+
var shaper = OpenTypeFonts.GetShaperForFont(mf);
48+
var _ttMeasurer = new OpenTypeFontTextMeasurer(shaper);
49+
4550
if (sc.Chart.HasLegend == false && isDataLabelLegend == false || sc.Chart.Series.Count == 0)
4651
{
4752
return;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using EPPlus.Fonts.OpenType.TextShaping;
2+
using OfficeOpenXml.Interfaces.Drawing.Text;
3+
using OfficeOpenXml.Interfaces.Fonts;
4+
using System.Collections.Generic;
5+
6+
namespace EPPlus.Fonts.OpenType.Integration
7+
{
8+
public class TextHandler
9+
{
10+
internal float CurrentFontSize { get; private set; }
11+
12+
TextShaper _currentShaper;
13+
TextLayoutEngine _currentLayout;
14+
15+
public TextHandler(MeasurementFont mf)
16+
{
17+
CurrentFontSize = mf.Size;
18+
SetFont(mf);
19+
}
20+
21+
public void SetFontSize(float fontSize)
22+
{
23+
CurrentFontSize = fontSize;
24+
}
25+
26+
public void SetFont(MeasurementFont mf)
27+
{
28+
CurrentFontSize = mf.Size;
29+
_currentShaper = (TextShaper)OpenTypeFonts.GetShaperForFont(mf);
30+
_currentLayout = OpenTypeFonts.GetTextLayoutEngineForFont(mf);
31+
}
32+
33+
/// <summary>
34+
/// Gets single line spacing (baseline-to-baseline distance).
35+
/// </summary>
36+
public float GetLineHeightInPoints()
37+
{
38+
return _currentShaper.GetLineHeightInPoints(CurrentFontSize);
39+
}
40+
41+
/// <summary>
42+
/// Calculates the total height of the font, in points.
43+
/// </summary>
44+
public float GetFontHeightInPoints()
45+
{
46+
return _currentShaper.GetFontHeightInPoints(CurrentFontSize);
47+
}
48+
49+
/// <summary>
50+
/// Calculates the distance from the top of the font's bounding box to the baseline.
51+
/// </summary>
52+
/// <param name="fontSize">The font size, in points, for which to calculate the baseline position. Must be a positive value.</param>
53+
/// <returns>The distance, in points, from the top of the font's bounding box to the baseline for the given font size.</returns>
54+
public float GetAscentInPoints()
55+
{
56+
return _currentShaper.GetAscentInPoints(CurrentFontSize);
57+
}
58+
59+
/// <summary>
60+
/// Calculates the font descent in points.
61+
/// </summary>
62+
public float GetDescentInPoints()
63+
{
64+
return _currentShaper.GetDescentInPoints(CurrentFontSize);
65+
}
66+
67+
/// <summary>
68+
/// Measures the width of text in PDF points.
69+
/// </summary>
70+
public float MeasureTextInPoints(string text, ShapingOptions options = null)
71+
{
72+
return _currentShaper.MeasureTextInPoints(text, CurrentFontSize, options);
73+
}
74+
75+
/// <summary>
76+
/// Measures the width of text in pixels.
77+
/// </summary>
78+
public float MeasureTextInPixels(string text, float dpi=96, ShapingOptions options = null)
79+
{
80+
return _currentShaper.MeasureTextInPixels(text, CurrentFontSize, dpi, options);
81+
}
82+
83+
/// <summary>
84+
/// Measure multi-line text and return bounding box.
85+
/// </summary>
86+
public MultiLineMetrics MeasureLines(string text, ShapingOptions options)
87+
{
88+
return _currentShaper.MeasureLines(text, CurrentFontSize, options);
89+
}
90+
91+
public List<string> WrapText(
92+
string text,
93+
double maxWidthPoints,
94+
ShapingOptions options = null)
95+
{
96+
return _currentLayout.WrapText(text, CurrentFontSize, maxWidthPoints, 0, options);
97+
}
98+
}
99+
}

src/EPPlus.Fonts.OpenType/Integration/TextLayoutEngine.RichText.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Date Author Change
1414
02/23/2026 EPPlus Software AB Performance fix: Shape() → ShapeLight() in ProcessFragment
1515
*************************************************************************************************/
1616
using EPPlus.Fonts.OpenType.Utilities;
17+
using OfficeOpenXml.Interfaces.Drawing.Text;
1718
using OfficeOpenXml.Interfaces.Fonts;
1819
using System;
1920
using System.Collections.Generic;
@@ -65,6 +66,21 @@ public List<string> WrapRichText(
6566

6667
return new List<string>(_lineListBuffer);
6768
}
69+
public List<string> WrapRichText(
70+
List<string> textFragments, List<MeasurementFont> fonts,
71+
double maxWidthPoints)
72+
{
73+
TextFragmentCollectionSimple fragmentCollection = new TextFragmentCollectionSimple(fonts, textFragments);
74+
return WrapRichText(fragmentCollection, maxWidthPoints);
75+
}
76+
77+
public List<TextLineSimple> WrapRichTextLines(
78+
string text, MeasurementFont font,
79+
double maxWidthPoints)
80+
{
81+
var tCollection = new TextFragmentCollectionSimple(new List<MeasurementFont>() { font }, new List<string> { text });
82+
return WrapRichTextLines(tCollection, maxWidthPoints);
83+
}
6884

6985
public List<TextLineSimple> WrapRichTextLines(
7086
List<TextFragment> fragments,
@@ -100,7 +116,7 @@ public List<TextLineSimple> WrapRichTextLines(
100116
{
101117
double largestAscent = 0;
102118
double largestDescent = 0;
103-
foreach(var lineFragment in line.LineFragments)
119+
foreach (var lineFragment in line.LineFragments)
104120
{
105121
var frag = fragments[lineFragment.RtFragIdx];
106122
if (frag == null) continue;
@@ -184,7 +200,7 @@ private void ProcessFragment(
184200
i++;
185201
}
186202

187-
if(state.LineFrag.Width > 0)
203+
if (state.LineFrag.Width > 0)
188204
{
189205
state.CurrentTextLine.LineFragments.Add(state.LineFrag);
190206
}
@@ -253,8 +269,8 @@ private void WrapCurrentLine(StringBuilder lineBuilder, WrapStateRichText state,
253269
// Bounds check to prevent ArgumentOutOfRangeException
254270
if (state.WordStart >= 0 && state.WordStart < lineBuilder.Length)
255271
{
256-
var lineStringWithTrail = lineBuilder.ToString(0, state.WordStart+1);//+1 was just added and should be here but everything else is sorta based on it being gone...
257-
if (lineStringWithTrail[lineStringWithTrail.Length-1] == ' ')
272+
var lineStringWithTrail = lineBuilder.ToString(0, state.WordStart + 1);//+1 was just added and should be here but everything else is sorta based on it being gone...
273+
if (lineStringWithTrail[lineStringWithTrail.Length - 1] == ' ')
258274
{
259275
state.CurrentTextLine.WasWrappedOnSpace = true;
260276
}

src/EPPlusTest/Drawing/TextMeasuring/ReadMeasureTests.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,10 @@ public void WrapMultipleFragments_SpacedEndWord()
8484

8585
fonts.Add(mf2);
8686

87-
var txtMeasurer = new FontMeasurerTrueType();
88-
89-
txtMeasurer.SetFont(mf);
90-
87+
var txtMeasurer = OpenTypeFonts.GetTextLayoutEngineForFont(mf2);
9188
var maxWidth = 114d;
9289

93-
var wrappedFragments = txtMeasurer.WrapMultipleTextFragments(txtRuns, fonts, maxWidth.PixelToPoint());
90+
var wrappedFragments = txtMeasurer.WrapRichText(txtRuns, fonts, maxWidth.PixelToPoint());
9491

9592
Assert.AreEqual(2, wrappedFragments.Count);
9693
Assert.AreEqual("HIJKLM", wrappedFragments[0]);
@@ -134,13 +131,11 @@ public void WrapMultipleFragments_LongPlusEndWord()
134131
fonts.Add(mf2);
135132
fonts.Add(mf2);
136133

137-
var txtMeasurer = new FontMeasurerTrueType();
138-
139-
txtMeasurer.SetFont(mf);
134+
var txtMeasurer = OpenTypeFonts.GetTextLayoutEngineForFont(mf);
140135

141136
var maxWidth = 114d;
142137

143-
var wrappedFragments = txtMeasurer.WrapMultipleTextFragments(txtRuns, fonts, maxWidth.PixelToPoint());
138+
var wrappedFragments = txtMeasurer.WrapRichText(txtRuns, fonts, maxWidth.PixelToPoint());
144139

145140
Assert.AreEqual(2, wrappedFragments.Count);
146141
Assert.AreEqual("HIJKLMpqrst", wrappedFragments[0]);

0 commit comments

Comments
 (0)