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

View File

@ -191,5 +191,17 @@ set_geom(GeomVertexData *vdata, GeomPrimitive *prim,
_state = state; _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 #endif // HAVE_FREETYPE

View File

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

View File

@ -626,7 +626,7 @@ assemble_text() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextAssembler::calc_width // Function: TextAssembler::calc_width
// Access: Private, Static // Access: Published, Static
// Description: Returns the width of a single character, according to // Description: Returns the width of a single character, according to
// its associated font. This also correctly calculates // its associated font. This also correctly calculates
// the width of cheesy ligatures and accented // the width of cheesy ligatures and accented
@ -668,7 +668,7 @@ calc_width(wchar_t character, const TextProperties &properties) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextAssembler::calc_width // Function: TextAssembler::calc_width
// Access: Private, Static // Access: Published, Static
// Description: Returns the width of a single TextGraphic image. // Description: Returns the width of a single TextGraphic image.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float TextAssembler:: 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(); 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. #ifndef CPPPARSER // interrogate has a bit of trouble with wstring.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextAssembler::scan_wtext // 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(wchar_t character, const TextProperties &properties);
static float calc_width(const TextGraphic *graphic, 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: private:
class ComputedProperties : public ReferenceCount { class ComputedProperties : public ReferenceCount {
public: public:

View File

@ -22,3 +22,17 @@
TextGlyph:: TextGlyph::
~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 const RenderState *get_state() const;
INLINE float get_advance() const; INLINE float get_advance() const;
virtual bool is_whitespace() const;
protected: protected:
int _character; int _character;
CPT(Geom) _geom; CPT(Geom) _geom;

View File

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

View File

@ -179,7 +179,7 @@ TextNode::
// wide character (greater than 255). // wide character (greater than 255).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float TextNode:: float TextNode::
calc_width(int character) const { calc_width(wchar_t character) const {
TextFont *font = get_font(); TextFont *font = get_font();
if (font == (TextFont *)NULL) { if (font == (TextFont *)NULL) {
return 0.0f; return 0.0f;
@ -188,6 +188,88 @@ calc_width(int character) const {
return TextAssembler::calc_width(character, *this); 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 // Function: TextNode::calc_width
// Access: Published // Access: Published

View File

@ -183,7 +183,7 @@ PUBLISHED:
INLINE void set_text(const string &text, Encoding encoding); INLINE void set_text(const string &text, Encoding encoding);
INLINE void clear_text(); INLINE void clear_text();
INLINE void append_text(const string &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 // After the text has been set, you can query this to determine how
// it will be wordwrapped. // it will be wordwrapped.
@ -191,8 +191,12 @@ PUBLISHED:
// These methods calculate the width of a single character or a line // These methods calculate the width of a single character or a line
// of text in the current font. // 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; 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. // Direct support for wide-character strings.
INLINE void set_wtext(const wstring &wtext); INLINE void set_wtext(const wstring &wtext);