diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 81ecd2e8db5..af8431ba1dc 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -370,8 +370,11 @@ class DATA_PT_paragraph(CurveButtonsPanelText, Panel): text = context.curve - layout.label(text="Align:") - layout.prop(text, "align", expand=True) + layout.label(text="Horizontal Alignment:") + layout.prop(text, "align_x", expand=True) + + layout.label(text="Vertical Alignment:") + layout.prop(text, "align_y", expand=True) split = layout.split() diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 98757407e89..b4088934ea4 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -628,6 +628,8 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, int mode, ListBase *r_nubase bool use_textbox; VChar *che; struct CharTrans *chartransdata = NULL, *ct; + /* Text at the beginning of the last used text-box (use for y-axis alignment). */ + int i_textbox = 0; struct TempLineInfo *lineinfo; float *f, xof, yof, xtrax, linedist; float twidth, maxlen = 0; @@ -830,6 +832,7 @@ makebreak: (cu->totbox > (curbox + 1)) && ((-(yof - tb_scale.y)) > (tb_scale.h - linedist) - yof_scale)) { + i_textbox = i + 1; maxlen = 0; curbox++; @@ -983,6 +986,60 @@ makebreak: } } + /* top-baseline is default, in this case, do nothing */ + if (cu->align_y != CU_ALIGN_Y_TOP_BASELINE) { + if (tb_scale.h != 0.0f) { + /* top and top-baseline are the same when text-boxes are used */ + if (cu->align_y != CU_ALIGN_Y_TOP && i_textbox < slen) { + /* all previous textboxes are 'full', only align the last used text-box */ + float yoff; + int lines; + struct CharTrans *ct_last, *ct_textbox; + + ct_last = chartransdata + slen - 1; + ct_textbox = chartransdata + i_textbox; + + lines = ct_last->linenr - ct_textbox->linenr + 1; + if (mem[slen - 1] == '\n') { + lines++; + } + + if (cu->align_y == CU_ALIGN_Y_BOTTOM) { + yoff = (lines * linedist) - tb_scale.h; + } + else if (cu->align_y == CU_ALIGN_Y_CENTER) { + yoff = 0.5f * ((lines * linedist) - tb_scale.h); + } + + ct = ct_textbox; + for (i = i_textbox - 1; i < slen; i++) { + ct->yof += yoff; + ct++; + } + } + } + else { + /* non text-box case handled separately */ + ct = chartransdata; + float yoff; + + if (cu->align_y == CU_ALIGN_Y_TOP) { + yoff = -linedist; + } + else if (cu->align_y == CU_ALIGN_Y_BOTTOM) { + yoff = (lnr - 1.0f) * linedist; + } + else if (cu->align_y == CU_ALIGN_Y_CENTER) { + yoff = (lnr - 2.0f) * linedist * 0.5f; + } + + for (i = 0; i <= slen; i++) { + ct->yof += yoff; + ct++; + } + } + } + MEM_freeN(lineinfo); /* TEXT ON CURVE */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 06200778ee5..01a567931b3 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -946,6 +946,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) cu1 = base->object->data; cu1->spacemode = cu->spacemode; + cu1->align_y = cu->align_y; cu1->spacing = cu->spacing; cu1->linedist = cu->linedist; cu1->shear = cu->shear; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 8f711c1b23b..6d139955ae1 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -230,7 +230,7 @@ typedef struct Curve { /* font part */ short lines; - char spacemode, pad1; + char spacemode, align_y; float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight; float xof, yof; float linewidth; @@ -329,6 +329,14 @@ enum { CU_FLUSH = 4, }; +/* Curve.align_y */ +enum { + CU_ALIGN_Y_TOP_BASELINE = 0, + CU_ALIGN_Y_TOP = 1, + CU_ALIGN_Y_CENTER = 2, + CU_ALIGN_Y_BOTTOM = 3, +}; + /* Nurb.flag */ enum { CU_SMOOTH = 1 << 0, diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index cb7a40a9238..b18fbf962bb 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -952,7 +952,7 @@ static void rna_def_nurbs(BlenderRNA *UNUSED(brna), StructRNA *srna) static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) { PropertyRNA *prop; - + static EnumPropertyItem prop_align_items[] = { {CU_LEFT, "LEFT", 0, "Left", "Align text to the left"}, {CU_MIDDLE, "CENTER", 0, "Center", "Center text"}, @@ -961,14 +961,28 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) {CU_FLUSH, "FLUSH", 0, "Flush", "Align to the left and the right, with equal character spacing"}, {0, NULL, 0, NULL, NULL} }; - + + static EnumPropertyItem prop_align_y_items[] = { + {CU_ALIGN_Y_TOP_BASELINE, "TOP_BASELINE", 0, "Top Base-Line", "Align to top but use the base-line of the text"}, + {CU_ALIGN_Y_TOP, "TOP", 0, "Top", "Align text to the top"}, + {CU_ALIGN_Y_CENTER, "CENTER", 0, "Center", "Align text to the middle"}, + {CU_ALIGN_Y_BOTTOM, "BOTTOM", 0, "Bottom", "Align text to the bottom"}, + {0, NULL, 0, NULL, NULL} + }; + /* Enums */ - prop = RNA_def_property(srna, "align", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(srna, "align_x", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "spacemode"); RNA_def_property_enum_items(prop, prop_align_items); - RNA_def_property_ui_text(prop, "Text Align", "Text align from the object center"); + RNA_def_property_ui_text(prop, "Text Horizontal Align", "Text horizontal align from the object center"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - + + prop = RNA_def_property(srna, "align_y", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "align_y"); + RNA_def_property_enum_items(prop, prop_align_y_items); + RNA_def_property_ui_text(prop, "Text Vertical Align", "Text vertical align from the object center"); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + /* number values */ prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fsize");