Add font family selector for watermark text
This commit is contained in:
@@ -203,6 +203,7 @@ pub enum WatermarkConfig {
|
||||
font_size: f32,
|
||||
opacity: f32,
|
||||
color: [u8; 4],
|
||||
font_family: Option<String>,
|
||||
},
|
||||
Image {
|
||||
path: std::path::PathBuf,
|
||||
|
||||
@@ -46,7 +46,8 @@ pub fn apply_watermark(
|
||||
font_size,
|
||||
opacity,
|
||||
color,
|
||||
} => apply_text_watermark(img, text, *position, *font_size, *opacity, *color),
|
||||
font_family,
|
||||
} => apply_text_watermark(img, text, *position, *font_size, *opacity, *color, font_family.as_deref()),
|
||||
WatermarkConfig::Image {
|
||||
path,
|
||||
position,
|
||||
@@ -56,7 +57,38 @@ pub fn apply_watermark(
|
||||
}
|
||||
}
|
||||
|
||||
fn find_system_font() -> Result<Vec<u8>> {
|
||||
fn find_system_font(family: Option<&str>) -> Result<Vec<u8>> {
|
||||
// If a specific font family was requested, try to find it via fontconfig
|
||||
if let Some(name) = family {
|
||||
if !name.is_empty() {
|
||||
// Try common font paths with the family name
|
||||
let search_dirs = [
|
||||
"/usr/share/fonts",
|
||||
"/usr/local/share/fonts",
|
||||
];
|
||||
let name_lower = name.to_lowercase();
|
||||
for dir in &search_dirs {
|
||||
if let Ok(entries) = walkdir(std::path::Path::new(dir)) {
|
||||
for path in entries {
|
||||
let file_name = path.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("")
|
||||
.to_lowercase();
|
||||
if file_name.contains(&name_lower)
|
||||
&& (file_name.ends_with(".ttf") || file_name.ends_with(".otf"))
|
||||
&& (file_name.contains("regular") || !file_name.contains("bold") && !file_name.contains("italic"))
|
||||
{
|
||||
if let Ok(data) = std::fs::read(&path) {
|
||||
return Ok(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to default system fonts
|
||||
let candidates = [
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
|
||||
"/usr/share/fonts/TTF/DejaVuSans.ttf",
|
||||
@@ -78,6 +110,25 @@ fn find_system_font() -> Result<Vec<u8>> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Recursively walk a directory and collect file paths
|
||||
fn walkdir(dir: &std::path::Path) -> std::io::Result<Vec<std::path::PathBuf>> {
|
||||
let mut results = Vec::new();
|
||||
if dir.is_dir() {
|
||||
for entry in std::fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
if let Ok(sub) = walkdir(&path) {
|
||||
results.extend(sub);
|
||||
}
|
||||
} else {
|
||||
results.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn apply_text_watermark(
|
||||
img: DynamicImage,
|
||||
text: &str,
|
||||
@@ -85,8 +136,9 @@ fn apply_text_watermark(
|
||||
font_size: f32,
|
||||
opacity: f32,
|
||||
color: [u8; 4],
|
||||
font_family: Option<&str>,
|
||||
) -> Result<DynamicImage> {
|
||||
let font_data = find_system_font()?;
|
||||
let font_data = find_system_font(font_family)?;
|
||||
let font = ab_glyph::FontArc::try_from_vec(font_data).map_err(|_| {
|
||||
PixstripError::Processing {
|
||||
operation: "watermark".into(),
|
||||
|
||||
Reference in New Issue
Block a user