mathjax / MathJax

Beautiful and accessible math in all browsers
http://www.mathjax.org/
Apache License 2.0
10k stars 1.16k forks source link

Rendering bug when Chinese chars in \text block #3224

Open cesaryuan opened 2 months ago

cesaryuan commented 2 months ago

Issue Summary

There is a rendering bug when Chinese chars in \text block. The affected version is 4.0.0-beta.6. And the 3.2.2 version is fine.

Steps to Reproduce:

  1. Open the following html, as you can see, Chinese \text block is rendered wrong.
    
    <!DOCTYPE html>
    <html>
Mathjax tex-mml-svg bug

Rendering bug when Chinese chars in \text block: $$\text{中文 bug}$$

Latin chars is fine: $$\text{adwaw da ai dawd,}$$

Version 3.2.2 is also fine

![image](https://github.com/mathjax/MathJax/assets/35998162/43c40ff4-4010-459b-86d3-01f04e8732db)

![image](https://github.com/mathjax/MathJax/assets/35998162/f2113898-7d9b-4f74-9ce6-0a9587c957a6)

### Technical details:

* MathJax Version: 4.0.0-beta.6
* Client OS: Windows 11
* Browser: Chrome 124.0.6367.63

I am using the default MathJax configuration:

and loading MathJax via

``` html
<script src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-mml-svg.js" id="MathJax-script"></script>

Supporting information:

<!DOCTYPE html>
<html>

<head>
    <title>Mathjax tex-mml-svg bug</title>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-mml-svg.js" id="MathJax-script"></script>
</head>

<body>
    <p>Rendering bug when Chinese chars in \text block: $$\text{中文 bug}$$</p>
    <p>Latin chars is fine: $$\text{adwaw da ai dawd,}$$</p>
    <p>Version 3.2.2 is also fine</p>
</body>

</html>
dpvc commented 2 months ago

Thanks for the report.

The easiest solution is to set the mtextInheritFont option to true in the output block of your configuration:

MathJax = {
  output: {
    mtextInheritFont: true
  }
};

If you want the non-Chinese text to be in the default MathJax font, then you can use the following patch instead:

MathJax = {
  startup: {
    ready() {
      const {SvgWrapper} = MathJax._.output.svg.Wrapper;
      SvgWrapper.prototype.placeChar = function (n, x, y, parent, variant = null, buffer = false) {
        if (variant === null) {
          variant = this.variant;
        }
        const C = n.toString(16).toUpperCase();
        const [ , , w, data] = this.getVariantChar(variant, n);
        if (data.unknown) {
          this.utext += String.fromCodePoint(n);
          return (buffer ? 0 : this.addUtext(x, y, parent, variant));
        }
        const dx = this.addUtext(x, y, parent, variant);
        if ('p' in data) {
          x += dx;
          const path = (data.p ? 'M' + data.p + 'Z' : '');
          this.place(x, y, this.adaptor.append(parent, this.charNode(variant, C, path)));
          return w + dx;
        }
        if ('c' in data) {
          const g = this.adaptor.append(parent, this.svg('g', {'data-c': C}));
          this.place(x, y, g);
          x = 0;
          for (const n of this.unicodeChars(data.c, variant)) {
            x += this.placeChar(n, x, y, g, variant);
          }
          return w + x + dx;
        }
        return w;
      };
      MathJax.startup.defaultReady();
    }
  }
};

The problem was that the placeChar() function wasn't handling characters that are not in the MathJax font properly (it did not process their widths correctly) in SVG output. This corrected routine should do the job.

I will make a PR to fix the problem in the next release.

dpvc commented 2 months ago

Sorry, I had mistyped mtextInheritFont in the first code block above. I have fixed it, so make sure you have the correct version if you use that.