[Scummvm-git-logs] scummvm master -> d69a76779c2a803aa92ac554158a650fc40b7d93

dreammaster noreply at scummvm.org
Thu Sep 25 10:37:44 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
d69a76779c BAGEL: MFC: Better CDC FloodFill implementation


Commit: d69a76779c2a803aa92ac554158a650fc40b7d93
    https://github.com/scummvm/scummvm/commit/d69a76779c2a803aa92ac554158a650fc40b7d93
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-09-25T03:36:08-07:00

Commit Message:
BAGEL: MFC: Better CDC FloodFill implementation

The previous version was very inefficient that it iterated
over single pixels at a time using a queue, resulting in a
very large queue size. This new version does entire line
segments, so the memory overhead is minimal.

Changed paths:
    engines/bagel/mfc/dc.cpp


diff --git a/engines/bagel/mfc/dc.cpp b/engines/bagel/mfc/dc.cpp
index abe2ec5f0c4..89455e10bee 100644
--- a/engines/bagel/mfc/dc.cpp
+++ b/engines/bagel/mfc/dc.cpp
@@ -893,40 +893,76 @@ void CDC::Impl::floodFill(int x, int y, COLORREF crColor) {
 		return;
 
 	uint color = GetNearestColor(crColor);
-	byte *pixel = (byte *)bitmap->getBasePtr(x, y);
-	const byte oldColor = *pixel;
-	int cx, cy;
-	int minX = 9999, maxX = -1, minY = 9999, maxY = -1;
+	byte *startPixel = (byte *)bitmap->getBasePtr(x, y);
+	const byte oldColor = *startPixel;
 
-	Common::Queue<Common::Pair<int, int>> queue;
+	if (color == oldColor)
+		return;
+
+	struct Point {
+		int x, y;
+	};
+
+	// Set up queue with initial point
+	Common::Queue<Point> queue;
 	queue.push({ x, y });
+	byte *pixelP;
+
+	int minX = x, maxX = x, minY = y, maxY = y;
 
 	while (!queue.empty()) {
-		cx = queue.front().first;
-		cy = queue.front().second;
+		Point startPt = queue.front();
 		queue.pop();
 
-		// Check bounds and color match
-		if (cx < 0 || cx >= bitmap->w || cy < 0 || cy >= bitmap->h)
-			continue;
-		pixel = (byte *)bitmap->getBasePtr(cx, cy);
-		if (*pixel != oldColor)
-			continue;
-
-		// Set new color
-		*pixel = color;
-
-		// Keep track of the modified area
-		minX = MIN(minX, cx);
-		maxX = MAX(maxX, cx);
-		minY = MIN(minY, cy);
-		maxY = MAX(maxY, cy);
-
-		// Push neighboring pixels
-		queue.push({ cx + 1, cy });
-		queue.push({ cx - 1, cy });
-		queue.push({ cx, cy + 1 });
-		queue.push({ cx, cy - 1 });
+		int curY = startPt.y;
+		int xStart = startPt.x;
+		int xEnd = startPt.x;
+
+		// Find the left edge, changing pixels as it goes 
+		pixelP = (byte *)bitmap->getBasePtr(xStart, curY);
+		*pixelP = color;
+		for (; xStart > 0 && *(pixelP - 1) == oldColor; --xStart, --pixelP)
+			*(pixelP - 1) = color;
+
+		// Find the right edge, changing pixels as it goes
+		pixelP = (byte *)bitmap->getBasePtr(xEnd, curY);
+		for (; xEnd < (bitmap->w - 1) && *(pixelP + 1) == oldColor; ++xEnd, ++pixelP)
+			*(pixelP + 1) = color;
+
+		// Track modified area
+		minX = MIN(minX, xStart);
+		maxX = MAX(maxX, xEnd);
+		minY = MIN(minY, curY);
+		maxY = MAX(maxY, curY);
+
+		// Scan for line segments above or below
+		for (int deltaY = -1; deltaY <= 1; deltaY += 2) {
+			int lineY = curY + deltaY;
+			if (lineY < 0 || lineY >= bitmap->h)
+				continue;
+
+			// Loop looking for line segments
+			pixelP = (byte *)bitmap->getBasePtr(xStart, lineY);
+			int curX = xStart;
+
+			while (curX <= xEnd) {
+				// Find the start of any line segment
+				if (*pixelP == oldColor) {
+					// Add new line starting point to queue
+					queue.push({ curX, lineY });
+
+					// Move beyond it
+					do {
+						++curX;
+						++pixelP;
+					} while (curX <= xEnd && *pixelP == oldColor);
+				} else {
+					// Move to next pixel, looking for new line segment
+					++curX;
+					++pixelP;
+				}
+			}
+		}
 	}
 
 	bitmap->addDirtyRect(Common::Rect(minX, minY, maxX + 1, maxY + 1));




More information about the Scummvm-git-logs mailing list