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

sev- noreply at scummvm.org
Sun Apr 16 19:13:54 UTC 2023


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

Summary:
4b83dd78d6  GRAPHICS: Refactor MacFont scaling into reusable methods
aaa32cf118  GRAPHICS: Fix scaling for BDF fonts


Commit: 4b83dd78d6b59383169b48c87654fc69bc34c1d0
    https://github.com/scummvm/scummvm/commit/4b83dd78d6b59383169b48c87654fc69bc34c1d0
Author: NischayDiwan (cs5200433 at iitd.ac.in)
Date: 2023-04-16T21:13:50+02:00

Commit Message:
 GRAPHICS: Refactor MacFont scaling into reusable methods

 - The refactoring code for MacFont that magnifies the font on a surface and then uses a grayscalemap to refactor the scaling, is pushed back into a resuable method in the base font class.
 - surface magnigy funtion transfer and scaleSingleGlyph method add to the font class.

Changed paths:
    graphics/font.cpp
    graphics/font.h
    graphics/fonts/macfont.cpp


diff --git a/graphics/font.cpp b/graphics/font.cpp
index fbb1bffd660..96f018c8351 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -508,4 +508,59 @@ TextAlign convertTextAlignH(TextAlign alignH, bool rtl) {
 	}
 }
 
+#define wholedivide(x, y)	(((x)+((y)-1))/(y))
+
+static void countupScore(int *dstGray, int x, int y, int bbw, int bbh, float scale) {
+	int newbbw = bbw * scale;
+	int newbbh = bbh * scale;
+	int x_ = x * newbbw;
+	int y_ = y * newbbh;
+	int x1 = x_ + newbbw;
+	int y1 = y_ + newbbh;
+
+	int newxbegin = x_ / bbw;
+	int newybegin = y_ / bbh;
+	int newxend = wholedivide(x1, bbw);
+	int newyend = wholedivide(y1, bbh);
+
+	for (int newy = newybegin; newy < newyend; newy++) {
+		for (int newx = newxbegin; newx < newxend; newx++) {
+			int newX = newx * bbw;
+			int newY = newy * bbh;
+			int newX1 = newX + bbw;
+			int newY1 = newY + bbh;
+			dstGray[newy * newbbw + newx] += (MIN(x1, newX1) - MAX(x_, newX)) *
+											 (MIN(y1, newY1) - MAX(y_, newY));
+		}
+	}
+}
+
+static void magnifyGray(Surface *src, int *dstGray, int width, int height, float scale) {
+	for (uint16 y = 0; y < height; y++) {
+		for (uint16 x = 0; x < width; x++) {
+			if (*((byte *)src->getBasePtr(x, y)) == 1)
+				countupScore(dstGray, x, y, width, height, scale);
+		}
+	}
+}
+
+void Font::scaleSingleGlyph(Surface *scaleSurface, int *grayScaleMap, int grayScaleMapSize, int width, int height, int xOffset, int yOffset, int grayLevel, int chr, int srcheight, int srcwidth, float scale) const {
+
+	scaleSurface->fillRect(Common::Rect(scaleSurface->w, scaleSurface->h), 0);
+	drawChar(scaleSurface, chr, xOffset, yOffset, 1);
+	memset(grayScaleMap, 0, grayScaleMapSize * sizeof(int));
+	magnifyGray(scaleSurface, grayScaleMap, srcwidth, srcheight, scale);
+	int *grayPtr = grayScaleMap;
+	for (int y = 0; y < height; y++) {
+		byte *dst = (byte *)scaleSurface->getBasePtr(0, y);
+		for (int x = 0; x < width; x++, grayPtr++, dst++) {
+			if (*grayPtr > grayLevel)
+				*dst = 1;
+			else
+				*dst = 0;
+		}
+	}
+
+}
+
 } // End of namespace Graphics
diff --git a/graphics/font.h b/graphics/font.h
index 1b51fd8fc49..87f1ca8cc48 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -269,6 +269,27 @@ public:
 	int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
 	/** @overload */
 	int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
+
+	/**
+	 * Scales the single gylph at @p chr the given the @p scale and the pointer @p grayScaleMap to the grayscale array. It fills @p scaleSurface surface 
+	 * and then we draw the character on @p scaleSurface surface. The @p scaleSUrface is magnified to grayScale array and then we change the @p scaleSurface using the 
+	 * grayScale array and @p grayLevel.
+	 *
+	 * @param grayScaleMap   The pointer to the grayScale array.
+	 * @param grayScaleMapSize  The size of the grayScale array.
+	 * @param scaleSurface  The surface to where character is scaled and drawn.
+	 * @param width     The width of the bouding box for scaled glyph.
+	 * @param height    The height of the bounding box for scaled glyph.
+	 * @param grayLevel The graylevel is the threshold value above which the pixel is considered
+	 * @param chr       The character to scale.
+	 * @param xOffset   The x offset of the bounding box for scaled glyph.
+	 * @param yOffset   The y offset of the bounding box for scaled glyph.
+	 * @param srcheight The height of the source glyph.
+	 * @param srcwidth  The width of the source glyph bounding box.
+	 * @param scale     The scale factor that is equal to @p newSize / @p srcSize of initializeScaling.
+	 */
+	void scaleSingleGlyph(Surface *scaleSurface, int *grayScaleMap, int grayScaleMapSize, int width, int height, int xOffset, int yOffset, int grayLevel, int chr, int srcheight, int srcwidth, float scale) const;
+
 };
 /** @} */
 } // End of namespace Graphics
diff --git a/graphics/fonts/macfont.cpp b/graphics/fonts/macfont.cpp
index 61b930279bf..483873f7931 100644
--- a/graphics/fonts/macfont.cpp
+++ b/graphics/fonts/macfont.cpp
@@ -481,11 +481,6 @@ int MacFONTFont::getKerningOffset(uint32 left, uint32 right) const {
 	return 0;
 }
 
-#if DEBUGSCALING
-bool dododo;
-#endif
-
-static void magnifyGray(Surface *src, int *dstGray, int width, int height, float scale);
 static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height);
 static void makeOutline(Surface *src, Surface *dst, MacGlyph *glyph, int height);
 static void makeItalic(Surface *src, Surface *dst, MacGlyph *glyph, int height);
@@ -588,39 +583,11 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize, int sla
 
 #if DEBUGSCALING
 		int ccc = 'c';
-		dododo = i == ccc;
 #endif
 
-		srcSurf.fillRect(Common::Rect(srcSurf.w, srcSurf.h), 0);
-		src->drawChar(&srcSurf, i + src->_data._firstChar, 0, 0, 1);
-		memset(dstGray, 0, dstGraySize * sizeof(int));
-		magnifyGray(&srcSurf, dstGray, srcglyph->width, src->_data._fRectHeight, scale);
-
 		MacGlyph *glyph = (i == src->_data._glyphs.size()) ? &data._defaultChar : &data._glyphs[i];
-		int *grayPtr = dstGray;
-
-		for (int y = 0; y < data._fRectHeight; y++) {
-			byte *dst = (byte *)srcSurf.getBasePtr(0, y);
-
-			for (int x = 0; x < glyph->bitmapWidth; x++, grayPtr++, dst++) {
-#if DEBUGSCALING
-				if (i == ccc) {
-					if (*grayPtr)
-						debugN(1, "%3d ", *grayPtr);
-					else
-						debugN(1, "    ");
-				}
-#endif
-				if (*grayPtr > grayLevel)
-					*dst = 1;
-				else
-					*dst = 0;
-			}
-#if DEBUGSCALING
-			if (i == ccc)
-				debug(1, "");
-#endif
-		}
+		src->scaleSingleGlyph(&srcSurf, dstGray, dstGraySize, glyph->bitmapWidth, data._fRectHeight, 0, 0, grayLevel, i + src->_data._firstChar,
+							src->_data._fRectHeight, srcglyph->width, scale);
 
 		if (slant & kMacFontBold) {
 			memset(dstGray, 0, dstGraySize * sizeof(int));
@@ -737,51 +704,6 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize, int sla
 	return new MacFONTFont(data);
 }
 
-#define wholedivide(x, y)	(((x)+((y)-1))/(y))
-
-static void countupScore(int *dstGray, int x, int y, int bbw, int bbh, float scale) {
-	int newbbw = bbw * scale;
-	int newbbh = bbh * scale;
-	int x_ = x * newbbw;
-	int y_ = y * newbbh;
-	int x1 = x_ + newbbw;
-	int y1 = y_ + newbbh;
-
-	int newxbegin = x_ / bbw;
-	int newybegin = y_ / bbh;
-	int newxend = wholedivide(x1, bbw);
-	int newyend = wholedivide(y1, bbh);
-
-	for (int newy = newybegin; newy < newyend; newy++) {
-		for (int newx = newxbegin; newx < newxend; newx++) {
-			int newX = newx * bbw;
-			int newY = newy * bbh;
-			int newX1 = newX + bbw;
-			int newY1 = newY + bbh;
-			dstGray[newy * newbbw + newx] += (MIN(x1, newX1) - MAX(x_, newX)) *
-											 (MIN(y1, newY1) - MAX(y_, newY));
-		}
-	}
-}
-
-static void magnifyGray(Surface *src, int *dstGray, int width, int height, float scale) {
-	for (uint16 y = 0; y < height; y++) {
-		for (uint16 x = 0; x < width; x++) {
-			if (*((byte *)src->getBasePtr(x, y)) == 1)
-				countupScore(dstGray, x, y, width, height, scale);
-#if DEBUGSCALING
-			if (dododo)
-				debugN("%c", *((byte *)src->getBasePtr(x, y)) == 1 ? '*' : ' ');
-#endif
-		}
-
-#if DEBUGSCALING
-		if (dododo)
-			debugN("\n");
-#endif
-	}
-}
-
 static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height) {
 	glyph->width++;
 	glyph->bitmapWidth++;


Commit: aaa32cf11828c972e901b8a3be5a216ec2fb2af7
    https://github.com/scummvm/scummvm/commit/aaa32cf11828c972e901b8a3be5a216ec2fb2af7
Author: NischayDiwan (cs5200433 at iitd.ac.in)
Date: 2023-04-16T21:13:50+02:00

Commit Message:
 GRAPHICS: Fix scaling for BDF fonts

 - The primary change is to fix or improve the scaling of BDF fonts
 - Now uses the same approach as in MacFonts scaling that is creating another surface and refactor it with a grayscalemap
 - Bugs - there are still some problems when testing in capital letters

Changed paths:
    graphics/fonts/bdf.cpp


diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index 9f257a6fb92..06c57c948c7 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -742,6 +742,11 @@ BdfFont *BdfFont::scaleFont(const BdfFont *src, int newSize) {
 		return nullptr;
 	}
 
+	Graphics::Surface srcSurf;
+	srcSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2, newSize * 2), PixelFormat::createFormatCLUT8());
+	int dstGraySize = newSize * 20 * newSize;
+	int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
+
 	float scale = (float)newSize / (float)src->getFontSize();
 
 	BdfFontData data;
@@ -753,7 +758,7 @@ BdfFont *BdfFont::scaleFont(const BdfFont *src, int newSize) {
 	data.defaultBox.height = (int)(roundf((float)src->_data.defaultBox.height * scale));
 	data.defaultBox.xOffset = (int)(roundf((float)src->_data.defaultBox.xOffset * scale));
 	data.defaultBox.yOffset = (int)(roundf((float)src->_data.defaultBox.yOffset * scale));
-	data.ascent = (int)roundf(((float)src->_data.ascent * scale));
+	data.ascent = (int)(roundf((float)src->_data.ascent * scale));
 	data.firstCharacter = src->_data.firstCharacter;
 	data.defaultCharacter = src->_data.defaultCharacter;
 	data.numCharacters = src->_data.numCharacters;
@@ -768,10 +773,10 @@ BdfFont *BdfFont::scaleFont(const BdfFont *src, int newSize) {
 
 	BdfBoundingBox *boxes = new BdfBoundingBox[data.numCharacters];
 	for (int i = 0; i < data.numCharacters; ++i) {
-		boxes[i].width = (int)(roundf((float)src->_data.boxes[i].width * scale));
-		boxes[i].height = (int)(roundf((float)src->_data.boxes[i].height * scale));
-		boxes[i].xOffset = (int)(roundf((float)src->_data.boxes[i].xOffset * scale));
-		boxes[i].yOffset = (int)(roundf((float)src->_data.boxes[i].yOffset * scale));
+		boxes[i].width = (int)(((float)src->_data.boxes[i].width * scale));
+		boxes[i].height = (int)(((float)src->_data.height * scale));
+		boxes[i].xOffset = (int)(((float)src->_data.boxes[i].xOffset * scale));
+		boxes[i].yOffset = (int)(((float)src->_data.boxes[i].yOffset * scale));
 	}
 	data.boxes = boxes;
 
@@ -782,62 +787,73 @@ BdfFont *BdfFont::scaleFont(const BdfFont *src, int newSize) {
 	data.advances = advances;
 
 	byte **bitmaps = new byte *[data.numCharacters];
-
 	for (int i = 0; i < data.numCharacters; i++) {
 		const BdfBoundingBox &box = data.boxes ? data.boxes[i] : data.defaultBox;
 		const BdfBoundingBox &srcBox = data.boxes ? src->_data.boxes[i] : src->_data.defaultBox;
 
+#if DRAWDEBUG
+		int ccc = 'd';
+#endif
 		if (src->_data.bitmaps[i]) {
-			const int bytes = ((box.width + 7) / 8) * box.height; // Dimensions have been already corrected
+			int grayLevel = box.height * box.width / 3;
+			int dstPitch = (box.width + 7) / 8 ;
+			const int bytes = dstPitch * box.height;
 			bitmaps[i] = new byte[bytes];
 
-			int srcPitch = (srcBox.width + 7) / 8;
-			int dstPitch = (box.width + 7) / 8;
+			src->scaleSingleGlyph(&srcSurf, dstGray, dstGraySize, box.width, box.height, box.xOffset, box.yOffset, grayLevel, i + src->_data.firstCharacter,
+								src->_data.height, srcBox.width, scale);
 
 			byte *ptr = bitmaps[i];
-
 			for (int y = 0; y < box.height; y++) {
-				const byte *srcd = (const byte *)&src->_data.bitmaps[i][((int)((float)y / scale)) * srcPitch];
+				byte *srcd = (byte *)srcSurf.getBasePtr(0, y);
 				byte *dst = ptr;
 				byte b = 0;
-
-				for (int x = 0; x < box.width; x++) {
+				for (int x = 0; x < box.width; x++, srcd++) {
 					b <<= 1;
-
-					int sx = (int)(roundf((float)x / scale));
-
-					if (srcd[sx / 8] & (0x80 >> (sx % 8))) {
+					if (*srcd == 1) {
 						b |= 1;
-#if DRAWDEBUG
-						debugN("#");
-					} else {
-						debugN(" ");
-#endif
 					}
-
 					if (x % 8 == 7) {
 						*dst++ = b;
 						b = 0;
 					}
 				}
-#if DRAWDEBUG
-				debug("");
-#endif
-
 				if (((box.width - 1) % 8)) {
 					b <<= 7 - ((box.width - 1) % 8);
 					*dst = b;
 				}
-
 				ptr += dstPitch;
+#if DRAWDEBUG
+				if (i == ccc) {
+					int *grayPtr = dstGray;
+					debugN("--> %d ", grayLevel);
+					grayPtr = &dstGray[y * box.width];
+					for (int x = 0; x < ; box.widthx++, grayPtr++)
+						debugN("%c", *grayPtr > grayLevel ? '@' : '_');
+					debugN("\n");
+					debugN("***");
+				}
+#endif
 			}
-
+#if DRAWDEBUG
+			if (i == ccc) {
+				for (int y = 0; y < box.height; y++) {
+					const byte *srcRow = (const byte *)&bitmaps[i][y * dstPitch];
+					for (int x = 0; x < box.width; x++) {
+						int sx = x;
+						debugN("%c", (srcRow[sx / 8] & (0x80 >> (sx % 8))) ? '#' : '_');
+					}
+					debugN("\n");
+				}
+			}
+#endif
 		} else {
 			bitmaps[i] = 0;
 		}
 	}
-
 	data.bitmaps = bitmaps;
+	free(dstGray);
+	srcSurf.free();
 
 	return new BdfFont(data, DisposeAfterUse::YES);
 }




More information about the Scummvm-git-logs mailing list