230 lines
7.0 KiB
C#
230 lines
7.0 KiB
C#
|
using System;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using System.Text;
|
||
|
using Quik;
|
||
|
|
||
|
namespace Quik.Media.Defaults
|
||
|
{
|
||
|
public static unsafe class FontConfig
|
||
|
{
|
||
|
private const string fontconfig = "fontconfig";
|
||
|
|
||
|
public static bool Exists { get; }
|
||
|
|
||
|
public static IntPtr FAMILY { get; } = Marshal.StringToHGlobalAnsi("family");
|
||
|
public static IntPtr STYLE { get; } = Marshal.StringToHGlobalAnsi("style");
|
||
|
public static IntPtr FILE { get; } = Marshal.StringToHGlobalAnsi("file");
|
||
|
public static IntPtr WEIGHT { get; } = Marshal.StringToHGlobalAnsi("weight");
|
||
|
public static IntPtr SLANT { get; } = Marshal.StringToHGlobalAnsi("slant");
|
||
|
|
||
|
|
||
|
static FontConfig()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
if (FcInitLoadConfigAndFonts() == null)
|
||
|
{
|
||
|
Exists = false;
|
||
|
}
|
||
|
Exists = true;
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
Exists = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcInitLoadConfigAndFonts")]
|
||
|
public static extern FcConfig* FcInitLoadConfigAndFonts();
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcConfigGetCurrent")]
|
||
|
public static extern FcConfig ConfigGetCurrent();
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcPatternCreate")]
|
||
|
public static extern FcPattern PatternCreate();
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcPatternCreate")]
|
||
|
public static extern bool FcPatternAdd(FcPattern pattern, IntPtr what, FcValue value, bool append);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcObjectSetBuild", CallingConvention = CallingConvention.Cdecl)]
|
||
|
public static extern FcObjectSet ObjectSetBuild(IntPtr i1, IntPtr i2, IntPtr i3, IntPtr i4, IntPtr i5, IntPtr i6);
|
||
|
|
||
|
public static FcObjectSet ObjectSetBuild(IntPtr i1)
|
||
|
{
|
||
|
return ObjectSetBuild(i1, IntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
public static FcObjectSet ObjectSetBuild(IntPtr i1, IntPtr i2)
|
||
|
{
|
||
|
return ObjectSetBuild(i1, i2, IntPtr.Zero);
|
||
|
}
|
||
|
public static FcObjectSet ObjectSetBuild(IntPtr i1, IntPtr i2, IntPtr i3)
|
||
|
{
|
||
|
return ObjectSetBuild(i1, i2, i3, IntPtr.Zero);
|
||
|
}
|
||
|
public static FcObjectSet ObjectSetBuild(IntPtr i1, IntPtr i2, IntPtr i3, IntPtr i4)
|
||
|
{
|
||
|
return ObjectSetBuild(i1, i2, i3, i4, IntPtr.Zero);
|
||
|
}
|
||
|
public static FcObjectSet ObjectSetBuild(IntPtr i1, IntPtr i2, IntPtr i3, IntPtr i4, IntPtr i5)
|
||
|
{
|
||
|
return ObjectSetBuild(i1, i2, i3, i4, i5, IntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcFontList")]
|
||
|
public static extern FcFontSet FontList(FcConfig config, FcPattern pattern, FcObjectSet objectSet);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcNameUnparse")]
|
||
|
public static extern IntPtr NameUnparse(FcPattern pat);
|
||
|
|
||
|
public static string NameUnparseStr(FcPattern pat) => Marshal.PtrToStringAnsi(NameUnparse(pat));
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcPatternGetString")]
|
||
|
public static extern FcResult PatternGetString(FcPattern p, IntPtr what, int n, out IntPtr val);
|
||
|
|
||
|
public static FcResult PatternGetString(FcPattern p, IntPtr what, out string str)
|
||
|
{
|
||
|
FcResult i = PatternGetString(p, what, 0, out IntPtr ptr);
|
||
|
|
||
|
if (i == FcResult.Match)
|
||
|
{
|
||
|
str = Marshal.PtrToStringAnsi(ptr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
str = null;
|
||
|
}
|
||
|
|
||
|
Marshal.FreeHGlobal(ptr);
|
||
|
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcPatternGet")]
|
||
|
public static extern FcResult PatternGet(FcPattern p, IntPtr what, int id, out FcValue value);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcFontSetDestroy")]
|
||
|
public static extern void FontSetDestroy(FcFontSet fs);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcObjectSetDestroy")]
|
||
|
public static extern void ObjectSetDestroy (FcObjectSet os);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcConfigDestroy")]
|
||
|
public static extern void ConfigDestroy (FcConfig cfg);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcPatternDestroy")]
|
||
|
public static extern void PatternDestroy (FcPattern os);
|
||
|
|
||
|
#region Range
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcRangeCreateDouble")]
|
||
|
public static extern IntPtr RangeCreateDouble(double begin, double end);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcRangeCreateInteger")]
|
||
|
public static extern IntPtr RangeCreateInteger (int begin, int end);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcRangeDestroy")]
|
||
|
public static extern void RangeDestroy(IntPtr range);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcRangeCopy")]
|
||
|
public static extern IntPtr RangeCopy (IntPtr range);
|
||
|
|
||
|
[DllImport(fontconfig, EntryPoint = "FcRangeGetDouble")]
|
||
|
public static extern bool RangeGetDouble(IntPtr range, out double start, out double end);
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
public enum FcResult
|
||
|
{
|
||
|
Match,
|
||
|
NoMatch,
|
||
|
TypeMismatch,
|
||
|
NoId,
|
||
|
OutOfMemory
|
||
|
}
|
||
|
|
||
|
public struct FcConfig
|
||
|
{
|
||
|
public readonly IntPtr Handle;
|
||
|
}
|
||
|
|
||
|
public struct FcPattern
|
||
|
{
|
||
|
public readonly IntPtr Handle;
|
||
|
}
|
||
|
|
||
|
public unsafe struct FcObjectSet
|
||
|
{
|
||
|
public readonly IntPtr Handle;
|
||
|
|
||
|
private Accessor* AsPtr => (Accessor*)Handle;
|
||
|
|
||
|
public int NObject => AsPtr->nobject;
|
||
|
|
||
|
public int SObject => AsPtr->sobject;
|
||
|
|
||
|
#pragma warning disable CS0649 // Will always have default value.
|
||
|
private struct Accessor
|
||
|
{
|
||
|
public int nobject;
|
||
|
public int sobject;
|
||
|
public byte** objects;
|
||
|
}
|
||
|
#pragma warning restore CS0649
|
||
|
}
|
||
|
|
||
|
public unsafe struct FcFontSet
|
||
|
{
|
||
|
public readonly IntPtr Handle;
|
||
|
private Accessor* AsPtr => (Accessor*)Handle;
|
||
|
|
||
|
public int NFont => AsPtr->nfont;
|
||
|
public int SFont => AsPtr->sfont;
|
||
|
|
||
|
public FcPattern this[int i]
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (i < 0 || i >= NFont)
|
||
|
throw new IndexOutOfRangeException();
|
||
|
|
||
|
return AsPtr->fonts[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma warning disable CS0649 // Will always have default value.
|
||
|
private struct Accessor
|
||
|
{
|
||
|
public int nfont;
|
||
|
public int sfont;
|
||
|
public FcPattern* fonts;
|
||
|
}
|
||
|
#pragma warning restore CS0649
|
||
|
}
|
||
|
|
||
|
public enum FcType
|
||
|
{
|
||
|
Unknown = -1,
|
||
|
Void,
|
||
|
Integer,
|
||
|
Double,
|
||
|
String,
|
||
|
Bool,
|
||
|
Matrix,
|
||
|
CharSet,
|
||
|
FTFace,
|
||
|
LangSet,
|
||
|
Range
|
||
|
}
|
||
|
|
||
|
[StructLayout(LayoutKind.Explicit)]
|
||
|
public readonly struct FcValue
|
||
|
{
|
||
|
[FieldOffset(0)] public readonly FcType Type;
|
||
|
[FieldOffset(sizeof(FcType))] public readonly IntPtr Pointer;
|
||
|
[FieldOffset(sizeof(FcType))] public readonly int Int;
|
||
|
[FieldOffset(sizeof(FcType))] public readonly double Double;
|
||
|
}
|
||
|
}
|