Changeset fc2677b


Ignore:
Timestamp:
Jul 11, 2009, 1:14:35 PM (12 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
3e36085
Parents:
2da7348
git-author:
Nelson Elhage <nelhage@mit.edu> (07/07/09 22:49:45)
git-committer:
Nelson Elhage <nelhage@mit.edu> (07/11/09 13:14:35)
Message:
editwin: Clean up and fix owl_editwin_fill_paragraph

We now implement a two-pass algorithm, that first replaces all
whitespace with single spaces, and then goes through and inserts
newlines as necessary to fill words. The code is slightly longer, but
I think much cleaner.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • editwin.c

    r2da7348 rfc2677b  
    5959static char *oe_copy_buf(owl_editwin *e, char *buf, int len);
    6060static int oe_copy_region(owl_editwin *e);
     61static int oe_display_column(owl_editwin *e);
    6162
    6263#define INCR 4096
     
    587588}
    588589
    589 #if 0 /*XXX*/
    590590/* linewrap the word just before the cursor.
    591591 * returns 0 on success
    592592 * returns -1 if we could not wrap.
    593593 */
    594 static int _owl_editwin_linewrap_word(owl_editwin *e)
    595 {
    596   int i;
    597   char *ptr1, *start;
     594static void _owl_editwin_linewrap_word(owl_editwin *e)
     595{
     596  oe_excursion x;
    598597  gunichar c;
    599598
    600   start = e->buff + e->lock;
    601 
    602   ptr1 = e->buff + e->index;
    603   ptr1 = g_utf8_find_prev_char(start, ptr1);
    604 
    605   while (ptr1) {
    606     c = g_utf8_get_char(ptr1);
    607     if (owl_util_can_break_after(c)) {
    608       if (c != ' ') {
    609         i = ptr1 - e->buff;
    610         oe_set_index(e, i);
    611         _owl_editwin_insert_bytes(e, 1);
    612         /* _owl_editwin_insert_bytes may move e->buff. */
    613         ptr1 = e->buff + i;
    614       }
    615       *ptr1 = '\n';
    616       return 0;
    617     }
    618     else if (c == '\n') {
    619       return 0;
    620     }
    621     ptr1 = g_utf8_find_prev_char(start, ptr1);
    622   }
    623   return -1;
    624 }
    625 #endif
     599  oe_save_excursion(e, &x);
     600
     601  while (owl_editwin_point_move(e, -1)) {
     602    c = owl_editwin_get_char_at_point(e);
     603    if (owl_util_can_break_after(c) || c == '\n') {
     604      if (c != '\n')
     605        owl_editwin_replace(e, c != ' ' ? 0 : 1, "\n");
     606      break;
     607    }
     608  }
     609
     610  oe_restore_excursion(e, &x);
     611}
    626612
    627613/* delete the character at the current point, following chars
     
    10361022}
    10371023
     1024static int oe_display_column(owl_editwin *e)
     1025{
     1026  oe_excursion x;
     1027  int lineindex;
     1028
     1029  oe_save_excursion(e, &x);
     1030  owl_editwin_move_to_beginning_of_line(e);
     1031  lineindex = e->index;
     1032  oe_restore_excursion(e, &x);
     1033  return oe_region_width(e, lineindex, e->index, 0);
     1034}
     1035
    10381036void owl_editwin_fill_paragraph(owl_editwin *e)
    10391037{
    1040 #if 0 /* XXX */
    10411038  oe_excursion x;
    1042   int i, save;
    1043 
    1044   /* save our starting point */
     1039  gunichar ch;
     1040  int sentence;
     1041
    10451042  oe_save_excursion(e, &x);
    10461043
    1047   save = e->index;
    1048 
    1049   /* scan back to the beginning of this paragraph */
    1050   for (i=save; i>=e->lock; i--) {
    1051     if ( (i<=e->lock) ||
    1052          ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
    1053       oe_set_index(i + 1);
     1044  /* Mark the end of the paragraph */
     1045  owl_editwin_forward_paragraph(e);
     1046  /* Skip the trailing newline */
     1047  owl_editwin_point_move(e, -1);
     1048  owl_editwin_set_mark(e);
     1049
     1050  owl_editwin_backward_paragraph(e);
     1051
     1052  /* Don't mess with the leading newline */
     1053  if (owl_editwin_get_char_at_point(e) == '\n')
     1054    owl_editwin_point_move(e, 1);
     1055
     1056  /*
     1057   * First pass: Scan forward replacing all series of spaces with ' '
     1058   * (or nothing after CJK ideograms)
     1059   */
     1060  sentence = 0;
     1061  for(;e->index < e->mark; owl_editwin_point_move(e, 1)) {
     1062    /* bail if we hit a trailing dot on the buffer */
     1063    if (strcmp(e->buff + e->index, "\n.") == 0) {
     1064      owl_editwin_set_mark(e);
    10541065      break;
    10551066    }
    1056   }
    1057 
    1058   /* main loop */
    1059   while (1) {
    1060     i = _owl_editwin_get_index_from_xy(e);
    1061 
    1062     /* bail if we hit the end of the buffer */
    1063     if (i >= e->bufflen || e->buff[i] == '\0') break;
    1064 
    1065     /* bail if we hit the end of the paragraph */
    1066     if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
    1067 
    1068     /* bail if we hit a trailing dot on the buffer */
    1069     if (e->buff[i] == '\n' && e->buff[i+1] == '.'
    1070         && ((i+2) >= e->bufflen || e->buff[i+2] == '\0'))
    1071       break;
    1072 
     1067
     1068    ch = owl_editwin_get_char_at_point(e);
     1069
     1070    if (owl_util_can_break_after(ch) || ch == '\n') {
     1071      if (g_unichar_isspace(ch)) {
     1072        owl_editwin_replace(e, 1, " ");
     1073      }
     1074
     1075      if (sentence)
     1076        owl_editwin_point_move(e, 1);
     1077
     1078      while(g_unichar_isspace(owl_editwin_get_char_at_point(e))
     1079            && e->index < e->mark) {
     1080        owl_editwin_delete_char(e);
     1081      }
     1082    }
     1083
     1084    if(ch == '.' || ch == '!' || ch == '?')
     1085      sentence = 1;
     1086    else
     1087      sentence = 0;
     1088  }
     1089
     1090  owl_editwin_backward_paragraph(e);
     1091
     1092  /* Now go through inserting newlines as needed */
     1093  while(e->index < e->mark) {
    10731094    /* if we've travelled too far, linewrap */
    1074     if ((e->buffx) >= e->fillcol) {
    1075       int len = e->bufflen;
     1095    if (oe_display_column(e) >= e->fillcol)
    10761096      _owl_editwin_linewrap_word(e);
    1077       /* we may have added a character. */
    1078       if (i < save) save += e->bufflen - len;
    1079       oe_set_index(i);
    1080     }
    1081 
    1082     /* did we hit the end of a line too soon? */
    1083     /* asedeno: Here we replace a newline with a space. We may want to
    1084        consider removing the space if the characters to either side
    1085        are CJK ideograms.*/
    1086     i = _owl_editwin_get_index_from_xy(e);
    1087     if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
    1088       /* ********* we need to make sure we don't pull in a word that's too long ***********/
    1089       e->buff[i]=' ';
    1090     }
    1091 
    1092     /* fix spacing */
    1093     i = _owl_editwin_get_index_from_xy(e);
    1094     if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
    1095       if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
    1096         owl_editwin_key_right(e);
    1097       } else {
    1098         owl_editwin_delete_char(e);
    1099         /* if we did this ahead of the save point, adjust it. Changing
    1100            by one is fine here because we're only removing an ASCII
    1101            space. */
    1102         if (i < save) save--;
    1103       }
    1104     } else {
    1105       owl_editwin_key_right(e);
    1106     }
    1107   }
    1108 
    1109   /* put cursor back at starting point */
     1097    owl_editwin_point_move(e, 1);
     1098  }
     1099
    11101100  oe_restore_excursion(e, &x);
    1111 #endif
    11121101}
    11131102
Note: See TracChangeset for help on using the changeset viewer.