Exemple #1
0
unsigned int SLsmg_strwidth (SLuchar_Type *u, SLuchar_Type *umax)
{
   unsigned char display_8bit;
   int utf8_mode = UTF8_Mode;
   int col;

   if (u == NULL)
     return 0;

   display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
   if (utf8_mode)
     display_8bit = 0xA0;

   col = This_Col;

   while (u < umax)
     {
	SLuchar_Type ch;
	unsigned int nconsumed;
	SLwchar_Type wc;

	ch = *u;
	if (ch < 0x80)
	  {
	     u++;

	     if ((ch >= 0x20) && (ch != 0x7F))
	       {
		  col++;
		  continue;
	       }
	     
	     if ((ch == '\t') && (SLsmg_Tab_Width > 0))
	       {
		  if (col >= 0)
		    col = (1 + col/SLsmg_Tab_Width) * SLsmg_Tab_Width;
		  else
		    col = ((col + 1)/SLsmg_Tab_Width) * SLsmg_Tab_Width;
		  
		  continue;
	       }

	     if ((ch == '\n')
		 && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
	       break;
	     
	     if ((ch == 0x8) && SLsmg_Backspace_Moves)
	       {
		  col--;
		  continue;
	       }
#if SLSMG_HAS_EMBEDDED_ESCAPE
	     if ((ch == 033) && Embedded_Escape_Mode)
	       {
		  SLsmg_Color_Type color;
		  if (0 == parse_embedded_escape (u, umax, 0, &u, &color))
		    continue;
	       }
#endif
	     col += 2;
	     continue;
	  }
	
	nconsumed = 1;
	if ((utf8_mode == 0)
	    || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
	  {	     
	     if ((utf8_mode == 0)
		 && (display_8bit && (*u >= display_8bit)))
	       col++;
	     else
	       col += 4*nconsumed;
	     u += nconsumed;
	     continue;
	  }

	u += nconsumed;
	if (wc < (SLwchar_Type)display_8bit)
	  {
	     col += 4;
	     continue;
	  }
	col += SLwchar_wcwidth (wc);
     }
   
   if (col < This_Col)
     return 0;

   return (unsigned int) (col - This_Col);
}
Exemple #2
0
int SLcurses_waddch (SLcurses_Window_Type *win, SLtt_Char_Type attr)
{
   SLtt_Char_Type ch;
   SLsmg_Color_Type color;
   int width;
   int is_acs;

   if (win == NULL) return -1;

   if (win->_cury >= win->nrows)
     {
	/* Curses seems to move current position to top of window. */
	win->_cury = win->_curx = 0;
	return -1;
     }

   win->modified = 1;

   ch = SLTT_EXTRACT_CHAR(attr);
   if (ch == 0) return -1;

   if (attr == ch)
     color = win->color;
   else
     {
	/* hack to pick up the default color for graphics chars */
	if (((attr & A_COLOR) == 0) && ((attr & A_ALTCHARSET) != 0))
	  {
	     SLCURSES_BUILD_CHAR(attr, attr, win->color);
	  }
	color = map_attr_to_object (attr);
     }

   is_acs = attr & A_ALTCHARSET;

   if (SLwchar_iscntrl((SLwchar_Type)ch))
     {
	if (ch == '\n')
	  {
	     SLcurses_wclrtoeol (win);
	     return do_newline (win);
	  }

	if (ch == '\r')
	  {
	     win->_curx = 0;
	     return 0;
	  }

	if (ch == '\b')
	  {
	     if (win->_curx > 0)
	       win->_curx--;

	     return 0;
	  }

	if (ch == '\t')
	  {
	     int err;
	     do
	       err = SLcurses_waddch (win, (SLtt_Char_Type)' ');
	     while (err == 0 && win->_curx % SLsmg_Tab_Width != 0);
	     return err;
	  }
     }

   width = SLwchar_isprint (ch)
	? (SLsmg_is_utf8_mode ()
		? SLwchar_wcwidth (ch)
		: 1)
	: 0;
   if (win->_curx + width > win->ncols)
     {
	SLcurses_wclrtoeol (win);
	do_newline (win);
     }

   SLcurses_placechar (win, ch, width, color, is_acs);
   win->_curx += width;

   return 0;
}
Exemple #3
0
/* Note: if len is < 0, entire string will be used.
 */
int SLcurses_waddnstr (SLcurses_Window_Type *w, char *str, int len)
{
   unsigned int nrows, ncols, crow, ccol;
   SLuchar_Type *u, *umax;
   int is_acs = 0;

   if ((w == NULL)
       || (str == NULL))
     return -1;

   w->modified = 1;
   nrows = w->nrows;
   ncols = w->ncols;
   crow = w->_cury;
   ccol = w->_curx;

   if (w->scroll_max <= nrows)
     nrows = w->scroll_max;

   if (crow >= nrows)
     crow = 0;			       /* wrap back to top */

   u = (SLuchar_Type *)str;
   umax = &u[len >= 0 ? (unsigned int)len : strlen(str)];
   while (u < umax)
     {
	SLwchar_Type ch;
	unsigned int nconsumed;
	int width = 1;

	if (SLsmg_is_utf8_mode () && SLutf8_decode (u, umax, &ch, &nconsumed))
	  {
	     u += nconsumed;
	     if ((ch & A_CHARTEXT) != ch)
	       {
		  ch = (SLwchar_Type)0xFFFDL;	/* Unicode replacement character */
		  width = 1;
	       }
	     else if (SLwchar_isprint (ch))
	       width = SLwchar_wcwidth (ch);
	     else
	       width = 0;	/* FIXME: cope with <%02X> printstrings. */
	  }
	else
	  {
	     ch = (SLwchar_Type)*u++;
	     if (ch < 0x20 || (ch >= 0x7f && ch < 0xa0))
	       width = 0;	/* FIXME: use display_8bit */
	  }
	if (ch == '\t')
	  width = 1;	/* HACK forcing linewrap if ccol==ncols */
	if (ch == 0)
	  continue;	/* Avoid adding a literal SLCURSES_NULLCHAR. */

	/* FIXME; should this function be defined in terms of waddch? */
	if (ch == '\n')
	  {
	     w->_cury = crow;
	     w->_curx = ccol;
	     SLcurses_wclrtoeol (w);
	     do_newline (w);
	     crow = w->_cury;
	     ccol = w->_curx;
	     continue;
	  }

	if (ccol + width > ncols)
	  {
	     w->_curx = ccol;
	     w->_cury = crow;
	     SLcurses_wclrtoeol(w);	/* no-op if width<=1 */
	     w->_curx = ccol = 0;
	     w->_cury = ++crow;
	     if (crow >= nrows)
	       {
		  do_newline (w);
		  crow = w->_cury;
		  ccol = w->_curx;
	       }
	  }

	if (ch == '\t')
	  {
	     /* assert (ccol < ncols); */
	     w->_curx = ccol;
	     w->_cury = crow;
	     do
	       {
		  SLcurses_placechar (w, (SLwchar_Type)' ', 1, w->color, is_acs);
		  w->_curx = ++ccol;
	       }
	     while (ccol < ncols && ccol % SLsmg_Tab_Width != 0);
	     continue;
	  }

	SLcurses_placechar (w, ch, width, w->color, is_acs);
	w->_curx = (ccol += width);
     }

   w->_curx = ccol;
   w->_cury = crow;

   return 0;
}
void SLsmg_write_wrapped_string (SLuchar_Type *u, int r, int c,
				 unsigned int dr, unsigned int dc,
				 int fill)
{
   int maxc = (int) dc;
   unsigned char *p, *pmax;
   int utf8_mode = UTF8_Mode;
   unsigned char display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;

   if (utf8_mode)
     display_8bit = 0xA0;

   if ((dr == 0) || (dc == 0)) return;
   if (u == NULL)
     u = (unsigned char *)"";

   p = u;
   pmax = u + strlen ((char *)u);
   
   dc = 0;
   while (1)
     {
	SLwchar_Type wc;
	unsigned int nconsumed;
	unsigned char ch = *p;
	unsigned int ddc;

	if ((ch == 0) || (ch == '\n'))
	  {
	     int diff;

	     diff = maxc - (int) dc;

	     SLsmg_gotorc (r, c);
	     SLsmg_write_chars (u, p);
	     if (fill && (diff > 0))
	       {
		  unsigned char *blank = (unsigned char *)" ";
		  while (diff--) SLsmg_write_chars (blank, blank+1);
	       }
	     if ((ch == 0) || (dr == 1)) break;

	     r++;
	     dc = 0;
	     dr--;
	     p++;
	     u = p;
	     continue;
	  }

	/* If the width of the characters buffered so far extend to or beyond
	 * the width of the box, then write them out and goto the
	 * next line. Note that dc > maxc if the displayable width of
	 * the last character to be written is greater than the width
	 * of the box.  This will be the case if (maxc<ddc) -- see below
	 */
	if ((int) dc >= maxc)
	  goto write_chars_and_reset;

	nconsumed = 1;
	if (ch < 0x80)
	  {
	     p++;
	     if ((ch >= 0x20) && (ch != 0x7F))
	       {
		  dc++;
		  continue;
	       }
	     /* Otherwise display as ^X */
	     dc += 2;
	     continue;
	  }

	nconsumed = 1;
	if ((utf8_mode == 0)
	    || (NULL == SLutf8_decode (p, pmax, &wc, &nconsumed)))
	  {	     
	     if ((utf8_mode == 0)
		 && (display_8bit && (*p >= display_8bit)))
	       {
		  dc++;
		  p += nconsumed;
		  continue;
	       }

	     ddc = 4*nconsumed;      /* <XX> */
	  }
	else if (wc < (SLwchar_Type)display_8bit)
	  ddc = 4;		       /* displays as <XX> */
	else
	  ddc = SLwchar_wcwidth (wc);

	dc += ddc;
	if (((int)dc > maxc) && (maxc > (int)ddc))
	  {
	     dc -= ddc;
	     goto write_chars_and_reset;
	  }
	p += nconsumed;
	continue;

	write_chars_and_reset:	
	SLsmg_gotorc (r, c);
	SLsmg_write_chars (u, p);
	while ((int)dc < maxc)
	  {
	     SLsmg_write_char (' ');
	     dc++;
	  }
	if (dr == 1) break;
	r++;
	dc = 0;
	dr--;
	u = p;
     }
}
Exemple #5
0
int SLcurses_winsch (SLcurses_Window_Type *w, int ch)
{
   int is_acs = 0;
   int colsneeded;
#ifndef HAVE_MEMMOVE
   int dest, src;
#endif
   SLcurses_Cell_Type *line = w->lines[w->_cury];

   /* Backtrack to start of this character. */
   while (w->_curx > 0 && line[w->_curx].main == SLCURSES_NULLATTR)
     w->_curx--;

   if (ch == (SLcurses_Char_Type)'\t')
     ch = ' ';	/* FIXME */

   if (SLwchar_isprint (ch))
     {
	if (SLsmg_is_utf8_mode ())
	  colsneeded = SLwchar_wcwidth (ch);
	else
	  colsneeded = 1;
     }
   else colsneeded = 0;

   if (colsneeded == 0)
     {
	int x, i;
	SLcurses_Cell_Type *b = NULL;
	/* Back one character. */
	for (x = w->_curx - 1; x >= 0; x--)
	  {
	     b = &line[x];
	     if (b->main != SLCURSES_NULLATTR)
	       break;
	  }
	if (x < 0)
	  {	/* Back to end of previous line. */
	     if (w->_cury == 0)
	       return (-1);
	     line = w->lines[w->_cury - 1];
	     for (x = w->ncols - 1; x >= 0; x--)
	       {
		  b = &line[x];
		  if (b->main != SLCURSES_NULLATTR)
		    break;
	       }
	     if (x < 0)
	       return (-1);
	  }
	/* b is previous character; insert combining character ch in *b. */
	for (i = 0; i < SLSMG_MAX_CHARS_PER_CELL-1; i++)
	  if (b->combining[i] == SLCURSES_NULLCHAR)
	    break;
	if (i < SLSMG_MAX_CHARS_PER_CELL-1)
	  b->combining[i] = ch;
	return 0;
     }

   /* Remove trailing character(s) from line. */
   if ((colsneeded > 0) && ((unsigned int)colsneeded <= w->ncols))
     {
	int i;
	for (i = w->ncols - colsneeded; i > 0; i--)
	  if (line[i].main != SLCURSES_NULLATTR)
	    break;
	/* line[w->ncols-colsneeded..w->ncols-1] will be shifted off the end,
	 * but if i < w->ncols-colsneeded, then line[i..w->ncols-colsneeded-1]
	 * must be blanked because they are part of a multicolumn character
	 * which is partially shifted off the end.
	 */
	while (i + colsneeded < (int)w->ncols)
	  SLCURSES_BUILD_CELL(&line[i++], ' ', w->color, is_acs);
     }

   /* line[_curx+colsneeded..ncols-1] = line[_curx..ncols-1-colsneeded]; */
#ifdef HAVE_MEMMOVE
   memmove(&line[w->_curx+colsneeded], &line[w->_curx], ncols-(w->_curx+colsneeded));
#else
   dest = w->ncols - 1;
   for (src = dest - colsneeded; src >= (int)w->_curx; src--, dest--)
     line[dest] = line[src];
#endif
   if (w->_curx + colsneeded <= w->ncols)
     SLcurses_placechar (w, ch, colsneeded, w->color, is_acs);

   w->modified = 1;
   return 0;
}
void SLsmg_write_chars (unsigned char *u, unsigned char *umax)
{
   SLsmg_Char_Type *p, *pmax;
   SLsmg_Color_Type color;
   int flags;
   int col, start_col, max_col;
   int newline_flag;
   int utf8_mode = UTF8_Mode;
   unsigned char display_8bit;
   int last_was_double_width = 0;
   int alt_char_set_flag;
   unsigned int i;
#if SLSMG_HAS_EMBEDDED_ESCAPE
   SLsmg_Color_Type default_color;
#endif
   if (Smg_Inited == 0) return;

   if (u >= umax)
     return;

   display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
   if (utf8_mode)
     display_8bit = 0xA0;

   color = This_Color;
   /* If we are using unicode characters for the line drawing characters, then
    * do not attempt to use the terminals alternate character set
    */
   alt_char_set_flag = (color & SLSMG_ACS_MASK);
   if (Current_ACS_Mode == ACS_MODE_UNICODE)
     color = color & ~SLSMG_ACS_MASK;
   
#if SLSMG_HAS_EMBEDDED_ESCAPE
   default_color = color;	       /* used for ESC[m */
#endif

   top:				       /* get here only on newline */

   newline_flag = 0;
   start_col = Start_Col;

   if (point_visible (0) == 0) return;

   col = This_Col;
   max_col = start_col + Screen_Cols;

   p = SL_Screen[This_Row - Start_Row].neew;
   pmax = p + Screen_Cols;

   if (col >= start_col)
     {
	p += (col - start_col);
	if ((p < pmax) && (p->nchars == 0))
	  {
	     /* It looks like we are about to overwrite the right side of a 
	      * double width character.  Let's see...
	      */
	     if (col > start_col)
	       {
		  p--;
		  if (p->nchars != 0)
		    {
		       p->nchars = 1;
		       p->wchars[0] = ' ';
		    }
		  p++;
	       }
	  }
     }
   
   
   flags = SL_Screen[This_Row - Start_Row].flags;
   i = 0;
   
   while (u < umax)
     {
	SLwchar_Type wc;
	unsigned int width, nconsumed;

     	if (*u < (SLuchar_Type) 0x80)		       /* ASCII */
	  {
	     unsigned char ch;

	     ch = (unsigned char) *u++;

	     if (alt_char_set_flag)
	       {
		  wc = ACS_Map[ch];
		  ADD_CHAR_OR_BREAK(wc);
		  continue;
	       }

	     if ((ch >= (SLuchar_Type)0x20) && (ch < (SLuchar_Type)0x7F))
	       {
		  ADD_CHAR_OR_BREAK(ch);
		  continue;
	       }
	     
	     if ((ch == '\t') && (SLsmg_Tab_Width > 0))
	       {
		  do
		    {
		       if (col < start_col)
			 col++;
		       else
			 {
			    ADD_CHAR_OR_BREAK(' ');
			    NEXT_CHAR_CELL;
			 }
		    }
		  while (col % SLsmg_Tab_Width);
		  continue;
	       }
	     
	     if ((ch == '\n')
		 && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
	       {
		  newline_flag = 1;
		  break;
	       }
	     
	     if ((ch == 0x8) && SLsmg_Backspace_Moves)
	       {
		  if (col != 0) 
		    {
		       if (i != 0) 
			 {
			    NEXT_CHAR_CELL;
			    col--;
			    p--;
			 }
		       col--;
		       p--;
		    }
		  continue;
	       }
#if SLSMG_HAS_EMBEDDED_ESCAPE
	     if ((ch == 033) && Embedded_Escape_Mode)
	       {
		  SLsmg_Color_Type next_color;

		  if (0 == parse_embedded_escape (u, umax, default_color, &u, &next_color))
		    {
		       if (i != 0)
			 NEXT_CHAR_CELL;
		       color = next_color;
		       continue;
		    }
	       }
#endif
	     ADD_CHAR_OR_BREAK('^');
	     if (ch == 127) ch = '?'; else ch = ch + '@';
	     ADD_CHAR_OR_BREAK (ch);
	     continue;
	  }

	nconsumed = 1;
	if ((utf8_mode == 0)
	    || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
	  {
	     unsigned int ii, jj;
	     unsigned char hexbuf[8];
	     
	     if ((utf8_mode == 0) 
		 && display_8bit && (*u >= display_8bit))
	       {
		  ADD_CHAR_OR_BREAK(*u);
	       }
	     else for (ii = 0; ii < nconsumed; ii++)
	       {
		  sprintf ((char *)hexbuf, "<%02X>", u[ii]);
		  for (jj = 0; jj < 4; jj++)
		    {
		       ADD_CHAR_OR_BREAK (hexbuf[jj]);
		    }
	       }
	     u += nconsumed;
	     continue;
	  }

	u += nconsumed;
	if (wc < (SLwchar_Type)display_8bit)
	  {
	     unsigned char hexbuf[8];
	     unsigned int jj;

	     sprintf ((char *)hexbuf, "<%02X>", (unsigned char) wc);
	     for (jj = 0; jj < 4; jj++)
	       {
		  ADD_CHAR_OR_BREAK (hexbuf[jj]);
	       }
	     continue;
	  }

	width = SLwchar_wcwidth (wc);
	if (width == 0)
	  {
	     /* Combining character--- must follow non-zero width char */
	     if (i == 0)
	       continue;
	     if (i < SLSMG_MAX_CHARS_PER_CELL)
	       {
		  ADD_TO_CHAR_CELL (wc);
	       }
	     continue;
	  }

	if (width == 2)
	  {
	     if (col + 2 <= start_col)
	       {
		  col += 2;
		  continue;
	       }

	     if (col + 1 == start_col)
	       {
		  /* double width character is clipped at left part of screen.
		   * So, display right edge as a space 
		   */
		  col++;	       /* left edge */
		  ADD_CHAR_OR_BREAK('<');
		  continue;
	       }
	     
	     if (i != 0) 	       /* finish active cell */
	       NEXT_CHAR_CELL;

	     if (last_was_double_width)
	       {
		  /* and right half of the cell */
		  last_was_double_width = 0;
		  NEXT_CHAR_CELL;
	       }

	     if (col + 2 > max_col)
	       {
		  /* right side of character gets clipped */
		  ADD_TO_CHAR_CELL('>');
		  col++;
		  break;
	       }
	     ADD_CHAR_OR_BREAK(wc);
	     last_was_double_width = 1;
	     continue;
	  }

	ADD_CHAR_OR_BREAK(wc);
     }
   
   if (i != 0)
     {
	NEXT_CHAR_CELL;
     }

   if (last_was_double_width)
     {
	if (col < max_col)
	  NEXT_CHAR_CELL;
	last_was_double_width = 0;
     }
   else if ((col < max_col) && (p->nchars == 0))
     {
	/* The left side of a double with character was overwritten */
	p->nchars = 1;
	p->wchars[0] = ' ';
     }
   SL_Screen[This_Row - Start_Row].flags = flags;
   This_Col = col;

   /* Why would u be NULL here?? */

   if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_IGNORED)
     {
#if SLSMG_HAS_EMBEDDED_ESCAPE
	if (Embedded_Escape_Mode && (u != NULL))
	  parse_embedded_set_color (u, umax, default_color);
#endif
	return;
     }

   if (newline_flag == 0)
     {
#if SLSMG_HAS_EMBEDDED_ESCAPE
	SLuchar_Type *usave = u;
#endif
	if (u == NULL)
	  return;

	while (u < umax)
	  {
	     if (*u == '\n') break;
	     u++;
	  }
	if (u >= umax)
	  {
#if SLSMG_HAS_EMBEDDED_ESCAPE
	     if (Embedded_Escape_Mode)
	       parse_embedded_set_color (usave, umax, default_color);
#endif
	     return;
	  }
	u++;
     }

   This_Row++;
   This_Col = 0;
   if (This_Row == Start_Row + (int)Screen_Rows)
     {
	if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_SCROLLS) scroll_up ();
     }
   goto top;
}
static void init_acs (int mode)
{
   unsigned int i;
   SLCONST ACS_Def_Type *acs;

   if (Current_ACS_Mode == mode)
     return;

   for (i = 0; i < 0x80; i++)
     ACS_Map[i] = ' ';

   if (mode == ACS_MODE_AUTO)
     {
	if (UTF8_Mode && 
	    (tt_unicode_ok != NULL) && (*tt_unicode_ok > 0))
	  mode = ACS_MODE_UNICODE;
	else
	  mode = ACS_MODE_TERMINFO;
     }

   switch (mode)
     {
      case ACS_MODE_UNICODE:
	SLsmg_Display_Eight_Bit = 0xA0;
	acs = UTF8_ACS_Map;
	while (acs->vt100_char != 0)
	  {
	     SLwchar_Type wch = acs->unicode;
	     if (SLwchar_wcwidth (wch) != 1)
	       wch = acs->unicode_narrow;
	     ACS_Map[acs->vt100_char] = wch;
	     acs++;
	  }
	break;
	
      case ACS_MODE_TERMINFO:
	if ((tt_Has_Alt_Charset != NULL)
	    && *tt_Has_Alt_Charset
	    && (tt_Graphics_Char_Pairs != NULL)
	    && (*tt_Graphics_Char_Pairs != NULL))
	  {
	     unsigned char *p = (unsigned char *) *tt_Graphics_Char_Pairs;
	     unsigned char *pmax = p + strlen ((char *) p);
	     
	     while (p < pmax)
	       {
		  unsigned char ch = *p++;
		  ACS_Map[ch & 0x7F] = *p++;
	       }
	     break;
	  }
	mode = ACS_MODE_ASCII;
	/* drop */
      case ACS_MODE_ASCII:
      default:
	acs = UTF8_ACS_Map;
	while (acs->vt100_char != 0)
	  {
	     ACS_Map[acs->vt100_char] = acs->ascii;
	     acs++;
	  }
	break;
     }

   Current_ACS_Mode = mode;
}
/* If the string u were written at the current positition, this function 
 * returns the number of bytes necessary to reach the specified width.
 */
unsigned int SLsmg_strbytes (SLuchar_Type *u, SLuchar_Type *umax, unsigned int width)
{
   SLuchar_Type *ustart;
   unsigned char display_8bit;
   int utf8_mode = UTF8_Mode;
   int col, col_max;

   if (u == NULL)
     return 0;

   display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
   if (utf8_mode)
     display_8bit = 0xA0;

   col = This_Col;
   col_max = col + width;
   ustart = u;

   while (u < umax)
     {
	SLuchar_Type ch;
	SLwchar_Type wc;
	unsigned int nconsumed = 1;

	ch = *u;
	if (ch < 0x80)
	  {
	     if ((ch >= 0x20) && (ch != 0x7F))
	       col++;
	     else if ((ch == '\t') && (SLsmg_Tab_Width > 0))
	       {
		  if (col >= 0)
		    col = (1 + col/SLsmg_Tab_Width) * SLsmg_Tab_Width;
		  else
		    col = ((col + 1)/SLsmg_Tab_Width) * SLsmg_Tab_Width;
	       }
	     else if ((ch == '\n')
		      && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
	       break;
	     else if ((ch == 0x8) && SLsmg_Backspace_Moves)
	       col--;
#if SLSMG_HAS_EMBEDDED_ESCAPE
	     else if ((ch == 033) && Embedded_Escape_Mode)
	       {
		  SLsmg_Color_Type color;
		  SLuchar_Type *u1 = u+1;
		  if (-1 == parse_embedded_escape (u1, umax, 0, &u1, &color))
		    col += 2;
		  nconsumed = (u1 - u);
	       }
#endif
	     else col += 2;
	  }
	else if ((utf8_mode == 0)
		 || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
	  {
	     if ((utf8_mode == 0)
		 && (display_8bit && (*u >= display_8bit)))
	       col++;
	     else
	       col += 4*nconsumed;     /* <XX> */
	  }
	else if (wc < (SLwchar_Type)display_8bit)
	  col += 4;
	else col += SLwchar_wcwidth (wc);
	
	if (col >= col_max)
	  break;
	
	u += nconsumed;
     }

   return (unsigned int) (u - ustart);
}
Exemple #9
0
SLuchar_Type *SLutf8_bskip_chars (SLuchar_Type *smin, SLuchar_Type *s,
				   unsigned int num, unsigned int *dnum,
				   int ignore_combining)
{
   unsigned int n;
   SLuchar_Type *smax = s;

   n = 0;
   while ((n < num) && (s > smin))
     {
	unsigned char ch;
	unsigned int dn;

	s--;
	ch = *s;
	if (ch < 0x80)
	  {
	     n++;
	     smax = s;
	     continue;
	  }
	
	dn = 0;
	while ((s != smin) 
	       && (Len_Map[ch] == 0)
	       && (dn < SLUTF8_MAX_MBLEN))
	  {
	     s--;
	     ch = *s;
	     dn++;
	  }

	if (ch <= 0xBF)
	  {
	     /* Invalid sequence */
	     n++;
	     smax--;
	     s = smax;
	     continue;
	  }

	if (ch > 0xBF)
	  {
	     SLwchar_Type w;
	     SLuchar_Type *s1;

	     if ((NULL == (s1 = SLutf8_decode (s, smax, &w, NULL)))
		 || (s1 != smax))
	       {
		  /* This means we backed up over an invalid sequence */
		  dn = (unsigned int) (smax - s);
		  n++;
		  smax--;
		  s = smax;
		  continue;
	       }
	     
	     if ((ignore_combining == 0) 
		 || (0 != SLwchar_wcwidth (w)))
	       n++;

	     smax = s;
	  }
     }

   if (dnum != NULL)
     *dnum = n;
   return s;
}
Exemple #10
0
SLuchar_Type *SLutf8_skip_chars (SLuchar_Type *s, SLuchar_Type *smax,
				  unsigned int num, unsigned int *dnum,
				  int ignore_combining)
{
   unsigned int n;

   n = 0;
   while ((n < num) && (s < smax))
     {
	unsigned int len = Len_Map[*s];

	if (len <= 1)
	  {
	     n++;
	     s++;
	     continue;
	  }

	if (s + len > smax)
	  {
	     s++;
	     n++;
	     continue;
	  }

	if (is_invalid_or_overlong_utf8 (s, len))
	  {
	     s++;
	     n++;
	     continue;
	  }
	
	if (ignore_combining)
	  {
	     SLwchar_Type w = fast_utf8_decode (s, len);
	     if (0 != SLwchar_wcwidth (w))
	       n++;
	     s += len;
	     continue;
	  }

	n++;
	s += len;
     }

   if (ignore_combining)
     {
	while (s < smax)
	  {
	     SLwchar_Type w;
	     unsigned int nconsumed;
	     if (NULL == SLutf8_decode (s, smax, &w, &nconsumed))
	       break;
	     
	     if (0 != SLwchar_wcwidth (w))
	       break;
	     
	     s += nconsumed;
	  }
     }

   if (dnum != NULL)
     *dnum = n;
   return s;
}