Panda3D

textFont.cxx

00001 // Filename: textFont.cxx
00002 // Created by:  drose (08Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "textFont.h"
00016 #include "config_text.h"
00017 #include "string_utils.h"
00018 #include "geomVertexData.h"
00019 #include "geomVertexFormat.h"
00020 #include "geomVertexWriter.h"
00021 #include "geomLinestrips.h"
00022 #include "geom.h"
00023 #include <ctype.h>
00024 
00025 TypeHandle TextFont::_type_handle;
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: TextFont::Constructor
00029 //       Access: Public
00030 //  Description: 
00031 ////////////////////////////////////////////////////////////////////
00032 TextFont::
00033 TextFont() {
00034   _is_valid = false;
00035   _line_height = 1.0f;
00036   _space_advance = 0.25f;
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: TextFont::Copy Constructor
00041 //       Access: Public
00042 //  Description: 
00043 ////////////////////////////////////////////////////////////////////
00044 TextFont::
00045 TextFont(const TextFont &copy) :
00046   Namable(copy),
00047   _is_valid(copy._is_valid),
00048   _line_height(copy._line_height),
00049   _space_advance(copy._space_advance)
00050 {
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: TextFont::Destructor
00055 //       Access: Published, Virtual
00056 //  Description:
00057 ////////////////////////////////////////////////////////////////////
00058 TextFont::
00059 ~TextFont() {
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: TextFont::write
00064 //       Access: Published, Virtual
00065 //  Description:
00066 ////////////////////////////////////////////////////////////////////
00067 void TextFont::
00068 write(ostream &out, int indent_level) const {
00069   indent(out, indent_level)
00070     << "TextFont " << get_name() << "\n";
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: TextFont::get_invalid_glyph
00075 //       Access: Public
00076 //  Description: Returns a special glyph that can be used as a
00077 //               placeholder for any character not in the font.  Note
00078 //               that it is not guaranteed that a font will return
00079 //               this particular glyph for a missing character (it may
00080 //               return a glyph of its own devising instead).  
00081 //
00082 //               Also note that even if a particular accented letter
00083 //               is missing from the font, Panda may still be able to
00084 //               render a suitable replacement by composing different
00085 //               glyphs together to simulate accent marks; this
00086 //               happens automatically behind the scenes.
00087 ////////////////////////////////////////////////////////////////////
00088 TextGlyph *TextFont::
00089 get_invalid_glyph() {
00090   if (_invalid_glyph == (TextGlyph *)NULL) {
00091     make_invalid_glyph();
00092   }
00093   return _invalid_glyph;
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: TextFont::string_render_mode
00098 //       Access: Public
00099 //  Description: Returns the RenderMode value associated with the given
00100 //               string representation, or RM_invalid if the string
00101 //               does not match any known RenderMode value.
00102 ////////////////////////////////////////////////////////////////////
00103 TextFont::RenderMode TextFont::
00104 string_render_mode(const string &string) {
00105   if (cmp_nocase_uh(string, "texture") == 0) {
00106     return RM_texture;
00107   } else if (cmp_nocase_uh(string, "wireframe") == 0) {
00108     return RM_wireframe;
00109   } else if (cmp_nocase_uh(string, "polygon") == 0) {
00110     return RM_polygon;
00111   } else if (cmp_nocase_uh(string, "extruded") == 0) {
00112     return RM_extruded;
00113   } else if (cmp_nocase_uh(string, "solid") == 0) {
00114     return RM_solid;
00115   } else {
00116     return RM_invalid;
00117   }
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: TextFont::string_winding_order
00122 //       Access: Public
00123 //  Description: Returns the WindingOrder value associated with the given
00124 //               string representation, or WO_invalid if the string
00125 //               does not match any known WindingOrder value.
00126 ////////////////////////////////////////////////////////////////////
00127 TextFont::WindingOrder TextFont::
00128 string_winding_order(const string &string) {
00129   if (cmp_nocase_uh(string, "default") == 0) {
00130     return WO_default;
00131   } else if (cmp_nocase_uh(string, "left") == 0) {
00132     return WO_left;
00133   } else if (cmp_nocase_uh(string, "right") == 0) {
00134     return WO_right;
00135   } else {
00136     return WO_invalid;
00137   }
00138 }
00139 
00140 ////////////////////////////////////////////////////////////////////
00141 //     Function: TextFont::make_invalid_glyph
00142 //       Access: Private
00143 //  Description: Constructs the special glyph used to represent a
00144 //               character not in the font.
00145 ////////////////////////////////////////////////////////////////////
00146 void TextFont::
00147 make_invalid_glyph() {
00148   CPT(GeomVertexFormat) vformat = GeomVertexFormat::get_v3();
00149   PT(GeomVertexData) vdata = 
00150     new GeomVertexData("invalid_glyph", vformat, GeomEnums::UH_static);
00151 
00152   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00153   vertex.add_data3(_line_height * 0.2, 0.0f, _line_height * 0.1f);
00154   vertex.add_data3(_line_height * 0.5f, 0.0f, _line_height * 0.1f);
00155   vertex.add_data3(_line_height * 0.5f, 0.0f, _line_height * 0.7f);
00156   vertex.add_data3(_line_height * 0.2, 0.0f, _line_height * 0.7f);
00157 
00158   PT(GeomPrimitive) prim = new GeomLinestrips(GeomEnums::UH_static);
00159   prim->add_consecutive_vertices(0, 4);
00160   prim->add_vertex(0);
00161   prim->close_primitive();
00162 
00163   PT(Geom) geom = new Geom(vdata);
00164   geom->add_primitive(prim);
00165 
00166   _invalid_glyph = new TextGlyph(0, geom, RenderState::make_empty(),
00167                                  _line_height * 0.7f);
00168 }
00169 
00170 ////////////////////////////////////////////////////////////////////
00171 //     Function: TextFont::RenderMode output operator
00172 //  Description:
00173 ////////////////////////////////////////////////////////////////////
00174 ostream &
00175 operator << (ostream &out, TextFont::RenderMode rm) {
00176   switch (rm) {
00177   case TextFont::RM_texture:
00178     return out << "texture";
00179   case TextFont::RM_wireframe:
00180     return out << "wireframe";
00181   case TextFont::RM_polygon:
00182     return out << "polygon";
00183   case TextFont::RM_extruded:
00184     return out << "extruded";
00185   case TextFont::RM_solid:
00186     return out << "solid";
00187 
00188   case TextFont::RM_invalid:
00189     return out << "invalid";
00190   }
00191 
00192   return out << "(**invalid TextFont::RenderMode(" << (int)rm << ")**)";
00193 }
00194 
00195 ////////////////////////////////////////////////////////////////////
00196 //     Function: TextFont::RenderMode input operator
00197 //  Description:
00198 ////////////////////////////////////////////////////////////////////
00199 istream &
00200 operator >> (istream &in, TextFont::RenderMode &rm) {
00201   string word;
00202   in >> word;
00203 
00204   rm = TextFont::string_render_mode(word);
00205   return in;
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: TextFont::WindingOrder output operator
00210 //  Description:
00211 ////////////////////////////////////////////////////////////////////
00212 ostream &
00213 operator << (ostream &out, TextFont::WindingOrder wo) {
00214   switch (wo) {
00215   case TextFont::WO_default:
00216     return out << "default";
00217   case TextFont::WO_left:
00218     return out << "left";
00219   case TextFont::WO_right:
00220     return out << "right";
00221 
00222   case TextFont::WO_invalid:
00223     return out << "invalid";
00224   }
00225 
00226   return out << "(**invalid TextFont::WindingOrder(" << (int)wo << ")**)";
00227 }
00228 
00229 ////////////////////////////////////////////////////////////////////
00230 //     Function: TextFont::WindingOrder input operator
00231 //  Description:
00232 ////////////////////////////////////////////////////////////////////
00233 istream &
00234 operator >> (istream &in, TextFont::WindingOrder &wo) {
00235   string word;
00236   in >> word;
00237 
00238   wo = TextFont::string_winding_order(word);
00239   return in;
00240 }
 All Classes Functions Variables Enumerations