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:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py7
-rw-r--r--source/blender/blenkernel/intern/font.c81
-rw-r--r--source/blender/blenlib/BLI_vfontdata.h3
-rw-r--r--source/blender/blenlib/intern/freetypefont.c17
-rw-r--r--source/blender/makesdna/DNA_curve_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_curve.c2
6 files changed, 83 insertions, 30 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 671cff4ebb4..9ba6bc70892 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -398,12 +398,13 @@ class DATA_PT_paragraph_alignment(CurveButtonsPanelText, Panel):
def draw(self, context):
layout = self.layout
- layout.use_property_split = False
+ layout.use_property_split = True
text = context.curve
- layout.row().prop(text, "align_x", expand=True)
- layout.row().prop(text, "align_y", expand=True)
+ col = layout.column()
+ col.prop(text, "align_x", text="Horizontal")
+ col.prop(text, "align_y", text="Vertical")
class DATA_PT_paragraph_spacing(CurveButtonsPanelText, Panel):
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index b5fba6d30e8..31de8d8d51e 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -635,6 +635,22 @@ struct TempLineInfo {
int wspace_nr; /* number of whitespaces of line */
};
+/**
+ * Font metric values explained:
+ *
+ * Baseline: Line where the text "rests", used as the origin vertical position for the glyphs.
+ * Em height: Space most glyphs should fit within.
+ * Ascent: the recommended distance above the baseline to fit most characters.
+ * Descent: the recommended distance below the baseline to fit most characters.
+ *
+ * We obtain ascent and descent from the font itself (FT_Face->ascender / face->height).
+ * And in some cases it is even the same value as FT_Face->bbox.yMax/yMin (font top and bottom respectively).
+ *
+ * The em_height here is relative to FT_Face->bbox.
+*/
+#define ASCENT(vfd) ((vfd)->ascender * (vfd)->em_height)
+#define DESCENT(vfd) ((vfd)->em_height - ASCENT(vfd))
+
bool BKE_vfont_to_curve_ex(Object *ob, Curve *cu, int mode, ListBase *r_nubase,
const wchar_t **r_text, int *r_text_len, bool *r_text_free,
struct CharTrans **r_chartransdata)
@@ -1019,26 +1035,30 @@ 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 */
+ if (i_textbox < slen) {
+ /* All previous textboxes are 'full', only align the last used text-box. */
+ struct CharTrans *ct_textbox = chartransdata + i_textbox;
float yoff = 0.0f;
- int lines;
- struct CharTrans *ct_last, *ct_textbox;
- ct_last = chartransdata + slen - 1;
- ct_textbox = chartransdata + i_textbox;
+ /* The initial Y origin of the textbox is harcoded to 1.0f * text scale. */
+ const float textbox_y_origin = 1.0f;
- 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);
+ switch (cu->align_y) {
+ case CU_ALIGN_Y_TOP_BASELINE:
+ break;
+ case CU_ALIGN_Y_TOP:
+ yoff = textbox_y_origin - ASCENT(vfd);
+ break;
+ case CU_ALIGN_Y_CENTER:
+ yoff = ((((vfd->em_height + (lnr - 1) * linedist) * 0.5f) - ASCENT(vfd)) -
+ (tb_scale.h * 0.5f) + textbox_y_origin);
+ break;
+ case CU_ALIGN_Y_BOTTOM_BASELINE:
+ yoff = textbox_y_origin + ((lnr - 1) * linedist) - tb_scale.h;
+ break;
+ case CU_ALIGN_Y_BOTTOM:
+ yoff = textbox_y_origin + ((lnr - 1) * linedist) - tb_scale.h + DESCENT(vfd);
+ break;
}
ct = ct_textbox;
@@ -1049,18 +1069,25 @@ makebreak:
}
}
else {
- /* non text-box case handled separately */
+ /* Non text-box case handled separately. */
ct = chartransdata;
float yoff = 0.0f;
- 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;
+ switch (cu->align_y) {
+ case CU_ALIGN_Y_TOP_BASELINE:
+ break;
+ case CU_ALIGN_Y_TOP:
+ yoff = -ASCENT(vfd);
+ break;
+ case CU_ALIGN_Y_CENTER:
+ yoff = ((vfd->em_height + (lnr - 1) * linedist) * 0.5f) - ASCENT(vfd);
+ break;
+ case CU_ALIGN_Y_BOTTOM_BASELINE:
+ yoff = (lnr - 1) * linedist;
+ break;
+ case CU_ALIGN_Y_BOTTOM:
+ yoff = (lnr - 1) * linedist + DESCENT(vfd);
+ break;
}
for (i = 0; i <= slen; i++) {
@@ -1339,6 +1366,8 @@ finally:
#undef MARGIN_Y_MIN
}
+#undef DESCENT
+#undef ASCENT
bool BKE_vfont_to_curve_nubase(Object *ob, int mode, ListBase *r_nubase)
{
diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h
index 1cc1ef17486..892d084f5ee 100644
--- a/source/blender/blenlib/BLI_vfontdata.h
+++ b/source/blender/blenlib/BLI_vfontdata.h
@@ -43,6 +43,9 @@ typedef struct VFontData {
struct GHash *characters;
char name[128];
float scale;
+ /* Calculated from the font. */
+ float em_height;
+ float ascender;
} VFontData;
typedef struct VChar {
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index c7604b3cd6d..3f3868bea45 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -359,10 +359,27 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
lcode = charcode = FT_Get_First_Char(face, &glyph_index);
}
+ /* Blender default BFont is not "complete". */
+ const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
+ (face->ascender != face->descender);
+
+ if (complete_font) {
+ /* We can get descender as well, but we simple store descender in relation to the ascender.
+ * Also note that descender is stored as a negative number. */
+ vfd->ascender = (float)face->ascender / (face->ascender - face->descender);
+ }
+ else {
+ vfd->ascender = 0.8f;
+ vfd->em_height = 1.0f;
+ }
/* Adjust font size */
if (face->bbox.yMax != face->bbox.yMin) {
vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin));
+
+ if (complete_font) {
+ vfd->em_height = (float)(face->ascender - face->descender) / (face->bbox.yMax - face->bbox.yMin);
+ }
}
else {
vfd->scale = 1.0f / 1000.0f;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 6e3573b9f80..7c7eaae4949 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -334,7 +334,8 @@ enum {
CU_ALIGN_Y_TOP_BASELINE = 0,
CU_ALIGN_Y_TOP = 1,
CU_ALIGN_Y_CENTER = 2,
- CU_ALIGN_Y_BOTTOM = 3,
+ CU_ALIGN_Y_BOTTOM_BASELINE = 3,
+ CU_ALIGN_Y_BOTTOM = 4,
};
/* Nurb.flag */
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 6b294b9b3cd..a90a5cdff90 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -969,6 +969,8 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
{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"},
+ {CU_ALIGN_Y_BOTTOM_BASELINE, "BOTTOM_BASELINE", 0, "Bottom Base-Line",
+ "Align text to the bottom but use the base-line of the text"},
{0, NULL, 0, NULL, NULL}
};