Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSv. Lockal <lockalsash@gmail.com>2012-01-16 20:23:25 +0400
committerSv. Lockal <lockalsash@gmail.com>2012-01-16 20:23:25 +0400
commitc150d0084f0e1cf86f063d993b31d02fc3e9c71f (patch)
tree851acfa580b5c463e6df632a77e30d4a47ea1dc1 /source/blender/blenkernel/intern/text.c
parentae9582836e047b1da87f8178e34ad63ed0b9824e (diff)
patch [#29859] UTF-8 support for text editor.
This also fixes cursor movement in the beginning of line and adds do_versions block for converting text files with old extended ascii encoding into UTF-8.
Diffstat (limited to 'source/blender/blenkernel/intern/text.c')
-rw-r--r--source/blender/blenkernel/intern/text.c801
1 files changed, 500 insertions, 301 deletions
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 7e102bc9854..bc86a53c35e 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -33,6 +33,8 @@
#include <string.h> /* strstr */
#include <sys/types.h>
#include <sys/stat.h>
+#include <wchar.h>
+#include <wctype.h>
#include "MEM_guardedalloc.h"
@@ -215,8 +217,48 @@ Text *add_empty_text(const char *name)
return ta;
}
+/* this function replaces extended ascii characters */
+/* to a valid utf-8 sequences */
+int txt_extended_ascii_as_utf8(char **str)
+{
+ int bad_char, added= 0, i= 0;
+ int length = strlen(*str);
+
+ while ((*str)[i]) {
+ if((bad_char= BLI_utf8_invalid_byte(*str+i, length)) == -1)
+ break;
+
+ added++;
+ i+= bad_char + 1;
+ }
+
+ if (added != 0) {
+ char *newstr = MEM_mallocN(length+added+1, "text_line");
+ int mi = 0;
+ i= 0;
+
+ while ((*str)[i]) {
+ if((bad_char= BLI_utf8_invalid_byte((*str)+i, length)) == -1) {
+ memcpy(newstr+mi, (*str)+i, length - i + 1);
+ break;
+ }
+
+ memcpy(newstr+mi, (*str)+i, bad_char);
+
+ BLI_str_utf8_from_unicode((*str)[i+bad_char], newstr+mi+bad_char);
+ i+= bad_char+1;
+ mi+= bad_char+2;
+ }
+ newstr[length+added] = '\0';
+ MEM_freeN(*str);
+ *str = newstr;
+ }
+
+ return added;
+}
+
// this function removes any control characters from
-// a textline
+// a textline and fixes invalid utf-8 sequences
static void cleanup_textline(TextLine * tl)
{
@@ -229,6 +271,7 @@ static void cleanup_textline(TextLine * tl)
i--;
}
}
+ tl->len+= txt_extended_ascii_as_utf8(&tl->line);
}
int reopen_text(Text *text)
@@ -689,16 +732,10 @@ static void txt_make_dirty (Text *text)
}
/* 0:whitespace, 1:punct, 2:alphanumeric */
-static short txt_char_type (char ch)
-{
- if (ch <= ' ') return 0; /* 32 */
- if (ch <= '/') return 1; /* 47 */
- if (ch <= '9') return 2; /* 57 */
- if (ch <= '@') return 1; /* 64 */
- if (ch <= 'Z') return 2; /* 90 */
- if (ch == '_') return 2; /* 95, dont delimit '_' */
- if (ch <= '`') return 1; /* 96 */
- if (ch <= 'z') return 2; /* 122 */
+static short txt_char_type(unsigned int ch)
+{
+ if (iswspace(ch)) return 0;
+ if (iswalpha(ch) || iswdigit(ch)) return 2;
return 1;
}
@@ -731,9 +768,42 @@ static void txt_curs_first (Text *text, TextLine **linep, int *charp)
}
}
-/****************************/
+/*****************************/
/* Cursor movement functions */
-/****************************/
+/*****************************/
+
+int txt_utf8_offset_to_index(char *str, int offset)
+{
+ int index= 0, pos= 0;
+ while (pos != offset) {
+ pos += BLI_str_utf8_size(str + pos);
+ index++;
+ }
+ return index;
+}
+
+int txt_utf8_index_to_offset(char *str, int index)
+{
+ int offset= 0, pos= 0;
+ while (pos != index) {
+ offset += BLI_str_utf8_size(str + offset);
+ pos++;
+ }
+ return offset;
+}
+
+/* returns the real number of characters in string */
+/* not the same as BLI_strlen_utf8, which returns length for wide characters */
+static int txt_utf8_len(const char *src)
+{
+ int len;
+
+ for (len=0; *src; len++) {
+ src += BLI_str_utf8_size(src);
+ }
+
+ return len;
+}
void txt_move_up(Text *text, short sel)
{
@@ -747,13 +817,13 @@ void txt_move_up(Text *text, short sel)
old= *charp;
if((*linep)->prev) {
+ int index = txt_utf8_offset_to_index((*linep)->line, *charp);
*linep= (*linep)->prev;
- if (*charp > (*linep)->len) {
- *charp= (*linep)->len;
- if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->next), old, txt_get_span(text->lines.first, *linep), (unsigned short) *charp);
- } else {
- if(!undoing) txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
- }
+ if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len;
+ else *charp= txt_utf8_index_to_offset((*linep)->line, index);
+
+ if(!undoing)
+ txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
} else {
txt_move_bol(text, sel);
}
@@ -773,12 +843,13 @@ void txt_move_down(Text *text, short sel)
old= *charp;
if((*linep)->next) {
+ int index = txt_utf8_offset_to_index((*linep)->line, *charp);
*linep= (*linep)->next;
- if (*charp > (*linep)->len) {
- *charp= (*linep)->len;
- if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->prev), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
- } else
- if(!undoing) txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
+ if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len;
+ else *charp= txt_utf8_index_to_offset((*linep)->line, index);
+
+ if(!undoing)
+ txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
} else {
txt_move_eol(text, sel);
}
@@ -790,7 +861,7 @@ void txt_move_left(Text *text, short sel)
{
TextLine **linep;
int *charp, oundoing= undoing;
- int tabsize = 1, i=0;
+ int tabsize= 0, i= 0;
if (!text) return;
if(sel) txt_curs_sel(text, &linep, &charp);
@@ -799,32 +870,36 @@ void txt_move_left(Text *text, short sel)
undoing= 1;
- // do nice left only if there are only spaces
- // TXT_TABSIZE hardcoded in DNA_text_types.h
- if (text->flags & TXT_TABSTOSPACES) {
- tabsize = TXT_TABSIZE;
-
- if (*charp < tabsize)
- tabsize = *charp;
- else {
- for (i=0;i<(*charp);i++)
+ if (*charp== 0) {
+ if ((*linep)->prev) {
+ txt_move_up(text, sel);
+ *charp= (*linep)->len;
+ }
+ }
+ else {
+ // do nice left only if there are only spaces
+ // TXT_TABSIZE hardcoded in DNA_text_types.h
+ if (text->flags & TXT_TABSTOSPACES) {
+ tabsize= (*charp < TXT_TABSIZE) ? *charp : TXT_TABSIZE;
+
+ for (i=0; i<(*charp); i++)
if ((*linep)->line[i] != ' ') {
- tabsize = 1;
+ tabsize= 0;
break;
}
+
// if in the middle of the space-tab
- if ((*charp) % tabsize != 0)
- tabsize = ((*charp) % tabsize);
+ if (tabsize && (*charp) % TXT_TABSIZE != 0)
+ tabsize= ((*charp) % TXT_TABSIZE);
}
- }
-
- if (*charp== 0) {
- if ((*linep)->prev) {
- txt_move_up(text, sel);
- *charp= (*linep)->len;
+
+ if (tabsize)
+ (*charp)-= tabsize;
+ else {
+ const char *prev= BLI_str_prev_char_utf8((*linep)->line + *charp);
+ *charp= prev - (*linep)->line;
}
}
- else (*charp)-= tabsize;
undoing= oundoing;
if(!undoing) txt_undo_add_op(text, sel?UNDO_SLEFT:UNDO_CLEFT);
@@ -835,8 +910,7 @@ void txt_move_left(Text *text, short sel)
void txt_move_right(Text *text, short sel)
{
TextLine **linep;
- int *charp, oundoing= undoing;
- int tabsize=1, i=0;
+ int *charp, oundoing= undoing, do_tab= 0, i;
if (!text) return;
if(sel) txt_curs_sel(text, &linep, &charp);
@@ -845,32 +919,33 @@ void txt_move_right(Text *text, short sel)
undoing= 1;
- // do nice right only if there are only spaces
- // spaces hardcoded in DNA_text_types.h
- if (text->flags & TXT_TABSTOSPACES) {
- tabsize = TXT_TABSIZE;
-
- if ((*charp) + tabsize > (*linep)->len)
- tabsize = 1;
- else {
- for (i=0;i<(*charp) + tabsize - ((*charp) % tabsize);i++)
- if ((*linep)->line[i] != ' ') {
- tabsize = 1;
- break;
- }
- // if in the middle of the space-tab
- tabsize -= (*charp) % tabsize;
- }
- }
-
if (*charp== (*linep)->len) {
if ((*linep)->next) {
txt_move_down(text, sel);
*charp= 0;
}
- } else {
- (*charp)+=tabsize;
+ }
+ else {
+ // do nice right only if there are only spaces
+ // spaces hardcoded in DNA_text_types.h
+ if (text->flags & TXT_TABSTOSPACES && (*linep)->line[*charp]== ' ') {
+ do_tab= 1;
+ for (i=0; i<*charp; i++)
+ if ((*linep)->line[i]!= ' ') {
+ do_tab= 0;
+ break;
+ }
+ }
+
+ if (do_tab) {
+ int tabsize= (*charp) % TXT_TABSIZE + 1;
+ for (i=*charp+1; (*linep)->line[i]==' ' && tabsize<TXT_TABSIZE; i++)
+ tabsize++;
+ (*charp)= i;
+ }
+ else (*charp)+= BLI_str_utf8_size((*linep)->line + *charp);
}
+
undoing= oundoing;
if(!undoing) txt_undo_add_op(text, sel?UNDO_SRIGHT:UNDO_CRIGHT);
@@ -896,9 +971,12 @@ void txt_jump_left(Text *text, short sel)
count= 0;
for (i=0; i<3; i++) {
if (count < 2) {
- while (*charp>0 && txt_char_type((*linep)->line[*charp-1])==i) {
- txt_move_left(text, sel);
- count++;
+ while (*charp>0) {
+ char *sym= BLI_str_prev_char_utf8((*linep)->line + *charp);
+ if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) {
+ txt_move_left(text, sel);
+ count++;
+ } else break;
}
}
}
@@ -927,9 +1005,12 @@ void txt_jump_right(Text *text, short sel)
count= 0;
for (i=0; i<3; i++) {
if (count < 2) {
- while (*charp<(*linep)->len && txt_char_type((*linep)->line[*charp])==i) {
- txt_move_right(text, sel);
- count++;
+ while (*charp<(*linep)->len) {
+ char *sym= (*linep)->line + *charp;
+ if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) {
+ txt_move_right(text, sel);
+ count++;
+ } else break;
}
}
}
@@ -1014,6 +1095,7 @@ void txt_move_toline (Text *text, unsigned int line, short sel)
txt_move_to(text, line, 0, sel);
}
+/* Moves to a certain byte in a line, not a certain utf8-character! */
void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel)
{
TextLine **linep, *oldl;
@@ -1396,42 +1478,45 @@ static void txt_shift_markers(Text *text, int lineno, int count)
void txt_insert_buf(Text *text, const char *in_buffer)
{
- int i=0, l=0, j, u, len, lineno= -1, count= 0;
+ int l=0, u, len, lineno= -1, count= 0;
+ size_t i=0, j;
TextLine *add;
+ char *buffer;
if (!text) return;
if (!in_buffer) return;
txt_delete_sel(text);
- if(!undoing) txt_undo_add_block (text, UNDO_IBLOCK, in_buffer);
+ len= strlen(in_buffer);
+ buffer= BLI_strdupn(in_buffer, len);
+ len+= txt_extended_ascii_as_utf8(&buffer);
+
+ if(!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer);
u= undoing;
undoing= 1;
/* Read the first line (or as close as possible */
- while (in_buffer[i] && in_buffer[i]!='\n') {
- txt_add_raw_char(text, in_buffer[i]);
- i++;
- }
+ while (buffer[i] && buffer[i]!='\n')
+ txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &i));
- if (in_buffer[i]=='\n') txt_split_curline(text);
- else { undoing = u; return; }
+ if (buffer[i]=='\n') txt_split_curline(text);
+ else { undoing = u; MEM_freeN(buffer); return; }
i++;
/* Read as many full lines as we can */
- len= strlen(in_buffer);
lineno= txt_get_span(text->lines.first, text->curl);
while (i<len) {
l=0;
- while (in_buffer[i] && in_buffer[i]!='\n') {
+ while (buffer[i] && buffer[i]!='\n') {
i++; l++;
}
- if(in_buffer[i]=='\n') {
- add= txt_new_linen(in_buffer +(i-l), l);
+ if(buffer[i]=='\n') {
+ add= txt_new_linen(buffer +(i-l), l);
BLI_insertlinkbefore(&text->lines, text->curl, add);
i++;
count++;
@@ -1441,21 +1526,19 @@ void txt_insert_buf(Text *text, const char *in_buffer)
count= 0;
}
- for (j= i-l; j<i && j<(int)strlen(in_buffer); j++) {
- txt_add_raw_char(text, in_buffer[j]);
- }
+ for (j= i-l; j<i && j<len; )
+ txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &j));
break;
}
}
+
+ MEM_freeN(buffer);
if(count) {
txt_shift_markers(text, lineno, count);
- count= 0;
}
undoing= u;
-
- (void)count;
}
/******************/
@@ -1525,12 +1608,30 @@ void txt_print_undo(Text *text)
ops= "Selection ";
} else if (op==UNDO_CTO) {
ops= "Cursor ";
- } else if (op==UNDO_INSERT) {
- ops= "Insert";
- } else if (op==UNDO_BS) {
- ops= "Backspace";
- } else if (op==UNDO_DEL) {
- ops= "Delete";
+ } else if (op==UNDO_INSERT_1) {
+ ops= "Insert ascii ";
+ } else if (op==UNDO_INSERT_2) {
+ ops= "Insert 2 bytes ";
+ } else if (op==UNDO_INSERT_3) {
+ ops= "Insert 3 bytes ";
+ } else if (op==UNDO_INSERT_4) {
+ ops= "Insert unicode ";
+ } else if (op==UNDO_BS_1) {
+ ops= "Backspace for ascii ";
+ } else if (op==UNDO_BS_2) {
+ ops= "Backspace for 2 bytes ";
+ } else if (op==UNDO_BS_3) {
+ ops= "Backspace for 3 bytes ";
+ } else if (op==UNDO_BS_4) {
+ ops= "Backspace for unicode ";
+ } else if (op==UNDO_DEL_1) {
+ ops= "Delete ascii ";
+ } else if (op==UNDO_DEL_2) {
+ ops= "Delete 2 bytes ";
+ } else if (op==UNDO_DEL_3) {
+ ops= "Delete 3 bytes ";
+ } else if (op==UNDO_DEL_4) {
+ ops= "Delete unicode ";
} else if (op==UNDO_SWAP) {
ops= "Cursor swap";
} else if (op==UNDO_DBLOCK) {
@@ -1550,10 +1651,35 @@ void txt_print_undo(Text *text)
}
printf ("Op (%o) at %d = %s", op, i, ops);
- if (op==UNDO_INSERT || op==UNDO_BS || op==UNDO_DEL) {
- i++;
- printf (" - Char is %c", text->undo_buf[i]);
+ if (op >= UNDO_INSERT_1 && op <= UNDO_DEL_4) {
i++;
+ printf (" - Char is ");
+ switch (op) {
+ case UNDO_INSERT_1: case UNDO_BS_1: case UNDO_DEL_1:
+ printf ("%c", text->undo_buf[i]);
+ i++;
+ break;
+ case UNDO_INSERT_2: case UNDO_BS_2: case UNDO_DEL_2:
+ printf ("%c%c", text->undo_buf[i], text->undo_buf[i+1]);
+ i+=2;
+ break;
+ case UNDO_INSERT_3: case UNDO_BS_3: case UNDO_DEL_3:
+ printf ("%c%c%c", text->undo_buf[i], text->undo_buf[i+1], text->undo_buf[i+2]);
+ i+=3;
+ break;
+ case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: {
+ unsigned int uc;
+ char c[BLI_UTF8_MAX+1];
+ size_t c_len;
+ uc= text->undo_buf[i]; i++;
+ uc= uc+(text->undo_buf[i]<<8); i++;
+ uc= uc+(text->undo_buf[i]<<16); i++;
+ uc= uc+(text->undo_buf[i]<<24); i++;
+ c_len= BLI_str_utf8_from_unicode(uc, c);
+ c[c_len]= '\0';
+ printf ("%s", c);
+ }
+ }
} else if (op==UNDO_STO || op==UNDO_CTO) {
i++;
@@ -1635,40 +1761,43 @@ static void txt_undo_add_op(Text *text, int op)
text->undo_buf[text->undo_pos+1]= 0;
}
+static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value)
+{
+ undo_buf[*undo_pos]= (value)&0xff;
+ (*undo_pos)++;
+ undo_buf[*undo_pos]= (value>>8)&0xff;
+ (*undo_pos)++;
+}
+
+static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int value)
+{
+ undo_buf[*undo_pos]= (value)&0xff;
+ (*undo_pos)++;
+ undo_buf[*undo_pos]= (value>>8)&0xff;
+ (*undo_pos)++;
+ undo_buf[*undo_pos]= (value>>16)&0xff;
+ (*undo_pos)++;
+ undo_buf[*undo_pos]= (value>>24)&0xff;
+ (*undo_pos)++;
+}
+
static void txt_undo_add_block(Text *text, int op, const char *buf)
{
- int length;
-
- length= strlen(buf);
+ unsigned int length= strlen(buf);
if(!max_undo_test(text, length+11))
return;
text->undo_pos++;
text->undo_buf[text->undo_pos]= op;
-
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>8)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>16)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>24)&0xff;
-
text->undo_pos++;
+
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
+
strncpy(text->undo_buf+text->undo_pos, buf, length);
text->undo_pos+=length;
- text->undo_buf[text->undo_pos]= (length)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>8)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>16)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (length>>24)&0xff;
-
- text->undo_pos++;
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
text->undo_buf[text->undo_pos]= op;
text->undo_buf[text->undo_pos+1]= 0;
@@ -1685,51 +1814,139 @@ void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fr
text->undo_buf[text->undo_pos]= op;
text->undo_pos++;
- text->undo_buf[text->undo_pos]= (fromc)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (fromc>>8)&0xff;
+
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml);
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol);
+
+ text->undo_buf[text->undo_pos]= op;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (froml)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (froml>>8)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (froml>>16)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (froml>>24)&0xff;
+ text->undo_buf[text->undo_pos+1]= 0;
+}
+static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
+{
+ char utf8[BLI_UTF8_MAX];
+ size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8);
+
+ if(!max_undo_test(text, 3 + utf8_size))
+ return;
+
text->undo_pos++;
- text->undo_buf[text->undo_pos]= (toc)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (toc>>8)&0xff;
+
+ if (utf8_size < 4) {
+ text->undo_buf[text->undo_pos]= op_start + utf8_size - 1;
+ text->undo_pos++;
+
+ for (i = 0; i < utf8_size; i++) {
+ text->undo_buf[text->undo_pos]= utf8[i];
+ text->undo_pos++;
+ }
+
+ text->undo_buf[text->undo_pos]= op_start + utf8_size - 1;
+ } else {
+ text->undo_buf[text->undo_pos]= op_start + 3;
+ text->undo_pos++;
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c);
+ text->undo_buf[text->undo_pos]= op_start + 3;
+ }
+
+ text->undo_buf[text->undo_pos+1]= 0;
+}
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (tol)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (tol>>8)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (tol>>16)&0xff;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= (tol>>24)&0xff;
+static unsigned short txt_undo_read_uint16(const char *undo_buf, int *undo_pos)
+{
+ unsigned short val;
+ val= undo_buf[*undo_pos]; (*undo_pos)--;
+ val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
+ return val;
+}
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= op;
+static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos)
+{
+ unsigned int val;
+ val= undo_buf[*undo_pos]; (*undo_pos)--;
+ val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
+ val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
+ val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--;
+ return val;
+}
- text->undo_buf[text->undo_pos+1]= 0;
+static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
+{
+ unsigned int unicode;
+ char utf8[BLI_UTF8_MAX+1];
+
+ switch (bytes) {
+ case 1: /* ascii */
+ unicode = undo_buf[*undo_pos]; (*undo_pos)--;
+ break;
+ case 2: /* 2-byte symbol */
+ utf8[2] = '\0';
+ utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--;
+ utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--;
+ unicode= BLI_str_utf8_as_unicode(utf8);
+ break;
+ case 3: /* 3-byte symbol */
+ utf8[3] = '\0';
+ utf8[2] = undo_buf[*undo_pos]; (*undo_pos)--;
+ utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--;
+ utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--;
+ unicode= BLI_str_utf8_as_unicode(utf8);
+ break;
+ case 4: /* 32-bit unicode symbol */
+ unicode= txt_undo_read_uint32(undo_buf, undo_pos);
+ }
+
+ return unicode;
}
-static void txt_undo_add_charop(Text *text, int op, char c)
+static unsigned short txt_redo_read_uint16(const char *undo_buf, int *undo_pos)
{
- if(!max_undo_test(text, 4))
- return;
+ unsigned short val;
+ val = undo_buf[*undo_pos]; (*undo_pos)++;
+ val = val+(undo_buf[*undo_pos]<<8); (*undo_pos)++;
+ return val;
+}
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= op;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= c;
- text->undo_pos++;
- text->undo_buf[text->undo_pos]= op;
- text->undo_buf[text->undo_pos+1]= 0;
+static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos)
+{
+ unsigned int val;
+ val= undo_buf[*undo_pos]; (*undo_pos)++;
+ val= val+(undo_buf[*undo_pos]<<8); (*undo_pos)++;
+ val= val+(undo_buf[*undo_pos]<<16); (*undo_pos)++;
+ val= val+(undo_buf[*undo_pos]<<24); (*undo_pos)++;
+ return val;
+}
+
+static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
+{
+ unsigned int unicode;
+ char utf8[BLI_UTF8_MAX+1];
+
+ switch (bytes) {
+ case 1: /* ascii */
+ unicode = undo_buf[*undo_pos]; (*undo_pos)++;
+ break;
+ case 2: /* 2-byte symbol */
+ utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++;
+ utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++;
+ utf8[2] = '\0';
+ unicode= BLI_str_utf8_as_unicode(utf8);
+ break;
+ case 3: /* 3-byte symbol */
+ utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++;
+ utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++;
+ utf8[2] = undo_buf[*undo_pos]; (*undo_pos)++;
+ utf8[3] = '\0';
+ unicode= BLI_str_utf8_as_unicode(utf8);
+ break;
+ case 4: /* 32-bit unicode symbol */
+ unicode= txt_undo_read_uint32(undo_buf, undo_pos);
+ }
+
+ return unicode;
}
void txt_do_undo(Text *text)
@@ -1792,13 +2009,8 @@ void txt_do_undo(Text *text)
text->undo_pos--;
text->undo_pos--;
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
-
- charp= text->undo_buf[text->undo_pos]; text->undo_pos--;
- charp= (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
+ charp= txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
if (op==UNDO_CTO) {
txt_move_toline(text, linep, 0);
@@ -1812,23 +2024,23 @@ void txt_do_undo(Text *text)
text->undo_pos--;
break;
- case UNDO_INSERT:
+ case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
txt_backspace_char(text);
- text->undo_pos--;
+ text->undo_pos-= op - UNDO_INSERT_1 + 1;
text->undo_pos--;
break;
- case UNDO_BS:
- txt_add_char(text, text->undo_buf[text->undo_pos]);
- text->undo_pos--;
+ case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
+ charp = op - UNDO_BS_1 + 1;
+ txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
text->undo_pos--;
- break;
-
- case UNDO_DEL:
- txt_add_char(text, text->undo_buf[text->undo_pos]);
+ break;
+
+ case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
+ charp = op - UNDO_DEL_1 + 1;
+ txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
txt_move_left(text, 0);
text->undo_pos--;
- text->undo_pos--;
break;
case UNDO_SWAP:
@@ -1836,10 +2048,7 @@ void txt_do_undo(Text *text)
break;
case UNDO_DBLOCK:
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
buf= MEM_mallocN(linep+1, "dblock buffer");
for (i=0; i < linep; i++){
@@ -1863,25 +2072,31 @@ void txt_do_undo(Text *text)
}
text->curc= holdc;
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ text->undo_pos--;
+ text->undo_pos--;
+ text->undo_pos--;
+ text->undo_pos--;
text->undo_pos--;
break;
case UNDO_IBLOCK:
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
-
+ linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
txt_delete_sel(text);
+
+ /* txt_backspace_char removes utf8-characters, not bytes */
+ buf= MEM_mallocN(linep+1, "iblock buffer");
+ for (i=0; i < linep; i++){
+ buf[(linep-1)-i]= text->undo_buf[text->undo_pos];
+ text->undo_pos--;
+ }
+ buf[i]= 0;
+ linep= txt_utf8_len(buf);
+ MEM_freeN(buf);
+
while (linep>0) {
txt_backspace_char(text);
- text->undo_pos--;
linep--;
}
@@ -1897,30 +2112,23 @@ void txt_do_undo(Text *text)
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
//linep is now the end line of the selection
- charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
- charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
//charp is the last char selected or text->line->len
- //set the selcetion for this now
+
+ //set the selection for this now
text->selc = charp;
text->sell = text->lines.first;
for (i= 0; i < linep; i++) {
text->sell = text->sell->next;
}
- linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
- linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
//first line to be selected
- charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
- charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
//first postion to be selected
text->curc = charp;
text->curl = text->lines.first;
@@ -2014,22 +2222,22 @@ void txt_do_redo(Text *text)
txt_move_down(text, 1);
break;
- case UNDO_INSERT:
- text->undo_pos++;
- txt_add_char(text, text->undo_buf[text->undo_pos]);
+ case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
text->undo_pos++;
+ charp = op - UNDO_INSERT_1 + 1;
+ txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp));
break;
- case UNDO_BS:
+ case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
text->undo_pos++;
txt_backspace_char(text);
- text->undo_pos++;
+ text->undo_pos+= op - UNDO_BS_1 + 1;
break;
- case UNDO_DEL:
+ case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
text->undo_pos++;
txt_delete_char(text);
- text->undo_pos++;
+ text->undo_pos+= op - UNDO_DEL_1 + 1;
break;
case UNDO_SWAP:
@@ -2049,15 +2257,8 @@ void txt_do_redo(Text *text)
text->undo_pos++;
- charp= text->undo_buf[text->undo_pos];
- text->undo_pos++;
- charp= charp+(text->undo_buf[text->undo_pos]<<8);
-
- text->undo_pos++;
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ charp= txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
+ linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
if (op==UNDO_CTO) {
txt_move_toline(text, linep, 0);
@@ -2072,12 +2273,9 @@ void txt_do_redo(Text *text)
case UNDO_DBLOCK:
text->undo_pos++;
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
-
+ linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
txt_delete_sel(text);
+
text->undo_pos+=linep;
text->undo_pos++;
@@ -2089,10 +2287,7 @@ void txt_do_redo(Text *text)
case UNDO_IBLOCK:
text->undo_pos++;
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
buf= MEM_mallocN(linep+1, "iblock buffer");
memcpy (buf, &text->undo_buf[text->undo_pos], linep);
@@ -2102,26 +2297,21 @@ void txt_do_redo(Text *text)
txt_insert_buf(text, buf);
MEM_freeN(buf);
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
- (void)linep;
-
+ text->undo_pos++;
+ text->undo_pos++;
+ text->undo_pos++;
+ text->undo_pos++;
break;
+
case UNDO_INDENT:
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
text->undo_pos++;
- charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
- charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
//charp is the first char selected or 0
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
//linep is now the first line of the selection
//set the selcetion for this now
text->curc = charp;
@@ -2130,13 +2320,10 @@ void txt_do_redo(Text *text)
text->curl = text->curl->next;
}
- charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
- charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
//last postion to be selected
- linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
- linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+
+ linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
//Last line to be selected
text->selc = charp;
@@ -2203,8 +2390,7 @@ void txt_split_curline (Text *text)
left[text->curc]=0;
right= MEM_mallocN(text->curl->len - text->curc+1, "textline_string");
- if (text->curl->len - text->curc) memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc);
- right[text->curl->len - text->curc]=0;
+ memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc+1);
MEM_freeN(text->curl->line);
if (text->curl->format) MEM_freeN(text->curl->format);
@@ -2228,7 +2414,7 @@ void txt_split_curline (Text *text)
txt_clean_text(text);
txt_pop_sel(text);
- if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, '\n');
+ if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n');
}
static void txt_delete_line (Text *text, TextLine *line)
@@ -2296,9 +2482,9 @@ static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
txt_clean_text(text);
}
-void txt_delete_char (Text *text)
+void txt_delete_char(Text *text)
{
- char c='\n';
+ unsigned int c='\n';
if (!text) return;
if (!text->curl) return;
@@ -2314,12 +2500,14 @@ void txt_delete_char (Text *text)
txt_pop_sel(text);
}
} else { /* Just deleting a char */
- int i= text->curc;
+ size_t c_len = 0;
+ TextMarker *mrk;
+ c= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len);
- TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0, 0);
+ mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
if (mrk) {
int lineno= mrk->lineno;
- if (mrk->end==i) {
+ if (mrk->end==text->curc) {
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
txt_clear_markers(text, mrk->group, TMARK_TEMP);
} else {
@@ -2328,18 +2516,15 @@ void txt_delete_char (Text *text)
return;
}
do {
- if (mrk->start>i) mrk->start--;
- mrk->end--;
+ if (mrk->start>text->curc) mrk->start-= c_len;
+ mrk->end-= c_len;
mrk= mrk->next;
} while (mrk && mrk->lineno==lineno);
}
- c= text->curl->line[i];
- while(i< text->curl->len) {
- text->curl->line[i]= text->curl->line[i+1];
- i++;
- }
- text->curl->len--;
+ memmove(text->curl->line+text->curc, text->curl->line+text->curc+c_len, text->curl->len-text->curc-c_len+1);
+
+ text->curl->len-= c_len;
txt_pop_sel(text);
}
@@ -2347,7 +2532,7 @@ void txt_delete_char (Text *text)
txt_make_dirty(text);
txt_clean_text(text);
- if(!undoing) txt_undo_add_charop(text, UNDO_DEL, c);
+ if(!undoing) txt_undo_add_charop(text, UNDO_DEL_1, c);
}
void txt_delete_word (Text *text)
@@ -2358,7 +2543,7 @@ void txt_delete_word (Text *text)
void txt_backspace_char (Text *text)
{
- char c='\n';
+ unsigned int c='\n';
if (!text) return;
if (!text->curl) return;
@@ -2378,12 +2563,15 @@ void txt_backspace_char (Text *text)
txt_pop_sel(text);
}
else { /* Just backspacing a char */
- int i= text->curc-1;
+ size_t c_len = 0;
+ TextMarker *mrk;
+ char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
+ c= BLI_str_utf8_as_unicode_and_size(prev, &c_len);
- TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0, 0);
+ mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
if (mrk) {
int lineno= mrk->lineno;
- if (mrk->start==i+1) {
+ if (mrk->start==text->curc) {
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
txt_clear_markers(text, mrk->group, TMARK_TEMP);
} else {
@@ -2392,19 +2580,16 @@ void txt_backspace_char (Text *text)
return;
}
do {
- if (mrk->start>i) mrk->start--;
- mrk->end--;
+ if (mrk->start>text->curc - c_len) mrk->start-= c_len;
+ mrk->end-= c_len;
mrk= mrk->next;
} while (mrk && mrk->lineno==lineno);
}
- c= text->curl->line[i];
- while(i< text->curl->len) {
- text->curl->line[i]= text->curl->line[i+1];
- i++;
- }
- text->curl->len--;
- text->curc--;
+ memcpy(text->curl->line + text->curc - c_len, text->curl->line + text->curc, text->curl->len-text->curc+1);
+
+ text->curl->len-= c_len;
+ text->curc-= c_len;
txt_pop_sel(text);
}
@@ -2412,7 +2597,7 @@ void txt_backspace_char (Text *text)
txt_make_dirty(text);
txt_clean_text(text);
- if(!undoing) txt_undo_add_charop(text, UNDO_BS, c);
+ if(!undoing) txt_undo_add_charop(text, UNDO_BS_1, c);
}
void txt_backspace_word (Text *text)
@@ -2436,11 +2621,12 @@ static void txt_convert_tab_to_spaces (Text *text)
txt_insert_buf(text, sb);
}
-static int txt_add_char_intern (Text *text, char add, int replace_tabs)
+static int txt_add_char_intern (Text *text, unsigned int add, int replace_tabs)
{
- int len, lineno;
- char *tmp;
+ int lineno;
+ char *tmp, ch[BLI_UTF8_MAX];
TextMarker *mrk;
+ size_t add_len;
if (!text) return 0;
if (!text->curl) return 0;
@@ -2458,43 +2644,42 @@ static int txt_add_char_intern (Text *text, char add, int replace_tabs)
txt_delete_sel(text);
+ add_len = BLI_str_utf8_from_unicode(add, ch);
mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0);
if (mrk) {
lineno= mrk->lineno;
do {
- if (mrk->start>text->curc) mrk->start++;
- mrk->end++;
+ if (mrk->start>text->curc) mrk->start+= add_len;
+ mrk->end+= add_len;
mrk= mrk->next;
} while (mrk && mrk->lineno==lineno);
}
- tmp= MEM_mallocN(text->curl->len+2, "textline_string");
-
- if(text->curc) memcpy(tmp, text->curl->line, text->curc);
- tmp[text->curc]= add;
+ tmp= MEM_mallocN(text->curl->len+add_len+1, "textline_string");
- len= text->curl->len - text->curc;
- if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
- tmp[text->curl->len+1]=0;
+ memcpy(tmp, text->curl->line, text->curc);
+ memcpy(tmp+text->curc, ch, add_len);
+ memcpy(tmp+text->curc+add_len, text->curl->line+text->curc, text->curl->len-text->curc+1);
+
make_new_line(text->curl, tmp);
- text->curc++;
+ text->curc+= add_len;
txt_pop_sel(text);
txt_make_dirty(text);
txt_clean_text(text);
- if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, add);
+ if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
return 1;
}
-int txt_add_char (Text *text, char add)
+int txt_add_char (Text *text, unsigned int add)
{
return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES);
}
-int txt_add_raw_char (Text *text, char add)
+int txt_add_raw_char (Text *text, unsigned int add)
{
return txt_add_char_intern(text, add, 0);
}
@@ -2505,34 +2690,48 @@ void txt_delete_selected(Text *text)
txt_make_dirty(text);
}
-int txt_replace_char (Text *text, char add)
+int txt_replace_char (Text *text, unsigned int add)
{
- char del;
+ unsigned int del;
+ size_t del_size = 0, add_size;
+ char ch[BLI_UTF8_MAX];
if (!text) return 0;
if (!text->curl) return 0;
/* If text is selected or we're at the end of the line just use txt_add_char */
if (text->curc==text->curl->len || txt_has_sel(text) || add=='\n') {
- TextMarker *mrk;
int i= txt_add_char(text, add);
- mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
- if (mrk && mrk->end==text->curc) mrk->end--;
+ TextMarker *mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
+ if (mrk) BLI_freelinkN(&text->markers, mrk);
return i;
}
- del= text->curl->line[text->curc];
- text->curl->line[text->curc]= (unsigned char) add;
- text->curc++;
- txt_pop_sel(text);
+ del= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size);
+ add_size= BLI_str_utf8_from_unicode(add, ch);
+ if (add_size > del_size) {
+ char *tmp= MEM_mallocN(text->curl->len+add_size-del_size+1, "textline_string");
+ memcpy(tmp, text->curl->line, text->curc);
+ memcpy(tmp+text->curc+add_size, text->curl->line+text->curc+del_size, text->curl->len-text->curc-del_size+1);
+ MEM_freeN(text->curl->line);
+ text->curl->line = tmp;
+ } else if (add_size < del_size) {
+ char *tmp= text->curl->line;
+ memmove(tmp+text->curc+add_size, tmp+text->curc+del_size, text->curl->len-text->curc-del_size+1);
+ }
+
+ memcpy(text->curl->line + text->curc, ch, add_size);
+ text->curc+= add_size;
+
+ txt_pop_sel(text);
txt_make_dirty(text);
txt_clean_text(text);
/* Should probably create a new op for this */
if(!undoing) {
- txt_undo_add_charop(text, UNDO_DEL, del);
- txt_undo_add_charop(text, UNDO_INSERT, add);
+ txt_undo_add_charop(text, UNDO_DEL_1, del);
+ txt_undo_add_charop(text, UNDO_INSERT_1, add);
}
return 1;
}