Exposed LoadFontFromImage()
This commit is contained in:
parent
5aea693f69
commit
87ad244ee0
3 changed files with 117 additions and 117 deletions
BIN
src/libraylib.a
Normal file
BIN
src/libraylib.a
Normal file
Binary file not shown.
|
@ -1096,6 +1096,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 Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||||
RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type); // 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 charsCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
RLAPI Image GenImageFontAtlas(CharInfo *chars, int charsCount, int fontSize, 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)
|
||||||
|
|
233
src/text.c
233
src/text.c
|
@ -86,7 +86,6 @@ static Font defaultFont; // Default font provided by raylib
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static Font LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||||
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||||
#endif
|
#endif
|
||||||
|
@ -285,7 +284,7 @@ Font LoadFont(const char *fileName)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
Image image = LoadImage(fileName);
|
Image image = LoadImage(fileName);
|
||||||
if (image.data != NULL) font = LoadImageFont(image, MAGENTA, DEFAULT_FIRST_CHAR);
|
if (image.data != NULL) font = LoadFontFromImage(image, MAGENTA, DEFAULT_FIRST_CHAR);
|
||||||
UnloadImage(image);
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +320,121 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load an Image font file (XNA style)
|
||||||
|
Font LoadFontFromImage(Image image, Color key, int firstChar)
|
||||||
|
{
|
||||||
|
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
|
||||||
|
|
||||||
|
int charSpacing = 0;
|
||||||
|
int lineSpacing = 0;
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
// Default number of characters supported
|
||||||
|
#define MAX_FONTCHARS 256
|
||||||
|
|
||||||
|
// We allocate a temporal arrays for chars data measures,
|
||||||
|
// once we get the actual number of chars, we copy data to a sized arrays
|
||||||
|
int tempCharValues[MAX_FONTCHARS];
|
||||||
|
Rectangle tempCharRecs[MAX_FONTCHARS];
|
||||||
|
|
||||||
|
Color *pixels = GetImageData(image);
|
||||||
|
|
||||||
|
// Parse image data to get charSpacing and lineSpacing
|
||||||
|
for (y = 0; y < image.height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < image.width; x++)
|
||||||
|
{
|
||||||
|
if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
charSpacing = x;
|
||||||
|
lineSpacing = y;
|
||||||
|
|
||||||
|
int charHeight = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while (!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++;
|
||||||
|
|
||||||
|
charHeight = j;
|
||||||
|
|
||||||
|
// Check array values to get characters: value, x, y, w, h
|
||||||
|
int index = 0;
|
||||||
|
int lineToRead = 0;
|
||||||
|
int xPosToRead = charSpacing;
|
||||||
|
|
||||||
|
// Parse image data to get rectangle sizes
|
||||||
|
while ((lineSpacing + lineToRead*(charHeight + lineSpacing)) < image.height)
|
||||||
|
{
|
||||||
|
while ((xPosToRead < image.width) &&
|
||||||
|
!COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key))
|
||||||
|
{
|
||||||
|
tempCharValues[index] = firstChar + index;
|
||||||
|
|
||||||
|
tempCharRecs[index].x = (float)xPosToRead;
|
||||||
|
tempCharRecs[index].y = (float)(lineSpacing + lineToRead*(charHeight + lineSpacing));
|
||||||
|
tempCharRecs[index].height = (float)charHeight;
|
||||||
|
|
||||||
|
int charWidth = 0;
|
||||||
|
|
||||||
|
while (!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++;
|
||||||
|
|
||||||
|
tempCharRecs[index].width = (float)charWidth;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
xPosToRead += (charWidth + charSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineToRead++;
|
||||||
|
xPosToRead = charSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceLog(LOG_DEBUG, "Font data parsed correctly from image");
|
||||||
|
|
||||||
|
// NOTE: We need to remove key color borders from image to avoid weird
|
||||||
|
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
|
||||||
|
for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
|
||||||
|
|
||||||
|
// Create a new image with the processed color data (key color replaced by BLANK)
|
||||||
|
Image fontClear = LoadImageEx(pixels, image.width, image.height);
|
||||||
|
|
||||||
|
free(pixels); // Free pixels array memory
|
||||||
|
|
||||||
|
// Create spritefont with all data parsed from image
|
||||||
|
Font spriteFont = { 0 };
|
||||||
|
|
||||||
|
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
||||||
|
spriteFont.charsCount = index;
|
||||||
|
|
||||||
|
UnloadImage(fontClear); // Unload processed image once converted to texture
|
||||||
|
|
||||||
|
// We got tempCharValues and tempCharsRecs populated with chars data
|
||||||
|
// Now we move temp data to sized charValues and charRecs arrays
|
||||||
|
spriteFont.chars = (CharInfo *)malloc(spriteFont.charsCount*sizeof(CharInfo));
|
||||||
|
|
||||||
|
for (int i = 0; i < spriteFont.charsCount; i++)
|
||||||
|
{
|
||||||
|
spriteFont.chars[i].value = tempCharValues[i];
|
||||||
|
spriteFont.chars[i].rec = tempCharRecs[i];
|
||||||
|
|
||||||
|
// NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
|
||||||
|
spriteFont.chars[i].offsetX = 0;
|
||||||
|
spriteFont.chars[i].offsetY = 0;
|
||||||
|
spriteFont.chars[i].advanceX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteFont.baseSize = (int)spriteFont.chars[0].rec.height;
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "Image file loaded correctly as Font");
|
||||||
|
|
||||||
|
return spriteFont;
|
||||||
|
}
|
||||||
|
|
||||||
// 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, int type)
|
CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type)
|
||||||
|
@ -837,121 +951,6 @@ bool IsEqualText(const char *text1, const char *text2)
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Load an Image font file (XNA style)
|
|
||||||
static Font LoadImageFont(Image image, Color key, int firstChar)
|
|
||||||
{
|
|
||||||
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
|
|
||||||
|
|
||||||
int charSpacing = 0;
|
|
||||||
int lineSpacing = 0;
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
|
|
||||||
// Default number of characters supported
|
|
||||||
#define MAX_FONTCHARS 256
|
|
||||||
|
|
||||||
// We allocate a temporal arrays for chars data measures,
|
|
||||||
// once we get the actual number of chars, we copy data to a sized arrays
|
|
||||||
int tempCharValues[MAX_FONTCHARS];
|
|
||||||
Rectangle tempCharRecs[MAX_FONTCHARS];
|
|
||||||
|
|
||||||
Color *pixels = GetImageData(image);
|
|
||||||
|
|
||||||
// Parse image data to get charSpacing and lineSpacing
|
|
||||||
for (y = 0; y < image.height; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < image.width; x++)
|
|
||||||
{
|
|
||||||
if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
charSpacing = x;
|
|
||||||
lineSpacing = y;
|
|
||||||
|
|
||||||
int charHeight = 0;
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
while (!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++;
|
|
||||||
|
|
||||||
charHeight = j;
|
|
||||||
|
|
||||||
// Check array values to get characters: value, x, y, w, h
|
|
||||||
int index = 0;
|
|
||||||
int lineToRead = 0;
|
|
||||||
int xPosToRead = charSpacing;
|
|
||||||
|
|
||||||
// Parse image data to get rectangle sizes
|
|
||||||
while ((lineSpacing + lineToRead*(charHeight + lineSpacing)) < image.height)
|
|
||||||
{
|
|
||||||
while ((xPosToRead < image.width) &&
|
|
||||||
!COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key))
|
|
||||||
{
|
|
||||||
tempCharValues[index] = firstChar + index;
|
|
||||||
|
|
||||||
tempCharRecs[index].x = (float)xPosToRead;
|
|
||||||
tempCharRecs[index].y = (float)(lineSpacing + lineToRead*(charHeight + lineSpacing));
|
|
||||||
tempCharRecs[index].height = (float)charHeight;
|
|
||||||
|
|
||||||
int charWidth = 0;
|
|
||||||
|
|
||||||
while (!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++;
|
|
||||||
|
|
||||||
tempCharRecs[index].width = (float)charWidth;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
xPosToRead += (charWidth + charSpacing);
|
|
||||||
}
|
|
||||||
|
|
||||||
lineToRead++;
|
|
||||||
xPosToRead = charSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceLog(LOG_DEBUG, "Font data parsed correctly from image");
|
|
||||||
|
|
||||||
// NOTE: We need to remove key color borders from image to avoid weird
|
|
||||||
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
|
|
||||||
for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
|
|
||||||
|
|
||||||
// Create a new image with the processed color data (key color replaced by BLANK)
|
|
||||||
Image fontClear = LoadImageEx(pixels, image.width, image.height);
|
|
||||||
|
|
||||||
free(pixels); // Free pixels array memory
|
|
||||||
|
|
||||||
// Create spritefont with all data parsed from image
|
|
||||||
Font spriteFont = { 0 };
|
|
||||||
|
|
||||||
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
|
||||||
spriteFont.charsCount = index;
|
|
||||||
|
|
||||||
UnloadImage(fontClear); // Unload processed image once converted to texture
|
|
||||||
|
|
||||||
// We got tempCharValues and tempCharsRecs populated with chars data
|
|
||||||
// Now we move temp data to sized charValues and charRecs arrays
|
|
||||||
spriteFont.chars = (CharInfo *)malloc(spriteFont.charsCount*sizeof(CharInfo));
|
|
||||||
|
|
||||||
for (int i = 0; i < spriteFont.charsCount; i++)
|
|
||||||
{
|
|
||||||
spriteFont.chars[i].value = tempCharValues[i];
|
|
||||||
spriteFont.chars[i].rec = tempCharRecs[i];
|
|
||||||
|
|
||||||
// NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
|
|
||||||
spriteFont.chars[i].offsetX = 0;
|
|
||||||
spriteFont.chars[i].offsetY = 0;
|
|
||||||
spriteFont.chars[i].advanceX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
spriteFont.baseSize = (int)spriteFont.chars[0].rec.height;
|
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "Image file loaded correctly as Font");
|
|
||||||
|
|
||||||
return spriteFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||||
// Load a BMFont file (AngelCode font file)
|
// Load a BMFont file (AngelCode font file)
|
||||||
static Font LoadBMFont(const char *fileName)
|
static Font LoadBMFont(const char *fileName)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue