Skip to content
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

PR: Use QRawFont and draw PainterPath of Glyph for animation to prevent tremulous spinning icons #202

Merged
merged 9 commits into from
Oct 17, 2022

Conversation

kumattau
Copy link
Contributor

@kumattau kumattau commented Jan 26, 2022

Maybe #39 can be fixed using QRawFont and draw PainterPath of Glyph.

Compared to QFont, QRawFont is available without registering to font database,
So this approach has

Pros:

  • no tremulous spinning
  • no family name collision (font patch is not required)

Cons:

  • cannot support color-font (PainterPath of Glyph does not have color)
  • cannot support font() API (this requires QFont registered to font database)
  • I tests it on ubuntu only. I cannot check this approach works on other platform or not

If qtawesome switches QFont to QRawFont, font patch in the update_font script ( #194 ) may not be needed.

How do you think, @dalthviz ?

Note: current code is example, so it needs refactoring, optimization, etc.

Edit:

Fixes #39

@dalthviz
Copy link
Member

Hi @kumattau thanks for checking into this! Testing this locally seems like this also works for Windows 👍

example

Regarding the pros and cons maybe we could use QRawFont only when needed as you are doing here but still registering the font to still have access to the font API if needed?

Just in case what do you think @ccordoba12 ?

@kumattau
Copy link
Contributor Author

Thank you for testing @dalthviz

On windows, "Stack, offset" bled quite a bit. this is because QPainterPath does not have hinting.
So, I changed it to use QPainterPath only for animations to keep rendering quality.

On my ubuntu, example.py is here.
Could you compare "Stack, offset" and "Stack, offset, draw path" on Windows ?

Screenshot from 2022-01-29 00-45-56

The drawing method can be selected by "draw" option.

  • path: do painter.drawPath()
  • text: do painter.drawText()
  • auto: do painter.drawPath when animation, otherwise do painter.drawText() (default)

@kumattau kumattau marked this pull request as ready for review January 28, 2022 15:54
@kumattau kumattau changed the title [WIP] Use QRawFont and draw PainterPath of Glyph PR: Use QRawFont and draw PainterPath of Glyph when animation Jan 28, 2022
@kumattau kumattau force-pushed the qrawfont branch 2 times, most recently from ad7aac7 to dcab164 Compare January 28, 2022 16:06
@kumattau
Copy link
Contributor Author

@dalthviz, I finished the update. This PR is ready for review.

@dalthviz dalthviz added this to the v1.2.0 milestone Jan 28, 2022
@dalthviz dalthviz linked an issue Jan 28, 2022 that may be closed by this pull request
@dalthviz
Copy link
Member

Checking the example.py on Windows this is what I'm getting:

imagen

Copy link
Member

@dalthviz dalthviz left a comment

Choose a reason for hiding this comment

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

Thanks @kumattau for working on this! I left some suggestions regarding the comments in the code and also maybe we need to also update the docs (at least the example code in this PR) but otherwise this LGTM 👍

example.py Outdated Show resolved Hide resolved
qtawesome/iconic_font.py Outdated Show resolved Hide resolved
qtawesome/iconic_font.py Outdated Show resolved Hide resolved
@kumattau kumattau marked this pull request as draft January 31, 2022 13:37
@kumattau
Copy link
Contributor Author

Thank you for review @dalthviz, I updated comment.
I've come up with a better way to do it and will experiment with it. Please wait a little longer.

@kumattau
Copy link
Contributor Author

kumattau commented Feb 1, 2022

Hi, @dalthviz

I've come up with a better way to do it and will experiment with it.

I try to drawImage a glyph of QRawfont.
On my ubuntu, the drawing quality is same as original drawText with QFont.
Could you try example.py on Windows and feedback me ?

If the drawImage is okey, qtawesome does not require for QFont except for font() API.
I think I want not to patch fonts if possible, so, it is the first step of the use of patch-free font.

@dalthviz
Copy link
Member

dalthviz commented Feb 1, 2022

Hi again @kumattau, this is what I'm seeing on Windows with the latest changes:

imagen

So, indeed the icon drawing locks cleaner 👍

However seems like the new code is not compatible with Qt <5.15. The tests are failling here since it our CI uses Qt 5.9.7 and locally I tried first testing with an env that had Qt 5.12.2 and the same error appeared. Could be possible to have a fallback in case QImage.setAlphaChannel doesn't exists in the Qt/PyQt/PySide version installed?

@kumattau
Copy link
Contributor Author

kumattau commented Feb 1, 2022

@dalthviz

Could be possible to have a fallback in case QImage.setAlphaChannel doesn't exists in the Qt/PyQt/PySide version installed?

Yes. I added fallback code and pushed it.
I will try to refactor the code and add three draw options (path, image, text).

@kumattau
Copy link
Contributor Author

kumattau commented Feb 7, 2022

Hi, @dalthviz

cannot support color-font (PainterPath of Glyph does not have color)

I found another issue.
QRawFont requires that the font has glyph.
So, for example, NotoColorEmoji.ttf, which does not have glyphs, cannot be rendered using QRawFont.

fonttools/fonttools#949 (comment)

qtawesome cannot switch the drawing method from drawPath() to the original drawText() if the font does not have glyphs.
Because QRawFont have bool supportsCharacter(char) method to check if the font has a glyph that corresponds to the given character, but this always returns True on ubuntu.

And the following error message output to the console if a glyph is missing, but this message cannot be stopped.

load glyph failed err=24

Should qtawesome support a font which does not have glyphs ?

@dalthviz
Copy link
Member

dalthviz commented Feb 7, 2022

Hi again @kumattau !

Should qtawesome support a font which does not have glyphs ?

I would say yes. Probably we need to find a reliable way to detect if the font does not have the needed glyphs, show some sort of warning letting users know that we were unable to use the specified config to draw the icon and then fallback to use the drawText/``text` option.

Maybe there are other ways to check for the character support more reliable than QRawFont.supportsCharacter ?

@kumattau
Copy link
Contributor Author

kumattau commented Feb 8, 2022

Hi @dalthviz

I would say yes.

I got it.

I would say yes. Probably we need to find a reliable way to detect if the font does not have the needed glyphs, show some sort of warning letting users know that we were unable to use the specified config to draw the icon and then fallback to use the drawText/``text` option.

I think fallback is possible.
If glyph is missing, the PainterPath is empty, so I can implement the fallback to drawText when PainterPath is emtpy.
The biggest issue at the moment is that I can't stop the following error messages.

load glyph failed err=24

It is quite annoying because it is always output when glyph is missing.

I will do some more research on this matter.

@dalthviz
Copy link
Member

Hi again @kumattau , hope everything is going well! Since we will try to release v1.2.0 soon, just to know if we can make this part of the release a couple of questions: Did you find any other info that could help with the missing elements here? and also, would you like to finish this or is okay for me or someone else to try finish it? Let us know!

@kumattau
Copy link
Contributor Author

@dalthviz Thank you for follow-up and I'm very sorry not to response.

I will do some more research on this matter.

The investigation has not progressed but I will reboot this PR soon (in this week or next week).
If my schedule is not suite the release, I'm no problem for you to try finish it at all.

@dalthviz
Copy link
Member

Thanks for the prompt response @kumattau ! If you still want to finish this at some point then no problem, happy to hear that :)

It would be nice to merge this for the next release v1.2.0 (which will be done probably mid-next week) but do not worry about the time, just knowing that this could be finished in the future and you are willing to keep checking on it are really good news 👍

@dalthviz dalthviz changed the title PR: Use QRawFont and draw PainterPath of Glyph when animation PR: Use QRawFont and draw PainterPath of Glyph for animation to prevent tremulous spinning icons Oct 12, 2022
@kumattau kumattau force-pushed the qrawfont branch 2 times, most recently from 5906d03 to 378d009 Compare October 13, 2022 21:22
@kumattau
Copy link
Contributor Author

@dalthviz

I rebased master and fixed "load glyph failed err=24" problem by fall backing draw=text
The draw option accepts text/path/glyphrun/image. If not specified, draw=path is used for non-animation and draw=text is used for animation.
example.py accepts global_default options (key=val format) for test.

In my linux, it is better that draw=image is used for non-animation and draw=text is used for animation.
Could you please try it in windows ?

* Fix QRawFont to be thread-local
* Add public iconic.rawfont() same as iconic.font()
* Use setCompositionMode instead of setAlphaChannel which is not supported on PyQt 5.9
* Add glyphrun to draw option
* Add draw option in global_defaults
* Add Fallback to text drawing if path/glyphrun/image drawing cannot be used
* Refectoring CharIconPainter._paint_icon()
@kumattau
Copy link
Contributor Author

Looking to spin, I still think draw=path would be better when animation.

@dalthviz dalthviz modified the milestones: v1.2.1, v1.2.0 Oct 14, 2022
@dalthviz
Copy link
Member

Thanks for the quick update @kumattau ! Doing some testing on Windows:

Default options (no args) - python example.py

default

draw=image option - python example.py draw=image

draw_image

draw=path option - python example.py draw=path

draw_path

draw=text option - python example.py draw=image

draw_text

Checking then seems like the draw=path should be the default when animation is requested and draw=image when not

@dalthviz
Copy link
Member

dalthviz commented Oct 14, 2022

Besides the suggestion above I think the only missing element is updating the example.py gif and documentation (adding the new draw option and also the possiblity to pass options to the example.py script) but I can take care of that in a follow-up PR before doing the release 👍

And again, thanks @kumattau for taking the time to update this!

qtawesome/iconic_font.py Outdated Show resolved Hide resolved
Co-authored-by: Daniel Althviz Moré <[email protected]>
@kumattau
Copy link
Contributor Author

@dalthviz

How about draw=glyphrun on windows ?

On linux, The quality of draw=glyphrun seems to be same as draw=text.

glyphrun can use rawfont (in other words, does not requires the installation of font) but cannot render emoji (without glyph).

@dalthviz
Copy link
Member

Checking draw=glyphrun on Windows I got this:

image

Looking more in detail the different draw options I would say that glyphrun looks quite similar to text and also as you said for some fonts using image doesn't look quite good, so lets leave the default draw option to be text for non-animated icons 👍

Thanks again @kumattau for the work here and checking all the draw options! I think this is ready to be merged then, right? Or maybe do you want to check something else on Windows? If is ready to be merged just mark the PR as Ready for review and I will merge it 👍

@kumattau kumattau marked this pull request as ready for review October 16, 2022 09:48
@kumattau
Copy link
Contributor Author

@dalthviz

My work has been finished.
The commits keep not to be squashed.
If you want to simplify the PR, please squash and merge it.

Copy link
Member

@dalthviz dalthviz left a comment

Choose a reason for hiding this comment

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

Thanks for all the work done here @kumattau !

@dalthviz dalthviz merged commit f6b7db8 into spyder-ide:master Oct 17, 2022
@dalthviz dalthviz mentioned this pull request Oct 17, 2022
@kumattau kumattau deleted the qrawfont branch October 17, 2022 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tremulous spinning icons
2 participants