diff options
| -rw-r--r-- | build.zig | 64 | ||||
| -rw-r--r-- | include/RFont.h | 3239 | ||||
| -rw-r--r-- | include/RSGL.h | 1926 | ||||
| -rw-r--r-- | include/RSGL_gl.h | 1013 | ||||
| -rw-r--r-- | main.zig | 32 | ||||
| -rw-r--r-- | rgfw.zig | 2305 |
6 files changed, 6254 insertions, 2325 deletions
@@ -1,25 +1,69 @@ const std = @import("std"); -pub fn build(b: *std.Build) void { +pub fn build(b: *std.Build) !void { + const opengl = b.option(bool, "opengl", "Exposes OpenGL helper functions in RGFW.h and links OpenGL. Default: true") orelse true; + const x11 = b.option(bool, "x11", "X11 backend. Default: true") orelse true; + const target = b.standardTargetOptions(.{}); -// const optimize = b.standardOptimizeOption(.{}); + const optimize = b.standardOptimizeOption(.{}); + var macros = std.ArrayList([2][]const u8).empty; + defer macros.deinit(b.allocator); + var syslibs = std.ArrayList(struct {[]const u8, std.Build.Module.LinkSystemLibraryOptions}).empty; + defer syslibs.deinit(b.allocator); + + try macros.append(b.allocator, [2][]const u8{"RSGL_RFONT", ""}); + + if (target.result.os.tag == std.Target.Os.Tag.linux or target.result.os.tag == std.Target.Os.Tag.macos) + try macros.append(b.allocator, [2][]const u8{"RGFW_UNIX", ""}); + + if (x11) { + try macros.append(b.allocator, [2][]const u8{"RGFW_X11", ""}); + try syslibs.append(b.allocator, struct {[]const u8, std.Build.Module.LinkSystemLibraryOptions}{"X11", .{}}); + try syslibs.append(b.allocator, struct {[]const u8, std.Build.Module.LinkSystemLibraryOptions}{"Xrandr", .{}}); + } else { + try macros.append(b.allocator, [2][]const u8{"RGFW_NO_X11", ""}); + } + if (opengl) { + try macros.append(b.allocator, [2][]const u8{"RGFW_OPENGL", ""}); + try syslibs.append(b.allocator, struct {[]const u8, std.Build.Module.LinkSystemLibraryOptions}{"GL", .{}}); + } else { + std.debug.panic("no backend other than OpenGL supported by RSGL.h", .{}); + } + + const rgfw = b.addTranslateC(.{ + .root_source_file = b.path("include/RGFW.h"), + .target = target, + .optimize = optimize, + }); + for (macros.items) |macro| {rgfw.defineCMacro(macro[0], macro[1]);} + const rgfw_mod = rgfw.addModule("rgfw"); + + const rsgl = b.addTranslateC(.{ + .root_source_file = b.path("include/RSGL_gl.h"), + .target = target, + .optimize = optimize, + }); + for (macros.items) |macro| {rsgl.defineCMacro(macro[0], macro[1]);} + const rsgl_mod = rsgl.addModule("rsgl"); const term = b.createModule(.{ .root_source_file = b.path("main.zig"), .target = target, - .link_libc = true, + .optimize = optimize, + .imports = &.{ + .{.name = "rgfw", .module = rgfw_mod}, + .{.name = "rsgl", .module = rsgl_mod}, + }, }); term.addCMacro("RGFW_IMPLEMENTATION", ""); - term.addCMacro("RGFW_OPENGL", ""); + term.addCMacro("RFONT_IMPLEMENTATION", ""); + term.addCMacro("RSGL_IMPLEMENTATION", ""); + for (macros.items) |macro| {term.addCMacro(macro[0], macro[1]);} term.addIncludePath(b.path("include")); - term.addCSourceFile(.{ - .file = b.addWriteFiles().add("rgfw.c", "#include <RGFW.h>"), - }); + term.addCSourceFile(.{.file = b.addWriteFiles().add("rgfw.c", "#include <RSGL_gl.h>\n#include <RGFW.h>"),}); - term.linkSystemLibrary("GL", .{}); - term.linkSystemLibrary("X11", .{}); - term.linkSystemLibrary("Xrandr", .{}); + for (syslibs.items) |lib| {term.linkSystemLibrary(lib[0], lib[1]);} const exe = b.addExecutable(.{ .name = "term", diff --git a/include/RFont.h b/include/RFont.h new file mode 100644 index 0000000..6d4b511 --- /dev/null +++ b/include/RFont.h @@ -0,0 +1,3239 @@ +/* +* Copyright (c) 2021-25 ColleagueRiley ColleagueRiley@gmail.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following r estrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +* +* +*/ + +/* +preprocessor args + +make sure + +** #define RFONT_IMPLEMENTATION ** - include function defines + +is in exactly one of your files or arguments + +#define RFONT_INT_DEFINED - int types are already defined +#define RFONT_C89 - uses cints instead of stdint.h and __inline instead of inline +#define RFONT_INLINE x - set your own inline + +#define RFONT_NO_STDIO - do not include stdio.h +#define RFONT_EXTERNAL_STB - load stb_truetype from stb_truetype.h instead of using the internal version +#define RFONT_EXTERNAL_STB_IMPLEMENTATION - the same as RFONT_EXTERNAL_STB but doesn't define STB_TRUETYPE_IMPLEMENTATION +-- NOTE: By default, opengl 3.3 vbos are used for rendering -- +*/ + +/* +credits : + +stb_truetype.h - a dependency for RFont, most of (a slightly motified version of) stb_truetype.h is included directly into RFont.h +http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - UTF-8 decoding function +fontstash - fontstash was used as a refference for some parts +*/ + +/* + +... = [add code here] + +BASIC TEMPLATE : +#define RFONT_IMPLEMENTATION +#include "RFont.h" + +... + +int main () { + ... + + RFont_renderer renderer = ...; + RFont_renderer_init(&renderer); + RFont_font* font = RFont_font_init(&renderer, "font.ttf", 20, 500, 500); + + i32 w = ...; + i32 h = ...; + + while (1) { + ... + RFont_renderer_set_framebuffer(&renderer, (u32)w, (u32)h); + RFont_renderer_set_color(&renderer, 0.0f, 1.0f, 0, 1.0f); + RFont_draw_text(&renderer, font, "text", 100, 100, 20); + ... + } + + RFont_font_free(&renderer, font); + RFont_renderer_free(&renderer); + ... +} +*/ + +#ifndef RFONT_INLINE + #ifdef RFONT_C89 + #define RFONT_INLINE + #else + #define RFONT_INLINE inline + #endif +#endif + +#ifndef RFONT_API + #ifdef RFONT_STATIC + #define RFONT_API static + #else + #define RFONT_API extern RFONT_INLINE + #endif +#endif + + +#ifndef RFONT_NO_STDIO +#include <stdio.h> +#endif + +#ifndef RFONT_MALLOC +#include <stdlib.h> +#define RFONT_MALLOC malloc +#define RFONT_FREE free +#endif + +#if !defined(RFONT_MEMCPY) || !defined(RFONT_MEMSET) + #include <string.h> +#endif + +#ifndef RFONT_MEMSET + #define RFONT_MEMSET(ptr, value, num) memset(ptr, value, num) +#endif + +#ifndef RFONT_MEMCPY + #define RFONT_MEMCPY(dist, src, len) memcpy(dist, src, len) +#endif + +#ifndef RFONT_ASSERT + #include <assert.h> + #define RFONT_ASSERT(x) assert(x) +#endif + +#if !defined(RFONT_FLOOR) || !defined(RFONT_CEIL) || !defined(RFONT_FABS) || !defined(RFONT_SQRT) + #include <math.h> +#endif + +#ifndef RFONT_FLOOR + #define RFONT_FLOOR(x) floor(x) +#endif + +#ifndef RFONT_CEIL + #define RFONT_CEIL(x) ceil(x) +#endif + +#ifndef RFONT_FABS + #define RFONT_FABS(x) fabs(x) +#endif + +#ifndef RFONT_SQRT + #define RFONT_SQRT(x) sqrt(x) +#endif + +#if defined(__STDC__) && !defined(__STDC_VERSION__) + #define RFONT_C89 +#endif + +#if !defined(RFONT_INT_DEFINED) + #define RFONT_INT_DEFINED + #if defined(_MSC_VER) || defined(__SYMBIAN32__) || defined(RFONT_C89) + typedef unsigned char u8; + typedef signed char i8; + typedef unsigned short u16; + typedef signed short i16; + typedef unsigned int u32; + typedef signed int i32; + typedef unsigned long u64; + typedef signed long i64; + #else + #include <stdint.h> + + typedef uint8_t u8; + typedef int8_t i8; + typedef uint16_t u16; + typedef int16_t i16; + typedef uint32_t u32; + typedef int32_t i32; + typedef uint64_t u64; + typedef int64_t i64; + #endif +#endif + +#if !defined(b8) + typedef u8 b8; +#endif + +/* +You can define these yourself if +you want to change anything +*/ + +#ifndef RFont_texture +typedef size_t RFont_texture; +#endif + +#ifndef RFont_surface +typedef void* RFont_surface; +#endif + +#ifndef RFONT_MAX_GLYPHS +#define RFONT_MAX_GLYPHS 256 +#endif + +#ifndef RFONT_INIT_VERTS +#define RFONT_INIT_VERTS 20 * RFONT_MAX_GLYPHS +#endif + +#ifndef RFONT_UNUSED +#define RFONT_UNUSED(x) (void) (x); +#endif + +#ifndef RFONT_RENDERER_H +#define RFONT_RENDERER_H + +typedef struct RFont_render_data { + float* verts; + float* tcoords; + u16* elements; + + RFont_texture atlas; + size_t nverts; + size_t nelements; +} RFont_render_data; + +typedef struct RFont_renderer_proc { + size_t (*size)(void); /*!< get the size of the renderer context */ + void (*initPtr)(void* ctx); /* any initalizations the renderer needs to do */ + RFont_texture (*create_atlas)(void* ctx, u32 atlasWidth, u32 atlasHeight); /* create a bitmap texture based on the given size */ + void (*free_atlas)(void* ctx, RFont_texture atlas); + void (*bitmap_to_atlas)(void* ctx, RFont_texture atlas, u32 atlasWidth, u32 atlasHeight, u32 maxHeight, u8* bitmap, float w, float h, float* x, float* y); /* add the given bitmap to the texture based on the given coords and size data */ + void (*render)(void* ctx, const RFont_render_data* data); /* render the text, using the vertices, atlas texture, and texture coords given. */ + void (*set_framebuffer)(void* ctx, u32 weight, u32 height); /*!< set the frame buffer size (for ortho, for example) */ + void (*set_color)(void* ctx, float r, float g, float b, float a); /*!< set the current rendering color */ + void (*set_surface)(void* ctx, RFont_surface surface); + void (*freePtr)(void* ctx); /* free any memory the renderer might need to free */ +} RFont_renderer_proc; + +typedef struct RFont_renderer { + void* ctx; /*!< source renderer data */ + RFont_renderer_proc proc; +} RFont_renderer; + +typedef struct RFont_font RFont_font; + +#endif /* RFONT_RENDERER_H */ + +#ifndef RFONT_H +#define RFONT_H + +RFONT_API size_t RFont_renderer_size(RFont_renderer* renderer); + +RFONT_API RFont_renderer* RFont_renderer_init(RFont_renderer_proc proc); +RFONT_API void RFont_renderer_initPtr(RFont_renderer_proc proc, void* ptr, RFont_renderer* renderer); + +RFONT_API void RFont_renderer_set_framebuffer(RFont_renderer* renderer, u32 w, u32 h); +RFONT_API void RFont_renderer_set_surface(RFont_renderer* renderer, RFont_surface surface); +RFONT_API void RFont_renderer_set_color(RFont_renderer* renderer, float r, float g, float b, float a); + +RFONT_API void RFont_renderer_free(RFont_renderer* renderer); +RFONT_API void RFont_renderer_freePtr(RFont_renderer* renderer); + +#define RFONT_GET_FONT_WIDTH(fontHeight) RFONT_MAX_GLYPHS * fontHeight + +typedef struct { + u32 codepoint; /* the character (for checking) */ + size_t size; /* the size of the glyph */ + i32 x, x2, y, y2; /* coords of the character on the texture */ + RFont_font* font; /* the font that the glyph belongs to */ + + /* source glyph data */ + i32 src; + float w, h, x1, y1, advance; +} RFont_glyph; + +typedef struct RFont_src RFont_src; + +struct RFont_font { + RFont_src* src; /* source stb font info */ + float fheight; /* source font height */ + float descent; /* font descent */ + float numOfLongHorMetrics; + float space_adv; + u32 maxHeight; + + RFont_glyph glyphs[RFONT_MAX_GLYPHS]; /* glyphs */ + size_t glyph_len; + + RFont_texture atlas; /* atlas texture */ + size_t atlasWidth, atlasHeight; + float atlasX, atlasY; /* the current position inside the atlas */ + + float verts[RFONT_INIT_VERTS * 3]; + float tcoords[RFONT_INIT_VERTS * 2]; + u16 elements[RFONT_INIT_VERTS * 6]; +}; + + +/** + * @brief Converts a codepoint to a utf8 string. + * @param codepoint The codepoint to convert to utf8. + * @return The utf8 string. +*/ +RFONT_API char* RFont_codepoint_to_utf8(u32 codepoint); + +#ifndef RFONT_NO_STDIO +/** + * @brief Init font stucture with a TTF file path. + * @param font_name The TTF file path. + * @param atlasWidth The width of the atlas texture. + * @param atlasHeight The height of the atlas texture. (This should == the max text size) + * @return The `RFont_font` created using the TTF file data. +*/ +RFONT_API RFont_font* RFont_font_init(RFont_renderer* renderer, const char* font_name, u32 maxHeight, size_t atlasWidth, size_t atlasHeight); +/** + * @brief Init a given font stucture with a TTF file path. + * @param font_name The TTF file path. + * @param atlasWidth The width of the atlas texture. + * @param atlasHeight The height of the atlas texture. (This should == the max text size) + * @pram ptr Pointer to the given font structure + * @return returns the same pointer or NULL if the font failed to load +*/ +RFONT_API RFont_font* RFont_font_init_ptr(RFont_renderer* renderer, const char* font_name, u32 maxHeight, size_t atlasWidth, size_t atlasHeight, RFont_font* font); + +#endif + +/** + * @brief Init font stucture with raw TTF data. + * @param font_data The raw TTF data. + * @param atlasWidth The width of the atlas texture. + * @param atlasHeight The height of the atlas texture. (This should == the max text size) + * @return The `RFont_font` created from the data. +*/ +RFONT_API RFont_font* RFont_font_init_data(RFont_renderer* renderer, u8* font_data, u32 maxHeight, size_t atlasWidth, size_t atlasHeight); + +/** + * @brief Init a given font stucture with raw TTF data. + * @param font_data The raw TTF data. + * @param atlasWidth The width of the atlas texture. + * @param atlasHeight The height of the atlas texture. (This should == the max text size) + * @return The `RFont_font` created from the data. + * @return returns the same pointer or NULL if the font failed to load +*/ +RFONT_API RFont_font* RFont_font_init_data_ptr(RFont_renderer* renderer, u8* font_data, u32 maxHeight, size_t atlasWidth, size_t atlasHeight, RFont_font* ptr); + +/** + * @brief Free data from the font stucture, including the stucture itself + * @param font The font stucture to free +*/ +RFONT_API void RFont_font_free(RFont_renderer* renderer, RFont_font* font); + +/** + * @brief Free data from the font stucture only (not including the stucture) + * @param font The strucutre with the font data to free +*/ +RFONT_API void RFont_font_free_ptr(RFont_renderer* renderer, RFont_font* font); + +typedef RFont_glyph (*RFont_glyph_fallback_callback)(RFont_renderer* renderer, RFont_font* font, u32 codepoint, size_t size); +RFont_glyph_fallback_callback RFont_set_glyph_fallback_callback(RFont_glyph_fallback_callback callback); + +/** + * @brief Add a character to the font's atlas. + * @param font The font to use. + * @param ch The character to add to the atlas. + * @param size The size of the character. + * @return The `RFont_glyph` created from the data and added to the atlas. +*/ +RFONT_API RFont_glyph RFont_font_add_char(RFont_renderer* renderer,RFont_font* font, char ch, size_t size); + +/** + * @brief Add a codepoint to the font's atlas. + * @param font The font to use. + * @param codepoint The codepoint to add to the atlas. + * @param size The size of the character. + * @return The `RFont_glyph` created from the data and added to the atlas. +*/ +RFONT_API RFont_glyph RFont_font_add_codepoint(RFont_renderer* renderer, RFont_font* font, u32 codepoint, size_t size); + +/** + * @brief Add a codepoint to the font's atlas. + * @param font The font to use. + * @param codepoint The codepoint to add to the atlas. + * @param size The size of the character. + * @param fallback If the fallback function should not be called. + * @return The `RFont_glyph` created from the data and added to the atlas. +*/ +RFONT_API RFont_glyph RFont_font_add_codepoint_ex(RFont_renderer* renderer, RFont_font* font, u32 codepoint, size_t size, b8 fallback); + +/** + * @brief Add a string to the font's atlas. + * @param font The font to use. + * @param ch The character to add to the atlas. + * @param sizes The supported sizes of the character. + * @param sizeLen length of the size array +*/ +RFONT_API void RFont_font_add_string(RFont_renderer* renderer, RFont_font* font, const char* string, size_t* sizes, size_t sizeLen); + +/** + * @brief Add a string to the font's atlas based on a given string length. + * @param font The font to use. + * @param ch The character to add to the atlas. + * @param strLen length of the string + * @param sizes The supported sizes of the character. + * @param sizeLen length of the size array +*/ +RFONT_API void RFont_font_add_string_len(RFont_renderer* renderer, RFont_font* font, const char* string, size_t strLen, size_t* sizes, size_t sizeLen); + +/** + * @brief Get the area of the text based on the size using the font. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param size The size of the text + * @param [OUTPUT] the output width + * @param [OUTPUT] the output height +*/ +RFONT_API void RFont_text_area(RFont_renderer* renderer, RFont_font* font, const char* text, u32 size, u32* w, u32* h); + +/** + * @brief Get the area of the text based on the size using the font, using a given length. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param size The size of the text + * @param spacing The spacing of the text + * @param [OUTPUT] the output width + * @param [OUTPUT] the output height +*/ +RFONT_API void RFont_text_area_spacing(RFont_renderer* renderer, RFont_font* font, const char* text, float spacing, u32 size, u32* w, u32* h); + +/** + * @brief Get the area of the text based on the size using the font, using a given length. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param len The length of the string + * @param size The size of the text + * @param stopNL the number of \n s until it stops (0 = don't stop until the end) + * @param spacing The spacing of the text + * @param [OUTPUT] the output width + * @param [OUTPUT] the output height +*/ +RFONT_API void RFont_text_area_len(RFont_renderer* renderer, RFont_font* font, const char* text, size_t len, u32 size, size_t stopNL, float spacing, u32* w, u32* h); + +/** + * @brief Draw a text string using the font. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param x The x position of the text + * @param y The y position of the text + * @param size The size of the text + * @return the number of verts rendered +*/ +RFONT_API size_t RFont_draw_text(RFont_renderer* renderer, RFont_font* font, const char* text, float x, float y, u32 size); + +/** + * @brief Draw a text string using the font and a given spacing. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param x The x position of the text + * @param y The y position of the text + * @param size The size of the text + * @param spacing The spacing of the text + * @return the number of verts rendered +*/ +RFONT_API size_t RFont_draw_text_spacing(RFont_renderer* renderer, RFont_font* font, const char* text, float x, float y, u32 size, float spacing); + +/** + * @brief Draw a text string using the font using a given length and a given spacing. + * @param font The font stucture to use for drawing + * @param text The string to draw + * @param len The length of the string + * @param x The x position of the text + * @param y The y position of the text + * @param size The size of the text + * @param spacing The spacing of the text + * @return the number of verts rendered +*/ +RFONT_API size_t RFont_draw_text_len(RFont_renderer* renderer, RFont_font* font, const char* text, size_t len, float x, float y, u32 size, float spacing); +#endif /* RFONT_H */ + +#ifdef RFONT_IMPLEMENTATION + +#ifndef RFONT_GET_TEXPOSX +#define RFONT_GET_TEXPOSX(x, w) (float)((float)(x) / (float)(w)) +#define RFONT_GET_TEXPOSY(y, h) (float)((float)(y) / (float)(h)) +#endif + +size_t RFont_renderer_size(RFont_renderer* renderer) { + size_t size = 0; + if (renderer->proc.size) + size = renderer->proc.size(); + return size; +} + +RFont_renderer* RFont_renderer_init(RFont_renderer_proc proc) { + void* ptr = NULL; + size_t size; + + RFont_renderer* renderer = (RFont_renderer*)RFONT_MALLOC(sizeof(RFont_renderer)); + renderer->proc = proc; + + size = RFont_renderer_size(renderer); + if (size) ptr = RFONT_MALLOC(size); + RFont_renderer_initPtr(proc, ptr, renderer); + return renderer; +} + +void RFont_renderer_initPtr(RFont_renderer_proc proc, void* ptr, RFont_renderer* renderer) { + renderer->ctx = ptr; + renderer->proc = proc; + if (renderer->proc.initPtr) + renderer->proc.initPtr(renderer->ctx); +} + +void RFont_renderer_set_framebuffer(RFont_renderer* renderer, u32 w, u32 h) { + if (renderer->proc.set_framebuffer) + renderer->proc.set_framebuffer(renderer->ctx, w, h); +} + +void RFont_renderer_set_surface(RFont_renderer* renderer, RFont_surface surface) { + if (renderer->proc.set_surface) + renderer->proc.set_surface(renderer, surface); +} + +void RFont_renderer_set_color(RFont_renderer* renderer, float r, float g, float b, float a) { + if (renderer->proc.set_color) + renderer->proc.set_color(renderer->ctx, r, g, b, a); +} + +void RFont_renderer_free(RFont_renderer* renderer) { + RFont_renderer_freePtr(renderer); + if (renderer->ctx) RFONT_FREE(renderer->ctx); + RFONT_FREE(renderer); +} + +void RFont_renderer_freePtr(RFont_renderer* renderer) { + if (renderer->proc.freePtr) + renderer->proc.freePtr(renderer->ctx); +} + +#define RFONT_CHAR(p, index) (((char*)p)[index]) +#define RFONT_BYTE(p, index) (((u8*)p)[index]) +#define RFONT_SHORT(arr, index) (i16)((i16)((u8*)arr)[(size_t)(index)]*256 + (i16)(((u8*)arr)[(size_t)(index) + 1])) +#define RFONT_USHORT(arr, index) (u16)((u16)((u8*)arr)[(size_t)(index)]*256 + (u16)(((u8*)arr)[(size_t)(index) + 1])) +#define RFONT_ULONG(arr, index) (u32)((u32)(((u8*)arr)[(size_t)(index)]<<24) + (u32)(((u8*)arr)[(size_t)(index) + 1]<<16) + (u32)(((u8*)arr)[(size_t)(index) + 2]<<8) + (u32)(((u8*)arr))[(size_t)(index) + 3]) + +/* +stb defines required by RFont + +you probably don't care about this part if you're reading just the RFont code +*/ + +#ifndef RFONT_EXTERNAL_STB +typedef struct { + unsigned char *data; + int cursor; + int size; +} rstbtt__buf; + +typedef struct rstbtt_fontinfo rstbtt_fontinfo; + +struct rstbtt_fontinfo { + unsigned char * data; /* pointer to .ttf file */ + int fontstart; /* offset of start of font */ + + int numGlyphs; /* number of glyphs, needed for range checking */ + + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; /* table locations as offset from start of .ttf */ + int index_map; /* a cmap mapping for our chosen character encoding */ + int indexToLocFormat; /* format needed to map from glyph index to glyph */ + + rstbtt__buf cff; /* cff font data */ + rstbtt__buf charstrings; /* the charstring index */ + rstbtt__buf gsubrs; /* global charstring subroutines index */ + rstbtt__buf subrs; /* private charstring subroutines index */ + rstbtt__buf fontdicts; /* array of font dicts */ + rstbtt__buf fdselect; /* map from glyph to fontdict */ +}; + +RFONT_API int rstbtt_InitFont(rstbtt_fontinfo *info, const unsigned char *data, int offset); + +RFONT_API unsigned char* rstbtt_GetGlyphBitmapSubpixel(const rstbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); + +RFONT_API int rstbtt_FindGlyphIndex(const rstbtt_fontinfo *info, int unicode_codepoint); + +RFONT_API int rstbtt_GetGlyphKernAdvance(const rstbtt_fontinfo *info, int glyph1, int glyph2); +RFONT_API int rstbtt_GetGlyphBox(const rstbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +#else +#ifdef RFONT_EXTERNAL_STB_IMPLEMENTATION + #define RFONT_EXTERNAL_STB +#endif + +#ifndef RFONT_EXTERNAL_STB_IMPLEMENTATION +#define STB_TRUETYPE_IMPLEMENTATION +#endif +#include "stb_truetype.h" + +typedef struct stbtt_fontinfo rstbtt_fontinfo; + +#define rstbtt_InitFont stbtt_InitFont +#define rstbtt_GetGlyphBitmapSubpixel stbtt_GetGlyphBitmapSubpixel +#define rstbtt_FindGlyphIndex stbtt_FindGlyphIndex +#define rstbtt_GetGlyphKernAdvance stbtt_GetGlyphKernAdvance +#define rstbtt_GetGlyphBox stbtt_GetGlyphBox +#endif /* RFONT_EXTERNAL_STB */ + +struct RFont_src { + rstbtt_fontinfo info; +}; + +/* +END of stb defines required by RFont + +you probably care about this part +*/ + +#ifndef RFONT_NO_STDIO +char* RFont_read_file(const char* font_name) { + size_t size, out; + char* ttf_buffer; + FILE* ttf_file = fopen(font_name, "rb"); + + if (ttf_file == NULL) return NULL; + + fseek(ttf_file, 0U, SEEK_END); + size = (size_t)ftell(ttf_file); + if (size <= 0) return NULL; + + ttf_buffer = (char*)RFONT_MALLOC(sizeof(char) * (size_t)size); + fseek(ttf_file, 0U, SEEK_SET); + + out = fread(ttf_buffer, 1, (size_t)size, ttf_file); + RFONT_UNUSED(out); + + return ttf_buffer; +} + +RFont_font* RFont_font_init(RFont_renderer* renderer, const char* font_name, u32 maxHeight, size_t atlasWidth, size_t atlasHeight) { + char* ttf_buffer = RFont_read_file(font_name); + RFont_font* font = RFont_font_init_data(renderer, (u8*)ttf_buffer, maxHeight, atlasWidth, atlasHeight); + return font; +} + +RFont_font* RFont_font_init_ptr(RFont_renderer* renderer, const char* font_name, u32 maxHeight, size_t atlasWidth, size_t atlasHeight, RFont_font* ptr) { + char* ttf_buffer = RFont_read_file(font_name); + RFont_font* font = RFont_font_init_data_ptr(renderer, (u8*)ttf_buffer, maxHeight, atlasWidth, atlasHeight, ptr); + return font; +} +#endif + +RFont_font* RFont_font_init_data(RFont_renderer* renderer, u8* font_data, u32 maxHeight, size_t atlasWidth, size_t atlasHeight) { + RFont_font* font = (RFont_font*)RFONT_MALLOC(sizeof(RFont_font)); + return RFont_font_init_data_ptr(renderer, font_data, maxHeight, atlasWidth, atlasHeight, font); +} + +RFont_font* RFont_font_init_data_ptr(RFont_renderer* renderer, u8* font_data, u32 maxHeight, size_t atlasWidth, size_t atlasHeight, RFont_font* font) { + u16 index = 0; + u16 vert_index = 0; + + i32 space_codepoint = 0; + font->src = (RFont_src*)RFONT_MALLOC(sizeof(RFont_src)); + font->atlasWidth = atlasWidth; + font->atlasHeight = atlasHeight; + font->maxHeight = maxHeight; + + rstbtt_InitFont(&font->src->info, font_data, 0); + + font->fheight = RFONT_SHORT(font->src->info.data, font->src->info.hhea + 4) - RFONT_SHORT(font->src->info.data, font->src->info.hhea + 6); + font->descent = RFONT_SHORT(font->src->info.data, font->src->info.hhea + 6); + + font->numOfLongHorMetrics = RFONT_USHORT(font->src->info.data, font->src->info.hhea + 34); + + + space_codepoint = rstbtt_FindGlyphIndex(&font->src->info, (int)' '); + if (' ' < font->numOfLongHorMetrics) + font->space_adv = RFONT_SHORT(font->src->info.data, font->src->info.hmtx + 4 * space_codepoint); + else + font->space_adv = RFONT_SHORT(font->src->info.data, font->src->info.hmtx + 4 * (i32)(font->numOfLongHorMetrics - 1)); + + if (renderer->proc.create_atlas) + font->atlas = renderer->proc.create_atlas(renderer->ctx, (u32)atlasWidth, (u32)atlasHeight); + + font->atlasX = 0; + font->atlasY = 0; + font->glyph_len = 0; + + for (index = 0; index < RFONT_INIT_VERTS; index += 6) { + font->elements[index + 0] = vert_index + 0; + font->elements[index + 1] = vert_index + 1; + font->elements[index + 2] = vert_index + 2; + font->elements[index + 3] = vert_index + 3; + font->elements[index + 4] = vert_index + 0; + font->elements[index + 5] = vert_index + 2; + vert_index += 4; + } + + return font; +} + +void RFont_font_free_ptr(RFont_renderer* renderer, RFont_font* font) { + if (renderer->proc.free_atlas) + renderer->proc.free_atlas(renderer->ctx, font->atlas); + RFONT_FREE(font->src); +} + +void RFont_font_free(RFont_renderer* renderer, RFont_font* font) { + RFONT_FREE(font->src->info.data); + RFont_font_free_ptr(renderer, font); + RFONT_FREE(font); +} + +/* +decode utf8 character to codepoint +*/ + +/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de> + See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. +*/ + +#define RFONT_UTF8_ACCEPT 0 +#define RFont_UTF8_REJECT 12 + +RFONT_API u32 RFont_decode_utf8(u32* state, u32* codep, u32 byte); + +u32 RFont_decode_utf8(u32* state, u32* codep, u32 byte) { + static const u8 utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00..1f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20..3f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40..5f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60..7f */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, /* 80..9f */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* a0..bf */ + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* c0..df */ + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, /* e0..ef */ + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, /* f0..ff */ + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, /* s0..s0 */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, /* s1..s2 */ + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, /* s3..s4 */ + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, /* s5..s6 */ + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* s7..s8 */ + }; + + u32 type = utf8d[byte]; + + *codep = (*state != RFONT_UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state * 16 + type]; + return *state; +} + +void RFont_font_add_string(RFont_renderer* renderer, RFont_font* font, const char* string, size_t* sizes, size_t sizeLen) { + RFont_font_add_string_len(renderer, font, string, 0, sizes, sizeLen); +} + +void RFont_font_add_string_len(RFont_renderer* renderer, RFont_font* font, const char* string, size_t strLen, size_t* sizes, size_t sizeLen) { + u32 i; + char* str; + for (str = (char*)string; (!strLen || (size_t)(str - string) < strLen) && *str; str++) + for (i = 0; i < sizeLen; i++) + RFont_font_add_char(renderer, font, *str, sizes[i]); +} + +RFont_glyph_fallback_callback RFont_glyph_fallback = NULL; +RFont_glyph_fallback_callback RFont_set_glyph_fallback_callback(RFont_glyph_fallback_callback callback) { + RFont_glyph_fallback_callback old = RFont_glyph_fallback; + RFont_glyph_fallback = callback; + return old; +} + +RFont_glyph RFont_font_add_char(RFont_renderer* renderer, RFont_font* font, char ch, size_t size) { + static u32 utf8state = 0, codepoint = 0; + + if (RFont_decode_utf8(&utf8state, &codepoint, (u8)ch) != RFONT_UTF8_ACCEPT) { + RFont_glyph g; + RFONT_MEMSET(&g, 0, sizeof(RFont_glyph)); + return g; + } + + return RFont_font_add_codepoint(renderer, font, codepoint, size); +} + +RFont_glyph RFont_font_add_codepoint(RFont_renderer* renderer, RFont_font* font, u32 codepoint, size_t size) { + return RFont_font_add_codepoint_ex(renderer, font, codepoint, size, 1); +} + +RFont_glyph RFont_font_add_codepoint_ex(RFont_renderer* renderer, RFont_font* font, u32 codepoint, size_t size, b8 fallback) { + RFont_glyph* glyph; + RFont_glyph glyphNull; + + u8* bitmap; + float scale; + + i32 x0, y0, x1, y1, w = 0, h = 0, advanceX = 0; + u32 i; + for (i = 0; i < font->glyph_len; i++) + if (font->glyphs[i].codepoint == codepoint && font->glyphs[i].size == size) + return font->glyphs[i]; + + RFONT_MEMSET(&glyphNull, 0, sizeof(glyphNull)); + if (i < sizeof(font->glyphs)) { + glyph = &font->glyphs[i]; + } else { + return glyphNull; + } + + glyph->src = rstbtt_FindGlyphIndex(&font->src->info, (int)codepoint); + + if ((glyph->src == 0 && codepoint) && fallback && RFont_glyph_fallback) { + RFont_glyph fallbackGlyph = RFont_glyph_fallback(renderer, font, codepoint, size); + if (fallbackGlyph.codepoint != 0 && fallbackGlyph.size != 0) { + return fallbackGlyph; + } + } + + if (glyph->src == 0 && codepoint) return RFont_font_add_codepoint_ex(renderer, font, 0, size, fallback); + font->glyph_len++; + + if (codepoint && rstbtt_GetGlyphBox(&font->src->info, glyph->src, &x0, &y0, &x1, &y1) == 0) { + return glyphNull; + } + + scale = ((float)size) / font->fheight; + bitmap = rstbtt_GetGlyphBitmapSubpixel(&font->src->info, 0, scale, 0.0f, 0.0f, glyph->src, &w, &h, 0, 0); + glyph->w = (float)w; + glyph->h = (float)h; + + if (codepoint) { + glyph->x1 = (float)floor((float)x0 * scale); + glyph->y1 = (float)floor((float)-y1 * scale); + } else glyph->y1 = (float)-((float)h * 0.75f); + + glyph->codepoint = codepoint; + glyph->size = size; + glyph->font = font; + + if (renderer->proc.bitmap_to_atlas) + renderer->proc.bitmap_to_atlas(renderer->ctx, font->atlas, (u32)font->atlasWidth, (u32)font->atlasHeight, font->maxHeight, bitmap, glyph->w, glyph->h, &font->atlasX, &font->atlasY); + + RFONT_FREE(bitmap); + glyph->x = (i32)(font->atlasX - glyph->w); + glyph->x2 = (i32)(font->atlasX); + + glyph->y = (i32)(font->atlasY); + glyph->y2 = (i32)((font->atlasY) + glyph->h); + + if (glyph->src < font->numOfLongHorMetrics) + advanceX = RFONT_SHORT(font->src->info.data, font->src->info.hmtx + 4 * glyph->src); + else + advanceX = RFONT_SHORT(font->src->info.data, font->src->info.hmtx + 4 * (i32)(font->numOfLongHorMetrics - 1)); + + glyph->advance = (u32)((float)advanceX * scale); + + return *glyph; +} + +void RFont_text_area(RFont_renderer* renderer, RFont_font* font, const char* text, u32 size, u32* w, u32* h) { + RFont_text_area_len(renderer, font, text, 0, size, 0, 0.0f, w, h); +} + +void RFont_text_area_spacing(RFont_renderer* renderer, RFont_font* font, const char* text, float spacing, u32 size, u32* w, u32* h) { + RFont_text_area_len(renderer, font, text, 0, size, 0, spacing, w, h); +} + +void RFont_text_area_len(RFont_renderer* renderer, RFont_font* font, const char* text, size_t len, u32 size, size_t stopNL, float spacing, u32* w, u32* h) { + float x = 0; + size_t y = 1; + + char* str; + + float scale = (((float)size) / font->fheight); + float space_adv = (scale * font->space_adv); + RFont_glyph glyph; + + for (str = (char*)text; (len == 0 || (size_t)(str - text) < len) && *str; str++) { + if (*str == '\n') { + if (y == stopNL) { + if (w) *w = (u32)x; + if (h) *h = (u32)y * size; + return; + } + + y++; + x = 0; + continue; + } + + if (*str == ' ' || *str == '\t') { + x += space_adv + spacing; + continue; + } + + glyph = RFont_font_add_char(renderer, font, *str, size); + + if (glyph.codepoint == 0 && glyph.size == 0) + continue; + + x += (float)glyph.advance + spacing; + } + + if (w) *w = (u32)x; + if(h) *h = (u32)(y * size); +} + +size_t RFont_draw_text(RFont_renderer* renderer, RFont_font* font, const char* text, float x, float y, u32 size) { + return RFont_draw_text_len(renderer, font, text, 0, x, y, size, 0.0f); +} + +size_t RFont_draw_text_spacing(RFont_renderer* renderer, RFont_font* font, const char* text, float x, float y, u32 size, float spacing) { + return RFont_draw_text_len(renderer, font, text, 0, x, y, size, spacing); +} + +char* RFont_codepoint_to_utf8(u32 codepoint) { + static char utf8[5]; + if (codepoint <= 0x7F) { + utf8[0] = (char)codepoint; + utf8[1] = 0; + } else if (codepoint <= 0x7FF) { + utf8[0] = (char)(0xC0 | (codepoint >> 6)); + utf8[1] = (char)(0x80 | (codepoint & 0x3F)); + utf8[2] = 0; + } else if (codepoint <= 0xFFFF) { + utf8[0] = (char)(0xE0 | (codepoint >> 12)); + utf8[1] = (char)(0x80 | ((codepoint >> 6) & 0x3F)); + utf8[2] = (char)(0x80 | (codepoint & 0x3F)); + utf8[3] = 0; + } else if (codepoint <= 0x10FFFF) { + utf8[0] = (char)(0xF0 | (codepoint >> 18)); + utf8[1] = (char)(0x80 | ((codepoint >> 12) & 0x3F)); + utf8[2] = (char)(0x80 | ((codepoint >> 6) & 0x3F)); + utf8[3] = (char)(0x80 | (codepoint & 0x3F)); + utf8[4] = 0; + } else { + utf8[0] = 0; + } + + return utf8; +} + +size_t RFont_draw_text_len(RFont_renderer* renderer, RFont_font* font, const char* text, size_t len, float x, float y, u32 size, float spacing) { + RFont_render_data data; + float startX = x; + float startY = y; + + size_t i = 0; + size_t tIndex = 0; + + char* str; + RFont_glyph glyph; + float realX, realY; + + float scale = (((float)size) / font->fheight); + float space_adv = (scale * font->space_adv); + + float descent_offset = (-font->descent * scale); + + data.verts = font->verts; + data.tcoords = font->tcoords; + data.elements = font->elements; + data.atlas = font->atlas; + data.nverts = 0; + data.nelements = 0; + + RFONT_UNUSED(startY); + + y = (y + (float)size - descent_offset); + + for (str = (char*)text; (len == 0 || (size_t)(str - text) < len) && *str; str++) { + if (*str == '\n') { + x = startX; + y += (float)size; + continue; + } + + if (*str == ' ' || *str == '\t') { + x += space_adv + spacing; + continue; + } + + glyph = RFont_font_add_char(renderer, font, *str, size); + + if (glyph.codepoint == 0 && glyph.size == 0) + continue; + + if (glyph.font != font) { + RFont_draw_text_len(renderer, glyph.font, RFont_codepoint_to_utf8(glyph.codepoint), 4, x, y - (float)size + descent_offset, size, spacing); + x += glyph.advance + spacing; + continue; + } + + realX = x + glyph.x1; + realY = y + glyph.y1; + + i = data.nverts * 3; + tIndex = data.nverts * 2; + + data.verts[i] = (i32)realX; + data.verts[i + 1] = realY; + data.verts[i + 2] = 0; + /* */ + data.verts[i + 3] = (i32)realX; + data.verts[i + 4] = realY + glyph.h; + data.verts[i + 5] = 0; + /* */ + data.verts[i + 6] = (i32)(realX + glyph.w); + data.verts[i + 7] = realY + glyph.h; + data.verts[i + 8] = 0; + /* */ + /* */ + data.verts[i + 9] = (i32)(realX + glyph.w); + data.verts[i + 10] = realY; + data.verts[i + 11] = 0; + + /* texture coords */ + data.tcoords[tIndex] = RFONT_GET_TEXPOSX(glyph.x, font->atlasWidth); + data.tcoords[tIndex + 1] = RFONT_GET_TEXPOSY(glyph.y, font->atlasWidth); + + /* */ + data.tcoords[tIndex + 2] = RFONT_GET_TEXPOSX(glyph.x, font->atlasWidth); + data.tcoords[tIndex + 3] = RFONT_GET_TEXPOSY(glyph.y2, font->atlasHeight); + /* */ + data.tcoords[tIndex + 4] = RFONT_GET_TEXPOSX(glyph.x2, font->atlasWidth); + data.tcoords[tIndex + 5] = RFONT_GET_TEXPOSY(glyph.y2, font->atlasHeight); + /* */ + /* */ + data.tcoords[tIndex + 6] = RFONT_GET_TEXPOSX(glyph.x2, font->atlasWidth); + data.tcoords[tIndex + 7] = RFONT_GET_TEXPOSY(glyph.y, font->atlasWidth); + + x += glyph.advance + spacing; + + data.nverts += 4; + data.nelements += 6; + } + + if (i && renderer->proc.render) + renderer->proc.render(renderer->ctx, &data); + + return data.nelements; +} + +/* +stb_truetype defines and source code required by RFont + +you probably don't care about this part if you're reading just the RFont code +*/ + +#ifndef RFONT_EXTERNAL_STB + typedef char rstbtt__check_size32[sizeof(i32)==4 ? 1 : -1]; + typedef char rstbtt__check_size16[sizeof(i16)==2 ? 1 : -1]; +#ifdef __cplusplus +extern "C" { +#endif + +enum { + rstbtt_vmove=1, + rstbtt_vline, + rstbtt_vcurve, + rstbtt_vcubic +}; + +typedef struct rstbtt_vertex { + float x,y,cx,cy,cx1,cy1; + unsigned char type,padding; +} rstbtt_vertex; + +RFONT_API int rstbtt_GetGlyphShape(const rstbtt_fontinfo *info, int glyph_index, rstbtt_vertex **vertices); + +/* @TODO: don't expose this structure */ +typedef struct +{ + int w,h,stride; + unsigned char *pixels; +} rstbtt__bitmap; + +/* rasterize a shape with quadratic beziers into a bitmap */ +RFONT_API void rstbtt_Rasterize(rstbtt__bitmap *result, /* 1-channel bitmap to draw into */ + float flatness_in_pixels, /* allowable error of curve in pixels */ + rstbtt_vertex *vertices, /* array of vertices defining shape */ + int num_verts, /* number of vertices in above array */ + float scale_x, float scale_y, /* scale applied to input vertices */ + float shift_x, float shift_y, /* translation applied to input vertices */ + int x_off, int y_off, /* another translation applied to input */ + int invert); /* if non-zero, vertically flip shape */ + +enum { /* platformID */ + rstbtt_PLATFORM_ID_UNICODE =0, + rstbtt_PLATFORM_ID_MAC =1, + rstbtt_PLATFORM_ID_ISO =2, + rstbtt_PLATFORM_ID_MICROSOFT =3 +}; + +enum { /* encodingID for rstbtt_PLATFORM_ID_UNICODE */ + rstbtt_UNICODE_EID_UNICODE_1_0 =0, + rstbtt_UNICODE_EID_UNICODE_1_1 =1, + rstbtt_UNICODE_EID_ISO_10646 =2, + rstbtt_UNICODE_EID_UNICODE_2_0_BMP=3, + rstbtt_UNICODE_EID_UNICODE_2_0_FULL=4 +}; + +enum { /* encodingID for rstbtt_PLATFORM_ID_MICROSOFT */ + rstbtt_MS_EID_SYMBOL =0, + rstbtt_MS_EID_UNICODE_BMP =1, + rstbtt_MS_EID_SHIFTJIS =2, + rstbtt_MS_EID_UNICODE_FULL =10 +}; + +enum { /* encodingID for rstbtt_PLATFORM_ID_MAC; same as Script Manager codes */ + rstbtt_MAC_EID_ROMAN =0, rstbtt_MAC_EID_ARABIC =4, + rstbtt_MAC_EID_JAPANESE =1, rstbtt_MAC_EID_HEBREW =5, + rstbtt_MAC_EID_CHINESE_TRAD =2, rstbtt_MAC_EID_GREEK =6, + rstbtt_MAC_EID_KOREAN =3, rstbtt_MAC_EID_RUSSIAN =7 +}; + +enum { /* languageID for rstbtt_PLATFORM_ID_MICROSOFT; same as LCID... + problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */ + rstbtt_MS_LANG_ENGLISH =0x0409, rstbtt_MS_LANG_ITALIAN =0x0410, + rstbtt_MS_LANG_CHINESE =0x0804, rstbtt_MS_LANG_JAPANESE =0x0411, + rstbtt_MS_LANG_DUTCH =0x0413, rstbtt_MS_LANG_KOREAN =0x0412, + rstbtt_MS_LANG_FRENCH =0x040c, rstbtt_MS_LANG_RUSSIAN =0x0419, + rstbtt_MS_LANG_GERMAN =0x0407, rstbtt_MS_LANG_SPANISH =0x0409, + rstbtt_MS_LANG_HEBREW =0x040d, rstbtt_MS_LANG_SWEDISH =0x041D +}; + +enum { /* languageID for rstbtt_PLATFORM_ID_MAC */ + rstbtt_MAC_LANG_ENGLISH =0 , rstbtt_MAC_LANG_JAPANESE =11, + rstbtt_MAC_LANG_ARABIC =12, rstbtt_MAC_LANG_KOREAN =23, + rstbtt_MAC_LANG_DUTCH =4 , rstbtt_MAC_LANG_RUSSIAN =32, + rstbtt_MAC_LANG_FRENCH =1 , rstbtt_MAC_LANG_SPANISH =6 , + rstbtt_MAC_LANG_GERMAN =2 , rstbtt_MAC_LANG_SWEDISH =5 , + rstbtt_MAC_LANG_HEBREW =10, rstbtt_MAC_LANG_CHINESE_SIMPLIFIED =33, + rstbtt_MAC_LANG_ITALIAN =3 , rstbtt_MAC_LANG_CHINESE_TRAD =19 +}; + +#ifdef __cplusplus +} +#endif + +#ifndef rstbtt_MAX_OVERSAMPLE +#define rstbtt_MAX_OVERSAMPLE 8 +#endif + +#if rstbtt_MAX_OVERSAMPLE > 255 +#error "rstbtt_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int rstbtt__test_oversample_pow2[(rstbtt_MAX_OVERSAMPLE & (rstbtt_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +#ifndef rstbtt_RASTERIZER_VERSION +#define rstbtt_RASTERIZER_VERSION 2 +#endif + +#ifdef _MSC_VER +#define rstbtt__NOTUSED(v) (void)(v) +#else +#define rstbtt__NOTUSED(v) (void)sizeof(v) +#endif + +#undef RFONT_API +#define RFONT_API extern + + + +RFONT_API u8 rstbtt__buf_get8(rstbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; +} + +RFONT_API u8 rstbtt__buf_peek8(rstbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; +} + +RFONT_API void rstbtt__buf_seek(rstbtt__buf *b, int o) +{ + assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +RFONT_API void rstbtt__buf_skip(rstbtt__buf *b, int o) +{ + rstbtt__buf_seek(b, b->cursor + o); +} + +RFONT_API u32 rstbtt__buf_get(rstbtt__buf *b, int n) +{ + u32 v = 0; + int i; + assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | rstbtt__buf_get8(b); + return v; +} + +RFONT_API rstbtt__buf rstbtt__new_buf(const void *p, size_t size) +{ + rstbtt__buf r; + assert(size < 0x40000000); + r.data = (u8*) p; + r.size = (int) size; + r.cursor = 0; + return r; +} + +#define rstbtt__buf_get16(b) (u16)rstbtt__buf_get((b), 2) +#define rstbtt__buf_get32(b) (u32)rstbtt__buf_get((b), 4) + +RFONT_API rstbtt__buf rstbtt__buf_range(const rstbtt__buf *b, int o, int s) +{ + rstbtt__buf r = rstbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; +} + +RFONT_API rstbtt__buf rstbtt__cff_get_index(rstbtt__buf *b) +{ + int count, start, offsize; + start = b->cursor; + count = rstbtt__buf_get16(b); + if (count) { + offsize = rstbtt__buf_get8(b); + assert(offsize >= 1 && offsize <= 4); + rstbtt__buf_skip(b, offsize * count); + rstbtt__buf_skip(b, (int)rstbtt__buf_get(b, offsize) - 1); + } + return rstbtt__buf_range(b, start, b->cursor - start); +} + +RFONT_API u32 rstbtt__cff_int(rstbtt__buf *b) +{ + int b0 = rstbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) return (u32)b0 - 139; + else if (b0 >= 247 && b0 <= 250) return (u32)((b0 - 247)*256 + rstbtt__buf_get8(b) + 108); + else if (b0 >= 251 && b0 <= 254) return (u32)(-(b0 - 251)*256 - rstbtt__buf_get8(b) - 108); + else if (b0 == 28) return rstbtt__buf_get16(b); + else if (b0 == 29) return rstbtt__buf_get32(b); + assert(0); + return 0; +} + +RFONT_API void rstbtt__cff_skip_operand(rstbtt__buf *b) { + int v, b0 = rstbtt__buf_peek8(b); + assert(b0 >= 28); + if (b0 == 30) { + rstbtt__buf_skip(b, 1); + while (b->cursor < b->size) { + v = rstbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } else { + rstbtt__cff_int(b); + } +} + +RFONT_API rstbtt__buf rstbtt__dict_get(rstbtt__buf *b, int key) +{ + rstbtt__buf_seek(b, 0); + while (b->cursor < b->size) { + int start = b->cursor, end, op; + while (rstbtt__buf_peek8(b) >= 28) + rstbtt__cff_skip_operand(b); + end = b->cursor; + op = rstbtt__buf_get8(b); + if (op == 12) op = rstbtt__buf_get8(b) | 0x100; + if (op == key) return rstbtt__buf_range(b, start, end-start); + } + return rstbtt__buf_range(b, 0, 0); +} + +RFONT_API void rstbtt__dict_get_ints(rstbtt__buf *b, int key, int outcount, u32 *out) +{ + int i; + rstbtt__buf operands = rstbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = rstbtt__cff_int(&operands); +} + +RFONT_API int rstbtt__cff_index_count(rstbtt__buf *b) +{ + rstbtt__buf_seek(b, 0); + return rstbtt__buf_get16(b); +} + +RFONT_API rstbtt__buf rstbtt__cff_index_get(rstbtt__buf b, int i) +{ + int count, offsize, start, end; + rstbtt__buf_seek(&b, 0); + count = rstbtt__buf_get16(&b); + offsize = rstbtt__buf_get8(&b); + assert(i >= 0 && i < count); + assert(offsize >= 1 && offsize <= 4); + rstbtt__buf_skip(&b, i*offsize); + start = (int)rstbtt__buf_get(&b, offsize); + end = (int)rstbtt__buf_get(&b, offsize); + return rstbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); +} + +#define rstbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define rstbtt_tag(p,str) rstbtt_tag4(p,str[0],str[1],str[2],str[3]) + +/* @OPTIMIZE: binary search */ +RFONT_API u32 rstbtt__find_table(u8 *data, u32 fontstart, const char *tag) +{ + i32 num_tables = RFONT_USHORT(data, fontstart+4); + u32 tabledir = fontstart + 12; + i32 i; + for (i=0; i < num_tables; ++i) { + u32 loc = tabledir + 16 * (u32)i; + if (rstbtt_tag(data+loc+0, tag)) + return RFONT_ULONG(data, loc+8); + } + return 0; +} + +RFONT_API rstbtt__buf rstbtt__get_subrs(rstbtt__buf cff, rstbtt__buf fontdict) +{ + u32 subrsoff = 0, private_loc[2] = { 0, 0 }; + rstbtt__buf pdict; + rstbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return rstbtt__new_buf(NULL, 0); + pdict = rstbtt__buf_range(&cff, (int)private_loc[1], (int)private_loc[0]); + rstbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return rstbtt__new_buf(NULL, 0); + rstbtt__buf_seek(&cff, (int)(private_loc[1] + subrsoff)); + return rstbtt__cff_get_index(&cff); +} + +RFONT_API void rstbtt_setvertex(rstbtt_vertex *v, u8 type, i32 x, i32 y, i32 cx, i32 cy) +{ + v->type = type; + v->x = (i16) x; + v->y = (i16) y; + v->cx = (i16) cx; + v->cy = (i16) cy; +} + +RFONT_API int rstbtt__close_shape(rstbtt_vertex *vertices, int num_vertices, int was_off, int start_off, + i32 sx, i32 sy, i32 scx, i32 scy, i32 cx, i32 cy) +{ + if (start_off) { + if (was_off) + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vcurve, sx,sy,scx,scy); + } else { + if (was_off) + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vcurve,sx,sy,cx,cy); + else + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vline,sx,sy,0,0); + } + return num_vertices; +} + +RFONT_API int rstbtt__GetGlyfOffset(const rstbtt_fontinfo *info, int glyph_index); + +RFONT_API int rstbtt__GetGlyphShapeTT(const rstbtt_fontinfo *info, int glyph_index, rstbtt_vertex **pvertices) +{ + i16 numberOfContours; + u8 *endPtsOfContours; + u8 *data = info->data; + rstbtt_vertex *vertices=0; + int num_vertices=0; + int g = rstbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if (g < 0) return 0; + + numberOfContours = RFONT_SHORT(data, g); + + if (numberOfContours > 0) { + u8 flags=0,flagcount; + i32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; + i32 x,y,cx,cy,sx,sy, scx,scy; + u8 *points; + endPtsOfContours = (data + g + 10); + ins = RFONT_USHORT(data, g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1+RFONT_USHORT(endPtsOfContours, numberOfContours*2-2); + + m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */ + vertices = (rstbtt_vertex *) RFONT_MALLOC((size_t)m * sizeof(vertices[0])); + if (vertices == 0) + return 0; + + next_move = 0; + flagcount=0; + + off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */ + + /* first load flags */ + + for (i=0; i < n; ++i) { + if (flagcount == 0) { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } else + --flagcount; + vertices[off+i].type = flags; + } + + /* now load x coordinates */ + x=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 2) { + i16 dx = *points++; + x += (flags & 16) ? dx : -dx; /* ??? */ + } else { + if (!(flags & 16)) { + x = x + (i16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].x = (i16) x; + } + + /* now load y coordinates */ + y=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 4) { + i16 dy = *points++; + y += (flags & 32) ? dy : -dy; /* ??? */ + } else { + if (!(flags & 32)) { + y = y + (i16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].y = (i16) y; + } + + /* now convert them to our format */ + num_vertices=0; + sx = sy = cx = cy = scx = scy = 0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + x = (i16) vertices[off+i].x; + y = (i16) vertices[off+i].y; + + if (next_move == i) { + if (i != 0) + num_vertices = rstbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + + /* now start the new one */ + start_off = !(flags & 1); + if (start_off) { + /* if we start off with an off-curve point, then when we need to find a point on the curve */ + /* where we can start, and we need to save some state for when we wraparound. */ + scx = x; + scy = y; + if (!(vertices[off+i+1].type & 1)) { + /* next point is also a curve point, so interpolate an on-point curve */ + sx = (x + (i32) vertices[off+i+1].x) >> 1; + sy = (y + (i32) vertices[off+i+1].y) >> 1; + } else { + /* otherwise just use the next point as our start point */ + sx = (i32) vertices[off+i+1].x; + sy = (i32) vertices[off+i+1].y; + ++i; /* we're using point i+1 as the starting point, so skip it */ + } + } else { + sx = x; + sy = y; + } + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vmove,sx,sy,0,0); + was_off = 0; + next_move = 1 + RFONT_USHORT(endPtsOfContours, j*2); + ++j; + } else { + if (!(flags & 1)) { /* if it's a curve */ + if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */ + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } else { + if (was_off) + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vcurve, x,y, cx, cy); + else + rstbtt_setvertex(&vertices[num_vertices++], rstbtt_vline, x,y,0,0); + was_off = 0; + } + } + } + num_vertices = rstbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + } else if (numberOfContours < 0) { + /* Compound shapes. */ + int more = 1; + u8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) { + u16 flags, gidx; + int comp_num_verts = 0, i; + rstbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1,0,0,1,0,0}, m, n; + + flags = (u16)RFONT_SHORT(comp, 0); comp+=2; + gidx = (u16)RFONT_SHORT(comp, 0); comp+=2; + + if (flags & 2) { /* XY values */ + if (flags & 1) { /* shorts */ + mtx[4] = RFONT_SHORT(comp, 0); comp+=2; + mtx[5] = RFONT_SHORT(comp, 0); comp+=2; + } else { + mtx[4] = RFONT_CHAR(comp, 0); comp+=1; + mtx[5] = RFONT_CHAR(comp, 0); comp+=1; + } + } + else { + /* @TODO handle matching point */ + assert(0); + } + if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */ + mtx[0] = mtx[3] = RFONT_SHORT(comp, 0 )/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */ + mtx[0] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + mtx[3] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */ + mtx[0] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + mtx[1] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + mtx[2] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + mtx[3] = RFONT_SHORT(comp, 0)/16384.0f; comp+=2; + } + + /* Find transformation scales. */ + m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + + /* Get indexed glyph. */ + comp_num_verts = rstbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) { + /* Transform vertices. */ + for (i = 0; i < comp_num_verts; ++i) { + rstbtt_vertex* v = &comp_verts[i]; + float x,y; + x=v->x; y=v->y; + v->x = (float)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->y = (float)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + x=v->cx; y=v->cy; + v->cx = (float)(m * (mtx[0] * (float)x + mtx[2] * (float)y + mtx[4])); + v->cy = (float)(n * (mtx[1] * (float)x + mtx[3] * (float)y + mtx[5])); + } + /* Append vertices. */ + tmp = (rstbtt_vertex*)RFONT_MALLOC((size_t)(num_vertices + comp_num_verts) * sizeof(rstbtt_vertex)); + if (!tmp) { + if (vertices) RFONT_FREE(vertices); + if (comp_verts) RFONT_FREE(comp_verts); + return 0; + } + if (num_vertices > 0) RFONT_MEMCPY(tmp, vertices, (size_t)num_vertices * sizeof(rstbtt_vertex)); + RFONT_MEMCPY(tmp+num_vertices, comp_verts, (size_t)comp_num_verts * sizeof(rstbtt_vertex)); + if (vertices) RFONT_FREE(vertices); + vertices = tmp; + RFONT_FREE(comp_verts); + num_vertices += comp_num_verts; + } + /* More components ? */ + more = flags & (1<<5); + } + } else { + /* numberOfCounters == 0, do nothing */ + } + + *pvertices = vertices; + return num_vertices; +} + +typedef struct +{ + int bounds; + int started; + float first_x, first_y; + float x, y; + i32 min_x, max_x, min_y, max_y; + + rstbtt_vertex *pvertices; + int num_vertices; +} rstbtt__csctx; + +#define rstbtt__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +RFONT_API void rstbtt__track_vertex(rstbtt__csctx *c, i32 x, i32 y) +{ + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +RFONT_API void rstbtt__csctx_v(rstbtt__csctx *c, u8 type, i32 x, i32 y, i32 cx, i32 cy, i32 cx1, i32 cy1) +{ + if (c->bounds) { + rstbtt__track_vertex(c, x, y); + if (type == rstbtt_vcubic) { + rstbtt__track_vertex(c, cx, cy); + rstbtt__track_vertex(c, cx1, cy1); + } + } else { + rstbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (i16) cx1; + c->pvertices[c->num_vertices].cy1 = (i16) cy1; + } + c->num_vertices++; +} + +RFONT_API void rstbtt__csctx_close_shape(rstbtt__csctx *ctx) +{ + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + rstbtt__csctx_v(ctx, rstbtt_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +RFONT_API void rstbtt__csctx_rmove_to(rstbtt__csctx *ctx, float dx, float dy) +{ + rstbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + rstbtt__csctx_v(ctx, rstbtt_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +RFONT_API void rstbtt__csctx_rline_to(rstbtt__csctx *ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + rstbtt__csctx_v(ctx, rstbtt_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +RFONT_API void rstbtt__csctx_rccurve_to(rstbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + rstbtt__csctx_v(ctx, rstbtt_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +RFONT_API rstbtt__buf rstbtt__get_subr(rstbtt__buf idx, int n) +{ + int count = rstbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return rstbtt__new_buf(NULL, 0); + return rstbtt__cff_index_get(idx, n); +} + +RFONT_API rstbtt__buf rstbtt__cid_get_glyph_subrs(const rstbtt_fontinfo *info, int glyph_index) +{ + rstbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + rstbtt__buf_seek(&fdselect, 0); + fmt = rstbtt__buf_get8(&fdselect); + if (fmt == 0) { + /* untested */ + rstbtt__buf_skip(&fdselect, glyph_index); + fdselector = rstbtt__buf_get8(&fdselect); + } else if (fmt == 3) { + nranges = rstbtt__buf_get16(&fdselect); + start = rstbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) { + v = rstbtt__buf_get8(&fdselect); + end = rstbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) rstbtt__new_buf(NULL, 0); + return rstbtt__get_subrs(info->cff, rstbtt__cff_index_get(info->fontdicts, fdselector)); +} + +RFONT_API int rstbtt__run_charstring(const rstbtt_fontinfo *info, int glyph_index, rstbtt__csctx *c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + rstbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define rstbtt__CSERR(s) (0) + + /* this currently ignores the initial width value, which isn't needed if we have hmtx */ + b = rstbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = rstbtt__buf_get8(&b); + switch (b0) { + /* @TODO implement hinting */ + case 0x13: /* hintmask */ + case 0x14: /* cntrmask */ + if (in_header) + maskbits += (sp / 2); /* implicit "vstem" */ + in_header = 0; + rstbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: /* hstem */ + case 0x03: /* vstem */ + case 0x12: /* hstemhm */ + case 0x17: /* vstemhm */ + maskbits += (sp / 2); + break; + + case 0x15: /* rmoveto */ + in_header = 0; + if (sp < 2) return rstbtt__CSERR("rmoveto stack"); + rstbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); + break; + case 0x04: /* vmoveto */ + in_header = 0; + if (sp < 1) return rstbtt__CSERR("vmoveto stack"); + rstbtt__csctx_rmove_to(c, 0, s[sp-1]); + break; + case 0x16: /* hmoveto */ + in_header = 0; + if (sp < 1) return rstbtt__CSERR("hmoveto stack"); + rstbtt__csctx_rmove_to(c, s[sp-1], 0); + break; + + case 0x05: /* rlineto */ + if (sp < 2) return rstbtt__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + rstbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + /* hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + starting from a different place. */ + + case 0x07: /* vlineto */ + if (sp < 1) return rstbtt__CSERR("vlineto stack"); + goto vlineto; + case 0x06: /* hlineto */ + if (sp < 1) return rstbtt__CSERR("hlineto stack"); + for (;;) { + if (i >= sp) break; + rstbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + rstbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: /* hvcurveto */ + if (sp < 4) return rstbtt__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: /* vhcurveto */ + if (sp < 4) return rstbtt__CSERR("vhcurveto stack"); + for (;;) { + if (i + 3 >= sp) break; + rstbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + rstbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); + i += 4; + } + break; + + case 0x08: /* rrcurveto */ + if (sp < 6) return rstbtt__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + rstbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x18: /* rcurveline */ + if (sp < 8) return rstbtt__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + rstbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + if (i + 1 >= sp) return rstbtt__CSERR("rcurveline stack"); + rstbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + case 0x19: /* rlinecurve */ + if (sp < 8) return rstbtt__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + rstbtt__csctx_rline_to(c, s[i], s[i+1]); + if (i + 5 >= sp) return rstbtt__CSERR("rlinecurve stack"); + rstbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x1A: /* vvcurveto */ + case 0x1B: /* hhcurveto */ + if (sp < 4) return rstbtt__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) { f = s[i]; i++; } + for (; i + 3 < sp; i += 4) { + if (b0 == 0x1B) + rstbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); + else + rstbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); + f = 0.0; + } + break; + + case 0x0A: /* callsubr */ + if (!has_subrs) { + if (info->fdselect.size) + subrs = rstbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + /* fallthrough */ + case 0x1D: /* callgsubr */ + if (sp < 1) return rstbtt__CSERR("call(g|)subr stack"); + v = (int) s[--sp]; + if (subr_stack_height >= 10) return rstbtt__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = rstbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return rstbtt__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: /* return */ + if (subr_stack_height <= 0) return rstbtt__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: /* endchar */ + rstbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { /* two-byte escape */ + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = rstbtt__buf_get8(&b); + switch (b1) { + /* @TODO These "flex" implementations ignore the flex-depth and resolution, + and always draw beziers. */ + case 0x22: /* hflex */ + if (sp < 7) return rstbtt__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + rstbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + rstbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: /* flex */ + if (sp < 13) return rstbtt__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + /* fd is s[12] */ + rstbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + rstbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: /* hflex1 */ + if (sp < 9) return rstbtt__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + rstbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + rstbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); + break; + + case 0x25: /* flex1 */ + if (sp < 11) return rstbtt__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1+dx2+dx3+dx4+dx5; + dy = dy1+dy2+dy3+dy4+dy5; + if (fabs(dx) > fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + rstbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + rstbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return rstbtt__CSERR("unimplemented"); + } + } break; + + default: + if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) + return rstbtt__CSERR("reserved operator"); + + /* push immediate */ + if (b0 == 255) { + f = (float)(i32)rstbtt__buf_get32(&b) / 0x10000; + } else { + rstbtt__buf_skip(&b, -1); + f = (float)(i16)rstbtt__cff_int(&b); + } + if (sp >= 48) return rstbtt__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return rstbtt__CSERR("no endchar"); + +#undef rstbtt__CSERR +} + +RFONT_API int rstbtt__GetGlyphShapeT2(const rstbtt_fontinfo *info, int glyph_index, rstbtt_vertex **pvertices) +{ + /* runs the charstring twice, once to count and once to output (to avoid realloc) */ + rstbtt__csctx count_ctx = rstbtt__CSCTX_INIT(1); + rstbtt__csctx output_ctx = rstbtt__CSCTX_INIT(0); + if (rstbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (rstbtt_vertex*)RFONT_MALLOC((size_t)count_ctx.num_vertices * sizeof(rstbtt_vertex)); + output_ctx.pvertices = *pvertices; + if (rstbtt__run_charstring(info, glyph_index, &output_ctx)) { + assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +RFONT_API int rstbtt_GetGlyphShape(const rstbtt_fontinfo *info, int glyph_index, rstbtt_vertex **pvertices) +{ + if (!info->cff.size) + return rstbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return rstbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + +RFONT_API int rstbtt__GetGlyphKernInfoAdvance(const rstbtt_fontinfo *info, int glyph1, int glyph2) +{ + u8 *data = info->data + info->kern; + u32 needle, straw; + int l, r, m; + + /* we only look at the first table. it must be 'horizontal' and format 0. */ + if (!info->kern) + return 0; + if (RFONT_USHORT(data, 2) < 1) /* number of tables, need at least 1 */ + return 0; + if (RFONT_USHORT(data, 8) != 1) /* horizontal flag must be set in format */ + return 0; + + l = 0; + r = RFONT_USHORT(data, 10) - 1; + needle = (u32)(glyph1 << 16 | glyph2); + while (l <= r) { + m = (l + r) >> 1; + straw = RFONT_ULONG(data, 18+(m*6)); /* note: unaligned read */ + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return RFONT_SHORT(data, 22+(m*6)); + } + return 0; +} + +RFONT_API i32 rstbtt__GetCoverageIndex(u8 *coverageTable, int glyph) +{ + u16 coverageFormat = RFONT_USHORT(coverageTable, 0); + switch(coverageFormat) { + case 1: { + u16 glyphCount = RFONT_USHORT(coverageTable, 2); + + /* Binary search. */ + i32 l=0, r=glyphCount-1, m; + int straw, needle=glyph; + while (l <= r) { + u8 *glyphArray = coverageTable + 4; + u16 glyphID; + m = (l + r) >> 1; + glyphID = RFONT_USHORT(glyphArray, 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; + } + } + } break; + + case 2: { + u16 rangeCount = RFONT_USHORT(coverageTable, 2); + u8 *rangeArray = coverageTable + 4; + + /* Binary search. */ + i32 l=0, r=rangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + u8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = RFONT_USHORT(rangeRecord, 0); + strawEnd = RFONT_USHORT(rangeRecord, 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + u16 startCoverageIndex = RFONT_USHORT(rangeRecord, 4); + return startCoverageIndex + glyph - strawStart; + } + } + } break; + + default: { + /* There are no other cases. */ + assert(0); + } break; + } + + return -1; +} + +RFONT_API i32 rstbtt__GetGlyphClass(u8 *classDefTable, int glyph) +{ + u16 classDefFormat = RFONT_USHORT(classDefTable, 0); + switch(classDefFormat) + { + case 1: { + u16 startGlyphID = RFONT_USHORT(classDefTable, 2); + u16 glyphCount = RFONT_USHORT(classDefTable, 4); + u8 *classDef1ValueArray = classDefTable + 6; + + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (i32)RFONT_USHORT(classDef1ValueArray, 2 * (glyph - startGlyphID)); + + classDefTable = classDef1ValueArray + 2 * glyphCount; + } break; + + case 2: { + u16 classRangeCount = RFONT_USHORT(classDefTable, 2); + u8 *classRangeRecords = classDefTable + 4; + + /* Binary search. */ + i32 l=0, r=classRangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + u8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = RFONT_USHORT(classRangeRecord, 0); + strawEnd = RFONT_USHORT(classRangeRecord, 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (i32)RFONT_USHORT(classRangeRecord, 4); + } + + classDefTable = classRangeRecords + 6 * classRangeCount; + } break; + + default: { + /* There are no other cases. */ + assert(0); + } break; + } + + return -1; +} + +/* Define to assert(x) if you want to break on unimplemented formats. */ +#define rstbtt_GPOS_TODO_assert(x) assert(x) + +RFONT_API i32 rstbtt__GetGlyphGPOSInfoAdvance(const rstbtt_fontinfo *info, int glyph1, int glyph2) +{ + u16 lookupListOffset; + u8 *lookupList; + u16 lookupCount; + u8 *data; + i32 i; + + if (!info->gpos) return 0; + + data = info->data + info->gpos; + + if (RFONT_USHORT(data, 0) != 1) return 0; /* Major version 1 */ + if (RFONT_USHORT(data, 2) != 0) return 0; /* Minor version 0 */ + + lookupListOffset = RFONT_USHORT(data, 8); + lookupList = data + lookupListOffset; + lookupCount = RFONT_USHORT(lookupList, 0); + + for (i=0; i<lookupCount; ++i) { + u16 lookupOffset = RFONT_USHORT(lookupList, 2 + 2 * i); + u8 *lookupTable = lookupList + lookupOffset; + + u16 lookupType = RFONT_USHORT(lookupTable, 0); + u16 subTableCount = RFONT_USHORT(lookupTable, 4); + u8 *subTableOffsets = lookupTable + 6; + switch(lookupType) { + case 2: { /* Pair Adjustment Positioning Subtable */ + i32 sti; + for (sti=0; sti<subTableCount; sti++) { + u16 subtableOffset = RFONT_USHORT(subTableOffsets, 2 * sti); + u8 *table = lookupTable + subtableOffset; + u16 posFormat = RFONT_USHORT(table, 0); + u16 coverageOffset = RFONT_USHORT(table, 2); + i32 coverageIndex = rstbtt__GetCoverageIndex(table + coverageOffset, glyph1); + if (coverageIndex == -1) continue; + + switch (posFormat) { + case 1: { + i32 l, r, m; + int straw, needle; + u16 valueFormat1 = RFONT_USHORT(table, 4); + u16 valueFormat2 = RFONT_USHORT(table, 6); + i32 valueRecordPairSizeInBytes = 2; + u16 pairSetCount = RFONT_USHORT(table, 8); + u16 pairPosOffset = RFONT_USHORT(table, 10 + 2 * coverageIndex); + u8 *pairValueTable = table + pairPosOffset; + u16 pairValueCount = RFONT_USHORT(pairValueTable, 0); + u8 *pairValueArray = pairValueTable + 2; + /* TODO: Support more formats. */ + rstbtt_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + rstbtt_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + assert(coverageIndex < pairSetCount); + rstbtt__NOTUSED(pairSetCount); + + needle=glyph2; + r=pairValueCount-1; + l=0; + + /* Binary search. */ + while (l <= r) { + u16 secondGlyph; + u8 *pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = RFONT_USHORT(pairValue, 0); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + i16 xAdvance = RFONT_SHORT(pairValue, 2); + return xAdvance; + } + } + } break; + + case 2: { + u16 valueFormat1 = RFONT_USHORT(table, 4); + u16 valueFormat2 = RFONT_USHORT(table, 6); + + u16 classDef1Offset = RFONT_USHORT(table, 8); + u16 classDef2Offset = RFONT_USHORT(table, 10); + int glyph1class = rstbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = rstbtt__GetGlyphClass(table + classDef2Offset, glyph2); + + u16 class1Count = RFONT_USHORT(table, 12); + u16 class2Count = RFONT_USHORT(table, 14); + assert(glyph1class < class1Count); + assert(glyph2class < class2Count); + + /* TODO: Support more formats. */ + rstbtt_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + rstbtt_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { + u8 *class1Records = table + 16; + u8 *class2Records = class1Records + 2 * (glyph1class * class2Count); + i16 xAdvance = RFONT_SHORT(class2Records, 2 * glyph2class); + return xAdvance; + } + } break; + + default: { + /* There are no other cases. */ + assert(0); + break; + }; + } + } + break; + }; + + default: + /* TODO: Implement other stuff. */ + break; + } + } + + return 0; +} + +RFONT_API int rstbtt_GetGlyphKernAdvance(const rstbtt_fontinfo *info, int g1, int g2) +{ + int xAdvance = 0; + + if (info->gpos) + xAdvance += rstbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + else if (info->kern) + xAdvance += rstbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + +typedef struct rstbtt__hheap_chunk +{ + struct rstbtt__hheap_chunk *next; +} rstbtt__hheap_chunk; + +typedef struct rstbtt__hheap +{ + struct rstbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; +} rstbtt__hheap; + +RFONT_API void *rstbtt__hheap_alloc(rstbtt__hheap *hh, size_t size) +{ + if (hh->first_free) { + void *p = hh->first_free; + hh->first_free = * (void **) p; + return p; + } else { + if (hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + rstbtt__hheap_chunk *c = (rstbtt__hheap_chunk *) RFONT_MALLOC(sizeof(rstbtt__hheap_chunk) + size * (size_t)count); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + sizeof(rstbtt__hheap_chunk) + size * (size_t)hh->num_remaining_in_head_chunk; + } +} + +RFONT_API void rstbtt__hheap_free(rstbtt__hheap *hh, void *p) +{ + *(void **) p = hh->first_free; + hh->first_free = p; +} + +RFONT_API void rstbtt__hheap_cleanup(rstbtt__hheap *hh) +{ + rstbtt__hheap_chunk *c = hh->head; + while (c) { + rstbtt__hheap_chunk *n = c->next; + RFONT_FREE(c); + c = n; + } +} + +typedef struct rstbtt__edge { + float x0,y0, x1,y1; + int invert; +} rstbtt__edge; + + +typedef struct rstbtt__active_edge +{ + struct rstbtt__active_edge *next; + float fx,fdx,fdy; + float direction; + float sy; + float ey; +} rstbtt__active_edge; + + +RFONT_API rstbtt__active_edge *rstbtt__new_active(rstbtt__hheap *hh, rstbtt__edge *e, int off_x, float start_point) { + rstbtt__active_edge *z = (rstbtt__active_edge *) rstbtt__hheap_alloc(hh, sizeof(*z)); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + assert(z != NULL); + /* assert(e->y0 <= start_point); */ + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= (float)off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} + +RFONT_API void rstbtt__handle_clipped_edge(float *scanline, int x, rstbtt__active_edge *e, float x0, float y0, float x1, float y1) { + if (y0 == y1) return; + assert(y0 < y1); + assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) { + x0 += (x1-x0) * (e->sy - y0) / (y1-y0); + y0 = e->sy; + } + if (y1 > e->ey) { + x1 += (x1-x0) * (e->ey - y1) / (y1-y0); + y1 = e->ey; + } + + if (x0 == x) + assert(x1 <= x+1); + else if (x0 == x+1) + assert(x1 >= x); + else if (x0 <= x) + assert(x1 <= x); + else if (x0 >= x+1) + assert(x1 >= x+1); + else + assert(x1 >= x && x1 <= x+1); + + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1-y0); + else if (x0 >= x+1 && x1 >= x+1) + ; + else { + assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); + scanline[x] += e->direction * (y1-y0) * (1-((x0 - (float)x)+(x1 - (float)x))/2.0f); /* coverage = 1 - average x position */ + } +} + +RFONT_API void rstbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, rstbtt__active_edge *e, float y_top) +{ + float y_bottom = y_top+1; + + while (e) { + /* brute force every pixel + compute intersection points with top & bottom */ + assert(e->ey >= y_top); + + if (e->fdx == 0) { + float x0 = e->fx; + if (x0 < len) { + if (x0 >= 0) { + rstbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); + rstbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); + } else { + rstbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); + } + } + } else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0,sy1; + float dy = e->fdy; + assert(e->sy <= y_bottom && e->ey >= y_top); + + if (e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } else { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } else { + x_bottom = xb; + sy1 = y_bottom; + } + + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + /* from here on, we don't have to range check x values */ + + if ((int) x_top == (int) x_bottom) { + float height; + /* simple case, only spans one pixel */ + int x = (int) x_top; + height = sy1 - sy0; + assert(x >= 0 && x < len); + scanline[x] += e->direction * (float)((1-((x_top - (float)x) + (x_bottom-(float)x))/2)) * height; + scanline_fill[x] += e->direction * height; /* everything right of this pixel is filled */ + } else { + int x,x1,x2; + float y_crossing, step, sign, area; + /* covers 2+ pixels */ + if (x_top > x_bottom) { + /* flip scanline vertically; signed area is the same */ + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } + + x1 = (int) x_top; + x2 = (int) x_bottom; + /* compute intersection with y axis at x1+1 */ + y_crossing = ((float)x1 + 1.0f - (float)x0) * dy + y_top; + + sign = e->direction; + /* area of the rectangle covered from y0..y_crossing */ + area = sign * (y_crossing-sy0); + /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */ + scanline[x1] += area * (1-(((float)x_top - (float)x1)+ ((float)(x1+1-x1)) / 2.0f)); + + step = sign * dy; + for (x = x1+1; x < x2; ++x) { + scanline[x] += area + step/2; + area += step; + } + y_crossing += dy * ((float)x2 - (float)(x1+1)); + + assert(fabs(area) <= 1.01f); + + scanline[x2] += area + sign * (1.0f-((float)((float)x2 - (float)x2) + ((float)x_bottom - (float)x2)) / 2.0f) * (float)(sy1-y_crossing); + + scanline_fill[x2] += sign * (sy1-sy0); + } + } else { + int x; + for (x=0; x < len; ++x) { + + float y0 = y_top; + float x1 = (float) (x); + float x2 = (float) (x+1); + float x3 = xb; + float y3 = y_bottom; + + float y1 = ((float)x - x0) / dx + y_top; + float y2 = ((float)x + 1 - x0) / dx + y_top; + + if (x0 < x1 && x3 > x2) { /*three segments descending down-right */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + rstbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); + rstbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + rstbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); + rstbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + rstbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + rstbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + rstbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + rstbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else { /* one segment */ + rstbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); + } + } + } + } + e = e->next; + } +} + +/* directly AA rasterize edges w/o supersampling */ +RFONT_API void rstbtt__rasterize_sorted_edges(rstbtt__bitmap *result, rstbtt__edge *e, int n, int vsubsample, int off_x, int off_y) +{ + rstbtt__hheap hh = { 0, 0, 0 }; + rstbtt__active_edge *active = NULL; + int y,j=0, i; + float scanline_data[129], *scanline, *scanline2; + + rstbtt__NOTUSED(vsubsample); + + if (result->w > 64) + scanline = (float *) RFONT_MALLOC((size_t)(result->w*2+1) * sizeof(float)); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float) (off_y + result->h) + 1; + + while (j < result->h) { + /* find center of pixel for this scanline */ + float scan_y_top = (float)y + 0.0f; + float scan_y_bottom = (float)y + 1.0f; + rstbtt__active_edge **step = &active; + + RFONT_MEMSET(scanline , 0, (size_t)result->w * sizeof(scanline[0])); + RFONT_MEMSET(scanline2, 0, (size_t)(result->w + 1) * sizeof(scanline[0])); + + /* update all active edges; + remove all active edges that terminate before the top of this scanline */ + while (*step) { + rstbtt__active_edge * z = *step; + if (z->ey <= scan_y_top) { + *step = z->next; /* delete from list (/) */ + assert(z->direction); + z->direction = 0; + rstbtt__hheap_free(&hh, z); + } else { + step = &((*step)->next); /* advance through list */ + } + } + + /* insert all edges that start before the bottom of this scanline */ + while (e->y0 <= scan_y_bottom) { + if (e->y0 != e->y1) { + rstbtt__active_edge *z = rstbtt__new_active(&hh, e, off_x, scan_y_top); + if (z != NULL) { + if (j == 0 && off_y != 0) { + if (z->ey < scan_y_top) { + /* this can happen due to subpixel positioning and some kind of fp rounding error i think */ + z->ey = scan_y_top; + } + } + assert(z->ey >= scan_y_top); /* if we get really unlucky a tiny bit of an edge can be out of bounds */ + /* insert at front */ + z->next = active; + active = z; + } + } + ++e; + } + + /* now process all active edges */ + if (active) + rstbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + + { + float sum = 0; + for (i=0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float) fabs(k)*255 + 0.5f; + m = (int) k; + if (m > 255) m = 255; + result->pixels[j*result->stride + i] = (unsigned char) m; + } + } + /* advance all the edges */ + step = &active; + while (*step) { + rstbtt__active_edge *z = *step; + z->fx += z->fdx; /* advance to position for current scanline */ + step = &((*step)->next); /* advance through list */ + } + + ++y; + ++j; + } + + rstbtt__hheap_cleanup(&hh); + + if (scanline != scanline_data) + RFONT_FREE(scanline); +} + +#define rstbtt__COMPARE(a,b) ((a)->y0 < (b)->y0) + +RFONT_API void rstbtt__sort_edges_ins_sort(rstbtt__edge *p, int n) +{ + int i,j; + for (i=1; i < n; ++i) { + rstbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) { + rstbtt__edge *b = &p[j-1]; + int c = rstbtt__COMPARE(a,b); + if (!c) break; + p[j] = p[j-1]; + --j; + } + if (i != j) + p[j] = t; + } +} + +RFONT_API void rstbtt__sort_edges_quicksort(rstbtt__edge *p, int n) +{ + /* threshold for transitioning to insertion sort */ + while (n > 12) { + rstbtt__edge t; + int c01,c12,c,m,i,j; + + /* compute median of three */ + m = n >> 1; + c01 = rstbtt__COMPARE(&p[0],&p[m]); + c12 = rstbtt__COMPARE(&p[m],&p[n-1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = rstbtt__COMPARE(&p[0],&p[n-1]); + /* 0>mid && mid<n: 0>n => n; 0<n => 0 */ + /* 0<mid && mid>n: 0>n => 0; 0<n => n */ + z = (c == c12) ? 0 : n-1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i=1; + j=n-1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;;++i) { + if (!rstbtt__COMPARE(&p[i], &p[0])) break; + } + for (;;--j) { + if (!rstbtt__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n-i)) { + rstbtt__sort_edges_quicksort(p,j); + p = p+i; + n = n-i; + } else { + rstbtt__sort_edges_quicksort(p+i, n-i); + n = j; + } + } +} + +RFONT_API void rstbtt__sort_edges(rstbtt__edge *p, int n) +{ + rstbtt__sort_edges_quicksort(p, n); + rstbtt__sort_edges_ins_sort(p, n); +} + +typedef struct +{ + float x,y; +} rstbtt__point; + +RFONT_API void rstbtt__rasterize(rstbtt__bitmap *result, rstbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + rstbtt__edge *e; + int n,i,j,k,m; +#if rstbtt_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif rstbtt_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else + #error "Unrecognized value of rstbtt_RASTERIZER_VERSION" +#endif + /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + now we have to blow out the windings into explicit edge lists */ + n = 0; + for (i=0; i < windings; ++i) + n += wcount[i]; + + e = (rstbtt__edge *) RFONT_MALLOC(sizeof(*e) * (size_t)(n+1)); /* add an extra one as a sentinel */ + if (e == 0) return; + n = 0; + + m=0; + for (i=0; i < windings; ++i) { + rstbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i]-1; + for (k=0; k < wcount[i]; j=k++) { + int a=k,b=j; + /* skip the edge if horizontal */ + if (p[j].y == p[k].y) + continue; + /* add edge from j to k to the list */ + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a=j,b=k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample; + ++n; + } + } + + /* now sort the edges by their highest point (should snap to integer, and then by x) + rstbtt_sort(e, n, sizeof(e[0]), rstbtt__edge_compare); */ + rstbtt__sort_edges(e, n); + + /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */ + rstbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y); + + RFONT_FREE(e); +} + +RFONT_API void rstbtt__add_point(rstbtt__point *points, int n, float x, float y) +{ + if (!points) return; /* during first pass, it's unallocated */ + points[n].x = x; + points[n].y = y; +} + +/* tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching */ +RFONT_API int rstbtt__tesselate_curve(rstbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +{ + /* midpoint */ + float mx = (x0 + 2*x1 + x2)/4; + float my = (y0 + 2*y1 + y2)/4; + /* versus directly drawn line */ + float dx = (x0+x2)/2 - mx; + float dy = (y0+y2)/2 - my; + if (n > 16) /* 65536 segments on one curve better be enough! */ + return 1; + if (dx*dx+dy*dy > objspace_flatness_squared) { /* half-pixel error allowed... need to be smaller if AA */ + rstbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); + rstbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); + } else { + rstbtt__add_point(points, *num_points,x2,y2); + *num_points = *num_points+1; + } + return 1; +} + +RFONT_API void rstbtt__tesselate_cubic(rstbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + /* @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough */ + float dx0 = x1-x0; + float dy0 = y1-y0; + float dx1 = x2-x1; + float dy1 = y2-y1; + float dx2 = x3-x2; + float dy2 = y3-y2; + float dx = x3-x0; + float dy = y3-y0; + float longlen = (float) (sqrt(dx0*dx0+dy0*dy0)+sqrt(dx1*dx1+dy1*dy1)+sqrt(dx2*dx2+dy2*dy2)); + float shortlen = (float) sqrt(dx*dx+dy*dy); + float flatness_squared = longlen*longlen-shortlen*shortlen; + + if (n > 16) /* 65536 segments on one curve better be enough! */ + return; + + if (flatness_squared > objspace_flatness_squared) { + float x01 = (x0+x1)/2; + float y01 = (y0+y1)/2; + float x12 = (x1+x2)/2; + float y12 = (y1+y2)/2; + float x23 = (x2+x3)/2; + float y23 = (y2+y3)/2; + + float xa = (x01+x12)/2; + float ya = (y01+y12)/2; + float xb = (x12+x23)/2; + float yb = (y12+y23)/2; + + float mx = (xa+xb)/2; + float my = (ya+yb)/2; + + rstbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); + rstbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); + } else { + rstbtt__add_point(points, *num_points,x3,y3); + *num_points = *num_points+1; + } +} + +/* returns number of contours */ +RFONT_API rstbtt__point *rstbtt_FlattenCurves(rstbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours) +{ + rstbtt__point *points=0; + int num_points=0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i,n=0,start=0, pass; + + /* count how many "moves" there are to get the contour count */ + for (i=0; i < num_verts; ++i) + if (vertices[i].type == rstbtt_vmove) + ++n; + + *num_contours = n; + if (n == 0) return 0; + + *contour_lengths = (int *) RFONT_MALLOC((size_t)(sizeof(**contour_lengths) * (size_t)n)); + + if (*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + /* make two passes through the points so we don't need to realloc */ + for (pass=0; pass < 2; ++pass) { + float x=0,y=0; + if (pass == 1) { + points = (rstbtt__point *) RFONT_MALLOC((size_t)num_points * sizeof(points[0])); + if (points == NULL) goto error; + } + num_points = 0; + n= -1; + for (i=0; i < num_verts; ++i) { + switch (vertices[i].type) { + case rstbtt_vmove: + /* start the next contour */ + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + rstbtt__add_point(points, num_points++, x,y); + break; + case rstbtt_vline: + x = vertices[i].x, y = vertices[i].y; + rstbtt__add_point(points, num_points++, x, y); + break; + case rstbtt_vcurve: + rstbtt__tesselate_curve(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + case rstbtt_vcubic: + rstbtt__tesselate_cubic(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x; + y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + RFONT_FREE(points); + RFONT_FREE(*contour_lengths); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +RFONT_API void rstbtt_Rasterize(rstbtt__bitmap *result, float flatness_in_pixels, rstbtt_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) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count = 0; + int *winding_lengths = NULL; + rstbtt__point *windings = rstbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count); + if (windings) { + rstbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert); + RFONT_FREE(winding_lengths); + RFONT_FREE(windings); + } +} + +RFONT_API void rstbtt_GetGlyphBitmapBoxSubpixel(const rstbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + int x0=0,y0=0,x1,y1; /* =0 suppresses compiler warning */ + if (!rstbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { + /* e.g. space character */ + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } else { + /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */ + if (ix0) *ix0 = (int)floor( (float)x0 * scale_x + shift_x); + if (iy0) *iy0 = (int)floor( (float)-y1 * scale_y + shift_y); + if (ix1) *ix1 = (int)ceil ( (float)x1 * scale_x + shift_x); + if (iy1) *iy1 = (int)ceil ((float)-y0 * scale_y + shift_y); + } +} + +RFONT_API unsigned char *rstbtt_GetGlyphBitmapSubpixel(const rstbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + int ix0,iy0,ix1,iy1; + rstbtt__bitmap gbm; + rstbtt_vertex *vertices; + int num_verts = rstbtt_GetGlyphShape(info, glyph, &vertices); + + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) { + RFONT_FREE(vertices); + return NULL; + } + scale_y = scale_x; + } + + rstbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + + /* now we get the size */ + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; /* in case we error */ + + if (width ) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + if (gbm.w && gbm.h) { + gbm.pixels = (unsigned char *) RFONT_MALLOC((size_t)(gbm.w * gbm.h)); + if (gbm.pixels) { + gbm.stride = gbm.w; + + rstbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1); + } + } + RFONT_FREE(vertices); + return gbm.pixels; +} + + +RFONT_API int rstbtt_InitFont(rstbtt_fontinfo *info, const unsigned char* const_data, int fontstart) +{ + unsigned char* data = (unsigned char*)const_data; + + u32 cmap, t; + i32 i,numTables; + + info->data = (unsigned char*)data; + info->fontstart = fontstart; + info->cff = rstbtt__new_buf(NULL, 0); + + cmap = rstbtt__find_table(data, (u32)fontstart, "cmap"); /* required */ + info->loca = (int)rstbtt__find_table(data, (u32)fontstart, "loca"); /* required */ + info->head = (int)rstbtt__find_table(data, (u32)fontstart, "head"); /* required */ + info->glyf = (int)rstbtt__find_table(data, (u32)fontstart, "glyf"); /* required */ + info->hhea = (int)rstbtt__find_table(data, (u32)fontstart, "hhea"); /* required */ + info->hmtx = (int)rstbtt__find_table(data, (u32)fontstart, "hmtx"); /* required */ + info->kern = (int)rstbtt__find_table(data, (u32)fontstart, "kern"); /* not required */ + info->gpos = (int)rstbtt__find_table(data, (u32)fontstart, "GPOS"); /* not required */ + + if (!cmap || !info->head || !info->hhea || !info->hmtx) + return 0; + if (info->glyf) { + /* required for truetype */ + if (!info->loca) return 0; + } else { + /* initialization for CFF / Type2 fonts (OTF) */ + rstbtt__buf b, topdict, topdictidx; + u32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + u32 cff; + + cff = rstbtt__find_table(data, (u32)fontstart, "CFF "); + if (!cff) return 0; + + info->fontdicts = rstbtt__new_buf(NULL, 0); + info->fdselect = rstbtt__new_buf(NULL, 0); + + /* @TODO this should use size from table (not 512MB) */ + info->cff = rstbtt__new_buf(data+cff, 512*1024*1024); + b = info->cff; + + /* read the header */ + rstbtt__buf_skip(&b, 2); + rstbtt__buf_seek(&b, rstbtt__buf_get8(&b)); /* hdrsize */ + + /* @TODO the name INDEX could list multiple fonts, + but we just use the first one. */ + rstbtt__cff_get_index(&b); /* name INDEX */ + topdictidx = rstbtt__cff_get_index(&b); + topdict = rstbtt__cff_index_get(topdictidx, 0); + rstbtt__cff_get_index(&b); /* string INDEX */ + info->gsubrs = rstbtt__cff_get_index(&b); + + rstbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + rstbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + rstbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + rstbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = rstbtt__get_subrs(b, topdict); + + /* weonly support Type 2 charstrings */ + if (cstype != 2) return 0; + if (charstrings == 0) return 0; + + if (fdarrayoff) { + /* looks like a CID font */ + if (!fdselectoff) return 0; + rstbtt__buf_seek(&b, (int)fdarrayoff); + info->fontdicts = rstbtt__cff_get_index(&b); + info->fdselect = rstbtt__buf_range(&b, (int)fdselectoff, (int)b.size - (int)fdselectoff); + } + + rstbtt__buf_seek(&b, (int)charstrings); + info->charstrings = rstbtt__cff_get_index(&b); + } + + t = rstbtt__find_table(data, (u32)fontstart, "maxp"); + if (t) + info->numGlyphs = RFONT_USHORT(data, t + 4); + else + info->numGlyphs = 0xffff; + + info->svg = -1; + + numTables = RFONT_USHORT(data, cmap + 2); + info->index_map = 0; + for (i=0; i < numTables; ++i) { + u32 encoding_record = (u32)(cmap + 4 + 8 * (u32)i); + /* find an encoding we understand: */ + switch(RFONT_USHORT(data, encoding_record)) { + case rstbtt_PLATFORM_ID_MICROSOFT: + switch (RFONT_USHORT(data, (int)encoding_record+2)) { + case rstbtt_MS_EID_UNICODE_BMP: + case rstbtt_MS_EID_UNICODE_FULL: + /* MS/Unicode */ + info->index_map = (int)(cmap + RFONT_ULONG(data, encoding_record + 4)); + break; + } + break; + case rstbtt_PLATFORM_ID_UNICODE: + /* Mac/iOS has these */ + /* all the encodingIDs are unicode, so we don't bother to check it */ + info->index_map = (int)(cmap + RFONT_ULONG(data, encoding_record+4)); + break; + } + } + if (info->index_map == 0) + return 0; + + info->indexToLocFormat = RFONT_USHORT(((u8*)data), info->head + 50); + return 1; +} + +RFONT_API int rstbtt_FindGlyphIndex(const rstbtt_fontinfo *info, int unicode_codepoint) { + u8 *data = info->data; + u32 index_map = (u32)info->index_map; + + u16 format = RFONT_USHORT(data, index_map); + if (format == 0) { /* apple byte encoding */ + i32 bytes = RFONT_USHORT(data, index_map + 2); + if (unicode_codepoint < bytes-6) + return RFONT_BYTE(data, (int)index_map + 6 + unicode_codepoint); + return 0; + } else if (format == 6) { + u32 first = RFONT_USHORT(data, index_map + 6); + u32 count = RFONT_USHORT(data, index_map + 8); + if ((u32) unicode_codepoint >= first && (u32) unicode_codepoint < (u32)(first + count)) + return RFONT_USHORT(data, (int)index_map + 10 + (unicode_codepoint - (int)first)*2); + return 0; + } else if (format == 2) { + assert(0); /* @TODO: high-byte mapping for japanese/chinese/korean */ + return 0; + } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */ + u16 segcount = RFONT_USHORT(data, index_map+6) >> 1; + u16 searchRange = RFONT_USHORT(data, index_map+8) >> 1; + u16 entrySelector = RFONT_USHORT(data, index_map+10); + u16 rangeShift = RFONT_USHORT(data, index_map+12) >> 1; + + /* do a binary search of the segments */ + u32 endCount = index_map + 14; + u32 search = endCount; + + if (unicode_codepoint > 0xffff) + return 0; + + /* they lie from endCount .. endCount + segCount + but searchRange is the nearest power of two, so... */ + if (unicode_codepoint >= RFONT_USHORT(data, search + rangeShift*2)) + search += rangeShift*2; + + /* now decrement to bias correctly to find smallest */ + search -= 2; + while (entrySelector) { + u16 end; + searchRange >>= 1; + end = RFONT_USHORT(data, search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + { + u16 offset, start; + u16 item = (u16) ((search - endCount) >> 1); + + assert(unicode_codepoint <= RFONT_USHORT(data, endCount + 2*item)); + start = RFONT_USHORT(data, index_map + 14 + segcount*2 + 2 + 2*item); + if (unicode_codepoint < start) + return 0; + + offset = RFONT_USHORT(data, index_map + 14 + segcount*6 + 2 + 2*item); + if (offset == 0) + return (u16) (unicode_codepoint + RFONT_SHORT(data, index_map + 14 + segcount*4 + 2 + 2*item)); + + return RFONT_USHORT(data, offset + (unicode_codepoint-start)*2 + (int)index_map + 14 + segcount*6 + 2 + 2*item); + } + } else if (format == 12 || format == 13) { + u32 ngroups = RFONT_ULONG(data, index_map+12); + i32 low,high; + low = 0; high = (i32)ngroups; + /* Binary search the right group. */ + while (low < high) { + i32 mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */ + u32 start_char = RFONT_ULONG(data, (int)index_map + 16 + mid * 12); + u32 end_char = RFONT_ULONG(data, (int)index_map + 16 + mid * 12 + 4); + if ((u32) unicode_codepoint < start_char) + high = mid; + else if ((u32) unicode_codepoint > end_char) + low = mid+1; + else { + u32 start_glyph = RFONT_ULONG(data, (int)index_map + 16 + mid * 12 + 8); + if (format == 12) + return (int)((int)start_glyph + unicode_codepoint - (int)start_char); + else /* format == 13 */ + return (int)start_glyph; + } + } + return 0; /* not found */ + } + /* @TODO */ + assert(0); + return 0; +} + +RFONT_API int rstbtt__GetGlyfOffset(const rstbtt_fontinfo *info, int glyph_index) +{ + int g1,g2; + + assert(!info->cff.size); + + if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */ + if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */ + + if (info->indexToLocFormat == 0) { + g1 = info->glyf + RFONT_USHORT(info->data, info->loca + glyph_index * 2) * 2; + g2 = info->glyf + RFONT_USHORT(info->data, info->loca + glyph_index * 2 + 2) * 2; + } else { + g1 = info->glyf + (int)RFONT_ULONG (info->data, info->loca + glyph_index * 4); + g2 = info->glyf + (int)RFONT_ULONG (info->data, info->loca + glyph_index * 4 + 4); + } + + return g1==g2 ? -1 : g1; /* if length is 0, return -1 */ +} + +RFONT_API int rstbtt__GetGlyphInfoT2(const rstbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + rstbtt__csctx c = rstbtt__CSCTX_INIT(1); + int r = rstbtt__run_charstring(info, glyph_index, &c); + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; + return r ? c.num_vertices : 0; +} + +RFONT_API int rstbtt_GetGlyphBox(const rstbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + if (info->cff.size) { + rstbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } else { + int g = rstbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; + + if (x0) *x0 = RFONT_SHORT(info->data, g + 2); + if (y0) *y0 = RFONT_SHORT(info->data, g + 4); + if (x1) *x1 = RFONT_SHORT(info->data, g + 6); + if (y1) *y1 = RFONT_SHORT(info->data, g + 8); + } + return 1; +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +#endif /* n RFONT_EXTERNAL_STB */ + +/* +END of stb_truetype defines and source code required by RFont +*/ + +#endif /* RFONT_IMPLEMENTATION */ diff --git a/include/RSGL.h b/include/RSGL.h new file mode 100644 index 0000000..cfd961b --- /dev/null +++ b/include/RSGL.h @@ -0,0 +1,1926 @@ +/* +* +* Copyright (c) 2021-26 ColleagueRiley ColleagueRiley@gmail.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +* +* +*/ + +/* + define args + (MAKE SURE RSGL_IMPLEMENTATION is in exactly one header or you use -DRSGL_IMPLEMENTATION) + #define RSGL_IMPLEMENTATION - makes it so source code is included with header + + #define RSGL_RFONT - do include functions to help with integrating RFont and RSGL + #define RSGL_MAX_BATCHES [number of batches] - set max number of batches to be allocated + #define RSGL_MAX_VERTS [number of verts] - set max number of verts to be allocated (global, not per batch) +*/ +#include <stdint.h> +#ifndef RSGL_MAX_BATCHES +#define RSGL_MAX_BATCHES 2028 +#endif +#ifndef RSGL_MAX_VERTS +#define RSGL_MAX_VERTS 8192 +#endif + +#ifndef RSGL_MALLOC +#include <stdlib.h> +#define RSGL_MALLOC malloc +#define RSGL_REALLOC realloc +#define RSGL_FREE free +#endif + +#ifndef RSGL_SIN +#include <math.h> +#define RSGL_SIN sinf +#define RSGL_COS cosf +#endif + +#ifndef RSGL_UNUSED +#define RSGL_UNUSED(x) (void) (x); +#endif + +#ifndef RSGL_MEMCPY + #include <string.h> + #define RSGL_MEMCPY(dest, src, count) memcpy(dest, src, count) + #define RSGL_MEMSET(ptr, value, num) memset(ptr, value, num) +#endif + +#ifndef RSGL_H +#define RSGL_H +#ifndef RSGLDEF +#ifdef __APPLE__ +#define RSGLDEF extern inline +#else +#define RSGLDEF inline +#endif +#endif + +#ifndef RSGL_INT_DEFINED + #define RSGL_INT_DEFINED + #if defined(_MSC_VER) || defined(__SYMBIAN32__) + typedef unsigned char u8; + typedef signed char i8; + typedef unsigned short u16; + typedef signed short i16; + typedef unsigned int u32; + typedef signed int i32; + typedef unsigned long long u64; + typedef signed long long i64; + #else + #include <stdint.h> + + typedef uint8_t u8; + typedef int8_t i8; + typedef uint16_t u16; + typedef int16_t i16; + typedef uint32_t u32; + typedef int32_t i32; + typedef uint64_t u64; + typedef int64_t i64; + #endif +#endif + +#ifndef RSGL_BOOL_DEFINED +#define RSGL_BOOL_DEFINED + +#include <stdbool.h> +typedef bool RSGL_bool; +#endif + +#define RSGL_TRUE (RSGL_bool)1 +#define RSGL_FALSE (RSGL_bool)0 + +typedef enum RSGL_textureFormat { + RSGL_formatNone = 0, + RSGL_formatRGB, /*!< 8-bit RGB (3 channels) */ + RSGL_formatBGR, /*!< 8-bit BGR (3 channels) */ + RSGL_formatRGBA, /*!< 8-bit RGBA (4 channels) */ + RSGL_formatBGRA, /*!< 8-bit BGRA (4 channels) */ + RSGL_formatRed, /*!< 8-bit RED (1 channel) */ + RSGL_formatGrayscale, /*!< 8-bit grayscale (1 channel) */ + RSGL_formatGrayscaleAlpha, /*!< 8-bit grayscale alpha (1 channel) */ + RSGL_formatCount +} RSGL_textureFormat; + +typedef enum RSGL_textureDataType { + RSGL_textureDataInt = 0, + RSGL_textureDataFloat +} RSGL_textureDataType; + +typedef enum RSGL_textureFilter { + RSGL_filterNearest = 0, + RSGL_filterLinear +} RSGL_textureFilter; + +typedef struct RSGL_textureBlob { + void* data; /* input data */ + size_t width; /* width of the texture */ + size_t height; /* height of the texture */ + RSGL_textureDataType dataType; + RSGL_textureFormat dataFormat; /* format of the input data */ + RSGL_textureFormat textureFormat; /* final format for the texture */ + RSGL_textureFilter minFilter; /* filter used when rendering a surface smaller than the base texture */ + RSGL_textureFilter magFilter; /* filter used when rendering a surface bigger than the base texture */ +} RSGL_textureBlob; + +#ifndef RSGL_texture +#define RSGL_texture size_t +#endif + +#ifndef RSGL_framebuffer +#define RSGL_framebuffer size_t +#endif + +/* +******* +RSGL shapes +******* +*/ + +#ifndef RSGL_rect +typedef struct RSGL_rect { float x, y, w, h; } RSGL_rect; +#endif + +#define RSGL_RECT(x, y, w, h) (RSGL_rect){(float)x, (float)y, (float)w, (float)h} + +#ifndef RSGL_cube +typedef struct RSGL_cube { float x, y, z, w, h, l; } RSGL_cube; +#endif + +#define RSGL_CUBE(x, y, z, w, h, l) (RSGL_cube){(float)x, (float)y, (float)z, (float)w, (float)h, (float)l} + +#ifndef RSGL_vec2D +typedef struct RSGL_vec2D { float x, y; } RSGL_vec2D; +#endif +#define RSGL_VEC2D(x, y) (RSGL_vec2D){(float)x, (float)y} + +#ifndef RSGL_vec3D +typedef struct RSGL_vec3D { float x, y, z; } RSGL_vec3D; +#endif + +#define RSGL_VEC3D(x, y, z) (RSGL_vec3D){(float)x, (float)y, (float)z} + +#define RSGL_TRIANGLE(p1, p2, p3) (RSGL_vec3D[3]){p1, p2, p3} +#define RSGL_createTriangle(p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z) RSGL_TRIANGLE3D(RSGL_VEC3D(p1x, p1y, p1z), RSGL_VEC3D(p2x, p2y, p2z), RSGL_VEC3D(p3x, p3y, p3z)) + +/* +the color stucture is in +ABGR by default for performance reasons +(converting color to hex for example) +*/ +#ifndef RSGL_color +typedef struct RSGL_color { + u8 a, b, g, r; +} RSGL_color; +#endif + +#define RSGL_RGBA(r, g, b, a) ((RSGL_color){(u8)(a), (u8)(b), (u8)(g), (u8)(r)}) +#define RSGL_RGB(r, g, b) ((RSGL_color){255, (u8)(b), (u8)(g), (u8)(r)}) + +#define RSGL_COLOR_TO_HEX(color) ((u32)(color) & 0xFFFFFF00) +#define RSGL_RGB_TO_HEX(r, g, b, a) (RSGL_COLOR_TO_HEX(RSGL_RGBA(r, g, b, a))) +#define RSGL_RGBA_TO_HEX(r, g, b) (RSGL_COLOR_TO_HEX(RSGL_RGB(r, g, b, a))) + +/* +********************* +RSGL matrix math +********************* +*/ + +#ifndef RSGL_mat4 +typedef struct RSGL_mat4 { + float m[16]; +} RSGL_mat4; +#endif + +RSGLDEF RSGL_mat4 RSGL_mat4_loadIdentity(void); +RSGLDEF RSGL_mat4 RSGL_mat4_scale(float matrix[16], float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_rotate(float matrix[16], float angle, float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_translate(float matrix[16], float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_perspective(float matrix[16], float fovY, float aspect, float zNear, float zFar); +RSGLDEF RSGL_mat4 RSGL_mat4_ortho(float matrix[16], float left, float right, float bottom, float top, float znear, float zfar); +RSGLDEF RSGL_mat4 RSGL_mat4_lookAt(float matrix[16], float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ); + +RSGLDEF RSGL_mat4 RSGL_mat4_multiply(float left[16], float right[16]); + +RSGLDEF RSGL_vec3D RSGL_mat4_multiplyPoint(RSGL_mat4 matrix, RSGL_vec3D point); + +/* +******* +RSGL_perspective +******* +*/ + +typedef enum RSGL_projectionType { + RSGL_projectionOrtho2D = 0, + RSGL_projectionOrtho3D, + RSGL_projectionPerspective3D, +} RSGL_projectionType; + +typedef struct RSGL_projection2D { + RSGL_projectionType type; + u32 width; + u32 height; +} RSGL_projection2D; + +typedef struct RSGL_projection3D { + RSGL_projectionType type; + float fov; + float ratio; + float pNear; + float pFar; +} RSGL_projection3D; + +typedef union RSGL_projection { + RSGL_projectionType type; + RSGL_projection2D p2D; + RSGL_projection3D p3D; +} RSGL_projection; + +RSGLDEF RSGL_mat4 RSGL_projection_getMatrix(const RSGL_projection* projection); + +/* +********************* +RSGL renderer +********************* +*/ + +/* used internally for RSGL_deleteProgram */ +typedef enum RSGL_shaderType { + RSGL_shaderTypeNone = 0, + RSGL_shaderTypeStandard = 1, /* standard vertex+fragment shader */ + RSGL_shaderTypeCompute = 2, + RSGL_shaderTypeGeometry = 4, /* unimplemented as of now */ +} RSGL_shaderType; + +/* shader program and blob */ +typedef struct RSGL_programBlob { + const char* vertex; + size_t vertexLen; + const char* fragment; + size_t fragmentLen; +} RSGL_programBlob; + +typedef struct RSGL_programInfo { + size_t program; + size_t perspectiveView; + size_t model; + size_t vertexPosition; + size_t vertexTexCoord; + size_t vertexColor; + + RSGL_shaderType type; +} RSGL_programInfo; + +typedef struct RSGL_BATCH { + size_t start, len; /* when batch starts and it's length */ + size_t elmStart, elmCount; /* when element batch starts and it's length */ + u32 type; + RSGL_texture tex; + float lineWidth; + RSGL_mat4 matrix; +} RSGL_BATCH; /* batch data type for rendering */ + +typedef struct RSGL_renderData { + float* verts; + float* texCoords; + float* colors; + u16* elements; + size_t elements_count; + size_t len; /* number of verts */ + + RSGL_mat4 perspective; /* perspective matrix */ +} RSGL_renderData; + +typedef enum RSGL_bufferType { + RSGL_arrayBuffer = 0, + RSGL_elementArrayBuffer, + RSGL_shaderStorageBuffer, + RSGL_textureBuffer, + RSGL_uniformBuffer +} RSGL_bufferType; + +typedef struct RSGL_renderBuffers { + size_t vertex, color, texture, elements; + size_t maxVerts; + + RSGL_BATCH batches[RSGL_MAX_BATCHES]; + size_t batchCount; +} RSGL_renderBuffers; + +typedef struct RSGL_renderState { + float* gradient; /* does not allocate any memory */ + + RSGL_rect source; + RSGL_texture texture; + u32 gradient_len; + + RSGL_color color; + + RSGL_vec3D rotate; + RSGL_programInfo* program; + RSGL_renderBuffers* buffers; + + RSGL_vec3D center; + float lineWidth; + RSGL_mat4 modelMatrix; + RSGL_mat4 viewMatrix; + RSGL_mat4 perspectiveMatrix; + RSGL_bool forceBatch; + RSGL_bool overflow; + RSGL_framebuffer framebuffer; +} RSGL_renderState; + +typedef struct RSGL_renderPass { + RSGL_programInfo* program; + float* matrix; + RSGL_renderBuffers* buffers; + RSGL_framebuffer framebuffer; +} RSGL_renderPass; + +typedef struct RSGL_rendererProc { + size_t (*size)(void); /* get the size of the renderer's internal struct */ + RSGL_programBlob (*defaultBlob)(void* ctx); + void (*initPtr)(void* ctx, void* proc); /* init render backend */ + void (*freePtr)(void* ctx); /* free render backend */ + void (*render)(void* ctx, const RSGL_renderPass* pass); + void (*clear)(void* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a); + void (*viewport)(void* ctx, i32 x, i32 y, i32 w, i32 h); + void (*setSurface)(void* ctx, void* surface); + RSGL_texture (*createTexture)(void* ctx, const RSGL_textureBlob* blob); + void (*copyToTexture)(void* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob); + void (*deleteTexture)(void* ctx, RSGL_texture tex); + void (*scissorStart)(void* ctx, float x, float y, float w, float h, float renderer_height); + void (*scissorEnd)(void* ctx); + RSGL_programInfo (*createProgram)(void* ctx, RSGL_programBlob* blob); + void (*deleteProgram)(void* ctx, const RSGL_programInfo* program); + size_t (*findShaderVariable)(void*, const RSGL_programInfo*, const char*, size_t); + void (*updateShaderVariable)(void*, const RSGL_programInfo*, size_t, const float[], u8); + RSGL_programInfo (*createComputeProgram)(void* ctx, const char* CShaderCode); + void (*dispatchComputeProgram)(void* ctx, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z); + void (*bindComputeTexture)(void* ctx, u32 texture, u8 format); + void (*createBuffer)(void* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer); + void (*updateBuffer)(void* ctx, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len); + void (*deleteBuffer)(void* ctx, size_t buffer); + RSGL_framebuffer (*createFramebuffer)(void* ctx, size_t width, size_t height); + void (*attachFramebuffer)(void* ctx, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel); + void (*deleteFramebuffer)(void* ctx, RSGL_framebuffer fbo); +} RSGL_rendererProc; + +typedef struct RSGL_renderer { + RSGL_renderData data; + RSGL_renderState state; + RSGL_rendererProc proc; + void* userPtr; + void* ctx; /* pointer for the renderer backend to store any internal data it wants/needs */ + + RSGL_texture defaultTexture; + RSGL_programInfo defaultProgram; + RSGL_mat4 defaultPerspectiveMatrix; + + float verts[RSGL_MAX_VERTS * 3]; + float texCoords[RSGL_MAX_VERTS * 2]; + float colors[RSGL_MAX_VERTS * 4]; + u16 elements[RSGL_MAX_VERTS * 6]; + RSGL_renderBuffers buffers; +} RSGL_renderer; + +RSGLDEF void RSGL_renderer_getRenderState(RSGL_renderer* renderer, RSGL_renderState* state); + +RSGLDEF size_t RSGL_renderer_size(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_initPtr(RSGL_rendererProc proc, + void* loader, /* opengl prozc address ex. wglProcAddress */ + void* ptr, /* pointer to allocate backend data */ + RSGL_renderer* renderer + ); + +RSGLDEF RSGL_renderer* RSGL_renderer_init(RSGL_rendererProc proc, void* loader); +RSGLDEF void RSGL_renderer_updateSize(RSGL_renderer* renderer, size_t width, size_t height); +RSGLDEF void RSGL_renderer_freePtr(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setSurface(RSGL_renderer* renderer, void* surface); + +RSGLDEF void RSGL_renderer_createBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t size, const void* data, size_t* buffer); +RSGLDEF void RSGL_renderer_updateBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len); +RSGLDEF void RSGL_renderer_deleteBuffer(RSGL_renderer* renderer, size_t buffer); + +RSGLDEF void RSGL_renderer_createRenderBuffers(RSGL_renderer* renderer, size_t size, RSGL_renderBuffers* buffers); +RSGLDEF void RSGL_renderer_deleteRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers); + +RSGLDEF void RSGL_renderer_render(RSGL_renderer* renderer); /* draw current batch */ +RSGLDEF void RSGL_renderer_updateRenderBuffers(RSGL_renderer* renderer); +RSGLDEF void RSGL_renderer_renderBuffers(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_free(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setRotate(RSGL_renderer* renderer, RSGL_vec3D rotate); /* apply rotation to drawing */ +RSGLDEF void RSGL_renderer_setTexture(RSGL_renderer* renderer, RSGL_texture texture); /* apply texture to drawing */ +RSGLDEF void RSGL_renderer_setTextureSource(RSGL_renderer* renderer, RSGL_texture texture, RSGL_rect rect); /* apply texture to drawing (limited to the given rect) */ +RSGLDEF void RSGL_renderer_setColor(RSGL_renderer* renderer, RSGL_color color); /* apply color to drawing */ +RSGLDEF void RSGL_renderer_setProgram(RSGL_renderer* renderer, RSGL_programInfo* program); /* use shader program for drawing */ +RSGLDEF void RSGL_renderer_setFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer framebuffer); +RSGLDEF void RSGL_renderer_setRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers); +RSGLDEF void RSGL_renderer_setGradient(RSGL_renderer* renderer, + float* gradient, /* array of gradients */ + size_t len /* length of array */ + ); /* apply gradient to drawing, based on color list*/ +RSGLDEF void RSGL_renderer_setCenter(RSGL_renderer* renderer, RSGL_vec3D center); /* the center of the drawing (or shape), this is used for rotation */ +RSGLDEF void RSGL_renderer_setOverflow(RSGL_renderer* renderer, RSGL_bool overflow); +/* args clear after a draw function by default, this toggles that */ +RSGLDEF void RSGL_renderer_clearArgs(RSGL_renderer* renderer); /* clears the args */ + +RSGLDEF RSGL_mat4 RSGL_renderer_initDrawMatrix(RSGL_renderer* renderer, RSGL_vec3D center); + +/* renders the current batches */ +RSGLDEF void RSGL_renderer_clear(RSGL_renderer* renderer, RSGL_color color); +RSGLDEF void RSGL_renderer_viewport(RSGL_renderer* renderer, RSGL_rect rect); +/* create a texture based on a given bitmap, this must be freed later using RSGL_deleteTexture or opengl*/ +RSGLDEF RSGL_texture RSGL_renderer_createTexture(RSGL_renderer* renderer, const RSGL_textureBlob* blob); +/* updates an existing texture wiht a new bitmap */ +RSGLDEF void RSGL_renderer_copyToTexture(RSGL_renderer* renderer, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob); +/* delete a texture */ +RSGLDEF void RSGL_renderer_deleteTexture(RSGL_renderer* renderer, RSGL_texture tex); +RSGLDEF RSGL_framebuffer RSGL_renderer_createFramebuffer(RSGL_renderer* renderer, size_t width, size_t height); +RSGLDEF void RSGL_renderer_attachFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel); +RSGLDEF void RSGL_renderer_deleteFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo); +/* starts scissoring */ +RSGLDEF void RSGL_renderer_scissorStart(RSGL_renderer* renderer, RSGL_rect scissor, i32 height); +/* stops scissoring */ +RSGLDEF void RSGL_renderer_scissorEnd(RSGL_renderer* renderer); +/* custom shader program */ +RSGLDEF RSGL_programBlob RSGL_renderer_defaultBlob(RSGL_renderer* ctx); +RSGLDEF RSGL_programInfo RSGL_renderer_createProgram(RSGL_renderer* renderer, RSGL_programBlob* blob); +RSGLDEF void RSGL_renderer_deleteProgram(RSGL_renderer* renderer, const RSGL_programInfo* program); +RSGLDEF size_t RSGL_renderer_findShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, const char* var, size_t len); +RSGLDEF void RSGL_renderer_updateShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, size_t var, const float value[], u8 len); +RSGLDEF void RSGL_renderer_forceBatch(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); +RSGLDEF void RSGL_renderer_setDefaultPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); + +RSGLDEF void RSGL_renderer_setModelMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); +RSGLDEF void RSGL_renderer_resetModelMatrix(RSGL_renderer* renderer); + +RSGLDEF RSGL_programInfo RSGL_renderer_createComputeProgram(RSGL_renderer* renderer, const char *CShaderCode); +RSGLDEF void RSGL_renderer_dispatchComputeProgram(RSGL_renderer* renderer, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z); +RSGLDEF void RSGL_renderer_bindComputeTexture(RSGL_renderer* renderer, u32 texture, u8 format); + +/* +******* +RSGL_draw low level +******* +RSGL_drawRawVerts is a function used internally by RSGL, but you can use it yourself +RSGL_drawRawVerts batches a given set of points based on th data to be rendered +*/ + +typedef enum RSGL_drawType { + RSGL_TRIANGLES = 0, + RSGL_POINTS = 1, + RSGL_LINES = 2 +} RSGL_drawType; + +typedef struct RSGL_rawVerts { + RSGL_drawType type; + float* verts; + float* texCoords; + u16* elements; + size_t elmCount; + size_t vert_count; +} RSGL_rawVerts; + +RSGLDEF i32 RSGL_drawRawVerts(RSGL_renderer* renderer, const RSGL_rawVerts* data); + +/* + ****** + * Rfont_RSGL RFont integration * + ****** + * */ + +#ifdef RSGL_RFONT +RSGLDEF struct RFont_renderer_proc RFont_RSGL_renderer_proc(void); + +RSGLDEF struct RFont_renderer* RFont_RSGL_renderer_init(struct RSGL_renderer* ptr); +RSGLDEF void RFont_RSGL_renderer_initPtr(struct RSGL_renderer* ptr, struct RFont_renderer* renderer); +RSGLDEF void RFont_RSGL_renderer_free(struct RFont_renderer* renderer); +#endif + +#endif /* ndef RSGL_H */ + +/* +******* +RSGL high level API +******* +*/ + +#if !defined(RSGL_NO_HIGHLEVEL) && !defined(RSGL_HIGHLEVEL_H) + + +/* +******* +RSGL_draw primitives +******* +*/ + +/* 2D shape drawing */ +/* in the function names, F means float */ + +RSGLDEF i32 RSGL_drawPoint(RSGL_renderer* renderer, RSGL_vec2D p); + +RSGLDEF i32 RSGL_drawRect(RSGL_renderer* renderer, RSGL_rect r); + +RSGLDEF i32 RSGL_drawRoundRect(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding); + +RSGLDEF i32 RSGL_drawPolygon(RSGL_renderer* renderer, RSGL_rect r, u32 sides); + +RSGLDEF i32 RSGL_drawArc(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc); + +RSGLDEF i32 RSGL_drawOval(RSGL_renderer* renderer, RSGL_rect o); + +RSGLDEF i32 RSGL_drawLine(RSGL_renderer* renderer, RSGL_vec2D p1, RSGL_vec2D p2, u32 thickness); + +/* 3D objects */ +RSGLDEF i32 RSGL_drawTriangle(RSGL_renderer* renderer, RSGL_vec3D[3]); +RSGLDEF i32 RSGL_drawPoint3D(RSGL_renderer* renderer, RSGL_vec3D p); +RSGLDEF i32 RSGL_drawLine3D(RSGL_renderer* renderer, RSGL_vec3D p1, RSGL_vec3D p2, u32 thickness); +RSGLDEF i32 RSGL_drawCube(RSGL_renderer* renderer, RSGL_cube cube); + +/* 2D outlines */ + +/* thickness means the thickness of the line */ +RSGLDEF i32 RSGL_drawTriangleOutline(RSGL_renderer* renderer, RSGL_vec3D triangle[3], u32 thickness); + +RSGLDEF i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness); +RSGLDEF i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness); + +RSGLDEF i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness); +RSGLDEF i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness); + +RSGLDEF i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect r, u32 sides, u32 thickness); +RSGLDEF i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect r, u32 sides, u32 thickness); + +RSGLDEF i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness); +RSGLDEF i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness); + +RSGLDEF i32 RSGL_drawOvalOutline(RSGL_renderer* renderer, RSGL_rect o, u32 thickness); + +/* +******* +RSGL_view +******* +*/ + +typedef enum RSGL_viewType { + RSGL_viewTypeNone = 0, + RSGL_viewType2D, + RSGL_viewType3D, +} RSGL_viewType; + +typedef struct RSGL_view2D { + RSGL_viewType type; + RSGL_vec3D offset; + RSGL_vec3D target; + float rotation; + float zoom; +} RSGL_view2D; + +/* RSGL translation */ +typedef struct RSGL_view3D { + RSGL_viewType type; + RSGL_vec3D pos; + RSGL_vec3D target; + RSGL_vec3D up; +} RSGL_view3D; + +typedef union RSGL_view { + RSGL_viewType type; + RSGL_view2D view2D; + RSGL_view3D view3D; +} RSGL_view; + +RSGLDEF RSGL_mat4 RSGL_view_getMatrix(const RSGL_view* view); + +#endif /* ndef RSGL_HIGHLEVEL_H && ndef RSGL_NO_HIGHLEVEL */ + +#ifdef RSGL_IMPLEMENTATION + +#ifndef M_PI + #define M_PI 3.14159265358979323846f +#endif +#ifndef DEG2RAD + #define DEG2RAD (float)(M_PI / 180.0f) +#endif +#ifndef RAD2DEG + #define RAD2DEG (float)(180.0f / M_PI) +#endif + +#define RSGL_GET_MATRIX_X(x, y, z) (float)(matrix.m[0] * x + matrix.m[4] * y + matrix.m[8] * z + matrix.m[12]) +#define RSGL_GET_MATRIX_Y(x, y, z) (float)(matrix.m[1] * x + matrix.m[5] * y + matrix.m[9] * z + matrix.m[13]) +#define RSGL_GET_MATRIX_Z(x, y, z) (float)(matrix.m[2] * x + matrix.m[6] * y + matrix.m[10] * z + matrix.m[14]) +#define RSGL_GET_MATRIX_W(x, y, z) (float)(matrix.m[2] * x + matrix.m[7] * y + matrix.m[11] * z + matrix.m[15]) + +#define RSGL_GET_MATRIX_POINT(x, y, z) \ + RSGL_GET_MATRIX_X((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)), \ + RSGL_GET_MATRIX_Y((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)), \ + RSGL_GET_MATRIX_Z((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)) + +#define RSGL_GET_MATRIX_POINTW(x, y, z) \ + RSGL_GET_MATRIX_X(x, y, z), \ + RSGL_GET_MATRIX_Y(x, y, z), \ + RSGL_GET_MATRIX_Z(x, y, z), \ + RSGL_GET_MATRIX_W(x, y, z) \ + +void RSGL_renderer_forceBatch(RSGL_renderer* renderer) { + renderer->state.forceBatch = RSGL_TRUE; +} + +void RSGL_renderer_setPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.perspectiveMatrix = matrix; +} + +void RSGL_renderer_setDefaultPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->defaultPerspectiveMatrix = matrix; +} + +void RSGL_renderer_setViewMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.viewMatrix = matrix; +} +void RSGL_renderer_resetViewMatrix(RSGL_renderer* renderer) { + RSGL_renderer_setViewMatrix(renderer, RSGL_mat4_loadIdentity()); +} + +void RSGL_renderer_setModelMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.modelMatrix = matrix; + renderer->state.forceBatch = RSGL_TRUE; +} + + +void RSGL_renderer_resetModelMatrix(RSGL_renderer* renderer) { + RSGL_renderer_setModelMatrix(renderer, RSGL_mat4_loadIdentity()); +} + +void RSGL_renderer_getRenderState(RSGL_renderer* renderer, RSGL_renderState* state) { + if (state) *state = renderer->state; +} + +void RSGL_renderer_setOverflow(RSGL_renderer* renderer, RSGL_bool overflow) { + renderer->state.overflow = overflow; +} +#include <stdio.h> +i32 RSGL_drawRawVerts(RSGL_renderer* renderer, const RSGL_rawVerts* data) { + if ((renderer->state.buffers->batchCount + 1 >= RSGL_MAX_BATCHES || renderer->data.len + data->vert_count >= renderer->state.buffers->maxVerts) && renderer->state.overflow) { + RSGL_renderer_render(renderer); + } + + RSGL_BATCH* batch = NULL; + RSGL_color c = renderer->state.color; + + if ( + renderer->state.buffers->batchCount == 0 || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].tex != renderer->state.texture || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].lineWidth != renderer->state.lineWidth || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].type != data->type || + renderer->state.forceBatch + ) { + renderer->state.forceBatch = RSGL_FALSE; + renderer->state.buffers->batchCount += 1; + + batch = &renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1]; + batch->start = renderer->data.len; + batch->len = 0; + batch->elmStart = renderer->data.elements_count; + batch->elmCount = 0; + batch->type = data->type; + batch->tex = renderer->state.texture; + batch->lineWidth = renderer->state.lineWidth; + batch->matrix = renderer->state.modelMatrix; + } else { + batch = &renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1]; + } + + if (batch == NULL) { + return -1; + } + + batch->elmCount += data->elmCount; + batch->len += data->vert_count; + + RSGL_MEMCPY(&renderer->data.verts[renderer->data.len * 3], data->verts, data->vert_count * sizeof(float) * 3); + RSGL_MEMCPY(&renderer->data.texCoords[renderer->data.len * 2], data->texCoords, data->vert_count * sizeof(float) * 2); + + size_t i; + for (i = 0; i < data->elmCount; i++) { + size_t index = renderer->data.elements_count + i; + u16 elm = data->elements[i] + (u16)renderer->data.len; + renderer->data.elements[index] = elm; + } + + renderer->data.elements_count += data->elmCount; + + float color[4] = {c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f}; + + if (renderer->state.gradient_len && renderer->state.gradient && (i64)(data->vert_count - 1) > 0) { + RSGL_MEMCPY(&renderer->data.colors[renderer->data.len * 4], color, sizeof(float) * 4); + RSGL_MEMCPY(&renderer->data.colors[renderer->data.len * 4 + 4], renderer->state.gradient, (data->vert_count - 1) * sizeof(float) * 4); + } + else { + size_t i; + for (i = 0; i < data->vert_count * 4; i += 4) + RSGL_MEMCPY(&renderer->data.colors[(renderer->data.len * 4) + i], color, sizeof(float) * 4); + } + + renderer->data.len += data->vert_count; + return renderer->state.buffers->batchCount - 1; +} + +/* +********************* +RSGL_GRAPHICS_CONTEXT +********************* +*/ + +void RSGL_renderer_setSurface(RSGL_renderer* renderer, void* surface) { + renderer->proc.setSurface(renderer->ctx, surface); +} + +void RSGL_renderer_createBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t size, const void* data, size_t* buffer) { + if (renderer->proc.createBuffer) { + renderer->proc.createBuffer(renderer->ctx, type, size, data, buffer); + } +} + +void RSGL_renderer_deleteRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers) { + RSGL_renderer_deleteBuffer(renderer, buffers->elements); + RSGL_renderer_deleteBuffer(renderer, buffers->vertex); + RSGL_renderer_deleteBuffer(renderer, buffers->color); + RSGL_renderer_deleteBuffer(renderer, buffers->texture); +} + +void RSGL_renderer_createRenderBuffers(RSGL_renderer* renderer, size_t size, RSGL_renderBuffers* buffers) { + buffers->maxVerts = size; + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 3 * sizeof(float), NULL, &buffers->vertex); + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 4 * sizeof(float), NULL, &buffers->color); + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 2 * sizeof(float), NULL, &buffers->texture); + renderer->proc.createBuffer(renderer->ctx, RSGL_elementArrayBuffer, size * 6 * sizeof(u16), NULL, &buffers->elements); +} + +void RSGL_renderer_updateBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len) { + if (renderer->proc.updateBuffer) + renderer->proc.updateBuffer(renderer->ctx, type, buffer, data, start, len); +} + +void RSGL_renderer_deleteBuffer(RSGL_renderer* renderer, size_t buffer) { + if (renderer->proc.deleteBuffer) + renderer->proc.deleteBuffer(renderer->ctx, buffer); +} + +void RSGL_renderer_updateRenderBuffers(RSGL_renderer* renderer) { + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->vertex, renderer->data.verts, 0, renderer->data.len * 3 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->color, renderer->data.colors, 0, renderer->data.len * 4 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->texture, renderer->data.texCoords, 0, renderer->data.len * 2 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_elementArrayBuffer, renderer->state.buffers->elements, renderer->data.elements, 0, renderer->data.elements_count * sizeof(u16)); +} + +void RSGL_renderer_renderBuffers(RSGL_renderer* renderer) { + RSGL_mat4 matrix = RSGL_mat4_multiply(renderer->defaultPerspectiveMatrix.m, renderer->state.perspectiveMatrix.m); + matrix = RSGL_mat4_multiply(matrix.m, renderer->state.viewMatrix.m); + + + RSGL_renderPass pass; + pass.program = renderer->state.program; + pass.matrix = matrix.m; + pass.buffers = renderer->state.buffers; + pass.framebuffer = renderer->state.framebuffer; + + if (renderer->proc.render) + renderer->proc.render(renderer->ctx, &pass); + + renderer->data.len = 0; + renderer->data.elements_count = 0; +} + +void RSGL_renderer_render(RSGL_renderer* renderer) { + if (renderer->data.len && renderer->state.buffers->batchCount) { + RSGL_renderer_updateRenderBuffers(renderer); + } + + RSGL_renderer_renderBuffers(renderer); + + renderer->state.buffers->batchCount = 0; +} + +size_t RSGL_renderer_size(RSGL_renderer* renderer) { + if (renderer->proc.size) return renderer->proc.size(); + return 0; +} + +void RSGL_renderer_initPtr(RSGL_rendererProc proc, void* loader, void* data, RSGL_renderer* renderer) { + renderer->ctx = data; + renderer->proc = proc; + RSGL_renderer_clearArgs(renderer); + renderer->state.color = RSGL_RGBA(0, 0, 0, 255); + + renderer->state.modelMatrix = RSGL_mat4_loadIdentity(); + renderer->data.verts = renderer->verts; + renderer->data.texCoords = renderer->texCoords; + renderer->data.elements = renderer->elements; + renderer->data.colors = renderer->colors; + renderer->data.len = 0; + renderer->data.elements_count = 0; + + if (renderer->proc.initPtr) { + renderer->proc.initPtr(renderer->ctx, loader); + } + + RSGL_renderer_setFramebuffer(renderer, 0); + + RSGL_programBlob pBlob = RSGL_renderer_defaultBlob(renderer); + renderer->defaultProgram = RSGL_renderer_createProgram(renderer, &pBlob); + RSGL_renderer_setProgram(renderer, &renderer->defaultProgram); + + u8 white[4] = {255, 255, 255, 255}; + RSGL_textureBlob blob; + blob.data = white; + blob.width = 1; + blob.height = 1; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; + blob.textureFormat = RSGL_formatRGBA; + renderer->defaultTexture = RSGL_renderer_createTexture(renderer, &blob); + + RSGL_renderer_setTexture(renderer, renderer->defaultTexture); + + RSGL_renderer_createRenderBuffers(renderer, RSGL_MAX_VERTS, &renderer->buffers); + renderer->buffers.batchCount = 0; + renderer->state.buffers = &renderer->buffers; + + RSGL_renderer_setModelMatrix(renderer, RSGL_mat4_loadIdentity()); + RSGL_renderer_resetViewMatrix(renderer); + RSGL_renderer_setPerspectiveMatrix(renderer, RSGL_mat4_loadIdentity()); +} + + +RSGL_renderer* RSGL_renderer_init(RSGL_rendererProc proc, void* loader) { + RSGL_renderer* renderer = (RSGL_renderer*)RSGL_MALLOC(sizeof(RSGL_renderer)); + void* data = RSGL_MALLOC(proc.size()); + RSGL_renderer_initPtr(proc, loader, data, renderer); + return renderer; +} + +void RSGL_renderer_freePtr(RSGL_renderer* renderer) { + RSGL_renderer_deleteRenderBuffers(renderer, &renderer->buffers); + + if (renderer->proc.freePtr) + renderer->proc.freePtr(renderer->ctx); + + renderer->state.buffers->batchCount = 0; + renderer->data.len = 0; + renderer->data.elements_count = 0; +} + +void RSGL_renderer_free(RSGL_renderer* renderer) { + RSGL_renderer_freePtr(renderer); + if (renderer->ctx) + RSGL_FREE(renderer->ctx); + RSGL_FREE(renderer); +} + +void RSGL_renderer_clear(RSGL_renderer* renderer, RSGL_color color) { + if (renderer->proc.clear) + renderer->proc.clear(renderer->ctx, renderer->state.framebuffer, ((float)color.r) / 255.0f, ((float)color.g) / 255.0f, ((float)color.b) / 255.0f, ((float)color.a) / 255.0f); +} +void RSGL_renderer_viewport(RSGL_renderer* renderer, RSGL_rect rect) { renderer->proc.viewport(renderer->ctx, rect.x, rect.y, rect.w, rect.h); } +RSGL_texture RSGL_renderer_createTexture(RSGL_renderer* renderer, const RSGL_textureBlob* blob) { + RSGL_texture tex = 0; + if (renderer->proc.createTexture) tex = renderer->proc.createTexture(renderer->ctx, blob); + return tex; +} +void RSGL_renderer_copyToTexture(RSGL_renderer* renderer, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob) { + return renderer->proc.copyToTexture(renderer->ctx, texture, x, y, blob); +} +void RSGL_renderer_deleteTexture(RSGL_renderer* renderer, RSGL_texture tex) { renderer->proc.deleteTexture(renderer->ctx, tex); } +void RSGL_renderer_scissorStart(RSGL_renderer* renderer, RSGL_rect scissor, i32 height) { + renderer->proc.scissorStart(renderer->ctx, scissor.x, scissor.y, scissor.w, scissor.h, height); +} + +RSGL_framebuffer RSGL_renderer_createFramebuffer(RSGL_renderer* renderer, size_t width, size_t height) { + RSGL_framebuffer framebuffer = 0; + if (renderer->proc.createFramebuffer) { + framebuffer = renderer->proc.createFramebuffer(renderer->ctx, width, height); + } + return framebuffer; +} + +void RSGL_renderer_attachFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel) { + if (renderer->proc.attachFramebuffer) + renderer->proc.attachFramebuffer(renderer->ctx, fbo, tex, attachType, mipLevel); +} + +void RSGL_renderer_deleteFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo) { + if (renderer->proc.deleteFramebuffer) + renderer->proc.deleteFramebuffer(renderer->ctx, fbo); +} + +void RSGL_renderer_scissorEnd(RSGL_renderer* renderer) { + renderer->proc.scissorEnd(renderer->ctx); +} +RSGL_programBlob RSGL_renderer_defaultBlob(RSGL_renderer* renderer) { + RSGL_programBlob blob; + RSGL_MEMSET(&blob, 0, sizeof(blob)); + + if (renderer->proc.defaultBlob) { + blob = renderer->proc.defaultBlob(renderer); + } + + return blob; +} +RSGL_programInfo RSGL_renderer_createProgram(RSGL_renderer* renderer, RSGL_programBlob* blob) { + RSGL_programInfo info; + RSGL_MEMSET(&info, 0, sizeof(info)); + + if (blob->fragment == NULL || blob->vertex == NULL) { + RSGL_programBlob pBlob = RSGL_renderer_defaultBlob(renderer); + renderer->defaultProgram = RSGL_renderer_createProgram(renderer, &pBlob); + + if (blob->vertex == NULL) { + blob->vertex = pBlob.vertex; + blob->vertexLen = pBlob.vertexLen; + } + + if (blob->fragment == NULL) { + blob->fragment = pBlob.fragment; + blob->fragmentLen = pBlob.fragmentLen; + } + } + + if (renderer->proc.createProgram) { + info = renderer->proc.createProgram(renderer->ctx, blob); + } + + return info; +} +void RSGL_renderer_deleteProgram(RSGL_renderer* renderer, const RSGL_programInfo* program) { return renderer->proc.deleteProgram(renderer->ctx, program); } + +size_t RSGL_renderer_findShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, const char* var, size_t len) { + return renderer->proc.findShaderVariable(renderer->ctx, program, var, len); +} + +void RSGL_renderer_updateShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, size_t var, const float value[], u8 len) { + if (renderer->proc.updateShaderVariable) { + renderer->proc.updateShaderVariable(renderer->ctx, program, var, value, len); + } +} + +RSGL_programInfo RSGL_renderer_createComputeProgram(RSGL_renderer* renderer, const char* CShaderCode) { + return renderer->proc.createComputeProgram(renderer->ctx, CShaderCode); +} + +void RSGL_renderer_dispatchComputeProgram(RSGL_renderer* renderer, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z) { + renderer->proc.dispatchComputeProgram(renderer->ctx, program, groups_x, groups_y, groups_z); +} + +void RSGL_renderer_bindComputeTexture(RSGL_renderer* renderer, u32 texture, u8 format) { + renderer->proc.bindComputeTexture(renderer->ctx, texture, format); +} + +void RSGL_renderer_updateSize(RSGL_renderer* renderer, size_t width, size_t height) { + RSGL_projection projection; + projection.p2D.type = RSGL_projectionOrtho2D; + projection.p2D.width = width; + projection.p2D.height = height; + + RSGL_mat4 matrix = RSGL_projection_getMatrix(&projection); + RSGL_renderer_setDefaultPerspectiveMatrix(renderer, matrix); +} + +void RSGL_renderer_setRotate(RSGL_renderer* renderer, RSGL_vec3D rotate){ + renderer->state.rotate = RSGL_VEC3D(rotate.x * DEG2RAD, rotate.y * DEG2RAD, rotate.z * DEG2RAD); +} +void RSGL_renderer_setTexture(RSGL_renderer* renderer, RSGL_texture texture) { + if (texture == 0) + renderer->state.texture = renderer->defaultTexture; + else + renderer->state.texture = texture; + + renderer->state.source = RSGL_RECT(0, 0, 1, 1); +} + +void RSGL_renderer_setTextureSource(RSGL_renderer* renderer, RSGL_texture texture, RSGL_rect rect) { + RSGL_renderer_setTexture(renderer, texture); + renderer->state.source = rect; +} + +void RSGL_renderer_setColor(RSGL_renderer* renderer, RSGL_color color) { + renderer->state.color = color; +} + +void RSGL_renderer_setRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers) { + if (buffers == NULL) + renderer->state.buffers = &renderer->buffers; + else + renderer->state.buffers = buffers; +} + +void RSGL_renderer_setProgram(RSGL_renderer* renderer, RSGL_programInfo* program) { + if (program == NULL) + renderer->state.program = &renderer->defaultProgram; + else + renderer->state.program = program; +} + +void RSGL_renderer_setFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer framebuffer) { + renderer->state.framebuffer = framebuffer; +} + +void RSGL_renderer_setGradient(RSGL_renderer* renderer, float gradient[], size_t len) { + renderer->state.gradient_len = len; + renderer->state.gradient = gradient; +} +void RSGL_renderer_setCenter(RSGL_renderer* renderer, RSGL_vec3D center) { + renderer->state.center = center; +} + +RSGL_mat4 RSGL_renderer_initDrawMatrix(RSGL_renderer* renderer, RSGL_vec3D center) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + + if (renderer->state.rotate.x || renderer->state.rotate.y || renderer->state.rotate.z) { + if (renderer->state.center.x != -1 && renderer->state.center.y != -1 && renderer->state.center.z != -1) + center = renderer->state.center; + + matrix = RSGL_mat4_translate(matrix.m, center.x, center.y, center.z); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.z, 0, 0, 1); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.y, 0, 1, 0); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.x, 1, 0, 0); + matrix = RSGL_mat4_translate(matrix.m, -center.x, -center.y, -center.z); + } + + return matrix; +} + +void RSGL_renderer_clearArgs(RSGL_renderer* renderer) { + RSGL_MEMSET(&renderer->state, 0, sizeof(renderer->state)); + renderer->state.center = RSGL_VEC3D(-1, -1, -1); + renderer->state.overflow = RSGL_TRUE; +} + +/* +**** +RFont_RSGL integration +**** +*/ + +#ifdef RSGL_RFONT + +#ifndef RFONT_H + +#ifdef RSGL_INT_DEFINED + #ifndef RFONT_INT_DEFINED + #define RFONT_INT_DEFINED + #endif +#endif + +#include "RFont.h" +#endif + +struct RFont_renderer* RFont_RSGL_renderer_init(struct RSGL_renderer* ptr) { + RFont_renderer* renderer = (RFont_renderer*)RFONT_MALLOC(sizeof(RFont_renderer)); + RFont_renderer_initPtr(RFont_RSGL_renderer_proc(), ptr, renderer); + return renderer; +} +void RFont_RSGL_renderer_initPtr(struct RSGL_renderer* ptr, struct RFont_renderer* renderer) { RFont_renderer_initPtr(RFont_RSGL_renderer_proc(), ptr, renderer); } + +void RFont_RSGL_renderer_free(struct RFont_renderer* renderer) { + RFONT_FREE(renderer); +} + +void RFont_RSGL_render_text(RSGL_renderer* renderer, const RFont_render_data* src) { + RSGL_texture save = renderer->state.texture; + RSGL_renderer_setTexture(renderer, src->atlas); + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = src->verts; + data.texCoords = src->tcoords; + data.elements = src->elements; + data.elmCount = src->nelements; + data.vert_count = src->nverts; + i32 batch = RSGL_drawRawVerts(renderer, &data); + RSGL_UNUSED(batch); + + RSGL_renderer_setTexture(renderer, save); +} + +RFont_texture RFont_RSGL_createAtlas(RSGL_renderer* renderer, u32 atlasWidth, u32 atlasHeight) { + RSGL_textureBlob blob; + blob.data = NULL; + blob.width = atlasWidth; + blob.height = atlasWidth; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; //RSGL_formatRGBA; + blob.textureFormat = RSGL_formatRGBA;//RSGL_formatRGBA; + RFont_texture id = RSGL_renderer_createTexture(renderer, &blob); + return id; +} + +void RFont_RSGL_deleteAtlas(RSGL_renderer* renderer, RFont_texture atlas) { + RSGL_renderer_deleteTexture(renderer, atlas); +} + +void RFont_RSGL_bitmapToAtlas(RSGL_renderer* renderer, RFont_texture atlas, u32 atlasWidth, u32 atlasHeight, u32 maxHeight, u8* bitmap, float w, float h, float* x, float* y) { + RSGL_UNUSED(atlasHeight); + if (((*x) + w) >= atlasWidth) { + *x = 0; + *y += (float)maxHeight; + } + + RSGL_textureBlob blob; + blob.width = w; + blob.height = h; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; + blob.textureFormat = blob.dataFormat; + + u8* newBitmap = (u8*)RSGL_MALLOC(w * h * 4); + + for (size_t indexY = 0; indexY < (size_t)h; indexY++) { + for (size_t indexX = 0; indexX < (size_t)w; indexX++) { + size_t index = ((indexY * (size_t)w * 4) + indexX * 4); + size_t oIndex = ((indexY * (size_t)w) + indexX); + + u8 value = bitmap[oIndex]; + + newBitmap[index + 0] = value; + newBitmap[index + 1] = value; + newBitmap[index + 2] = value; + newBitmap[index + 3] = value; + } + } + + blob.data = newBitmap; + + RSGL_renderer_copyToTexture(renderer, atlas, (size_t)(*x), (size_t)(*y), &blob); + + RSGL_FREE(newBitmap); + + *x += w; +} + +void RFont_RSGL_setFrameBuffer(RSGL_renderer* renderer, u32 width, u32 height) { + RSGL_renderer_updateSize(renderer, width, height); +} + +void RFont_RSGL_setColor(RSGL_renderer* renderer, float r, float g, float b, float a) { + RSGL_renderer_setColor(renderer, RSGL_RGBA(r * 255.0f, g * 255.0f, b * 255.0f, a * 255.0f)); +} + +RFont_renderer_proc RFont_RSGL_renderer_proc(void) { + RFont_renderer_proc proc; + RSGL_MEMSET(&proc, 0, sizeof(proc)); + proc.create_atlas = (RFont_texture (*)(void* ctx, u32 atlasWidth, u32 atlasHeight))RFont_RSGL_createAtlas; + proc.free_atlas = (void (*)(void*, RSGL_texture))RFont_RSGL_deleteAtlas; + proc.bitmap_to_atlas = (void(*)(void*, RFont_texture, u32, u32, u32, u8*, float, float, float*, float*))RFont_RSGL_bitmapToAtlas; + proc.render = (void (*)(void*, const RFont_render_data* data))RFont_RSGL_render_text; + proc.set_framebuffer = (void (*)(void*, u32, u32))RFont_RSGL_setFrameBuffer; + proc.set_color = (void (*)(void*, float, float, float, float))RFont_RSGL_setColor; + return proc; +} + +#endif + +#if !defined(RSGL_NO_HIGHLEVEL) + +/* +**** +RSGL_draw +**** +*/ + +i32 RSGL_drawPoint(RSGL_renderer* renderer, RSGL_vec2D p) { + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, RSGL_VEC3D(p.x, p.y, 0.0f)); + + float points[] = {RSGL_GET_MATRIX_POINT((float)p.x, (float)p.y, 0.0f)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y }; + u16 elements[] = { 0 }; + + RSGL_rawVerts data; + data.type = RSGL_POINTS; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 1; + data.vert_count = 1; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawRect(RSGL_renderer* renderer, RSGL_rect r) { + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + }; + + RSGL_vec3D center = (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + RSGL_GET_MATRIX_POINT(r.x, r.y, 0.0f), + RSGL_GET_MATRIX_POINT(r.x, r.y + r.h, 0.0f), + RSGL_GET_MATRIX_POINT(r.x + r.w, r.y, 0.0f), + RSGL_GET_MATRIX_POINT(r.x + r.w, r.y + r.h, 0.0f), + }; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 4; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawRoundRect(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding) { + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x / 2), r.y, r.w - rounding.x, r.h)); + RSGL_drawRect(renderer, RSGL_RECT(r.x, r.y + (rounding.y / 2), r.w, r.h - rounding.y)); + + RSGL_drawArc(renderer, RSGL_RECT(r.x, r.y, rounding.x, rounding.y), (RSGL_vec2D){180, 270}); + RSGL_drawArc(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y, rounding.x, rounding.y), (RSGL_vec2D){90, 180}); + RSGL_drawArc(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y + (r.h - rounding.y), rounding.x, rounding.y), (RSGL_vec2D){0, 90}); + return RSGL_drawArc(renderer, RSGL_RECT(r.x, r.y + (r.h - rounding.y), rounding.x, rounding.y), (RSGL_vec2D){270, 360}); +} + +i32 RSGL_drawPolygonOutlineEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc); + +i32 RSGL_drawPolygonEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc) { + static float verts[360 * 3]; + static float texcoords[360 * 2]; + static u16 elements[360 * 6]; + + RSGL_vec3D center = (RSGL_vec3D){o.x + (o.w / 2.0f), o.y + (o.h / 2.0f), 0}; + + o = (RSGL_rect){o.x, o.y, o.w / 2, o.h / 2}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float displacement = 360.0f / (float)sides; + float angle = displacement * arc.x; + + size_t vIndex = 0; + size_t tIndex = 0; + size_t iIndex = 0; + + float texCenterX = (0.5 * (renderer->state.source.w)); + float texCenterY = (0.5 * (renderer->state.source.h)); + + RSGL_UNUSED(texCenterX); + RSGL_UNUSED(texCenterY); + + { + RSGL_vec2D p = {center.x, center.y}; + + texcoords[tIndex] = (renderer->state.source.x) + texCenterX; + texcoords[tIndex + 1] = (renderer->state.source.y) + texCenterY; + float temp[3] = { RSGL_GET_MATRIX_POINT(p.x, p.y, 0.0) }; + memcpy(verts + vIndex, temp, 3 * sizeof(float)); + + angle += displacement; + tIndex += 2; + vIndex += 3; + } + + u32 i; + for (i = 0; i < sides + 1; i++) { + RSGL_vec2D p = {RSGL_COS(angle * DEG2RAD), RSGL_SIN(angle * DEG2RAD)}; + + texcoords[tIndex] = ((p.x + 1.0f) * texCenterX) + (renderer->state.source.x) ; + texcoords[tIndex + 1] = ((p.y + 1.0f) * texCenterY) + (renderer->state.source.y); + + float temp[3] = { RSGL_GET_MATRIX_POINT(o.x + o.w + (p.x * o.w), o.y + o.h + (p.y * o.h), 0.0) }; + memcpy(&verts[vIndex], temp, 3 * sizeof(float)); + + elements[iIndex + 0] = i; + + if (i < sides) + elements[iIndex + 1] = i + 1; + else + elements[iIndex + 1] = 1; + + elements[iIndex + 2] = 0; + + angle += displacement; + tIndex += 2; + vIndex += 3; + iIndex += 3; + } + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = verts; + data.texCoords = texcoords; + data.elements = elements; + data.elmCount = iIndex; + data.vert_count = (vIndex / 3); + + i32 out = RSGL_drawRawVerts(renderer, &data); + return out; +} + +i32 RSGL_drawPolygon(RSGL_renderer* renderer, RSGL_rect o, u32 sides) { return RSGL_drawPolygonEx(renderer, o, sides, (RSGL_vec2D){0, (float)sides}); } + + +i32 RSGL_drawArc(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc) { + u32 verts = (u32)((float)((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10) + 0.5); + verts %= 360; + + return RSGL_drawPolygonEx(renderer, o, verts, arc); +} + +i32 RSGL_drawOval(RSGL_renderer* renderer, RSGL_rect o) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + return RSGL_drawPolygonEx(renderer, o, verts, (RSGL_vec2D){0, verts}); +} + +/* + 3D +*/ + +i32 RSGL_drawPoint3D(RSGL_renderer* renderer, RSGL_vec3D p) { + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, p); + + float points[] = {RSGL_GET_MATRIX_POINT((float)p.x, (float)p.y, (float)p.z)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y }; + u16 elements[] = { 0, }; + + RSGL_rawVerts data; + data.type = RSGL_POINTS; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 1; + data.vert_count = 1; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawLine3D(RSGL_renderer* renderer, RSGL_vec3D p1, RSGL_vec3D p2, u32 thickness) { + renderer->state.lineWidth = thickness; + + RSGL_vec3D center = {(p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f, (p1.z + p2.z) / 2.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(p1.x, p1.y, p1.z), RSGL_GET_MATRIX_POINT(p2.x, p2.y, p2.z)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y, renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h}; + u16 elements[] = { 0, 1 }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 4; + data.vert_count = 2; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawTriangle(RSGL_renderer* renderer, RSGL_vec3D t[3]) { + RSGL_vec3D center = {t[2].x, (t[2].y + t[0].y) / 2.0f, t[1].z}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y, t[0].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y, t[1].z), + RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z) + }; + + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + ((float)(t[2].x - t[0].x)/t[1].x < 1) ? (renderer->state.source.x + (float)(t[2].x - t[0].x) / t[1].x) : renderer->state.source.x, renderer->state.source.y, + }; + + u16 elements[] = { + 0, 1, 2, + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 3; + data.vert_count = 3; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawCube(RSGL_renderer* renderer, RSGL_cube cube) { + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + }; + + RSGL_vec3D center = { + cube.x + (cube.w / 2.0f), + cube.y + (cube.h / 2.0f), + cube.z + }; + + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + // Front face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + // Back face + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + // Left face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + // Right face + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + // Top face + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + // Bottom face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + }; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1, + + 4, 5, 6, + 7, 6, 5, + + 8, 9, 10, + 11, 10, 9, + + 12, 13, 14, + 15, 14, 13, + + 16, 17, 18, + 19, 18, 17, + + 20, 21, 22, + 23, 21, 22, + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = sizeof(elements) / sizeof(u16); + data.vert_count = sizeof(points) / sizeof(float) / 3; + + return RSGL_drawRawVerts(renderer, &data); +} + +/* +outlines +*/ + +i32 RSGL_drawLine(RSGL_renderer* renderer, RSGL_vec2D p1, RSGL_vec2D p2, u32 thickness) { + renderer->state.lineWidth = thickness; + + RSGL_vec3D center = {(p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f, 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(p1.x, p1.y, 0.0f), RSGL_GET_MATRIX_POINT(p2.x, p2.y, 0.0f)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y, renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h}; + + u16 elements[] = { 0, 1 }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 4; + data.vert_count = 2; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawTriangleOutline(RSGL_renderer* renderer, RSGL_vec3D t[3], u32 thickness) { + renderer->state.lineWidth = thickness; + RSGL_vec3D center = {t[2].x, (t[2].y + t[0].y) / 2.0f, 0}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z), + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y,t[0].z), + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y, t[0].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y,t[1].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y, t[1].z), + RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z)}; + + float texCoords[18]; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texCoords; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 6; + + return RSGL_drawRawVerts(renderer, &data); +} +i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness) { + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y}, (RSGL_vec2D){r.x + r.w, r.y}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y}, (RSGL_vec2D){r.x, r.y + r.h}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y + r.h}, (RSGL_vec2D){r.x + r.w, r.y + r.h}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + return RSGL_drawLine(renderer, (RSGL_vec2D){r.x + r.w, r.y}, (RSGL_vec2D){r.x + r.w, r.y + r.h}, thickness); +} +i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness) { + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x/2), r.y, r.w - rounding.x, (int)(thickness + !thickness))); + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x/2), r.y + r.h, r.w - rounding.x, (int)(thickness + !thickness))); + RSGL_drawRect(renderer, RSGL_RECT(r.x, r.y + (rounding.y/2), (int)(thickness + !thickness), r.h - rounding.y)); + RSGL_drawRect(renderer, RSGL_RECT(r.x + r.w, r.y + (rounding.y/2), (int)(thickness + !thickness), r.h - rounding.y)); + + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x, r.y, rounding.x, rounding.y), (RSGL_vec2D){180, 270}, thickness); + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y, rounding.x, rounding.y), (RSGL_vec2D){90, 180}, thickness); + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y + (r.h - rounding.y) - 1, rounding.x, rounding.y + 2), (RSGL_vec2D){0, 90}, thickness); + return RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + 1, r.y + (r.h - rounding.y) - 1, rounding.x, rounding.y + 2), (RSGL_vec2D){270, 360}, thickness); +} + +i32 RSGL_drawPolygonOutlineEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc) { + static float verts[360 * 2 * 3]; + static float texCoords[360 * 2 * 2]; + + RSGL_vec3D center = (RSGL_vec3D) {o.x + (o.w / 2.0f), o.y + (o.h / 2.0f), 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + o = (RSGL_rect){o.x + (o.w / 2), o.y + (o.h / 2), o.w / 2, o.h / 2}; + + float displacement = 360.0f / (float)sides; + float centralAngle = displacement * arc.x; + + i32 i; + u32 j; + size_t index = 0; + + for (i = arc.x; i < arc.y; i++) { + for (j = 0; j < 2; j++) { + float temp[3] = { + RSGL_GET_MATRIX_POINT( + o.x + (RSGL_SIN(DEG2RAD * centralAngle) * o.w), + o.y + (RSGL_COS(DEG2RAD * centralAngle) * o.h), + (0.0) + ) + }; + memcpy(verts + index, temp, sizeof(float) * 3); + + if (!j) centralAngle += displacement; + index += 3; + } + } + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = verts; + data.texCoords = texCoords; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 6; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect o, u32 sides, u32 thickness) { + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, sides, (RSGL_vec2D){0, (float)sides}); +} +i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, verts, arc); +} + +i32 RSGL_drawOvalOutline(RSGL_renderer* renderer, RSGL_rect o, u32 thickness) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, verts, (RSGL_vec2D){0, verts}); +} + +/* +****** +RSGL_view +****** +*/ + +/* Multiply the current matrix by a rotation matrix */ +RSGL_mat4 RSGL_projection_getMatrix(const RSGL_projection* projection) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + switch (projection->type) { + case RSGL_projectionPerspective3D: + matrix = RSGL_mat4_perspective(matrix.m, projection->p3D.fov, projection->p3D.ratio, projection->p3D.pNear, projection->p3D.pFar); + break; + case RSGL_projectionOrtho3D: { + double top = projection->p3D.fov / 2.0; + double right = top * projection->p3D.ratio; + + matrix = RSGL_mat4_ortho(matrix.m, -right, right, -top, top, projection->p3D.pNear, projection->p3D.pFar); + break; + } + case RSGL_projectionOrtho2D: + matrix = RSGL_mat4_ortho(matrix.m, 0, projection->p2D.width, projection->p2D.height, 0, 0, 1.0); + break; + default: break; + } + + return matrix; +} + + +RSGL_mat4 RSGL_view_getMatrix(const RSGL_view* view) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + switch (view->type) { + case RSGL_viewType2D: + matrix = RSGL_mat4_translate(matrix.m, -view->view2D.target.x, -view->view2D.target.y, -view->view2D.target.z); + matrix = RSGL_mat4_rotate(matrix.m, view->view2D.rotation, 0, 0, 1); + matrix = RSGL_mat4_scale(matrix.m, view->view2D.zoom, view->view2D.zoom, 1.0f); + matrix = RSGL_mat4_translate(matrix.m, view->view2D.offset.x, view->view2D.offset.y, view->view2D.offset.z); + break; + case RSGL_viewType3D: + matrix = RSGL_mat4_lookAt(matrix.m, view->view3D.pos.x, view->view3D.pos.y, view->view3D.pos.z, view->view3D.target.x, view->view3D.target.y, view->view3D.target.z, + view->view3D.up.x, view->view3D.up.y, view->view3D.up.z); + break; + default: break; + } + + return matrix; +} + +#endif + +/* +****** +RSGL_Matrix +****** +*/ + + +RSGL_mat4 RSGL_mat4_lookAt(float matrix[16], float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ) { + float matLookAt[16]; + + float length = 0.0f; + float ilength = 0.0f; + + RSGL_vec3D vz = { eyeX - targetX, eyeY - targetY, eyeZ - targetZ }; + + RSGL_vec3D v = vz; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vz.x *= ilength; + vz.y *= ilength; + vz.z *= ilength; + + RSGL_vec3D vx = { upY*vz.z - upZ*vz.y, upZ*vz.x - upX*vz.z, upX*vz.y - upY*vz.x }; + + v = vx; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vx.x *= ilength; + vx.y *= ilength; + vx.z *= ilength; + + RSGL_vec3D vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x }; + + matLookAt[0] = vx.x; + matLookAt[1] = vy.x; + matLookAt[2] = vz.x; + matLookAt[3] = 0.0f; + matLookAt[4] = vx.y; + matLookAt[5] = vy.y; + matLookAt[6] = vz.y; + matLookAt[7] = 0.0f; + matLookAt[8] = vx.z; + matLookAt[9] = vy.z; + matLookAt[10] = vz.z; + matLookAt[11] = 0.0f; + matLookAt[12] = -(vx.x*eyeX + vx.y*eyeY + vx.z*eyeZ); + matLookAt[13] = -(vy.x*eyeX + vy.y*eyeY + vy.z*eyeZ); + matLookAt[14] = -(vz.x*eyeX + vz.y*eyeY + vz.z*eyeZ); + matLookAt[15] = 1.0f; + + return RSGL_mat4_multiply(matrix, matLookAt); +} + +RSGL_mat4 RSGL_mat4_ortho(float matrix[16], float left, float right, float bottom, float top, float znear, float zfar) { + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(zfar - znear); + + float matOrtho[16] = { + (2.0f / rl), 0.0f, 0.0f, 0.0f, + 0.0f, (2.0f / tb), 0.0f, 0.00, + 0.0f, 0.0f, (-2.0f / fn), 0.0f, + (-((float)left + (float)right) / rl), -((float)top + (float)bottom)/tb, (-((float)zfar + (float)znear) / fn), 1.0f + }; + + return RSGL_mat4_multiply(matrix, matOrtho); +} + +RSGL_mat4 RSGL_mat4_scale(float matrix[16], float x, float y, float z) { + RSGL_mat4 result; + + for (int i = 0; i < 16; ++i) { + result.m[i] = matrix[i]; + } + + result.m[0] += matrix[0]*x + matrix[4]*y + matrix[8]*z; + result.m[13] += matrix[1]*x + matrix[5]*y + matrix[9]*z; + result.m[10] += matrix[2]*x + matrix[6]*y + matrix[10]*z; + result.m[11] += matrix[2] + matrix[6] + matrix[10]; + + return result; +} + + + +/* Multiply the current matrix by a translation matrix */ +RSGL_mat4 RSGL_mat4_translate(float matrix[16], float x, float y, float z) { + RSGL_mat4 result; + + for (int i = 0; i < 16; ++i) { + result.m[i] = matrix[i]; + } + + result.m[12] += matrix[0]*x + matrix[4]*y + matrix[8]*z; + result.m[13] += matrix[1]*x + matrix[5]*y + matrix[9]*z; + result.m[14] += matrix[2]*x + matrix[6]*y + matrix[10]*z; + + return result; +} + +RSGL_mat4 RSGL_mat4_loadIdentity(void) { + RSGL_mat4 matrix = (RSGL_mat4) { + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } + }; + + return matrix; +} + +RSGL_mat4 RSGL_mat4_rotate(float matrix[16], float angle, float x, float y, float z) { + /* Axis vector (x, y, z) normalization */ + float lengthSquared = x * x + y * y + z * z; + if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) { + float inverseLength = 1.0f / sqrtf(lengthSquared); + x *= inverseLength; + y *= inverseLength; + z *= inverseLength; + } + + /* Rotation matrix generation */ + float sinres = RSGL_SIN(angle); + float cosres = RSGL_COS(angle); + float t = 1.0f - cosres; + + float matRotation[16] = { + x * x * t + cosres, y * x * t + z * sinres, z * x * t - y * sinres, 0.0f, + x * y * t - z * sinres, y * y * t + cosres, z * y * t + x * sinres, 0.0f, + x * z * t + y * sinres, y * z * t - x * sinres, z * z * t + cosres, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + return RSGL_mat4_multiply(matRotation, matrix); +} + +RSGL_mat4 RSGL_mat4_perspective(float matrix[16], float fovY, float aspect, float zNear, float zFar) { + fovY = (fovY * DEG2RAD) / 2.0f; + const float f = (RSGL_COS(fovY) / RSGL_SIN(fovY)); + + float perspective[16] = { + (f / aspect), 0.0f, 0.0f, 0.0f, + 0, f, 0.0f, 0.0f, + 0.0f, 0.0f, (zFar + zNear) / (zNear - zFar), -1.0f, + 0.0f, 0.0f, (2.0f * zFar * zNear) / (zNear - zFar), 0.0f + }; + + return RSGL_mat4_multiply(matrix, perspective); +} + +RSGL_vec3D RSGL_mat4_multiplyPoint(RSGL_mat4 matrix, RSGL_vec3D point) { + return (RSGL_vec3D){RSGL_GET_MATRIX_POINT(point.x, point.y, point.z)}; +} + +RSGL_mat4 RSGL_mat4_multiply(float left[16], float right[16]) { + return (RSGL_mat4) { + { + left[0] * right[0] + left[1] * right[4] + left[2] * right[8] + left[3] * right[12], + left[0] * right[1] + left[1] * right[5] + left[2] * right[9] + left[3] * right[13], + left[0] * right[2] + left[1] * right[6] + left[2] * right[10] + left[3] * right[14], + left[0] * right[3] + left[1] * right[7] + left[2] * right[11] + left[3] * right[15], + left[4] * right[0] + left[5] * right[4] + left[6] * right[8] + left[7] * right[12], + left[4] * right[1] + left[5] * right[5] + left[6] * right[9] + left[7] * right[13], + left[4] * right[2] + left[5] * right[6] + left[6] * right[10] + left[7] * right[14], + left[4] * right[3] + left[5] * right[7] + left[6] * right[11] + left[7] * right[15], + left[8] * right[0] + left[9] * right[4] + left[10] * right[8] + left[11] * right[12], + left[8] * right[1] + left[9] * right[5] + left[10] * right[9] + left[11] * right[13], + left[8] * right[2] + left[9] * right[6] + left[10] * right[10] + left[11] * right[14], + left[8] * right[3] + left[9] * right[7] + left[10] * right[11] + left[11] * right[15], + left[12] * right[0] + left[13] * right[4] + left[14] * right[8] + left[15] * right[12], + left[12] * right[1] + left[13] * right[5] + left[14] * right[9] + left[15] * right[13], + left[12] * right[2] + left[13] * right[6] + left[14] * right[10] + left[15] * right[14], + left[12] * right[3] + left[13] * right[7] + left[14] * right[11] + left[15] * right[15] + } + }; +} +#endif /* RSGL_IMPLEMENTATION */ diff --git a/include/RSGL_gl.h b/include/RSGL_gl.h new file mode 100644 index 0000000..b1d1d05 --- /dev/null +++ b/include/RSGL_gl.h @@ -0,0 +1,1013 @@ +#ifndef RSGL_H
+#include "RSGL.h"
+#endif
+
+// WebGL doesn't support compute shaders iirc so yeah
+#if defined(__EMSCRIPTEN__) && defined(RSGL_USE_COMPUTE)
+#undef RSGL_USE_COMPUTE
+#endif
+
+#ifdef __EMSCRIPTEN__
+ #if defined(RSGL_GL2)
+ #undef RSGL_GL2
+ #define RSGL_GLES2
+ #endif
+ #if defined(RSGL_GL3)
+ #undef RSGL_GL3
+ #define RSGL_GLES3
+ #endif
+#endif
+
+
+#if !defined(RSGL_GLES3) && !defined(RSGL_GLES2) && !defined(RSGL_GL2) && !defined(RSGL_GL3)
+ #ifndef __EMSCRIPTEN__
+ #define RSGL_GL3
+ #else
+ #define RSGL_GLES3
+ #endif
+#endif
+
+#if defined(RSGL_GLES3) || defined(RSGL_GLES2)
+ #ifndef RSGL_NO_GL_LOADER
+ #define RSGL_NO_GL_LOADER
+ #endif
+#endif
+
+#ifndef RSGL_GL_H
+#define RSGL_GL_H
+
+typedef struct RSGL_glRenderer {
+ u32 vao;
+} RSGL_glRenderer;
+
+RSGLDEF RSGL_rendererProc RSGL_GL_rendererProc(void);
+RSGLDEF size_t RSGL_GL_size(void);
+
+RSGLDEF RSGL_renderer* RSGL_GL_renderer_init(void* loader);
+RSGLDEF void RSGL_GL_renderer_initPtr(void* loader, RSGL_glRenderer* ptr, RSGL_renderer* renderer);
+RSGLDEF void RSGL_GL_render(RSGL_glRenderer* ctx, const RSGL_renderPass* pass);
+RSGLDEF void RSGL_GL_initPtr(RSGL_glRenderer* ctx, void* proc); /* init render backend */
+RSGLDEF void RSGL_GL_freePtr(RSGL_glRenderer* ctx); /* free render backend */
+RSGLDEF void RSGL_GL_clear(RSGL_glRenderer* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a);
+RSGLDEF void RSGL_GL_viewport(RSGL_glRenderer* ctx, i32 x, i32 y, i32 w, i32 h);
+RSGLDEF void RSGL_GL_createBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer);
+RSGLDEF void RSGL_GL_updateBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t buffer, const void* data, size_t start, size_t end);
+RSGLDEF void RSGL_GL_deleteBuffer(RSGL_glRenderer* ctx, size_t buffer);
+RSGLDEF RSGL_programBlob RSGL_GL_defaultBlob(RSGL_glRenderer* ctx);
+/* create a texture based on a given bitmap, this must be freed later using RSGL_deleteTexture or opengl*/
+RSGLDEF RSGL_texture RSGL_GL_createTexture(RSGL_glRenderer* ctx, const RSGL_textureBlob* blob);
+/* updates an existing texture wiht a new bitmap */
+RSGLDEF void RSGL_GL_copyToTexture(RSGL_glRenderer* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob);
+/* delete a texture */
+RSGLDEF void RSGL_GL_deleteTexture(RSGL_glRenderer* ctx, RSGL_texture tex);
+/* starts scissoring */
+RSGLDEF void RSGL_GL_scissorStart(RSGL_glRenderer* ctx, float x, float y, float w, float h, float renderer_height);
+/* stops scissoring */
+RSGLDEF void RSGL_GL_scissorEnd(RSGL_glRenderer* ctx);
+/* program loading */
+RSGLDEF RSGL_programInfo RSGL_GL_createProgram(RSGL_glRenderer* ctx, RSGL_programBlob* blob);
+RSGLDEF void RSGL_GL_deleteProgram(RSGL_glRenderer* ctx, const RSGL_programInfo* program);
+RSGLDEF size_t RSGL_GL_findShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len);
+RSGLDEF void RSGL_GL_updateShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, size_t var, const float value[], u8 len);
+
+RSGLDEF RSGL_framebuffer RSGL_GL_createFramebuffer(RSGL_glRenderer* renderer, size_t width, size_t height);
+RSGLDEF void RSGL_GL_attachFramebuffer(RSGL_glRenderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel);
+RSGLDEF void RSGL_GL_deleteFramebuffer(RSGL_glRenderer* renderer, RSGL_framebuffer fbo);
+
+#ifdef RSGL_USE_COMPUTE
+RSGLDEF RSGL_programInfo RSGL_GL_createComputeProgram(RSGL_glRenderer* ctx, const char* CShaderCode);
+RSGLDEF void RSGL_GL_dispatchComputeProgram(RSGL_glRenderer* ctx, RSGL_programInfo program, u32 groups_x, u32 groups_y, u32 groups_z);
+RSGLDEF void RSGL_GL_bindComputeTexture(RSGL_glRenderer* ctx, u32 texture, u8 format);
+#endif
+#endif
+
+#ifdef RSGL_IMPLEMENTATION
+
+RSGL_renderer* RSGL_GL_renderer_init(void* loader) { return RSGL_renderer_init(RSGL_GL_rendererProc(), loader); }
+void RSGL_GL_renderer_initPtr(void* loader, RSGL_glRenderer* ptr, RSGL_renderer* renderer) { return RSGL_renderer_initPtr(RSGL_GL_rendererProc(), loader, ptr, renderer); }
+
+
+/* prevent winapi conflicts (opengl includes windows.h for some reason) */
+#define OEMRESOURCE
+
+#define GL_GLEXT_PROTOTYPES
+
+#ifndef __APPLE__
+#include <GL/gl.h>
+#else
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif
+
+#if defined(RSGL_GLES3)
+ #include <GLES3/gl3.h>
+#elif defined(RSGL_GLES2)
+ #include <GLES2/gl2.h>
+#endif
+
+#if defined(_WIN32)
+typedef char GLchar;
+typedef int GLsizei;
+#include <GL/glext.h>
+#endif
+
+#ifndef RSGL_NO_GL_LOADER
+
+typedef void (*RSGL_gl_proc)(void); // function pointer equivalent of void*
+#define RSGL_PROC_DEF(proc, name) name##SRC = (name##PROC)(RSGL_gl_proc)proc(#name)
+
+typedef void (*RSGLapiproc)(void);
+typedef RSGLapiproc (*RSGLloadfunc)(const char *name);
+
+typedef void (*glShaderSourcePROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef GLuint (*glCreateShaderPROC) (GLenum type);
+typedef void (*glCompileShaderPROC) (GLuint shader);
+typedef GLuint (*glCreateProgramPROC) (void);
+typedef void (*glAttachShaderPROC) (GLuint program, GLuint shader);
+typedef void (*glBindAttribLocationPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (*glLinkProgramPROC) (GLuint program);
+typedef void (*glBindBufferPROC) (GLenum target, GLuint buffer);
+typedef void (*glBufferDataPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (*glEnableVertexAttribArrayPROC) (GLuint index);
+typedef void (*glVertexAttribPointerPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (*glDisableVertexAttribArrayPROC) (GLuint index);
+typedef void (*glDeleteBuffersPROC) (GLsizei n, const GLuint *buffers);
+typedef void (*glUseProgramPROC) (GLuint program);
+typedef void (*glDetachShaderPROC) (GLuint program, GLuint shader);
+typedef void (*glDeleteShaderPROC) (GLuint shader);
+typedef void (*glDeleteProgramPROC) (GLuint program);
+typedef void (*glBufferSubDataPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (*glGetShaderivPROC)(GLuint shader, GLenum pname, GLint *params);
+typedef void (*glGetShaderInfoLogPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (*glGetProgramivPROC)(GLuint program, GLenum pname, GLint *params);
+typedef void (*glGetProgramInfoLogPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (*glGenBuffersPROC)(GLsizei n, GLuint *buffers);
+typedef GLint (*glGetUniformLocationPROC)(GLuint program, const GLchar *name);
+typedef GLint (*glGetAttribLocationPROC)(GLuint program, const GLchar *name);
+typedef void (*glUniformMatrix4fvPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (*glTexImage2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (*glActiveTexturePROC) (GLenum texture);
+typedef void (*glUniform1fPROC) (GLint location, GLfloat v0);
+typedef void (*glUniform2fPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (*glUniform3fPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (*glUniform4fPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ typedef void (*glGenVertexArraysPROC)(GLsizei n, GLuint *arrays);
+ typedef void (*glBindVertexArrayPROC)(GLuint array);
+ typedef void (*glDeleteVertexArraysPROC) (GLsizei n, const GLuint *arrays);
+
+ glGenVertexArraysPROC glGenVertexArraysSRC = NULL;
+ glBindVertexArrayPROC glBindVertexArraySRC = NULL;
+ glDeleteVertexArraysPROC glDeleteVertexArraysSRC = NULL;
+#endif
+
+glShaderSourcePROC glShaderSourceSRC = NULL;
+glCreateShaderPROC glCreateShaderSRC = NULL;
+glCompileShaderPROC glCompileShaderSRC = NULL;
+glCreateProgramPROC glCreateProgramSRC = NULL;
+glAttachShaderPROC glAttachShaderSRC = NULL;
+glBindAttribLocationPROC glBindAttribLocationSRC = NULL;
+glLinkProgramPROC glLinkProgramSRC = NULL;
+glBindBufferPROC glBindBufferSRC = NULL;
+glBufferDataPROC glBufferDataSRC = NULL;
+glEnableVertexAttribArrayPROC glEnableVertexAttribArraySRC = NULL;
+glVertexAttribPointerPROC glVertexAttribPointerSRC = NULL;
+glDisableVertexAttribArrayPROC glDisableVertexAttribArraySRC = NULL;
+glDeleteBuffersPROC glDeleteBuffersSRC = NULL;
+glUseProgramPROC glUseProgramSRC = NULL;
+glDetachShaderPROC glDetachShaderSRC = NULL;
+glDeleteShaderPROC glDeleteShaderSRC = NULL;
+glDeleteProgramPROC glDeleteProgramSRC = NULL;
+glBufferSubDataPROC glBufferSubDataSRC = NULL;
+glGetShaderivPROC glGetShaderivSRC = NULL;
+glGetShaderInfoLogPROC glGetShaderInfoLogSRC = NULL;
+glGetProgramivPROC glGetProgramivSRC = NULL;
+glGetProgramInfoLogPROC glGetProgramInfoLogSRC = NULL;
+glGenBuffersPROC glGenBuffersSRC = NULL;
+glGetUniformLocationPROC glGetUniformLocationSRC = NULL;
+glGetAttribLocationPROC glGetAttribLocationSRC = NULL;
+glUniformMatrix4fvPROC glUniformMatrix4fvSRC = NULL;
+glActiveTexturePROC glActiveTextureSRC = NULL;
+glUniform1fPROC glUniform1fSRC = NULL;
+glUniform2fPROC glUniform2fSRC = NULL;
+glUniform3fPROC glUniform3fSRC = NULL;
+glUniform4fPROC glUniform4fSRC = NULL;
+
+typedef void (*glBindFramebufferPROC) (GLenum target, GLuint framebuffer);
+typedef void (*glGenFramebuffersPROC) (GLsizei n, GLuint *ids);
+typedef void (*glDeleteFramebuffersPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (*glFramebufferTexture2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+
+#ifdef RSGL_USE_COMPUTE
+typedef void (*glDispatchComputePROC)(GLuint x, GLuint y, GLuint z);
+glDispatchComputePROC glDispatchComputeSRC = NULL;
+
+typedef void (*glMemoryBarrierPROC)(GLenum e);
+glMemoryBarrierPROC glMemoryBarrierSRC = NULL;
+
+typedef void (*glBindImageTexturePROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+glBindImageTexturePROC glBindImageTextureSRC = NULL;
+
+#endif
+
+glBindFramebufferPROC glBindFramebufferSRC = NULL;
+glGenFramebuffersPROC glGenFramebuffersSRC = NULL;
+glDeleteFramebuffersPROC glDeleteFramebuffersSRC = NULL;
+glFramebufferTexture2DPROC glFramebufferTexture2DSRC = NULL;
+
+#define glUniform1f glUniform1fSRC
+#define glUniform2f glUniform2fSRC
+#define glUniform3f glUniform3fSRC
+#define glUniform4f glUniform4fSRC
+#define glActiveTexture glActiveTextureSRC
+#define glShaderSource glShaderSourceSRC
+#define glCreateShader glCreateShaderSRC
+#define glCompileShader glCompileShaderSRC
+#define glCreateProgram glCreateProgramSRC
+#define glAttachShader glAttachShaderSRC
+#define glBindAttribLocation glBindAttribLocationSRC
+#define glLinkProgram glLinkProgramSRC
+#define glBindBuffer glBindBufferSRC
+#define glBufferData glBufferDataSRC
+#define glEnableVertexAttribArray glEnableVertexAttribArraySRC
+#define glVertexAttribPointer glVertexAttribPointerSRC
+#define glDisableVertexAttribArray glDisableVertexAttribArraySRC
+#define glDeleteBuffers glDeleteBuffersSRC
+#define glUseProgram glUseProgramSRC
+#define glDetachShader glDetachShaderSRC
+#define glDeleteShader glDeleteShaderSRC
+#define glDeleteProgram glDeleteProgramSRC
+#define glBufferSubData glBufferSubDataSRC
+#define glGetShaderiv glGetShaderivSRC
+#define glGetShaderInfoLog glGetShaderInfoLogSRC
+#define glGetProgramiv glGetProgramivSRC
+#define glGetProgramInfoLog glGetProgramInfoLogSRC
+#define glGenBuffers glGenBuffersSRC
+#define glGetUniformLocation glGetUniformLocationSRC
+#define glGetAttribLocation glGetAttribLocationSRC
+#define glUniformMatrix4fv glUniformMatrix4fvSRC
+#define glBindFramebuffer glBindFramebufferSRC
+#define glGenFramebuffers glGenFramebuffersSRC
+#define glDeleteFramebuffers glDeleteFramebuffersSRC
+#define glFramebufferTexture2D glFramebufferTexture2DSRC
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ #define glGenVertexArrays glGenVertexArraysSRC
+ #define glBindVertexArray glBindVertexArraySRC
+ #define glDeleteVertexArrays glDeleteVertexArraysSRC
+#endif
+
+#ifdef RSGL_USE_COMPUTE
+#define glMemoryBarrier glMemoryBarrierSRC
+#define glDispatchCompute glDispatchComputeSRC
+#define glBindImageTexture glBindImageTextureSRC
+#endif
+
+#ifndef GL_TEXTURE_SWIZZLE_RGBA
+ #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+extern int RSGL_loadGLModern(RSGLloadfunc proc);
+#endif
+
+#define RSGL_MULTILINE_STR(...) #__VA_ARGS__
+size_t RSGL_GL_size(void) {
+ return sizeof(RSGL_glRenderer);
+}
+
+RSGL_rendererProc RSGL_GL_rendererProc() {
+ RSGL_rendererProc proc;
+ RSGL_MEMSET(&proc, 0, sizeof(proc));
+
+ proc.render = (void (*)(void*, const RSGL_renderPass* pass))RSGL_GL_render;
+ proc.size = (size_t (*)(void))RSGL_GL_size;
+ proc.initPtr = (void (*)(void*, void*))RSGL_GL_initPtr;
+ proc.freePtr = (void (*)(void*))RSGL_GL_freePtr;
+ proc.clear = (void (*)(void*, RSGL_framebuffer, float, float, float, float))RSGL_GL_clear;
+ proc.viewport = (void (*)(void*, i32, i32, i32, i32))RSGL_GL_viewport;
+ proc.createTexture = (RSGL_texture (*)(void*, const RSGL_textureBlob* blob))RSGL_GL_createTexture;
+ proc.copyToTexture = (void (*)(void*, RSGL_texture, size_t, size_t, const RSGL_textureBlob* blob))RSGL_GL_copyToTexture;
+ proc.deleteTexture = (void (*)(void*, RSGL_texture))RSGL_GL_deleteTexture;
+ proc.scissorStart = (void (*)(void*, float, float, float, float, float))RSGL_GL_scissorStart;
+ proc.scissorEnd = (void (*)(void*))RSGL_GL_scissorEnd;
+ proc.createProgram = (RSGL_programInfo (*)(void*, RSGL_programBlob* blob))RSGL_GL_createProgram;
+ proc.deleteProgram = (void (*)(void*, const RSGL_programInfo*))RSGL_GL_deleteProgram;
+ proc.findShaderVariable = (size_t (*)(void*, const RSGL_programInfo*, const char*, size_t))RSGL_GL_findShaderVariable;
+ proc.updateShaderVariable = (void (*)(void*, const RSGL_programInfo*, size_t, const float[], u8))RSGL_GL_updateShaderVariable;
+ proc.createBuffer = (void (*)(void*, RSGL_bufferType, size_t, const void*, size_t*))RSGL_GL_createBuffer;
+ proc.updateBuffer = (void (*)(void*, RSGL_bufferType, size_t, void*, size_t, size_t))RSGL_GL_updateBuffer;
+ proc.deleteBuffer = (void (*)(void*, size_t))RSGL_GL_deleteBuffer;
+ proc.defaultBlob = (RSGL_programBlob (*)(void*))RSGL_GL_defaultBlob;
+ proc.createFramebuffer = (RSGL_framebuffer (*)(void*, size_t, size_t))RSGL_GL_createFramebuffer;
+ proc.attachFramebuffer = (void (*)(void*, RSGL_framebuffer, RSGL_texture, u8, u8))RSGL_GL_attachFramebuffer;
+ proc.deleteFramebuffer = (void (*)(void*, RSGL_framebuffer))RSGL_GL_deleteFramebuffer;
+
+
+// proc.setSurface = (void (*)(void*, void*))RSGL_GL_setSurface;
+#ifdef RSGL_USE_COMPUTE
+ proc.createComputeProgram = (RSGL_programInfo (*)(void*, const char*))RSGL_GL_createComputeProgram;
+ proc.dispatchComputeProgram = (void (*)(void*, const RSGL_programInfo*, u32, u32, u32))RSGL_GL_dispatchComputeProgram;
+ proc.bindComputeTexture = (void (*)(void*, u32, u8))RSGL_GL_bindComputeTexture;
+#else
+ proc.createComputeProgram = NULL;
+ proc.dispatchComputeProgram = NULL;
+ proc.bindComputeTexture = NULL;
+#endif
+ return proc;
+}
+
+void RSGL_GL_deleteTexture(RSGL_glRenderer* ctx, RSGL_texture tex) { glDeleteTextures(1, (u32*)&tex); }
+void RSGL_GL_viewport(RSGL_glRenderer* ctx, i32 x, i32 y, i32 w, i32 h) { glViewport(x, y, w ,h); }
+
+void RSGL_GL_clear(RSGL_glRenderer* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a) {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+ glClearColor(r, g, b, a);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+GLuint RSGL_GL_bufferTypeToNative(RSGL_bufferType type) {
+ switch (type) {
+ case RSGL_arrayBuffer: return GL_ARRAY_BUFFER;
+ case RSGL_elementArrayBuffer: return GL_ELEMENT_ARRAY_BUFFER;
+ #if !defined(__APPLE__)
+ case RSGL_shaderStorageBuffer: return GL_SHADER_STORAGE_BUFFER;
+ #endif
+ #if !defined(__APPLE__) || defined(RSGL_GLES3)
+ case RSGL_textureBuffer: return GL_TEXTURE_BUFFER;
+ case RSGL_uniformBuffer: return GL_UNIFORM_BUFFER;
+ #endif
+ default: break;
+ }
+
+ return GL_ARRAY_BUFFER;
+}
+
+void RSGL_GL_createBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer) {
+ glGenBuffers(1, (u32*)buffer);
+
+ GLenum usage = GL_STATIC_DRAW;
+ if (data == NULL)
+ usage = GL_DYNAMIC_DRAW;
+
+ glBindBuffer(RSGL_GL_bufferTypeToNative(type), *(u32*)buffer);
+ glBufferData(RSGL_GL_bufferTypeToNative(type), size, data, usage);
+}
+
+void RSGL_GL_updateBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t buffer, const void* data, size_t start, size_t end) {
+ glBindBuffer(RSGL_GL_bufferTypeToNative(type), *(u32*)&buffer);
+ glBufferSubData(RSGL_GL_bufferTypeToNative(type), start, end, data);
+}
+
+void RSGL_GL_deleteBuffer(RSGL_glRenderer* ctx, size_t buffer) {
+ glDeleteBuffers(1, (u32*)&buffer);
+}
+
+RSGL_programBlob RSGL_GL_defaultBlob(RSGL_glRenderer* ctx) {
+#ifdef RSGL_GL3
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 330 \n
+ in vec3 vertexPosition; \n
+ in vec2 vertexTexCoord; \n
+ in vec4 vertexColor; \n
+ out vec2 fragTexCoord; \n
+ out vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 330 \n
+ in vec2 fragTexCoord;
+ in vec4 fragColor;
+ out vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ finalColor = texture(texture0, fragTexCoord) * fragColor;
+ }
+ );
+
+#elif defined(RSGL_GLES3)
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 300 es \n
+ in vec3 vertexPosition; \n
+ in vec2 vertexTexCoord; \n
+ in vec4 vertexColor; \n
+ out vec2 fragTexCoord; \n
+ out vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 300 es \n
+ precision mediump float; \n
+ in vec2 fragTexCoord;
+ in vec4 fragColor;
+ out vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ finalColor = texture(texture0, fragTexCoord) * fragColor;
+ }
+ );
+
+#elif defined(RSGL_GLES2) || defined(RSGL_GL2)
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 100 \n
+ attribute vec3 vertexPosition; \n
+ attribute vec2 vertexTexCoord; \n
+ attribute vec4 vertexColor; \n
+ varying vec2 fragTexCoord; \n
+ varying vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 100 \n
+ precision mediump float; \n
+ varying vec2 fragTexCoord; \n
+ varying vec4 fragColor; \n
+ vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ gl_FragColor= texture2D(texture0, fragTexCoord) * fragColor;
+ }
+ );
+#endif
+
+ RSGL_programBlob blob;
+ blob.vertex = defaultVShaderCode;
+ blob.vertexLen = sizeof(defaultVShaderCode);
+ blob.fragment = defaultFShaderCode;
+ blob.fragmentLen = sizeof(defaultFShaderCode );
+
+ return blob;
+}
+
+/*
+print matrix array code snippet
+ for (size_t iy = 0; iy < 4; iy++) {
+ for (size_t ix = 0; ix < 4; ix++) {
+ printf("%f, ", matrix[(iy * 4) + ix]);
+ }
+ printf("\n");
+ }
+
+ printf("\n\n");
+*/
+
+
+
+void RSGL_GL_initPtr(RSGL_glRenderer* ctx, void* proc) {
+ #if !defined(__EMSCRIPTEN__) && !defined(RSGL_NO_GL_LOADER)
+ if (RSGL_loadGLModern((RSGLloadfunc)proc)) {
+ #ifdef RSGL_DEBUG
+ printf("Failed to load an OpenGL 3.3 Context, reverting to OpenGL Legacy\n");
+ #endif
+ return;
+ }
+ #else
+ RSGL_UNUSED(proc);
+ #endif
+
+#ifdef RSGL_DEBUG
+ printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
+ printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
+ printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
+ printf("GLSL Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
+#endif
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glGenVertexArrays(1, &ctx->vao);
+#endif
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+void RSGL_GL_freePtr(RSGL_glRenderer* ctx) {
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glDeleteVertexArrays(0, &ctx->vao);
+#endif
+}
+
+void RSGL_GL_render(RSGL_glRenderer* ctx, const RSGL_renderPass* pass) {
+ glBindFramebuffer(GL_FRAMEBUFFER, pass->framebuffer);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glBindVertexArray(ctx->vao);
+#endif
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->vertex);
+ glEnableVertexAttribArray(pass->program->vertexPosition);
+ glVertexAttribPointer(pass->program->vertexPosition, 3, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->texture);
+ glEnableVertexAttribArray(pass->program->vertexTexCoord);
+ glVertexAttribPointer(pass->program->vertexTexCoord, 2, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->color);
+ glEnableVertexAttribArray(pass->program->vertexColor);
+ glVertexAttribPointer(pass->program->vertexColor, 4, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pass->buffers->elements);
+
+ glUseProgram(pass->program->program);
+ glUniformMatrix4fv(pass->program->perspectiveView, 1, GL_FALSE, pass->matrix);
+
+ u32 i;
+ for (i = 0; i < pass->buffers->batchCount; i++) {
+ GLenum mode = GL_TRIANGLES;
+ glBindTexture(GL_TEXTURE_2D, pass->buffers->batches[i].tex);
+
+ if (pass->buffers->batches[i].lineWidth)
+ glLineWidth(pass->buffers->batches[i].lineWidth);
+
+ glUniformMatrix4fv(pass->program->model, 1, GL_FALSE, pass->buffers->batches[i].matrix.m);
+
+ switch (pass->buffers->batches[i].type) {
+ case RSGL_TRIANGLES: mode = GL_TRIANGLES; break;
+ case RSGL_POINTS: mode = GL_POINTS; break;
+ case RSGL_LINES: mode = GL_LINES; break;
+ default: break;
+ }
+
+ glDrawElements(mode, (i32)pass->buffers->batches[i].elmCount, GL_UNSIGNED_SHORT, (void*)(pass->buffers->batches[i].elmStart * sizeof(u16)));
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glUseProgram(0);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glBindVertexArray(0);
+#endif
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void RSGL_GL_scissorStart(RSGL_glRenderer* ctx, float x, float y, float w, float h, float renderer_height) {
+ glEnable(GL_SCISSOR_TEST);
+
+ glScissor(x, renderer_height - (y + h), w, h);
+}
+
+void RSGL_GL_scissorEnd(RSGL_glRenderer* ctx) {
+ glDisable(GL_SCISSOR_TEST);
+}
+
+GLuint RSGL_GL_textureFormatToNative(RSGL_textureFormat format) {
+ switch (format) {
+ case RSGL_formatRGB: return GL_RGB;
+ case RSGL_formatBGR: return GL_BGR;
+ case RSGL_formatRGBA: return GL_RGBA;
+ case RSGL_formatBGRA: return GL_BGRA;
+ case RSGL_formatRed: return GL_RED;
+ case RSGL_formatGrayscale: return GL_RED;
+ case RSGL_formatGrayscaleAlpha: return GL_RED;
+ default: break;
+ }
+
+ return GL_RGBA;
+}
+
+GLuint RSGL_GL_textureDataTypeToNative(RSGL_textureDataType type) {
+ switch (type) {
+ case RSGL_textureDataInt: return GL_UNSIGNED_BYTE;
+ case RSGL_textureDataFloat: return GL_FLOAT;
+ default: break;
+ }
+
+ return GL_UNSIGNED_BYTE;
+}
+
+GLuint RSGL_GL_textureFilterToNative(RSGL_textureFilter filter) {
+ switch (filter) {
+ case RSGL_filterNearest: return GL_NEAREST;
+ case RSGL_filterLinear: return GL_LINEAR;
+ default: break;
+ }
+
+ return GL_LINEAR;
+}
+
+/* textures / images */
+RSGL_texture RSGL_GL_createTexture(RSGL_glRenderer* ctx, const RSGL_textureBlob* blob) {
+ unsigned int id = 0;
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, RSGL_GL_textureFilterToNative(blob->minFilter));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, RSGL_GL_textureFilterToNative(blob->magFilter));
+
+#ifndef RSGL_GLES2
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, blob->width);
+#endif
+
+#if defined(RSGL_GLES2)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+#endif
+
+ u32 dataFormat = RSGL_GL_textureFormatToNative(blob->dataFormat);
+ u32 textureFormat = RSGL_GL_textureFormatToNative(blob->textureFormat);
+ u32 dataType = RSGL_GL_textureDataTypeToNative(blob->dataType);
+
+#ifndef RSGL_GLES2
+ if (blob->dataFormat == RSGL_formatGrayscale) {
+ static GLint swizzleRgbaParams[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ } else if (blob->dataFormat == RSGL_formatGrayscaleAlpha) {
+ static GLint swizzleRgbaParams[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ }
+#endif
+
+ glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, blob->width, blob->height, 0, textureFormat, dataType, blob->data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return id;
+}
+
+void RSGL_GL_copyToTexture(RSGL_glRenderer* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob) {
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+#ifndef RSGL_GLES2
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, blob->width);
+#endif
+
+ u32 dataFormat = RSGL_GL_textureFormatToNative(blob->dataFormat);
+
+ u32 dataType = RSGL_GL_textureDataTypeToNative(blob->dataType);
+
+#ifndef RSGL_GLES2
+ if (blob->dataFormat == RSGL_formatGrayscale) {
+ static GLint swizzleRgbaParams[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ } else if (blob->dataFormat == RSGL_formatGrayscaleAlpha) {
+ static GLint swizzleRgbaParams[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ }
+#endif
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, (i32)blob->width, (i32)blob->height, dataFormat, dataType, blob->data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+#ifndef GL_DEBUG_TYPE_ERROR
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_INFO_LOG_LENGTH 0x8B84
+#endif
+
+#ifdef RSGL_DEBUG
+void RSGL_opengl_getError(void) {
+ GLenum err;
+ while ((err = glGetError()) != GL_NO_ERROR) {
+ switch (err) {
+ case GL_INVALID_ENUM:
+ printf("OpenGL error: GL_INVALID_ENUM\n");
+ break;
+ case GL_INVALID_VALUE:
+ printf("OpenGL error: GL_INVALID_VALUE\n");
+ break;
+ case GL_INVALID_OPERATION:
+ printf("OpenGL error: GL_INVALID_OPERATION\n");
+ break;
+ case GL_STACK_OVERFLOW:
+ printf("OpenGL error: GL_STACK_OVERFLOW\n");
+ break;
+ case GL_STACK_UNDERFLOW:
+ printf("OpenGL error: GL_STACK_UNDERFLOW\n");
+ break;
+ default:
+ printf("OpenGL error: Unknown error code 0x%x\n", err);
+ break;
+ }
+ }
+}
+
+
+void RSGL_debug_shader(u32 src, const char *shader, const char *action) {
+ GLint status;
+ if (action[0] == 'l')
+ glGetProgramiv(src, GL_LINK_STATUS, &status);
+ else
+ glGetShaderiv(src, GL_COMPILE_STATUS, &status);
+
+ if (status == GL_TRUE)
+ printf("%s Shader %s successfully.\n", shader, action);
+ else {
+ printf("%s Shader failed to %s.\n", shader, action);
+
+ GLchar infoLog[512];
+ if (action[0] == 'c') {
+ glGetShaderInfoLog(src, 512, NULL, infoLog);
+ printf("%s Shader info log:\n%s\n", shader, infoLog);
+ } else {
+ glGetProgramInfoLog(src, 512, NULL, infoLog);
+ printf("%s info log:\n%s\n", shader, infoLog);
+ }
+
+ RSGL_opengl_getError();
+ }
+}
+#endif
+
+RSGL_programInfo RSGL_GL_createProgram(RSGL_glRenderer* ctx, RSGL_programBlob* blob) {
+ RSGL_programInfo program;
+ u32 vShader, fShader;
+
+ /* compile vertex shader */
+ vShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vShader, 1, &blob->vertex, NULL);
+ glCompileShader(vShader);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(vShader, "Vertex", "compile");
+#endif
+
+ /* compile fragment shader */
+ fShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fShader, 1, &blob->fragment, NULL);
+ glCompileShader(fShader);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(fShader, "Fragment", "compile");
+#endif
+
+ /* create program and link vertex and fragment shaders */
+ program.program = glCreateProgram();
+
+ glAttachShader(program.program, vShader);
+ glAttachShader(program.program, fShader);
+ glLinkProgram(program.program);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(program.program, "Program", "link");
+#endif
+
+ glDeleteShader(vShader);
+ glDeleteShader(fShader);
+
+ glUseProgram(program.program);
+
+ program.vertexPosition = glGetAttribLocation(program.program, "vertexPosition");
+ program.vertexTexCoord = glGetAttribLocation(program.program, "vertexTexCoord");
+ program.vertexColor = glGetAttribLocation(program.program, "vertexColor");
+
+ program.perspectiveView = glGetUniformLocation(program.program, "pv");
+ program.model = glGetUniformLocation(program.program, "model");
+
+ #ifdef RSGL_DEBUG
+ if (program.perspectiveView < 0 || program.model < 0) {
+ printf("Failed to locate the shader variables\n");
+ }
+ #endif
+
+ glUseProgram(0);
+
+ program.type = RSGL_shaderTypeStandard;
+ return program;
+}
+
+void RSGL_GL_deleteProgram(RSGL_glRenderer* ctx, const RSGL_programInfo* program) {
+ glUseProgram(0);
+ glDeleteProgram(program->program);
+}
+
+size_t RSGL_GL_findShaderArray(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len) {
+ glUseProgram(program->program);
+ int loc = glGetAttribLocation(program->program, var);
+ glUseProgram(0);
+ return loc;
+}
+
+size_t RSGL_GL_findShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len) {
+ glUseProgram(program->program);
+ int loc = glGetUniformLocation(program->program, var);
+ glUseProgram(0);
+ return loc;
+}
+
+void RSGL_GL_updateShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, size_t var, const float value[], u8 len) {
+ glUseProgram(program->program);
+ int loc = (int)var;
+
+ switch (len) {
+ case 1: glUniform1f(loc, value[0]); break;
+ case 2: glUniform2f(loc, value[0], value[1]); break;
+ case 3: glUniform3f(loc, value[0], value[1], value[2]); break;
+ case 4: glUniform4f(loc, value[0], value[1], value[2], value[3]); break;
+ case 16: glUniformMatrix4fv(loc, 1, GL_FALSE, value); break;
+ default: break;
+ }
+
+ glUseProgram(0);
+}
+
+RSGL_framebuffer RSGL_GL_createFramebuffer(RSGL_glRenderer* ctx, size_t width, size_t height) {
+ u32 result = 0;
+ glGenFramebuffers(1, &result);
+ return (RSGL_framebuffer)result;
+}
+
+void RSGL_GL_attachFramebuffer(RSGL_glRenderer* ctx, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ if (attachType < 8)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, tex, mipLevel);
+
+ if (attachType == 100)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, mipLevel);
+
+ if (attachType == 200)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, mipLevel);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void RSGL_GL_deleteFramebuffer(RSGL_glRenderer* ctx, RSGL_framebuffer fbo) {
+ u32 value = fbo;
+ glDeleteFramebuffers(1, &value);
+}
+
+#ifdef RSGL_USE_COMPUTE
+
+#ifndef GL_RG8
+#define GL_RG8 0x822B
+#endif
+
+#ifndef GL_READ_WRITE
+#define GL_READ_WRITE 0x88BA
+#endif
+
+#ifndef GL_COMPUTE_SHADER
+#define GL_COMPUTE_SHADER 0x91B9
+#endif
+
+#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#endif
+
+RSGL_programInfo RSGL_GL_createComputeProgram(RSGL_glRenderer* ctx, const char* CShaderCode) {
+ RSGL_programInfo program;
+ program.type = RSGL_shaderTypeCompute;
+
+ u32 compute = glCreateShader(GL_COMPUTE_SHADER);
+ glShaderSource(compute, 1, &CShaderCode, NULL);
+ glCompileShader(compute);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(compute, "Compute", "compile");
+#endif
+
+ program.program = glCreateProgram();
+ glAttachShader(program.program, compute);
+ glLinkProgram(program.program);
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(program.program, "Program", "link");
+#endif
+
+ glDeleteShader(compute);
+
+ return program;
+}
+
+void RSGL_GL_dispatchComputeProgram(RSGL_glRenderer* ctx, RSGL_programInfo program, u32 groups_x, u32 groups_y, u32 groups_z) {
+ glUseProgram(program.program);
+ glDispatchCompute(groups_x, groups_y, groups_z);
+ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+}
+
+
+void RSGL_GL_bindComputeTexture(RSGL_glRenderer* ctx, u32 texture, u8 format) {
+ u16 c = 0;
+ switch (format) {
+ case 2: c = GL_RG8; break;
+ case 3: c = GL_RGB8; break;
+ case 4: c = GL_RGBA8; break;
+ default: break;
+ }
+ glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, c);
+}
+
+#endif
+
+#ifndef RSGL_NO_GL_LOADER
+int RSGL_loadGLModern(RSGLloadfunc proc) {
+ RSGL_PROC_DEF(proc, glShaderSource);
+ RSGL_PROC_DEF(proc, glCreateShader);
+ RSGL_PROC_DEF(proc, glCompileShader);
+ RSGL_PROC_DEF(proc, glCreateProgram);
+ RSGL_PROC_DEF(proc, glAttachShader);
+ RSGL_PROC_DEF(proc, glBindAttribLocation);
+ RSGL_PROC_DEF(proc, glLinkProgram);
+ RSGL_PROC_DEF(proc, glBindBuffer);
+ RSGL_PROC_DEF(proc, glBufferData);
+ RSGL_PROC_DEF(proc, glEnableVertexAttribArray);
+ RSGL_PROC_DEF(proc, glVertexAttribPointer);
+ RSGL_PROC_DEF(proc, glDisableVertexAttribArray);
+ RSGL_PROC_DEF(proc, glDeleteBuffers);
+ RSGL_PROC_DEF(proc, glUseProgram);
+ RSGL_PROC_DEF(proc, glDetachShader);
+ RSGL_PROC_DEF(proc, glDeleteShader);
+ RSGL_PROC_DEF(proc, glDeleteProgram);
+ RSGL_PROC_DEF(proc, glBufferSubData);
+ RSGL_PROC_DEF(proc, glGetShaderiv);
+ RSGL_PROC_DEF(proc, glGetShaderInfoLog);
+ RSGL_PROC_DEF(proc, glGetProgramiv);
+ RSGL_PROC_DEF(proc, glGetProgramInfoLog);
+ RSGL_PROC_DEF(proc, glGenBuffers);
+ RSGL_PROC_DEF(proc, glGetUniformLocation);
+ RSGL_PROC_DEF(proc, glGetAttribLocation);
+ RSGL_PROC_DEF(proc, glUniformMatrix4fv);
+ RSGL_PROC_DEF(proc, glActiveTexture);
+ RSGL_PROC_DEF(proc, glUniform1f);
+ RSGL_PROC_DEF(proc, glUniform2f);
+ RSGL_PROC_DEF(proc, glUniform3f);
+ RSGL_PROC_DEF(proc, glUniform4f);
+ RSGL_PROC_DEF(proc, glBindFramebuffer);
+ RSGL_PROC_DEF(proc, glGenFramebuffers);
+ RSGL_PROC_DEF(proc, glDeleteFramebuffers);
+ RSGL_PROC_DEF(proc, glFramebufferTexture2D);
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ RSGL_PROC_DEF(proc, glBindVertexArray);
+ RSGL_PROC_DEF(proc, glGenVertexArrays);
+ RSGL_PROC_DEF(proc, glDeleteVertexArrays);
+#endif
+#ifdef RSGL_USE_COMPUTE
+ RSGL_PROC_DEF(proc, glDispatchCompute);
+ RSGL_PROC_DEF(proc, glMemoryBarrier);
+ RSGL_PROC_DEF(proc, glBindImageTexture);
+#endif
+
+ if (
+ glShaderSourceSRC == NULL ||
+ glCreateShaderSRC == NULL ||
+ glCompileShaderSRC == NULL ||
+ glCreateProgramSRC == NULL ||
+ glAttachShaderSRC == NULL ||
+ glBindAttribLocationSRC == NULL ||
+ glLinkProgramSRC == NULL ||
+ glBindBufferSRC == NULL ||
+ glBufferDataSRC == NULL ||
+ glVertexAttribPointerSRC == NULL ||
+ glDisableVertexAttribArraySRC == NULL ||
+ glDeleteBuffersSRC == NULL ||
+ glUseProgramSRC == NULL ||
+ glDetachShaderSRC == NULL ||
+ glDeleteShaderSRC == NULL ||
+ glDeleteProgramSRC == NULL ||
+ glBufferSubDataSRC == NULL ||
+ glGetShaderivSRC == NULL ||
+ glGetShaderInfoLogSRC == NULL ||
+ glGetProgramivSRC == NULL ||
+ glGetProgramInfoLogSRC == NULL ||
+ glGenBuffersSRC == NULL ||
+ glGetUniformLocationSRC == NULL ||
+ glUniformMatrix4fvSRC == NULL ||
+ glBindFramebufferSRC == NULL ||
+ glGenFramebuffersSRC == NULL ||
+ glDeleteFramebuffersSRC == NULL ||
+ glFramebufferTexture2DSRC == NULL
+ )
+ return 1;
+ return 0;
+}
+#endif
+
+#endif /* RSGL_IMPLEMENTATION */
@@ -1,5 +1,6 @@ const std = @import("std"); -const rgfw = @import("rgfw.zig"); +const rgfw = @import("rgfw"); +const rsgl = @import("rsgl"); fn keyfunc (event: [*c]const rgfw.RGFW_event) callconv(.c) void { if(event.*.key.value == rgfw.RGFW_keyEscape) { @@ -8,23 +9,34 @@ fn keyfunc (event: [*c]const rgfw.RGFW_event) callconv(.c) void { } pub fn main() !void { + var hints: *rgfw.RGFW_glHints = rgfw.RGFW_getGlobalHints_OpenGL(); + hints.major = 3; + hints.minor = 3; + hints.profile = rgfw.RGFW_glCompatibility; + rgfw.RGFW_setGlobalHints_OpenGL(hints); + const win: ?*rgfw.RGFW_window = rgfw.RGFW_createWindow("a window", 0, 0, 800, 600, rgfw.RGFW_windowCenter | rgfw.RGFW_windowNoResize | rgfw.RGFW_windowOpenGL); _ = rgfw.RGFW_setEventCallback(rgfw.RGFW_keyPressed, keyfunc); - var mouseX: i32 = 0; - var mouseY: i32 = 0; + const renderer: *rsgl.RSGL_renderer = rsgl.RSGL_renderer_init(rsgl.RSGL_GL_rendererProc(), @constCast(&rgfw.RGFW_getProcAddress_OpenGL)); + + rsgl.RSGL_renderer_viewport(renderer, rsgl.RSGL_RECT(0, 0, 500, 500)); + rsgl.RSGL_renderer_updateSize(renderer, 500, 500); while(rgfw.RGFW_FALSE == rgfw.RGFW_window_shouldClose(win)) { - var event: rgfw.RGFW_event = undefined; - while(rgfw.RGFW_TRUE == rgfw.RGFW_window_checkEvent(win, &event)) { - _ = rgfw.RGFW_window_getMouse(win, &mouseX, &mouseY); - if(event.type == rgfw.RGFW_mouseButtonPressed and event.button.value == rgfw.RGFW_mouseLeft) { - std.debug.print("You clicked at x: {d}, y: {d}\n", .{mouseX, mouseY}); - } + rgfw.RGFW_pollEvents(); + if(rgfw.RGFW_TRUE == rgfw.RGFW_isMousePressed(rgfw.RGFW_mouseLeft)) { + std.debug.print("You clicked\n", .{}); } if(rgfw.RGFW_TRUE == rgfw.RGFW_isMousePressed(rgfw.RGFW_mouseRight)) { - std.debug.print("The right mouse button was clicked at x: {d}, y: {d}\n", .{mouseX, mouseY}); + std.debug.print("The right mouse button was clicked\n", .{}); } + + rsgl.RSGL_renderer_clear(renderer, rsgl.RSGL_RGB(10, 50, 100)); + + rsgl.RSGL_renderer_setColor(renderer, rsgl.RSGL_RGB(255, 0, 0)); + _ = rsgl.RSGL_drawRect(renderer, rsgl.RSGL_RECT(200, 200, 200, 200)); + rsgl.RSGL_renderer_render(renderer); rgfw.RGFW_window_swapBuffers_OpenGL(win); } rgfw.RGFW_window_close(win); diff --git a/rgfw.zig b/rgfw.zig deleted file mode 100644 index e8c3586..0000000 --- a/rgfw.zig +++ /dev/null @@ -1,2305 +0,0 @@ -const __root = @This(); -pub const __builtin = @import("std").zig.c_translation.builtins; -pub const __helpers = @import("std").zig.c_translation.helpers; -pub extern fn __assert_fail(__assertion: [*c]const u8, __file: [*c]const u8, __line: c_uint, __function: [*c]const u8) noreturn; -pub extern fn __assert_perror_fail(__errnum: c_int, __file: [*c]const u8, __line: c_uint, __function: [*c]const u8) noreturn; -pub extern fn __assert(__assertion: [*c]const u8, __file: [*c]const u8, __line: c_int) noreturn; -pub const ptrdiff_t = c_long; -pub const wchar_t = c_int; -pub const max_align_t = extern struct { - __aro_max_align_ll: c_longlong = 0, - __aro_max_align_ld: c_longdouble = 0, -}; -pub const struct___va_list_tag_1 = extern struct { - unnamed_0: c_uint = 0, - unnamed_1: c_uint = 0, - unnamed_2: ?*anyopaque = null, - unnamed_3: ?*anyopaque = null, -}; -pub const __builtin_va_list = [1]struct___va_list_tag_1; -pub const va_list = __builtin_va_list; -pub const __gnuc_va_list = __builtin_va_list; -pub const __u_char = u8; -pub const __u_short = c_ushort; -pub const __u_int = c_uint; -pub const __u_long = c_ulong; -pub const __int8_t = i8; -pub const __uint8_t = u8; -pub const __int16_t = c_short; -pub const __uint16_t = c_ushort; -pub const __int32_t = c_int; -pub const __uint32_t = c_uint; -pub const __int64_t = c_long; -pub const __uint64_t = c_ulong; -pub const __int_least8_t = __int8_t; -pub const __uint_least8_t = __uint8_t; -pub const __int_least16_t = __int16_t; -pub const __uint_least16_t = __uint16_t; -pub const __int_least32_t = __int32_t; -pub const __uint_least32_t = __uint32_t; -pub const __int_least64_t = __int64_t; -pub const __uint_least64_t = __uint64_t; -pub const __quad_t = c_long; -pub const __u_quad_t = c_ulong; -pub const __intmax_t = c_long; -pub const __uintmax_t = c_ulong; -pub const __dev_t = c_ulong; -pub const __uid_t = c_uint; -pub const __gid_t = c_uint; -pub const __ino_t = c_ulong; -pub const __ino64_t = c_ulong; -pub const __mode_t = c_uint; -pub const __nlink_t = c_ulong; -pub const __off_t = c_long; -pub const __off64_t = c_long; -pub const __pid_t = c_int; -pub const __fsid_t = extern struct { - __val: [2]c_int = @import("std").mem.zeroes([2]c_int), -}; -pub const __clock_t = c_long; -pub const __rlim_t = c_ulong; -pub const __rlim64_t = c_ulong; -pub const __id_t = c_uint; -pub const __time_t = c_long; -pub const __useconds_t = c_uint; -pub const __suseconds_t = c_long; -pub const __suseconds64_t = c_long; -pub const __daddr_t = c_int; -pub const __key_t = c_int; -pub const __clockid_t = c_int; -pub const __timer_t = ?*anyopaque; -pub const __blksize_t = c_long; -pub const __blkcnt_t = c_long; -pub const __blkcnt64_t = c_long; -pub const __fsblkcnt_t = c_ulong; -pub const __fsblkcnt64_t = c_ulong; -pub const __fsfilcnt_t = c_ulong; -pub const __fsfilcnt64_t = c_ulong; -pub const __fsword_t = c_long; -pub const __ssize_t = c_long; -pub const __syscall_slong_t = c_long; -pub const __syscall_ulong_t = c_ulong; -pub const __loff_t = __off64_t; -pub const __caddr_t = [*c]u8; -pub const __intptr_t = c_long; -pub const __socklen_t = c_uint; -pub const __sig_atomic_t = c_int; -const union_unnamed_2 = extern union { - __wch: c_uint, - __wchb: [4]u8, -}; -pub const __mbstate_t = extern struct { - __count: c_int = 0, - __value: union_unnamed_2 = @import("std").mem.zeroes(union_unnamed_2), -}; -pub const struct__G_fpos_t = extern struct { - __pos: __off_t = 0, - __state: __mbstate_t = @import("std").mem.zeroes(__mbstate_t), -}; -pub const __fpos_t = struct__G_fpos_t; -pub const struct__G_fpos64_t = extern struct { - __pos: __off64_t = 0, - __state: __mbstate_t = @import("std").mem.zeroes(__mbstate_t), -}; -pub const __fpos64_t = struct__G_fpos64_t; -pub const struct__IO_marker = opaque {}; // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/types/struct_FILE.h:75:7: warning: struct demoted to opaque type - has bitfield -pub const struct__IO_FILE = opaque { - pub const fclose = __root.fclose; - pub const fflush = __root.fflush; - pub const setbuf = __root.setbuf; - pub const setvbuf = __root.setvbuf; - pub const fprintf = __root.fprintf; - pub const vfprintf = __root.vfprintf; - pub const fscanf = __root.fscanf; - pub const vfscanf = __root.vfscanf; - pub const fgetc = __root.fgetc; - pub const getc = __root.getc; - pub const fseek = __root.fseek; - pub const ftell = __root.ftell; - pub const rewind = __root.rewind; - pub const fgetpos = __root.fgetpos; - pub const fsetpos = __root.fsetpos; - pub const clearerr = __root.clearerr; - pub const feof = __root.feof; - pub const ferror = __root.ferror; - pub const fileno = __root.fileno; - pub const pclose = __root.pclose; - pub const __uflow = __root.__uflow; - pub const __overflow = __root.__overflow; - pub const uflow = __root.__uflow; - pub const overflow = __root.__overflow; -}; -pub const __FILE = struct__IO_FILE; -pub const FILE = struct__IO_FILE; -pub const struct__IO_codecvt = opaque {}; -pub const struct__IO_wide_data = opaque {}; -pub const _IO_lock_t = anyopaque; -pub const fpos_t = __fpos_t; -pub extern var stdin: ?*FILE; -pub extern var stdout: ?*FILE; -pub extern var stderr: ?*FILE; -pub extern fn remove(__filename: [*c]const u8) c_int; -pub extern fn rename(__old: [*c]const u8, __new: [*c]const u8) c_int; -pub extern fn fclose(__stream: ?*FILE) c_int; -pub extern fn tmpfile() ?*FILE; -pub extern fn tmpnam([*c]u8) [*c]u8; -pub extern fn fflush(__stream: ?*FILE) c_int; -pub extern fn fopen(noalias __filename: [*c]const u8, noalias __modes: [*c]const u8) ?*FILE; -pub extern fn freopen(noalias __filename: [*c]const u8, noalias __modes: [*c]const u8, noalias __stream: ?*FILE) ?*FILE; -pub extern fn fdopen(__fd: c_int, __modes: [*c]const u8) ?*FILE; -pub extern fn setbuf(noalias __stream: ?*FILE, noalias __buf: [*c]u8) void; -pub extern fn setvbuf(noalias __stream: ?*FILE, noalias __buf: [*c]u8, __modes: c_int, __n: usize) c_int; -pub extern fn fprintf(noalias __stream: ?*FILE, noalias __format: [*c]const u8, ...) c_int; -pub extern fn printf(noalias __format: [*c]const u8, ...) c_int; -pub extern fn sprintf(noalias __s: [*c]u8, noalias __format: [*c]const u8, ...) c_int; -pub extern fn vfprintf(noalias __s: ?*FILE, noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn vprintf(noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn vsprintf(noalias __s: [*c]u8, noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn snprintf(noalias __s: [*c]u8, __maxlen: usize, noalias __format: [*c]const u8, ...) c_int; -pub extern fn vsnprintf(noalias __s: [*c]u8, __maxlen: usize, noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn fscanf(noalias __stream: ?*FILE, noalias __format: [*c]const u8, ...) c_int; -pub extern fn scanf(noalias __format: [*c]const u8, ...) c_int; -pub extern fn sscanf(noalias __s: [*c]const u8, noalias __format: [*c]const u8, ...) c_int; -pub extern fn vfscanf(noalias __s: ?*FILE, noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn vscanf(noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn vsscanf(noalias __s: [*c]const u8, noalias __format: [*c]const u8, __arg: [*c]struct___va_list_tag_1) c_int; -pub extern fn fgetc(__stream: ?*FILE) c_int; -pub extern fn getc(__stream: ?*FILE) c_int; -pub extern fn getchar() c_int; -pub extern fn fputc(__c: c_int, __stream: ?*FILE) c_int; -pub extern fn putc(__c: c_int, __stream: ?*FILE) c_int; -pub extern fn putchar(__c: c_int) c_int; -pub extern fn fgets(noalias __s: [*c]u8, __n: c_int, noalias __stream: ?*FILE) [*c]u8; -pub extern fn fputs(noalias __s: [*c]const u8, noalias __stream: ?*FILE) c_int; -pub extern fn puts(__s: [*c]const u8) c_int; -pub extern fn ungetc(__c: c_int, __stream: ?*FILE) c_int; -pub extern fn fread(noalias __ptr: ?*anyopaque, __size: usize, __n: usize, noalias __stream: ?*FILE) usize; -pub extern fn fwrite(noalias __ptr: ?*const anyopaque, __size: usize, __n: usize, noalias __s: ?*FILE) usize; -pub extern fn fseek(__stream: ?*FILE, __off: c_long, __whence: c_int) c_int; -pub extern fn ftell(__stream: ?*FILE) c_long; -pub extern fn rewind(__stream: ?*FILE) void; -pub extern fn fgetpos(noalias __stream: ?*FILE, noalias __pos: [*c]fpos_t) c_int; -pub extern fn fsetpos(__stream: ?*FILE, __pos: [*c]const fpos_t) c_int; -pub extern fn clearerr(__stream: ?*FILE) void; -pub extern fn feof(__stream: ?*FILE) c_int; -pub extern fn ferror(__stream: ?*FILE) c_int; -pub extern fn perror(__s: [*c]const u8) void; -pub extern fn fileno(__stream: ?*FILE) c_int; -pub extern fn pclose(__stream: ?*FILE) c_int; -pub extern fn popen(__command: [*c]const u8, __modes: [*c]const u8) ?*FILE; -pub extern fn ctermid(__s: [*c]u8) [*c]u8; -pub extern fn __uflow(?*FILE) c_int; -pub extern fn __overflow(?*FILE, c_int) c_int; -pub const div_t = extern struct { - quot: c_int = 0, - rem: c_int = 0, -}; -pub const ldiv_t = extern struct { - quot: c_long = 0, - rem: c_long = 0, -}; -pub const lldiv_t = extern struct { - quot: c_longlong = 0, - rem: c_longlong = 0, -}; -pub extern fn __ctype_get_mb_cur_max() usize; -pub extern fn atof(__nptr: [*c]const u8) f64; -pub extern fn atoi(__nptr: [*c]const u8) c_int; -pub extern fn atol(__nptr: [*c]const u8) c_long; -pub extern fn atoll(__nptr: [*c]const u8) c_longlong; -pub extern fn strtod(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8) f64; -pub extern fn strtof(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8) f32; -pub extern fn strtold(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8) c_longdouble; -pub extern fn strtol(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8, __base: c_int) c_long; -pub extern fn strtoul(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8, __base: c_int) c_ulong; -pub extern fn strtoll(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8, __base: c_int) c_longlong; -pub extern fn strtoull(noalias __nptr: [*c]const u8, noalias __endptr: [*c][*c]u8, __base: c_int) c_ulonglong; -pub extern fn rand() c_int; -pub extern fn srand(__seed: c_uint) void; -pub extern fn malloc(__size: usize) ?*anyopaque; -pub extern fn calloc(__nmemb: usize, __size: usize) ?*anyopaque; -pub extern fn realloc(__ptr: ?*anyopaque, __size: usize) ?*anyopaque; -pub extern fn free(__ptr: ?*anyopaque) void; -pub extern fn aligned_alloc(__alignment: usize, __size: usize) ?*anyopaque; -pub extern fn abort() noreturn; -pub extern fn atexit(__func: ?*const fn () callconv(.c) void) c_int; -pub extern fn at_quick_exit(__func: ?*const fn () callconv(.c) void) c_int; -pub extern fn exit(__status: c_int) noreturn; -pub extern fn quick_exit(__status: c_int) noreturn; -pub extern fn _Exit(__status: c_int) noreturn; -pub extern fn getenv(__name: [*c]const u8) [*c]u8; -pub extern fn system(__command: [*c]const u8) c_int; -pub const __compar_fn_t = ?*const fn (?*const anyopaque, ?*const anyopaque) callconv(.c) c_int; -pub extern fn bsearch(__key: ?*const anyopaque, __base: ?*const anyopaque, __nmemb: usize, __size: usize, __compar: __compar_fn_t) ?*anyopaque; -pub extern fn qsort(__base: ?*anyopaque, __nmemb: usize, __size: usize, __compar: __compar_fn_t) void; -pub extern fn abs(__x: c_int) c_int; -pub extern fn labs(__x: c_long) c_long; -pub extern fn llabs(__x: c_longlong) c_longlong; -pub extern fn div(__numer: c_int, __denom: c_int) div_t; -pub extern fn ldiv(__numer: c_long, __denom: c_long) ldiv_t; -pub extern fn lldiv(__numer: c_longlong, __denom: c_longlong) lldiv_t; -pub extern fn mblen(__s: [*c]const u8, __n: usize) c_int; -pub extern fn mbtowc(noalias __pwc: [*c]wchar_t, noalias __s: [*c]const u8, __n: usize) c_int; -pub extern fn wctomb(__s: [*c]u8, __wchar: wchar_t) c_int; -pub extern fn mbstowcs(noalias __pwcs: [*c]wchar_t, noalias __s: [*c]const u8, __n: usize) usize; -pub extern fn wcstombs(noalias __s: [*c]u8, noalias __pwcs: [*c]const wchar_t, __n: usize) usize; -pub extern fn memcpy(noalias __dest: ?*anyopaque, noalias __src: ?*const anyopaque, __n: usize) ?*anyopaque; -pub extern fn memmove(__dest: ?*anyopaque, __src: ?*const anyopaque, __n: usize) ?*anyopaque; -pub extern fn memset(__s: ?*anyopaque, __c: c_int, __n: usize) ?*anyopaque; -pub extern fn memcmp(__s1: ?*const anyopaque, __s2: ?*const anyopaque, __n: usize) c_int; -pub extern fn __memcmpeq(__s1: ?*const anyopaque, __s2: ?*const anyopaque, __n: usize) c_int; -pub extern fn memchr(__s: ?*const anyopaque, __c: c_int, __n: usize) ?*anyopaque; -pub extern fn strcpy(noalias __dest: [*c]u8, noalias __src: [*c]const u8) [*c]u8; -pub extern fn strncpy(noalias __dest: [*c]u8, noalias __src: [*c]const u8, __n: usize) [*c]u8; -pub extern fn strcat(noalias __dest: [*c]u8, noalias __src: [*c]const u8) [*c]u8; -pub extern fn strncat(noalias __dest: [*c]u8, noalias __src: [*c]const u8, __n: usize) [*c]u8; -pub extern fn strcmp(__s1: [*c]const u8, __s2: [*c]const u8) c_int; -pub extern fn strncmp(__s1: [*c]const u8, __s2: [*c]const u8, __n: usize) c_int; -pub extern fn strcoll(__s1: [*c]const u8, __s2: [*c]const u8) c_int; -pub extern fn strxfrm(noalias __dest: [*c]u8, noalias __src: [*c]const u8, __n: usize) usize; -pub extern fn strchr(__s: [*c]const u8, __c: c_int) [*c]u8; -pub extern fn strrchr(__s: [*c]const u8, __c: c_int) [*c]u8; -pub extern fn strcspn(__s: [*c]const u8, __reject: [*c]const u8) usize; -pub extern fn strspn(__s: [*c]const u8, __accept: [*c]const u8) usize; -pub extern fn strpbrk(__s: [*c]const u8, __accept: [*c]const u8) [*c]u8; -pub extern fn strstr(__haystack: [*c]const u8, __needle: [*c]const u8) [*c]u8; -pub extern fn strtok(noalias __s: [*c]u8, noalias __delim: [*c]const u8) [*c]u8; -pub extern fn __strtok_r(noalias __s: [*c]u8, noalias __delim: [*c]const u8, noalias __save_ptr: [*c][*c]u8) [*c]u8; -pub extern fn strtok_r(noalias __s: [*c]u8, noalias __delim: [*c]const u8, noalias __save_ptr: [*c][*c]u8) [*c]u8; -pub extern fn strlen(__s: [*c]const u8) usize; -pub extern fn strerror(__errnum: c_int) [*c]u8; -pub const int_least8_t = __int_least8_t; -pub const int_least16_t = __int_least16_t; -pub const int_least32_t = __int_least32_t; -pub const int_least64_t = __int_least64_t; -pub const uint_least8_t = __uint_least8_t; -pub const uint_least16_t = __uint_least16_t; -pub const uint_least32_t = __uint_least32_t; -pub const uint_least64_t = __uint_least64_t; -pub const int_fast8_t = i8; -pub const int_fast16_t = c_long; -pub const int_fast32_t = c_long; -pub const int_fast64_t = c_long; -pub const uint_fast8_t = u8; -pub const uint_fast16_t = c_ulong; -pub const uint_fast32_t = c_ulong; -pub const uint_fast64_t = c_ulong; -pub const intmax_t = __intmax_t; -pub const uintmax_t = __uintmax_t; -pub const @"u8" = u8; -pub const @"i8" = i8; -pub const @"u16" = u16; -pub const @"i16" = i16; -pub const @"u32" = u32; -pub const @"i32" = i32; -pub const @"u64" = u64; -pub const @"i64" = i64; -pub const RGFW_check_size64 = [1]u8; -pub const RGFW_check_size32 = [1]u8; -pub const RGFW_check_size16 = [1]u8; -pub const RGFW_bool = @"u8"; -pub const struct_RGFW_info = opaque { - pub const RGFW_init_ptr = __root.RGFW_init_ptr; - pub const RGFW_deinit_ptr = __root.RGFW_deinit_ptr; - pub const RGFW_setInfo = __root.RGFW_setInfo; - pub const ptr = __root.RGFW_init_ptr; - pub const setInfo = __root.RGFW_setInfo; -}; -pub const RGFW_info = struct_RGFW_info; -pub const struct_RGFW_window = opaque { - pub const RGFW_window_createSurface = __root.RGFW_window_createSurface; - pub const RGFW_window_createSurfacePtr = __root.RGFW_window_createSurfacePtr; - pub const RGFW_window_blitSurface = __root.RGFW_window_blitSurface; - pub const RGFW_window_getPosition = __root.RGFW_window_getPosition; - pub const RGFW_window_getSize = __root.RGFW_window_getSize; - pub const RGFW_window_getSizeInPixels = __root.RGFW_window_getSizeInPixels; - pub const RGFW_window_getFlags = __root.RGFW_window_getFlags; - pub const RGFW_window_getExitKey = __root.RGFW_window_getExitKey; - pub const RGFW_window_setExitKey = __root.RGFW_window_setExitKey; - pub const RGFW_window_setEnabledEvents = __root.RGFW_window_setEnabledEvents; - pub const RGFW_window_getEnabledEvents = __root.RGFW_window_getEnabledEvents; - pub const RGFW_window_setDisabledEvents = __root.RGFW_window_setDisabledEvents; - pub const RGFW_window_setEventState = __root.RGFW_window_setEventState; - pub const RGFW_window_getUserPtr = __root.RGFW_window_getUserPtr; - pub const RGFW_window_setUserPtr = __root.RGFW_window_setUserPtr; - pub const RGFW_window_getSrc = __root.RGFW_window_getSrc; - pub const RGFW_window_setLayer_OSX = __root.RGFW_window_setLayer_OSX; - pub const RGFW_window_getView_OSX = __root.RGFW_window_getView_OSX; - pub const RGFW_window_getWindow_OSX = __root.RGFW_window_getWindow_OSX; - pub const RGFW_window_getHWND = __root.RGFW_window_getHWND; - pub const RGFW_window_getHDC = __root.RGFW_window_getHDC; - pub const RGFW_window_getWindow_X11 = __root.RGFW_window_getWindow_X11; - pub const RGFW_window_getWindow_Wayland = __root.RGFW_window_getWindow_Wayland; - pub const RGFW_window_setFlags = __root.RGFW_window_setFlags; - pub const RGFW_window_checkEvent = __root.RGFW_window_checkEvent; - pub const RGFW_window_checkQueuedEvent = __root.RGFW_window_checkQueuedEvent; - pub const RGFW_window_isKeyPressed = __root.RGFW_window_isKeyPressed; - pub const RGFW_window_isKeyDown = __root.RGFW_window_isKeyDown; - pub const RGFW_window_isKeyReleased = __root.RGFW_window_isKeyReleased; - pub const RGFW_window_isMousePressed = __root.RGFW_window_isMousePressed; - pub const RGFW_window_isMouseDown = __root.RGFW_window_isMouseDown; - pub const RGFW_window_isMouseReleased = __root.RGFW_window_isMouseReleased; - pub const RGFW_window_didMouseLeave = __root.RGFW_window_didMouseLeave; - pub const RGFW_window_didMouseEnter = __root.RGFW_window_didMouseEnter; - pub const RGFW_window_isMouseInside = __root.RGFW_window_isMouseInside; - pub const RGFW_window_isDataDragging = __root.RGFW_window_isDataDragging; - pub const RGFW_window_getDataDrag = __root.RGFW_window_getDataDrag; - pub const RGFW_window_didDataDrop = __root.RGFW_window_didDataDrop; - pub const RGFW_window_getDataDrop = __root.RGFW_window_getDataDrop; - pub const RGFW_window_close = __root.RGFW_window_close; - pub const RGFW_window_closePtr = __root.RGFW_window_closePtr; - pub const RGFW_window_fetchSize = __root.RGFW_window_fetchSize; - pub const RGFW_window_move = __root.RGFW_window_move; - pub const RGFW_window_moveToMonitor = __root.RGFW_window_moveToMonitor; - pub const RGFW_window_resize = __root.RGFW_window_resize; - pub const RGFW_window_setAspectRatio = __root.RGFW_window_setAspectRatio; - pub const RGFW_window_setMinSize = __root.RGFW_window_setMinSize; - pub const RGFW_window_setMaxSize = __root.RGFW_window_setMaxSize; - pub const RGFW_window_focus = __root.RGFW_window_focus; - pub const RGFW_window_isInFocus = __root.RGFW_window_isInFocus; - pub const RGFW_window_raise = __root.RGFW_window_raise; - pub const RGFW_window_maximize = __root.RGFW_window_maximize; - pub const RGFW_window_setFullscreen = __root.RGFW_window_setFullscreen; - pub const RGFW_window_center = __root.RGFW_window_center; - pub const RGFW_window_minimize = __root.RGFW_window_minimize; - pub const RGFW_window_restore = __root.RGFW_window_restore; - pub const RGFW_window_setFloating = __root.RGFW_window_setFloating; - pub const RGFW_window_setOpacity = __root.RGFW_window_setOpacity; - pub const RGFW_window_setBorder = __root.RGFW_window_setBorder; - pub const RGFW_window_borderless = __root.RGFW_window_borderless; - pub const RGFW_window_setDND = __root.RGFW_window_setDND; - pub const RGFW_window_allowsDND = __root.RGFW_window_allowsDND; - pub const RGFW_window_setMousePassthrough = __root.RGFW_window_setMousePassthrough; - pub const RGFW_window_setName = __root.RGFW_window_setName; - pub const RGFW_window_setIcon = __root.RGFW_window_setIcon; - pub const RGFW_window_setIconEx = __root.RGFW_window_setIconEx; - pub const RGFW_window_setMouse = __root.RGFW_window_setMouse; - pub const RGFW_window_setMouseStandard = __root.RGFW_window_setMouseStandard; - pub const RGFW_window_setMouseDefault = __root.RGFW_window_setMouseDefault; - pub const RGFW_window_setRawMouseMode = __root.RGFW_window_setRawMouseMode; - pub const RGFW_window_captureMouse = __root.RGFW_window_captureMouse; - pub const RGFW_window_captureRawMouse = __root.RGFW_window_captureRawMouse; - pub const RGFW_window_isRawMouseMode = __root.RGFW_window_isRawMouseMode; - pub const RGFW_window_isCaptured = __root.RGFW_window_isCaptured; - pub const RGFW_window_hide = __root.RGFW_window_hide; - pub const RGFW_window_show = __root.RGFW_window_show; - pub const RGFW_window_flash = __root.RGFW_window_flash; - pub const RGFW_window_setShouldClose = __root.RGFW_window_setShouldClose; - pub const RGFW_window_getMouse = __root.RGFW_window_getMouse; - pub const RGFW_window_showMouse = __root.RGFW_window_showMouse; - pub const RGFW_window_isMouseHidden = __root.RGFW_window_isMouseHidden; - pub const RGFW_window_moveMouse = __root.RGFW_window_moveMouse; - pub const RGFW_window_shouldClose = __root.RGFW_window_shouldClose; - pub const RGFW_window_isFullscreen = __root.RGFW_window_isFullscreen; - pub const RGFW_window_isHidden = __root.RGFW_window_isHidden; - pub const RGFW_window_isMinimized = __root.RGFW_window_isMinimized; - pub const RGFW_window_isMaximized = __root.RGFW_window_isMaximized; - pub const RGFW_window_isFloating = __root.RGFW_window_isFloating; - pub const RGFW_window_scaleToMonitor = __root.RGFW_window_scaleToMonitor; - pub const RGFW_window_getMonitor = __root.RGFW_window_getMonitor; - pub const RGFW_window_createContext_OpenGL = __root.RGFW_window_createContext_OpenGL; - pub const RGFW_window_createContextPtr_OpenGL = __root.RGFW_window_createContextPtr_OpenGL; - pub const RGFW_window_getContext_OpenGL = __root.RGFW_window_getContext_OpenGL; - pub const RGFW_window_deleteContext_OpenGL = __root.RGFW_window_deleteContext_OpenGL; - pub const RGFW_window_deleteContextPtr_OpenGL = __root.RGFW_window_deleteContextPtr_OpenGL; - pub const RGFW_window_makeCurrentWindow_OpenGL = __root.RGFW_window_makeCurrentWindow_OpenGL; - pub const RGFW_window_makeCurrentContext_OpenGL = __root.RGFW_window_makeCurrentContext_OpenGL; - pub const RGFW_window_swapBuffers_OpenGL = __root.RGFW_window_swapBuffers_OpenGL; - pub const RGFW_window_swapInterval_OpenGL = __root.RGFW_window_swapInterval_OpenGL; - pub const RGFW_setRootWindow = __root.RGFW_setRootWindow; - pub const RGFW_window_eventQueuePop = __root.RGFW_window_eventQueuePop; - pub const createSurface = __root.RGFW_window_createSurface; - pub const createSurfacePtr = __root.RGFW_window_createSurfacePtr; - pub const blitSurface = __root.RGFW_window_blitSurface; - pub const getPosition = __root.RGFW_window_getPosition; - pub const getSize = __root.RGFW_window_getSize; - pub const getSizeInPixels = __root.RGFW_window_getSizeInPixels; - pub const getFlags = __root.RGFW_window_getFlags; - pub const getExitKey = __root.RGFW_window_getExitKey; - pub const setExitKey = __root.RGFW_window_setExitKey; - pub const setEnabledEvents = __root.RGFW_window_setEnabledEvents; - pub const getEnabledEvents = __root.RGFW_window_getEnabledEvents; - pub const setDisabledEvents = __root.RGFW_window_setDisabledEvents; - pub const setEventState = __root.RGFW_window_setEventState; - pub const getUserPtr = __root.RGFW_window_getUserPtr; - pub const setUserPtr = __root.RGFW_window_setUserPtr; - pub const getSrc = __root.RGFW_window_getSrc; - pub const setLayer_OSX = __root.RGFW_window_setLayer_OSX; - pub const getView_OSX = __root.RGFW_window_getView_OSX; - pub const getWindow_OSX = __root.RGFW_window_getWindow_OSX; - pub const getHWND = __root.RGFW_window_getHWND; - pub const getHDC = __root.RGFW_window_getHDC; - pub const getWindow_X11 = __root.RGFW_window_getWindow_X11; - pub const getWindow_Wayland = __root.RGFW_window_getWindow_Wayland; - pub const setFlags = __root.RGFW_window_setFlags; - pub const checkEvent = __root.RGFW_window_checkEvent; - pub const checkQueuedEvent = __root.RGFW_window_checkQueuedEvent; - pub const isKeyPressed = __root.RGFW_window_isKeyPressed; - pub const isKeyDown = __root.RGFW_window_isKeyDown; - pub const isKeyReleased = __root.RGFW_window_isKeyReleased; - pub const isMousePressed = __root.RGFW_window_isMousePressed; - pub const isMouseDown = __root.RGFW_window_isMouseDown; - pub const isMouseReleased = __root.RGFW_window_isMouseReleased; - pub const didMouseLeave = __root.RGFW_window_didMouseLeave; - pub const didMouseEnter = __root.RGFW_window_didMouseEnter; - pub const isMouseInside = __root.RGFW_window_isMouseInside; - pub const isDataDragging = __root.RGFW_window_isDataDragging; - pub const getDataDrag = __root.RGFW_window_getDataDrag; - pub const didDataDrop = __root.RGFW_window_didDataDrop; - pub const getDataDrop = __root.RGFW_window_getDataDrop; - pub const close = __root.RGFW_window_close; - pub const closePtr = __root.RGFW_window_closePtr; - pub const fetchSize = __root.RGFW_window_fetchSize; - pub const move = __root.RGFW_window_move; - pub const moveToMonitor = __root.RGFW_window_moveToMonitor; - pub const resize = __root.RGFW_window_resize; - pub const setAspectRatio = __root.RGFW_window_setAspectRatio; - pub const setMinSize = __root.RGFW_window_setMinSize; - pub const setMaxSize = __root.RGFW_window_setMaxSize; - pub const focus = __root.RGFW_window_focus; - pub const isInFocus = __root.RGFW_window_isInFocus; - pub const raise = __root.RGFW_window_raise; - pub const maximize = __root.RGFW_window_maximize; - pub const setFullscreen = __root.RGFW_window_setFullscreen; - pub const center = __root.RGFW_window_center; - pub const minimize = __root.RGFW_window_minimize; - pub const restore = __root.RGFW_window_restore; - pub const setFloating = __root.RGFW_window_setFloating; - pub const setOpacity = __root.RGFW_window_setOpacity; - pub const setBorder = __root.RGFW_window_setBorder; - pub const borderless = __root.RGFW_window_borderless; - pub const setDND = __root.RGFW_window_setDND; - pub const allowsDND = __root.RGFW_window_allowsDND; - pub const setMousePassthrough = __root.RGFW_window_setMousePassthrough; - pub const setName = __root.RGFW_window_setName; - pub const setIcon = __root.RGFW_window_setIcon; - pub const setIconEx = __root.RGFW_window_setIconEx; - pub const setMouse = __root.RGFW_window_setMouse; - pub const setMouseStandard = __root.RGFW_window_setMouseStandard; - pub const setMouseDefault = __root.RGFW_window_setMouseDefault; - pub const setRawMouseMode = __root.RGFW_window_setRawMouseMode; - pub const captureMouse = __root.RGFW_window_captureMouse; - pub const captureRawMouse = __root.RGFW_window_captureRawMouse; - pub const isRawMouseMode = __root.RGFW_window_isRawMouseMode; - pub const isCaptured = __root.RGFW_window_isCaptured; - pub const hide = __root.RGFW_window_hide; - pub const show = __root.RGFW_window_show; - pub const flash = __root.RGFW_window_flash; - pub const setShouldClose = __root.RGFW_window_setShouldClose; - pub const getMouse = __root.RGFW_window_getMouse; - pub const showMouse = __root.RGFW_window_showMouse; - pub const isMouseHidden = __root.RGFW_window_isMouseHidden; - pub const moveMouse = __root.RGFW_window_moveMouse; - pub const shouldClose = __root.RGFW_window_shouldClose; - pub const isFullscreen = __root.RGFW_window_isFullscreen; - pub const isHidden = __root.RGFW_window_isHidden; - pub const isMinimized = __root.RGFW_window_isMinimized; - pub const isMaximized = __root.RGFW_window_isMaximized; - pub const isFloating = __root.RGFW_window_isFloating; - pub const scaleToMonitor = __root.RGFW_window_scaleToMonitor; - pub const getMonitor = __root.RGFW_window_getMonitor; - pub const createContext_OpenGL = __root.RGFW_window_createContext_OpenGL; - pub const createContextPtr_OpenGL = __root.RGFW_window_createContextPtr_OpenGL; - pub const getContext_OpenGL = __root.RGFW_window_getContext_OpenGL; - pub const deleteContext_OpenGL = __root.RGFW_window_deleteContext_OpenGL; - pub const deleteContextPtr_OpenGL = __root.RGFW_window_deleteContextPtr_OpenGL; - pub const makeCurrentWindow_OpenGL = __root.RGFW_window_makeCurrentWindow_OpenGL; - pub const makeCurrentContext_OpenGL = __root.RGFW_window_makeCurrentContext_OpenGL; - pub const swapBuffers_OpenGL = __root.RGFW_window_swapBuffers_OpenGL; - pub const swapInterval_OpenGL = __root.RGFW_window_swapInterval_OpenGL; - pub const setRootWindow = __root.RGFW_setRootWindow; - pub const eventQueuePop = __root.RGFW_window_eventQueuePop; -}; -pub const RGFW_window = struct_RGFW_window; -pub const struct_RGFW_window_src = opaque {}; -pub const RGFW_window_src = struct_RGFW_window_src; -pub const RGFW_format = @"u8"; -pub const RGFW_formatRGB8: c_int = 0; -pub const RGFW_formatBGR8: c_int = 1; -pub const RGFW_formatRGBA8: c_int = 2; -pub const RGFW_formatARGB8: c_int = 3; -pub const RGFW_formatBGRA8: c_int = 4; -pub const RGFW_formatABGR8: c_int = 5; -pub const RGFW_formatCount: c_int = 6; -pub const enum_RGFW_format_enum = c_uint; -pub const struct_RGFW_colorLayout = extern struct { - r: @"i32" = 0, - g: @"i32" = 0, - b: @"i32" = 0, - a: @"i32" = 0, - channels: @"u32" = 0, -}; -pub const RGFW_colorLayout = struct_RGFW_colorLayout; -pub const RGFW_convertImageDataFunc = ?*const fn (dest_data: [*c]@"u8", src_data: [*c]@"u8", srcLayout: [*c]const RGFW_colorLayout, destLayout: [*c]const RGFW_colorLayout, count: usize) callconv(.c) void; -pub const struct_RGFW_nativeImage = opaque {}; -pub const RGFW_nativeImage = struct_RGFW_nativeImage; -pub const struct_RGFW_surface = opaque { - pub const RGFW_surface_getNativeImage = __root.RGFW_surface_getNativeImage; - pub const RGFW_surface_free = __root.RGFW_surface_free; - pub const RGFW_surface_freePtr = __root.RGFW_surface_freePtr; - pub const RGFW_surface_setConvertFunc = __root.RGFW_surface_setConvertFunc; - pub const getNativeImage = __root.RGFW_surface_getNativeImage; - pub const freePtr = __root.RGFW_surface_freePtr; - pub const setConvertFunc = __root.RGFW_surface_setConvertFunc; -}; -pub const RGFW_surface = struct_RGFW_surface; -pub const struct_RGFW_gammaRamp = extern struct { - red: [*c]@"u16" = null, - green: [*c]@"u16" = null, - blue: [*c]@"u16" = null, - count: usize = 0, - pub const RGFW_freeGammaRamp = __root.RGFW_freeGammaRamp; - pub const freeGammaRamp = __root.RGFW_freeGammaRamp; -}; -pub const RGFW_gammaRamp = struct_RGFW_gammaRamp; -pub const struct_RGFW_monitorMode = extern struct { - w: @"i32" = 0, - h: @"i32" = 0, - refreshRate: f32 = 0, - red: @"u8" = 0, - blue: @"u8" = 0, - green: @"u8" = 0, - src: ?*anyopaque = null, - pub const RGFW_freeModes = __root.RGFW_freeModes; - pub const RGFW_monitorModeCompare = __root.RGFW_monitorModeCompare; - pub const freeModes = __root.RGFW_freeModes; - pub const monitorModeCompare = __root.RGFW_monitorModeCompare; -}; -pub const RGFW_monitorMode = struct_RGFW_monitorMode; -pub const struct_RGFW_monitorNode = opaque {}; -pub const RGFW_monitorNode = struct_RGFW_monitorNode; -pub const struct_RGFW_monitor = extern struct { - x: @"i32" = 0, - y: @"i32" = 0, - name: [128]u8 = @import("std").mem.zeroes([128]u8), - scaleX: f32 = 0, - scaleY: f32 = 0, - pixelRatio: f32 = 0, - physW: f32 = 0, - physH: f32 = 0, - mode: RGFW_monitorMode = @import("std").mem.zeroes(RGFW_monitorMode), - userPtr: ?*anyopaque = null, - node: ?*RGFW_monitorNode = null, - pub const RGFW_monitor_getModes = __root.RGFW_monitor_getModes; - pub const RGFW_monitor_getModesPtr = __root.RGFW_monitor_getModesPtr; - pub const RGFW_monitor_findClosestMode = __root.RGFW_monitor_findClosestMode; - pub const RGFW_monitor_getGammaRamp = __root.RGFW_monitor_getGammaRamp; - pub const RGFW_monitor_getGammaRampPtr = __root.RGFW_monitor_getGammaRampPtr; - pub const RGFW_monitor_setGammaRamp = __root.RGFW_monitor_setGammaRamp; - pub const RGFW_monitor_setGamma = __root.RGFW_monitor_setGamma; - pub const RGFW_monitor_setGammaPtr = __root.RGFW_monitor_setGammaPtr; - pub const RGFW_monitor_getWorkarea = __root.RGFW_monitor_getWorkarea; - pub const RGFW_monitor_getPosition = __root.RGFW_monitor_getPosition; - pub const RGFW_monitor_getName = __root.RGFW_monitor_getName; - pub const RGFW_monitor_getScale = __root.RGFW_monitor_getScale; - pub const RGFW_monitor_getPhysicalSize = __root.RGFW_monitor_getPhysicalSize; - pub const RGFW_monitor_setUserPtr = __root.RGFW_monitor_setUserPtr; - pub const RGFW_monitor_getUserPtr = __root.RGFW_monitor_getUserPtr; - pub const RGFW_monitor_getMode = __root.RGFW_monitor_getMode; - pub const RGFW_monitor_requestMode = __root.RGFW_monitor_requestMode; - pub const RGFW_monitor_setMode = __root.RGFW_monitor_setMode; - pub const RGFW_monitor_scaleToWindow = __root.RGFW_monitor_scaleToWindow; - pub const getModes = __root.RGFW_monitor_getModes; - pub const getModesPtr = __root.RGFW_monitor_getModesPtr; - pub const findClosestMode = __root.RGFW_monitor_findClosestMode; - pub const getGammaRamp = __root.RGFW_monitor_getGammaRamp; - pub const getGammaRampPtr = __root.RGFW_monitor_getGammaRampPtr; - pub const setGammaRamp = __root.RGFW_monitor_setGammaRamp; - pub const setGamma = __root.RGFW_monitor_setGamma; - pub const setGammaPtr = __root.RGFW_monitor_setGammaPtr; - pub const getWorkarea = __root.RGFW_monitor_getWorkarea; - pub const getPosition = __root.RGFW_monitor_getPosition; - pub const getName = __root.RGFW_monitor_getName; - pub const getScale = __root.RGFW_monitor_getScale; - pub const getPhysicalSize = __root.RGFW_monitor_getPhysicalSize; - pub const setUserPtr = __root.RGFW_monitor_setUserPtr; - pub const getUserPtr = __root.RGFW_monitor_getUserPtr; - pub const getMode = __root.RGFW_monitor_getMode; - pub const requestMode = __root.RGFW_monitor_requestMode; - pub const setMode = __root.RGFW_monitor_setMode; - pub const scaleToWindow = __root.RGFW_monitor_scaleToWindow; -}; -pub const RGFW_monitor = struct_RGFW_monitor; -pub const RGFW_modeRequest = @"u8"; -pub const RGFW_monitorScale: c_int = 1; -pub const RGFW_monitorRefresh: c_int = 2; -pub const RGFW_monitorRGB: c_int = 4; -pub const RGFW_monitorAll: c_int = 7; -pub const enum_RGFW_modeRequest_enum = c_uint; -pub const RGFW_mouse = anyopaque; -pub const RGFW_key = @"u8"; -pub const RGFW_keyNULL: c_int = 0; -pub const RGFW_keyEscape: c_int = 27; -pub const RGFW_keyBacktick: c_int = 96; -pub const RGFW_key0: c_int = 48; -pub const RGFW_key1: c_int = 49; -pub const RGFW_key2: c_int = 50; -pub const RGFW_key3: c_int = 51; -pub const RGFW_key4: c_int = 52; -pub const RGFW_key5: c_int = 53; -pub const RGFW_key6: c_int = 54; -pub const RGFW_key7: c_int = 55; -pub const RGFW_key8: c_int = 56; -pub const RGFW_key9: c_int = 57; -pub const RGFW_keyMinus: c_int = 45; -pub const RGFW_keyEqual: c_int = 61; -pub const RGFW_keyEquals: c_int = 61; -pub const RGFW_keyBackSpace: c_int = 8; -pub const RGFW_keyTab: c_int = 9; -pub const RGFW_keySpace: c_int = 32; -pub const RGFW_keyA: c_int = 97; -pub const RGFW_keyB: c_int = 98; -pub const RGFW_keyC: c_int = 99; -pub const RGFW_keyD: c_int = 100; -pub const RGFW_keyE: c_int = 101; -pub const RGFW_keyF: c_int = 102; -pub const RGFW_keyG: c_int = 103; -pub const RGFW_keyH: c_int = 104; -pub const RGFW_keyI: c_int = 105; -pub const RGFW_keyJ: c_int = 106; -pub const RGFW_keyK: c_int = 107; -pub const RGFW_keyL: c_int = 108; -pub const RGFW_keyM: c_int = 109; -pub const RGFW_keyN: c_int = 110; -pub const RGFW_keyO: c_int = 111; -pub const RGFW_keyP: c_int = 112; -pub const RGFW_keyQ: c_int = 113; -pub const RGFW_keyR: c_int = 114; -pub const RGFW_keyS: c_int = 115; -pub const RGFW_keyT: c_int = 116; -pub const RGFW_keyU: c_int = 117; -pub const RGFW_keyV: c_int = 118; -pub const RGFW_keyW: c_int = 119; -pub const RGFW_keyX: c_int = 120; -pub const RGFW_keyY: c_int = 121; -pub const RGFW_keyZ: c_int = 122; -pub const RGFW_keyPeriod: c_int = 46; -pub const RGFW_keyComma: c_int = 44; -pub const RGFW_keySlash: c_int = 47; -pub const RGFW_keyBracket: c_int = 91; -pub const RGFW_keyCloseBracket: c_int = 93; -pub const RGFW_keySemicolon: c_int = 59; -pub const RGFW_keyApostrophe: c_int = 39; -pub const RGFW_keyBackSlash: c_int = 92; -pub const RGFW_keyReturn: c_int = 10; -pub const RGFW_keyEnter: c_int = 10; -pub const RGFW_keyDelete: c_int = 127; -pub const RGFW_keyF1: c_int = 128; -pub const RGFW_keyF2: c_int = 129; -pub const RGFW_keyF3: c_int = 130; -pub const RGFW_keyF4: c_int = 131; -pub const RGFW_keyF5: c_int = 132; -pub const RGFW_keyF6: c_int = 133; -pub const RGFW_keyF7: c_int = 134; -pub const RGFW_keyF8: c_int = 135; -pub const RGFW_keyF9: c_int = 136; -pub const RGFW_keyF10: c_int = 137; -pub const RGFW_keyF11: c_int = 138; -pub const RGFW_keyF12: c_int = 139; -pub const RGFW_keyF13: c_int = 140; -pub const RGFW_keyF14: c_int = 141; -pub const RGFW_keyF15: c_int = 142; -pub const RGFW_keyF16: c_int = 143; -pub const RGFW_keyF17: c_int = 144; -pub const RGFW_keyF18: c_int = 145; -pub const RGFW_keyF19: c_int = 146; -pub const RGFW_keyF20: c_int = 147; -pub const RGFW_keyF21: c_int = 148; -pub const RGFW_keyF22: c_int = 149; -pub const RGFW_keyF23: c_int = 150; -pub const RGFW_keyF24: c_int = 151; -pub const RGFW_keyF25: c_int = 152; -pub const RGFW_keyCapsLock: c_int = 153; -pub const RGFW_keyShiftL: c_int = 154; -pub const RGFW_keyControlL: c_int = 155; -pub const RGFW_keyAltL: c_int = 156; -pub const RGFW_keySuperL: c_int = 157; -pub const RGFW_keyShiftR: c_int = 158; -pub const RGFW_keyControlR: c_int = 159; -pub const RGFW_keyAltR: c_int = 160; -pub const RGFW_keySuperR: c_int = 161; -pub const RGFW_keyUp: c_int = 162; -pub const RGFW_keyDown: c_int = 163; -pub const RGFW_keyLeft: c_int = 164; -pub const RGFW_keyRight: c_int = 165; -pub const RGFW_keyInsert: c_int = 166; -pub const RGFW_keyMenu: c_int = 167; -pub const RGFW_keyEnd: c_int = 168; -pub const RGFW_keyHome: c_int = 169; -pub const RGFW_keyPageUp: c_int = 170; -pub const RGFW_keyPageDown: c_int = 171; -pub const RGFW_keyNumLock: c_int = 172; -pub const RGFW_keyPadSlash: c_int = 173; -pub const RGFW_keyPadMultiply: c_int = 174; -pub const RGFW_keyPadPlus: c_int = 175; -pub const RGFW_keyPadMinus: c_int = 176; -pub const RGFW_keyPadEqual: c_int = 177; -pub const RGFW_keyPadEquals: c_int = 177; -pub const RGFW_keyPad1: c_int = 178; -pub const RGFW_keyPad2: c_int = 179; -pub const RGFW_keyPad3: c_int = 180; -pub const RGFW_keyPad4: c_int = 181; -pub const RGFW_keyPad5: c_int = 182; -pub const RGFW_keyPad6: c_int = 183; -pub const RGFW_keyPad7: c_int = 184; -pub const RGFW_keyPad8: c_int = 185; -pub const RGFW_keyPad9: c_int = 186; -pub const RGFW_keyPad0: c_int = 187; -pub const RGFW_keyPadPeriod: c_int = 188; -pub const RGFW_keyPadReturn: c_int = 189; -pub const RGFW_keyScrollLock: c_int = 190; -pub const RGFW_keyPrintScreen: c_int = 191; -pub const RGFW_keyPause: c_int = 192; -pub const RGFW_keyWorld1: c_int = 193; -pub const RGFW_keyWorld2: c_int = 194; -pub const RGFW_keyLast: c_int = 256; -pub const enum_RGFW_key_enum = c_uint; -pub const RGFW_mouseButton = @"u8"; -pub const RGFW_mouseLeft: c_int = 0; -pub const RGFW_mouseMiddle: c_int = 1; -pub const RGFW_mouseRight: c_int = 2; -pub const RGFW_mouseMisc1: c_int = 3; -pub const RGFW_mouseMisc2: c_int = 4; -pub const RGFW_mouseMisc3: c_int = 5; -pub const RGFW_mouseMisc4: c_int = 6; -pub const RGFW_mouseMisc5: c_int = 7; -pub const RGFW_mouseFinal: c_int = 8; -pub const enum_RGFW_mouseButton_enum = c_uint; -pub const RGFW_keymod = @"u8"; -pub const RGFW_modCapsLock: c_int = 1; -pub const RGFW_modNumLock: c_int = 2; -pub const RGFW_modControl: c_int = 4; -pub const RGFW_modAlt: c_int = 8; -pub const RGFW_modShift: c_int = 16; -pub const RGFW_modSuper: c_int = 32; -pub const RGFW_modScrollLock: c_int = 64; -pub const enum_RGFW_keymod_enum = c_uint; -pub const RGFW_dndActionType = @"u8"; -pub const RGFW_dndActionNone: c_int = 0; -pub const RGFW_dndActionEnter: c_int = 1; -pub const RGFW_dndActionMove: c_int = 2; -pub const RGFW_dndActionExit: c_int = 3; -pub const enum_RGFW_dndActionType_enum = c_uint; -pub const RGFW_dataTransferType = @"u8"; -pub const RGFW_dataNone: c_int = 0; -pub const RGFW_dataText: c_int = 1; -pub const RGFW_dataFile: c_int = 2; -pub const RGFW_dataURL: c_int = 3; -pub const RGFW_dataImage: c_int = 4; -pub const RGFW_dataUnknown: c_int = 5; -pub const enum_RGFW_dataTransferType_enum = c_uint; -pub const struct_RGFW_dataTransfer = extern struct { - data: [*c]const u8 = null, - length: usize = 0, - type: RGFW_dataTransferType = 0, - pub const RGFW_writeClipboard = __root.RGFW_writeClipboard; - pub const writeClipboard = __root.RGFW_writeClipboard; -}; -pub const RGFW_dataTransfer = struct_RGFW_dataTransfer; -pub const struct_RGFW_dataDropNode = extern struct { - data: [*c]const u8 = null, - length: usize = 0, - type: RGFW_dataTransferType = 0, - next: [*c]struct_RGFW_dataDropNode = null, -}; -pub const RGFW_dataDropNode = struct_RGFW_dataDropNode; -pub const RGFW_eventType = @"u8"; -pub const RGFW_eventNone: c_int = 0; -pub const RGFW_keyPressed: c_int = 1; -pub const RGFW_keyReleased: c_int = 2; -pub const RGFW_keyChar: c_int = 3; -pub const RGFW_mouseButtonPressed: c_int = 4; -pub const RGFW_mouseButtonReleased: c_int = 5; -pub const RGFW_mouseScroll: c_int = 6; -pub const RGFW_mouseMotion: c_int = 7; -pub const RGFW_mouseRawMotion: c_int = 8; -pub const RGFW_mouseEnter: c_int = 9; -pub const RGFW_mouseLeave: c_int = 10; -pub const RGFW_windowMoved: c_int = 11; -pub const RGFW_windowResized: c_int = 12; -pub const RGFW_windowFocusIn: c_int = 13; -pub const RGFW_windowFocusOut: c_int = 14; -pub const RGFW_windowRefresh: c_int = 15; -pub const RGFW_windowClose: c_int = 16; -pub const RGFW_windowMaximized: c_int = 17; -pub const RGFW_windowMinimized: c_int = 18; -pub const RGFW_windowRestored: c_int = 19; -pub const RGFW_dataDrop: c_int = 20; -pub const RGFW_dataDrag: c_int = 21; -pub const RGFW_scaleUpdated: c_int = 22; -pub const RGFW_monitorConnected: c_int = 23; -pub const RGFW_monitorDisconnected: c_int = 24; -pub const RGFW_eventCount: c_int = 25; -pub const RGFW_mousePosChanged: c_int = 7; -pub const enum_RGFW_eventType_enum = c_uint; -pub const RGFW_eventFlag = @"u32"; -pub const RGFW_keyPressedFlag: c_int = 2; -pub const RGFW_keyReleasedFlag: c_int = 4; -pub const RGFW_keyCharFlag: c_int = 8; -pub const RGFW_mouseScrollFlag: c_int = 64; -pub const RGFW_mouseButtonPressedFlag: c_int = 16; -pub const RGFW_mouseButtonReleasedFlag: c_int = 32; -pub const RGFW_mouseMotionFlag: c_int = 128; -pub const RGFW_mouseRawMotionFlag: c_int = 256; -pub const RGFW_mouseEnterFlag: c_int = 512; -pub const RGFW_mouseLeaveFlag: c_int = 1024; -pub const RGFW_windowMovedFlag: c_int = 2048; -pub const RGFW_windowResizedFlag: c_int = 4096; -pub const RGFW_windowFocusInFlag: c_int = 8192; -pub const RGFW_windowFocusOutFlag: c_int = 16384; -pub const RGFW_windowRefreshFlag: c_int = 32768; -pub const RGFW_windowMaximizedFlag: c_int = 131072; -pub const RGFW_windowMinimizedFlag: c_int = 262144; -pub const RGFW_windowRestoredFlag: c_int = 524288; -pub const RGFW_scaleUpdatedFlag: c_int = 4194304; -pub const RGFW_windowCloseFlag: c_int = 65536; -pub const RGFW_dataDropFlag: c_int = 1048576; -pub const RGFW_dataDragFlag: c_int = 2097152; -pub const RGFW_monitorConnectedFlag: c_int = 8388608; -pub const RGFW_monitorDisconnectedFlag: c_int = 16777216; -pub const RGFW_mousePosChangedFlag: c_int = 128; -pub const RGFW_keyEventsFlag: c_int = 14; -pub const RGFW_mouseEventsFlag: c_int = 2032; -pub const RGFW_windowEventsFlag: c_int = 5150720; -pub const RGFW_windowFocusEventsFlag: c_int = 24576; -pub const RGFW_dataDragDropEventsFlag: c_int = 3145728; -pub const RGFW_monitorEventsFlag: c_int = 25165824; -pub const RGFW_allEventFlags: c_int = 33554430; -pub const enum_RGFW_eventFlag_enum = c_uint; -pub const struct_RGFW_commonEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, -}; -pub const RGFW_commonEvent = struct_RGFW_commonEvent; -pub const struct_RGFW_windowFocusEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - state: RGFW_bool = 0, -}; -pub const RGFW_windowFocusEvent = struct_RGFW_windowFocusEvent; -pub const struct_RGFW_mouseButtonEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - value: RGFW_mouseButton = 0, - state: RGFW_bool = 0, -}; -pub const RGFW_mouseButtonEvent = struct_RGFW_mouseButtonEvent; -pub const struct_RGFW_mouseDeltaEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - x: f32 = 0, - y: f32 = 0, -}; -pub const RGFW_mouseDeltaEvent = struct_RGFW_mouseDeltaEvent; -pub const struct_RGFW_mouseMotionEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - x: @"i32" = 0, - y: @"i32" = 0, - inWindow: RGFW_bool = 0, -}; -pub const RGFW_mouseMotionEvent = struct_RGFW_mouseMotionEvent; -pub const struct_RGFW_keyEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - value: RGFW_key = 0, - repeat: RGFW_bool = 0, - mod: RGFW_keymod = 0, - state: RGFW_bool = 0, -}; -pub const RGFW_keyEvent = struct_RGFW_keyEvent; -pub const struct_RGFW_keyCharEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - value: @"u32" = 0, -}; -pub const RGFW_keyCharEvent = struct_RGFW_keyCharEvent; -pub const struct_RGFW_dataDropEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - value: [*c]const RGFW_dataDropNode = null, -}; -pub const RGFW_dataDropEvent = struct_RGFW_dataDropEvent; -pub const struct_RGFW_dataDragEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - x: @"i32" = 0, - y: @"i32" = 0, - action: RGFW_dndActionType = 0, - dataType: RGFW_dataTransferType = 0, -}; -pub const RGFW_dataDragEvent = struct_RGFW_dataDragEvent; -pub const struct_RGFW_scaleUpdatedEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - x: f32 = 0, - y: f32 = 0, -}; -pub const RGFW_scaleUpdatedEvent = struct_RGFW_scaleUpdatedEvent; -pub const struct_RGFW_monitorEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - monitor: [*c]const RGFW_monitor = null, - state: RGFW_bool = 0, -}; -pub const RGFW_monitorEvent = struct_RGFW_monitorEvent; -pub const struct_RGFW_windowUpdateEvent = extern struct { - type: RGFW_eventType = 0, - win: ?*RGFW_window = null, - x: @"i32" = 0, - y: @"i32" = 0, - w: @"i32" = 0, - h: @"i32" = 0, -}; -pub const RGFW_windowUpdateEvent = struct_RGFW_windowUpdateEvent; -pub const union_RGFW_event = extern union { - type: RGFW_eventType, - common: RGFW_commonEvent, - focus: RGFW_windowFocusEvent, - update: RGFW_windowUpdateEvent, - button: RGFW_mouseButtonEvent, - delta: RGFW_mouseDeltaEvent, - mouse: RGFW_mouseMotionEvent, - key: RGFW_keyEvent, - keyChar: RGFW_keyCharEvent, - drop: RGFW_dataDropEvent, - drag: RGFW_dataDragEvent, - scale: RGFW_scaleUpdatedEvent, - monitor: RGFW_monitorEvent, - pub const RGFW_checkEvent = __root.RGFW_checkEvent; - pub const RGFW_checkQueuedEvent = __root.RGFW_checkQueuedEvent; - pub const RGFW_eventQueuePush = __root.RGFW_eventQueuePush; - pub const RGFW_eventQueuePushAndCall = __root.RGFW_eventQueuePushAndCall; - pub const checkEvent = __root.RGFW_checkEvent; - pub const checkQueuedEvent = __root.RGFW_checkQueuedEvent; - pub const eventQueuePush = __root.RGFW_eventQueuePush; - pub const eventQueuePushAndCall = __root.RGFW_eventQueuePushAndCall; -}; -pub const RGFW_event = union_RGFW_event; -pub const RGFW_eventWait = @"i32"; -pub const RGFW_eventNoWait: c_int = 0; -pub const RGFW_eventWaitNext: c_int = -1; -pub const enum_RGFW_eventWait_enum = c_int; -pub const RGFW_genericFunc = ?*const fn (e: [*c]const RGFW_event) callconv(.c) void; -pub const struct_RGFW_callbacks = extern struct { - arr: [25]RGFW_genericFunc = @import("std").mem.zeroes([25]RGFW_genericFunc), -}; -pub const RGFW_callbacks = struct_RGFW_callbacks; -pub const RGFW_windowFlags = @"u32"; -pub const RGFW_windowNoBorder: c_int = 1; -pub const RGFW_windowNoResize: c_int = 2; -pub const RGFW_windowAllowDND: c_int = 4; -pub const RGFW_windowHideMouse: c_int = 8; -pub const RGFW_windowFullscreen: c_int = 16; -pub const RGFW_windowTranslucent: c_int = 32; -pub const RGFW_windowTransparent: c_int = 32; -pub const RGFW_windowCenter: c_int = 64; -pub const RGFW_windowRawMouse: c_int = 128; -pub const RGFW_windowScaleToMonitor: c_int = 256; -pub const RGFW_windowHide: c_int = 512; -pub const RGFW_windowMaximize: c_int = 1024; -pub const RGFW_windowCenterCursor: c_int = 2048; -pub const RGFW_windowFloating: c_int = 4096; -pub const RGFW_windowFocusOnShow: c_int = 8192; -pub const RGFW_windowMinimize: c_int = 16384; -pub const RGFW_windowFocus: c_int = 32768; -pub const RGFW_windowCaptureMouse: c_int = 65536; -pub const RGFW_windowOpenGL: c_int = 131072; -pub const RGFW_windowEGL: c_int = 262144; -pub const RGFW_noDeinitOnClose: c_int = 524288; -pub const RGFW_windowedFullscreen: c_int = 1025; -pub const RGFW_windowCaptureRawMouse: c_int = 65664; -pub const enum_RGFW_windowFlags_enum = c_uint; -pub const RGFW_icon = @"u8"; -pub const RGFW_iconTaskbar: c_int = 1; -pub const RGFW_iconWindow: c_int = 2; -pub const RGFW_iconBoth: c_int = 3; -pub const enum_RGFW_icon_enum = c_uint; -pub const RGFW_mouseIcon = @"u8"; -pub const RGFW_mouseNormal: c_int = 0; -pub const RGFW_mouseArrow: c_int = 1; -pub const RGFW_mouseIbeam: c_int = 2; -pub const RGFW_mouseText: c_int = 2; -pub const RGFW_mouseCrosshair: c_int = 3; -pub const RGFW_mousePointingHand: c_int = 4; -pub const RGFW_mouseResizeEW: c_int = 5; -pub const RGFW_mouseResizeNS: c_int = 6; -pub const RGFW_mouseResizeNWSE: c_int = 7; -pub const RGFW_mouseResizeNESW: c_int = 8; -pub const RGFW_mouseResizeNW: c_int = 9; -pub const RGFW_mouseResizeN: c_int = 10; -pub const RGFW_mouseResizeNE: c_int = 11; -pub const RGFW_mouseResizeE: c_int = 12; -pub const RGFW_mouseResizeSE: c_int = 13; -pub const RGFW_mouseResizeS: c_int = 14; -pub const RGFW_mouseResizeSW: c_int = 15; -pub const RGFW_mouseResizeW: c_int = 16; -pub const RGFW_mouseResizeAll: c_int = 17; -pub const RGFW_mouseNotAllowed: c_int = 18; -pub const RGFW_mouseWait: c_int = 19; -pub const RGFW_mouseProgress: c_int = 20; -pub const RGFW_mouseIconCount: c_int = 21; -pub const RGFW_mouseIconFinal: c_int = 16; -pub const enum_RGFW_mouseIcon_enum = c_uint; -pub const RGFW_flashRequest = @"u8"; -pub const RGFW_flashCancel: c_int = 0; -pub const RGFW_flashBriefly: c_int = 1; -pub const RGFW_flashUntilFocused: c_int = 2; -pub const enum_RGFW_flashRequest_enum = c_uint; -pub const RGFW_debugType = @"u8"; -pub const RGFW_typeError: c_int = 0; -pub const RGFW_typeWarning: c_int = 1; -pub const RGFW_typeInfo: c_int = 2; -pub const enum_RGFW_debugType_enum = c_uint; -pub const RGFW_errorCode = @"u8"; -pub const RGFW_noError: c_int = 0; -pub const RGFW_errOutOfMemory: c_int = 1; -pub const RGFW_errOpenGLContext: c_int = 2; -pub const RGFW_errEGLContext: c_int = 3; -pub const RGFW_errWayland: c_int = 4; -pub const RGFW_errX11: c_int = 5; -pub const RGFW_errDirectXContext: c_int = 6; -pub const RGFW_errIOKit: c_int = 7; -pub const RGFW_errClipboard: c_int = 8; -pub const RGFW_errFailedFuncLoad: c_int = 9; -pub const RGFW_errBuffer: c_int = 10; -pub const RGFW_errMetal: c_int = 11; -pub const RGFW_errPlatform: c_int = 12; -pub const RGFW_errEventQueue: c_int = 13; -pub const RGFW_infoWindow: c_int = 14; -pub const RGFW_infoBuffer: c_int = 15; -pub const RGFW_infoGlobal: c_int = 16; -pub const RGFW_infoOpenGL: c_int = 17; -pub const RGFW_warningWayland: c_int = 18; -pub const RGFW_warningOpenGL: c_int = 19; -pub const enum_RGFW_errorCode_enum = c_uint; -pub const struct_RGFW_debugInfo = extern struct { - type: RGFW_debugType = 0, - code: RGFW_errorCode = 0, - msg: [*c]const u8 = null, -}; -pub const RGFW_debugInfo = struct_RGFW_debugInfo; -pub const RGFW_debugFunc = ?*const fn (info: [*c]const RGFW_debugInfo) callconv(.c) void; -pub const RGFW_proc = ?*const fn () callconv(.c) void; -pub const struct_RGFW_glContext = opaque { - pub const RGFW_glContext_getSourceContext = __root.RGFW_glContext_getSourceContext; - pub const getSourceContext = __root.RGFW_glContext_getSourceContext; -}; -pub const RGFW_glContext = struct_RGFW_glContext; -pub const struct_RGFW_eglContext = opaque {}; -pub const RGFW_eglContext = struct_RGFW_eglContext; -pub const RGFW_glReleaseBehavior = @"i32"; -pub const RGFW_glReleaseFlush: c_int = 0; -pub const RGFW_glReleaseNone: c_int = 1; -pub const enum_RGFW_glReleaseBehavior_enum = c_uint; -pub const RGFW_glProfile = @"i32"; -pub const RGFW_glCore: c_int = 0; -pub const RGFW_glForwardCompatibility: c_int = 1; -pub const RGFW_glCompatibility: c_int = 2; -pub const RGFW_glES: c_int = 3; -pub const RGFW_glWeb: c_int = 4; -pub const enum_RGFW_glProfile_enum = c_uint; -pub const RGFW_glRenderer = @"i32"; -pub const RGFW_glAccelerated: c_int = 0; -pub const RGFW_glSoftware: c_int = 1; -pub const enum_RGFW_glRenderer_enum = c_uint; -pub const struct_RGFW_glHints = extern struct { - stencil: @"i32" = 0, - samples: @"i32" = 0, - stereo: @"i32" = 0, - auxBuffers: @"i32" = 0, - doubleBuffer: @"i32" = 0, - red: @"i32" = 0, - green: @"i32" = 0, - blue: @"i32" = 0, - alpha: @"i32" = 0, - depth: @"i32" = 0, - accumRed: @"i32" = 0, - accumGreen: @"i32" = 0, - accumBlue: @"i32" = 0, - accumAlpha: @"i32" = 0, - sRGB: RGFW_bool = 0, - robustness: RGFW_bool = 0, - debug: RGFW_bool = 0, - noError: RGFW_bool = 0, - releaseBehavior: RGFW_glReleaseBehavior = 0, - profile: RGFW_glProfile = 0, - major: @"i32" = 0, - minor: @"i32" = 0, - share: ?*RGFW_glContext = null, - shareEGL: ?*RGFW_eglContext = null, - renderer: RGFW_glRenderer = 0, - pub const RGFW_setGlobalHints_OpenGL = __root.RGFW_setGlobalHints_OpenGL; - pub const OpenGL = __root.RGFW_setGlobalHints_OpenGL; -}; -pub const RGFW_glHints = struct_RGFW_glHints; -pub extern fn RGFW_alloc(size: usize) ?*anyopaque; -pub extern fn RGFW_free(ptr: ?*anyopaque) void; -pub extern fn RGFW_sizeofWindow() usize; -pub extern fn RGFW_sizeofWindowSrc() usize; -pub extern fn RGFW_useWayland(wayland: RGFW_bool) void; -pub extern fn RGFW_usingWayland() RGFW_bool; -pub extern fn RGFW_getLayer_OSX() ?*anyopaque; -pub extern fn RGFW_getDisplay_X11() ?*anyopaque; -pub const struct_wl_display = opaque {}; -pub extern fn RGFW_getDisplay_Wayland() ?*struct_wl_display; -pub extern fn RGFW_setClassName(name: [*c]const u8) void; -pub extern fn RGFW_setXInstName(name: [*c]const u8) void; -pub extern fn RGFW_moveToMacOSResourceDir() void; -pub extern fn RGFW_copyImageData(dest_data: [*c]@"u8", w: @"i32", h: @"i32", dest_format: RGFW_format, src_data: [*c]@"u8", src_format: RGFW_format, func: RGFW_convertImageDataFunc) void; -pub extern fn RGFW_sizeofNativeImage() usize; -pub extern fn RGFW_sizeofSurface() usize; -pub extern fn RGFW_nativeFormat() RGFW_format; -pub extern fn RGFW_createSurface(data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format) ?*RGFW_surface; -pub extern fn RGFW_createSurfacePtr(data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format, surface: ?*RGFW_surface) RGFW_bool; -pub extern fn RGFW_surface_getNativeImage(surface: ?*RGFW_surface) ?*RGFW_nativeImage; -pub extern fn RGFW_surface_free(surface: ?*RGFW_surface) void; -pub extern fn RGFW_surface_freePtr(surface: ?*RGFW_surface) void; -pub extern fn RGFW_createMouse(data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format) ?*RGFW_mouse; -pub extern fn RGFW_createMouseStandard(mouse: RGFW_mouseIcon) ?*RGFW_mouse; -pub extern fn RGFW_freeMouse(mouse: ?*RGFW_mouse) void; -pub extern fn RGFW_monitor_getModes(monitor: [*c]RGFW_monitor, count: [*c]usize) [*c]RGFW_monitorMode; -pub extern fn RGFW_freeModes(modes: [*c]RGFW_monitorMode) void; -pub extern fn RGFW_monitor_getModesPtr(monitor: [*c]RGFW_monitor, modes: [*c][*c]RGFW_monitorMode) usize; -pub extern fn RGFW_monitor_findClosestMode(monitor: [*c]RGFW_monitor, mode: [*c]RGFW_monitorMode, closest: [*c]RGFW_monitorMode) RGFW_bool; -pub extern fn RGFW_monitor_getGammaRamp(monitor: [*c]RGFW_monitor) [*c]RGFW_gammaRamp; -pub extern fn RGFW_freeGammaRamp(ramp: [*c]RGFW_gammaRamp) void; -pub extern fn RGFW_monitor_getGammaRampPtr(monitor: [*c]RGFW_monitor, ramp: [*c]RGFW_gammaRamp) usize; -pub extern fn RGFW_monitor_setGammaRamp(monitor: [*c]RGFW_monitor, ramp: [*c]RGFW_gammaRamp) RGFW_bool; -pub extern fn RGFW_monitor_setGamma(monitor: [*c]RGFW_monitor, gamma: f32) RGFW_bool; -pub extern fn RGFW_monitor_setGammaPtr(monitor: [*c]RGFW_monitor, gamma: f32, ptr: [*c]@"u16", count: usize) RGFW_bool; -pub extern fn RGFW_monitor_getWorkarea(monitor: [*c]RGFW_monitor, x: [*c]@"i32", y: [*c]@"i32", width: [*c]@"i32", height: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_monitor_getPosition(monitor: [*c]RGFW_monitor, x: [*c]@"i32", y: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_monitor_getName(monitor: [*c]RGFW_monitor) [*c]const u8; -pub extern fn RGFW_monitor_getScale(monitor: [*c]RGFW_monitor, x: [*c]f32, y: [*c]f32) RGFW_bool; -pub extern fn RGFW_monitor_getPhysicalSize(monitor: [*c]RGFW_monitor, w: [*c]f32, h: [*c]f32) RGFW_bool; -pub extern fn RGFW_monitor_setUserPtr(monitor: [*c]RGFW_monitor, userPtr: ?*anyopaque) void; -pub extern fn RGFW_monitor_getUserPtr(monitor: [*c]RGFW_monitor) ?*anyopaque; -pub extern fn RGFW_monitor_getMode(monitor: [*c]RGFW_monitor, mode: [*c]RGFW_monitorMode) RGFW_bool; -pub extern fn RGFW_pollMonitors() void; -pub extern fn RGFW_getMonitors(len: [*c]usize) [*c][*c]RGFW_monitor; -pub extern fn RGFW_getMonitorsPtr(max: usize, monitors: [*c][*c]RGFW_monitor, len: [*c]usize) RGFW_bool; -pub extern fn RGFW_getPrimaryMonitor() [*c]RGFW_monitor; -pub extern fn RGFW_monitor_requestMode(mon: [*c]RGFW_monitor, mode: [*c]RGFW_monitorMode, request: RGFW_modeRequest) RGFW_bool; -pub extern fn RGFW_monitor_setMode(mon: [*c]RGFW_monitor, mode: [*c]RGFW_monitorMode) RGFW_bool; -pub extern fn RGFW_monitorModeCompare(mon: [*c]RGFW_monitorMode, mon2: [*c]RGFW_monitorMode, request: RGFW_modeRequest) RGFW_bool; -pub extern fn RGFW_monitor_scaleToWindow(mon: [*c]RGFW_monitor, win: ?*struct_RGFW_window) RGFW_bool; -pub extern fn RGFW_setRawMouseMode(state: RGFW_bool) void; -pub extern fn RGFW_setBuildDND(allow: RGFW_bool) void; -pub extern fn RGFW_waitForEvent(waitMS: @"i32") void; -pub extern fn RGFW_setQueueEvents(queue: RGFW_bool) void; -pub extern fn RGFW_setEventCallback(@"type": RGFW_eventType, func: RGFW_genericFunc) RGFW_genericFunc; -pub extern fn RGFW_setDualEventCallback(@"type": RGFW_eventType, func: RGFW_genericFunc, first: [*c]RGFW_genericFunc, second: [*c]RGFW_genericFunc) void; -pub extern fn RGFW_setAllEventCallbacks(func: RGFW_genericFunc, callbacks: [*c]RGFW_callbacks) void; -pub extern fn RGFW_pollEvents() void; -pub extern fn RGFW_stopCheckEvents() void; -pub extern fn RGFW_checkEvent(event: [*c]RGFW_event) RGFW_bool; -pub extern fn RGFW_checkQueuedEvent(event: [*c]RGFW_event) RGFW_bool; -pub extern fn RGFW_isKeyPressed(key: RGFW_key) RGFW_bool; -pub extern fn RGFW_isKeyReleased(key: RGFW_key) RGFW_bool; -pub extern fn RGFW_isKeyDown(key: RGFW_key) RGFW_bool; -pub extern fn RGFW_isMousePressed(button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_isMouseReleased(button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_isMouseDown(button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_getMouseScroll(x: [*c]f32, y: [*c]f32) void; -pub extern fn RGFW_getMouseVector(x: [*c]f32, y: [*c]f32) void; -pub extern fn RGFW_createWindow(name: [*c]const u8, x: @"i32", y: @"i32", w: @"i32", h: @"i32", flags: RGFW_windowFlags) ?*RGFW_window; -pub extern fn RGFW_createWindowPtr(name: [*c]const u8, x: @"i32", y: @"i32", w: @"i32", h: @"i32", flags: RGFW_windowFlags, win: ?*RGFW_window) ?*RGFW_window; -pub extern fn RGFW_window_createSurface(win: ?*RGFW_window, data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format) ?*RGFW_surface; -pub extern fn RGFW_window_createSurfacePtr(win: ?*RGFW_window, data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format, surface: ?*RGFW_surface) RGFW_bool; -pub extern fn RGFW_surface_setConvertFunc(surface: ?*RGFW_surface, func: RGFW_convertImageDataFunc) void; -pub extern fn RGFW_window_blitSurface(win: ?*RGFW_window, surface: ?*RGFW_surface) void; -pub extern fn RGFW_window_getPosition(win: ?*RGFW_window, x: [*c]@"i32", y: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_getSize(win: ?*RGFW_window, w: [*c]@"i32", h: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_getSizeInPixels(win: ?*RGFW_window, w: [*c]@"i32", h: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_getFlags(win: ?*RGFW_window) @"u32"; -pub extern fn RGFW_window_getExitKey(win: ?*RGFW_window) RGFW_key; -pub extern fn RGFW_window_setExitKey(win: ?*RGFW_window, key: RGFW_key) void; -pub extern fn RGFW_window_setEnabledEvents(win: ?*RGFW_window, events: RGFW_eventFlag) void; -pub extern fn RGFW_window_getEnabledEvents(win: ?*RGFW_window) RGFW_eventFlag; -pub extern fn RGFW_window_setDisabledEvents(win: ?*RGFW_window, events: RGFW_eventFlag) void; -pub extern fn RGFW_window_setEventState(win: ?*RGFW_window, event: RGFW_eventFlag, state: RGFW_bool) void; -pub extern fn RGFW_window_getUserPtr(win: ?*RGFW_window) ?*anyopaque; -pub extern fn RGFW_window_setUserPtr(win: ?*RGFW_window, ptr: ?*anyopaque) void; -pub extern fn RGFW_window_getSrc(win: ?*RGFW_window) ?*RGFW_window_src; -pub extern fn RGFW_window_setLayer_OSX(win: ?*RGFW_window, layer: ?*anyopaque) void; -pub extern fn RGFW_window_getView_OSX(win: ?*RGFW_window) ?*anyopaque; -pub extern fn RGFW_window_getWindow_OSX(win: ?*RGFW_window) ?*anyopaque; -pub extern fn RGFW_window_getHWND(win: ?*RGFW_window) ?*anyopaque; -pub extern fn RGFW_window_getHDC(win: ?*RGFW_window) ?*anyopaque; -pub extern fn RGFW_window_getWindow_X11(win: ?*RGFW_window) @"u64"; -pub const struct_wl_surface = opaque {}; -pub extern fn RGFW_window_getWindow_Wayland(win: ?*RGFW_window) ?*struct_wl_surface; -pub extern fn RGFW_window_setFlags(win: ?*RGFW_window, RGFW_windowFlags) void; -pub extern fn RGFW_window_checkEvent(win: ?*RGFW_window, event: [*c]RGFW_event) RGFW_bool; -pub extern fn RGFW_window_checkQueuedEvent(win: ?*RGFW_window, event: [*c]RGFW_event) RGFW_bool; -pub extern fn RGFW_window_isKeyPressed(win: ?*RGFW_window, key: RGFW_key) RGFW_bool; -pub extern fn RGFW_window_isKeyDown(win: ?*RGFW_window, key: RGFW_key) RGFW_bool; -pub extern fn RGFW_window_isKeyReleased(win: ?*RGFW_window, key: RGFW_key) RGFW_bool; -pub extern fn RGFW_window_isMousePressed(win: ?*RGFW_window, button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_window_isMouseDown(win: ?*RGFW_window, button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_window_isMouseReleased(win: ?*RGFW_window, button: RGFW_mouseButton) RGFW_bool; -pub extern fn RGFW_window_didMouseLeave(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_didMouseEnter(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isMouseInside(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isDataDragging(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_getDataDrag(win: ?*RGFW_window, x: [*c]@"i32", y: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_didDataDrop(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_getDataDrop(win: ?*RGFW_window) [*c]RGFW_dataDropNode; -pub extern fn RGFW_window_close(win: ?*RGFW_window) void; -pub extern fn RGFW_window_closePtr(win: ?*RGFW_window) void; -pub extern fn RGFW_window_fetchSize(win: ?*RGFW_window, w: [*c]@"i32", h: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_move(win: ?*RGFW_window, x: @"i32", y: @"i32") void; -pub extern fn RGFW_window_moveToMonitor(win: ?*RGFW_window, m: [*c]RGFW_monitor) void; -pub extern fn RGFW_window_resize(win: ?*RGFW_window, w: @"i32", h: @"i32") void; -pub extern fn RGFW_window_setAspectRatio(win: ?*RGFW_window, w: @"i32", h: @"i32") void; -pub extern fn RGFW_window_setMinSize(win: ?*RGFW_window, w: @"i32", h: @"i32") void; -pub extern fn RGFW_window_setMaxSize(win: ?*RGFW_window, w: @"i32", h: @"i32") void; -pub extern fn RGFW_window_focus(win: ?*RGFW_window) void; -pub extern fn RGFW_window_isInFocus(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_raise(win: ?*RGFW_window) void; -pub extern fn RGFW_window_maximize(win: ?*RGFW_window) void; -pub extern fn RGFW_window_setFullscreen(win: ?*RGFW_window, fullscreen: RGFW_bool) void; -pub extern fn RGFW_window_center(win: ?*RGFW_window) void; -pub extern fn RGFW_window_minimize(win: ?*RGFW_window) void; -pub extern fn RGFW_window_restore(win: ?*RGFW_window) void; -pub extern fn RGFW_window_setFloating(win: ?*RGFW_window, floating: RGFW_bool) void; -pub extern fn RGFW_window_setOpacity(win: ?*RGFW_window, opacity: @"u8") void; -pub extern fn RGFW_window_setBorder(win: ?*RGFW_window, border: RGFW_bool) void; -pub extern fn RGFW_window_borderless(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_setDND(win: ?*RGFW_window, allow: RGFW_bool) void; -pub extern fn RGFW_window_allowsDND(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_setMousePassthrough(win: ?*RGFW_window, passthrough: RGFW_bool) void; -pub extern fn RGFW_window_setName(win: ?*RGFW_window, name: [*c]const u8) void; -pub extern fn RGFW_window_setIcon(win: ?*RGFW_window, data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format) RGFW_bool; -pub extern fn RGFW_window_setIconEx(win: ?*RGFW_window, data: [*c]@"u8", w: @"i32", h: @"i32", format: RGFW_format, @"type": RGFW_icon) RGFW_bool; -pub extern fn RGFW_window_setMouse(win: ?*RGFW_window, mouse: ?*RGFW_mouse) RGFW_bool; -pub extern fn RGFW_window_setMouseStandard(win: ?*RGFW_window, icon: RGFW_mouseIcon) RGFW_bool; -pub extern fn RGFW_window_setMouseDefault(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_setRawMouseMode(win: ?*RGFW_window, state: RGFW_bool) void; -pub extern fn RGFW_window_captureMouse(win: ?*RGFW_window, state: RGFW_bool) void; -pub extern fn RGFW_window_captureRawMouse(win: ?*RGFW_window, state: RGFW_bool) void; -pub extern fn RGFW_window_isRawMouseMode(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isCaptured(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_hide(win: ?*RGFW_window) void; -pub extern fn RGFW_window_show(win: ?*RGFW_window) void; -pub extern fn RGFW_window_flash(win: ?*RGFW_window, request: RGFW_flashRequest) void; -pub extern fn RGFW_window_setShouldClose(win: ?*RGFW_window, shouldClose: RGFW_bool) void; -pub extern fn RGFW_getGlobalMouse(x: [*c]@"i32", y: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_getMouse(win: ?*RGFW_window, x: [*c]@"i32", y: [*c]@"i32") RGFW_bool; -pub extern fn RGFW_window_showMouse(win: ?*RGFW_window, show: RGFW_bool) void; -pub extern fn RGFW_window_isMouseHidden(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_moveMouse(win: ?*RGFW_window, x: @"i32", y: @"i32") void; -pub extern fn RGFW_window_shouldClose(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isFullscreen(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isHidden(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isMinimized(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isMaximized(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_isFloating(win: ?*RGFW_window) RGFW_bool; -pub extern fn RGFW_window_scaleToMonitor(win: ?*RGFW_window) void; -pub extern fn RGFW_window_getMonitor(win: ?*RGFW_window) [*c]RGFW_monitor; -pub extern fn RGFW_readClipboard() [*c]const RGFW_dataTransfer; -pub extern fn RGFW_readClipboardPtr(buffer: [*c]@"u8", capacity: usize, data: [*c]RGFW_dataTransfer) RGFW_bool; -pub extern fn RGFW_writeClipboard(data: [*c]const RGFW_dataTransfer) RGFW_bool; -pub extern fn RGFW_setDebugCallback(func: RGFW_debugFunc) RGFW_debugFunc; -pub extern fn RGFW_debugCallback(@"type": RGFW_debugType, code: RGFW_errorCode, msg: [*c]const u8) void; -pub extern fn RGFW_setGlobalHints_OpenGL(hints: [*c]RGFW_glHints) void; -pub extern fn RGFW_resetGlobalHints_OpenGL() void; -pub extern fn RGFW_getGlobalHints_OpenGL() [*c]RGFW_glHints; -pub extern fn RGFW_window_createContext_OpenGL(win: ?*RGFW_window, hints: [*c]RGFW_glHints) ?*RGFW_glContext; -pub extern fn RGFW_window_createContextPtr_OpenGL(win: ?*RGFW_window, ctx: ?*RGFW_glContext, hints: [*c]RGFW_glHints) RGFW_bool; -pub extern fn RGFW_window_getContext_OpenGL(win: ?*RGFW_window) ?*RGFW_glContext; -pub extern fn RGFW_window_deleteContext_OpenGL(win: ?*RGFW_window, ctx: ?*RGFW_glContext) void; -pub extern fn RGFW_window_deleteContextPtr_OpenGL(win: ?*RGFW_window, ctx: ?*RGFW_glContext) void; -pub extern fn RGFW_glContext_getSourceContext(ctx: ?*RGFW_glContext) ?*anyopaque; -pub extern fn RGFW_window_makeCurrentWindow_OpenGL(win: ?*RGFW_window) void; -pub extern fn RGFW_window_makeCurrentContext_OpenGL(win: ?*RGFW_window) void; -pub extern fn RGFW_window_swapBuffers_OpenGL(win: ?*RGFW_window) void; -pub extern fn RGFW_getCurrentContext_OpenGL() ?*anyopaque; -pub extern fn RGFW_getCurrentWindow_OpenGL() ?*RGFW_window; -pub extern fn RGFW_window_swapInterval_OpenGL(win: ?*RGFW_window, swapInterval: @"i32") void; -pub extern fn RGFW_getProcAddress_OpenGL(procname: [*c]const u8) RGFW_proc; -pub extern fn RGFW_extensionSupported_OpenGL(extension: [*c]const u8, len: usize) RGFW_bool; -pub extern fn RGFW_extensionSupportedPlatform_OpenGL(extension: [*c]const u8, len: usize) RGFW_bool; -pub extern fn RGFW_setRootWindow(win: ?*RGFW_window) void; -pub extern fn RGFW_getRootWindow() ?*RGFW_window; -pub extern fn RGFW_eventQueuePush(event: [*c]const RGFW_event) void; -pub extern fn RGFW_eventQueuePushAndCall(event: [*c]const RGFW_event) void; -pub extern fn RGFW_eventQueueFlush() void; -pub extern fn RGFW_eventQueuePop() [*c]RGFW_event; -pub extern fn RGFW_window_eventQueuePop(win: ?*RGFW_window) [*c]RGFW_event; -pub extern fn RGFW_apiKeyToRGFW(keycode: @"u32") RGFW_key; -pub extern fn RGFW_rgfwToApiKey(keycode: RGFW_key) @"u32"; -pub extern fn RGFW_physicalToMappedKey(keycode: RGFW_key) RGFW_key; -pub extern fn RGFW_sizeofInfo() usize; -pub extern fn RGFW_init() @"i32"; -pub extern fn RGFW_deinit() void; -pub extern fn RGFW_init_ptr(info: ?*RGFW_info) @"i32"; -pub extern fn RGFW_deinit_ptr(info: ?*RGFW_info) void; -pub extern fn RGFW_setInfo(info: ?*RGFW_info) void; -pub extern fn RGFW_getInfo() ?*RGFW_info; - -pub const __VERSION__ = "Aro aro-zig"; -pub const __Aro__ = ""; -pub const __STDC__ = @as(c_int, 1); -pub const __STDC_HOSTED__ = @as(c_int, 1); -pub const __STDC_UTF_16__ = @as(c_int, 1); -pub const __STDC_UTF_32__ = @as(c_int, 1); -pub const __STDC_EMBED_NOT_FOUND__ = @as(c_int, 0); -pub const __STDC_EMBED_FOUND__ = @as(c_int, 1); -pub const __STDC_EMBED_EMPTY__ = @as(c_int, 2); -pub const __STDC_VERSION__ = @as(c_long, 201710); -pub const __GNUC__ = @as(c_int, 7); -pub const __GNUC_MINOR__ = @as(c_int, 1); -pub const __GNUC_PATCHLEVEL__ = @as(c_int, 0); -pub const __ARO_EMULATE_NO__ = @as(c_int, 0); -pub const __ARO_EMULATE_CLANG__ = @as(c_int, 1); -pub const __ARO_EMULATE_GCC__ = @as(c_int, 2); -pub const __ARO_EMULATE_MSVC__ = @as(c_int, 3); -pub const __ARO_EMULATE__ = __ARO_EMULATE_GCC__; -pub inline fn __building_module(x: anytype) @TypeOf(@as(c_int, 0)) { - _ = &x; - return @as(c_int, 0); -} -pub const linux = @as(c_int, 1); -pub const __linux = @as(c_int, 1); -pub const __linux__ = @as(c_int, 1); -pub const unix = @as(c_int, 1); -pub const __unix = @as(c_int, 1); -pub const __unix__ = @as(c_int, 1); -pub const __code_model_small__ = @as(c_int, 1); -pub const __amd64__ = @as(c_int, 1); -pub const __amd64 = @as(c_int, 1); -pub const __x86_64__ = @as(c_int, 1); -pub const __x86_64 = @as(c_int, 1); -pub const __SEG_GS = @as(c_int, 1); -pub const __SEG_FS = @as(c_int, 1); -pub const __seg_gs = @compileError("unable to translate macro: undefined identifier `address_space`"); // <builtin>:33:9 -pub const __seg_fs = @compileError("unable to translate macro: undefined identifier `address_space`"); // <builtin>:34:9 -pub const __LAHF_SAHF__ = @as(c_int, 1); -pub const __AES__ = @as(c_int, 1); -pub const __VAES__ = @as(c_int, 1); -pub const __PCLMUL__ = @as(c_int, 1); -pub const __VPCLMULQDQ__ = @as(c_int, 1); -pub const __LZCNT__ = @as(c_int, 1); -pub const __RDRND__ = @as(c_int, 1); -pub const __FSGSBASE__ = @as(c_int, 1); -pub const __BMI__ = @as(c_int, 1); -pub const __BMI2__ = @as(c_int, 1); -pub const __POPCNT__ = @as(c_int, 1); -pub const __PRFCHW__ = @as(c_int, 1); -pub const __RDSEED__ = @as(c_int, 1); -pub const __ADX__ = @as(c_int, 1); -pub const __MOVBE__ = @as(c_int, 1); -pub const __FMA__ = @as(c_int, 1); -pub const __F16C__ = @as(c_int, 1); -pub const __GFNI__ = @as(c_int, 1); -pub const __SHA__ = @as(c_int, 1); -pub const __FXSR__ = @as(c_int, 1); -pub const __XSAVE__ = @as(c_int, 1); -pub const __XSAVEOPT__ = @as(c_int, 1); -pub const __XSAVEC__ = @as(c_int, 1); -pub const __XSAVES__ = @as(c_int, 1); -pub const __PKU__ = @as(c_int, 1); -pub const __CLFLUSHOPT__ = @as(c_int, 1); -pub const __CLWB__ = @as(c_int, 1); -pub const __SHSTK__ = @as(c_int, 1); -pub const __RDPID__ = @as(c_int, 1); -pub const __WAITPKG__ = @as(c_int, 1); -pub const __MOVDIRI__ = @as(c_int, 1); -pub const __MOVDIR64B__ = @as(c_int, 1); -pub const __PTWRITE__ = @as(c_int, 1); -pub const __INVPCID__ = @as(c_int, 1); -pub const __HRESET__ = @as(c_int, 1); -pub const __AVXVNNI__ = @as(c_int, 1); -pub const __SERIALIZE__ = @as(c_int, 1); -pub const __CRC32__ = @as(c_int, 1); -pub const __AVX2__ = @as(c_int, 1); -pub const __AVX__ = @as(c_int, 1); -pub const __SSE4_2__ = @as(c_int, 1); -pub const __SSE4_1__ = @as(c_int, 1); -pub const __SSSE3__ = @as(c_int, 1); -pub const __SSE3__ = @as(c_int, 1); -pub const __SSE2__ = @as(c_int, 1); -pub const __SSE__ = @as(c_int, 1); -pub const __SSE_MATH__ = @as(c_int, 1); -pub const __MMX__ = @as(c_int, 1); -pub const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 = @as(c_int, 1); -pub const __SIZEOF_FLOAT128__ = @as(c_int, 16); -pub const _LP64 = @as(c_int, 1); -pub const __LP64__ = @as(c_int, 1); -pub const __FLOAT128__ = @as(c_int, 1); -pub const __ORDER_LITTLE_ENDIAN__ = @as(c_int, 1234); -pub const __ORDER_BIG_ENDIAN__ = @as(c_int, 4321); -pub const __ORDER_PDP_ENDIAN__ = @as(c_int, 3412); -pub const __BYTE_ORDER__ = __ORDER_LITTLE_ENDIAN__; -pub const __LITTLE_ENDIAN__ = @as(c_int, 1); -pub const __ELF__ = @as(c_int, 1); -pub const __ATOMIC_RELAXED = @as(c_int, 0); -pub const __ATOMIC_CONSUME = @as(c_int, 1); -pub const __ATOMIC_ACQUIRE = @as(c_int, 2); -pub const __ATOMIC_RELEASE = @as(c_int, 3); -pub const __ATOMIC_ACQ_REL = @as(c_int, 4); -pub const __ATOMIC_SEQ_CST = @as(c_int, 5); -pub const __ATOMIC_BOOL_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_CHAR_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_CHAR16_T_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_CHAR32_T_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_WCHAR_T_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_WINT_T_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_SHORT_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_INT_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_LONG_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_LLONG_LOCK_FREE = @as(c_int, 1); -pub const __ATOMIC_POINTER_LOCK_FREE = @as(c_int, 1); -pub const __WINT_UNSIGNED__ = @as(c_int, 1); -pub const __CHAR_BIT__ = @as(c_int, 8); -pub const __BOOL_WIDTH__ = @as(c_int, 8); -pub const __SCHAR_MAX__ = @as(c_int, 127); -pub const __SCHAR_WIDTH__ = @as(c_int, 8); -pub const __SHRT_MAX__ = @as(c_int, 32767); -pub const __SHRT_WIDTH__ = @as(c_int, 16); -pub const __INT_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __INT_WIDTH__ = @as(c_int, 32); -pub const __LONG_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __LONG_WIDTH__ = @as(c_int, 64); -pub const __LONG_LONG_MAX__ = @as(c_longlong, 9223372036854775807); -pub const __LONG_LONG_WIDTH__ = @as(c_int, 64); -pub const __WCHAR_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __WCHAR_WIDTH__ = @as(c_int, 32); -pub const __WINT_MAX__ = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const __WINT_WIDTH__ = @as(c_int, 32); -pub const __INTMAX_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __INTMAX_WIDTH__ = @as(c_int, 64); -pub const __SIZE_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const __SIZE_WIDTH__ = @as(c_int, 64); -pub const __UINTMAX_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const __UINTMAX_WIDTH__ = @as(c_int, 64); -pub const __PTRDIFF_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __PTRDIFF_WIDTH__ = @as(c_int, 64); -pub const __INTPTR_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __INTPTR_WIDTH__ = @as(c_int, 64); -pub const __UINTPTR_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const __UINTPTR_WIDTH__ = @as(c_int, 64); -pub const __SIG_ATOMIC_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __SIG_ATOMIC_WIDTH__ = @as(c_int, 32); -pub const __BITINT_MAXWIDTH__ = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const __SIZEOF_FLOAT__ = @as(c_int, 4); -pub const __SIZEOF_DOUBLE__ = @as(c_int, 8); -pub const __SIZEOF_LONG_DOUBLE__ = @as(c_int, 10); -pub const __SIZEOF_SHORT__ = @as(c_int, 2); -pub const __SIZEOF_INT__ = @as(c_int, 4); -pub const __SIZEOF_LONG__ = @as(c_int, 8); -pub const __SIZEOF_LONG_LONG__ = @as(c_int, 8); -pub const __SIZEOF_POINTER__ = @as(c_int, 8); -pub const __SIZEOF_PTRDIFF_T__ = @as(c_int, 8); -pub const __SIZEOF_SIZE_T__ = @as(c_int, 8); -pub const __SIZEOF_WCHAR_T__ = @as(c_int, 4); -pub const __SIZEOF_WINT_T__ = @as(c_int, 4); -pub const __SIZEOF_INT128__ = @as(c_int, 16); -pub const __INTPTR_TYPE__ = c_long; -pub const __UINTPTR_TYPE__ = c_ulong; -pub const __INTMAX_TYPE__ = c_long; -pub const __INTMAX_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `L`"); // <builtin>:160:9 -pub const __INTMAX_C = __helpers.L_SUFFIX; -pub const __UINTMAX_TYPE__ = c_ulong; -pub const __UINTMAX_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `UL`"); // <builtin>:163:9 -pub const __UINTMAX_C = __helpers.UL_SUFFIX; -pub const __PTRDIFF_TYPE__ = c_long; -pub const __SIZE_TYPE__ = c_ulong; -pub const __WCHAR_TYPE__ = c_int; -pub const __WINT_TYPE__ = c_uint; -pub const __CHAR16_TYPE__ = c_ushort; -pub const __CHAR32_TYPE__ = c_uint; -pub const __INT8_TYPE__ = i8; -pub const __INT8_FMTd__ = "hhd"; -pub const __INT8_FMTi__ = "hhi"; -pub const __INT8_C_SUFFIX__ = ""; -pub inline fn __INT8_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const __INT16_TYPE__ = c_short; -pub const __INT16_FMTd__ = "hd"; -pub const __INT16_FMTi__ = "hi"; -pub const __INT16_C_SUFFIX__ = ""; -pub inline fn __INT16_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const __INT32_TYPE__ = c_int; -pub const __INT32_FMTd__ = "d"; -pub const __INT32_FMTi__ = "i"; -pub const __INT32_C_SUFFIX__ = ""; -pub inline fn __INT32_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const __INT64_TYPE__ = c_long; -pub const __INT64_FMTd__ = "ld"; -pub const __INT64_FMTi__ = "li"; -pub const __INT64_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `L`"); // <builtin>:189:9 -pub const __INT64_C = __helpers.L_SUFFIX; -pub const __UINT8_TYPE__ = u8; -pub const __UINT8_FMTo__ = "hho"; -pub const __UINT8_FMTu__ = "hhu"; -pub const __UINT8_FMTx__ = "hhx"; -pub const __UINT8_FMTX__ = "hhX"; -pub const __UINT8_C_SUFFIX__ = ""; -pub inline fn __UINT8_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const __UINT8_MAX__ = @as(c_int, 255); -pub const __INT8_MAX__ = @as(c_int, 127); -pub const __UINT16_TYPE__ = c_ushort; -pub const __UINT16_FMTo__ = "ho"; -pub const __UINT16_FMTu__ = "hu"; -pub const __UINT16_FMTx__ = "hx"; -pub const __UINT16_FMTX__ = "hX"; -pub const __UINT16_C_SUFFIX__ = ""; -pub inline fn __UINT16_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const __UINT16_MAX__ = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const __INT16_MAX__ = @as(c_int, 32767); -pub const __UINT32_TYPE__ = c_uint; -pub const __UINT32_FMTo__ = "o"; -pub const __UINT32_FMTu__ = "u"; -pub const __UINT32_FMTx__ = "x"; -pub const __UINT32_FMTX__ = "X"; -pub const __UINT32_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `U`"); // <builtin>:214:9 -pub const __UINT32_C = __helpers.U_SUFFIX; -pub const __UINT32_MAX__ = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const __INT32_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __UINT64_TYPE__ = c_ulong; -pub const __UINT64_FMTo__ = "lo"; -pub const __UINT64_FMTu__ = "lu"; -pub const __UINT64_FMTx__ = "lx"; -pub const __UINT64_FMTX__ = "lX"; -pub const __UINT64_C_SUFFIX__ = @compileError("unable to translate macro: undefined identifier `UL`"); // <builtin>:223:9 -pub const __UINT64_C = __helpers.UL_SUFFIX; -pub const __UINT64_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const __INT64_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __INT_LEAST8_TYPE__ = i8; -pub const __INT_LEAST8_MAX__ = @as(c_int, 127); -pub const __INT_LEAST8_WIDTH__ = @as(c_int, 8); -pub const INT_LEAST8_FMTd__ = "hhd"; -pub const INT_LEAST8_FMTi__ = "hhi"; -pub const __UINT_LEAST8_TYPE__ = u8; -pub const __UINT_LEAST8_MAX__ = @as(c_int, 255); -pub const UINT_LEAST8_FMTo__ = "hho"; -pub const UINT_LEAST8_FMTu__ = "hhu"; -pub const UINT_LEAST8_FMTx__ = "hhx"; -pub const UINT_LEAST8_FMTX__ = "hhX"; -pub const __INT_FAST8_TYPE__ = i8; -pub const __INT_FAST8_MAX__ = @as(c_int, 127); -pub const __INT_FAST8_WIDTH__ = @as(c_int, 8); -pub const INT_FAST8_FMTd__ = "hhd"; -pub const INT_FAST8_FMTi__ = "hhi"; -pub const __UINT_FAST8_TYPE__ = u8; -pub const __UINT_FAST8_MAX__ = @as(c_int, 255); -pub const UINT_FAST8_FMTo__ = "hho"; -pub const UINT_FAST8_FMTu__ = "hhu"; -pub const UINT_FAST8_FMTx__ = "hhx"; -pub const UINT_FAST8_FMTX__ = "hhX"; -pub const __INT_LEAST16_TYPE__ = c_short; -pub const __INT_LEAST16_MAX__ = @as(c_int, 32767); -pub const __INT_LEAST16_WIDTH__ = @as(c_int, 16); -pub const INT_LEAST16_FMTd__ = "hd"; -pub const INT_LEAST16_FMTi__ = "hi"; -pub const __UINT_LEAST16_TYPE__ = c_ushort; -pub const __UINT_LEAST16_MAX__ = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const UINT_LEAST16_FMTo__ = "ho"; -pub const UINT_LEAST16_FMTu__ = "hu"; -pub const UINT_LEAST16_FMTx__ = "hx"; -pub const UINT_LEAST16_FMTX__ = "hX"; -pub const __INT_FAST16_TYPE__ = c_short; -pub const __INT_FAST16_MAX__ = @as(c_int, 32767); -pub const __INT_FAST16_WIDTH__ = @as(c_int, 16); -pub const INT_FAST16_FMTd__ = "hd"; -pub const INT_FAST16_FMTi__ = "hi"; -pub const __UINT_FAST16_TYPE__ = c_ushort; -pub const __UINT_FAST16_MAX__ = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const UINT_FAST16_FMTo__ = "ho"; -pub const UINT_FAST16_FMTu__ = "hu"; -pub const UINT_FAST16_FMTx__ = "hx"; -pub const UINT_FAST16_FMTX__ = "hX"; -pub const __INT_LEAST32_TYPE__ = c_int; -pub const __INT_LEAST32_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __INT_LEAST32_WIDTH__ = @as(c_int, 32); -pub const INT_LEAST32_FMTd__ = "d"; -pub const INT_LEAST32_FMTi__ = "i"; -pub const __UINT_LEAST32_TYPE__ = c_uint; -pub const __UINT_LEAST32_MAX__ = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const UINT_LEAST32_FMTo__ = "o"; -pub const UINT_LEAST32_FMTu__ = "u"; -pub const UINT_LEAST32_FMTx__ = "x"; -pub const UINT_LEAST32_FMTX__ = "X"; -pub const __INT_FAST32_TYPE__ = c_int; -pub const __INT_FAST32_MAX__ = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const __INT_FAST32_WIDTH__ = @as(c_int, 32); -pub const INT_FAST32_FMTd__ = "d"; -pub const INT_FAST32_FMTi__ = "i"; -pub const __UINT_FAST32_TYPE__ = c_uint; -pub const __UINT_FAST32_MAX__ = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const UINT_FAST32_FMTo__ = "o"; -pub const UINT_FAST32_FMTu__ = "u"; -pub const UINT_FAST32_FMTx__ = "x"; -pub const UINT_FAST32_FMTX__ = "X"; -pub const __INT_LEAST64_TYPE__ = c_long; -pub const __INT_LEAST64_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __INT_LEAST64_WIDTH__ = @as(c_int, 64); -pub const INT_LEAST64_FMTd__ = "ld"; -pub const INT_LEAST64_FMTi__ = "li"; -pub const __UINT_LEAST64_TYPE__ = c_ulong; -pub const __UINT_LEAST64_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const UINT_LEAST64_FMTo__ = "lo"; -pub const UINT_LEAST64_FMTu__ = "lu"; -pub const UINT_LEAST64_FMTx__ = "lx"; -pub const UINT_LEAST64_FMTX__ = "lX"; -pub const __INT_FAST64_TYPE__ = c_long; -pub const __INT_FAST64_MAX__ = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const __INT_FAST64_WIDTH__ = @as(c_int, 64); -pub const INT_FAST64_FMTd__ = "ld"; -pub const INT_FAST64_FMTi__ = "li"; -pub const __UINT_FAST64_TYPE__ = c_ulong; -pub const __UINT_FAST64_MAX__ = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const UINT_FAST64_FMTo__ = "lo"; -pub const UINT_FAST64_FMTu__ = "lu"; -pub const UINT_FAST64_FMTx__ = "lx"; -pub const UINT_FAST64_FMTX__ = "lX"; -pub const __FLT16_DENORM_MIN__ = @as(f16, 5.9604644775390625e-8); -pub const __FLT16_HAS_DENORM__ = ""; -pub const __FLT16_DIG__ = @as(c_int, 3); -pub const __FLT16_DECIMAL_DIG__ = @as(c_int, 5); -pub const __FLT16_EPSILON__ = @as(f16, 9.765625e-4); -pub const __FLT16_HAS_INFINITY__ = ""; -pub const __FLT16_HAS_QUIET_NAN__ = ""; -pub const __FLT16_MANT_DIG__ = @as(c_int, 11); -pub const __FLT16_MAX_10_EXP__ = @as(c_int, 4); -pub const __FLT16_MAX_EXP__ = @as(c_int, 16); -pub const __FLT16_MAX__ = @as(f16, 6.5504e+4); -pub const __FLT16_MIN_10_EXP__ = -@as(c_int, 4); -pub const __FLT16_MIN_EXP__ = -@as(c_int, 13); -pub const __FLT16_MIN__ = @as(f16, 6.103515625e-5); -pub const __FLT_DENORM_MIN__ = @as(f32, 1.40129846e-45); -pub const __FLT_HAS_DENORM__ = ""; -pub const __FLT_DIG__ = @as(c_int, 6); -pub const __FLT_DECIMAL_DIG__ = @as(c_int, 9); -pub const __FLT_EPSILON__ = @as(f32, 1.19209290e-7); -pub const __FLT_HAS_INFINITY__ = ""; -pub const __FLT_HAS_QUIET_NAN__ = ""; -pub const __FLT_MANT_DIG__ = @as(c_int, 24); -pub const __FLT_MAX_10_EXP__ = @as(c_int, 38); -pub const __FLT_MAX_EXP__ = @as(c_int, 128); -pub const __FLT_MAX__ = @as(f32, 3.40282347e+38); -pub const __FLT_MIN_10_EXP__ = -@as(c_int, 37); -pub const __FLT_MIN_EXP__ = -@as(c_int, 125); -pub const __FLT_MIN__ = @as(f32, 1.17549435e-38); -pub const __DBL_DENORM_MIN__ = @as(f64, 4.9406564584124654e-324); -pub const __DBL_HAS_DENORM__ = ""; -pub const __DBL_DIG__ = @as(c_int, 15); -pub const __DBL_DECIMAL_DIG__ = @as(c_int, 17); -pub const __DBL_EPSILON__ = @as(f64, 2.2204460492503131e-16); -pub const __DBL_HAS_INFINITY__ = ""; -pub const __DBL_HAS_QUIET_NAN__ = ""; -pub const __DBL_MANT_DIG__ = @as(c_int, 53); -pub const __DBL_MAX_10_EXP__ = @as(c_int, 308); -pub const __DBL_MAX_EXP__ = @as(c_int, 1024); -pub const __DBL_MAX__ = @as(f64, 1.7976931348623157e+308); -pub const __DBL_MIN_10_EXP__ = -@as(c_int, 307); -pub const __DBL_MIN_EXP__ = -@as(c_int, 1021); -pub const __DBL_MIN__ = @as(f64, 2.2250738585072014e-308); -pub const __LDBL_DENORM_MIN__ = @as(c_longdouble, 3.64519953188247460253e-4951); -pub const __LDBL_HAS_DENORM__ = ""; -pub const __LDBL_DIG__ = @as(c_int, 18); -pub const __LDBL_DECIMAL_DIG__ = @as(c_int, 21); -pub const __LDBL_EPSILON__ = @as(c_longdouble, 1.08420217248550443401e-19); -pub const __LDBL_HAS_INFINITY__ = ""; -pub const __LDBL_HAS_QUIET_NAN__ = ""; -pub const __LDBL_MANT_DIG__ = @as(c_int, 64); -pub const __LDBL_MAX_10_EXP__ = @as(c_int, 4932); -pub const __LDBL_MAX_EXP__ = @as(c_int, 16384); -pub const __LDBL_MAX__ = @as(c_longdouble, 1.18973149535723176502e+4932); -pub const __LDBL_MIN_10_EXP__ = -@as(c_int, 4931); -pub const __LDBL_MIN_EXP__ = -@as(c_int, 16381); -pub const __LDBL_MIN__ = @as(c_longdouble, 3.36210314311209350626e-4932); -pub const __FLT_EVAL_METHOD__ = @as(c_int, 0); -pub const __FLT_RADIX__ = @as(c_int, 2); -pub const __DECIMAL_DIG__ = __LDBL_DECIMAL_DIG__; -pub const __pic__ = @as(c_int, 2); -pub const __PIC__ = @as(c_int, 2); -pub const __GLIBC_MINOR__ = @as(c_int, 42); -pub const RGFW_OPENGL = @as(c_int, 1); -pub const RGFW_MACOS_X11 = ""; -pub const RGFW_X11 = ""; -pub const RGFW_UNIX = ""; -pub const _POSIX_C_SOURCE = @as(c_long, 199309); -pub const _ASSERT_H = @as(c_int, 1); -pub const _FEATURES_H = @as(c_int, 1); -pub const __KERNEL_STRICT_NAMES = ""; -pub inline fn __GNUC_PREREQ(maj: anytype, min: anytype) @TypeOf(((__GNUC__ << @as(c_int, 16)) + __GNUC_MINOR__) >= ((maj << @as(c_int, 16)) + min)) { - _ = &maj; - _ = &min; - return ((__GNUC__ << @as(c_int, 16)) + __GNUC_MINOR__) >= ((maj << @as(c_int, 16)) + min); -} -pub inline fn __glibc_clang_prereq(maj: anytype, min: anytype) @TypeOf(@as(c_int, 0)) { - _ = &maj; - _ = &min; - return @as(c_int, 0); -} -pub const __GLIBC_USE = @compileError("unable to translate macro: undefined identifier `__GLIBC_USE_`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/features.h:191:9 -pub const __GLIBC_USE_ISOC2Y = @as(c_int, 0); -pub const __GLIBC_USE_ISOC23 = @as(c_int, 0); -pub const __USE_ISOC11 = @as(c_int, 1); -pub const __USE_ISOC99 = @as(c_int, 1); -pub const __USE_ISOC95 = @as(c_int, 1); -pub const __USE_POSIX = @as(c_int, 1); -pub const __USE_POSIX2 = @as(c_int, 1); -pub const __USE_POSIX199309 = @as(c_int, 1); -pub const __WORDSIZE = @as(c_int, 64); -pub const __WORDSIZE_TIME64_COMPAT32 = @as(c_int, 1); -pub const __SYSCALL_WORDSIZE = @as(c_int, 64); -pub const __TIMESIZE = __WORDSIZE; -pub const __USE_TIME_BITS64 = @as(c_int, 1); -pub const __USE_FORTIFY_LEVEL = @as(c_int, 0); -pub const __GLIBC_USE_DEPRECATED_GETS = @as(c_int, 0); -pub const __GLIBC_USE_DEPRECATED_SCANF = @as(c_int, 0); -pub const __GLIBC_USE_C23_STRTOL = @as(c_int, 0); -pub const _STDC_PREDEF_H = @as(c_int, 1); -pub const __STDC_IEC_559__ = @as(c_int, 1); -pub const __STDC_IEC_60559_BFP__ = @as(c_long, 201404); -pub const __STDC_IEC_559_COMPLEX__ = @as(c_int, 1); -pub const __STDC_IEC_60559_COMPLEX__ = @as(c_long, 201404); -pub const __STDC_ISO_10646__ = @as(c_long, 201706); -pub const __GNU_LIBRARY__ = @as(c_int, 6); -pub const __GLIBC__ = @as(c_int, 2); -pub inline fn __GLIBC_PREREQ(maj: anytype, min: anytype) @TypeOf(((__GLIBC__ << @as(c_int, 16)) + __GLIBC_MINOR__) >= ((maj << @as(c_int, 16)) + min)) { - _ = &maj; - _ = &min; - return ((__GLIBC__ << @as(c_int, 16)) + __GLIBC_MINOR__) >= ((maj << @as(c_int, 16)) + min); -} -pub const _SYS_CDEFS_H = @as(c_int, 1); -pub const __glibc_has_attribute = @compileError("unable to translate macro: undefined identifier `__has_attribute`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:45:10 -pub inline fn __glibc_has_builtin(name: anytype) @TypeOf(__builtin.has_builtin(name)) { - _ = &name; - return __builtin.has_builtin(name); -} -pub const __glibc_has_extension = @compileError("unable to translate macro: undefined identifier `__has_extension`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:55:10 -pub const __LEAF = @compileError("unable to translate macro: undefined identifier `__leaf__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:65:11 -pub const __LEAF_ATTR = @compileError("unable to translate macro: undefined identifier `__leaf__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:66:11 -pub const __THROW = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:79:11 -pub const __THROWNL = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:80:11 -pub const __NTH = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:81:11 -pub const __NTHNL = @compileError("unable to translate macro: undefined identifier `__nothrow__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:82:11 -pub const __COLD = @compileError("unable to translate macro: undefined identifier `__cold__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:102:11 -pub inline fn __P(args: anytype) @TypeOf(args) { - _ = &args; - return args; -} -pub inline fn __PMT(args: anytype) @TypeOf(args) { - _ = &args; - return args; -} -pub const __CONCAT = @compileError("unable to translate C expr: unexpected token '##'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:131:9 -pub const __STRING = @compileError("unable to translate C expr: unexpected token ''"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:132:9 -pub const __ptr_t = ?*anyopaque; -pub const __BEGIN_DECLS = ""; -pub const __END_DECLS = ""; -pub const __attribute_overloadable__ = ""; -pub inline fn __bos(ptr: anytype) @TypeOf(__builtin.object_size(ptr, __USE_FORTIFY_LEVEL > @as(c_int, 1))) { - _ = &ptr; - return __builtin.object_size(ptr, __USE_FORTIFY_LEVEL > @as(c_int, 1)); -} -pub inline fn __bos0(ptr: anytype) @TypeOf(__builtin.object_size(ptr, @as(c_int, 0))) { - _ = &ptr; - return __builtin.object_size(ptr, @as(c_int, 0)); -} -pub inline fn __glibc_objsize0(__o: anytype) @TypeOf(__bos0(__o)) { - _ = &__o; - return __bos0(__o); -} -pub inline fn __glibc_objsize(__o: anytype) @TypeOf(__bos(__o)) { - _ = &__o; - return __bos(__o); -} -pub const __warnattr = @compileError("unable to translate macro: undefined identifier `__warning__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:366:10 -pub const __errordecl = @compileError("unable to translate macro: undefined identifier `__error__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:367:10 -pub const __flexarr = @compileError("unable to translate C expr: unexpected token '['"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:379:10 -pub const __glibc_c99_flexarr_available = @as(c_int, 1); -pub const __REDIRECT = @compileError("unable to translate C expr: unexpected token '__asm__'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:410:10 -pub const __REDIRECT_NTH = @compileError("unable to translate C expr: unexpected token '__asm__'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:417:11 -pub const __REDIRECT_NTHNL = @compileError("unable to translate C expr: unexpected token '__asm__'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:419:11 -pub const __ASMNAME = @compileError("unable to translate macro: undefined identifier `__USER_LABEL_PREFIX__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:422:10 -pub inline fn __ASMNAME2(prefix: anytype, cname: anytype) @TypeOf(__STRING(prefix) ++ cname) { - _ = &prefix; - _ = &cname; - return __STRING(prefix) ++ cname; -} -pub const __REDIRECT_FORTIFY = __REDIRECT; -pub const __REDIRECT_FORTIFY_NTH = __REDIRECT_NTH; -pub const __attribute_malloc__ = @compileError("unable to translate macro: undefined identifier `__malloc__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:452:10 -pub const __attribute_alloc_size__ = @compileError("unable to translate macro: undefined identifier `__alloc_size__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:460:10 -pub const __attribute_alloc_align__ = @compileError("unable to translate macro: undefined identifier `__alloc_align__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:469:10 -pub const __attribute_pure__ = @compileError("unable to translate macro: undefined identifier `__pure__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:479:10 -pub const __attribute_const__ = @compileError("unable to translate C expr: unexpected token '__attribute__'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:486:10 -pub const __attribute_maybe_unused__ = @compileError("unable to translate macro: undefined identifier `__unused__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:492:10 -pub const __attribute_used__ = @compileError("unable to translate macro: undefined identifier `__used__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:501:10 -pub const __attribute_noinline__ = @compileError("unable to translate macro: undefined identifier `__noinline__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:502:10 -pub const __attribute_deprecated__ = @compileError("unable to translate macro: undefined identifier `__deprecated__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:510:10 -pub const __attribute_deprecated_msg__ = @compileError("unable to translate macro: undefined identifier `__deprecated__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:520:10 -pub const __attribute_format_arg__ = @compileError("unable to translate macro: undefined identifier `__format_arg__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:533:10 -pub const __attribute_format_strfmon__ = @compileError("unable to translate macro: undefined identifier `__format__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:543:10 -pub const __attribute_nonnull__ = @compileError("unable to translate macro: undefined identifier `__nonnull__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:555:11 -pub inline fn __nonnull(params: anytype) @TypeOf(__attribute_nonnull__(params)) { - _ = ¶ms; - return __attribute_nonnull__(params); -} -pub const __returns_nonnull = @compileError("unable to translate macro: undefined identifier `__returns_nonnull__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:568:10 -pub const __attribute_warn_unused_result__ = @compileError("unable to translate macro: undefined identifier `__warn_unused_result__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:577:10 -pub const __wur = ""; -pub const __always_inline = @compileError("unable to translate macro: undefined identifier `__always_inline__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:595:10 -pub const __attribute_artificial__ = @compileError("unable to translate macro: undefined identifier `__artificial__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:604:10 -pub const __extern_inline = @compileError("unable to translate C expr: unexpected token 'extern'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:626:11 -pub const __extern_always_inline = @compileError("unable to translate C expr: unexpected token 'extern'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:627:11 -pub const __fortify_function = __extern_always_inline ++ __attribute_artificial__; -pub const __va_arg_pack = @compileError("unable to translate macro: undefined identifier `__builtin_va_arg_pack`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:638:10 -pub const __va_arg_pack_len = @compileError("unable to translate macro: undefined identifier `__builtin_va_arg_pack_len`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:639:10 -pub const __restrict_arr = @compileError("unable to translate C expr: unexpected token '__restrict'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:666:10 -pub inline fn __glibc_unlikely(cond: anytype) @TypeOf(__builtin.expect(cond, @as(c_int, 0))) { - _ = &cond; - return __builtin.expect(cond, @as(c_int, 0)); -} -pub inline fn __glibc_likely(cond: anytype) @TypeOf(__builtin.expect(cond, @as(c_int, 1))) { - _ = &cond; - return __builtin.expect(cond, @as(c_int, 1)); -} -pub const __attribute_nonstring__ = ""; -pub inline fn __attribute_copy__(arg: anytype) void { - _ = &arg; - return; -} -pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI = @as(c_int, 0); -pub inline fn __LDBL_REDIR1(name: anytype, proto: anytype, alias: anytype) @TypeOf(name ++ proto) { - _ = &name; - _ = &proto; - _ = &alias; - return name ++ proto; -} -pub inline fn __LDBL_REDIR(name: anytype, proto: anytype) @TypeOf(name ++ proto) { - _ = &name; - _ = &proto; - return name ++ proto; -} -pub inline fn __LDBL_REDIR1_NTH(name: anytype, proto: anytype, alias: anytype) @TypeOf(name ++ proto ++ __THROW) { - _ = &name; - _ = &proto; - _ = &alias; - return name ++ proto ++ __THROW; -} -pub inline fn __LDBL_REDIR_NTH(name: anytype, proto: anytype) @TypeOf(name ++ proto ++ __THROW) { - _ = &name; - _ = &proto; - return name ++ proto ++ __THROW; -} -pub inline fn __LDBL_REDIR2_DECL(name: anytype) void { - _ = &name; - return; -} -pub inline fn __LDBL_REDIR_DECL(name: anytype) void { - _ = &name; - return; -} -pub inline fn __REDIRECT_LDBL(name: anytype, proto: anytype, alias: anytype) @TypeOf(__REDIRECT(name, proto, alias)) { - _ = &name; - _ = &proto; - _ = &alias; - return __REDIRECT(name, proto, alias); -} -pub inline fn __REDIRECT_NTH_LDBL(name: anytype, proto: anytype, alias: anytype) @TypeOf(__REDIRECT_NTH(name, proto, alias)) { - _ = &name; - _ = &proto; - _ = &alias; - return __REDIRECT_NTH(name, proto, alias); -} -pub const __glibc_macro_warning1 = @compileError("unable to translate macro: undefined identifier `_Pragma`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:807:10 -pub const __glibc_macro_warning = @compileError("unable to translate macro: undefined identifier `GCC`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:808:10 -pub const __HAVE_GENERIC_SELECTION = @as(c_int, 1); -pub inline fn __fortified_attr_access(a: anytype, o: anytype, s: anytype) void { - _ = &a; - _ = &o; - _ = &s; - return; -} -pub inline fn __attr_access(x: anytype) void { - _ = &x; - return; -} -pub inline fn __attr_access_none(argno: anytype) void { - _ = &argno; - return; -} -pub inline fn __attr_dealloc(dealloc: anytype, argno: anytype) void { - _ = &dealloc; - _ = &argno; - return; -} -pub const __attr_dealloc_free = ""; -pub const __attribute_returns_twice__ = @compileError("unable to translate macro: undefined identifier `__returns_twice__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:872:10 -pub const __attribute_struct_may_alias__ = @compileError("unable to translate macro: undefined identifier `__may_alias__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/sys/cdefs.h:881:10 -pub const __stub___compat_bdflush = ""; -pub const __stub_chflags = ""; -pub const __stub_fchflags = ""; -pub const __stub_gtty = ""; -pub const __stub_revoke = ""; -pub const __stub_setlogin = ""; -pub const __stub_sigreturn = ""; -pub const __stub_stty = ""; -pub const __ASSERT_VOID_CAST = @compileError("unable to translate C expr: unexpected token ''"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/assert.h:40:10 -pub const assert = @compileError("unable to translate macro: undefined identifier `__FILE__`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/assert.h:115:11 -pub const __ASSERT_FUNCTION = @compileError("unable to translate C expr: unexpected token '__extension__'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/assert.h:137:12 -pub const static_assert = @compileError("unable to translate C expr: unexpected token '_Static_assert'"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/assert.h:155:10 -pub const RGFW_ASSERT = assert; -pub const RGFW_STATIC_ASSERT = @compileError("unable to translate macro: undefined identifier `RGFW_check_`"); // include/RGFW.h:237:10 -pub const _STDIO_H = @as(c_int, 1); -pub const __need_size_t = ""; -pub const __need_NULL = ""; -pub const __STDC_VERSION_STDDEF_H__ = @as(c_long, 202311); -pub const NULL = __helpers.cast(?*anyopaque, @as(c_int, 0)); -pub const offsetof = @compileError("unable to translate macro: undefined identifier `__builtin_offsetof`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stddef.h:18:9 -pub const __need___va_list = ""; -pub const __STDC_VERSION_STDARG_H__ = @as(c_int, 0); -pub const va_start = @compileError("unable to translate macro: undefined identifier `__builtin_va_start`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stdarg.h:12:9 -pub const va_end = @compileError("unable to translate macro: undefined identifier `__builtin_va_end`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stdarg.h:14:9 -pub const va_arg = @compileError("unable to translate macro: undefined identifier `__builtin_va_arg`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stdarg.h:15:9 -pub const __va_copy = @compileError("unable to translate macro: undefined identifier `__builtin_va_copy`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stdarg.h:18:9 -pub const va_copy = @compileError("unable to translate macro: undefined identifier `__builtin_va_copy`"); // /nix/store/5x5y75rc3l43ic0lwal6wzk7wi1ga3m1-zig-0.16.0/lib/zig/compiler/aro/include/stdarg.h:22:9 -pub const __GNUC_VA_LIST = @as(c_int, 1); -pub const _BITS_TYPES_H = @as(c_int, 1); -pub const __S16_TYPE = c_short; -pub const __U16_TYPE = c_ushort; -pub const __S32_TYPE = c_int; -pub const __U32_TYPE = c_uint; -pub const __SLONGWORD_TYPE = c_long; -pub const __ULONGWORD_TYPE = c_ulong; -pub const __SQUAD_TYPE = c_long; -pub const __UQUAD_TYPE = c_ulong; -pub const __SWORD_TYPE = c_long; -pub const __UWORD_TYPE = c_ulong; -pub const __SLONG32_TYPE = c_int; -pub const __ULONG32_TYPE = c_uint; -pub const __S64_TYPE = c_long; -pub const __U64_TYPE = c_ulong; -pub const _BITS_TYPESIZES_H = @as(c_int, 1); -pub const __SYSCALL_SLONG_TYPE = __SLONGWORD_TYPE; -pub const __SYSCALL_ULONG_TYPE = __ULONGWORD_TYPE; -pub const __DEV_T_TYPE = __UQUAD_TYPE; -pub const __UID_T_TYPE = __U32_TYPE; -pub const __GID_T_TYPE = __U32_TYPE; -pub const __INO_T_TYPE = __SYSCALL_ULONG_TYPE; -pub const __INO64_T_TYPE = __UQUAD_TYPE; -pub const __MODE_T_TYPE = __U32_TYPE; -pub const __NLINK_T_TYPE = __SYSCALL_ULONG_TYPE; -pub const __FSWORD_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __OFF_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __OFF64_T_TYPE = __SQUAD_TYPE; -pub const __PID_T_TYPE = __S32_TYPE; -pub const __RLIM_T_TYPE = __SYSCALL_ULONG_TYPE; -pub const __RLIM64_T_TYPE = __UQUAD_TYPE; -pub const __BLKCNT_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __BLKCNT64_T_TYPE = __SQUAD_TYPE; -pub const __FSBLKCNT_T_TYPE = __SYSCALL_ULONG_TYPE; -pub const __FSBLKCNT64_T_TYPE = __UQUAD_TYPE; -pub const __FSFILCNT_T_TYPE = __SYSCALL_ULONG_TYPE; -pub const __FSFILCNT64_T_TYPE = __UQUAD_TYPE; -pub const __ID_T_TYPE = __U32_TYPE; -pub const __CLOCK_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __TIME_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __USECONDS_T_TYPE = __U32_TYPE; -pub const __SUSECONDS_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __SUSECONDS64_T_TYPE = __SQUAD_TYPE; -pub const __DADDR_T_TYPE = __S32_TYPE; -pub const __KEY_T_TYPE = __S32_TYPE; -pub const __CLOCKID_T_TYPE = __S32_TYPE; -pub const __TIMER_T_TYPE = ?*anyopaque; -pub const __BLKSIZE_T_TYPE = __SYSCALL_SLONG_TYPE; -pub const __FSID_T_TYPE = @compileError("unable to translate macro: undefined identifier `__val`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/typesizes.h:73:9 -pub const __SSIZE_T_TYPE = __SWORD_TYPE; -pub const __CPU_MASK_TYPE = __SYSCALL_ULONG_TYPE; -pub const __OFF_T_MATCHES_OFF64_T = @as(c_int, 1); -pub const __INO_T_MATCHES_INO64_T = @as(c_int, 1); -pub const __RLIM_T_MATCHES_RLIM64_T = @as(c_int, 1); -pub const __STATFS_MATCHES_STATFS64 = @as(c_int, 1); -pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 = @as(c_int, 1); -pub const __FD_SETSIZE = @as(c_int, 1024); -pub const _BITS_TIME64_H = @as(c_int, 1); -pub const __TIME64_T_TYPE = __TIME_T_TYPE; -pub const _____fpos_t_defined = @as(c_int, 1); -pub const ____mbstate_t_defined = @as(c_int, 1); -pub const _____fpos64_t_defined = @as(c_int, 1); -pub const ____FILE_defined = @as(c_int, 1); -pub const __FILE_defined = @as(c_int, 1); -pub const __struct_FILE_defined = @as(c_int, 1); -pub const __getc_unlocked_body = @compileError("TODO postfix inc/dec expr"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/types/struct_FILE.h:113:9 -pub const __putc_unlocked_body = @compileError("TODO postfix inc/dec expr"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/types/struct_FILE.h:117:9 -pub const _IO_EOF_SEEN = @as(c_int, 0x0010); -pub inline fn __feof_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_EOF_SEEN) != @as(c_int, 0)) { - _ = &_fp; - return (_fp.*._flags & _IO_EOF_SEEN) != @as(c_int, 0); -} -pub const _IO_ERR_SEEN = @as(c_int, 0x0020); -pub inline fn __ferror_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0)) { - _ = &_fp; - return (_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0); -} -pub const _IO_USER_LOCK = __helpers.promoteIntLiteral(c_int, 0x8000, .hex); -pub const _IOFBF = @as(c_int, 0); -pub const _IOLBF = @as(c_int, 1); -pub const _IONBF = @as(c_int, 2); -pub const BUFSIZ = @as(c_int, 8192); -pub const EOF = -@as(c_int, 1); -pub const SEEK_SET = @as(c_int, 0); -pub const SEEK_CUR = @as(c_int, 1); -pub const SEEK_END = @as(c_int, 2); -pub const L_tmpnam = @as(c_int, 20); -pub const TMP_MAX = __helpers.promoteIntLiteral(c_int, 238328, .decimal); -pub const _BITS_STDIO_LIM_H = @as(c_int, 1); -pub const FILENAME_MAX = @as(c_int, 4096); -pub const L_ctermid = @as(c_int, 9); -pub const L_cuserid = @as(c_int, 9); -pub const FOPEN_MAX = @as(c_int, 16); -pub const __attr_dealloc_fclose = __attr_dealloc(fclose, @as(c_int, 1)); -pub const _BITS_FLOATN_H = ""; -pub const __HAVE_FLOAT128 = @as(c_int, 1); -pub const __HAVE_DISTINCT_FLOAT128 = @as(c_int, 1); -pub const __HAVE_FLOAT64X = @as(c_int, 1); -pub const __HAVE_FLOAT64X_LONG_DOUBLE = @as(c_int, 1); -pub const __f128 = @compileError("unable to translate macro: undefined identifier `f128`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn.h:72:12 -pub const __CFLOAT128 = @compileError("unable to translate: invalid numeric type"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn.h:86:12 -pub const _BITS_FLOATN_COMMON_H = ""; -pub const __HAVE_FLOAT16 = @as(c_int, 0); -pub const __HAVE_FLOAT32 = @as(c_int, 1); -pub const __HAVE_FLOAT64 = @as(c_int, 1); -pub const __HAVE_FLOAT32X = @as(c_int, 1); -pub const __HAVE_FLOAT128X = @as(c_int, 0); -pub const __HAVE_DISTINCT_FLOAT16 = __HAVE_FLOAT16; -pub const __HAVE_DISTINCT_FLOAT32 = @as(c_int, 0); -pub const __HAVE_DISTINCT_FLOAT64 = @as(c_int, 0); -pub const __HAVE_DISTINCT_FLOAT32X = @as(c_int, 0); -pub const __HAVE_DISTINCT_FLOAT64X = @as(c_int, 0); -pub const __HAVE_DISTINCT_FLOAT128X = __HAVE_FLOAT128X; -pub const __HAVE_FLOAT128_UNLIKE_LDBL = (__HAVE_DISTINCT_FLOAT128 != 0) and (__LDBL_MANT_DIG__ != @as(c_int, 113)); -pub const __HAVE_FLOATN_NOT_TYPEDEF = @as(c_int, 1); -pub const __f32 = @compileError("unable to translate macro: undefined identifier `f32`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:93:12 -pub const __f64 = @compileError("unable to translate macro: undefined identifier `f64`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:105:12 -pub const __f32x = @compileError("unable to translate macro: undefined identifier `f32x`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:113:12 -pub const __f64x = @compileError("unable to translate macro: undefined identifier `f64x`"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:125:12 -pub const __CFLOAT32 = @compileError("unable to translate: invalid numeric type"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:151:12 -pub const __CFLOAT64 = @compileError("unable to translate: invalid numeric type"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:163:12 -pub const __CFLOAT32X = @compileError("unable to translate: invalid numeric type"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:171:12 -pub const __CFLOAT64X = @compileError("unable to translate: invalid numeric type"); // /nix/store/fbbw928argckfii0j322346ihmllg7a7-glibc-2.42-61-dev/include/bits/floatn-common.h:183:12 -pub const RGFW_SNPRINTF = snprintf; -pub const RGFW_USERPTR = NULL; -pub const RGFW_UNUSED = __helpers.DISCARD; -pub inline fn RGFW_ROUND(x: anytype) @"i32" { - _ = &x; - return __helpers.cast(@"i32", if (__helpers.cast(bool, x >= @as(c_int, 0))) x + @as(f32, 0.5) else x - @as(f32, 0.5)); -} -pub inline fn RGFW_ROUNDF(x: anytype) f32 { - _ = &x; - return __helpers.cast(f32, __helpers.cast(@"i32", x + (if (__helpers.cast(bool, x < @as(f32, 0.0))) -@as(f32, 0.5) else @as(f32, 0.5)))); -} -pub inline fn RGFW_MIN(x: anytype, y: anytype) @TypeOf(if (__helpers.cast(bool, x < y)) x else y) { - _ = &x; - _ = &y; - return if (__helpers.cast(bool, x < y)) x else y; -} -pub const __need_wchar_t = ""; -pub const _STDLIB_H = @as(c_int, 1); -pub const __ldiv_t_defined = @as(c_int, 1); -pub const __lldiv_t_defined = @as(c_int, 1); -pub const RAND_MAX = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const EXIT_FAILURE = @as(c_int, 1); -pub const EXIT_SUCCESS = @as(c_int, 0); -pub const MB_CUR_MAX = __ctype_get_mb_cur_max(); -pub const __COMPAR_FN_T = ""; -pub const RGFW_ALLOC = malloc; -pub const RGFW_FREE = free; -pub const _STRING_H = @as(c_int, 1); -pub inline fn RGFW_MEMZERO(ptr: anytype, num: anytype) @TypeOf(memset(ptr, @as(c_int, 0), num)) { - _ = &ptr; - _ = # - return memset(ptr, @as(c_int, 0), num); -} -pub inline fn RGFW_MEMCPY(dist: anytype, src: anytype, len: anytype) @TypeOf(memcpy(dist, src, len)) { - _ = &dist; - _ = &src; - _ = &len; - return memcpy(dist, src, len); -} -pub inline fn RGFW_STRNCMP(s1: anytype, s2: anytype, max: anytype) @TypeOf(strncmp(s1, s2, max)) { - _ = &s1; - _ = &s2; - _ = &max; - return strncmp(s1, s2, max); -} -pub inline fn RGFW_STRNCPY(dist: anytype, src: anytype, len: anytype) @TypeOf(strncpy(dist, src, len)) { - _ = &dist; - _ = &src; - _ = &len; - return strncpy(dist, src, len); -} -pub inline fn RGFW_STRSTR(str: anytype, substr: anytype) @TypeOf(strstr(str, substr)) { - _ = &str; - _ = &substr; - return strstr(str, substr); -} -pub inline fn RGFW_STRTOL(str: anytype, endptr: anytype, base: anytype) @TypeOf(strtol(str, endptr, base)) { - _ = &str; - _ = &endptr; - _ = &base; - return strtol(str, endptr, base); -} -pub inline fn RGFW_ATOF(num: anytype) @TypeOf(atof(num)) { - _ = # - return atof(num); -} -pub const RGFW_MAX_EVENTS = @as(c_int, 32); -pub const RGFW_PREALLOCATED_MONITORS = @as(c_int, 6); -pub const RGFW_COCOA_FRAME_NAME = NULL; -pub const RGFWDEF = @compileError("unable to translate C expr: unexpected token 'inline'"); // include/RGFW.h:355:11 -pub const RGFW_HEADER = ""; -pub const __CLANG_STDINT_H = ""; -pub const _STDINT_H = @as(c_int, 1); -pub const __GLIBC_USE_LIB_EXT2 = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_BFP_EXT = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_BFP_EXT_C23 = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_EXT = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_FUNCS_EXT = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C23 = @as(c_int, 0); -pub const __GLIBC_USE_IEC_60559_TYPES_EXT = @as(c_int, 0); -pub const _BITS_WCHAR_H = @as(c_int, 1); -pub const __WCHAR_MAX = __WCHAR_MAX__; -pub const __WCHAR_MIN = -__WCHAR_MAX - @as(c_int, 1); -pub const _BITS_STDINT_INTN_H = @as(c_int, 1); -pub const _BITS_STDINT_UINTN_H = @as(c_int, 1); -pub const _BITS_STDINT_LEAST_H = @as(c_int, 1); -pub const __intptr_t_defined = ""; -pub const INT8_MIN = -@as(c_int, 128); -pub const INT16_MIN = -@as(c_int, 32767) - @as(c_int, 1); -pub const INT32_MIN = -__helpers.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); -pub const INT64_MIN = -__INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); -pub const INT8_MAX = @as(c_int, 127); -pub const INT16_MAX = @as(c_int, 32767); -pub const INT32_MAX = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const INT64_MAX = __INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); -pub const UINT8_MAX = @as(c_int, 255); -pub const UINT16_MAX = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const UINT32_MAX = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const UINT64_MAX = __UINT64_C(__helpers.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); -pub const INT_LEAST8_MIN = -@as(c_int, 128); -pub const INT_LEAST16_MIN = -@as(c_int, 32767) - @as(c_int, 1); -pub const INT_LEAST32_MIN = -__helpers.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); -pub const INT_LEAST64_MIN = -__INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); -pub const INT_LEAST8_MAX = @as(c_int, 127); -pub const INT_LEAST16_MAX = @as(c_int, 32767); -pub const INT_LEAST32_MAX = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const INT_LEAST64_MAX = __INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); -pub const UINT_LEAST8_MAX = @as(c_int, 255); -pub const UINT_LEAST16_MAX = __helpers.promoteIntLiteral(c_int, 65535, .decimal); -pub const UINT_LEAST32_MAX = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub const UINT_LEAST64_MAX = __UINT64_C(__helpers.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); -pub const INT_FAST8_MIN = -@as(c_int, 128); -pub const INT_FAST16_MIN = -__helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); -pub const INT_FAST32_MIN = -__helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); -pub const INT_FAST64_MIN = -__INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); -pub const INT_FAST8_MAX = @as(c_int, 127); -pub const INT_FAST16_MAX = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const INT_FAST32_MAX = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const INT_FAST64_MAX = __INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); -pub const UINT_FAST8_MAX = @as(c_int, 255); -pub const UINT_FAST16_MAX = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const UINT_FAST32_MAX = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const UINT_FAST64_MAX = __UINT64_C(__helpers.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); -pub const INTPTR_MIN = -__helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); -pub const INTPTR_MAX = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const UINTPTR_MAX = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const INTMAX_MIN = -__INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)) - @as(c_int, 1); -pub const INTMAX_MAX = __INT64_C(__helpers.promoteIntLiteral(c_int, 9223372036854775807, .decimal)); -pub const UINTMAX_MAX = __UINT64_C(__helpers.promoteIntLiteral(c_int, 18446744073709551615, .decimal)); -pub const PTRDIFF_MIN = -__helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal) - @as(c_int, 1); -pub const PTRDIFF_MAX = __helpers.promoteIntLiteral(c_long, 9223372036854775807, .decimal); -pub const SIG_ATOMIC_MIN = -__helpers.promoteIntLiteral(c_int, 2147483647, .decimal) - @as(c_int, 1); -pub const SIG_ATOMIC_MAX = __helpers.promoteIntLiteral(c_int, 2147483647, .decimal); -pub const SIZE_MAX = __helpers.promoteIntLiteral(c_ulong, 18446744073709551615, .decimal); -pub const WCHAR_MIN = __WCHAR_MIN; -pub const WCHAR_MAX = __WCHAR_MAX; -pub const WINT_MIN = @as(c_uint, 0); -pub const WINT_MAX = __helpers.promoteIntLiteral(c_uint, 4294967295, .decimal); -pub inline fn INT8_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub inline fn INT16_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub inline fn INT32_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const INT64_C = __helpers.L_SUFFIX; -pub inline fn UINT8_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub inline fn UINT16_C(c: anytype) @TypeOf(c) { - _ = &c; - return c; -} -pub const UINT32_C = __helpers.U_SUFFIX; -pub const UINT64_C = __helpers.UL_SUFFIX; -pub const INTMAX_C = __helpers.L_SUFFIX; -pub const UINTMAX_C = __helpers.UL_SUFFIX; -pub const RGFW_INT_DEFINED = ""; -pub const RGFW_BOOL_DEFINED = ""; -pub inline fn RGFW_BOOL(x: anytype) RGFW_bool { - _ = &x; - return __helpers.cast(RGFW_bool, x != @as(c_int, 0)); -} -pub const RGFW_TRUE = __helpers.cast(RGFW_bool, @as(c_int, 1)); -pub const RGFW_FALSE = __helpers.cast(RGFW_bool, @as(c_int, 0)); -pub const RGFW_ENUM = @compileError("unable to translate macro: untranslatable usage of arg `name`"); // include/RGFW.h:419:9 -pub inline fn RGFW_BIT(x: anytype) @TypeOf(@as(c_int, 1) << x) { - _ = &x; - return @as(c_int, 1) << x; -} -pub const _G_fpos_t = struct__G_fpos_t; -pub const _G_fpos64_t = struct__G_fpos64_t; -pub const _IO_marker = struct__IO_marker; -pub const _IO_FILE = struct__IO_FILE; -pub const _IO_codecvt = struct__IO_codecvt; -pub const _IO_wide_data = struct__IO_wide_data; -pub const RGFW_format_enum = enum_RGFW_format_enum; -pub const RGFW_modeRequest_enum = enum_RGFW_modeRequest_enum; -pub const RGFW_key_enum = enum_RGFW_key_enum; -pub const RGFW_mouseButton_enum = enum_RGFW_mouseButton_enum; -pub const RGFW_keymod_enum = enum_RGFW_keymod_enum; -pub const RGFW_dndActionType_enum = enum_RGFW_dndActionType_enum; -pub const RGFW_dataTransferType_enum = enum_RGFW_dataTransferType_enum; -pub const RGFW_eventType_enum = enum_RGFW_eventType_enum; -pub const RGFW_eventFlag_enum = enum_RGFW_eventFlag_enum; -pub const RGFW_eventWait_enum = enum_RGFW_eventWait_enum; -pub const RGFW_windowFlags_enum = enum_RGFW_windowFlags_enum; -pub const RGFW_icon_enum = enum_RGFW_icon_enum; -pub const RGFW_mouseIcon_enum = enum_RGFW_mouseIcon_enum; -pub const RGFW_flashRequest_enum = enum_RGFW_flashRequest_enum; -pub const RGFW_debugType_enum = enum_RGFW_debugType_enum; -pub const RGFW_errorCode_enum = enum_RGFW_errorCode_enum; -pub const RGFW_glReleaseBehavior_enum = enum_RGFW_glReleaseBehavior_enum; -pub const RGFW_glProfile_enum = enum_RGFW_glProfile_enum; -pub const RGFW_glRenderer_enum = enum_RGFW_glRenderer_enum; -pub const wl_display = struct_wl_display; -pub const wl_surface = struct_wl_surface; |
