mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
text: add experimental kerning support, enabled by 'text-kerning'
This commit is contained in:
parent
4080e03d05
commit
e1c0e7d1d4
@ -48,6 +48,12 @@ ConfigVariableBool text_dynamic_merge
|
|||||||
"operation. Usually it's a performance "
|
"operation. Usually it's a performance "
|
||||||
"advantage to keep this true. See TextNode::set_flatten_flags()."));
|
"advantage to keep this true. See TextNode::set_flatten_flags()."));
|
||||||
|
|
||||||
|
ConfigVariableBool text_kerning
|
||||||
|
("text-kerning", false,
|
||||||
|
PRC_DESC("Set this true to enable kerning when the font provides kerning "
|
||||||
|
"tables. This can result in more aesthetically pleasing spacing "
|
||||||
|
"between individual glyphs."));
|
||||||
|
|
||||||
ConfigVariableInt text_anisotropic_degree
|
ConfigVariableInt text_anisotropic_degree
|
||||||
("text-anisotropic-degree", 1,
|
("text-anisotropic-degree", 1,
|
||||||
PRC_DESC("This is the default anisotropic-degree that is set on dynamic "
|
PRC_DESC("This is the default anisotropic-degree that is set on dynamic "
|
||||||
|
@ -30,6 +30,7 @@ NotifyCategoryDecl(text, EXPCL_PANDA_TEXT, EXPTP_PANDA_TEXT);
|
|||||||
|
|
||||||
extern ConfigVariableBool text_flatten;
|
extern ConfigVariableBool text_flatten;
|
||||||
extern ConfigVariableBool text_dynamic_merge;
|
extern ConfigVariableBool text_dynamic_merge;
|
||||||
|
extern ConfigVariableBool text_kerning;
|
||||||
extern ConfigVariableInt text_anisotropic_degree;
|
extern ConfigVariableInt text_anisotropic_degree;
|
||||||
extern ConfigVariableInt text_texture_margin;
|
extern ConfigVariableInt text_texture_margin;
|
||||||
extern ConfigVariableDouble text_poly_margin;
|
extern ConfigVariableDouble text_poly_margin;
|
||||||
|
@ -278,6 +278,32 @@ get_glyph(int character, CPT(TextGlyph) &glyph) {
|
|||||||
return (glyph_index != 0);
|
return (glyph_index != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount by which to offset the second glyph when it directly
|
||||||
|
* follows the first glyph. This is an additional offset that is added on top
|
||||||
|
* of the advance.
|
||||||
|
*/
|
||||||
|
PN_stdfloat DynamicTextFont::
|
||||||
|
get_kerning(int first, int second) const {
|
||||||
|
if (!_is_valid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_Face face = acquire_face();
|
||||||
|
if (!FT_HAS_KERNING(face)) {
|
||||||
|
release_face(face);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int first_index = FT_Get_Char_Index(face, first);
|
||||||
|
int second_index = FT_Get_Char_Index(face, second);
|
||||||
|
|
||||||
|
FT_Vector delta;
|
||||||
|
FT_Get_Kerning(face, first_index, second_index, FT_KERNING_DEFAULT, &delta);
|
||||||
|
release_face(face);
|
||||||
|
|
||||||
|
return delta.x / (_font_pixels_per_unit * 64);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from both constructors to set up some initial values.
|
* Called from both constructors to set up some initial values.
|
||||||
|
@ -123,6 +123,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool get_glyph(int character, CPT(TextGlyph) &glyph);
|
virtual bool get_glyph(int character, CPT(TextGlyph) &glyph);
|
||||||
|
virtual PN_stdfloat get_kerning(int first, int second) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
@ -609,6 +609,8 @@ assemble_text() {
|
|||||||
* Returns the width of a single character, according to its associated font.
|
* Returns the width of a single character, according to its associated font.
|
||||||
* This also correctly calculates the width of cheesy ligatures and accented
|
* This also correctly calculates the width of cheesy ligatures and accented
|
||||||
* characters, which may not exist in the font as such.
|
* characters, which may not exist in the font as such.
|
||||||
|
*
|
||||||
|
* This does not take kerning into account, however.
|
||||||
*/
|
*/
|
||||||
PN_stdfloat TextAssembler::
|
PN_stdfloat TextAssembler::
|
||||||
calc_width(wchar_t character, const TextProperties &properties) {
|
calc_width(wchar_t character, const TextProperties &properties) {
|
||||||
@ -1399,6 +1401,9 @@ assemble_row(TextAssembler::TextRow &row,
|
|||||||
PN_stdfloat xpos = 0.0f;
|
PN_stdfloat xpos = 0.0f;
|
||||||
align = TextProperties::A_left;
|
align = TextProperties::A_left;
|
||||||
|
|
||||||
|
// Remember previous character, for kerning.
|
||||||
|
int prev_char = -1;
|
||||||
|
|
||||||
bool underscore = false;
|
bool underscore = false;
|
||||||
PN_stdfloat underscore_start = 0.0f;
|
PN_stdfloat underscore_start = 0.0f;
|
||||||
const TextProperties *underscore_properties = NULL;
|
const TextProperties *underscore_properties = NULL;
|
||||||
@ -1450,11 +1455,13 @@ assemble_row(TextAssembler::TextRow &row,
|
|||||||
if (character == ' ') {
|
if (character == ' ') {
|
||||||
// A space is a special case.
|
// A space is a special case.
|
||||||
xpos += properties->get_glyph_scale() * properties->get_text_scale() * font->get_space_advance();
|
xpos += properties->get_glyph_scale() * properties->get_text_scale() * font->get_space_advance();
|
||||||
|
prev_char = -1;
|
||||||
|
|
||||||
} else if (character == '\t') {
|
} else if (character == '\t') {
|
||||||
// So is a tab character.
|
// So is a tab character.
|
||||||
PN_stdfloat tab_width = properties->get_tab_width();
|
PN_stdfloat tab_width = properties->get_tab_width();
|
||||||
xpos = (floor(xpos / tab_width) + 1.0f) * tab_width;
|
xpos = (floor(xpos / tab_width) + 1.0f) * tab_width;
|
||||||
|
prev_char = -1;
|
||||||
|
|
||||||
} else if (character == text_soft_hyphen_key) {
|
} else if (character == text_soft_hyphen_key) {
|
||||||
// And so is the 'soft-hyphen' key character.
|
// And so is the 'soft-hyphen' key character.
|
||||||
@ -1493,6 +1500,7 @@ assemble_row(TextAssembler::TextRow &row,
|
|||||||
placed_glyphs.push_back(placement);
|
placed_glyphs.push_back(placement);
|
||||||
|
|
||||||
xpos += advance * glyph_scale;
|
xpos += advance * glyph_scale;
|
||||||
|
prev_char = -1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// A printable character.
|
// A printable character.
|
||||||
@ -1521,6 +1529,14 @@ assemble_row(TextAssembler::TextRow &row,
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the kerning delta.
|
||||||
|
if (text_kerning) {
|
||||||
|
if (prev_char != -1) {
|
||||||
|
xpos += font->get_kerning(prev_char, character);
|
||||||
|
}
|
||||||
|
prev_char = character;
|
||||||
|
}
|
||||||
|
|
||||||
// Build up a GlyphPlacement, indicating all of the Geoms that go into
|
// Build up a GlyphPlacement, indicating all of the Geoms that go into
|
||||||
// this character. Normally, there is only one Geom per character, but
|
// this character. Normally, there is only one Geom per character, but
|
||||||
// it may involve multiple Geoms if we need to add cheesy accents or
|
// it may involve multiple Geoms if we need to add cheesy accents or
|
||||||
|
@ -54,6 +54,16 @@ TextFont::
|
|||||||
~TextFont() {
|
~TextFont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount by which to offset the second glyph when it directly
|
||||||
|
* follows the first glyph. This is an additional offset that is added on top
|
||||||
|
* of the advance.
|
||||||
|
*/
|
||||||
|
PN_stdfloat TextFont::
|
||||||
|
get_kerning(int first, int second) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -74,6 +74,8 @@ PUBLISHED:
|
|||||||
|
|
||||||
INLINE CPT(TextGlyph) get_glyph(int character);
|
INLINE CPT(TextGlyph) get_glyph(int character);
|
||||||
|
|
||||||
|
virtual PN_stdfloat get_kerning(int first, int second) const;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user