Support aliased font texture generation
Useful for bitmaps pixelated fonts where anti-aliasing is not desired! Change also enables additional font generation mechanisms in a future (cleartype, hinting...).
This commit is contained in:
parent
1fcb3c0317
commit
dfb8837c46
3 changed files with 28 additions and 9 deletions
|
@ -29,19 +29,18 @@ int main()
|
||||||
fontDefault.baseSize = 16;
|
fontDefault.baseSize = 16;
|
||||||
fontDefault.charsCount = 95;
|
fontDefault.charsCount = 95;
|
||||||
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
|
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
|
||||||
fontDefault.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 95, false);
|
fontDefault.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 95, FONT_DEFAULT);
|
||||||
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
|
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
|
||||||
Image atlas = GenImageFontAtlas(fontDefault.chars, 95, 16, 4, 0);
|
Image atlas = GenImageFontAtlas(fontDefault.chars, 95, 16, 4, 0);
|
||||||
fontDefault.texture = LoadTextureFromImage(atlas);
|
fontDefault.texture = LoadTextureFromImage(atlas);
|
||||||
UnloadImage(atlas);
|
UnloadImage(atlas);
|
||||||
|
|
||||||
// SDF font generation from TTF font
|
// SDF font generation from TTF font
|
||||||
// NOTE: SDF chars data is generated with LoadFontData(), it's just a bool option
|
|
||||||
Font fontSDF = { 0 };
|
Font fontSDF = { 0 };
|
||||||
fontSDF.baseSize = 16;
|
fontSDF.baseSize = 16;
|
||||||
fontSDF.charsCount = 95;
|
fontSDF.charsCount = 95;
|
||||||
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
|
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
|
||||||
fontSDF.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 0, true);
|
fontSDF.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 0, FONT_SDF);
|
||||||
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
|
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
|
||||||
atlas = GenImageFontAtlas(fontSDF.chars, 95, 16, 0, 1);
|
atlas = GenImageFontAtlas(fontSDF.chars, 95, 16, 0, 1);
|
||||||
fontSDF.texture = LoadTextureFromImage(atlas);
|
fontSDF.texture = LoadTextureFromImage(atlas);
|
||||||
|
|
|
@ -721,6 +721,13 @@ typedef enum {
|
||||||
WRAP_MIRROR
|
WRAP_MIRROR
|
||||||
} TextureWrapMode;
|
} TextureWrapMode;
|
||||||
|
|
||||||
|
// Font type, defines generation method
|
||||||
|
typedef enum {
|
||||||
|
FONT_DEFAULT = 0, // Default font generation, anti-aliased
|
||||||
|
FONT_BITMAP, // Bitmap font generation, no anti-aliasing
|
||||||
|
FONT_SDF // SDF font generation, requires external shader
|
||||||
|
} FontType;
|
||||||
|
|
||||||
// Color blending modes (pre-defined)
|
// Color blending modes (pre-defined)
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BLEND_ALPHA = 0,
|
BLEND_ALPHA = 0,
|
||||||
|
@ -1056,7 +1063,7 @@ RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle
|
||||||
RLAPI Font GetFontDefault(void); // Get the default Font
|
RLAPI Font GetFontDefault(void); // Get the default Font
|
||||||
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
||||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load font from file with extended parameters
|
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load font from file with extended parameters
|
||||||
RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf); // Load font data for further use
|
RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use
|
||||||
RLAPI Image GenImageFontAtlas(CharInfo *chars, int fontSize, int charsCount, int padding, int packMethod); // Generate image font atlas using chars info
|
RLAPI Image GenImageFontAtlas(CharInfo *chars, int fontSize, int charsCount, int padding, int packMethod); // Generate image font atlas using chars info
|
||||||
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
|
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
|
||||||
|
|
||||||
|
|
23
src/text.c
23
src/text.c
|
@ -283,7 +283,7 @@ Font LoadFont(const char *fileName)
|
||||||
{
|
{
|
||||||
font.baseSize = DEFAULT_TTF_FONTSIZE;
|
font.baseSize = DEFAULT_TTF_FONTSIZE;
|
||||||
font.charsCount = DEFAULT_TTF_NUMCHARS;
|
font.charsCount = DEFAULT_TTF_NUMCHARS;
|
||||||
font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, false);
|
font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, FONT_DEFAULT);
|
||||||
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 4, 0);
|
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 4, 0);
|
||||||
font.texture = LoadTextureFromImage(atlas);
|
font.texture = LoadTextureFromImage(atlas);
|
||||||
UnloadImage(atlas);
|
UnloadImage(atlas);
|
||||||
|
@ -319,8 +319,8 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
|
||||||
|
|
||||||
font.baseSize = fontSize;
|
font.baseSize = fontSize;
|
||||||
font.charsCount = (charsCount > 0) ? charsCount : 95;
|
font.charsCount = (charsCount > 0) ? charsCount : 95;
|
||||||
font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, false);
|
font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, FONT_DEFAULT);
|
||||||
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 0, 0);
|
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 2, 0);
|
||||||
font.texture = LoadTextureFromImage(atlas);
|
font.texture = LoadTextureFromImage(atlas);
|
||||||
UnloadImage(atlas);
|
UnloadImage(atlas);
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
|
||||||
|
|
||||||
// Load font data for further use
|
// Load font data for further use
|
||||||
// NOTE: Requires TTF font and can generate SDF data
|
// NOTE: Requires TTF font and can generate SDF data
|
||||||
CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf)
|
CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type)
|
||||||
{
|
{
|
||||||
// NOTE: Using some SDF generation default values,
|
// NOTE: Using some SDF generation default values,
|
||||||
// trades off precision with ability to handle *smaller* sizes
|
// trades off precision with ability to handle *smaller* sizes
|
||||||
|
@ -337,6 +337,8 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
|
||||||
#define SDF_ON_EDGE_VALUE 128
|
#define SDF_ON_EDGE_VALUE 128
|
||||||
#define SDF_PIXEL_DIST_SCALE 64.0f
|
#define SDF_PIXEL_DIST_SCALE 64.0f
|
||||||
|
|
||||||
|
#define BITMAP_ALPHA_THRESHOLD 80
|
||||||
|
|
||||||
// In case no chars count provided, default to 95
|
// In case no chars count provided, default to 95
|
||||||
charsCount = (charsCount > 0) ? charsCount : 95;
|
charsCount = (charsCount > 0) ? charsCount : 95;
|
||||||
|
|
||||||
|
@ -390,9 +392,20 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
|
||||||
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
|
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
|
||||||
// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
|
// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
|
||||||
|
|
||||||
if (!sdf) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
if (type != FONT_SDF) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
||||||
else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
||||||
|
|
||||||
|
if (type == FONT_BITMAP)
|
||||||
|
{
|
||||||
|
// Aliased bitmap (black & white) font generation, avoiding anti-aliasing
|
||||||
|
// NOTE: For optimum results, bitmap font should be generated at base pixel size
|
||||||
|
for (int p = 0; p < chw*chh; p++)
|
||||||
|
{
|
||||||
|
if (chars[i].data[p] < BITMAP_ALPHA_THRESHOLD) chars[i].data[p] = 0;
|
||||||
|
else chars[i].data[p] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chars[i].rec.width = (float)chw;
|
chars[i].rec.width = (float)chw;
|
||||||
chars[i].rec.height = (float)chh;
|
chars[i].rec.height = (float)chh;
|
||||||
chars[i].offsetY += (int)((float)ascent*scaleFactor);
|
chars[i].offsetY += (int)((float)ascent*scaleFactor);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue