diff --git a/sample-short.epub b/sample-short.epub new file mode 100644 index 0000000..af9abc0 Binary files /dev/null and b/sample-short.epub differ diff --git a/src/reader.rs b/src/reader.rs index 356d2b9..c25a402 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -3,11 +3,9 @@ use crate::book::Book; use crate::style::{StyleProfile, TextAlignment}; use crate::theme::{self, BgType, Theme}; -pub fn recalculate_pages(book: &mut Book, font_size: f32, line_height: f32, panel_width: f32, panel_height: f32) { - // 中文全角字符宽度 ≈ 1.0 × font_size +pub fn recalculate_pages(book: &mut Book, font_size: f32, line_height: f32, panel_width: f32, panel_height: f32, style: &StyleProfile) { let char_width = font_size * 1.0; - // 安全系数 0.97:抵消段落间距/缩进等样式增加的内容 - let safety = 0.97; + let safety = 0.95; let chars_per_line = if char_width > 0.0 { ((panel_width / char_width) * safety).max(1.0) as usize } else { @@ -20,7 +18,8 @@ pub fn recalculate_pages(book: &mut Book, font_size: f32, line_height: f32, pane }; let chars_per_page = chars_per_line * lines_per_page; for section in &mut book.sections { - section.pages = calculate_pages(§ion.content, chars_per_page); + let styled = style.apply_to_text(§ion.content); + section.pages = calculate_pages(&styled, chars_per_page); } } @@ -156,7 +155,7 @@ egui::ComboBox::from_id_salt("bg_type_selector") let panel_size = ui.available_size(); let recalc_width = (panel_size.x - 48.0).max(100.0); let recalc_height = (panel_size.y - 60.0).max(200.0); - recalculate_pages(book, style.font_size, style.line_height(), recalc_width, recalc_height); + recalculate_pages(book, style.font_size, style.line_height(), recalc_width, recalc_height, style); // --- Bottom progress bar --- let total_pages = if *current_section < book.sections.len() { @@ -242,8 +241,8 @@ egui::ComboBox::from_id_salt("bg_type_selector") if *current_page < section.pages.len().saturating_sub(1) { let start = section.pages[*current_page]; let end = section.pages[*current_page + 1]; - let raw_text: String = section.content.chars().skip(start).take(end - start).collect(); - let indented = style.apply_to_text(&raw_text); + let styled_full = style.apply_to_text(§ion.content); + let page_text: String = styled_full.chars().skip(start).take(end - start).collect(); let align = match style.alignment { TextAlignment::Left => egui::Align::LEFT, @@ -256,13 +255,13 @@ egui::ComboBox::from_id_salt("bg_type_selector") |ui| { let mut is_heading = false; let mut text_start = 0usize; - let char_indices: Vec<_> = indented.char_indices().collect(); + let char_indices: Vec<_> = page_text.char_indices().collect(); let mut idx = 0; while idx < char_indices.len() { let (byte_pos, ch) = char_indices[idx]; if ch == '\x01' || ch == '\x02' { if byte_pos > text_start { - let text = &indented[text_start..byte_pos]; + let text = &page_text[text_start..byte_pos]; let mut rt = egui::RichText::new(text) .size(style.font_size) .color(colors.text); @@ -276,14 +275,14 @@ egui::ComboBox::from_id_salt("bg_type_selector") if idx < char_indices.len() { text_start = char_indices[idx].0; } else { - text_start = indented.len(); + text_start = page_text.len(); } } else { idx += 1; } } - if text_start < indented.len() { - let text = &indented[text_start..]; + if text_start < page_text.len() { + let text = &page_text[text_start..]; let mut rt = egui::RichText::new(text) .size(style.font_size) .color(colors.text);