NanoMichael / MicroTeX

A dynamic, cross-platform, and embeddable LaTeX rendering library
MIT License
417 stars 69 forks source link

Vector output with no dependencies? #131

Closed cesss closed 2 years ago

cesss commented 2 years ago

I see that the library is focused in rasterizing the LaTeX output, using Cairo or other backends for that purpose. If I'm reading the docs correctly, even SVG files generated by the headless mode are raster images. However, I'm interested in getting the output as resolution-independent vector graphics.

I imagine that this should be easy to do, because if you are rasterizing something, you need to have it first in vector format, so I guess there's some part of the library that manages LaTeX as vector graphics.

Can you tell me what would be the best place in the code for generating vector output? (preferably in the openmath branch, because I prefer to use UTF8 rather than wide strings).

Thanks a lot!

NanoMichael commented 2 years ago

I imagine that this should be easy to do, because if you are rasterizing something, you need to have it first in vector format, so I guess there's some part of the library that manages LaTeX as vector graphics.

Unfortunately, that's not true. The "Save as SVG" is implemented by the Cairo backend, so the vector generation was done by Cairo, it is implemented like:

// the file path to save the SVG file
std::string file;
// create a SvgSurface to draw contents
auto surface = Cairo::SvgSurface::create(file, width, height);
auto context = Cairo::Context::create(surface);
// draw whatever you want
// ...

But with compile option -DGLYPH_RENDER_TYPE=0 (that means render glyphs use graphical-path and typeface both) or -DGLYPH_RENDER_TYPE=1 (that means render glyphs use graphical-path only), that should be easy to generate vector output (like SVG). You may want to check out the wasm SVG implementation (it implements a really simple SVG rendering).

Here is a demo for the wasm build, make sure you select the SVG rendering mode.

cesss commented 2 years ago

But what kind of data do you send to Cairo? I'm interested in the data before Cairo is called...

NanoMichael commented 2 years ago

But what kind of data do you send to Cairo? I'm interested in the data before Cairo is called...

Take glyph drawing as an example, if using the graphical path, the data was like:

M 0 0 L 20 20

that draws a line from (0, 0) to (20, 20), the corresponding Cairo drawing commands are:

cairo_move_to(_context, 0, 0);
cairo_line_to(_context, 20, 20);
cairo_stroke(_context);

Please see the d attr of SVG doc.

cesss commented 2 years ago

Ok, thanks a lot! One more question: so, the SVG generated by Cairo is a vector file, or a rasterized image? I mean, if you import the SVG in Inkscape (or in any other SVG editor/viewer), and you zoom it a lot, do you see pixels, or is it vector data?

sp1ritCS commented 2 years ago

that depends on the cairo surface you use. The SVG or PostScript surfaces write vector data, while the PNG surface gives you a raster.

The gtkmm headless mode only outputs to SVG

cesss commented 2 years ago

Ah, then it's perfect, I think I can use it as is (I'll be using the openmath branch, which I suppose is the recommended one in this moment).

Thanks a lot! I'm closing this, because it's clear.