diff --git a/src/libraylib.a b/src/libraylib.a new file mode 100644 index 000000000..84e0b6bbb Binary files /dev/null and b/src/libraylib.a differ diff --git a/src/raylib.h b/src/raylib.h index 3b7a322af..430e66dbf 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1096,6 +1096,7 @@ RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle RLAPI Font GetFontDefault(void); // Get the default Font 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 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 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) diff --git a/src/text.c b/src/text.c index b9c298a17..80b75f106 100644 --- a/src/text.c +++ b/src/text.c @@ -86,7 +86,6 @@ static Font defaultFont; // Default font provided by raylib //---------------------------------------------------------------------------------- // 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) static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) #endif @@ -285,7 +284,7 @@ Font LoadFont(const char *fileName) #endif { 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); } @@ -321,6 +320,121 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha 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 // NOTE: Requires TTF font and can generate SDF data 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 //---------------------------------------------------------------------------------- -// 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) // Load a BMFont file (AngelCode font file) static Font LoadBMFont(const char *fileName)