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

Reply via email to