Makie.jl icon indicating copy to clipboard operation
Makie.jl copied to clipboard

some latex strings can not be correctly rendered

Open thudjx opened this issue 2 years ago • 14 comments

By now, I have found 2 latex characters that can not be correctly rendered. The MWE is

fig = Figure(resolution=(100,100))
Label(fig[1,1], L"\partial")
save("mwe.pdf", fig)

, which results in image And similarly, L"\degree" is rendered into image

The infomation of julia is

julia> versioninfo()
Julia Version 1.7.3
Commit 742b9abb4d (2022-05-06 12:58 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: AMD EPYC 7542 32-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, znver2)

and the versions of packages are:

[13f3f980] CairoMakie v0.8.3
[b964fa9f] LaTeXStrings v1.3.0
[0a4f8689] MathTeXEngine v0.4.0

I have tried to generate tex elements by:

julia> generate_tex_elements(L"\partial")
1-element Vector{Any}:
 (TeXChar '∂' [U+2202 in cmmi10 - Regular], [0.0, 0.0], 1.0)

julia> generate_tex_elements(L"\degree")
1-element Vector{Any}:
 (TeXChar '°' [U+00B0 in cmmi10 - Regular], [0.0, 0.0], 1.0)

, which are normal. And to check if the .ttf files are correct:

with_theme(Theme(font=joinpath((dirname ∘ dirname)(pathof(Makie.MathTeXEngine)), "assets", "fonts", "ComputerModern", "cmmi10.ttf"))) do
           fig = Figure()
           ax = Axis(fig[1,1])
           fig
           end

, which also works fine.

thudjx avatar May 27 '22 16:05 thudjx

Just tested and can confirm that this happens with CairoMakie. ~~but not with GLMakie.~~ For GLMakie the L"\partial" is rendered correctly

image

but L"\degree" isn't image

EDIT: Typo

fatteneder avatar May 27 '22 20:05 fatteneder

Regarding degree: I wonder if this is even supported by MathTeXEngine, because according to https://en.wikipedia.org/wiki/Degree_symbol#Software-specific it is only provided by the gensymb package. As a workaround you could use ^{\circ}. I just tested and it renders in both GLMakie and CairoMakie

image

fatteneder avatar May 27 '22 20:05 fatteneder

Also: \partial renders correctly to PDF with

[13f3f980] CairoMakie v0.8.0
[b964fa9f] LaTeXStrings v1.3.0
[0a4f8689] MathTeXEngine v0.4.0

as can be seen here (second to last slide): https://github.com/fatteneder/MakieSlides.jl/blob/ff2615ed9678abd6f9bd55baac80265531678ddb/examples/presentation.pdf

fatteneder avatar May 27 '22 20:05 fatteneder

also https://github.com/JuliaPlots/Makie.jl/issues/1967

evident in these examples

https://lazarusa.github.io/BeautifulMakie/ScattersLines/MultipleMulticoloredLineCbarAround/ https://lazarusa.github.io/BeautifulMakie/ScattersLines/latexSample/

AshtonSBradley avatar May 28 '22 00:05 AshtonSBradley

@fatteneder It can be checked that L"\degree" can be correctly generated:

julia> generate_tex_elements(L"\degree")
1-element Vector{Any}:
 (TeXChar '°' [U+00B0 in cmmi10 - Regular], [0.0, 0.0], 1.0)

although the result is different from:

julia> generate_tex_elements(L"^\circ")
1-element Vector{Any}:
 (TeXChar '∘' [U+00B1 in cmsy10 - Regular], [0.12000000178813934, 0.0], 0.6)

thudjx avatar May 28 '22 01:05 thudjx

I vaguely remember that @Kolaru said that some difficulty lies in the way needed symbols are accessed in the computer modern fonts. The pipeline we use accesses glyphs from FreeType fonts via unicode Chars. However, imagine a font that has two different glyphs for the character 'a', you would not be able to pick the correct glyph by passing the Char. You instead need an integer specifying the position of the glyph in the font. And I can imagine that there would be more symbols to access for MathTeXEngine if Makie allowed glyph indexing by integer instead of by Char. Buy that's just an educated guess from my side.

jkrumbiegel avatar May 28 '22 06:05 jkrumbiegel

That's a very interesting one.

The pipeline for symbol finding in MathTexEngine is currently

  1. Parse command e.g. \alpha or α (unicode input are supported)
  2. In both case convert it to a common reprensentation (something like (command=\alpha, char=α)
  3. Look at the ComputerModern char table if it contains the command 3.1. If yes, use the info there (specific font + glyph index in the font) 3.2. If no, use the char in the default font

The problem is just that \degree and \partial don't have the proper mapping in the CM char table. That should be an easy fix.

However, imagine a font that has two different glyphs for the character 'a', you would not be able to pick the correct glyph by passing the Char. You instead need an integer specifying the position of the glyph in the font.

This problem is why we need step 3 above and we can not use a unicode font directly. It is a bit trickier than that even, since, as far as I understood, different glyphs for the same char are at the same index in the font (Char are already just integers pointing to the glyph number in a font, the proper char association being guaranteed for proper unicode fonts).

Kolaru avatar May 28 '22 12:05 Kolaru

However, imagine a font that has two different glyphs for the character 'a', you would not be able to pick the correct glyph by passing the Char. You instead need an integer specifying the position of the glyph in the font.

Isn't this why Unicode variation sequences exist? https://freetype.org/freetype2/docs/reference/ft2-glyph_variants.html If I understand correctly then you could select the right glyph by providing a base char and then a selector taken from the range U+E0100-U+E01EF.

I am currently in the process of understanding how unicode emojis can be rendered, because some of those come with such a sequence (usually flags, peoples and their skin tones). However I am having trouble in using the FreeType API here.

fatteneder avatar May 28 '22 16:05 fatteneder

Isn't this why Unicode variation sequences exist? https://freetype.org/freetype2/docs/reference/ft2-glyph_variants.html If I understand correctly then you could select the right glyph by providing a base char and then a selector taken from the range U+E0100-U+E01EF.

Oh yes you are right. After some looking I also see that the variation glyphs seem to just be outside of the unicode indices in the font, so it may be possible to do it with Makie and Cairo actually.

Still, I haven't check if FreeTypeAbstraction.jl supports the variation sequence.

Kolaru avatar May 28 '22 19:05 Kolaru

I think it does not, but there is a feature request from you :) https://github.com/JuliaGraphics/FreeTypeAbstraction.jl/issues/59

fatteneder avatar May 28 '22 21:05 fatteneder

One problem is that GLMakie will not be able to render emoji with the SDF pipeline.

jkrumbiegel avatar May 29 '22 20:05 jkrumbiegel

Indeed, I was made aware of this at https://github.com/fatteneder/MakieSlides.jl/pull/15#issuecomment-1137872633

We are working around this for now using scatter and use actual pngs of the emojis as markers.

The problem I had with FreeType was that I could not even query a glyph index for an unicode variation sequence. I still think it was due to me not really understanding FreeType, but I did not follow up on this due to the rendering issue you mention.

fatteneder avatar May 29 '22 20:05 fatteneder

I found two more characters that can not be rendered: \hbar and \AA.

thudjx avatar Jun 11 '22 03:06 thudjx

@Kolaru I've added a draft PR that switches the GlyphCollection representation to Culong not Char so that glyphs can be directly targeted without a detour through the font's charmap. CairoMakie was already easily switched to drawing using that format. Could you try and feed whatever glyph indices you want to try for currently impossible glyphs and see if this would alleviate that issue? If you run a basic example with a LaTeXString you'll see that it errors and at that position you'll need to return the glyph index you will generate in MathTeXEngine.

jkrumbiegel avatar Jul 14 '22 20:07 jkrumbiegel