add text-soft-break-key and text-never-break-before

This commit is contained in:
David Rose 2004-03-04 19:14:58 +00:00
parent 9ca106399c
commit 56a9f1feae
4 changed files with 55 additions and 10 deletions

View File

@ -52,14 +52,29 @@ const float text_tab_width = config_text.GetFloat("text-tab-width", 5.0f);
// identified as the soft-hyphen character.
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,
// 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;
// If the rightmost whitespace character falls before this fraction of
// 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);
// 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_magfilter = Texture::FT_invalid;
@ -119,7 +134,10 @@ init_libtext() {
// Make sure libexpress is initialized before we ask something of
// TextEncoder.
init_libexpress();
string encoded = config_text.GetString("text-soft-hyphen-output", "-");
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));
}

View File

@ -39,8 +39,11 @@ extern const float text_small_caps_scale;
extern const string text_default_font;
extern const float text_tab_width;
extern const int text_soft_hyphen_key;
extern const int text_soft_break_key;
extern wstring *text_soft_hyphen_output;
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_magfilter;

View File

@ -30,7 +30,9 @@ TypeHandle TextFont::_type_handle;
////////////////////////////////////////////////////////////////////
static INLINE bool
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 width = initial_width;
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) {
any_spaces = true;
// 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
// 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) {
// We only consider this as a possible hyphenation point if
// (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;
}
} else {
} else if (text[q] != text_soft_break_key) {
// Some normal, printable character.
width += calc_width(text[q]);
}
@ -279,6 +281,19 @@ wordwrap_to(const wstring &text, float wordwrap_width,
} else if (any_spaces) {
// Otherwise, break at a space if we can.
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++) {
if (text[pi] != text_soft_hyphen_key) {
if (text[pi] != text_soft_hyphen_key &&
text[pi] != text_soft_break_key) {
output_text += text[pi];
}
}

View File

@ -142,10 +142,18 @@ TextNode::
string TextNode::
wordwrap_to(const string &text, float wordwrap_width,
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 wrapped =
_font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
return encode_wtext(wrapped);
}