mirror of https://github.com/bjornbytes/lovr.git
Unicode;
This commit is contained in:
parent
db2ed2d0a5
commit
73d8b8aa3e
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
49
src/util.c
49
src/util.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue