has_character, is_whitespace

This commit is contained in:
David Rose 2008-11-25 20:38:52 +00:00
parent afbccd3132
commit cb50a97b20
10 changed files with 234 additions and 8 deletions

View File

@ -16,7 +16,7 @@
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::Constructor
// Access: Publiic
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DynamicTextGlyph::
@ -33,7 +33,7 @@ DynamicTextGlyph(int character, DynamicTextPage *page, int x, int y,
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::Constructor
// Access: Publiic
// Access: Public
// Description: This constructor makes an empty glyph, whose only
// purpose is to remember its width. It has no bitmap
// and no Geom.

View File

@ -191,5 +191,17 @@ set_geom(GeomVertexData *vdata, GeomPrimitive *prim,
_state = state;
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::is_whitespace
// Access: Public, Virtual
// Description: Returns true if this glyph represents invisible
// whitespace, or false if it corresponds to some
// visible character.
////////////////////////////////////////////////////////////////////
bool DynamicTextGlyph::
is_whitespace() const {
return (_page == (DynamicTextPage *)NULL);
}
#endif // HAVE_FREETYPE

View File

@ -51,6 +51,7 @@ public:
float font_pixels_per_unit, float tex_pixels_per_unit);
void set_geom(GeomVertexData *vdata, GeomPrimitive *prim,
const RenderState *state);
virtual bool is_whitespace() const;
DynamicTextPage *_page;
int _geom_count;

View File

@ -626,7 +626,7 @@ assemble_text() {
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::calc_width
// Access: Private, Static
// Access: Published, Static
// Description: Returns the width of a single character, according to
// its associated font. This also correctly calculates
// the width of cheesy ligatures and accented
@ -668,7 +668,7 @@ calc_width(wchar_t character, const TextProperties &properties) {
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::calc_width
// Access: Private, Static
// Access: Published, Static
// Description: Returns the width of a single TextGraphic image.
////////////////////////////////////////////////////////////////////
float TextAssembler::
@ -677,6 +677,113 @@ calc_width(const TextGraphic *graphic, const TextProperties &properties) {
return (frame[1] - frame[0]) * properties.get_glyph_scale() * properties.get_text_scale();
}
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::has_exact_character
// Access: Published, Static
// Description: Returns true if the named character exists in the
// font exactly as named, false otherwise. Note that
// because Panda can assemble glyphs together
// automatically using cheesy accent marks, this is not
// a reliable indicator of whether a suitable glyph can
// be rendered for the character. For that, use
// has_character() instead.
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// but returns false for characters that would render
// with the "invalid glyph". It also returns false for
// characters that would be synthesized within Panda,
// but see has_character().
////////////////////////////////////////////////////////////////////
bool TextAssembler::
has_exact_character(wchar_t character, const TextProperties &properties) {
if (character == ' ' || character == '\n') {
// A space is a special case. Every font implicitly has a space.
// We also treat newlines specially.
return true;
}
TextFont *font = properties.get_font();
nassertr(font != (TextFont *)NULL, false);
const TextGlyph *glyph = NULL;
return font->get_glyph(character, glyph);
}
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::has_character
// Access: Published, Static
// Description: Returns true if the named character exists in the
// font or can be synthesized by Panda, false otherwise.
// (Panda can synthesize some accented characters by
// combining similar-looking glyphs from the font.)
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// but returns false for characters that would render
// with the "invalid glyph".
////////////////////////////////////////////////////////////////////
bool TextAssembler::
has_character(wchar_t character, const TextProperties &properties) {
if (character == ' ' || character == '\n') {
// A space is a special case. Every font implicitly has a space.
// We also treat newlines specially.
return true;
}
bool got_glyph;
const TextGlyph *first_glyph = NULL;
const TextGlyph *second_glyph = NULL;
UnicodeLatinMap::AccentType accent_type;
int additional_flags;
float glyph_scale;
float advance_scale;
get_character_glyphs(character, &properties,
got_glyph, first_glyph, second_glyph, accent_type,
additional_flags, glyph_scale, advance_scale);
return got_glyph;
}
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::is_whitespace
// Access: Published, Static
// Description: Returns true if the indicated character represents
// whitespace in the font, or false if anything visible
// will be rendered for it.
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// and returns false for any other characters, including
// characters that do not exist in the font (these would
// be rendered with the "invalid glyph", which is
// visible).
//
// Note that this function can be reliably used to
// identify Unicode whitespace characters only if the
// font has all of the whitespace characters defined.
// It will return false for any character not in the
// font, even if it is an official Unicode whitespace
// character.
////////////////////////////////////////////////////////////////////
bool TextAssembler::
is_whitespace(wchar_t character, const TextProperties &properties) {
if (character == ' ' || character == '\n') {
// A space or a newline is a special case.
return true;
}
TextFont *font = properties.get_font();
nassertr(font != (TextFont *)NULL, false);
const TextGlyph *glyph = NULL;
if (!font->get_glyph(character, glyph)) {
return false;
}
return glyph->is_whitespace();
}
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
////////////////////////////////////////////////////////////////////
// Function: TextAssembler::scan_wtext

View File

@ -93,6 +93,10 @@ PUBLISHED:
static float calc_width(wchar_t character, const TextProperties &properties);
static float calc_width(const TextGraphic *graphic, const TextProperties &properties);
static bool has_exact_character(wchar_t character, const TextProperties &properties);
static bool has_character(wchar_t character, const TextProperties &properties);
static bool is_whitespace(wchar_t character, const TextProperties &properties);
private:
class ComputedProperties : public ReferenceCount {
public:

View File

@ -22,3 +22,17 @@
TextGlyph::
~TextGlyph() {
}
////////////////////////////////////////////////////////////////////
// Function: TextGlyph::is_whitespace
// Access: Public, Virtual
// Description: Returns true if this glyph represents invisible
// whitespace, or false if it corresponds to some
// visible character.
////////////////////////////////////////////////////////////////////
bool TextGlyph::
is_whitespace() const {
// In a static font, there is no explicit glyph for whitespace, so
// all glyphs are non-whitespace.
return false;
}

View File

@ -42,6 +42,8 @@ public:
INLINE const RenderState *get_state() const;
INLINE float get_advance() const;
virtual bool is_whitespace() const;
protected:
int _character;
CPT(Geom) _geom;

View File

@ -1161,7 +1161,7 @@ append_text(const string &text) {
// Unicode.
////////////////////////////////////////////////////////////////////
INLINE void TextNode::
append_unicode_char(int character) {
append_unicode_char(wchar_t character) {
TextEncoder::append_unicode_char(character);
invalidate_with_measure();
}

View File

@ -179,7 +179,7 @@ TextNode::
// wide character (greater than 255).
////////////////////////////////////////////////////////////////////
float TextNode::
calc_width(int character) const {
calc_width(wchar_t character) const {
TextFont *font = get_font();
if (font == (TextFont *)NULL) {
return 0.0f;
@ -188,6 +188,88 @@ calc_width(int character) const {
return TextAssembler::calc_width(character, *this);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::has_exact_character
// Access: Published
// Description: Returns true if the named character exists in the
// font exactly as named, false otherwise. Note that
// because Panda can assemble glyphs together
// automatically using cheesy accent marks, this is not
// a reliable indicator of whether a suitable glyph can
// be rendered for the character. For that, use
// has_character() instead.
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// but returns false for characters that would render
// with the "invalid glyph". It also returns false for
// characters that would be synthesized within Panda,
// but see has_character().
////////////////////////////////////////////////////////////////////
bool TextNode::
has_exact_character(wchar_t character) const {
TextFont *font = get_font();
if (font == (TextFont *)NULL) {
return false;
}
return TextAssembler::has_exact_character(character, *this);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::has_character
// Access: Published
// Description: Returns true if the named character exists in the
// font or can be synthesized by Panda, false otherwise.
// (Panda can synthesize some accented characters by
// combining similar-looking glyphs from the font.)
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// but returns false for characters that would render
// with the "invalid glyph".
////////////////////////////////////////////////////////////////////
bool TextNode::
has_character(wchar_t character) const {
TextFont *font = get_font();
if (font == (TextFont *)NULL) {
return false;
}
return TextAssembler::has_character(character, *this);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::is_whitespace
// Access: Published
// Description: Returns true if the indicated character represents
// whitespace in the font, or false if anything visible
// will be rendered for it.
//
// This returns true for whitespace and Unicode
// whitespace characters (if they exist in the font),
// and returns false for any other characters, including
// characters that do not exist in the font (these would
// be rendered with the "invalid glyph", which is
// visible).
//
// Note that this function can be reliably used to
// identify Unicode whitespace characters only if the
// font has all of the whitespace characters defined.
// It will return false for any character not in the
// font, even if it is an official Unicode whitespace
// character.
////////////////////////////////////////////////////////////////////
bool TextNode::
is_whitespace(wchar_t character) const {
TextFont *font = get_font();
if (font == (TextFont *)NULL) {
return false;
}
return TextAssembler::is_whitespace(character, *this);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::calc_width
// Access: Published

View File

@ -183,7 +183,7 @@ PUBLISHED:
INLINE void set_text(const string &text, Encoding encoding);
INLINE void clear_text();
INLINE void append_text(const string &text);
INLINE void append_unicode_char(int character);
INLINE void append_unicode_char(wchar_t character);
// After the text has been set, you can query this to determine how
// it will be wordwrapped.
@ -191,9 +191,13 @@ PUBLISHED:
// These methods calculate the width of a single character or a line
// of text in the current font.
float calc_width(int character) const;
float calc_width(wchar_t character) const;
INLINE float calc_width(const string &line) const;
bool has_exact_character(wchar_t character) const;
bool has_character(wchar_t character) const;
bool is_whitespace(wchar_t character) const;
// Direct support for wide-character strings.
INLINE void set_wtext(const wstring &wtext);
INLINE void append_wtext(const wstring &text);