Font:getVertices;

This commit is contained in:
bjorn 2022-07-03 22:40:05 -07:00
parent 889b1d8271
commit 4e8fe82f94
3 changed files with 83 additions and 33 deletions

View File

@ -106,6 +106,16 @@ static void online(void* context, const char* string, size_t length) {
lua_rawseti(L, -2, index);
}
static int l_lovrFontGetWidth(lua_State* L) {
Font* font = luax_checktype(L, 1, Font);
uint32_t count;
ColoredString stack;
ColoredString* strings = luax_checkcoloredstrings(L, 2, &count, &stack);
float width = lovrFontGetWidth(font, strings, count);
lua_pushnumber(L, width);
return 1;
}
static int l_lovrFontGetLines(lua_State* L) {
Font* font = luax_checktype(L, 1, Font);
uint32_t count;
@ -118,14 +128,41 @@ static int l_lovrFontGetLines(lua_State* L) {
return 1;
}
static int l_lovrFontGetWidth(lua_State* L) {
static int l_lovrFontGetVertices(lua_State* L) {
Font* font = luax_checktype(L, 1, Font);
uint32_t count;
ColoredString stack;
ColoredString* strings = luax_checkcoloredstrings(L, 2, &count, &stack);
float width = lovrFontGetWidth(font, strings, count);
lua_pushnumber(L, width);
return 1;
float wrap = luax_checkfloat(L, 3);
HorizontalAlign halign = luax_checkenum(L, 4, HorizontalAlign, "center");
VerticalAlign valign = luax_checkenum(L, 5, VerticalAlign, "middle");
size_t totalLength = 0;
for (uint32_t i = 0; i < count; i++) {
totalLength += strings[i].length;
}
GlyphVertex* vertices = malloc(totalLength * 4 * sizeof(GlyphVertex));
lovrAssert(vertices, "Out of memory");
uint32_t glyphCount, lineCount;
Material* material;
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material);
int vertexCount = glyphCount * 4;
lua_createtable(L, vertexCount, 0);
for (int i = 0; i < vertexCount; i++) {
lua_createtable(L, 4, 0);
lua_pushnumber(L, vertices[i].position.x);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, vertices[i].position.y);
lua_rawseti(L, -2, 2);
lua_pushnumber(L, vertices[i].uv.u / 65535.f);
lua_rawseti(L, -2, 3);
lua_pushnumber(L, vertices[i].uv.v / 65535.f);
lua_rawseti(L, -2, 4);
lua_rawseti(L, -2, i + 1);
}
luax_pushtype(L, Material, material);
if (strings != &stack) free(strings);
free(vertices);
return 2;
}
const luaL_Reg lovrFont[] = {
@ -140,5 +177,6 @@ const luaL_Reg lovrFont[] = {
{ "getKerning", l_lovrFontGetKerning },
{ "getWidth", l_lovrFontGetWidth },
{ "getLines", l_lovrFontGetLines },
{ "getVertices", l_lovrFontGetVertices },
{ NULL, NULL }
};

View File

@ -33,12 +33,6 @@ typedef struct {
struct { float u, v; } uv;
} ShapeVertex;
typedef struct {
struct { float x, y; } position;
struct { uint16_t u, v; } uv;
struct { uint8_t r, g, b, a; } color;
} GlyphVertex;
typedef struct {
struct { float x, y, z; } position;
struct { float x, y, z; } normal;
@ -4186,31 +4180,19 @@ static void aline(GlyphVertex* vertices, uint32_t head, uint32_t tail, float wid
}
}
void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign) {
font = font ? font : lovrGraphicsGetDefaultFont();
float space = lovrFontGetGlyph(font, ' ', NULL)->advance;
size_t totalLength = 0;
for (uint32_t i = 0; i < count; i++) {
totalLength += strings[i].length;
}
uint32_t stack = tempPush();
GlyphVertex* vertices = tempAlloc(totalLength * 4 * sizeof(GlyphVertex));
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material) {
uint32_t vertexCount = 0;
uint32_t glyphCount = 0;
uint32_t lineCount = 1;
uint32_t lineStart = 0;
uint32_t wordStart = 0;
*glyphCount = 0;
*lineCount = 1;
float x = 0.f;
float y = 0.f;
float wordStartX = 0.f;
float prevWordEndX = 0.f;
float leading = lovrRasterizerGetLeading(font->info.rasterizer) * font->lineSpacing;
float ascent = lovrRasterizerGetAscent(font->info.rasterizer);
float scale = 1.f / font->pixelDensity;
wrap /= scale;
float space = lovrFontGetGlyph(font, ' ', NULL)->advance;
for (uint32_t i = 0; i < count; i++) {
size_t bytes;
@ -4240,7 +4222,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
y -= leading;
wordStartX = 0.f;
prevWordEndX = 0.f;
lineCount++;
(*lineCount)++;
previous = '\0';
str += bytes;
continue;
@ -4253,8 +4235,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
Glyph* glyph = lovrFontGetGlyph(font, codepoint, &resized);
if (resized) {
tempPop(stack);
lovrPassText(pass, font, strings, count, transform, wrap, halign, valign);
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, glyphCount, lineCount, material);
return;
}
@ -4276,7 +4257,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
aline(vertices, lineStart, wordStart, prevWordEndX, halign);
lineStart = wordStart;
wordStartX = 0.f;
lineCount++;
(*lineCount)++;
x -= dx;
y -= dy;
}
@ -4288,7 +4269,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[3] }, { uv[2], uv[1] }, { r, g, b, a } };
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], y + bb[1] }, { uv[0], uv[3] }, { r, g, b, a } };
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[1] }, { uv[2], uv[3] }, { r, g, b, a } };
glyphCount++;
(*glyphCount)++;
// Advance
x += glyph->advance;
@ -4299,6 +4280,30 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
// Align last line
aline(vertices, lineStart, vertexCount, x, halign);
*material = font->material;
}
void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign) {
font = font ? font : lovrGraphicsGetDefaultFont();
size_t totalLength = 0;
for (uint32_t i = 0; i < count; i++) {
totalLength += strings[i].length;
}
uint32_t stack = tempPush();
GlyphVertex* vertices = tempAlloc(totalLength * 4 * sizeof(GlyphVertex));
uint32_t glyphCount;
uint32_t lineCount;
float leading = lovrRasterizerGetLeading(font->info.rasterizer) * font->lineSpacing;
float ascent = lovrRasterizerGetAscent(font->info.rasterizer);
float scale = 1.f / font->pixelDensity;
wrap /= scale;
Material* material;
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material);
mat4_scale(transform, scale, scale, scale);
mat4_translate(transform, 0.f, -ascent + valign / 2.f * (leading * lineCount), 0.f);
@ -4309,13 +4314,13 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
.material = font->material,
.transform = transform,
.vertex.format = VERTEX_GLYPH,
.vertex.count = vertexCount,
.vertex.count = glyphCount * 4,
.vertex.data = vertices,
.index.count = glyphCount * 6,
.index.pointer = (void**) &indices
});
for (uint32_t i = 0; i < vertexCount; i += 4) {
for (uint32_t i = 0; i < glyphCount * 4; i += 4) {
uint16_t quad[] = { i + 0, i + 2, i + 1, i + 1, i + 2, i + 3 };
memcpy(indices, quad, sizeof(quad));
indices += COUNTOF(quad);

View File

@ -367,6 +367,12 @@ typedef enum {
ALIGN_BOTTOM
} VerticalAlign;
typedef struct {
struct { float x, y; } position;
struct { uint16_t u, v; } uv;
struct { uint8_t r, g, b, a; } color;
} GlyphVertex;
Font* lovrFontCreate(FontInfo* info);
void lovrFontDestroy(void* ref);
const FontInfo* lovrFontGetInfo(Font* font);
@ -377,6 +383,7 @@ void lovrFontSetLineSpacing(Font* font, float spacing);
float lovrFontGetKerning(Font* font, uint32_t first, uint32_t second);
float lovrFontGetWidth(Font* font, ColoredString* strings, uint32_t count);
void lovrFontGetLines(Font* font, ColoredString* strings, uint32_t count, float wrap, void (*callback)(void* context, const char* string, size_t length), void* context);
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material);
// Model