Compare commits

...

10 Commits

74 changed files with 396 additions and 2252 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ obj/
riderModule.iml
/_ReSharper.Caches/
.idea
.vs
.vscode
nuget_repo
**/out

2
.gitmodules vendored
View File

@ -4,3 +4,5 @@
[submodule "lib/freetype"]
path = lib/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
[submodule "freetype"]
branch = VER-2-9-1

View File

@ -1,60 +0,0 @@
# This is going to create an environment for you to cross compile all the
# packages needed to build this project.
#
# As always, debian > ubuntu <3
FROM debian:stable-slim
WORKDIR /root
# Download and Install dependencies.
# Install WGET
RUN apt-get update
RUN apt-get install -y sudo wget
# Add the .NET package repository to the repository listing.
RUN wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN rm packages-microsoft-prod.deb
# APT dependencies.
RUN apt-get update
RUN apt-get install -y \
build-essential \
bzip2 \
cmake \
clang \
cpio \
dotnet-sdk-6.0 \
gcc-arm-linux-gnueabihf \
gcc-aarch64-linux-gnu \
gcc-i686-linux-gnu \
git \
libssl-dev \
libxml2-dev \
lzma-dev \
mingw-w64 \
nuget \
ninja-build \
patch \
python3 \
xz-utils \
zlib1g-dev
# Clone osxcross
# Let's do this later.
# RUN git clone https://github.com/tpoechtrager/osxcross.git osxcross
# Setup interactive shell.
# Setup sudo. Remove password prompt for group "wheel".
RUN echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/quik_sudo_conf
# Create a default user and switch.
RUN adduser --comment "" --disabled-password quik
USER quik
WORKDIR /home/quik
# Copy bashrc
RUN cp /etc/bash.bashrc ~/.bashrc
RUN echo source $HOME/src/sh/bashrc.sh >> ~/.bashrc
# Execute an interactive shell.
CMD bash

View File

@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
</Project>

View File

@ -1,3 +0,0 @@
#!/bin/bash
cd $(dirname "$0")
../sh/quik_build_native.sh .

View File

@ -0,0 +1,16 @@
using System;
using Quik.FreeType;
namespace Quik.Media.Defaults
{
public static class FTProvider
{
private static FTLibrary _ft;
public static FTLibrary Ft => _ft;
static FTProvider()
{
FT.InitFreeType(out _ft);
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.IO;
using Quik.FreeType;
using Quik.Media;
using Quik.Media.Color;
namespace Quik.Media.Defaults
{
public class QFontFreeType : QFont
{
private MemoryStream ms;
private FTFace face;
public override FontInfo Info => throw new NotImplementedException();
public QFontFreeType(Stream stream)
{
ms = new MemoryStream();
stream.CopyTo(ms);
FTError e = FT.NewMemoryFace(Ft, ms.GetBuffer(), ms.Length, 0, out face);
if (e != FTError.None)
{
throw new Exception("Could not load font face from stream.");
}
}
public override bool HasRune(int rune)
{
return FT.GetCharIndex(face, (ulong)rune) != 0;
}
public override QFontPage RasterizePage(int codepage, float size, in FontRasterizerOptions options)
{
FT.SetCharSize(face, 0, (long)Math.Round(64*size), 0, (uint)Math.Round(options.Resolution));
QGlyphMetrics[] allMetrics = new QGlyphMetrics[256];
// Figure out the map size needed.
int pixels = 0;
for (int i = 0; i < 256; i++)
{
uint index = FT.GetCharIndex(face, (ulong)(codepage + i));
FT.LoadGlyph(face, index, FTLoadFlags.Default);
ref readonly FTGlyphMetrics metrics = ref face.Glyph.Metrics;
allMetrics[i] = new QGlyphMetrics(
codepage + i,
new QVec2(metrics.Width, metrics.Height),
new QVec2(metrics.HorizontalBearingX/64f, metrics.HorizontalBearingY/64f),
new QVec2(metrics.VerticalBearingX/64f, metrics.VerticalBearingY/64f),
new QVec2(metrics.HorizontalAdvance/64f, metrics.VerticalAdvance/64f)
);
pixels = (int)Math.Max(pixels, Math.Max(face.Glyph.Metrics.Width/64f, face.Glyph.Metrics.Height/64f));
}
int bits = Math.ILogB(pixels);
if (1 << bits != pixels)
{
pixels = 1 << bits + 1;
}
// Now we can create a bitmap and render our glyphs.
QImageBuffer buffer = new QImageBuffer(QImageFormat.RedU8, (int)pixels, (int)pixels, 256);
for (int i = 0; i < 256; i++)
{
uint index = FT.GetCharIndex(face, (ulong)(codepage + i));
FT.LoadGlyph(face, index, FTLoadFlags.Default);
FT.RenderGlyph(face.Glyph, options.Sdf ? FTRenderMode.Sdf : FTRenderMode.Mono);
ref readonly FTBitmap bitmap = ref face.Glyph.Bitmap;
buffer.LockBits3d(out QImageLock dst, QImageLockOptions.Default, i);
if (bitmap.Buffer != IntPtr.Zero) unsafe
{
for (int j = 0; j < bitmap.Rows; j++)
{
Buffer.MemoryCopy(
(byte*)bitmap.Buffer + (j * bitmap.Pitch),
(byte*)dst.ImagePtr + (j * dst.Width),
dst.Width,
bitmap.Width);
}
}
buffer.UnlockBits();
}
return new QFontPage(this, codepage, size, options, buffer, allMetrics);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
ms.Dispose();
}
FT.DoneFace(face);
}
private static FTLibrary Ft => FTProvider.Ft;
}
}

View File

@ -5,12 +5,12 @@ using Quik.Media;
using Quik.Media.Color;
using Quik.Stb;
namespace Quik.Media.Stb
namespace Quik.Media.Defaults
{
public unsafe class QImageStbi : QImage
{
private readonly StbImage image;
private ImageBuffer buffer;
private QImageBuffer buffer;
public override int Width => image.Width;
@ -47,8 +47,8 @@ namespace Quik.Media.Stb
if (options.MipLevel > 0) throw new Exception("This image has no mip levels.");
buffer?.Dispose();
buffer = new ImageBuffer(options.Format, Width, Height);
QImageLock dst = buffer.Lock();
buffer = new QImageBuffer(options.Format, Width, Height);
buffer.LockBits2d(out QImageLock dst, QImageLockOptions.Default);
byte *srcPtr = (byte*)image.ImagePointer;
QImageLock src = new QImageLock(InternalFormat, Width, Height, 1, (IntPtr)srcPtr);
@ -76,7 +76,7 @@ namespace Quik.Media.Stb
public override void UnlockBits()
{
buffer.Unlock();
buffer.UnlockBits();
}
protected override void Dispose(bool disposing)

View File

@ -10,7 +10,7 @@
<ItemGroup>
<ProjectReference Include="..\Quik\Quik.csproj" />
<ProjectReference Include="..\Quik.StbImage\Quik.StbImage.csproj" />
<ProjectReference Include="..\Quik.StbTrueType\Quik.StbTrueType.csproj" />
<ProjectReference Include="..\Quik.FreeType\Quik.FreeType.csproj" />
</ItemGroup>
</Project>

View File

@ -9,7 +9,7 @@ using Quik.Media;
// WebRequest is obsolete but runs on .NET framework.
#pragma warning disable SYSLIB0014
namespace Quik.Media.Stb
namespace Quik.Media.Defaults
{
public class StbMediaLoader : MediaLoader<string>, MediaLoader<Uri>, MediaLoader<FileInfo>, MediaLoader<FontInfo>
{

View File

@ -1,36 +0,0 @@
using System;
using System.IO;
using Quik.Media.Color;
namespace Quik.Media.Stb
{
public class QFontStbtt : QFont
{
public override FontInfo Info => throw new NotImplementedException();
public QFontStbtt(Stream source)
{
}
public override QGlyphMetrics[] GetMetricsForPage(int codepage)
{
throw new NotImplementedException();
}
public override QGlyphMetrics GetMetricsForRune(int rune)
{
throw new NotImplementedException();
}
public override bool HasRune(int rune)
{
throw new NotImplementedException();
}
public override QImage RenderPage(int codepage, float resolution, bool sdf)
{
throw new NotImplementedException();
}
}
}

View File

@ -37,6 +37,11 @@ namespace Quik.OpenTK
IsGLInitialized = true;
}
window.Closing += (ea) =>
{
Environment.Exit(0);
};
return port;
}

View File

@ -72,7 +72,8 @@ namespace Quik.OpenTK
_vertexEngine.Reset();
_vertexEngine.ProcessCommands(new QRectangle(), queue);
_window.Context.MakeCurrent();
if (!_window.Context.IsCurrent)
_window.Context.MakeCurrent();
if (!_glDriver.IsInit)
_glDriver.Init();

View File

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenTK" Version="4.7.4" />
<PackageReference Include="OpenTK" Version="4.8.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,12 +0,0 @@
cmake_minimum_required(VERSION 3.0)
project(quik_stbi LANGUAGES C VERSION 1.0)
add_compile_options(-static-libgcc)
add_library(stbi SHARED "quik_stbi.c")
target_include_directories(stbi PRIVATE "../lib")
install(
TARGETS stbi
RUNTIME DESTINATION .
LIBRARY DESTINATION .)

View File

@ -1,12 +0,0 @@
using System;
namespace Quik.Stb.Image
{
[AttributeUsage(System.AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class NativeTypeNameAttribute : System.Attribute
{
public NativeTypeNameAttribute(string typename)
{
}
}
}

View File

@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RuntimeIdentifiers>linux-arm;linux-arm64;linux-x64;win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup>
<!-- Nuget Properties. -->
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>Quik.StbImage</PackageId>
<Version>1.0.0</Version>
<Authors>STBI Authors, H. Utku Maden</Authors>
<Description>
A C# wrapper for the ubiquitous Stb Image library.
</Description>
</PropertyGroup>
<ItemGroup>
<Content Include="runtimes/**">
<PackagePath>runtimes</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -1,144 +0,0 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Quik.Stb
{
/// <summary>
/// A class that encompasses all features of stb_image.h in a safe way.
/// </summary>
public unsafe class StbImage : IDisposable
{
private bool isDisposed = false;
/// <summary>
/// Pointer to the image.
/// </summary>
public IntPtr ImagePointer { get; }
/// <summary>
/// Width of the image.
/// </summary>
public int Width { get; }
/// <summary>
/// Height of the image.
/// </summary>
/// <value></value>
public int Height { get; }
/// <summary>
/// Internal image format.
/// </summary>
public StbiImageFormat Format { get; }
public bool IsFloat { get; }
private StbImage(IntPtr image, int x, int y, StbiImageFormat format, bool isFloat)
{
ImagePointer = image;
Width = x;
Height = y;
Format = format;
IsFloat = isFloat;
}
~StbImage()
{
Dispose(false);
}
public void Dispose() => Dispose(true);
private void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
GC.SuppressFinalize(this);
}
Stbi.image_free(ImagePointer.ToPointer());
isDisposed = true;
}
/// <summary>
/// Set to flip the y-axis of loaded images on load.
/// </summary>
public static bool FlipVerticallyOnLoad { set => Stbi.set_flip_vertically_on_load(1); }
/// <summary>
/// Set to unpremultiply images on load.
/// </summary>
/// <remarks>
/// According to the stb_image documentation, only iPhone PNG images
/// can come with premultiplied alpha.
/// </remarks>
public static bool UnpremultiplyOnLoad { set => Stbi.set_unpremultiply_on_load(1); }
/// <summary>
/// Try loading an image, without raising exceptions.
/// </summary>
/// <param name="image">The resulting image.</param>
/// <param name="stream">Source stream.</param>
/// <param name="format">The desired image format.</param>
/// <returns>True on success.</returns>
public static bool TryLoad(out StbImage image, Stream stream, StbiImageFormat format = StbiImageFormat.Default, bool isFloat = false)
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
stream.Position = 0;
IntPtr imagePtr;
if (isFloat)
{
imagePtr = (IntPtr)Stbi.loadf_from_callbacks(&cb, null, &x, &y, &iFormat, (int)format);
}
else
{
imagePtr = (IntPtr)Stbi.load_from_callbacks(&cb, null, &x, &y, &iFormat, (int)format);
}
if (imagePtr != IntPtr.Zero)
{
image = new StbImage(imagePtr, x, y, (StbiImageFormat)iFormat, isFloat);
return true;
}
else
{
image = null;
return false;
}
}
/// <summary>
/// Load an image.
/// </summary>
/// <param name="stream">The stream to load from.</param>
/// <param name="format">The desired image format.</param>
/// <returns>The image object.</returns>
public static StbImage Load(Stream stream, StbiImageFormat format = StbiImageFormat.Default, bool isFloat = false)
{
if (TryLoad(out StbImage image, stream, format, isFloat))
{
return image;
}
string reason = Marshal.PtrToStringUTF8((IntPtr)Stbi.failure_reason());
throw new Exception($"Failed to load image: {reason}");
}
public bool IsLoadable(Stream stream)
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
stream.Position = 0;
int result = Stbi.info_from_callbacks(&cb, null, &x, &y, &iFormat);
return result != 0;
}
}
}

View File

@ -1,65 +0,0 @@
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
namespace Quik.Stb
{
public unsafe static partial class Stbi
{
private delegate void FailedAssertProc(byte *expression, byte *file, int line, byte *function);
private static readonly string[] LibraryNames = new string[]
{
//FIXME: This is wrong on so many levels, but, i need to do this
// in order to get a change of this running.
"runtimes/win-x64/native/libstbi.dll",
"runtimes/win-x86/native/libstbi.dll",
"runtimes/linux-arm/native/libstbi.so",
"runtimes/linux-arm64/native/libstbi.so",
"runtimes/linux-x64/native/libstbi.so",
"runtimes/native/libstbi.dylib",
"libstbi.dll",
"libstbi.so",
"libstbi.dylib",
};
static Stbi()
{
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver);
quik_stbi_failed_assert_store(Marshal.GetFunctionPointerForDelegate<FailedAssertProc>(FailedAssert));
}
private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName != "stbi")
return IntPtr.Zero;
foreach (string name in LibraryNames)
{
if (NativeLibrary.TryLoad(name, assembly, searchPath, out IntPtr handle))
{
return handle;
}
}
return NativeLibrary.Load(libraryName);
}
private static void FailedAssert(byte *expression, byte *file, int line, byte *function)
{
string expr = expression == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)expression);
string f = file == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)file);
string func = function == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)function);
Exception ex = new Exception("Assert failed in native stbi code.");
ex.Data.Add("Expression", expr);
ex.Data.Add("File", f);
ex.Data.Add("Line", line);
ex.Data.Add("Function", func);
throw ex;
}
}
}

View File

@ -1,177 +0,0 @@
using System;
using System.Runtime.InteropServices;
using Quik.Stb.Image;
namespace Quik.Stb
{
[NativeTypeName("unsigned int")]
public enum StbiEnum : uint
{
STBI_default = 0,
STBI_grey = 1,
STBI_grey_alpha = 2,
STBI_rgb = 3,
STBI_rgb_alpha = 4,
}
public partial struct stbi_io_callbacks
{
[NativeTypeName("int (*)(void *, char *, int)")]
public IntPtr read;
[NativeTypeName("void (*)(void *, int)")]
public IntPtr skip;
[NativeTypeName("int (*)(void *)")]
public IntPtr eof;
}
public static unsafe partial class Stbi
{
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void quik_stbi_failed_assert_store([NativeTypeName("quik_failed_assert_cb_t")] IntPtr cb);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_callbacks", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_file", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_gif_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_gif_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int** delays, int* x, int* y, int* z, int* comp, int req_comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16_from_callbacks", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_file_16", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_from_file_16([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_memory", ExactSpelling = true)]
public static extern float* loadf_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_callbacks", ExactSpelling = true)]
public static extern float* loadf_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf", ExactSpelling = true)]
public static extern float* loadf([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_file", ExactSpelling = true)]
public static extern float* loadf_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_hdr_to_ldr_gamma", ExactSpelling = true)]
public static extern void hdr_to_ldr_gamma(float gamma);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_hdr_to_ldr_scale", ExactSpelling = true)]
public static extern void hdr_to_ldr_scale(float scale);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_ldr_to_hdr_gamma", ExactSpelling = true)]
public static extern void ldr_to_hdr_gamma(float gamma);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_ldr_to_hdr_scale", ExactSpelling = true)]
public static extern void ldr_to_hdr_scale(float scale);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_callbacks", ExactSpelling = true)]
public static extern int is_hdr_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_memory", ExactSpelling = true)]
public static extern int is_hdr_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr", ExactSpelling = true)]
public static extern int is_hdr([NativeTypeName("const char *")] sbyte* filename);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_file", ExactSpelling = true)]
public static extern int is_hdr_from_file([NativeTypeName("FILE *")] void* f);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_failure_reason", ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* failure_reason();
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_image_free", ExactSpelling = true)]
public static extern void image_free(void* retval_from_stbi_load);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_memory", ExactSpelling = true)]
public static extern int info_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_callbacks", ExactSpelling = true)]
public static extern int info_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_memory", ExactSpelling = true)]
public static extern int is_16_bit_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_callbacks", ExactSpelling = true)]
public static extern int is_16_bit_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info", ExactSpelling = true)]
public static extern int info([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_file", ExactSpelling = true)]
public static extern int info_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit", ExactSpelling = true)]
public static extern int is_16_bit([NativeTypeName("const char *")] sbyte* filename);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_file", ExactSpelling = true)]
public static extern int is_16_bit_from_file([NativeTypeName("FILE *")] void* f);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_unpremultiply_on_load", ExactSpelling = true)]
public static extern void set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_convert_iphone_png_to_rgb", ExactSpelling = true)]
public static extern void convert_iphone_png_to_rgb(int flag_true_if_should_convert);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_flip_vertically_on_load", ExactSpelling = true)]
public static extern void set_flip_vertically_on_load(int flag_true_if_should_flip);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_unpremultiply_on_load_thread", ExactSpelling = true)]
public static extern void set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_convert_iphone_png_to_rgb_thread", ExactSpelling = true)]
public static extern void convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_flip_vertically_on_load_thread", ExactSpelling = true)]
public static extern void set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc_guesssize", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc_guesssize([NativeTypeName("const char *")] sbyte* buffer, int len, int initial_size, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc_guesssize_headerflag", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc_guesssize_headerflag([NativeTypeName("const char *")] sbyte* buffer, int len, int initial_size, int* outlen, int parse_header);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc([NativeTypeName("const char *")] sbyte* buffer, int len, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_buffer", ExactSpelling = true)]
public static extern int zlib_decode_buffer([NativeTypeName("char *")] sbyte* obuffer, int olen, [NativeTypeName("const char *")] sbyte* ibuffer, int ilen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_noheader_malloc", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_noheader_malloc([NativeTypeName("const char *")] sbyte* buffer, int len, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_noheader_buffer", ExactSpelling = true)]
public static extern int zlib_decode_noheader_buffer([NativeTypeName("char *")] sbyte* obuffer, int olen, [NativeTypeName("const char *")] sbyte* ibuffer, int ilen);
}
}

View File

@ -1,11 +0,0 @@
namespace Quik.Stb
{
public enum StbiImageFormat
{
Default = (int)StbiEnum.STBI_default,
Grey = (int)StbiEnum.STBI_grey,
GreyAlpha = (int)StbiEnum.STBI_grey_alpha,
Rgb = (int)StbiEnum.STBI_rgb,
Rgba = (int)StbiEnum.STBI_rgb_alpha
}
}

View File

@ -1,60 +0,0 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Quik.Stb
{
public unsafe class StbiStreamWrapper : IDisposable
{
private Stream _stream;
private bool _keepOpen;
private bool _isDisposed;
private delegate int ReadProc(void *userdata, byte* buffer, int count);
private delegate void SkipProc(void *userdata, int count);
private delegate int Eof(void *userdata);
public StbiStreamWrapper(Stream stream, bool keepOpen = false)
{
if (stream == null) throw new ArgumentNullException(nameof(stream));
_stream = stream;
_keepOpen = keepOpen;
}
public void CreateCallbacks(out stbi_io_callbacks cb)
{
cb = default;
cb.read = Marshal.GetFunctionPointerForDelegate<ReadProc>(ReadCb);
cb.skip = Marshal.GetFunctionPointerForDelegate<SkipProc>(SkipCb);
cb.eof = Marshal.GetFunctionPointerForDelegate<Eof>(EofCb);
}
private int ReadCb(void *userdata, byte* buffer, int count)
{
Span<byte> bytes = new Span<byte>(buffer, count);
return _stream.Read(bytes);
}
private void SkipCb(void *userdata, int count)
{
_stream.Seek(count, SeekOrigin.Current);
}
private int EofCb(void *userdata)
{
if (!_stream.CanRead || _stream.Position == _stream.Length)
return 1;
return 0;
}
public void Dispose()
{
if (_isDisposed) return;
if (!_keepOpen) _stream.Dispose();
_isDisposed = true;
}
}
}

View File

@ -1,3 +0,0 @@
#!/bin/bash
cd $(dirname "$0")
../sh/quik_build_native.sh .

View File

@ -1,30 +0,0 @@
-x
c
-l
stbi
--config
compatible-codegen
single-file
exclude-fnptr-codegen
generate-aggressive-inlining
generate-setslastsystemerror-attribute
unix-types
--include-directory
../lib
--include-directory
../Quik.StbImage
--include-directory
/usr/lib/llvm-14/lib/clang/14.0.6/include
--file
../Quik.StbImage.redist/quik_stbi.h
../lib/stb/stb_image.h
--methodClassName
Stbi
--namespace
Quik.Stb
--output
Stbi.cs
--prefixStrip
stbi_
--with-type
FILE=void

View File

@ -1,6 +0,0 @@
#include "quik_stbi.h"
QUIK_DEFINE_LIB(quik_stbi);
#define STB_IMAGE_IMPLEMENTATION 1
#include "stb/stb_image.h"

View File

@ -1,18 +0,0 @@
#ifndef _QUIK_STBI_H_
#define _QUIK_STBI_H_
#include "quik/quik_common.h"
QUIK_DECLARE_LIB(quik_stbi)
/* TODO: Change this declaration so we can export a DLL properly in windows. */
#define STBIDEF QEXTERN
#define STBI_ASSERT(EXPR) do { \
if (!(EXPR)) \
quik_stbi_failed_assert(#EXPR, __FILE__, __LINE__ - 2, __QUIK_FUNCTION__); \
} while(0)
#include "stb/stb_image.h"
#endif

View File

@ -1,12 +0,0 @@
cmake_minimum_required(VERSION 3.0)
project(quik_stbtt LANGUAGES C VERSION 1.0)
add_compile_options(-static-libgcc)
add_library(stbtt SHARED "quik_stbtt.c")
target_include_directories(stbtt PRIVATE "../lib")
install(
TARGETS stbtt
RUNTIME DESTINATION .
LIBRARY DESTINATION .)

View File

@ -1,12 +0,0 @@
using System;
namespace Quik.Stb.TrueType
{
[AttributeUsage(System.AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class NativeTypeNameAttribute : System.Attribute
{
public NativeTypeNameAttribute(string typename)
{
}
}
}

View File

@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Quik.StbTrueType.redist" Version="1.0" />
</ItemGroup>
<ItemGroup>
<Content Include="runtimes/**">
<PackagePath>runtimes</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -1,355 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace Quik.Stb
{
public unsafe class StbFont : IDisposable
{
IntPtr _buffer;
stbtt_fontinfo* _info;
List<stbtt_kerningentry> _kerningTable;
public IntPtr FontBuffer => _buffer;
public ref stbtt_fontinfo FontInfo => ref *_info;
public IReadOnlyList<stbtt_kerningentry> KerningTable
{
get
{
if (_kerningTable != null)
return _kerningTable;
int count = Stbtt.GetKerningTableLength(_info);
if (count == 0)
{
return _kerningTable = new List<stbtt_kerningentry>();
}
else
{
stbtt_kerningentry[] array = new stbtt_kerningentry[count];
fixed (stbtt_kerningentry *ptr = array)
Stbtt.GetKerningTable(_info, ptr, count);
return _kerningTable = new List<stbtt_kerningentry>(array);
}
}
}
public int Ascend { get; }
public int Descend { get; }
public int VerticalLineGap { get; }
public int AscendOS2 { get; }
public int DescendOS2 { get; }
public int VerticalLineGapOS2 { get; }
public Box BoundingBox { get; }
private StbFont(IntPtr buffer, stbtt_fontinfo* info)
{
_buffer = buffer;
_info = info;
int a, b, c, d;
Stbtt.GetFontVMetrics(_info, &a, &b, &c);
Ascend = a;
Descend = b;
VerticalLineGap = c;
Stbtt.GetFontVMetricsOS2(_info, &a, &b, &c);
AscendOS2 = a;
DescendOS2 = b;
VerticalLineGapOS2 = c;
Stbtt.GetFontBoundingBox(_info, &a, &b, &c, &d);
BoundingBox = new Box(a, b, c, d);
}
~StbFont()
{
Dispose(false);
}
public int FindGlyphIndex(int codepoint)
{
return Stbtt.FindGlyphIndex(_info, codepoint);
}
public int FindGlyphIndex(Rune codepoint) => FindGlyphIndex(codepoint.Value);
public float ScaleForPixelHeight(float pixels)
{
return Stbtt.ScaleForPixelHeight(_info, pixels);
}
public float ScaleForMappingEmToPixels(float pixels)
{
return Stbtt.ScaleForMappingEmToPixels(_info, pixels);
}
public void GetCodepointHMetrics(int codepoint, out int advance, out int bearing)
{
int a, b;
Stbtt.GetCodepointHMetrics(_info, codepoint, &a, &b);
advance = a;
bearing = b;
}
public void GetCodepointHMetrics(Rune codepoint, out int advance, out int bearing)
=> GetCodepointHMetrics(codepoint.Value, out advance, out bearing);
public int GetCodepointKernAdvance(int cp1, int cp2)
{
return Stbtt.GetCodepointKernAdvance(_info, cp1, cp2);
}
public int GetCodepointKernAdvance(Rune cp1, Rune cp2) => GetCodepointKernAdvance(cp1.Value, cp2.Value);
public int GetCodepointBox(int codepoint, out Box box)
{
int x0, y0;
int x1, y1;
int rval;
rval = Stbtt.GetCodepointBox(_info, codepoint, &x0, &y0, &x1, &y1);
box = new Box(x0, y0, x1, y1);
return rval;
}
public void GetGlyphHMetrics(int glyph, out int advance, out int bearing)
{
int a, b;
Stbtt.GetGlyphHMetrics(_info, glyph, &a, &b);
advance = a;
bearing = b;
}
public int GetGlyphKernAdvance(int gl1, int gl2)
{
return Stbtt.GetGlyphKernAdvance(_info, gl1, gl2);
}
public int GetGlyphBox(int glyph, out Box box)
{
int x0, y0;
int x1, y1;
int rval;
rval = Stbtt.GetGlyphBox(_info, glyph, &x0, &y0, &x1, &y1);
box = new Box(x0, y0, x1, y1);
return rval;
}
public bool IsGlyphEmpty(int glyph)
{
return Stbtt.IsGlyphEmpty(_info, glyph) != 0;
}
public Bitmap GetCodepointBitmap(float scaleX, float scaleY, int codepoint, out int offsetX, out int offsetY)
{
int w, h, x, y;
void* ptr = Stbtt.GetCodepointBitmap(_info, scaleX, scaleY, codepoint, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeBitmap);
}
public Bitmap GetCodepointBitmap(float scaleX, float scaleY, Rune codepoint, out int offsetX, out int offsetY)
=> GetCodepointBitmap(scaleX, scaleY, codepoint.Value, out offsetX, out offsetY);
public Bitmap GetCodepointBitmapSubpixel(float scaleX, float scaleY, float shiftX, float shiftY, int codepoint, out int offsetX, out int offsetY)
{
int w, h, x, y;
void* ptr = Stbtt.GetCodepointBitmapSubpixel(_info, scaleX, scaleY, shiftX, shiftY, codepoint, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeBitmap);
}
public Bitmap GetCodepointBitmapSubpixel(float scaleX, float scaleY, float shiftX, float shiftY, Rune codepoint, out int offsetX, out int offsetY)
=> GetCodepointBitmapSubpixel(scaleX, scaleY, shiftX, shiftY, codepoint.Value, out offsetX, out offsetY);
public Bitmap GetGlyphBitmap(float scaleX, float scaleY, int glyph, out int offsetX, out int offsetY)
{
int w, h, x, y;
void* ptr = Stbtt.GetGlyphBitmap(_info, scaleX, scaleY, glyph, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeBitmap);
}
public Bitmap GetGlyphBitmapSubpixel(float scaleX, float scaleY, float shiftX, float shiftY, int glyph, out int offsetX, out int offsetY)
{
int w, h, x, y;
void* ptr = Stbtt.GetGlyphBitmapSubpixel(_info, scaleX, scaleY, shiftX, shiftY, glyph, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeBitmap);
}
public Bitmap GetGlyphSdf(float scale, int glyph, int padding, byte edgeValue, float pixelDistScale, out int offsetX, out int offsetY)
{
int w, h, x, y;
void *ptr = Stbtt.GetGlyphSDF(_info, scale, glyph, padding, edgeValue, pixelDistScale, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeSdf);
}
public Bitmap GetCodepointSdf(float scale, int codepoint, int padding, byte edgeValue, float pixelDistScale, out int offsetX, out int offsetY)
{
int w, h, x, y;
void *ptr = Stbtt.GetCodepointSDF(_info, scale, codepoint, padding, edgeValue, pixelDistScale, &w, &h, &x, &y);
offsetX = x;
offsetY = y;
return new Bitmap((IntPtr)ptr, w, h, FreeSdf);
}
public Bitmap GetCodepointSdf(float scale, Rune codepoint, int padding, byte edgeValue, float pixelDistScale, out int offsetX, out int offsetY)
=> GetCodepointSdf(scale, codepoint.Value, padding, edgeValue, pixelDistScale, out offsetX, out offsetY);
public void Dispose()
{
Dispose(true);
}
bool isDisposed = false;
private void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
GC.SuppressFinalize(this);
}
Marshal.FreeHGlobal(_buffer);
Marshal.FreeHGlobal((IntPtr)_info);
isDisposed = true;
}
public static bool TryLoad(Stream stream, out StbFont font)
{
byte* buffer = (byte*)Marshal.AllocHGlobal((int)stream.Length);
stbtt_fontinfo* fontInfo = (stbtt_fontinfo*)Marshal.AllocHGlobal(sizeof(stbtt_fontinfo));
stream.Read(new Span<byte>(buffer, (int)stream.Length));
int nfont = Stbtt.GetNumberOfFonts(buffer);
if (nfont == 0)
{
font = null;
return false;
}
int offset = Stbtt.GetFontOffsetForIndex(buffer, 0);
if (Stbtt.InitFont(fontInfo, (byte*)buffer, offset) == 0)
{
Marshal.FreeHGlobal((IntPtr)buffer);
Marshal.FreeHGlobal((IntPtr)fontInfo);
font = null;
return false;
}
font = new StbFont((IntPtr)buffer, fontInfo);
return true;
}
public static StbFont Load(Stream stream)
{
if (TryLoad(stream, out StbFont font))
{
return font;
}
throw new Exception("Could not load the font.");
}
private static void FreeBitmap(IntPtr buffer)
{
Stbtt.FreeBitmap((byte*)buffer, null);
}
private static void FreeSdf(IntPtr buffer)
{
Stbtt.FreeSDF((byte*)buffer, null);
}
public struct Box
{
public int X0;
public int Y0;
public int X1;
public int Y1;
public Box(int x0, int y0, int x1, int y1)
{
X0 = x0; Y0 = y0;
X1 = x1; Y1 = y1;
}
}
public class Bitmap : IDisposable
{
public IntPtr Buffer { get; }
public int Width { get; }
public int Height { get; }
private readonly Action<IntPtr> Destroy;
public Bitmap(IntPtr buffer, int width, int height, Action<IntPtr> destroy)
{
Buffer = buffer;
Width = width;
Height = height;
Destroy = destroy;
}
~Bitmap()
{
Dispose(false);
}
public void Dispose() => Dispose(true);
private bool isDiposed = false;
public void Dispose(bool disposing)
{
if (isDiposed) return;
if (disposing)
{
GC.SuppressFinalize(this);
}
Destroy(Buffer);
isDiposed = true;
}
}
}
}

View File

@ -1,64 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace Quik.Stb
{
public unsafe static partial class Stbtt
{
private delegate void FailedAssertProc(byte *expression, byte *file, int line, byte *function);
private static readonly string[] LibraryNames = new string[]
{
//FIXME: This is wrong on so many levels, but, i need to do this
// in order to get a change of this running.
"runtimes/win-x64/native/libstbtt.dll",
"runtimes/win-x86/native/libstbtt.dll",
"runtimes/linux-arm/native/libstbtt.so",
"runtimes/linux-arm64/native/libstbtt.so",
"runtimes/linux-x64/native/libstbtt.so",
"runtimes/native/libstbtt.dylib",
"libstbtt.dll",
"libstbtt.so",
"libstbtt.dylib",
};
static Stbtt()
{
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver);
quik_stbtt_failed_assert_store(Marshal.GetFunctionPointerForDelegate<FailedAssertProc>(FailedAssert));
}
private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName != "stbtt")
return IntPtr.Zero;
foreach (string name in LibraryNames)
{
if (NativeLibrary.TryLoad(name, assembly, searchPath, out IntPtr handle))
{
return handle;
}
}
return NativeLibrary.Load(libraryName);
}
private static void FailedAssert(byte *expression, byte *file, int line, byte *function)
{
string expr = expression == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)expression);
string f = file == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)file);
string func = function == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)function);
Exception ex =
new Exception($"Assert failed in native stbtt code. ({System.IO.Path.GetFileName(f)}:{line})");
ex.Data.Add("Expression", expr);
ex.Data.Add("File", f);
ex.Data.Add("Line", line);
ex.Data.Add("Function", func);
throw ex;
}
}
}

View File

@ -1,495 +0,0 @@
using System;
using System.Runtime.InteropServices;
using Quik.Stb.TrueType;
namespace Quik.Stb
{
public unsafe partial struct stbtt__buf
{
[NativeTypeName("unsigned char *")]
public byte* data;
public int cursor;
public int size;
}
public partial struct stbtt_bakedchar
{
[NativeTypeName("unsigned short")]
public ushort x0;
[NativeTypeName("unsigned short")]
public ushort y0;
[NativeTypeName("unsigned short")]
public ushort x1;
[NativeTypeName("unsigned short")]
public ushort y1;
public float xoff;
public float yoff;
public float xadvance;
}
public partial struct stbtt_aligned_quad
{
public float x0;
public float y0;
public float s0;
public float t0;
public float x1;
public float y1;
public float s1;
public float t1;
}
public partial struct stbtt_packedchar
{
[NativeTypeName("unsigned short")]
public ushort x0;
[NativeTypeName("unsigned short")]
public ushort y0;
[NativeTypeName("unsigned short")]
public ushort x1;
[NativeTypeName("unsigned short")]
public ushort y1;
public float xoff;
public float yoff;
public float xadvance;
public float xoff2;
public float yoff2;
}
public partial struct stbrp_rect
{
}
public unsafe partial struct stbtt_pack_range
{
public float font_size;
public int first_unicode_codepoint_in_range;
public int* array_of_unicode_codepoints;
public int num_chars;
public stbtt_packedchar* chardata_for_range;
[NativeTypeName("unsigned char")]
public byte h_oversample;
[NativeTypeName("unsigned char")]
public byte v_oversample;
}
public unsafe partial struct stbtt_pack_context
{
public void* user_allocator_context;
public void* pack_info;
public int width;
public int height;
public int stride_in_bytes;
public int padding;
public int skip_missing;
[NativeTypeName("unsigned int")]
public uint h_oversample;
[NativeTypeName("unsigned int")]
public uint v_oversample;
[NativeTypeName("unsigned char *")]
public byte* pixels;
public void* nodes;
}
public unsafe partial struct stbtt_fontinfo
{
public void* userdata;
[NativeTypeName("unsigned char *")]
public byte* data;
public int fontstart;
public int numGlyphs;
public int loca;
public int head;
public int glyf;
public int hhea;
public int hmtx;
public int kern;
public int gpos;
public int svg;
public int index_map;
public int indexToLocFormat;
public stbtt__buf cff;
public stbtt__buf charstrings;
public stbtt__buf gsubrs;
public stbtt__buf subrs;
public stbtt__buf fontdicts;
public stbtt__buf fdselect;
}
public partial struct stbtt_kerningentry
{
public int glyph1;
public int glyph2;
public int advance;
}
[NativeTypeName("unsigned int")]
public enum StbttV : uint
{
STBTT_vmove = 1,
STBTT_vline,
STBTT_vcurve,
STBTT_vcubic,
}
public partial struct stbtt_vertex
{
public short x;
public short y;
public short cx;
public short cy;
public short cx1;
public short cy1;
[NativeTypeName("unsigned char")]
public byte type;
[NativeTypeName("unsigned char")]
public byte padding;
}
public unsafe partial struct stbtt__bitmap
{
public int w;
public int h;
public int stride;
[NativeTypeName("unsigned char *")]
public byte* pixels;
}
[NativeTypeName("unsigned int")]
public enum StbttPlatform : uint
{
STBTT_PLATFORM_ID_UNICODE = 0,
STBTT_PLATFORM_ID_MAC = 1,
STBTT_PLATFORM_ID_ISO = 2,
STBTT_PLATFORM_ID_MICROSOFT = 3,
}
[NativeTypeName("unsigned int")]
public enum StbttUnicode : uint
{
STBTT_UNICODE_EID_UNICODE_1_0 = 0,
STBTT_UNICODE_EID_UNICODE_1_1 = 1,
STBTT_UNICODE_EID_ISO_10646 = 2,
STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3,
STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4,
}
[NativeTypeName("unsigned int")]
public enum StbttMs : uint
{
STBTT_MS_EID_SYMBOL = 0,
STBTT_MS_EID_UNICODE_BMP = 1,
STBTT_MS_EID_SHIFTJIS = 2,
STBTT_MS_EID_UNICODE_FULL = 10,
}
[NativeTypeName("unsigned int")]
public enum StbttMac : uint
{
STBTT_MAC_EID_ROMAN = 0,
STBTT_MAC_EID_ARABIC = 4,
STBTT_MAC_EID_JAPANESE = 1,
STBTT_MAC_EID_HEBREW = 5,
STBTT_MAC_EID_CHINESE_TRAD = 2,
STBTT_MAC_EID_GREEK = 6,
STBTT_MAC_EID_KOREAN = 3,
STBTT_MAC_EID_RUSSIAN = 7,
}
[NativeTypeName("unsigned int")]
public enum StbttMsLang : uint
{
STBTT_MS_LANG_ENGLISH = 0x0409,
STBTT_MS_LANG_ITALIAN = 0x0410,
STBTT_MS_LANG_CHINESE = 0x0804,
STBTT_MS_LANG_JAPANESE = 0x0411,
STBTT_MS_LANG_DUTCH = 0x0413,
STBTT_MS_LANG_KOREAN = 0x0412,
STBTT_MS_LANG_FRENCH = 0x040c,
STBTT_MS_LANG_RUSSIAN = 0x0419,
STBTT_MS_LANG_GERMAN = 0x0407,
STBTT_MS_LANG_SPANISH = 0x0409,
STBTT_MS_LANG_HEBREW = 0x040d,
STBTT_MS_LANG_SWEDISH = 0x041D,
}
[NativeTypeName("unsigned int")]
public enum StbttMacLang : uint
{
STBTT_MAC_LANG_ENGLISH = 0,
STBTT_MAC_LANG_JAPANESE = 11,
STBTT_MAC_LANG_ARABIC = 12,
STBTT_MAC_LANG_KOREAN = 23,
STBTT_MAC_LANG_DUTCH = 4,
STBTT_MAC_LANG_RUSSIAN = 32,
STBTT_MAC_LANG_FRENCH = 1,
STBTT_MAC_LANG_SPANISH = 6,
STBTT_MAC_LANG_GERMAN = 2,
STBTT_MAC_LANG_SWEDISH = 5,
STBTT_MAC_LANG_HEBREW = 10,
STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33,
STBTT_MAC_LANG_ITALIAN = 3,
STBTT_MAC_LANG_CHINESE_TRAD = 19,
}
public static unsafe partial class Stbtt
{
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void quik_stbtt_failed_assert_store([NativeTypeName("quik_failed_assert_cb_t")] IntPtr cb);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_BakeFontBitmap", ExactSpelling = true)]
public static extern int BakeFontBitmap([NativeTypeName("const unsigned char *")] byte* data, int offset, float pixel_height, [NativeTypeName("unsigned char *")] byte* pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar* chardata);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetBakedQuad", ExactSpelling = true)]
public static extern void GetBakedQuad([NativeTypeName("const stbtt_bakedchar *")] stbtt_bakedchar* chardata, int pw, int ph, int char_index, float* xpos, float* ypos, stbtt_aligned_quad* q, int opengl_fillrule);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetScaledFontVMetrics", ExactSpelling = true)]
public static extern void GetScaledFontVMetrics([NativeTypeName("const unsigned char *")] byte* fontdata, int index, float size, float* ascent, float* descent, float* lineGap);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackBegin", ExactSpelling = true)]
public static extern int PackBegin(stbtt_pack_context* spc, [NativeTypeName("unsigned char *")] byte* pixels, int width, int height, int stride_in_bytes, int padding, void* alloc_context);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackEnd", ExactSpelling = true)]
public static extern void PackEnd(stbtt_pack_context* spc);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackFontRange", ExactSpelling = true)]
public static extern int PackFontRange(stbtt_pack_context* spc, [NativeTypeName("const unsigned char *")] byte* fontdata, int font_index, float font_size, int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar* chardata_for_range);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackFontRanges", ExactSpelling = true)]
public static extern int PackFontRanges(stbtt_pack_context* spc, [NativeTypeName("const unsigned char *")] byte* fontdata, int font_index, stbtt_pack_range* ranges, int num_ranges);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackSetOversampling", ExactSpelling = true)]
public static extern void PackSetOversampling(stbtt_pack_context* spc, [NativeTypeName("unsigned int")] uint h_oversample, [NativeTypeName("unsigned int")] uint v_oversample);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackSetSkipMissingCodepoints", ExactSpelling = true)]
public static extern void PackSetSkipMissingCodepoints(stbtt_pack_context* spc, int skip);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetPackedQuad", ExactSpelling = true)]
public static extern void GetPackedQuad([NativeTypeName("const stbtt_packedchar *")] stbtt_packedchar* chardata, int pw, int ph, int char_index, float* xpos, float* ypos, stbtt_aligned_quad* q, int align_to_integer);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackFontRangesGatherRects", ExactSpelling = true)]
public static extern int PackFontRangesGatherRects(stbtt_pack_context* spc, [NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, stbtt_pack_range* ranges, int num_ranges, stbrp_rect* rects);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackFontRangesPackRects", ExactSpelling = true)]
public static extern void PackFontRangesPackRects(stbtt_pack_context* spc, stbrp_rect* rects, int num_rects);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_PackFontRangesRenderIntoRects", ExactSpelling = true)]
public static extern int PackFontRangesRenderIntoRects(stbtt_pack_context* spc, [NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, stbtt_pack_range* ranges, int num_ranges, stbrp_rect* rects);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetNumberOfFonts", ExactSpelling = true)]
public static extern int GetNumberOfFonts([NativeTypeName("const unsigned char *")] byte* data);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetFontOffsetForIndex", ExactSpelling = true)]
public static extern int GetFontOffsetForIndex([NativeTypeName("const unsigned char *")] byte* data, int index);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_InitFont", ExactSpelling = true)]
public static extern int InitFont(stbtt_fontinfo* info, [NativeTypeName("const unsigned char *")] byte* data, int offset);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FindGlyphIndex", ExactSpelling = true)]
public static extern int FindGlyphIndex([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int unicode_codepoint);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_ScaleForPixelHeight", ExactSpelling = true)]
public static extern float ScaleForPixelHeight([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float pixels);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_ScaleForMappingEmToPixels", ExactSpelling = true)]
public static extern float ScaleForMappingEmToPixels([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float pixels);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetFontVMetrics", ExactSpelling = true)]
public static extern void GetFontVMetrics([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int* ascent, int* descent, int* lineGap);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetFontVMetricsOS2", ExactSpelling = true)]
public static extern int GetFontVMetricsOS2([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int* typoAscent, int* typoDescent, int* typoLineGap);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetFontBoundingBox", ExactSpelling = true)]
public static extern void GetFontBoundingBox([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int* x0, int* y0, int* x1, int* y1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointHMetrics", ExactSpelling = true)]
public static extern void GetCodepointHMetrics([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int codepoint, int* advanceWidth, int* leftSideBearing);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointKernAdvance", ExactSpelling = true)]
public static extern int GetCodepointKernAdvance([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int ch1, int ch2);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointBox", ExactSpelling = true)]
public static extern int GetCodepointBox([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int codepoint, int* x0, int* y0, int* x1, int* y1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphHMetrics", ExactSpelling = true)]
public static extern void GetGlyphHMetrics([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int glyph_index, int* advanceWidth, int* leftSideBearing);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphKernAdvance", ExactSpelling = true)]
public static extern int GetGlyphKernAdvance([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int glyph1, int glyph2);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphBox", ExactSpelling = true)]
public static extern int GetGlyphBox([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int glyph_index, int* x0, int* y0, int* x1, int* y1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetKerningTableLength", ExactSpelling = true)]
public static extern int GetKerningTableLength([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetKerningTable", ExactSpelling = true)]
public static extern int GetKerningTable([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, stbtt_kerningentry* table, int table_length);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_IsGlyphEmpty", ExactSpelling = true)]
public static extern int IsGlyphEmpty([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int glyph_index);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointShape", ExactSpelling = true)]
public static extern int GetCodepointShape([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int unicode_codepoint, stbtt_vertex** vertices);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphShape", ExactSpelling = true)]
public static extern int GetGlyphShape([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int glyph_index, stbtt_vertex** vertices);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FreeShape", ExactSpelling = true)]
public static extern void FreeShape([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, stbtt_vertex* vertices);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FindSVGDoc", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* FindSVGDoc([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int gl);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointSVG", ExactSpelling = true)]
public static extern int GetCodepointSVG([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int unicode_codepoint, [NativeTypeName("const char **")] sbyte** svg);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphSVG", ExactSpelling = true)]
public static extern int GetGlyphSVG([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, int gl, [NativeTypeName("const char **")] sbyte** svg);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FreeBitmap", ExactSpelling = true)]
public static extern void FreeBitmap([NativeTypeName("unsigned char *")] byte* bitmap, void* userdata);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointBitmap", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetCodepointBitmap([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale_x, float scale_y, int codepoint, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointBitmapSubpixel", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetCodepointBitmapSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeCodepointBitmap", ExactSpelling = true)]
public static extern void MakeCodepointBitmap([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeCodepointBitmapSubpixel", ExactSpelling = true)]
public static extern void MakeCodepointBitmapSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeCodepointBitmapSubpixelPrefilter", ExactSpelling = true)]
public static extern void MakeCodepointBitmapSubpixelPrefilter([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float* sub_x, float* sub_y, int codepoint);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointBitmapBox", ExactSpelling = true)]
public static extern void GetCodepointBitmapBox([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* font, int codepoint, float scale_x, float scale_y, int* ix0, int* iy0, int* ix1, int* iy1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointBitmapBoxSubpixel", ExactSpelling = true)]
public static extern void GetCodepointBitmapBoxSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int* ix0, int* iy0, int* ix1, int* iy1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphBitmap", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetGlyphBitmap([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale_x, float scale_y, int glyph, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphBitmapSubpixel", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetGlyphBitmapSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeGlyphBitmap", ExactSpelling = true)]
public static extern void MakeGlyphBitmap([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeGlyphBitmapSubpixel", ExactSpelling = true)]
public static extern void MakeGlyphBitmapSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_MakeGlyphBitmapSubpixelPrefilter", ExactSpelling = true)]
public static extern void MakeGlyphBitmapSubpixelPrefilter([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, [NativeTypeName("unsigned char *")] byte* output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float* sub_x, float* sub_y, int glyph);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphBitmapBox", ExactSpelling = true)]
public static extern void GetGlyphBitmapBox([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* font, int glyph, float scale_x, float scale_y, int* ix0, int* iy0, int* ix1, int* iy1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphBitmapBoxSubpixel", ExactSpelling = true)]
public static extern void GetGlyphBitmapBoxSubpixel([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int* ix0, int* iy0, int* ix1, int* iy1);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_Rasterize", ExactSpelling = true)]
public static extern void Rasterize(stbtt__bitmap* result, float flatness_in_pixels, stbtt_vertex* vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void* userdata);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FreeSDF", ExactSpelling = true)]
public static extern void FreeSDF([NativeTypeName("unsigned char *")] byte* bitmap, void* userdata);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetGlyphSDF", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetGlyphSDF([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale, int glyph, int padding, [NativeTypeName("unsigned char")] byte onedge_value, float pixel_dist_scale, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetCodepointSDF", ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* GetCodepointSDF([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* info, float scale, int codepoint, int padding, [NativeTypeName("unsigned char")] byte onedge_value, float pixel_dist_scale, int* width, int* height, int* xoff, int* yoff);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_FindMatchingFont", ExactSpelling = true)]
public static extern int FindMatchingFont([NativeTypeName("const unsigned char *")] byte* fontdata, [NativeTypeName("const char *")] sbyte* name, int flags);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_CompareUTF8toUTF16_bigendian", ExactSpelling = true)]
public static extern int CompareUTF8toUTF16_bigendian([NativeTypeName("const char *")] sbyte* s1, int len1, [NativeTypeName("const char *")] sbyte* s2, int len2);
[DllImport("stbtt", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbtt_GetFontNameString", ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* GetFontNameString([NativeTypeName("const stbtt_fontinfo *")] stbtt_fontinfo* font, int* length, int platformID, int encodingID, int languageID, int nameID);
}
}

View File

@ -1,3 +0,0 @@
#!/bin/bash
cd $(dirname "$0")
../sh/quik_build_native.sh .

View File

@ -1,30 +0,0 @@
-x
c
-l
stbtt
--config
compatible-codegen
single-file
exclude-fnptr-codegen
generate-aggressive-inlining
generate-setslastsystemerror-attribute
unix-types
--include-directory
../lib
--include-directory
../Quik.StbTrueType.redist
--include-directory
/usr/lib/llvm-14/lib/clang/14.0.6/include
--file
../Quik.StbTrueType.redist/quik_stbtt.h
../lib/stb/stb_truetype.h
--methodClassName
Stbtt
--namespace
Quik.Stb
--output
Stbtt.cs
--prefixStrip
stbtt_
--with-type
FILE=void

View File

@ -1,6 +0,0 @@
#include "quik_stbtt.h"
QUIK_DEFINE_LIB(quik_stbtt);
#define STB_TRUETYPE_IMPLEMENTATION 1
#include "stb/stb_truetype.h"

View File

@ -1,14 +0,0 @@
#ifndef _QUIK_STBTT_H_
#define _QUIK_STBTT_H_
#include "quik/quik_common.h"
QUIK_DECLARE_LIB(quik_stbtt);
#define STBTT_assert(EXPR) do { \
quik_stbtt_failed_assert(#EXPR, __FILE__, __LINE__ - 2, __QUIK_FUNCTION__); \
} while(0)
#include "stb/stb_truetype.h"
#endif

View File

@ -1,21 +1,17 @@

Microsoft Visual Studio Solution File, Format Version 12.00
#
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
# Visual Studio Version 17
VisualStudioVersion = 17.9.34701.34
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.StbImage", "Quik.StbImage\Quik.StbImage.csproj", "{B1D7A987-F50A-4B6C-943D-F74525431BF5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.StbTrueType", "Quik.StbTrueType\Quik.StbTrueType.csproj", "{AD5B02B0-F957-4816-8CE9-5F278B856C70}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.Media.Stb", "Quik.Media.Stb\Quik.Media.Stb.csproj", "{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AE05ADE5-A809-479F-97D5-BEAFE7604285}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.Stb.Tests", "tests\Quik.Stb.Tests\Quik.Stb.Tests.csproj", "{BC7D3002-B79B-4141-B6CC-74FB2175B474}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuikDemo", "tests\QuikDemo\QuikDemo.csproj", "{79CBF97F-4884-4692-94FB-75DDEB61E26F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuikDemo", "tests\QuikDemo\QuikDemo.csproj", "{79CBF97F-4884-4692-94FB-75DDEB61E26F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik.Media.Defaults", "Quik.Media.Defaults\Quik.Media.Defaults.csproj", "{B517D2BF-CB9D-4448-BE50-EA85E100EB47}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -51,54 +47,6 @@ Global
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|x64.ActiveCfg = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|x64.Build.0 = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|x86.ActiveCfg = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Debug|x86.Build.0 = Debug|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|Any CPU.Build.0 = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|x64.ActiveCfg = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|x64.Build.0 = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|x86.ActiveCfg = Release|Any CPU
{B1D7A987-F50A-4B6C-943D-F74525431BF5}.Release|x86.Build.0 = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|x64.ActiveCfg = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|x64.Build.0 = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|x86.ActiveCfg = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Debug|x86.Build.0 = Debug|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|Any CPU.Build.0 = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|x64.ActiveCfg = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|x64.Build.0 = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|x86.ActiveCfg = Release|Any CPU
{AD5B02B0-F957-4816-8CE9-5F278B856C70}.Release|x86.Build.0 = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|x64.ActiveCfg = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|x64.Build.0 = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|x86.ActiveCfg = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Debug|x86.Build.0 = Debug|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|Any CPU.Build.0 = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|x64.ActiveCfg = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|x64.Build.0 = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|x86.ActiveCfg = Release|Any CPU
{3D354BE0-42A7-45C4-AAEA-B0F8963A5745}.Release|x86.Build.0 = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|x64.ActiveCfg = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|x64.Build.0 = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|x86.ActiveCfg = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Debug|x86.Build.0 = Debug|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|Any CPU.Build.0 = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|x64.ActiveCfg = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|x64.Build.0 = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|x86.ActiveCfg = Release|Any CPU
{BC7D3002-B79B-4141-B6CC-74FB2175B474}.Release|x86.Build.0 = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -111,9 +59,26 @@ Global
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x64.Build.0 = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x86.ActiveCfg = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x86.Build.0 = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x64.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x64.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x86.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x86.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|Any CPU.Build.0 = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x64.ActiveCfg = Release|Any CPU
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{BC7D3002-B79B-4141-B6CC-74FB2175B474} = {AE05ADE5-A809-479F-97D5-BEAFE7604285}
{79CBF97F-4884-4692-94FB-75DDEB61E26F} = {AE05ADE5-A809-479F-97D5-BEAFE7604285}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EF011093-DA56-4E14-B2AB-D565B64F73E1}
EndGlobalSection
EndGlobal

View File

@ -1,60 +1,92 @@
using System;
using System.Runtime.InteropServices;
namespace Quik.Media.Color
namespace Quik.Media
{
public class ImageBuffer : IDisposable
public class QImageBuffer : QImage
{
private byte[] buffer;
GCHandle handle;
public QImageFormat Format { get; }
public int Width { get; }
public int Height { get; }
public int Depth { get; }
public override QImageFormat InternalFormat { get; }
public override int Width { get; }
public override int Height { get; }
public override int Depth { get; }
public ImageBuffer(QImageFormat format, int width, int height, int depth = 1)
public QImageBuffer(QImageFormat format, int width, int height, int depth = 1)
{
Format = format;
InternalFormat = format;
Width = width;
Height = height;
Depth = depth;
buffer = new byte[width * height * depth];
buffer = new byte[width * height * depth * format.BytesPerPixel()];
}
~ImageBuffer()
~QImageBuffer()
{
Dispose(false);
}
public QImageLock Lock()
private QImageLock Lock()
{
handle.Free();
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
return new QImageLock(Format, Width, Height, Depth, ptr);
return new QImageLock(InternalFormat, Width, Height, Depth, ptr);
}
public void Unlock()
protected override void Dispose(bool disposing)
{
handle.Free();
}
private bool isDiposed = false;
private void Dispose(bool disposing)
{
if (isDiposed) return;
if (handle.IsAllocated) handle.Free();
buffer = null;
handle.Free();
isDiposed = true;
GC.SuppressFinalize(this);
}
public void Dispose()
public override void LockBits2d(out QImageLock imageLock, QImageLockOptions options)
{
Dispose(true);
if (options.Format != options.Format) throw new InvalidOperationException("This image type cannot be converted.");
if (Depth > 1) throw new InvalidOperationException("This texture has a depth component.");
UnlockBits();
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
imageLock = new QImageLock(InternalFormat, Width, Height, Depth, ptr);
}
public override void LockBits3d(out QImageLock imageLock, QImageLockOptions options)
{
if (options.Format != options.Format) throw new InvalidOperationException("This image type cannot be converted.");
UnlockBits();
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
imageLock = new QImageLock(InternalFormat, Width, Height, Depth, ptr);
}
public override void LockBits3d(out QImageLock imageLock, QImageLockOptions options, int depth)
{
if (options.Format != options.Format) throw new InvalidOperationException("This image type cannot be converted.");
if (depth < 0 || depth > Depth)
throw new ArgumentOutOfRangeException(nameof(depth), "Depth must be in range.");
UnlockBits();
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
imageLock = new QImageLock(
InternalFormat,
Width,
Height,
1,
ptr + (depth * Width * Height * InternalFormat.BytesPerPixel()));
}
public override void UnlockBits()
{
if (handle.IsAllocated)
handle.Free();
}
}
}

View File

@ -32,7 +32,7 @@ namespace Quik.Media
}
}
public static int BitsPerPixel(this QImageFormat format)
public static int BytesPerPixel(this QImageFormat format)
{
switch (format)
{

View File

@ -6,31 +6,27 @@ namespace Quik.Media
{
public string Family { get; }
public FontStyle Style { get; }
public float Size { get; }
public override string ToString()
{
return $"{Family} {Style} {Size}";
return $"{Family} {Style}";
}
public override int GetHashCode()
{
return Family.GetHashCode() ^
(Style.GetHashCode() * 3976061) ^
(Size.GetHashCode() * 9428791);
(Style.GetHashCode() * 3976061);
}
public static bool operator==(FontInfo a, FontInfo b)
{
return (a.Style == b.Style) &&
(a.Size == b.Size) &&
(a.Family == a.Family);
}
public static bool operator!=(FontInfo a, FontInfo b)
{
return (a.Style != b.Style) ||
(a.Size != b.Size) ||
(a.Family != b.Family);
}

66
Quik/Media/ImageBuffer.cs Normal file
View File

@ -0,0 +1,66 @@
using System;
using System.Runtime.InteropServices;
namespace Quik.Media.Color
{
public class QImageBuffer : QImage
{
private byte[] buffer;
GCHandle handle;
public override QImageFormat InternalFormat { get; }
public override int Width { get; }
public override int Height { get; }
public override int Depth { get; }
public QImageBuffer(QImageFormat format, int width, int height, int depth = 1)
{
InternalFormat = format;
Width = width;
Height = height;
Depth = depth;
buffer = new byte[width * height * depth];
}
~QImageBuffer()
{
Dispose(false);
}
private QImageLock Lock()
{
handle.Free();
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
return new QImageLock(InternalFormat, Width, Height, Depth, ptr);
}
protected override void Dispose(bool disposing)
{
buffer = null;
handle.Free();
GC.SuppressFinalize(this);
}
public override void LockBits2d(out QImageLock imageLock, QImageLockOptions options)
{
imageLock = Lock();
}
public override void LockBits3d(out QImageLock imageLock, QImageLockOptions options)
{
imageLock = Lock();
}
public override void LockBits3d(out QImageLock imageLock, QImageLockOptions options, int depth)
{
imageLock = Lock();
}
public override void UnlockBits()
{
handle.Free();
}
}
}

View File

@ -10,12 +10,10 @@ namespace Quik.Media
public abstract FontInfo Info { get; }
public string Family => Info.Family;
public FontStyle Style => Info.Style;
public float Size => Info.Size;
public abstract bool HasRune(int rune);
public abstract QImage RenderPage(int codepage, float resolution, bool sdf);
public abstract QGlyphMetrics GetMetricsForRune(int rune);
public abstract QGlyphMetrics[] GetMetricsForPage(int codepage);
public abstract QFontPage RasterizePage(int codepage, float size, in FontRasterizerOptions options);
public QFontPage RasterizePage(int codepage, float size) => RasterizePage(codepage, size, FontRasterizerOptions.Default);
// IDisposable
private bool isDisposed = false;
@ -30,4 +28,62 @@ namespace Quik.Media
protected virtual void Dispose(bool disposing) { }
public void Dispose() => DisposePrivate(true);
}
public struct FontRasterizerOptions
{
public float Resolution { get; set; }
public bool Sdf { get; set; }
public static readonly FontRasterizerOptions Default = new FontRasterizerOptions()
{
Resolution = 96.0f,
Sdf = true
};
}
public class QFontPage : IDisposable
{
public QFont Font { get; }
public int CodePage { get; }
public float Size { get; }
public virtual QImage Image { get; } = null;
public virtual QGlyphMetrics[] Metrics { get; } = Array.Empty<QGlyphMetrics>();
public FontRasterizerOptions Options { get; }
public float Resolution => Options.Resolution;
public bool Sdf => Options.Sdf;
public void Dispose() => DisposeInternal(false);
protected QFontPage(QFont font, int codepage, float size, in FontRasterizerOptions options)
{
Font = font;
CodePage = codepage;
Size = size;
Options = options;
}
public QFontPage(QFont font, int codepage, float size, in FontRasterizerOptions options, QImage image, QGlyphMetrics[] metrics)
: this(font, codepage, size, options)
{
Image = image;
Metrics = metrics;
}
private bool isDisposed = false;
private void DisposeInternal(bool disposing)
{
if (isDisposed) return;
Dispose(disposing);
isDisposed = true;
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Image?.Dispose();
}
}
}
}

View File

@ -10,10 +10,10 @@ namespace Quik.Media
/// </summary>
public int Rune { get; }
/// <summary>
/// Location of the glyph on the atlas.
/// </summary>
public QRectangle Location { get; }
// /// <summary>
// /// Location of the glyph on the atlas.
// /// </summary>
// public QRectangle Location { get; }
/// <summary>
/// Size of the glyph in units.
@ -37,14 +37,14 @@ namespace Quik.Media
public QGlyphMetrics(
int character,
QRectangle location,
// QRectangle location,
QVec2 size,
QVec2 horizontalBearing,
QVec2 verticalBearing,
QVec2 advance)
{
Rune = character;
Location = location;
// Location = location;
Size = size;
HorizontalBearing = horizontalBearing;
VerticalBearing = verticalBearing;

View File

@ -16,7 +16,7 @@ namespace Quik.OpenGL
private delegate void GLI4Proc(int x, int y, int z, int w);
private delegate void GLF4Proc(float x, float y, float z, float w);
private delegate void DrawElementsProc(GLEnum primitive, int size, GLEnum type, void *offset);
private delegate void DrawArraysProc(GLEnum primitive, int size, void *offset);
private delegate void DrawArraysProc(GLEnum primitive, int first, int offset);
private delegate void GetIntegervProc(GLEnum pname, int *data);
private delegate void GetFloatvProc(GLEnum pname, float *data);
private delegate byte* GetStringProc(GLEnum pname);
@ -88,7 +88,7 @@ namespace Quik.OpenGL
public static void DrawElements(GLEnum primitive, int count, GLEnum type, int offset) => _drawElements(primitive, count, type, (void*)offset);
[MethodImpl(AggressiveInlining)]
public static void DrawArrays(GLEnum primitive, int count, int offset) => _drawArrays(primitive, count, (void*)offset);
public static void DrawArrays(GLEnum primitive, int offset, int count) => _drawArrays(primitive, offset, count);
[MethodImpl(AggressiveInlining)]
public static void Get(GLEnum pname, out int value)

View File

@ -93,7 +93,7 @@ namespace Quik.OpenGL
QMat4.Orthographic(out QMat4 matrix, view);
GL.UseProgram(program);
GL.Uniform1(iMaxZ, queue.ZDepth);
GL.Uniform1(iMaxZ, queue.ZDepth+1);
GL.UniformMatrix4(m4Transforms, false, in matrix);
GL.Uniform1(fSdfThreshold, 0.0f);
GL.Uniform1(txTexture, 0);
@ -116,7 +116,7 @@ namespace Quik.OpenGL
GL.Uniform1(iEnableTexture, 0);
}
GL.DrawArrays(GL_TRIANGLES, call.Count, call.Start);
GL.DrawElements(GL_TRIANGLES, call.Count, GL_UNSIGNED_INT, sizeof(int)*call.Start);
}
}
@ -138,6 +138,7 @@ namespace Quik.OpenGL
int shader = GL.CreateShader(type);
GL.ShaderSource(shader, text);
GL.CompileShader(shader);
if (CheckShader(shader, out string msg) == false)
{
@ -157,7 +158,7 @@ namespace Quik.OpenGL
GL.GetShader(shader, GL_COMPILE_STATUS, out int i);
if (i != (int)GL_OK)
if (i != (int)GL_TRUE)
{
message = GL.GetShaderInfoLog(shader);
return false;
@ -229,15 +230,13 @@ namespace Quik.OpenGL
public DrawData(GL21Driver driver, DrawQueue queue)
{
int a = 0, b = 0, c = 0, d = 0;
Queue = queue;
this.driver = driver;
VertexArray = GL.GenVertexArray();
GL.GenBuffers(4, out a);
vbo1 = a;
vbo2 = b;
ebo1 = c;
ebo2 = d;
GL.GenBuffers(1, out vbo1);
GL.GenBuffers(1, out vbo2);
GL.GenBuffers(1, out ebo1);
GL.GenBuffers(1, out ebo2);
isDisposed = false;
}
@ -257,7 +256,11 @@ namespace Quik.OpenGL
GL.VertexAttribPointer(driver.v2Position, 2, GL_FLOAT, false, QuikVertex.Stride, QuikVertex.PositionOffset);
GL.VertexAttribIPointer(driver.iZIndex, 1, GL_UNSIGNED_INT, QuikVertex.Stride, QuikVertex.ZIndexOffset);
GL.VertexAttribPointer(driver.v2TexPos, 2, GL_FLOAT, false, QuikVertex.Stride, QuikVertex.TextureCoordinatesOffset);
GL.VertexAttribPointer(driver.v4Color, 4, GL_FLOAT, false, QuikVertex.Stride, QuikVertex.ColorOffset);
GL.VertexAttribPointer(driver.v4Color, 4, GL_UNSIGNED_BYTE, true, QuikVertex.Stride, QuikVertex.ColorOffset);
GL.EnableVertexAttribArray(driver.v2Position);
GL.EnableVertexAttribArray(driver.iZIndex);
GL.EnableVertexAttribArray(driver.v2TexPos);
GL.EnableVertexAttribArray(driver.v4Color);
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, Queue.ElementCount * sizeof(int), Queue.ElementArray, GL_STREAM_DRAW);

View File

@ -3,6 +3,8 @@ namespace Quik.OpenGL
public enum GLEnum : int
{
GL_OK = 0,
GL_TRUE = 1,
GL_FALSE = 0,
GL_MAJOR_VERSION = 0x821B,
GL_MINOR_VERSION = 0x821C,
GL_VENDOR = 0x1F00,

View File

@ -2,7 +2,7 @@
* QUIK: User Interface Kit
* Copyright (C) 2023 Halit Utku Maden, et al.
*/
#version 110
#version 120
varying vec2 fv2TexPos;
varying vec4 fv4Color;

View File

@ -2,7 +2,7 @@
* QUIK: User Interface Kit
* Copyright (C) 2023 Halit Utku Maden, et al.
*/
#version 110
#version 120
attribute vec2 v2Position; /**< The vertex position.*/
attribute int iZIndex; /**< The z index. */
@ -21,5 +21,5 @@ void main(void)
gl_Position = v * m4Transforms;
fv2TexPos = v2TexPos;
fv4Color = fv4Color;
fv4Color = v4Color;
}

View File

@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="46.12664pt"
height="18.818359pt"
viewBox="0 0 16.272453 6.6386992"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="quik.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:document-units="mm"
showgrid="false"
fit-margin-top="2"
fit-margin-left="2"
fit-margin-right="2"
fit-margin-bottom="2"
inkscape:zoom="8.2344211"
inkscape:cx="30.846127"
inkscape:cy="13.965766"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
lock-margins="true"
units="pt" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-29.294981,-112.71488)">
<g
id="g25273">
<text
xml:space="preserve"
style="font-size:6.35px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583"
x="29.445532"
y="118.04341"
id="text2725"><tspan
sodipodi:role="line"
id="tspan2723"
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:'Arial Bold Italic';stroke-width:0.264583"
x="29.445532"
y="118.04341">Q</tspan></text>
<text
xml:space="preserve"
style="font-style:italic;font-weight:bold;font-size:5.99722px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold Italic';stroke-width:0.264583"
x="34.059269"
y="117.71337"
id="text16833"><tspan
sodipodi:role="line"
id="tspan16831"
style="font-size:5.99722px;stroke-width:0.264583"
x="34.059269"
y="117.71337">UIK</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 34.395642,118.32379 H 44.759014"
id="path20974"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,13 +0,0 @@
# QUIK Toolchain file for Linux-arm systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH "/usr/arm-linux-gnueabihf")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,13 +0,0 @@
# QUIK Toolchain file for Linux-arm64 (aarch64) systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH "/usr/aarch64-linux-gnu")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,9 +0,0 @@
# QUIK Toolchain file for Linux-x64 (amd64) systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)
add_compile_options(-m64)

View File

@ -1,14 +0,0 @@
# QUIK Toolchain file for Linux-x86 (i386) systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER i686-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER i686-linux-gnu-g++)
add_compile_options(-m32 -march=i686)
set(CMAKE_FIND_ROOT_PATH "/usr/i686-linux-gnu")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,14 +0,0 @@
# QUIK Toolchain file for Windows-x64 systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
add_compile_options(-m64)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,14 +0,0 @@
# QUIK Toolchain file for Windows-x86 systems.
# Copyright (C) 2023
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
set(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
add_compile_options(-m32)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -4,10 +4,4 @@ services:
user: quik
working_dir: /home/quik
volumes:
- src:/home/quik/src
volumes:
src:
driver_opts:
type: none
device: ${PWD}
o: bind
- .:/home/quik/src

@ -1 +1 @@
Subproject commit 1ecfd2199012edb403605c7f68618a761eaf1193
Subproject commit 86bc8a95056c97a810986434a3f268cbe67f2902

View File

@ -1,47 +0,0 @@
#ifndef _QUIK_COMMON_H_
#define _QUIK_COMMON_H_
#include "stdlib.h"
#if __GNUC__ || __MSC_VER
#define __QUIK_FUNCTION__ __FUNCTION__
#define QEXTERN extern
#else
#define __QUIK_FUNCTION__ NULL
#endif
/**
* @brief Callback for failed assert function for QUIK redist libraries.
* @param[in] expr The expression that failed.
* @param[in] file The failing file (if available)
* @param[in] line The failing line number (if available)
* @param[in] func The failing function (if available)
*/
typedef void (*quik_failed_assert_cb_t)(const char *expr, const char *file, int line, const char* func);
#define DECLARE_ASSERT_CB(NAME) \
QEXTERN quik_failed_assert_cb_t NAME##_failed_assert
#define DECLARE_ASSERT_STORE(NAME) \
QEXTERN void NAME##_failed_assert_store(quik_failed_assert_cb_t cb)
#define DEFINE_ASSERT_CB(NAME) \
quik_failed_assert_cb_t NAME##_failed_assert
#define DEFINE_ASSERT_STORE(NAME) \
void NAME##_failed_assert_store(quik_failed_assert_cb_t cb) { \
NAME##_failed_assert = cb != NULL ? cb : quik_default_assert; \
}
#define QUIK_DECLARE_LIB(NAME) \
DECLARE_ASSERT_CB(NAME); \
DECLARE_ASSERT_STORE(NAME);
#define QUIK_DEFINE_LIB(NAME) \
DEFINE_ASSERT_CB(NAME); \
DEFINE_ASSERT_STORE(NAME);
inline static void quik_default_assert(const char *expr, const char *file, int line, const char *function)
{
abort();
}
#endif

View File

@ -1,5 +0,0 @@
source $HOME/src/sh/init.sh
echo QUIK Project Copyright \(C\) 2023
echo
echo This is an interactive shell for QUIK build image.
echo SuperUser \(su/sudo\) commands are enabled without a password. Beware.

View File

@ -1,15 +0,0 @@
#!/bin/bash
# Change to source directory
cd $HOME/src
export QUIK_SRC=$PWD
export QNUGET_LOCAL=QuikLocal
export QNUGET_LOCAL_PATH=$QUIK_SRC/nuget_repo
# export QNUGET_REMOTE=nuget
# Create nuget repository.
mkdir -p $QUIK_SRC/nuget_repo
nuget sources Add -Name $QNUGET_LOCAL -Source $QNUGET_LOCAL_PATH -NonInteractive
source sh/quik_build_native.sh

View File

@ -1,43 +0,0 @@
#!/bin/bash
# $1 Source path of the project.
# $2 Target architecture list.
SRC=$1
NAME=$(dirname $SRC)
ARCHS=$2
if [ -z "$SRC" ]
then
echo You need to provide a source path.
return
fi
if [ -z "$ARCHS" ]
then
ARCHS="linux-arm linux-arm64 linux-x64 win-x64 win-x86"
fi
cd $SRC
for ARCH in $ARCHS; do
# Output directory.
PREFIX=runtimes/$ARCH/native
# Build directory.
BUILD=out/$ARCH
# Cmake toolchain file.
TOOLCHAIN=../cmake/$ARCH.cmake
# Create directories.
mkdir -p $PREFIX $BUILD
# Configure CMAKE.
cmake -B $BUILD -S . \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$PREFIX \
-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN
# Build and install.
ninja -C $BUILD all
ninja -C $BUILD install
done

View File

@ -1,72 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Runtime.InteropServices;
using Quik.Stb;
namespace Quik.Stb
{
[TestClass]
[TestCategory("Load Font")]
public class LoadFont
{
StbFont? font;
[TestInitialize]
public void Initialize()
{
using (Stream? str = GetType().Assembly.GetManifestResourceStream("Quik.Stb.Tests.res.Varicka.ttf"))
{
Assert.IsNotNull(str, "Test font file not packed.");
font = StbFont.Load(str);
}
}
[TestCleanup]
public void Deinitialize()
{
font?.Dispose();
}
[TestMethod]
public void AscendIsValid()
{
Assert.AreNotEqual(-1, font!.Ascend);
}
[TestMethod]
public void DescendIsValid()
{
Assert.AreNotEqual(-1, font!.Descend);
}
[TestMethod]
public void VLineGapIsValid()
{
Assert.AreNotEqual(-1, font!.VerticalLineGap);
}
[TestMethod]
public void BBoxIsValid()
{
Assert.AreNotEqual(default, font!.BoundingBox);
}
[TestMethod]
public void KerningTableIsValid()
{
Assert.IsNotNull(font!.KerningTable);
}
[TestMethod]
public void GetGlyphsForAscii()
{
for (int i = 0; i < 128; i++)
{
int glyph = font!.FindGlyphIndex(i);
Assert.AreNotEqual(-1, glyph);
}
}
}
}

View File

@ -1,45 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
namespace Quik.Stb.Tests
{
[TestClass]
[TestCategory("Load Image")]
public class LoadImage
{
[TestMethod("Set Global Options")]
public void SetGlobals()
{
Quik.Stb.StbImage.FlipVerticallyOnLoad = true;
Quik.Stb.StbImage.UnpremultiplyOnLoad = true;
}
private Stream GetImage(string path)
{
Stream? str = GetType().Assembly.GetManifestResourceStream(path);
Assert.IsNotNull(str, $"Could not find test image resource {path}.");
return str;
}
private unsafe void TestImage(string path, int width, int height)
{
StbImage image = StbImage.Load(GetImage(path));
Assert.IsNotNull(image);
Assert.AreEqual(width, image.Width, "Width does not match.");
Assert.AreEqual(height, image.Height, "Height does not match.");
image.Dispose();
}
const int WIDTH = 768;
const int HEIGHT = 512;
[TestMethod("Load a single frame GIF")]
public unsafe void LoadGif() => TestImage("Quik.Stb.Tests.res.kodim.kodim23.gif", WIDTH, HEIGHT);
[TestMethod("Load a JPEG")]
public unsafe void LoadJpg() => TestImage("Quik.Stb.Tests.res.kodim.kodim23.jpg", WIDTH, HEIGHT);
[TestMethod("Load a PNG")] public unsafe void LoadPng() => TestImage("Quik.Stb.Tests.res.kodim.kodim23.png", WIDTH, HEIGHT);
}
}

View File

@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="res/**"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Quik.StbImage\Quik.StbImage.csproj" />
<ProjectReference Include="..\..\Quik.StbTrueType\Quik.StbTrueType.csproj" />
</ItemGroup>
</Project>

Binary file not shown.

View File

@ -1,12 +0,0 @@
Varicka (Truetype and Opentype with no OT features)
Based on 'Varick', from "Decorative Condensed Alphabets", by Dan Solo, Page 94.
Letter spacing is set to balance the letterforms themselves; the space between most adjacent letters is identical to the horizontal space inside such letters as 'O' and 'H'. Kerning is supplied as needed for certain letter combinations, particularly those that have a letter with a projection on the left, such as A, E, F, H, K, P, and R.
Varicka is superficially similar to Red Rooster's Triple Gothic Condensed, but the Solo book's font has different features and some very different letterforms.
This font is free and available for all use, personal and commercial, with no restrictions.
Character
February 13, 2010

View File

@ -1,3 +0,0 @@
Kodak Image Suite Test Images owned by Kodak. Image 23 was taken by Steve Kelly.
The original image file kodim23.png and its derivatives are only included for
test purposes only and should not be redistributed with the software.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

View File

@ -1,6 +1,9 @@
using Quik;
using Quik.CommandMachine;
using Quik.Controls;
using Quik.OpenTK;
namespace QuikDemo
{
public static class Program
@ -9,7 +12,17 @@ namespace QuikDemo
public static void Main(string[] args)
{
Application.Run(new Quik.Controls.View());
Application.Run(new EmptyView());
}
}
public class EmptyView : View
{
protected override void PaintBegin(CommandQueue cmd)
{
base.PaintBegin(cmd);
cmd.Rectangle(new QRectangle(0, 0, 16, 16));
}
}
}

View File

@ -2,7 +2,7 @@
<ItemGroup>
<ProjectReference Include="..\..\Quik\Quik.csproj" />
<ProjectReference Include="..\..\Quik.Media.Stb\Quik.Media.Stb.csproj" />
<ProjectReference Include="..\..\Quik.Media.Defaults\Quik.Media.Defaults.csproj" />
<ProjectReference Include="..\..\Quik.OpenTK\Quik.OpenTK.csproj" />
</ItemGroup>