ref: 6a7fd148339a91c66a265f4dc374350c31a38eaf
parent: 6d385e674fac76cb443d84210269f588d2ea1155
author: Clownacy <Clownacy@users.noreply.github.com>
date: Tue Jul 23 13:20:56 EDT 2019
Font refactor part 2: SDL_Surface No per-component alpha support here
--- a/src/Backends/Rendering.h
+++ b/src/Backends/Rendering.h
@@ -26,6 +26,7 @@
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);
--- a/src/Backends/Rendering/SDLSurface.cpp
+++ b/src/Backends/Rendering/SDLSurface.cpp
@@ -14,6 +14,11 @@
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 @@
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)
--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -255,6 +255,11 @@
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));
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -1788,7 +1788,7 @@
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);