Changeset 84027015


Ignore:
Timestamp:
Jan 17, 2008, 1:23:53 AM (16 years ago)
Author:
Alejandro R. Sedeño <asedeno@mit.edu>
Branches:
master, barnowl_perlaim, debian, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
b2c1bd4
Parents:
a8d5a39
Message:
editwin.c - lots of utf-8 cleanup that I had been putting off.
util.c - a can we break here'' function based on perl's Text::WrapI18N
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • editwin.c

    re0ffe77 r84027015  
    351351int _owl_editwin_linewrap_word(owl_editwin *e)
    352352{
    353   int i, z;
    354 
    355   z = _owl_editwin_get_index_from_xy(e);
    356   /* move back and line wrap the previous word */
    357   for (i = z - 1; ; i--) {
    358     /* move back until you find a space or hit the beginning of the line */
    359     if (e->buff[i] == ' ') {
    360       /* replace the space with a newline */
    361       e->buff[i] = '\n';
    362       e->buffy++;
    363       e->buffx = z - i - 1;
    364       /* were we on the last line */
    365       return(0);
    366     } else if (e->buff[i] == '\n' || i <= e->lock) {
    367       /* we hit the beginning of the line or the buffer, we cannot
    368        * wrap.
    369        */
    370       return(-1);
    371     }
    372   }
     353  int x, y;
     354  int i;
     355  char *ptr1, *start;
     356  gunichar c;
     357
     358  /* saving values */
     359  x = e->buffx;
     360  y = e->buffy;
     361  start = e->buff + e->lock;
     362
     363  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     364  ptr1 = g_utf8_find_prev_char(start, ptr1);
     365
     366  while (ptr1) {
     367    c = g_utf8_get_char(ptr1);
     368    if (owl_util_can_break_after(c)) {
     369      if (c != ' ') {
     370        _owl_editwin_set_xy_by_index(e, ptr1 - e->buff);
     371        owl_editwin_key_right(e);
     372        /* _owl_editwin_insert_bytes may move e->buff. */
     373        i = ptr1 - e->buff;
     374        _owl_editwin_insert_bytes(e,1);
     375        ptr1 = e->buff + i;
     376      }
     377      *ptr1 = '\n';
     378      return 0;
     379    }
     380    ptr1 = g_utf8_find_prev_char(start, ptr1);
     381  }
     382  return -1;
    373383}
    374384
     
    642652}
    643653
     654/* We assume x,y are not set to point to a mid-char */
     655gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
     656{
     657  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
     658}
     659
     660
    644661void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
    645662{
     
    687704  int x, i;
    688705
     706  /* Find line */
    689707  ptr1 = e->buff;
    690708  ptr2 = strchr(ptr1, '\n');
     
    694712  }
    695713  ptr2 = ptr1;
     714
     715  /* Find char */
    696716  x = 0;
    697717  while (ptr2 != NULL && x < e->buffx) {
     
    701721    ptr2 = g_utf8_next_char(ptr2);
    702722  }
     723 
     724  /* calculate x offset */
    703725  return x - e->buffx;
    704726}
     
    805827void owl_editwin_move_to_nextword(owl_editwin *e)
    806828{
    807   /* asedeno: needs fixing for utf-8*/
    808829  int i, x;
     830  gunichar c = '\0';
    809831
    810832  /* if we're starting on a space, find the first non-space */
     
    819841  }
    820842
    821   /* find the next space, newline or end of line and go there, if
    822      already at the end of the line, continue on to the next */
    823   i=owl_editwin_get_numchars_on_line(e, e->buffy);
     843  /* find the next space, newline or end of line and go
     844     there, if already at the end of the line, continue on to the next */
     845  i=owl_editwin_get_numcells_on_line(e, e->buffy);
     846  c = _owl_editwin_get_char_at_xy(e);
    824847  if (e->buffx < i) {
    825848    /* move right till end of line */
    826849    while (e->buffx < i) {
    827       e->buffx++;
    828       if (e->buff[_owl_editwin_get_index_from_xy(e)]==' ') return;
     850      owl_editwin_key_right(e);
     851      c = _owl_editwin_get_char_at_xy(e);
     852      if (c == ' ') return;
    829853      if (e->buffx == i) return;
    830854    }
     
    832856    /* try to move down */
    833857    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    834       if (e->buffy+1 <  owl_editwin_get_numlines(e)) {
     858      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    835859        e->buffx=0;
    836860        e->buffy++;
     
    845869void owl_editwin_move_to_previousword(owl_editwin *e)
    846870{
    847   /* asedeno: needs fixing for utf-8*/
    848   int i, x;
     871  int i;
     872  gunichar c;
     873  char *ptr1, *ptr2;
    849874
    850875  /* are we already at the beginning of the word? */
    851   i=_owl_editwin_get_index_from_xy(e);
    852   if ( (e->buff[i]!=' ' && e->buff[i]!='\n' && e->buff[i]!='\0') &&
    853        (e->buff[i-1]==' ' || e->buff[i-1]=='\n') ) {
     876  c = _owl_editwin_get_char_at_xy(e);
     877  i = _owl_editwin_get_index_from_xy(e);
     878  ptr1 = e->buff + i;
     879  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
     880    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
     881    c = g_utf8_get_char(ptr1);
     882    if (c == ' ' || c == '\n') {
     883      owl_editwin_key_left(e);     
     884    }
     885  }
     886
     887  /* are we starting on a space character? */
     888  i = _owl_editwin_get_index_from_xy(e);
     889  while (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0') {
     890    /* find the first non-space */
     891    owl_editwin_key_left(e);     
     892    i = _owl_editwin_get_index_from_xy(e);
     893  }
     894
     895  /* find the last non-space */
     896  owl_editwin_key_left(e);
     897  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     898  while (ptr1 >= e->buff + e->lock) {
     899    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
     900    if (!ptr2) break;
     901   
     902    c = g_utf8_get_char(ptr2);
     903    if (c == ' ' || c == '\n'){
     904      break;
     905    }
    854906    owl_editwin_key_left(e);
    855   }
    856    
    857   /* are we starting on a space character? */
    858   i=_owl_editwin_get_index_from_xy(e);
    859   if (e->buff[i]==' ' || e->buff[i]=='\n' || e->buff[i]=='\0') {
    860     /* find the first non-space */
    861     for (x=i; x>=e->lock; x--) {
    862       if (e->buff[x]!=' ' && e->buff[x]!='\n' && e->buff[x]!='\0') {
    863         _owl_editwin_set_xy_by_index(e, x);
    864         break;
    865       }
    866     }
    867   }
    868 
    869   /* find the last non-space */
    870   i=_owl_editwin_get_index_from_xy(e);
    871   for (x=i; x>=e->lock; x--) {
    872     if (e->buff[x-1]==' ' || e->buff[x-1]=='\n') {
    873       _owl_editwin_set_xy_by_index(e, x);
    874       break;
    875     }
    876   }
    877   _owl_editwin_set_xy_by_index(e, x);
     907    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     908  }
    878909}
    879910
     
    881912void owl_editwin_delete_nextword(owl_editwin *e)
    882913{
    883   /* asedeno: needs fixing for utf-8*/
    884   int z;
     914  char *ptr1, *start;
     915  gunichar c;
    885916
    886917  if (e->bufflen==0) return;
    887918
    888   /* if we start out on a space character then gobble all the spaces
    889      up first */
    890   while (1) {
    891     z=_owl_editwin_get_index_from_xy(e);
    892     if (e->buff[z]==' ' || e->buff[z]=='\n') {
    893       owl_editwin_delete_char(e);
    894     } else {
    895       break;
    896     }
    897   }
    898 
    899   /* then nuke the next word */
    900   while (1) {
    901     z=_owl_editwin_get_index_from_xy(e);
    902     /* z == e->bufflen check added to prevent a hang I (nelhage) have
    903        seen repeatedly while using owl. I'm not sure precisely what
    904        conditions lead to it. */
    905     if (z == e->bufflen
    906         || e->buff[z+1]==' ' || e->buff[z+1]=='\n' || e->buff[z+1]=='\0') break;
    907     owl_editwin_delete_char(e);
    908   }
    909   owl_editwin_delete_char(e);
     919  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     920  /* if we start out on a space character then jump past all the
     921     spaces up first */
     922  while (*ptr1 == ' ' || *ptr1 == '\n') {
     923    ++ptr1;
     924  }
     925
     926  /* then jump past the next word */
     927 
     928  while (ptr1 && ptr1 - e->buff < e->bufflen) {
     929    c = g_utf8_get_char(ptr1);
     930    if (c == ' ' || c == '\n' || c == '\0') break;
     931    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     932  }
     933
     934  if (ptr1) { /* We broke on a space, */
     935    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     936    if (ptr1) { /* and there's a character after it, */
     937      /* nuke everything back to our starting point. */
     938      _owl_editwin_remove_bytes(e, ptr1 - start);
     939      return;
     940    }
     941  }
     942 
     943  /* If we get here, we ran out of string, drop what's left. */
     944  *start = '\0';
     945  e->bufflen = start - e->buff;
    910946}
    911947
    912948void owl_editwin_delete_previousword(owl_editwin *e)
    913949{
    914   /* asedeno: needs fixing for utf-8*/
    915950  /* go backwards to the last non-space character, then delete chars */
    916   int i, startpos, endpos;
     951  int startpos, endpos;
    917952
    918953  startpos = _owl_editwin_get_index_from_xy(e);
    919954  owl_editwin_move_to_previousword(e);
    920955  endpos = _owl_editwin_get_index_from_xy(e);
    921   for (i=0; i<startpos-endpos; i++) {
    922     owl_editwin_delete_char(e);
    923   }
     956  _owl_editwin_remove_bytes(e, startpos-endpos);
    924957}
    925958
    926959void owl_editwin_delete_to_endofline(owl_editwin *e)
    927960{
    928   /* asedeno: needs fixing for utf-8*/
    929961  int i;
    930962
     
    9871019void owl_editwin_fill_paragraph(owl_editwin *e)
    9881020{
    989   /* asedeno: needs fixing for utf-8*/
    9901021  int i, save;
    9911022
     
    10181049
    10191050    /* did we hit the end of a line too soon? */
     1051    /* asedeno: Here we replace a newline with a space. We may want to
     1052       consider removing the space if the characters to either side
     1053       are CJK ideograms.*/
    10201054    i = _owl_editwin_get_index_from_xy(e);
    10211055    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
     
    10311065      } else {
    10321066        owl_editwin_delete_char(e);
    1033         /* if we did this ahead of the save point, adjust it */
     1067        /* if we did this ahead of the save point, adjust it. Changing
     1068           by one is fine here because we're only removing an ASCII
     1069           space. */
    10341070        if (i < save) save--;
    10351071      }
  • util.c

    rc1522ec r84027015  
    832832}
    833833
     834/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
     835int owl_util_can_break_after(gunichar c)
     836{
     837 
     838  if (c == ' ') return 1;
     839  if (c >= 0x3000 && c <= 0x312f) {
     840    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
     841    if (c == 0x300a || c == 0x300c || c == 0x300e ||
     842        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
     843        c == 0x3018 || c == 0x301a)
     844      return 0;
     845    return 1;
     846  }
     847  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
     848  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
     849  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
     850  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
     851  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
     852  return 0;
     853}
     854
    834855/**************************************************************************/
    835856/************************* REGRESSION TESTS *******************************/
Note: See TracChangeset for help on using the changeset viewer.