diff --git a/Vocaluxe/Base/Fonts/CFont.cs b/Vocaluxe/Base/Fonts/CFontStyle.cs similarity index 54% rename from Vocaluxe/Base/Fonts/CFont.cs rename to Vocaluxe/Base/Fonts/CFontStyle.cs index 19e26c6e..360323ad 100644 --- a/Vocaluxe/Base/Fonts/CFont.cs +++ b/Vocaluxe/Base/Fonts/CFontStyle.cs @@ -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 _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 _Glyphs = new Dictionary(); 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(); + _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; - } } \ No newline at end of file diff --git a/Vocaluxe/Base/Fonts/CFonts.cs b/Vocaluxe/Base/Fonts/CFonts.cs index e599e715..2a9525c1 100644 --- a/Vocaluxe/Base/Fonts/CFonts.cs +++ b/Vocaluxe/Base/Fonts/CFonts.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #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; + } + + /// + /// Struct used for describing a font family (a type of text with 4 different styles) + /// + 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; diff --git a/Vocaluxe/Base/Fonts/CGlyph.cs b/Vocaluxe/Base/Fonts/CGlyph.cs index 087fa4f2..dcc2bff3 100644 --- a/Vocaluxe/Base/Fonts/CGlyph.cs +++ b/Vocaluxe/Base/Fonts/CGlyph.cs @@ -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; diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index b8276467..6f34656a 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -241,7 +241,7 @@ - + diff --git a/VocaluxeLib/Structs.cs b/VocaluxeLib/Structs.cs index d0c73628..f2b09991 100644 --- a/VocaluxeLib/Structs.cs +++ b/VocaluxeLib/Structs.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));