plotters icon indicating copy to clipboard operation
plotters copied to clipboard

Confusing Font/Text Structs

Open siefkenj opened this issue 3 years ago • 2 comments

Looking through the code, there seems to be a lot of different font/text structs. Some can be converted into one another with .into() and others cannot. Some need a reference to the backend. In particular TextStyle vs TextStyleBuilder confuse me.

Can you explain the logic around so many different font objects? Can it be simplified?

siefkenj avatar May 27 '21 15:05 siefkenj

Hi, the font object is a little bit tricky. Please let me explain the general out-line at this point.

For API users, what they want to use is any types that impls IntoTextStyle. This allows the API flexible, as you can either pass a string as font name, or a tuple of (font_name, font_size), etc. Another additional note to this type: We support relative sizing, for example ("serif", (10).percent_height()) will turns into a text style that depends on its parent's height.

And TextStyle is actual struct that describes style information about a text. Currently it's a collection of font, color and the anchor position. P.S. more data may be added in the future.

The type FontDesc is what we used to describe a font. This struct is a little bit trickier as Plotters allows different font implementations. For example, Plotters use font-kit backed font implementation by default. While for WASM, Plotters use the web-browser. Also, if we want a minimize the dependency, we can opt-in the mocked font, which only estimate the font size. (This is what happening if you use SVG backend and disable default features - this is how criterion is using plotters.)

I don't think we have a TextStyleBuilder type.

Let me know if you have any thoughts.

Also, thanks for the layout PR!

38 avatar Jun 01 '21 21:06 38

There is a TextStyleBuilder, see https://docs.rs/plotters/latest/plotters/style/trait.IntoTextStyle.html

It can be confusing when typing by mistake with_color instead of color:

let text_style = plotters::style::text::TextStyle::from(("sans-serif", 20).into_font())
    .with_color(&BLUE);

..because you expect a TextStyle but you get a TextStyleBuilder which cannot be used as is, for example:

201 | plotters::element::text::Text::new("my text", (0, 0), text_style);
    | ----------------------------------                    ^^^^^^^^^^ the trait `std::convert::From<&plotters::style::text::TextStyleBuilder<'_, plotters::style::TextStyle<'_>>>` is not implemented for `plotters::style::FontDesc<'_>`
    | |
    | required by a bound introduced by this call

..then you try to use into_text_style(P) which requires a parameter which in the examples is the drawing_area object! When processing a large number of drawing_areas one would think to create a TextStyle object and reuse it but on this path you might think it's not possible. It could have been simpler to accept only a pixels value instead of a SizeDesc; one can very easily convert the SizeDesc to a pixels value manually. Quite a few of the into_text_style implementations ignore the parameter.

aleb avatar Nov 17 '22 12:11 aleb