First Step to make CFonts threadsave
This commit is contained in:
1 parent
32241a91dc
commit
7f60e6f321
5 files changed
+135
-138
No files matched your search
@@ -19,54 +19,69 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Xml.Serialization;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
|
||||
namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
class CFont : IDisposable
|
||||
class CFontStyle : IDisposable
|
||||
{
|
||||
private readonly Dictionary<char, CGlyph> _Glyphs;
|
||||
private readonly string _FilePath;
|
||||
private readonly EStyle _Style;
|
||||
public readonly float Outline; //0..1, 0=not outline 1=100% outline
|
||||
public readonly SColorF OutlineColor;
|
||||
private readonly float _MaxGlyphHeight;
|
||||
private readonly Dictionary<char, CGlyph> _Glyphs = new Dictionary<char, CGlyph>();
|
||||
private PrivateFontCollection _Fonts;
|
||||
private FontFamily _Family;
|
||||
private readonly float _MaxGlyphHeight;
|
||||
|
||||
private readonly string _FilePath;
|
||||
|
||||
private bool _Disposed;
|
||||
|
||||
public CFont(string file)
|
||||
public CFontStyle(string file, EStyle style, float outline, SColorF outlineColor)
|
||||
{
|
||||
_FilePath = file;
|
||||
|
||||
_Glyphs = new Dictionary<char, CGlyph>();
|
||||
_Style = style;
|
||||
Outline = outline;
|
||||
OutlineColor = outlineColor;
|
||||
|
||||
switch (CConfig.TextureQuality)
|
||||
{
|
||||
case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
|
||||
_MaxGlyphHeight = 25f;
|
||||
_MaxGlyphHeight = 20f;
|
||||
break;
|
||||
case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
|
||||
_MaxGlyphHeight = 50f;
|
||||
_MaxGlyphHeight = 40f;
|
||||
break;
|
||||
case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
|
||||
_MaxGlyphHeight = 100f;
|
||||
_MaxGlyphHeight = 60f;
|
||||
break;
|
||||
case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
|
||||
_MaxGlyphHeight = 200f;
|
||||
_MaxGlyphHeight = 80f;
|
||||
break;
|
||||
case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
|
||||
_MaxGlyphHeight = 400f;
|
||||
break;
|
||||
default:
|
||||
_MaxGlyphHeight = 100f;
|
||||
break;
|
||||
default:
|
||||
_MaxGlyphHeight = 60f;
|
||||
break;
|
||||
}
|
||||
_MaxGlyphHeight = 50;
|
||||
}
|
||||
|
||||
public Font GetFont()
|
||||
private FontStyle _GetSystemFontStyle()
|
||||
{
|
||||
switch (_Style)
|
||||
{
|
||||
case EStyle.Normal:
|
||||
return FontStyle.Regular;
|
||||
case EStyle.Italic:
|
||||
return FontStyle.Italic;
|
||||
case EStyle.Bold:
|
||||
return FontStyle.Bold;
|
||||
case EStyle.BoldItalic:
|
||||
return FontStyle.Bold | FontStyle.Italic;
|
||||
}
|
||||
throw new ArgumentException("Invalid style: " + _Style);
|
||||
}
|
||||
|
||||
public Font GetSystemFont(float height)
|
||||
{
|
||||
if (_Fonts == null)
|
||||
{
|
||||
@@ -81,99 +96,83 @@ namespace Vocaluxe.Base.Fonts
|
||||
CLog.LogError("Error opening font file " + _FilePath + ": " + e.Message);
|
||||
}
|
||||
}
|
||||
return new Font(_Family, CFonts.Height, CFonts.GetFontStyle(), GraphicsUnit.Pixel);
|
||||
return new Font(_Family, height, _GetSystemFontStyle(), GraphicsUnit.Pixel);
|
||||
}
|
||||
|
||||
public void DrawGlyph(char chr, float x, float y, float z, SColorF color)
|
||||
public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color)
|
||||
{
|
||||
CTexture texture;
|
||||
SRectF rect;
|
||||
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
|
||||
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
|
||||
CDraw.DrawTexture(texture, rect, color);
|
||||
}
|
||||
|
||||
public void DrawGlyph(char chr, float x, float y, float z, SColorF color, float begin, float end)
|
||||
public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color, float begin, float end)
|
||||
{
|
||||
CTexture texture;
|
||||
SRectF rect;
|
||||
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
|
||||
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
|
||||
CDraw.DrawTexture(texture, rect, color, begin, end);
|
||||
}
|
||||
|
||||
public void DrawGlyphReflection(char chr, float x, float y, float z, SColorF color, float rspace, float rheight)
|
||||
public void DrawGlyphReflection(char chr, float fontHeight, float x, float y, float z, SColorF color, float rspace, float rheight)
|
||||
{
|
||||
CTexture texture;
|
||||
SRectF rect;
|
||||
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
|
||||
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
|
||||
CDraw.DrawTextureReflection(texture, rect, color, rect, rspace, rheight);
|
||||
}
|
||||
|
||||
public float GetWidth(char chr)
|
||||
public float GetWidth(char chr, float height)
|
||||
{
|
||||
return GetOrAddGlyph(chr).Width;
|
||||
return GetOrAddGlyph(chr, height).GetWidth(height);
|
||||
}
|
||||
|
||||
public float GetHeight(char chr)
|
||||
public float GetHeight(char chr, float height)
|
||||
{
|
||||
return GetOrAddGlyph(chr).Height;
|
||||
return GetOrAddGlyph(chr, height).GetHeight(height);
|
||||
}
|
||||
|
||||
public CGlyph GetOrAddGlyph(char chr)
|
||||
public CGlyph GetOrAddGlyph(char chr, float height)
|
||||
{
|
||||
CGlyph glyph;
|
||||
if (!_Glyphs.TryGetValue(chr, out glyph))
|
||||
{
|
||||
glyph = new CGlyph(chr, _MaxGlyphHeight);
|
||||
float maxHeight = (_MaxGlyphHeight + 50 >= height) ? _MaxGlyphHeight : (float)Math.Round(height / 50) * 50;
|
||||
glyph = new CGlyph(chr, this, maxHeight);
|
||||
_Glyphs.Add(chr, glyph);
|
||||
}
|
||||
if (glyph.MaxHeight + 50 < CFonts.Height)
|
||||
if (glyph.MaxHeight + 50 < height)
|
||||
{
|
||||
glyph.UnloadTexture();
|
||||
glyph = new CGlyph(chr, (float)Math.Round(CFonts.Height / 50) * 50);
|
||||
glyph = new CGlyph(chr, this, (float)Math.Round(height / 50) * 50);
|
||||
_Glyphs[chr] = glyph;
|
||||
}
|
||||
return glyph;
|
||||
}
|
||||
|
||||
public void UnloadGlyphs()
|
||||
private void _UnloadGlyphs()
|
||||
{
|
||||
foreach (CGlyph glyph in _Glyphs.Values)
|
||||
glyph.UnloadTexture();
|
||||
_Glyphs.Clear();
|
||||
}
|
||||
|
||||
private bool _Disposed;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_Disposed)
|
||||
{
|
||||
if (_Fonts != null)
|
||||
{
|
||||
_Fonts.Dispose();
|
||||
UnloadGlyphs();
|
||||
_Fonts = null;
|
||||
}
|
||||
_UnloadGlyphs();
|
||||
_Disposed = true;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
struct SFontFamily
|
||||
{
|
||||
public string Name;
|
||||
|
||||
public int PartyModeID;
|
||||
public string ThemeName;
|
||||
public string Folder;
|
||||
|
||||
public string FileNormal;
|
||||
public string FileItalic;
|
||||
public string FileBold;
|
||||
public string FileBoldItalic;
|
||||
|
||||
public float Outline; //0..1, 0=not outline 1=100% outline
|
||||
public SColorF OutlineColor;
|
||||
|
||||
public CFont Normal;
|
||||
public CFont Italic;
|
||||
public CFont Bold;
|
||||
public CFont BoldItalic;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
@@ -25,6 +26,38 @@ using VocaluxeLib.Menu;
|
||||
|
||||
namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
struct SFont
|
||||
{
|
||||
public string Name;
|
||||
public EStyle Style;
|
||||
public float Height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struct used for describing a font family (a type of text with 4 different styles)
|
||||
/// </summary>
|
||||
struct SFontFamily
|
||||
{
|
||||
public string Name;
|
||||
|
||||
public int PartyModeID;
|
||||
public string ThemeName;
|
||||
public string Folder;
|
||||
|
||||
public string FileNormal;
|
||||
public string FileItalic;
|
||||
public string FileBold;
|
||||
public string FileBoldItalic;
|
||||
|
||||
public float Outline; //0..1, 0=not outline 1=100% outline
|
||||
public SColorF OutlineColor;
|
||||
|
||||
public CFontStyle Normal;
|
||||
public CFontStyle Italic;
|
||||
public CFontStyle Bold;
|
||||
public CFontStyle BoldItalic;
|
||||
}
|
||||
|
||||
static class CFonts
|
||||
{
|
||||
private static bool _IsInitialized;
|
||||
@@ -42,16 +75,6 @@ namespace Vocaluxe.Base.Fonts
|
||||
set { _Height = value < 0f ? 0f : value; }
|
||||
}
|
||||
|
||||
public static float Outline
|
||||
{
|
||||
get { return _FontFamilies[_CurrentFont].Outline; }
|
||||
}
|
||||
|
||||
public static SColorF OutlineColor
|
||||
{
|
||||
get { return _FontFamilies[_CurrentFont].OutlineColor; }
|
||||
}
|
||||
|
||||
public static bool Init()
|
||||
{
|
||||
if (_IsInitialized)
|
||||
@@ -74,12 +97,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
_IsInitialized = false;
|
||||
}
|
||||
|
||||
public static Font GetFont()
|
||||
{
|
||||
return _GetCurrentFont().GetFont();
|
||||
}
|
||||
|
||||
private static CFont _GetCurrentFont()
|
||||
private static CFontStyle _GetCurrentFont()
|
||||
{
|
||||
switch (Style)
|
||||
{
|
||||
@@ -92,8 +110,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
case EStyle.BoldItalic:
|
||||
return _FontFamilies[_CurrentFont].BoldItalic;
|
||||
}
|
||||
//Just in case...
|
||||
return _FontFamilies[_CurrentFont].Normal;
|
||||
throw new ArgumentException("Invalid Style: " + Style);
|
||||
}
|
||||
|
||||
#region DrawText
|
||||
@@ -125,13 +142,13 @@ namespace Vocaluxe.Base.Fonts
|
||||
return;
|
||||
|
||||
Height = h;
|
||||
CFont font = _GetCurrentFont();
|
||||
CFontStyle font = _GetCurrentFont();
|
||||
|
||||
float dx = x;
|
||||
foreach (char chr in text)
|
||||
{
|
||||
font.DrawGlyph(chr, dx, y, z, color);
|
||||
dx += font.GetWidth(chr);
|
||||
font.DrawGlyph(chr, h, dx, y, z, color);
|
||||
dx += font.GetWidth(chr, h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +161,13 @@ namespace Vocaluxe.Base.Fonts
|
||||
return;
|
||||
|
||||
Height = h;
|
||||
CFont font = _GetCurrentFont();
|
||||
CFontStyle font = _GetCurrentFont();
|
||||
|
||||
float dx = x;
|
||||
foreach (char chr in text)
|
||||
{
|
||||
font.DrawGlyphReflection(chr, dx, y, z, color, rspace, rheight);
|
||||
dx += font.GetWidth(chr);
|
||||
font.DrawGlyphReflection(chr, h, dx, y, z, color, rspace, rheight);
|
||||
dx += font.GetWidth(chr, h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,11 +189,11 @@ namespace Vocaluxe.Base.Fonts
|
||||
float x1 = x + w * begin;
|
||||
float x2 = x + w * end;
|
||||
|
||||
CFont font = _GetCurrentFont();
|
||||
CFontStyle font = _GetCurrentFont();
|
||||
|
||||
foreach (char chr in text)
|
||||
{
|
||||
float w2 = font.GetWidth(chr);
|
||||
float w2 = font.GetWidth(chr, h);
|
||||
float b = (x1 - dx) / w2;
|
||||
|
||||
if (b < 1f)
|
||||
@@ -188,7 +205,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
if (e > 1f)
|
||||
e = 1f;
|
||||
font.DrawGlyph(chr, dx, y, z, color, b, e);
|
||||
font.DrawGlyph(chr, h, dx, y, z, color, b, e);
|
||||
}
|
||||
}
|
||||
dx += w2;
|
||||
@@ -196,23 +213,6 @@ namespace Vocaluxe.Base.Fonts
|
||||
}
|
||||
#endregion DrawText
|
||||
|
||||
public static FontStyle GetFontStyle()
|
||||
{
|
||||
switch (Style)
|
||||
{
|
||||
case EStyle.Normal:
|
||||
return FontStyle.Regular;
|
||||
case EStyle.Italic:
|
||||
return FontStyle.Italic;
|
||||
case EStyle.Bold:
|
||||
return FontStyle.Bold;
|
||||
case EStyle.BoldItalic:
|
||||
return FontStyle.Bold | FontStyle.Italic;
|
||||
default:
|
||||
return FontStyle.Regular;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetFont(string fontName)
|
||||
{
|
||||
int index = _GetPartyFontIndex(fontName, PartyModeID);
|
||||
@@ -259,14 +259,14 @@ namespace Vocaluxe.Base.Fonts
|
||||
|
||||
public static float GetTextWidth(string text)
|
||||
{
|
||||
CFont font = _GetCurrentFont();
|
||||
return text.Sum(chr => font.GetWidth(chr));
|
||||
CFontStyle font = _GetCurrentFont();
|
||||
return text.Sum(chr => font.GetWidth(chr, Height));
|
||||
}
|
||||
|
||||
public static float GetTextHeight(string text)
|
||||
{
|
||||
CFont font = _GetCurrentFont();
|
||||
return text == "" ? 0 : text.Select(font.GetHeight).Max();
|
||||
CFontStyle font = _GetCurrentFont();
|
||||
return text == "" ? 0 : text.Select(chr => font.GetHeight(chr, Height)).Max();
|
||||
}
|
||||
|
||||
private static int _GetFontIndex(string fontName)
|
||||
@@ -365,10 +365,10 @@ namespace Vocaluxe.Base.Fonts
|
||||
|
||||
if (ok)
|
||||
{
|
||||
sf.Normal = new CFont(Path.Combine(fontFolder, sf.Folder, sf.FileNormal));
|
||||
sf.Italic = new CFont(Path.Combine(fontFolder, sf.Folder, sf.FileItalic));
|
||||
sf.Bold = new CFont(Path.Combine(fontFolder, sf.Folder, sf.FileBold));
|
||||
sf.BoldItalic = new CFont(Path.Combine(fontFolder, sf.Folder, sf.FileBoldItalic));
|
||||
sf.Normal = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileNormal), EStyle.Normal, sf.Outline, sf.OutlineColor);
|
||||
sf.Italic = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileItalic), EStyle.Italic, sf.Outline, sf.OutlineColor);
|
||||
sf.Bold = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileBold), EStyle.Bold, sf.Outline, sf.OutlineColor);
|
||||
sf.BoldItalic = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileBoldItalic), EStyle.BoldItalic, sf.Outline, sf.OutlineColor);
|
||||
_FontFamilies.Add(sf);
|
||||
}
|
||||
else
|
||||
@@ -455,13 +455,13 @@ namespace Vocaluxe.Base.Fonts
|
||||
foreach (char chr in text)
|
||||
{
|
||||
Style = EStyle.Normal;
|
||||
_FontFamilies[_CurrentFont].Normal.GetOrAddGlyph(chr);
|
||||
_FontFamilies[_CurrentFont].Normal.GetOrAddGlyph(chr, Height);
|
||||
Style = EStyle.Bold;
|
||||
_FontFamilies[_CurrentFont].Bold.GetOrAddGlyph(chr);
|
||||
_FontFamilies[_CurrentFont].Bold.GetOrAddGlyph(chr, Height);
|
||||
Style = EStyle.Italic;
|
||||
_FontFamilies[_CurrentFont].Italic.GetOrAddGlyph(chr);
|
||||
_FontFamilies[_CurrentFont].Italic.GetOrAddGlyph(chr, Height);
|
||||
Style = EStyle.BoldItalic;
|
||||
_FontFamilies[_CurrentFont].BoldItalic.GetOrAddGlyph(chr);
|
||||
_FontFamilies[_CurrentFont].BoldItalic.GetOrAddGlyph(chr, Height);
|
||||
}
|
||||
}
|
||||
Style = EStyle.Normal;
|
||||
|
||||
@@ -36,26 +36,13 @@ namespace Vocaluxe.Base.Fonts
|
||||
private readonly RectangleF _DrawBounding;
|
||||
public readonly float MaxHeight;
|
||||
|
||||
public float Width
|
||||
{
|
||||
get { return _BoundingBox.Width * _GetFactor(); }
|
||||
}
|
||||
|
||||
public float Height
|
||||
{
|
||||
get { return _BoundingBox.Height * _GetFactor(); }
|
||||
}
|
||||
|
||||
public CGlyph(char chr, float maxHeight)
|
||||
public CGlyph(char chr, CFontStyle fontStyle, float maxHeight)
|
||||
{
|
||||
MaxHeight = maxHeight;
|
||||
float oldHeight = CFonts.Height;
|
||||
float outline = CFonts.Outline;
|
||||
float outlineSize = outline * maxHeight;
|
||||
float outlineSize = fontStyle.Outline * maxHeight;
|
||||
string chrString = chr.ToString();
|
||||
|
||||
CFonts.Height = maxHeight;
|
||||
Font fo = CFonts.GetFont();
|
||||
Font fo = fontStyle.GetSystemFont(maxHeight);
|
||||
SizeF fullSize;
|
||||
Size bmpSize;
|
||||
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
|
||||
@@ -105,7 +92,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
float emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
|
||||
path.AddString(chrString, fo.FontFamily, (int)fo.Style, emSize, point, new StringFormat());
|
||||
|
||||
using (var pen = new Pen(CFonts.OutlineColor.AsColor(), outlineSize))
|
||||
using (var pen = new Pen(fontStyle.OutlineColor.AsColor(), outlineSize))
|
||||
{
|
||||
pen.LineJoin = LineJoin.Round;
|
||||
g.DrawPath(pen, path);
|
||||
@@ -134,7 +121,6 @@ namespace Vocaluxe.Base.Fonts
|
||||
}
|
||||
}
|
||||
}
|
||||
CFonts.Height = oldHeight;
|
||||
}
|
||||
|
||||
public void UnloadTexture()
|
||||
@@ -142,15 +128,25 @@ namespace Vocaluxe.Base.Fonts
|
||||
CDraw.RemoveTexture(ref _Texture);
|
||||
}
|
||||
|
||||
private float _GetFactor()
|
||||
private float _GetFactor(float fontHeight)
|
||||
{
|
||||
return CFonts.Height / _BoundingBox.Height;
|
||||
return fontHeight / _BoundingBox.Height;
|
||||
}
|
||||
|
||||
public void GetTextureAndRect(float x, float y, float z, out CTexture texture, out SRectF rect)
|
||||
public float GetWidth(float fontHeight)
|
||||
{
|
||||
return _BoundingBox.Width * _GetFactor(fontHeight);
|
||||
}
|
||||
|
||||
public float GetHeight(float fontHeight)
|
||||
{
|
||||
return _BoundingBox.Height * _GetFactor(fontHeight);
|
||||
}
|
||||
|
||||
public void GetTextureAndRect(float fontHeight, float x, float y, float z, out CTexture texture, out SRectF rect)
|
||||
{
|
||||
texture = _Texture;
|
||||
float factor = _GetFactor();
|
||||
float factor = _GetFactor(fontHeight);
|
||||
x += _DrawBounding.X * factor;
|
||||
y += _DrawBounding.Y * factor;
|
||||
float h = _DrawBounding.Height * factor;
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
<Compile Include="Base\CDraw.cs" />
|
||||
<Compile Include="Lib\Sound\Playback\PortAudio\CPt1.cs" />
|
||||
<Compile Include="Lib\Sound\Playback\PortAudio\CSyncTimer.cs" />
|
||||
<Compile Include="Base\Fonts\CFont.cs" />
|
||||
<Compile Include="Base\Fonts\CFontStyle.cs" />
|
||||
<Compile Include="Base\CGame.cs" />
|
||||
<Compile Include="Base\CController.cs" />
|
||||
<Compile Include="Base\CLanguage.cs" />
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using VocaluxeLib.Songs;
|
||||
@@ -48,6 +49,7 @@ namespace VocaluxeLib
|
||||
A = color.A;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public Color AsColor()
|
||||
{
|
||||
return Color.FromArgb((int)(A * 255), (int)(R * 255), (int)(G * 255), (int)(B * 255));
|
||||
|
||||
Reference in new issue
Block a user