Removed FLTK own character composition rules --> left to OSs. Closes STR #2421.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7901 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy
2010-11-28 09:12:36 +00:00
parent 6b301d4365
commit dcfdf8be20
3 changed files with 42 additions and 317 deletions
+6 -162
View File
@@ -40,7 +40,11 @@
characters (even 0), and will correctly display any UTF text, using
^X notation for unprintable control characters. It assumes the
font can draw any characters of the used scripts, which is true
for standard fonts under MSWindows and Mac OS X.</P>
for standard fonts under MSWindows and Mac OS X.
Characters can be input using the keyboard or the character palette/map.
Character composition is done using using dead keys and/or a compose
key as defined by the operating system.
</P>
<CENTER><TABLE border=1 WIDTH=90% summary="Fl_Input keyboard and mouse bindings.">
@@ -84,168 +88,8 @@
expected.</TD></TR>
<TR><TD><B>Shift+move</B></TD><TD>Move the cursor but also extend the
selection.</TD></TR>
<TR><TD><B>RightCtrl or
<BR>Compose</B></TD><TD>
\anchor Fl_Input_Compose_Character
Start a compose-character
sequence. The next one or two keys typed define the character to
insert (see table that follows.)
<p>For instance, to type "á" type [compose][a]['] or [compose]['][a].
<P>The character "nbsp" (non-breaking space) is typed by using
[compose][space].
<P>The single-character sequences may be followed by a space if
necessary to remove ambiguity. For instance, if you really want to
type "ª~" rather than "ã" you must type [compose][a][space][~].
<p>The same key may be used to "quote" control characters into the
text. If you need a ^Q character you can get one by typing
[compose][Control+Q].
<p>X may have a key on the keyboard
defined as XK_Multi_key. If so this key may be used as well
as the right-hand control key. You can set this up with the program
xmodmap.
<p>If your keyboard is set to support a foreign language you should
also be able to type "dead key" prefix characters. On X you will
actually be able to see what dead key you typed, and if you then move
the cursor without completing the sequence the accent will remain
inserted.
<p>Under MSWindows or Mac OS X, character composition is done using
system-defined keystroke series.</TD></TR>
</TABLE></CENTER>
<!-- NEW PAGE -->
<center><table border=1 summary="Character Composition Table">
<caption align="top">Character Composition Table</caption>
<tr>
<th>Keys</th><th>Char</th>
<th>Keys</th><th>Char</th>
<th>Keys</th><th>Char</th>
<th>Keys</th><th>Char</th>
<th>Keys</th><th>Char</th>
<th>Keys</th><th>Char</th>
</tr><tr>
<td align=center>sp</td><td align=center><small>nbsp</small></td>
<td align=center>*</td><td align=center>°</td>
<td align=center>` A</td><td align=center>À</td>
<td align=center>D -</td><td align=center>Ð</td>
<td align=center>` a</td><td align=center>à</td>
<td align=center>d -</td><td align=center>ð</td>
</tr><tr>
<td align=center>!</td><td align=center>¡</td>
<td align=center>+ -</td><td align=center>±</td>
<td align=center>' A</td><td align=center>Á</td>
<td align=center>~ N</td><td align=center>Ñ</td>
<td align=center>' a</td><td align=center>á</td>
<td align=center>~ n</td><td align=center>ñ</td>
</tr><tr>
<td align=center>%</td><td align=center>¢</td>
<td align=center>2</td><td align=center>²</td>
<td align=center>A ^</td><td align=center>Â</td>
<td align=center>` O</td><td align=center>Ò</td>
<td align=center>^ a</td><td align=center>â</td>
<td align=center>` o</td><td align=center>ò</td>
</tr><tr>
<td align=center>#</td><td align=center>£</td>
<td align=center>3</td><td align=center>³</td>
<td align=center>~ A</td><td align=center>Ã</td>
<td align=center>' O</td><td align=center>Ó</td>
<td align=center>~ a</td><td align=center>ã</td>
<td align=center>' o</td><td align=center>ó</td>
</tr><tr>
<td align=center>$</td><td align=center>¤</td>
<td align=center>'</td><td align=center>´</td>
<td align=center>: A</td><td align=center>Ä</td>
<td align=center>^ O</td><td align=center>Ô</td>
<td align=center>: a</td><td align=center>ä</td>
<td align=center>^ o</td><td align=center>ô</td>
</tr><tr>
<td align=center>y =</td><td align=center>¥</td>
<td align=center>u</td><td align=center>µ</td>
<td align=center>* A</td><td align=center>Å</td>
<td align=center>~ O</td><td align=center>Õ</td>
<td align=center>* a</td><td align=center>å</td>
<td align=center>~ o</td><td align=center>õ</td>
</tr><tr>
<td align=center>|</td><td align=center>¦</td>
<td align=center>p</td><td align=center>¶</td>
<td align=center>A E</td><td align=center>Æ</td>
<td align=center>: O</td><td align=center>Ö</td>
<td align=center>a e</td><td align=center>æ</td>
<td align=center>: o</td><td align=center>ö</td>
</tr><tr>
<td align=center>&</td><td align=center>§</td>
<td align=center>.</td><td align=center>·</td>
<td align=center>, C</td><td align=center>Ç</td>
<td align=center>x</td><td align=center>×</td>
<td align=center>, c</td><td align=center>ç</td>
<td align=center>- :</td><td align=center>÷</td>
</tr><tr>
<td align=center>:</td><td align=center>¨</td>
<td align=center>,</td><td align=center>¸</td>
<td align=center>E `</td><td align=center>È</td>
<td align=center>O /</td><td align=center>Ø</td>
<td align=center>` e</td><td align=center>è</td>
<td align=center>o /</td><td align=center>ø</td>
</tr><tr>
<td align=center>c</td><td align=center>©</td>
<td align=center>1</td><td align=center>¹</td>
<td align=center>' E</td><td align=center>É</td>
<td align=center>` U</td><td align=center>Ù</td>
<td align=center>' e</td><td align=center>é</td>
<td align=center>` u</td><td align=center>ù</td>
</tr><tr>
<td align=center>a</td><td align=center>ª</td>
<td align=center>o</td><td align=center>º</td>
<td align=center>^ E</td><td align=center>Ê</td>
<td align=center>' U</td><td align=center>Ú</td>
<td align=center>^ e</td><td align=center>ê</td>
<td align=center>' u</td><td align=center>ú</td>
</tr><tr>
<td align=center>&lt; &lt;</td><td align=center>«</td>
<td align=center>&gt; &gt;</td><td align=center>»</td>
<td align=center>: E</td><td align=center>Ë</td>
<td align=center>^ U</td><td align=center>Û</td>
<td align=center>: e</td><td align=center>ë</td>
<td align=center>^ u</td><td align=center>û</td>
</tr><tr>
<td align=center>~</td><td align=center>¬</td>
<td align=center>1 4</td><td align=center>¼</td>
<td align=center>` I</td><td align=center>Ì</td>
<td align=center>: U</td><td align=center>Ü</td>
<td align=center>` i</td><td align=center>ì</td>
<td align=center>: u</td><td align=center>ü</td>
</tr><tr>
<td align=center>-</td><td align=center>­</td>
<td align=center>1 2</td><td align=center>½</td>
<td align=center>' I</td><td align=center>Í</td>
<td align=center>' Y</td><td align=center>Ý</td>
<td align=center>' i</td><td align=center>í</td>
<td align=center>' y</td><td align=center>ý</td>
</tr><tr>
<td align=center>r</td><td align=center>®</td>
<td align=center>3 4</td><td align=center>¾</td>
<td align=center>^ I</td><td align=center>Î</td>
<td align=center>T H</td><td align=center>Þ</td>
<td align=center>^ i</td><td align=center>î</td>
<td align=center>t h</td><td align=center>þ</td>
</tr><tr>
<td align=center>_</td><td align=center>¯</td>
<td align=center>?</td><td align=center>¿</td>
<td align=center>: I</td><td align=center>Ï</td>
<td align=center>s s</td><td align=center>ß</td>
<td align=center>: i</td><td align=center>ï</td>
<td align=center>: y</td><td align=center>ÿ</td>
</tr>
</table></center>
*/
*/
class FL_EXPORT Fl_Input : public Fl_Input_ {
int handle_key();
int shift_position(int p);
+10 -14
View File
@@ -164,6 +164,7 @@ should return 1. If you
return zero then FLTK assumes you ignored the key and will
then attempt to send it to a parent widget. If none of them want
it, it will change the event into a \p FL_SHORTCUT event.
FL_KEYBOARD events are also generated by the character palette/map.
To receive \p FL_KEYBOARD events you must also
respond to the \p FL_FOCUS and \p FL_UNFOCUS
@@ -171,7 +172,7 @@ events.
If you are writing a text-editing widget you may also want to call the
Fl::compose()
function to translate individual keystrokes into foreign characters.
function to translate individual keystrokes into characters.
\p FL_KEYUP events are sent to the widget that
currently has focus. This is not necessarily the same widget
@@ -411,21 +412,15 @@ window modal.
\section events_compose_characters FLTK Compose-Character Sequences
\todo Does Fltk Compose Character Sequences text need updating
after the addition of UTF-8 handling to FLTK-1.3.x ?
The foreign-letter compose processing done by the Fl_Input widget's
\ref Fl_Input_Compose_Character "compose"
key handler is provided in a function that you can call if you are
The character composition done by Fl_Input widget
requires that you call the Fl::compose() function if you are
writing your own text editor widget.
FLTK uses its own compose processing to allow "preview" of
the partially composed sequence, which is impossible with the
usual "dead key" processing.
Although currently only characters in the ISO-8859-1
character set are handled, you should call this in case any
enhancements to the processing are done in the future. The
Currently, all characters made by single key strokes
with or without modifier keys, or by system-defined character
compose sequences (that can involve dead keys or a compose key) can be input.
You should call Fl::compose() in case any
enhancements to this processing are done in the future. The
interface has been designed to handle arbitrary UTF-8 encoded
text.
@@ -434,6 +429,7 @@ The following methods are provided for character composition:
\li Fl::compose()
\li Fl::compose_reset()
Under Mac OS X, FLTK "previews" partially composed sequences.
\htmlonly
<hr>
+26 -141
View File
@@ -28,40 +28,47 @@
#include <FL/Fl.H>
#include <FL/x.H>
#if !defined(__APPLE__) && !defined(WIN32)
static const char* const compose_pairs =
//"=E _'f _\"..+ ++^ %%^S< OE ^Z ^''^^\"\"^-*- --~ TM^s> oe ^z:Y" // this is not unicode but CP1252
" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? " // unicode from U+00A0
"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" // unicode from U+00C0
"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";// unicode from U+00E0
#endif
#ifndef FL_DOXYGEN
// at present, this is effectively used by Mac OS X only
int Fl::compose_state = 0;
#endif
#if defined(__APPLE__) || defined(WIN32)
// under Mac OS X and MS Windows, character composition is handled by the OS
/** Any text editing widget should call this for each FL_KEYBOARD event.
Use of this function is very simple.
<p>If <i>true</i> is returned, then it has modified the
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
insert (it may be of zero length!). In will also set the "del"
parameter to the number of <i>bytes</i> to the left of the cursor to
delete, this is used to delete the results of the previous call to
Fl::compose().
<p>If <i>false</i> is returned, the keys should be treated as function
keys, and del is set to zero. You could insert the text anyways, if
you don't know what else to do.
<p>Though the current implementation returns immediately, future
versions may take quite awhile, as they may pop up a window or do
other user-interface things to allow characters to be selected.
*/
int Fl::compose(int& del) {
// character composition is now handled by the OS
del = 0;
#ifdef WIN32
unsigned char ascii = (unsigned)e_text[0];
if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0;
#elif defined(__APPLE__)
#if defined(__APPLE__)
// this stuff is to be treated as a function key
if(Fl::e_length == 0 || Fl::e_keysym == FL_Enter || Fl::e_keysym == FL_KP_Enter ||
Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&FL_META || Fl::e_state&FL_CTRL ) {
Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&(FL_META | FL_CTRL) ) {
return 0;
}
#else
unsigned char ascii = (unsigned)e_text[0];
if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0;
#endif
if(Fl::compose_state) {
del = 1;
Fl::compose_state = 0;
} else {
#ifdef WIN32
#ifndef __APPLE__
// Only insert non-control characters:
if (! (ascii & ~31 && ascii!=127)) { return 0; }
#endif
@@ -69,128 +76,6 @@ int Fl::compose(int& del) {
return 1;
}
#else
/** Any text editing widget should call this for each FL_KEYBOARD event.
Use of this function is very simple.
<p>If <i>true</i> is returned, then it has modified the
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
insert (it may be of zero length!). In will also set the "del"
parameter to the number of <i>bytes</i> to the left of the cursor to
delete, this is used to delete the results of the previous call to
Fl::compose().
<p>If <i>false</i> is returned, the keys should be treated as function
keys, and del is set to zero. You could insert the text anyways, if
you don't know what else to do.
<p>Though the current implementation returns immediately, future
versions may take quite awhile, as they may pop up a window or do
other user-interface things to allow characters to be selected.
*/
int Fl::compose(int& del) {
del = 0;
unsigned char ascii = (unsigned)e_text[0];
// Alt+letters are reserved for shortcuts. But alt+foreign letters
// has to be allowed, because some key layouts require alt to be held
// down in order to type them...
//
// OSX users sometimes need to hold down ALT for keys, so we only check
// for META on OSX...
if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0;
if (compose_state == 1) { // after the compose key
if ( // do not get distracted by any modifier keys
e_keysym==FL_Shift_L||
e_keysym==FL_Shift_R ||
e_keysym==FL_Alt_L ||
e_keysym==FL_Alt_R ||
e_keysym==FL_Meta_L ||
e_keysym==FL_Meta_R ||
e_keysym==FL_Control_R ||
e_keysym==FL_Control_L ||
e_keysym==FL_Menu
) return 0;
if (ascii == ' ') { // space turns into nbsp
int len = fl_utf8encode(0xA0, e_text);
e_text[len] = '\0';
e_length = len;
compose_state = 0;
return 1;
} else if (ascii < ' ' || ascii == 127) {
compose_state = 0;
return 0;
}
// see if it is either character of any pair:
for (const char *p = compose_pairs; *p; p += 2)
if (p[0] == ascii || p[1] == ascii) {
if (p[1] == ' ') {
int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text);
e_text[len] = '\0';
e_length = len;
}
compose_state = ascii;
return 1;
}
if (e_length) { // compose key also "quotes" control characters
compose_state = 0;
return 1;
}
} else if (compose_state) { // second character of compose
char c1 = char(compose_state); // retrieve first character
// now search for the pair in either order:
for (const char *p = compose_pairs; *p; p += 2) {
if ( (p[0] == ascii && p[1] == c1) || (p[1] == ascii && p[0] == c1)) {
int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text);
e_text[len] = '\0';
e_length = len;
del = 1; // delete the old character and insert new one
compose_state = 0;
return 1;
}
}
}
int i = e_keysym;
// See if they type the compose prefix key:
if (i == FL_Control_R || i == 0xff20/* Multi-Key */) {
compose_state = 1;
return 1;
}
// See if they typed a dead key. This gets it into the same state as
// typing prefix+accent:
if (i >= 0xfe50 && i <= 0xfe5b) {
ascii = e_text[0];
for (const char *p = compose_pairs; *p; p += 2)
if (p[0] == ascii ||
(p[1] == ' ' && (p - compose_pairs) / 2 + 0xA0 == ascii)) {
compose_state = p[0];
return 1;
}
compose_state = 0;
return 1;
}
// Only insert non-control characters:
if (e_length && (ascii & ~31 && ascii!=127)) {compose_state = 0; return 1;}
return 0;
}
#endif // __APPLE__ || WIN32
//
// End of "$Id$"
//