Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preload font files into memory to avoid frequent IO. #366

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type ResvgRenderOptions = {
loadSystemFonts?: boolean // Default: true, if set to false, it will be faster.
fontFiles?: string[] // A list of local font file paths to load.
fontDirs?: string[] // A list of local font directories to load.
preloadFonts?: boolean // Default: false. When enabled, font files will be read into memory at once to avoid frequent IO.
defaultFontSize?: number // Default: 12
defaultFontFamily?: string // Default: "", if `loadSystemFonts` is enabled, it will be set to the first font in the list of system fonts.
serifFamily?: string
Expand Down
6 changes: 3 additions & 3 deletions js-binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
/* auto-generated by NAPI-RS */

export function renderAsync(svg: string | Buffer, options?: string | undefined | null, signal?: AbortSignal | undefined | null): Promise<RenderedImage>
export class BBox {
export declare class BBox {
x: number
y: number
width: number
height: number
}
export class Resvg {
export declare class Resvg {
constructor(svg: string | Buffer, options?: string | undefined | null)
/** Renders an SVG in Node.js */
render(): RenderedImage
Expand Down Expand Up @@ -40,7 +40,7 @@ export class Resvg {
/** Get the SVG height */
get height(): number
}
export class RenderedImage {
export declare class RenderedImage {
/** Write the image data to Buffer */
asPng(): Buffer
/** Get the RGBA pixels of the image */
Expand Down
46 changes: 37 additions & 9 deletions src/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,48 @@ use woff2::decode::{convert_woff2_to_ttf, is_woff2};
/// Loads fonts.
#[cfg(not(target_arch = "wasm32"))]
pub fn load_fonts(font_options: &JsFontOptions) -> Database {
// Create a new font database
let mut fontdb = Database::new();
let now = std::time::Instant::now();

// 加载指定路径的字体
for path in &font_options.font_files {
if let Err(e) = fontdb.load_font_file(path) {
warn!("Failed to load '{}' cause {}.", path, e);
if font_options.preload_fonts {
// 预加载模式: 一次性读取所有字体文件到内存
for path in &font_options.font_files {
match std::fs::read(path) {
Ok(buffer) => {
let _ = fontdb.load_font_data(buffer);
}
Err(e) => {
warn!("Failed to read font file '{}' cause {}.", path, e);
}
}
}

// 加载字体目录
for dir in &font_options.font_dirs {
if let Ok(entries) = std::fs::read_dir(dir) {
for entry in entries.flatten() {
if let Ok(path) = entry.path().canonicalize() {
if path.is_file() {
if let Ok(buffer) = std::fs::read(&path) {
let _ = fontdb.load_font_data(buffer);
}
}
}
}
}
}
} else {
// 默认模式: 直接传递文件路径
for path in &font_options.font_files {
if let Err(e) = fontdb.load_font_file(path) {
warn!("Failed to load '{}' cause {}.", path, e);
}
}
}

// Load font directories
for path in &font_options.font_dirs {
fontdb.load_fonts_dir(path);
// Load font directories
for path in &font_options.font_dirs {
fontdb.load_fonts_dir(path);
}
}

// 加载系统字体
Expand Down
7 changes: 7 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ pub struct JsFontOptions {
/// A list of local font directories to load.
pub font_dirs: Vec<String>,

/// Whether to preload font files into memory to improve performance.
/// When enabled, font files will be read into memory at once to avoid frequent IO.
///
/// Default: false
pub preload_fonts: bool,

/// The default font family.
///
/// Will be used when no `font-family` attribute is set in the SVG.
Expand Down Expand Up @@ -284,6 +290,7 @@ impl Default for JsFontOptions {
load_system_fonts: true,
font_files: vec![],
font_dirs: vec![],
preload_fonts: false,
default_font_family: "".to_string(),
default_font_size: 12.0,
serif_family: "Times New Roman".to_string(),
Expand Down