From 4b83dd78d6b59383169b48c87654fc69bc34c1d0 Mon Sep 17 00:00:00 2001 From: NischayDiwan Date: Sun, 16 Apr 2023 20:03:28 +0530 Subject: [PATCH] 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. --- graphics/font.cpp | 55 +++++++++++++++++++++++++ graphics/font.h | 21 ++++++++++ graphics/fonts/macfont.cpp | 82 +------------------------------------- 3 files changed, 78 insertions(+), 80 deletions(-) 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 &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const; /** @overload */ int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array &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++;