Mudlet: Bug Crash on using setFont() with "esint10" and "Adobe Blank"

Created on 7 Mar 2019  路  18Comments  路  Source: Mudlet/Mudlet

Brief summary of issue / Description of requested feature:

I created a key binding to cycle through my available fonts, and change the font of the minimap which is comprised of monospace utf8 ascii art, so that i could find the best looking font out of what my system offers.

In the process I found if you increment the list of fonts beyond the available fonts(size of the fonts table), it will crash Mudlet.

here is the key binding script I was using at the time:

if not fontlist then
    fontlist=getAvailableFonts()
    fontindex={}
  for k,v in pairs(fontlist) do
            fontindex[#fontindex+1]=k
  end
end
fontx = fontx or 0
fontx = fontx + 1
--fontx=150
echo(fontx .. ": " .. fontindex[fontx] .. "\n")
setFont("minimap", fontindex[fontx])

Steps to reproduce the issue / Reasons for adding feature:

to reproduce try setting the font with fontindex[fontx] where fontx exceeds the boundaries of the fontindex table.

Error output / Expected result of feature

On Mudlet crash the linux console I launched it from reported: Floating point exception (core dumped)

Extra information, such as Mudlet version, operating system and ideas for how to solve / implement:

Mudlet 3.17.1-dev on Ubuntu 18.10 with KDE

bug low

All 18 comments

That is good(?) to know, someone will take a look at it I am sure (if I don't) - I guess in the meantime you should change:

fontx = fontx + 1

to be:

fontx = fontx + 1
if fontx > #fontindex then
  fontx = 1
end

I won't mark this as a bug until I or another Maker can confirm it - the mechanism does sound odd as setting the font of something to an empty name - i.e. setFont(QString()) in the C++ side should just reset the font to the application default one IIRC...? :slightly_frowning_face:

Humm, I'm not getting a crash with that code (I had the "Echo Lua errors to the main console" option on and when I hit that point I get a:

[  LUA  ] - object: <Change info font type> function:<Key5>
            <[string "Key: Change info font type"]:12: attempt to concatenate field '?' (a nil 
value)>

and in the Central Debug Console I see:

LUA ERROR: when running script Change info font type (Key5),
reason: [string "Key: Change info font type"]:12: attempt to concatenate field '?' (a nil value)

I am not sure why you are getting a crash though :skull_and_crossbones: ...

:thinking: Ah, it may be that it is bugging out on that reporting line before it - was that a later addition?

:negative_squared_cross_mark: Nope that just causes things to bail out with:

[  LUA  ] - object: <Change info font type (up)> function:<Key5>
            <setFont: bad argument #2 type (name as string expected, got nil!)>

Basically I cannot reproduce this bug - marking as Need more info


:thought_balloon: BTW As a second option that enables you to reverse the changing direction (I have over 150 fonts to play with) I have used:

if not fontlist then
    fontlist=getAvailableFonts()
    fontindex={}
  for k,v in pairs(fontlist) do
    fontindex[#fontindex+1]=k
  end
end
fontx = fontx or #fontindex + 1
fontx = fontx - 1
if fontx < 1 or fontx > #fontindex then
  fontx = #fontindex
end
echo(fontx .. ": " .. fontindex[fontx] .. "\n")
setFont("info", fontindex[fontx])

If there is anything I can do like running Mudlet in some kind of debug mode, let me know, will provide whatever help I can.

Actually I just did this (font 900, way past what I have, and it report the nil value instead of crashing):


if not fontlist then
    fontlist=getAvailableFonts()
    fontindex={}
  for k,v in pairs(fontlist) do
            fontindex[#fontindex+1]=k
  end
end
fontx=900
fontx = fontx or 0
fontx = fontx + 1
--if fontx > #fontindex then
--  fontx = 1
--end
echo(fontx .. ": " .. fontindex[fontx] .. "\n")
setFont("minimap", fontindex[fontx])

and now I am no longer crashing, so maybe its a specific font causing the crash, will see if i can figure out which one.

:confused: Curiouser and curiouser...

I figured it out Font 213 is the one that crashes me, I was able to display 212 then the next one crashed me.

I then ran:

lua display(fontindex[213])

which shows the font "esint10" so it is the culprit for the crash, I have repeated this crash a handful of times now, its always "esint10"

Bad font! -- Naughty font!!! Update: oops it is us, not the font. :flushed:

so here is my new function, LOL:

if not fontlist then
    fontlist=getAvailableFonts()
    fontindex={}
  for k,v in pairs(fontlist) do
            fontindex[#fontindex+1]=k
  end
end
--fontx=200
fontx = fontx or 0
fontx = fontx + 1
if fontindex[fontx] == "esint10" then
    fontx = fontx + 1
end
if fontx > #fontindex then
  fontx = 1
end
echo(fontx .. ": " .. fontindex[fontx] .. "\n")
setFont("minimap", fontindex[fontx])

That is the only font on my system that causes that crash.

That font was designed by a "Eddie Saudrais" according to http://luc.devroye.org/fonts-44942.html and after some conversion or other is located here: http://tug.ctan.org/tex-archive/fonts/ps-type1/esint/ ... :man_shrugging:

yeah, somehow I ended up with it on my system, and had yet to actually install any fonts, so it either came with Ubuntu or got installed alongside one of my applications.

The crash happens on https://github.com/Mudlet/Mudlet/blob/development/src/TTextEdit.cpp#L298 because mFontWidth is 0. I have a feeling this font doesn't even have the W character that we retrieve the width of?

image

Need a failsafe in place for such weird fonts.

I can confirm this - I too get a crash with that font. Why on earth are we taking the width of a particular glyph anyhow - and a 'W' of all things? Even font designers don't consider that character - instead they talk able the 'M' (em) width! :open_mouth:

Looking at the Qt Docs I see that QFontMetrics::width(QChar) has been declared obsolete:

int QFontMetrics::width(QChar ch) const

This is an overloaded function.
screenshot_20190308_101002
Returns the logical width of character ch in pixels. This is a distance appropriate for drawing a subsequent character after ch.

Some of the metrics are described in the image to the right. The central dark rectangles cover the logical width() of each character. The outer pale rectangles cover the leftBearing() and rightBearing() of each character. Notice that the bearings of "f" in this particular font are both negative, while the bearings of "o" are both positive.

Warning: This function will produce incorrect results for Arabic characters or non-spacing marks in the middle of a string, as the glyph shaping and positioning of marks that happens when processing strings cannot be taken into account. When implementing an interactive text control, use QTextLayout instead.

See also boundingRect().
screenshot_20190308_101002

It strike me that - given that we are emulating a mono- (or more properly a duo-) space font in many places we might want to use one of these instead:

int QFontMetrics::maxWidth() const

Returns the width of the widest character in the font.

int QFontMetrics::averageCharWidth() const

Returns the average width of glyphs in the font.

This function was introduced in Qt 4.2.

Let's try average instead

But still, this font will break things even on average

You mean that there are fonts that declare (or the Qt library font handling code calculates) that their average character width (sum of the widths of all the characters present in font divided by that number of characters) is zero? That would surprise me - and render that metric pretty much useless! :astonished:

:bulb: Looking at that diagram also reminds me - we should make sure that kerning is turned off for fonts when used for the MUD text in the TConsole/TTextEdit classes. Kerning (the moving some characters pairs closer to each other because there is space in their glyphs for them to overlap) has no place in mono-spaced fonts but if other glyphs from proportional fonts are being pulled in to substitute for missing ones in the mono-spaced font then they may perhaps be getting kerned anyhow...

Yeah, if we found a font that has a zero with W, I reckon we can find one that has zero width average too. Should just reject be using that font outright since we divide by the font width in a few places.

Not sure about that - it is perfectly reasonable (IMHO) to find fonts without 'W's - there are a few Western languages that do not themselves have some letters that are in the 26 that form the alphabet of English (how about Cyrillic scripts like Russian?) and also those ideographic ones from the Far East ... but not having any printable characters is another thing entirely - unless you are programming in Whitespace :rofl:

Was this page helpful?
0 / 5 - 0 ratings