summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-09-29 10:48:52 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-09-29 10:48:52 +0800
commit2e01665a238512beca31d7636f78c1134d74f352 (patch)
tree329928ea5055539ff44f835d0abe2719b75ab6eb
parentf8048392526edf075a77118eceb1e8d26b6ca910 (diff)
image: get system text
-rw-r--r--Cargo.lock86
-rw-r--r--Cargo.toml2
-rw-r--r--src/image.rs38
3 files changed, 124 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index eaeae7d..30a0b0a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "ab_glyph"
-version = "0.2.31"
+version = "0.2.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e074464580a518d16a7126262fffaaa47af89d4099d4cb403f8ed938ba12ee7d"
+checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2"
dependencies = [
"ab_glyph_rasterizer",
"owned_ttf_parser",
@@ -177,6 +177,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
+name = "core_maths"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30"
+dependencies = [
+ "libm",
+]
+
+[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -315,6 +324,29 @@ dependencies = [
]
[[package]]
+name = "fontconfig-parser"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
+dependencies = [
+ "roxmltree",
+]
+
+[[package]]
+name = "fontdb"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905"
+dependencies = [
+ "fontconfig-parser",
+ "log",
+ "memmap2",
+ "slotmap",
+ "tinyvec",
+ "ttf-parser",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -463,6 +495,8 @@ dependencies = [
name = "java2flowchart"
version = "0.1.0"
dependencies = [
+ "ab_glyph",
+ "fontdb",
"image",
"imageproc",
"phf",
@@ -558,6 +592,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
+name = "memmap2"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -987,6 +1030,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
[[package]]
+name = "roxmltree"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
+
+[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1080,6 +1129,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
+name = "slotmap"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1150,6 +1208,21 @@ dependencies = [
]
[[package]]
+name = "tinyvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
name = "toml"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1188,6 +1261,9 @@ name = "ttf-parser"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
+dependencies = [
+ "core_maths",
+]
[[package]]
name = "typenum"
@@ -1219,6 +1295,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 5613b7a..7880576 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,8 @@ version = "0.1.0"
edition = "2024"
[dependencies]
+ab_glyph = "0.2.32"
+fontdb = "0.23.0"
image = "0.25.8"
imageproc = "0.25.0"
phf = { version = "0.13.1", features = ["macros"] }
diff --git a/src/image.rs b/src/image.rs
index cd76950..d642d32 100644
--- a/src/image.rs
+++ b/src/image.rs
@@ -1,7 +1,10 @@
+use ab_glyph::FontArc;
+use fontdb::{Database, Family, Query, Source};
use image::{ColorType, DynamicImage, ImageBuffer, imageops};
use imageproc::drawing::{Canvas, draw_filled_rect_mut, draw_polygon_mut};
use imageproc::point::Point;
use imageproc::rect::Rect;
+use std::io;
use std::path::Path;
use crate::ast::DepthExpr;
@@ -49,6 +52,41 @@ mod colors {
]);
}
+// TODO: store as singleton
+fn get_font() -> Result<FontArc, io::Error> {
+ let mut db = Database::new();
+ db.load_system_fonts();
+
+ let id = db
+ .query(&Query {
+ families: &[Family::SansSerif],
+ weight: fontdb::Weight::NORMAL,
+ stretch: fontdb::Stretch::Normal,
+ style: fontdb::Style::Normal,
+ })
+ .or_else(|| {
+ db.faces()
+ .next()
+ .map(|f| f.id)
+ })
+ .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "no system fonts"))?;
+
+ let face = db
+ .face(id)
+ .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "face missing"))?;
+
+ match &face.source {
+ Source::File(path) => std::fs::read(path).and_then(|bytes| FontArc::try_from_vec(bytes).map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "parse font failed"))),
+ Source::Binary(data) => FontArc::try_from_vec(
+ data.as_ref()
+ .as_ref()
+ .to_vec(),
+ )
+ .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "parse font failed")),
+ _ => Err(io::Error::new(io::ErrorKind::Unsupported, "unsupported font source")),
+ }
+}
+
fn ext(img: &mut DynamicImage, (curw, curh): &mut Offset, (extw, exth): &mut Offset) {
let (w, h) = img.dimensions();
let extedw = *extw + *curw;