Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c740d70
feat(font): replace font-kit/ab_glyph stack with fontique/harfrust/sk…
pbdeuchler Apr 29, 2026
3187a6f
test(font): cover the new context pipeline against the bitmap backend
pbdeuchler Apr 29, 2026
ac403d0
refactor(font): drop the legacy native backends and their dependencies
pbdeuchler Apr 29, 2026
de1acd8
fix(font): re-export InvalidFont alongside register_font
pbdeuchler Apr 29, 2026
0a57bb1
cr: address Claude code review, remove random crufty API surface, fix…
pbdeuchler Apr 29, 2026
0df95d1
chore(ci): install libfontconfig-dev on Linux runners
pbdeuchler Apr 29, 2026
6d8179a
feat(font): add dynamic_font example, seal FontContext as pub(crate)
pbdeuchler Apr 29, 2026
11f700d
fix(font): add skrifa hinting and subpixel-aware rasterization
pbdeuchler Apr 30, 2026
681dc87
chore: remove LLM cruft comments
pbdeuchler Apr 30, 2026
69719d7
chore: remove builder and pointless inner struct from earlier versions
pbdeuchler Apr 30, 2026
a11e987
fix: fix example and bugs preventing them from running around type hi…
pbdeuchler Apr 30, 2026
8d3d634
chore: once again remove LLM comment cruft
pbdeuchler Apr 30, 2026
a895174
fix: kerning baseline fix and quick compilation fix since somehow we …
pbdeuchler Apr 30, 2026
f24a7e8
nit: make engine declarations a bit more readable
pbdeuchler May 1, 2026
dbb1360
nit: invert if for better readability
pbdeuchler May 1, 2026
6fa6833
chore: fix tests by creating font family fallback behavior, mimicking…
pbdeuchler May 1, 2026
f83f203
chore: screwed up submodules somehow, fixing
pbdeuchler May 1, 2026
d42ea18
nit: flatten Result<Option<>> to just Option<> per cr comments
pbdeuchler May 1, 2026
21e85ba
chore: check in fonts used in dynamic_font example
pbdeuchler May 1, 2026
de4f0aa
fix(font): push the chart's font context when laying out series labels
pbdeuchler May 1, 2026
c75959e
feat(examples): add modern.rs dark-theme line chart example
pbdeuchler May 1, 2026
0d7198c
Update plotters/src/style/font/system.rs
pbdeuchler May 1, 2026
909e82b
Update plotters/src/style/font/context.rs
pbdeuchler May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/plotters-backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install fontconfig
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/plotters-bitmap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install fontconfig
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
Expand Down
103 changes: 66 additions & 37 deletions .github/workflows/plotters-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
profile: minimal
Expand All @@ -20,68 +22,95 @@ jobs:
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.88.0
override: true
args: --all-features
build_and_test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
with:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- name: Install fontconfig
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
- uses: actions-rs/cargo@v1
with:
command: test
args: --verbose
- uses: actions-rs/cargo@v1
with:
- uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --no-default-features --features=svg_backend --lib
test_all_features:
test_all_features_exclude_ab_glyph:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
- uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --all-features
# This is all features except for ab_glyph, which will break doctests
args: --verbose --features=serialization,evcxr
test_all_features_exclude_doctests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
# Run all tests with ab_glyph, but exclude doctests
args: --lib --bins --tests --verbose --all-features
run_all_examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions-rs/cargo@v1
with:
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/cargo@v1
with:
command: build
args: --verbose --release --examples
- name: Run all the examples
run: |
cd plotters
for example in examples/*.rs
do
../target/release/examples/$(basename ${example} .rs)
done
tar -czvf example-outputs.tar.gz plotters-doc-data
- uses: actions/upload-artifact@v4
with:
- name: Run all the examples
run: |
cd plotters
for example in examples/*.rs
do
../target/release/examples/$(basename ${example} .rs)
done
tar -czvf example-outputs.tar.gz plotters-doc-data
- uses: actions/upload-artifact@v4
with:
name: example-outputs
path: plotters/example-outputs.tar.gz
3 changes: 3 additions & 0 deletions .github/workflows/plotters-svg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install fontconfig
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/rust-clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev

- name: Install Rust toolchain
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af #@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/wasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install fontconfig
run: sudo apt-get update && sudo apt-get install -y libfontconfig-dev
- name: Install WASM tool chain
run: rustup target add wasm32-unknown-unknown
- name: Check WASM Target Compiles
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "plotters-doc-data"]
path = plotters/plotters-doc-data
url = https://github.com/38/plotters-doc-data
[submodule "plotters/plotters-doc-data"]
path = plotters/plotters-doc-data
url = git@github.com:plotters-rs/plotters-doc-data.git
32 changes: 18 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,25 +532,30 @@ The following list is a complete list of features that can be opted in or out.

| Name | Description | Additional Dependency |Default?|
|---------|--------------|--------|------------|
| bitmap\_encoder | Allow `BitMapBackend` to save the result to bitmap files | image, rusttype, font-kit | Yes |
| bitmap\_encoder | Allow `BitMapBackend` to save the result to bitmap files | image | Yes |
| svg\_backend | Enable `SVGBackend` Support | None | Yes |
| bitmap\_gif| Opt-in GIF animation Rendering support for `BitMapBackend`, implies `bitmap` enabled | gif | Yes |

- Font manipulation features

| Name | Description | Additional Dependency | Default? |
|----------|------------------------------------------|-----------------------|----------|
| ttf | Allows TrueType font support | font-kit | Yes |
| ab_glyph | Skips loading system fonts, unlike `ttf` | ab_glyph | No |

`ab_glyph` supports TrueType and OpenType fonts, but does not attempt to
load fonts provided by the system on which it is running.
It is pure Rust, and easier to cross compile.
To use this, you *must* call `plotters::style::register_font` before
using any `plotters` functions which require the ability to render text.
This function only exists when the `ab_glyph` feature is enabled.
Native text rendering is always available. Plotters resolves system fonts
through `fontique`, shapes text with `harfrust`, reads outlines with `skrifa`,
and rasterizes glyphs with `zeno`. Use `DrawingArea::with_fonts` when a chart
should use in-memory fonts instead of, or in addition to, system fonts. See
[`plotters/examples/dynamic_font.rs`](plotters/examples/dynamic_font.rs) for an
end-to-end example that downloads Roboto from Google Fonts at runtime and
attaches it to a chart through the new pipeline.

| Name | Description | Additional Dependency | Default? |
|----------|-----------------------------------------------------------------------------------|-----------------------|----------|
| ab_glyph | Compatibility shim: exposes `register_font` and disables default system font use | None | No |

The `ab_glyph` feature is retained for source compatibility with code that
uses `plotters::style::register_font`. New code should prefer
`DrawingArea::with_fonts` for per-area font registration.
`register_font` only exists when the `ab_glyph` feature is enabled.
```rust,ignore
/// Register a font in the fonts table.
/// Register a font in the legacy process-global font table.
///
/// The `name` parameter gives the name this font shall be referred to
/// in the other APIs, like `"sans-serif"`.
Expand Down Expand Up @@ -646,4 +651,3 @@ pub struct RGBAColor(pub u8, pub u8, pub u8, pub f64);
In the case that error handling is important, you need manually call the `present()` method before the backend gets dropped.
For more information, please see the examples.


32 changes: 18 additions & 14 deletions doc-template/readme.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,25 +270,30 @@ The following list is a complete list of features that can be opted in or out.

| Name | Description | Additional Dependency |Default?|
|---------|--------------|--------|------------|
| bitmap\_encoder | Allow `BitMapBackend` to save the result to bitmap files | image, rusttype, font-kit | Yes |
| bitmap\_encoder | Allow `BitMapBackend` to save the result to bitmap files | image | Yes |
| svg\_backend | Enable `SVGBackend` Support | None | Yes |
| bitmap\_gif| Opt-in GIF animation Rendering support for `BitMapBackend`, implies `bitmap` enabled | gif | Yes |

- Font manipulation features

| Name | Description | Additional Dependency | Default? |
|----------|------------------------------------------|-----------------------|----------|
| ttf | Allows TrueType font support | font-kit | Yes |
| ab_glyph | Skips loading system fonts, unlike `ttf` | ab_glyph | No |

`ab_glyph` supports TrueType and OpenType fonts, but does not attempt to
load fonts provided by the system on which it is running.
It is pure Rust, and easier to cross compile.
To use this, you *must* call `plotters::style::register_font` before
using any `plotters` functions which require the ability to render text.
This function only exists when the `ab_glyph` feature is enabled.
Native text rendering is always available. Plotters resolves system fonts
through `fontique`, shapes text with `harfrust`, reads outlines with `skrifa`,
and rasterizes glyphs with `zeno`. Use `DrawingArea::with_fonts` when a chart
should use in-memory fonts instead of, or in addition to, system fonts. See
[`plotters/examples/dynamic_font.rs`](plotters/examples/dynamic_font.rs) for an
end-to-end example that downloads Roboto from Google Fonts at runtime and
attaches it to a chart through the new pipeline.

| Name | Description | Additional Dependency | Default? |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ab_glyph doesn't add the ab_glyph dep?

Copy link
Copy Markdown
Contributor Author

@pbdeuchler pbdeuchler May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore, it all goes through the same pipeline. ab_glyph just turns off system font discovery now.

|----------|-----------------------------------------------------------------------------------|-----------------------|----------|
| ab_glyph | Compatibility shim: exposes `register_font` and disables default system font use | None | No |

The `ab_glyph` feature is retained for source compatibility with code that
uses `plotters::style::register_font`. New code should prefer
`DrawingArea::with_fonts` for per-area font registration.
`register_font` only exists when the `ab_glyph` feature is enabled.
```rust,ignore
/// Register a font in the fonts table.
/// Register a font in the legacy process-global font table.
///
/// The `name` parameter gives the name this font shall be referred to
/// in the other APIs, like `"sans-serif"`.
Expand Down Expand Up @@ -369,4 +374,3 @@ pub fn register_font(
For more information, please see the examples.

$$style$$

2 changes: 1 addition & 1 deletion plotters-bitmap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ gif_backend = ["gif", "image_encoder"]

[dev-dependencies.plotters]
default-features = false
features = ["ttf", "line_series", "bitmap_backend"]
features = ["line_series", "bitmap_backend"]
path = "../plotters"

[dev-dependencies]
Expand Down
3 changes: 1 addition & 2 deletions plotters-svg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ version = "0.3.6"
path = "../plotters-backend"

[dependencies.image]
version = "0.25.9"
version = "0.25.10"
optional = true
default-features = false
features = ["jpeg", "png", "bmp"]
Expand All @@ -27,5 +27,4 @@ bitmap_encoder = ["image"]

[dev-dependencies.plotters]
default-features = false
features = ["ttf"]
path = "../plotters"
2 changes: 1 addition & 1 deletion plotters-svg/src/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ impl<'a> DrawingBackend for SVGBackend<'a> {

let color = image::ColorType::Rgb8;

encoder.write_image(src, w, h, color).map_err(|e| {
encoder.write_image(src, w, h, color.into()).map_err(|e| {
DrawingErrorKind::DrawingError(Error::new(
std::io::ErrorKind::Other,
format!("Image error: {}", e),
Expand Down
25 changes: 8 additions & 17 deletions plotters/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,11 @@ optional = true
path = "../plotters-svg"

[target.'cfg(not(all(target_arch = "wasm32", not(target_os = "wasi"))))'.dependencies]
ttf-parser = { version = "0.25.1", optional = true }
lazy_static = { version = "1.4.0", optional = true }
pathfinder_geometry = { version = "0.5.1", optional = true }
font-kit = { version = "0.14.2", optional = true }
ab_glyph = { version = "0.2.12", optional = true }
once_cell = { version = "1.8.0", optional = true }

fontique = "0.9.0"
harfrust = "0.6.0"
once_cell = "1.8.0"
skrifa = "0.42.1"
zeno = "0.3.3"

[target.'cfg(not(all(target_arch = "wasm32", not(target_os = "wasi"))))'.dependencies.image]
version = "0.25.9"
Expand Down Expand Up @@ -72,8 +70,7 @@ features = [
default = [
"bitmap_backend", "bitmap_encoder", "bitmap_gif",
"svg_backend",
"chrono",
"ttf",
"datetime",
"image",
"deprecated_items", "all_series", "all_elements",
"full_palette",
Expand Down Expand Up @@ -104,13 +101,8 @@ line_series = []
point_series = []
surface_series = []

# Font implementation
ttf = ["font-kit", "ttf-parser", "lazy_static", "pathfinder_geometry"]
# dlopen fontconfig C library at runtime instead of linking at build time
# Can be useful for cross compiling, especially considering fontconfig has lots of C dependencies
fontconfig-dlopen = ["font-kit/source-fontconfig-dlopen"]

ab_glyph = ["dep:ab_glyph", "once_cell"]
# Font compatibility
ab_glyph = []

# Misc
datetime = ["chrono"]
Expand Down Expand Up @@ -143,4 +135,3 @@ path = "benches/main.rs"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "doc_cfg"]

2 changes: 1 addition & 1 deletion plotters/examples/3d-plot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let z_axis = (-3.0..3.0).step(0.1);

let mut chart = ChartBuilder::on(&area)
.caption("3D Plot Test", ("sans", 20))
.caption("3D Plot Test", ("sans-serif", 20))
.build_cartesian_3d(x_axis.clone(), -3.0..3.0, z_axis.clone())?;

chart.with_projection(|mut pb| {
Expand Down
Loading
Loading