Revision: 32441
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32441
Author:   nazgul
Date:     2010-10-13 08:06:39 +0200 (Wed, 13 Oct 2010)

Log Message:
-----------
Text space
==========

Main changes:
- lines could be partially shown when they starts somewhere behind the upper
  boundary of area but because of word-wrapping some part of line will be show
- fixed caret navigatiog in area when tabs aren't replaced by spaces
- highlight the whole current line not only it's wrapped segment with caret
- when you're in replace mode cursor would be as long as the tab's width if 
it's under tab symbol

This fixes:
  #22399: Text Editor: word-wrapped lines prevent navigating through text with 
up-arrow.
  #21163: Text editor scrollbar problem with word wrap

Modified Paths:
--------------
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/space_text/space_text.c
    trunk/blender/source/blender/editors/space_text/text_draw.c
    trunk/blender/source/blender/editors/space_text/text_intern.h
    trunk/blender/source/blender/editors/space_text/text_ops.c
    trunk/blender/source/blender/makesdna/DNA_space_types.h

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c   2010-10-13 
04:00:01 UTC (rev 32440)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c   2010-10-13 
06:06:39 UTC (rev 32441)
@@ -4646,6 +4646,7 @@
                                                SpaceText *st= (SpaceText *)sl;
 
                                                st->text= newlibadr(fd, 
sc->id.lib, st->text);
+                                               st->drawcache= NULL;
 
                                        }
                                        else if(sl->spacetype==SPACE_SCRIPT) {
@@ -4877,6 +4878,8 @@
 
                                        st->text= 
restore_pointer_by_name(newmain, (ID *)st->text, 1);
                                        if(st->text==NULL) st->text= 
newmain->text.first;
+
+                                       st->drawcache= NULL;
                                }
                                else if(sl->spacetype==SPACE_SCRIPT) {
                                        SpaceScript *scpt= (SpaceScript *)sl;

Modified: trunk/blender/source/blender/editors/space_text/space_text.c
===================================================================
--- trunk/blender/source/blender/editors/space_text/space_text.c        
2010-10-13 04:00:01 UTC (rev 32440)
+++ trunk/blender/source/blender/editors/space_text/space_text.c        
2010-10-13 06:06:39 UTC (rev 32441)
@@ -92,6 +92,7 @@
        SpaceText *stext= (SpaceText*) sl;
        
        stext->text= NULL;
+       text_free_caches(stext);
 }
 
 
@@ -104,9 +105,11 @@
 static SpaceLink *text_duplicate(SpaceLink *sl)
 {
        SpaceText *stextn= MEM_dupallocN(sl);
-       
+
        /* clear or remove stuff from old */
-       
+
+       stextn->drawcache= NULL; /* space need it's own cache */
+
        return (SpaceLink *)stextn;
 }
 
@@ -132,8 +135,11 @@
 
                        switch(wmn->action) {
                                case NA_EDITED:
-                                       if(st->text)
+                                       if(st->text) {
+                                               text_drawcache_tag_update(st, 
1);
                                                text_update_edited(st->text);
+                                       }
+
                                        ED_area_tag_redraw(sa);
                                        /* no break -- fall down to tag redraw 
*/
                                case NA_ADDED:

Modified: trunk/blender/source/blender/editors/space_text/text_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_text/text_draw.c 2010-10-13 
04:00:01 UTC (rev 32440)
+++ trunk/blender/source/blender/editors/space_text/text_draw.c 2010-10-13 
06:06:39 UTC (rev 32441)
@@ -10,7 +10,6 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
@@ -521,9 +520,22 @@
        linep= text->lines.first;
        i= st->top;
        while(i>0 && linep) {
-               if(linep == linein) return; /* Line before top */
-               linep= linep->next;
-               i--;
+               int lines= text_get_visible_lines(st, ar, linep->line);
+
+               /* Line before top */
+               if(linep == linein) {
+                       if(lines <= i)
+                               /* no visible part of line */
+                               return;
+               }
+
+               if (i-lines<0) {
+                       break;
+               } else {
+                       linep= linep->next;
+                       (*offl)+= lines-1;
+                       i-= lines;
+               }
        }
 
        max= wrap_width(st, ar);
@@ -548,10 +560,18 @@
 
                        while(chars--) {
                                if(i-start>=max) {
-                                       if(chop && linep==linein && i >= cursin)
+                                       if(chop && linep==linein && i >= 
cursin) {
+                                               if (i==cursin) {
+                                                       (*offl)++;
+                                                       *offc -= end-start;
+                                               }
+
                                                return;
+                                       }
+
                                        (*offl)++;
                                        *offc -= end-start;
+
                                        start= end;
                                        end += max;
                                        chop= 1;
@@ -570,8 +590,67 @@
        }
 }
 
-static int get_char_pos(SpaceText *st, char *line, int cur)
+void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int 
cursin, int *offl, int *offc)
 {
+       int i, j, start, end, chars, max, chop;
+       char ch;
+
+       *offl= *offc= 0;
+
+       if(!st->text) return;
+       if(!st->wordwrap) return;
+
+       max= wrap_width(st, ar);
+
+       start= 0;
+       end= max;
+       chop= 1;
+       chars= 0;
+       *offc= 0;
+
+       for(i=0, j=0; linein->line[j]!='\0'; j++) {
+
+               /* Mimic replacement of tabs */
+               ch= linein->line[j];
+               if(ch=='\t') {
+                       chars= st->tabnumber-i%st->tabnumber;
+                       if(i<cursin) cursin += chars-1;
+                       ch= ' ';
+               }
+               else
+                       chars= 1;
+
+               while(chars--) {
+                       if(i-start>=max) {
+                               if(chop && i >= cursin) {
+                                       if (i==cursin) {
+                                               (*offl)++;
+                                               *offc -= end-start;
+                                       }
+
+                                       return;
+                               }
+
+                               (*offl)++;
+                               *offc -= end-start;
+
+                               start= end;
+                               end += max;
+                               chop= 1;
+                       }
+                       else if(ch==' ' || ch=='-') {
+                               end = i+1;
+                               chop= 0;
+                               if(i >= cursin)
+                                       return;
+                       }
+                       i++;
+               }
+       }
+}
+
+int text_get_char_pos(SpaceText *st, char *line, int cur)
+{
        int a=0, i;
        
        for(i=0; i<cur && line[i]; i++) {
@@ -583,7 +662,7 @@
        return a;
 }
 
-static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, 
char *format)
+static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, 
char *format, int skip)
 {
        FlattenString fs;
        int basex, i, a, len, start, end, max, lines;
@@ -599,6 +678,14 @@
        end= max;
        for(i=0; i<len; i++) {
                if(i-start >= max) {
+                       /* skip hidden part of line */
+                       if(skip) {
+                               skip--;
+                               start= end;
+                               end += max;
+                               continue;
+                       }
+
                        /* Draw the visible portion of text on the overshot 
line */
                        for(a=start; a<end; a++) {
                                if(st->showsyntax && format) 
format_draw_color(format[a]);
@@ -609,6 +696,8 @@
                        lines++;
                        start= end;
                        end += max;
+
+                       if(y<=0) break;
                }
                else if(str[i]==' ' || str[i]=='-') {
                        end = i+1;
@@ -616,7 +705,7 @@
        }
 
        /* Draw the remaining text */
-       for(a=start; a<len; a++) {
+       for(a=start; a<len && y > 0; a++) {
                if(st->showsyntax && format)
                        format_draw_color(format[a]);
 
@@ -631,7 +720,7 @@
 static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int 
draw, int x, int y, char *format)
 {
        FlattenString fs;
-       int r=0, w= 0;
+       int r=0, w= 0, amount;
        int *acc;
        char *in;
 
@@ -647,18 +736,26 @@
 
        if(draw) {
                if(st->showsyntax && format) {
-                       int amount, a;
+                       int a;
                        format = format+cshift;
                
                        amount = strlen(in);
+                       if(maxwidth)
+                               amount= MIN2(amount, maxwidth);
                        
                        for(a = 0; a < amount; a++) {
                                format_draw_color(format[a]);
                                x += text_font_draw_character(st, x, y, in[a]);
                        }
                }
-               else
+               else {
+                       amount = strlen(in);
+                       if(maxwidth)
+                               amount= MIN2(amount, maxwidth);
+
+                       in[amount]= 0;
                        text_font_draw(st, x, y, in);
+               }
        }
        else {
                while(w-- && *acc++ < maxwidth)
@@ -675,18 +772,307 @@
                return r+TXT_OFFSET;
 }
 
+/************************ cache utilities *****************************/
+
+typedef struct DrawCache {
+       int *line_height;
+       int total_lines, nlines;
+
+       /* this is needed to check cache relevance */
+       int winx, wordwrap, showlinenrs, tabnumber;
+       short lheight;
+       char cwidth;
+       char text_id[MAX_ID_NAME];
+
+       /* for partial lines recalculation */
+       short update_flag;
+       int valid_head, valid_tail; /* amount of unchanged lines */
+} DrawCache;
+
+static void text_drawcache_init(SpaceText *st)
+{
+       DrawCache *drawcache= MEM_callocN(sizeof (DrawCache), "text draw 
cache");
+
+       drawcache->winx= -1;
+       drawcache->nlines= BLI_countlist(&st->text->lines);
+       drawcache->text_id[0]= '\0';
+
+       st->drawcache= drawcache;
+}
+
+static void text_update_drawcache(SpaceText *st, ARegion *ar)
+{
+       DrawCache *drawcache;
+       int full_update= 0, nlines= 0;
+       Text *txt= st->text;
+
+       if(!st->drawcache) text_drawcache_init(st);
+
+       text_update_character_width(st);
+
+       drawcache= (DrawCache *)st->drawcache;
+       nlines= drawcache->nlines;
+
+       /* check if full cache update is needed */
+       full_update|= drawcache->winx != ar->winx;                 /* area was 
resized */
+       full_update|= drawcache->wordwrap != st->wordwrap;         /* 
word-wrapping option was toggled */
+       full_update|= drawcache->showlinenrs != st->showlinenrs; /* 
word-wrapping option was toggled */
+       full_update|= drawcache->tabnumber != st->tabnumber;  /* word-wrapping 
option was toggled */
+       full_update|= drawcache->lheight != st->lheight;      /* word-wrapping 
option was toggled */
+       full_update|= drawcache->cwidth != st->cwidth;        /* word-wrapping 
option was toggled */
+       full_update|= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); 
/* text datablock was changed */
+
+       if(st->wordwrap) {
+               /* update line heights */
+               if(full_update || !drawcache->line_height) {
+                       drawcache->valid_head  = 0;
+                       drawcache->valid_tail  = 0;
+                       drawcache->update_flag = 1;
+               }
+
+               if(drawcache->update_flag) {
+                       TextLine *line= st->text->lines.first;
+                       int lineno= 0, size, lines_count;
+                       int *fp= drawcache->line_height, *new_tail, *old_tail;
+
+                       nlines= BLI_countlist(&txt->lines);
+                       size= sizeof(int)*nlines;
+
+                       if(fp) fp= MEM_reallocN(fp, size);
+                       else fp= MEM_callocN(size, "text drawcache 
line_height");
+
+                       drawcache->valid_tail= drawcache->valid_head= 0;
+                       old_tail= fp + drawcache->nlines - 
drawcache->valid_tail;
+                       new_tail= fp + nlines - drawcache->valid_tail;
+                       memmove(new_tail, old_tail, drawcache->valid_tail);
+
+                       drawcache->total_lines= 0;
+
+                       if(st->showlinenrs)
+                               st->linenrs_tot= 
(int)floor(log10((float)nlines)) + 1;
+
+                       while(line) {
+                               if(drawcache->valid_head) { /* we're inside 
valid head lines */
+                                       lines_count= fp[lineno];
+                                       drawcache->valid_head--;
+                               } else if (lineno > new_tail - fp) {  /* we-re 
inside valid tail lines */
+                                       lines_count= fp[lineno];
+                               } else {
+                                       lines_count= text_get_visible_lines(st, 
ar, line->line);
+                               }
+
+                               fp[lineno]= lines_count;
+
+                               line= line->next;
+                               lineno++;
+                               drawcache->total_lines+= lines_count;
+                       }
+
+                       drawcache->line_height= fp;
+               }
+       } else {
+               if(drawcache->line_height) {
+                       MEM_freeN(drawcache->line_height);
+                       drawcache->line_height= NULL;
+               }
+
+               if(full_update || drawcache->update_flag) {
+                       nlines= BLI_countlist(&txt->lines);
+
+                       if(st->showlinenrs)
+                               st->linenrs_tot= 
(int)floor(log10((float)nlines)) + 1;
+               }
+
+               drawcache->total_lines= nlines;
+       }
+
+       drawcache->nlines= nlines;
+
+       /* store settings */
+       drawcache->winx        = ar->winx;
+       drawcache->wordwrap    = st->wordwrap;
+       drawcache->lheight     = st->lheight;
+       drawcache->cwidth      = st->cwidth;
+       drawcache->showlinenrs = st->showlinenrs;
+       drawcache->tabnumber   = st->tabnumber;
+
+       strncpy(drawcache->text_id, txt->id.name, MAX_ID_NAME);
+
+       /* clear update flag */
+       drawcache->update_flag = 0;
+       drawcache->valid_head  = 0;
+       drawcache->valid_tail  = 0;
+}
+
+void text_drawcache_tag_update(SpaceText *st, int full)
+{
+       DrawCache *drawcache= (DrawCache *)st->drawcache;
+
+       if(drawcache) {
+               Text *txt= st->text;
+
+               if(drawcache->update_flag) {
+                       /* happens when tagging update from space listener */

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to