From 3e4db4615f4444dc42f0141ebafda0428f52d95d Mon Sep 17 00:00:00 2001 From: Ke Shi Date: Sun, 13 Oct 2024 17:16:50 +0800 Subject: [PATCH] [80_6] Improving Radical Box Typesetting (#2118) ## What Improving Fraction Box Typesetting. ## Why For some opentype math font, math table gives more precise information about typesetting radical. ## How to test your changes? Open `devel/80_6.tmu`. It is evident that the Asana Math and Fira Math opentype fonts have undergone changes, with significant adjustments in the spacing and positioning before and after the degree symbol. In contrast, the latter two hardcoded opentype fonts have remained unchanged. Before: ![image](https://github.com/user-attachments/assets/70946804-6b11-48e9-b975-a16b716d9697) After: ![image](https://github.com/user-attachments/assets/49e2a0a4-214d-487d-91e8-46a872a083dd) --- devel/80_6.tmu | 40 ++++++++++++++++++++++ src/Graphics/Fonts/font.cpp | 7 ++++ src/Graphics/Fonts/font.hpp | 33 +++++++++++------- src/Plugins/Freetype/unicode_font.cpp | 15 ++++++++ src/Typeset/Boxes/Composite/math_boxes.cpp | 14 ++++++-- src/Typeset/Concat/concat_math.cpp | 14 ++++++-- 6 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 devel/80_6.tmu diff --git a/devel/80_6.tmu b/devel/80_6.tmu new file mode 100644 index 000000000..c79a92f92 --- /dev/null +++ b/devel/80_6.tmu @@ -0,0 +1,40 @@ +> + +> + +<\body> + Asana Math: + + <\equation*> + |}>>>>>>>>> + + + Fira Math: + + <\equation*> + |}>>>>>>>>>> + + + TeX Gyre Pagella Math: + + <\equation*> + |}>>>>>>>>>> + + + \ TeX Gyre Schola Math: + + + |}>>>>>>>>> + > + + +<\initial> + <\collection> + + + + + + + + diff --git a/src/Graphics/Fonts/font.cpp b/src/Graphics/Fonts/font.cpp index 138671882..ea010f92b 100644 --- a/src/Graphics/Fonts/font.cpp +++ b/src/Graphics/Fonts/font.cpp @@ -109,6 +109,13 @@ font_rep::copy_math_pars (font fn) { 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; + sqrt_ver_gap = fn->sqrt_ver_gap; + sqrt_ver_disp_gap = fn->sqrt_ver_disp_gap; + sqrt_rule_thickness = fn->sqrt_rule_thickness; + sqrt_extra_ascender = fn->sqrt_extra_ascender; + sqrt_degree_rise_percent = fn->sqrt_degree_rise_percent; + sqrt_kern_before_degree = fn->sqrt_kern_before_degree; + sqrt_kern_after_degree = fn->sqrt_kern_after_degree; } void diff --git a/src/Graphics/Fonts/font.hpp b/src/Graphics/Fonts/font.hpp index ee8105a4a..b0781d3f1 100644 --- a/src/Graphics/Fonts/font.hpp +++ b/src/Graphics/Fonts/font.hpp @@ -75,19 +75,26 @@ struct font_rep : rep { SI yshift; // vertical script shift inside fractions // only for opentype fonts - SI upper_limit_gap_min; - 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 upper_limit_gap_min; + 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 sqrt_ver_gap; + SI sqrt_ver_disp_gap; + SI sqrt_rule_thickness; + SI sqrt_extra_ascender; + int sqrt_degree_rise_percent; + SI sqrt_kern_before_degree; + SI sqrt_kern_after_degree; 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 08cab7828..1b66f2194 100644 --- a/src/Plugins/Freetype/unicode_font.cpp +++ b/src/Plugins/Freetype/unicode_font.cpp @@ -477,6 +477,21 @@ unicode_font_rep::unicode_font_rep (string name, string family2, int size2, math_table->constants_table[fractionDenominatorGapMin]); frac_denom_disp_gap_min= design_unit_to_metric ( math_table->constants_table[fractionDenominatorGapMin]); + // sqrt boxes + sqrt_ver_gap= design_unit_to_metric ( + math_table->constants_table[radicalVerticalGap]); + sqrt_ver_disp_gap= design_unit_to_metric ( + math_table->constants_table[radicalDisplayStyleVerticalGap]); + sqrt_rule_thickness= design_unit_to_metric ( + math_table->constants_table[radicalRuleThickness]); + sqrt_extra_ascender= design_unit_to_metric ( + math_table->constants_table[radicalExtraAscender]); + sqrt_degree_rise_percent= + math_table->constants_table[radicalDegreeBottomRaisePercent]; + sqrt_kern_before_degree= design_unit_to_metric ( + math_table->constants_table[radicalKernBeforeDegree]); + sqrt_kern_after_degree= design_unit_to_metric ( + math_table->constants_table[radicalKernAfterDegree]); } } } diff --git a/src/Typeset/Boxes/Composite/math_boxes.cpp b/src/Typeset/Boxes/Composite/math_boxes.cpp index e48c9d747..c536165cb 100644 --- a/src/Typeset/Boxes/Composite/math_boxes.cpp +++ b/src/Typeset/Boxes/Composite/math_boxes.cpp @@ -177,7 +177,10 @@ sqrt_box_rep::sqrt_box_rep (path ip, box b1, box b2, box sqrtb, font fn2, SI by= sqrtb->y2 + dy; if (sqrtb->x2 - sqrtb->x4 > wline) dx-= (sqrtb->x2 - sqrtb->x4); - pencil rpen= pen->set_width (wline); + bool use_open_type= (fn->math_type == MATH_TYPE_OPENTYPE) && + (fn->sqrt_degree_rise_percent > 0); + pencil rpen= use_open_type ? pen->set_width (fn->sqrt_rule_thickness) + : pen->set_width (wline); insert (b1, 0, 0); if (!is_nil (b2)) { SI X = -sqrtb->w (); @@ -191,6 +194,13 @@ sqrt_box_rep::sqrt_box_rep (path ip, box b1, box b2, box sqrtb, font fn2, else if (occurs ("agella", fn->res_name)) Y+= (16 * bw) >> 3; else Y+= (15 * bw) >> 3; } + else if (use_open_type) { + Y+= fn->sqrt_degree_rise_percent * sqrtb->h () / 100; + M = fn->sqrt_kern_after_degree; + sep= 0; + // we don't use it because it looks out of harmony + // b2->x1-= fn->sqrt_kern_before_degree; + } else { if (bh < 3 * bw) Y+= bh >> 1; else Y+= (bw * 3) >> 1; @@ -203,7 +213,7 @@ sqrt_box_rep::sqrt_box_rep (path ip, box b1, box b2, box sqrtb, font fn2, position (); left_justify (); y1-= wline; - y2+= wline; + y2+= use_open_type ? fn->sqrt_extra_ascender : wline; x2+= sep >> 1; right_italic_restore (b1); diff --git a/src/Typeset/Concat/concat_math.cpp b/src/Typeset/Concat/concat_math.cpp index 0d1da4f56..48a24619c 100644 --- a/src/Typeset/Concat/concat_math.cpp +++ b/src/Typeset/Concat/concat_math.cpp @@ -11,6 +11,7 @@ #include "analyze.hpp" #include "concater.hpp" +#include "font.hpp" #include "packrat.hpp" using namespace moebius; @@ -453,9 +454,9 @@ concater_rep::typeset_sqrt (tree t, path ip) { typeset_wide_sqrt (t, ip); return; } - box ind; + box ind; + bool disp= env->display_style; if (N (t) == 2) { - bool disp= env->display_style; tree old; if (disp) old= env->local_begin (MATH_DISPLAY, "false"); tree old_il= env->local_begin_script (); @@ -467,8 +468,15 @@ concater_rep::typeset_sqrt (tree t, path ip) { font lfn = env->fn; bool stix= starts (lfn->res_name, "stix-"); if (stix) lfn= rubber_font (lfn); + SI gap= (3 * sep >> 1); + bool use_opentype= + (lfn->math_type == MATH_TYPE_OPENTYPE) && (lfn->sqrt_ver_gap > 0); + if (use_opentype) { + gap= + (disp ? lfn->sqrt_ver_disp_gap : lfn->sqrt_ver_gap) + (lfn->wline >> 1); + } box sqrtb= delimiter_box (decorate_left (ip), "", lfn, env->pen, - b->y1, b->y2 + (3 * sep >> 1)); + b->y1, b->y2 + gap); if (stix) sqrtb= shift_box (decorate_left (ip), sqrtb, -env->fn->wline / 2, -env->fn->wline / 3, false, true);