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

osgText::Text::AlignmentType::LEFT_TOP makes text jump #1269

Open
rubenlg opened this issue Nov 7, 2023 · 0 comments
Open

osgText::Text::AlignmentType::LEFT_TOP makes text jump #1269

rubenlg opened this issue Nov 7, 2023 · 0 comments

Comments

@rubenlg
Copy link

rubenlg commented Nov 7, 2023

osgText::Text::AlignmentType::LEFT_TOP should align the text to the tallest possible glyph, but in practice it's aligning to the tallest glyph currently present in the input text. This is a problem when the text changes dynamically, because it will jump around as glyphs of different sizes appear. Here's a small repro case with text appearing letter by letter to illustrate the bug. Sorry for the hardcoded Linux font.

#include <osgDB/ReadFile>
#include <osgText/Text>
#include <osgViewer/Viewer>
#include <string>

const std::string TEXT = "aeiAg!";

class TextAnimationCallback : public osg::NodeCallback {
public:
  explicit TextAnimationCallback(osgText::Text *textNode)
      : textNode_(textNode) {}

  virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) {
    double currentTime = nv->getFrameStamp()->getSimulationTime();
    if (currentTime - startTime_ >= 0.3) {
      textNode_->setText(TEXT.substr(0, letterIndex_ + 1),
                         osgText::String::Encoding::ENCODING_UTF8);
      letterIndex_ = (letterIndex_ + 1) % TEXT.size();
      startTime_ = currentTime;
    }
    traverse(node, nv);
  }
private:
  osg::ref_ptr<osgText::Text> textNode_;
  unsigned int letterIndex_ = 0;
  double startTime_ = 0.0;
};

int main() {
  osg::ref_ptr<osgText::Text> textNode = new osgText::Text;

  textNode->setText("____________"); // placeholder for osgViewer
  textNode->setFont(osgText::readFontFile(
      "/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf"));
  textNode->setRotation(
      osg::Quat(osg::inDegrees(90.0f), osg::Vec3(1.0f, 0.0f, 0.0f)));
  textNode->setAlignment(osgText::Text::AlignmentType::LEFT_TOP);
  textNode->setUpdateCallback(new TextAnimationCallback(textNode));

  osgViewer::Viewer viewer;
  viewer.setSceneData(textNode);
  return viewer.run();
}

I suppose a possible workaround, to achieve top alignment while this isn't fixed, would be to align to the baseline and then correct the position by using the ascender property from osgText::Font::getVerticalSize. But I haven't tried it yet.

Note that a proper fix for this would be a breaking change, since there might be code out there relying on its current behavior. Maybe fixing it properly would require introducing new enum values, such as LEFT_TOP_STABLE?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant