[Bf-blender-cvs] [50253272bcd] experimental-build: Fixes for font vertical alignment + fallback for internal font
Dalai Felinto
noreply at git.blender.org
Fri Aug 31 23:40:42 CEST 2018
Commit: 50253272bcd655751bbc9abd286c80ddd0299fdd
Author: Dalai Felinto
Date: Fri Aug 31 18:40:02 2018 -0300
Branches: experimental-build
https://developer.blender.org/rB50253272bcd655751bbc9abd286c80ddd0299fdd
Fixes for font vertical alignment + fallback for internal font
===================================================================
M source/blender/blenkernel/intern/font.c
M source/blender/blenlib/BLI_vfontdata.h
M source/blender/blenlib/intern/freetypefont.c
M source/blender/makesdna/DNA_curve_types.h
M source/blender/makesrna/intern/rna_curve.c
===================================================================
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index b5fba6d30e8..45a581324a8 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -635,6 +635,23 @@ 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 EM_HEIGHT vfd->em_height
+#define ASCENT vfd->ascender * EM_HEIGHT
+#define DESCENT EM_HEIGHT - ASCENT
+
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,27 +1036,33 @@ 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. */
+#define TEXTBOX_Y_ORIGIN 1.0f
- lines = ct_last->linenr - ct_textbox->linenr + 1;
- if (mem[slen - 1] == '\n') {
- lines++;
+ switch (cu->align_y) {
+ case CU_ALIGN_Y_TOP_BASELINE:
+ break;
+ case CU_ALIGN_Y_TOP:
+ yoff = TEXTBOX_Y_ORIGIN - ASCENT;
+ break;
+ case CU_ALIGN_Y_CENTER:
+ yoff = (((EM_HEIGHT + (lnr - 1) * linedist) * 0.5f) - ASCENT)
+ -(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;
+ break;
}
- 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);
- }
+#undef TEXTBOX_Y_ORIGIN
ct = ct_textbox;
for (i = i_textbox - 1; i < slen; i++) {
@@ -1049,18 +1072,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;
+ break;
+ case CU_ALIGN_Y_CENTER:
+ yoff = ((EM_HEIGHT + (lnr - 1) * linedist) * 0.5f) - ASCENT;
+ break;
+ case CU_ALIGN_Y_BOTTOM_BASELINE:
+ yoff = (lnr - 1) * linedist;
+ break;
+ case CU_ALIGN_Y_BOTTOM:
+ yoff = (lnr - 1) * linedist + DESCENT;
+ break;
}
for (i = 0; i <= slen; i++) {
@@ -1339,6 +1369,9 @@ finally:
#undef MARGIN_Y_MIN
}
+#undef DESCENT
+#undef ASCENT
+#undef EM_HEIGHT
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..b1732da2aad 100644
--- a/source/blender/blenlib/BLI_vfontdata.h
+++ b/source/blender/blenlib/BLI_vfontdata.h
@@ -43,6 +43,8 @@ typedef struct VFontData {
struct GHash *characters;
char name[128];
float scale;
+ 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..afc34037e88 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -359,10 +359,26 @@ 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));
+
+ 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}
};
More information about the Bf-blender-cvs
mailing list