diff options
Diffstat (limited to 'source/blender/blenkernel/intern/seqeffects.c')
-rw-r--r-- | source/blender/blenkernel/intern/seqeffects.c | 165 |
1 files changed, 158 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 11a6cb7acc3..f375c2b1e4f 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -38,10 +38,13 @@ #include "BLI_math.h" /* windows needs for M_PI */ #include "BLI_utildefines.h" +#include "BLI_rect.h" +#include "BLI_string.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_anim_types.h" +#include "DNA_space_types.h" #include "BKE_fcurve.h" #include "BKE_sequencer.h" @@ -52,11 +55,10 @@ #include "RNA_access.h" -/* TODO(sergey): Could be considered a bad level call, but - * need this for gaussian table. - */ #include "RE_pipeline.h" +#include "BLF_api.h" + static void slice_get_byte_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, const ImBuf *ibuf3, const ImBuf *out, int start_line, unsigned char **rect1, unsigned char **rect2, unsigned char **rect3, unsigned char **rect_out) @@ -2670,8 +2672,8 @@ static void do_gaussian_blur_effect_byte(Sequence *seq, { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f), - size_y = (int) (data->size_y + 0.5f); + const int size_x = (int) (data->size_x + 0.5f); + const int size_y = (int) (data->size_y + 0.5f); int i, j; /* Make gaussian weight tabke. */ @@ -2754,8 +2756,8 @@ static void do_gaussian_blur_effect_float(Sequence *seq, { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f), - size_y = (int) (data->size_y + 0.5f); + const int size_x = (int) (data->size_x + 0.5f); + const int size_y = (int) (data->size_y + 0.5f); int i, j; /* Make gaussian weight tabke. */ @@ -2879,6 +2881,134 @@ static void do_gaussian_blur_effect(const SeqRenderData *context, } } +/*********************** text *************************/ +static void init_text_effect(Sequence *seq) +{ + TextVars *data; + + if (seq->effectdata) + MEM_freeN(seq->effectdata); + + data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars"); + data->text_size = 30; + BLI_strncpy(data->text, "Text", sizeof(data->text)); + + data->loc[0] = 0.5f; + data->align = SEQ_TEXT_ALIGN_X_CENTER; + data->align_y = SEQ_TEXT_ALIGN_Y_BOTTOM; +} + +static int num_inputs_text(void) +{ + return 0; +} + +static int early_out_text(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1)) +{ + TextVars *data = seq->effectdata; + if (data->text[0] == 0 || data->text_size < 1) { + return EARLY_USE_INPUT_1; + } + return EARLY_NO_INPUT; +} + +static ImBuf *do_text_effect(const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float UNUSED(facf0), float UNUSED(facf1), + ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + TextVars *data = seq->effectdata; + int width = out->x; + int height = out->y; + struct ColorManagedDisplay *display; + const char *display_device; + const int mono = blf_mono_font_render; // XXX + int line_height; + int y_ofs, x, y; + float proxy_size_comp; + + display_device = context->scene->display_settings.display_device; + display = IMB_colormanagement_display_get_named(display_device); + + /* Compensate text size for preview render size. */ + if (ELEM(context->preview_render_size, SEQ_PROXY_RENDER_SIZE_SCENE, SEQ_PROXY_RENDER_SIZE_FULL)) { + proxy_size_comp = context->scene->r.size / 100.0f; + } + else if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_100) { + proxy_size_comp = 1.0f; + } + else { + proxy_size_comp = context->preview_render_size / 100.0f; + } + + /* set before return */ + BLF_size(mono, proxy_size_comp * data->text_size, 72); + + BLF_enable(mono, BLF_WORD_WRAP); + + /* use max width to enable newlines only */ + BLF_wordwrap(mono, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1); + + BLF_buffer(mono, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display); + + line_height = BLF_height_max(mono); + + y_ofs = -BLF_descender(mono); + + x = (data->loc[0] * width); + y = (data->loc[1] * height) + y_ofs; + + if ((data->align == SEQ_TEXT_ALIGN_X_LEFT) && + (data->align_y == SEQ_TEXT_ALIGN_Y_TOP)) + { + y -= line_height; + } + else { + /* vars for calculating wordwrap */ + struct { + struct ResultBLF info; + rctf rect; + } wrap; + + BLF_boundbox_ex(mono, data->text, sizeof(data->text), &wrap.rect, &wrap.info); + + if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) { + x -= BLI_rctf_size_x(&wrap.rect); + } + else if (data->align == SEQ_TEXT_ALIGN_X_CENTER) { + x -= BLI_rctf_size_x(&wrap.rect) / 2; + } + + if (data->align_y == SEQ_TEXT_ALIGN_Y_TOP) { + y -= line_height; + } + else if (data->align_y == SEQ_TEXT_ALIGN_Y_BOTTOM) { + y += (wrap.info.lines - 1) * line_height; + } + else if (data->align_y == SEQ_TEXT_ALIGN_Y_CENTER) { + y += (((wrap.info.lines - 1) / 2) * line_height) - (line_height / 2); + } + } + + /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */ + if (data->flag & SEQ_TEXT_SHADOW) { + int fontx, fonty; + fontx = BLF_width_max(mono); + fonty = line_height; + BLF_position(mono, x + max_ii(fontx / 25, 1), y + max_ii(fonty / 25, 1), 0.0f); + BLF_buffer_col(mono, 0.0f, 0.0f, 0.0f, 1.0f); + BLF_draw_buffer(mono, data->text, BLF_DRAW_STR_DUMMY_MAX); + } + BLF_position(mono, x, y, 0.0f); + BLF_buffer_col(mono, 1.0f, 1.0f, 1.0f, 1.0f); + BLF_draw_buffer(mono, data->text, BLF_DRAW_STR_DUMMY_MAX); + + BLF_buffer(mono, NULL, NULL, 0, 0, 0, NULL); + + BLF_disable(mono, BLF_WORD_WRAP); + + return out; +} + /*********************** sequence effect factory *************************/ static void init_noop(Sequence *UNUSED(seq)) @@ -2901,6 +3031,19 @@ static int num_inputs_default(void) return 2; } +static void copy_effect_default(Sequence *dst, Sequence *src) +{ + dst->effectdata = MEM_dupallocN(src->effectdata); +} + +static void free_effect_default(Sequence *seq) +{ + if (seq->effectdata) + MEM_freeN(seq->effectdata); + + seq->effectdata = NULL; +} + static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { return EARLY_DO_EFFECT; @@ -3076,6 +3219,14 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.early_out = early_out_gaussian_blur; rval.execute_slice = do_gaussian_blur_effect; break; + case SEQ_TYPE_TEXT: + rval.num_inputs = num_inputs_text; + rval.init = init_text_effect; + rval.free = free_effect_default; + rval.copy = copy_effect_default; + rval.early_out = early_out_text; + rval.execute = do_text_effect; + break; } return rval; |