mirror of https://github.com/bjornbytes/lovr.git
Font alignment;
This commit is contained in:
parent
a6cb4ee53f
commit
390220f945
|
@ -11,11 +11,13 @@ map_int_t BlendModes;
|
|||
map_int_t CompareModes;
|
||||
map_int_t DrawModes;
|
||||
map_int_t FilterModes;
|
||||
map_int_t HorizontalAligns;
|
||||
map_int_t MeshAttributeTypes;
|
||||
map_int_t MeshDrawModes;
|
||||
map_int_t MeshUsages;
|
||||
map_int_t PolygonWindings;
|
||||
map_int_t TextureProjections;
|
||||
map_int_t VerticalAligns;
|
||||
map_int_t WrapModes;
|
||||
|
||||
static void luax_readvertices(lua_State* L, int index, vec_float_t* points) {
|
||||
|
@ -103,6 +105,11 @@ int l_lovrGraphicsInit(lua_State* L) {
|
|||
map_set(&FilterModes, "nearest", FILTER_NEAREST);
|
||||
map_set(&FilterModes, "linear", FILTER_LINEAR);
|
||||
|
||||
map_init(&HorizontalAligns);
|
||||
map_set(&HorizontalAligns, "left", ALIGN_LEFT);
|
||||
map_set(&HorizontalAligns, "right", ALIGN_RIGHT);
|
||||
map_set(&HorizontalAligns, "center", ALIGN_CENTER);
|
||||
|
||||
map_init(&MeshAttributeTypes);
|
||||
map_set(&MeshAttributeTypes, "float", MESH_FLOAT);
|
||||
map_set(&MeshAttributeTypes, "byte", MESH_BYTE);
|
||||
|
@ -127,6 +134,11 @@ int l_lovrGraphicsInit(lua_State* L) {
|
|||
map_set(&TextureProjections, "2d", PROJECTION_ORTHOGRAPHIC);
|
||||
map_set(&TextureProjections, "3d", PROJECTION_PERSPECTIVE);
|
||||
|
||||
map_init(&VerticalAligns);
|
||||
map_set(&VerticalAligns, "top", ALIGN_TOP);
|
||||
map_set(&VerticalAligns, "bottom", ALIGN_BOTTOM);
|
||||
map_set(&VerticalAligns, "middle", ALIGN_MIDDLE);
|
||||
|
||||
map_init(&WrapModes);
|
||||
map_set(&WrapModes, "clamp", WRAP_CLAMP);
|
||||
map_set(&WrapModes, "repeat", WRAP_REPEAT);
|
||||
|
@ -524,16 +536,12 @@ int l_lovrGraphicsCube(lua_State* L) {
|
|||
|
||||
int l_lovrGraphicsPrint(lua_State* L) {
|
||||
const char* str = luaL_checkstring(L, 1);
|
||||
float x = luaL_optnumber(L, 2, 0);
|
||||
float y = luaL_optnumber(L, 3, 0);
|
||||
float z = luaL_optnumber(L, 4, 0);
|
||||
float w = luaL_optnumber(L, 5, 0);
|
||||
float h = luaL_optnumber(L, 6, .1);
|
||||
float angle = luaL_optnumber(L, 7, 0);
|
||||
float ax = luaL_optnumber(L, 8, 0);
|
||||
float ay = luaL_optnumber(L, 9, 1);
|
||||
float az = luaL_optnumber(L, 10, 0);
|
||||
lovrGraphicsPrint(str, x, y, z, w, h, angle, ax, ay, az);
|
||||
float transform[16];
|
||||
int index = luax_readtransform(L, 2, transform);
|
||||
float wrap = luaL_optnumber(L, index++, 0);
|
||||
HorizontalAlign halign = *(HorizontalAlign*) luax_optenum(L, index++, "center", &HorizontalAligns, "alignment");
|
||||
VerticalAlign valign = *(VerticalAlign*) luax_optenum(L, index++, "middle", &VerticalAligns, "alignment");
|
||||
lovrGraphicsPrint(str, transform, wrap, halign, valign);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,13 +37,15 @@ extern map_int_t DrawModes;
|
|||
extern map_int_t EventTypes;
|
||||
extern map_int_t FilterModes;
|
||||
extern map_int_t HeadsetEyes;
|
||||
extern map_int_t HorizontalAligns;
|
||||
extern map_int_t MeshAttributeTypes;
|
||||
extern map_int_t MeshDrawModes;
|
||||
extern map_int_t MeshUsages;
|
||||
extern map_int_t PolygonWindings;
|
||||
extern map_int_t TextureProjections;
|
||||
extern map_int_t TimeUnits;
|
||||
extern map_int_t VerticalAligns;
|
||||
extern map_int_t WrapModes;
|
||||
|
||||
void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format);
|
||||
void luax_readtransform(lua_State* L, int i, mat4 transform);
|
||||
int luax_readtransform(lua_State* L, int i, mat4 transform);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "math/mat4.h"
|
||||
#include "math/transform.h"
|
||||
|
||||
void luax_readtransform(lua_State* L, int i, mat4 m) {
|
||||
int luax_readtransform(lua_State* L, int i, mat4 m) {
|
||||
if (lua_isnumber(L, i)) {
|
||||
float x = luaL_optnumber(L, i++, 0);
|
||||
float y = luaL_optnumber(L, i++, 0);
|
||||
|
@ -13,11 +13,14 @@ void luax_readtransform(lua_State* L, int i, mat4 m) {
|
|||
float ay = luaL_optnumber(L, i++, 1);
|
||||
float az = luaL_optnumber(L, i++, 0);
|
||||
mat4_setTransform(m, x, y, z, s, angle, ax, ay, az);
|
||||
return i;
|
||||
} else if (lua_isnoneornil(L, i)) {
|
||||
mat4_identity(m);
|
||||
return i;
|
||||
} else {
|
||||
Transform* transform = luax_checktype(L, i, Transform);
|
||||
mat4_init(m, transform->matrix);
|
||||
return ++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,20 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int lovrFontAlignLine(vec_float_t* vertices, int index, float width, HorizontalAlign halign) {
|
||||
while (index < vertices->length) {
|
||||
if (halign == ALIGN_CENTER) {
|
||||
vertices->data[index] -= width / 2;
|
||||
} else if (halign == ALIGN_RIGHT) {
|
||||
vertices->data[index] -= width;
|
||||
}
|
||||
|
||||
index += 5;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
Font* lovrFontCreate(FontData* fontData) {
|
||||
Font* font = lovrAlloc(sizeof(Font), lovrFontDestroy);
|
||||
if (!font) return NULL;
|
||||
|
@ -52,14 +66,14 @@ void lovrFontDestroy(const Ref* ref) {
|
|||
free(font);
|
||||
}
|
||||
|
||||
void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
|
||||
void lovrFontPrint(Font* font, const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign) {
|
||||
FontAtlas* atlas = &font->atlas;
|
||||
|
||||
float cx = 0;
|
||||
float cy = -font->fontData->height * font->lineHeight / 2;
|
||||
float cy = -font->fontData->height * .8;
|
||||
float u = atlas->width;
|
||||
float v = atlas->height;
|
||||
float scale = h / font->fontData->height;
|
||||
float scale = 1 / (float) font->fontData->height;
|
||||
|
||||
int len = strlen(str);
|
||||
const char* start = str;
|
||||
|
@ -69,6 +83,7 @@ void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float
|
|||
size_t bytes;
|
||||
|
||||
int linePtr = 0;
|
||||
int lineCount = 1;
|
||||
|
||||
vec_reserve(&font->vertices, len * 30);
|
||||
vec_clear(&font->vertices);
|
||||
|
@ -76,16 +91,11 @@ void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float
|
|||
while ((bytes = utf8_decode(str, end, &codepoint)) > 0) {
|
||||
|
||||
// Newlines
|
||||
if (codepoint == '\n' || (w && cx > w / scale && codepoint == ' ')) {
|
||||
|
||||
// Center the line
|
||||
while (linePtr < font->vertices.length) {
|
||||
font->vertices.data[linePtr] -= cx / 2;
|
||||
linePtr += 5;
|
||||
}
|
||||
|
||||
if (codepoint == '\n' || (wrap && cx * scale > wrap && codepoint == ' ')) {
|
||||
linePtr = lovrFontAlignLine(&font->vertices, linePtr, cx, halign);
|
||||
lineCount++;
|
||||
cx = 0;
|
||||
cy -= font->fontData->size * font->lineHeight;
|
||||
cy -= font->fontData->height * font->lineHeight;
|
||||
previous = '\0';
|
||||
str += bytes;
|
||||
continue;
|
||||
|
@ -100,7 +110,7 @@ void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float
|
|||
|
||||
// Start over if texture was repacked
|
||||
if (u != atlas->width || v != atlas->height) {
|
||||
lovrFontPrint(font, start, x, y, z, w, h, angle, ax, ay, az);
|
||||
lovrFontPrint(font, start, transform, wrap, halign, valign);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,20 +142,25 @@ void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float
|
|||
str += bytes;
|
||||
}
|
||||
|
||||
// Center the last line
|
||||
while (linePtr < font->vertices.length) {
|
||||
font->vertices.data[linePtr] -= cx / 2;
|
||||
linePtr += 5;
|
||||
// Align the last line
|
||||
lovrFontAlignLine(&font->vertices, linePtr, cx, halign);
|
||||
|
||||
// Calculate vertical offset
|
||||
float offsety = 0;
|
||||
if (valign == ALIGN_MIDDLE) {
|
||||
offsety = lineCount * font->fontData->height * font->lineHeight * .5f;
|
||||
} else if (valign == ALIGN_BOTTOM) {
|
||||
offsety = lineCount * font->fontData->height * font->lineHeight;
|
||||
}
|
||||
|
||||
// We override the depth test to LEQUAL to prevent blending issues with glyphs, not great
|
||||
CompareMode oldCompareMode = lovrGraphicsGetDepthTest();
|
||||
|
||||
// Render!
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsTranslate(x, y, z);
|
||||
lovrGraphicsMatrixTransform(transform);
|
||||
lovrGraphicsScale(scale, scale, scale);
|
||||
lovrGraphicsRotate(angle, ax, ay, az);
|
||||
lovrGraphicsTranslate(0, -cy / 2, 0);
|
||||
lovrGraphicsTranslate(0, offsety, 0);
|
||||
lovrGraphicsSetDepthTest(COMPARE_LEQUAL);
|
||||
lovrGraphicsBindTexture(font->texture);
|
||||
lovrGraphicsSetShapeData(font->vertices.data, font->vertices.length);
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
#include "loaders/font.h"
|
||||
#include "util.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "math/math.h"
|
||||
#include "lib/map/map.h"
|
||||
#include "lib/vec/vec.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
ALIGN_LEFT,
|
||||
ALIGN_RIGHT,
|
||||
ALIGN_CENTER
|
||||
} HorizontalAlign;
|
||||
|
||||
typedef enum {
|
||||
ALIGN_TOP,
|
||||
ALIGN_BOTTOM,
|
||||
ALIGN_MIDDLE
|
||||
} VerticalAlign;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
|
@ -24,12 +37,12 @@ typedef struct {
|
|||
FontAtlas atlas;
|
||||
map_int_t kerning;
|
||||
vec_float_t vertices;
|
||||
int lineHeight;
|
||||
float lineHeight;
|
||||
} Font;
|
||||
|
||||
Font* lovrFontCreate(FontData* fontData);
|
||||
void lovrFontDestroy(const Ref* ref);
|
||||
void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az);
|
||||
void lovrFontPrint(Font* font, const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
|
||||
float lovrFontGetLineHeight(Font* font);
|
||||
void lovrFontSetLineHeight(Font* font, float lineHeight);
|
||||
int lovrFontGetKerning(Font* font, unsigned int a, unsigned int b);
|
||||
|
|
|
@ -806,7 +806,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
|
|||
lovrGraphicsPop();
|
||||
}
|
||||
|
||||
void lovrGraphicsPrint(const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
|
||||
void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign) {
|
||||
lovrGraphicsEnsureFont();
|
||||
lovrFontPrint(state.activeFont, str, x, y, z, w, h, angle, ax, ay, az);
|
||||
lovrFontPrint(state.activeFont, str, transform, wrap, halign, valign);
|
||||
}
|
||||
|
|
|
@ -162,4 +162,4 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float
|
|||
void lovrGraphicsPlaneFullscreen(Texture* texture);
|
||||
void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform);
|
||||
void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az);
|
||||
void lovrGraphicsPrint(const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az);
|
||||
void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
|
||||
|
|
Loading…
Reference in New Issue