[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