mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
provide a default font
This commit is contained in:
parent
b65a885478
commit
7a7563ba2d
@ -390,6 +390,14 @@
|
|||||||
#define FREETYPE_LPATH
|
#define FREETYPE_LPATH
|
||||||
#define FREETYPE_LIBS
|
#define FREETYPE_LIBS
|
||||||
|
|
||||||
|
// Define this true to compile in a default font, so every TextNode
|
||||||
|
// will always have a font available without requiring the user to
|
||||||
|
// specify one. Define it empty not to do this, saving a few
|
||||||
|
// kilobytes on the generated library. Sorry, you can't pick a
|
||||||
|
// particular font to be the default; it's hardcoded in the source.
|
||||||
|
// This does require the Freetype library, above.
|
||||||
|
#define COMPILE_IN_DEFAULT_FONT 1
|
||||||
|
|
||||||
// Is Maya installed? This matters only to programs in PANDATOOL.
|
// Is Maya installed? This matters only to programs in PANDATOOL.
|
||||||
#define MAYA_LOCATION /usr/aw/maya3.0
|
#define MAYA_LOCATION /usr/aw/maya3.0
|
||||||
#defer MAYA_LIBS $[if $[WINDOWS_PLATFORM],Foundation.lib OpenMaya.lib OpenMayaAnim.lib,Foundation OpenMaya OpenMayaAnim]
|
#defer MAYA_LIBS $[if $[WINDOWS_PLATFORM],Foundation.lib OpenMaya.lib OpenMayaAnim.lib,Foundation OpenMaya OpenMayaAnim]
|
||||||
|
@ -22,6 +22,9 @@ $[cdefine HAVE_RAD_MSS]
|
|||||||
/* Define if we have Freetype 2.0 or better available. */
|
/* Define if we have Freetype 2.0 or better available. */
|
||||||
$[cdefine HAVE_FREETYPE]
|
$[cdefine HAVE_FREETYPE]
|
||||||
|
|
||||||
|
/* Define if we want to compile in a default font. */
|
||||||
|
$[cdefine COMPILE_IN_DEFAULT_FONT]
|
||||||
|
|
||||||
/* Define if we have Maya available. */
|
/* Define if we have Maya available. */
|
||||||
$[cdefine HAVE_MAYA]
|
$[cdefine HAVE_MAYA]
|
||||||
|
|
||||||
|
@ -13,9 +13,11 @@
|
|||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_text.h \
|
config_text.h \
|
||||||
|
default_font.h \
|
||||||
dynamicTextFont.I dynamicTextFont.h \
|
dynamicTextFont.I dynamicTextFont.h \
|
||||||
dynamicTextGlyph.I dynamicTextGlyph.h \
|
dynamicTextGlyph.I dynamicTextGlyph.h \
|
||||||
dynamicTextPage.I dynamicTextPage.h \
|
dynamicTextPage.I dynamicTextPage.h \
|
||||||
|
fontPool.I fontPool.h \
|
||||||
geomTextGlyph.I geomTextGlyph.h \
|
geomTextGlyph.I geomTextGlyph.h \
|
||||||
staticTextFont.I staticTextFont.h \
|
staticTextFont.I staticTextFont.h \
|
||||||
stringDecoder.I stringDecoder.h \
|
stringDecoder.I stringDecoder.h \
|
||||||
@ -25,9 +27,11 @@
|
|||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
config_text.cxx \
|
config_text.cxx \
|
||||||
|
default_font.cxx \
|
||||||
dynamicTextFont.cxx \
|
dynamicTextFont.cxx \
|
||||||
dynamicTextGlyph.cxx \
|
dynamicTextGlyph.cxx \
|
||||||
dynamicTextPage.cxx \
|
dynamicTextPage.cxx \
|
||||||
|
fontPool.cxx \
|
||||||
geomTextGlyph.cxx \
|
geomTextGlyph.cxx \
|
||||||
stringDecoder.cxx \
|
stringDecoder.cxx \
|
||||||
staticTextFont.cxx \
|
staticTextFont.cxx \
|
||||||
@ -38,6 +42,7 @@
|
|||||||
dynamicTextFont.I dynamicTextFont.h \
|
dynamicTextFont.I dynamicTextFont.h \
|
||||||
dynamicTextGlyph.I dynamicTextGlyph.h \
|
dynamicTextGlyph.I dynamicTextGlyph.h \
|
||||||
dynamicTextPage.I dynamicTextPage.h \
|
dynamicTextPage.I dynamicTextPage.h \
|
||||||
|
fontPool.I fontPool.h \
|
||||||
geomTextGlyph.I geomTextGlyph.h \
|
geomTextGlyph.I geomTextGlyph.h \
|
||||||
staticTextFont.I staticTextFont.h \
|
staticTextFont.I staticTextFont.h \
|
||||||
stringDecoder.I stringDecoder.h \
|
stringDecoder.I stringDecoder.h \
|
||||||
|
@ -45,6 +45,7 @@ const float text_pixels_per_unit = config_text.GetFloat("text-pixels-per-unit",
|
|||||||
const float text_scale_factor = config_text.GetFloat("text-scale-factor", 2.0f);
|
const float text_scale_factor = config_text.GetFloat("text-scale-factor", 2.0f);
|
||||||
const bool text_small_caps = config_text.GetBool("text-small-caps", false);
|
const bool text_small_caps = config_text.GetBool("text-small-caps", false);
|
||||||
const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
|
const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
|
||||||
|
const string text_default_font = config_text.GetString("text-default-font", "");
|
||||||
|
|
||||||
Texture::FilterType text_minfilter = Texture::FT_invalid;
|
Texture::FilterType text_minfilter = Texture::FT_invalid;
|
||||||
Texture::FilterType text_magfilter = Texture::FT_invalid;
|
Texture::FilterType text_magfilter = Texture::FT_invalid;
|
||||||
@ -79,11 +80,11 @@ init_libtext() {
|
|||||||
|
|
||||||
string text_encoding = config_text.GetString("text-encoding", "iso8859");
|
string text_encoding = config_text.GetString("text-encoding", "iso8859");
|
||||||
if (text_encoding == "iso8859") {
|
if (text_encoding == "iso8859") {
|
||||||
TextNode::_default_encoding = TextNode::E_iso8859;
|
TextNode::set_default_encoding(TextNode::E_iso8859);
|
||||||
} else if (text_encoding == "utf8") {
|
} else if (text_encoding == "utf8") {
|
||||||
TextNode::_default_encoding = TextNode::E_utf8;
|
TextNode::set_default_encoding(TextNode::E_utf8);
|
||||||
} else if (text_encoding == "unicode") {
|
} else if (text_encoding == "unicode") {
|
||||||
TextNode::_default_encoding = TextNode::E_unicode;
|
TextNode::set_default_encoding(TextNode::E_unicode);
|
||||||
} else {
|
} else {
|
||||||
text_cat.error()
|
text_cat.error()
|
||||||
<< "Invalid text-encoding: " << text_encoding << "\n";
|
<< "Invalid text-encoding: " << text_encoding << "\n";
|
||||||
|
@ -39,6 +39,7 @@ extern const float text_pixels_per_unit;
|
|||||||
extern const float text_scale_factor;
|
extern const float text_scale_factor;
|
||||||
extern const bool text_small_caps;
|
extern const bool text_small_caps;
|
||||||
extern const float text_small_caps_scale;
|
extern const float text_small_caps_scale;
|
||||||
|
extern const string text_default_font;
|
||||||
|
|
||||||
extern Texture::FilterType text_minfilter;
|
extern Texture::FilterType text_minfilter;
|
||||||
extern Texture::FilterType text_magfilter;
|
extern Texture::FilterType text_magfilter;
|
||||||
|
3365
panda/src/text/default_font.cxx
Normal file
3365
panda/src/text/default_font.cxx
Normal file
File diff suppressed because it is too large
Load Diff
32
panda/src/text/default_font.h
Normal file
32
panda/src/text/default_font.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Filename: default_font.h
|
||||||
|
// Created by: drose (31Jan03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 DEFAULT_FONT_H
|
||||||
|
#define DEFAULT_FONT_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_FREETYPE) && defined(COMPILE_IN_DEFAULT_FONT)
|
||||||
|
|
||||||
|
extern const char default_font_data[];
|
||||||
|
extern const int default_font_size;
|
||||||
|
|
||||||
|
#endif // HAVE_FREETYPE && COMPILE_IN_DEFAULT_FONT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -52,33 +52,8 @@ static const float points_per_inch = 72.0f;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
DynamicTextFont::
|
DynamicTextFont::
|
||||||
DynamicTextFont(const Filename &font_filename, int face_index) {
|
DynamicTextFont(const Filename &font_filename, int face_index) {
|
||||||
_texture_margin = text_texture_margin;
|
initialize();
|
||||||
_poly_margin = text_poly_margin;
|
|
||||||
_page_x_size = text_page_x_size;
|
|
||||||
_page_y_size = text_page_y_size;
|
|
||||||
_point_size = text_point_size;
|
|
||||||
_tex_pixels_per_unit = text_pixels_per_unit;
|
|
||||||
_scale_factor = text_scale_factor;
|
|
||||||
_small_caps = text_small_caps;
|
|
||||||
_small_caps_scale = text_small_caps_scale;
|
|
||||||
|
|
||||||
// We don't necessarily want to use mipmaps, since we don't want to
|
|
||||||
// regenerate those every time the texture changes, but we probably
|
|
||||||
// do want at least linear filtering. Use whatever the Configrc
|
|
||||||
// file suggests.
|
|
||||||
_minfilter = text_minfilter;
|
|
||||||
_magfilter = text_magfilter;
|
|
||||||
|
|
||||||
// Anisotropic filtering can help the look of the text, and doesn't
|
|
||||||
// require generating mipmaps, but does require hardware support.
|
|
||||||
_anisotropic_degree = text_anisotropic_degree;
|
|
||||||
|
|
||||||
|
|
||||||
_preferred_page = 0;
|
|
||||||
|
|
||||||
if (!_ft_initialized) {
|
|
||||||
initialize_ft_library();
|
|
||||||
}
|
|
||||||
if (!_ft_ok) {
|
if (!_ft_ok) {
|
||||||
text_cat.error()
|
text_cat.error()
|
||||||
<< "Unable to read font " << font_filename
|
<< "Unable to read font " << font_filename
|
||||||
@ -136,6 +111,50 @@ DynamicTextFont(const Filename &font_filename, int face_index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description: This constructor accepts a table of data representing
|
||||||
|
// the font file, loaded from some source other than a
|
||||||
|
// filename on disk.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DynamicTextFont::
|
||||||
|
DynamicTextFont(const char *font_data, int data_length, int face_index) {
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
if (!_ft_ok) {
|
||||||
|
text_cat.error()
|
||||||
|
<< "Unable to read font: FreeType library not initialized properly.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int error;
|
||||||
|
error = FT_New_Memory_Face(_ft_library,
|
||||||
|
(const FT_Byte *)font_data, data_length,
|
||||||
|
face_index, &_face);
|
||||||
|
|
||||||
|
if (error == FT_Err_Unknown_File_Format) {
|
||||||
|
text_cat.error()
|
||||||
|
<< "Unable to read font: unknown file format.\n";
|
||||||
|
} else if (error) {
|
||||||
|
text_cat.error()
|
||||||
|
<< "Unable to read font: invalid.\n";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
string name = _face->family_name;
|
||||||
|
if (_face->style_name != NULL) {
|
||||||
|
name += " ";
|
||||||
|
name += _face->style_name;
|
||||||
|
}
|
||||||
|
set_name(name);
|
||||||
|
|
||||||
|
text_cat.info()
|
||||||
|
<< "Loaded font " << get_name() << "\n";
|
||||||
|
_is_valid = true;
|
||||||
|
reset_scale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::Constructor
|
// Function: DynamicTextFont::Constructor
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -334,6 +353,43 @@ get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) {
|
|||||||
return (glyph_index != 0 && glyph != (DynamicTextGlyph *)NULL);
|
return (glyph_index != 0 && glyph != (DynamicTextGlyph *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::initialize
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called from both constructors to set up some internal
|
||||||
|
// structures.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DynamicTextFont::
|
||||||
|
initialize() {
|
||||||
|
_texture_margin = text_texture_margin;
|
||||||
|
_poly_margin = text_poly_margin;
|
||||||
|
_page_x_size = text_page_x_size;
|
||||||
|
_page_y_size = text_page_y_size;
|
||||||
|
_point_size = text_point_size;
|
||||||
|
_tex_pixels_per_unit = text_pixels_per_unit;
|
||||||
|
_scale_factor = text_scale_factor;
|
||||||
|
_small_caps = text_small_caps;
|
||||||
|
_small_caps_scale = text_small_caps_scale;
|
||||||
|
|
||||||
|
// We don't necessarily want to use mipmaps, since we don't want to
|
||||||
|
// regenerate those every time the texture changes, but we probably
|
||||||
|
// do want at least linear filtering. Use whatever the Configrc
|
||||||
|
// file suggests.
|
||||||
|
_minfilter = text_minfilter;
|
||||||
|
_magfilter = text_magfilter;
|
||||||
|
|
||||||
|
// Anisotropic filtering can help the look of the text, and doesn't
|
||||||
|
// require generating mipmaps, but does require hardware support.
|
||||||
|
_anisotropic_degree = text_anisotropic_degree;
|
||||||
|
|
||||||
|
|
||||||
|
_preferred_page = 0;
|
||||||
|
|
||||||
|
if (!_ft_initialized) {
|
||||||
|
initialize_ft_library();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::update_filters
|
// Function: DynamicTextFont::update_filters
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
class EXPCL_PANDA DynamicTextFont : public TextFont {
|
class EXPCL_PANDA DynamicTextFont : public TextFont {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
DynamicTextFont(const Filename &font_filename, int face_index = 0);
|
DynamicTextFont(const Filename &font_filename, int face_index = 0);
|
||||||
|
DynamicTextFont(const char *font_data, int data_length, int face_index);
|
||||||
virtual ~DynamicTextFont();
|
virtual ~DynamicTextFont();
|
||||||
|
|
||||||
INLINE bool set_point_size(float point_size);
|
INLINE bool set_point_size(float point_size);
|
||||||
@ -94,6 +95,7 @@ public:
|
|||||||
float &glyph_scale);
|
float &glyph_scale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initialize();
|
||||||
void update_filters();
|
void update_filters();
|
||||||
bool reset_scale();
|
bool reset_scale();
|
||||||
DynamicTextGlyph *make_glyph(int glyph_index);
|
DynamicTextGlyph *make_glyph(int glyph_index);
|
||||||
|
131
panda/src/text/fontPool.I
Normal file
131
panda/src/text/fontPool.I
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// Filename: fontPool.I
|
||||||
|
// Created by: drose (31Jan03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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: FontPool::has_font
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Returns true if the font has ever been loaded,
|
||||||
|
// false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool FontPool::
|
||||||
|
has_font(const string &filename) {
|
||||||
|
return get_ptr()->ns_has_font(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::verify_font
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Loads the given filename up into a font, if it has
|
||||||
|
// not already been loaded, and returns true to indicate
|
||||||
|
// success, or false to indicate failure. If this
|
||||||
|
// returns true, it is guaranteed that a subsequent call
|
||||||
|
// to load_font() with the same font name will
|
||||||
|
// return a valid Font pointer.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool FontPool::
|
||||||
|
verify_font(const string &filename) {
|
||||||
|
return load_font(filename) != (TextFont *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::load_font
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Loads the given filename up into a font, if it has
|
||||||
|
// not already been loaded, and returns the new font.
|
||||||
|
// If a font with the same filename was previously
|
||||||
|
// loaded, returns that one instead. If the font
|
||||||
|
// file cannot be found, returns NULL.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextFont *FontPool::
|
||||||
|
load_font(const string &filename) {
|
||||||
|
return get_ptr()->ns_load_font(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::add_font
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Adds the indicated already-loaded font to the
|
||||||
|
// pool. The font will always replace any
|
||||||
|
// previously-loaded font in the pool that had the
|
||||||
|
// same filename.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FontPool::
|
||||||
|
add_font(const string &filename, TextFont *font) {
|
||||||
|
get_ptr()->ns_add_font(filename, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::release_font
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Removes the indicated font from the pool,
|
||||||
|
// indicating it will never be loaded again; the font
|
||||||
|
// may then be freed. If this function is never called,
|
||||||
|
// a reference count will be maintained on every font
|
||||||
|
// every loaded, and fonts will never be freed.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FontPool::
|
||||||
|
release_font(const string &filename) {
|
||||||
|
get_ptr()->ns_release_font(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::release_all_fonts
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Releases all fonts in the pool and restores the
|
||||||
|
// pool to the empty state.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FontPool::
|
||||||
|
release_all_fonts() {
|
||||||
|
get_ptr()->ns_release_all_fonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::garbage_collect
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Releases only those fonts in the pool that have a
|
||||||
|
// reference count of exactly 1; i.e. only those
|
||||||
|
// fonts that are not being used outside of the pool.
|
||||||
|
// Returns the number of fonts released.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int FontPool::
|
||||||
|
garbage_collect() {
|
||||||
|
return get_ptr()->ns_garbage_collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::list_contents
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Lists the contents of the font pool to the
|
||||||
|
// indicated output stream.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FontPool::
|
||||||
|
list_contents(ostream &out) {
|
||||||
|
get_ptr()->ns_list_contents(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::Constructor
|
||||||
|
// Access: Private
|
||||||
|
// Description: The constructor is not intended to be called
|
||||||
|
// directly; there's only supposed to be one FontPool
|
||||||
|
// in the universe and it constructs itself.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FontPool::
|
||||||
|
FontPool() {
|
||||||
|
}
|
234
panda/src/text/fontPool.cxx
Normal file
234
panda/src/text/fontPool.cxx
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
// Filename: fontPool.cxx
|
||||||
|
// Created by: drose (31Jan03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 "fontPool.h"
|
||||||
|
#include "config_util.h"
|
||||||
|
#include "config_express.h"
|
||||||
|
#include "virtualFileSystem.h"
|
||||||
|
#include "nodePath.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
FontPool *FontPool::_global_ptr = (FontPool *)NULL;
|
||||||
|
|
||||||
|
static Loader model_loader;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_has_font
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of has_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool FontPool::
|
||||||
|
ns_has_font(const string &str) {
|
||||||
|
Filename filename;
|
||||||
|
int face_index;
|
||||||
|
lookup_filename(str, filename, face_index);
|
||||||
|
|
||||||
|
Fonts::const_iterator ti;
|
||||||
|
ti = _fonts.find(filename);
|
||||||
|
if (ti != _fonts.end()) {
|
||||||
|
// This font was previously loaded.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_load_font
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of load_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TextFont *FontPool::
|
||||||
|
ns_load_font(const string &str) {
|
||||||
|
Filename filename;
|
||||||
|
int face_index;
|
||||||
|
lookup_filename(str, filename, face_index);
|
||||||
|
|
||||||
|
Fonts::const_iterator ti;
|
||||||
|
ti = _fonts.find(filename);
|
||||||
|
if (ti != _fonts.end()) {
|
||||||
|
// This font was previously loaded.
|
||||||
|
return (*ti).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_cat.info()
|
||||||
|
<< "Loading font " << filename << "\n";
|
||||||
|
|
||||||
|
// Now, figure out how to load the font. If its filename extension
|
||||||
|
// is "egg" or "bam", or if it's unspecified, assume it's a model
|
||||||
|
// file, representing a static font.
|
||||||
|
PT(TextFont) font;
|
||||||
|
|
||||||
|
string extension = filename.get_extension();
|
||||||
|
if (extension.empty() || extension == "egg" || extension == "bam") {
|
||||||
|
PT(PandaNode) node = model_loader.load_sync(filename);
|
||||||
|
if (node != (PandaNode *)NULL) {
|
||||||
|
// It is a model. Elevate all the priorities by 1, and make a
|
||||||
|
// font out of it.
|
||||||
|
NodePath np(node);
|
||||||
|
np.adjust_all_priorities(1);
|
||||||
|
font = new StaticTextFont(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FREETYPE
|
||||||
|
if (font == (TextFont *)NULL || !font->is_valid()) {
|
||||||
|
// If we couldn't load the font as a model, try using FreeType to
|
||||||
|
// load it as a font file.
|
||||||
|
font = new DynamicTextFont(filename, face_index);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (font == (TextFont *)NULL || !font->is_valid()) {
|
||||||
|
// This font was not found or could not be read.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fonts[filename] = font;
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_add_font
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of add_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FontPool::
|
||||||
|
ns_add_font(const string &filename, TextFont *font) {
|
||||||
|
// We blow away whatever font was there previously, if any.
|
||||||
|
_fonts[filename] = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_release_font
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of release_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FontPool::
|
||||||
|
ns_release_font(const string &filename) {
|
||||||
|
Fonts::iterator ti;
|
||||||
|
ti = _fonts.find(filename);
|
||||||
|
if (ti != _fonts.end()) {
|
||||||
|
_fonts.erase(ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_release_all_fonts
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of release_all_fonts().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FontPool::
|
||||||
|
ns_release_all_fonts() {
|
||||||
|
_fonts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_garbage_collect
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of garbage_collect().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int FontPool::
|
||||||
|
ns_garbage_collect() {
|
||||||
|
int num_released = 0;
|
||||||
|
Fonts new_set;
|
||||||
|
|
||||||
|
Fonts::iterator ti;
|
||||||
|
for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
|
||||||
|
TextFont *font = (*ti).second;
|
||||||
|
if (font->get_ref_count() == 1) {
|
||||||
|
if (text_cat.is_debug()) {
|
||||||
|
text_cat.debug()
|
||||||
|
<< "Releasing " << (*ti).first << "\n";
|
||||||
|
}
|
||||||
|
num_released++;
|
||||||
|
} else {
|
||||||
|
new_set.insert(new_set.end(), *ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_fonts.swap(new_set);
|
||||||
|
return num_released;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::ns_list_contents
|
||||||
|
// Access: Private
|
||||||
|
// Description: The nonstatic implementation of list_contents().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FontPool::
|
||||||
|
ns_list_contents(ostream &out) {
|
||||||
|
out << _fonts.size() << " fonts:\n";
|
||||||
|
Fonts::iterator ti;
|
||||||
|
for (ti = _fonts.begin(); ti != _fonts.end(); ++ti) {
|
||||||
|
TextFont *font = (*ti).second;
|
||||||
|
out << " " << (*ti).first
|
||||||
|
<< " (count = " << font->get_ref_count() << ")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::lookup_filename
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Accepts a font "filename", which might consist of a
|
||||||
|
// filename followed by an optional colon and a face
|
||||||
|
// index, and splits it out into its two components.
|
||||||
|
// Then it looks up the filename on the model path.
|
||||||
|
// Sets the filename and face index accordingly.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FontPool::
|
||||||
|
lookup_filename(const string &str,
|
||||||
|
Filename &filename, int &face_index) {
|
||||||
|
int colon = (int)str.length() - 1;
|
||||||
|
// Scan backwards over digits for a colon.
|
||||||
|
while (colon >= 0 && isdigit(str[colon])) {
|
||||||
|
colon--;
|
||||||
|
}
|
||||||
|
if (colon >= 0 && str[colon] == ':') {
|
||||||
|
string digits = str.substr(colon + 1);
|
||||||
|
filename = str.substr(0, colon);
|
||||||
|
face_index = atoi(digits.c_str());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
filename = str;
|
||||||
|
face_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now look up the filename on the model path.
|
||||||
|
if (use_vfs) {
|
||||||
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
vfs->resolve_filename(filename, get_model_path());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
filename.resolve_filename(get_model_path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FontPool::get_ptr
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Initializes and/or returns the global pointer to the
|
||||||
|
// one FontPool object in the system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FontPool *FontPool::
|
||||||
|
get_ptr() {
|
||||||
|
if (_global_ptr == (FontPool *)NULL) {
|
||||||
|
_global_ptr = new FontPool;
|
||||||
|
}
|
||||||
|
return _global_ptr;
|
||||||
|
}
|
75
panda/src/text/fontPool.h
Normal file
75
panda/src/text/fontPool.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Filename: fontPool.h
|
||||||
|
// Created by: drose (31Jan03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 FONTPOOL_H
|
||||||
|
#define FONTPOOL_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
#include "filename.h"
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : FontPool
|
||||||
|
// Description : This is the preferred interface for loading fonts for
|
||||||
|
// the TextNode system. It is similar to ModelPool and
|
||||||
|
// TexturePool in that it unifies references to the same
|
||||||
|
// filename.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA FontPool {
|
||||||
|
PUBLISHED:
|
||||||
|
// These functions take string parameters instead of Filenames
|
||||||
|
// because that's somewhat more convenient to the scripting
|
||||||
|
// language.
|
||||||
|
INLINE static bool has_font(const string &filename);
|
||||||
|
INLINE static bool verify_font(const string &filename);
|
||||||
|
INLINE static TextFont *load_font(const string &filename);
|
||||||
|
INLINE static void add_font(const string &filename, TextFont *font);
|
||||||
|
INLINE static void release_font(const string &filename);
|
||||||
|
INLINE static void release_all_fonts();
|
||||||
|
|
||||||
|
INLINE static int garbage_collect();
|
||||||
|
|
||||||
|
INLINE static void list_contents(ostream &out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
INLINE FontPool();
|
||||||
|
|
||||||
|
bool ns_has_font(const string &str);
|
||||||
|
TextFont *ns_load_font(const string &str);
|
||||||
|
void ns_add_font(const string &filename, TextFont *font);
|
||||||
|
void ns_release_font(const string &filename);
|
||||||
|
void ns_release_all_fonts();
|
||||||
|
int ns_garbage_collect();
|
||||||
|
void ns_list_contents(ostream &out);
|
||||||
|
|
||||||
|
static void lookup_filename(const string &str,
|
||||||
|
Filename &filename, int &face_index);
|
||||||
|
|
||||||
|
static FontPool *get_ptr();
|
||||||
|
|
||||||
|
static FontPool *_global_ptr;
|
||||||
|
typedef pmap<string, PT(TextFont) > Fonts;
|
||||||
|
Fonts _fonts;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "fontPool.I"
|
||||||
|
|
||||||
|
#endif
|
@ -44,7 +44,9 @@ thaw() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextNode::set_font
|
// Function: TextNode::set_font
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets the font that will be used when making text.
|
// Description: Sets the font that will be used when making text. If
|
||||||
|
// this is set to NULL, the default font will be used,
|
||||||
|
// which can be set via set_default_font().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void TextNode::
|
INLINE void TextNode::
|
||||||
set_font(TextFont *font) {
|
set_font(TextFont *font) {
|
||||||
@ -57,13 +59,45 @@ set_font(TextFont *font) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextNode::get_font
|
// Function: TextNode::get_font
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the font currently in use.
|
// Description: Returns the font currently in use, if any. If this
|
||||||
|
// returns NULL, the default font will be used, which
|
||||||
|
// can be retrieved via get_default_font().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE TextFont *TextNode::
|
INLINE TextFont *TextNode::
|
||||||
get_font() const {
|
get_font() const {
|
||||||
return _font;
|
return _font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::set_default_font
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Specifies the default font to be used for any
|
||||||
|
// TextNode whose font is uninitialized or NULL. See
|
||||||
|
// set_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void TextNode::
|
||||||
|
set_default_font(TextFont *font) {
|
||||||
|
// If the user overrides the default, we don't need to try to load
|
||||||
|
// whatever it would have been.
|
||||||
|
_loaded_default_font = true;
|
||||||
|
_default_font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::get_default_font
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Specifies the default font to be used for any
|
||||||
|
// TextNode whose font is uninitialized or NULL. See
|
||||||
|
// set_font().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextFont *TextNode::
|
||||||
|
get_default_font() {
|
||||||
|
if (!_loaded_default_font) {
|
||||||
|
load_default_font();
|
||||||
|
}
|
||||||
|
return _default_font;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextNode::set_encoding
|
// Function: TextNode::set_encoding
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -96,6 +130,30 @@ get_encoding() const {
|
|||||||
return _encoding;
|
return _encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::set_default_encoding
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Specifies the default encoding to be used for all
|
||||||
|
// subsequently created TextNode objects. See
|
||||||
|
// set_encoding().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void TextNode::
|
||||||
|
set_default_encoding(TextNode::Encoding encoding) {
|
||||||
|
_default_encoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::get_default_encoding
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Specifies the default encoding to be used for all
|
||||||
|
// subsequently created TextNode objects. See
|
||||||
|
// set_encoding().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE TextNode::Encoding TextNode::
|
||||||
|
get_default_encoding() {
|
||||||
|
return _default_encoding;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextNode::set_expand_amp
|
// Function: TextNode::set_expand_amp
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include "textGlyph.h"
|
#include "textGlyph.h"
|
||||||
#include "stringDecoder.h"
|
#include "stringDecoder.h"
|
||||||
#include "config_text.h"
|
#include "config_text.h"
|
||||||
|
#include "fontPool.h"
|
||||||
|
#include "default_font.h"
|
||||||
|
#include "dynamicTextFont.h"
|
||||||
|
|
||||||
#include "compose_matrix.h"
|
#include "compose_matrix.h"
|
||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
@ -47,6 +50,8 @@
|
|||||||
|
|
||||||
TypeHandle TextNode::_type_handle;
|
TypeHandle TextNode::_type_handle;
|
||||||
|
|
||||||
|
PT(TextFont) TextNode::_default_font;
|
||||||
|
bool TextNode::_loaded_default_font = false;
|
||||||
TextNode::Encoding TextNode::_default_encoding;
|
TextNode::Encoding TextNode::_default_encoding;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -255,7 +260,16 @@ generate() {
|
|||||||
// Now build a new sub-tree for all the text components.
|
// Now build a new sub-tree for all the text components.
|
||||||
PT(PandaNode) root = new PandaNode(get_text());
|
PT(PandaNode) root = new PandaNode(get_text());
|
||||||
|
|
||||||
if (!has_text() || _font.is_null()) {
|
if (!has_text()) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFont *font = get_font();
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
|
font = get_default_font();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,13 +284,15 @@ generate() {
|
|||||||
|
|
||||||
wstring wtext = get_wtext();
|
wstring wtext = get_wtext();
|
||||||
if (has_wordwrap()) {
|
if (has_wordwrap()) {
|
||||||
wtext = _font->wordwrap_to(wtext, _wordwrap_width, false);
|
wtext = font->wordwrap_to(wtext, _wordwrap_width, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble the text.
|
// Assemble the text.
|
||||||
LVector2f ul, lr;
|
LVector2f ul, lr;
|
||||||
int num_rows = 0;
|
int num_rows = 0;
|
||||||
PT(PandaNode) text_root = assemble_text(wtext.begin(), wtext.end(), ul, lr, num_rows);
|
PT(PandaNode) text_root =
|
||||||
|
assemble_text(wtext.begin(), wtext.end(), font,
|
||||||
|
ul, lr, num_rows);
|
||||||
|
|
||||||
// Parent the text in.
|
// Parent the text in.
|
||||||
PT(PandaNode) text = new PandaNode("text");
|
PT(PandaNode) text = new PandaNode("text");
|
||||||
@ -821,18 +837,28 @@ do_measure() {
|
|||||||
_lr3d.set(0.0f, 0.0f, 0.0f);
|
_lr3d.set(0.0f, 0.0f, 0.0f);
|
||||||
_num_rows = 0;
|
_num_rows = 0;
|
||||||
|
|
||||||
if (!has_text() || _font.is_null()) {
|
if (!has_text()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFont *font = get_font();
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
|
font = get_default_font();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring wtext = get_wtext();
|
wstring wtext = get_wtext();
|
||||||
if (has_wordwrap()) {
|
if (has_wordwrap()) {
|
||||||
wtext = _font->wordwrap_to(wtext, _wordwrap_width, false);
|
wtext = font->wordwrap_to(wtext, _wordwrap_width, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
LVector2f ul, lr;
|
LVector2f ul, lr;
|
||||||
int num_rows = 0;
|
int num_rows = 0;
|
||||||
measure_text(wtext.begin(), wtext.end(), ul, lr, num_rows);
|
measure_text(wtext.begin(), wtext.end(), font,
|
||||||
|
ul, lr, num_rows);
|
||||||
|
|
||||||
_num_rows = num_rows;
|
_num_rows = num_rows;
|
||||||
_ul2d = ul;
|
_ul2d = ul;
|
||||||
@ -857,25 +883,23 @@ do_measure() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float TextNode::
|
float TextNode::
|
||||||
assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
PandaNode *dest) {
|
TextFont *font, PandaNode *dest) {
|
||||||
nassertr(_font != (TextFont *)NULL, 0.0f);
|
|
||||||
|
|
||||||
float xpos = 0.0f;
|
float xpos = 0.0f;
|
||||||
while (si != send && (*si) != '\n') {
|
while (si != send && (*si) != '\n') {
|
||||||
wchar_t character = *si;
|
wchar_t character = *si;
|
||||||
|
|
||||||
if (character == ' ') {
|
if (character == ' ') {
|
||||||
// A space is a special case.
|
// A space is a special case.
|
||||||
xpos += _font->get_space_advance();
|
xpos += font->get_space_advance();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// A printable character.
|
// A printable character.
|
||||||
|
|
||||||
const TextGlyph *glyph;
|
const TextGlyph *glyph;
|
||||||
float glyph_scale;
|
float glyph_scale;
|
||||||
if (!_font->get_glyph(character, glyph, glyph_scale)) {
|
if (!font->get_glyph(character, glyph, glyph_scale)) {
|
||||||
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 (character < 128 && isprint((unsigned int)character)) {
|
if (character < 128 && isprint((unsigned int)character)) {
|
||||||
text_cat.warning(false)
|
text_cat.warning(false)
|
||||||
@ -918,8 +942,7 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PT(PandaNode) TextNode::
|
PT(PandaNode) TextNode::
|
||||||
assemble_text(wstring::iterator si, const wstring::iterator &send,
|
assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
LVector2f &ul, LVector2f &lr, int &num_rows) {
|
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
||||||
nassertr(_font != (TextFont *)NULL, (PandaNode *)NULL);
|
|
||||||
float line_height = get_line_height();
|
float line_height = get_line_height();
|
||||||
|
|
||||||
ul.set(0.0f, 0.8f * line_height);
|
ul.set(0.0f, 0.8f * line_height);
|
||||||
@ -936,7 +959,7 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
|||||||
nassertr(strlen(numstr) < 20, root_node);
|
nassertr(strlen(numstr) < 20, root_node);
|
||||||
|
|
||||||
PT(PandaNode) row = new PandaNode(numstr);
|
PT(PandaNode) row = new PandaNode(numstr);
|
||||||
float row_width = assemble_row(si, send, row);
|
float row_width = assemble_row(si, send, font, row);
|
||||||
if (si != send) {
|
if (si != send) {
|
||||||
// Skip past the newline.
|
// Skip past the newline.
|
||||||
++si;
|
++si;
|
||||||
@ -988,21 +1011,22 @@ assemble_text(wstring::iterator si, const wstring::iterator &send,
|
|||||||
// it.
|
// it.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float TextNode::
|
float TextNode::
|
||||||
measure_row(wstring::iterator &si, const wstring::iterator &send) {
|
measure_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
|
TextFont *font) {
|
||||||
float xpos = 0.0f;
|
float xpos = 0.0f;
|
||||||
while (si != send && *si != '\n') {
|
while (si != send && *si != '\n') {
|
||||||
wchar_t character = *si;
|
wchar_t character = *si;
|
||||||
|
|
||||||
if (character == ' ') {
|
if (character == ' ') {
|
||||||
// A space is a special case.
|
// A space is a special case.
|
||||||
xpos += _font->get_space_advance();
|
xpos += font->get_space_advance();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// A printable character.
|
// A printable character.
|
||||||
|
|
||||||
const TextGlyph *glyph;
|
const TextGlyph *glyph;
|
||||||
float glyph_scale;
|
float glyph_scale;
|
||||||
if (_font->get_glyph(character, glyph, glyph_scale)) {
|
if (font->get_glyph(character, glyph, glyph_scale)) {
|
||||||
xpos += glyph->get_advance() * glyph_scale;
|
xpos += glyph->get_advance() * glyph_scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1020,8 +1044,7 @@ measure_row(wstring::iterator &si, const wstring::iterator &send) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void TextNode::
|
void TextNode::
|
||||||
measure_text(wstring::iterator si, const wstring::iterator &send,
|
measure_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
LVector2f &ul, LVector2f &lr, int &num_rows) {
|
TextFont *font, LVector2f &ul, LVector2f &lr, int &num_rows) {
|
||||||
nassertv(_font != (TextFont *)NULL);
|
|
||||||
float line_height = get_line_height();
|
float line_height = get_line_height();
|
||||||
|
|
||||||
ul.set(0.0f, 0.8f * line_height);
|
ul.set(0.0f, 0.8f * line_height);
|
||||||
@ -1029,7 +1052,7 @@ measure_text(wstring::iterator si, const wstring::iterator &send,
|
|||||||
|
|
||||||
float posy = 0.0f;
|
float posy = 0.0f;
|
||||||
while (si != send) {
|
while (si != send) {
|
||||||
float row_width = measure_row(si, send);
|
float row_width = measure_row(si, send, font);
|
||||||
if (si != send) {
|
if (si != send) {
|
||||||
// Skip past the newline.
|
// Skip past the newline.
|
||||||
++si;
|
++si;
|
||||||
@ -1268,3 +1291,40 @@ make_card_with_border() {
|
|||||||
|
|
||||||
return card_geode.p();
|
return card_geode.p();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::load_default_font
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: This functin is called once (or never), the first
|
||||||
|
// time someone attempts to render a TextNode using the
|
||||||
|
// default font. It should attempt to load the default
|
||||||
|
// font, using the compiled-in version if it is
|
||||||
|
// available, or whatever system file may be named in
|
||||||
|
// Configrc.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextNode::
|
||||||
|
load_default_font() {
|
||||||
|
_loaded_default_font = true;
|
||||||
|
|
||||||
|
if (!text_default_font.empty()) {
|
||||||
|
// First, attempt to load the user-specified filename.
|
||||||
|
_default_font = FontPool::load_font(text_default_font);
|
||||||
|
if (_default_font->is_valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, attempt to load the compiled-in font, if we have one.
|
||||||
|
#if defined(HAVE_FREETYPE) && defined(COMPILE_IN_DEFAULT_FONT)
|
||||||
|
_default_font = new DynamicTextFont(default_font_data, default_font_size, 0);
|
||||||
|
if (_default_font->is_valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Finally, fall back to a hardcoded font file, which we hope is on
|
||||||
|
// the model path. (Use text_default_font, above, if you don't want
|
||||||
|
// to use this file and would prefer to specify a different font
|
||||||
|
// file instead.)
|
||||||
|
_default_font = FontPool::load_font("cmss12");
|
||||||
|
}
|
||||||
|
@ -75,9 +75,15 @@ PUBLISHED:
|
|||||||
INLINE void set_font(TextFont *font);
|
INLINE void set_font(TextFont *font);
|
||||||
INLINE TextFont *get_font() const;
|
INLINE TextFont *get_font() const;
|
||||||
|
|
||||||
|
INLINE static void set_default_font(TextFont *);
|
||||||
|
INLINE static TextFont *get_default_font();
|
||||||
|
|
||||||
INLINE void set_encoding(Encoding encoding);
|
INLINE void set_encoding(Encoding encoding);
|
||||||
INLINE Encoding get_encoding() const;
|
INLINE Encoding get_encoding() const;
|
||||||
|
|
||||||
|
INLINE static void set_default_encoding(Encoding encoding);
|
||||||
|
INLINE static Encoding get_default_encoding();
|
||||||
|
|
||||||
INLINE void set_expand_amp(bool expand_amp);
|
INLINE void set_expand_amp(bool expand_amp);
|
||||||
INLINE bool get_expand_amp() const;
|
INLINE bool get_expand_amp() const;
|
||||||
|
|
||||||
@ -243,12 +249,15 @@ private:
|
|||||||
void do_measure();
|
void do_measure();
|
||||||
|
|
||||||
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
|
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
|
||||||
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
float assemble_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
PandaNode *dest);
|
TextFont *font, PandaNode *dest);
|
||||||
PT(PandaNode) assemble_text(wstring::iterator si, const wstring::iterator &send,
|
PT(PandaNode) assemble_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
|
TextFont *font,
|
||||||
LVector2f &ul, LVector2f &lr, int &num_rows);
|
LVector2f &ul, LVector2f &lr, int &num_rows);
|
||||||
float measure_row(wstring::iterator &si, const wstring::iterator &send);
|
float measure_row(wstring::iterator &si, const wstring::iterator &send,
|
||||||
|
TextFont *font);
|
||||||
void measure_text(wstring::iterator si, const wstring::iterator &send,
|
void measure_text(wstring::iterator si, const wstring::iterator &send,
|
||||||
|
TextFont *font,
|
||||||
LVector2f &ul, LVector2f &lr, int &num_rows);
|
LVector2f &ul, LVector2f &lr, int &num_rows);
|
||||||
#endif // CPPPARSER
|
#endif // CPPPARSER
|
||||||
|
|
||||||
@ -256,6 +265,8 @@ private:
|
|||||||
PT(PandaNode) make_card();
|
PT(PandaNode) make_card();
|
||||||
PT(PandaNode) make_card_with_border();
|
PT(PandaNode) make_card_with_border();
|
||||||
|
|
||||||
|
static void load_default_font();
|
||||||
|
|
||||||
PT(TextFont) _font;
|
PT(TextFont) _font;
|
||||||
PT(PandaNode) _internal_geom;
|
PT(PandaNode) _internal_geom;
|
||||||
|
|
||||||
@ -311,7 +322,8 @@ private:
|
|||||||
LPoint3f _ul3d, _lr3d;
|
LPoint3f _ul3d, _lr3d;
|
||||||
int _num_rows;
|
int _num_rows;
|
||||||
|
|
||||||
public:
|
static PT(TextFont) _default_font;
|
||||||
|
static bool _loaded_default_font;
|
||||||
static Encoding _default_encoding;
|
static Encoding _default_encoding;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "config_text.cxx"
|
#include "config_text.cxx"
|
||||||
|
#include "default_font.cxx"
|
||||||
#include "dynamicTextFont.cxx"
|
#include "dynamicTextFont.cxx"
|
||||||
#include "dynamicTextGlyph.cxx"
|
#include "dynamicTextGlyph.cxx"
|
||||||
#include "dynamicTextPage.cxx"
|
#include "dynamicTextPage.cxx"
|
||||||
|
#include "fontPool.cxx"
|
||||||
#include "geomTextGlyph.cxx"
|
#include "geomTextGlyph.cxx"
|
||||||
#include "staticTextFont.cxx"
|
#include "staticTextFont.cxx"
|
||||||
#include "stringDecoder.cxx"
|
#include "stringDecoder.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user