DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2158
Version: 1.3-current
Link: http://www.fltk.org/str.php?L2158
Version: 1.3-current
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Int_Input.H>
#include <FL/Fl_Output.H>
#include <FL/fl_ask.H>
#include <FL/fl_utf8.h>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Text_Editor.H>
#include <assert.h>
#include <stdio.h>
#include <wchar.h>
Fl_Double_Window* mainWindow = 0;
Fl_Group* controlGroup = 0;
Fl_Int_Input* unicodeInput = 0;
Fl_Output* encodedOutput = 0;
Fl_Group* encodedGroup = 0;
Fl_Box* encodedBitBox[32]; /* program only handles up to 4-byte encoding */
Fl_Output* wcwidthOutput = 0;
Fl_Output* mkwidthOutput = 0;
Fl_Output* flwidthOutput = 0;
Fl_Output* pxwidthOutput = 0;
Fl_Group* displayGroup = 0;
Fl_Text_Display* lastGlyphTD = 0;
Fl_Text_Display* wrapMode15TD = 0;
Fl_Text_Display* wrapMode10TD = 0;
Fl_Text_Buffer* lastGlyphTB = 0;
Fl_Text_Buffer* wrapMode15TB = 0;
Fl_Text_Buffer* wrapMode10TB = 0;
/* provide explicit explanation of Unicode to UTF-8 encodings for clarity,
* and also as an easy way of colour coding the bits from each UCS byte.
* Note that FLTK only handles U+0 to U+10FFFF to be RFC 3629 compliant,
* [partially anyway, because it doesn't handle known illegal characters]
* so the 5- and 6-byte encodings are only included for completeness.
*/
const char* unicodeToUtf8bytes[7] = {
"U+00000000 - U+0000007F : ", /* dummy entry for offset calculations
*/
"U+00000000 - U+0000007F : 0aaaaaaa",
"U+00000080 - U+000007FF : 110bbbaa 10aaaaaa",
"U+00000800 - U+0000FFFF : 1110bbbb 10bbbbaa 10aaaaaa",
"U+00010000 - U+001FFFFF : 11110ccc 10ccbbbb 10bbbbaa 10aaaaaa",
"U+00200000 - U+03FFFFFF : 111110dd 10cccccc 10ccbbbb 10bbbbaa 10aaaaaa",
"U+04000000 - U+7FFFFFFF : 1111110d 10dddddd 10cccccc 10ccbbbb 10bbbbaa
10aaaaaa"
};
void setBitBoxColour(int utf8len, int byte, int bit) {
assert(1 <= utf8len && utf8len <= 6);
assert(0 <= byte && byte < 6);
assert(0 <= bit && bit < 8);
int b = 8*byte + bit;
/* this demo designed to show 4-byte UTF-8, before U+10FFFF limit found */
if (b >= 32)
return;
/* calculate offset into string by using dummy zero entry as template */
int offset = strlen(unicodeToUtf8bytes[0]);
/* calculate index into byte groups - use 9 to allow for spaces */
int i = offset + 9*byte + bit;
char c = unicodeToUtf8bytes[utf8len][i];
Fl_Box* box = encodedBitBox[b];
switch(c) {
case '0': box->labelcolor(FL_BLACK); break;
case '1': box->labelcolor(FL_BLACK); break;
case 'a': box->labelcolor(FL_BLUE); break;
case 'b': box->labelcolor(FL_DARK_GREEN); break;
case 'c': box->labelcolor(FL_CYAN); break;
case 'd': box->labelcolor(FL_DARK_BLUE); break;
default: box->labelcolor(FL_RED); break;
}
}
void setEncodeOutput(unsigned int ucs, const char* utf8, int utf8len) {
char output[32], buffer[32]; /* big enough for 6 * 5 chars for "\0xFF" */
output[0] = buffer[0] = '\0';
for (int i = 0; i < utf8len; i++) {
char c = utf8[i];
if (' ' < c && c < '~') {
sprintf(buffer, "%c", c);
strcat(output, buffer);
} else {
sprintf(buffer, "\\0x%02hhX", c);
strcat(output, buffer);
}
}
encodedOutput->value(output);
}
void clearBitBoxes() {
for (int i = 0; i < 32; i++)
encodedBitBox[i]->label("");
}
void clearFields() {
encodedOutput->value("");
clearBitBoxes();
wcwidthOutput->value("");
mkwidthOutput->value("");
flwidthOutput->value("");
pxwidthOutput->value("");
}
void setBitBoxText(unsigned int ucs, const char* utf8, int utf8len) {
clearBitBoxes();
/* this demo designed to show 4-byte UTF-8, before U+10FFFF limit found */
if (1 > utf8len || utf8len > 4)
return;
for (int i = 0; i < utf8len; i++) {
char c = utf8[i];
for (int j = 0; j < 8; j++) {
int b = 8*i + j;
int v = (c & 0xFF) & (0x01 << (8-1-j));
setBitBoxColour(utf8len, i, j);
encodedBitBox[b]->label((v == 0) ? "0" : "1");
}
}
}
void setWidths(unsigned int ucs, const char* utf8, int utf8len) {
int width;
char buffer[32];
width = wcwidth((wchar_t)ucs);
sprintf(buffer, "%d", width);
wcwidthOutput->value(buffer);
width = fl_wcwidth_(ucs);
sprintf(buffer, "%d", width);
mkwidthOutput->value(buffer);
width = fl_wcwidth(utf8);
sprintf(buffer, "%d", width);
flwidthOutput->value(buffer);
double pixels = fl_width(utf8);
sprintf(buffer, "%.2f", pixels);
pxwidthOutput->value(buffer);
}
void toDisplays(unsigned int ucs, const char* utf8, int utf8len) {
lastGlyphTB->text(utf8);
wrapMode15TD->insert(utf8);
wrapMode10TD->insert(utf8);
}
void unicodeCallback(Fl_Widget* w, void* userData) {
assert(w == unicodeInput);
clearFields();
unsigned int ucs = 0;
if (sscanf(unicodeInput->value(), "%x", &ucs) == 1) {
if (ucs > 0x10FFFFU)
fl_alert("Unicode value is outside the range 0x0 - 0x10FFFF of RFC
3629.\n"
"FLTK will decode this as 0xFFFD (REPLACEMENT CHARACTER)"
);
char utf8[10];
unsigned int len = fl_utf8encode(ucs, utf8);
utf8[len] = '\0'; /* utf8 is not 0-terminated so add to ease debugging */
setEncodeOutput(ucs, utf8, len);
setBitBoxText(ucs, utf8, len);
setWidths(ucs, utf8, len);
toDisplays(ucs, utf8, len);
}
}
int main(int argc, char* argv[]) {
mainWindow = new Fl_Double_Window(410, 310, (const char*)"Unidecode?");
controlGroup = new Fl_Group(5, 5, 400, 170);
controlGroup->box(FL_UP_BOX);
unicodeInput = new Fl_Int_Input(120, 10, 200, 20, "Unicode : ");
unicodeInput->tooltip("unicode value [hex] i.e. U+004F is 0x4F");
unicodeInput->callback(unicodeCallback, 0);
encodedOutput = new Fl_Output(120, 30, 200, 20, "UTF-8 : ");
encodedOutput->tooltip("utf-8 encoding, with possible extra mapping by FLTK");
encodedGroup = new Fl_Group(120, 55, 300, 20, "bits UTF-8 : ");
encodedGroup->tooltip("bits in utf-8 sequence, colour-coded by UCS byte");
encodedGroup->align(FL_ALIGN_LEFT);
for (int byte = 0; byte < 4; byte++) {
for (int bit = 0; bit < 8; bit++) {
int b = (8 * byte) + bit; /* which bit box */
int o = (8 * byte) + (8 * b); /* offset to that box */
encodedBitBox[b] = new Fl_Box(120+o, 55, 8, 20, "0");
}
}
encodedGroup->end();
wcwidthOutput = new Fl_Output(120, 80, 200, 20, "wcwidth : ");
wcwidthOutput->tooltip("width of input ucs using system wcwidth() and
locale");
mkwidthOutput = new Fl_Output(120, 100, 200, 20, "mk_wcwidth : ");
mkwidthOutput->tooltip("width of input ucs using Markus Kuhn's wcwidth()");
flwidthOutput = new Fl_Output(120, 120, 200, 20, "fl_wcwidth : ");
flwidthOutput->tooltip("width of [mapped?] ucs using Markus Kuhn's
wcwidth()");
pxwidthOutput = new Fl_Output(120, 140, 200, 20, "pixel Width : ");
pxwidthOutput->tooltip("pixel width of character in current font");
displayGroup = new Fl_Group(5, 175, 400, 130);
displayGroup->box(FL_UP_BOX);
lastGlyphTD = new Fl_Text_Display(15, 195, 120, 100, "last glyph");
lastGlyphTB = new Fl_Text_Buffer();
lastGlyphTD->buffer(lastGlyphTB);
lastGlyphTD->wrap_mode(1, 0);
lastGlyphTD->insert("");
wrapMode15TD = new Fl_Text_Display(145, 195, 120, 100, "wrap_mode(1,5)");
wrapMode15TB = new Fl_Text_Buffer();
wrapMode15TD->buffer(wrapMode15TB);
wrapMode15TD->wrap_mode(1, 5);
wrapMode15TD->insert("");
wrapMode10TD = new Fl_Text_Display(275, 195, 120, 100, "wrap_mode(1,0)");
wrapMode10TB = new Fl_Text_Buffer();
wrapMode10TD->buffer(wrapMode10TB);
wrapMode10TD->wrap_mode(1, 0);
wrapMode10TD->insert("");
mainWindow->resizable(displayGroup);
mainWindow->show(argc, argv);
return Fl::run();
}
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs