aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2018-06-20 00:52:14 +0200
committerRay <raysan5@gmail.com>2018-06-20 00:52:14 +0200
commit75ba5aca551d2b16fa75ba31e616b009ac5dde6a (patch)
tree9e2b3d03856958d81ba07161d5c0d0a7e869000f /src
parent372e4a1139f8ac4b5e1220771447f1220104b112 (diff)
downloadraylib-75ba5aca551d2b16fa75ba31e616b009ac5dde6a.tar.gz
raylib-75ba5aca551d2b16fa75ba31e616b009ac5dde6a.zip
Improved font generation and SDF
Added: data to CharInfo struct Added: LoadFontData() Added: GenImageFontAtlas() Removed: LoadFontEx() Removed: LoadTTF() [internal] Some code tweaks
Diffstat (limited to 'src')
-rw-r--r--src/raylib.h27
-rw-r--r--src/text.c356
-rw-r--r--src/textures.c4
3 files changed, 229 insertions, 158 deletions
diff --git a/src/raylib.h b/src/raylib.h
index e0cfaa6d..49434d52 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -389,6 +389,7 @@ typedef struct CharInfo {
int offsetX; // Character offset X when drawing
int offsetY; // Character offset Y when drawing
int advanceX; // Character advance position X
+ unsigned char *data; // Character pixel data (grayscale)
} CharInfo;
// Font type, includes texture and charSet array data
@@ -955,29 +956,29 @@ RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint);
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
RLAPI void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
-
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
//------------------------------------------------------------------------------------
// Font loading/unloading functions
-RLAPI Font GetDefaultFont(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 void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
+RLAPI Font GetDefaultFont(void); // Get the default Font
+RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
+RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf); // Load font data for further use
+RLAPI Image GenImageFontAtlas(CharInfo *chars, int fontSize, int charsCount, int packing); // Generate image font atlas using chars info
+RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
// Text drawing functions
-RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
-RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-RLAPI void DrawTextEx(Font font, const char* text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using Font and additional parameters
+RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
+RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
+RLAPI void DrawTextEx(Font font, const char* text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters
// Text misc. functions
-RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
-RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
-RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
-RLAPI int GetGlyphIndex(Font font, int character); // Returns index position for a unicode character on sprite font
+RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
+RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
+RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
+RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+RLAPI int GetGlyphIndex(Font font, int character); // Get index position for a unicode character on sprite font
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
diff --git a/src/text.c b/src/text.c
index 9755ff8b..3c3ff751 100644
--- a/src/text.c
+++ b/src/text.c
@@ -47,16 +47,14 @@
#include "utils.h" // Required for: fopen() Android mapping
#if defined(SUPPORT_FILEFORMAT_TTF)
- // Following libs are used on LoadTTF()
- #define STBTT_STATIC // Define stb_truetype functions static to this module
+ #define STB_RECT_PACK_IMPLEMENTATION
+ #include "external/stb_rect_pack.h" // Required for: ttf font rectangles packaging
+
+ #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION
- #include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
+ #include "external/stb_truetype.h" // Required for: ttf font data reading
#endif
-// Rectangle packing functions (not used at the moment)
-//#define STB_RECT_PACK_IMPLEMENTATION
-//#include "stb_rect_pack.h"
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -89,7 +87,7 @@ static Font LoadImageFont(Image image, Color key, int firstChar); // Load a Imag
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
#endif
#if defined(SUPPORT_FILEFORMAT_TTF)
-static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
+//static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
#endif
#if defined(SUPPORT_DEFAULT_FONT)
@@ -276,68 +274,244 @@ Font LoadFont(const char *fileName)
// Default hardcoded values for ttf file loading
#define DEFAULT_TTF_FONTSIZE 32 // Font first character (32 - space)
#define DEFAULT_TTF_NUMCHARS 95 // ASCII 32..126 is 95 glyphs
- #define DEFAULT_FIRST_CHAR 32 // Expected first char for image spritefont
+ #define DEFAULT_FIRST_CHAR 32 // Expected first char for image sprite font
- Font spriteFont = { 0 };
+ Font font = { 0 };
#if defined(SUPPORT_FILEFORMAT_TTF)
- if (IsFileExtension(fileName, ".ttf")) spriteFont = LoadFontEx(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
+ if (IsFileExtension(fileName, ".ttf"))
+ {
+ font.baseSize = DEFAULT_TTF_FONTSIZE;
+ font.charsCount = DEFAULT_TTF_NUMCHARS;
+ font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, false);
+ Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 0);
+ font.texture = LoadTextureFromImage(atlas);
+ UnloadImage(atlas);
+ }
else
#endif
#if defined(SUPPORT_FILEFORMAT_FNT)
- if (IsFileExtension(fileName, ".fnt")) spriteFont = LoadBMFont(fileName);
+ if (IsFileExtension(fileName, ".fnt")) font = LoadBMFont(fileName);
else
#endif
{
Image image = LoadImage(fileName);
- if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, DEFAULT_FIRST_CHAR);
+ if (image.data != NULL) font = LoadImageFont(image, MAGENTA, DEFAULT_FIRST_CHAR);
UnloadImage(image);
}
- if (spriteFont.texture.id == 0)
+ if (font.texture.id == 0)
{
TraceLog(LOG_WARNING, "[%s] Font could not be loaded, using default font", fileName);
- spriteFont = GetDefaultFont();
+ font = GetDefaultFont();
}
- else SetTextureFilter(spriteFont.texture, FILTER_POINT); // By default we set point filter (best performance)
+ else SetTextureFilter(font.texture, FILTER_POINT); // By default we set point filter (best performance)
- return spriteFont;
+ return font;
}
-// Load Font from TTF font file with generation parameters
-// NOTE: You can pass an array with desired characters, those characters should be available in the font
-// if array is NULL, default char set is selected 32..126
-Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars)
+// 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, bool sdf)
{
- Font spriteFont = { 0 };
- int totalChars = 95; // Default charset [32..126]
- bool fontCharsLoaded = false;
+ // NOTE: Using some SDF generation default values,
+ // trades off precision with ability to handle *smaller* sizes
+ #define SDF_CHAR_PADDING 4
+ #define SDF_ON_EDGE_VALUE 128
+ #define SDF_PIXEL_DIST_SCALE 64.0f
+
+ CharInfo *chars = (CharInfo *)malloc(charsCount*sizeof(CharInfo));
+
+ // Load font data (including pixel data) from TTF file
+ // NOTE: Loaded information should be enough to generate font image atlas,
+ // using any packaging method
+ FILE *fontFile = fopen(fileName, "rb"); // Load font file
+
+ fseek(fontFile, 0, SEEK_END);
+ long size = ftell(fontFile); // Get file size
+ fseek(fontFile, 0, SEEK_SET); // Reset file pointer
+
+ unsigned char *fontBuffer = (unsigned char *)malloc(size);
+
+ fread(fontBuffer, size, 1, fontFile);
+ fclose(fontFile);
+
+ // Init font for data reading
+ stbtt_fontinfo fontInfo;
+ if (!stbtt_InitFont(&fontInfo, fontBuffer, 0)) TraceLog(LOG_WARNING, "Failed to init font!");
-#if defined(SUPPORT_FILEFORMAT_TTF)
- if (IsFileExtension(fileName, ".ttf"))
+ // Calculate font scale factor
+ float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, fontSize);
+
+ // Calculate font basic metrics
+ // NOTE: ascent is equivalent to font baseline
+ int ascent, descent, lineGap;
+ stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
+ ascent *= scaleFactor;
+ descent *= scaleFactor;
+
+ // Fill fontChars in case not provided externally
+ // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
+ int genFontChars = false;
+ if (fontChars == NULL) genFontChars = true;
+ if (genFontChars)
+ {
+ fontChars = (int *)malloc(charsCount*sizeof(int));
+ for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
+ }
+
+ // NOTE: Using simple packaging, one char after another
+ for (int i = 0; i < charsCount; i++)
+ {
+ int chw = 0, chh = 0; // Character width and height (on generation)
+ int ch = fontChars[i]; // Character value to get info for
+ chars[i].value = ch;
+
+ // Render a unicode codepoint to a bitmap
+ // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
+ // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
+ // 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);
+ 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);
+
+ chars[i].rec.width = (float)chw;
+ chars[i].rec.height = (float)chh;
+ chars[i].offsetY += ascent;
+
+ // Get bounding box for character (may be offset to account for chars that dip above or below the line)
+ int chX1, chY1, chX2, chY2;
+ stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
+
+ TraceLog(LOG_DEBUG, "Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
+ TraceLog(LOG_DEBUG, "Character offsetY: %i", ascent + chY1);
+
+ stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
+ chars[i].advanceX *= scaleFactor;
+ }
+
+ free(fontBuffer);
+ if (genFontChars) free(fontChars);
+
+ return chars;
+}
+
+// Generate image font atlas using chars info
+// NOTE: Packing method: 0-Default, 1-Skyline
+Image GenImageFontAtlas(CharInfo *chars, int charsCount, int fontSize, int packing)
+{
+ Image atlas = { 0 };
+
+ int padding = 10;
+
+ // Calculate atlas texture size based on fontSize
+ // NOTE: Font texture size is predicted (being as much conservative as possible)
+ // Predictive method consist of supposing same number of chars by line-column (sqrtf)
+ // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests...
+ //float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)charsCount));
+ //int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
+
+ // TODO: TEXTURE SIZE NOT GOOD ENOUGH! -> Calculate chars area -> guess texture size?
+ float requiredArea = 0;
+ for (int i = 0; i < charsCount; i++) requiredArea += ((chars[i].rec.width + 2*padding)*(chars[i].rec.height + 2*padding));
+ float guessSize = sqrtf(requiredArea)*1.25f;
+ int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
+
+ atlas.width = textureSize; // Atlas bitmap width
+ atlas.height = textureSize; // Atlas bitmap height
+ atlas.data = (unsigned char *)calloc(1, atlas.width*atlas.height); // Create a bitmap to store characters (8 bpp)
+ atlas.format = UNCOMPRESSED_GRAYSCALE;
+ atlas.mipmaps = 1;
+
+ if (packing == 0) // Use basic packing algorythm
{
- if (charsCount != 0) totalChars = charsCount;
+ int offsetX = padding;
+ int offsetY = padding;
- if (fontChars == NULL)
+ // NOTE: Using simple packaging, one char after another
+ for (int i = 0; i < charsCount; i++)
{
- fontChars = (int *)malloc(totalChars*sizeof(int));
- for (int i = 0; i < totalChars; i++) fontChars[i] = i + 32; // Default first character: SPACE[32]
- fontCharsLoaded = true;
+ // Copy pixel data from fc.data to atlas
+ for (int y = 0; y < (int)chars[i].rec.height; y++)
+ {
+ for (int x = 0; x < (int)chars[i].rec.width; x++)
+ {
+ ((unsigned char *)atlas.data)[(offsetY + y)*atlas.width + (offsetX + x)] = chars[i].data[y*(int)chars[i].rec.width + x];
+ }
+ }
+
+ chars[i].rec.x = offsetX;
+ chars[i].rec.y = offsetY;
+
+ // Move atlas position X for next character drawing
+ offsetX += ((int)chars[i].advanceX + 2*padding);
+
+ if (offsetX >= (atlas.width - (int)chars[i].rec.width - padding))
+ {
+ offsetX = padding;
+ offsetY += (fontSize + 2*padding);
+
+ if (offsetY > (atlas.height - fontSize - padding)) break;
+ }
}
+ }
+ else if (packing == 1) // Use Skyline rect packing algorythm
+ {
+ stbrp_context *context = (stbrp_context *)malloc(sizeof(*context));
+ stbrp_node *nodes = (stbrp_node *)malloc(charsCount*sizeof(*nodes));
+
+ stbrp_init_target(context, atlas.width, atlas.height, nodes, charsCount);
+ stbrp_rect *rects = (stbrp_rect *)malloc(charsCount*sizeof(stbrp_rect));
- spriteFont = LoadTTF(fileName, fontSize, totalChars, fontChars);
+ // Fill rectangles for packaging
+ for (int i = 0; i < charsCount; i++)
+ {
+ rects[i].id = i;
+ rects[i].w = (int)chars[i].rec.width + 2*padding;
+ rects[i].h = (int)chars[i].rec.height + 2*padding;
+ }
+
+ // Package rectangles into atlas
+ stbrp_pack_rects(context, rects, charsCount);
- if (fontCharsLoaded) free(fontChars);
+ for (int i = 0; i < charsCount; i++)
+ {
+ chars[i].rec.x = rects[i].x + padding;
+ chars[i].rec.y = rects[i].y + padding;
+
+ if (rects[i].was_packed)
+ {
+ // Copy pixel data from fc.data to atlas
+ for (int y = 0; y < (int)chars[i].rec.height; y++)
+ {
+ for (int x = 0; x < (int)chars[i].rec.width; x++)
+ {
+ ((unsigned char *)atlas.data)[(rects[i].y + padding + y)*atlas.width + (rects[i].x + padding + x)] = chars[i].data[y*(int)chars[i].rec.width + x];
+ }
+ }
+ }
+ else TraceLog(LOG_WARNING, "Character could not be packed: %i", i);
+ }
+
+ free(nodes);
+ free(context);
}
-#endif
+
+ // Convert image data from GRAYSCALE to GRAY_ALPHA
+ //ImageAlphaMask(&atlas, atlas); // WARNING: Not working in this case, requires manual operation
+ unsigned char *dataGrayAlpha = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)*2); // Two channels
- if (spriteFont.texture.id == 0)
+ for (int i = 0, k = 0; i < atlas.width*atlas.height; i++, k += 2)
{
- TraceLog(LOG_WARNING, "[%s] Font could not be generated, using default font", fileName);
- spriteFont = GetDefaultFont();
+ dataGrayAlpha[k] = 255;
+ dataGrayAlpha[k + 1] = ((unsigned char *)atlas.data)[i];
}
- return spriteFont;
+ free(atlas.data);
+ atlas.data = dataGrayAlpha;
+ atlas.format = UNCOMPRESSED_GRAY_ALPHA;
+
+ return atlas;
}
// Unload Font from GPU memory (VRAM)
@@ -811,108 +985,4 @@ static Font LoadBMFont(const char *fileName)
return font;
}
-#endif
-
-#if defined(SUPPORT_FILEFORMAT_TTF)
-// Generate a sprite font from TTF file data (font size required)
-// TODO: Review texture packing method and generation (use oversampling)
-static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars)
-{
- #define MAX_TTF_SIZE 16 // Maximum ttf file size in MB
-
- // NOTE: Font texture size is predicted (being as much conservative as possible)
- // Predictive method consist of supposing same number of chars by line-column (sqrtf)
- // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests...
-
- // Calculate next power-of-two value
- float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)charsCount));
- int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
-
- TraceLog(LOG_INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize);
-
- unsigned char *ttfBuffer = (unsigned char *)malloc(MAX_TTF_SIZE*1024*1024);
- unsigned char *dataBitmap = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)); // One channel bitmap returned!
- stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*charsCount);
-
- Font font = { 0 };
-
- FILE *ttfFile = fopen(fileName, "rb");
-
- if (ttfFile == NULL)
- {
- TraceLog(LOG_WARNING, "[%s] TTF file could not be opened", fileName);
- return font;
- }
-
- // NOTE: We try reading up to 16 MB of elements of 1 byte
- fread(ttfBuffer, 1, MAX_TTF_SIZE*1024*1024, ttfFile);
-
- // Find font baseline (vertical origin of the font)
- // NOTE: This value is required because y-offset depends on it!
- stbtt_fontinfo fontInfo;
- int ascent, baseline;
- float scale;
-
- stbtt_InitFont(&fontInfo, ttfBuffer, 0);
- scale = stbtt_ScaleForPixelHeight(&fontInfo, fontSize);
- stbtt_GetFontVMetrics(&fontInfo, &ascent, 0, 0);
- baseline = (int)(ascent*scale);
-
- if (fontChars[0] != 32) TraceLog(LOG_WARNING, "TTF spritefont loading: first character is not SPACE(32) character");
-
- // NOTE: Using stb_truetype crappy packing method, no guarantee the font fits the image...
- // TODO: Replace this function by a proper packing method and support random chars order,
- // we already receive a list (fontChars) with the ordered expected characters
- int result = stbtt_BakeFontBitmap(ttfBuffer, 0, fontSize, dataBitmap, textureSize, textureSize, fontChars[0], charsCount, charData);
-
- //if (result > 0) TraceLog(LOG_INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result);
- if (result < 0) TraceLog(LOG_WARNING, "TTF spritefont loading: Not all the characters fit in the font");
-
- free(ttfBuffer);
-
- // Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
- unsigned char *dataGrayAlpha = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)*2); // Two channels
-
- for (int i = 0, k = 0; i < textureSize*textureSize; i++, k += 2)
- {
- dataGrayAlpha[k] = 0xff;
- dataGrayAlpha[k + 1] = dataBitmap[i];
- }
-
- free(dataBitmap);
-
- // Sprite font generation from TTF extracted data
- Image image;
- image.width = textureSize;
- image.height = textureSize;
- image.mipmaps = 1;
- image.format = UNCOMPRESSED_GRAY_ALPHA;
- image.data = dataGrayAlpha;
- font.texture = LoadTextureFromImage(image); // Load image into texture
- UnloadImage(image); // Unloads image data (dataGrayAlpha)
-
-
- // Fill font characters info data
- font.baseSize = fontSize;
- font.charsCount = charsCount;
- font.chars = (CharInfo *)malloc(font.charsCount*sizeof(CharInfo));
-
- for (int i = 0; i < font.charsCount; i++)
- {
- font.chars[i].value = fontChars[i];
-
- font.chars[i].rec.x = (int)charData[i].x0;
- font.chars[i].rec.y = (int)charData[i].y0;
- font.chars[i].rec.width = (int)charData[i].x1 - (int)charData[i].x0;
- font.chars[i].rec.height = (int)charData[i].y1 - (int)charData[i].y0;
-
- font.chars[i].offsetX = charData[i].xoff;
- font.chars[i].offsetY = baseline + charData[i].yoff;
- font.chars[i].advanceX = (int)charData[i].xadvance;
- }
-
- free(charData);
-
- return font;
-}
-#endif
+#endif \ No newline at end of file
diff --git a/src/textures.c b/src/textures.c
index eeaf7ffd..29316a7a 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -828,9 +828,9 @@ void ImageFormat(Image *image, int newFormat)
} break;
case UNCOMPRESSED_GRAY_ALPHA:
{
- image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
+ image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
- for (int i = 0; i < image->width*image->height*2; i += 2, k++)
+ for (int i = 0; i < image->width*image->height*2; i += 2, k++)
{
((unsigned char *)image->data)[i] = (unsigned char)((pixels[k].x*0.299f + (float)pixels[k].y*0.587f + (float)pixels[k].z*0.114f)*255.0f);
((unsigned char *)image->data)[i + 1] = (unsigned char)(pixels[k].w*255.0f);