-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix #281601 and fix #284218 [workaround]: broken on-screen rendering … #5794
Conversation
Important note: this PR must be thoroughly tested to check if it does not re-introduce kerning problems (especially under Windows). |
// only needed for certain artificially emboldened fonts | ||
// see https://musescore.org/en/node/281601#comment-900261 | ||
// in Qt 5.12.x this workaround should be no more necessary if | ||
// env variable QT_MAX_CACHED_GLYPH_SIZE is set to 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense then to use #if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, but we should also check that it is possible to defined QT_MAX_CACHED_GLYPH_SIZE=1 inside MuseScore code (maybe before all the initializations) and that it works without slowing the program (in my pc it does not slow down the program, but better safe than sorry).
This comment is just a reminder that in the future (if and when we will use a newer version of Qt) the workaround could be no more needed.
Thanks for the workaround and for the explanation you have linked! I have also noticed that if zoom factor in However I am not sure that it would be correct to use this workaround. The reason of my concern is that changing font size actually changes various font properties and metrics in the way which doesn't directly correspond to scaling glyphs of fixed size. One of important aspects of that is spacing between letters being dependent on font size so scaling font size by some factor doesn't actually scale size of a text block by the same factor. In MuseScore this leads to this workaround leading to noticeable shifts in relative letters positions and occasional collisions of text with other elements when changing zoom level (which is especially noticeable when changing zoom level with Ctrl + mouse wheel). These occasional collisions result from layout assuming font size different to what is used by drawing procedure with this workaround. The implementation in this PR limits this effect to bold text only but independently of font face, so even text using fonts not suffering from the emboldening issues will show the behaviour which I described above. The part with collisions should probably be resolved if layout would use the same font size as with this workaround, but this also may be not the correct way to handle text layout. It might be arguable and dependent on a particular context, but the primary purpose of layout in MuseScore editor (at least in page mode) seems to be to show the appearance which would be the same as what would be produced after printing the score on a paper. If we accept this purpose of layout as the main one in this context, then the correct way to handle text layout seems to be what is implemented in MuseScore right now: using font size suitable for paper printing and scaling text by pixel transformations rather than by changing font size. As of Qt 5.12, my self-builds with Qt 5.12.5 (on Linux) still show this emboldening issue, but setting |
By the way, this issue also seems to belong to the same set of font emboldening issues. |
@dmitrio95 : you are right: I can see this spacing shift when zooming in and out. By the way, issue https://musescore.org/en/node/279766 is exactly this bug. I don't know if it is possible to somehow identify the problematic fonts. |
Dmitri Ovodok dixit:
As of Qt 5.12, my self-builds with Qt 5.12.5 (on Linux) still show this
emboldening issue, but setting `QT_MAX_CACHED_GLYPH_SIZE=1` indeed
fixes the issue. I didn't check its effect on text painting performance
though but could do that if needed.
Has anyone contacted the Qt developers about this? This seems like an
issue we’d not be the only ones to have, and which they might know a
proper fix, now we’re aware of a (version-dependent) workaround.
|
Well, I tried three times to ask for help in Qt forum these years, but they answered only once. |
Howard Chang dixit:
+#if defined Q_OS_WIN || defined Q_OS_LINUX
Yeah you're right. I thought this was unfamiliar because normally I see this:
`#if (defined (_MSCVER) || defined (_MSC_VER))`
That’s also irregular.
So I think it's probably better to have parentheses.
Standard style is:
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
But, as we said, we almost certainly want this instead:
#ifndef Q_OS_MAC
|
I think I managed to make the workaround work. |
Mmmh, the dimension is not yet the correct one, as seen in the vtests, but I think this could be the correct way of takling this bug (hopefully). |
Ok. I found that this workaround works for screen painting only, but not for png, pdf or svg export. In those cases a further rescaling involving screen dpi and painting device dpi is involved, but I could not find something which perfectly works in all cases (and by perfectly I mean 100% superposition). |
The remaining small vtest differences might well be due to some floating point rounding going on? |
libmscore/textbase.cpp
Outdated
qreal dx = p->worldTransform().dx(); | ||
qreal dy = p->worldTransform().dy(); | ||
qreal factor = 1 / mm; // correction factor for bold text drawing | ||
p->setMatrix(QMatrix(mm * factor, 0.0, 0.0, mm * factor, dx, dy)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t mm * factor
= 1 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
due to floating point arithmetic not exactly. But should be... so also might be the cause for the remaining small offsets. Guess p->setMatrix(QMatrix(1.0, 0.0, 0.0, 1.0, dx, dy));
would be more correct here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It is a leftover because at the beginning I was manually adjusting the factor to see when the problem was disappearing.
I found that the problem is indeed the fact that the diagonal elements of the painter matrix are not 1. If you look at exported output in the current MuseScore version, you will see that for svg there is no problem (m11 is forced to 1); for pdf and png when the resolution is 360 or larger there is no problem (m11 is greater or equal to 1, since it is resolution / internal resolution and the internal resolution at the moment is 360).
Well, for pdf the synthetically emboldened fonts are not emboldened, so there is not actually a problem (if we can say so) for m11<1.
For png export, when the resolution is lower than 360, for some font dimensions we see the problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if maybe use this workaround only when painting to the screen (I also don't know what happens when using two screens at different resolutions), and let the export function unchanged. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MuseScore doesn't deal too well with 2 screens with different DPIs already (it always only takes the settings of the primary screen as far as I can tell), I don't expect this PR to change that
Joachim Schmitz dixit:
due to floating point arithmetic not exactly. But should be...
Yeah, but mathematically, so we could inline this, perhaps as:
p->setMatrix(QMatrix(/* mm * factor */ 1, 0.0, 0.0, /* mm * factor */ 1, dx, dy));
|
Yes, better for documentation. I'd use |
By the way, have you tried the artifacts? Do they work ok for you? |
Well, your 2nd commit didn't generate artifacts |
Ouch, I forgot the collect_artifacts. 😅 |
You see problem in exported images only when the resolution is (significantly) below 360. |
Antonio Lotti (ABL) dixit:
(Freetype), but it seems that Qt text framework is a little buggy when
using Freetype (the one at hand is one example; another one
Indeed, exporting the same text from LibreOffice (using Freetype) works,
the distance between the two copies of the glyph visible in the 2.3.2
export is filled black here.
Maybe a good candidate for GSoC 2021 could be implementing a new text
drawing engine (for score texts, not for all the program texts)
independent of Qt
OK, but please make that still use the (system) freetype library,
ideally with fontconfig, so that the user settings for that (what
kind of kerning (autohinter, bytecode, etc.) and which fonts to
allow with which substitutions etc.) are still honoured. I currently
use that to ensure only fonts with a licence suitable for embedding
end up in the PDF (glyph substitution can choose an arbitrary one
from the system otherwise).
Too bad the Qt people appear to not be interested (you said some‐
thing about them not having responded to inquiries regarding this)…
|
Also http://www.mirbsd.org/music/free/resources/Gentium-1.03.zip
and then “Gentium Italic”…
|
Would a 170DPI screen count as high (enough) for testing? (it is for reproducing the issue) |
One additional problem of Qt is that even when they solve a bug, most of the time they do not backport it to older Qt versions (such as Qt 5.9.x that we are using for MuseScore). I think MuseScore is already using Freetype to draw score symbols, but texts have additional difficulties (kerning, ligatures, etc...). Qt is using Harfbuzz for text shaping, but I don't know how complicate a text engine can become. |
Maybe, no idea. I think the most problematic cases could be those that require the "-x" ("--gui-scaling") option. |
Antonio Lotti (ABL) dixit:
texts have additional difficulties (kerning, ligatures, etc...). Qt is
Not to mention combining characters, like I use ɔ plus ⃝ to
fake, as ɔ⃝, the copyleft sign, and this ends… somewhat badly,
http://www.mirbsd.org/music/free/Pachelbel%20--%20Canon%20in%20D.pdf
merely has it not centred in the footer, but when editing that
file without limiting MuseScore to a certain set of fonts, these
two are rendered one after another, like: ɔ ⃝
|
Looks good there too, not using those options |
…of synthetically emboldened fonts
I limited the workaround only for the cases in which it could be really necessary. Unfortunately, I don't know how to limit it only to misbehaving fonts (so it is applied to all bold fonts when not exporting a vectorial format and when m11 is < 1). |
I found a better way to deal with font rescaling between the different dpi involved. |
Aww yes: https://doc.qt.io/qt-5.12/qtextlayout.html#QTextLayout-2 This kind of documentation issue is… troubling. And so much thanks for working on it! |
@@ -130,7 +130,7 @@ void Preferences::init(bool storeInMemoryOnly) | |||
{PREF_EXPORT_MP3_BITRATE, new IntPreference(128, false)}, | |||
{PREF_EXPORT_MUSICXML_EXPORTBREAKS, new EnumPreference(QVariant::fromValue(MusicxmlExportBreaks::ALL), false)}, | |||
{PREF_EXPORT_MUSICXML_EXPORTLAYOUT, new BoolPreference(true, false)}, | |||
{PREF_EXPORT_PDF_DPI, new IntPreference(300, false)}, | |||
{PREF_EXPORT_PDF_DPI, new IntPreference(DPI, false)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn’t this change the default dpi for the PDF export from 300 to 360?
If so, at least https://github.com/musescore/MuseScore/blob/master/build/Linux%2BBSD/mscore.1.in#L209 needs adjusting, and maybe the QCommandLineArg thingy used for --help
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That line in the manual page is about PNG resolution and that has been changed to 360 a while ago already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether changing PDF's DPI is the right way, IMHO printers usually default to 300 DPI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, pdf is a vectorial format, so dpi does not really make sense for it (except if it is rasterizing things as images).
By using pdf dpi equal to internal DPI, we ensure that the matrix elements are 1 and therefore no problems with fonts should appear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes, the DPI is only used for embedded images I guess.
Thar line in the manual page is about png resolution
Oh right, sorry.
and that has been changed to 360 a while ago already
Free manpage fix for you ☻
|
See #6066 |
@AntonioBL Do I understand correctly that the workaround is not needed with let's say Qt 5.12.8 and higher? |
In principle, the workaround is not needed for Qt >=5.12 if we set QT_MAX_CACHED_GLYPH_SIZE=1 during the program initialization with qputenv (if we do not change the zoom logic). Maybe the best thing to be done would be to change the zoom logic so that the diagonal elements of the painter are always 1.0 (the coordinate system is not scaled); I think this could also help for Windows font rendering and maybe, once this is implemented, we could return to native font engine (instead of FreeType engine; this would help for loading DRM-protected fonts). However, that would be a huge reworking (with possible additional side-effect bugs). |
…of synthetically emboldened fonts
Resolves: https://musescore.org/en/node/284218 and https://musescore.org/en/node/281601
See https://musescore.org/en/node/281601#comment-900261 for the explanation of the Qt bug involved.
This is a workaround.