[Bf-blender-cvs] [235c309e5f8] master: Add background rectangle option to video sequencer Text strip

Paul Melis noreply at git.blender.org
Fri Nov 6 16:09:03 CET 2020


Commit: 235c309e5f86e84fb08e1ff2c5c11eb0b775c388
Author: Paul Melis
Date:   Fri Nov 6 15:42:52 2020 +0100
Branches: master
https://developer.blender.org/rB235c309e5f86e84fb08e1ff2c5c11eb0b775c388

Add background rectangle option to video sequencer Text strip

This adds a Box option to the Text strip's style properties, plus related Box Margin value:

{F9208309}

When enabled the text is placed on top of a solid-filled rectangle of a chosen color, as shown below:

{F9208324}

When the box option is disabled the text strip works the same as it does now. When the box option is enabled the meaning of the Shadow option changes to provide a drop-shadow on the rectangle (and not on the text itself). The latter made more sense to me.

The box margin is specified as a fraction of the image width. The offset of the drop-down box shadow is fixed to a specific fraction of the image width as well.

I tested this feature on a movie of a couple of minutes containing dozens of text strips (all with box background), edge cases like multi-line strings and text overlapping the image edges.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D9468

===================================================================

M	release/scripts/startup/bl_ui/space_sequencer.py
M	source/blender/makesdna/DNA_sequence_types.h
M	source/blender/makesrna/intern/rna_sequencer.c
M	source/blender/sequencer/intern/effects.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 0171fa902db..25548d93445 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -1187,6 +1187,21 @@ class SEQUENCER_PT_effect_text_style(SequencerButtonsPanel, Panel):
         subsub.active = strip.use_shadow and (not strip.mute)
         subsub.prop(strip, "shadow_color", text="")
         row.prop_decorator(strip, "shadow_color")
+        
+        row = layout.row(align=True, heading="Box")
+        row.use_property_decorate = False
+        sub = row.row(align=True)
+        sub.prop(strip, "use_box", text="")
+        subsub = sub.row(align=True)
+        subsub.active = strip.use_box and (not strip.mute)
+        subsub.prop(strip, "box_color", text="")
+        row.prop_decorator(strip, "box_color")
+        
+        row = layout.row(align=True, heading="Box Margin")
+        row.use_property_decorate = False
+        sub = row.row(align=True)
+        sub.prop(strip, "box_margin")
+        sub.active = strip.use_box and (not strip.mute)
 
 
 class SEQUENCER_PT_source(SequencerButtonsPanel, Panel):
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 1847fbfa986..e21f3e1e706 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -341,17 +341,19 @@ typedef struct TextVars {
   VFont *text_font;
   int text_blf_id;
   int text_size;
-  float color[4], shadow_color[4];
+  float color[4], shadow_color[4], box_color[4];
   float loc[2];
   float wrap_width;
+  float box_margin;
   char flag;
   char align, align_y;
-  char _pad[1];
+  char _pad[5];
 } TextVars;
 
 /* TextVars.flag */
 enum {
   SEQ_TEXT_SHADOW = (1 << 0),
+  SEQ_TEXT_BOX = (1 << 1),
 };
 
 /* TextVars.align */
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 07f3672cb0a..2ffb9612486 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1512,12 +1512,14 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
   prop = RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "storage", SEQ_STORAGE_PROXY_CUSTOM_DIR);
   RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Use a custom directory to store data");
-  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
+  RNA_def_property_update(
+      prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
 
   prop = RNA_def_property(srna, "use_proxy_custom_file", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "storage", SEQ_STORAGE_PROXY_CUSTOM_FILE);
   RNA_def_property_ui_text(prop, "Proxy Custom File", "Use a custom file to read proxy data from");
-  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
+  RNA_def_property_update(
+      prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
 }
 
 static void rna_def_color_balance(BlenderRNA *brna)
@@ -2181,7 +2183,8 @@ static void rna_def_proxy(StructRNA *srna)
   RNA_def_property_ui_text(
       prop, "Use Proxy / Timecode", "Use a preview proxy and/or time-code index for this strip");
   RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_proxy_set");
-  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
+  RNA_def_property_update(
+      prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
 
   prop = RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
   RNA_def_property_pointer_sdna(prop, NULL, "strip->proxy");
@@ -2864,6 +2867,11 @@ static void rna_def_text(StructRNA *srna)
   RNA_def_property_ui_text(prop, "Shadow Color", "");
   RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
 
+  prop = RNA_def_property(srna, "box_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+  RNA_def_property_float_sdna(prop, NULL, "box_color");
+  RNA_def_property_ui_text(prop, "Box Color", "");
+  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
+
   prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ);
   RNA_def_property_float_sdna(prop, NULL, "loc");
   RNA_def_property_ui_text(prop, "Location", "Location of the text");
@@ -2878,6 +2886,14 @@ static void rna_def_text(StructRNA *srna)
   RNA_def_property_ui_range(prop, 0.0, 1.0, 1, -1);
   RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
 
+  prop = RNA_def_property(srna, "box_margin", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_float_sdna(prop, NULL, "box_margin");
+  RNA_def_property_ui_text(prop, "Box Margin", "Box margin as factor of image width");
+  RNA_def_property_range(prop, 0, 1.0);
+  RNA_def_property_ui_range(prop, 0.0, 1.0, 1, -1);
+  RNA_def_property_float_default(prop, 0.01f);
+  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
+
   prop = RNA_def_property(srna, "align_x", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_sdna(prop, NULL, "align");
   RNA_def_property_enum_items(prop, text_align_x_items);
@@ -2900,6 +2916,11 @@ static void rna_def_text(StructRNA *srna)
   RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_TEXT_SHADOW);
   RNA_def_property_ui_text(prop, "Shadow", "Display shadow behind text");
   RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
+
+  prop = RNA_def_property(srna, "use_box", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_TEXT_BOX);
+  RNA_def_property_ui_text(prop, "Shadow", "Display colored box behind text");
+  RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
 }
 
 static void rna_def_color_mix(StructRNA *srna)
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index 041ef1c411d..4c7b1566f68 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -3788,6 +3788,11 @@ static void init_text_effect(Sequence *seq)
 
   copy_v4_fl(data->color, 1.0f);
   data->shadow_color[3] = 1.0f;
+  data->box_color[0] = 0.5f;
+  data->box_color[1] = 0.5f;
+  data->box_color[2] = 0.5f;
+  data->box_color[3] = 1.0f;
+  data->box_margin = 0.01f;
 
   BLI_strncpy(data->text, "Text", sizeof(data->text));
 
@@ -3929,18 +3934,18 @@ static ImBuf *do_text_effect(const SeqRenderData *context,
   x = (data->loc[0] * width);
   y = (data->loc[1] * height) + y_ofs;
 
+  /* vars for calculating wordwrap and optional box */
+  struct {
+    struct ResultBLF info;
+    rctf rect;
+  } wrap;
+
+  BLF_boundbox_ex(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info);
+
   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(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info);
-
     if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) {
       x -= BLI_rctf_size_x(&wrap.rect);
     }
@@ -3959,8 +3964,34 @@ static ImBuf *do_text_effect(const SeqRenderData *context,
     }
   }
 
+  if (data->flag & SEQ_TEXT_BOX) {
+    if (out->rect) {
+      const int margin = data->box_margin * width;
+      const int minx = x + wrap.rect.xmin - margin;
+      const int maxx = x + wrap.rect.xmax + margin;
+      const int miny = y + wrap.rect.ymin - margin;
+      const int maxy = y + wrap.rect.ymax + margin;
+
+      if (data->flag & SEQ_TEXT_SHADOW) {
+        /* draw a shadow behind the box */
+        int shadow_offset = 0.005f * width;
+
+        if (shadow_offset == 0) {
+          shadow_offset = 1;
+        }
+
+        IMB_rectfill_area_replace(out,
+                                  data->shadow_color,
+                                  minx + shadow_offset,
+                                  miny - shadow_offset,
+                                  maxx + shadow_offset,
+                                  maxy - shadow_offset);
+      }
+      IMB_rectfill_area_replace(out, data->box_color, minx, miny, maxx, maxy);
+    }
+  }
   /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */
-  if (data->flag & SEQ_TEXT_SHADOW) {
+  else if (data->flag & SEQ_TEXT_SHADOW) {
     int fontx, fonty;
     fontx = BLF_width_max(font);
     fonty = line_height;



More information about the Bf-blender-cvs mailing list