better font rendering
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
This commit is contained in:
parent
8d597328f9
commit
d76bb49e45
3 changed files with 88 additions and 24 deletions
|
|
@ -19,6 +19,11 @@ static struct ft_table {
|
||||||
FT_Error (*FT_Load_Char)(FT_Face face,
|
FT_Error (*FT_Load_Char)(FT_Face face,
|
||||||
FT_ULong char_code,
|
FT_ULong char_code,
|
||||||
FT_Int32 load_flags);
|
FT_Int32 load_flags);
|
||||||
|
FT_Error (*FT_Get_Kerning)(FT_Face face,
|
||||||
|
FT_UInt left_glyph,
|
||||||
|
FT_UInt right_glyph,
|
||||||
|
FT_UInt kern_mode,
|
||||||
|
FT_Vector* akerning);
|
||||||
FT_Error (*FT_Done_Face)(FT_Face face);
|
FT_Error (*FT_Done_Face)(FT_Face face);
|
||||||
FT_Error (*FT_Done_FreeType)(FT_Library library);
|
FT_Error (*FT_Done_FreeType)(FT_Library library);
|
||||||
|
|
||||||
|
|
@ -42,10 +47,12 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
|
||||||
|
|
||||||
memset(px, 0, tw * th * 4);
|
memset(px, 0, tw * th * 4);
|
||||||
while(text[0] != 0) {
|
while(text[0] != 0) {
|
||||||
int c;
|
FT_Bitmap* bmp;
|
||||||
FT_Bitmap* bmp;
|
int cy, cx;
|
||||||
int cy, cx;
|
int c, c2;
|
||||||
int l = MwUTF8ToUTF32(text, &c);
|
int l = MwUTF8ToUTF32(text, &c);
|
||||||
|
FT_Vector vec;
|
||||||
|
const char* old_text;
|
||||||
if(l <= 0) break;
|
if(l <= 0) break;
|
||||||
text += l;
|
text += l;
|
||||||
|
|
||||||
|
|
@ -60,7 +67,7 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
|
||||||
|
|
||||||
for(cy = 0; cy < bmp->rows; cy++) {
|
for(cy = 0; cy < bmp->rows; cy++) {
|
||||||
for(cx = 0; cx < bmp->width; cx++) {
|
for(cx = 0; cx < bmp->width; cx++) {
|
||||||
int ox = x + cx + ttf->face->glyph->bitmap_left;
|
int ox = x + (ttf->face->glyph->metrics.horiBearingX / 64) + cx + ttf->face->glyph->bitmap_left;
|
||||||
int oy = y + (ttf->face->height * HEIGHT / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * HEIGHT / ttf->face->units_per_EM);
|
int oy = y + (ttf->face->height * HEIGHT / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * HEIGHT / ttf->face->units_per_EM);
|
||||||
unsigned char* opx = &px[(oy * tw + ox) * 4];
|
unsigned char* opx = &px[(oy * tw + ox) * 4];
|
||||||
|
|
||||||
|
|
@ -71,7 +78,18 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x += ttf->face->glyph->metrics.horiAdvance / 64;
|
x += ceil(ttf->face->glyph->metrics.horiAdvance / 64);
|
||||||
|
|
||||||
|
old_text = text;
|
||||||
|
text += MwUTF8ToUTF32(text, &c2);
|
||||||
|
|
||||||
|
if(c2 != '\n') {
|
||||||
|
ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec);
|
||||||
|
|
||||||
|
x += ceil(vec.x / 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
text = old_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = MwLoadRaw(handle, px, tw, th);
|
p = MwLoadRaw(handle, px, tw, th);
|
||||||
|
|
@ -91,10 +109,11 @@ static int ft2_MwTextWidth(MwFLFont ttf, const char* text) {
|
||||||
int tw = 0, mtw = 0;
|
int tw = 0, mtw = 0;
|
||||||
|
|
||||||
while(text[0] != 0) {
|
while(text[0] != 0) {
|
||||||
int c;
|
int c, c2;
|
||||||
int l = MwUTF8ToUTF32(text, &c);
|
FT_Vector vec;
|
||||||
if(l <= 0) break;
|
const char* old_text;
|
||||||
text += l;
|
|
||||||
|
text += MwUTF8ToUTF32(text, &c);
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
tw = 0;
|
tw = 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -102,15 +121,26 @@ static int ft2_MwTextWidth(MwFLFont ttf, const char* text) {
|
||||||
|
|
||||||
ft_table.FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
|
ft_table.FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
|
||||||
|
|
||||||
tw += ttf->face->glyph->metrics.horiAdvance / 64;
|
tw += ceil(ttf->face->glyph->metrics.horiAdvance / 64);
|
||||||
|
|
||||||
|
old_text = text;
|
||||||
|
text += MwUTF8ToUTF32(text, &c2);
|
||||||
|
|
||||||
|
if(c2 != '\n') {
|
||||||
|
ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec);
|
||||||
|
|
||||||
|
tw += ceil(vec.x / 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
text = old_text;
|
||||||
if(tw > mtw) mtw = tw;
|
if(tw > mtw) mtw = tw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mtw;
|
return mtw + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ft2_MwTextHeight(MwFLFont ttf, int count) {
|
static int ft2_MwTextHeight(MwFLFont ttf, int count) {
|
||||||
return (ttf->face->height * HEIGHT / ttf->face->units_per_EM) * count;
|
return ceil((ttf->face->height * HEIGHT / ttf->face->units_per_EM) * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* ft2_MwFontLoad(unsigned char* data, unsigned int size) {
|
static void* ft2_MwFontLoad(unsigned char* data, unsigned int size) {
|
||||||
|
|
@ -146,6 +176,7 @@ int MWFL_FT2Setup(void) {
|
||||||
ft_table.FT_New_Memory_Face = MwDynamicSymbol(ftlib, "FT_New_Memory_Face");
|
ft_table.FT_New_Memory_Face = MwDynamicSymbol(ftlib, "FT_New_Memory_Face");
|
||||||
ft_table.FT_Set_Pixel_Sizes = MwDynamicSymbol(ftlib, "FT_Set_Pixel_Sizes");
|
ft_table.FT_Set_Pixel_Sizes = MwDynamicSymbol(ftlib, "FT_Set_Pixel_Sizes");
|
||||||
ft_table.FT_Load_Char = MwDynamicSymbol(ftlib, "FT_Load_Char");
|
ft_table.FT_Load_Char = MwDynamicSymbol(ftlib, "FT_Load_Char");
|
||||||
|
ft_table.FT_Get_Kerning = MwDynamicSymbol(ftlib, "FT_Get_Kerning");
|
||||||
ft_table.FT_Done_Face = MwDynamicSymbol(ftlib, "FT_Done_Face");
|
ft_table.FT_Done_Face = MwDynamicSymbol(ftlib, "FT_Done_Face");
|
||||||
ft_table.FT_Done_FreeType = MwDynamicSymbol(ftlib, "FT_Done_FreeType");
|
ft_table.FT_Done_FreeType = MwDynamicSymbol(ftlib, "FT_Done_FreeType");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,17 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
|
||||||
|
|
||||||
memset(px, 0, tw * th * 4);
|
memset(px, 0, tw * th * 4);
|
||||||
while(text[0] != 0) {
|
while(text[0] != 0) {
|
||||||
int c;
|
int c, c2;
|
||||||
int x0, y0, x1, y1, cx, cy;
|
int x0, y0, x1, y1, cx, cy;
|
||||||
int ow, oh;
|
int ow, oh;
|
||||||
unsigned char* out;
|
unsigned char* out;
|
||||||
|
int kern;
|
||||||
|
const char* old_text;
|
||||||
|
|
||||||
text += MwUTF8ToUTF32(text, &c);
|
text += MwUTF8ToUTF32(text, &c);
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
x = 0;
|
x = 0;
|
||||||
y += (ttf->ascent - ttf->descent) * ttf->scale;
|
y += ceil((ttf->ascent - ttf->descent) * ttf->scale);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,8 +49,8 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
|
||||||
|
|
||||||
for(cy = 0; cy < oh; cy++) {
|
for(cy = 0; cy < oh; cy++) {
|
||||||
for(cx = 0; cx < ow; cx++) {
|
for(cx = 0; cx < ow; cx++) {
|
||||||
int ox = x + (lsb * ttf->scale) + cx;
|
int ox = x + ceil(lsb * ttf->scale) + cx;
|
||||||
int oy = y + (ttf->ascent * ttf->scale) + y0 + cy;
|
int oy = y + ceil(ttf->ascent * ttf->scale) + y0 + cy;
|
||||||
unsigned char* opx = &px[(oy * tw + ox) * 4];
|
unsigned char* opx = &px[(oy * tw + ox) * 4];
|
||||||
|
|
||||||
opx[0] = color->common.red;
|
opx[0] = color->common.red;
|
||||||
|
|
@ -58,7 +60,18 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x += ax * ttf->scale;
|
x += ceil(ax * ttf->scale);
|
||||||
|
|
||||||
|
old_text = text;
|
||||||
|
text += MwUTF8ToUTF32(text, &c2);
|
||||||
|
|
||||||
|
if(c2 != '\n') {
|
||||||
|
kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2);
|
||||||
|
|
||||||
|
x += ceil(kern * ttf->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
text = old_text;
|
||||||
|
|
||||||
free(out);
|
free(out);
|
||||||
}
|
}
|
||||||
|
|
@ -78,22 +91,41 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
|
||||||
|
|
||||||
static int stbtt_MwTextWidth(MwFLFont ttf, const char* text) {
|
static int stbtt_MwTextWidth(MwFLFont ttf, const char* text) {
|
||||||
int ax, lsb;
|
int ax, lsb;
|
||||||
int tw = 0;
|
int tw = 0, mtw = 0;
|
||||||
|
|
||||||
while(text[0] != 0) {
|
while(text[0] != 0) {
|
||||||
int c;
|
int kern;
|
||||||
|
int c, c2;
|
||||||
|
const char* old_text;
|
||||||
|
|
||||||
text += MwUTF8ToUTF32(text, &c);
|
text += MwUTF8ToUTF32(text, &c);
|
||||||
|
if(c == '\n') {
|
||||||
|
tw = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
|
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
|
||||||
|
|
||||||
tw += ax * ttf->scale;
|
tw += ceil(ax * ttf->scale);
|
||||||
|
|
||||||
|
old_text = text;
|
||||||
|
text += MwUTF8ToUTF32(text, &c2);
|
||||||
|
|
||||||
|
if(c2 != '\n') {
|
||||||
|
kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2);
|
||||||
|
|
||||||
|
tw += ceil(kern * ttf->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
text = old_text;
|
||||||
|
if(tw > mtw) mtw = tw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tw;
|
return mtw + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbtt_MwTextHeight(MwFLFont ttf, int count) {
|
static int stbtt_MwTextHeight(MwFLFont ttf, int count) {
|
||||||
return (ttf->ascent - ttf->descent) * ttf->scale * count;
|
return ceil((ttf->ascent - ttf->descent) * ttf->scale * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* stbtt_MwFontLoad(unsigned char* data, unsigned int size) {
|
static void* stbtt_MwFontLoad(unsigned char* data, unsigned int size) {
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,8 @@ sub generate {
|
||||||
print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n");
|
print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n");
|
||||||
print( OUT " \$(LD) \$(LDFLAGS) $c_dllout $dllout\$@ "
|
print( OUT " \$(LD) \$(LDFLAGS) $c_dllout $dllout\$@ "
|
||||||
. cobjs($dir, $prefobj)
|
. cobjs($dir, $prefobj)
|
||||||
. " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}user32.lib ${lib}advapi32.lib\n");
|
. " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}user32.lib ${lib}advapi32.lib\n"
|
||||||
|
);
|
||||||
print(OUT " $c_dllafter\n");
|
print(OUT " $c_dllafter\n");
|
||||||
print(OUT "\n");
|
print(OUT "\n");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue