KEMBAR78
GUI: Change in the BDF fonts scaling code by NischayDiwan · Pull Request #4867 · scummvm/scummvm · GitHub
Skip to content

Conversation

@NischayDiwan
Copy link
Contributor

  • The primary change is to fix or improve the scaling of BDF fonts
  • Now uses the same approach as in MacFonts scaling
  • Bugs - there are still some problems when testing in capital letters
  • Note: the change in graphics.cpp for the testbed engine now calls the scale font function.

Copy link
Member

@sev- sev- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is not correct. You are generating dstGray but then do not use it at all.

}

#if DRAWDEBUG
bool dododo11;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this sitting in a common space and not in the method?

Also, if you want to keep it, please give it a meaningful name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have copied this as it is from the MacFont Code, it basically allows the debug to run in the Magnify gray function as well.
I will remove that.

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.maxAdvance = (int)(((float)src->_data.maxAdvance * scale));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you do not want to round but use the floor()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed that, will fix it.

if (src->_data.bitmaps[i]) {
const int bytes = ((box.width + 7) / 8) * box.height; // Dimensions have been already corrected
bitmaps[i] = new byte[bytes];
// int hs = srcBox.height;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out and not removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I will fix this.

}
#endif
if (*grayPtr > grayLevel)
*dst = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please refactor this magnification method, stick it into Common::Font (base method) and then reuse it in both MacFont and here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, what to change here please clarify

Copy link
Member

@sev- sev- Apr 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the magnification of a srcSurf via dstGray into a separate reusable method.

debugN("\n");
#endif
}
const int bytes = dstPitch*h;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not conform to our code formatting conventions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix that.

Copy link
Member

@sev- sev- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too many strange decisions. And still not following our code formatting guidelines


#if DRAWDEBUG
int ccc = 'a';
dododo11 = i == ccc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it still here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes fixed that

grayScaleMap = (int *)malloc(grayScaleMapSize * sizeof(int));
}

Surface *Font::scaleSingleGlyph(int width, int height, int grayLevel, int chr, int xOffset, int srcheight, int srcwidth, float scale){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad code formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is the function line, please check I have changed it

return scaleSurface;
}

void Font::deinitializeScaling(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad code formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes same fixed it

PixelFormat::createFormatCLUT8());
int dstGraySize = newSize * 20 * newSize;
int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
BdfFont* srcCopy = new BdfFont(src->_data, DisposeAfterUse::YES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nad code formatting. And WHY BdfFont????

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes removed that, check the new commit

srcCopy->initializeScaling(src->getFontSize(), newSize);

Graphics::Surface tmpSurf;
// srcSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2, newSize * 2),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this still commented out instead of being removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed that

// int dstGraySize = newSize * 20 * newSize;
// int *dstGray = (int *)malloc(dstGraySize * sizeof(int));

tmpSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2 + 2, newSize * 2 + 2),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this still here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed the comments, tmpSurf is not used in any of those 3 functions, but outside though so I have kept it as it is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please move its creation closer to the usage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I have fixed that but It has to be declare in the outside the for loop.

Copy link
Member

@sev- sev- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More changes are still needed.

graphics/font.h Outdated
class Font {
public:
Font() {}
Font() {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intent of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the semicolon earlier by mistake, it was not in original files

graphics/font.h Outdated
/**
* Initializes the scalesurface for scaling and the grayScaleMap for the given @p srcSize and @p newSize.
*
* @param srcSize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you have to describe the parameters, not just enumerate them

graphics/font.h Outdated
*
* @param width The width of the bouding box.
* @param height The height of the bounding box.
* @param grayLevel The gray level.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is "gray level"? you need to describe it here.

graphics/font.h Outdated
/**
* Scales the single gylph at @p chr the given the @p scale and @p resGray and returns the scaled surface with updated @p resGray
*
* @param width The width of the bouding box.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bounding box of what?


#if DRAWDEBUG
if (i == ccc) {
warning("BdfFont::scaleFont(): %d %d", data.height,box.height);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this as a warning? And if you do, the code formatting is off.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that is not required, removed it now

return nullptr;
}

BdfFont *srcCopy = new BdfFont(src->_data, DisposeAfterUse::YES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you creating a whole copy of the entire font? Please, do not do it.

}

BdfFont *srcCopy = new BdfFont(src->_data, DisposeAfterUse::YES);
srcCopy->initializeScaling(src->getFontSize(), newSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initializeScaling() should be called for this copy of the object, not creating another one pointlessly.

// int dstGraySize = newSize * 20 * newSize;
// int *dstGray = (int *)malloc(dstGraySize * sizeof(int));

tmpSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2 + 2, newSize * 2 + 2),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please move its creation closer to the usage.

Copy link
Member

@sev- sev- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, a lot of problems, starting from basics that are code formatting, ending with memory leaks, possible memory override and in general, oddities.

As we discussed on Discord, I recommend allocating dstGray() in the caller code, e.g. in the scaleFont() calls and pass it to the scaleSingleGlyph(). This way you just avoid any modifications to the class state. Instead, you decided to go your own way, but the implementation is very problematic. I outlined it in the comments.

for (int i = origFont->getFontHeight(); i <= 20; i++) {

//const Graphics::BdfFont *font = Graphics::BdfFont::scaleFont(origFont, i);
// const Graphics::BdfFont *font = Graphics::BdfFont::scaleFont(origFont, i);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed this

: _data(data), _dispose(dispose) {
}

// BdfFont::BdfFont(DisposeAfterUse::Flag dispose)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the comments

}

void BdfFont::assignFontData(const BdfFontData &data) {
_data = data;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what is happening with the previous thing which was in _data?


float scale = (float)newSize / (float)src->getFontSize();

BdfFont *scaledFont = new BdfFont(src->_data, DisposeAfterUse::YES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you passing src->_data here when later you just overwrite it? Please, avoid it.

return new BdfFont(data, DisposeAfterUse::YES);
}

void BdfFont::assignFontData(const BdfFontData &data) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the _dispose flag? Also, in accordance with other similar methods in other classes, it is better name it setData()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initialize the Font using the constructor, and this method only changes the data. I will rename it to setData. _dispose flag is handled by the constructor used at the beginning

class BdfFont : public Font {
public:
BdfFont(const BdfFontData &data, DisposeAfterUse::Flag dispose);
// BdfFont(DisposeAfterUse::Flag dispose);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this

const int bytes = dstPitch * box.height;
#if DRAWDEBUG
if (i == ccc) {
int *dstGray = *dstGrayPointer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this declaration which immediately goes out of scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dstGray is being used in the debug part of code, so needed declaration. It was getting its value from dstGrayPointer defined above, now changed it and removed dstGrayPointer, as it was redundant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to declare it, then you declare it incorrectly. Try to compile with DRAWDEBUG on. It will not even compile!

const int bytes = ((box.width + 7) / 8) * box.height; // Dimensions have been already corrected
int *dstGrayPointer = 0;
Graphics::Surface *srcSurf = scaledFont->scaleSingleGlyph(box.width, box.height, grayLevel, i + src->_data.firstCharacter,
box.xOffset, src->_data.height, srcBox.width, scale, &dstGrayPointer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, now you allocate dstGrayPointer in scaleSingleGlyph(). Where do you free this memory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is happening in the deconstructor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I missunderstood, I have replace it to dstGra, which is required for debuging

@NischayDiwan NischayDiwan force-pushed the master branch 2 times, most recently from 2c4dff0 to 9672dad Compare April 11, 2023 17:00
byte b = 0;

for (int x = 0; x < box.width; x++) {
for (int x = 0; x < box.width; x++,srcd++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not conform to our code formatting guidelines.

 - 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.
 - 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
@sev-
Copy link
Member

sev- commented Apr 16, 2023

Thank you!

@sev- sev- merged commit aaa32cf into scummvm:master Apr 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants