mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
initial pass at dynamic text
This commit is contained in:
parent
68aa6f0e52
commit
9292457ce5
@ -2,6 +2,8 @@
|
||||
dtoolutil:c dtoolbase:c dtool:m
|
||||
|
||||
#begin lib_target
|
||||
#define USE_FREETYPE yes
|
||||
|
||||
#define TARGET text
|
||||
#define LOCAL_LIBS \
|
||||
cull putil gobj sgattrib graph sgraph linmath sgraphutil pnmimage gsgbase \
|
||||
@ -11,16 +13,27 @@
|
||||
|
||||
#define SOURCES \
|
||||
config_text.h \
|
||||
dynamicTextFont.I dynamicTextFont.h \
|
||||
dynamicTextGlyph.I dynamicTextGlyph.h \
|
||||
dynamicTextPage.I dynamicTextPage.h \
|
||||
staticTextFont.I staticTextFont.h \
|
||||
textFont.I textFont.h \
|
||||
textGlyph.I textGlyph.h \
|
||||
textNode.I textNode.h textNode.cxx
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_text.cxx staticTextFont.cxx textFont.cxx textGlyph.cxx
|
||||
config_text.cxx \
|
||||
dynamicTextFont.cxx \
|
||||
dynamicTextGlyph.cxx \
|
||||
dynamicTextPage.cxx \
|
||||
staticTextFont.cxx \
|
||||
textFont.cxx textGlyph.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
config_text.h \
|
||||
dynamicTextFont.I dynamicTextFont.h \
|
||||
dynamicTextGlyph.I dynamicTextGlyph.h \
|
||||
dynamicTextPage.I dynamicTextPage.h \
|
||||
staticTextFont.I staticTextFont.h \
|
||||
textFont.I textFont.h \
|
||||
textGlyph.I textGlyph.h \
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "config_text.h"
|
||||
#include "staticTextFont.h"
|
||||
#include "dynamicTextFont.h"
|
||||
#include "dynamicTextPage.h"
|
||||
#include "textFont.h"
|
||||
#include "textNode.h"
|
||||
|
||||
@ -28,6 +30,8 @@ NotifyCategoryDef(text, "");
|
||||
|
||||
ConfigureFn(config_text) {
|
||||
StaticTextFont::init_type();
|
||||
DynamicTextFont::init_type();
|
||||
DynamicTextPage::init_type();
|
||||
TextFont::init_type();
|
||||
TextNode::init_type();
|
||||
}
|
||||
|
76
panda/src/text/dynamicTextFont.I
Normal file
76
panda/src/text/dynamicTextFont.I
Normal file
@ -0,0 +1,76 @@
|
||||
// Filename: dynamicTextFont.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: DynamicTextFont::set_margin
|
||||
// Access: Published
|
||||
// Description: Sets the number of pixels of padding that is added
|
||||
// around the border of each glyph before adding it to
|
||||
// the texture map. This reduces the bleed in from
|
||||
// neighboring glyphs in the texture map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DynamicTextFont::
|
||||
set_margin(int margin) {
|
||||
_margin = margin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::get_margin
|
||||
// Access: Published
|
||||
// Description: Returns the number of pixels of padding that is added
|
||||
// around the border of each glyph. See set_margin().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DynamicTextFont::
|
||||
get_margin() const {
|
||||
return _margin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::set_page_size
|
||||
// Access: Published
|
||||
// Description: Sets the x, y size of the textures that are created
|
||||
// for the DynamicTextFont.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DynamicTextFont::
|
||||
set_page_size(int x_size, int y_size) {
|
||||
_page_x_size = x_size;
|
||||
_page_y_size = y_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::get_page_x_size
|
||||
// Access: Published
|
||||
// Description: Returns the x size of the textures that are created
|
||||
// for the DynamicTextFont. See set_page_size().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DynamicTextFont::
|
||||
get_page_x_size() const {
|
||||
return _page_x_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::get_page_y_size
|
||||
// Access: Published
|
||||
// Description: Returns the y size of the textures that are created
|
||||
// for the DynamicTextFont. See set_page_size().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DynamicTextFont::
|
||||
get_page_y_size() const {
|
||||
return _page_y_size;
|
||||
}
|
284
panda/src/text/dynamicTextFont.cxx
Normal file
284
panda/src/text/dynamicTextFont.cxx
Normal file
@ -0,0 +1,284 @@
|
||||
// Filename: dynamicTextFont.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 "dynamicTextFont.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
#include "config_text.h"
|
||||
#include "config_util.h"
|
||||
|
||||
FT_Library DynamicTextFont::_ft_library;
|
||||
bool DynamicTextFont::_ft_initialized = false;
|
||||
bool DynamicTextFont::_ft_ok = false;
|
||||
|
||||
TypeHandle DynamicTextFont::_type_handle;
|
||||
|
||||
|
||||
// This constant determines how big a particular point size font
|
||||
// appears. By convention, 10 points is 1 foot high.
|
||||
static const float points_per_unit = 10.0f;
|
||||
|
||||
// A universal convention.
|
||||
static const float points_per_inch = 72.0f;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::Constructor
|
||||
// Access: Published
|
||||
// Description: The constructor expects the name of some font file
|
||||
// that FreeType can read, along with face_index,
|
||||
// indicating which font within the file to load
|
||||
// (usually 0), the point size of the font, and the
|
||||
// resolution at which to generate the font.
|
||||
//
|
||||
// The choice of point size affects the apparent size of
|
||||
// the generated characters (as well as the clarity),
|
||||
// while the pixels_per_unit affects only the clarity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextFont::
|
||||
DynamicTextFont(const Filename &font_filename, int face_index,
|
||||
float point_size, float pixels_per_unit) {
|
||||
_margin = 2;
|
||||
_page_x_size = 256;
|
||||
_page_y_size = 256;
|
||||
_pixels_per_unit = pixels_per_unit;
|
||||
|
||||
float units_per_inch = (points_per_inch / points_per_unit);
|
||||
int dpi = (int)(_pixels_per_unit * units_per_inch);
|
||||
|
||||
if (!_ft_initialized) {
|
||||
initialize_ft_library();
|
||||
}
|
||||
if (!_ft_ok) {
|
||||
text_cat.error()
|
||||
<< "Unable to read font " << font_filename << ": FreeType library not available.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Filename path(font_filename);
|
||||
if (!path.resolve_filename(get_model_path())) {
|
||||
text_cat.error()
|
||||
<< "Unable to find font file " << font_filename << "\n";
|
||||
} else {
|
||||
string os_specific = path.to_os_specific();
|
||||
|
||||
int error = FT_New_Face(_ft_library,
|
||||
os_specific.c_str(),
|
||||
face_index,
|
||||
&_face);
|
||||
if (error == FT_Err_Unknown_File_Format) {
|
||||
text_cat.error()
|
||||
<< "Unable to read font " << font_filename << ": unknown file format.\n";
|
||||
} else if (error) {
|
||||
text_cat.error()
|
||||
<< "Unable to read font " << font_filename << ": invalid.\n";
|
||||
|
||||
} else {
|
||||
string name = _face->family_name;
|
||||
name += " ";
|
||||
name += _face->style_name;
|
||||
|
||||
_is_valid = true;
|
||||
set_name(name);
|
||||
|
||||
text_cat.info()
|
||||
<< "Loaded font " << get_name() << "\n";
|
||||
|
||||
error = FT_Set_Char_Size(_face,
|
||||
(int)(point_size * 64), (int)(point_size * 64),
|
||||
dpi, dpi);
|
||||
if (error) {
|
||||
text_cat.warning()
|
||||
<< "Unable to set point size of " << get_name()
|
||||
<< " to " << point_size << " at " << dpi << " dots per inch.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::get_num_pages
|
||||
// Access: Published
|
||||
// Description: Returns the number of pages associated with the font.
|
||||
// Initially, the font has zero pages; when the first
|
||||
// piece of text is rendered with the font, it will add
|
||||
// additional pages as needed. Each page is a Texture
|
||||
// object that contains the images for each of the
|
||||
// glyphs currently in use somewhere.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DynamicTextFont::
|
||||
get_num_pages() const {
|
||||
return _pages.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::get_page
|
||||
// Access: Published
|
||||
// Description: Returns the nth page associated with the font.
|
||||
// Initially, the font has zero pages; when the first
|
||||
// piece of text is rendered with the font, it will add
|
||||
// additional pages as needed. Each page is a Texture
|
||||
// object that contains the images for each of the
|
||||
// glyphs currently in use somewhere.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextPage *DynamicTextFont::
|
||||
get_page(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_pages.size(), (DynamicTextPage *)NULL);
|
||||
return _pages[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::write
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DynamicTextFont::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "DynamicTextFont " << get_name() << ".\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::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 *DynamicTextFont::
|
||||
get_glyph(int character) {
|
||||
Cache::iterator ci = _cache.find(character);
|
||||
if (ci != _cache.end()) {
|
||||
return (*ci).second;
|
||||
}
|
||||
DynamicTextGlyph *glyph = make_glyph(character);
|
||||
_cache.insert(Cache::value_type(character, glyph));
|
||||
return glyph;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::make_glyph
|
||||
// Access: Private
|
||||
// Description: Slots a space in the texture map for the new
|
||||
// character and renders the glyph, returning the
|
||||
// newly-created TextGlyph object, or NULL if the
|
||||
// glyph cannot be created for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextGlyph *DynamicTextFont::
|
||||
make_glyph(int character) {
|
||||
int error = FT_Load_Char(_face, character, FT_LOAD_RENDER);
|
||||
if (error) {
|
||||
text_cat.error()
|
||||
<< "Unable to render character " << character << "\n";
|
||||
return (DynamicTextGlyph *)NULL;
|
||||
}
|
||||
|
||||
FT_GlyphSlot slot = _face->glyph;
|
||||
FT_Bitmap &bitmap = slot->bitmap;
|
||||
|
||||
if (bitmap.pixel_mode != ft_pixel_mode_grays) {
|
||||
text_cat.error()
|
||||
<< "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
|
||||
return (DynamicTextGlyph *)NULL;
|
||||
}
|
||||
|
||||
if (bitmap.num_grays != 256) {
|
||||
// We expect 256 levels of grayscale to come back from FreeType,
|
||||
// since that's what we asked for.
|
||||
text_cat.warning()
|
||||
<< "Expected 256 levels of gray, got " << bitmap.num_grays << "\n";
|
||||
}
|
||||
|
||||
DynamicTextGlyph *glyph = slot_glyph(bitmap.width, bitmap.rows);
|
||||
|
||||
// Now copy the rendered glyph into the texture.
|
||||
unsigned char *buffer_row = bitmap.buffer;
|
||||
for (int yi = 0; yi < bitmap.rows; yi++) {
|
||||
unsigned char *texture_row = glyph->get_row(yi);
|
||||
nassertr(texture_row != (unsigned char *)NULL, (DynamicTextGlyph *)NULL);
|
||||
memcpy(texture_row, buffer_row, bitmap.width);
|
||||
buffer_row += bitmap.pitch;
|
||||
}
|
||||
glyph->_page->mark_dirty(Texture::DF_image);
|
||||
|
||||
float advance = slot->advance.x / 64.0;
|
||||
glyph->make_geom(slot->bitmap_top, slot->bitmap_left, advance,
|
||||
_pixels_per_unit);
|
||||
return glyph;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::slot_glyph
|
||||
// Access: Private
|
||||
// Description: Chooses a page that will have room for a glyph of the
|
||||
// indicated size (after expanding the indicated size by
|
||||
// the current margin). Returns the newly-allocated
|
||||
// glyph on the chosen page; the glyph has not been
|
||||
// filled in yet except with its size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextGlyph *DynamicTextFont::
|
||||
slot_glyph(int x_size, int y_size) {
|
||||
// Increase the indicated size by the current margin.
|
||||
x_size += _margin * 2;
|
||||
y_size += _margin * 2;
|
||||
|
||||
Pages::iterator pi;
|
||||
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
|
||||
DynamicTextPage *page = (*pi);
|
||||
|
||||
DynamicTextGlyph *glyph = page->slot_glyph(x_size, y_size, _margin);
|
||||
if (glyph != (DynamicTextGlyph *)NULL) {
|
||||
return glyph;
|
||||
}
|
||||
|
||||
if (page->is_empty()) {
|
||||
// If we couldn't even put in on an empty page, we're screwed.
|
||||
text_cat.error()
|
||||
<< "Glyph of size " << x_size << " by " << y_size
|
||||
<< " won't fit on an empty page.\n";
|
||||
return (DynamicTextGlyph *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// We need to make a new page.
|
||||
PT(DynamicTextPage) page = new DynamicTextPage(this);
|
||||
_pages.push_back(page);
|
||||
return page->slot_glyph(x_size, y_size, _margin);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextFont::initialize_ft_library
|
||||
// Access: Private, Static
|
||||
// Description: Should be called exactly once to initialize the
|
||||
// FreeType library.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DynamicTextFont::
|
||||
initialize_ft_library() {
|
||||
if (!_ft_initialized) {
|
||||
int error = FT_Init_FreeType(&_ft_library);
|
||||
_ft_initialized = true;
|
||||
if (error) {
|
||||
text_cat.error()
|
||||
<< "Unable to initialize FreeType; DynamicTextFonts will not load.\n";
|
||||
} else {
|
||||
_ft_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_FREETYPE
|
111
panda/src/text/dynamicTextFont.h
Normal file
111
panda/src/text/dynamicTextFont.h
Normal file
@ -0,0 +1,111 @@
|
||||
// Filename: dynamicTextFont.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 DYNAMICTEXTFONT_H
|
||||
#define DYNAMICTEXTFONT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
#include "config_text.h"
|
||||
#include "textFont.h"
|
||||
#include "dynamicTextGlyph.h"
|
||||
#include "dynamicTextPage.h"
|
||||
#include "filename.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DynamicTextFont
|
||||
// Description : A DynamicTextFont is a special TextFont object that
|
||||
// rasterizes its glyphs from a standard font file
|
||||
// (e.g. a TTF file) on the fly. It requires the
|
||||
// FreeType 2.0 library (or any higher,
|
||||
// backward-compatible version).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DynamicTextFont : public TextFont {
|
||||
PUBLISHED:
|
||||
DynamicTextFont(const Filename &font_filename, int face_index,
|
||||
float point_size, float pixels_per_unit);
|
||||
|
||||
INLINE void set_margin(int margin);
|
||||
INLINE int get_margin() const;
|
||||
|
||||
INLINE void set_page_size(int x_size, int y_size);
|
||||
INLINE int get_page_x_size() const;
|
||||
INLINE int get_page_y_size() const;
|
||||
|
||||
int get_num_pages() const;
|
||||
DynamicTextPage *get_page(int n) const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
virtual const TextGlyph *get_glyph(int character);
|
||||
|
||||
private:
|
||||
DynamicTextGlyph *make_glyph(int character);
|
||||
DynamicTextGlyph *slot_glyph(int x_size, int y_size);
|
||||
|
||||
static void initialize_ft_library();
|
||||
|
||||
int _margin;
|
||||
int _page_x_size, _page_y_size;
|
||||
float _pixels_per_unit;
|
||||
|
||||
typedef pvector< PT(DynamicTextPage) > Pages;
|
||||
Pages _pages;
|
||||
|
||||
typedef pmap<int, DynamicTextGlyph *> Cache;
|
||||
Cache _cache;
|
||||
|
||||
FT_Face _face;
|
||||
|
||||
static FT_Library _ft_library;
|
||||
static bool _ft_initialized;
|
||||
static bool _ft_ok;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TextFont::init_type();
|
||||
register_type(_type_handle, "DynamicTextFont",
|
||||
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 "dynamicTextFont.I"
|
||||
|
||||
#endif // HAVE_FREETYPE
|
||||
|
||||
#endif
|
54
panda/src/text/dynamicTextGlyph.I
Normal file
54
panda/src/text/dynamicTextGlyph.I
Normal file
@ -0,0 +1,54 @@
|
||||
// Filename: dynamicTextGlyph.I
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: DynamicTextGlyph::Constructor
|
||||
// Access: Publiic
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DynamicTextGlyph::
|
||||
DynamicTextGlyph(DynamicTextPage *page, int x, int y,
|
||||
int x_size, int y_size, int margin) :
|
||||
_page(page),
|
||||
_x(x), _y(y),
|
||||
_x_size(x_size), _y_size(y_size),
|
||||
_margin(margin)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::intersects
|
||||
// Access: Public
|
||||
// Description: Returns true if the particular position this glyph
|
||||
// has been assigned to overlaps the rectangle whose
|
||||
// top left corner is at x, y and whose size is given by
|
||||
// x_size, y_size, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DynamicTextGlyph::
|
||||
intersects(int x, int y, int x_size, int y_size) const {
|
||||
int hright = x + x_size;
|
||||
int hbot = y + y_size;
|
||||
|
||||
int mright = _x + _x_size;
|
||||
int mbot = _y + _y_size;
|
||||
|
||||
return !(x >= mright || hright <= _x ||
|
||||
y >= mbot || hbot <= _y);
|
||||
}
|
116
panda/src/text/dynamicTextGlyph.cxx
Normal file
116
panda/src/text/dynamicTextGlyph.cxx
Normal file
@ -0,0 +1,116 @@
|
||||
// Filename: dynamicTextGlyph.cxx
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "dynamicTextGlyph.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
#include "dynamicTextPage.h"
|
||||
#include "geomTristrip.h"
|
||||
#include "textureTransition.h"
|
||||
#include "transparencyTransition.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::get_row
|
||||
// Access: Publiic
|
||||
// Description: Returns a pointer to the first byte in the pixel
|
||||
// buffer associated with the leftmost pixel in the
|
||||
// indicated row, where 0 is the topmost row and _y_size
|
||||
// - _margin * 2 - 1 is the bottommost row.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
unsigned char *DynamicTextGlyph::
|
||||
get_row(int y) {
|
||||
nassertr(y >= 0 && y < _y_size - _margin * 2, (unsigned char *)NULL);
|
||||
nassertr(_page != (DynamicTextPage *)NULL, (unsigned char *)NULL);
|
||||
nassertr(_page->_pbuffer != (PixelBuffer *)NULL, (unsigned char *)NULL);
|
||||
|
||||
// First, offset y by the glyph's start.
|
||||
y += _y + _margin;
|
||||
// Also, get the x start.
|
||||
int x = _x + _margin;
|
||||
|
||||
// Invert y.
|
||||
y = _page->_pbuffer->get_ysize() - 1 - y;
|
||||
|
||||
int offset = (y * _page->_pbuffer->get_xsize()) + x;
|
||||
return _page->_pbuffer->_image + offset;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextGlyph::make_geom
|
||||
// Access: Publiic
|
||||
// Description: Creates the actual geometry for the glyph. The
|
||||
// parameters bitmap_top and bitmap_left are from
|
||||
// FreeType, and indicate the position of the top left
|
||||
// corner of the bitmap relative to the glyph's origin.
|
||||
// The advance number represents the number of pixels
|
||||
// the pen should be advanced after drawing this glyph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DynamicTextGlyph::
|
||||
make_geom(int bitmap_top, int bitmap_left,
|
||||
float advance, float pixels_per_unit) {
|
||||
// Determine the corners of the rectangle in geometric units.
|
||||
float top = (bitmap_top + _margin) / pixels_per_unit;
|
||||
float left = (bitmap_left - _margin) / pixels_per_unit;
|
||||
float bottom = (bitmap_top - _y_size - _margin) / pixels_per_unit;
|
||||
float right = (bitmap_left + _x_size + _margin) / pixels_per_unit;
|
||||
|
||||
// And the corresponding corners in UV units.
|
||||
float uv_top = 1.0f - (float)_y / _page->get_y_size();
|
||||
float uv_left = (float)_x / _page->get_x_size();
|
||||
float uv_bottom = 1.0f - (float)(_y + _y_size) / _page->get_y_size();
|
||||
float uv_right = (float)(_x + _x_size) / _page->get_x_size();
|
||||
|
||||
// Create a corresponding tristrip.
|
||||
_geom = new GeomTristrip;
|
||||
|
||||
PTA_Vertexf coords;
|
||||
coords.push_back(Vertexf(left, 0, top));
|
||||
coords.push_back(Vertexf(left, 0, bottom));
|
||||
coords.push_back(Vertexf(right, 0, top));
|
||||
coords.push_back(Vertexf(right, 0, bottom));
|
||||
|
||||
PTA_TexCoordf texcoords;
|
||||
texcoords.push_back(TexCoordf(uv_left, uv_top));
|
||||
texcoords.push_back(TexCoordf(uv_left, uv_bottom));
|
||||
texcoords.push_back(TexCoordf(uv_right, uv_top));
|
||||
texcoords.push_back(TexCoordf(uv_right, uv_bottom));
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
PTA_int lengths;
|
||||
lengths.push_back(4);
|
||||
|
||||
_geom->set_coords(coords);
|
||||
_geom->set_texcoords(texcoords, G_PER_VERTEX);
|
||||
_geom->set_colors(colors, G_OVERALL);
|
||||
_geom->set_lengths(lengths);
|
||||
_geom->set_num_prims(1);
|
||||
|
||||
TextureTransition *tex = new TextureTransition(_page);
|
||||
TransparencyTransition *trans = new TransparencyTransition(TransparencyProperty::M_alpha);
|
||||
|
||||
_trans.set_transition(tex);
|
||||
_trans.set_transition(trans);
|
||||
|
||||
_advance = advance / pixels_per_unit;
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_FREETYPE
|
57
panda/src/text/dynamicTextGlyph.h
Normal file
57
panda/src/text/dynamicTextGlyph.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Filename: dynamicTextGlyph.h
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DYNAMICTEXTGLYPH_H
|
||||
#define DYNAMICTEXTGLYPH_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
#include "textGlyph.h"
|
||||
|
||||
class DynamicTextPage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DynamicTextGlyph
|
||||
// Description : A specialization on TextGlyph that is generated and
|
||||
// stored by a DynamicTextFont. This keeps some
|
||||
// additional information, such as where the glyph
|
||||
// appears on a texture map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DynamicTextGlyph : public TextGlyph {
|
||||
public:
|
||||
INLINE DynamicTextGlyph(DynamicTextPage *page, int x, int y,
|
||||
int x_size, int y_size, int margin);
|
||||
|
||||
INLINE bool intersects(int x, int y, int x_size, int y_size) const;
|
||||
unsigned char *get_row(int y);
|
||||
void make_geom(int top, int left, float advance, float pixels_per_unit);
|
||||
|
||||
DynamicTextPage *_page;
|
||||
|
||||
int _x, _y;
|
||||
int _x_size, _y_size;
|
||||
int _margin;
|
||||
};
|
||||
|
||||
#include "dynamicTextGlyph.I"
|
||||
|
||||
#endif // HAVE_FREETYPE
|
||||
|
||||
#endif
|
50
panda/src/text/dynamicTextPage.I
Normal file
50
panda/src/text/dynamicTextPage.I
Normal file
@ -0,0 +1,50 @@
|
||||
// Filename: dynamicTextPage.I
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: DynamicTextPage::get_x_size
|
||||
// Access: Published
|
||||
// Description: Returns the x size of the page (texture), in pixels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DynamicTextPage::
|
||||
get_x_size() const {
|
||||
return _x_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::get_y_size
|
||||
// Access: Published
|
||||
// Description: Returns the y size of the page (texture), in pixels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DynamicTextPage::
|
||||
get_y_size() const {
|
||||
return _y_size;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::is_empty
|
||||
// Access: Published
|
||||
// Description: Returns true if the page has no glyphs, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DynamicTextPage::
|
||||
is_empty() const {
|
||||
return _glyphs.empty();
|
||||
}
|
140
panda/src/text/dynamicTextPage.cxx
Normal file
140
panda/src/text/dynamicTextPage.cxx
Normal file
@ -0,0 +1,140 @@
|
||||
// Filename: dynamicTextPage.cxx
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "dynamicTextPage.h"
|
||||
#include "dynamicTextFont.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
|
||||
TypeHandle DynamicTextPage::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::Constructor
|
||||
// Access: Publiic
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextPage::
|
||||
DynamicTextPage(DynamicTextFont *font) :
|
||||
_font(font)
|
||||
{
|
||||
_x_size = _font->get_page_x_size();
|
||||
_y_size = _font->get_page_y_size();
|
||||
|
||||
// Initialize the Texture to an empty, black (transparent) image of
|
||||
// the appropriate size.
|
||||
_pbuffer = new PixelBuffer(_x_size, _y_size, 1, 1,
|
||||
PixelBuffer::T_unsigned_byte,
|
||||
PixelBuffer::F_alpha);
|
||||
mark_dirty(DF_image);
|
||||
|
||||
// We don't necessarily want to use mipmaps, since we don't want to
|
||||
// regenerate those every time the texture changes, but we do want
|
||||
// at least linear filtering.
|
||||
set_magfilter(FT_linear);
|
||||
set_minfilter(FT_linear);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::slot_glyph
|
||||
// Access: Publiic
|
||||
// Description: Finds space within the page for a glyph of the
|
||||
// indicated size. If space is found, creates a new
|
||||
// glyph object and returns it; otherwise, returns NULL.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextGlyph *DynamicTextPage::
|
||||
slot_glyph(int x_size, int y_size, int margin) {
|
||||
int x, y;
|
||||
if (!find_hole(x, y, x_size, y_size)) {
|
||||
// No room for the glyph.
|
||||
return (DynamicTextGlyph *)NULL;
|
||||
}
|
||||
|
||||
// The glyph can be fit at (x, y). Slot it.
|
||||
PT(DynamicTextGlyph) glyph =
|
||||
new DynamicTextGlyph(this, x, y, x_size, y_size, margin);
|
||||
_glyphs.push_back(glyph);
|
||||
return glyph;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::find_hole
|
||||
// Access: Private
|
||||
// Description: Searches for a hole of at least x_size by y_size
|
||||
// pixels somewhere within the page. If a suitable hole
|
||||
// is found, sets x and y to the top left corner and
|
||||
// returns true; otherwise, returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DynamicTextPage::
|
||||
find_hole(int &x, int &y, int x_size, int y_size) const {
|
||||
y = 0;
|
||||
while (y + y_size <= _y_size) {
|
||||
int next_y = _y_size;
|
||||
// Scan along the row at 'y'.
|
||||
x = 0;
|
||||
while (x + x_size <= _x_size) {
|
||||
int next_x = x;
|
||||
|
||||
// Consider the spot at x, y.
|
||||
DynamicTextGlyph *overlap = find_overlap(x, y, x_size, y_size);
|
||||
|
||||
if (overlap == (DynamicTextGlyph *)NULL) {
|
||||
// Hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
next_x = overlap->_x + overlap->_x_size;
|
||||
next_y = min(next_y, overlap->_y + overlap->_y_size);
|
||||
nassertr(next_x > x, false);
|
||||
x = next_x;
|
||||
}
|
||||
|
||||
nassertr(next_y > y, false);
|
||||
y = next_y;
|
||||
}
|
||||
|
||||
// Nope, wouldn't fit anywhere.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DynamicTextPage::find_overlap
|
||||
// Access: Private
|
||||
// Description: If the rectangle whose top left corner is x, y and
|
||||
// whose size is x_size, y_size describes an empty hole
|
||||
// that does not overlap any placed glyphs, returns
|
||||
// NULL; otherwise, returns the first placed glyph
|
||||
// that the image does overlap. It is assumed the
|
||||
// rectangle lies completely within the boundaries of
|
||||
// the page itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DynamicTextGlyph *DynamicTextPage::
|
||||
find_overlap(int x, int y, int x_size, int y_size) const {
|
||||
Glyphs::const_iterator gi;
|
||||
for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
|
||||
DynamicTextGlyph *glyph = (*gi);
|
||||
if (glyph->intersects(x, y, x_size, y_size)) {
|
||||
return glyph;
|
||||
}
|
||||
}
|
||||
|
||||
return (DynamicTextGlyph *)NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_FREETYPE
|
85
panda/src/text/dynamicTextPage.h
Normal file
85
panda/src/text/dynamicTextPage.h
Normal file
@ -0,0 +1,85 @@
|
||||
// Filename: dynamicTextPage.h
|
||||
// Created by: drose (09Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 DYNAMICTEXTPAGE_H
|
||||
#define DYNAMICTEXTPAGE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
||||
#include "texture.h"
|
||||
#include "dynamicTextGlyph.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class DynamicTextFont;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DynamicTextPage
|
||||
// Description : A single "page" of a DynamicTextFont. This is a
|
||||
// single texture that holds a number of glyphs for
|
||||
// rendering. The font starts out with one page, and
|
||||
// will add more as it needs them.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DynamicTextPage : public Texture {
|
||||
public:
|
||||
DynamicTextPage(DynamicTextFont *font);
|
||||
|
||||
DynamicTextGlyph *slot_glyph(int x_size, int y_size, int margin);
|
||||
|
||||
INLINE int get_x_size() const;
|
||||
INLINE int get_y_size() const;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE bool is_empty() const;
|
||||
|
||||
private:
|
||||
bool find_hole(int &x, int &y, int x_size, int y_size) const;
|
||||
DynamicTextGlyph *find_overlap(int x, int y, int x_size, int y_size) const;
|
||||
|
||||
typedef pvector< PT(DynamicTextGlyph) > Glyphs;
|
||||
Glyphs _glyphs;
|
||||
|
||||
int _x_size, _y_size;
|
||||
|
||||
DynamicTextFont *_font;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
Texture::init_type();
|
||||
register_type(_type_handle, "DynamicTextPage",
|
||||
Texture::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;
|
||||
};
|
||||
|
||||
#include "dynamicTextPage.I"
|
||||
|
||||
#endif // HAVE_FREETYPE
|
||||
|
||||
#endif
|
@ -41,6 +41,7 @@ StaticTextFont(Node *font_def) {
|
||||
_glyphs.clear();
|
||||
|
||||
find_characters(font_def);
|
||||
_is_valid = !_glyphs.empty();
|
||||
|
||||
if (_font->is_of_type(NamedNode::get_class_type())) {
|
||||
NamedNode *named_node = DCAST(NamedNode, _font);
|
||||
@ -48,16 +49,6 @@ StaticTextFont(Node *font_def) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StaticTextFont::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
StaticTextFont::
|
||||
~StaticTextFont() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StaticTextFont::write
|
||||
// Access: Published, Virtual
|
||||
@ -167,13 +158,13 @@ write(ostream &out, int indent_level) const {
|
||||
// code, or NULL if there is no such glyph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const TextGlyph *StaticTextFont::
|
||||
get_glyph(int character) const {
|
||||
get_glyph(int character) {
|
||||
Glyphs::const_iterator gi = _glyphs.find(character);
|
||||
if (gi == _glyphs.end()) {
|
||||
// No definition for this character.
|
||||
return (TextGlyph *)NULL;
|
||||
} else {
|
||||
return &(*gi).second;
|
||||
return (*gi).second;
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +253,7 @@ find_characters(Node *root) {
|
||||
width = alist[ilist[0]][0];
|
||||
}
|
||||
|
||||
_glyphs[character] = TextGlyph(ch, trans, width);
|
||||
_glyphs[character] = new TextGlyph(ch, trans, width);
|
||||
}
|
||||
|
||||
} else if (name == "ds") {
|
||||
|
@ -19,17 +19,12 @@
|
||||
#ifndef STATICTEXTFONT_H
|
||||
#define STATICTEXTFONT_H
|
||||
|
||||
#include <pandabase.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 "pt_Node.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class Node;
|
||||
@ -47,19 +42,18 @@ class GeomPoint;
|
||||
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;
|
||||
virtual const TextGlyph *get_glyph(int character);
|
||||
|
||||
private:
|
||||
bool find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
|
||||
AllTransitionsWrapper &trans);
|
||||
void find_characters(Node *root);
|
||||
|
||||
typedef pmap<int, TextGlyph> Glyphs;
|
||||
typedef pmap<int, PT(TextGlyph)> Glyphs;
|
||||
Glyphs _glyphs;
|
||||
float _font_height;
|
||||
PT_Node _font;
|
||||
@ -80,8 +74,6 @@ public:
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class TextNode;
|
||||
};
|
||||
|
||||
#include "staticTextFont.I"
|
||||
|
@ -17,6 +17,17 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextFont::is_valid
|
||||
// Access: Published
|
||||
// Description: Returns true if the font is valid and ready to use,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TextFont::
|
||||
is_valid() const {
|
||||
return _is_valid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextFont::get_line_height
|
||||
// Access: Published
|
||||
|
@ -40,6 +40,7 @@ isblank(char ch) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TextFont::
|
||||
TextFont() {
|
||||
_is_valid = false;
|
||||
_line_height = 1.0;
|
||||
}
|
||||
|
||||
@ -59,7 +60,7 @@ TextFont::
|
||||
// or 0.0 if the character is not known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float TextFont::
|
||||
calc_width(int ch) const {
|
||||
calc_width(int ch) {
|
||||
if (ch == ' ') {
|
||||
// A space is a special case.
|
||||
return 0.25;
|
||||
@ -82,7 +83,7 @@ calc_width(int ch) const {
|
||||
// character.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float TextFont::
|
||||
calc_width(const string &line) const {
|
||||
calc_width(const string &line) {
|
||||
float width = 0.0;
|
||||
|
||||
string::const_iterator si;
|
||||
@ -104,7 +105,7 @@ calc_width(const string &line) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string TextFont::
|
||||
wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const {
|
||||
bool preserve_trailing_whitespace) {
|
||||
string output_text;
|
||||
|
||||
size_t p = 0;
|
||||
|
@ -46,19 +46,21 @@ public:
|
||||
PUBLISHED:
|
||||
virtual ~TextFont();
|
||||
|
||||
INLINE bool is_valid() const;
|
||||
INLINE float get_line_height() const;
|
||||
|
||||
float calc_width(int ch) const;
|
||||
float calc_width(const string &line) const;
|
||||
float calc_width(int ch);
|
||||
float calc_width(const string &line);
|
||||
string wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const;
|
||||
bool preserve_trailing_whitespace);
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
virtual const TextGlyph *get_glyph(int character) const=0;
|
||||
virtual const TextGlyph *get_glyph(int character)=0;
|
||||
|
||||
protected:
|
||||
bool _is_valid;
|
||||
float _line_height;
|
||||
|
||||
public:
|
||||
|
@ -24,6 +24,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TextGlyph::
|
||||
TextGlyph() {
|
||||
_geom = (Geom *)NULL;
|
||||
_advance = 0.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -21,8 +21,10 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "allTransitionsWrapper.h"
|
||||
#include "referenceCount.h"
|
||||
#include "geom.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class Geom;
|
||||
class TextGlyph;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -31,7 +33,7 @@ class TextGlyph;
|
||||
// font. This is a piece of renderable geometry of some
|
||||
// kind.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class TextGlyph {
|
||||
class TextGlyph : public ReferenceCount {
|
||||
public:
|
||||
INLINE TextGlyph();
|
||||
INLINE TextGlyph(Geom *geom, const AllTransitionsWrapper &trans, float advance);
|
||||
@ -42,8 +44,8 @@ public:
|
||||
INLINE const AllTransitionsWrapper &get_trans() const;
|
||||
INLINE float get_advance() const;
|
||||
|
||||
private:
|
||||
Geom *_geom;
|
||||
protected:
|
||||
PT(Geom) _geom;
|
||||
AllTransitionsWrapper _trans;
|
||||
float _advance;
|
||||
};
|
||||
|
@ -47,7 +47,29 @@ END_PUBLISH
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TextNode
|
||||
// Description :
|
||||
// Description : The primary interface to this module. This class
|
||||
// does basic text assembly; given a string of text and
|
||||
// a TextFont object, it creates a piece of geometry
|
||||
// that may be placed in the 3-d or 2-d world to
|
||||
// represent the indicated text.
|
||||
//
|
||||
// The TextNode may be used in one of two ways.
|
||||
// Naively, it may be parented to the scene graph
|
||||
// directly; used in this way, you can optionally call
|
||||
// freeze() and thaw() between changing many parameters
|
||||
// in the text at once, to avoid unnecessary expensive
|
||||
// regeneration with each parameter change. However, it
|
||||
// will work, if slowly, even if you never call freeze()
|
||||
// and thaw().
|
||||
//
|
||||
// The second way TextNode may be used is as a text
|
||||
// generator. To use it in this way, call freeze() once
|
||||
// on the TextNode when you create it, and never call
|
||||
// thaw(). Do not parent the TextNode to the scene
|
||||
// graph; instea, set the properties of the text and
|
||||
// call generate() to return a node which you may parent
|
||||
// wherever you like. Each time you call generate() a
|
||||
// new node is returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA TextNode : public NamedNode {
|
||||
PUBLISHED:
|
||||
|
@ -1,4 +1,7 @@
|
||||
#include "config_text.cxx"
|
||||
#include "dynamicTextFont.cxx"
|
||||
#include "dynamicTextGlyph.cxx"
|
||||
#include "dynamicTextPage.cxx"
|
||||
#include "staticTextFont.cxx"
|
||||
#include "textFont.cxx"
|
||||
#include "textGlyph.cxx"
|
||||
|
Loading…
x
Reference in New Issue
Block a user