44using System . Runtime . InteropServices ;
55using System . Drawing . Text ;
66using System . Drawing ;
7+ using System . Linq ;
78
89namespace FastReport . Utils
910{
@@ -13,8 +14,9 @@ namespace FastReport.Utils
1314 public partial class FRPrivateFontCollection
1415 {
1516 private readonly PrivateFontCollection collection = TypeConverters . FontConverter . PrivateFontCollection ;
16- private Dictionary < string , string > FontFiles = new Dictionary < string , string > ( ) ;
17- private Dictionary < string , MemoryFont > MemoryFonts = new Dictionary < string , MemoryFont > ( ) ;
17+
18+ private readonly Dictionary < string , DictionaryFont > _fonts = new Dictionary < string , DictionaryFont > ( ) ;
19+
1820
1921 internal PrivateFontCollection Collection { get { return collection ; } }
2022
@@ -30,7 +32,7 @@ public partial class FRPrivateFontCollection
3032 /// <returns>true if the font is contained in this collection.</returns>
3133 public bool HasFont ( string fontName )
3234 {
33- return FontFiles . ContainsKey ( fontName ) || MemoryFonts . ContainsKey ( fontName ) ;
35+ return _fonts . ContainsKey ( fontName ) ;
3436 }
3537
3638 /// <summary>
@@ -40,18 +42,11 @@ public bool HasFont(string fontName)
4042 /// <returns>Either FileStream or MemoryStream containing font data.</returns>
4143 public Stream GetFontStream ( string fontName )
4244 {
43- if ( FontFiles . ContainsKey ( fontName ) )
44- {
45- return new FileStream ( FontFiles [ fontName ] , FileMode . Open , FileAccess . Read ) ;
46- }
47- else if ( MemoryFonts . ContainsKey ( fontName ) )
45+ if ( _fonts . TryGetValue ( fontName , out var font ) )
4846 {
49- MemoryFont font = MemoryFonts [ fontName ] ;
50- byte [ ] buffer = new byte [ font . Length ] ;
51- Marshal . Copy ( font . Memory , buffer , 0 , font . Length ) ;
52- return new MemoryStream ( buffer ) ;
47+ return font . GetFontStream ( ) ;
5348 }
54-
49+
5550 return null ;
5651 }
5752
@@ -65,7 +60,8 @@ public bool AddFontFile(string filename)
6560 bool success = false ;
6661 if ( File . Exists ( filename ) )
6762 {
68- if ( ! FontFiles . ContainsValue ( filename ) )
63+ // if (!FontFiles.ContainsValue(filename))
64+ if ( ! _fonts . Values . OfType < FontFromFile > ( ) . Any ( fontFile => fontFile . _filepath == filename ) )
6965 {
7066 collection . AddFontFile ( filename ) ;
7167 RegisterFontInternal ( filename ) ;
@@ -91,6 +87,24 @@ public bool AddFontFile(string filename)
9187 public void AddFontFromStream ( Stream stream )
9288 {
9389 collection . AddFont ( stream ) ;
90+ stream . Position = 0 ;
91+
92+ var fontFamily = Families [ Families . Length - 1 ] ;
93+ string fontName = fontFamily . Name ;
94+
95+ var isBold = fontFamily . IsStyleAvailable ( FontStyle . Bold ) ;
96+ // every time is false
97+ //var isItalic = fontFamily.IsStyleAvailable(FontStyle.Italic);
98+
99+ fontName = fontName + ( isBold ? "-B" : "" ) /*+ (isItalic ? "-I" : "")*/ ;
100+
101+ if ( ! _fonts . ContainsKey ( fontName ) )
102+ {
103+ var ms = new MemoryStream ( ) ;
104+ stream . CopyTo ( ms ) ;
105+ ms . Position = 0 ;
106+ _fonts . Add ( fontName , new FontFromStream ( ms ) ) ;
107+ }
94108 }
95109#endif
96110
@@ -103,21 +117,71 @@ public void AddMemoryFont(IntPtr memory, int length)
103117 {
104118 collection . AddMemoryFont ( memory , length ) ;
105119 string fontName = Families [ Families . Length - 1 ] . Name ;
106- if ( ! FontFiles . ContainsKey ( fontName ) )
107- MemoryFonts . Add ( fontName , new MemoryFont ( memory , length ) ) ;
120+ if ( ! _fonts . ContainsKey ( fontName ) )
121+ _fonts . Add ( fontName , new MemoryFont ( memory , length ) ) ;
108122 }
109123
110- private struct MemoryFont
124+ private abstract class DictionaryFont
111125 {
112- public readonly IntPtr Memory ;
113- public readonly int Length ;
126+ public abstract Stream GetFontStream ( ) ;
127+ }
128+
129+ private sealed class FontFromFile : DictionaryFont
130+ {
131+ internal readonly string _filepath ;
132+
133+ public FontFromFile ( string filepath )
134+ {
135+ _filepath = filepath ;
136+ }
137+
138+ public override Stream GetFontStream ( )
139+ {
140+ return new FileStream ( _filepath , FileMode . Open , FileAccess . Read ) ;
141+ }
142+
143+ public override string ToString ( )
144+ {
145+ return _filepath ;
146+ }
147+ }
148+
149+ private sealed class FontFromStream : DictionaryFont
150+ {
151+ private readonly Stream _stream ;
152+
153+ public FontFromStream ( Stream stream )
154+ {
155+ _stream = stream ;
156+ }
157+
158+ public override Stream GetFontStream ( )
159+ {
160+ var newStream = new MemoryStream ( ) ;
161+ _stream . CopyTo ( newStream ) ;
162+ _stream . Position = 0 ;
163+ newStream . Position = 0 ;
164+ return newStream ;
165+ }
166+ }
167+
168+ private sealed class MemoryFont : DictionaryFont
169+ {
170+ private readonly IntPtr Memory ;
171+ private readonly int Length ;
114172
115173 public MemoryFont ( IntPtr memory , int length )
116174 {
117175 Memory = memory ;
118176 Length = length ;
119177 }
120- }
121178
179+ public override Stream GetFontStream ( )
180+ {
181+ byte [ ] buffer = new byte [ Length ] ;
182+ Marshal . Copy ( Memory , buffer , 0 , Length ) ;
183+ return new MemoryStream ( buffer ) ;
184+ }
185+ }
122186 }
123187}
0 commit comments