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 "
|
||||
"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
|
||||
("text-anisotropic-degree", 1,
|
||||
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_dynamic_merge;
|
||||
extern ConfigVariableBool text_kerning;
|
||||
extern ConfigVariableInt text_anisotropic_degree;
|
||||
extern ConfigVariableInt text_texture_margin;
|
||||
extern ConfigVariableDouble text_poly_margin;
|
||||
|
@ -278,6 +278,32 @@ get_glyph(int character, CPT(TextGlyph) &glyph) {
|
||||
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.
|
||||
|
@ -123,6 +123,7 @@ PUBLISHED:
|
||||
|
||||
public:
|
||||
virtual bool get_glyph(int character, CPT(TextGlyph) &glyph);
|
||||
virtual PN_stdfloat get_kerning(int first, int second) const;
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
|
@ -609,6 +609,8 @@ assemble_text() {
|
||||
* Returns the width of a single character, according to its associated font.
|
||||
* This also correctly calculates the width of cheesy ligatures and accented
|
||||
* characters, which may not exist in the font as such.
|
||||
*
|
||||
* This does not take kerning into account, however.
|
||||
*/
|
||||
PN_stdfloat TextAssembler::
|
||||
calc_width(wchar_t character, const TextProperties &properties) {
|
||||
@ -1399,6 +1401,9 @@ assemble_row(TextAssembler::TextRow &row,
|
||||
PN_stdfloat xpos = 0.0f;
|
||||
align = TextProperties::A_left;
|
||||
|
||||
// Remember previous character, for kerning.
|
||||
int prev_char = -1;
|
||||
|
||||
bool underscore = false;
|
||||
PN_stdfloat underscore_start = 0.0f;
|
||||
const TextProperties *underscore_properties = NULL;
|
||||
@ -1450,11 +1455,13 @@ assemble_row(TextAssembler::TextRow &row,
|
||||
if (character == ' ') {
|
||||
// A space is a special case.
|
||||
xpos += properties->get_glyph_scale() * properties->get_text_scale() * font->get_space_advance();
|
||||
prev_char = -1;
|
||||
|
||||
} else if (character == '\t') {
|
||||
// So is a tab character.
|
||||
PN_stdfloat tab_width = properties->get_tab_width();
|
||||
xpos = (floor(xpos / tab_width) + 1.0f) * tab_width;
|
||||
prev_char = -1;
|
||||
|
||||
} else if (character == text_soft_hyphen_key) {
|
||||
// And so is the 'soft-hyphen' key character.
|
||||
@ -1493,6 +1500,7 @@ assemble_row(TextAssembler::TextRow &row,
|
||||
placed_glyphs.push_back(placement);
|
||||
|
||||
xpos += advance * glyph_scale;
|
||||
prev_char = -1;
|
||||
|
||||
} else {
|
||||
// A printable character.
|
||||
@ -1521,6 +1529,14 @@ assemble_row(TextAssembler::TextRow &row,
|
||||
<< "\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
|
||||
// this character. Normally, there is only one Geom per character, but
|
||||
// it may involve multiple Geoms if we need to add cheesy accents or
|
||||
|
@ -54,6 +54,16 @@ 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);
|
||||
|
||||
virtual PN_stdfloat get_kerning(int first, int second) const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user