H. Utku Maden
9339295378
I have had a long break from this project due to other higher priority things going on in my life. Big changes inbound.
177 lines
5.1 KiB
C#
177 lines
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Quik.Typography;
|
|
|
|
namespace Quik.FreeType
|
|
{
|
|
public class FreeTypeFontManager : IQuikFontManager, IDisposable
|
|
{
|
|
public QuikContext Context { get; set; }
|
|
|
|
internal FTLibrary _library;
|
|
private Dictionary<string, FontCacheEntry> _cache = new Dictionary<string, FontCacheEntry>();
|
|
private Dictionary<QuikFontStyle, FreeTypeFont> _fonts= new Dictionary<QuikFontStyle, FreeTypeFont>();
|
|
|
|
public event FreeTypeFontManagerFontFinder FontNotFound;
|
|
|
|
public FreeTypeFontManager()
|
|
{
|
|
FT.InitFreeType(out _library);
|
|
|
|
// FIXME: There are operating system specific ways to achieve this. This is
|
|
// definitely not the best way to do this.
|
|
|
|
// Scan the fonts folder and build up a font cache.
|
|
string path = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
if (OperatingSystem.IsLinux())
|
|
{
|
|
path = "/usr/share/fonts";
|
|
}
|
|
else if (OperatingSystem.IsWindows())
|
|
{
|
|
path = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.Windows),
|
|
"Fonts");
|
|
}
|
|
// For macOS I don't know. Too bad.
|
|
}
|
|
|
|
DirectoryInfo directory = new DirectoryInfo(path);
|
|
ScanDirectoryForFonts(directory);
|
|
}
|
|
|
|
private void ScanDirectoryForFonts(DirectoryInfo directory)
|
|
{
|
|
foreach (FileSystemInfo node in directory.GetFileSystemInfos())
|
|
{
|
|
if (node.Attributes.HasFlag(FileAttributes.Directory))
|
|
{
|
|
ScanDirectoryForFonts(node as DirectoryInfo);
|
|
}
|
|
else
|
|
{
|
|
ScanFileForFonts(node as FileInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ScanFileForFonts(FileInfo file)
|
|
{
|
|
if (file is null) return;
|
|
|
|
if (FT.NewFace(_library, file.FullName, 0, out FTFace face) == FTError.None)
|
|
{
|
|
FontCacheEntry entry;
|
|
string name = face.FamilyName;
|
|
string style = face.StyleName;
|
|
|
|
if (name is null)
|
|
goto done_face;
|
|
|
|
if (_cache.ContainsKey(name))
|
|
{
|
|
entry = _cache[name];
|
|
}
|
|
else
|
|
{
|
|
entry = new FontCacheEntry();
|
|
entry.Family = name;
|
|
_cache[name] = entry;
|
|
}
|
|
|
|
switch (style.ToLowerInvariant())
|
|
{
|
|
case "regular":
|
|
entry.Regular = file;
|
|
break;
|
|
case "bold":
|
|
entry.Bold = file;
|
|
break;
|
|
case "italic":
|
|
entry.Italic = file;
|
|
break;
|
|
}
|
|
|
|
done_face:
|
|
FT.DoneFace(face);
|
|
}
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
// Nothing to do.
|
|
}
|
|
|
|
public QuikFont GetFont(QuikFontStyle fontStyle)
|
|
{
|
|
FreeTypeFont font;
|
|
|
|
if (_fonts.TryGetValue(fontStyle, out font))
|
|
return font;
|
|
|
|
FileInfo file = FindFont(fontStyle);
|
|
if (file == null)
|
|
{
|
|
FontNotFound?.Invoke(fontStyle, ref file);
|
|
if (file == null)
|
|
{
|
|
throw new Exception("Could not find the font you are looking for.");
|
|
}
|
|
}
|
|
|
|
font = new FreeTypeFont(this, file, fontStyle);
|
|
_fonts.Add(fontStyle, font);
|
|
return font;
|
|
}
|
|
|
|
private FileInfo FindFont(QuikFontStyle fontStyle)
|
|
{
|
|
FontCacheEntry entry;
|
|
if (_cache.TryGetValue(fontStyle.Family, out entry))
|
|
{
|
|
switch (fontStyle.Type)
|
|
{
|
|
case QuikFontType.Normal:
|
|
return entry.Regular;
|
|
case QuikFontType.Bold:
|
|
return entry.Bold;
|
|
case QuikFontType.Italic:
|
|
return entry.Italic;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
// IDisposable
|
|
private void ReleaseUnmanagedResources()
|
|
{
|
|
FT.DoneFreeType(_library);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
ReleaseUnmanagedResources();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
~FreeTypeFontManager()
|
|
{
|
|
ReleaseUnmanagedResources();
|
|
}
|
|
|
|
private class FontCacheEntry
|
|
{
|
|
public string Family;
|
|
public FileInfo Regular;
|
|
public FileInfo Bold;
|
|
public FileInfo Italic;
|
|
}
|
|
}
|
|
|
|
public delegate void FreeTypeFontManagerFontFinder(QuikFontStyle style, ref FileInfo info);
|
|
} |