mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
split TextFont into TextFont and StaticTextFont, preparing for DynamicTextFont
This commit is contained in:
parent
11cf6b7c6b
commit
00e38798ef
@ -108,7 +108,11 @@ class Loader:
|
|||||||
nodePath = hidden.attachNewNode(node)
|
nodePath = hidden.attachNewNode(node)
|
||||||
nodePath.adjustAllPriorities(priority)
|
nodePath.adjustAllPriorities(priority)
|
||||||
# Now create text font from the node
|
# Now create text font from the node
|
||||||
font = TextFont(node)
|
# Temporary try..except for old pandas.
|
||||||
|
try:
|
||||||
|
font = StaticTextFont(node)
|
||||||
|
except:
|
||||||
|
font = TextFont(node)
|
||||||
# And remove node path
|
# And remove node path
|
||||||
nodePath.removeNode()
|
nodePath.removeNode()
|
||||||
return font
|
return font
|
||||||
|
@ -10,13 +10,21 @@
|
|||||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
|
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_text.h textFont.I textFont.h \
|
config_text.h \
|
||||||
|
staticTextFont.I staticTextFont.h \
|
||||||
|
textFont.I textFont.h \
|
||||||
|
textGlyph.I textGlyph.h \
|
||||||
textNode.I textNode.h textNode.cxx
|
textNode.I textNode.h textNode.cxx
|
||||||
|
|
||||||
#define INCLUDED_SOURCES config_text.cxx textFont.cxx
|
#define INCLUDED_SOURCES \
|
||||||
|
config_text.cxx staticTextFont.cxx textFont.cxx textGlyph.cxx
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
config_text.h textFont.I textFont.h textNode.I textNode.h
|
config_text.h \
|
||||||
|
staticTextFont.I staticTextFont.h \
|
||||||
|
textFont.I textFont.h \
|
||||||
|
textGlyph.I textGlyph.h \
|
||||||
|
textNode.I textNode.h
|
||||||
|
|
||||||
#define IGATESCAN all
|
#define IGATESCAN all
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "config_text.h"
|
#include "config_text.h"
|
||||||
|
#include "staticTextFont.h"
|
||||||
#include "textFont.h"
|
#include "textFont.h"
|
||||||
#include "textNode.h"
|
#include "textNode.h"
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ Configure(config_text);
|
|||||||
NotifyCategoryDef(text, "");
|
NotifyCategoryDef(text, "");
|
||||||
|
|
||||||
ConfigureFn(config_text) {
|
ConfigureFn(config_text) {
|
||||||
|
StaticTextFont::init_type();
|
||||||
TextFont::init_type();
|
TextFont::init_type();
|
||||||
TextNode::init_type();
|
TextNode::init_type();
|
||||||
}
|
}
|
||||||
|
18
panda/src/text/staticTextFont.I
Normal file
18
panda/src/text/staticTextFont.I
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Filename: staticTextFont.I
|
||||||
|
// Created by: drose (03May01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
297
panda/src/text/staticTextFont.cxx
Normal file
297
panda/src/text/staticTextFont.cxx
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
// Filename: staticTextFont.cxx
|
||||||
|
// Created by: drose (03May01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "staticTextFont.h"
|
||||||
|
#include "config_text.h"
|
||||||
|
|
||||||
|
#include "geom.h"
|
||||||
|
#include "geomPoint.h"
|
||||||
|
#include "geomNode.h"
|
||||||
|
#include "namedNode.h"
|
||||||
|
#include "renderRelation.h"
|
||||||
|
|
||||||
|
TypeHandle StaticTextFont::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description: The constructor expects the root node to a model
|
||||||
|
// generated via egg-mkfont, which consists of a set of
|
||||||
|
// models, one per each character in the font.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
StaticTextFont::
|
||||||
|
StaticTextFont(Node *font_def) {
|
||||||
|
nassertv(font_def != (Node *)NULL);
|
||||||
|
_font = font_def;
|
||||||
|
_glyphs.clear();
|
||||||
|
|
||||||
|
find_characters(font_def);
|
||||||
|
|
||||||
|
if (_font->is_of_type(NamedNode::get_class_type())) {
|
||||||
|
NamedNode *named_node = DCAST(NamedNode, _font);
|
||||||
|
set_name(named_node->get_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
StaticTextFont::
|
||||||
|
~StaticTextFont() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::write
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void StaticTextFont::
|
||||||
|
write(ostream &out, int indent_level) const {
|
||||||
|
indent(out, indent_level)
|
||||||
|
<< "StaticTextFont " << get_name() << "; "
|
||||||
|
<< _glyphs.size() << " characters available in font:\n";
|
||||||
|
Glyphs::const_iterator gi;
|
||||||
|
|
||||||
|
// Figure out which symbols we have. We collect lowercase letters,
|
||||||
|
// uppercase letters, and digits together for the user's
|
||||||
|
// convenience.
|
||||||
|
static const int num_letters = 26;
|
||||||
|
static const int num_digits = 10;
|
||||||
|
bool lowercase[num_letters];
|
||||||
|
bool uppercase[num_letters];
|
||||||
|
bool digits[num_digits];
|
||||||
|
|
||||||
|
memset(lowercase, 0, sizeof(bool) * num_letters);
|
||||||
|
memset(uppercase, 0, sizeof(bool) * num_letters);
|
||||||
|
memset(digits, 0, sizeof(bool) * num_digits);
|
||||||
|
|
||||||
|
int count_lowercase = 0;
|
||||||
|
int count_uppercase = 0;
|
||||||
|
int count_digits = 0;
|
||||||
|
|
||||||
|
for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
|
||||||
|
int ch = (*gi).first;
|
||||||
|
if (islower(ch)) {
|
||||||
|
count_lowercase++;
|
||||||
|
lowercase[ch - 'a'] = true;
|
||||||
|
|
||||||
|
} else if (isupper(ch)) {
|
||||||
|
count_uppercase++;
|
||||||
|
uppercase[ch - 'A'] = true;
|
||||||
|
|
||||||
|
} else if (isdigit(ch)) {
|
||||||
|
count_digits++;
|
||||||
|
digits[ch - '0'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count_lowercase == num_letters) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "All lowercase letters\n";
|
||||||
|
|
||||||
|
} else if (count_lowercase > 0) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "Some lowercase letters: ";
|
||||||
|
for (int i = 0; i < num_letters; i++) {
|
||||||
|
if (lowercase[i]) {
|
||||||
|
out << (char)(i + 'a');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count_uppercase == num_letters) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "All uppercase letters\n";
|
||||||
|
|
||||||
|
} else if (count_uppercase > 0) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "Some uppercase letters: ";
|
||||||
|
for (int i = 0; i < num_letters; i++) {
|
||||||
|
if (uppercase[i]) {
|
||||||
|
out << (char)(i + 'A');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count_digits == num_digits) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "All digits\n";
|
||||||
|
|
||||||
|
} else if (count_digits > 0) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "Some digits: ";
|
||||||
|
for (int i = 0; i < num_digits; i++) {
|
||||||
|
if (digits[i]) {
|
||||||
|
out << (char)(i + '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
|
||||||
|
int ch = (*gi).first;
|
||||||
|
if (!isalnum(ch)) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< ch;
|
||||||
|
if (isprint(ch)) {
|
||||||
|
out << " = '" << (char)ch << "'\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::get_glyph
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the glyph associated with the given character
|
||||||
|
// code, or NULL if there is no such glyph.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const TextGlyph *StaticTextFont::
|
||||||
|
get_glyph(int character) const {
|
||||||
|
Glyphs::const_iterator gi = _glyphs.find(character);
|
||||||
|
if (gi == _glyphs.end()) {
|
||||||
|
// No definition for this character.
|
||||||
|
return (TextGlyph *)NULL;
|
||||||
|
} else {
|
||||||
|
return &(*gi).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::find_character_gsets
|
||||||
|
// Access: Private
|
||||||
|
// Description: Given that 'root' is a Node containing at least a
|
||||||
|
// polygon and a point which define the character's
|
||||||
|
// appearance and kern position, respectively,
|
||||||
|
// recursively walk the hierarchy and root and locate
|
||||||
|
// those two Geoms.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool StaticTextFont::
|
||||||
|
find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
|
||||||
|
AllTransitionsWrapper &trans) {
|
||||||
|
if (root->is_of_type(GeomNode::get_class_type())) {
|
||||||
|
GeomNode *geode = (GeomNode *)root;
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < geode->get_num_geoms(); i++) {
|
||||||
|
dDrawable *geom = geode->get_geom(i);
|
||||||
|
if (geom->is_of_type(GeomPoint::get_class_type())) {
|
||||||
|
dot = DCAST(GeomPoint, geom);
|
||||||
|
|
||||||
|
} else if (geom->is_of_type(Geom::get_class_type())) {
|
||||||
|
ch = DCAST(Geom, geom);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
TypeHandle graph_type = RenderRelation::get_class_type();
|
||||||
|
int num_children = root->get_num_children(graph_type);
|
||||||
|
for (int i = 0; i < num_children; i++) {
|
||||||
|
NodeRelation *child_arc = root->get_child(graph_type, i);
|
||||||
|
if (find_character_gsets(child_arc->get_child(), ch, dot, trans)) {
|
||||||
|
trans.extract_from(child_arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::find_characters
|
||||||
|
// Access: Private
|
||||||
|
// Description: Walk the hierarchy beginning at the indicated root
|
||||||
|
// and locate any nodes whose names are just integers.
|
||||||
|
// These are taken to be characters, and their
|
||||||
|
// definitions and kern informations are retrieved.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void StaticTextFont::
|
||||||
|
find_characters(Node *root) {
|
||||||
|
string name;
|
||||||
|
if (root->is_of_type(NamedNode::get_class_type())) {
|
||||||
|
name = DCAST(NamedNode, root)->get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_digits = !name.empty();
|
||||||
|
const char *p = name.c_str();
|
||||||
|
while (all_digits && *p != '\0') {
|
||||||
|
// VC++ complains if we treat an int as a bool, so we have to do
|
||||||
|
// this != 0 comparsion on the int isdigit() function to shut it
|
||||||
|
// up.
|
||||||
|
all_digits = (isdigit(*p) != 0);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_digits) {
|
||||||
|
int character = atoi(name.c_str());
|
||||||
|
Geom *ch = NULL;
|
||||||
|
GeomPoint *dot = NULL;
|
||||||
|
AllTransitionsWrapper trans;
|
||||||
|
find_character_gsets(root, ch, dot, trans);
|
||||||
|
if (dot != NULL) {
|
||||||
|
// Get the first vertex from the "dot" geoset. This will be the
|
||||||
|
// origin of the next character.
|
||||||
|
PTA_Vertexf alist;
|
||||||
|
PTA_ushort ilist;
|
||||||
|
float width;
|
||||||
|
dot->get_coords(alist, ilist);
|
||||||
|
if (ilist.empty()) {
|
||||||
|
width = alist[0][0];
|
||||||
|
} else {
|
||||||
|
width = alist[ilist[0]][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
_glyphs[character] = TextGlyph(ch, trans, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (name == "ds") {
|
||||||
|
// The group "ds" is a special node that indicate's the font's
|
||||||
|
// design size, or line height.
|
||||||
|
|
||||||
|
Geom *ch = NULL;
|
||||||
|
GeomPoint *dot = NULL;
|
||||||
|
AllTransitionsWrapper trans;
|
||||||
|
find_character_gsets(root, ch, dot, trans);
|
||||||
|
if (dot != NULL) {
|
||||||
|
// Get the first vertex from the "dot" geoset. This will be the
|
||||||
|
// design size indicator.
|
||||||
|
PTA_Vertexf alist;
|
||||||
|
PTA_ushort ilist;
|
||||||
|
dot->get_coords(alist, ilist);
|
||||||
|
if (ilist.empty()) {
|
||||||
|
_line_height = alist[0][2];
|
||||||
|
} else {
|
||||||
|
_line_height = alist[ilist[0]][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
TypeHandle graph_type = RenderRelation::get_class_type();
|
||||||
|
int num_children = root->get_num_children(graph_type);
|
||||||
|
for (int i = 0; i < num_children; i++) {
|
||||||
|
NodeRelation *child_arc = root->get_child(graph_type, i);
|
||||||
|
find_characters(child_arc->get_child());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
panda/src/text/staticTextFont.h
Normal file
89
panda/src/text/staticTextFont.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Filename: staticTextFont.h
|
||||||
|
// Created by: drose (03May01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef STATICTEXTFONT_H
|
||||||
|
#define STATICTEXTFONT_H
|
||||||
|
|
||||||
|
#include <pandabase.h>
|
||||||
|
|
||||||
|
#include "config_text.h"
|
||||||
|
#include "textFont.h"
|
||||||
|
#include "textGlyph.h"
|
||||||
|
|
||||||
|
#include <typedReferenceCount.h>
|
||||||
|
#include <namable.h>
|
||||||
|
#include <pt_Node.h>
|
||||||
|
#include <allTransitionsWrapper.h>
|
||||||
|
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
class Node;
|
||||||
|
class Geom;
|
||||||
|
class GeomPoint;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : StaticTextFont
|
||||||
|
// Description : A StaticTextFont is loaded up from a model that was
|
||||||
|
// previously generated via egg-mkfont, and contains all
|
||||||
|
// of its glyphs already generated and available for
|
||||||
|
// use. It doesn't require linking with any external
|
||||||
|
// libraries like FreeType.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA StaticTextFont : public TextFont {
|
||||||
|
PUBLISHED:
|
||||||
|
StaticTextFont(Node *font_def);
|
||||||
|
virtual ~StaticTextFont();
|
||||||
|
|
||||||
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual const TextGlyph *get_glyph(int character) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
|
||||||
|
AllTransitionsWrapper &trans);
|
||||||
|
void find_characters(Node *root);
|
||||||
|
|
||||||
|
typedef pmap<int, TextGlyph> Glyphs;
|
||||||
|
Glyphs _glyphs;
|
||||||
|
float _font_height;
|
||||||
|
PT_Node _font;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
TextFont::init_type();
|
||||||
|
register_type(_type_handle, "StaticTextFont",
|
||||||
|
TextFont::get_class_type());
|
||||||
|
}
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class TextNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "staticTextFont.I"
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
// Filename: textFont.I
|
// Filename: textFont.I
|
||||||
// Created by: drose (03May01)
|
// Created by: drose (08Feb02)
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -21,26 +21,9 @@
|
|||||||
// Function: TextFont::get_line_height
|
// Function: TextFont::get_line_height
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the number of units high each line of text
|
// Description: Returns the number of units high each line of text
|
||||||
// is. This is based on the font.
|
// is.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float TextFont::
|
INLINE float TextFont::
|
||||||
get_line_height() const {
|
get_line_height() const {
|
||||||
return _font_height;
|
return _line_height;
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: TextFont::get_line_height
|
|
||||||
// Access: Published
|
|
||||||
// Description: Returns the number of units high each line of text
|
|
||||||
// is. This is based on the font.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE const TextFont::CharDef *TextFont::
|
|
||||||
get_char(int character) const {
|
|
||||||
CharDefs::const_iterator cdi = _defs.find(character);
|
|
||||||
if (cdi == _defs.end()) {
|
|
||||||
// No definition for this character.
|
|
||||||
return (CharDef *)NULL;
|
|
||||||
} else {
|
|
||||||
return &(*cdi).second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Filename: textFont.cxx
|
// Filename: textFont.cxx
|
||||||
// Created by: drose (03May01)
|
// Created by: drose (08Feb02)
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -18,17 +18,11 @@
|
|||||||
|
|
||||||
#include "textFont.h"
|
#include "textFont.h"
|
||||||
#include "config_text.h"
|
#include "config_text.h"
|
||||||
|
|
||||||
#include "geom.h"
|
|
||||||
#include "geomPoint.h"
|
|
||||||
#include "geomNode.h"
|
|
||||||
#include "namedNode.h"
|
|
||||||
#include "renderRelation.h"
|
|
||||||
|
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
|
||||||
TypeHandle TextFont::_type_handle;
|
TypeHandle TextFont::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: isblank
|
// Function: isblank
|
||||||
// Description: An internal function, similar to isspace(), except it
|
// Description: An internal function, similar to isspace(), except it
|
||||||
@ -39,40 +33,19 @@ isblank(char ch) {
|
|||||||
return (ch == ' ' || ch == '\t');
|
return (ch == ' ' || ch == '\t');
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: TextFont::CharDef::Constructor
|
|
||||||
// Access: Public
|
|
||||||
// Description:
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
TextFont::CharDef::
|
|
||||||
CharDef(Geom *geom, float width, const AllTransitionsWrapper &trans) :
|
|
||||||
_geom(geom), _width(width), _trans(trans) { }
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::Constructor
|
// Function: TextFont::Constructor
|
||||||
// Access: Published
|
// Access: Public
|
||||||
// Description: The constructor expects the root node to a model
|
// Description:
|
||||||
// generated via egg-mkfont, which consists of a set of
|
|
||||||
// models, one per each character in the font.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
TextFont::
|
TextFont::
|
||||||
TextFont(Node *font_def) {
|
TextFont() {
|
||||||
nassertv(font_def != (Node *)NULL);
|
_line_height = 1.0;
|
||||||
_font = font_def;
|
|
||||||
_defs.clear();
|
|
||||||
_font_height = 1.0;
|
|
||||||
|
|
||||||
find_characters(font_def);
|
|
||||||
|
|
||||||
if (_font->is_of_type(NamedNode::get_class_type())) {
|
|
||||||
NamedNode *named_node = DCAST(NamedNode, _font);
|
|
||||||
set_name(named_node->get_name());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::Destructor
|
// Function: TextFont::Destructor
|
||||||
// Access: Published
|
// Access: Published, Virtual
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
TextFont::
|
TextFont::
|
||||||
@ -86,19 +59,19 @@ TextFont::
|
|||||||
// or 0.0 if the character is not known.
|
// or 0.0 if the character is not known.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float TextFont::
|
float TextFont::
|
||||||
calc_width(char ch) const {
|
calc_width(int ch) const {
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
// A space is a special case.
|
// A space is a special case.
|
||||||
return 0.25;
|
return 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharDefs::const_iterator cdi = _defs.find(ch);
|
const TextGlyph *glyph = get_glyph(ch);
|
||||||
if (cdi == _defs.end()) {
|
if (glyph == (TextGlyph *)NULL) {
|
||||||
// Unknown character.
|
// Unknown character.
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*cdi).second._width;
|
return glyph->get_advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -242,224 +215,13 @@ wordwrap_to(const string &text, float wordwrap_width,
|
|||||||
return output_text;
|
return output_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::write
|
// Function: TextFont::write
|
||||||
// Access: Published
|
// Access: Published, Virtual
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void TextFont::
|
void TextFont::
|
||||||
write(ostream &out, int indent_level) const {
|
write(ostream &out, int indent_level) const {
|
||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "TextFont " << get_name() << "; "
|
<< "TextFont " << get_name() << "\n";
|
||||||
<< _defs.size() << " characters available in font:\n";
|
|
||||||
CharDefs::const_iterator di;
|
|
||||||
|
|
||||||
// Figure out which symbols we have. We collect lowercase letters,
|
|
||||||
// uppercase letters, and digits together for the user's
|
|
||||||
// convenience.
|
|
||||||
static const int num_letters = 26;
|
|
||||||
static const int num_digits = 10;
|
|
||||||
bool lowercase[num_letters];
|
|
||||||
bool uppercase[num_letters];
|
|
||||||
bool digits[num_digits];
|
|
||||||
|
|
||||||
memset(lowercase, 0, sizeof(bool) * num_letters);
|
|
||||||
memset(uppercase, 0, sizeof(bool) * num_letters);
|
|
||||||
memset(digits, 0, sizeof(bool) * num_digits);
|
|
||||||
|
|
||||||
int count_lowercase = 0;
|
|
||||||
int count_uppercase = 0;
|
|
||||||
int count_digits = 0;
|
|
||||||
|
|
||||||
for (di = _defs.begin(); di != _defs.end(); ++di) {
|
|
||||||
int ch = (*di).first;
|
|
||||||
if (islower(ch)) {
|
|
||||||
count_lowercase++;
|
|
||||||
lowercase[ch - 'a'] = true;
|
|
||||||
|
|
||||||
} else if (isupper(ch)) {
|
|
||||||
count_uppercase++;
|
|
||||||
uppercase[ch - 'A'] = true;
|
|
||||||
|
|
||||||
} else if (isdigit(ch)) {
|
|
||||||
count_digits++;
|
|
||||||
digits[ch - '0'] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count_lowercase == num_letters) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "All lowercase letters\n";
|
|
||||||
|
|
||||||
} else if (count_lowercase > 0) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "Some lowercase letters: ";
|
|
||||||
for (int i = 0; i < num_letters; i++) {
|
|
||||||
if (lowercase[i]) {
|
|
||||||
out << (char)(i + 'a');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count_uppercase == num_letters) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "All uppercase letters\n";
|
|
||||||
|
|
||||||
} else if (count_uppercase > 0) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "Some uppercase letters: ";
|
|
||||||
for (int i = 0; i < num_letters; i++) {
|
|
||||||
if (uppercase[i]) {
|
|
||||||
out << (char)(i + 'A');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count_digits == num_digits) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "All digits\n";
|
|
||||||
|
|
||||||
} else if (count_digits > 0) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< "Some digits: ";
|
|
||||||
for (int i = 0; i < num_digits; i++) {
|
|
||||||
if (digits[i]) {
|
|
||||||
out << (char)(i + '0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (di = _defs.begin(); di != _defs.end(); ++di) {
|
|
||||||
int ch = (*di).first;
|
|
||||||
if (!isalnum(ch)) {
|
|
||||||
indent(out, indent_level + 2)
|
|
||||||
<< ch;
|
|
||||||
if (isprint(ch)) {
|
|
||||||
out << " = '" << (char)ch << "'\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: TextFont::find_character_gsets
|
|
||||||
// Access: Private
|
|
||||||
// Description: Given that 'root' is a Node containing at least a
|
|
||||||
// polygon and a point which define the character's
|
|
||||||
// appearance and kern position, respectively,
|
|
||||||
// recursively walk the hierarchy and root and locate
|
|
||||||
// those two Geoms.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool TextFont::
|
|
||||||
find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
|
|
||||||
AllTransitionsWrapper &trans) {
|
|
||||||
if (root->is_of_type(GeomNode::get_class_type())) {
|
|
||||||
GeomNode *geode = (GeomNode *)root;
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
for (int i = 0; i < geode->get_num_geoms(); i++) {
|
|
||||||
dDrawable *geom = geode->get_geom(i);
|
|
||||||
if (geom->is_of_type(GeomPoint::get_class_type())) {
|
|
||||||
dot = DCAST(GeomPoint, geom);
|
|
||||||
|
|
||||||
} else if (geom->is_of_type(Geom::get_class_type())) {
|
|
||||||
ch = DCAST(Geom, geom);
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
TypeHandle graph_type = RenderRelation::get_class_type();
|
|
||||||
int num_children = root->get_num_children(graph_type);
|
|
||||||
for (int i = 0; i < num_children; i++) {
|
|
||||||
NodeRelation *child_arc = root->get_child(graph_type, i);
|
|
||||||
if (find_character_gsets(child_arc->get_child(), ch, dot, trans)) {
|
|
||||||
trans.extract_from(child_arc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: TextFont::find_characters
|
|
||||||
// Access: Private
|
|
||||||
// Description: Walk the hierarchy beginning at the indicated root
|
|
||||||
// and locate any nodes whose names are just integers.
|
|
||||||
// These are taken to be characters, and their
|
|
||||||
// definitions and kern informations are retrieved.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void TextFont::
|
|
||||||
find_characters(Node *root) {
|
|
||||||
string name;
|
|
||||||
if (root->is_of_type(NamedNode::get_class_type())) {
|
|
||||||
name = DCAST(NamedNode, root)->get_name();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool all_digits = !name.empty();
|
|
||||||
const char *p = name.c_str();
|
|
||||||
while (all_digits && *p != '\0') {
|
|
||||||
// VC++ complains if we treat an int as a bool, so we have to do
|
|
||||||
// this != 0 comparsion on the int isdigit() function to shut it
|
|
||||||
// up.
|
|
||||||
all_digits = (isdigit(*p) != 0);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_digits) {
|
|
||||||
int character = atoi(name.c_str());
|
|
||||||
Geom *ch = NULL;
|
|
||||||
GeomPoint *dot = NULL;
|
|
||||||
AllTransitionsWrapper trans;
|
|
||||||
find_character_gsets(root, ch, dot, trans);
|
|
||||||
if (dot != NULL) {
|
|
||||||
// Get the first vertex from the "dot" geoset. This will be the
|
|
||||||
// origin of the next character.
|
|
||||||
PTA_Vertexf alist;
|
|
||||||
PTA_ushort ilist;
|
|
||||||
float width;
|
|
||||||
dot->get_coords(alist, ilist);
|
|
||||||
if (ilist.empty()) {
|
|
||||||
width = alist[0][0];
|
|
||||||
} else {
|
|
||||||
width = alist[ilist[0]][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
_defs[character] = CharDef(ch, width, trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (name == "ds") {
|
|
||||||
// The group "ds" is a special node that indicate's the font's
|
|
||||||
// design size, or line height.
|
|
||||||
|
|
||||||
Geom *ch = NULL;
|
|
||||||
GeomPoint *dot = NULL;
|
|
||||||
AllTransitionsWrapper trans;
|
|
||||||
find_character_gsets(root, ch, dot, trans);
|
|
||||||
if (dot != NULL) {
|
|
||||||
// Get the first vertex from the "dot" geoset. This will be the
|
|
||||||
// design size indicator.
|
|
||||||
PTA_Vertexf alist;
|
|
||||||
PTA_ushort ilist;
|
|
||||||
dot->get_coords(alist, ilist);
|
|
||||||
if (ilist.empty()) {
|
|
||||||
_font_height = alist[0][2];
|
|
||||||
} else {
|
|
||||||
_font_height = alist[ilist[0]][2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
TypeHandle graph_type = RenderRelation::get_class_type();
|
|
||||||
int num_children = root->get_num_children(graph_type);
|
|
||||||
for (int i = 0; i < num_children; i++) {
|
|
||||||
NodeRelation *child_arc = root->get_child(graph_type, i);
|
|
||||||
find_characters(child_arc->get_child());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Filename: textFont.h
|
// Filename: textFont.h
|
||||||
// Created by: drose (03May01)
|
// Created by: drose (08Feb02)
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -19,61 +19,47 @@
|
|||||||
#ifndef TEXTFONT_H
|
#ifndef TEXTFONT_H
|
||||||
#define TEXTFONT_H
|
#define TEXTFONT_H
|
||||||
|
|
||||||
#include <pandabase.h>
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "config_text.h"
|
#include "config_text.h"
|
||||||
|
#include "typedReferenceCount.h"
|
||||||
#include <typedReferenceCount.h>
|
#include "namable.h"
|
||||||
#include <namable.h>
|
|
||||||
#include <pt_Node.h>
|
|
||||||
#include <allTransitionsWrapper.h>
|
|
||||||
|
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
class Geom;
|
class TextGlyph;
|
||||||
class GeomPoint;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : TextFont
|
// Class : TextFont
|
||||||
// Description :
|
// Description : An encapsulation of a font; i.e. a set of glyphs that
|
||||||
|
// may be assembled together by a TextNode to represent
|
||||||
|
// a string of text.
|
||||||
|
//
|
||||||
|
// This is just an abstract interface; see
|
||||||
|
// StaticTextFont or DynamicTextFont for an actual
|
||||||
|
// implementation.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA TextFont : public TypedReferenceCount, public Namable {
|
class EXPCL_PANDA TextFont : public TypedReferenceCount, public Namable {
|
||||||
|
public:
|
||||||
|
TextFont();
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
TextFont(Node *font_def);
|
virtual ~TextFont();
|
||||||
~TextFont();
|
|
||||||
|
|
||||||
INLINE float get_line_height() const;
|
INLINE float get_line_height() const;
|
||||||
|
|
||||||
float calc_width(char ch) const;
|
float calc_width(int ch) const;
|
||||||
float calc_width(const string &line) const;
|
float calc_width(const string &line) const;
|
||||||
string wordwrap_to(const string &text, float wordwrap_width,
|
string wordwrap_to(const string &text, float wordwrap_width,
|
||||||
bool preserve_trailing_whitespace) const;
|
bool preserve_trailing_whitespace) const;
|
||||||
|
|
||||||
void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
// Private interfaces for the benefit of TextNode.
|
virtual const TextGlyph *get_glyph(int character) const=0;
|
||||||
class CharDef {
|
|
||||||
public:
|
|
||||||
CharDef() { }
|
|
||||||
CharDef(Geom *geom, float width, const AllTransitionsWrapper &trans);
|
|
||||||
Geom *_geom;
|
|
||||||
float _width;
|
|
||||||
AllTransitionsWrapper _trans;
|
|
||||||
};
|
|
||||||
|
|
||||||
INLINE const CharDef *get_char(int character) const;
|
protected:
|
||||||
|
float _line_height;
|
||||||
private:
|
|
||||||
bool find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
|
|
||||||
AllTransitionsWrapper &trans);
|
|
||||||
void find_characters(Node *root);
|
|
||||||
|
|
||||||
typedef pmap<int, CharDef> CharDefs;
|
|
||||||
CharDefs _defs;
|
|
||||||
float _font_height;
|
|
||||||
PT_Node _font;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
@ -91,8 +77,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
friend class TextNode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "textFont.I"
|
#include "textFont.I"
|
||||||
|
97
panda/src/text/textGlyph.I
Normal file
97
panda/src/text/textGlyph.I
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Filename: textGlyph.I
|
||||||
|
// Created by: drose (08Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::Default constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description: This constructor makes an invalid glyph.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextGlyph::
|
||||||
|
TextGlyph() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextGlyph::
|
||||||
|
TextGlyph(Geom *geom, const AllTransitionsWrapper &trans, float advance) :
|
||||||
|
_geom(geom), _trans(trans), _advance(advance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::Copy Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextGlyph::
|
||||||
|
TextGlyph(const TextGlyph ©) :
|
||||||
|
_geom(copy._geom),
|
||||||
|
_trans(copy._trans),
|
||||||
|
_advance(copy._advance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::Copy Assignment Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void TextGlyph::
|
||||||
|
operator = (const TextGlyph ©) {
|
||||||
|
_geom = copy._geom;
|
||||||
|
_trans = copy._trans;
|
||||||
|
_advance = copy._advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::get_geom
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns a Geom that renders the particular glyph.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE Geom *TextGlyph::
|
||||||
|
get_geom() const {
|
||||||
|
return _geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::get_trans
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the state transitions that should be applied
|
||||||
|
// to the glyph geometry to render it correctly.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const AllTransitionsWrapper &TextGlyph::
|
||||||
|
get_trans() const {
|
||||||
|
return _trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextGlyph::get_advance
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the distance by which the character pointer
|
||||||
|
// should be advanced after placing this character;
|
||||||
|
// i.e. the approximate width the character takes up on
|
||||||
|
// the line.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float TextGlyph::
|
||||||
|
get_advance() const {
|
||||||
|
return _advance;
|
||||||
|
}
|
19
panda/src/text/textGlyph.cxx
Normal file
19
panda/src/text/textGlyph.cxx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Filename: textGlyph.cxx
|
||||||
|
// Created by: drose (08Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "textGlyph.h"
|
53
panda/src/text/textGlyph.h
Normal file
53
panda/src/text/textGlyph.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Filename: textGlyph.h
|
||||||
|
// Created by: drose (08Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TEXTGLYPH_H
|
||||||
|
#define TEXTGLYPH_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "allTransitionsWrapper.h"
|
||||||
|
|
||||||
|
class Geom;
|
||||||
|
class TextGlyph;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : TextGlyph
|
||||||
|
// Description : A representation of a single glyph (character) from a
|
||||||
|
// font. This is a piece of renderable geometry of some
|
||||||
|
// kind.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class TextGlyph {
|
||||||
|
public:
|
||||||
|
INLINE TextGlyph();
|
||||||
|
INLINE TextGlyph(Geom *geom, const AllTransitionsWrapper &trans, float advance);
|
||||||
|
INLINE TextGlyph(const TextGlyph ©);
|
||||||
|
INLINE void operator = (const TextGlyph ©);
|
||||||
|
|
||||||
|
INLINE Geom *get_geom() const;
|
||||||
|
INLINE const AllTransitionsWrapper &get_trans() const;
|
||||||
|
INLINE float get_advance() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Geom *_geom;
|
||||||
|
AllTransitionsWrapper _trans;
|
||||||
|
float _advance;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "textGlyph.I"
|
||||||
|
|
||||||
|
#endif
|
@ -16,6 +16,7 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
#include "textNode.h"
|
#include "textNode.h"
|
||||||
|
#include "textGlyph.h"
|
||||||
#include "config_text.h"
|
#include "config_text.h"
|
||||||
|
|
||||||
#include "compose_matrix.h"
|
#include "compose_matrix.h"
|
||||||
@ -447,12 +448,12 @@ assemble_row(const char *&source, Node *dest) {
|
|||||||
} else {
|
} else {
|
||||||
// A printable character.
|
// A printable character.
|
||||||
|
|
||||||
const TextFont::CharDef *def = _font->get_char(character);
|
const TextGlyph *glyph = _font->get_glyph(character);
|
||||||
if (def == (const TextFont::CharDef *)NULL) {
|
if (glyph == (const TextGlyph *)NULL) {
|
||||||
text_cat.warning()
|
text_cat.warning()
|
||||||
<< "No definition in " << _font->get_name()
|
<< "No definition in " << _font->get_name()
|
||||||
<< " for character " << character;
|
<< " for character " << character;
|
||||||
if (isprint(character)) {
|
if (character < 128 && isprint(character)) {
|
||||||
text_cat.warning(false)
|
text_cat.warning(false)
|
||||||
<< " ('" << (char)character << "')";
|
<< " ('" << (char)character << "')";
|
||||||
}
|
}
|
||||||
@ -460,9 +461,9 @@ assemble_row(const char *&source, Node *dest) {
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Geom *char_geom = def->_geom;
|
Geom *char_geom = glyph->get_geom();
|
||||||
float char_width = def->_width;
|
float char_advance = glyph->get_advance();
|
||||||
const AllTransitionsWrapper &trans = def->_trans;
|
const AllTransitionsWrapper &trans = glyph->get_trans();
|
||||||
|
|
||||||
LMatrix4f mat = LMatrix4f::ident_mat();
|
LMatrix4f mat = LMatrix4f::ident_mat();
|
||||||
mat.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
mat.set_row(3, LVector3f(xpos, 0.0f, 0.0f));
|
||||||
@ -475,7 +476,7 @@ assemble_row(const char *&source, Node *dest) {
|
|||||||
trans.store_to(rel);
|
trans.store_to(rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
xpos += char_width;
|
xpos += char_advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source++;
|
source++;
|
||||||
@ -575,10 +576,10 @@ measure_row(const char *&source) {
|
|||||||
} else {
|
} else {
|
||||||
// A printable character.
|
// A printable character.
|
||||||
|
|
||||||
const TextFont::CharDef *def = _font->get_char(character);
|
const TextGlyph *glyph = _font->get_glyph(character);
|
||||||
if (def != (const TextFont::CharDef *)NULL) {
|
if (glyph != (const TextGlyph *)NULL) {
|
||||||
float char_width = def->_width;
|
float char_advance = glyph->get_advance();
|
||||||
xpos += char_width;
|
xpos += char_advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source++;
|
source++;
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
#include "config_text.cxx"
|
#include "config_text.cxx"
|
||||||
|
#include "staticTextFont.cxx"
|
||||||
#include "textFont.cxx"
|
#include "textFont.cxx"
|
||||||
|
#include "textGlyph.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user