From d3206f01ec18e61e8cd9c7e88b02a6313ab227fa Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Wed, 15 Apr 2009 08:35:28 +0000 Subject: [PATCH] More Fl_Input keyboard fixes / OS X transparency for RGBA data / some utf8 reorganisation git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6765 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- CHANGES | 4 +- FL/Fl.H | 5 ++ FL/Fl_Input_.H | 6 ++- FL/fl_utf8.h | 18 ++++++- src/Fl_Input.cxx | 103 +++++++++++++++++++++++++++++--------- src/Fl_Input_.cxx | 10 ++++ src/Fl_Text_Buffer.cxx | 27 ++-------- src/Fl_Text_Display.cxx | 35 +++---------- src/Fl_Text_Editor.cxx | 24 +-------- src/fl_draw_image_mac.cxx | 3 +- src/fl_utf.c | 7 +++ src/fl_utf8.cxx | 6 +++ test/unittest_images.cxx | 12 +++-- 13 files changed, 153 insertions(+), 107 deletions(-) diff --git a/CHANGES b/CHANGES index 932027936..1a0e7a543 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ CHANGES IN FLTK 1.3.0 - - Added improved OS X cursor control to Fl_Input (STR #2169) + - Fixed fl_draw_image to obey the alpha channel, hoping that + this has no adverse effect on existing software (OS X only) + - Added OS X cursor control to Fl_Input (STR #2169) - Fix for multiple popups, when dragging and calling fl_alert() and friends from the callback (STR #2159) - Avoiding crashes for recursive common dialogs (this does not diff --git a/FL/Fl.H b/FL/Fl.H index dc09c22f8..e81b88c04 100644 --- a/FL/Fl.H +++ b/FL/Fl.H @@ -1014,6 +1014,11 @@ public: }; + /** \defgroup fl_unicode Unicode and UTF-8 functions + fl global Unicode and UTF-8 ahndling functions + @{ */ + /** @} */ + #endif // !Fl_H // diff --git a/FL/Fl_Input_.H b/FL/Fl_Input_.H index e72062c2f..dbddbd895 100644 --- a/FL/Fl_Input_.H +++ b/FL/Fl_Input_.H @@ -145,7 +145,7 @@ public: Same as value()[n], but may be faster in plausible implementations. No bounds checking is done. */ -char index(int i) const {return value_[i];} + char index(int i) const {return value_[i];} /** Returns the number of characters in value(). This may be greater than strlen(value()) if there are nul @@ -265,6 +265,10 @@ char index(int i) const {return value_[i];} */ void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP)); else type((uchar)(type() & ~FL_INPUT_WRAP)); } + /** + Return the number of lines displayed on a single page. + */ + int linesPerPage(); }; #endif diff --git a/FL/fl_utf8.h b/FL/fl_utf8.h index f365de5be..9db53d3ff 100644 --- a/FL/fl_utf8.h +++ b/FL/fl_utf8.h @@ -30,6 +30,11 @@ /*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ +/** + \file fl_utf8.h + \brief header for Unicode and UTF8 chracter handling +*/ + #ifndef _HAVE_FL_UTF8_HDR_ #define _HAVE_FL_UTF8_HDR_ @@ -78,12 +83,20 @@ extern "C" { # endif +/** \addtogroup fl_unicode + @{ +*/ + int fl_unichar_to_utf8_size(Fl_Unichar); /* F2: comes from FLTK2 */ /* OD: comes from OksiD */ -/* F2: How many bytes will be used to encode this wide character as UTF8? */ +/** + Return the number of bytes needed to encode the given UCS4 character in UTF8. + \param [in] ucs UCS4 encoded character + \return number of bytes required + */ FL_EXPORT int fl_utf8bytes(unsigned ucs); /* OD: returns the byte length of the first UTF-8 char sequence (returns -1 if not valid) */ @@ -222,6 +235,9 @@ FL_EXPORT void fl_make_path_for_file( const char *path ); /* OD: recursively create a path in the file system */ FL_EXPORT char fl_make_path( const char *path ); + +/** @} */ + /*****************************************************************************/ #ifdef __cplusplus diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx index 1ebda7d85..39dc8c5bd 100644 --- a/src/Fl_Input.cxx +++ b/src/Fl_Input.cxx @@ -146,10 +146,27 @@ int Fl_Input::handle_key() { if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); break; - case FL_Delete: // FIXME - if (Fl::event_state() & FL_SHIFT) ascii = ctrl('X'); - else ascii = ctrl('D'); - break; + case FL_Delete: +#ifdef __APPLE__ + if (mods==0 || mods==FL_CTRL) { // delete next char + ascii = ctrl('D'); + } else if (mods==FL_ALT) { // delete next word + if (mark() != position()) return cut(); + cut(position(), word_end(position())); + return 1; + } else if (mods==FL_META) { // delete to the end of the line + if (mark() != position()) return cut(); + cut(position(), line_end(position())); + return 1; + } else return 1; +#else + if (mods==0) { + ascii = ctrl('D'); + } else if (mods==FL_SHIFT) { + ascii = ctrl('X'); + } else return 1; +#endif + break; case FL_Left: #ifdef __APPLE__ if (mods==0) { // char left @@ -190,18 +207,31 @@ int Fl_Input::handle_key() { } else return 1; #endif // __APPLE__ break; - case FL_Page_Up: // FIXME - fl_font(textfont(),textsize()); //ensure current font is set to ours - repeat_num=h()/fl_height(); // number of lines to scroll - if (!repeat_num) repeat_num=1; + case FL_Page_Up: +#ifdef __APPLE__ + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else return 1; + break; +#else + repeat_num = linesPerPage(); + // fall through +#endif case FL_Up: #ifdef __APPLE__ if (mods==0) { // line up ascii = ctrl('P'); - } else if (mods==FL_CTRL) { - return 1; // FIXME scroll text down one page - // FIXME Fl_Inut_ does not support an independent scroll value - // (heck, it doesn't even support a scrollbar - what do you expect ;-) + } else if (mods==FL_CTRL) { // scroll text down one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); } else if (mods==FL_ALT) { // line start and up if (line_start(position())==position() && position()>0) return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE; @@ -214,21 +244,37 @@ int Fl_Input::handle_key() { #else if (mods==0) { // line up ascii = ctrl('P'); - } else if (mods==FL_CTRL) { - return 1; // FIXME scroll text down one line + } else if (mods==FL_CTRL) { // scroll text down one line + // Fl_Input has no scroll control, so instead we move the cursor by one page + ascii = ctrl('P'); } else return 1; #endif break; - case FL_Page_Down: // FIXME - fl_font(textfont(),textsize()); - repeat_num=h()/fl_height(); - if (!repeat_num) repeat_num=1; + case FL_Page_Down: +#ifdef __APPLE__ + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else return 1; + break; +#else + repeat_num = linesPerPage(); + // fall through +#endif case FL_Down: #ifdef __APPLE__ if (mods==0) { // line down ascii = ctrl('N'); } else if (mods==FL_CTRL) { - return 1; // FIXME scroll text up one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); } else if (mods==FL_ALT) { // line end and down if (line_end(position())==position() && position() undobufferlength) { if (undobuffer) { @@ -991,7 +970,7 @@ int Fl_Text_Buffer::expand_character(int pos, int indent, char *outStr) { mTabDist, mNullSubsChar); if (ret > 1 && (c & 0x80)) { int i; - i = utf_len(c); + i = fl_utf8len(c); while (i > 1) { i--; pos++; @@ -1040,7 +1019,7 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi return 0; } else if (c & 0x80) { *outStr = c; - return utf_len(c); + return fl_utf8len(c); } /* Otherwise, just return the character */ @@ -1068,7 +1047,7 @@ int Fl_Text_Buffer::character_width(char c, int indent, int tabDist, char nullSu else if ((c & 0x80) && !(c & 0x40)) return 0; else if (c & 0x80) { - return utf_len(c); + return fl_utf8len(c); } return 1; } diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx index ea00b0ac8..cb63b8f66 100644 --- a/src/Fl_Text_Display.cxx +++ b/src/Fl_Text_Display.cxx @@ -77,27 +77,6 @@ static int scroll_x = 0; // CET - FIXME #define TMPFONTWIDTH 6 -static int utf_len(char c) -{ - if (!(c & 0x80)) return 1; - if (c & 0x40) { - if (c & 0x20) { - if (c & 0x10) { - if (c & 0x08) { - if (c & 0x04) { - return 6; - } - return 5; - } - return 4; - } - return 3; - } - return 2; - } - return 0; -} - /** Creates a new text display widget.*/ Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) : Fl_Group(X, Y, W, H, l) { @@ -872,7 +851,7 @@ int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) { mBuffer->tab_distance(), mBuffer->null_substitution_character() ); if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { int i, ii = 0;; - i = utf_len(lineStr[ charIndex ]); + i = fl_utf8len(lineStr[ charIndex ]); while (i > 1) { i--; ii++; @@ -1626,7 +1605,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, expandedChar, buf->tab_distance(), buf->null_substitution_character() ); if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { int i, ii = 0;; - i = utf_len(lineStr[ charIndex ]); + i = fl_utf8len(lineStr[ charIndex ]); while (i > 1) { i--; ii++; @@ -1664,7 +1643,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, buf->tab_distance(), buf->null_substitution_character() ); if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { int i, ii = 0;; - i = utf_len(lineStr[ charIndex ]); + i = fl_utf8len(lineStr[ charIndex ]); while (i > 1) { i--; ii++; @@ -1687,7 +1666,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, *outPtr = expandedChar[ i ]; int l = 1; if (*outPtr & 0x80) { - l = utf_len(*outPtr); + l = fl_utf8len(*outPtr); } charWidth = string_width( &expandedChar[ i ], l, charStyle ); } else @@ -1711,7 +1690,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, buf->tab_distance(), buf->null_substitution_character() ); if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { int i, ii = 0;; - i = utf_len(lineStr[ charIndex ]); + i = fl_utf8len(lineStr[ charIndex ]); while (i > 1) { i--; ii++; @@ -1734,7 +1713,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, *outPtr = expandedChar[ i ]; int l = 1; if (*outPtr & 0x80) { - l = utf_len(*outPtr); + l = fl_utf8len(*outPtr); } charWidth = string_width( &expandedChar[ i ], l, charStyle ); } else @@ -2071,7 +2050,7 @@ int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) { mBuffer->tab_distance(), mBuffer->null_substitution_character() ); if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { int i, ii = 0;; - i = utf_len(lineStr[ charIndex ]); + i = fl_utf8len(lineStr[ charIndex ]); while (i > 1) { i--; ii++; diff --git a/src/Fl_Text_Editor.cxx b/src/Fl_Text_Editor.cxx index d70626b75..bd56eeb6c 100644 --- a/src/Fl_Text_Editor.cxx +++ b/src/Fl_Text_Editor.cxx @@ -34,26 +34,6 @@ #include #include -static int utf_len(char c) -{ - if (!(c & 0x80)) return 1; - if (c & 0x40) { - if (c & 0x20) { - if (c & 0x10) { - if (c & 0x08) { - if (c & 0x04) { - return 6; - } - return 5; - } - return 4; - } - return 3; - } - return 2; - } - return 0; -} /* Keyboard Control Matrix @@ -268,7 +248,7 @@ int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) { int l = 1; char c = e->buffer()->character(e->insert_position()); if (c & 0x80 && c & 0x40) { - l = utf_len(c); + l = fl_utf8len(c); } e->buffer()->select(e->insert_position(), e->insert_position()+l); } @@ -429,7 +409,7 @@ int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) { int l = 1; char c = e->buffer()->character(e->insert_position()); if (c & 0x80 && c & 0x40) { - l = utf_len(c); + l = fl_utf8len(c); } e->buffer()->select(e->insert_position(), e->insert_position()+l); } diff --git a/src/fl_draw_image_mac.cxx b/src/fl_draw_image_mac.cxx index 343e0f84c..5e7a1ce1e 100644 --- a/src/fl_draw_image_mac.cxx +++ b/src/fl_draw_image_mac.cxx @@ -75,7 +75,8 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, lut = CGColorSpaceCreateDeviceRGB(); CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, 0L); CGImageRef img = CGImageCreate( W, H, 8, 8*delta, linedelta, - lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast, + //lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast, + lut, delta&1?kCGImageAlphaNone:kCGImageAlphaLast, src, 0L, false, kCGRenderingIntentDefault); // draw the image into the destination context if (img) { diff --git a/src/fl_utf.c b/src/fl_utf.c index a48a785e2..e9ed34896 100644 --- a/src/fl_utf.c +++ b/src/fl_utf.c @@ -28,6 +28,11 @@ #include #include +/** \addtogroup fl_unicode + @{ +*/ + + #if 0 /** \defgroup fl_unichar Unicode Character Functions @@ -844,3 +849,5 @@ int fl_utf8test(const char* src, unsigned srclen) { } return ret; } + +/** @} */ diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx index d5416e7ef..c9a320600 100644 --- a/src/fl_utf8.cxx +++ b/src/fl_utf8.cxx @@ -76,6 +76,10 @@ extern "C" { #undef fl_open +/** \addtogroup fl_unicode + @{ +*/ + /*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ /*** but only 16 bits are really used under Linux and win32 ***/ @@ -793,6 +797,8 @@ void fl_make_path_for_file( const char *path ) free( p ); } +/** @} */ + // // End of "$Id: $". // diff --git a/test/unittest_images.cxx b/test/unittest_images.cxx index 161854af6..d6ffbabfa 100644 --- a/test/unittest_images.cxx +++ b/test/unittest_images.cxx @@ -42,10 +42,10 @@ public: drgba = img_rgba = (uchar*)malloc(128*128*4); for (y=0; y<128; y++) { for (x=0; x<128; x++) { - *drgb++ = *drgba = *dg++ = *dga++ = y<<1; - *drgb++ = *drgba = x<<1; - *drgb++ = *drgba = (127-x)<<1; - *dga++ = *drgba = x+y; + *drgba++ = *drgb++ = *dga++ = *dg++ = y<<1; + *drgba++ = *drgb++ = x<<1; + *drgba++ = *drgb++ = (127-x)<<1; + *drgba++ = *dga++ = x+y; } } return new ImageTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); @@ -64,20 +64,24 @@ public: } void draw() { Fl_Box::draw(); + int xx = x()+10, yy = y()+10; fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130); fl_draw_image(img_rgb, xx+1, yy+1, 128, 128, 3); fl_draw("RGB", xx+134, yy+64); + xx = x()+10; yy = y()+10+134; fl_color(FL_BLACK); fl_rectf(xx, yy, 130, 130); fl_color(FL_WHITE); fl_rectf(xx+1, yy+1, 64, 64); fl_color(FL_WHITE); fl_rectf(xx+65, yy+65, 64, 64); fl_draw_image(img_rgba, xx+1, yy+1, 128, 128, 4); fl_color(FL_BLACK); fl_draw("RGBA", xx+134, yy+64); + xx = x()+10+200; yy = y()+10; fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130); fl_draw_image(img_gray, xx+1, yy+1, 128, 128, 1); fl_draw("Gray", xx+134, yy+64); + xx = x()+10+200; yy = y()+10+134; fl_color(FL_BLACK); fl_rectf(xx, yy, 130, 130); fl_color(FL_WHITE); fl_rectf(xx+1, yy+1, 64, 64);