mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
TextFont::make_copy()
This commit is contained in:
parent
62889f3fa6
commit
6a7580ca45
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define TARGET pnmtext
|
#define TARGET pnmtext
|
||||||
#define LOCAL_LIBS \
|
#define LOCAL_LIBS \
|
||||||
pnmimage putil linmath
|
pnmimage putil linmath pipeline
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_pnmtext.cxx config_pnmtext.h \
|
config_pnmtext.cxx config_pnmtext.h \
|
||||||
|
@ -12,25 +12,3 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FreetypeFace::get_face
|
|
||||||
// Access: Published
|
|
||||||
// Description: Retrieves the internal freetype face.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE FT_Face FreetypeFace::
|
|
||||||
get_face() {
|
|
||||||
return _face;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FreetypeFace::set_face
|
|
||||||
// Access: Published
|
|
||||||
// Description: Sets the internal freetype face.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void FreetypeFace::
|
|
||||||
set_face(FT_Face face) {
|
|
||||||
if (_face != NULL){
|
|
||||||
FT_Done_Face(_face);
|
|
||||||
}
|
|
||||||
_face = face;
|
|
||||||
}
|
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
|
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
|
|
||||||
|
#include "config_pnmtext.h"
|
||||||
|
|
||||||
|
FT_Library FreetypeFace::_ft_library;
|
||||||
|
bool FreetypeFace::_ft_initialized = false;
|
||||||
|
bool FreetypeFace::_ft_ok = false;
|
||||||
|
|
||||||
TypeHandle FreetypeFace::_type_handle;
|
TypeHandle FreetypeFace::_type_handle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -24,8 +30,16 @@ TypeHandle FreetypeFace::_type_handle;
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
FreetypeFace::
|
FreetypeFace::
|
||||||
FreetypeFace() {
|
FreetypeFace() : _lock("FreetypeFace::_lock") {
|
||||||
_face = NULL;
|
_face = NULL;
|
||||||
|
_char_size = 0;
|
||||||
|
_dpi = 0;
|
||||||
|
_pixel_width = 0;
|
||||||
|
_pixel_height = 0;
|
||||||
|
|
||||||
|
if (!_ft_initialized) {
|
||||||
|
initialize_ft_library();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -40,4 +54,131 @@ FreetypeFace::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFace::acquire_face
|
||||||
|
// Access: Public
|
||||||
|
// Description: Retrieves the internal freetype face, and also
|
||||||
|
// acquires the lock. The freetype face is set to the
|
||||||
|
// indicated size, either as a char_size and dpi, or as
|
||||||
|
// a specific pixel_width and height, before returning.
|
||||||
|
//
|
||||||
|
// You must call release_face() when you are done using
|
||||||
|
// it, to release the lock.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FT_Face FreetypeFace::
|
||||||
|
acquire_face(int char_size, int dpi, int pixel_width, int pixel_height) {
|
||||||
|
_lock.acquire();
|
||||||
|
|
||||||
|
if (pixel_height != 0) {
|
||||||
|
if (pixel_height != _pixel_height || pixel_width != _pixel_width) {
|
||||||
|
_char_size = 0;
|
||||||
|
_dpi = 0;
|
||||||
|
_pixel_height = pixel_height;
|
||||||
|
_pixel_width = pixel_width;
|
||||||
|
FT_Set_Pixel_Sizes(_face, _pixel_width, _pixel_height);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (char_size != _char_size || dpi != _dpi) {
|
||||||
|
_char_size = char_size;
|
||||||
|
_dpi = dpi;
|
||||||
|
_pixel_height = 0;
|
||||||
|
_pixel_width = 0;
|
||||||
|
if (_char_size != 0) {
|
||||||
|
FT_Set_Char_Size(_face, _char_size, _char_size, _dpi, _dpi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _face;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFace::release_face
|
||||||
|
// Access: Public
|
||||||
|
// Description: Releases the lock acquired by a previous call to
|
||||||
|
// acquire_face(), and allows another thread to use the
|
||||||
|
// face.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FreetypeFace::
|
||||||
|
release_face(FT_Face face) {
|
||||||
|
nassertv(_face == face);
|
||||||
|
_lock.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFace::set_face
|
||||||
|
// Access: Public
|
||||||
|
// Description: Replaces the internal freetype face.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FreetypeFace::
|
||||||
|
set_face(FT_Face face) {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
|
||||||
|
if (_face != NULL){
|
||||||
|
FT_Done_Face(_face);
|
||||||
|
}
|
||||||
|
_face = face;
|
||||||
|
_char_size = 0;
|
||||||
|
_dpi = 0;
|
||||||
|
_pixel_width = 0;
|
||||||
|
_pixel_height = 0;
|
||||||
|
|
||||||
|
_name = _face->family_name;
|
||||||
|
if (_face->style_name != NULL) {
|
||||||
|
_name += " ";
|
||||||
|
_name += _face->style_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnmtext_cat.info()
|
||||||
|
<< "Loaded font " << _name << "\n";
|
||||||
|
|
||||||
|
if (pnmtext_cat.is_debug()) {
|
||||||
|
pnmtext_cat.debug()
|
||||||
|
<< _name << " has " << _face->num_charmaps << " charmaps:\n";
|
||||||
|
for (int i = 0; i < _face->num_charmaps; i++) {
|
||||||
|
pnmtext_cat.debug(false) << " " << (void *)_face->charmaps[i];
|
||||||
|
}
|
||||||
|
pnmtext_cat.debug(false) << "\n";
|
||||||
|
pnmtext_cat.debug()
|
||||||
|
<< "default charmap is " << (void *)_face->charmap << "\n";
|
||||||
|
}
|
||||||
|
if (_face->charmap == NULL) {
|
||||||
|
// If for some reason FreeType didn't set us up a charmap,
|
||||||
|
// then set it up ourselves.
|
||||||
|
if (_face->num_charmaps == 0) {
|
||||||
|
pnmtext_cat.warning()
|
||||||
|
<< _name << " has no charmaps available.\n";
|
||||||
|
} else {
|
||||||
|
pnmtext_cat.warning()
|
||||||
|
<< _name << " has no default Unicode charmap.\n";
|
||||||
|
if (_face->num_charmaps > 1) {
|
||||||
|
pnmtext_cat.warning()
|
||||||
|
<< "Arbitrarily choosing first of "
|
||||||
|
<< _face->num_charmaps << " charmaps.\n";
|
||||||
|
}
|
||||||
|
FT_Set_Charmap(_face, _face->charmaps[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFace::initialize_ft_library
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Should be called exactly once to initialize the
|
||||||
|
// FreeType library.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FreetypeFace::
|
||||||
|
initialize_ft_library() {
|
||||||
|
if (!_ft_initialized) {
|
||||||
|
int error = FT_Init_FreeType(&_ft_library);
|
||||||
|
_ft_initialized = true;
|
||||||
|
if (error) {
|
||||||
|
pnmtext_cat.error()
|
||||||
|
<< "Unable to initialize FreeType; dynamic fonts will not load.\n";
|
||||||
|
} else {
|
||||||
|
_ft_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // HAVE_FREETYPE
|
#endif // HAVE_FREETYPE
|
||||||
|
@ -19,13 +19,10 @@
|
|||||||
|
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
|
|
||||||
//#include "config_pnmtext.h"
|
|
||||||
//#include "filename.h"
|
|
||||||
//#include "pvector.h"
|
|
||||||
//#include "pmap.h"
|
|
||||||
//#include "pnmImage.h"
|
|
||||||
#include "typedReferenceCount.h"
|
#include "typedReferenceCount.h"
|
||||||
#include "namable.h"
|
#include "namable.h"
|
||||||
|
#include "pmutex.h"
|
||||||
|
#include "mutexHolder.h"
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
@ -40,16 +37,33 @@
|
|||||||
class EXPCL_PANDA_PNMTEXT FreetypeFace : public TypedReferenceCount, public Namable {
|
class EXPCL_PANDA_PNMTEXT FreetypeFace : public TypedReferenceCount, public Namable {
|
||||||
public:
|
public:
|
||||||
FreetypeFace();
|
FreetypeFace();
|
||||||
|
|
||||||
PUBLISHED:
|
|
||||||
~FreetypeFace();
|
~FreetypeFace();
|
||||||
|
|
||||||
INLINE FT_Face get_face();
|
FT_Face acquire_face();
|
||||||
INLINE void set_face(FT_Face face);
|
FT_Face acquire_face(int char_size, int dpi, int pixel_width, int pixel_height);
|
||||||
|
void release_face(FT_Face face);
|
||||||
|
|
||||||
|
void set_face(FT_Face face);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FT_Face _face;
|
static void initialize_ft_library();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This is provided as a permanent storage for the raw font data, if
|
||||||
|
// needed.
|
||||||
|
string _font_data;
|
||||||
|
|
||||||
|
string _name;
|
||||||
|
FT_Face _face;
|
||||||
|
int _char_size;
|
||||||
|
int _dpi;
|
||||||
|
int _pixel_width;
|
||||||
|
int _pixel_height;
|
||||||
|
Mutex _lock;
|
||||||
|
|
||||||
|
static FT_Library _ft_library;
|
||||||
|
static bool _ft_initialized;
|
||||||
|
static bool _ft_ok;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
@ -67,6 +81,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class FreetypeFont;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ get_native_antialias() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE int FreetypeFont::
|
INLINE int FreetypeFont::
|
||||||
get_font_pixel_size() const {
|
get_font_pixel_size() const {
|
||||||
return _font_pixel_size;
|
return _pixel_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -231,3 +231,31 @@ INLINE float FreetypeFont::
|
|||||||
get_points_per_inch() {
|
get_points_per_inch() {
|
||||||
return _points_per_inch;
|
return _points_per_inch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFont::acquire_face
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Retrieves the internal freetype face, and also
|
||||||
|
// acquires the lock.
|
||||||
|
//
|
||||||
|
// You must call release_face() when you are done using
|
||||||
|
// it, to release the lock.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FT_Face FreetypeFont::
|
||||||
|
acquire_face() const {
|
||||||
|
nassertr(_face != NULL, NULL);
|
||||||
|
return _face->acquire_face(_char_size, _dpi, _pixel_width, _pixel_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFont::release_face
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Releases the lock acquired by a previous call to
|
||||||
|
// acquire_face(), and allows another thread to use the
|
||||||
|
// face.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FreetypeFont::
|
||||||
|
release_face(FT_Face face) const {
|
||||||
|
nassertv(_face != NULL);
|
||||||
|
_face->release_face(face);
|
||||||
|
}
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include "config_express.h"
|
#include "config_express.h"
|
||||||
#include "virtualFileSystem.h"
|
#include "virtualFileSystem.h"
|
||||||
|
|
||||||
FT_Library FreetypeFont::_ft_library;
|
|
||||||
bool FreetypeFont::_ft_initialized = false;
|
|
||||||
bool FreetypeFont::_ft_ok = false;
|
|
||||||
|
|
||||||
// This constant determines how big a particular point size font
|
// This constant determines how big a particular point size font
|
||||||
// appears to be. By convention, 10 points is 1 unit (e.g. 1 foot)
|
// appears to be. By convention, 10 points is 1 unit (e.g. 1 foot)
|
||||||
// high.
|
// high.
|
||||||
@ -40,8 +36,6 @@ const float FreetypeFont::_points_per_inch = 72.0f;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
FreetypeFont::
|
FreetypeFont::
|
||||||
FreetypeFont() {
|
FreetypeFont() {
|
||||||
_font_loaded = false;
|
|
||||||
|
|
||||||
_face = NULL;
|
_face = NULL;
|
||||||
|
|
||||||
_point_size = text_point_size;
|
_point_size = text_point_size;
|
||||||
@ -51,13 +45,37 @@ FreetypeFont() {
|
|||||||
_scale_factor = text_scale_factor;
|
_scale_factor = text_scale_factor;
|
||||||
_native_antialias = text_native_antialias;
|
_native_antialias = text_native_antialias;
|
||||||
|
|
||||||
_font_pixel_size = 0;
|
|
||||||
_line_height = 1.0f;
|
_line_height = 1.0f;
|
||||||
_space_advance = 0.25f;
|
_space_advance = 0.25f;
|
||||||
|
|
||||||
if (!_ft_initialized) {
|
_char_size = 0;
|
||||||
initialize_ft_library();
|
_dpi = 0;
|
||||||
}
|
_pixel_width = 0;
|
||||||
|
_pixel_height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FreetypeFont::Copy Constructor
|
||||||
|
// Access: Protected
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FreetypeFont::
|
||||||
|
FreetypeFont(const FreetypeFont ©) :
|
||||||
|
Namable(copy),
|
||||||
|
_face(copy._face),
|
||||||
|
_point_size(copy._point_size),
|
||||||
|
_requested_pixels_per_unit(copy._requested_pixels_per_unit),
|
||||||
|
_tex_pixels_per_unit(copy._tex_pixels_per_unit),
|
||||||
|
_requested_scale_factor(copy._requested_scale_factor),
|
||||||
|
_scale_factor(copy._scale_factor),
|
||||||
|
_native_antialias(copy._native_antialias),
|
||||||
|
_line_height(copy._line_height),
|
||||||
|
_space_advance(copy._space_advance),
|
||||||
|
_char_size(copy._char_size),
|
||||||
|
_dpi(copy._dpi),
|
||||||
|
_pixel_width(copy._pixel_width),
|
||||||
|
_pixel_height(copy._pixel_height)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -70,31 +88,32 @@ FreetypeFont() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool FreetypeFont::
|
bool FreetypeFont::
|
||||||
load_font(const Filename &font_filename, int face_index) {
|
load_font(const Filename &font_filename, int face_index) {
|
||||||
if (!_ft_ok) {
|
unload_font();
|
||||||
|
_face = new FreetypeFace;
|
||||||
|
if (!_face->_ft_ok) {
|
||||||
pnmtext_cat.error()
|
pnmtext_cat.error()
|
||||||
<< "Unable to read font " << font_filename
|
<< "Unable to read font " << font_filename
|
||||||
<< ": FreeType library not initialized properly.\n";
|
<< ": FreeType library not initialized properly.\n";
|
||||||
|
unload_font();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unload_font();
|
|
||||||
|
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
int error;
|
int error;
|
||||||
Filename path(font_filename);
|
Filename path(font_filename);
|
||||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
vfs->resolve_filename(path, get_model_path());
|
vfs->resolve_filename(path, get_model_path());
|
||||||
exists = vfs->read_file(path, _raw_font_data, true);
|
exists = vfs->read_file(path, _face->_font_data, true);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
error = FT_New_Memory_Face(_ft_library,
|
error = FT_New_Memory_Face(_face->_ft_library,
|
||||||
(const FT_Byte *)_raw_font_data.data(),
|
(const FT_Byte *)_face->_font_data.data(),
|
||||||
_raw_font_data.length(),
|
_face->_font_data.length(),
|
||||||
face_index, &face);
|
face_index, &face);
|
||||||
_face = new FreetypeFace();
|
|
||||||
_face->set_face(face);
|
_face->set_face(face);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool okflag = false;
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
pnmtext_cat.error()
|
pnmtext_cat.error()
|
||||||
<< "Unable to find font file " << font_filename << "\n";
|
<< "Unable to find font file " << font_filename << "\n";
|
||||||
@ -107,11 +126,15 @@ load_font(const Filename &font_filename, int face_index) {
|
|||||||
<< "Unable to read font " << font_filename << ": invalid.\n";
|
<< "Unable to read font " << font_filename << ": invalid.\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return font_loaded();
|
okflag = reset_scale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!okflag) {
|
||||||
|
unload_font();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return okflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -123,22 +146,24 @@ load_font(const Filename &font_filename, int face_index) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool FreetypeFont::
|
bool FreetypeFont::
|
||||||
load_font(const char *font_data, int data_length, int face_index) {
|
load_font(const char *font_data, int data_length, int face_index) {
|
||||||
if (!_ft_ok) {
|
unload_font();
|
||||||
|
_face = new FreetypeFace;
|
||||||
|
|
||||||
|
if (!_face->_ft_ok) {
|
||||||
pnmtext_cat.error()
|
pnmtext_cat.error()
|
||||||
<< "Unable to read font: FreeType library not initialized properly.\n";
|
<< "Unable to read font: FreeType library not initialized properly.\n";
|
||||||
|
unload_font();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unload_font();
|
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
error = FT_New_Memory_Face(_ft_library,
|
error = FT_New_Memory_Face(_face->_ft_library,
|
||||||
(const FT_Byte *)font_data, data_length,
|
(const FT_Byte *)font_data, data_length,
|
||||||
face_index, &face);
|
face_index, &face);
|
||||||
_face = new FreetypeFace();
|
|
||||||
_face->set_face(face);
|
_face->set_face(face);
|
||||||
|
|
||||||
|
bool okflag = false;
|
||||||
if (error == FT_Err_Unknown_File_Format) {
|
if (error == FT_Err_Unknown_File_Format) {
|
||||||
pnmtext_cat.error()
|
pnmtext_cat.error()
|
||||||
<< "Unable to read font: unknown file format.\n";
|
<< "Unable to read font: unknown file format.\n";
|
||||||
@ -147,10 +172,14 @@ load_font(const char *font_data, int data_length, int face_index) {
|
|||||||
<< "Unable to read font: invalid.\n";
|
<< "Unable to read font: invalid.\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return font_loaded();
|
okflag = reset_scale();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!okflag) {
|
||||||
|
unload_font();
|
||||||
|
}
|
||||||
|
|
||||||
|
return okflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -160,10 +189,7 @@ load_font(const char *font_data, int data_length, int face_index) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void FreetypeFont::
|
void FreetypeFont::
|
||||||
unload_font() {
|
unload_font() {
|
||||||
if (_font_loaded) {
|
_face = NULL;
|
||||||
_face = NULL;
|
|
||||||
_font_loaded = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -174,7 +200,7 @@ unload_font() {
|
|||||||
// false otherwise.
|
// false otherwise.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool FreetypeFont::
|
bool FreetypeFont::
|
||||||
load_glyph(int glyph_index, bool prerender) {
|
load_glyph(FT_Face face, int glyph_index, bool prerender) {
|
||||||
int flags = FT_LOAD_RENDER;
|
int flags = FT_LOAD_RENDER;
|
||||||
if (!_native_antialias) {
|
if (!_native_antialias) {
|
||||||
flags |= FT_LOAD_MONOCHROME;
|
flags |= FT_LOAD_MONOCHROME;
|
||||||
@ -186,7 +212,7 @@ load_glyph(int glyph_index, bool prerender) {
|
|||||||
flags = 0;
|
flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int error = FT_Load_Glyph(_face->get_face(), glyph_index, flags);
|
int error = FT_Load_Glyph(face, glyph_index, flags);
|
||||||
if (error) {
|
if (error) {
|
||||||
pnmtext_cat.error()
|
pnmtext_cat.error()
|
||||||
<< "Unable to render glyph " << glyph_index << "\n";
|
<< "Unable to render glyph " << glyph_index << "\n";
|
||||||
@ -256,57 +282,6 @@ copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image) {
|
|||||||
<< "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
|
<< "Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FreetypeFont::font_loaded
|
|
||||||
// Access: Private
|
|
||||||
// Description: Called after a font has been successfully loaded,
|
|
||||||
// either from disk or from memory image.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool FreetypeFont::
|
|
||||||
font_loaded() {
|
|
||||||
string name = _face->get_face()->family_name;
|
|
||||||
if (_face->get_face()->style_name != NULL) {
|
|
||||||
name += " ";
|
|
||||||
name += _face->get_face()->style_name;
|
|
||||||
}
|
|
||||||
set_name(name);
|
|
||||||
|
|
||||||
pnmtext_cat.info()
|
|
||||||
<< "Loaded font " << name << "\n";
|
|
||||||
_font_loaded = true;
|
|
||||||
reset_scale();
|
|
||||||
|
|
||||||
if (pnmtext_cat.is_debug()) {
|
|
||||||
pnmtext_cat.debug()
|
|
||||||
<< name << " has " << _face->get_face()->num_charmaps << " charmaps:\n";
|
|
||||||
for (int i = 0; i < _face->get_face()->num_charmaps; i++) {
|
|
||||||
pnmtext_cat.debug(false) << " " << (void *)_face->get_face()->charmaps[i];
|
|
||||||
}
|
|
||||||
pnmtext_cat.debug(false) << "\n";
|
|
||||||
pnmtext_cat.debug()
|
|
||||||
<< "default charmap is " << (void *)_face->get_face()->charmap << "\n";
|
|
||||||
}
|
|
||||||
if (_face->get_face()->charmap == NULL) {
|
|
||||||
// If for some reason FreeType didn't set us up a charmap,
|
|
||||||
// then set it up ourselves.
|
|
||||||
if (_face->get_face()->num_charmaps == 0) {
|
|
||||||
pnmtext_cat.warning()
|
|
||||||
<< name << " has no charmaps available.\n";
|
|
||||||
} else {
|
|
||||||
pnmtext_cat.warning()
|
|
||||||
<< name << " has no default Unicode charmap.\n";
|
|
||||||
if (_face->get_face()->num_charmaps > 1) {
|
|
||||||
pnmtext_cat.warning()
|
|
||||||
<< "Arbitrarily choosing first of "
|
|
||||||
<< _face->get_face()->num_charmaps << " charmaps.\n";
|
|
||||||
}
|
|
||||||
FT_Set_Charmap(_face->get_face(), _face->get_face()->charmaps[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: FreetypeFont::reset_scale
|
// Function: FreetypeFont::reset_scale
|
||||||
@ -317,6 +292,14 @@ font_loaded() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool FreetypeFont::
|
bool FreetypeFont::
|
||||||
reset_scale() {
|
reset_scale() {
|
||||||
|
if (_face == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the face, without requesting a particular size yet (we'll
|
||||||
|
// figure out the size in a second).
|
||||||
|
FT_Face face = _face->acquire_face(0, 0, 0, 0);
|
||||||
|
|
||||||
// The font may be rendered larger (by a factor of _scale_factor),
|
// The font may be rendered larger (by a factor of _scale_factor),
|
||||||
// and then reduced into the texture. Hence the difference between
|
// and then reduced into the texture. Hence the difference between
|
||||||
// _font_pixels_per_unit and _tex_pixels_per_unit.
|
// _font_pixels_per_unit and _tex_pixels_per_unit.
|
||||||
@ -324,13 +307,13 @@ reset_scale() {
|
|||||||
_scale_factor = _requested_scale_factor;
|
_scale_factor = _requested_scale_factor;
|
||||||
_font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
|
_font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
|
||||||
|
|
||||||
|
_pixel_height = 0;
|
||||||
|
_pixel_width = 0;
|
||||||
float units_per_inch = (_points_per_inch / _points_per_unit);
|
float units_per_inch = (_points_per_inch / _points_per_unit);
|
||||||
int dpi = (int)(_font_pixels_per_unit * units_per_inch);
|
_dpi = (int)(_font_pixels_per_unit * units_per_inch);
|
||||||
|
_char_size = (int)(_point_size * 64);
|
||||||
|
|
||||||
_font_pixel_size = 0;
|
int error = FT_Set_Char_Size(face, _char_size, _char_size, _dpi, _dpi);
|
||||||
int error = FT_Set_Char_Size(_face->get_face(),
|
|
||||||
(int)(_point_size * 64), (int)(_point_size * 64),
|
|
||||||
dpi, dpi);
|
|
||||||
if (error) {
|
if (error) {
|
||||||
// If we were unable to set a particular char size, perhaps we
|
// If we were unable to set a particular char size, perhaps we
|
||||||
// have a non-scalable font. Try to figure out the next larger
|
// have a non-scalable font. Try to figure out the next larger
|
||||||
@ -339,16 +322,16 @@ reset_scale() {
|
|||||||
int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
|
int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
|
||||||
int best_size = -1;
|
int best_size = -1;
|
||||||
int largest_size = -1;
|
int largest_size = -1;
|
||||||
if (_face->get_face()->num_fixed_sizes > 0) {
|
if (face->num_fixed_sizes > 0) {
|
||||||
largest_size = 0;
|
largest_size = 0;
|
||||||
int best_diff = 0;
|
int best_diff = 0;
|
||||||
for (int i = 0; i < _face->get_face()->num_fixed_sizes; i++) {
|
for (int i = 0; i < face->num_fixed_sizes; i++) {
|
||||||
int diff = _face->get_face()->available_sizes[i].height - desired_height;
|
int diff = face->available_sizes[i].height - desired_height;
|
||||||
if (diff > 0 && (best_size == -1 || diff < best_diff)) {
|
if (diff > 0 && (best_size == -1 || diff < best_diff)) {
|
||||||
best_size = i;
|
best_size = i;
|
||||||
best_diff = diff;
|
best_diff = diff;
|
||||||
}
|
}
|
||||||
if (_face->get_face()->available_sizes[i].height > _face->get_face()->available_sizes[largest_size].height) {
|
if (face->available_sizes[i].height > face->available_sizes[largest_size].height) {
|
||||||
largest_size = i;
|
largest_size = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,13 +341,12 @@ reset_scale() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (best_size >= 0) {
|
if (best_size >= 0) {
|
||||||
int pixel_height = _face->get_face()->available_sizes[best_size].height;
|
_pixel_height = face->available_sizes[best_size].height;
|
||||||
int pixel_width = _face->get_face()->available_sizes[best_size].width;
|
_pixel_width = face->available_sizes[best_size].width;
|
||||||
error = FT_Set_Pixel_Sizes(_face->get_face(), pixel_width, pixel_height);
|
error = FT_Set_Pixel_Sizes(face, _pixel_width, _pixel_height);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
_font_pixels_per_unit = pixel_height * _points_per_unit / _point_size;
|
_font_pixels_per_unit = _pixel_height * _points_per_unit / _point_size;
|
||||||
_scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
|
_scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
|
||||||
_font_pixel_size = pixel_height;
|
|
||||||
|
|
||||||
if (_scale_factor < 1.0) {
|
if (_scale_factor < 1.0) {
|
||||||
// No point in enlarging a fixed-point font.
|
// No point in enlarging a fixed-point font.
|
||||||
@ -378,44 +360,26 @@ reset_scale() {
|
|||||||
if (error) {
|
if (error) {
|
||||||
pnmtext_cat.warning()
|
pnmtext_cat.warning()
|
||||||
<< "Unable to set " << get_name()
|
<< "Unable to set " << get_name()
|
||||||
<< " to " << _point_size << "pt at " << dpi << " dpi.\n";
|
<< " to " << _point_size << "pt at " << _dpi << " dpi.\n";
|
||||||
_line_height = 1.0f;
|
_line_height = 1.0f;
|
||||||
|
_face->release_face(face);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_line_height = _face->get_face()->size->metrics.height / (_font_pixels_per_unit * 64.0f);
|
_line_height = face->size->metrics.height / (_font_pixels_per_unit * 64.0f);
|
||||||
|
|
||||||
// Determine the correct width for a space.
|
// Determine the correct width for a space.
|
||||||
error = FT_Load_Char(_face->get_face(), ' ', FT_LOAD_DEFAULT);
|
error = FT_Load_Char(face, ' ', FT_LOAD_DEFAULT);
|
||||||
if (error) {
|
if (error) {
|
||||||
// Space isn't defined. Oh well.
|
// Space isn't defined. Oh well.
|
||||||
_space_advance = 0.25f * _line_height;
|
_space_advance = 0.25f * _line_height;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_space_advance = _face->get_face()->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
|
_space_advance = face->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_face->release_face(face);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FreetypeFont::initialize_ft_library
|
|
||||||
// Access: Private, Static
|
|
||||||
// Description: Should be called exactly once to initialize the
|
|
||||||
// FreeType library.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void FreetypeFont::
|
|
||||||
initialize_ft_library() {
|
|
||||||
if (!_ft_initialized) {
|
|
||||||
int error = FT_Init_FreeType(&_ft_library);
|
|
||||||
_ft_initialized = true;
|
|
||||||
if (error) {
|
|
||||||
pnmtext_cat.error()
|
|
||||||
<< "Unable to initialize FreeType; dynamic fonts will not load.\n";
|
|
||||||
} else {
|
|
||||||
_ft_ok = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_FREETYPE
|
#endif // HAVE_FREETYPE
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
class EXPCL_PANDA_PNMTEXT FreetypeFont : public Namable {
|
class EXPCL_PANDA_PNMTEXT FreetypeFont : public Namable {
|
||||||
protected:
|
protected:
|
||||||
FreetypeFont();
|
FreetypeFont();
|
||||||
|
FreetypeFont(const FreetypeFont ©);
|
||||||
|
|
||||||
bool load_font(const Filename &font_filename, int face_index);
|
bool load_font(const Filename &font_filename, int face_index);
|
||||||
bool load_font(const char *font_data, int data_length, int face_index);
|
bool load_font(const char *font_data, int data_length, int face_index);
|
||||||
@ -73,13 +74,14 @@ PUBLISHED:
|
|||||||
INLINE static float get_points_per_inch();
|
INLINE static float get_points_per_inch();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool load_glyph(int glyph_index, bool prerender = true);
|
INLINE FT_Face acquire_face() const;
|
||||||
|
INLINE void release_face(FT_Face face) const;
|
||||||
|
|
||||||
|
bool load_glyph(FT_Face face, int glyph_index, bool prerender = true);
|
||||||
void copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image);
|
void copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool font_loaded();
|
|
||||||
bool reset_scale();
|
bool reset_scale();
|
||||||
static void initialize_ft_library();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float _point_size;
|
float _point_size;
|
||||||
@ -95,19 +97,12 @@ protected:
|
|||||||
float _space_advance;
|
float _space_advance;
|
||||||
|
|
||||||
PT(FreetypeFace) _face;
|
PT(FreetypeFace) _face;
|
||||||
|
int _char_size;
|
||||||
|
int _dpi;
|
||||||
|
int _pixel_width;
|
||||||
|
int _pixel_height;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _font_loaded;
|
|
||||||
|
|
||||||
// This string is used to hold the data read from the font file in
|
|
||||||
// vfs mode. Since the FreeType library keeps pointers into this
|
|
||||||
// data, we have to keep it around.
|
|
||||||
string _raw_font_data;
|
|
||||||
|
|
||||||
static FT_Library _ft_library;
|
|
||||||
static bool _ft_initialized;
|
|
||||||
static bool _ft_ok;
|
|
||||||
|
|
||||||
static const float _points_per_unit;
|
static const float _points_per_unit;
|
||||||
static const float _points_per_inch;
|
static const float _points_per_inch;
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,22 @@ PNMTextMaker(const char *font_data, int data_length, int face_index) {
|
|||||||
_is_valid = load_font(font_data, data_length, face_index);
|
_is_valid = load_font(font_data, data_length, face_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMTextMaker::Copy Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PNMTextMaker::
|
||||||
|
PNMTextMaker(const PNMTextMaker ©) :
|
||||||
|
FreetypeFont(copy),
|
||||||
|
_is_valid(copy._is_valid),
|
||||||
|
_align(copy._align),
|
||||||
|
_interior_flag(copy._interior_flag),
|
||||||
|
_fg(copy._fg),
|
||||||
|
_interior(copy._interior)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PNMTextMaker::Destructor
|
// Function: PNMTextMaker::Destructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -124,7 +140,9 @@ calc_width(const wstring &text) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PNMTextGlyph *PNMTextMaker::
|
PNMTextGlyph *PNMTextMaker::
|
||||||
get_glyph(int character) {
|
get_glyph(int character) {
|
||||||
int glyph_index = FT_Get_Char_Index(_face->get_face(), character);
|
FT_Face face = acquire_face();
|
||||||
|
int glyph_index = FT_Get_Char_Index(face, character);
|
||||||
|
release_face(face);
|
||||||
|
|
||||||
Glyphs::iterator gi;
|
Glyphs::iterator gi;
|
||||||
gi = _glyphs.find(glyph_index);
|
gi = _glyphs.find(glyph_index);
|
||||||
@ -159,23 +177,25 @@ initialize() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PNMTextGlyph *PNMTextMaker::
|
PNMTextGlyph *PNMTextMaker::
|
||||||
make_glyph(int glyph_index) {
|
make_glyph(int glyph_index) {
|
||||||
if (!load_glyph(glyph_index)) {
|
FT_Face face = acquire_face();
|
||||||
|
if (!load_glyph(face, glyph_index)) {
|
||||||
|
release_face(face);
|
||||||
return (PNMTextGlyph *)NULL;
|
return (PNMTextGlyph *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_GlyphSlot slot = _face->get_face()->glyph;
|
FT_GlyphSlot slot = face->glyph;
|
||||||
|
|
||||||
FT_Bitmap &bitmap = slot->bitmap;
|
FT_Bitmap &bitmap = slot->bitmap;
|
||||||
|
|
||||||
double advance = slot->advance.x / 64.0;
|
double advance = slot->advance.x / 64.0;
|
||||||
|
|
||||||
|
PNMTextGlyph *glyph = new PNMTextGlyph(advance);
|
||||||
|
|
||||||
if (bitmap.width == 0 || bitmap.rows == 0) {
|
if (bitmap.width == 0 || bitmap.rows == 0) {
|
||||||
// If we got an empty bitmap, it's a special case.
|
// If we got an empty bitmap, it's a special case.
|
||||||
PNMTextGlyph *glyph = new PNMTextGlyph(advance);
|
|
||||||
glyph->rescale(_scale_factor);
|
glyph->rescale(_scale_factor);
|
||||||
return glyph;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PNMTextGlyph *glyph = new PNMTextGlyph(advance);
|
|
||||||
PNMImage &glyph_image = glyph->_image;
|
PNMImage &glyph_image = glyph->_image;
|
||||||
glyph_image.clear(bitmap.width, bitmap.rows, 3);
|
glyph_image.clear(bitmap.width, bitmap.rows, 3);
|
||||||
copy_bitmap_to_pnmimage(bitmap, glyph_image);
|
copy_bitmap_to_pnmimage(bitmap, glyph_image);
|
||||||
@ -187,8 +207,10 @@ make_glyph(int glyph_index) {
|
|||||||
glyph->determine_interior();
|
glyph->determine_interior();
|
||||||
}
|
}
|
||||||
glyph->rescale(_scale_factor);
|
glyph->rescale(_scale_factor);
|
||||||
return glyph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
release_face(face);
|
||||||
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -40,6 +40,7 @@ class EXPCL_PANDA_PNMTEXT PNMTextMaker : public FreetypeFont {
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
PNMTextMaker(const Filename &font_filename, int face_index);
|
PNMTextMaker(const Filename &font_filename, int face_index);
|
||||||
PNMTextMaker(const char *font_data, int data_length, int face_index);
|
PNMTextMaker(const char *font_data, int data_length, int face_index);
|
||||||
|
PNMTextMaker(const PNMTextMaker ©);
|
||||||
~PNMTextMaker();
|
~PNMTextMaker();
|
||||||
|
|
||||||
enum Alignment {
|
enum Alignment {
|
||||||
|
@ -99,6 +99,36 @@ DynamicTextFont(const char *font_data, int data_length, int face_index) {
|
|||||||
_needs_image_processing = false;
|
_needs_image_processing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::Copy Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DynamicTextFont::
|
||||||
|
DynamicTextFont(const DynamicTextFont ©) :
|
||||||
|
TextFont(copy),
|
||||||
|
FreetypeFont(copy),
|
||||||
|
_texture_margin(copy._texture_margin),
|
||||||
|
_poly_margin(copy._poly_margin),
|
||||||
|
_page_x_size(copy._page_x_size),
|
||||||
|
_page_y_size(copy._page_y_size),
|
||||||
|
_minfilter(copy._minfilter),
|
||||||
|
_magfilter(copy._magfilter),
|
||||||
|
_anisotropic_degree(copy._anisotropic_degree),
|
||||||
|
_render_mode(copy._render_mode),
|
||||||
|
_winding_order(copy._winding_order),
|
||||||
|
_fg(copy._fg),
|
||||||
|
_bg(copy._bg),
|
||||||
|
_outline_color(copy._outline_color),
|
||||||
|
_outline_width(copy._outline_width),
|
||||||
|
_outline_feather(copy._outline_feather),
|
||||||
|
_has_outline(copy._has_outline),
|
||||||
|
_tex_format(copy._tex_format),
|
||||||
|
_needs_image_processing(copy._needs_image_processing),
|
||||||
|
_preferred_page(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::Destructor
|
// Function: DynamicTextFont::Destructor
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -108,6 +138,16 @@ DynamicTextFont::
|
|||||||
~DynamicTextFont() {
|
~DynamicTextFont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DynamicTextFont::make_copy
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new copy of the same font.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(TextFont) DynamicTextFont::
|
||||||
|
make_copy() const {
|
||||||
|
return new DynamicTextFont(*this);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DynamicTextFont::get_num_pages
|
// Function: DynamicTextFont::get_num_pages
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -216,8 +256,9 @@ write(ostream &out, int indent_level) const {
|
|||||||
indent(out, indent_level + 2)
|
indent(out, indent_level + 2)
|
||||||
<< glyph_index;
|
<< glyph_index;
|
||||||
|
|
||||||
if (FT_HAS_GLYPH_NAMES(_face->get_face())) {
|
FT_Face face = acquire_face();
|
||||||
int error = FT_Get_Glyph_Name(_face->get_face(), glyph_index,
|
if (FT_HAS_GLYPH_NAMES(face)) {
|
||||||
|
int error = FT_Get_Glyph_Name(face, glyph_index,
|
||||||
glyph_name, max_glyph_name);
|
glyph_name, max_glyph_name);
|
||||||
|
|
||||||
// Some fonts, notably MS Mincho, claim to have glyph names but
|
// Some fonts, notably MS Mincho, claim to have glyph names but
|
||||||
@ -226,6 +267,7 @@ write(ostream &out, int indent_level) const {
|
|||||||
out << " (" << glyph_name << ")";
|
out << " (" << glyph_name << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_face(face);
|
||||||
|
|
||||||
out << ", count = " << glyph->_geom_count << "\n";
|
out << ", count = " << glyph->_geom_count << "\n";
|
||||||
}
|
}
|
||||||
@ -249,7 +291,8 @@ get_glyph(int character, const TextGlyph *&glyph) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int glyph_index = FT_Get_Char_Index(_face->get_face(), character);
|
FT_Face face = acquire_face();
|
||||||
|
int glyph_index = FT_Get_Char_Index(face, character);
|
||||||
if (text_cat.is_spam()) {
|
if (text_cat.is_spam()) {
|
||||||
text_cat.spam()
|
text_cat.spam()
|
||||||
<< *this << " maps " << character << " to glyph " << glyph_index << "\n";
|
<< *this << " maps " << character << " to glyph " << glyph_index << "\n";
|
||||||
@ -259,7 +302,7 @@ get_glyph(int character, const TextGlyph *&glyph) {
|
|||||||
if (ci != _cache.end()) {
|
if (ci != _cache.end()) {
|
||||||
glyph = (*ci).second;
|
glyph = (*ci).second;
|
||||||
} else {
|
} else {
|
||||||
DynamicTextGlyph *dynamic_glyph = make_glyph(character, glyph_index);
|
DynamicTextGlyph *dynamic_glyph = make_glyph(character, face, glyph_index);
|
||||||
_cache.insert(Cache::value_type(glyph_index, dynamic_glyph));
|
_cache.insert(Cache::value_type(glyph_index, dynamic_glyph));
|
||||||
glyph = dynamic_glyph;
|
glyph = dynamic_glyph;
|
||||||
}
|
}
|
||||||
@ -269,6 +312,7 @@ get_glyph(int character, const TextGlyph *&glyph) {
|
|||||||
glyph_index = 0;
|
glyph_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
release_face(face);
|
||||||
return (glyph_index != 0);
|
return (glyph_index != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,12 +443,12 @@ determine_tex_format() {
|
|||||||
// glyph cannot be created for some reason.
|
// glyph cannot be created for some reason.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
DynamicTextGlyph *DynamicTextFont::
|
DynamicTextGlyph *DynamicTextFont::
|
||||||
make_glyph(int character, int glyph_index) {
|
make_glyph(int character, FT_Face face, int glyph_index) {
|
||||||
if (!load_glyph(glyph_index, false)) {
|
if (!load_glyph(face, glyph_index, false)) {
|
||||||
return (DynamicTextGlyph *)NULL;
|
return (DynamicTextGlyph *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_GlyphSlot slot = _face->get_face()->glyph;
|
FT_GlyphSlot slot = face->glyph;
|
||||||
FT_Bitmap &bitmap = slot->bitmap;
|
FT_Bitmap &bitmap = slot->bitmap;
|
||||||
|
|
||||||
if ((bitmap.width == 0 || bitmap.rows == 0) && (glyph_index == 0)) {
|
if ((bitmap.width == 0 || bitmap.rows == 0) && (glyph_index == 0)) {
|
||||||
@ -423,7 +467,7 @@ make_glyph(int character, int glyph_index) {
|
|||||||
// Re-stroke the glyph to make it an outline glyph.
|
// Re-stroke the glyph to make it an outline glyph.
|
||||||
/*
|
/*
|
||||||
FT_Stroker stroker;
|
FT_Stroker stroker;
|
||||||
FT_Stroker_New(_face->get_face()->memory, &stroker);
|
FT_Stroker_New(face->memory, &stroker);
|
||||||
FT_Stroker_Set(stroker, 16 * 16, FT_STROKER_LINECAP_BUTT,
|
FT_Stroker_Set(stroker, 16 * 16, FT_STROKER_LINECAP_BUTT,
|
||||||
FT_STROKER_LINEJOIN_ROUND, 0);
|
FT_STROKER_LINEJOIN_ROUND, 0);
|
||||||
|
|
||||||
|
@ -44,8 +44,11 @@ class EXPCL_PANDA_TEXT DynamicTextFont : public TextFont, public FreetypeFont {
|
|||||||
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);
|
DynamicTextFont(const char *font_data, int data_length, int face_index);
|
||||||
|
DynamicTextFont(const DynamicTextFont ©);
|
||||||
virtual ~DynamicTextFont();
|
virtual ~DynamicTextFont();
|
||||||
|
|
||||||
|
virtual PT(TextFont) make_copy() const;
|
||||||
|
|
||||||
INLINE const string &get_name() const;
|
INLINE const string &get_name() const;
|
||||||
|
|
||||||
INLINE bool set_point_size(float point_size);
|
INLINE bool set_point_size(float point_size);
|
||||||
@ -113,7 +116,7 @@ private:
|
|||||||
void initialize();
|
void initialize();
|
||||||
void update_filters();
|
void update_filters();
|
||||||
void determine_tex_format();
|
void determine_tex_format();
|
||||||
DynamicTextGlyph *make_glyph(int character, int glyph_index);
|
DynamicTextGlyph *make_glyph(int character, FT_Face face, int glyph_index);
|
||||||
void copy_bitmap_to_texture(const FT_Bitmap &bitmap, DynamicTextGlyph *glyph);
|
void copy_bitmap_to_texture(const FT_Bitmap &bitmap, DynamicTextGlyph *glyph);
|
||||||
void copy_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph);
|
void copy_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph);
|
||||||
void blend_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph,
|
void blend_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph,
|
||||||
|
@ -74,6 +74,16 @@ StaticTextFont(PandaNode *font_def) {
|
|||||||
set_name(font_def->get_name());
|
set_name(font_def->get_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: StaticTextFont::make_copy
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new copy of the same font.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(TextFont) StaticTextFont::
|
||||||
|
make_copy() const {
|
||||||
|
return new StaticTextFont(_font);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: StaticTextFont::write
|
// Function: StaticTextFont::write
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
|
@ -41,6 +41,8 @@ class EXPCL_PANDA_TEXT StaticTextFont : public TextFont {
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
StaticTextFont(PandaNode *font_def);
|
StaticTextFont(PandaNode *font_def);
|
||||||
|
|
||||||
|
virtual PT(TextFont) make_copy() const;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -36,6 +36,20 @@ TextFont() {
|
|||||||
_space_advance = 0.25f;
|
_space_advance = 0.25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextFont::Copy Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TextFont::
|
||||||
|
TextFont(const TextFont ©) :
|
||||||
|
Namable(copy),
|
||||||
|
_is_valid(copy._is_valid),
|
||||||
|
_line_height(copy._line_height),
|
||||||
|
_space_advance(copy._space_advance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::Destructor
|
// Function: TextFont::Destructor
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
class EXPCL_PANDA_TEXT TextFont : public TypedReferenceCount, public Namable {
|
class EXPCL_PANDA_TEXT TextFont : public TypedReferenceCount, public Namable {
|
||||||
public:
|
public:
|
||||||
TextFont();
|
TextFont();
|
||||||
|
TextFont(const TextFont ©);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
virtual ~TextFont();
|
virtual ~TextFont();
|
||||||
@ -68,6 +69,7 @@ PUBLISHED:
|
|||||||
WO_invalid,
|
WO_invalid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual PT(TextFont) make_copy() const=0;
|
||||||
|
|
||||||
INLINE bool is_valid() const;
|
INLINE bool is_valid() const;
|
||||||
INLINE operator bool () const;
|
INLINE operator bool () const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user