Three label improvements and plans for an annotation tool

I have been emailing Geoffrey about edits I have made to Avogadro and he recommended that I send the messages here.

These are the three changes I have made that I think would be of general interest:

  1. Displaying different fonts in textRenderer:
    Whenever textRenderer has to render a character, if the character has already been rendered, textRenderer reuses the old glyph. If the font is changed, the old glyph in the old font is still used. To get around this, I used overloaded functions to pass the font. If the passed font is different than the old font, I delete all glyphs and clear the character table. Glyphs will now be rendered in the new font. (changed in TextRendererPrivate::do_draw)

  2. White outline for black fonts:
    If the text color is black, then set the outline color to be white, else use the previous method for defining outline color.
    This makes black text readable on a black and white printout. (changed in TextRendererPrivate::do_draw)

  3. Labels moved forward:
    Currently, labelengine calls textRenderer to draw the labels and passes a Vector3D for the label position, but shifts the position by adding some multiple of the camera’s z axis. However, because things are drawn with perspective (farther things are smaller) this z axis is not perpendicular to the screen everywhere. Labels on atoms near the edge of the screen are visibly shifted toward the edge. Also, longer bond labels sometimes end up inside of bonds, especially if the bonds are perpendicular to the screen.

Solution: I have moved the label shifting into TextRenderer::draw.
Added wincoords.z() *= 0.5; after the line wincoords.y() += h/2; (changed in TextRenderer::draw)
Removed renderRadius addition to drawPos (changed in labelengine::renderOpaque)

I have not used git before and don’t know how it works, but if anyone wants example code let me know what you want and how and I would be happy to provide it.

My next goal is to make an “annotation tool”. Geoffrey recommended:

There are two parts of what you describe – some code that would live within the annotation tool (i.e., tracking mouse clicks and drags) and some new code which will live within the label engine (i.e., responding to those modifications). Basically, the annotation tool will store some new data in the atoms and bonds with the positions of the labels.

My additional thoughts:

  1. Right-clicking on a label returns it to its default location.
  2. I need to think about how the labels will respond to rotation of the view. I will probably store the data in the form of (x,y) displacements in the plane of the screen.
  3. If the label has been moved far from its target, a line should be drawn connecting them.

Any other suggestions before I begin?

Thomas Sexton

Many apologies – I’ve been traveling and didn’t have much time to get back to writing longer e-mails until today.

  1. Displaying different fonts in textRenderer:
    Whenever textRenderer has to render a character, if the character has already been rendered, textRenderer reuses the old glyph. If the font is changed, the old glyph in the old font is still used. To get around this, I used overloaded functions to pass the font. If the passed font is different than the old font, I delete all glyphs and clear the character table. Glyphs will now be rendered in the new font. (changed in TextRendererPrivate::do_draw)

This is great, as I’ve said earlier.

  1. White outline for black fonts:
    If the text color is black, then set the outline color to be white, else use the previous method for defining outline color.
    This makes black text readable on a black and white printout. (changed in TextRendererPrivate::do_draw)

Yup.

  1. Labels moved forward:
    Currently, labelengine calls textRenderer to draw the labels and passes a Vector3D for the label position, but shifts the position by adding some multiple of the camera’s z axis. However, because things are drawn with perspective (farther things are smaller) this z axis is not perpendicular to the screen everywhere. Labels on atoms near the edge of the screen are visibly shifted toward the edge. Also, longer bond labels sometimes end up inside of bonds, especially if the bonds are perpendicular to the screen.

Solution: I have moved the label shifting into TextRenderer::draw.
Added wincoords.z() *= 0.5; after the line wincoords.y() += h/2; (changed in TextRenderer::draw)
Removed renderRadius addition to drawPos (changed in labelengine::renderOpaque)

Yup.

I have not used git before and don’t know how it works, but if anyone wants example code let me know what you want and how and I would be happy to provide it.

Ideally, it would be great to have these as separate patches, but if you can send me the modified code files, I can submit it to code review for you.

My next goal is to make an “annotation tool”. Geoffrey recommended:

There are two parts of what you describe – some code that would live within the annotation tool (i.e., tracking mouse clicks and drags) and some new code which will live within the label engine (i.e., responding to those modifications). Basically, the annotation tool will store some new data in the atoms and bonds with the positions of the labels.

My additional thoughts:

  1. Right-clicking on a label returns it to its default location.
  2. I need to think about how the labels will respond to rotation of the view. I will probably store the data in the form of (x,y) displacements in the plane of the screen.
  3. If the label has been moved far from its target, a line should be drawn connecting them.

Yes, I think that’s exactly right. So the annotation tool will add a QObject property to a particular atom or bond that’s been clicked. (I’d look at the select tool for a starting point.)

http://qt-project.org/doc/qt-4.8/qobject.html#setProperty

e.g.

atom->setProperty(“label_XY”) = QPoint(3,4);

if (atom->property(“label_XY”).isValid())

Hope that helps,
-Geoff