Font refactor part 5: Sigil (optimised software renderer)

This commit is contained in:
Clownacy 2019-07-23 21:46:57 +01:00
parent 8aad8a6628
commit d3129bc4bc

View file

@ -22,11 +22,9 @@ typedef struct Backend_Surface
typedef struct Backend_Glyph typedef struct Backend_Glyph
{ {
unsigned char *pixels; void *pixels;
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
int pitch;
unsigned short total_greys;
unsigned char pixel_mode; unsigned char pixel_mode;
} Backend_Glyph; } Backend_Glyph;
@ -267,7 +265,11 @@ Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width
if (glyph == NULL) if (glyph == NULL)
return NULL; return NULL;
glyph->pixels = (unsigned char*)malloc(pitch * height); switch (pixel_mode)
{
case FONT_PIXEL_MODE_LCD:
{
glyph->pixels = malloc(width * height * sizeof(double) * 3);
if (glyph->pixels == NULL) if (glyph->pixels == NULL)
{ {
@ -275,12 +277,73 @@ Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width
return NULL; return NULL;
} }
memcpy(glyph->pixels, pixels, pitch * height); double *destination_pointer = (double*)glyph->pixels;
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
for (unsigned int x = 0; x < width; ++x)
{
for (unsigned int i = 0; i < 3; ++i)
{
*destination_pointer++ = pow((*source_pointer++ / 255.0), 1.0 / 1.8); // Gamma correction
}
}
}
break;
}
case FONT_PIXEL_MODE_GRAY:
{
glyph->pixels = malloc(width * height * sizeof(double));
if (glyph->pixels == NULL)
{
free(glyph);
return NULL;
}
double *destination_pointer = (double*)glyph->pixels;
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = pow((double)*source_pointer++ / (total_greys - 1), 1.0 / 1.8); // Gamma correction
}
}
break;
}
case FONT_PIXEL_MODE_MONO:
{
glyph->pixels = malloc(width * height);
if (glyph->pixels == NULL)
{
free(glyph);
return NULL;
}
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->pixels + y * width;
memcpy(destination_pointer, source_pointer, width);
}
break;
}
}
glyph->width = width; glyph->width = width;
glyph->height = height; glyph->height = height;
glyph->pitch = pitch;
glyph->total_greys = total_greys;
glyph->pixel_mode = pixel_mode; glyph->pixel_mode = pixel_mode;
return glyph; return glyph;
@ -301,7 +364,7 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
{ {
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width / 3, surface->width); ++ix) for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width / 3, surface->width); ++ix)
{ {
const unsigned char *font_pixel = glyph->pixels + iy * glyph->pitch + ix * 3; const double *font_pixel = (double*)glyph->pixels + (iy * glyph->width + ix) * 3;
if (font_pixel[0] || font_pixel[1] || font_pixel[2]) if (font_pixel[0] || font_pixel[1] || font_pixel[2])
{ {
@ -309,7 +372,7 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
for (unsigned int j = 0; j < 3; ++j) for (unsigned int j = 0; j < 3; ++j)
{ {
const double alpha = pow((font_pixel[j] / 255.0), 1.0 / 1.8); // Gamma correction const double alpha = font_pixel[j];
bitmap_pixel[j] = (unsigned char)((colours[j] * alpha) + (bitmap_pixel[j] * (1.0 - alpha))); // Alpha blending bitmap_pixel[j] = (unsigned char)((colours[j] * alpha) + (bitmap_pixel[j] * (1.0 - alpha))); // Alpha blending
} }
} }
@ -323,12 +386,10 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
{ {
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix) for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix)
{ {
const unsigned char font_pixel = glyph->pixels[iy * glyph->pitch + ix]; const double alpha = ((double*)glyph->pixels)[iy * glyph->width + ix];
if (font_pixel) if (alpha)
{ {
const double alpha = pow((double)font_pixel / (glyph->total_greys - 1), 1.0 / 1.8); // Gamma-corrected
unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3; unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3;
for (unsigned int j = 0; j < 3; ++j) for (unsigned int j = 0; j < 3; ++j)
@ -344,7 +405,7 @@ void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, l
{ {
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix) for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, surface->width); ++ix)
{ {
if (glyph->pixels[iy * glyph->pitch + ix]) if (((unsigned char*)glyph->pixels)[iy * glyph->width + ix])
{ {
unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3; unsigned char *bitmap_pixel = surface->pixels + (y + iy) * surface->pitch + (x + ix) * 3;