diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs
index 79ae5999..008542ef 100644
--- a/Vocaluxe/Base/CDataBase.cs
+++ b/Vocaluxe/Base/CDataBase.cs
@@ -950,7 +950,7 @@ namespace Vocaluxe.Base
reader.Read();
byte[] data = _GetBytes(reader);
reader.Dispose();
- tex = CDraw.EnqueueTexture(w, h, ref data);
+ tex = CDraw.EnqueueTexture(w, h, data);
return true;
}
}
@@ -1000,7 +1000,7 @@ namespace Vocaluxe.Base
origin.Dispose();
}
- tex = CDraw.EnqueueTexture(w, h, ref data);
+ tex = CDraw.EnqueueTexture(w, h, data);
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@w", DbType.Int32).Value = w;
@@ -1180,7 +1180,7 @@ namespace Vocaluxe.Base
result = true;
reader.Read();
byte[] data = _GetBytes(reader);
- tex = CDraw.AddTexture(w, h, ref data);
+ tex = CDraw.AddTexture(w, h, data);
/*using (Bitmap bmp = new Bitmap(w, h))
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs
index aaba1a2f..82c0bdd2 100644
--- a/Vocaluxe/Base/CDraw.cs
+++ b/Vocaluxe/Base/CDraw.cs
@@ -149,19 +149,19 @@ namespace Vocaluxe.Base
return _Draw.AddTexture(texturePath);
}
- public static STexture AddTexture(int w, int h, ref byte[] data)
+ public static STexture AddTexture(int w, int h, byte[] data)
{
- return _Draw.AddTexture(w, h, ref data);
+ return _Draw.AddTexture(w, h, data);
}
- public static STexture EnqueueTexture(int w, int h, ref byte[] data)
+ public static STexture EnqueueTexture(int w, int h, byte[] data)
{
- return _Draw.EnqueueTexture(w, h, ref data);
+ return _Draw.EnqueueTexture(w, h, data);
}
- public static bool UpdateTexture(ref STexture texture, ref byte[] data)
+ public static bool UpdateTexture(ref STexture texture, byte[] data)
{
- return _Draw.UpdateTexture(ref texture, ref data);
+ return _Draw.UpdateTexture(ref texture, data);
}
public static void RemoveTexture(ref STexture texture)
diff --git a/Vocaluxe/Base/Fonts/CFont.cs b/Vocaluxe/Base/Fonts/CFont.cs
new file mode 100644
index 00000000..fc6004f9
--- /dev/null
+++ b/Vocaluxe/Base/Fonts/CFont.cs
@@ -0,0 +1,170 @@
+#region license
+// /*
+// This file is part of Vocaluxe.
+//
+// Vocaluxe is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Vocaluxe is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Vocaluxe. If not, see .
+// */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Text;
+using VocaluxeLib.Menu;
+
+namespace Vocaluxe.Base.Fonts
+{
+ class CFont : IDisposable
+ {
+ private readonly Dictionary _Glyphs;
+ private PrivateFontCollection _Fonts;
+ private FontFamily _Family;
+ private readonly float _MaxGlyphHeight;
+
+ private readonly string _FilePath;
+
+ public CFont(string file)
+ {
+ _FilePath = file;
+
+ _Glyphs = new Dictionary();
+
+ switch (CConfig.TextureQuality)
+ {
+ case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
+ _MaxGlyphHeight = 25f;
+ break;
+ case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
+ _MaxGlyphHeight = 50f;
+ break;
+ case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
+ _MaxGlyphHeight = 100f;
+ break;
+ case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
+ _MaxGlyphHeight = 200f;
+ break;
+ case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
+ _MaxGlyphHeight = 400f;
+ break;
+ default:
+ _MaxGlyphHeight = 100f;
+ break;
+ }
+ }
+
+ public Font GetFont()
+ {
+ if (_Fonts == null)
+ {
+ _Fonts = new PrivateFontCollection();
+ try
+ {
+ _Fonts.AddFontFile(_FilePath);
+ _Family = _Fonts.Families[0];
+ }
+ catch (Exception e)
+ {
+ CLog.LogError("Error opening font file " + _FilePath + ": " + e.Message);
+ }
+ }
+ return new Font(_Family, CFonts.Height, CFonts.GetFontStyle(), GraphicsUnit.Pixel);
+ }
+
+ public void DrawGlyph(char chr, float x, float y, float z, SColorF color)
+ {
+ STexture texture;
+ SRectF rect;
+ GetOrAddGlyph(chr).GetTextureAndRect(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)
+ {
+ STexture texture;
+ SRectF rect;
+ GetOrAddGlyph(chr).GetTextureAndRect(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)
+ {
+ STexture texture;
+ SRectF rect;
+ GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
+ CDraw.DrawTextureReflection(texture, rect, color, rect, rspace, rheight);
+ }
+
+ public float GetWidth(char chr)
+ {
+ return GetOrAddGlyph(chr).Width;
+ }
+
+ public float GetHeight(char chr)
+ {
+ return GetOrAddGlyph(chr).Height;
+ }
+
+ public CGlyph GetOrAddGlyph(char chr)
+ {
+ CGlyph glyph;
+ if (!_Glyphs.TryGetValue(chr, out glyph))
+ {
+ glyph = new CGlyph(chr, _MaxGlyphHeight);
+ _Glyphs.Add(chr, glyph);
+ }
+ return glyph;
+ }
+
+ public void UnloadGlyphs()
+ {
+ //foreach (CGlyph glyph in _Glyphs.Values)
+ // glyph.UnloadTexture();
+ _Glyphs.Clear();
+ }
+
+ public void Dispose()
+ {
+ if (_Fonts != null)
+ {
+ _Fonts.Dispose();
+ _Fonts = null;
+ UnloadGlyphs();
+ }
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ struct SFont
+ {
+ public string Name;
+
+ public bool IsThemeFont;
+ 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
new file mode 100644
index 00000000..99c271a8
--- /dev/null
+++ b/Vocaluxe/Base/Fonts/CFonts.cs
@@ -0,0 +1,503 @@
+#region license
+// /*
+// This file is part of Vocaluxe.
+//
+// Vocaluxe is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Vocaluxe is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Vocaluxe. If not, see .
+// */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using VocaluxeLib.Menu;
+
+namespace Vocaluxe.Base.Fonts
+{
+ static class CFonts
+ {
+ private static readonly XmlWriterSettings _Settings = new XmlWriterSettings();
+
+ private static List _Fonts;
+ private static int _CurrentFont;
+ private static float _Height = 1f;
+
+ public static int PartyModeID { get; set; }
+
+ public static EStyle Style = EStyle.Normal;
+
+ public static float Height
+ {
+ get { return _Height; }
+ set { _Height = value < 0f ? 0f : value; }
+ }
+
+ public static float Outline
+ {
+ get { return _Fonts[_CurrentFont].Outline; }
+ }
+
+ public static SColorF OutlineColor
+ {
+ get { return _Fonts[_CurrentFont].OutlineColor; }
+ }
+
+ public static void Init()
+ {
+ _Settings.Indent = true;
+ _Settings.Encoding = Encoding.UTF8;
+ _Settings.ConformanceLevel = ConformanceLevel.Document;
+
+ _CurrentFont = 0;
+ PartyModeID = -1;
+ _BuildFonts();
+ }
+
+ private static void _BuildFonts()
+ {
+ _Fonts = new List();
+ _CurrentFont = 0;
+
+ _LoadFontList();
+ }
+
+ public static Font GetFont()
+ {
+ return _GetCurrentFont().GetFont();
+ }
+
+ private static CFont _GetCurrentFont()
+ {
+ switch (Style)
+ {
+ case EStyle.Normal:
+ return _Fonts[_CurrentFont].Normal;
+ case EStyle.Italic:
+ return _Fonts[_CurrentFont].Italic;
+ case EStyle.Bold:
+ return _Fonts[_CurrentFont].Bold;
+ case EStyle.BoldItalic:
+ return _Fonts[_CurrentFont].BoldItalic;
+ }
+ //Just in case...
+ return _Fonts[_CurrentFont].Normal;
+ }
+
+ #region DrawText
+ public static void DrawText(string text, int x, int y, int h)
+ {
+ DrawText(text, h, x, y, 0f, new SColorF(0f, 0f, 0f, 1f));
+ }
+
+ public static void DrawText(string text, float x, float y, float z)
+ {
+ DrawText(text, Height, x, y, z, new SColorF(0f, 0f, 0f, 1f));
+ }
+
+ ///
+ /// Draws a text string
+ ///
+ /// The text to be drawn
+ /// The text's x-position
+ /// The text's y-position
+ /// The text's height
+ /// The text's z-position
+ /// The text color
+ public static void DrawText(string text, float h, float x, float y, float z, SColorF color)
+ {
+ if (h <= 0f)
+ return;
+
+ if (text == "")
+ return;
+
+ Height = h;
+ CFont font = _GetCurrentFont();
+
+ float dx = x;
+ foreach (char chr in text)
+ {
+ font.DrawGlyph(chr, dx, y, z, color);
+ dx += font.GetWidth(chr);
+ }
+ }
+
+ public static void DrawTextReflection(string text, float h, float x, float y, float z, SColorF color, float rspace, float rheight)
+ {
+ if (h <= 0f)
+ return;
+
+ if (text == "")
+ return;
+
+ Height = h;
+ CFont font = _GetCurrentFont();
+
+ float dx = x;
+ foreach (char chr in text)
+ {
+ font.DrawGlyphReflection(chr, dx, y, z, color, rspace, rheight);
+ dx += font.GetWidth(chr);
+ }
+ }
+
+ public static void DrawText(string text, float h, float x, float y, float z, SColorF color, float begin, float end)
+ {
+ if (h <= 0f)
+ return;
+
+ if (text == "")
+ return;
+
+ Height = h;
+
+ float dx = x;
+ float w = GetTextWidth(text);
+ if (w <= 0f)
+ return;
+
+ float x1 = x + w * begin;
+ float x2 = x + w * end;
+
+ CFont font = _GetCurrentFont();
+
+ foreach (char chr in text)
+ {
+ float w2 = font.GetWidth(chr);
+ float b = (x1 - dx) / w2;
+
+ if (b < 1f)
+ {
+ if (b < 0f)
+ b = 0f;
+ float e = (x2 - dx) / w2;
+ if (e > 0f)
+ {
+ if (e > 1f)
+ e = 1f;
+ font.DrawGlyph(chr, dx, y, z, color, b, e);
+ }
+ }
+ dx += w2;
+ }
+ }
+ #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(PartyModeID, fontName);
+ if (index < 0)
+ index = _GetThemeFontIndex(CConfig.Theme, fontName);
+ if (index < 0)
+ index = _GetFontIndex(fontName);
+ if (index >= 0)
+ _CurrentFont = index;
+ }
+
+ ///
+ /// Calculates the bounds for a CText object
+ ///
+ /// The CText object of which the bounds should be calculated for
+ /// RectangleF object containing the bounds
+ public static RectangleF GetTextBounds(CText text)
+ {
+ return GetTextBounds(text, text.Height);
+ }
+
+ ///
+ /// Calculates the bounds for a CText object
+ ///
+ /// The CText object of which the bounds should be calculated for
+ /// The height of the CText object
+ /// RectangleF object containing the bounds
+ public static RectangleF GetTextBounds(CText text, float height)
+ {
+ float oldHeight = Height;
+ int oldFont = _CurrentFont;
+ EStyle oldStyle = Style;
+ Height = height;
+ SetFont(text.Font);
+ Style = text.Style;
+ var result = new RectangleF(text.X, text.Y, GetTextWidth(CLanguage.Translate(text.Text, text.TranslationID)),
+ GetTextHeight(CLanguage.Translate(text.Text, text.TranslationID)));
+ //restore old values
+ Height = oldHeight;
+ _CurrentFont = oldFont;
+ Style = oldStyle;
+ return result;
+ }
+
+ public static float GetTextWidth(string text)
+ {
+ CFont font = _GetCurrentFont();
+ return text.Sum(chr => font.GetWidth(chr));
+ }
+
+ public static float GetTextHeight(string text)
+ {
+ //return TextRenderer.MeasureText(text, GetFont()).Height;
+ CFont font = _GetCurrentFont();
+ return text == "" ? 0 : text.Select(font.GetHeight).Max();
+ }
+
+ private static void _LoadFontFiles(CXMLReader xmlReader, string fontFolder, string themeName = "", int partyModeId = -1)
+ {
+ string value = string.Empty;
+ int i = 1;
+ while (xmlReader.GetValue("//root/Fonts/Font" + i + "/Folder", out value, value))
+ {
+ SFont sf = new SFont {Folder = value, IsThemeFont = themeName != "", ThemeName = themeName, PartyModeID = partyModeId};
+
+ bool ok = true;
+
+ string name;
+ ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/Name", out name, value);
+ sf.Name = name;
+
+ ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileNormal", out value, value);
+ sf.FileNormal = value;
+ value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
+ CFont f = new CFont(value);
+ sf.Normal = f;
+
+ ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileItalic", out value, value);
+ sf.FileItalic = value;
+ value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
+ f = new CFont(value);
+ sf.Italic = f;
+
+ ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBold", out value, value);
+ sf.FileBold = value;
+ value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
+ f = new CFont(value);
+ sf.Bold = f;
+
+ ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBoldItalic", out value, value);
+ sf.FileBoldItalic = value;
+ value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
+ f = new CFont(value);
+ sf.BoldItalic = f;
+
+ sf.Outline = 0f;
+ ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/Outline", ref sf.Outline);
+
+ sf.OutlineColor = new SColorF(0f, 0f, 0f, 1f);
+ ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorR", ref sf.OutlineColor.R);
+ ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorG", ref sf.OutlineColor.G);
+ ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorB", ref sf.OutlineColor.B);
+ ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorA", ref sf.OutlineColor.A);
+
+ if (ok)
+ _Fonts.Add(sf);
+ else
+ {
+ string fontTypes;
+ if (partyModeId >= 0)
+ fontTypes = "theme fonts for party mode";
+ else if (themeName != "")
+ fontTypes = "theme fonts for theme \"" + themeName + "\"";
+ else
+ fontTypes = "basic fonts";
+ CLog.LogError("Error loading " + fontTypes + ": Error in Font" + i);
+ }
+ i++;
+ }
+ }
+
+ ///
+ /// Load default fonts
+ ///
+ ///
+ private static void _LoadFontList()
+ {
+ CXMLReader xmlReader = CXMLReader.OpenFile(Path.Combine(CSettings.FolderFonts, CSettings.FileFonts));
+ if (xmlReader == null)
+ return;
+
+ _Fonts.Clear();
+
+ _LoadFontFiles(xmlReader, Path.Combine(Directory.GetCurrentDirectory(), CSettings.FolderFonts));
+ }
+
+ ///
+ /// Loads theme fonts from skin file
+ ///
+ public static void LoadThemeFonts(string themeName, string fontFolder, CXMLReader xmlReader)
+ {
+ _LoadFontFiles(xmlReader, fontFolder, themeName);
+ CLog.StartBenchmark(1, "BuildGlyphs");
+ _BuildGlyphs();
+ CLog.StopBenchmark(1, "BuildGlyphs");
+ }
+
+ ///
+ /// Loads party mode fonts from skin file
+ ///
+ public static void LoadPartyModeFonts(int partyModeID, string fontFolder, CXMLReader xmlReader)
+ {
+ _LoadFontFiles(xmlReader, fontFolder, "", partyModeID);
+ CLog.StartBenchmark(1, "BuildGlyphs");
+ _BuildGlyphs();
+ CLog.StopBenchmark(1, "BuildGlyphs");
+ }
+
+ public static void SaveThemeFonts(string themeName, XmlWriter writer)
+ {
+ if (_Fonts.Count == 0)
+ return;
+
+ int index = 0;
+ int fontNr = 1;
+ bool setStart = false;
+ while (index < _Fonts.Count)
+ {
+ if (_Fonts[index].IsThemeFont && _Fonts[index].ThemeName == themeName)
+ {
+ if (!setStart)
+ {
+ writer.WriteStartElement("Fonts");
+ setStart = true;
+ }
+
+ writer.WriteStartElement("Font" + fontNr);
+
+ writer.WriteElementString("Name", _Fonts[index].Name);
+ writer.WriteElementString("Folder", _Fonts[index].Folder);
+
+ writer.WriteElementString("Outline", _Fonts[index].Outline.ToString("#0.00"));
+ writer.WriteElementString("OutlineColorR", _Fonts[index].OutlineColor.R.ToString("#0.00"));
+ writer.WriteElementString("OutlineColorG", _Fonts[index].OutlineColor.G.ToString("#0.00"));
+ writer.WriteElementString("OutlineColorB", _Fonts[index].OutlineColor.B.ToString("#0.00"));
+ writer.WriteElementString("OutlineColorA", _Fonts[index].OutlineColor.A.ToString("#0.00"));
+
+ writer.WriteElementString("FileNormal", _Fonts[index].FileNormal);
+ writer.WriteElementString("FileBold", _Fonts[index].FileBold);
+ writer.WriteElementString("FileItalic", _Fonts[index].FileItalic);
+ writer.WriteElementString("FileBoldItalic", _Fonts[index].FileBoldItalic);
+
+ writer.WriteEndElement();
+
+ fontNr++;
+ }
+ index++;
+ }
+
+ if (setStart)
+ writer.WriteEndElement();
+ }
+
+ public static void UnloadThemeFonts(string themeName)
+ {
+ if (_Fonts.Count == 0)
+ return;
+
+ int index = 0;
+ while (index < _Fonts.Count)
+ {
+ if (_Fonts[index].IsThemeFont && _Fonts[index].ThemeName == themeName)
+ {
+ _Fonts[index].Normal.UnloadGlyphs();
+ _Fonts[index].Italic.UnloadGlyphs();
+ _Fonts[index].Bold.UnloadGlyphs();
+ _Fonts[index].BoldItalic.UnloadGlyphs();
+ _Fonts.RemoveAt(index);
+ }
+ else
+ index++;
+ }
+ }
+
+ private static int _GetFontIndex(string fontName)
+ {
+ for (int i = 0; i < _Fonts.Count; i++)
+ {
+ if (!_Fonts[i].IsThemeFont && _Fonts[i].Name == fontName)
+ return i;
+ }
+
+ return -1;
+ }
+
+ private static int _GetThemeFontIndex(string themeName, string fontName)
+ {
+ if (themeName == "" || fontName == "")
+ return -1;
+
+ for (int i = 0; i < _Fonts.Count; i++)
+ {
+ if (_Fonts[i].IsThemeFont && _Fonts[i].Name == fontName && _Fonts[i].ThemeName == themeName)
+ return i;
+ }
+
+ return -1;
+ }
+
+ private static int _GetPartyFontIndex(int partyModeID, string fontName)
+ {
+ if (partyModeID == -1 || fontName == "")
+ return -1;
+
+ for (int i = 0; i < _Fonts.Count; i++)
+ {
+ if (!_Fonts[i].IsThemeFont && _Fonts[i].PartyModeID == partyModeID && _Fonts[i].Name == fontName)
+ return i;
+ }
+
+ return -1;
+ }
+
+ private static void _BuildGlyphs()
+ {
+ const string text = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+
+ for (int i = 0; i < _Fonts.Count; i++)
+ {
+ _CurrentFont = i;
+
+ foreach (char chr in text)
+ {
+ Style = EStyle.Normal;
+ _Fonts[_CurrentFont].Normal.GetOrAddGlyph(chr);
+ Style = EStyle.Bold;
+ _Fonts[_CurrentFont].Bold.GetOrAddGlyph(chr);
+ Style = EStyle.Italic;
+ _Fonts[_CurrentFont].Italic.GetOrAddGlyph(chr);
+ Style = EStyle.BoldItalic;
+ _Fonts[_CurrentFont].BoldItalic.GetOrAddGlyph(chr);
+ }
+ }
+ Style = EStyle.Normal;
+ SetFont("Normal");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vocaluxe/Base/Fonts/CGlyph.cs b/Vocaluxe/Base/Fonts/CGlyph.cs
new file mode 100644
index 00000000..ea0f1e18
--- /dev/null
+++ b/Vocaluxe/Base/Fonts/CGlyph.cs
@@ -0,0 +1,212 @@
+#region license
+// /*
+// This file is part of Vocaluxe.
+//
+// Vocaluxe is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Vocaluxe is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Vocaluxe. If not, see .
+// */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.Drawing.Text;
+using System.Runtime.InteropServices;
+using VocaluxeLib.Menu;
+
+namespace Vocaluxe.Base.Fonts
+{
+ class CGlyph
+ {
+ private STexture _Texture;
+ private readonly SizeF _BoundingBox;
+ private readonly RectangleF _DrawBounding;
+
+ public float Width
+ {
+ get { return _BoundingBox.Width * _GetFactor(); }
+ }
+
+ public float Height
+ {
+ get { return _BoundingBox.Height * _GetFactor(); }
+ }
+
+ public CGlyph(char chr, float maxHeight)
+ {
+ float oldHeight = CFonts.Height;
+ float outline = CFonts.Outline;
+ float outlineSize = outline * maxHeight;
+ string chrString = chr.ToString();
+
+ CFonts.Height = maxHeight; // *factor;
+ //float factor = _GetFactor(chr, flags);
+ Font fo = CFonts.GetFont();
+ SizeF fullSize, boundingSize;
+ Size bmpSize;
+ using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
+ {
+ fullSize = g.MeasureString(chrString, fo);
+ fullSize.Width += outlineSize;
+ if (chr != ' ')
+ {
+ //Gets exact height and width for drawing more than 1 char. But width is to small to draw char on bitmap as e.g. italic chars will get cropped
+ boundingSize = g.MeasureString(chrString, fo, -1, new StringFormat(StringFormat.GenericTypographic));
+ boundingSize.Width += outlineSize;
+ if (boundingSize.Height > 0)
+ boundingSize.Height += outlineSize;
+ else
+ boundingSize.Height = fullSize.Height;
+ bmpSize = new Size((int)fullSize.Width, (int)Math.Round(boundingSize.Height));
+ }
+ else
+ {
+ boundingSize = fullSize;
+ bmpSize = new Size(1, 1);
+ }
+ _BoundingBox = boundingSize;
+ }
+ using (Bitmap bmp = new Bitmap(bmpSize.Width, bmpSize.Height, PixelFormat.Format32bppArgb))
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ g.Clear(Color.Transparent);
+
+ if (chr == ' ')
+ {
+ _Texture = CDraw.AddTexture(bmp);
+ _DrawBounding = new RectangleF(0, 0, 1, 1);
+ }
+ else
+ {
+ g.SmoothingMode = SmoothingMode.AntiAlias;
+ g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
+
+ PointF point = new PointF(outlineSize / 2, outlineSize / 2);
+
+ using (GraphicsPath path = new GraphicsPath())
+ {
+ //Have to use size in em not pixels!
+ 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 (Pen pen = new Pen(CFonts.OutlineColor.AsColor(), outlineSize))
+ {
+ pen.LineJoin = LineJoin.Round;
+ g.DrawPath(pen, path);
+ g.FillPath(Brushes.White, path);
+ }
+ }
+ Rectangle realBounds = _GetRealBounds(bmp);
+ _DrawBounding = realBounds;
+ float dx = (fullSize.Width - boundingSize.Width - 1) / 2;
+ _DrawBounding.X -= dx;
+ using (Bitmap bmpCropped = bmp.Clone(realBounds, PixelFormat.Format32bppArgb))
+ {
+ _Texture = CDraw.AddTexture(bmpCropped);
+ if (false)
+ {
+ if (outline > 0)
+ bmpCropped.Save("font/" + chr + "o" + CFonts.Style + "2.png", ImageFormat.Png);
+ else
+ bmpCropped.Save("font/" + chr + CFonts.Style + "2.png", ImageFormat.Png);
+ }
+ }
+ }
+ }
+ CFonts.Height = oldHeight;
+ }
+
+ ~CGlyph()
+ {
+ CDraw.RemoveTexture(ref _Texture);
+ }
+
+ private float _GetFactor()
+ {
+ return CFonts.Height / _BoundingBox.Height;
+ }
+
+ public void GetTextureAndRect(float x, float y, float z, out STexture texture, out SRectF rect)
+ {
+ texture = _Texture;
+ float factor = _GetFactor();
+ x += _DrawBounding.X * factor;
+ y += _DrawBounding.Y * factor;
+ float w = _DrawBounding.Width * factor;
+ float h = _DrawBounding.Height * factor;
+ rect = new SRectF(x, y, w, h, z);
+ }
+
+ private static Rectangle _GetRealBounds(Bitmap bmp)
+ {
+ int minX = 0, maxX = bmp.Width - 1, minY = 0;
+ BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+ int values = bmpData.Width * bmp.Height;
+ Int32[] rgbValues = new Int32[values];
+ Marshal.Copy(bmpData.Scan0, rgbValues, 0, values);
+ int index = 0;
+ bool found = false;
+ //find from top
+ for (int y = 0; y < bmp.Height && !found; y++)
+ {
+ for (int x = 0; x < bmp.Width; x++)
+ {
+ if (rgbValues[index] != 0)
+ {
+ minX = x;
+ maxX = x;
+ minY = y;
+ found = true;
+ break;
+ }
+ index++;
+ }
+ }
+ found = false;
+ //find left
+ for (int x = 0; x < minX && !found; x++)
+ {
+ index = x + minY * bmp.Width;
+ for (int y = minY; y < bmp.Height; y++)
+ {
+ if (rgbValues[index] != 0)
+ {
+ found = true;
+ minX = x;
+ break;
+ }
+ index += bmp.Width;
+ }
+ }
+ found = false;
+ //find right
+ for (int x = bmp.Width - 1; x > maxX && !found; x--)
+ {
+ index = x + minY * bmp.Width;
+ for (int y = minY; y < bmp.Height; y++)
+ {
+ if (rgbValues[index] != 0)
+ {
+ found = true;
+ maxX = x;
+ break;
+ }
+ index += bmp.Width;
+ }
+ }
+ return new Rectangle(minX, minY, maxX - minX + 1, bmp.Height - minY);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs
index 814ff8c3..535da199 100644
--- a/Vocaluxe/Lib/Draw/CDirect3D.cs
+++ b/Vocaluxe/Lib/Draw/CDirect3D.cs
@@ -915,14 +915,14 @@ namespace Vocaluxe.Lib.Draw
bmp2.Dispose();
}
- return AddTexture(w, h, ref data);
+ return AddTexture(w, h, data);
}
- public STexture AddTexture(int w, int h, ref byte[] data)
+ public STexture AddTexture(int w, int h, byte[] data)
{
STexture texture = new STexture(-1);
- Texture t = _CreateTexture(w, h, ref data, ref texture);
+ Texture t = _CreateTexture(w, h, data, ref texture);
lock (_MutexTexture)
{
@@ -933,7 +933,7 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
- private Texture _CreateTexture(int w, int h, ref byte[] data, ref STexture texture)
+ private Texture _CreateTexture(int w, int h, byte[] data, ref STexture texture)
{
texture.Width = w;
texture.Height = h;
@@ -972,7 +972,7 @@ namespace Vocaluxe.Lib.Draw
return t;
}
- public STexture EnqueueTexture(int w, int h, ref byte[] data)
+ public STexture EnqueueTexture(int w, int h, byte[] data)
{
STexture texture = new STexture(-1);
STextureQueue queue = new STextureQueue {Data = data, Height = h, Width = w};
@@ -999,7 +999,7 @@ namespace Vocaluxe.Lib.Draw
/// The texture to update
/// A byte array containing the new texture's data
/// True if succeeded
- public bool UpdateTexture(ref STexture texture, ref byte[] data)
+ public bool UpdateTexture(ref STexture texture, byte[] data)
{
if ((texture.Index >= 0) && (_Textures.Count > 0) && _TextureExists(ref texture))
{
@@ -1350,7 +1350,7 @@ namespace Vocaluxe.Lib.Draw
else
return;
- Texture t = _CreateTexture(q.Width, q.Height, ref q.Data, ref texture);
+ Texture t = _CreateTexture(q.Width, q.Height, q.Data, ref texture);
_D3DTextures[q.ID] = t;
_Textures[texture.Index] = texture;
diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs
index da58a68e..58617230 100644
--- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs
+++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs
@@ -398,12 +398,12 @@ namespace Vocaluxe.Lib.Draw
}
}
- public STexture EnqueueTexture(int w, int h, ref byte[] data)
+ public STexture EnqueueTexture(int w, int h, byte[] data)
{
- return AddTexture(w, h, ref data);
+ return AddTexture(w, h, data);
}
- public STexture AddTexture(int w, int h, ref byte[] data)
+ public STexture AddTexture(int w, int h, byte[] data)
{
using (Bitmap bmp = new Bitmap(w, h))
{
@@ -414,7 +414,7 @@ namespace Vocaluxe.Lib.Draw
}
}
- public bool UpdateTexture(ref STexture texture, ref byte[] data)
+ public bool UpdateTexture(ref STexture texture, byte[] data)
{
if ((texture.Index >= 0) && (_Textures.Count > 0) && (_Bitmaps.Count > texture.Index))
{
diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs
index 60814872..a0553a34 100644
--- a/Vocaluxe/Lib/Draw/COpenGL.cs
+++ b/Vocaluxe/Lib/Draw/COpenGL.cs
@@ -782,7 +782,7 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
- public STexture AddTexture(int w, int h, ref byte[] data)
+ public STexture AddTexture(int w, int h, byte[] data)
{
STexture texture = new STexture(-1);
@@ -843,7 +843,7 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
- public STexture EnqueueTexture(int w, int h, ref byte[] data)
+ public STexture EnqueueTexture(int w, int h, byte[] data)
{
STexture texture = new STexture(-1);
STextureQueue queue = new STextureQueue {Data = data, Height = h, Width = w};
@@ -864,7 +864,7 @@ namespace Vocaluxe.Lib.Draw
#endregion adding
#region updating
- public bool UpdateTexture(ref STexture texture, ref byte[] data)
+ public bool UpdateTexture(ref STexture texture, byte[] data)
{
if (_TextureExists(ref texture))
{
diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs
index f4ac27ff..3a48be4c 100644
--- a/Vocaluxe/Lib/Draw/IDraw.cs
+++ b/Vocaluxe/Lib/Draw/IDraw.cs
@@ -41,9 +41,9 @@ namespace Vocaluxe.Lib.Draw
STexture AddTexture(string texturePath);
STexture AddTexture(Bitmap bitmap);
- STexture AddTexture(int w, int h, ref byte[] data);
- STexture EnqueueTexture(int w, int h, ref byte[] data);
- bool UpdateTexture(ref STexture texture, ref byte[] data);
+ STexture AddTexture(int w, int h, byte[] data);
+ STexture EnqueueTexture(int w, int h, byte[] data);
+ bool UpdateTexture(ref STexture texture, byte[] data);
void RemoveTexture(ref STexture texture);
// Basic Draw Methods
diff --git a/Vocaluxe/Lib/Sound/COpenALPlay.cs b/Vocaluxe/Lib/Sound/COpenALPlay.cs
index f1fe898b..36017220 100644
--- a/Vocaluxe/Lib/Sound/COpenALPlay.cs
+++ b/Vocaluxe/Lib/Sound/COpenALPlay.cs
@@ -790,7 +790,7 @@ namespace Vocaluxe.Lib.Sound
{
if (_Data.BytesNotRead >= buf.Length)
{
- _Data.Read(ref buf);
+ _Data.Read(buf);
byte[] b = new byte[2];
diff --git a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
index 54ab8263..9c195495 100644
--- a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
+++ b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
@@ -816,7 +816,7 @@ namespace Vocaluxe.Lib.Sound
{
if (_NoMoreData || _Data.BytesNotRead >= buf.Length)
{
- _Data.Read(ref buf);
+ _Data.Read(buf);
byte[] b = new byte[2];
for (int i = 0; i < buf.Length; i += _ByteCount)
diff --git a/Vocaluxe/Lib/Sound/IPlayback.cs b/Vocaluxe/Lib/Sound/IPlayback.cs
index d6f6d563..e021692f 100644
--- a/Vocaluxe/Lib/Sound/IPlayback.cs
+++ b/Vocaluxe/Lib/Sound/IPlayback.cs
@@ -103,7 +103,7 @@ namespace Vocaluxe.Lib.Sound
}
}
- public void Read(ref byte[] data)
+ public void Read(byte[] data)
{
long read = 0L;
while (read < data.Length && _BytesNotRead > 0L)
diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
index 135d3129..e9dcd175 100644
--- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
+++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
@@ -664,10 +664,10 @@ namespace Vocaluxe.Lib.Video
if (frame.Index == -1 || _Width != (int)frame.Width || _Height != (int)frame.Height)
{
CDraw.RemoveTexture(ref frame);
- frame = CDraw.AddTexture(_Width, _Height, ref _FrameBuffer[num].Data);
+ frame = CDraw.AddTexture(_Width, _Height, _FrameBuffer[num].Data);
}
else
- CDraw.UpdateTexture(ref frame, ref _FrameBuffer[num].Data);
+ CDraw.UpdateTexture(ref frame, _FrameBuffer[num].Data);
lock (_MutexSyncSignals)
{
diff --git a/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs b/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs
index ac5b15cf..c5449dbc 100644
--- a/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs
+++ b/Vocaluxe/Lib/Video/CVideoDecoderGstreamer.cs
@@ -119,17 +119,16 @@ namespace Vocaluxe.Lib.Video
private void _UploadNewFrame(ref STexture frame, ref byte[] data, int width, int height)
{
- if (data != null)
+ if (data == null)
+ return;
+ if (frame.Index == -1 || width != (int)frame.Width || height != (int)frame.Height || data.Length == 0)
{
- if (frame.Index == -1 || width != (int)frame.Width || height != (int)frame.Height || data.Length == 0)
- {
- CDraw.RemoveTexture(ref frame);
- frame = CDraw.AddTexture(width, height, ref data);
- }
- else
- CDraw.UpdateTexture(ref frame, ref data);
- data = null;
+ CDraw.RemoveTexture(ref frame);
+ frame = CDraw.AddTexture(width, height, data);
}
+ else
+ CDraw.UpdateTexture(ref frame, data);
+ data = null;
}
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Webcam/CAForgeNet.cs b/Vocaluxe/Lib/Webcam/CAForgeNet.cs
index c53b16c6..99c1f820 100644
--- a/Vocaluxe/Lib/Webcam/CAForgeNet.cs
+++ b/Vocaluxe/Lib/Webcam/CAForgeNet.cs
@@ -59,10 +59,10 @@ namespace Vocaluxe.Lib.Webcam
if (frame.Index == -1 || _Width != (int)frame.Width || _Height != (int)frame.Height)
{
CDraw.RemoveTexture(ref frame);
- frame = CDraw.AddTexture(_Width, _Height, ref _Data);
+ frame = CDraw.AddTexture(_Width, _Height, _Data);
}
else
- CDraw.UpdateTexture(ref frame, ref _Data);
+ CDraw.UpdateTexture(ref frame, _Data);
}
}
return false;