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

@ -365,6 +365,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
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);
@ -445,7 +446,7 @@ keystroke(const MouseWatcherParameter &param, 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);

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}
@ -307,7 +318,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
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 {

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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);
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];
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);
// 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.
// 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);
// 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;
}