mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
add text-soft-break-key and text-never-break-before
This commit is contained in:
parent
9ca106399c
commit
56a9f1feae
@ -52,14 +52,29 @@ const float text_tab_width = config_text.GetFloat("text-tab-width", 5.0f);
|
|||||||
// identified as the soft-hyphen character.
|
// identified as the soft-hyphen character.
|
||||||
const int text_soft_hyphen_key = config_text.GetInt("text-soft-hyphen-key", 3);
|
const int text_soft_hyphen_key = config_text.GetInt("text-soft-hyphen-key", 3);
|
||||||
|
|
||||||
|
// This is similar to the soft-hyphen key, above, except that when it
|
||||||
|
// is used as a break point, no character is introduced in its place.
|
||||||
|
const int text_soft_break_key = config_text.GetInt("text-soft-break-key", 4);
|
||||||
|
|
||||||
// This is the string that is output, encoded in the default encoding,
|
// This is the string that is output, encoded in the default encoding,
|
||||||
// to represent the soft-hyphen character.
|
// to represent the hyphen character that is introduced when the line
|
||||||
|
// is broken at a soft-hyphen key.
|
||||||
wstring *text_soft_hyphen_output;
|
wstring *text_soft_hyphen_output;
|
||||||
|
|
||||||
// If the rightmost whitespace character falls before this fraction of
|
// If the rightmost whitespace character falls before this fraction of
|
||||||
// the line, hyphenate a word to the right of that if possible.
|
// the line, hyphenate a word to the right of that if possible.
|
||||||
const float text_hyphen_ratio = config_text.GetFloat("text-hyphen-ratio", 0.7);
|
const float text_hyphen_ratio = config_text.GetFloat("text-hyphen-ratio", 0.7);
|
||||||
|
|
||||||
|
// This string represents a list of individual characters that should
|
||||||
|
// never appear at the beginning of a line following a forced break.
|
||||||
|
// Typically these will be punctuation characters.
|
||||||
|
wstring *text_never_break_before;
|
||||||
|
|
||||||
|
// Unless we have more than this number of text_never_break_before
|
||||||
|
// characters in a row, in which case forget it and break wherever we
|
||||||
|
// can.
|
||||||
|
const int text_max_never_break = config_text.GetInt("text-max-never-break", 3);
|
||||||
|
|
||||||
Texture::FilterType text_minfilter = Texture::FT_invalid;
|
Texture::FilterType text_minfilter = Texture::FT_invalid;
|
||||||
Texture::FilterType text_magfilter = Texture::FT_invalid;
|
Texture::FilterType text_magfilter = Texture::FT_invalid;
|
||||||
|
|
||||||
@ -119,7 +134,10 @@ init_libtext() {
|
|||||||
// Make sure libexpress is initialized before we ask something of
|
// Make sure libexpress is initialized before we ask something of
|
||||||
// TextEncoder.
|
// TextEncoder.
|
||||||
init_libexpress();
|
init_libexpress();
|
||||||
string encoded = config_text.GetString("text-soft-hyphen-output", "-");
|
|
||||||
TextEncoder encoder;
|
TextEncoder encoder;
|
||||||
text_soft_hyphen_output = new wstring(encoder.decode_text(encoded));
|
string st1 = config_text.GetString("text-soft-hyphen-output", "-");
|
||||||
|
text_soft_hyphen_output = new wstring(encoder.decode_text(st1));
|
||||||
|
|
||||||
|
string st2 = config_text.GetString("text-never-break-before", ",.-:?!;");
|
||||||
|
text_never_break_before = new wstring(encoder.decode_text(st2));
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,11 @@ extern const float text_small_caps_scale;
|
|||||||
extern const string text_default_font;
|
extern const string text_default_font;
|
||||||
extern const float text_tab_width;
|
extern const float text_tab_width;
|
||||||
extern const int text_soft_hyphen_key;
|
extern const int text_soft_hyphen_key;
|
||||||
|
extern const int text_soft_break_key;
|
||||||
extern wstring *text_soft_hyphen_output;
|
extern wstring *text_soft_hyphen_output;
|
||||||
extern const float text_hyphen_ratio;
|
extern const float text_hyphen_ratio;
|
||||||
|
extern wstring *text_never_break_before;
|
||||||
|
extern const int text_max_never_break;
|
||||||
|
|
||||||
extern Texture::FilterType text_minfilter;
|
extern Texture::FilterType text_minfilter;
|
||||||
extern Texture::FilterType text_magfilter;
|
extern Texture::FilterType text_magfilter;
|
||||||
|
@ -30,7 +30,9 @@ TypeHandle TextFont::_type_handle;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
static INLINE bool
|
static INLINE bool
|
||||||
isbreakpoint(unsigned int ch) {
|
isbreakpoint(unsigned int ch) {
|
||||||
return (ch == ' ' || ch == '\t' || ch == (unsigned int)text_soft_hyphen_key);
|
return (ch == ' ' || ch == '\t' ||
|
||||||
|
ch == (unsigned int)text_soft_hyphen_key ||
|
||||||
|
ch == (unsigned int)text_soft_break_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -219,7 +221,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
|||||||
float hyphen_width = calc_width(*text_soft_hyphen_output);
|
float hyphen_width = calc_width(*text_soft_hyphen_output);
|
||||||
float width = initial_width;
|
float width = initial_width;
|
||||||
while (q < text.length() && text[q] != '\n') {
|
while (q < text.length() && text[q] != '\n') {
|
||||||
if (isspacew(text[q])) {
|
if (isspacew(text[q]) || text[q] == text_soft_break_key) {
|
||||||
if (!last_was_space) {
|
if (!last_was_space) {
|
||||||
any_spaces = true;
|
any_spaces = true;
|
||||||
// We only care about logging whether there is a soft-hyphen
|
// We only care about logging whether there is a soft-hyphen
|
||||||
@ -235,7 +237,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A soft hyphen character is not printed, but marks a point
|
// A soft hyphen character is not printed, but marks a point
|
||||||
// that we might hyphenate a word if we need to.
|
// at which we might hyphenate a word if we need to.
|
||||||
if (text[q] == text_soft_hyphen_key) {
|
if (text[q] == text_soft_hyphen_key) {
|
||||||
// We only consider this as a possible hyphenation point if
|
// We only consider this as a possible hyphenation point if
|
||||||
// (a) it is not the very first character, and (b) there is
|
// (a) it is not the very first character, and (b) there is
|
||||||
@ -246,7 +248,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
|||||||
last_hyphen = q;
|
last_hyphen = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (text[q] != text_soft_break_key) {
|
||||||
// Some normal, printable character.
|
// Some normal, printable character.
|
||||||
width += calc_width(text[q]);
|
width += calc_width(text[q]);
|
||||||
}
|
}
|
||||||
@ -279,6 +281,19 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
|||||||
} else if (any_spaces) {
|
} else if (any_spaces) {
|
||||||
// Otherwise, break at a space if we can.
|
// Otherwise, break at a space if we can.
|
||||||
q = last_space;
|
q = last_space;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, this is a forced break. Accept the longest line
|
||||||
|
// we can that does not leave the next line beginning with one
|
||||||
|
// of our forbidden characters.
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < text_max_never_break && q - i > p &&
|
||||||
|
text_never_break_before->find(text[q - i]) != wstring::npos) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < text_max_never_break) {
|
||||||
|
q -= i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +329,8 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t pi = p; pi < q; pi++) {
|
for (size_t pi = p; pi < q; pi++) {
|
||||||
if (text[pi] != text_soft_hyphen_key) {
|
if (text[pi] != text_soft_hyphen_key &&
|
||||||
|
text[pi] != text_soft_break_key) {
|
||||||
output_text += text[pi];
|
output_text += text[pi];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,18 @@ TextNode::
|
|||||||
string TextNode::
|
string TextNode::
|
||||||
wordwrap_to(const string &text, float wordwrap_width,
|
wordwrap_to(const string &text, float wordwrap_width,
|
||||||
bool preserve_trailing_whitespace) const {
|
bool preserve_trailing_whitespace) const {
|
||||||
nassertr(_font != (TextFont *)NULL, text);
|
TextFont *font = get_font();
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
|
font = get_default_font();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font == (TextFont *)NULL) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
wstring decoded = decode_text(text);
|
wstring decoded = decode_text(text);
|
||||||
wstring wrapped =
|
wstring wrapped =
|
||||||
_font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
|
font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
|
||||||
return encode_wtext(wrapped);
|
return encode_wtext(wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user