Skip to content

Commit

Permalink
[80_4] Improving the Typesetting of Limit Boxes
Browse files Browse the repository at this point in the history
## What
Improving the Typesetting of Limit Boxes.

## Why
For some OpenType fonts, the heights of the upper and lower limits in
the limit box environment are not suitable.

## How to test your changes?
Open `devel/80_4.tmu`.

Before (Anasa Math font), the upper limit is too high:

![image](https://github.com/user-attachments/assets/e5ac5e1c-d3dc-422f-82e5-723beeee16e3)

After:

![image](https://github.com/user-attachments/assets/03ff3b2e-33d1-41a1-ae68-a891402240fd)
  • Loading branch information
KeShih authored Oct 3, 2024
1 parent 87095f6 commit 06912c2
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 5 deletions.
18 changes: 18 additions & 0 deletions devel/80_4.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<TMU|<tuple|1.0.3|1.2.9.2-rc5>>

<style|<tuple|generic|chinese>>

<\body>
<\equation*>
<big|sum><rsub|𝑘=0><rsup|\<infty\>><big|sum><rsub|k=<frac|1+<frac|1|2>|2>><rsup|<frac|2|2+<frac|1|2>>>lim<rsub|𝑘=0><rsup|\<infty\>>lim<rsub|k=<frac|1+<frac|1|2>|2>><rsup|<frac|2|2+<frac|1|2>>>
</equation*>
</body>

<\initial>
<\collection>
<associate|font|Asana Math>
<associate|font-family|rm>
<associate|page-medium|paper>
<associate|page-screen-margin|false>
</collection>
</initial>
6 changes: 6 additions & 0 deletions src/Graphics/Fonts/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ font_rep::copy_math_pars (font fn) {
wfn = fn->wfn;
wline = fn->wline;
wquad = fn->wquad;

// opentype math parameters
upper_limit_gap_min = fn->upper_limit_gap_min;
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;
}

void
Expand Down
9 changes: 8 additions & 1 deletion src/Graphics/Fonts/font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct font_glyphs;
#define MATH_TYPE_NORMAL 0
#define MATH_TYPE_STIX 1
#define MATH_TYPE_TEX_GYRE 2
#define MATH_TYPE_OPENTYPE 3

#define START_OF_LINE 1
#define END_OF_LINE 2
Expand All @@ -52,7 +53,7 @@ struct font_glyphs;

struct font_rep : rep<font> {
int type; // font type
int math_type; // For TeX Gyre math fonts and Stix
int math_type; // For TeX Gyre math fonts and Stix and OpenType fonts
SI size; // requested size
SI design_size; // design size in points/256
SI display_size; // display size in points/PIXEL
Expand All @@ -73,6 +74,12 @@ struct font_rep : rep<font> {
SI ysup_hi_lim; // upper limit for supscripts
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 wpt; // width of one point in font
SI hpt; // height of one point in font (usually wpt)
SI wfn; // wpt * design size in points
Expand Down
14 changes: 14 additions & 0 deletions src/Plugins/Freetype/tt_face.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
******************************************************************************/

#include "tt_face.hpp"
#include "analyze.hpp"
#include "file.hpp"
#include "font.hpp"
#include "tm_debug.hpp"
#include "tm_timer.hpp"
Expand Down Expand Up @@ -54,6 +56,18 @@ tt_face_rep::tt_face_rep (string name) : rep<tt_face> (name) {
}
ft_select_charmap (ft_face, ft_encoding_adobe_custom);
bad_face= false;

// .ttf/.otf file may contain a math table
string font_suffix= locase_all (suffix (u));
if (font_suffix == "ttf" || font_suffix == "otf") {
string buf;
if (!load_string (u, buf, false)) {
math_table= parse_mathtable (buf);
}
if (!is_nil (math_table) && DEBUG_STD) {
debug_fonts << "Math table loaded for " << name << "\n";
}
}
}

tt_face
Expand Down
6 changes: 4 additions & 2 deletions src/Plugins/Freetype/tt_face.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
#ifndef TT_FACE_H
#define TT_FACE_H
#include "Freetype/free_type.hpp"
#include "Freetype/tt_tools.hpp"
#include "bitmap_font.hpp"
#include "hashmap.hpp"

RESOURCE (tt_face);

struct tt_face_rep : rep<tt_face> {
bool bad_face;
FT_Face ft_face;
bool bad_face;
FT_Face ft_face;
ot_mathtable math_table;
tt_face_rep (string name);
};

Expand Down
34 changes: 32 additions & 2 deletions src/Plugins/Freetype/tt_tools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
#ifndef TT_TOOLS_H
#define TT_TOOLS_H

#include "basic.hpp"
#include "hashset.hpp"
#include "tm_debug.hpp"
#include "tree.hpp"
#include "url.hpp"

Expand Down Expand Up @@ -137,7 +139,12 @@ enum MathConstantRecordEnum {
radicalExtraAscender,
radicalKernBeforeDegree,
radicalKernAfterDegree,
otmathConstantsRecordsEnd // keep at the end
otmathConstantsRecordsEnd, // count the number of records
scriptPercentScaleDown,
scriptScriptPercentScaleDown,
delimitedSubFormulaMinHeight,
displayOperatorMinHeight,
radicalDegreeBottomRaisePercent
};

struct DeviceTable {
Expand All @@ -152,6 +159,9 @@ struct MathValueRecord {
bool hasDevice;
DeviceTable deviceTable;
MathValueRecord () : hasDevice (false) {}

// cast to int
operator int () const { return value; }
};

struct MathConstantsTable {
Expand All @@ -161,7 +171,27 @@ struct MathConstantsTable {
unsigned int displayOperatorMinHeight;
array<MathValueRecord> records;
int radicalDegreeBottomRaisePercent;
MathConstantsTable () : records (otmathConstantsRecordsEnd){};
MathConstantsTable ()
: records (MathConstantRecordEnum::otmathConstantsRecordsEnd){};

int operator[] (int i) {
if (i >= 0 && i < MathConstantRecordEnum::otmathConstantsRecordsEnd)
return records[i];
switch (i) {
case MathConstantRecordEnum::scriptPercentScaleDown:
return scriptPercentScaleDown;
case MathConstantRecordEnum::scriptScriptPercentScaleDown:
return scriptScriptPercentScaleDown;
case MathConstantRecordEnum::delimitedSubFormulaMinHeight:
return delimitedSubFormulaMinHeight;
case MathConstantRecordEnum::displayOperatorMinHeight:
return displayOperatorMinHeight;
case MathConstantRecordEnum::radicalDegreeBottomRaisePercent:
return radicalDegreeBottomRaisePercent;
}
TM_FAILED ("MathConstantsTable: index out of range");
return 0; // should never reach here
}
};

struct MathKernTable {
Expand Down
65 changes: 65 additions & 0 deletions src/Plugins/Freetype/unicode_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Freetype/free_type.hpp"
#include "Freetype/tt_face.hpp"
#include "Freetype/tt_file.hpp"
#include "Freetype/tt_tools.hpp"
#include "analyze.hpp"
#include "converter.hpp"
#include "cork.hpp"
Expand Down Expand Up @@ -140,6 +141,9 @@ struct unicode_font_rep : font_rep {

hashmap<string, int> native; // additional native (non unicode) characters

tt_face math_face;
ot_mathtable math_table;

unicode_font_rep (string name, string family, int size, int hdpi, int vdpi);
void tex_gyre_operators ();

Expand All @@ -164,6 +168,9 @@ struct unicode_font_rep : font_rep {
SI get_rsub_correction (string s);
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);
};

/******************************************************************************
Expand Down Expand Up @@ -430,6 +437,23 @@ unicode_font_rep::unicode_font_rep (string name, string family2, int size2,
above_correct= above_fira_italic_table ();
}
}
else {
// try to get OpenType math table
tt_face math_face2= tt_face (family);
if (!is_nil (math_face2->math_table)) {
this->math_face = math_face2;
this->math_table= math_face2->math_table;
math_type = MATH_TYPE_OPENTYPE;
upper_limit_gap_min=
design_unit_to_metric (math_table->constants_table[upperLimitGapMin]);
upper_limit_baseline_rise_min= design_unit_to_metric (
math_table->constants_table[upperLimitBaselineRiseMin]);
lower_limit_gap_min=
design_unit_to_metric (math_table->constants_table[lowerLimitGapMin]);
lower_limit_baseline_drop_min= design_unit_to_metric (
math_table->constants_table[lowerLimitBaselineDropMin]);
}
}
}

/******************************************************************************
Expand Down Expand Up @@ -975,6 +999,47 @@ unicode_font (string family, int size, int hdpi, int vdpi) {
tm_new<unicode_font_rep> (name, family, size, hdpi, vdpi));
}

/******************************************************************************
* OpenType
******************************************************************************/

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);
}

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);
}

font
unicode_font (string family, int size, int dpi) {
return unicode_font (family, size, dpi, dpi);
Expand Down
12 changes: 12 additions & 0 deletions src/Typeset/Boxes/Composite/script_boxes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Boxes/Composite/italic_correct.hpp"
#include "Boxes/composite.hpp"
#include "Boxes/construct.hpp"
#include "font.hpp"

/******************************************************************************
* subroutine for scripts
Expand Down Expand Up @@ -86,11 +87,18 @@ lim_box_rep::lim_box_rep (path ip, box r2, box lo, box hi, font fn2, bool gl)
type= 0;
if (!is_nil (lo)) type+= 1;
if (!is_nil (hi)) type+= 2;
bool use_opentype= (fn->math_type == MATH_TYPE_OPENTYPE) &&
(fn->lower_limit_gap_min > 0) &&
(fn->lower_limit_baseline_drop_min > 0);
if (!is_nil (lo)) {
SI top= max (lo->y2, fn->y2 * script (fn->size, 1) / fn->size) + sep_lo;
Y = ref->y1;
X = ((SI) (ref->right_slope () * (Y + top - lo->y1))) +
((ref->x1 + ref->x2) >> 1);
if (use_opentype) {
top= lo->y2 + fn->lower_limit_gap_min;
top= max (top, fn->lower_limit_baseline_drop_min);
}
insert (lo, X - (lo->x2 >> 1), Y - top);
italic_correct (lo);
}
Expand All @@ -99,6 +107,10 @@ lim_box_rep::lim_box_rep (path ip, box r2, box lo, box hi, font fn2, bool gl)
Y = ref->y2;
X = ((SI) (ref->right_slope () * (Y + hi->y2 - bot))) +
((ref->x1 + ref->x2) >> 1);
if (use_opentype) {
bot= hi->y1 - fn->upper_limit_gap_min;
bot= min (bot, -fn->upper_limit_baseline_rise_min);
}
insert (hi, X - (hi->x2 >> 1), Y - bot);
italic_correct (hi);
}
Expand Down

0 comments on commit 06912c2

Please sign in to comment.