diff --git a/panda/src/text/config_text.cxx b/panda/src/text/config_text.cxx index 01ecbb208e..9f5691d5f4 100644 --- a/panda/src/text/config_text.cxx +++ b/panda/src/text/config_text.cxx @@ -38,7 +38,7 @@ const bool text_flatten = config_text.GetBool("text-flatten", true); const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false); const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1); const int text_texture_margin = config_text.GetInt("text-texture-margin", 2); -const float text_poly_margin = config_text.GetFloat("text-poly-margin", 0.6f); +const float text_poly_margin = config_text.GetFloat("text-poly-margin", 0.0f); const int text_page_x_size = config_text.GetInt("text-page-x-size", 256); const int text_page_y_size = config_text.GetInt("text-page-y-size", 256); const float text_point_size = config_text.GetFloat("text-point-size", 10.0f); diff --git a/panda/src/text/dynamicTextFont.I b/panda/src/text/dynamicTextFont.I index f63571fc4d..717213268f 100644 --- a/panda/src/text/dynamicTextFont.I +++ b/panda/src/text/dynamicTextFont.I @@ -151,8 +151,10 @@ get_texture_margin() const { // helps prevent the edges of the glyphs from being cut // off at small minifications. It is not related to the // amount of extra pixels reserved in the texture map -// (but it should be no larger than this number, which -// is controlled by set_texture_margin()). +// (but it should be set somewhat smaller than this +// number, which is controlled by set_texture_margin(), +// to prevent bleed-in from neighboring letters in the +// texture). //////////////////////////////////////////////////////////////////// INLINE void DynamicTextFont:: set_poly_margin(float poly_margin) { diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 2ac4cc0c26..2b1c21330f 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -55,8 +55,19 @@ PT(TextFont) TextNode::_default_font; bool TextNode::_loaded_default_font = false; TextNode::Encoding TextNode::_default_encoding; -// This is the factor by which CP_tiny scales the character down. -static const float tiny_accent_scale = 0.3f; +// This is the factor by which CT_small scales the character down. +static const float small_accent_scale = 0.6f; + +// This is the factor by which CT_tiny scales the character down. +static const float tiny_accent_scale = 0.4f; + +// This is the factor by which CT_squash scales the character in X and Y. +static const float squash_accent_scale_x = 0.8f; +static const float squash_accent_scale_y = 0.5f; + +// This is the factor by which CT_small_squash scales the character in X and Y. +static const float small_squash_accent_scale_x = 0.6f; +static const float small_squash_accent_scale_y = 0.3f; // This is the factor by which the advance is reduced for the first // character of a two-character ligature. @@ -1037,7 +1048,7 @@ assemble_row(wstring::iterator &si, const wstring::iterator &send, // got and it's probably pretty close. LMatrix4f rotate = LMatrix4f::translate_mat(-centroid) * - LMatrix4f::rotate_mat_normaxis(180.0f, LVecBase3f(0.0f, 1.0f, 0.0f)) * + LMatrix4f::rotate_mat_normaxis(180.0f, LVecBase3f(0.0f, -1.0f, 0.0f)) * LMatrix4f::translate_mat(centroid); glyph_xform *= rotate; } @@ -1331,57 +1342,68 @@ tack_on_accent(UnicodeLatinMap::AccentType accent_type, // have a grave accent character, but a lot of fonts put the // reverse apostrophe there instead. And some fonts (particularly // fonts from mf) don't even do backslash. - tack_on_accent('/', CP_above, CT_tiny_mirror_x, min_vert, max_vert, centroid, + tack_on_accent('/', CP_above, CT_small_squash_mirror_y, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_acute: - tack_on_accent('/', CP_above, CT_tiny, min_vert, max_vert, centroid, + tack_on_accent('/', CP_above, CT_small_squash, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_breve: - tack_on_accent(')', CP_above, CT_tiny_rotate_90, min_vert, max_vert, centroid, + tack_on_accent(')', CP_above, CT_tiny_rotate_270, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_inverted_breve: - tack_on_accent('(', CP_above, CT_tiny_rotate_90, min_vert, max_vert, centroid, + tack_on_accent('(', CP_above, CT_tiny_rotate_270, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_circumflex: tack_on_accent('^', CP_above, CT_none, min_vert, max_vert, centroid, - font, dest, geom_array, num_geoms); + font, dest, geom_array, num_geoms) || + tack_on_accent('v', CP_above, CT_squash_mirror_y, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_circumflex_below: tack_on_accent('^', CP_below, CT_none, min_vert, max_vert, centroid, - font, dest, geom_array, num_geoms); + font, dest, geom_array, num_geoms) || + tack_on_accent('v', CP_below, CT_squash_mirror_y, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_caron: tack_on_accent('^', CP_above, CT_mirror_y, min_vert, max_vert, centroid, - font, dest, geom_array, num_geoms); + font, dest, geom_array, num_geoms) || + tack_on_accent('v', CP_above, CT_squash, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); + break; case UnicodeLatinMap::AT_tilde: tack_on_accent('~', CP_above, CT_none, min_vert, max_vert, centroid, - font, dest, geom_array, num_geoms); + font, dest, geom_array, num_geoms) || + tack_on_accent('s', CP_above, CT_squash_mirror_diag, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_tilde_below: tack_on_accent('~', CP_below, CT_none, min_vert, max_vert, centroid, - font, dest, geom_array, num_geoms); + font, dest, geom_array, num_geoms) || + tack_on_accent('s', CP_below, CT_squash_mirror_diag, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_diaeresis: - tack_on_accent(':', CP_above, CT_rotate_90, min_vert, max_vert, centroid, + tack_on_accent(':', CP_above, CT_small_rotate_270, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; case UnicodeLatinMap::AT_diaeresis_below: - tack_on_accent(':', CP_below, CT_rotate_90, min_vert, max_vert, centroid, + tack_on_accent(':', CP_below, CT_small_rotate_270, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); break; @@ -1416,8 +1438,12 @@ tack_on_accent(UnicodeLatinMap::AccentType accent_type, break; case UnicodeLatinMap::AT_cedilla: + tack_on_accent('c', CP_bottom, CT_tiny_mirror_x, min_vert, max_vert, centroid, + font, dest, geom_array, num_geoms); + /* tack_on_accent(',', CP_bottom, CT_none, min_vert, max_vert, centroid, font, dest, geom_array, num_geoms); + */ break; case UnicodeLatinMap::AT_comma_below: @@ -1445,9 +1471,11 @@ tack_on_accent(UnicodeLatinMap::AccentType accent_type, // Function: TextNode::tack_on_accent // Access: Private // Description: Generates a cheesy accent mark above (or below, etc.) -// the character. +// the character. Returns true if successful, or false +// if the named accent character doesn't exist in the +// font. //////////////////////////////////////////////////////////////////// -void TextNode:: +bool TextNode:: tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement, TextNode::CheesyTransform transform, const LPoint3f &min_vert, const LPoint3f &max_vert, @@ -1473,23 +1501,44 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement, case CT_mirror_x: accent_mat = LMatrix4f::scale_mat(-1.0f, 1.0f, 1.0f); - - t = -min_accent[0]; + t = min_accent[0]; min_accent[0] = -max_accent[0]; - max_accent[0] = t; + max_accent[0] = -t; break; case CT_mirror_y: - accent_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); - - t = -min_accent[2]; + accent_mat = LMatrix4f::scale_mat(1.0f, 1.0f, -1.0f); + t = min_accent[2]; min_accent[2] = -max_accent[2]; - max_accent[2] = t; + max_accent[2] = -t; break; case CT_rotate_90: accent_mat = - LMatrix4f::rotate_mat_normaxis(90.0f, LVecBase3f(0.0f, 1.0f, 0.0f)); + LMatrix4f::rotate_mat_normaxis(90.0f, LVecBase3f(0.0f, -1.0f, 0.0f)); + // rotate min, max + t = min_accent[0]; + u = max_accent[0]; + max_accent[0] = -min_accent[2]; + min_accent[0] = -max_accent[2]; + max_accent[2] = u; + min_accent[2] = t; + break; + + case CT_rotate_180: + accent_mat = LMatrix4f::scale_mat(-1.0f, -1.0f, 1.0f); + + t = min_accent[0]; + min_accent[0] = -max_accent[0]; + max_accent[0] = -t; + t = min_accent[2]; + min_accent[2] = -max_accent[2]; + max_accent[2] = -t; + break; + + case CT_rotate_270: + accent_mat = + LMatrix4f::rotate_mat_normaxis(270.0f, LVecBase3f(0.0f, -1.0f, 0.0f)); // rotate min, max t = min_accent[0]; u = max_accent[0]; @@ -1499,6 +1548,74 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement, max_accent[2] = -t; break; + case CT_squash: + accent_mat = LMatrix4f::scale_mat(squash_accent_scale_x, 1.0f, squash_accent_scale_y); + min_accent[0] *= squash_accent_scale_x; + max_accent[0] *= squash_accent_scale_x; + min_accent[2] *= squash_accent_scale_y; + max_accent[2] *= squash_accent_scale_y; + break; + + case CT_squash_mirror_y: + accent_mat = LMatrix4f::scale_mat(squash_accent_scale_x, 1.0f, -squash_accent_scale_y); + min_accent[0] *= squash_accent_scale_x; + max_accent[0] *= squash_accent_scale_x; + t = min_accent[2]; + min_accent[2] = -max_accent[2] * squash_accent_scale_y; + max_accent[2] = -t * squash_accent_scale_y; + break; + + case CT_squash_mirror_diag: + accent_mat = + LMatrix4f::rotate_mat_normaxis(270.0f, LVecBase3f(0.0f, -1.0f, 0.0f)) * + LMatrix4f::scale_mat(-squash_accent_scale_x, 1.0f, squash_accent_scale_y); + + // rotate min, max + t = min_accent[0]; + u = max_accent[0]; + min_accent[0] = min_accent[2] * -squash_accent_scale_x; + max_accent[0] = max_accent[2] * -squash_accent_scale_x; + min_accent[2] = -u * squash_accent_scale_y; + max_accent[2] = -t * squash_accent_scale_y; + break; + + case CT_small_squash: + accent_mat = LMatrix4f::scale_mat(small_squash_accent_scale_x, 1.0f, small_squash_accent_scale_y); + min_accent[0] *= small_squash_accent_scale_x; + max_accent[0] *= small_squash_accent_scale_x; + min_accent[2] *= small_squash_accent_scale_y; + max_accent[2] *= small_squash_accent_scale_y; + break; + + case CT_small_squash_mirror_y: + accent_mat = LMatrix4f::scale_mat(small_squash_accent_scale_x, 1.0f, -small_squash_accent_scale_y); + min_accent[0] *= small_squash_accent_scale_x; + max_accent[0] *= small_squash_accent_scale_x; + t = min_accent[2]; + min_accent[2] = -max_accent[2] * small_squash_accent_scale_y; + max_accent[2] = -t * small_squash_accent_scale_y; + break; + + case CT_small: + accent_mat = LMatrix4f::scale_mat(small_accent_scale); + min_accent *= small_accent_scale; + max_accent *= small_accent_scale; + break; + + case CT_small_rotate_270: + accent_mat = + LMatrix4f::rotate_mat_normaxis(270.0f, LVecBase3f(0.0f, -1.0f, 0.0f)) * + LMatrix4f::scale_mat(small_accent_scale); + + // rotate min, max + t = min_accent[0]; + u = max_accent[0]; + min_accent[0] = min_accent[2] * small_accent_scale; + max_accent[0] = max_accent[2] * small_accent_scale; + min_accent[2] = -u * small_accent_scale; + max_accent[2] = -t * small_accent_scale; + break; + case CT_tiny: accent_mat = LMatrix4f::scale_mat(tiny_accent_scale); min_accent *= tiny_accent_scale; @@ -1508,14 +1625,16 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement, case CT_tiny_mirror_x: accent_mat = LMatrix4f::scale_mat(-tiny_accent_scale, 1.0f, tiny_accent_scale); - t = -min_accent[0] * tiny_accent_scale; + t = min_accent[0]; min_accent[0] = -max_accent[0] * tiny_accent_scale; - max_accent[0] = t; + max_accent[0] = -t * tiny_accent_scale; + min_accent[2] *= tiny_accent_scale; + max_accent[2] *= tiny_accent_scale; break; - case CT_tiny_rotate_90: + case CT_tiny_rotate_270: accent_mat = - LMatrix4f::rotate_mat_normaxis(90.0f, LVecBase3f(0.0f, 1.0f, 0.0f)) * + LMatrix4f::rotate_mat_normaxis(270.0f, LVecBase3f(0.0f, -1.0f, 0.0f)) * LMatrix4f::scale_mat(tiny_accent_scale); // rotate min, max @@ -1568,9 +1687,13 @@ tack_on_accent(char accent_mark, TextNode::CheesyPlacement placement, dest->add_geom(accent_geom, accent_glyph->get_state()); geom_array[num_geoms++] = accent_geom; + + return true; } } } + + return false; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/text/textNode.h b/panda/src/text/textNode.h index 203c014b27..69e792b789 100644 --- a/panda/src/text/textNode.h +++ b/panda/src/text/textNode.h @@ -281,9 +281,18 @@ private: CT_mirror_x, CT_mirror_y, CT_rotate_90, + CT_rotate_180, + CT_rotate_270, + CT_squash, + CT_squash_mirror_y, + CT_squash_mirror_diag, + CT_small_squash, + CT_small_squash_mirror_y, + CT_small, + CT_small_rotate_270, CT_tiny, CT_tiny_mirror_x, - CT_tiny_rotate_90, + CT_tiny_rotate_270, }; void get_character_glyphs(int character, TextFont *font, @@ -298,7 +307,7 @@ private: const LPoint3f ¢roid, TextFont *font, GeomNode *dest, Geom *geom_array[], int &num_geoms); - void tack_on_accent(char accent_mark, CheesyPlacement placement, + bool tack_on_accent(char accent_mark, CheesyPlacement placement, CheesyTransform transform, const LPoint3f &min_vert, const LPoint3f &max_vert, const LPoint3f ¢roid,