Skip to content

Commit 029e3a7

Browse files
committed
Merge branch 'feature/svg_chart_and_shape' of https://github.com/EPPlusSoftware/EPPlus into feature/svg_chart_and_shape
2 parents 1be9324 + 007f1c0 commit 029e3a7

49 files changed

Lines changed: 1302 additions & 3176 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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.TrueTypeMeasurer;
4-
using EPPlus.Fonts.OpenType.TrueTypeMeasurer.DataHolders;
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Date Author Change
1414
using EPPlus.Export.ImageRenderer;
1515
using EPPlus.Export.ImageRenderer.Utils;
1616
using EPPlus.Fonts.OpenType;
17+
using EPPlus.Fonts.OpenType.Integration;
1718
using EPPlus.Graphics;
1819
using EPPlusImageRenderer.RenderItems;
1920
using OfficeOpenXml;
@@ -35,7 +36,9 @@ internal DrawingBase(ExcelDrawing drawing)
3536

3637
var wb = drawing._drawings.Worksheet.Workbook;
3738
Theme = wb.ThemeManager.GetOrCreateTheme();
38-
TextMeasurer = new FontMeasurerTrueType();
39+
40+
var shaper = OpenTypeFonts.GetTextShaper(Theme.FontScheme.MajorFont[0].Typeface);
41+
TextMeasurer = new OpenTypeFontTextMeasurer(shaper);
3942
}
4043

4144

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

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
using EPPlus.Fonts.OpenType;
22
using EPPlus.Fonts.OpenType.Integration;
33
using EPPlus.Fonts.OpenType.TextShaping;
4-
using EPPlus.Fonts.OpenType.Integration;
5-
using EPPlus.Fonts.OpenType.TextShaping;
6-
using EPPlus.Fonts.OpenType.TrueTypeMeasurer.DataHolders;
74
using EPPlus.Fonts.OpenType.Utils;
85
using EPPlus.Graphics;
96
using EPPlusImageRenderer;
@@ -25,7 +22,7 @@ namespace EPPlus.Export.ImageRenderer.RenderItems.Shared
2522
{
2623
internal abstract class ParagraphItem : RenderItem
2724
{
28-
ITextMeasurerWrap _measurer;
25+
TextLayoutEngine _layout;
2926

3027
double _leftMargin;
3128
double _rightMargin;
@@ -37,7 +34,7 @@ internal abstract class ParagraphItem : RenderItem
3734
List<string> _paragraphLines = new List<string>();
3835
protected List<string> _textRunDisplayText = new List<string>();
3936

40-
TextFragmentCollection _textFragments;
37+
TextFragmentCollectionSimple _textFragments;
4138
List<EPPlus.Fonts.OpenType.Integration.TextFragment> _newTextFragments;
4239
internal protected MeasurementFont _paragraphFont;
4340
internal TextBodyItem ParentTextBody { get; set; }
@@ -56,8 +53,8 @@ public ParagraphItem(TextBodyItem textBody, DrawingBase renderer, BoundingBox pa
5653
var defaultFont = new MeasurementFont { FontFamily = "Aptos Narrow", Size = 11, Style = MeasurementFontStyles.Regular };
5754
_paragraphFont = defaultFont;
5855

59-
_measurer = new FontMeasurerTrueType(defaultFont);
60-
ParagraphLineSpacing = GetParagraphLineSpacingInPoints(100, _measurer);
56+
_layout = OpenTypeFonts.GetTextLayoutEngineForFont(defaultFont);
57+
ParagraphLineSpacing = GetParagraphLineSpacingInPoints(100, (TextShaper)OpenTypeFonts.GetShaperForFont(defaultFont), defaultFont.Size);
6158
}
6259

6360
public ParagraphItem(TextBodyItem textBody, DrawingBase renderer, BoundingBox parent, ExcelDrawingParagraph p, string textIfEmpty = null) : base(renderer, parent)
@@ -140,45 +137,42 @@ public ParagraphItem(TextBodyItem textBody, DrawingBase renderer, BoundingBox pa
140137
Bounds.Width = parent.Width - _rightMargin - _leftMargin;
141138
}
142139

140+
//---Initialize / calculate lines and runs---
141+
//measurer must be set before AddLinesAndRichText
142+
_paragraphFont = p.DefaultRunProperties.GetMeasureFont();
143+
143144
//---Get measurer---
144-
_measurer = p._prd.Package.Settings.TextSettings.GenericTextMeasurerTrueType;
145+
_layout = OpenTypeFonts.GetTextLayoutEngineForFont(_paragraphFont);
145146

146147
//---Calculate linespacing---
147148
int numLines = _paragraphLines.Count;
148149
_lsType = p.LineSpacing.LineSpacingType;
149-
ParagraphLineSpacing = GetParagraphLineSpacingInPoints(p.LineSpacing.Value, _measurer);
150-
151-
//---Initialize / calculate lines and runs---
152-
//measurer must be set before AddLinesAndRichText
153-
_paragraphFont = p.DefaultRunProperties.GetMeasureFont();
154-
_measurer.SetFont(_paragraphFont);
150+
ParagraphLineSpacing = GetParagraphLineSpacingInPoints(p.LineSpacing.Value,
151+
(TextShaper) OpenTypeFonts.GetShaperForFont(_paragraphFont),
152+
_paragraphFont.Size);
155153

156154
AddLinesAndTextRuns(p, textIfEmpty);
157155
}
158156

159-
private double GetParagraphLineSpacingInPoints(double spacingValue, ITextMeasurerWrap fmExact)
157+
private double GetParagraphLineSpacingInPoints(double spacingValue, TextShaper fmExact, float fontSize)
160158
{
161159
if (_lsType == eDrawingTextLineSpacing.Exactly)
162160
{
163161
if (IsFirstParagraph)
164162
{
165163
_lineSpacingAscendantOnly = spacingValue;
166-
_lineSpacingAscendantOnly = spacingValue;
167164
}
168165
return spacingValue;
169-
return spacingValue;
170166
}
171167
else
172168
{
173169
var multiplier = (spacingValue / 100);
174170
_lsMultiplier = multiplier;
175171
if (IsFirstParagraph)
176172
{
177-
_lineSpacingAscendantOnly = multiplier * fmExact.GetBaseLine();
178-
_lineSpacingAscendantOnly = multiplier * fmExact.GetBaseLine();
173+
_lineSpacingAscendantOnly = multiplier * fmExact.GetAscentInPoints(fontSize);
179174
}
180-
return multiplier * fmExact.GetSingleLineSpacing();
181-
return multiplier * fmExact.GetSingleLineSpacing();
175+
return multiplier * fmExact.GetLineHeightInPoints(fontSize);
182176
}
183177
}
184178

@@ -201,8 +195,9 @@ public void AddText(string text, double prevWidth)
201195
}
202196
public void AddText(string text, ExcelTextFont font, bool isOld)
203197
{
204-
var measurer = new FontMeasurerTrueType();
205-
var displayText = measurer.MeasureAndWrapText(text, font.GetMeasureFont(), ParentTextBody.MaxWidth);
198+
var mf = font.GetMeasureFont();
199+
var measurer = OpenTypeFonts.GetTextLayoutEngineForFont(mf);
200+
var displayText = measurer.WrapText(text, mf.Size, ParentTextBody.MaxWidth);
206201
var container = CreateTextRun(text, font, Bounds, string.Join("\r\n", displayText.ToArray()));
207202
//container.BaseLineSpacing = _lineSpacingAscendantOnly;
208203
//container.LineSpacingPerNewLine = _lsMultiplier.Value * _measurer.GetSingleLineSpacing().PointToPixel(true);
@@ -214,7 +209,8 @@ public void AddText(string text, ExcelTextFont font, bool isOld)
214209

215210
public void AddText(string text, ExcelTextFont font, double prevWidth)
216211
{
217-
var measurer = new FontMeasurerTrueType();
212+
var mf = font.GetMeasureFont();
213+
var measurer = OpenTypeFonts.GetTextLayoutEngineForFont(mf);
218214
//var displayText = measurer.MeasureAndWrapTextLines(text, font.GetMeasureFont(), ParentTextBody.MaxWidth);
219215

220216
var container = CreateTextRun(text, font, Bounds, text);
@@ -278,9 +274,14 @@ internal void AddLinesAndTextRuns(string textIfEmpty)
278274
GenerateTextFragments(textIfEmpty);
279275
var lines = new List<TextLineSimple>();
280276

281-
var measurer = new FontMeasurerTrueType();
277+
var measurer = OpenTypeFonts.GetTextLayoutEngineForFont(_paragraphFont);
282278
var maxWidth = ParentTextBody.MaxWidth + 0.001; //TODO: fix for equal width issue;
283-
lines = measurer.MeasureAndWrapTextLines_New(textIfEmpty, _paragraphFont, maxWidth);
279+
280+
List<TextFragment> textFragments = new List<TextFragment>();
281+
var fragment = new TextFragment() { Font = _paragraphFont, Text = textIfEmpty };
282+
textFragments.Add(fragment);
283+
284+
lines = measurer.WrapRichTextLines(textFragments, maxWidth);
284285
bool lineSpacingIsExact = _lsMultiplier.HasValue == false;
285286
double runLineSpacing = 0;
286287
double greatestWidth = 0;
@@ -378,9 +379,11 @@ private void AddLinesAndTextRuns(ExcelDrawingParagraph p, string textIfEmpty)
378379

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

385388
//Bounds.Width = maxWidth;
386389
if (HorizontalAlignment != eTextAlignment.Center)
@@ -484,13 +487,15 @@ private void AddLinesAndTextRuns(ExcelDrawingParagraph p, string textIfEmpty)
484487

485488
List<TextLineSimple> WrapToSimpleTextLines(ExcelDrawingParagraph p)
486489
{
487-
var ttMeasurer = (FontMeasurerTrueType)_measurer;
488-
489490
if (_newTextFragments.Count > 0)
490491
{
491-
ttMeasurer.SetFont(_newTextFragments[0].Font);
492+
if(_layout == null)
493+
{
494+
_layout = OpenTypeFonts.GetTextLayoutEngineForFont((_newTextFragments[0].Font));
495+
}
496+
492497
var maxWidthPoints = Math.Round(ParentTextBody.MaxWidth, 0, MidpointRounding.AwayFromZero);
493-
return ttMeasurer.WrapMultipleTextFragmentsToTextLines_New(_newTextFragments, maxWidthPoints);
498+
return _layout.WrapRichTextLines(_newTextFragments, maxWidthPoints);
494499
}
495500
return new List<TextLineSimple>();
496501
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using OfficeOpenXml.Drawing;
88
using OfficeOpenXml.Drawing.Theme;
99
using OfficeOpenXml.Interfaces.Drawing.Text;
10+
using OfficeOpenXml.Interfaces.Fonts;
1011
using OfficeOpenXml.Style;
1112
using OfficeOpenXml.Utils;
1213
using System;
@@ -174,7 +175,8 @@ internal virtual void ImportTextBody(ExcelTextBody body, ExcelHorizontalAlignmen
174175

175176
Bounds.Top = GetAlignmentVertical();
176177
}
177-
private double GetParagraphAscendantSpacingInPixels(eDrawingTextLineSpacing lineSpacingType, double spacingValue, ITextMeasurerWrap fmExact, out double multiplier)
178+
179+
private double GetParagraphAscendantSpacingInPixels(eDrawingTextLineSpacing lineSpacingType, double spacingValue, ITextShaper fmExact, float fontSize, out double multiplier)
178180
{
179181
if (lineSpacingType == eDrawingTextLineSpacing.Exactly)
180182
{
@@ -184,7 +186,7 @@ private double GetParagraphAscendantSpacingInPixels(eDrawingTextLineSpacing line
184186
else
185187
{
186188
multiplier = (spacingValue / 100);
187-
return multiplier * fmExact.GetBaseLine().PointToPixel();
189+
return multiplier * fmExact.GetAscentInPoints(fontSize).PointToPixel();
188190
}
189191
}
190192

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);
@@ -305,8 +309,11 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
305309
var ret = new List<SvgTextBox>();
306310
if (Axis.LabelPosition == eTickLabelPosition.None) return ret;
307311

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

0 commit comments

Comments
 (0)