bug fixes

This commit is contained in:
David Rose 2002-02-16 09:37:22 +00:00
parent 1c7347f28e
commit 55ae74b3d1
8 changed files with 96 additions and 64 deletions

View File

@ -361,10 +361,11 @@ keystroke(const MouseWatcherParameter &param, bool background) {
// three bytes, or it might remain a one-byte character. // three bytes, or it might remain a one-byte character.
TextNode *text_node = get_text_def(S_focus); TextNode *text_node = get_text_def(S_focus);
string new_char = text_node->encode_wchar(keycode); string new_char = text_node->encode_wchar(keycode);
if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) { if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) {
overflow(param); overflow(param);
} else { } else {
_cursor_position = min(_cursor_position, (int)_text.length());
string new_text = string new_text =
_text.substr(0, _cursor_position) + new_char + _text.substr(0, _cursor_position) + new_char +
_text.substr(_cursor_position); _text.substr(_cursor_position);
@ -378,7 +379,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
} else { } else {
measure_text = new_text; measure_text = new_text;
} }
// Check the length. // Check the length.
bool too_long = false; bool too_long = false;
if (_max_width > 0.0f) { if (_max_width > 0.0f) {
@ -435,7 +436,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
} }
} }
} }
if (too_long) { if (too_long) {
overflow(param); overflow(param);
@ -445,7 +446,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
_obscured_text = measure_text; _obscured_text = measure_text;
} }
_cursor_position += new_char.size(); _cursor_position += new_char.length();
_cursor_stale = true; _cursor_stale = true;
_text_geom_stale = true; _text_geom_stale = true;
type(param); type(param);

View File

@ -258,11 +258,14 @@ write(ostream &out, int indent_level) const {
// code, as well as an optional scaling parameter that // code, as well as an optional scaling parameter that
// should be applied to the glyph's geometry and advance // should be applied to the glyph's geometry and advance
// parameters. Returns true if the glyph exists, false // parameters. Returns true if the glyph exists, false
// if it does not. // if it does not. Even if the return value is false,
// the value for glyph might be filled in with a
// printable glyph.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DynamicTextFont:: bool DynamicTextFont::
get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) { get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) {
if (!_is_valid) { if (!_is_valid) {
glyph = (TextGlyph *)NULL;
return false; return false;
} }

View File

@ -160,7 +160,9 @@ write(ostream &out, int indent_level) const {
// code, as well as an optional scaling parameter that // code, as well as an optional scaling parameter that
// should be applied to the glyph's geometry and advance // should be applied to the glyph's geometry and advance
// parameters. Returns true if the glyph exists, false // parameters. Returns true if the glyph exists, false
// if it does not. // if it does not. Even if the return value is false,
// the value for glyph might be filled in with a
// printable glyph.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool StaticTextFont:: bool StaticTextFont::
get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) { get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) {

View File

@ -33,6 +33,16 @@ isblank(int ch) {
return (ch == ' ' || ch == '\t'); return (ch == ' ' || ch == '\t');
} }
////////////////////////////////////////////////////////////////////
// Function: isspacew
// Description: An internal function that works like isspace() but is
// safe to call for a wide character.
////////////////////////////////////////////////////////////////////
INLINE bool
isspacew(int ch) {
return isascii(ch) && isspace(ch);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextFont::Constructor // Function: TextFont::Constructor
// Access: Public // Access: Public
@ -69,7 +79,8 @@ calc_width(int character) {
const TextGlyph *glyph; const TextGlyph *glyph;
float glyph_scale; float glyph_scale;
if (!get_glyph(character, glyph, glyph_scale)) { get_glyph(character, glyph, glyph_scale);
if (glyph == (TextGlyph *)NULL) {
// Unknown character. // Unknown character.
return 0.0f; return 0.0f;
} }
@ -266,7 +277,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
// Preserve any initial whitespace and newlines. // Preserve any initial whitespace and newlines.
float initial_width = 0.0f; float initial_width = 0.0f;
while (p < text.length() && isspace(text[p])) { while (p < text.length() && isspacew(text[p])) {
if (text[p] == '\n') { if (text[p] == '\n') {
initial_width = 0.0f; initial_width = 0.0f;
} else { } else {
@ -278,7 +289,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
bool needs_newline = false; bool needs_newline = false;
while (p < text.length()) { while (p < text.length()) {
nassertr(!isspace(text[p]), wstring()); nassertr(!isspacew(text[p]), wstring());
// Scan the next n characters, until the end of the string or an // Scan the next n characters, until the end of the string or an
// embedded newline character, or we exceed wordwrap_width. // embedded newline character, or we exceed wordwrap_width.
@ -289,7 +300,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
float width = initial_width; float width = initial_width;
while (q < text.length() && text[q] != '\n') { while (q < text.length() && text[q] != '\n') {
if (isspace(text[q])) { if (isspacew(text[q])) {
any_spaces = true; any_spaces = true;
} }
@ -303,11 +314,11 @@ wordwrap_to(const wstring &text, float wordwrap_width,
break; break;
} }
} }
if (overflow && any_spaces) { if (overflow && any_spaces) {
// If we stopped because we exceeded the wordwrap width, then // If we stopped because we exceeded the wordwrap width, then
// back up to the end of the last complete word. // back up to the end of the last complete word.
while (q > p && !isspace(text[q])) { while (q > p && !isspacew(text[q])) {
q--; q--;
} }
} }
@ -319,7 +330,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
} }
// Trim off any more blanks on the end. // Trim off any more blanks on the end.
while (q > p && isspace(text[q - 1])) { while (q > p && isspacew(text[q - 1])) {
q--; q--;
} }
@ -356,7 +367,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
// Preserve any initial whitespace and newlines. // Preserve any initial whitespace and newlines.
initial_width = 0.0f; initial_width = 0.0f;
while (p < text.length() && isspace(text[p])) { while (p < text.length() && isspacew(text[p])) {
if (text[p] == '\n') { if (text[p] == '\n') {
initial_width = 0.0f; initial_width = 0.0f;
} else { } else {

View File

@ -1078,22 +1078,6 @@ calc_width(const string &line) const {
return _font->calc_width(decode_text(line)); return _font->calc_width(decode_text(line));
} }
////////////////////////////////////////////////////////////////////
// Function: TextNode::wordwrap_to
// Access: Published
// Description: Inserts newlines into the given text at the
// appropriate places in order to make each line be the
// longest possible line that is not longer than
// wordwrap_width (and does not break any words, if
// possible). Returns the new string.
////////////////////////////////////////////////////////////////////
INLINE string TextNode::
wordwrap_to(const string &text, float wordwrap_width,
bool preserve_trailing_whitespace) const {
nassertr(_font != (TextFont *)NULL, text);
return encode_wtext(_font->wordwrap_to(decode_text(text), wordwrap_width, preserve_trailing_whitespace));
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextNode::rebuild // Function: TextNode::rebuild
// Access: Published // Access: Published

View File

@ -105,6 +105,25 @@ set_text(const string &text) {
rebuild(true); rebuild(true);
} }
////////////////////////////////////////////////////////////////////
// Function: TextNode::wordwrap_to
// Access: Published
// Description: Inserts newlines into the given text at the
// appropriate places in order to make each line be the
// longest possible line that is not longer than
// wordwrap_width (and does not break any words, if
// possible). Returns the new string.
////////////////////////////////////////////////////////////////////
string TextNode::
wordwrap_to(const string &text, float wordwrap_width,
bool preserve_trailing_whitespace) const {
nassertr(_font != (TextFont *)NULL, text);
wstring decoded = decode_text(text);
wstring wrapped =
_font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
return encode_wtext(wrapped);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextNode::write // Function: TextNode::write
@ -797,7 +816,7 @@ measure_row(wstring::iterator &si, const wstring::iterator &send) {
if (character == ' ') { if (character == ' ') {
// A space is a special case. // A space is a special case.
xpos += 0.25f; xpos += _font->get_space_advance();
} else { } else {
// A printable character. // A printable character.

View File

@ -193,8 +193,8 @@ PUBLISHED:
INLINE float calc_width(int character) const; INLINE float calc_width(int character) const;
INLINE float calc_width(const string &line) const; INLINE float calc_width(const string &line) const;
INLINE string wordwrap_to(const string &text, float wordwrap_width, string wordwrap_to(const string &text, float wordwrap_width,
bool preserve_trailing_whitespace) const; bool preserve_trailing_whitespace) const;
virtual void write(ostream &out, int indent_level = 0) const; virtual void write(ostream &out, int indent_level = 0) const;

View File

@ -1199,7 +1199,9 @@ void wglGraphicsWindow::handle_reshape() {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wglGraphicsWindow::handle_mouse_motion(int x, int y) { void wglGraphicsWindow::handle_mouse_motion(int x, int y) {
_input_devices[0].set_pointer_in_window(x, y); if (!_input_devices.empty()) {
_input_devices[0].set_pointer_in_window(x, y);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1209,7 +1211,9 @@ void wglGraphicsWindow::handle_mouse_motion(int x, int y) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wglGraphicsWindow::handle_mouse_entry(int state) { void wglGraphicsWindow::handle_mouse_entry(int state) {
if (state == MOUSE_EXITED) { if (state == MOUSE_EXITED) {
_input_devices[0].set_pointer_out_of_window(); if (!_input_devices.empty()) {
_input_devices[0].set_pointer_out_of_window();
}
} }
} }
@ -1220,9 +1224,11 @@ void wglGraphicsWindow::handle_mouse_entry(int state) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wglGraphicsWindow:: void wglGraphicsWindow::
handle_keypress(ButtonHandle key, int x, int y) { handle_keypress(ButtonHandle key, int x, int y) {
_input_devices[0].set_pointer_in_window(x, y); if (!_input_devices.empty()) {
if (key != ButtonHandle::none()) { _input_devices[0].set_pointer_in_window(x, y);
_input_devices[0].button_down(key); if (key != ButtonHandle::none()) {
_input_devices[0].button_down(key);
}
} }
} }
@ -1234,7 +1240,9 @@ handle_keypress(ButtonHandle key, int x, int y) {
void wglGraphicsWindow:: void wglGraphicsWindow::
handle_keyrelease(ButtonHandle key) { handle_keyrelease(ButtonHandle key) {
if (key != ButtonHandle::none()) { if (key != ButtonHandle::none()) {
_input_devices[0].button_up(key); if (!_input_devices.empty()) {
_input_devices[0].button_up(key);
}
} }
} }
@ -1647,31 +1655,35 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_IME_COMPOSITION: case WM_IME_COMPOSITION:
if (lparam & GCS_RESULTSTR) { if (lparam & GCS_RESULTSTR) {
HIMC hIMC = ImmGetContext(hwnd); if (!_input_devices.empty()) {
nassertr(hIMC != 0, 0); HIMC hIMC = ImmGetContext(hwnd);
nassertr(hIMC != 0, 0);
static const int max_ime_result = 128;
static char ime_result[max_ime_result]; static const int max_ime_result = 128;
static char ime_result[max_ime_result];
// There's a rumor that ImmGetCompositionStringW() doesn't
// work for Win95 or Win98; for these OS's we must use // There's a rumor that ImmGetCompositionStringW() doesn't
// ImmGetCompositionStringA(). How does this affect the // work for Win95 or Win98; for these OS's we must use
// returning of multibyte characters? // ImmGetCompositionStringA(). How does this affect the
DWORD result_size = // returning of multibyte characters?
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, DWORD result_size =
ime_result, max_ime_result); ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
ImmReleaseContext(hwnd, hIMC); ime_result, max_ime_result);
ImmReleaseContext(hwnd, hIMC);
// Add this string into the text buffer of the application.
// Add this string into the text buffer of the application.
// ImmGetCompositionStringW() returns a string, but it's
// filled in with wstring data: every two characters defines a // ImmGetCompositionStringW() returns a string, but it's
// 16-bit unicode char. The docs aren't clear on the // filled in with wstring data: every two characters defines a
// endianness of this. I guess it's safe to assume all Win32 // 16-bit unicode char. The docs aren't clear on the
// machines are little-endian. // endianness of this. I guess it's safe to assume all Win32
for (DWORD i = 0; i < result_size; i += 2) { // machines are little-endian.
int result = ((int)ime_result[i + 1] << 8) | ime_result[i]; for (DWORD i = 0; i < result_size; i += 2) {
_input_devices[0].keystroke(result); int result =
((int)(unsigned char)ime_result[i + 1] << 8) |
(unsigned char)ime_result[i];
_input_devices[0].keystroke(result);
}
} }
return 0; return 0;
} }