[graphics] Allocate canvases and fonts from graphics subsystem's arena
This commit is contained in:
parent
6bf989564d
commit
28f5af32fa
|
@ -114,14 +114,13 @@ bool mg_egl_surface_get_hidden(mg_surface_data* interface)
|
||||||
return(mp_layer_get_hidden(&surface->layer));
|
return(mp_layer_get_hidden(&surface->layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_surface mg_egl_surface_create_for_window(mp_window window)
|
mg_surface_data* mg_egl_surface_create_for_window(mp_window window)
|
||||||
{
|
{
|
||||||
mg_surface res = mg_surface_nil();
|
mg_egl_surface* surface = 0;
|
||||||
|
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
mg_egl_surface* surface = malloc_type(mg_egl_surface);
|
surface = malloc_type(mg_egl_surface);
|
||||||
memset(surface, 0, sizeof(mg_egl_surface));
|
memset(surface, 0, sizeof(mg_egl_surface));
|
||||||
|
|
||||||
surface->interface.backend = MG_BACKEND_GLES;
|
surface->interface.backend = MG_BACKEND_GLES;
|
||||||
|
@ -182,8 +181,6 @@ mg_surface mg_egl_surface_create_for_window(mp_window window)
|
||||||
mg_gl_load_gles(&surface->api, (mg_gl_load_proc)eglGetProcAddress);
|
mg_gl_load_gles(&surface->api, (mg_gl_load_proc)eglGetProcAddress);
|
||||||
|
|
||||||
eglSwapInterval(surface->eglDisplay, 1);
|
eglSwapInterval(surface->eglDisplay, 1);
|
||||||
|
|
||||||
res = mg_surface_handle_alloc((mg_surface_data*)surface);
|
|
||||||
}
|
}
|
||||||
return(res);
|
return((mg_surface_data*)surface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
#ifndef __EGL_SURFACE_H_
|
#ifndef __EGL_SURFACE_H_
|
||||||
#define __EGL_SURFACE_H_
|
#define __EGL_SURFACE_H_
|
||||||
|
|
||||||
#include"graphics.h"
|
#include"graphics_internal.h"
|
||||||
#include"mp_app.h"
|
#include"mp_app.h"
|
||||||
|
|
||||||
mg_surface mg_egl_surface_create_for_window(mp_window window);
|
mg_surface_data* mg_egl_surface_create_for_window(mp_window window);
|
||||||
|
|
||||||
#endif // __EGL_SURFACE_H_
|
#endif // __EGL_SURFACE_H_
|
||||||
|
|
383
src/graphics.c
383
src/graphics.c
|
@ -120,12 +120,6 @@ typedef struct mg_glyph_data
|
||||||
|
|
||||||
} mg_glyph_data;
|
} mg_glyph_data;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MG_STREAM_MAX_COUNT = 128,
|
|
||||||
MG_IMAGE_MAX_COUNT = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MG_MATRIX_STACK_MAX_DEPTH = 64,
|
MG_MATRIX_STACK_MAX_DEPTH = 64,
|
||||||
|
@ -137,7 +131,6 @@ enum
|
||||||
typedef struct mg_font_data
|
typedef struct mg_font_data
|
||||||
{
|
{
|
||||||
list_elt freeListElt;
|
list_elt freeListElt;
|
||||||
u32 generation;
|
|
||||||
|
|
||||||
u32 rangeCount;
|
u32 rangeCount;
|
||||||
u32 glyphCount;
|
u32 glyphCount;
|
||||||
|
@ -180,14 +173,15 @@ typedef struct mg_data
|
||||||
mem_arena handleArena;
|
mem_arena handleArena;
|
||||||
list_info handleFreeList;
|
list_info handleFreeList;
|
||||||
|
|
||||||
|
mem_arena resourceArena;
|
||||||
|
list_info canvasFreeList;
|
||||||
|
list_info fontFreeList;
|
||||||
|
|
||||||
} mg_data;
|
} mg_data;
|
||||||
|
|
||||||
typedef struct mg_canvas_data
|
typedef struct mg_canvas_data
|
||||||
{
|
{
|
||||||
list_elt freeListElt;
|
list_elt freeListElt;
|
||||||
u32 generation;
|
|
||||||
|
|
||||||
u64 frameCounter;
|
|
||||||
|
|
||||||
mg_attributes attributes;
|
mg_attributes attributes;
|
||||||
bool textFlip;
|
bool textFlip;
|
||||||
|
@ -206,12 +200,6 @@ typedef struct mg_canvas_data
|
||||||
u32 primitiveCount;
|
u32 primitiveCount;
|
||||||
mg_primitive primitives[MG_MAX_PRIMITIVE_COUNT];
|
mg_primitive primitives[MG_MAX_PRIMITIVE_COUNT];
|
||||||
|
|
||||||
/*
|
|
||||||
vec2 atlasPos;
|
|
||||||
u32 atlasLineHeight;
|
|
||||||
mg_image blankImage;
|
|
||||||
*/
|
|
||||||
|
|
||||||
//NOTE: these are used at render time
|
//NOTE: these are used at render time
|
||||||
mp_rect clip;
|
mp_rect clip;
|
||||||
mg_mat2x3 transform;
|
mg_mat2x3 transform;
|
||||||
|
@ -235,9 +223,8 @@ void mg_init()
|
||||||
if(!__mgData.init)
|
if(!__mgData.init)
|
||||||
{
|
{
|
||||||
mem_arena_init(&__mgData.handleArena);
|
mem_arena_init(&__mgData.handleArena);
|
||||||
|
mem_arena_init(&__mgData.resourceArena);
|
||||||
__mgData.init = true;
|
__mgData.init = true;
|
||||||
|
|
||||||
//...
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +421,12 @@ bool mg_surface_is_nil(mg_surface surface) { return(surface.h == 0); }
|
||||||
|
|
||||||
mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend)
|
mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend)
|
||||||
{
|
{
|
||||||
mg_surface surface = mg_surface_nil();
|
if(__mgData.init)
|
||||||
|
{
|
||||||
|
mg_init();
|
||||||
|
}
|
||||||
|
mg_surface surfaceHandle = mg_surface_nil();
|
||||||
|
mg_surface_data* surface = 0;
|
||||||
|
|
||||||
switch(backend)
|
switch(backend)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +451,11 @@ mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(surface);
|
if(surface)
|
||||||
|
{
|
||||||
|
surfaceHandle = mg_surface_handle_alloc(surface);
|
||||||
|
}
|
||||||
|
return(surfaceHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_surface_destroy(mg_surface handle)
|
void mg_surface_destroy(mg_surface handle)
|
||||||
|
@ -2166,167 +2162,181 @@ bool mg_font_is_nil(mg_font font) { return(font.h == 0); }
|
||||||
|
|
||||||
mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges)
|
mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges)
|
||||||
{
|
{
|
||||||
mg_font_data* fontData = malloc_type(mg_font_data);
|
if(!__mgData.init)
|
||||||
mg_font font = mg_font_handle_alloc(fontData);
|
|
||||||
|
|
||||||
stbtt_fontinfo stbttFontInfo;
|
|
||||||
stbtt_InitFont(&stbttFontInfo, buffer, 0);
|
|
||||||
|
|
||||||
//NOTE(martin): load font metrics data
|
|
||||||
fontData->unitsPerEm = 1./stbtt_ScaleForMappingEmToPixels(&stbttFontInfo, 1);
|
|
||||||
|
|
||||||
int ascent, descent, lineGap, x0, x1, y0, y1;
|
|
||||||
stbtt_GetFontVMetrics(&stbttFontInfo, &ascent, &descent, &lineGap);
|
|
||||||
stbtt_GetFontBoundingBox(&stbttFontInfo, &x0, &y0, &x1, &y1);
|
|
||||||
|
|
||||||
fontData->extents.ascent = ascent;
|
|
||||||
fontData->extents.descent = -descent;
|
|
||||||
fontData->extents.leading = lineGap;
|
|
||||||
fontData->extents.width = x1 - x0;
|
|
||||||
|
|
||||||
stbtt_GetCodepointBox(&stbttFontInfo, 'x', &x0, &y0, &x1, &y1);
|
|
||||||
fontData->extents.xHeight = y1 - y0;
|
|
||||||
|
|
||||||
stbtt_GetCodepointBox(&stbttFontInfo, 'M', &x0, &y0, &x1, &y1);
|
|
||||||
fontData->extents.capHeight = y1 - y0;
|
|
||||||
|
|
||||||
//NOTE(martin): load codepoint ranges
|
|
||||||
fontData->rangeCount = rangeCount;
|
|
||||||
fontData->glyphMap = malloc_array(mg_glyph_map_entry, rangeCount);
|
|
||||||
fontData->glyphCount = 0;
|
|
||||||
|
|
||||||
for(int i=0; i<rangeCount; i++)
|
|
||||||
{
|
{
|
||||||
//NOTE(martin): initialize the map entry.
|
mg_init();
|
||||||
// The glyph indices are offseted by 1, to reserve 0 as an invalid glyph index.
|
|
||||||
fontData->glyphMap[i].range = ranges[i];
|
|
||||||
fontData->glyphMap[i].firstGlyphIndex = fontData->glyphCount + 1;
|
|
||||||
fontData->glyphCount += ranges[i].count;
|
|
||||||
}
|
}
|
||||||
|
mg_font fontHandle = mg_font_nil();
|
||||||
|
|
||||||
fontData->glyphs = malloc_array(mg_glyph_data, fontData->glyphCount);
|
mg_font_data* font = ListPopEntry(&__mgData.fontFreeList, mg_font_data, freeListElt);
|
||||||
|
if(!font)
|
||||||
//NOTE(martin): first do a count of outlines
|
|
||||||
int outlineCount = 0;
|
|
||||||
for(int rangeIndex=0; rangeIndex<rangeCount; rangeIndex++)
|
|
||||||
{
|
{
|
||||||
utf32 codePoint = fontData->glyphMap[rangeIndex].range.firstCodePoint;
|
font = mem_arena_alloc_type(&__mgData.resourceArena, mg_font_data);
|
||||||
u32 firstGlyphIndex = fontData->glyphMap[rangeIndex].firstGlyphIndex;
|
}
|
||||||
u32 endGlyphIndex = firstGlyphIndex + fontData->glyphMap[rangeIndex].range.count;
|
if(font)
|
||||||
|
{
|
||||||
|
memset(font, 0, sizeof(mg_font_data));
|
||||||
|
fontHandle = mg_font_handle_alloc(font);
|
||||||
|
|
||||||
for(int glyphIndex = firstGlyphIndex;
|
stbtt_fontinfo stbttFontInfo;
|
||||||
glyphIndex < endGlyphIndex; glyphIndex++)
|
stbtt_InitFont(&stbttFontInfo, buffer, 0);
|
||||||
|
|
||||||
|
//NOTE(martin): load font metrics data
|
||||||
|
font->unitsPerEm = 1./stbtt_ScaleForMappingEmToPixels(&stbttFontInfo, 1);
|
||||||
|
|
||||||
|
int ascent, descent, lineGap, x0, x1, y0, y1;
|
||||||
|
stbtt_GetFontVMetrics(&stbttFontInfo, &ascent, &descent, &lineGap);
|
||||||
|
stbtt_GetFontBoundingBox(&stbttFontInfo, &x0, &y0, &x1, &y1);
|
||||||
|
|
||||||
|
font->extents.ascent = ascent;
|
||||||
|
font->extents.descent = -descent;
|
||||||
|
font->extents.leading = lineGap;
|
||||||
|
font->extents.width = x1 - x0;
|
||||||
|
|
||||||
|
stbtt_GetCodepointBox(&stbttFontInfo, 'x', &x0, &y0, &x1, &y1);
|
||||||
|
font->extents.xHeight = y1 - y0;
|
||||||
|
|
||||||
|
stbtt_GetCodepointBox(&stbttFontInfo, 'M', &x0, &y0, &x1, &y1);
|
||||||
|
font->extents.capHeight = y1 - y0;
|
||||||
|
|
||||||
|
//NOTE(martin): load codepoint ranges
|
||||||
|
font->rangeCount = rangeCount;
|
||||||
|
font->glyphMap = malloc_array(mg_glyph_map_entry, rangeCount);
|
||||||
|
font->glyphCount = 0;
|
||||||
|
|
||||||
|
for(int i=0; i<rangeCount; i++)
|
||||||
{
|
{
|
||||||
int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint);
|
//NOTE(martin): initialize the map entry.
|
||||||
if(stbttGlyphIndex == 0)
|
// The glyph indices are offseted by 1, to reserve 0 as an invalid glyph index.
|
||||||
{
|
font->glyphMap[i].range = ranges[i];
|
||||||
//NOTE(martin): the codepoint is not found in the font
|
font->glyphMap[i].firstGlyphIndex = font->glyphCount + 1;
|
||||||
codePoint++;
|
font->glyphCount += ranges[i].count;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//NOTE(martin): load glyph outlines
|
|
||||||
stbtt_vertex* vertices = 0;
|
|
||||||
outlineCount += stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices);
|
|
||||||
stbtt_FreeShape(&stbttFontInfo, vertices);
|
|
||||||
codePoint++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//NOTE(martin): allocate outlines
|
|
||||||
fontData->outlines = malloc_array(mg_path_elt, outlineCount);
|
|
||||||
fontData->outlineCount = 0;
|
|
||||||
|
|
||||||
//NOTE(martin): load metrics and outlines
|
font->glyphs = malloc_array(mg_glyph_data, font->glyphCount);
|
||||||
for(int rangeIndex=0; rangeIndex<rangeCount; rangeIndex++)
|
|
||||||
{
|
|
||||||
utf32 codePoint = fontData->glyphMap[rangeIndex].range.firstCodePoint;
|
|
||||||
u32 firstGlyphIndex = fontData->glyphMap[rangeIndex].firstGlyphIndex;
|
|
||||||
u32 endGlyphIndex = firstGlyphIndex + fontData->glyphMap[rangeIndex].range.count;
|
|
||||||
|
|
||||||
for(int glyphIndex = firstGlyphIndex;
|
//NOTE(martin): first do a count of outlines
|
||||||
glyphIndex < endGlyphIndex; glyphIndex++)
|
int outlineCount = 0;
|
||||||
|
for(int rangeIndex=0; rangeIndex<rangeCount; rangeIndex++)
|
||||||
{
|
{
|
||||||
mg_glyph_data* glyph = &(fontData->glyphs[glyphIndex-1]);
|
utf32 codePoint = font->glyphMap[rangeIndex].range.firstCodePoint;
|
||||||
|
u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex;
|
||||||
|
u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count;
|
||||||
|
|
||||||
int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint);
|
for(int glyphIndex = firstGlyphIndex;
|
||||||
if(stbttGlyphIndex == 0)
|
glyphIndex < endGlyphIndex; glyphIndex++)
|
||||||
{
|
{
|
||||||
//NOTE(martin): the codepoint is not found in the font, we zero the glyph info
|
int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint);
|
||||||
memset(glyph, 0, sizeof(*glyph));
|
if(stbttGlyphIndex == 0)
|
||||||
codePoint++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
glyph->exists = true;
|
|
||||||
glyph->codePoint = codePoint;
|
|
||||||
|
|
||||||
//NOTE(martin): load glyph metric
|
|
||||||
int xAdvance, xBearing, x0, y0, x1, y1;
|
|
||||||
stbtt_GetGlyphHMetrics(&stbttFontInfo, stbttGlyphIndex, &xAdvance, &xBearing);
|
|
||||||
stbtt_GetGlyphBox(&stbttFontInfo, stbttGlyphIndex, &x0, &y0, &x1, &y1);
|
|
||||||
|
|
||||||
glyph->extents.xAdvance = (f32)xAdvance;
|
|
||||||
glyph->extents.yAdvance = 0;
|
|
||||||
glyph->extents.xBearing = (f32)xBearing;
|
|
||||||
glyph->extents.yBearing = y0;
|
|
||||||
|
|
||||||
glyph->extents.width = x1 - x0;
|
|
||||||
glyph->extents.height = y1 - y0;
|
|
||||||
|
|
||||||
//NOTE(martin): load glyph outlines
|
|
||||||
|
|
||||||
stbtt_vertex* vertices = 0;
|
|
||||||
int vertexCount = stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices);
|
|
||||||
|
|
||||||
glyph->pathDescriptor = (mg_path_descriptor){.startIndex = fontData->outlineCount,
|
|
||||||
.count = vertexCount,
|
|
||||||
.startPoint = {0, 0}};
|
|
||||||
|
|
||||||
mg_path_elt* elements = fontData->outlines + fontData->outlineCount;
|
|
||||||
fontData->outlineCount += vertexCount;
|
|
||||||
vec2 currentPos = {0, 0};
|
|
||||||
|
|
||||||
for(int vertIndex = 0; vertIndex < vertexCount; vertIndex++)
|
|
||||||
{
|
|
||||||
f32 x = vertices[vertIndex].x;
|
|
||||||
f32 y = vertices[vertIndex].y;
|
|
||||||
f32 cx = vertices[vertIndex].cx;
|
|
||||||
f32 cy = vertices[vertIndex].cy;
|
|
||||||
f32 cx1 = vertices[vertIndex].cx1;
|
|
||||||
f32 cy1 = vertices[vertIndex].cy1;
|
|
||||||
|
|
||||||
switch(vertices[vertIndex].type)
|
|
||||||
{
|
{
|
||||||
case STBTT_vmove:
|
//NOTE(martin): the codepoint is not found in the font
|
||||||
elements[vertIndex].type = MG_PATH_MOVE;
|
codePoint++;
|
||||||
elements[vertIndex].p[0] = (vec2){x, y};
|
continue;
|
||||||
break;
|
|
||||||
|
|
||||||
case STBTT_vline:
|
|
||||||
elements[vertIndex].type = MG_PATH_LINE;
|
|
||||||
elements[vertIndex].p[0] = (vec2){x, y};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STBTT_vcurve:
|
|
||||||
{
|
|
||||||
elements[vertIndex].type = MG_PATH_QUADRATIC;
|
|
||||||
elements[vertIndex].p[0] = (vec2){cx, cy};
|
|
||||||
elements[vertIndex].p[1] = (vec2){x, y};
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case STBTT_vcubic:
|
|
||||||
elements[vertIndex].type = MG_PATH_CUBIC;
|
|
||||||
elements[vertIndex].p[0] = (vec2){cx, cy};
|
|
||||||
elements[vertIndex].p[1] = (vec2){cx1, cy1};
|
|
||||||
elements[vertIndex].p[2] = (vec2){x, y};
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
currentPos = (vec2){x, y};
|
//NOTE(martin): load glyph outlines
|
||||||
|
stbtt_vertex* vertices = 0;
|
||||||
|
outlineCount += stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices);
|
||||||
|
stbtt_FreeShape(&stbttFontInfo, vertices);
|
||||||
|
codePoint++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//NOTE(martin): allocate outlines
|
||||||
|
font->outlines = malloc_array(mg_path_elt, outlineCount);
|
||||||
|
font->outlineCount = 0;
|
||||||
|
|
||||||
|
//NOTE(martin): load metrics and outlines
|
||||||
|
for(int rangeIndex=0; rangeIndex<rangeCount; rangeIndex++)
|
||||||
|
{
|
||||||
|
utf32 codePoint = font->glyphMap[rangeIndex].range.firstCodePoint;
|
||||||
|
u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex;
|
||||||
|
u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count;
|
||||||
|
|
||||||
|
for(int glyphIndex = firstGlyphIndex;
|
||||||
|
glyphIndex < endGlyphIndex; glyphIndex++)
|
||||||
|
{
|
||||||
|
mg_glyph_data* glyph = &(font->glyphs[glyphIndex-1]);
|
||||||
|
|
||||||
|
int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint);
|
||||||
|
if(stbttGlyphIndex == 0)
|
||||||
|
{
|
||||||
|
//NOTE(martin): the codepoint is not found in the font, we zero the glyph info
|
||||||
|
memset(glyph, 0, sizeof(*glyph));
|
||||||
|
codePoint++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
glyph->exists = true;
|
||||||
|
glyph->codePoint = codePoint;
|
||||||
|
|
||||||
|
//NOTE(martin): load glyph metric
|
||||||
|
int xAdvance, xBearing, x0, y0, x1, y1;
|
||||||
|
stbtt_GetGlyphHMetrics(&stbttFontInfo, stbttGlyphIndex, &xAdvance, &xBearing);
|
||||||
|
stbtt_GetGlyphBox(&stbttFontInfo, stbttGlyphIndex, &x0, &y0, &x1, &y1);
|
||||||
|
|
||||||
|
glyph->extents.xAdvance = (f32)xAdvance;
|
||||||
|
glyph->extents.yAdvance = 0;
|
||||||
|
glyph->extents.xBearing = (f32)xBearing;
|
||||||
|
glyph->extents.yBearing = y0;
|
||||||
|
|
||||||
|
glyph->extents.width = x1 - x0;
|
||||||
|
glyph->extents.height = y1 - y0;
|
||||||
|
|
||||||
|
//NOTE(martin): load glyph outlines
|
||||||
|
|
||||||
|
stbtt_vertex* vertices = 0;
|
||||||
|
int vertexCount = stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices);
|
||||||
|
|
||||||
|
glyph->pathDescriptor = (mg_path_descriptor){.startIndex = font->outlineCount,
|
||||||
|
.count = vertexCount,
|
||||||
|
.startPoint = {0, 0}};
|
||||||
|
|
||||||
|
mg_path_elt* elements = font->outlines + font->outlineCount;
|
||||||
|
font->outlineCount += vertexCount;
|
||||||
|
vec2 currentPos = {0, 0};
|
||||||
|
|
||||||
|
for(int vertIndex = 0; vertIndex < vertexCount; vertIndex++)
|
||||||
|
{
|
||||||
|
f32 x = vertices[vertIndex].x;
|
||||||
|
f32 y = vertices[vertIndex].y;
|
||||||
|
f32 cx = vertices[vertIndex].cx;
|
||||||
|
f32 cy = vertices[vertIndex].cy;
|
||||||
|
f32 cx1 = vertices[vertIndex].cx1;
|
||||||
|
f32 cy1 = vertices[vertIndex].cy1;
|
||||||
|
|
||||||
|
switch(vertices[vertIndex].type)
|
||||||
|
{
|
||||||
|
case STBTT_vmove:
|
||||||
|
elements[vertIndex].type = MG_PATH_MOVE;
|
||||||
|
elements[vertIndex].p[0] = (vec2){x, y};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STBTT_vline:
|
||||||
|
elements[vertIndex].type = MG_PATH_LINE;
|
||||||
|
elements[vertIndex].p[0] = (vec2){x, y};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STBTT_vcurve:
|
||||||
|
{
|
||||||
|
elements[vertIndex].type = MG_PATH_QUADRATIC;
|
||||||
|
elements[vertIndex].p[0] = (vec2){cx, cy};
|
||||||
|
elements[vertIndex].p[1] = (vec2){x, y};
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case STBTT_vcubic:
|
||||||
|
elements[vertIndex].type = MG_PATH_CUBIC;
|
||||||
|
elements[vertIndex].p[0] = (vec2){cx, cy};
|
||||||
|
elements[vertIndex].p[1] = (vec2){cx1, cy1};
|
||||||
|
elements[vertIndex].p[2] = (vec2){x, y};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentPos = (vec2){x, y};
|
||||||
|
}
|
||||||
|
stbtt_FreeShape(&stbttFontInfo, vertices);
|
||||||
|
codePoint++;
|
||||||
}
|
}
|
||||||
stbtt_FreeShape(&stbttFontInfo, vertices);
|
|
||||||
codePoint++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(font);
|
return(fontHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_font_destroy(mg_font fontHandle)
|
void mg_font_destroy(mg_font fontHandle)
|
||||||
|
@ -2337,7 +2347,8 @@ void mg_font_destroy(mg_font fontHandle)
|
||||||
free(fontData->glyphMap);
|
free(fontData->glyphMap);
|
||||||
free(fontData->glyphs);
|
free(fontData->glyphs);
|
||||||
free(fontData->outlines);
|
free(fontData->outlines);
|
||||||
free(fontData);
|
|
||||||
|
ListPush(&__mgData.fontFreeList, &fontData->freeListElt);
|
||||||
mg_handle_recycle(fontHandle.h);
|
mg_handle_recycle(fontHandle.h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2598,7 +2609,6 @@ mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
||||||
mg_canvas mg_canvas_nil() { return((mg_canvas){.h = 0}); }
|
mg_canvas mg_canvas_nil() { return((mg_canvas){.h = 0}); }
|
||||||
bool mg_canvas_is_nil(mg_canvas canvas) { return(canvas.h == 0); }
|
bool mg_canvas_is_nil(mg_canvas canvas) { return(canvas.h == 0); }
|
||||||
|
|
||||||
|
|
||||||
#if MG_COMPILE_BACKEND_METAL
|
#if MG_COMPILE_BACKEND_METAL
|
||||||
mg_canvas_backend* mg_mtl_canvas_create(mg_surface surface);
|
mg_canvas_backend* mg_mtl_canvas_create(mg_surface surface);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2609,7 +2619,7 @@ bool mg_canvas_is_nil(mg_canvas canvas) { return(canvas.h == 0); }
|
||||||
|
|
||||||
mg_canvas mg_canvas_create(mg_surface surface)
|
mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
{
|
{
|
||||||
mg_canvas canvas = mg_canvas_nil();
|
mg_canvas canvasHandle = mg_canvas_nil();
|
||||||
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
||||||
if(surfaceData)
|
if(surfaceData)
|
||||||
{
|
{
|
||||||
|
@ -2634,32 +2644,31 @@ mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
|
|
||||||
if(backend)
|
if(backend)
|
||||||
{
|
{
|
||||||
mg_canvas_data* canvasData = malloc_type(mg_canvas_data);
|
mg_canvas_data* canvas = ListPopEntry(&__mgData.canvasFreeList, mg_canvas_data, freeListElt);
|
||||||
memset(canvasData, 0, sizeof(mg_canvas_data));
|
if(!canvas)
|
||||||
|
{
|
||||||
|
canvas = mem_arena_alloc_type(&__mgData.resourceArena, mg_canvas_data);
|
||||||
|
}
|
||||||
|
if(canvas)
|
||||||
|
{
|
||||||
|
memset(canvas, 0, sizeof(mg_canvas_data));
|
||||||
|
}
|
||||||
|
|
||||||
canvasData->backend = backend;
|
canvas->backend = backend;
|
||||||
|
|
||||||
canvasData->primitiveCount = 0;
|
canvas->attributes.color = (mg_color){0, 0, 0, 1};
|
||||||
canvasData->path.startIndex = 0;
|
canvas->attributes.tolerance = 1;
|
||||||
canvasData->path.count = 0;
|
canvas->attributes.width = 10;
|
||||||
canvasData->nextShapeIndex = 0;
|
canvas->attributes.clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
|
||||||
canvasData->attributes.color = (mg_color){0, 0, 0, 1};
|
|
||||||
canvasData->attributes.tolerance = 1;
|
|
||||||
canvasData->attributes.width = 10;
|
|
||||||
canvasData->attributes.clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
|
|
||||||
|
|
||||||
canvasData->transform = (mg_mat2x3){{1, 0, 0,
|
canvasHandle = mg_canvas_handle_alloc(canvas);
|
||||||
0, 1, 0}};
|
mg_canvas_set_current(canvasHandle);
|
||||||
|
|
||||||
|
|
||||||
canvas = mg_canvas_handle_alloc(canvasData);
|
|
||||||
mg_canvas_set_current(canvas);
|
|
||||||
|
|
||||||
//TODO: move that in mg_canvas_set_current() if needed?
|
//TODO: move that in mg_canvas_set_current() if needed?
|
||||||
mg_surface_prepare(surface);
|
mg_surface_prepare(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(canvas);
|
return(canvasHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_canvas_destroy(mg_canvas handle)
|
void mg_canvas_destroy(mg_canvas handle)
|
||||||
|
@ -2677,7 +2686,7 @@ void mg_canvas_destroy(mg_canvas handle)
|
||||||
{
|
{
|
||||||
canvas->backend->destroy(canvas->backend);
|
canvas->backend->destroy(canvas->backend);
|
||||||
}
|
}
|
||||||
free(canvas);
|
ListPush(&__mgData.canvasFreeList, &canvas->freeListElt);
|
||||||
mg_handle_recycle(handle.h);
|
mg_handle_recycle(handle.h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2918,8 +2927,6 @@ void mg_flush()
|
||||||
canvas->primitiveCount = 0;
|
canvas->primitiveCount = 0;
|
||||||
canvas->path.startIndex = 0;
|
canvas->path.startIndex = 0;
|
||||||
canvas->path.count = 0;
|
canvas->path.count = 0;
|
||||||
|
|
||||||
canvas->frameCounter++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
#ifndef __MTL_SURFACE_H_
|
#ifndef __MTL_SURFACE_H_
|
||||||
#define __MTL_SURFACE_H_
|
#define __MTL_SURFACE_H_
|
||||||
|
|
||||||
#include"graphics.h"
|
#include"graphics_internal.h"
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
#import<Metal/Metal.h>
|
#import<Metal/Metal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mg_surface mg_mtl_surface_create_for_window(mp_window window);
|
mg_surface_data* mg_mtl_surface_create_for_window(mp_window window);
|
||||||
|
|
||||||
void* mg_mtl_surface_render_encoder(mg_surface surface);
|
void* mg_mtl_surface_render_encoder(mg_surface surface);
|
||||||
void* mg_mtl_surface_compute_encoder(mg_surface surface);
|
void* mg_mtl_surface_compute_encoder(mg_surface surface);
|
||||||
|
|
|
@ -165,16 +165,13 @@ bool mg_mtl_surface_get_hidden(mg_surface_data* interface)
|
||||||
//TODO fix that according to real scaling, depending on the monitor settings
|
//TODO fix that according to real scaling, depending on the monitor settings
|
||||||
static const f32 MG_MTL_SURFACE_CONTENTS_SCALING = 2;
|
static const f32 MG_MTL_SURFACE_CONTENTS_SCALING = 2;
|
||||||
|
|
||||||
mg_surface mg_mtl_surface_create_for_window(mp_window window)
|
mg_surface_data* mg_mtl_surface_create_for_window(mp_window window)
|
||||||
{
|
{
|
||||||
|
mg_mtl_surface* surface = 0;
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(!windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
return(mg_surface_nil());
|
surface = (mg_mtl_surface*)malloc(sizeof(mg_mtl_surface));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mg_mtl_surface* surface = (mg_mtl_surface*)malloc(sizeof(mg_mtl_surface));
|
|
||||||
|
|
||||||
//NOTE(martin): setup interface functions
|
//NOTE(martin): setup interface functions
|
||||||
surface->interface.backend = MG_BACKEND_METAL;
|
surface->interface.backend = MG_BACKEND_METAL;
|
||||||
|
@ -235,10 +232,8 @@ mg_surface mg_mtl_surface_create_for_window(mp_window window)
|
||||||
surface->drawable = nil;
|
surface->drawable = nil;
|
||||||
surface->commandBuffer = nil;
|
surface->commandBuffer = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_surface handle = mg_surface_handle_alloc((mg_surface_data*)surface);
|
|
||||||
return(handle);
|
|
||||||
}
|
}
|
||||||
|
return((mg_surface_data*)surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* mg_mtl_surface_layer(mg_surface surface)
|
void* mg_mtl_surface_layer(mg_surface surface)
|
||||||
|
|
Loading…
Reference in New Issue