diff --git a/devel/80_5.tmu b/devel/80_5.tmu new file mode 100644 index 0000000000..836689ef1f --- /dev/null +++ b/devel/80_5.tmu @@ -0,0 +1,20 @@ +> + +> + +<\body> + |2+>|2+|2+>>|1+|2+>|2+|2+>>> > + + <\equation*> + |2+>|2+|2+>>|1+|2+>|2+|2+>>>\ + + + +<\initial> + <\collection> + + + + + + diff --git a/src/Graphics/Fonts/font.cpp b/src/Graphics/Fonts/font.cpp index ac80b98303..1386718821 100644 --- a/src/Graphics/Fonts/font.cpp +++ b/src/Graphics/Fonts/font.cpp @@ -100,6 +100,15 @@ font_rep::copy_math_pars (font fn) { upper_limit_baseline_rise_min= fn->upper_limit_baseline_rise_min; lower_limit_gap_min = fn->lower_limit_gap_min; lower_limit_baseline_drop_min= fn->lower_limit_baseline_drop_min; + frac_rule_thickness = fn->frac_rule_thickness; + frac_num_shift_up = fn->frac_num_shift_up; + frac_num_disp_shift_up = fn->frac_num_disp_shift_up; + frac_num_gap_min = fn->frac_num_gap_min; + frac_num_disp_gap_min = fn->frac_num_disp_gap_min; + frac_denom_shift_down = fn->frac_denom_shift_down; + frac_denom_disp_shift_down = fn->frac_denom_disp_shift_down; + frac_denom_gap_min = fn->frac_denom_gap_min; + frac_denom_disp_gap_min = fn->frac_denom_disp_gap_min; } void diff --git a/src/Graphics/Fonts/font.hpp b/src/Graphics/Fonts/font.hpp index 21475fb54e..ee8105a4a3 100644 --- a/src/Graphics/Fonts/font.hpp +++ b/src/Graphics/Fonts/font.hpp @@ -79,6 +79,15 @@ struct font_rep : rep { SI upper_limit_baseline_rise_min; SI lower_limit_gap_min; SI lower_limit_baseline_drop_min; + SI frac_rule_thickness; + SI frac_num_shift_up; + SI frac_num_disp_shift_up; + SI frac_num_gap_min; + SI frac_num_disp_gap_min; + SI frac_denom_shift_down; + SI frac_denom_disp_shift_down; + SI frac_denom_gap_min; + SI frac_denom_disp_gap_min; SI wpt; // width of one point in font SI hpt; // height of one point in font (usually wpt) diff --git a/src/Plugins/Freetype/unicode_font.cpp b/src/Plugins/Freetype/unicode_font.cpp index e180bfc920..5e0af9993e 100644 --- a/src/Plugins/Freetype/unicode_font.cpp +++ b/src/Plugins/Freetype/unicode_font.cpp @@ -169,8 +169,11 @@ struct unicode_font_rep : font_rep { SI get_rsup_correction (string s); SI get_wide_correction (string s, int mode); - SI design_unit_to_metric (int du); - int metric_to_design_unit (SI m); + double design_unit_to_metric_factor; + double metric_to_design_unit_factor; + void init_design_unit_factor (); + SI design_unit_to_metric (int du); + int metric_to_design_unit (SI m); }; /****************************************************************************** @@ -444,6 +447,8 @@ unicode_font_rep::unicode_font_rep (string name, string family2, int size2, this->math_face = math_face2; this->math_table= math_face2->math_table; math_type = MATH_TYPE_OPENTYPE; + init_design_unit_factor (); + // limit boxes upper_limit_gap_min= design_unit_to_metric (math_table->constants_table[upperLimitGapMin]); upper_limit_baseline_rise_min= design_unit_to_metric ( @@ -452,6 +457,26 @@ unicode_font_rep::unicode_font_rep (string name, string family2, int size2, design_unit_to_metric (math_table->constants_table[lowerLimitGapMin]); lower_limit_baseline_drop_min= design_unit_to_metric ( math_table->constants_table[lowerLimitBaselineDropMin]); + // frac boxes + frac_rule_thickness= design_unit_to_metric ( + math_table->constants_table[fractionRuleThickness]); + frac_num_shift_up= design_unit_to_metric ( + math_table->constants_table[fractionNumeratorShiftUp]); + frac_num_disp_shift_up= design_unit_to_metric ( + math_table->constants_table[fractionNumeratorDisplayStyleShiftUp]); + frac_num_gap_min= design_unit_to_metric ( + math_table->constants_table[fractionNumeratorGapMin]); + frac_num_disp_gap_min= design_unit_to_metric ( + math_table->constants_table[fractionNumDisplayStyleGapMin]); + frac_denom_shift_down= design_unit_to_metric ( + math_table->constants_table[fractionDenominatorShiftDown]); + frac_denom_disp_shift_down= design_unit_to_metric ( + math_table + ->constants_table[fractionDenominatorDisplayStyleShiftDown]); + frac_denom_gap_min= design_unit_to_metric ( + math_table->constants_table[fractionDenominatorGapMin]); + frac_denom_disp_gap_min= design_unit_to_metric ( + math_table->constants_table[fractionDenominatorGapMin]); } } } @@ -1003,41 +1028,32 @@ unicode_font (string family, int size, int hdpi, int vdpi) { * OpenType ******************************************************************************/ +inline void +unicode_font_rep::init_design_unit_factor () { + int units_of_m= 0; + SI em = 0; + // get the design units of the width of 'm' + FT_UInt glyph_index= FT_Get_Char_Index (math_face->ft_face, 'm'); + FT_Load_Glyph (math_face->ft_face, glyph_index, FT_LOAD_NO_SCALE); + units_of_m= math_face->ft_face->glyph->metrics.horiAdvance; + + // get the width of the character 'm' + metric ex; + get_extents ("m", ex); + em= ex->x2 - ex->x1; + + metric_to_design_unit_factor= (double) units_of_m / (double) em; + design_unit_to_metric_factor= (double) em / (double) units_of_m; +} + inline SI unicode_font_rep::design_unit_to_metric (int du) { - // use 'm' as a reference character - static int units_of_m= 0; - static SI em = 0; - if (units_of_m == 0) { - // get the design units of the width of 'm' - FT_UInt glyph_index= FT_Get_Char_Index (math_face->ft_face, 'm'); - FT_Load_Glyph (math_face->ft_face, glyph_index, FT_LOAD_NO_SCALE); - units_of_m= math_face->ft_face->glyph->metrics.horiAdvance; - - // get the width of the character 'm' - metric ex; - get_extents ("m", ex); - em= ex->x2 - ex->x1; - } - return (SI) ((du * em) / units_of_m); + return (SI) design_unit_to_metric_factor * du; } inline int unicode_font_rep::metric_to_design_unit (SI m) { - static int units_of_m= 0; - static SI em = 0; - if (units_of_m == 0) { - // get the units of the character 'm' - FT_UInt glyph_index= FT_Get_Char_Index (math_face->ft_face, 'm'); - FT_Load_Glyph (math_face->ft_face, glyph_index, FT_LOAD_NO_SCALE); - units_of_m= math_face->ft_face->glyph->metrics.horiAdvance; - - // get the width of the character 'm' - metric ex; - get_extents ("m", ex); - em= ex->x2 - ex->x1; - } - return (int) ((m * units_of_m) / em); + return (int) metric_to_design_unit_factor * m; } font diff --git a/src/Typeset/Boxes/Composite/math_boxes.cpp b/src/Typeset/Boxes/Composite/math_boxes.cpp index 4a6bff3253..e48c9d747b 100644 --- a/src/Typeset/Boxes/Composite/math_boxes.cpp +++ b/src/Typeset/Boxes/Composite/math_boxes.cpp @@ -14,6 +14,7 @@ #include "Boxes/composite.hpp" #include "Boxes/construct.hpp" #include "analyze.hpp" +#include "font.hpp" /****************************************************************************** * Miscellaneous routines @@ -62,7 +63,8 @@ italic_correction (box L, box R) { struct frac_box_rep : public composite_box_rep { font fn, sfn; pencil pen; - frac_box_rep (path ip, box b1, box b2, font fn, font sfn, pencil pen); + frac_box_rep (path ip, box b1, box b2, font fn, font sfn, pencil pen, + bool opentype_disp); operator tree () { return tree (TUPLE, "frac", bs[0], bs[1]); } box adjust_kerning (int mode, double factor); box expand_glyphs (int mode, double factor); @@ -70,7 +72,7 @@ struct frac_box_rep : public composite_box_rep { }; frac_box_rep::frac_box_rep (path ip, box b1, box b2, font fn2, font sfn2, - pencil pen2) + pencil pen2, bool opentype_disp) : composite_box_rep (ip), fn (fn2), sfn (sfn2), pen (pen2) { // Italic correction does not lead to nicer results, // because right correction is not equilibrated w.r.t. left correction @@ -84,10 +86,34 @@ frac_box_rep::frac_box_rep (path ip, box b1, box b2, font fn2, font sfn2, SI d = sep >> 1; pencil bar_pen= pen->set_width (bar_w); - insert (b1, (w >> 1) - (b1->x2 >> 1), bar_y + sep + (bar_w >> 1) - b1_y); - insert (b2, (w >> 1) - (b2->x2 >> 1), bar_y - sep - (bar_w >> 1) - b2_y); - insert (line_box (decorate_middle (ip), d, 0, w - d, 0, bar_pen), 0, bar_y); + bool use_opentype= + (fn->math_type == MATH_TYPE_OPENTYPE) && (fn->frac_num_gap_min > 0); + + if (use_opentype) { + SI num_gap_min = fn->frac_num_gap_min; + SI den_gap_min = fn->frac_denom_gap_min; + SI num_shift_up = fn->frac_num_shift_up; + SI den_shift_down= fn->frac_denom_shift_down; + + if (opentype_disp) { + num_gap_min = fn->frac_num_disp_gap_min; + den_gap_min = fn->frac_denom_disp_gap_min; + num_shift_up = fn->frac_num_disp_shift_up; + den_shift_down= fn->frac_denom_disp_shift_down; + } + + insert (b1, (w >> 1) - (b1->x2 >> 1), + max (num_shift_up, bar_y + num_gap_min + (bar_w >> 1) - b1->y1)); + insert (b2, (w >> 1) - (b2->x2 >> 1), + min (-den_shift_down, bar_y - den_gap_min - (bar_w >> 1) - b2->y2)); + insert (line_box (decorate_middle (ip), d, 0, w - d, 0, bar_pen), 0, bar_y); + } + else { + insert (b1, (w >> 1) - (b1->x2 >> 1), bar_y + sep + (bar_w >> 1) - b1_y); + insert (b2, (w >> 1) - (b2->x2 >> 1), bar_y - sep - (bar_w >> 1) - b2_y); + insert (line_box (decorate_middle (ip), d, 0, w - d, 0, bar_pen), 0, bar_y); + } italic_correct (b1); italic_correct (b2); position (); @@ -698,8 +724,9 @@ wide_box_rep::get_bracket_extents (SI& lo, SI& hi) { ******************************************************************************/ box -frac_box (path ip, box b1, box b2, font fn, font sfn, pencil pen) { - return tm_new (ip, b1, b2, fn, sfn, pen); +frac_box (path ip, box b1, box b2, font fn, font sfn, pencil pen, + bool opentype_disp) { + return tm_new (ip, b1, b2, fn, sfn, pen, opentype_disp); } box diff --git a/src/Typeset/Boxes/construct.hpp b/src/Typeset/Boxes/construct.hpp index 1eee08765b..6899a7aca6 100644 --- a/src/Typeset/Boxes/construct.hpp +++ b/src/Typeset/Boxes/construct.hpp @@ -145,7 +145,8 @@ box highlight_box (path ip, box b, box xb, ornament_parameters ps); box highlight_box (path ip, box b, SI w, brush col, brush sunc, brush shad); box art_box (path ip, box b, art_box_parameters ps); -box frac_box (path ip, box b1, box b2, font fn, font sfn, pencil pen); +box frac_box (path ip, box b1, box b2, font fn, font sfn, pencil pen, + bool opentype_disp= false); box sqrt_box (path ip, box b1, box b2, box sqrtb, font fn, pencil pen); box neg_box (path ip, box b, font fn, pencil pen); box tree_box (path ip, array bs, font fn, pencil pen); diff --git a/src/Typeset/Concat/concat_math.cpp b/src/Typeset/Concat/concat_math.cpp index 3dfba83992..0d1da4f561 100644 --- a/src/Typeset/Concat/concat_math.cpp +++ b/src/Typeset/Concat/concat_math.cpp @@ -393,7 +393,7 @@ concater_rep::typeset_frac (tree t, path ip) { if (disp) env->local_end (MATH_DISPLAY, old); else env->local_end_script (old); if (num->w () <= env->frac_max && den->w () <= env->frac_max) - print (frac_box (ip, num, den, env->fn, sfn, env->pen)); + print (frac_box (ip, num, den, env->fn, sfn, env->pen, disp)); else typeset_wide_frac (t, ip); }