]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/elements/CanvasText.cxx
Canvas: rework style setter system.
[simgear.git] / simgear / canvas / elements / CanvasText.cxx
index c92a9ecfbad7e80705921389aaf5795c454c60e0..a00cc1fa703f6b362a687034b6255dd273025c2d 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,
@@ -188,22 +254,32 @@ namespace canvas
     _text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
     _text->setRotation(osg::Quat(osg::PI, osg::X_AXIS));
 
-    addStyle("fill", &TextOSG::setFill, _text);
-    addStyle("background", &TextOSG::setBackgroundColor, _text);
-    addStyle("character-size",
-             static_cast<void (TextOSG::*)(float)>(&TextOSG::setCharacterSize),
-             _text);
-    addStyle("character-aspect-ratio", &TextOSG::setCharacterAspect, _text);
-    addStyle("padding", &TextOSG::setBoundingBoxMargin, _text);
-    //  TEXT              = 1 default
-    //  BOUNDINGBOX       = 2
-    //  FILLEDBOUNDINGBOX = 4
-    //  ALIGNMENT         = 8
-    addStyle<int>("draw-mode", &TextOSG::setDrawMode, _text);
-    addStyle("max-width", &TextOSG::setMaximumWidth, _text);
-    addStyle("font", &Text::setFont, this);
-    addStyle("alignment", &Text::setAlignment, this);
-    addStyle("text", &Text::setText, this);
+    if( !isInit<Text>() )
+    {
+      osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
+
+      addStyle("fill", "color", &TextOSG::setFill, text);
+      addStyle("background", "color", &TextOSG::setBackgroundColor, text);
+      addStyle("character-size",
+               "numeric",
+               static_cast<
+                 void (TextOSG::*)(float)
+               > (&TextOSG::setCharacterSize),
+               text);
+      addStyle("character-aspect-ratio",
+               "numeric",
+               &TextOSG::setCharacterAspect, text);
+      addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
+      //  TEXT              = 1 default
+      //  BOUNDINGBOX       = 2
+      //  FILLEDBOUNDINGBOX = 4
+      //  ALIGNMENT         = 8
+      addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
+      addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
+      addStyle("font", "", &Text::setFont);
+      addStyle("alignment", "", &Text::setAlignment);
+      addStyle("text", "", &Text::setText);
+    }
 
     setupStyle();
   }