Skip to content

Commit 3ca576d

Browse files
committed
Merge branch 'refactor/upgrade-opentypefont' into feature/svg_chart_and_shape
2 parents cdcec2e + dd8d23d commit 3ca576d

13 files changed

Lines changed: 413 additions & 174 deletions

File tree

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

Lines changed: 149 additions & 44 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);
@@ -304,8 +308,11 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
304308
var ret = new List<SvgTextBox>();
305309
if (Axis.LabelPosition == eTickLabelPosition.None) return ret;
306310

307-
var tm = Chart.WorkSheet._package.Settings.TextSettings.GenericTextMeasurerTrueType;
308311
var mf = Axis.Font.GetMeasureFont();
312+
313+
var shaper = OpenTypeFonts.GetShaperForFont(mf);
314+
var tm = new OpenTypeFontTextMeasurer(shaper);
315+
309316
var axisStyle = GetAxisStyleEntry();
310317
double maxWidth, maxHeight;
311318
if(Axis.AxisPosition==eAxisPosition.Left || Axis.AxisPosition == eAxisPosition.Right)

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

Lines changed: 15 additions & 2 deletions
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;
@@ -98,16 +103,24 @@ private SvgRenderRectItem GetLegendRectangleAndEntrySize(SvgChart sc, ExcelChart
98103
var text = s.GetHeaderText(index);
99104
var entry = l.Entries.FirstOrDefault(x => x.Index == index);
100105
ExcelTextFont font;
106+
MeasurementFont mf;
101107
if(entry==null || entry.Font.IsEmpty)
102108
{
103109
font = l.Font;
110+
mf = l.Font.GetMeasureFont();
104111
}
105112
else
106113
{
107114
font = entry.Font;
115+
mf = entry.Font.GetMeasureFont();
116+
}
117+
118+
if(_ttMeasurer == null)
119+
{
120+
_ttMeasurer = new OpenTypeFontTextMeasurer(OpenTypeFonts.GetShaperForFont(mf));
108121
}
109122

110-
var tm = _ttMeasurer.MeasureText(text, font.GetMeasureFont());
123+
var tm = _ttMeasurer.MeasureText(text, mf);
111124
_seriesHeadersMeasure.Add(tm);
112125

113126
if(tm.Width > widest)

src/EPPlus.Fonts.OpenType.Tests/TextFragmentCollectionTests.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void MeasureBold()
3737
var maxSizePoints = Math.Round(300d, 0, MidpointRounding.AwayFromZero).PixelToPoint();
3838

3939
var measurer = OpenTypeFonts.GetShaperForFont(font2);
40-
var widthInPoints = measurer.GetDescentInPoints(font2.Size);
40+
var widthInPoints = measurer.ShapeLight(test).GetWidthInPoints(font2.Size);
4141

4242
var inPixels = Math.Round(widthInPoints.PointToPixel(),0,MidpointRounding.AwayFromZero);
4343

@@ -54,8 +54,10 @@ public void MeasureGoudy()
5454
Style = MeasurementFontStyles.Regular
5555
};
5656

57+
var text = "Goudy size";
58+
5759
var measurer = OpenTypeFonts.GetShaperForFont(font5);
58-
var widthInPoints = measurer.GetDescentInPoints(font5.Size);
60+
var widthInPoints = measurer.ShapeLight(text).GetWidthInPoints(16f);
5961

6062
var inPixels = Math.Round(widthInPoints.PointToPixel(), 0, MidpointRounding.AwayFromZero);
6163

@@ -121,25 +123,25 @@ public void MeasureWrappedWidthsWithInternalLineBreaks()
121123

122124
var line1 = wrappedLines[0];
123125

124-
var pixels11 = Math.Round(line1.RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
126+
var pixels11 = Math.Round(line1.LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
125127
var pixelsWholeline1 = Math.Round(line1.Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
126128

127129
Assert.AreEqual(44, pixels11);
128130
Assert.AreEqual(pixels11, pixelsWholeline1);
129131

130132
var line2 = wrappedLines[1];
131133

132-
var pixels21 = Math.Round(line2.RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
134+
var pixels21 = Math.Round(line2.LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
133135
var pixelsWholeline2 = Math.Round(line2.Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
134136

135137
Assert.AreEqual(7, pixels21);
136138
Assert.AreEqual(pixels21, pixelsWholeline2);
137139

138140
var line3 = wrappedLines[2];
139141

140-
var pixels31 = Math.Round(line3.RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
141-
var pixels32 = Math.Round(line3.RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
142-
var pixels33 = Math.Round(line3.RtFragments[2].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
142+
var pixels31 = Math.Round(line3.LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
143+
var pixels32 = Math.Round(line3.LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
144+
var pixels33 = Math.Round(line3.LineFragments[2].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
143145
var pixelsWholeLine3 = Math.Round(line3.Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
144146

145147
//~54 px
@@ -154,8 +156,8 @@ public void MeasureWrappedWidthsWithInternalLineBreaks()
154156

155157
var line4 = wrappedLines[3];
156158

157-
var pixels41 = Math.Round(line4.RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
158-
var pixels42 = Math.Round(line4.RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
159+
var pixels41 = Math.Round(line4.LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
160+
var pixels42 = Math.Round(line4.LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
159161
var pixelsWholeLine4 = Math.Round(line4.Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
160162
//~34 px
161163
Assert.AreEqual(33, pixels41);
@@ -166,8 +168,8 @@ public void MeasureWrappedWidthsWithInternalLineBreaks()
166168

167169
var line5 = wrappedLines[4];
168170

169-
var pixels51 = Math.Round(line5.RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
170-
var pixels52 = Math.Round(line5.RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
171+
var pixels51 = Math.Round(line5.LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
172+
var pixels52 = Math.Round(line5.LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
171173
var pixelsWholeLine5 = Math.Round(line5.Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
172174
Assert.AreEqual(35, pixels51);
173175
//This line does NOT contain a space at the end
@@ -227,9 +229,9 @@ public void MeasureWrappedWidths()
227229

228230
var wrappedLines = ttMeasurer.WrapRichTextLines(textFragments, maxSizePoints);
229231

230-
var pixels1 = Math.Round(wrappedLines[0].RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
231-
var pixels2 = Math.Round(wrappedLines[0].RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
232-
var pixels3 = Math.Round(wrappedLines[0].RtFragments[2].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
232+
var pixels1 = Math.Round(wrappedLines[0].LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
233+
var pixels2 = Math.Round(wrappedLines[0].LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
234+
var pixels3 = Math.Round(wrappedLines[0].LineFragments[2].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
233235
var pixelsWholeLine = Math.Round(wrappedLines[0].Width.PointToPixel(),0, MidpointRounding.AwayFromZero);
234236

235237
//~54 px
@@ -242,8 +244,8 @@ public void MeasureWrappedWidths()
242244
//Total Width: ~140
243245
Assert.AreEqual(140d, pixelsWholeLine);
244246

245-
var pixels21 = Math.Round(wrappedLines[1].RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
246-
var pixels22 = Math.Round(wrappedLines[1].RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
247+
var pixels21 = Math.Round(wrappedLines[1].LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
248+
var pixels22 = Math.Round(wrappedLines[1].LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
247249
var pixelsWholeLine2 = Math.Round(wrappedLines[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
248250
//~34 px
249251
Assert.AreEqual(33, pixels21);
@@ -252,8 +254,8 @@ public void MeasureWrappedWidths()
252254

253255
Assert.AreEqual(281, pixelsWholeLine2);
254256

255-
var pixels31 = Math.Round(wrappedLines[2].RtFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
256-
var pixels32 = Math.Round(wrappedLines[2].RtFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
257+
var pixels31 = Math.Round(wrappedLines[2].LineFragments[0].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
258+
var pixels32 = Math.Round(wrappedLines[2].LineFragments[1].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
257259
var pixelsWholeLine3 = Math.Round(wrappedLines[2].Width.PointToPixel(), 0, MidpointRounding.AwayFromZero);
258260
Assert.AreEqual(35, pixels31);
259261
//This line does NOT contain a space at the end

0 commit comments

Comments
 (0)