-
Notifications
You must be signed in to change notification settings - Fork 845
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
Get MolDraw2DQt working again #3592
Get MolDraw2DQt working again #3592
Conversation
needs polish and testing non-freetype drawing doesn't work still
With the giant caveat that you need a QGuiApplication to use fonts. We try to detect that
@d-b-w : I'd love your feedback/thoughts on this |
@ZontaNicola - |
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.
Thanks for this, @greglandrum - It looks pretty wild to try to figure out the right conversions for some of this.
My only real concern is about the non-ascii data.
void getStringSize(const std::string &label, double &label_width, | ||
double &label_height) const override; | ||
#endif | ||
void drawChar(char c, const Point2D &cds) override; |
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.
What happens to non-ascii characters? Would they be rendered as individual utf-8 bytes?
I ask bc I know I've seen people talk in the RDK mailing list about, e.g. "±" in images.
I wonder if it would make sense to have this interface use QChar/QString.
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.
The API for this is set at the MolDraw2D level and it is really only setup for text made up of single-byte characters.
We could think about moving to supporting wide chars, particularly now that the freetype support is there, but that's a bigger story
: DrawText(max_fnt_sz, min_fnt_sz), d_qp(qp) { | ||
PRECONDITION( | ||
QCoreApplication::instance(), | ||
"need a global QGuiApplication instance to use the Qt font system"); |
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 think I've usually seen "QApplication" in this error message :)
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.
sorry, I don't follow you here.
// of the RDKit source tree. | ||
// | ||
|
||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do |
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 thought that the main was in catch_qt.cpp?
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.
catch_main.cpp is currently used for moldraw2DTestCatch
bool no_freetype = true; | ||
MolDraw2DQt drawer(qimg.width(), qimg.height(), qpt, -1, -1, no_freetype); | ||
MolDraw2DUtils::prepareAndDrawMolecule(drawer, *m1); | ||
qimg.save("qttest-1b.png"); |
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.
We've used http://pdiff.sourceforge.net/ to check things like this, but it's super sensitive to, e.g., platform differences or library updates. May not be useful for the RDKit
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.
yeah, I think comparing PNGs to each other byte-for-byte isn't useful
void setColour(const DrawColour &col); | ||
|
||
void drawLine(const Point2D &cds1, const Point2D &cds2); | ||
void drawChar(char c, const Point2D &cds); | ||
void drawPolygon(const std::vector<Point2D> &cds); | ||
void clearDrawing(); | ||
|
||
#if 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.
bc these aren't implemented yet?
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.
should have removed those, they were vestigial
|
||
QPen pen(this_col); | ||
pen.setJoinStyle(Qt::RoundJoin); | ||
pen.setColor(this_col); |
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.
does this do something different from the QPen constructor two lines up?
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.
nope. That looks like a mistake
font.setPixelSize(fontSize()); | ||
d_qp.setFont(font); | ||
QPointF loc(cds.x, cds.y); | ||
QString text; |
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.
what about:
QString text (QChar (c))
QPen pen(this_col); | ||
pen.setJoinStyle(Qt::RoundJoin); | ||
pen.setColor(this_col); | ||
d_qp.setPen(pen); |
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.
is the painter used by other functions?
I like putting changes to painters between QPainter::save() and QPainter::restore() to make sure they don't bleed through, just a suggestion
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.
It is used elsewhere, but the rest of the code should already be handling that particular problem since the drawing code runs across multiple rendering platforms, not all of which support equivalents to QPainter's save() and restore() methods
} | ||
|
||
for (size_t i = 0; i < draw_chars.size(); ++i) { | ||
double char_width = |
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 you could use QFontMetrics::boundingRect(QChar) 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.
yeah, this is the lowest-common denominator implementation that I added to just get things working
I will go back and look at doing it more correctly
@@ -33,11 +67,11 @@ void MolDraw2DQt::setColour(const DrawColour &col) { | |||
QPen pen(this_col); | |||
pen.setJoinStyle(Qt::RoundJoin); | |||
pen.setColor(this_col); |
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.
you can also get rid of this line
@ptosco @ricrogz @bp-kelley : I'm leaning towards reclassifying this as a bug fix. It's a bit more substantial than the usual bug fix, but it takes code which doesn't work at all any more and gets it working again. It can't break existing code that uses 2020.09 since MolDraw2DQt doesn't work at all for that release. |
@greglandrum I agree with the reclassification. Thanks for your work on this - I think this is going to be useful to many. I guess to expose it usefully to Python it needs to be interfaced with either PyQt5 or PySide2, right? |
I agree, reclassifying as a bug fix sounds the right thing to do. |
@ZontaNicola Thanks for the review. I made your suggested changes. |
Ok, merging this as is now that I have the CI builds working on at least linux and the Mac. |
* Qt drawing works with freetype. needs polish and testing non-freetype drawing doesn't work still * make the Qt rendering anti-aliased * non-freetype fonts work in Qt With the giant caveat that you need a QGuiApplication to use fonts. We try to detect that * cleanup * changes in response to review * add qt support to CI builds * fix VS build problem * try resolving a linux link error * Update linux_build.yml * Update linux_build.yml * another attempt to get the linux CI builds working * getting closer? * Update linux_build.yml * disable the qt CI builds on windows
The original plan was to deprecate it, but it could be useful to have a non-cairo way to create high-quality PNGs. Qt lets us do that. So this updates the class to get it working with the new font handling code.
Some caveats: