MakieOrg / MakieTeX.jl

TeX integration in Makie
http://makieorg.github.io/MakieTeX.jl/
MIT License
92 stars 13 forks source link

Fonts! #36

Open asinghvi17 opened 2 years ago

asinghvi17 commented 2 years ago

Some useful resources for font changes:

Moelf commented 1 year ago

from trying the package it's clear that text(...; font = blah) doesn't work with MakieTeX.jl right now.

What's needed for the interaction to happen? I though as a naive implementation we just need to inject something like this into the tectonic input right?

\usepackage{fontspec}%
\newfontfeature{Microtype}{protrusion=default;expansion=default;}%
\setmainfont{texgyrepagella-regular.otf}[%
  Microtype,
  Ligatures = TeX,
  BoldFont = texgyrepagella-bold.otf,
  ItalicFont = texgyrepagella-italic.otf,
  BoldItalicFont = texgyrepagella-bolditalic.otf,
]%
asinghvi17 commented 1 year ago

Something like that, but we would need to figure out how to get all the other font types as well as a good math font.

(actually, now that you mention it - my Fontconfig PR to Makie has some code which should work well. I could move some of that dep to Makie for now.)

Also, the way the text algorithm works now precludes MakieTeX from hooking into it as it previously did. I'd have to refactor that algorithm to (preferably) accept scatters as well, which could then be used for both emojis and images.

Moelf commented 1 year ago

ok rn I just want a minimal working thing so I can be compliant with publication requirement with Makie and the only requirement is to render something like

\sqrt{s} = 13 \text{TeV}

using Helvetica (or Nimbus).


I think for Makie's use case, i.e., text!(L"....", font = ), it's fine to replace everything (mainfont, mathfont ... ) in .tex file, my reasoning is that, users are most likely just adding annotation or axis labels, not trying to write an essay with MakieTeX, we don't need a lot of fancy automatic detection fall back select best blah blah, just do what user wants as a start

Moelf commented 1 year ago

the way the text algorithm works now precludes MakieTeX from hooking into it as it previously did.

are you saying that right now there's no method in this repo that can "see" font = blah from Makie?

asinghvi17 commented 1 year ago

yes, even the old test!(L"...") uses MathTeXEngine as it does in base Makie

well: you can use LTeX, which should be able to see font, but it hasn't been updated to the new interface.

asinghvi17 commented 1 year ago

requirement is to render something like

How would you do that without a Helvetica math font anyway? Unless I misunderstand this would show up in CMU even in normal latex?

Moelf commented 1 year ago

I don't know but matplotlib (which goes through texlive) can render it: https://gitlab.sauerburger.com/cern/fsauerbu/atlasify/-/blob/master/atlasify/__init__.py#L60

in any case, when using Helvetica, \sqrt{s} looks very different compared to default font CMU

Moelf commented 1 year ago

yes, even the old test!(L"...") uses MathTeXEngine as it does in base Makie

wait, so is this pkg right now completely useless? what does it even do if it can't intercept text!() call?

edit: oh, we can plot TeXImg? that's fine then, I mean I'm not saying I have to use text!() API, just something that can allow me to change font and put a label somewhere in the image

asinghvi17 commented 1 year ago

provides an LTeX layoutable which can render arbitrary latex, that's about it

asinghvi17 commented 1 year ago

for now, if you know which math font you want you could provide a custom preamble to LTeX, like so:

tex_to_render = TeXDocument("this is a full and compilable latex document pasted into a string in Julia")
LTeX(fig[i, j]; tex = tex_to_render, ...)

and then you can load your custom fonts etc.

I'll have a look at how Matplotlib does this and see what I can do though!

Moelf commented 1 year ago

I'd be happy to help since I know a little bit around Makie code base by now

asinghvi17 commented 1 year ago

Am testing out the text refactor-ish thing now...will allow an extension to be added for Pango pretty easily as well.

Moelf commented 1 year ago

ok here's a super hacky idea:

  1. make a function here, something like textext!(fig, Lstring; fonts, color, size... <whatever we want>)
  2. this function does a few things
    • implement the injection of fonts and color as we see fit (basically extend what this repo already does)
    • render the tex text to an image (compile_latex())
    • call Makie.scatter!(...) with marker = load(image_path.pdf)
  3. since we load()ed the image, we have a chance to correct the size tuple to scatter!() so the image marker has the correct aspect ratio

this API shouldn't be too bad because we can take whatever Makie.scatter uses and pass them through, user needs to give us location and marker size anyway.

this has the benefit that we can do whatever we want with textext!() function and experiments what are the most useful set of things users may want to customize, before worrying about how to interface with Makie's stuff

asinghvi17 commented 1 year ago

We mostly have that in TeXLabel, it just needs the font stuff implemented. Backgroundcolor, color, etc is all implemented already. The issue here is that users can't use e.g. CachedTeX in axis labels. For that, all we need is for text (which is currently comprised of 1 Text{GlyphCollection} and 1 LineSegments plot) to also have a scatter plot, which we provide render-able markers to. A subtype of AbstractMatrix{RGBAf} should suffice for GLMakie and WGLMakie, and we depend on CairoMakie anyway so we can hook into its scatter rendering.

asinghvi17 commented 1 year ago

If you have an idea of how we can: (a) figure out how to get fonts into LaTeX generally, given a font family and a path to its file, (b) figure out a good correlation between math fonts and user fonts (maybe a lookup table which someone has already implemented in the LaTeX world?)

then I think those would be the natural next steps.

Moelf commented 1 year ago

figure out how to get fonts into LaTeX generally, given a font family and a path to its file,

figure out a good correlation between math fonts and user fonts

we assume for now user has some LaTeX knowledge, so for example in textext! we can have 1-to-1 options to LaTeX, (; mainfont=..., mathfont=...)

asinghvi17 commented 1 year ago

Ok, that sounds good. Yeah I guess we can assume that any font a user provides must be installed, I'm not the most familiar with fontconfig but it seems you can specify bold/italic/etc fonts as separate font files. The way I see this, there are two cases:

  1. Makie doesn't really support this, but if all fonts are in one file, then how would we support this?
  2. If all fonts are in separate files, this becomes pretty straightforward.

I guess fonts[:regular] would map to mainfont, bold to boldfont, italic to italicfont, etc. Most fonts describe their styles in a space-separated way - can we change that to either underscored or pascal cased (first letter of each word is capitalized)?

We could just assume a CMU math font until told otherwise by the user, that works.

Moelf commented 1 year ago
julia> function main()
           tex = CachedTeX(MakieTeX.texdoc(raw"$\sqrt{s} = 13 \text{TeV}$"));
           f,a,_ = plot(1:3, 1:3)
           marker = MakieTeX.recordsurf2img(tex, 4) #increase render density
           scatter!(a, 1.5, 1.5; marker, markersize=100)
           CairoMakie.save("/tmp/jl_onm7cZSLiJ.png", f)
       end

image


I don't understand why it's rotated (I thought recordsurf2img already corrected for it) and also why the aspect ratio is wrong

Moelf commented 1 year ago

ok, if we apply rotl90 and also use CachedTex.dims, we can get desired result

julia> function main()
           tex = CachedTeX(MakieTeX.texdoc(raw"$\sqrt{s} = 13 \text{TeV}$"));
           f,a,_ = plot(1:3, 1:3)
           marker = MakieTeX.rotl90(MakieTeX.recordsurf2img(tex, 4))
           scatter!(a, 1.5, 1.5; marker, markersize=tex.dims .*2)
           CairoMakie.save("/tmp/jl_onm7cZSLiJ.png", f)
       end

image