6.1. Two-Dimensional Text

The text node, SoText2( C++ | Java | .NET ), defines text strings that are rendered as 2D screen-aligned text. Just as other shape nodes cause their shape to be drawn when encountered during rendering traversal, an SoText2( C++ | Java | .NET ) node causes text to be drawn, using the current values for font and color. Text attributes used by SoText2( C++ | Java | .NET ) are specified in the SoFont( C++ | Java | .NET ) node. These attributes include font type and point size. Two-dimensional text does not scale in size according to changes in distance from the camera.

SoText2( C++ | Java | .NET ) has the following fields:

string (SoMFString)

the text string or strings to display. You can specify multiple strings.

spacing (SoSFFloat)

the spacing between lines of text. The default interval is 1.0. For a multiple-string field, the vertical distance from the top of one line to the top of the next line is equal to spacing times the font size.

justification (SoSFEnum)

alignment of the text strings relative to the text origin. Justification can be LEFT (the default), RIGHT, or CENTER.

The text origin is positioned at (0, 0, 0), transformed by the current geometric transformation. Text is drawn relative to the text origin, according to the specified justification. For example, if you specify RIGHT justification, the right side of the text aligns with the text origin.

Use the SoFont( C++ | Java | .NET ) node to specify a font type and size for subsequent text nodes (both 2D and 3D) in the scene graph. This node contains the following fields:

For example, to specify 140-point Courier bold italic:


C++
SoFont *font = new SoFont;
font->name.setValue("Courier-BoldOblique");
font->size.setValue(140);
  

.NET
SoFont font = new SoFont();
font.name.Value = "Courier-BoldOblique";
font.size.Value = 140;

Java
SoFont font = new SoFont();
font.name.setValue("Courier-BoldOblique");
font.size.setValue(140);

Example 6.1, “ Using 2D Text renders a globe and uses 2D text to label the continents Africa and Asia. The SoFont( C++ | Java | .NET ) node specifies 24-point Times Roman as the current font. Figure 6.1, “ 2D Text Example shows the scene graph for this example. Figure 6.2, “ Simple Text” shows the image produced by this program.


Example 6.1.  Using 2D Text


C++
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoTexture2.h>
#include <Inventor/nodes/SoTranslation.h>

#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/viewers/SoXtExaminerViewer.h>

main(int argc, char **argv)
{
   Widget myWindow = SoXt::init(argv[0]);
   if(myWindow == NULL) exit(1);

   SoGroup *root = new SoGroup;
   root->ref();

   // Choose a font.
   SoFont *myFont = new SoFont;
   myFont->name.setValue("Times-Roman");
   myFont->size.setValue(24.0);
   root->addChild(myFont);

   // Add the globe, a sphere with a texture map.
   // Put it within a separator.
   SoSeparator *sphereSep = new SoSeparator;
   SoTexture2  *myTexture2 = new SoTexture2;
   root->addChild(sphereSep);
   sphereSep->addChild(myTexture2);
   sphereSep->addChild(new SoSphere);
   myTexture2->filename = "globe.rgb";

   // Add Text2 for AFRICA, translated to proper location.
   SoSeparator *africaSep = new SoSeparator;
   SoTranslation *africaTranslate = new SoTranslation;
   SoText2 *africaText = new SoText2;
   africaTranslate->translation.setValue(.25,.0,1.25);
   africaText->string = "AFRICA";
   root->addChild(africaSep);
   africaSep->addChild(africaTranslate);
   africaSep->addChild(africaText);

   // Add Text2 for ASIA, translated to proper location.
   SoSeparator *asiaSep = new SoSeparator;
   SoTranslation *asiaTranslate = new SoTranslation;
   SoText2 *asiaText = new SoText2;
   asiaTranslate->translation.setValue(.8,.8,0);
   asiaText->string = "ASIA";
   root->addChild(asiaSep);
   asiaSep->addChild(asiaTranslate);
   asiaSep->addChild(asiaText);

   SoXtExaminerViewer *myViewer = 
            new SoXtExaminerViewer(myWindow);
   myViewer->setSceneGraph(root);
   myViewer->setTitle("2D Text");
   myViewer->setBackgroundColor(SbColor(0.35, 0.35, 0.35));
   myViewer->show();
   myViewer->viewAll();
   
   SoXt::show(myWindow);
   SoXt::mainLoop();
}
    

.NET
using System;
using System.Windows.Forms;

using OIV.Inventor.Nodes;
using OIV.Inventor.Win.Viewers;

namespace _06_1_Text
{
  public partial class MainForm : Form
  {
    SoWinExaminerViewer myViewer;

    public MainForm()
    {
      InitializeComponent();
      CreateSample();
    }

    String LOCALFONTNAME = "Times New Roman;Regular";

    public void CreateSample()
    {
      SoGroup root = new SoGroup();

      // Choose a font
      SoFont myFont = new SoFont();
      myFont.name.Value = (LOCALFONTNAME);

      myFont.size.Value = (24.0f);
      root.AddChild(myFont);

      // Add the globe, a sphere with a texture map.
      // Put it within a separator.
      SoSeparator sphereSep = new SoSeparator();
      SoTexture2 myTexture2 = new SoTexture2();
      SoComplexity sphereComplexity = new SoComplexity();
      sphereComplexity.value.Value = (0.55f);
      root.AddChild(sphereSep);
      sphereSep.AddChild(myTexture2);
      sphereSep.AddChild(sphereComplexity);
      sphereSep.AddChild(new SoSphere());
      myTexture2.filename.Value = "../../../../../data/globe.png";

      // Add Text2 for AFRICA, translated to proper location.
      SoSeparator africaSep = new SoSeparator();
      SoTranslation africaTranslate = new SoTranslation();
      SoText2 africaText = new SoText2();
      africaTranslate.translation.SetValue(.25f, .0f, 1.25f);
      africaText.stringField.SetValue("AFRICA");
      root.AddChild(africaSep);
      africaSep.AddChild(africaTranslate);
      africaSep.AddChild(africaText);

      // Add Text2 for ASIA, translated to proper location.
      SoSeparator asiaSep = new SoSeparator();
      SoTranslation asiaTranslate = new SoTranslation();
      SoText2 asiaText = new SoText2();
      asiaTranslate.translation.SetValue(0.8f, 0.8f, 0.0f);
      asiaText.stringField.SetValue("ASIA");
      root.AddChild(asiaSep);
      asiaSep.AddChild(asiaTranslate);
      asiaSep.AddChild(asiaText);

      myViewer = new SoWinExaminerViewer(this, "", true,
          SoWinFullViewer.BuildFlags.BUILD_ALL, SoWinViewer.Types.BROWSER);
      myViewer.SetSceneGraph(root);
      myViewer.SetTitle("2D Text");

      // In Inventor 2.1, if the machine does not have hardware texture
      // mapping, we must override the default drawStyle to display textures.
      myViewer.SetDrawStyle(SoWinViewer.DrawTypes.STILL, SoWinViewer.DrawStyles.VIEW_AS_IS);

      myViewer.ViewAll();
    }
  }
}
  

Java
import tools.*;
import java.awt.*;
import java.net.*;

import com.openinventor.inventor.awt. *;
import com.openinventor.inventor.nodes. *;

public class Main extends DemoInventor {
  private Panel panel;

  public static void main(String[] args) {
    Main applet = new Main();
    isAnApplet = false;
    applet.start();
    demoMain(applet, "Text");
  }

  public void start() {
    super.start();

    // Choose a font
    SoFont myFont = new SoFont();
    myFont.name.setValue("Times-Roman");
    myFont.size.setValue(24.0F);
    //myFont.size.setValue(.2F);

    // Add the globe, a sphere with a texture map.
    // Put it within a separator.
    SoSeparator sphereSep = new SoSeparator();
    SoTexture2 myTexture2 = new SoTexture2();
    SoComplexity sphereComplexity = new SoComplexity();
    sphereComplexity.value.setValue(0.55F);
    {
      sphereSep.addChild(myTexture2);
      sphereSep.addChild(sphereComplexity);
      sphereSep.addChild(new SoSphere());
    }

    URL url_texture = getURL("../../../../data/textures/rgb/globe.rgb");
    if (url_texture == null) return;
    myTexture2.filename.setValue(url_texture.getFile());

    // Add Text2 for AFRICA, translated to proper location.
    SoSeparator africaSep = new SoSeparator();
    SoTranslation africaTranslate = new SoTranslation();
    SoText2 africaText = new SoText2();
    africaTranslate.translation.setValue(.25F,.0F,1.25F);
    africaText.string.setValue("AFRICA");
    {
      africaSep.addChild(africaTranslate);
      africaSep.addChild(africaText);
    }

    // Add Text2 for ASIA, translated to proper location.
    SoSeparator asiaSep = new SoSeparator();
    SoTranslation asiaTranslate = new SoTranslation();
    SoText2 asiaText = new SoText2();
    asiaTranslate.translation.setValue(.8F,.8F,.0F);
    asiaText.string.setValue("ASIA");
    {
      asiaSep.addChild(asiaTranslate);
      asiaSep.addChild(asiaText);
    }

    SoGroup root = new SoGroup();
    { // assemble scene graph
      root.addChild(myFont);
      root.addChild(sphereSep);
      root.addChild(africaSep);
      root.addChild(asiaSep);
    }

    SwSimpleViewer myViewer = new SwSimpleViewer(SwSimpleViewer.EXAMINER);
    myViewer.setSceneGraph(root);
    myViewer.setName("2D Text");

    setLayout(new BorderLayout());
    panel = new Panel(new BorderLayout());

    panel.add(myViewer);
    add(panel);
  }

  public void stop() {
    remove(panel);
    panel = null;
    super.stop();
  }
}