Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

NodeText.cpp

/*
 * NodeText.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include "stdafx.h"

#include "NodeText.h"
#include "Proto.h"
#include "FieldValue.h"
#include "MFString.h"
#include "SFNode.h"
#include "MFFloat.h"
#include "SFFloat.h"
#include "SFString.h"
#include "SFBool.h"
#include "Scene.h"
#include "NodeFontStyle.h"
#include "FontInfo.h"
#include "Util.h"

ProtoText::ProtoText(Scene *scene)
  : Proto(scene, "Text")
{
    string.set(
          addExposedField(MFSTRING, "string", new MFString()));
    fontStyle.set(
          addExposedField(SFNODE, "fontStyle", new SFNode(NULL), 
                          NODE_FONT_STYLE));
    length.set(
          addExposedField(MFFLOAT, "length", new MFFloat(), new SFFloat(0.0f)));
    maxExtent.set(
          addExposedField(SFFLOAT, "maxExtent", new SFFloat(0.0f), 
                      new SFFloat(0.0f)));

}

Node *
ProtoText::create(Scene *scene)
{ 
    return new NodeText(scene, this); 
}

NodeText::NodeText(Scene *scene, Proto *def)
  : Node(scene, def)
{
}

#ifdef HAVE_LIBGLUT
#include "GL/glut.h"

// yet another ugly textnode implementation 8-(

void
NodeText::draw()
{
    MFString      *mfstring = string();
    NodeFontStyle  *fontStyle = (NodeFontStyle *) 
                    ((SFNode *) getField(fontStyle_Index(),true))->getValue();

    float fsize = 1;
    if (fontStyle)
        fsize = fontStyle->size()->getValue();
    
    GLfloat diff_color[4];
    GLfloat em_color[4];

    glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff_color);
    glGetMaterialfv(GL_FRONT, GL_EMISSION, em_color);
    GLfloat color[4];
    for (int i = 0; i < 3; i++) {
        color[i] = em_color[i];
        if (_scene->getNumLights() != 0)
           color[i] += diff_color[i];
        if (color[i] > 1)
           color[i] = 1 ;
    }
    color[3] = diff_color[3];

    glPushAttrib(GL_ENABLE_BIT);

    glDisable(GL_LIGHTING);
    glDisable(GL_BLEND);
    
    Util::myGlColor4f(color[0], color[1], color[2], color[3]);
    glEnable(GL_LINE_SMOOTH);

    for (int j = 0; j < mfstring->getSize(); j++) {
      const char  *str = mfstring->getValue(j);
      int        n = strlen(str);
        glPushMatrix();
        glTranslatef(0, -j * fsize, 0);
        const float GLUT_STROKE_ROMAN_SIZE = 119.05;
        float scale = 1/GLUT_STROKE_ROMAN_SIZE;
        glScalef(scale * fsize, scale * fsize, 1.0);
      for (int i = 0; i < n; i++)
            glutStrokeCharacter(GLUT_STROKE_ROMAN, str[i]);
        glPopMatrix();
    }

    glLineWidth(1.0);

    glPopAttrib();
}

#else

void
NodeText::draw()
{
    MFString         *mfstring = string();
    NodeFontStyle  *fontStyle = (NodeFontStyle *) 
                    ((SFNode *) getField(fontStyle_Index(),true))->getValue();
//    const float    *length = ((MFFloat *) getField(length_Index()))->getValue();
//    float     maxExtent = ((SFFloat *) getField(maxExtent_Index()))->getValue();
    FontInfo         *font = NULL;
    bool        fhorizontal = true;
    bool        bleftToRight = true;
    float       fsize = 1.0f;
    float       fspacing = 1.0f;
    bool        btopToBottom = true;

    if (fontStyle) {
      MFString       *ffamily = fontStyle->family();
                  fhorizontal = fontStyle->horizontal()->getValue();
//    MFString       *justify = fontStyle->justify();
//    const char     *language = fontStyle->language()->getValue();
                  bleftToRight = fontStyle->leftToRight()->getValue();
                  fsize = fontStyle->size()->getValue();
                  fspacing = fontStyle->spacing()->getValue();
      const char     *sstyle = fontStyle->style()->getValue();
                  btopToBottom = fontStyle->topToBottom()->getValue();

      for (int i = 0; i < ffamily->getSize(); i++) {
          font = _scene->LoadGLFont(ffamily->getValue(i), sstyle);
          if (font) break;
      }

    } else {
      font = _scene->LoadGLFont("SERIF", "PLAIN");
    }

    if (!font) return;      // couldn't find the font

    glPushMatrix();
    glPushAttrib(GL_TEXTURE_BIT);

    glScalef(fsize, fsize, 1.0f);

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

#ifndef _WIN32
glRasterPos4i(0, 0, 0, 0);
#endif
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    float       sPlane[4] = {1.0, 0.0, 0.0, 0.0};
    float       tPlane[4] = {0.0, 1.0, 0.0, 0.0};

    float       ySpacing = btopToBottom ? - fspacing : fspacing;

    for (int j = 0; j < mfstring->getSize(); j++) {
      const char  *str = mfstring->getValue(j);
      int        n = strlen(str);
      if (fhorizontal) {
          sPlane[3] = 0.0f;
          glPushMatrix();
          for (int i = 0; i < n; i++) {
            if (bleftToRight) {
                glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
                glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
                glCallList(font->displayListBase + str[i]);
                sPlane[3] += font->kernX[str[i]];
            } else {
                glTranslatef(-font->kernX[str[i]], 0.0f, 0.0f);
                sPlane[3] -= font->kernX[str[i]];
                glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
                glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
                glPushMatrix();
                glCallList(font->displayListBase + str[i]);
                glPopMatrix();
            }
          }
          glPopMatrix();
          glTranslatef(0.0f, ySpacing, 0.0f);
          tPlane[3] += ySpacing;
      } else {
          tPlane[3] = 0.0f;
          if (!bleftToRight) {
            glTranslatef(-fspacing * 0.5f, 0.0f, 0.0f);
            sPlane[3] += -fspacing * 0.5f;
          }
          glPushMatrix();
          for (int i = 0; i < n; i++) {
            if (btopToBottom) {
                float       y = -font->kernY[str[i]];
                if (y == 0.0) y = -1.0f;  // FIXME:  default advance?
                glTranslatef(0.0f, y, 0.0f);
                tPlane[3] += y;
                glPushMatrix();
                glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
                glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
                glCallList(font->displayListBase + str[i]);
                glPopMatrix();
            } else {
                glPushMatrix();
                glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
                glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
                glCallList(font->displayListBase + str[i]);
                glPopMatrix();
                float       y = font->kernY[str[i]];
                if (y == 0.0) y = 1.0f;   // FIXME:  default advance?
                glTranslatef(0.0f, y, 0.0f);
                tPlane[3] += y;
            }
          }
          glPopMatrix();
          if (bleftToRight) {
            glTranslatef(fspacing * 0.5f, 0.0f, 0.0f);
            sPlane[3] += fspacing * 0.5f;
          }
      }
    }

    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);

    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

    glPopAttrib();
    glPopMatrix();
}

#endif

Generated by  Doxygen 1.6.0   Back to index