Esempio n. 1
0
int text_get_span_wrap(SpaceText *st, ARegion *ar, TextLine *from, TextLine *to)
{
	if(st->wordwrap) {
		int ret=0;
		TextLine *tmp= from;

		/* Look forwards */
		while (tmp) {
			if (tmp == to) return ret;
			ret+= text_get_visible_lines(st, ar, tmp->line);
			tmp= tmp->next;
		}

		return ret;
	} else return txt_get_span(from, to);
}
Esempio n. 2
0
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_dpi;         /* 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_dpi;
	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;
}
Esempio n. 3
0
/* Sets (offl, offc) for transforming (line, curs) to its wrapped position */
void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc)
{
	Text *text;
	TextLine *linep;
	int i, j, start, end, max, chop;
	char ch;

	*offl = *offc = 0;

	if (!st->text) return;
	if (!st->wordwrap) return;

	text = st->text;

	/* Move pointer to first visible line (top) */
	linep = text->lines.first;
	i = st->top;
	while (i > 0 && linep) {
		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);
	cursin = txt_utf8_offset_to_column(linein->line, cursin);

	while (linep) {
		start = 0;
		end = max;
		chop = 1;
		*offc = 0;
		for (i = 0, j = 0; linep->line[j]; j += BLI_str_utf8_size_safe(linep->line + j)) {
			int chars;
			int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */

			/* Mimic replacement of tabs */
			ch = linep->line[j];
			if (ch == '\t') {
				chars = st->tabnumber - i % st->tabnumber;
				if (linep == linein && i < cursin) cursin += chars - 1;
				ch = ' ';
			}
			else {
				chars = 1;
			}

			while (chars--) {
				if (i + columns - start > max) {
					end = MIN2(end, i);

					if (chop && linep == linein && 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 (linep == linein && i >= cursin)
						return;
				}
				i += columns;
			}
		}
		if (linep == linein) break;
		linep = linep->next;
	}
}
Esempio n. 4
0
static void draw_cursor(SpaceText *st, ARegion *ar)
{
	Text *text = st->text;
	int vcurl, vcurc, vsell, vselc, hidden = 0;
	int x, y, w, i;
	const int lheight = st->lheight_dpi + TXT_LINE_SPACING;

	/* Draw the selection */
	if (text->curl != text->sell || text->curc != text->selc) {
		int offl, offc;
		/* Convert all to view space character coordinates */
		wrap_offset(st, ar, text->curl, text->curc, &offl, &offc);
		vcurl = txt_get_span(text->lines.first, text->curl) - st->top + offl;
		vcurc = text_get_char_pos(st, text->curl->line, text->curc) - st->left + offc;
		wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
		vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
		vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;

		if (vcurc < 0) vcurc = 0;
		if (vselc < 0) vselc = 0, hidden = 1;
		
		UI_ThemeColor(TH_SHADE2);
		x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
		y = ar->winy;

		if (vcurl == vsell) {
			y -= vcurl * lheight;
			if (vcurc < vselc)
				glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight);
			else
				glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight);
		}
		else {
			int froml, fromc, tol, toc;

			if (vcurl < vsell) {
				froml = vcurl; tol = vsell;
				fromc = vcurc; toc = vselc;
			}
			else {
				froml = vsell; tol = vcurl;
				fromc = vselc; toc = vcurc;
			}

			y -= froml * lheight;
			glRecti(x + fromc * st->cwidth - 1, y, ar->winx, y - lheight); y -= lheight;
			for (i = froml + 1; i < tol; i++)
				glRecti(x - 4, y, ar->winx, y - lheight),  y -= lheight;

			glRecti(x - 4, y, x + toc * st->cwidth, y - lheight);  y -= lheight;
		}
	}
	else {
		int offl, offc;
		wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
		vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
		vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;

		if (vselc < 0) {
			vselc = 0;
			hidden = 1;
		}
	}

	if (st->line_hlight) {
		int x1, x2, y1, y2;

		if (st->wordwrap) {
			int visible_lines = text_get_visible_lines(st, ar, text->sell->line);
			int offl, offc;

			wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);

			y1 = ar->winy - (vsell - offl) * lheight;
			y2 = y1 - (lheight * visible_lines);
		}
		else {
			y1 = ar->winy - vsell * lheight;
			y2 = y1 - (lheight);
		}

		if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */
			x1 = 0; // st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
			x2 = x1 + ar->winx;

			glColor4ub(255, 255, 255, 32);
			
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glEnable(GL_BLEND);
			glRecti(x1 - 4, y1, x2, y2);
			glDisable(GL_BLEND);
		}
	}
	
	if (!hidden) {
		/* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */
		x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
		x += vselc * st->cwidth;
		y = ar->winy - vsell * lheight;
		
		if (st->overwrite) {
			char ch = text->sell->line[text->selc];
			
			y += TXT_LINE_SPACING;
			w = st->cwidth;
			if (ch == '\t') w *= st->tabnumber - (vselc + st->left) % st->tabnumber;
			
			UI_ThemeColor(TH_HILITE);
			glRecti(x, y - lheight - 1, x + w, y - lheight + 1);
		}
		else {
			UI_ThemeColor(TH_HILITE);
			glRecti(x - 1, y, x + 1, y - lheight);
		}
	}
}
Esempio n. 5
0
/* Sets (offl, offc) for transforming (line, curs) to its wrapped position */
void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc)
{
	Text *text;
	TextLine *linep;
	int i, j, start, end, chars, max, chop;
	char ch;

	*offl= *offc= 0;

	if(!st->text) return;
	if(!st->wordwrap) return;

	text= st->text;

	/* Move pointer to first visible line (top) */
	linep= text->lines.first;
	i= st->top;
	while(i>0 && linep) {
		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);

	while(linep) {
		start= 0;
		end= max;
		chop= 1;
		chars= 0;
		*offc= 0;
		for(i=0, j=0; linep->line[j]!='\0'; j++) {

			/* Mimic replacement of tabs */
			ch= linep->line[j];
			if(ch=='\t') {
				chars= st->tabnumber-i%st->tabnumber;
				if(linep==linein && i<cursin) cursin += chars-1;
				ch= ' ';
			}
			else
				chars= 1;

			while(chars--) {
				if(i-start>=max) {
					if(chop && linep==linein && 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(linep==linein && i >= cursin)
						return;
				}
				i++;
			}
		}
		if(linep==linein) break;
		linep= linep->next;
	}
}