plotters
plotters copied to clipboard
Confusing Font/Text Structs
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?
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!
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.