Font refactor part 2: SDL_Surface

No per-component alpha support here
This commit is contained in:
Clownacy 2019-07-23 17:20:56 +01:00
parent 6d385e674f
commit 6a7fd14833
4 changed files with 92 additions and 5 deletions

View file

@ -26,6 +26,7 @@ void Backend_BlitToScreen(Backend_Surface *source_surface, const RECT *rect, lon
void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue);
void Backend_ColourFillToScreen(const RECT *rect, unsigned char red, unsigned char green, unsigned char blue);
void Backend_ScreenToSurface(Backend_Surface *surface, const RECT *rect);
BOOL Backend_SupportsSubpixelGlyph(void);
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, unsigned short total_greys, unsigned char pixel_mode);
void Backend_UnloadGlyph(Backend_Glyph *glyph);
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours);

View file

@ -14,6 +14,11 @@ typedef struct Backend_Surface
SDL_Surface *sdl_surface;
} Backend_Surface;
typedef struct Backend_Glyph
{
SDL_Surface *sdl_surface;
} Backend_Glyph;
static SDL_Window *window;
static SDL_Surface *window_surface;
@ -132,14 +137,90 @@ void Backend_ScreenToSurface(Backend_Surface *surface, const RECT *rect)
Backend_Blit(&framebuffer, rect, surface, rect->left, rect->top, FALSE);
}
void Backend_DrawText(Backend_Surface *surface, FontObject *font, int x, int y, const char *text, unsigned long colour)
BOOL Backend_SupportsSubpixelGlyph(void)
{
DrawText(font, (unsigned char*)surface->sdl_surface->pixels, surface->sdl_surface->pitch, surface->sdl_surface->w, surface->sdl_surface->h, x, y, colour, text, strlen(text));
return FALSE; // SDL_Surfaces don't have per-component alpha
}
void Backend_DrawTextToScreen(FontObject *font, int x, int y, const char *text, unsigned long colour)
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, unsigned short total_greys, unsigned char pixel_mode)
{
Backend_DrawText(&framebuffer, font, x, y, text, colour);
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));
if (glyph == NULL)
return NULL;
glyph->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_RGBA32);
if (glyph->sdl_surface == NULL)
{
free(glyph);
return NULL;
}
switch (pixel_mode)
{
// FONT_PIXEL_MODE_LCD is unsupported
case FONT_PIXEL_MODE_GRAY:
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->sdl_surface->pixels + y * glyph->sdl_surface->pitch;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = (unsigned char)(pow((double)*source_pointer++ / (total_greys - 1), 1.0 / 1.8) * 255.0);
}
}
break;
case FONT_PIXEL_MODE_MONO:
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->sdl_surface->pixels + y * glyph->sdl_surface->pitch;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = *source_pointer++ ? 0xFF : 0;
}
}
break;
}
return glyph;
}
void Backend_UnloadGlyph(Backend_Glyph *glyph)
{
SDL_FreeSurface(glyph->sdl_surface);
free(glyph);
}
void Backend_DrawGlyph(Backend_Surface *surface, Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = glyph->sdl_surface->w;
rect.h = glyph->sdl_surface->h;
SDL_SetSurfaceColorMod(glyph->sdl_surface, colours[0], colours[1], colours[2]);
SDL_BlitSurface(glyph->sdl_surface, NULL, surface->sdl_surface, &rect);
}
void Backend_DrawGlyphToScreen(Backend_Glyph *glyph, long x, long y, const unsigned char *colours)
{
Backend_DrawGlyph(&framebuffer, glyph, x, y, colours);
}
void Backend_HandleDeviceLoss(void)

View file

@ -255,6 +255,11 @@ void Backend_ScreenToSurface(Backend_Surface *surface, const RECT *rect)
Backend_Blit(&framebuffer, rect, surface, rect->left, rect->top, FALSE);
}
BOOL Backend_SupportsSubpixelGlyph(void)
{
return TRUE; // It's a software renderer, baby
}
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, unsigned short total_greys, unsigned char pixel_mode)
{
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));

View file

@ -1788,7 +1788,7 @@ FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsign
FT_Init_FreeType(&font_object->library);
#ifndef DISABLE_FONT_ANTIALIASING
font_object->lcd_mode = FT_Library_SetLcdFilter(font_object->library, FT_LCD_FILTER_DEFAULT) != FT_Err_Unimplemented_Feature;
font_object->lcd_mode = Backend_SupportsSubpixelGlyph() && FT_Library_SetLcdFilter(font_object->library, FT_LCD_FILTER_DEFAULT) != FT_Err_Unimplemented_Feature;
#endif
font_object->data = (unsigned char*)malloc(data_size);