mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
more control over encoding
This commit is contained in:
parent
84cb559f00
commit
9aeeb1ce1a
@ -154,6 +154,7 @@ get_default_encoding() {
|
||||
return _default_encoding;
|
||||
}
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::set_expand_amp
|
||||
// Access: Published
|
||||
@ -185,6 +186,7 @@ INLINE bool TextNode::
|
||||
get_expand_amp() const {
|
||||
return (_flags & F_expand_amp) != 0;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_line_height
|
||||
@ -1129,6 +1131,21 @@ set_text(const string &text) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::set_text
|
||||
// Access: Published
|
||||
// Description: The two-parameter version of set_text() accepts an
|
||||
// explicit encoding; the text is immediately decoded
|
||||
// and stored as a wide-character string. Subsequent
|
||||
// calls to get_text() will return the same text
|
||||
// re-encoded using whichever encoding is specified by
|
||||
// set_encoding().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextNode::
|
||||
set_text(const string &text, TextNode::Encoding encoding) {
|
||||
set_wtext(decode_text(text, encoding));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::clear_text
|
||||
// Access: Published
|
||||
@ -1159,7 +1176,8 @@ has_text() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_text
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: Returns the current text, as encoded via the current
|
||||
// encoding system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
get_text() const {
|
||||
@ -1170,6 +1188,17 @@ get_text() const {
|
||||
return _text;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_text
|
||||
// Access: Published
|
||||
// Description: Returns the current text, as encoded via the indicated
|
||||
// encoding system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
get_text(TextNode::Encoding encoding) const {
|
||||
return encode_wtext(get_wtext(), encoding);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::append_text
|
||||
// Access: Published
|
||||
@ -1184,14 +1213,14 @@ append_text(const string &text) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::append_char
|
||||
// Function: TextNode::append_unicode_char
|
||||
// Access: Published
|
||||
// Description: Appends a single character to the end of the stored
|
||||
// text. This may be a wide character, up to 16 bits in
|
||||
// Unicode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextNode::
|
||||
append_char(int character) {
|
||||
append_unicode_char(int character) {
|
||||
_wtext = get_wtext() + wstring(1, (wchar_t)character);
|
||||
_flags = (_flags | F_got_wtext) & ~F_got_text;
|
||||
invalidate_with_measure();
|
||||
@ -1210,7 +1239,7 @@ get_num_chars() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_char
|
||||
// Function: TextNode::get_unicode_char
|
||||
// Access: Published
|
||||
// Description: Returns the Unicode value of the nth character in the
|
||||
// stored text. This may be a wide character (greater
|
||||
@ -1218,12 +1247,35 @@ get_num_chars() const {
|
||||
// according to set_encoding().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TextNode::
|
||||
get_char(int index) const {
|
||||
get_unicode_char(int index) const {
|
||||
get_wtext();
|
||||
nassertr(index >= 0 && index < (int)_wtext.length(), 0);
|
||||
return _wtext[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_encoded_char
|
||||
// Access: Published
|
||||
// Description: Returns the nth char of the stored text, as a one-,
|
||||
// two-, or three-byte encoded string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
get_encoded_char(int index) const {
|
||||
return get_encoded_char(index, get_encoding());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_encoded_char
|
||||
// Access: Published
|
||||
// Description: Returns the nth char of the stored text, as a one-,
|
||||
// two-, or three-byte encoded string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
get_encoded_char(int index, TextNode::Encoding encoding) const {
|
||||
wstring wch(1, (wchar_t)get_unicode_char(index));
|
||||
return encode_wtext(wch, encoding);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::get_text_as_ascii
|
||||
// Access: Published
|
||||
@ -1248,6 +1300,21 @@ get_text_as_ascii() const {
|
||||
return encode_wtext(get_wtext_as_ascii());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::reencode_text
|
||||
// Access: Published, Static
|
||||
// Description: Given the indicated text string, which is assumed to
|
||||
// be encoded via the encoding "from", decodes it and
|
||||
// then reencodes it into the encoding "to", and returns
|
||||
// the newly encoded string. This does not change or
|
||||
// affect any properties on the TextNode itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
reencode_text(const string &text, TextNode::Encoding from,
|
||||
TextNode::Encoding to) {
|
||||
return encode_wtext(decode_text(text, from), to);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::calc_width
|
||||
// Access: Published
|
||||
@ -1491,6 +1558,28 @@ wordwrap_to(const wstring &wtext, float wordwrap_width,
|
||||
return _font->wordwrap_to(wtext, wordwrap_width, preserve_trailing_whitespace);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::encode_wtext
|
||||
// Access: Public
|
||||
// Description: Encodes a wide-text string into a single-char string,
|
||||
// according to the current encoding.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
encode_wtext(const wstring &wtext) const {
|
||||
return encode_wtext(wtext, _encoding);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::decode_text
|
||||
// Access: Public
|
||||
// Description: Returns the given wstring decoded to a single-byte
|
||||
// string, via the current encoding system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE wstring TextNode::
|
||||
decode_text(const string &text) const {
|
||||
return decode_text(text, _encoding);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::invalidate_no_measure
|
||||
// Access: Private
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "cullTraverserData.h"
|
||||
#include "geometricBoundingVolume.h"
|
||||
#include "accumulatedAttribs.h"
|
||||
#include "renderState.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "dcast.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -466,18 +468,34 @@ get_wtext_as_ascii() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::encode_wchar
|
||||
// Access: Public
|
||||
// Access: Public, Static
|
||||
// Description: Encodes a single wide char into a one-, two-, or
|
||||
// three-byte string, according to the current encoding
|
||||
// system in effect.
|
||||
// three-byte string, according to the given encoding
|
||||
// system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string TextNode::
|
||||
encode_wchar(wchar_t ch) const {
|
||||
switch (_encoding) {
|
||||
encode_wchar(wchar_t ch, TextNode::Encoding encoding) {
|
||||
switch (encoding) {
|
||||
case E_iso8859:
|
||||
if (isascii((unsigned int)ch)) {
|
||||
if (ch < 0x100) {
|
||||
return string(1, (char)ch);
|
||||
} else {
|
||||
// The character won't fit in the 8-bit ISO 8859. See if we can
|
||||
// make it fit by reducing it to its ascii equivalent
|
||||
// (essentially stripping off an unusual accent mark).
|
||||
const UnicodeLatinMap::Entry *map_entry =
|
||||
UnicodeLatinMap::look_up(ch);
|
||||
if (map_entry != NULL && map_entry->_ascii_equiv != 0) {
|
||||
// Yes, it has an ascii equivalent.
|
||||
if (map_entry->_ascii_additional != 0) {
|
||||
// In fact, it has two of them.
|
||||
return
|
||||
string(1, map_entry->_ascii_equiv) +
|
||||
string(1, map_entry->_ascii_additional);
|
||||
}
|
||||
return string(1, map_entry->_ascii_equiv);
|
||||
}
|
||||
// Nope; return "." for lack of anything better.
|
||||
return ".";
|
||||
}
|
||||
|
||||
@ -506,16 +524,16 @@ encode_wchar(wchar_t ch) const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::encode_wtext
|
||||
// Access: Public
|
||||
// Access: Public, Static
|
||||
// Description: Encodes a wide-text string into a single-char string,
|
||||
// accoding to the current encoding.
|
||||
// according to the given encoding.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string TextNode::
|
||||
encode_wtext(const wstring &wtext) const {
|
||||
encode_wtext(const wstring &wtext, TextNode::Encoding encoding) {
|
||||
string result;
|
||||
|
||||
for (wstring::const_iterator pi = wtext.begin(); pi != wtext.end(); ++pi) {
|
||||
result += encode_wchar(*pi);
|
||||
result += encode_wchar(*pi, encoding);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -523,13 +541,13 @@ encode_wtext(const wstring &wtext) const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::decode_text
|
||||
// Access: Public
|
||||
// Access: Public, Static
|
||||
// Description: Returns the given wstring decoded to a single-byte
|
||||
// string, via the current encoding system.
|
||||
// string, via the given encoding system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
wstring TextNode::
|
||||
decode_text(const string &text) const {
|
||||
switch (_encoding) {
|
||||
decode_text(const string &text, TextNode::Encoding encoding) {
|
||||
switch (encoding) {
|
||||
case E_utf8:
|
||||
{
|
||||
StringUtf8Decoder decoder(text);
|
||||
@ -762,22 +780,24 @@ recompute_internal_bound() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::decode_text_impl
|
||||
// Access: Private
|
||||
// Access: Private, Static
|
||||
// Description: Decodes the eight-bit stream from the indicated
|
||||
// decoder, returning the decoded wide-char string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
wstring TextNode::
|
||||
decode_text_impl(StringDecoder &decoder) const {
|
||||
decode_text_impl(StringDecoder &decoder) {
|
||||
wstring result;
|
||||
bool expand_amp = get_expand_amp();
|
||||
// bool expand_amp = get_expand_amp();
|
||||
|
||||
wchar_t character = decoder.get_next_character();
|
||||
while (!decoder.is_eof()) {
|
||||
/*
|
||||
if (character == '&' && expand_amp) {
|
||||
// An ampersand in expand_amp mode is treated as an escape
|
||||
// character.
|
||||
character = expand_amp_sequence(decoder);
|
||||
}
|
||||
*/
|
||||
result += character;
|
||||
character = decoder.get_next_character();
|
||||
}
|
||||
@ -785,6 +805,7 @@ decode_text_impl(StringDecoder &decoder) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::expand_amp_sequence
|
||||
// Access: Private
|
||||
@ -832,7 +853,7 @@ expand_amp_sequence(StringDecoder &decoder) const {
|
||||
int code;
|
||||
} tokens[] = {
|
||||
{ "amp", '&' }, { "lt", '<' }, { "gt", '>' }, { "quot", '"' },
|
||||
{ "nbsp", ' ' /* 160 */ },
|
||||
{ "nbsp", ' ' },
|
||||
|
||||
{ "iexcl", 161 }, { "cent", 162 }, { "pound", 163 }, { "curren", 164 },
|
||||
{ "yen", 165 }, { "brvbar", 166 }, { "brkbar", 166 }, { "sect", 167 },
|
||||
@ -873,6 +894,7 @@ expand_amp_sequence(StringDecoder &decoder) const {
|
||||
// Some unrecognized sequence.
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1494,6 +1516,10 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
float t, u;
|
||||
LMatrix4f accent_mat;
|
||||
|
||||
// This gets set to true if the glyph gets mirrored and needs
|
||||
// to have backface culling disabled.
|
||||
bool mirrored = false;
|
||||
|
||||
switch (transform) {
|
||||
case CT_none:
|
||||
accent_mat = LMatrix4f::ident_mat();
|
||||
@ -1504,6 +1530,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
t = min_accent[0];
|
||||
min_accent[0] = -max_accent[0];
|
||||
max_accent[0] = -t;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_mirror_y:
|
||||
@ -1511,6 +1538,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
t = min_accent[2];
|
||||
min_accent[2] = -max_accent[2];
|
||||
max_accent[2] = -t;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_rotate_90:
|
||||
@ -1563,6 +1591,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
t = min_accent[2];
|
||||
min_accent[2] = -max_accent[2] * squash_accent_scale_y;
|
||||
max_accent[2] = -t * squash_accent_scale_y;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_squash_mirror_diag:
|
||||
@ -1577,6 +1606,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
max_accent[0] = max_accent[2] * -squash_accent_scale_x;
|
||||
min_accent[2] = -u * squash_accent_scale_y;
|
||||
max_accent[2] = -t * squash_accent_scale_y;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_small_squash:
|
||||
@ -1594,6 +1624,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
t = min_accent[2];
|
||||
min_accent[2] = -max_accent[2] * small_squash_accent_scale_y;
|
||||
max_accent[2] = -t * small_squash_accent_scale_y;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_small:
|
||||
@ -1630,6 +1661,7 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
max_accent[0] = -t * tiny_accent_scale;
|
||||
min_accent[2] *= tiny_accent_scale;
|
||||
max_accent[2] *= tiny_accent_scale;
|
||||
mirrored = true;
|
||||
break;
|
||||
|
||||
case CT_tiny_rotate_270:
|
||||
@ -1685,7 +1717,21 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement,
|
||||
accent_mat.set_row(3, trans);
|
||||
accent_geom->transform_vertices(accent_mat);
|
||||
|
||||
if (mirrored) {
|
||||
// Once someone asks for this pointer, we hold its reference
|
||||
// count and never free it.
|
||||
static CPT(RenderState) disable_backface;
|
||||
if (disable_backface == (const RenderState *)NULL) {
|
||||
disable_backface = RenderState::make
|
||||
(CullFaceAttrib::make(CullFaceAttrib::M_cull_none));
|
||||
}
|
||||
|
||||
CPT(RenderState) state =
|
||||
accent_glyph->get_state()->compose(disable_backface);
|
||||
dest->add_geom(accent_geom, state);
|
||||
} else {
|
||||
dest->add_geom(accent_geom, accent_glyph->get_state());
|
||||
}
|
||||
geom_array[num_geoms++] = accent_geom;
|
||||
|
||||
return true;
|
||||
|
@ -84,8 +84,10 @@ PUBLISHED:
|
||||
INLINE static void set_default_encoding(Encoding encoding);
|
||||
INLINE static Encoding get_default_encoding();
|
||||
|
||||
/*
|
||||
INLINE void set_expand_amp(bool expand_amp);
|
||||
INLINE bool get_expand_amp() const;
|
||||
*/
|
||||
|
||||
INLINE float get_line_height() const;
|
||||
|
||||
@ -180,15 +182,21 @@ PUBLISHED:
|
||||
INLINE CoordinateSystem get_coordinate_system() const;
|
||||
|
||||
INLINE void set_text(const string &text);
|
||||
INLINE void set_text(const string &text, Encoding encoding);
|
||||
INLINE void clear_text();
|
||||
INLINE bool has_text() const;
|
||||
INLINE string get_text() const;
|
||||
INLINE string get_text(Encoding encoding) const;
|
||||
INLINE void append_text(const string &text);
|
||||
INLINE void append_char(int character);
|
||||
INLINE void append_unicode_char(int character);
|
||||
INLINE int get_num_chars() const;
|
||||
INLINE int get_char(int index) const;
|
||||
INLINE int get_unicode_char(int index) const;
|
||||
INLINE string get_encoded_char(int index) const;
|
||||
INLINE string get_encoded_char(int index, Encoding encoding) const;
|
||||
INLINE string get_text_as_ascii() const;
|
||||
|
||||
INLINE static string reencode_text(const string &text, Encoding from, Encoding to);
|
||||
|
||||
INLINE float calc_width(int character) const;
|
||||
INLINE float calc_width(const string &line) const;
|
||||
string wordwrap_to(const string &text, float wordwrap_width,
|
||||
@ -225,9 +233,11 @@ public:
|
||||
INLINE wstring wordwrap_to(const wstring &wtext, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const;
|
||||
|
||||
string encode_wchar(wchar_t ch) const;
|
||||
string encode_wtext(const wstring &wtext) const;
|
||||
wstring decode_text(const string &text) const;
|
||||
static string encode_wchar(wchar_t ch, Encoding encoding);
|
||||
INLINE string encode_wtext(const wstring &wtext) const;
|
||||
static string encode_wtext(const wstring &wtext, Encoding encoding);
|
||||
INLINE wstring decode_text(const string &text) const;
|
||||
static wstring decode_text(const string &text, Encoding encoding);
|
||||
|
||||
// From parent class PandaNode
|
||||
virtual int get_unsafe_to_apply_attribs() const;
|
||||
@ -245,8 +255,8 @@ public:
|
||||
virtual BoundingVolume *recompute_internal_bound();
|
||||
|
||||
private:
|
||||
wstring decode_text_impl(StringDecoder &decoder) const;
|
||||
int expand_amp_sequence(StringDecoder &decoder) const;
|
||||
static wstring decode_text_impl(StringDecoder &decoder);
|
||||
// int expand_amp_sequence(StringDecoder &decoder) const;
|
||||
|
||||
INLINE void invalidate_no_measure();
|
||||
INLINE void invalidate_with_measure();
|
||||
@ -344,7 +354,7 @@ private:
|
||||
F_frame_corners = 0x00000100,
|
||||
F_card_transp = 0x00000200,
|
||||
F_has_card_border = 0x00000400,
|
||||
F_expand_amp = 0x00000800,
|
||||
// F_expand_amp = 0x00000800,
|
||||
F_got_text = 0x00001000,
|
||||
F_got_wtext = 0x00002000,
|
||||
F_needs_rebuild = 0x00004000,
|
||||
|
Loading…
x
Reference in New Issue
Block a user