shithub: cstory

Download patch

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);