]> git.mxchange.org Git - simgear.git/commitdiff
Fix CanvasText horizontal alignment.
authorThomas Geymayer <tomgey@gmail.com>
Sat, 9 Feb 2013 11:09:43 +0000 (12:09 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sat, 9 Feb 2013 11:17:45 +0000 (12:17 +0100)
Don't reduce width of bounding box below character width
even if outline of rendered character is smaller. This
prevents trailing spaces from being ignored and also
fixes continuously chaging alignment (especially with
monospace fonts).

simgear/canvas/elements/CanvasText.cxx

index c92a9ecfbad7e80705921389aaf5795c454c60e0..8c4028bf0eacfbea81021fceb52dccfc11aff696 100644 (file)
@@ -44,6 +44,8 @@ namespace canvas
     protected:
 
       canvas::Text *_text_element;
+
+      virtual void computePositions(unsigned int contextID) const;
   };
 
   //----------------------------------------------------------------------------
@@ -175,6 +177,70 @@ namespace canvas
     return bb;
   }
 
+  //----------------------------------------------------------------------------
+  void Text::TextOSG::computePositions(unsigned int contextID) const
+  {
+    if( _textureGlyphQuadMap.empty() || _layout == VERTICAL )
+      return osgText::Text::computePositions(contextID);
+
+    // TODO check when it can be larger
+    assert( _textureGlyphQuadMap.size() == 1 );
+
+    const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second;
+    const GlyphQuads::Glyphs& glyphs = quads._glyphs;
+    const GlyphQuads::Coords2& coords = quads._coords;
+    const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers;
+
+    float wr = _characterHeight / getCharacterAspectRatio();
+
+    size_t cur_line = static_cast<size_t>(-1);
+    for(size_t i = 0; i < glyphs.size(); ++i)
+    {
+      // Check horizontal offsets
+
+      bool first_char = cur_line != line_numbers[i];
+      cur_line = line_numbers[i];
+
+      bool last_char = (i + 1 == glyphs.size())
+                    || (cur_line != line_numbers[i + 1]);
+
+      if( first_char || last_char )
+      {
+        // From osg/src/osgText/Text.cpp:
+        //
+        // osg::Vec2 upLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...);
+        // osg::Vec2 lowLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...);
+        // osg::Vec2 lowRight = local+osg::Vec2(width+fHorizQuadMargin, ...);
+        // osg::Vec2 upRight = local+osg::Vec2(width+fHorizQuadMargin, ...);
+
+        float left = coords[i * 4].x(),
+              right = coords[i * 4 + 2].x(),
+              width = glyphs[i]->getWidth() * wr;
+
+        // (local + width + fHoriz) - (local - fHoriz) = width + 2*fHoriz | -width
+        float margin = 0.5f * (right - left - width),
+              cursor_x = left + margin
+                       - glyphs[i]->getHorizontalBearing().x() * wr;
+
+        if( first_char )
+        {
+          if( cur_line == 0 || cursor_x < _textBB._min.x() )
+            _textBB._min.x() = cursor_x;
+        }
+
+        if( last_char )
+        {
+          float cursor_w = cursor_x + glyphs[i]->getHorizontalAdvance() * wr;
+
+          if( cur_line == 0 || cursor_w > _textBB._max.x() )
+            _textBB._max.x() = cursor_w;
+        }
+      }
+    }
+
+    return osgText::Text::computePositions(contextID);
+  }
+
   //----------------------------------------------------------------------------
   Text::Text( const CanvasWeakPtr& canvas,
               const SGPropertyNode_ptr& node,