This commit is contained in:
bjorn 2017-02-06 01:54:11 -08:00
parent db2ed2d0a5
commit 73d8b8aa3e
4 changed files with 72 additions and 9 deletions

View File

@ -4,7 +4,10 @@
#include "math/math.h"
#include "loaders/font.h"
#include "loaders/texture.h"
#include "util.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
Font* lovrFontCreate(FontData* fontData) {
Font* font = lovrAlloc(sizeof(Font), lovrFontDestroy);
@ -43,22 +46,29 @@ void lovrFontDestroy(const Ref* ref) {
void lovrFontPrint(Font* font, const char* str) {
FontAtlas* atlas = &font->atlas;
vec_reserve(&font->vertices, strlen(str) * 30);
vec_clear(&font->vertices);
float x = 0;
float y = 0;
float u = atlas->width;
float v = atlas->height;
for (unsigned int i = 0; i < strlen(str); i++) {
if (str[i] == '\n') {
int length = strlen(str);
const char* end = str + length;
size_t bytes;
unsigned int codepoint;
vec_reserve(&font->vertices, length * 30);
vec_clear(&font->vertices);
while ((bytes = utf8_decode(str, end, &codepoint)) > 0) {
if (codepoint == '\n') {
x = 0;
y -= font->fontData->size;
str += bytes;
continue;
}
Glyph* glyph = lovrFontGetGlyph(font, str[i]);
Glyph* glyph = lovrFontGetGlyph(font, codepoint);
int gx = glyph->x;
int gy = glyph->y;
@ -88,6 +98,7 @@ void lovrFontPrint(Font* font, const char* str) {
}
x += glyph->advance;
str += bytes;
}
lovrGraphicsSetShapeData(font->vertices.data, font->vertices.length);
@ -106,8 +117,10 @@ int lovrFontGetDescent(Font* font) {
return font->fontData->descent;
}
Glyph* lovrFontGetGlyph(Font* font, char character) {
char key[2] = { character, '\0' };
Glyph* lovrFontGetGlyph(Font* font, uint32_t codepoint) {
char key[6];
snprintf(key, 6, "%d", codepoint);
FontAtlas* atlas = &font->atlas;
vec_glyph_t* glyphs = &atlas->glyphs;
Glyph* glyph = map_get(glyphs, key);
@ -115,7 +128,7 @@ Glyph* lovrFontGetGlyph(Font* font, char character) {
// Add the glyph to the atlas if it isn't there
if (!glyph) {
Glyph g;
lovrFontDataLoadGlyph(font->fontData, character, &g);
lovrFontDataLoadGlyph(font->fontData, codepoint, &g);
map_set(glyphs, key, g);
glyph = map_get(glyphs, key);
lovrFontAddGlyph(font, glyph);

View File

@ -51,6 +51,6 @@ void lovrFontPrint(Font* font, const char* str);
int lovrFontGetHeight(Font* font);
int lovrFontGetAscent(Font* font);
int lovrFontGetDescent(Font* font);
Glyph* lovrFontGetGlyph(Font* font, char character);
Glyph* lovrFontGetGlyph(Font* font, uint32_t codepoint);
void lovrFontAddGlyph(Font* font, Glyph* glyph);
void lovrFontExpandTexture(Font* font);

View File

@ -39,3 +39,52 @@ void lovrRetain(const Ref* ref) {
void lovrRelease(const Ref* ref) {
if (--((Ref*) ref)->count == 0 && ref->free) ref->free(ref);
}
// https://github.com/starwing/luautf8
size_t utf8_decode(const char *s, const char *e, unsigned *pch) {
unsigned ch;
if (s >= e) {
*pch = 0;
return 0;
}
ch = (unsigned char)s[0];
if (ch < 0xC0) goto fallback;
if (ch < 0xE0) {
if (s+1 >= e || (s[1] & 0xC0) != 0x80)
goto fallback;
*pch = ((ch & 0x1F) << 6) |
(s[1] & 0x3F);
return 2;
}
if (ch < 0xF0) {
if (s+2 >= e || (s[1] & 0xC0) != 0x80
|| (s[2] & 0xC0) != 0x80)
goto fallback;
*pch = ((ch & 0x0F) << 12) |
((s[1] & 0x3F) << 6) |
(s[2] & 0x3F);
return 3;
}
{
int count = 0; /* to count number of continuation bytes */
unsigned res = 0;
while ((ch & 0x40) != 0) { /* still have continuation bytes? */
int cc = (unsigned char)s[++count];
if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
goto fallback; /* invalid byte sequence, fallback */
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
ch <<= 1; /* to test next bit */
}
if (count > 5)
goto fallback; /* invalid byte sequence */
res |= ((ch & 0x7F) << (count * 5)); /* add first byte */
*pch = res;
return count+1;
}
fallback:
*pch = ch;
return 1;
}

View File

@ -22,3 +22,4 @@ void lovrSleep(double seconds);
void* lovrAlloc(size_t size, void (*destructor)(const Ref* ref));
void lovrRetain(const Ref* ref);
void lovrRelease(const Ref* ref);
size_t utf8_decode(const char *s, const char *e, unsigned *pch);