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.
This commit is contained in:
NischayDiwan 2023-04-16 20:03:28 +05:30 committed by Eugene Sandulenko
parent d2ab6daea8
commit 4b83dd78d6
3 changed files with 78 additions and 80 deletions

View File

@ -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

View File

@ -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

View File

@ -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++;