k3/src/k3font.h
2025-09-13 11:59:12 +03:00

82 lines
1.7 KiB
C

#pragma once
#include"k3.h"
#include"k3batch.h"
#include<string.h>
#define k3_FONT_ALIGN_LEFT 0
#define k3_FONT_ALIGN_CENTER 1
#define k3_FONT_ALIGN_RIGHT 2
struct k3FontGlyph {
uint32_t cp;
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
int16_t xoffset;
int16_t yoffset;
uint16_t xadvance;
uint8_t page;
uint8_t chnl;
};
struct k3Font {
void *ud;
float lineScale;
uint16_t baseline;
uint16_t texW, texH;
size_t glyphCount;
struct k3FontGlyph *glyphs;
size_t pageCount;
struct k3Tex **pages;
};
typedef struct k3Tex*(*k3FontTexLoader)(struct k3Font*, const char *name);
struct k3Font *k3FontCreate();
int k3FontLoad(struct k3Font*, const uint8_t *buf, size_t len, k3FontTexLoader);
void k3FontSz(struct k3Font*, float sz, const char *txt, float wall, struct k3RectF *ret);
void k3FontDraw(struct k3Font*, float x, float y, float sz, const char *txt, float wall, int alignment, vec4 color);
struct k3FontGlyph *k3FontGetGlyph(struct k3Font*, uint32_t cp);
static inline int k3UTF8Encode(uint32_t cp, uint8_t ret[static 4]) {
if(cp < 0x80) {
ret[0] = cp;
return 1;
} else if(cp < 0x800) {
ret[0] = 192 | (cp >> 6);
ret[1] = 128 | (cp & 63);
return 2;
} else if(cp < 0x10000) {
ret[0] = 224 | (cp >> 12);
ret[1] = 128 | ((cp >> 6) & 63);
ret[2] = 128 | (cp & 63);
return 3;
} else if(cp < 0x110000) {
ret[0] = 240 | (cp >> 18);
ret[1] = 128 | ((cp >> 12) & 63);
ret[2] = 128 | ((cp >> 6) & 63);
ret[3] = 128 | (cp & 63);
return 4;
}
return 0;
}
static inline const char *k3UTF8LastCodepointZ(const char *txt) {
size_t len = strlen(txt);
while(len--) {
if((txt[len] & 0xC0) != 0x80) {
return &txt[len];
}
}
return NULL;
}