Redesigned SpriteFont struct
This commit is contained in:
parent
aa982f80f5
commit
92bcf09c53
2 changed files with 134 additions and 125 deletions
78
src/raylib.h
78
src/raylib.h
|
@ -241,20 +241,13 @@ typedef struct Texture2D {
|
||||||
int format; // Data format (TextureFormat)
|
int format; // Data format (TextureFormat)
|
||||||
} Texture2D;
|
} Texture2D;
|
||||||
|
|
||||||
// Character type (one font glyph)
|
|
||||||
typedef struct Character {
|
|
||||||
int value; //char value = ' '; (int)value = 32;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
} Character;
|
|
||||||
|
|
||||||
// SpriteFont type, includes texture and charSet array data
|
// SpriteFont type, includes texture and charSet array data
|
||||||
typedef struct SpriteFont {
|
typedef struct SpriteFont {
|
||||||
Texture2D texture;
|
Texture2D texture; // Font texture
|
||||||
int numChars;
|
int size; // Base size (default chars height)
|
||||||
Character *charSet;
|
int numChars; // Number of characters
|
||||||
|
int *charValues; // Characters values array
|
||||||
|
Rectangle *charRecs; // Characters rectangles within the texture
|
||||||
} SpriteFont;
|
} SpriteFont;
|
||||||
|
|
||||||
// Camera type, defines a camera position/orientation in 3d space
|
// Camera type, defines a camera position/orientation in 3d space
|
||||||
|
@ -276,7 +269,7 @@ typedef struct VertexData {
|
||||||
unsigned int vboId[4];
|
unsigned int vboId[4];
|
||||||
} VertexData;
|
} VertexData;
|
||||||
|
|
||||||
// Shader type
|
// Shader type (generic shader)
|
||||||
typedef struct Shader {
|
typedef struct Shader {
|
||||||
unsigned int id; // Shader program id
|
unsigned int id; // Shader program id
|
||||||
|
|
||||||
|
@ -411,6 +404,8 @@ void EndDrawing(void); // End canvas drawin
|
||||||
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
|
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
|
||||||
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
|
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||||
|
|
||||||
|
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Returns a ray trace from mouse position
|
||||||
|
|
||||||
void SetTargetFPS(int fps); // Set target FPS (maximum)
|
void SetTargetFPS(int fps); // Set target FPS (maximum)
|
||||||
float GetFPS(void); // Returns current FPS
|
float GetFPS(void); // Returns current FPS
|
||||||
float GetFrameTime(void); // Returns time in seconds for one frame
|
float GetFrameTime(void); // Returns time in seconds for one frame
|
||||||
|
@ -421,38 +416,13 @@ int GetHexValue(Color color); // Returns hexadecim
|
||||||
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
|
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
|
||||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
||||||
|
|
||||||
void SetConfigFlags(char flags); // Enable some window configurations
|
void SetConfigFlags(char flags); // Setup some window configuration flags
|
||||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||||
|
|
||||||
bool IsFileDropped(void); // Check if a file have been dropped into window
|
bool IsFileDropped(void); // Check if a file have been dropped into window
|
||||||
char **GetDroppedFiles(int *count); // Retrieve dropped files into window
|
char **GetDroppedFiles(int *count); // Retrieve dropped files into window
|
||||||
void ClearDroppedFiles(void); // Clear dropped files paths buffer
|
void ClearDroppedFiles(void); // Clear dropped files paths buffer
|
||||||
|
|
||||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Gives the ray trace from mouse position
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// Shaders System Functions (Module: rlgl)
|
|
||||||
// NOTE: This functions are useless when using OpenGL 1.1
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
|
|
||||||
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id
|
|
||||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
|
||||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
|
||||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
|
||||||
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
|
||||||
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
|
|
||||||
bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled
|
|
||||||
|
|
||||||
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
|
||||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
|
|
||||||
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
|
|
||||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment
|
|
||||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment
|
|
||||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
|
||||||
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
|
||||||
|
|
||||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Input Handling Functions (Module: core)
|
// Input Handling Functions (Module: core)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
@ -517,7 +487,8 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
|
||||||
// Camera System Functions (Module: camera)
|
// Camera System Functions (Module: camera)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
|
void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
|
||||||
Camera UpdateCamera(Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
|
void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
|
||||||
|
void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
|
||||||
|
|
||||||
void SetCameraPosition(Vector3 position); // Set internal camera position
|
void SetCameraPosition(Vector3 position); // Set internal camera position
|
||||||
void SetCameraTarget(Vector3 target); // Set internal camera target
|
void SetCameraTarget(Vector3 target); // Set internal camera target
|
||||||
|
@ -571,7 +542,7 @@ Image LoadImageFromRES(const char *rresName, int resId);
|
||||||
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
||||||
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // Load a texture from raw data into GPU memory
|
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // Load a texture from raw data into GPU memory
|
||||||
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
||||||
Texture2D LoadTextureFromImage(Image image); // Load a texture from image data (and generate mipmaps)
|
Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
|
||||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||||
Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
||||||
|
@ -599,7 +570,7 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position,
|
||||||
int fontSize, int spacing, Color tint);
|
int fontSize, int spacing, Color tint);
|
||||||
int MeasureText(const char *text, int fontSize); // Measure string width for default font
|
int MeasureText(const char *text, int fontSize); // Measure string width for default font
|
||||||
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
|
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
|
||||||
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
|
|
||||||
void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
|
void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
|
||||||
const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
|
const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||||
|
|
||||||
|
@ -645,6 +616,29 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V
|
||||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
|
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
|
||||||
Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface
|
Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Shaders System Functions (Module: rlgl)
|
||||||
|
// NOTE: This functions are useless when using OpenGL 1.1
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
|
||||||
|
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shaders strings and return program id
|
||||||
|
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||||
|
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||||
|
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||||
|
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
||||||
|
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
|
||||||
|
bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled
|
||||||
|
|
||||||
|
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||||
|
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
|
||||||
|
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
|
||||||
|
void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment
|
||||||
|
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment
|
||||||
|
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
||||||
|
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
||||||
|
|
||||||
|
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Audio Loading and Playing Functions (Module: audio)
|
// Audio Loading and Playing Functions (Module: audio)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
181
src/text.c
181
src/text.c
|
@ -67,7 +67,7 @@ static SpriteFont defaultFont; // Default font provided by raylib
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
|
static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
|
||||||
static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures
|
static int ParseImageData(Image image, int **charValues, Rectangle **charSet); // Parse image pixel data to obtain characters data
|
||||||
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
||||||
static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required)
|
static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required)
|
||||||
|
|
||||||
|
@ -181,21 +181,23 @@ extern void LoadDefaultFont(void)
|
||||||
|
|
||||||
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data
|
defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int));
|
||||||
// This memory should be freed at end! --> Done on CloseWindow()
|
defaultFont.charRecs = (Rectangle *)malloc(defaultFont.numChars*sizeof(Rectangle)); // Allocate space for our character rectangle data
|
||||||
|
// This memory should be freed at end! --> Done on CloseWindow()
|
||||||
int currentLine = 0;
|
int currentLine = 0;
|
||||||
int currentPosX = charsDivisor;
|
int currentPosX = charsDivisor;
|
||||||
int testPosX = charsDivisor;
|
int testPosX = charsDivisor;
|
||||||
|
|
||||||
for (int i = 0; i < defaultFont.numChars; i++)
|
for (int i = 0; i < defaultFont.numChars; i++)
|
||||||
{
|
{
|
||||||
defaultFont.charSet[i].value = FONT_FIRST_CHAR + i; // First char is 32
|
defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32
|
||||||
defaultFont.charSet[i].x = currentPosX;
|
|
||||||
defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
|
defaultFont.charRecs[i].x = currentPosX;
|
||||||
defaultFont.charSet[i].w = charsWidth[i];
|
defaultFont.charRecs[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
|
||||||
defaultFont.charSet[i].h = charsHeight;
|
defaultFont.charRecs[i].width = charsWidth[i];
|
||||||
|
defaultFont.charRecs[i].height = charsHeight;
|
||||||
|
|
||||||
testPosX += (defaultFont.charSet[i].w + charsDivisor);
|
testPosX += (defaultFont.charRecs[i].width + charsDivisor);
|
||||||
|
|
||||||
if (testPosX >= defaultFont.texture.width)
|
if (testPosX >= defaultFont.texture.width)
|
||||||
{
|
{
|
||||||
|
@ -203,11 +205,13 @@ extern void LoadDefaultFont(void)
|
||||||
currentPosX = 2 * charsDivisor + charsWidth[i];
|
currentPosX = 2 * charsDivisor + charsWidth[i];
|
||||||
testPosX = currentPosX;
|
testPosX = currentPosX;
|
||||||
|
|
||||||
defaultFont.charSet[i].x = charsDivisor;
|
defaultFont.charRecs[i].x = charsDivisor;
|
||||||
defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
|
defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor);
|
||||||
}
|
}
|
||||||
else currentPosX = testPosX;
|
else currentPosX = testPosX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultFont.size = defaultFont.charRecs[0].y;
|
||||||
|
|
||||||
TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
|
TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +219,8 @@ extern void LoadDefaultFont(void)
|
||||||
extern void UnloadDefaultFont(void)
|
extern void UnloadDefaultFont(void)
|
||||||
{
|
{
|
||||||
UnloadTexture(defaultFont.texture);
|
UnloadTexture(defaultFont.texture);
|
||||||
free(defaultFont.charSet);
|
free(defaultFont.charValues);
|
||||||
|
free(defaultFont.charRecs);
|
||||||
|
|
||||||
TraceLog(INFO, "Unloaded default font data");
|
TraceLog(INFO, "Unloaded default font data");
|
||||||
}
|
}
|
||||||
|
@ -238,25 +243,20 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||||
{
|
{
|
||||||
Image image = LoadImage(fileName);
|
Image image = LoadImage(fileName);
|
||||||
|
|
||||||
// At this point we have a data array...
|
|
||||||
|
|
||||||
Color *imagePixels = GetImageData(image);
|
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||||
ImageConvertToPOT(&image, MAGENTA);
|
ImageConvertToPOT(&image, MAGENTA);
|
||||||
#endif
|
#endif
|
||||||
// Process bitmap Font pixel data to get measures (Character array)
|
// Process bitmap font pixel data to get characters measures
|
||||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
||||||
int numChars = ParseImageData(imagePixels, image.width, image.height, &spriteFont.charSet);
|
int numChars = ParseImageData(image, &spriteFont.charValues, &spriteFont.charRecs);
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName);
|
TraceLog(DEBUG, "[%s] SpriteFont data parsed correctly", fileName);
|
||||||
TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
|
TraceLog(DEBUG, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
|
||||||
|
|
||||||
spriteFont.numChars = numChars;
|
spriteFont.numChars = numChars;
|
||||||
|
|
||||||
spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
|
spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
|
||||||
|
spriteFont.size = spriteFont.charRecs[0].height;
|
||||||
|
|
||||||
free(imagePixels);
|
|
||||||
UnloadImage(image);
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,8 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||||
void UnloadSpriteFont(SpriteFont spriteFont)
|
void UnloadSpriteFont(SpriteFont spriteFont)
|
||||||
{
|
{
|
||||||
UnloadTexture(spriteFont.texture);
|
UnloadTexture(spriteFont.texture);
|
||||||
free(spriteFont.charSet);
|
free(spriteFont.charValues);
|
||||||
|
free(spriteFont.charRecs);
|
||||||
|
|
||||||
TraceLog(INFO, "Unloaded sprite font data");
|
TraceLog(INFO, "Unloaded sprite font data");
|
||||||
}
|
}
|
||||||
|
@ -298,32 +299,32 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int f
|
||||||
float scaleFactor;
|
float scaleFactor;
|
||||||
unsigned char letter;
|
unsigned char letter;
|
||||||
|
|
||||||
Character c;
|
Rectangle rec;
|
||||||
|
|
||||||
//if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
//if (fontSize <= spriteFont.charRecs[0].height) scaleFactor = 1.0f;
|
||||||
//else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
//else scaleFactor = (float)fontSize / spriteFont.charRecs[0].height;
|
||||||
|
|
||||||
scaleFactor = (float)fontSize/spriteFont.charSet[0].h;
|
scaleFactor = (float)fontSize/spriteFont.charRecs[0].height;
|
||||||
|
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
if ((unsigned char)text[i] == 0xc2)
|
if ((unsigned char)text[i] == 0xc2)
|
||||||
{
|
{
|
||||||
letter = (unsigned char)text[i + 1];
|
letter = (unsigned char)text[i + 1];
|
||||||
c = spriteFont.charSet[letter - FONT_FIRST_CHAR];
|
rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if ((unsigned char)text[i] == 0xc3)
|
else if ((unsigned char)text[i] == 0xc3)
|
||||||
{
|
{
|
||||||
letter = (unsigned char)text[i + 1];
|
letter = (unsigned char)text[i + 1];
|
||||||
c = spriteFont.charSet[letter - FONT_FIRST_CHAR + 64];
|
rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR + 64];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
|
else rec = spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR];
|
||||||
|
|
||||||
DrawTexturePro(spriteFont.texture, (Rectangle){ c.x, c.y, c.w, c.h }, (Rectangle){ position.x + offsetX, position.y, c.w*scaleFactor, c.h*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
|
DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + offsetX, position.y, rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
|
||||||
|
|
||||||
offsetX += (c.w*scaleFactor + spacing);
|
offsetX += (rec.width*scaleFactor + spacing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,25 +364,19 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
|
||||||
|
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
textWidth += spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w;
|
textWidth += spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR].width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
if (fontSize <= spriteFont.charRecs[0].height) scaleFactor = 1.0f;
|
||||||
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
else scaleFactor = (float)fontSize / spriteFont.charRecs[0].height;
|
||||||
|
|
||||||
Vector2 vec;
|
Vector2 vec;
|
||||||
vec.x = (float)textWidth * scaleFactor + (len - 1) * spacing; // Adds chars spacing to measure
|
vec.x = (float)textWidth * scaleFactor + (len - 1) * spacing; // Adds chars spacing to measure
|
||||||
vec.y = (float)spriteFont.charSet[0].h * scaleFactor;
|
vec.y = (float)spriteFont.charRecs[0].height * scaleFactor;
|
||||||
|
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the base size for a SpriteFont (chars height)
|
|
||||||
int GetFontBaseSize(SpriteFont spriteFont)
|
|
||||||
{
|
|
||||||
return spriteFont.charSet[0].h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shows current FPS on top-left corner
|
// Shows current FPS on top-left corner
|
||||||
// NOTE: Uses default font
|
// NOTE: Uses default font
|
||||||
void DrawFPS(int posX, int posY)
|
void DrawFPS(int posX, int posY)
|
||||||
|
@ -420,8 +415,8 @@ static bool PixelIsMagenta(Color p)
|
||||||
return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255));
|
return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse image pixel data to obtain character set measures
|
// Parse image pixel data to obtain characters data (measures)
|
||||||
static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet)
|
static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
|
||||||
{
|
{
|
||||||
int charSpacing = 0;
|
int charSpacing = 0;
|
||||||
int lineSpacing = 0;
|
int lineSpacing = 0;
|
||||||
|
@ -429,15 +424,20 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
Character tempCharSet[MAX_FONTCHARS]; // We allocate a temporal array for charData, once we get the actual charNumber we copy data to a sized array.
|
// 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);
|
||||||
|
|
||||||
for(y = 0; y < imgHeight; y++)
|
for(y = 0; y < image.height; y++)
|
||||||
{
|
{
|
||||||
for(x = 0; x < imgWidth; x++)
|
for(x = 0; x < image.width; x++)
|
||||||
{
|
{
|
||||||
if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
|
if (!PixelIsMagenta(pixels[y*image.width + x])) break;
|
||||||
}
|
}
|
||||||
if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
|
if (!PixelIsMagenta(pixels[y*image.width + x])) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
charSpacing = x;
|
charSpacing = x;
|
||||||
|
@ -446,7 +446,7 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
|
||||||
int charHeight = 0;
|
int charHeight = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
while(!PixelIsMagenta(imgDataPixel[(lineSpacing + j)*imgWidth + charSpacing])) j++;
|
while(!PixelIsMagenta(pixels[(lineSpacing + j)*image.width + charSpacing])) j++;
|
||||||
|
|
||||||
charHeight = j;
|
charHeight = j;
|
||||||
|
|
||||||
|
@ -455,21 +455,22 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
|
||||||
int lineToRead = 0;
|
int lineToRead = 0;
|
||||||
int xPosToRead = charSpacing;
|
int xPosToRead = charSpacing;
|
||||||
|
|
||||||
while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < imgHeight)
|
while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height)
|
||||||
{
|
{
|
||||||
while((xPosToRead < imgWidth) &&
|
while((xPosToRead < image.width) &&
|
||||||
!PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
|
!PixelIsMagenta((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead])))
|
||||||
{
|
{
|
||||||
tempCharSet[index].value = FONT_FIRST_CHAR + index;
|
tempCharValues[index] = FONT_FIRST_CHAR + index;
|
||||||
tempCharSet[index].x = xPosToRead;
|
|
||||||
tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
|
tempCharRecs[index].x = xPosToRead;
|
||||||
tempCharSet[index].h = charHeight;
|
tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
|
||||||
|
tempCharRecs[index].height = charHeight;
|
||||||
|
|
||||||
int charWidth = 0;
|
int charWidth = 0;
|
||||||
|
|
||||||
while(!PixelIsMagenta(imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead + charWidth])) charWidth++;
|
while(!PixelIsMagenta(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth])) charWidth++;
|
||||||
|
|
||||||
tempCharSet[index].w = charWidth;
|
tempCharRecs[index].width = charWidth;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
@ -479,12 +480,20 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
|
||||||
lineToRead++;
|
lineToRead++;
|
||||||
xPosToRead = charSpacing;
|
xPosToRead = charSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(pixels);
|
||||||
|
|
||||||
// We got tempCharSet populated with char data and the number of chars (index)
|
// We got tempCharValues and tempCharsRecs populated with chars data
|
||||||
// Now we move temp data to real charSet (passed as parameter to the function)
|
// Now we move temp data to sized charValues and charRecs arrays (passed as parameter to the function)
|
||||||
(*charSet) = (Character *)malloc(index * sizeof(Character)); // BE CAREFUL! This memory should be freed!
|
// NOTE: This memory should be freed!
|
||||||
|
(*charRecs) = (Rectangle *)malloc(index*sizeof(Rectangle));
|
||||||
|
(*charValues) = (int *)malloc(index*sizeof(int));
|
||||||
|
|
||||||
for (int i = 0; i < index; i++) (*charSet)[i] = tempCharSet[i];
|
for (int i = 0; i < index; i++)
|
||||||
|
{
|
||||||
|
(*charValues)[i] = tempCharValues[i];
|
||||||
|
(*charRecs)[i] = tempCharRecs[i];
|
||||||
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +537,7 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||||
{
|
{
|
||||||
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
|
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
|
TraceLog(DEBUG, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
|
||||||
|
|
||||||
spriteFont.numChars = (int)rbmfHeader.numChars;
|
spriteFont.numChars = (int)rbmfHeader.numChars;
|
||||||
|
|
||||||
|
@ -566,15 +575,16 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||||
|
|
||||||
free(imagePixels);
|
free(imagePixels);
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
||||||
|
|
||||||
spriteFont.texture = LoadTextureFromImage(image);
|
spriteFont.texture = LoadTextureFromImage(image);
|
||||||
UnloadImage(image); // Unload image data
|
UnloadImage(image); // Unload image data
|
||||||
|
|
||||||
//TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);
|
//TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName);
|
||||||
|
|
||||||
// Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
|
// Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
|
||||||
spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data
|
spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int));
|
||||||
|
spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle));
|
||||||
|
|
||||||
int currentLine = 0;
|
int currentLine = 0;
|
||||||
int currentPosX = charsDivisor;
|
int currentPosX = charsDivisor;
|
||||||
|
@ -582,13 +592,14 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||||
|
|
||||||
for (int i = 0; i < spriteFont.numChars; i++)
|
for (int i = 0; i < spriteFont.numChars; i++)
|
||||||
{
|
{
|
||||||
spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i;
|
spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i;
|
||||||
spriteFont.charSet[i].x = currentPosX;
|
|
||||||
spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
|
spriteFont.charRecs[i].x = currentPosX;
|
||||||
spriteFont.charSet[i].w = (int)rbmfCharWidthData[i];
|
spriteFont.charRecs[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
|
||||||
spriteFont.charSet[i].h = (int)rbmfHeader.charHeight;
|
spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i];
|
||||||
|
spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight;
|
||||||
|
|
||||||
testPosX += (spriteFont.charSet[i].w + charsDivisor);
|
testPosX += (spriteFont.charRecs[i].width + charsDivisor);
|
||||||
|
|
||||||
if (testPosX > spriteFont.texture.width)
|
if (testPosX > spriteFont.texture.width)
|
||||||
{
|
{
|
||||||
|
@ -596,11 +607,13 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||||
currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
|
currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
|
||||||
testPosX = currentPosX;
|
testPosX = currentPosX;
|
||||||
|
|
||||||
spriteFont.charSet[i].x = charsDivisor;
|
spriteFont.charRecs[i].x = charsDivisor;
|
||||||
spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
|
spriteFont.charRecs[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
|
||||||
}
|
}
|
||||||
else currentPosX = testPosX;
|
else currentPosX = testPosX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spriteFont.size = spriteFont.charRecs[0].height;
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
|
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
|
||||||
}
|
}
|
||||||
|
@ -699,8 +712,10 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
|
||||||
|
|
||||||
print(100,160, 0, "This is a test");
|
print(100,160, 0, "This is a test");
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
font.numChars = 95;
|
font.numChars = 95;
|
||||||
font.charSet = (Character *)malloc(font.numChars*sizeof(Character));
|
font.charValues (int *)malloc(font.numChars*sizeof(int));
|
||||||
|
font.charRecs = (Character *)malloc(font.numChars*sizeof(Character));
|
||||||
font.texture = LoadTextureFromImage(image);
|
font.texture = LoadTextureFromImage(image);
|
||||||
|
|
||||||
//stbtt_aligned_quad letter;
|
//stbtt_aligned_quad letter;
|
||||||
|
@ -708,16 +723,16 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
|
||||||
|
|
||||||
for (int i = 0; i < font.numChars; i++)
|
for (int i = 0; i < font.numChars; i++)
|
||||||
{
|
{
|
||||||
font.charSet[i].value = i + 32;
|
font.charValues[i] = i + 32;
|
||||||
|
|
||||||
//stbtt_GetPackedQuad(chardata[0], 512, 512, i, &x, &y, &letter, 0);
|
//stbtt_GetPackedQuad(chardata[0], 512, 512, i, &x, &y, &letter, 0);
|
||||||
|
|
||||||
font.charSet[i].x = chardata[i + 32].x0;
|
font.charRecs[i].x = chardata[i + 32].x0;
|
||||||
font.charSet[i].y = chardata[i + 32].y0;
|
font.charRecs[i].y = chardata[i + 32].y0;
|
||||||
font.charSet[i].w = chardata[i + 32].x1 - chardata[i + 32].x0;
|
font.charRecs[i].width = chardata[i + 32].x1 - chardata[i + 32].x0;
|
||||||
font.charSet[i].h = chardata[i + 32].y1 - chardata[i + 32].y0;
|
font.charRecs[i].height = chardata[i + 32].y1 - chardata[i + 32].y0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
UnloadImage(image);
|
UnloadImage(image);
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue