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
This commit is contained in:
Matthias Melcher 2009-04-15 08:35:28 +00:00
parent b214cef3a8
commit d3206f01ec
13 changed files with 153 additions and 107 deletions

View File

@ -1,6 +1,8 @@
CHANGES IN FLTK 1.3.0 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() - Fix for multiple popups, when dragging and calling fl_alert()
and friends from the callback (STR #2159) and friends from the callback (STR #2159)
- Avoiding crashes for recursive common dialogs (this does not - Avoiding crashes for recursive common dialogs (this does not

View File

@ -1014,6 +1014,11 @@ public:
}; };
/** \defgroup fl_unicode Unicode and UTF-8 functions
fl global Unicode and UTF-8 ahndling functions
@{ */
/** @} */
#endif // !Fl_H #endif // !Fl_H
// //

View File

@ -145,7 +145,7 @@ public:
Same as value()[n], but may be faster in plausible Same as value()[n], but may be faster in plausible
implementations. No bounds checking is done. 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 Returns the number of characters in value(). This
may be greater than strlen(value()) if there are nul 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)); void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP));
else 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 #endif

View File

@ -30,6 +30,11 @@
/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ /*** 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_ #ifndef _HAVE_FL_UTF8_HDR_
#define _HAVE_FL_UTF8_HDR_ #define _HAVE_FL_UTF8_HDR_
@ -78,12 +83,20 @@
extern "C" { extern "C" {
# endif # endif
/** \addtogroup fl_unicode
@{
*/
int fl_unichar_to_utf8_size(Fl_Unichar); int fl_unichar_to_utf8_size(Fl_Unichar);
/* F2: comes from FLTK2 */ /* F2: comes from FLTK2 */
/* OD: comes from OksiD */ /* 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); FL_EXPORT int fl_utf8bytes(unsigned ucs);
/* OD: returns the byte length of the first UTF-8 char sequence (returns -1 if not valid) */ /* 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 */ /* OD: recursively create a path in the file system */
FL_EXPORT char fl_make_path( const char *path ); FL_EXPORT char fl_make_path( const char *path );
/** @} */
/*****************************************************************************/ /*****************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -146,9 +146,26 @@ int Fl_Input::handle_key() {
if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); if (Fl::event_state() & FL_CTRL) ascii = ctrl('C');
else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V');
break; break;
case FL_Delete: // FIXME case FL_Delete:
if (Fl::event_state() & FL_SHIFT) ascii = ctrl('X'); #ifdef __APPLE__
else ascii = ctrl('D'); 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; break;
case FL_Left: case FL_Left:
#ifdef __APPLE__ #ifdef __APPLE__
@ -190,18 +207,31 @@ int Fl_Input::handle_key() {
} else return 1; } else return 1;
#endif // __APPLE__ #endif // __APPLE__
break; break;
case FL_Page_Up: // FIXME case FL_Page_Up:
fl_font(textfont(),textsize()); //ensure current font is set to ours #ifdef __APPLE__
repeat_num=h()/fl_height(); // number of lines to scroll if (mods==0) { // scroll text one page
if (!repeat_num) repeat_num=1; // 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: case FL_Up:
#ifdef __APPLE__ #ifdef __APPLE__
if (mods==0) { // line up if (mods==0) { // line up
ascii = ctrl('P'); ascii = ctrl('P');
} else if (mods==FL_CTRL) { } else if (mods==FL_CTRL) { // scroll text down one page
return 1; // FIXME scroll text down one page // OS X scrolls the view, but does not move the cursor
// FIXME Fl_Inut_ does not support an independent scroll value // Fl_Input has no scroll control, so instead we move the cursor by one page
// (heck, it doesn't even support a scrollbar - what do you expect ;-) repeat_num = linesPerPage();
ascii = ctrl('P');
} else if (mods==FL_ALT) { // line start and up } else if (mods==FL_ALT) { // line start and up
if (line_start(position())==position() && position()>0) if (line_start(position())==position() && position()>0)
return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE; return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE;
@ -214,21 +244,37 @@ int Fl_Input::handle_key() {
#else #else
if (mods==0) { // line up if (mods==0) { // line up
ascii = ctrl('P'); ascii = ctrl('P');
} else if (mods==FL_CTRL) { } else if (mods==FL_CTRL) { // scroll text down one line
return 1; // FIXME 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; } else return 1;
#endif #endif
break; break;
case FL_Page_Down: // FIXME case FL_Page_Down:
fl_font(textfont(),textsize()); #ifdef __APPLE__
repeat_num=h()/fl_height(); if (mods==0) { // scroll text one page
if (!repeat_num) repeat_num=1; // 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: case FL_Down:
#ifdef __APPLE__ #ifdef __APPLE__
if (mods==0) { // line down if (mods==0) { // line down
ascii = ctrl('N'); ascii = ctrl('N');
} else if (mods==FL_CTRL) { } 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 } else if (mods==FL_ALT) { // line end and down
if (line_end(position())==position() && position()<size()) if (line_end(position())==position() && position()<size())
return shift_position(line_end(position()+1)) + NORMAL_INPUT_MOVE; return shift_position(line_end(position()+1)) + NORMAL_INPUT_MOVE;
@ -241,15 +287,19 @@ int Fl_Input::handle_key() {
#else #else
if (mods==0) { // line down if (mods==0) { // line down
ascii = ctrl('N'); ascii = ctrl('N');
} else if (mods==FL_CTRL) { } else if (mods==FL_CTRL) { // scroll text up one line
return 1; // FIXME scroll text up one line // Fl_Input has no scroll control, so instead we move the cursor by one page
ascii = ctrl('N');
} else return 1; } else return 1;
#endif #endif
break; break;
case FL_Home: case FL_Home:
#ifdef __APPLE__ #ifdef __APPLE__
if (mods==0) { if (mods==0) { // scroll display to the top
return 1; // FIXME scroll display to the top // 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
shift_position(0);
return 1;
} else return 1; } else return 1;
#else #else
if (mods==0) { if (mods==0) {
@ -262,8 +312,11 @@ int Fl_Input::handle_key() {
break; break;
case FL_End: case FL_End:
#ifdef __APPLE__ #ifdef __APPLE__
if (mods==0) { if (mods==0) { // scroll display to the bottom
return 1; // FIXME scroll display to the bottom // 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
shift_position(size());
return 1;
} else return 1; } else return 1;
#else #else
if (mods==0) { if (mods==0) {

View File

@ -1024,6 +1024,16 @@ Fl_Input_::~Fl_Input_() {
if (bufsize) free((void*)buffer); if (bufsize) free((void*)buffer);
} }
int Fl_Input_::linesPerPage() {
int n = 1;
if (input_type() == FL_MULTILINE_INPUT) {
fl_font(textfont(),textsize()); //ensure current font is set to ours
n = h()/fl_height(); // number of lines to scroll
if (n<=0) n = 1;
}
return n;
}
// //
// End of "$Id$". // End of "$Id$".
// //

View File

@ -83,27 +83,6 @@ static int undocut; // number of characters deleted there
static int undoinsert; // number of characters inserted static int undoinsert; // number of characters inserted
static int undoyankcut; // length of valid contents of buffer, even if undocut=0 static int undoyankcut; // length of valid contents of buffer, even if undocut=0
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;
}
static void undobuffersize(int n) { static void undobuffersize(int n) {
if (n > undobufferlength) { if (n > undobufferlength) {
if (undobuffer) { if (undobuffer) {
@ -991,7 +970,7 @@ int Fl_Text_Buffer::expand_character(int pos, int indent, char *outStr) {
mTabDist, mNullSubsChar); mTabDist, mNullSubsChar);
if (ret > 1 && (c & 0x80)) { if (ret > 1 && (c & 0x80)) {
int i; int i;
i = utf_len(c); i = fl_utf8len(c);
while (i > 1) { while (i > 1) {
i--; i--;
pos++; pos++;
@ -1040,7 +1019,7 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi
return 0; return 0;
} else if (c & 0x80) { } else if (c & 0x80) {
*outStr = c; *outStr = c;
return utf_len(c); return fl_utf8len(c);
} }
/* Otherwise, just return the character */ /* 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)) else if ((c & 0x80) && !(c & 0x40))
return 0; return 0;
else if (c & 0x80) { else if (c & 0x80) {
return utf_len(c); return fl_utf8len(c);
} }
return 1; return 1;
} }

View File

@ -77,27 +77,6 @@ static int scroll_x = 0;
// CET - FIXME // CET - FIXME
#define TMPFONTWIDTH 6 #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.*/ /** Creates a new text display widget.*/
Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l)
: Fl_Group(X, Y, W, H, 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() ); mBuffer->tab_distance(), mBuffer->null_substitution_character() );
if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) {
int i, ii = 0;; int i, ii = 0;;
i = utf_len(lineStr[ charIndex ]); i = fl_utf8len(lineStr[ charIndex ]);
while (i > 1) { while (i > 1) {
i--; i--;
ii++; 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() ); expandedChar, buf->tab_distance(), buf->null_substitution_character() );
if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) {
int i, ii = 0;; int i, ii = 0;;
i = utf_len(lineStr[ charIndex ]); i = fl_utf8len(lineStr[ charIndex ]);
while (i > 1) { while (i > 1) {
i--; i--;
ii++; ii++;
@ -1664,7 +1643,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
buf->tab_distance(), buf->null_substitution_character() ); buf->tab_distance(), buf->null_substitution_character() );
if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) {
int i, ii = 0;; int i, ii = 0;;
i = utf_len(lineStr[ charIndex ]); i = fl_utf8len(lineStr[ charIndex ]);
while (i > 1) { while (i > 1) {
i--; i--;
ii++; ii++;
@ -1687,7 +1666,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
*outPtr = expandedChar[ i ]; *outPtr = expandedChar[ i ];
int l = 1; int l = 1;
if (*outPtr & 0x80) { if (*outPtr & 0x80) {
l = utf_len(*outPtr); l = fl_utf8len(*outPtr);
} }
charWidth = string_width( &expandedChar[ i ], l, charStyle ); charWidth = string_width( &expandedChar[ i ], l, charStyle );
} else } else
@ -1711,7 +1690,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
buf->tab_distance(), buf->null_substitution_character() ); buf->tab_distance(), buf->null_substitution_character() );
if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) {
int i, ii = 0;; int i, ii = 0;;
i = utf_len(lineStr[ charIndex ]); i = fl_utf8len(lineStr[ charIndex ]);
while (i > 1) { while (i > 1) {
i--; i--;
ii++; ii++;
@ -1734,7 +1713,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
*outPtr = expandedChar[ i ]; *outPtr = expandedChar[ i ];
int l = 1; int l = 1;
if (*outPtr & 0x80) { if (*outPtr & 0x80) {
l = utf_len(*outPtr); l = fl_utf8len(*outPtr);
} }
charWidth = string_width( &expandedChar[ i ], l, charStyle ); charWidth = string_width( &expandedChar[ i ], l, charStyle );
} else } 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() ); mBuffer->tab_distance(), mBuffer->null_substitution_character() );
if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) {
int i, ii = 0;; int i, ii = 0;;
i = utf_len(lineStr[ charIndex ]); i = fl_utf8len(lineStr[ charIndex ]);
while (i > 1) { while (i > 1) {
i--; i--;
ii++; ii++;

View File

@ -34,26 +34,6 @@
#include <FL/Fl_Text_Editor.H> #include <FL/Fl_Text_Editor.H>
#include <FL/fl_ask.H> #include <FL/fl_ask.H>
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 /* Keyboard Control Matrix
@ -268,7 +248,7 @@ int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) {
int l = 1; int l = 1;
char c = e->buffer()->character(e->insert_position()); char c = e->buffer()->character(e->insert_position());
if (c & 0x80 && c & 0x40) { if (c & 0x80 && c & 0x40) {
l = utf_len(c); l = fl_utf8len(c);
} }
e->buffer()->select(e->insert_position(), e->insert_position()+l); 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; int l = 1;
char c = e->buffer()->character(e->insert_position()); char c = e->buffer()->character(e->insert_position());
if (c & 0x80 && c & 0x40) { if (c & 0x80 && c & 0x40) {
l = utf_len(c); l = fl_utf8len(c);
} }
e->buffer()->select(e->insert_position(), e->insert_position()+l); e->buffer()->select(e->insert_position(), e->insert_position()+l);
} }

View File

@ -75,7 +75,8 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
lut = CGColorSpaceCreateDeviceRGB(); lut = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, 0L); CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, 0L);
CGImageRef img = CGImageCreate( W, H, 8, 8*delta, linedelta, 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); src, 0L, false, kCGRenderingIntentDefault);
// draw the image into the destination context // draw the image into the destination context
if (img) { if (img) {

View File

@ -28,6 +28,11 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
/** \addtogroup fl_unicode
@{
*/
#if 0 #if 0
/** /**
\defgroup fl_unichar Unicode Character Functions \defgroup fl_unichar Unicode Character Functions
@ -844,3 +849,5 @@ int fl_utf8test(const char* src, unsigned srclen) {
} }
return ret; return ret;
} }
/** @} */

View File

@ -76,6 +76,10 @@ extern "C" {
#undef fl_open #undef fl_open
/** \addtogroup fl_unicode
@{
*/
/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ /*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/
/*** but only 16 bits are really used under Linux and win32 ***/ /*** 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 ); free( p );
} }
/** @} */
// //
// End of "$Id: $". // End of "$Id: $".
// //

View File

@ -42,10 +42,10 @@ public:
drgba = img_rgba = (uchar*)malloc(128*128*4); drgba = img_rgba = (uchar*)malloc(128*128*4);
for (y=0; y<128; y++) { for (y=0; y<128; y++) {
for (x=0; x<128; x++) { for (x=0; x<128; x++) {
*drgb++ = *drgba = *dg++ = *dga++ = y<<1; *drgba++ = *drgb++ = *dga++ = *dg++ = y<<1;
*drgb++ = *drgba = x<<1; *drgba++ = *drgb++ = x<<1;
*drgb++ = *drgba = (127-x)<<1; *drgba++ = *drgb++ = (127-x)<<1;
*dga++ = *drgba = x+y; *drgba++ = *dga++ = x+y;
} }
} }
return new ImageTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); return new ImageTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H);
@ -64,20 +64,24 @@ public:
} }
void draw() { void draw() {
Fl_Box::draw(); Fl_Box::draw();
int xx = x()+10, yy = y()+10; int xx = x()+10, yy = y()+10;
fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130); fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130);
fl_draw_image(img_rgb, xx+1, yy+1, 128, 128, 3); fl_draw_image(img_rgb, xx+1, yy+1, 128, 128, 3);
fl_draw("RGB", xx+134, yy+64); fl_draw("RGB", xx+134, yy+64);
xx = x()+10; yy = y()+10+134; xx = x()+10; yy = y()+10+134;
fl_color(FL_BLACK); fl_rectf(xx, yy, 130, 130); 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+1, yy+1, 64, 64);
fl_color(FL_WHITE); fl_rectf(xx+65, yy+65, 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_draw_image(img_rgba, xx+1, yy+1, 128, 128, 4);
fl_color(FL_BLACK); fl_draw("RGBA", xx+134, yy+64); fl_color(FL_BLACK); fl_draw("RGBA", xx+134, yy+64);
xx = x()+10+200; yy = y()+10; xx = x()+10+200; yy = y()+10;
fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130); fl_color(FL_BLACK); fl_rect(xx, yy, 130, 130);
fl_draw_image(img_gray, xx+1, yy+1, 128, 128, 1); fl_draw_image(img_gray, xx+1, yy+1, 128, 128, 1);
fl_draw("Gray", xx+134, yy+64); fl_draw("Gray", xx+134, yy+64);
xx = x()+10+200; yy = y()+10+134; xx = x()+10+200; yy = y()+10+134;
fl_color(FL_BLACK); fl_rectf(xx, yy, 130, 130); 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+1, yy+1, 64, 64);