shithub: cstory

Download patch

ref: 52c2a5ceee262e18b7e4ff7f3c117ab765c1efc8
parent: 11bbad7372539841811bffad257e425283ecc79d
author: Clownacy <Clownacy@users.noreply.github.com>
date: Tue Sep 15 16:48:18 EDT 2020

Make software renderer a bit more foolproof

This also eliminates some comparisons with mismatching signedness

--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -283,9 +283,56 @@
 
 void RenderBackend_DrawGlyph(long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height)
 {
-	for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph_height, glyph_destination_surface->height); ++iy)
+	size_t surface_x;
+	size_t surface_y;
+
+	// Clamp to within the destination surface's boundaries
+	if (x < 0)
 	{
-		for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph_width, glyph_destination_surface->width); ++ix)
+		surface_x = -x;
+
+		if (surface_x >= glyph_width)
+			return; // Glyph is offscreen to the left
+
+		glyph_x += surface_x;
+		glyph_width -= surface_x;
+	}
+	else
+	{
+		surface_x = x;
+	}
+
+	if (surface_x >= glyph_destination_surface->width)
+		return; // Glyph is offscreen to the right
+
+	if (glyph_width >= glyph_destination_surface->width - surface_x)
+		glyph_width = glyph_destination_surface->width - surface_x;
+
+	if (y < 0)
+	{
+		surface_y = -y;
+
+		if (surface_y >= glyph_height)
+			return; // Glyph is offscreen to the top
+
+		glyph_y += surface_y;
+		glyph_height -= surface_y;
+	}
+	else
+	{
+		surface_y = y;
+	}
+
+	if (surface_y >= glyph_destination_surface->height)
+		return; // Glyph is offscreen to the bottom
+
+	if (glyph_height >= glyph_destination_surface->height - surface_y)
+		glyph_height = glyph_destination_surface->height - surface_y;
+
+	// Do the actual drawing
+	for (size_t iy = 0; iy < glyph_height; ++iy)
+	{
+		for (size_t ix = 0; ix < glyph_width; ++ix)
 		{
 			const unsigned char alpha_int = glyph_atlas->pixels[(glyph_y + iy) * glyph_atlas->width + (glyph_x + ix)];
 
@@ -293,7 +340,7 @@
 			{
 				const float alpha = alpha_int / 255.0f;
 
-				unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
+				unsigned char *bitmap_pixel = &glyph_destination_surface->pixels[(surface_y + iy) * glyph_destination_surface->pitch + (surface_x + ix) * 3];
 
 				for (unsigned int j = 0; j < 3; ++j)
 					bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha)));	// Alpha blending