diff --git a/src-tauri/src/epub.rs b/src-tauri/src/epub.rs index a236068..9847c97 100644 --- a/src-tauri/src/epub.rs +++ b/src-tauri/src/epub.rs @@ -5,6 +5,9 @@ use std::io::Write; use zip::write::SimpleFileOptions; use zip::{CompressionMethod, ZipWriter}; +static LITERATA: &[u8] = include_bytes!("../../public/fonts/Literata-VF.ttf"); +static LITERATA_ITALIC: &[u8] = include_bytes!("../../public/fonts/Literata-Italic-VF.ttf"); + #[derive(Deserialize)] pub struct EpubFile { path: String, @@ -17,10 +20,8 @@ fn build(files: &[EpubFile]) -> Result, String> { let mut zip = ZipWriter::new(buffer); let stored = SimpleFileOptions::default().compression_method(CompressionMethod::Stored); - zip.start_file("mimetype", stored) - .map_err(|e| e.to_string())?; - zip.write_all(b"application/epub+zip") - .map_err(|e| e.to_string())?; + zip.start_file("mimetype", stored).map_err(|e| e.to_string())?; + zip.write_all(b"application/epub+zip").map_err(|e| e.to_string())?; let deflated = SimpleFileOptions::default().compression_method(CompressionMethod::Deflated); for file in files { @@ -33,11 +34,18 @@ fn build(files: &[EpubFile]) -> Result, String> { .map_err(|e| format!("failed to decode \"{}\": {e}", file.path))?, _ => file.data.as_bytes().to_vec(), }; - zip.start_file(&file.path, deflated) - .map_err(|e| e.to_string())?; + zip.start_file(&file.path, deflated).map_err(|e| e.to_string())?; zip.write_all(&bytes).map_err(|e| e.to_string())?; } + for (path, bytes) in [ + ("OEBPS/fonts/Literata-VF.ttf", LITERATA), + ("OEBPS/fonts/Literata-Italic-VF.ttf", LITERATA_ITALIC), + ] { + zip.start_file(path, deflated).map_err(|e| e.to_string())?; + zip.write_all(bytes).map_err(|e| e.to_string())?; + } + Ok(zip.finish().map_err(|e| e.to_string())?.into_inner()) } diff --git a/src/export/epub.ts b/src/export/epub.ts index dc15011..eacdbbf 100644 --- a/src/export/epub.ts +++ b/src/export/epub.ts @@ -389,24 +389,8 @@ export function bookToEpub(book: Book): EpubFile[] { return files; } -function toBase64(bytes: Uint8Array): string { - let binary = ""; - for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]); - return btoa(binary); -} - -async function fontFile(url: string, path: string): Promise { - const response = await fetch(url); - const buffer = await response.arrayBuffer(); - return { path, data: toBase64(new Uint8Array(buffer)), encoding: "base64" }; -} - export async function buildEpub(book: Book): Promise { const files = bookToEpub(book); - files.push( - await fontFile("/fonts/Literata-VF.ttf", "OEBPS/fonts/Literata-VF.ttf"), - await fontFile("/fonts/Literata-Italic-VF.ttf", "OEBPS/fonts/Literata-Italic-VF.ttf"), - ); const buf = await invoke("package_epub", { files }); return new Uint8Array(buf); }