790 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			790 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
#ifndef SOKOL_FONTSTASH_INCLUDED
 | 
						|
/*
 | 
						|
    sokol_fontstash.h -- renderer for https://github.com/memononen/fontstash
 | 
						|
                         on top of sokol_gl.h
 | 
						|
 | 
						|
    Project URL: https://github.com/floooh/sokol
 | 
						|
 | 
						|
    Do this:
 | 
						|
 | 
						|
        #define SOKOL_FONTSTASH_IMPL
 | 
						|
 | 
						|
    before you include this file in *one* C or C++ file to create the
 | 
						|
    implementation.
 | 
						|
 | 
						|
    The following defines are used by the implementation to select the
 | 
						|
    platform-specific embedded shader code (these are the same defines as
 | 
						|
    used by sokol_gfx.h and sokol_app.h):
 | 
						|
 | 
						|
    SOKOL_GLCORE33
 | 
						|
    SOKOL_GLES2
 | 
						|
    SOKOL_GLES3
 | 
						|
    SOKOL_D3D11
 | 
						|
    SOKOL_METAL
 | 
						|
 | 
						|
    ...optionally provide the following macros to override defaults:
 | 
						|
 | 
						|
    SOKOL_ASSERT(c)     - your own assert macro (default: assert(c))
 | 
						|
    SOKOL_MALLOC(s)     - your own malloc function (default: malloc(s))
 | 
						|
    SOKOL_FREE(p)       - your own free function (default: free(p))
 | 
						|
    SOKOL_API_DECL      - public function declaration prefix (default: extern)
 | 
						|
    SOKOL_API_IMPL      - public function implementation prefix (default: -)
 | 
						|
    SOKOL_LOG(msg)      - your own logging function (default: puts(msg))
 | 
						|
    SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
 | 
						|
 | 
						|
    Include the following headers before including sokol_fontstash.h:
 | 
						|
 | 
						|
        sokol_gfx.h
 | 
						|
 | 
						|
    Additionally include the following headers for including the sokol_fontstash.h
 | 
						|
    implementation:
 | 
						|
 | 
						|
        sokol_gl.h
 | 
						|
 | 
						|
    HOW TO
 | 
						|
    ======
 | 
						|
    --- First initialize sokol-gfx and sokol-gl as usual:
 | 
						|
 | 
						|
            sg_setup(&(sg_desc){...});
 | 
						|
            sgl_setup(&(sgl_desc){...});
 | 
						|
 | 
						|
    --- Create at least one fontstash context with sfons_create() (this replaces
 | 
						|
        glfonsCreate() from fontstash.h's example GL renderer:
 | 
						|
 | 
						|
            FONScontext* ctx = sfons_create(atlas_width, atlas_height, FONS_ZERO_TOPLEFT);
 | 
						|
 | 
						|
        Each FONScontext manages one font atlas texture which can hold rasterized
 | 
						|
        glyphs for multiple fonts.
 | 
						|
 | 
						|
    --- From here on, use fontstash.h's functions "as usual" to add TTF
 | 
						|
        font data and draw text. Note that (just like with sokol-gl), text
 | 
						|
        rendering can happen anywhere in the frame, not only inside
 | 
						|
        a sokol-gfx rendering pass.
 | 
						|
 | 
						|
    --- You can use the helper function
 | 
						|
 | 
						|
            uint32_t sfons_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
 | 
						|
 | 
						|
        To convert a 0..255 RGBA color into a packed uint32_t color value
 | 
						|
        expected by fontstash.h.
 | 
						|
 | 
						|
    --- Once per frame before calling sgl_draw(), call:
 | 
						|
 | 
						|
            sfons_flush(FONScontext* ctx)
 | 
						|
 | 
						|
        ...this will update the dynamic sokol-gfx texture with the latest font
 | 
						|
        atlas content.
 | 
						|
 | 
						|
    --- To actually render the text (and any other sokol-gl draw commands),
 | 
						|
        call sgl_draw() inside a sokol-gfx frame.
 | 
						|
 | 
						|
    --- NOTE that you can mix fontstash.h calls with sokol-gl calls to mix
 | 
						|
        text rendering with sokol-gl rendering. You can also use
 | 
						|
        sokol-gl's matrix stack to position fontstash.h text in 3D.
 | 
						|
 | 
						|
    --- finally on application shutdown, call:
 | 
						|
 | 
						|
            sfons_shutdown()
 | 
						|
 | 
						|
        before sgl_shutdown() and sg_shutdown()
 | 
						|
 | 
						|
 | 
						|
    WHAT HAPPENS UNDER THE HOOD:
 | 
						|
    ============================
 | 
						|
 | 
						|
    sfons_create():
 | 
						|
        - creates a sokol-gfx shader compatible with sokol-gl
 | 
						|
        - creates an sgl_pipeline object with alpha-blending using
 | 
						|
          this shader
 | 
						|
        - creates a 1-byte-per-pixel font atlas texture via sokol-gfx
 | 
						|
          (pixel format SG_PIXELFORMAT_R8)
 | 
						|
 | 
						|
    fonsDrawText():
 | 
						|
        - this will call the following sequence of sokol-gl functions:
 | 
						|
 | 
						|
            sgl_enable_texture();
 | 
						|
            sgl_texture(...);
 | 
						|
            sgl_push_pipeline();
 | 
						|
            sgl_load_pipeline(...);
 | 
						|
            sgl_begin_triangles();
 | 
						|
            for each vertex:
 | 
						|
                sg_v2f_t2f_c1i(...);
 | 
						|
            sgl_end();
 | 
						|
            sgl_pop_pipeline();
 | 
						|
            sgl_disable_texture();
 | 
						|
 | 
						|
        - note that sokol-gl will merge several sgl_*_begin/sgl_end pairs
 | 
						|
          into a single draw call if no relevant state has changed, typically
 | 
						|
          all calls to fonsDrawText() will be merged into a single draw call
 | 
						|
          as long as all calls use the same FONScontext
 | 
						|
 | 
						|
    sfons_flush():
 | 
						|
        - this will call sg_update_image() on the font atlas texture
 | 
						|
          if fontstash.h has added any rasterized glyphs since the last
 | 
						|
          frame
 | 
						|
 | 
						|
    sfons_shutdown():
 | 
						|
        - destroy the font atlas texture, sgl_pipeline and sg_shader objects
 | 
						|
 | 
						|
    LICENSE
 | 
						|
    =======
 | 
						|
    zlib/libpng license
 | 
						|
 | 
						|
    Copyright (c) 2018 Andre Weissflog
 | 
						|
 | 
						|
    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 SOKOL_FONTSTASH_INCLUDED (1)
 | 
						|
#include <stdint.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#if !defined(SOKOL_GFX_INCLUDED)
 | 
						|
#error "Please include sokol_gfx.h before sokol_fontstash.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef SOKOL_API_DECL
 | 
						|
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_IMPL)
 | 
						|
#define SOKOL_API_DECL __declspec(dllexport)
 | 
						|
#elif defined(_WIN32) && defined(SOKOL_DLL)
 | 
						|
#define SOKOL_API_DECL __declspec(dllimport)
 | 
						|
#else
 | 
						|
#define SOKOL_API_DECL extern
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#ifdef __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
SOKOL_API_DECL FONScontext* sfons_create(int width, int height, int flags);
 | 
						|
SOKOL_API_DECL void sfons_destroy(FONScontext* ctx);
 | 
						|
SOKOL_API_DECL void sfons_flush(FONScontext* ctx);
 | 
						|
SOKOL_API_DECL uint32_t sfons_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
} /* extern "C" */
 | 
						|
#endif
 | 
						|
#endif /* SOKOL_FONTSTASH_INCLUDED */
 | 
						|
 | 
						|
/*-- IMPLEMENTATION ----------------------------------------------------------*/
 | 
						|
#ifdef SOKOL_FONTSTASH_IMPL
 | 
						|
#define SOKOL_FONTSTASH_IMPL_INCLUDED (1)
 | 
						|
#include <string.h>     /* memset, memcpy */
 | 
						|
 | 
						|
#if !defined(SOKOL_GL_INCLUDED)
 | 
						|
#error "Please include sokol_gl.h before sokol_fontstash.h"
 | 
						|
#endif
 | 
						|
#if !defined(FONS_H)
 | 
						|
#error "Please include fontstash.h before sokol_fontstash.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef SOKOL_API_IMPL
 | 
						|
    #define SOKOL_API_IMPL
 | 
						|
#endif
 | 
						|
#ifndef SOKOL_DEBUG
 | 
						|
    #ifndef NDEBUG
 | 
						|
        #define SOKOL_DEBUG (1)
 | 
						|
    #endif
 | 
						|
#endif
 | 
						|
#ifndef SOKOL_ASSERT
 | 
						|
    #include <assert.h>
 | 
						|
    #define SOKOL_ASSERT(c) assert(c)
 | 
						|
#endif
 | 
						|
#ifndef SOKOL_MALLOC
 | 
						|
    #include <stdlib.h>
 | 
						|
    #define SOKOL_MALLOC(s) malloc(s)
 | 
						|
    #define SOKOL_FREE(p) free(p)
 | 
						|
#endif
 | 
						|
#ifndef SOKOL_LOG
 | 
						|
    #ifdef SOKOL_DEBUG
 | 
						|
        #include <stdio.h>
 | 
						|
        #define SOKOL_LOG(s) { SOKOL_ASSERT(s); puts(s); }
 | 
						|
    #else
 | 
						|
        #define SOKOL_LOG(s)
 | 
						|
    #endif
 | 
						|
#endif
 | 
						|
#ifndef SOKOL_UNREACHABLE
 | 
						|
    #define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(SOKOL_GLCORE33)
 | 
						|
static const char* _sfons_vs_src =
 | 
						|
    "#version 330\n"
 | 
						|
    "uniform mat4 mvp;\n"
 | 
						|
    "uniform mat4 tm;\n"
 | 
						|
    "in vec4 position;\n"
 | 
						|
    "in vec2 texcoord0;\n"
 | 
						|
    "in vec4 color0;\n"
 | 
						|
    "out vec4 uv;\n"
 | 
						|
    "out vec4 color;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "    gl_Position = mvp * position;\n"
 | 
						|
    "    uv = tm * vec4(texcoord0, 0.0, 1.0);\n"
 | 
						|
    "    color = color0;\n"
 | 
						|
    "}\n";
 | 
						|
static const char* _sfons_fs_src =
 | 
						|
    "#version 330\n"
 | 
						|
    "uniform sampler2D tex;\n"
 | 
						|
    "in vec4 uv;\n"
 | 
						|
    "in vec4 color;\n"
 | 
						|
    "out vec4 frag_color;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "    frag_color = vec4(1.0, 1.0, 1.0, texture(tex, uv.xy).r) * color;\n"
 | 
						|
    "}\n";
 | 
						|
#elif defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
 | 
						|
static const char* _sfons_vs_src =
 | 
						|
    "uniform mat4 mvp;\n"
 | 
						|
    "uniform mat4 tm;\n"
 | 
						|
    "attribute vec4 position;\n"
 | 
						|
    "attribute vec2 texcoord0;\n"
 | 
						|
    "attribute vec4 color0;\n"
 | 
						|
    "varying vec4 uv;\n"
 | 
						|
    "varying vec4 color;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "    gl_Position = mvp * position;\n"
 | 
						|
    "    uv = tm * vec4(texcoord0, 0.0, 1.0);\n"
 | 
						|
    "    color = color0;\n"
 | 
						|
    "}\n";
 | 
						|
static const char* _sfons_fs_src =
 | 
						|
    "precision mediump float;\n"
 | 
						|
    "uniform sampler2D tex;\n"
 | 
						|
    "varying vec4 uv;\n"
 | 
						|
    "varying vec4 color;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "    gl_FragColor = vec4(1.0, 1.0, 1.0, texture2D(tex, uv.xy).r) * color;\n"
 | 
						|
    "}\n";
 | 
						|
#elif defined(SOKOL_METAL)
 | 
						|
static const char* _sfons_vs_src =
 | 
						|
    "#include <metal_stdlib>\n"
 | 
						|
    "using namespace metal;\n"
 | 
						|
    "struct params_t {\n"
 | 
						|
    "  float4x4 mvp;\n"
 | 
						|
    "  float4x4 tm;\n"
 | 
						|
    "};\n"
 | 
						|
    "struct vs_in {\n"
 | 
						|
    "  float4 pos [[attribute(0)]];\n"
 | 
						|
    "  float2 uv [[attribute(1)]];\n"
 | 
						|
    "  float4 color [[attribute(2)]];\n"
 | 
						|
    "};\n"
 | 
						|
    "struct vs_out {\n"
 | 
						|
    "  float4 pos [[position]];\n"
 | 
						|
    "  float4 uv;\n"
 | 
						|
    "  float4 color;\n"
 | 
						|
    "};\n"
 | 
						|
    "vertex vs_out _main(vs_in in [[stage_in]], constant params_t& params [[buffer(0)]]) {\n"
 | 
						|
    "  vs_out out;\n"
 | 
						|
    "  out.pos = params.mvp * in.pos;\n"
 | 
						|
    "  out.uv = params.tm * float4(in.uv, 0.0, 1.0);\n"
 | 
						|
    "  out.color = in.color;\n"
 | 
						|
    "  return out;\n"
 | 
						|
    "}\n";
 | 
						|
static const char* _sfons_fs_src =
 | 
						|
    "#include <metal_stdlib>\n"
 | 
						|
    "using namespace metal;\n"
 | 
						|
    "struct fs_in {\n"
 | 
						|
    "  float4 uv;\n"
 | 
						|
    "  float4 color;\n"
 | 
						|
    "};\n"
 | 
						|
    "fragment float4 _main(fs_in in [[stage_in]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]]) {\n"
 | 
						|
    "  return float4(1.0, 1.0, 1.0, tex.sample(smp, in.uv.xy).r) * in.color;\n"
 | 
						|
    "}\n";
 | 
						|
#elif defined(SOKOL_D3D11)
 | 
						|
/*
 | 
						|
    Shader blobs for D3D11, compiled with:
 | 
						|
 | 
						|
    fxc.exe /T vs_4_0 /Fh vs.h /Gec /O3 vs.hlsl
 | 
						|
    fxc.exe /T ps_4_0 /Fh fs.h /Gec /O3 fs.hlsl
 | 
						|
 | 
						|
    Vertex shader source:
 | 
						|
 | 
						|
        cbuffer params: register(b0) {
 | 
						|
            float4x4 mvp;
 | 
						|
            float4x4 tm;
 | 
						|
        };
 | 
						|
        struct vs_in {
 | 
						|
            float4 pos: POSITION;
 | 
						|
            float2 uv: TEXCOORD0;
 | 
						|
            float4 color: COLOR0;
 | 
						|
        };
 | 
						|
        struct vs_out {
 | 
						|
            float4 uv: TEXCOORD0;
 | 
						|
            float4 color: COLOR0;
 | 
						|
            float4 pos: SV_Position;
 | 
						|
        };
 | 
						|
        vs_out main(vs_in inp) {
 | 
						|
            vs_out outp;
 | 
						|
            outp.pos = mul(mvp, inp.pos);
 | 
						|
            outp.uv = mul(tm, float4(inp.uv, 0.0, 1.0));
 | 
						|
            outp.color = inp.color;
 | 
						|
            return outp;
 | 
						|
        };
 | 
						|
 | 
						|
    Pixel shader source:
 | 
						|
 | 
						|
        Texture2D<float4> tex: register(t0);
 | 
						|
        sampler smp: register(s0);
 | 
						|
        float4 main(float4 uv: TEXCOORD0, float4 color: COLOR0): SV_Target0 {
 | 
						|
            return float4(1.0, 1.0, 1.0, tex.Sample(smp, uv.xy).r) * color;
 | 
						|
        }
 | 
						|
*/
 | 
						|
static const uint8_t _sfons_vs_bin[] = {
 | 
						|
     68,  88,  66,  67,  89, 173,
 | 
						|
    124, 225,  74, 102, 159,  55,
 | 
						|
     47,  64, 241,  32,  31, 107,
 | 
						|
    240, 204,   1,   0,   0,   0,
 | 
						|
    244,   3,   0,   0,   5,   0,
 | 
						|
      0,   0,  52,   0,   0,   0,
 | 
						|
      8,   1,   0,   0, 120,   1,
 | 
						|
      0,   0, 236,   1,   0,   0,
 | 
						|
    120,   3,   0,   0,  82,  68,
 | 
						|
     69,  70, 204,   0,   0,   0,
 | 
						|
      1,   0,   0,   0,  68,   0,
 | 
						|
      0,   0,   1,   0,   0,   0,
 | 
						|
     28,   0,   0,   0,   0,   4,
 | 
						|
    254, 255,   0,  17,   0,   0,
 | 
						|
    163,   0,   0,   0,  60,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,   1,   0,   0,   0,
 | 
						|
    112,  97, 114,  97, 109, 115,
 | 
						|
      0, 171,  60,   0,   0,   0,
 | 
						|
      2,   0,   0,   0,  92,   0,
 | 
						|
      0,   0, 128,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0, 140,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,  64,   0,
 | 
						|
      0,   0,   2,   0,   0,   0,
 | 
						|
    144,   0,   0,   0,   0,   0,
 | 
						|
      0,   0, 160,   0,   0,   0,
 | 
						|
     64,   0,   0,   0,  64,   0,
 | 
						|
      0,   0,   2,   0,   0,   0,
 | 
						|
    144,   0,   0,   0,   0,   0,
 | 
						|
      0,   0, 109, 118, 112,   0,
 | 
						|
      3,   0,   3,   0,   4,   0,
 | 
						|
      4,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0, 116, 109,
 | 
						|
      0,  77, 105,  99, 114, 111,
 | 
						|
    115, 111, 102, 116,  32,  40,
 | 
						|
     82,  41,  32,  72,  76,  83,
 | 
						|
     76,  32,  83, 104,  97, 100,
 | 
						|
    101, 114,  32,  67, 111, 109,
 | 
						|
    112, 105, 108, 101, 114,  32,
 | 
						|
     49,  48,  46,  49,   0, 171,
 | 
						|
     73,  83,  71,  78, 104,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      8,   0,   0,   0,  80,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   3,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
     15,  15,   0,   0,  89,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   3,   0,
 | 
						|
      0,   0,   1,   0,   0,   0,
 | 
						|
      3,   3,   0,   0,  98,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   3,   0,
 | 
						|
      0,   0,   2,   0,   0,   0,
 | 
						|
     15,  15,   0,   0,  80,  79,
 | 
						|
     83,  73,  84,  73,  79,  78,
 | 
						|
      0,  84,  69,  88,  67,  79,
 | 
						|
     79,  82,  68,   0,  67,  79,
 | 
						|
     76,  79,  82,   0,  79,  83,
 | 
						|
     71,  78, 108,   0,   0,   0,
 | 
						|
      3,   0,   0,   0,   8,   0,
 | 
						|
      0,   0,  80,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,  15,   0,
 | 
						|
      0,   0,  89,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      1,   0,   0,   0,  15,   0,
 | 
						|
      0,   0,  95,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      2,   0,   0,   0,  15,   0,
 | 
						|
      0,   0,  84,  69,  88,  67,
 | 
						|
     79,  79,  82,  68,   0,  67,
 | 
						|
     79,  76,  79,  82,   0,  83,
 | 
						|
     86,  95,  80, 111, 115, 105,
 | 
						|
    116, 105, 111, 110,   0, 171,
 | 
						|
     83,  72,  68,  82, 132,   1,
 | 
						|
      0,   0,  64,   0,   1,   0,
 | 
						|
     97,   0,   0,   0,  89,   0,
 | 
						|
      0,   4,  70, 142,  32,   0,
 | 
						|
      0,   0,   0,   0,   8,   0,
 | 
						|
      0,   0,  95,   0,   0,   3,
 | 
						|
    242,  16,  16,   0,   0,   0,
 | 
						|
      0,   0,  95,   0,   0,   3,
 | 
						|
     50,  16,  16,   0,   1,   0,
 | 
						|
      0,   0,  95,   0,   0,   3,
 | 
						|
    242,  16,  16,   0,   2,   0,
 | 
						|
      0,   0, 101,   0,   0,   3,
 | 
						|
    242,  32,  16,   0,   0,   0,
 | 
						|
      0,   0, 101,   0,   0,   3,
 | 
						|
    242,  32,  16,   0,   1,   0,
 | 
						|
      0,   0, 103,   0,   0,   4,
 | 
						|
    242,  32,  16,   0,   2,   0,
 | 
						|
      0,   0,   1,   0,   0,   0,
 | 
						|
    104,   0,   0,   2,   1,   0,
 | 
						|
      0,   0,  56,   0,   0,   8,
 | 
						|
    242,   0,  16,   0,   0,   0,
 | 
						|
      0,   0,  86,  21,  16,   0,
 | 
						|
      1,   0,   0,   0,  70, 142,
 | 
						|
     32,   0,   0,   0,   0,   0,
 | 
						|
      5,   0,   0,   0,  50,   0,
 | 
						|
      0,  10, 242,   0,  16,   0,
 | 
						|
      0,   0,   0,   0,  70, 142,
 | 
						|
     32,   0,   0,   0,   0,   0,
 | 
						|
      4,   0,   0,   0,   6,  16,
 | 
						|
     16,   0,   1,   0,   0,   0,
 | 
						|
     70,  14,  16,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   8,
 | 
						|
    242,  32,  16,   0,   0,   0,
 | 
						|
      0,   0,  70,  14,  16,   0,
 | 
						|
      0,   0,   0,   0,  70, 142,
 | 
						|
     32,   0,   0,   0,   0,   0,
 | 
						|
      7,   0,   0,   0,  54,   0,
 | 
						|
      0,   5, 242,  32,  16,   0,
 | 
						|
      1,   0,   0,   0,  70,  30,
 | 
						|
     16,   0,   2,   0,   0,   0,
 | 
						|
     56,   0,   0,   8, 242,   0,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     86,  21,  16,   0,   0,   0,
 | 
						|
      0,   0,  70, 142,  32,   0,
 | 
						|
      0,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,  50,   0,   0,  10,
 | 
						|
    242,   0,  16,   0,   0,   0,
 | 
						|
      0,   0,  70, 142,  32,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   6,  16,  16,   0,
 | 
						|
      0,   0,   0,   0,  70,  14,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     50,   0,   0,  10, 242,   0,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     70, 142,  32,   0,   0,   0,
 | 
						|
      0,   0,   2,   0,   0,   0,
 | 
						|
    166,  26,  16,   0,   0,   0,
 | 
						|
      0,   0,  70,  14,  16,   0,
 | 
						|
      0,   0,   0,   0,  50,   0,
 | 
						|
      0,  10, 242,  32,  16,   0,
 | 
						|
      2,   0,   0,   0,  70, 142,
 | 
						|
     32,   0,   0,   0,   0,   0,
 | 
						|
      3,   0,   0,   0, 246,  31,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     70,  14,  16,   0,   0,   0,
 | 
						|
      0,   0,  62,   0,   0,   1,
 | 
						|
     83,  84,  65,  84, 116,   0,
 | 
						|
      0,   0,   9,   0,   0,   0,
 | 
						|
      1,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   6,   0,   0,   0,
 | 
						|
      7,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      1,   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,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      1,   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,   0,   0,   0,
 | 
						|
      0,   0,   0,   0
 | 
						|
};
 | 
						|
static uint8_t _sfons_fs_bin[] = {
 | 
						|
     68,  88,  66,  67, 180,  53,
 | 
						|
    115, 174, 239,  17, 254, 112,
 | 
						|
     63, 104, 217, 123, 150, 145,
 | 
						|
    179,  27,   1,   0,   0,   0,
 | 
						|
    120,   2,   0,   0,   5,   0,
 | 
						|
      0,   0,  52,   0,   0,   0,
 | 
						|
    200,   0,   0,   0,  24,   1,
 | 
						|
      0,   0,  76,   1,   0,   0,
 | 
						|
    252,   1,   0,   0,  82,  68,
 | 
						|
     69,  70, 140,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   2,   0,   0,   0,
 | 
						|
     28,   0,   0,   0,   0,   4,
 | 
						|
    255, 255,   0,  17,   0,   0,
 | 
						|
    100,   0,   0,   0,  92,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,   1,   0,   0,   0,
 | 
						|
     96,   0,   0,   0,   2,   0,
 | 
						|
      0,   0,   5,   0,   0,   0,
 | 
						|
      4,   0,   0,   0, 255, 255,
 | 
						|
    255, 255,   0,   0,   0,   0,
 | 
						|
      1,   0,   0,   0,  13,   0,
 | 
						|
      0,   0, 115, 109, 112,   0,
 | 
						|
    116, 101, 120,   0,  77, 105,
 | 
						|
     99, 114, 111, 115, 111, 102,
 | 
						|
    116,  32,  40,  82,  41,  32,
 | 
						|
     72,  76,  83,  76,  32,  83,
 | 
						|
    104,  97, 100, 101, 114,  32,
 | 
						|
     67, 111, 109, 112, 105, 108,
 | 
						|
    101, 114,  32,  49,  48,  46,
 | 
						|
     49,   0,  73,  83,  71,  78,
 | 
						|
     72,   0,   0,   0,   2,   0,
 | 
						|
      0,   0,   8,   0,   0,   0,
 | 
						|
     56,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      3,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,  15,   3,   0,   0,
 | 
						|
     65,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      3,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,  15,  15,   0,   0,
 | 
						|
     84,  69,  88,  67,  79,  79,
 | 
						|
     82,  68,   0,  67,  79,  76,
 | 
						|
     79,  82,   0, 171,  79,  83,
 | 
						|
     71,  78,  44,   0,   0,   0,
 | 
						|
      1,   0,   0,   0,   8,   0,
 | 
						|
      0,   0,  32,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   3,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,  15,   0,
 | 
						|
      0,   0,  83,  86,  95,  84,
 | 
						|
     97, 114, 103, 101, 116,   0,
 | 
						|
    171, 171,  83,  72,  68,  82,
 | 
						|
    168,   0,   0,   0,  64,   0,
 | 
						|
      0,   0,  42,   0,   0,   0,
 | 
						|
     90,   0,   0,   3,   0,  96,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     88,  24,   0,   4,   0, 112,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     85,  85,   0,   0,  98,  16,
 | 
						|
      0,   3,  50,  16,  16,   0,
 | 
						|
      0,   0,   0,   0,  98,  16,
 | 
						|
      0,   3, 242,  16,  16,   0,
 | 
						|
      1,   0,   0,   0, 101,   0,
 | 
						|
      0,   3, 242,  32,  16,   0,
 | 
						|
      0,   0,   0,   0, 104,   0,
 | 
						|
      0,   2,   1,   0,   0,   0,
 | 
						|
     69,   0,   0,   9, 242,   0,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     70,  16,  16,   0,   0,   0,
 | 
						|
      0,   0, 150, 115,  16,   0,
 | 
						|
      0,   0,   0,   0,   0,  96,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
     54,   0,   0,   5,  18,   0,
 | 
						|
     16,   0,   0,   0,   0,   0,
 | 
						|
      1,  64,   0,   0,   0,   0,
 | 
						|
    128,  63,  56,   0,   0,   7,
 | 
						|
    242,  32,  16,   0,   0,   0,
 | 
						|
      0,   0,   6,  12,  16,   0,
 | 
						|
      0,   0,   0,   0,  70,  30,
 | 
						|
     16,   0,   1,   0,   0,   0,
 | 
						|
     62,   0,   0,   1,  83,  84,
 | 
						|
     65,  84, 116,   0,   0,   0,
 | 
						|
      4,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      3,   0,   0,   0,   1,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   1,   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,   1,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   0,   0,
 | 
						|
      0,   0,   0,   0,   1,   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,   0,   0,   0,   0,   0,
 | 
						|
      0,   0
 | 
						|
};
 | 
						|
#elif defined(SOKOL_DUMMY_BACKEND)
 | 
						|
static const char* _sfons_vs_src = "";
 | 
						|
static const char* _sfons_fs_src = "";
 | 
						|
#endif
 | 
						|
 | 
						|
typedef struct _sfons_t {
 | 
						|
    sg_shader shd;
 | 
						|
    sgl_pipeline pip;
 | 
						|
    sg_image img;
 | 
						|
    int width, height;
 | 
						|
    bool img_dirty;
 | 
						|
} _sfons_t;
 | 
						|
 | 
						|
static int _sfons_render_create(void* user_ptr, int width, int height) {
 | 
						|
    SOKOL_ASSERT(user_ptr && (width > 8) && (height > 8));
 | 
						|
    _sfons_t* sfons = (_sfons_t*) user_ptr;
 | 
						|
 | 
						|
    /* sokol-gl compatible shader which treats RED channel as alpha */
 | 
						|
    if (sfons->shd.id == SG_INVALID_ID) {
 | 
						|
        sg_shader_desc shd_desc;
 | 
						|
        memset(&shd_desc, 0, sizeof(shd_desc));
 | 
						|
        shd_desc.attrs[0].name = "position";
 | 
						|
        shd_desc.attrs[1].name = "texcoord0";
 | 
						|
        shd_desc.attrs[2].name = "color0";
 | 
						|
        shd_desc.attrs[0].sem_name = "POSITION";
 | 
						|
        shd_desc.attrs[1].sem_name = "TEXCOORD";
 | 
						|
        shd_desc.attrs[2].sem_name = "COLOR";
 | 
						|
        sg_shader_uniform_block_desc* ub = &shd_desc.vs.uniform_blocks[0];
 | 
						|
        ub->size = 128;
 | 
						|
        ub->uniforms[0].name = "mvp";
 | 
						|
        ub->uniforms[0].type = SG_UNIFORMTYPE_MAT4;
 | 
						|
        ub->uniforms[1].name = "tm";
 | 
						|
        ub->uniforms[1].type = SG_UNIFORMTYPE_MAT4;
 | 
						|
        shd_desc.fs.images[0].name = "tex";
 | 
						|
        shd_desc.fs.images[0].type = SG_IMAGETYPE_2D;
 | 
						|
        #if defined(SOKOL_D3D11)
 | 
						|
            shd_desc.vs.byte_code = _sfons_vs_bin;
 | 
						|
            shd_desc.vs.byte_code_size = sizeof(_sfons_vs_bin);
 | 
						|
            shd_desc.fs.byte_code = _sfons_fs_bin;
 | 
						|
            shd_desc.fs.byte_code_size = sizeof(_sfons_fs_bin);
 | 
						|
        #else
 | 
						|
            shd_desc.vs.source = _sfons_vs_src;
 | 
						|
            shd_desc.fs.source = _sfons_fs_src;
 | 
						|
        #endif
 | 
						|
        shd_desc.label = "sfons-shader";
 | 
						|
        sfons->shd = sg_make_shader(&shd_desc);
 | 
						|
    }
 | 
						|
 | 
						|
    /* sokol-gl pipeline object */
 | 
						|
    if (sfons->pip.id == SG_INVALID_ID) {
 | 
						|
        sg_pipeline_desc pip_desc;
 | 
						|
        memset(&pip_desc, 0, sizeof(pip_desc));
 | 
						|
        pip_desc.shader = sfons->shd;
 | 
						|
        pip_desc.blend.enabled = true;
 | 
						|
        pip_desc.blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
 | 
						|
        pip_desc.blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
 | 
						|
        sfons->pip = sgl_make_pipeline(&pip_desc);
 | 
						|
    }
 | 
						|
 | 
						|
    /* create or re-create font atlas texture */
 | 
						|
    if (sfons->img.id != SG_INVALID_ID) {
 | 
						|
        sg_destroy_image(sfons->img);
 | 
						|
        sfons->img.id = SG_INVALID_ID;
 | 
						|
    }
 | 
						|
    sfons->width = width;
 | 
						|
    sfons->height = height;
 | 
						|
 | 
						|
    SOKOL_ASSERT(sfons->img.id == SG_INVALID_ID);
 | 
						|
    sg_image_desc img_desc;
 | 
						|
    memset(&img_desc, 0, sizeof(img_desc));
 | 
						|
    img_desc.width = sfons->width;
 | 
						|
    img_desc.height = sfons->height;
 | 
						|
    img_desc.min_filter = SG_FILTER_LINEAR;
 | 
						|
    img_desc.mag_filter = SG_FILTER_LINEAR;
 | 
						|
    img_desc.usage = SG_USAGE_DYNAMIC;
 | 
						|
    img_desc.pixel_format = SG_PIXELFORMAT_R8;
 | 
						|
    sfons->img = sg_make_image(&img_desc);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int _sfons_render_resize(void* user_ptr, int width, int height) {
 | 
						|
    return _sfons_render_create(user_ptr, width, height);
 | 
						|
}
 | 
						|
 | 
						|
static void _sfons_render_update(void* user_ptr, int* rect, const unsigned char* data) {
 | 
						|
    SOKOL_ASSERT(user_ptr && rect && data);
 | 
						|
    _sfons_t* sfons = (_sfons_t*) user_ptr;
 | 
						|
    sfons->img_dirty = true;
 | 
						|
}
 | 
						|
 | 
						|
static void _sfons_render_draw(void* user_ptr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts) {
 | 
						|
    SOKOL_ASSERT(user_ptr && verts && tcoords && colors && (nverts > 0));
 | 
						|
    _sfons_t* sfons = (_sfons_t*) user_ptr;
 | 
						|
    sgl_enable_texture();
 | 
						|
    sgl_texture(sfons->img);
 | 
						|
    sgl_push_pipeline();
 | 
						|
    sgl_load_pipeline(sfons->pip);
 | 
						|
    sgl_begin_triangles();
 | 
						|
    for (int i = 0; i < nverts; i++) {
 | 
						|
        sgl_v2f_t2f_c1i(verts[2*i+0], verts[2*i+1], tcoords[2*i+0], tcoords[2*i+1], colors[i]);
 | 
						|
    }
 | 
						|
    sgl_end();
 | 
						|
    sgl_pop_pipeline();
 | 
						|
    sgl_disable_texture();
 | 
						|
}
 | 
						|
 | 
						|
static void _sfons_render_delete(void* user_ptr) {
 | 
						|
    SOKOL_ASSERT(user_ptr);
 | 
						|
    _sfons_t* sfons = (_sfons_t*) user_ptr;
 | 
						|
    if (sfons->img.id != SG_INVALID_ID) {
 | 
						|
        sg_destroy_image(sfons->img);
 | 
						|
        sfons->img.id = SG_INVALID_ID;
 | 
						|
    }
 | 
						|
    if (sfons->pip.id != SG_INVALID_ID) {
 | 
						|
        sgl_destroy_pipeline(sfons->pip);
 | 
						|
        sfons->pip.id = SG_INVALID_ID;
 | 
						|
    }
 | 
						|
    if (sfons->shd.id != SG_INVALID_ID) {
 | 
						|
        sg_destroy_shader(sfons->shd);
 | 
						|
        sfons->shd.id = SG_INVALID_ID;
 | 
						|
    }
 | 
						|
    SOKOL_FREE(sfons);
 | 
						|
}
 | 
						|
 | 
						|
SOKOL_API_IMPL FONScontext* sfons_create(int width, int height, int flags) {
 | 
						|
    SOKOL_ASSERT((width > 0) && (height > 0));
 | 
						|
    FONSparams params;
 | 
						|
    _sfons_t* sfons = (_sfons_t*) SOKOL_MALLOC(sizeof(_sfons_t));
 | 
						|
    memset(sfons, 0, sizeof(_sfons_t));
 | 
						|
    memset(¶ms, 0, sizeof(params));
 | 
						|
    params.width = width;
 | 
						|
    params.height = height;
 | 
						|
    params.flags = (unsigned char) flags;
 | 
						|
    params.renderCreate = _sfons_render_create;
 | 
						|
    params.renderResize = _sfons_render_resize;
 | 
						|
    params.renderUpdate = _sfons_render_update;
 | 
						|
    params.renderDraw = _sfons_render_draw;
 | 
						|
    params.renderDelete = _sfons_render_delete;
 | 
						|
    params.userPtr = sfons;
 | 
						|
    return fonsCreateInternal(¶ms);
 | 
						|
}
 | 
						|
 | 
						|
SOKOL_API_IMPL void sfons_destroy(FONScontext* ctx) {
 | 
						|
    SOKOL_ASSERT(ctx);
 | 
						|
    fonsDeleteInternal(ctx);
 | 
						|
}
 | 
						|
 | 
						|
SOKOL_API_IMPL void sfons_flush(FONScontext* ctx) {
 | 
						|
    SOKOL_ASSERT(ctx && ctx->params.userPtr);
 | 
						|
    _sfons_t* sfons = (_sfons_t*) ctx->params.userPtr;
 | 
						|
    if (sfons->img_dirty) {
 | 
						|
        sfons->img_dirty = false;
 | 
						|
        sg_image_content content;
 | 
						|
        memset(&content, 0, sizeof(content));
 | 
						|
        content.subimage[0][0].ptr = ctx->texData;
 | 
						|
        content.subimage[0][0].size = sfons->width * sfons->height;
 | 
						|
        sg_update_image(sfons->img, &content);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
SOKOL_API_IMPL uint32_t sfons_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
 | 
						|
    return (r) | (g<<8) | (b<<16) | (a<<24);
 | 
						|
}
 | 
						|
 | 
						|
#endif /* SOKOL_FONTSTASH_IMPL */
 |