Panda3D
|
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 ©) : 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 }