예제 #1
0
void curses_drawwindow(WINDOW *win)
{
    int i,j,w,drawx,drawy;
    unsigned tmp;

    for (j=0; j<win->height; j++){
        if (win->line[j].touched)
        {
            needupdate = true;

            win->line[j].touched=false;

            for (i=0,w=0; w<win->width; i++,w++){
                drawx=((win->x+w)*fontwidth);
                drawy=((win->y+j)*fontheight);//-j;
                if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){
				const char* utf8str = win->line[j].chars+i;
				int len = ANY_LENGTH;
                tmp = UTF8_getch(&utf8str, &len);
                int FG = win->line[j].FG[w];
                int BG = win->line[j].BG[w];
                FillRectDIB(drawx,drawy,fontwidth,fontheight,BG);

                if ( tmp != UNKNOWN_UNICODE){
					int cw = mk_wcwidth((wchar_t)tmp);
					len = ANY_LENGTH-len;
					if(cw>1) 
					{
						FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG);
						w+=cw-1;
					}
					if(len>1)
					{
						i+=len-1;
					}
                    if(tmp) OutputChar(tmp, drawx,drawy,FG);
                } else {
                    switch ((unsigned char)win->line[j].chars[i]) {
                    case LINE_OXOX_C://box bottom/top side (horizontal line)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_XOXO_C://box left/right side (vertical line)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_OXXO_C://box top left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_OOXX_C://box top right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOOX_C://box bottom right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOO_C://box bottom left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOX_C://box bottom north T (left, right, up)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG);
                        break;
                    case LINE_XXXO_C://box bottom east T (up, right, down)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_OXXX_C://box bottom south T (left, right, down)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XXXX_C://box X (left down up right)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOXX_C://box bottom east T (left, down, up)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        break;
                    default:
                        break;
                    }
                    };//switch (tmp)
                }//(tmp < 0)
            };//for (i=0;i<_windows[w].width;i++)
        }
    };// for (j=0;j<_windows[w].height;j++)
    win->draw=false;                //We drew the window, mark it as so

    if (needupdate) try_update();
}
예제 #2
0
void curses_drawwindow(WINDOW *win)
{
    int i,j,w,drawx,drawy;
    unsigned tmp;
    RECT update = {win->x * fontwidth, -1,
                   (win->x + win->width) * fontwidth, -1};

    for (j=0; j<win->height; j++){
        if (win->line[j].touched)
        {
            update.bottom = (win->y+j+1)*fontheight;
            if (update.top == -1)
            {
                update.top = update.bottom - fontheight;
            }

            win->line[j].touched=false;

            for (i=0,w=0; w<win->width; i++,w++){
                drawx=((win->x+w)*fontwidth);
                drawy=((win->y+j)*fontheight);//-j;
                if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){
                const char* utf8str = win->line[j].chars+i;
                int len = ANY_LENGTH;
                tmp = UTF8_getch(&utf8str, &len);
                int FG = win->line[j].FG[w];
                int BG = win->line[j].BG[w];
                FillRectDIB(drawx,drawy,fontwidth,fontheight,BG);

                if (tmp != UNKNOWN_UNICODE) {

                    int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue);
                    SetTextColor(backbuffer,color);

                    int cw = mk_wcwidth(tmp);
                    len = ANY_LENGTH-len;
                    if (cw > 1) {
                        FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG);
                        w += cw - 1;
                    }
                    if (len > 1) {
                        i += len - 1;
                    }
                    if (tmp) ExtTextOutW (backbuffer, drawx, drawy, 0, NULL, (WCHAR*)&tmp, 1, NULL);
                } else {
                    switch ((unsigned char)win->line[j].chars[i]) {
                    case LINE_OXOX_C://box bottom/top side (horizontal line)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_XOXO_C://box left/right side (vertical line)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_OXXO_C://box top left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_OOXX_C://box top right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOOX_C://box bottom right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOO_C://box bottom left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOX_C://box bottom north T (left, right, up)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG);
                        break;
                    case LINE_XXXO_C://box bottom east T (up, right, down)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_OXXX_C://box bottom south T (left, right, down)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XXXX_C://box X (left down up right)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOXX_C://box bottom east T (left, down, up)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        break;
                    default:
                        break;
                    }
                    };//switch (tmp)
                }//(tmp < 0)
            };//for (i=0;i<_windows[w].width;i++)
        }
    };// for (j=0;j<_windows[w].height;j++)
    win->draw=false;                //We drew the window, mark it as so
    if (update.top != -1)
    {
        RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
    }
}
예제 #3
0
// utf-8 version
std::string word_rewrap (const std::string &ins, int width)
{
    std::ostringstream o;
    std::string in = ins;

    // find non-printing tags
    std::vector<size_t> tag_positions = get_tag_positions(in);

    int lastwb  = 0; //last word break
    int lastout = 0;
    const char *instr = in.c_str();
    bool skipping_tag = false;

    for (int j = 0, x = 0; j < in.size(); ) {
        const char *ins = instr + j;
        int len = ANY_LENGTH;
        unsigned uc = UTF8_getch(&ins, &len);

        if (uc == '<') { // maybe skip non-printing tag
            std::vector<size_t>::iterator it;
            for (it = tag_positions.begin(); it != tag_positions.end(); ++it) {
                if (*it == j) {
                    skipping_tag = true;
                    break;
                }
            }
        }

        j += ANY_LENGTH - len;

        if (skipping_tag) {
            if (uc == '>') {
                skipping_tag = false;
            }
            continue;
        }

        x += mk_wcwidth(uc);

        if (x > width) {
            if (lastwb == lastout) {
                lastwb = j;
            }
            for(int k = lastout; k < lastwb; k++) {
                o << in[k];
            }
            o << '\n';
            x = 0;
            lastout = j = lastwb;
        }

        if (uc == ' ' || uc >= 0x2E80) {
            lastwb = j;
        }
    }
    for (int k = lastout; k < in.size(); k++) {
        o << in[k];
    }

    return o.str();
}
예제 #4
0
파일: gui-entry.c 프로젝트: Adam-/irssi
static int i_isalnum(unichar c)
{
	if (term_type == TERM_TYPE_UTF8)
		return (g_unichar_isalnum(c) || mk_wcwidth(c) == 0);
	return (c >= 0 && c <= 255) ? isalnum(c) : 0;
}
예제 #5
0
파일: fmtext.c 프로젝트: alexmv/barnowl
/* Truncate the message so that each line begins at column 'acol' and
 * ends at 'bcol' or sooner.  The first column is number 0.  The new
 * message is placed in 'out'.  The message is expected to end in a
 * new line for now.
 *
 * NOTE: This needs to be modified to deal with backing up if we find
 * a SPACING COMBINING MARK at the end of a line. If that happens, we
 * should back up to the last non-mark character and stop there.
 *
 * NOTE: If a line ends at bcol, we omit the newline. This is so printing
 * to ncurses works.
 */
void owl_fmtext_truncate_cols(const owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
{
  const char *ptr_s, *ptr_e, *ptr_c, *last;
  int col, st, padding, chwidth;

  /* copy the default attributes */
  out->default_attrs = in->default_attrs;
  out->default_fgcolor = in->default_fgcolor;
  out->default_bgcolor = in->default_bgcolor;

  last=in->textbuff+in->textlen-1;
  ptr_s=in->textbuff;
  while (ptr_s <= last) {
    ptr_e=strchr(ptr_s, '\n');
    if (!ptr_e) {
      /* but this shouldn't happen if we end in a \n */
      break;
    }
    
    if (ptr_e == ptr_s) {
      owl_fmtext_append_normal(out, "\n");
      ++ptr_s;
      continue;
    }

    col = 0;
    st = 0;
    padding = 0;
    chwidth = 0;
    ptr_c = ptr_s;
    while(ptr_c < ptr_e) {
      gunichar c = g_utf8_get_char(ptr_c);
      if (!owl_fmtext_is_format_char(c)) {
	chwidth = mk_wcwidth(c);
	if (col + chwidth > bcol) break;
	
	if (col >= acol) {
	  if (st == 0) {
	    ptr_s = ptr_c;
	    padding = col - acol;
	    ++st;
	  }
	}
	col += chwidth;
	chwidth = 0;
      }
      ptr_c = g_utf8_next_char(ptr_c);
    }
    if (st) {
      /* lead padding */
      owl_fmtext_append_spaces(out, padding);
      if (ptr_c == ptr_e) {
	/* We made it to the newline. */
	_owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
      }
      else if (chwidth > 1) {
        /* Last char is wide, truncate. */
        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
        owl_fmtext_append_normal(out, "\n");
      }
      else {
        /* Last char fits perfectly, We skip to the next char and back
         * up a byte to make sure we get it all.
         */
        ptr_c = g_utf8_next_char(ptr_c);
        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
      }
    }
    else {
      owl_fmtext_append_normal(out, "\n");
    }
    ptr_s = g_utf8_next_char(ptr_e);
  }
}
예제 #6
0
int main (int argc, char** argv)
{
  UnitTest t (16);

  // Ensure environment has no influence.
  unsetenv ("TASKDATA");
  unsetenv ("TASKRC");

  t.is (mk_wcwidth ('a'),    1, "U+0061 --> 1");

  t.is (mk_wcwidth (0x5149), 2, "U+5149 --> 2");
  t.is (mk_wcwidth (0x9a8c), 2, "U+9a8c --> 2");
  t.is (mk_wcwidth (0x4e70), 2, "U+4e70 --> 2");
  t.is (mk_wcwidth (0x94b1), 2, "U+94b1 --> 2");
  t.is (mk_wcwidth (0x5305), 2, "U+5305 --> 2");
  t.is (mk_wcwidth (0x91cd), 2, "U+91cd --> 2");
  t.is (mk_wcwidth (0x65b0), 2, "U+65b0 --> 2");
  t.is (mk_wcwidth (0x8bbe), 2, "U+8bbe --> 2");
  t.is (mk_wcwidth (0x8ba1), 2, "U+8ba1 --> 2");
  t.is (mk_wcwidth (0x5411), 2, "U+5411 --> 2");
  t.is (mk_wcwidth (0x4e0a), 2, "U+4e0a --> 2");
  t.is (mk_wcwidth (0x4e0b), 2, "U+4e0b --> 2");
  t.is (mk_wcwidth (0x7bad), 2, "U+7bad --> 2");
  t.is (mk_wcwidth (0x5934), 2, "U+5934 --> 2");
  t.is (mk_wcwidth (0xff0c), 2, "U+ff0c --> 2"); // comma

  return 0;
}
예제 #7
0
파일: fqwcwidth.cpp 프로젝트: ashang/fqterm
int get_str_width(uint32_t ucs) {
  return mk_wcwidth(ucs);
}
예제 #8
0
int waddch(WINDOW *win, const chtype ch)
{
    char charcode;
    charcode=ch;

    switch (ch){        //LINE_NESW  - X for on, O for off
        case LINE_XOXO:   //#define LINE_XOXO 4194424
            charcode=LINE_XOXO_C;
            break;
        case LINE_OXOX:   //#define LINE_OXOX 4194417
            charcode=LINE_OXOX_C;
            break;
        case LINE_XXOO:   //#define LINE_XXOO 4194413
            charcode=LINE_XXOO_C;
            break;
        case LINE_OXXO:   //#define LINE_OXXO 4194412
            charcode=LINE_OXXO_C;
            break;
        case LINE_OOXX:   //#define LINE_OOXX 4194411
            charcode=LINE_OOXX_C;
            break;
        case LINE_XOOX:   //#define LINE_XOOX 4194410
            charcode=LINE_XOOX_C;
            break;
        case LINE_XXOX:   //#define LINE_XXOX 4194422
            charcode=LINE_XXOX_C;
            break;
        case LINE_XXXO:   //#define LINE_XXXO 4194420
            charcode=LINE_XXXO_C;
            break;
        case LINE_XOXX:   //#define LINE_XOXX 4194421
            charcode=LINE_XOXX_C;
            break;
        case LINE_OXXX:   //#define LINE_OXXX 4194423
            charcode=LINE_OXXX_C;
            break;
        case LINE_XXXX:   //#define LINE_XXXX 4194414
            charcode=LINE_XXXX_C;
            break;
        default:
            charcode = (char)ch;
            break;
        }


    int cury=win->cursory;
    int p = win->cursorx;
    int curx=(win->line[cury].width_in_bytes==win->width)?win->cursorx:cursorx_to_position(win->line[cury].chars, win->cursorx, &p);

    if(curx!=p)
    {
        const char* ts = win->line[cury].chars+p;
        int len = ANY_LENGTH;
        unsigned tc = UTF8_getch(&ts, &len);
        int tw = mk_wcwidth((wchar_t)tc);
        win->line[cury].width_in_bytes += erease_utf8_by_cw(win->line[cury].chars+p, tw, tw, win->width*4-p-1);
        curx = p+tw-1;
    }
    else if(win->line[cury].width_in_bytes!=win->width)
    {
        win->line[cury].width_in_bytes += erease_utf8_by_cw(win->line[cury].chars+p, 1, 1, win->width*4-p-1);
    }

//if (win2 > -1){
   win->line[cury].chars[curx]=charcode;
   win->line[cury].FG[win->cursorx]=win->FG;
   win->line[cury].BG[win->cursorx]=win->BG;


    win->draw=true;
    addedchar(win);
    return 1;
  //  else{
  //  win2=win2+1;

}
예제 #9
0
파일: wcwidth.c 프로젝트: phschoen/tig
/*
 * The following functions are the same as mk_wcwidth() and
 * mk_wcwidth_cjk(), except that spacing characters in the East Asian
 * Ambiguous (A) category as defined in Unicode Technical Report #11
 * have a column width of 2. This variant might be useful for users of
 * CJK legacy encodings who want to migrate to UCS without changing
 * the traditional terminal character-width behaviour. It is not
 * otherwise recommended for general use.
 */
int mk_wcwidth_cjk(wchar_t ucs)
{
  /* sorted list of non-overlapping intervals of East Asian Ambiguous
   * characters, generated by
   *
   * uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf \
   *    +E000..F8FF \
   *    +F0000..FFFFD \
   *    +100000..10FFFD  c
   *
   * "WIDTH-A" is a file extracted from EastAsianWidth.txt by selecting
   * only those with width "A", and omitting:
   *
   *    0xAD
   *    all lines with "COMBINING"
   *
   * (uniset does not recognize the range expressions in WIDTH-A).
   */
  static const struct interval ambiguous[] = {
    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B2 },
    { 0x00B4, 0x00B4 }, { 0x00B6, 0x00B6 }, { 0x00B8, 0x00BA },
    { 0x00BC, 0x00BC }, { 0x00BF, 0x00BF }, { 0x00C6, 0x00C6 },
    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00DE },
    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00E8 }, { 0x00EC, 0x00EC },
    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F2 }, { 0x00F7, 0x00F8 },
    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
    { 0x0126, 0x0126 }, { 0x012B, 0x012B }, { 0x0131, 0x0131 },
    { 0x0138, 0x0138 }, { 0x013F, 0x013F }, { 0x0144, 0x0144 },
    { 0x0148, 0x0148 }, { 0x014D, 0x014D }, { 0x0152, 0x0152 },
    { 0x0166, 0x0166 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02C9 },
    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02D8 },
    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x0391 },
    { 0x03A3, 0x03A3 }, { 0x03B1, 0x03B1 }, { 0x03C3, 0x03C3 },
    { 0x0401, 0x0401 }, { 0x0410, 0x0410 }, { 0x0451, 0x0451 },
    { 0x2010, 0x2010 }, { 0x2013, 0x2013 }, { 0x2016, 0x2016 },
    { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2020 },
    { 0x2024, 0x2024 }, { 0x2030, 0x2030 }, { 0x2032, 0x2032 },
    { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x203E, 0x203E },
    { 0x2074, 0x2074 }, { 0x207F, 0x207F }, { 0x2081, 0x2081 },
    { 0x20AC, 0x20AC }, { 0x2103, 0x2103 }, { 0x2105, 0x2105 },
    { 0x2109, 0x2109 }, { 0x2113, 0x2113 }, { 0x2116, 0x2116 },
    { 0x2121, 0x2121 }, { 0x2126, 0x2126 }, { 0x212B, 0x212B },
    { 0x2153, 0x2153 }, { 0x215B, 0x215B }, { 0x2160, 0x2160 },
    { 0x2170, 0x2170 }, { 0x2189, 0x2189 }, { 0x2190, 0x2190 },
    { 0x2195, 0x2195 }, { 0x21B8, 0x21B8 }, { 0x21D2, 0x21D2 },
    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
    { 0x2202, 0x2202 }, { 0x2207, 0x2207 }, { 0x220B, 0x220B },
    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
    { 0x221A, 0x221A }, { 0x221D, 0x221D }, { 0x2223, 0x2223 },
    { 0x2225, 0x2225 }, { 0x2227, 0x2227 }, { 0x222E, 0x222E },
    { 0x2234, 0x2234 }, { 0x223C, 0x223C }, { 0x2248, 0x2248 },
    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2260 },
    { 0x2264, 0x2264 }, { 0x226A, 0x226A }, { 0x226E, 0x226E },
    { 0x2282, 0x2282 }, { 0x2286, 0x2286 }, { 0x2295, 0x2295 },
    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
    { 0x2312, 0x2312 }, { 0x2460, 0x2460 }, { 0x249C, 0x249C },
    { 0x24EB, 0x24EB }, { 0x2500, 0x2500 }, { 0x2550, 0x2550 },
    { 0x2580, 0x2580 }, { 0x2592, 0x2592 }, { 0x25A0, 0x25A0 },
    { 0x25A3, 0x25A3 }, { 0x25B2, 0x25B2 }, { 0x25B6, 0x25B7 },
    { 0x25BC, 0x25BC }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C6 },
    { 0x25CB, 0x25CB }, { 0x25CE, 0x25CE }, { 0x25E2, 0x25E2 },
    { 0x25EF, 0x25EF }, { 0x2605, 0x2605 }, { 0x2609, 0x2609 },
    { 0x260E, 0x260E }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
    { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2660 },
    { 0x2663, 0x2663 }, { 0x2667, 0x2667 }, { 0x266C, 0x266C },
    { 0x266F, 0x266F }, { 0x269E, 0x269E }, { 0x26BF, 0x26BF },
    { 0x26C6, 0x26C6 }, { 0x26CF, 0x26CF }, { 0x26D5, 0x26D5 },
    { 0x26E3, 0x26E3 }, { 0x26E8, 0x26E8 }, { 0x26EB, 0x26EB },
    { 0x26F4, 0x26F4 }, { 0x26F6, 0x26F6 }, { 0x26FB, 0x26FB },
    { 0x26FE, 0x26FE }, { 0x273D, 0x273D }, { 0x2776, 0x2776 },
    { 0x2B56, 0x2B56 }, { 0x3248, 0x3248 }, { 0xE000, 0xF8FF },
    { 0xFFFD, 0xFFFD }, { 0x1F100, 0x1F100 }, { 0x1F110, 0x1F110 },
    { 0x1F130, 0x1F130 }, { 0x1F170, 0x1F170 }, { 0x1F18F, 0x1F18F },
    { 0x1F19B, 0x1F19B }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
  };

  /* binary search in table of non-spacing characters */
  if (Lookup((unsigned long) ucs, ambiguous))
    return 2;

  return mk_wcwidth(ucs);
}
예제 #10
0
파일: unicode.c 프로젝트: AmirAbrams/haiku
INTERNAL int vterm_unicode_width(int codepoint)
{
  return mk_wcwidth(codepoint);
}
예제 #11
0
파일: text.cpp 프로젝트: georgebrock/task
// text       "one two three\n  four"
// bytes       0123456789012 3456789
// characters  1234567890a23 4567890
//
// leading_ws
// ws             ^   ^       ^^
// punct
// break                     ^
bool extractLine (
  std::string& line,
  const std::string& text,
  int width,
  bool hyphenate,
  unsigned int& offset)
{
  // Terminate processing.
  // Note: bytes vs bytes.
  if (offset >= text.length ())
    return false;

  std::string::size_type last_last_bytes = offset;
  std::string::size_type last_bytes = offset;
  std::string::size_type bytes = offset;
  unsigned int last_ws = 0;
  int character;
  int char_width = 0;
  int line_width = 0;
  while (1)
  {
    last_last_bytes = last_bytes;
    last_bytes = bytes;
    character = utf8_next_char (text, bytes);

    if (character == 0 ||
        character == '\n')
    {
      line = text.substr (offset, last_bytes - offset);
      offset = bytes;
      break;
    }
    else if (character == ' ')
      last_ws = last_bytes;

    char_width = mk_wcwidth (character);
    if (line_width + char_width > width)
    {
      int last_last_character = text[last_last_bytes];
      int last_character = text[last_bytes];

      // [case 1] one| two --> last_last != 32, last == 32, ws == 0
      if (last_last_character != ' ' &&
          last_character      == ' ')
      {
        line = text.substr (offset, last_bytes - offset);
        offset = last_bytes + 1;
        break;
      }

      // [case 2] one |two --> last_last == 32, last != 32, ws != 0
      else if (last_last_character == ' ' &&
               last_character      != ' ' &&
               last_ws             != 0)
      {
        line = text.substr (offset, last_bytes - offset - 1);
        offset = last_bytes;
        break;
      }

      else if (last_last_character != ' ' &&
               last_character      != ' ')
      {
        // [case 3] one t|wo --> last_last != 32, last != 32, ws != 0
        if (last_ws != 0)
        {
          line = text.substr (offset, last_ws - offset);
          offset = last_ws + 1;
          break;
        }
        // [case 4] on|e two --> last_last != 32, last != 32, ws == 0
        else
        {
          if (hyphenate)
          {
            line = text.substr (offset, last_bytes - offset - 1) + "-";
            offset = last_last_bytes;
          }
          else
          {
            line = text.substr (offset, last_bytes - offset);
            offset = last_bytes;
          }
        }

        break;
      }
    }

    line_width += char_width;
  }

  return true;
}
예제 #12
0
void curses_drawwindow(WINDOW *win)
{
    int i,j,w,drawx,drawy;
    unsigned tmp;

    int miny = 99999;
    int maxy = -99999;

    for (j=0; j<win->height; j++)
    {
        if (win->line[j].touched)
        {
            if(j<miny) {
                miny=j;
            }
            if(j>maxy) {
                maxy=j;
            }


            win->line[j].touched=false;

            for (i=0,w=0; w<win->width; i++,w++)
            {
                drawx=((win->x+w)*fontwidth);
                drawy=((win->y+j)*fontheight);//-j;
                if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight))
                {
                    const char* utf8str = win->line[j].chars+i;
                    int len = ANY_LENGTH;
                    tmp = UTF8_getch(&utf8str, &len);
                    int FG = win->line[j].FG[w];
                    int BG = win->line[j].BG[w];
                    FillRectDIB(drawx,drawy,fontwidth,fontheight,BG);

                    if ( tmp != UNKNOWN_UNICODE){
                        int cw = mk_wcwidth((wchar_t)tmp);
                        len = ANY_LENGTH-len;
                        if(cw>1)
                        {
                            FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG);
                            w+=cw-1;
                        }
                        if(len>1)
                        {
                            i+=len-1;
                        }
                        if(0!=tmp) {
                            OutputChar(tmp, drawx,drawy,FG);
                        }
                    } else {
                        switch ((unsigned char)win->line[j].chars[i]) {
                        case LINE_OXOX_C://box bottom/top side (horizontal line)
                            HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                            break;
                        case LINE_XOXO_C://box left/right side (vertical line)
                            VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                            break;
                        case LINE_OXXO_C://box top left
                            HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                            break;
                        case LINE_OOXX_C://box top right
                            HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                            break;
                        case LINE_XOOX_C://box bottom right
                            HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                            break;
                        case LINE_XXOO_C://box bottom left
                            HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                            break;
                        case LINE_XXOX_C://box bottom north T (left, right, up)
                            HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG);
                            break;
                        case LINE_XXXO_C://box bottom east T (up, right, down)
                            VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                            HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                            break;
                        case LINE_OXXX_C://box bottom south T (left, right, down)
                            HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                            break;
                        case LINE_XXXX_C://box X (left down up right)
                            HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                            VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                            break;
                        case LINE_XOXX_C://box bottom east T (left, down, up)
                            VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                            HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                            break;
                        default:
                            break;
                        }//switch (tmp)
                    }
                }//(tmp < 0)
            }//for (i=0;i<_windows[w].width;i++)
        }
    }// for (j=0;j<_windows[w].height;j++)
    win->draw=false;                //We drew the window, mark it as so

    if(maxy>=0)
    {
        int tx=win->x, ty=win->y+miny, tw=win->width, th=maxy-miny+1;
        int maxw=WindowWidth/fontwidth, maxh=WindowHeight/fontheight;
        if(tw+tx>maxw) {
            tw= maxw-tx;
        }
        if(th+ty>maxh) {
            th= maxh-ty;
        }
        SDL_UpdateRect(screen, tx*fontwidth, ty*fontheight, tw*fontwidth, th*fontheight);
    }
}
예제 #13
0
void curses_drawwindow(WINDOW *win)
{
    int i,j,w,drawx,drawy;
    unsigned tmp;

    SDL_Rect update_rect;
    update_rect.x = win->x * fontwidth;
    update_rect.w = win->width * fontwidth;
    update_rect.y = 9999; // default value
    update_rect.h = 9999; // default value

    int jr = 0;

    for (j=0; j<win->height; j++){
        if (win->line[j].touched)
        {
            if (update_rect.y == 9999)
            {
                update_rect.y = (win->y+j)*fontheight;
                jr=j;
            }
            update_rect.h = (j-jr+1)*fontheight;

            needupdate = true;

            win->line[j].touched=false;

            for (i=0,w=0; w<win->width; i++,w++){
                drawx=((win->x+w)*fontwidth);
                drawy=((win->y+j)*fontheight);//-j;
                if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){
                const char* utf8str = win->line[j].chars+i;
                int len = ANY_LENGTH;
                tmp = UTF8_getch(&utf8str, &len);
                int FG = win->line[j].FG[w];
                int BG = win->line[j].BG[w];
                FillRectDIB(drawx,drawy,fontwidth,fontheight,BG);

                if ( tmp != UNKNOWN_UNICODE){
                    int cw = mk_wcwidth(tmp);
                    len = ANY_LENGTH-len;
                    if(cw>1)
                    {
                        FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG);
                        w+=cw-1;
                    }
                    if(len>1)
                    {
                        i+=len-1;
                    }
                    if(tmp) OutputChar(tmp, drawx,drawy,FG);
                } else {
                    switch ((unsigned char)win->line[j].chars[i]) {
                    case LINE_OXOX_C://box bottom/top side (horizontal line)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_XOXO_C://box left/right side (vertical line)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_OXXO_C://box top left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_OOXX_C://box top right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOOX_C://box bottom right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOO_C://box bottom left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOX_C://box bottom north T (left, right, up)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG);
                        break;
                    case LINE_XXXO_C://box bottom east T (up, right, down)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_OXXX_C://box bottom south T (left, right, down)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XXXX_C://box X (left down up right)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOXX_C://box bottom east T (left, down, up)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        break;
                    default:
                        break;
                    }
                    };//switch (tmp)
                }//(tmp < 0)
            };//for (i=0;i<_windows[w].width;i++)
        }
    };// for (j=0;j<_windows[w].height;j++)
    win->draw=false;                //We drew the window, mark it as so

    if (g && win == g->w_terrain && use_tiles)
    {
        update_rect.y = win->y*tilecontext->tile_height;
        update_rect.h = win->height*tilecontext->tile_height;
        update_rect.x = win->y*tilecontext->tile_width;
        update_rect.w = win->width*tilecontext->tile_width;
        //GfxDraw(thegame, win->x*fontwidth, win->y*fontheight, thegame->terrain_view_x, thegame->terrain_view_y, win->width*fontwidth, win->height*fontheight);
        tilecontext->draw(win->x * fontwidth, win->y * fontheight, g->ter_view_x, g->ter_view_y, tilecontext->terrain_term_x * fontwidth, tilecontext->terrain_term_y * fontheight);
    }
//*/
    if (update_rect.y != 9999)
    {
        SDL_UpdateRect(screen, update_rect.x, update_rect.y, update_rect.w, update_rect.h);
    }
    if (needupdate) try_update();
}
예제 #14
0
파일: text.cpp 프로젝트: codito/task
////////////////////////////////////////////////////////////////////////////////
// Walk the input text looking for a break point.  A break point is one of:
//   - EOS
//   - \n
//   - last space before 'length' characters
//   - first 'length' characters
void extractLine (
  std::string& text,
  std::string& line,
  int length,
  bool hyphenate)
{
  std::string::size_type bytes      = 0;
  std::string::size_type previous   = std::string::npos;
  std::string::size_type last_space = std::string::npos;
  int character;
  int width = 0;
  while (width < length)
  {
    previous = bytes;
    character = utf8_next_char (text, bytes);

    // Record last seen space.
    if (character == ' ')
      last_space = previous;

    // Newline is an early break point.
    if (character == '\n')
    {
      line = text.substr (0, bytes - 1);
      text = text.substr (bytes);
      return;
    }

    // EOS is an early break point.
    if (character == 0)
    {
      line = text;
      text = "";
      return;
    }

    width += mk_wcwidth (character);
  }

  // Case where EOS was not quite reached.
  //  012345
  // |eleven|\0
  if (text[bytes] == '\0')
  {
    line = text;
    text = "";
    return;
  }

  // Case where a word ends at the right margin.
  //  012345
  // |eleven|_
  if (text[bytes] == ' ')
  {
    line = text.substr (0, bytes);
    text = text.substr (bytes + 1);
    return;
  }

  // Case where a word straddles the margin, but there is an earlier space
  // to break on.
  //  012345
  // |one_tw|o
  if (last_space != std::string::npos)
  {
    line = text.substr (0, last_space);
    text = text.substr (last_space + 1);
    return;
  }

  // Case where a word needs to be split, and there is no last_space.
  // Hyphenation becomes the issue.
  //  012345
  // |fiftee|n
  // |fifte-|en
  else
  {
    if (hyphenate)
    {
      line = text.substr (0, previous) + "-";
      text = text.substr (previous);
    }
    else
    {
      line = text.substr (0, bytes);
      text = text.substr (bytes);
    }

    return;
  }
}
예제 #15
0
void curses_drawwindow(WINDOW *win)
{
    int i,j,drawx,drawy;
    unsigned tmp;
    RECT update = {win->x * fontwidth, -1,
                   (win->x + win->width) * fontwidth, -1};

    for (j=0; j<win->height; j++){
        if (win->line[j].touched)
        {
            update.bottom = (win->y+j+1)*fontheight;
            if (update.top == -1)
            {
                update.top = update.bottom - fontheight;
            }

            win->line[j].touched=false;

            for (i=0; i<win->width; i++){
                const cursecell &cell = win->line[j].chars[i];
                if( cell.ch.empty() ) {
                    continue; // second cell of a multi-cell character
                }
                drawx=((win->x+i)*fontwidth);
                drawy=((win->y+j)*fontheight);//-j;
                if( drawx + fontwidth > WindowWidth || drawy + fontheight > WindowHeight ) {
                    // Outside of the display area, would not render anyway
                    continue;
                }
                const char* utf8str = cell.ch.c_str();
                int len = cell.ch.length();
                tmp = UTF8_getch(&utf8str, &len);
                int FG = cell.FG;
                int BG = cell.BG;
                FillRectDIB(drawx,drawy,fontwidth,fontheight,BG);

                if (tmp != UNKNOWN_UNICODE) {

                    int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue);
                    SetTextColor(backbuffer,color);

                    int cw = mk_wcwidth(tmp);
                    if (cw > 1) {
                        FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG);
                        i += cw - 1;
                    }
                    if (tmp) {
                        const std::wstring utf16 = widen(cell.ch);
                        ExtTextOutW( backbuffer, drawx, drawy, 0, NULL, utf16.c_str(), utf16.length(), NULL );
                    }
                } else {
                    switch ((unsigned char)win->line[j].chars[i].ch[0]) {
                    case LINE_OXOX_C://box bottom/top side (horizontal line)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_XOXO_C://box left/right side (vertical line)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_OXXO_C://box top left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_OOXX_C://box top right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOOX_C://box bottom right
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOO_C://box bottom left
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG);
                        break;
                    case LINE_XXOX_C://box bottom north T (left, right, up)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG);
                        break;
                    case LINE_XXXO_C://box bottom east T (up, right, down)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG);
                        break;
                    case LINE_OXXX_C://box bottom south T (left, right, down)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG);
                        break;
                    case LINE_XXXX_C://box X (left down up right)
                        HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG);
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        break;
                    case LINE_XOXX_C://box bottom east T (left, down, up)
                        VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG);
                        HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG);
                        break;
                    default:
                        break;
                    };//switch (tmp)
                }//(tmp < 0)
            };//for (i=0;i<_windows[w].width;i++)
        }
    };// for (j=0;j<_windows[w].height;j++)
    win->draw=false;                //We drew the window, mark it as so
    if (update.top != -1)
    {
        RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
    }
}
예제 #16
0
/*
 * The following functions are the same as mk_wcwidth() and
 * mk_wcwidth_cjk(), except that spacing characters in the East Asian
 * Ambiguous (A) category as defined in Unicode Technical Report #11
 * have a column width of 2. This variant might be useful for users of
 * CJK legacy encodings who want to migrate to UCS without changing
 * the traditional terminal character-width behaviour. It is not
 * otherwise recommended for general use.
 */
int
mk_wcwidth_cjk(wchar_t ucs)
{
    /* sorted list of non-overlapping intervals of East Asian Ambiguous
     * characters, generated by
     *
     * uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf \
     *    +E000..F8FF \
     *    +F0000..FFFFD \
     *    +100000..10FFFD  c
     *
     * "WIDTH-A" is a file extracted from EastAsianWidth.txt by selecting
     * only those with width "A", and omitting:
     *
     *    0xAD
     *    all lines with "COMBINING"
     *
     * (uniset does not recognize the range expressions in WIDTH-A).
     */
  /* *INDENT-OFF* */
  static const struct interval ambiguous[] = {
    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
    { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
    { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
    { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
    { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
    { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
    { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
    { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
    { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
    { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
    { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
    { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
    { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
    { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
    { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
    { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
    { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
    { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
    { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
    { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
    { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
    { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
    { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
    { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
    { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
    { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
    { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
    { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
    { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
    { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
  };
  /* *INDENT-ON* */

    /* binary search in table of non-spacing characters */
    if (bisearch((unsigned long) ucs, ambiguous,
		 (int) (sizeof(ambiguous) / sizeof(struct interval) - 1)))
	  return 2;

    return mk_wcwidth(ucs);
}
예제 #17
0
/*
 * The following functions are the same as mk_wcwidth() and
 * mk_wcswidth(), except that spacing characters in the East Asian
 * Ambiguous (A) category as defined in Unicode Technical Report #11
 * have a column width of 2. This variant might be useful for users of
 * CJK legacy encodings who want to migrate to UCS without changing
 * the traditional terminal character-width behaviour. It is not
 * otherwise recommended for general use.
 */
int mk_wcwidth_cjk(wchar_t ucs)
{
  /* sorted list of non-overlapping intervals of East Asian Ambiguous
   * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
  static const struct interval ambiguous[] = {
    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
    { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
    { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
    { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
    { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
    { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
    { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
    { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
    { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
    { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
    { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
    { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
    { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
    { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
    { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
    { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
    { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
    { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
    { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
    { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
    { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
    { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
    { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
    { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
    { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
    { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
    { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
    { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
    { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
    { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
  };

  /* binary search in table of non-spacing characters */
  if (bisearch(ucs, ambiguous,
               sizeof(ambiguous) / sizeof(struct interval) - 1))
    return 2;

  return mk_wcwidth(ucs);
}
예제 #18
0
int main (int argc, char** argv)
{
  UnitTest t (16);

  t.is (mk_wcwidth ('a'),    1, "U+0061 --> 1");

  t.is (mk_wcwidth (0x5149), 2, "U+5149 --> 2");
  t.is (mk_wcwidth (0x9a8c), 2, "U+9a8c --> 2");
  t.is (mk_wcwidth (0x4e70), 2, "U+4e70 --> 2");
  t.is (mk_wcwidth (0x94b1), 2, "U+94b1 --> 2");
  t.is (mk_wcwidth (0x5305), 2, "U+5305 --> 2");
  t.is (mk_wcwidth (0x91cd), 2, "U+91cd --> 2");
  t.is (mk_wcwidth (0x65b0), 2, "U+65b0 --> 2");
  t.is (mk_wcwidth (0x8bbe), 2, "U+8bbe --> 2");
  t.is (mk_wcwidth (0x8ba1), 2, "U+8ba1 --> 2");
  t.is (mk_wcwidth (0x5411), 2, "U+5411 --> 2");
  t.is (mk_wcwidth (0x4e0a), 2, "U+4e0a --> 2");
  t.is (mk_wcwidth (0x4e0b), 2, "U+4e0b --> 2");
  t.is (mk_wcwidth (0x7bad), 2, "U+7bad --> 2");
  t.is (mk_wcwidth (0x5934), 2, "U+5934 --> 2");
  t.is (mk_wcwidth (0xff0c), 2, "U+ff0c --> 2"); // comma

  return 0;
}