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:
authorCampbell Barton <ideasman42@gmail.com>2012-12-19 08:02:19 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-12-19 08:02:19 +0400
commitf43923d86d0a4d6dbbdc8d7fc05d383a23b3e5e2 (patch)
tree8167b27c9cfd062892dd503c916eda7e788f6fb2 /source/blender/editors/space_text/text_draw.c
parentbfde24a36836e7b4d9d7721c791abb90ed145024 (diff)
generalize formatting code so different formatters can be registered and each has their own source file,
Since we will likely have OSL formatting added soon.
Diffstat (limited to 'source/blender/editors/space_text/text_draw.c')
-rw-r--r--source/blender/editors/space_text/text_draw.c350
1 files changed, 4 insertions, 346 deletions
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 24f40dbbe2a..2066df39b73 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -58,6 +58,7 @@
#include "UI_resources.h"
#include "text_intern.h"
+#include "text_format.h"
/******************** text font drawing ******************/
// XXX, fixme
@@ -105,350 +106,6 @@ static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char
return st->cwidth;
}
-/****************** flatten string **********************/
-
-static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
-{
- int i;
-
- if (fs->pos + len > fs->len) {
- char *nbuf; int *naccum;
- fs->len *= 2;
-
- nbuf = MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf");
- naccum = MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum");
-
- memcpy(nbuf, fs->buf, fs->pos * sizeof(*fs->buf));
- memcpy(naccum, fs->accum, fs->pos * sizeof(*fs->accum));
-
- if (fs->buf != fs->fixedbuf) {
- MEM_freeN(fs->buf);
- MEM_freeN(fs->accum);
- }
-
- fs->buf = nbuf;
- fs->accum = naccum;
- }
-
- for (i = 0; i < len; i++) {
- fs->buf[fs->pos + i] = c[i];
- fs->accum[fs->pos + i] = accum;
- }
-
- fs->pos += len;
-}
-
-int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
-{
- int r, i, total = 0;
-
- memset(fs, 0, sizeof(FlattenString));
- fs->buf = fs->fixedbuf;
- fs->accum = fs->fixedaccum;
- fs->len = sizeof(fs->fixedbuf);
-
- for (r = 0, i = 0; *in; r++) {
- if (*in == '\t') {
- i = st->tabnumber - (total % st->tabnumber);
- total += i;
-
- while (i--)
- flatten_string_append(fs, " ", r, 1);
-
- in++;
- }
- else {
- size_t len = BLI_str_utf8_size_safe(in);
- flatten_string_append(fs, in, r, len);
- in += len;
- total++;
- }
- }
-
- flatten_string_append(fs, "\0", r, 1);
-
- return total;
-}
-
-void flatten_string_free(FlattenString *fs)
-{
- if (fs->buf != fs->fixedbuf)
- MEM_freeN(fs->buf);
- if (fs->accum != fs->fixedaccum)
- MEM_freeN(fs->accum);
-}
-
-/* Checks the specified source string for a Python built-in function name. This
- * name must start at the beginning of the source string and must be followed by
- * a non-identifier (see text_check_identifier(char)) or null character.
- *
- * If a built-in function is found, the length of the matching name is returned.
- * Otherwise, -1 is returned.
- *
- * See:
- * http://docs.python.org/py3k/reference/lexical_analysis.html#keywords
- */
-
-static int find_builtinfunc(char *string)
-{
- int a, i;
- const char *builtinfuncs[] = {
- /* "False", "None", "True", */ /* see find_bool() */
- "and", "as", "assert", "break",
- "class", "continue", "def", "del", "elif", "else", "except",
- "finally", "for", "from", "global", "if", "import", "in",
- "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
- "return", "try", "while", "with", "yield",
- };
-
- for (a = 0; a < sizeof(builtinfuncs) / sizeof(builtinfuncs[0]); a++) {
- i = 0;
- while (1) {
- /* If we hit the end of a keyword... (eg. "def") */
- if (builtinfuncs[a][i] == '\0') {
- /* If we still have identifier chars in the source (eg. "definate") */
- if (text_check_identifier(string[i]))
- i = -1; /* No match */
- break; /* Next keyword if no match, otherwise we're done */
-
- /* If chars mismatch, move on to next keyword */
- }
- else if (string[i] != builtinfuncs[a][i]) {
- i = -1;
- break; /* Break inner loop, start next keyword */
- }
- i++;
- }
- if (i > 0) break; /* If we have a match, we're done */
- }
- return i;
-}
-
-/* Checks the specified source string for a Python special name. This name must
- * start at the beginning of the source string and must be followed by a non-
- * identifier (see text_check_identifier(char)) or null character.
- *
- * If a special name is found, the length of the matching name is returned.
- * Otherwise, -1 is returned. */
-
-static int find_specialvar(char *string)
-{
- int i = 0;
- /* Check for "def" */
- if (string[0] == 'd' && string[1] == 'e' && string[2] == 'f')
- i = 3;
- /* Check for "class" */
- else if (string[0] == 'c' && string[1] == 'l' && string[2] == 'a' && string[3] == 's' && string[4] == 's')
- i = 5;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-static int find_decorator(char *string)
-{
- if (string[0] == '@') {
- int i = 1;
- while (text_check_identifier(string[i])) {
- i++;
- }
- return i;
- }
- return -1;
-}
-
-static int find_bool(char *string)
-{
- int i = 0;
- /* Check for "False" */
- if (string[0] == 'F' && string[1] == 'a' && string[2] == 'l' && string[3] == 's' && string[4] == 'e')
- i = 5;
- /* Check for "True" */
- else if (string[0] == 'T' && string[1] == 'r' && string[2] == 'u' && string[3] == 'e')
- i = 4;
- /* Check for "None" */
- else if (string[0] == 'N' && string[1] == 'o' && string[2] == 'n' && string[3] == 'e')
- i = 4;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-/* Ensures the format string for the given line is long enough, reallocating
- * as needed. Allocation is done here, alone, to ensure consistency. */
-static int text_check_format_len(TextLine *line, unsigned int len)
-{
- if (line->format) {
- if (strlen(line->format) < len) {
- MEM_freeN(line->format);
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
- }
- else {
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
-
- return 1;
-}
-
-/* Formats the specified line. If do_next is set, the process will move on to
- * the succeeding line if it is affected (eg. multiline strings). Format strings
- * may contain any of the following characters:
- * '_' Whitespace
- * '#' Comment text
- * '!' Punctuation and other symbols
- * 'n' Numerals
- * 'l' String letters
- * 'v' Special variables (class, def)
- * 'b' Built-in names (print, for, etc.)
- * 'q' Other text (identifiers, etc.)
- * It is terminated with a null-terminator '\0' followed by a continuation
- * flag indicating whether the line is part of a multi-line string. */
-
-static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
-{
- FlattenString fs;
- char *str, *fmt, orig, cont, find, prev = ' ';
- int len, i;
-
- /* Get continuation from previous line */
- if (line->prev && line->prev->format != NULL) {
- fmt = line->prev->format;
- cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else cont = 0;
-
- /* Get original continuation from this line */
- if (line->format != NULL) {
- fmt = line->format;
- orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else orig = 0xFF;
-
- len = flatten_string(st, &fs, line->line);
- str = fs.buf;
- if (!text_check_format_len(line, len)) {
- flatten_string_free(&fs);
- return;
- }
- fmt = line->format;
-
- while (*str) {
- /* Handle escape sequences by skipping both \ and next char */
- if (*str == '\\') {
- *fmt = prev; fmt++; str++;
- if (*str == '\0') break;
- *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
- continue;
- }
- /* Handle continuations */
- else if (cont) {
- /* Triple strings ("""...""" or '''...''') */
- if (cont & TXT_TRISTR) {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find && *(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont = 0;
- }
- /* Handle other strings */
- }
- else {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find) cont = 0;
- }
-
- *fmt = 'l';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- /* Not in a string... */
- else {
- /* Deal with comments first */
- if (prev == '#' || *str == '#') {
- *fmt = '#';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- else if (*str == '"' || *str == '\'') {
- /* Strings */
- find = *str;
- cont = (*str == '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR;
- if (*(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont |= TXT_TRISTR;
- }
- *fmt = 'l';
- }
- /* Whitespace (all ws. has been converted to spaces) */
- else if (*str == ' ')
- *fmt = '_';
- /* Numbers (digits not part of an identifier and periods followed by digits) */
- else if ((prev != 'q' && text_check_digit(*str)) || (*str == '.' && text_check_digit(*(str + 1))))
- *fmt = 'n';
- /* Booleans */
- else if (prev != 'q' && (i = find_bool(str)) != -1)
- if (i > 0) {
- while (i > 1) {
- *fmt = 'n'; fmt++; str++;
- i--;
- }
- *fmt = 'n';
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Punctuation */
- else if (text_check_delim(*str))
- *fmt = '!';
- /* Identifiers and other text (no previous ws. or delims. so text continues) */
- else if (prev == 'q') {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
- else {
- /* Special vars(v) or built-in keywords(b) */
- if ((i = find_specialvar(str)) != -1)
- prev = 'v';
- else if ((i = find_builtinfunc(str)) != -1)
- prev = 'b';
- else if ((i = find_decorator(str)) != -1)
- prev = 'v'; /* could have a new color for this */
- if (i > 0) {
- while (i > 1) {
- *fmt = prev; fmt++; str++;
- i--;
- }
- *fmt = prev;
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- }
- }
- prev = *fmt;
- fmt++;
- str++;
- }
-
- /* Terminate and add continuation char */
- *fmt = '\0'; fmt++;
- *fmt = cont;
-
- /* If continuation has changed and we're allowed, process the next line */
- if (cont != orig && do_next && line->next) {
- txt_format_line(st, line->next, do_next);
- }
-
- flatten_string_free(&fs);
-}
-
#if 0
/* Formats every line of the current text */
static void txt_format_text(SpaceText *st)
@@ -1620,6 +1277,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
void draw_text_main(SpaceText *st, ARegion *ar)
{
Text *text = st->text;
+ TextFormatType *tft = ED_text_format_get(text);
TextLine *tmp;
rcti scroll, back;
char linenr[12];
@@ -1651,7 +1309,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
lineno = 0;
for (i = 0; i < st->top && tmp; i++) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->wordwrap) {
int lines = text_get_visible_lines_no(st, lineno);
@@ -1700,7 +1358,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->showlinenrs && !wrap_skip) {
/* draw line number */