fix [#36066] crash when Tab out text object
authorCampbell Barton <ideasman42@gmail.com>
Tue, 9 Jul 2013 06:21:45 +0000 (06:21 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 9 Jul 2013 06:21:45 +0000 (06:21 +0000)
the way Curve.len is used at the moment is really stupid, calculate string size on save for now, but should really store the length in bytes and total number of characters.

source/blender/blenkernel/intern/text.c
source/blender/blenlib/BLI_string_utf8.h
source/blender/blenlib/intern/string_utf8.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_curve_types.h

index 296f25e303e163486a68f2100cd3e26779403a4e..aec924e15b3082667d3eb51cc22d0da814295f22 100644 (file)
@@ -847,19 +847,6 @@ int txt_utf8_column_to_offset(const char *str, int column)
        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)
 {
        TextLine **linep;
@@ -2059,7 +2046,7 @@ void txt_do_undo(Text *text)
                                text->undo_pos--;
                        }
                        buf[i] = 0;
-                       linep = txt_utf8_len(buf);
+                       linep = BLI_strlen_utf8(buf);
                        MEM_freeN(buf);
                        
                        /* skip over the length that was stored again */
index d20cbd2a91cb03b2610cc0cd71121b3c7197a81e..adef843d2cc18ff439fa5252d9637a7dc06a5bd9 100644 (file)
@@ -51,8 +51,10 @@ char        *BLI_str_prev_char_utf8(const char *p);
 
 /* wchar_t functions, copied from blenders own font.c originally */
 size_t       BLI_wstrlen_utf8(const wchar_t *src);
+size_t       BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes);
 size_t       BLI_strlen_utf8(const char *strc);
-size_t       BLI_strnlen_utf8(const char *start, const size_t maxlen);
+size_t       BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes);
+size_t       BLI_strnlen_utf8(const char *strc, const size_t maxlen);
 size_t       BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
 size_t       BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
 
index b8dca95ae3319046568e6c149bde43619f23ffbc..ab0073a7585c00293eee8a445c394742d27554ca 100644 (file)
@@ -245,24 +245,16 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
        return len;
 }
 
-/* this is very close to 'BLI_str_utf8_size' functionality, perhaps we should de-duplicate */
-/* size of UTF-8 character in bytes */
-static size_t strlen_utf8_char(const char *strc)
+size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
 {
-       if ((*strc & 0xe0) == 0xc0) {
-               if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
-                       return 2;
-       }
-       else if ((*strc & 0xf0) == 0xe0) {
-               if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
-                       return 3;
-       }
-       else if ((*strc & 0xf8) == 0xf0) {
-               if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
-                       return 4;
-       }
+       size_t len;
+       const char *strc_orig = strc;
 
-       return 1;
+       for (len = 0; *strc; len++)
+               strc += BLI_str_utf8_size_safe(strc);
+
+       *r_len_bytes = (strc - strc_orig);
+       return len;
 }
 
 size_t BLI_strlen_utf8(const char *strc)
@@ -270,25 +262,37 @@ size_t BLI_strlen_utf8(const char *strc)
        size_t len;
 
        for (len = 0; *strc; len++)
-               strc += strlen_utf8_char(strc);
+               strc += BLI_str_utf8_size_safe(strc);
 
        return len;
 }
 
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes)
+{
+       size_t len;
+       const char *strc_orig = strc;
+       const char *strc_end = strc + maxlen;
+
+       for (len = 0; *strc && strc < strc_end; len++) {
+               strc += BLI_str_utf8_size_safe(strc);
+       }
+
+       *r_len_bytes = (strc - strc_orig);
+       return len;
+}
+
 /**
  * \param start the string to measure the length.
  * \param maxlen the string length (in bytes)
  * \return the unicode length (not in bytes!)
  */
-size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
+size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
 {
-       const char *strc = start;
-       const char *strc_end = start + maxlen;
-
        size_t len;
+       const char *strc_end = strc + maxlen;
 
        for (len = 0; *strc && strc < strc_end; len++) {
-               strc += strlen_utf8_char(strc);
+               strc += BLI_str_utf8_size_safe(strc);
        }
 
        return len;
index 9b6699f3f215ccba1db7c0f82191d559f6763b7d..dd4361be1ff704ce64b64e5797fda502181d7756 100644 (file)
@@ -1642,13 +1642,6 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
        }
 }
 
-static int amount_of_chars(char *str)
-{
-       // Since the data is saved as UTF-8 to the cu->str
-       // The cu->len is not same as the strlen(cu->str)
-       return strlen(str);
-}
-
 static void write_curves(WriteData *wd, ListBase *idbase)
 {
        Curve *cu;
@@ -1666,8 +1659,12 @@ static void write_curves(WriteData *wd, ListBase *idbase)
                        if (cu->adt) write_animdata(wd, cu->adt);
                        
                        if (cu->vfont) {
-                               writedata(wd, DATA, amount_of_chars(cu->str)+1, cu->str);
-                               writestruct(wd, DATA, "CharInfo", cu->len+1, cu->strinfo);
+                               /* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */
+                               int len_bytes;
+                               int len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
+
+                               writedata(wd, DATA, len_bytes + 1, cu->str);
+                               writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
                                writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
                        }
                        else {
index deb9902c35d073c694419ffe0bfac564b5fdbd51..964fa11b0a24a0344d999cf52a894fb17e91e349 100644 (file)
@@ -215,6 +215,10 @@ typedef struct Curve {
        void *lastsel;
        
        /* font part */
+       /* WARNING: cu->len is...
+        * - strlen(cu->str) object-mode (bytes).
+        * - BLI_strlen_utf8(cu->str) in edit-mode.
+        * This should be cleaned up and some point, see 'write_curves' - campbell */
        short len, lines, pos, spacemode;
        float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight;
        float xof, yof;