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:
authorDalai Felinto <dfelinto@gmail.com>2018-09-05 04:21:12 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-09-05 04:33:14 +0300
commit312af01fb4faa7d1ff0dea4d2ef936caa9af4c67 (patch)
tree260a1b6625b210d319b2baf7433287051cc5ff78 /source/blender/blenkernel/intern/font.c
parent053669e4aec11e5dbad61dd7308fe68a23f67034 (diff)
3D Text: improvements to vertical alignment
They way Blender handles vertical alignment is very buggy: - Top-Base: It works perfectly. - Bottom: It is actually bottom-baseline, and it fails when line size is != 1.0 when working with text boxes. - Top: Poorly implemented, it should use font's ascent (recommended distance from baseline), so it has room for accents, but it's not one line distance far from the origin (as it is now). - Center: Poorly implemented. This is tricky since there is no silver bullet. To clear this situation I created a new option (Bottom-Baseline), and addressed the issues above. I'm getting the ascent and descent from freetype2, and use this for padding above/below the text. Also for vertically centering the text.
Diffstat (limited to 'source/blender/blenkernel/intern/font.c')
-rw-r--r--source/blender/blenkernel/intern/font.c81
1 files changed, 55 insertions, 26 deletions
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)
{