From 1f6a3a55e1f26abc0c7558eeb9bd4f1f33dd91fb Mon Sep 17 00:00:00 2001 From: "H. Utku Maden" Date: Sat, 16 Sep 2023 09:58:50 +0300 Subject: [PATCH] Ressurrect old freetype library. --- Quik.FreeType/FT.cs | 83 +++++++++++++ Quik.FreeType/FTError.cs | 7 ++ Quik.FreeType/FTLoadFlags.cs | 28 +++++ Quik.FreeType/FTRenderMode.cs | 12 ++ Quik.FreeType/FaceFlag.cs | 28 +++++ Quik.FreeType/Quik.FreeType.csproj | 13 +++ Quik.FreeType/Structures.cs | 180 +++++++++++++++++++++++++++++ Quik.sln | 14 +++ 8 files changed, 365 insertions(+) create mode 100644 Quik.FreeType/FT.cs create mode 100644 Quik.FreeType/FTError.cs create mode 100644 Quik.FreeType/FTLoadFlags.cs create mode 100644 Quik.FreeType/FTRenderMode.cs create mode 100644 Quik.FreeType/FaceFlag.cs create mode 100644 Quik.FreeType/Quik.FreeType.csproj create mode 100644 Quik.FreeType/Structures.cs diff --git a/Quik.FreeType/FT.cs b/Quik.FreeType/FT.cs new file mode 100644 index 0000000..4af977e --- /dev/null +++ b/Quik.FreeType/FT.cs @@ -0,0 +1,83 @@ +using System; +using System.Runtime.InteropServices; + +namespace Quik.FreeType +{ + public static class FT + { + private const string freetype2 = "freetype"; + + [DllImport(freetype2, EntryPoint = "FT_Init_FreeType")] + public static extern FTError InitFreeType(out FTLibrary library); + + [DllImport(freetype2, EntryPoint = "FT_Done_FreeType")] + public static extern FTError DoneFreeType(FTLibrary library); + + [DllImport(freetype2, EntryPoint = "FT_New_Face")] + public static extern FTError NewFace( + FTLibrary library, + [MarshalAs(UnmanagedType.LPStr)] string path, + long faceIndex, + out FTFace face); + + [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")] + public static extern FTError NewMemoryFace( + FTLibrary library, + IntPtr buffer, + long size, + long faceIndex, + out FTFace face); + + [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")] + public static extern FTError NewMemoryFace( + FTLibrary library, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer, + long size, + long faceIndex, + out FTFace face); + + [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")] + public static extern FTError NewMemoryFace( + FTLibrary library, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Span buffer, + long size, + long faceIndex, + out FTFace face); + + // public static extern FTError OpenFace(FTLibrary library, in FTOpenArgs args, long faceIndex, out FTFace face); + + // [DllImport(freetype2, EntryPoint = "FT_Attach_File")] + // public static extern FTError AttachFile(FTFace face, [MarshalAs(UnmanagedType.LPStr)] string filePathName); + + [DllImport(freetype2, EntryPoint = "FT_Set_Char_Size")] + public static extern FTError SetCharSize( + FTFace library, + long charWidth, + long charHeight, + uint horizontalResolution, + uint verticalResolution); + + + [DllImport(freetype2, EntryPoint = "FT_Get_Char_Index")] + public static extern uint GetCharIndex(FTFace face, ulong charCode); + + [DllImport(freetype2, EntryPoint = "FT_Load_Glyph")] + public static extern FTError LoadGlyph(FTFace face, uint charIndex, FTLoadFlags flags); + + [DllImport(freetype2, EntryPoint = "FT_Render_Glyph")] + public static extern FTError RenderGlyph(FTGlyphSlot slot, FTRenderMode mode); + + [DllImport(freetype2, EntryPoint = "FT_Done_Face")] + public static extern FTError DoneFace(FTFace face); + + [DllImport(freetype2, EntryPoint = "FT_Bitmap_Init")] + public static extern void BitmapInit(ref FTBitmap bitmap); + + [DllImport(freetype2, EntryPoint = "FT_Bitmap_Convert")] + public static extern void BitmapConvert(FTLibrary library, in FTBitmap source, ref FTBitmap target, + int alignment); + + [DllImport(freetype2, EntryPoint = "FT_Bitmap_Done")] + public static extern void BitmapDone(FTLibrary library, ref FTBitmap bitmap); + } +} \ No newline at end of file diff --git a/Quik.FreeType/FTError.cs b/Quik.FreeType/FTError.cs new file mode 100644 index 0000000..d80c4b7 --- /dev/null +++ b/Quik.FreeType/FTError.cs @@ -0,0 +1,7 @@ +namespace Quik.FreeType +{ + public enum FTError : int + { + None = 0, + } +} \ No newline at end of file diff --git a/Quik.FreeType/FTLoadFlags.cs b/Quik.FreeType/FTLoadFlags.cs new file mode 100644 index 0000000..ad8ff4a --- /dev/null +++ b/Quik.FreeType/FTLoadFlags.cs @@ -0,0 +1,28 @@ +using System; + +namespace Quik.FreeType +{ + [Flags] + public enum FTLoadFlags + { + Default = 0, + NoScale = 1 << 0, + NoHinting = 1 << 1, + Render = 1 << 2, + NoBitmap = 1 << 3, + VerticalLayout = 1 << 4, + ForceAutoHint = 1 << 5, + CropBitmap = 1 << 6, + Pedantic = 1 << 7, + IgnoreGlobalAdvanceWidth = 1 << 9, + NoRecurse = 1 << 10, + IgnoreTransform = 1 << 11, + Monochrome= 1 << 12, + LinearDesign = 1 << 13, + SbitsOnly = 1 << 14, + NoAutoHint = 1 << 15, + Color = 1 << 20, + ComputeMetrics = 1 << 21, + BitmapMetricsOnly = 1 << 22 + } +} \ No newline at end of file diff --git a/Quik.FreeType/FTRenderMode.cs b/Quik.FreeType/FTRenderMode.cs new file mode 100644 index 0000000..c3cd212 --- /dev/null +++ b/Quik.FreeType/FTRenderMode.cs @@ -0,0 +1,12 @@ +namespace Quik.FreeType +{ + public enum FTRenderMode + { + Normal = 0, + Light, + Mono, + Lcd, + LcdVertical, + Sdf + } +} \ No newline at end of file diff --git a/Quik.FreeType/FaceFlag.cs b/Quik.FreeType/FaceFlag.cs new file mode 100644 index 0000000..dde662f --- /dev/null +++ b/Quik.FreeType/FaceFlag.cs @@ -0,0 +1,28 @@ +using System; + +namespace Quik.FreeType +{ + [Flags] + public enum FaceFlag : int + { + Scalable = 1 << 0, + FixedSizes = 1 << 1, + FixedWidth = 1 << 2, + Sfnt = 1 << 3, + Horizontal = 1 << 4, + Vertical = 1 << 5, + Kerning = 1 << 6, + FastGlyphs = 1 << 7, + MultipleMasters = 1 << 8, + GlyphNames = 1 << 9, + ExternalStream = 1 << 10, + Hinter = 1 << 11, + CidKeyed = 1 << 12, + Tricky = 1 << 13, + Color = 1 << 14, + Variation = 1 << 15, + Svg = 1 << 16, + Sbix = 1 << 17, + SbixOverlay = 1 << 18 + } +} \ No newline at end of file diff --git a/Quik.FreeType/Quik.FreeType.csproj b/Quik.FreeType/Quik.FreeType.csproj new file mode 100644 index 0000000..a11ae84 --- /dev/null +++ b/Quik.FreeType/Quik.FreeType.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + 7.3 + true + + + + + + + diff --git a/Quik.FreeType/Structures.cs b/Quik.FreeType/Structures.cs new file mode 100644 index 0000000..046b38f --- /dev/null +++ b/Quik.FreeType/Structures.cs @@ -0,0 +1,180 @@ +using System; +using System.Runtime.InteropServices; + +namespace Quik.FreeType +{ + public struct FTLibrary + { + private IntPtr _handle; + public IntPtr Handle => _handle; + } + + public unsafe struct FTFace + { + private IntPtr _handle; + public IntPtr Handle => _handle; + private unsafe FTFaceInternal* Ptr => (FTFaceInternal*)_handle; + + public long NumberOfGlyphs => Ptr->NumberOfGlyphs; + public long FaceIndex => Ptr->FaceIndex; + public FaceFlag FaceFlags => (FaceFlag)Ptr->FaceFlags; + public long StyleFlags => Ptr->StyleFlags; + public string FamilyName => Marshal.PtrToStringUTF8(Ptr->FamilyName); + public string StyleName => Marshal.PtrToStringUTF8(Ptr->StyleName); + public int NumberOfFixedSizes => Ptr->NumberOfFixedSizes; + public int NumberOfCharMaps => Ptr->NumberOfCharMaps; + public FTGlyphSlot Glyph => Ptr->Glyph; + public short Ascender => Ptr->Ascender; + public short Descender => Ptr->Descender; + public ref readonly FTSizeMetrics ScaledSize => ref ((FTSize*)Ptr->Size)->Metrics; + } + + public struct FTBox + { + public long XMin; + public long YMin; + public long XMax; + public long YMax; + } + + internal struct FTFaceInternal + { + public long NumberOfFaces; + public long FaceIndex; + public long FaceFlags; + public long StyleFlags; + public long NumberOfGlyphs; + public IntPtr FamilyName; + public IntPtr StyleName; + public int NumberOfFixedSizes; + public IntPtr AvailableSizes; + public int NumberOfCharMaps; + public IntPtr Charmaps; + public FTGeneric Generic; + public FTBox BoundingBox; + public ushort UnitsPerEm; + public short Ascender; + public short Descender; + public short Height; + public short MaxAdvanceWidth; + public short MaxAdvanceHeight; + public short UnderlinePosition; + public short UnderlineThickness; + public FTGlyphSlot Glyph; + public IntPtr Size; + public IntPtr Charmap; + + // Rest of the struct is private to implementation. + } + + public struct FTGeneric + { + public IntPtr Data; + public IntPtr Finalizer; + } + + public struct FTVector + { + public long X; + public long Y; + } + + public struct FTBitmap + { + public uint Rows; + public uint Width; + public int Pitch; + public IntPtr Buffer; + public ushort NumberOfGrays; + public byte PixelMode; + public byte PaletteMode; + public IntPtr Palette; + } + + public struct FTOutline + { + public short NumberOfContours; + public short NumberOfPoints; + public IntPtr Points; + public IntPtr Tags; + public IntPtr Contours; + public int Flags; + } + + internal struct FTGlyphSlotInternal + { + public FTLibrary Library; + public FTFace Face; + public FTGlyphSlot Next; + public uint GlyphIndex; + public FTGeneric Generic; + public FTGlyphMetrics Metrics; + public long LinearHorizontalAdvance; + public long LinearVerticalAdvance; + public FTVector Advance; + public int Format; + public FTBitmap Bitmap; + public int BitmapLeft; + public int BitmapTop; + public FTOutline Outline; + public uint NumberOfSubGlyphs; + public IntPtr SubGlyphs; + public IntPtr ControlData; + public long ControlLength; + public long LsbDelta; + public long RsbDelta; + public IntPtr Other; + public IntPtr Internal; + } + + public unsafe struct FTGlyphSlot + { + private IntPtr _handle; + public IntPtr Handle => _handle; + private FTGlyphSlotInternal* Ptr => (FTGlyphSlotInternal*) _handle; + + public FTLibrary Library => Ptr->Library; + public FTFace Face => Ptr->Face; + public FTGlyphSlot Next => Ptr->Next; + public uint GlyphIndex => Ptr->GlyphIndex; + public ref readonly FTGlyphMetrics Metrics => ref Ptr->Metrics; + public long LinearHorizontalAdvance => Ptr->LinearHorizontalAdvance; + public long LinearVerticalAdvance => Ptr->LinearVerticalAdvance; + public FTVector Advance => Ptr->Advance; + public ref readonly FTBitmap Bitmap => ref Ptr->Bitmap; + public long BitmapLeft => Ptr->BitmapLeft; + public long BitmapTop => Ptr->BitmapTop; + } + + public struct FTGlyphMetrics + { + public long Width; + public long Height; + public long HorizontalBearingX; + public long HorizontalBearingY; + public long HorizontalAdvance; + public long VerticalBearingX; + public long VerticalBearingY; + public long VerticalAdvance; + } + + public struct FTSizeMetrics + { + public short Xppem; + public short Yppem; + public long XScale; + public long YScale; + public long Ascender; + public long Descender; + public long Height; + public long MaxAdvance; + } + + public struct FTSize + { + public IntPtr Face; + public FTGeneric Generic; + public FTSizeMetrics Metrics; + private IntPtr Privates; + } +} \ No newline at end of file diff --git a/Quik.sln b/Quik.sln index 608f7b9..9c1b081 100644 --- a/Quik.sln +++ b/Quik.sln @@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuikDemo", "tests\QuikDemo\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.Media.Defaults", "Quik.Media.Defaults\Quik.Media.Defaults.csproj", "{B517D2BF-CB9D-4448-BE50-EA85E100EB47}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.FreeType", "Quik.FreeType\Quik.FreeType.csproj", "{D19734B9-E54F-4CED-B49A-998608801843}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,6 +99,18 @@ Global {B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x64.Build.0 = Release|Any CPU {B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x86.ActiveCfg = Release|Any CPU {B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x86.Build.0 = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|x64.ActiveCfg = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|x64.Build.0 = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|x86.ActiveCfg = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Debug|x86.Build.0 = Debug|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|Any CPU.Build.0 = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|x64.ActiveCfg = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|x64.Build.0 = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|x86.ActiveCfg = Release|Any CPU + {D19734B9-E54F-4CED-B49A-998608801843}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {BC7D3002-B79B-4141-B6CC-74FB2175B474} = {AE05ADE5-A809-479F-97D5-BEAFE7604285}