Merge pull request #621 from olliwang/freetype

Fixes FreeType errors when dealing with multiple NVGcontext objects.
This commit is contained in:
Mikko Mononen 2021-12-02 20:05:03 +02:00 • committed by GitHub
commit 645e9147a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -157,108 +157,10 @@ struct FONSttFontImpl {
};
typedef struct FONSttFontImpl FONSttFontImpl;
static FT_Library ftLibrary;
int fons__tt_init(FONScontext *context)
{
FT_Error ftError;
FONS_NOTUSED(context);
ftError = FT_Init_FreeType(&ftLibrary);
return ftError == 0;
}
int fons__tt_done(FONScontext *context)
{
FT_Error ftError;
FONS_NOTUSED(context);
ftError = FT_Done_FreeType(ftLibrary);
return ftError == 0;
}
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize, int fontIndex)
{
FT_Error ftError;
FONS_NOTUSED(context);
//font->font.userdata = stash;
ftError = FT_New_Memory_Face(ftLibrary, (const FT_Byte*)data, dataSize, fontIndex, &font->font);
return ftError == 0;
}
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{
*ascent = font->font->ascender;
*descent = font->font->descender;
*lineGap = font->font->height - (*ascent - *descent);
}
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{
return size / font->font->units_per_EM;
}
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{
return FT_Get_Char_Index(font->font, codepoint);
}
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{
FT_Error ftError;
FT_GlyphSlot ftGlyph;
FT_Fixed advFixed;
FONS_NOTUSED(scale);
ftError = FT_Set_Pixel_Sizes(font->font, 0, size);
if (ftError) return 0;
ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT);
if (ftError) return 0;
ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, &advFixed);
if (ftError) return 0;
ftGlyph = font->font->glyph;
*advance = (int)advFixed;
*lsb = (int)ftGlyph->metrics.horiBearingX;
*x0 = ftGlyph->bitmap_left;
*x1 = *x0 + ftGlyph->bitmap.width;
*y0 = -ftGlyph->bitmap_top;
*y1 = *y0 + ftGlyph->bitmap.rows;
return 1;
}
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{
FT_GlyphSlot ftGlyph = font->font->glyph;
int ftGlyphOffset = 0;
unsigned int x, y;
FONS_NOTUSED(outWidth);
FONS_NOTUSED(outHeight);
FONS_NOTUSED(scaleX);
FONS_NOTUSED(scaleY);
FONS_NOTUSED(glyph); // glyph has already been loaded by fons__tt_buildGlyphBitmap
for ( y = 0; y < ftGlyph->bitmap.rows; y++ ) {
for ( x = 0; x < ftGlyph->bitmap.width; x++ ) {
output[(y * outStride) + x] = ftGlyph->bitmap.buffer[ftGlyphOffset++];
}
}
}
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{
FT_Vector ftKerning;
FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning);
return (int)((ftKerning.x + 32) >> 6); // Round up and convert to integer
}
#else
#define STB_TRUETYPE_IMPLEMENTATION
static void* fons__tmpalloc(size_t size, void* up);
static void fons__tmpfree(void* ptr, void* up);
#define STBTT_malloc(x,u) fons__tmpalloc(x,u)
#define STBTT_free(x,u) fons__tmpfree(x,u)
#include "stb_truetype.h"
struct FONSttFontImpl {
@ -266,68 +168,6 @@ struct FONSttFontImpl {
};
typedef struct FONSttFontImpl FONSttFontImpl;
int fons__tt_init(FONScontext *context)
{
FONS_NOTUSED(context);
return 1;
}
int fons__tt_done(FONScontext *context)
{
FONS_NOTUSED(context);
return 1;
}
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize, int fontIndex)
{
int offset, stbError;
FONS_NOTUSED(dataSize);
font->font.userdata = context;
offset = stbtt_GetFontOffsetForIndex(data, fontIndex);
if (offset == -1) {
stbError = 0;
} else {
stbError = stbtt_InitFont(&font->font, data, offset);
}
return stbError;
}
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{
stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap);
}
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{
return stbtt_ScaleForMappingEmToPixels(&font->font, size);
}
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{
return stbtt_FindGlyphIndex(&font->font, codepoint);
}
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{
FONS_NOTUSED(size);
stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb);
stbtt_GetGlyphBitmapBox(&font->font, glyph, scale, scale, x0, y0, x1, y1);
return 1;
}
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{
stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph);
}
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{
return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2);
}
#endif
#ifndef FONS_SCRATCH_BUF_SIZE
@ -451,8 +291,176 @@ struct FONScontext
int nstates;
void (*handleError)(void* uptr, int error, int val);
void* errorUptr;
#ifdef FONS_USE_FREETYPE
FT_Library ftLibrary;
#endif
};
#ifdef FONS_USE_FREETYPE
int fons__tt_init(FONScontext *context)
{
FT_Error ftError;
FONS_NOTUSED(context);
ftError = FT_Init_FreeType(&context->ftLibrary);
return ftError == 0;
}
int fons__tt_done(FONScontext *context)
{
FT_Error ftError;
FONS_NOTUSED(context);
ftError = FT_Done_FreeType(context->ftLibrary);
return ftError == 0;
}
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize, int fontIndex)
{
FT_Error ftError;
FONS_NOTUSED(context);
ftError = FT_New_Memory_Face(context->ftLibrary, (const FT_Byte*)data, dataSize, fontIndex, &font->font);
return ftError == 0;
}
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{
*ascent = font->font->ascender;
*descent = font->font->descender;
*lineGap = font->font->height - (*ascent - *descent);
}
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{
return size / font->font->units_per_EM;
}
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{
return FT_Get_Char_Index(font->font, codepoint);
}
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{
FT_Error ftError;
FT_GlyphSlot ftGlyph;
FT_Fixed advFixed;
FONS_NOTUSED(scale);
ftError = FT_Set_Pixel_Sizes(font->font, 0, size);
if (ftError) return 0;
ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT);
if (ftError) return 0;
ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, &advFixed);
if (ftError) return 0;
ftGlyph = font->font->glyph;
*advance = (int)advFixed;
*lsb = (int)ftGlyph->metrics.horiBearingX;
*x0 = ftGlyph->bitmap_left;
*x1 = *x0 + ftGlyph->bitmap.width;
*y0 = -ftGlyph->bitmap_top;
*y1 = *y0 + ftGlyph->bitmap.rows;
return 1;
}
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{
FT_GlyphSlot ftGlyph = font->font->glyph;
int ftGlyphOffset = 0;
unsigned int x, y;
FONS_NOTUSED(outWidth);
FONS_NOTUSED(outHeight);
FONS_NOTUSED(scaleX);
FONS_NOTUSED(scaleY);
FONS_NOTUSED(glyph); // glyph has already been loaded by fons__tt_buildGlyphBitmap
for ( y = 0; y < ftGlyph->bitmap.rows; y++ ) {
for ( x = 0; x < ftGlyph->bitmap.width; x++ ) {
output[(y * outStride) + x] = ftGlyph->bitmap.buffer[ftGlyphOffset++];
}
}
}
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{
FT_Vector ftKerning;
FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning);
return (int)((ftKerning.x + 32) >> 6); // Round up and convert to integer
}
#else
static void* fons__tmpalloc(size_t size, void* up);
static void fons__tmpfree(void* ptr, void* up);
#define STBTT_malloc(x,u) fons__tmpalloc(x,u)
#define STBTT_free(x,u) fons__tmpfree(x,u)
int fons__tt_init(FONScontext *context)
{
FONS_NOTUSED(context);
return 1;
}
int fons__tt_done(FONScontext *context)
{
FONS_NOTUSED(context);
return 1;
}
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize, int fontIndex)
{
int offset, stbError;
FONS_NOTUSED(dataSize);
font->font.userdata = context;
offset = stbtt_GetFontOffsetForIndex(data, fontIndex);
if (offset == -1) {
stbError = 0;
} else {
stbError = stbtt_InitFont(&font->font, data, offset);
}
return stbError;
}
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{
stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap);
}
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{
return stbtt_ScaleForMappingEmToPixels(&font->font, size);
}
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{
return stbtt_FindGlyphIndex(&font->font, codepoint);
}
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{
FONS_NOTUSED(size);
stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb);
stbtt_GetGlyphBitmapBox(&font->font, glyph, scale, scale, x0, y0, x1, y1);
return 1;
}
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{
stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph);
}
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{
return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2);
}
#endif
#ifdef STB_TRUETYPE_IMPLEMENTATION
static void* fons__tmpalloc(size_t size, void* up)