From 55ae74b3d15d3a378dbef0f83b8674f2d4c08138 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 16 Feb 2002 09:37:22 +0000 Subject: [PATCH] bug fixes --- panda/src/pgui/pgEntry.cxx | 9 +-- panda/src/text/dynamicTextFont.cxx | 5 +- panda/src/text/staticTextFont.cxx | 4 +- panda/src/text/textFont.cxx | 27 +++++--- panda/src/text/textNode.I | 16 ----- panda/src/text/textNode.cxx | 21 +++++- panda/src/text/textNode.h | 4 +- panda/src/wgldisplay/wglGraphicsWindow.cxx | 74 +++++++++++++--------- 8 files changed, 96 insertions(+), 64 deletions(-) diff --git a/panda/src/pgui/pgEntry.cxx b/panda/src/pgui/pgEntry.cxx index 9eb837d4c0..e92c545426 100644 --- a/panda/src/pgui/pgEntry.cxx +++ b/panda/src/pgui/pgEntry.cxx @@ -361,10 +361,11 @@ keystroke(const MouseWatcherParameter ¶m, bool background) { // three bytes, or it might remain a one-byte character. TextNode *text_node = get_text_def(S_focus); string new_char = text_node->encode_wchar(keycode); - + if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) { overflow(param); } else { + _cursor_position = min(_cursor_position, (int)_text.length()); string new_text = _text.substr(0, _cursor_position) + new_char + _text.substr(_cursor_position); @@ -378,7 +379,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) { } else { measure_text = new_text; } - + // Check the length. bool too_long = false; if (_max_width > 0.0f) { @@ -435,7 +436,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) { } } } - + if (too_long) { overflow(param); @@ -445,7 +446,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) { _obscured_text = measure_text; } - _cursor_position += new_char.size(); + _cursor_position += new_char.length(); _cursor_stale = true; _text_geom_stale = true; type(param); diff --git a/panda/src/text/dynamicTextFont.cxx b/panda/src/text/dynamicTextFont.cxx index 0978782f5c..a93b50190c 100644 --- a/panda/src/text/dynamicTextFont.cxx +++ b/panda/src/text/dynamicTextFont.cxx @@ -258,11 +258,14 @@ write(ostream &out, int indent_level) const { // code, as well as an optional scaling parameter that // should be applied to the glyph's geometry and advance // 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:: get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) { if (!_is_valid) { + glyph = (TextGlyph *)NULL; return false; } diff --git a/panda/src/text/staticTextFont.cxx b/panda/src/text/staticTextFont.cxx index edb5c265ab..b7ef4c182b 100644 --- a/panda/src/text/staticTextFont.cxx +++ b/panda/src/text/staticTextFont.cxx @@ -160,7 +160,9 @@ write(ostream &out, int indent_level) const { // code, as well as an optional scaling parameter that // should be applied to the glyph's geometry and advance // 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:: get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) { diff --git a/panda/src/text/textFont.cxx b/panda/src/text/textFont.cxx index 2558e61943..94abb0d2f7 100644 --- a/panda/src/text/textFont.cxx +++ b/panda/src/text/textFont.cxx @@ -33,6 +33,16 @@ isblank(int ch) { 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 // Access: Public @@ -69,7 +79,8 @@ calc_width(int character) { const TextGlyph *glyph; float glyph_scale; - if (!get_glyph(character, glyph, glyph_scale)) { + get_glyph(character, glyph, glyph_scale); + if (glyph == (TextGlyph *)NULL) { // Unknown character. return 0.0f; } @@ -266,7 +277,7 @@ wordwrap_to(const wstring &text, float wordwrap_width, // Preserve any initial whitespace and newlines. float initial_width = 0.0f; - while (p < text.length() && isspace(text[p])) { + while (p < text.length() && isspacew(text[p])) { if (text[p] == '\n') { initial_width = 0.0f; } else { @@ -278,7 +289,7 @@ wordwrap_to(const wstring &text, float wordwrap_width, bool needs_newline = false; 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 // embedded newline character, or we exceed wordwrap_width. @@ -289,7 +300,7 @@ wordwrap_to(const wstring &text, float wordwrap_width, float width = initial_width; while (q < text.length() && text[q] != '\n') { - if (isspace(text[q])) { + if (isspacew(text[q])) { any_spaces = true; } @@ -303,11 +314,11 @@ wordwrap_to(const wstring &text, float wordwrap_width, break; } } - + if (overflow && any_spaces) { // If we stopped because we exceeded the wordwrap width, then // back up to the end of the last complete word. - while (q > p && !isspace(text[q])) { + while (q > p && !isspacew(text[q])) { q--; } } @@ -319,7 +330,7 @@ wordwrap_to(const wstring &text, float wordwrap_width, } // Trim off any more blanks on the end. - while (q > p && isspace(text[q - 1])) { + while (q > p && isspacew(text[q - 1])) { q--; } @@ -356,7 +367,7 @@ wordwrap_to(const wstring &text, float wordwrap_width, // Preserve any initial whitespace and newlines. initial_width = 0.0f; - while (p < text.length() && isspace(text[p])) { + while (p < text.length() && isspacew(text[p])) { if (text[p] == '\n') { initial_width = 0.0f; } else { diff --git a/panda/src/text/textNode.I b/panda/src/text/textNode.I index 815f46d807..8dda0b5d3d 100644 --- a/panda/src/text/textNode.I +++ b/panda/src/text/textNode.I @@ -1078,22 +1078,6 @@ calc_width(const string &line) const { 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 // Access: Published diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 36c3a17eb7..15b4988055 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -105,6 +105,25 @@ set_text(const string &text) { 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 @@ -797,7 +816,7 @@ measure_row(wstring::iterator &si, const wstring::iterator &send) { if (character == ' ') { // A space is a special case. - xpos += 0.25f; + xpos += _font->get_space_advance(); } else { // A printable character. diff --git a/panda/src/text/textNode.h b/panda/src/text/textNode.h index bcc5ad56b7..0bc5166c67 100644 --- a/panda/src/text/textNode.h +++ b/panda/src/text/textNode.h @@ -193,8 +193,8 @@ PUBLISHED: INLINE float calc_width(int character) const; INLINE float calc_width(const string &line) const; - INLINE string wordwrap_to(const string &text, float wordwrap_width, - bool preserve_trailing_whitespace) const; + string wordwrap_to(const string &text, float wordwrap_width, + bool preserve_trailing_whitespace) const; virtual void write(ostream &out, int indent_level = 0) const; diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 203aafa11e..ea38637517 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -1199,7 +1199,9 @@ void wglGraphicsWindow::handle_reshape() { // Description: //////////////////////////////////////////////////////////////////// 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) { 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:: handle_keypress(ButtonHandle key, int x, int y) { - _input_devices[0].set_pointer_in_window(x, y); - if (key != ButtonHandle::none()) { - _input_devices[0].button_down(key); + if (!_input_devices.empty()) { + _input_devices[0].set_pointer_in_window(x, y); + if (key != ButtonHandle::none()) { + _input_devices[0].button_down(key); + } } } @@ -1234,7 +1240,9 @@ handle_keypress(ButtonHandle key, int x, int y) { void wglGraphicsWindow:: handle_keyrelease(ButtonHandle key) { 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: if (lparam & GCS_RESULTSTR) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - - 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 - // ImmGetCompositionStringA(). How does this affect the - // returning of multibyte characters? - DWORD result_size = - ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - ImmReleaseContext(hwnd, hIMC); - - // 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 - // 16-bit unicode char. The docs aren't clear on the - // endianness of this. I guess it's safe to assume all Win32 - // machines are little-endian. - for (DWORD i = 0; i < result_size; i += 2) { - int result = ((int)ime_result[i + 1] << 8) | ime_result[i]; - _input_devices[0].keystroke(result); + if (!_input_devices.empty()) { + HIMC hIMC = ImmGetContext(hwnd); + nassertr(hIMC != 0, 0); + + 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 + // ImmGetCompositionStringA(). How does this affect the + // returning of multibyte characters? + DWORD result_size = + ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, + ime_result, max_ime_result); + ImmReleaseContext(hwnd, hIMC); + + // 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 + // 16-bit unicode char. The docs aren't clear on the + // endianness of this. I guess it's safe to assume all Win32 + // machines are little-endian. + for (DWORD i = 0; i < result_size; i += 2) { + int result = + ((int)(unsigned char)ime_result[i + 1] << 8) | + (unsigned char)ime_result[i]; + _input_devices[0].keystroke(result); + } } return 0; }