use super::*;
use crate::hnc8::TextFraming;
use crate::hnc8::native_page::admits_native_mode;
use std::io::Write;
pub fn uses_native_text<S, C>(source: &mut S, limits: &Limits, cancellation: &C) -> Result<bool>
where
S: RangedSource,
C: Cancellation,
{
validate(limits)?;
let mut reader = match Hnc8Reader::open(source, limits, cancellation) {
Ok(reader) if !admits_native_mode(reader.header()) => return Ok(false),
Ok(reader) => reader,
Err(error) => return image_unless_fatal(error, Hnc8Stage::Container),
};
loop {
let page = match reader.next_page() {
Ok(Some(page)) => page,
Ok(None) => return Ok(false),
Err(error) => return image_unless_fatal(error, Hnc8Stage::Container),
};
loop {
match reader.next_image() {
Ok(Some(_)) => {}
Ok(None) => break,
Err(error) => return image_unless_fatal(error, Hnc8Stage::Container),
}
}
if page.text.length == 0 {
continue;
}
if reader.header().variant == Variant::HnB {
return Ok(true);
}
return match reader.inspect_text() {
Ok(text) => Ok(text.framing == TextFraming::Native),
Err(error) => image_unless_fatal(error, Hnc8Stage::Text).map(|_| true),
};
}
}
fn image_unless_fatal(error: Error, stage: Hnc8Stage) -> Result<bool> {
match error.kind {
ErrorKind::Cancelled | ErrorKind::Io(_) => Err(container(error, stage)),
_ => Ok(false),
}
}
#[allow(clippy::too_many_arguments)]
pub fn convert_document_pdf<S, F, W, V, C>(
source: &mut S,
sink: &mut W,
fonts: Option<C8FontSources<'_, F>>,
table: Option<&QmTable>,
visitor: &mut V,
options: ComposeOptions,
limits: &Limits,
cancellation: &C,
) -> Result<ComposeReport>
where
S: RangedSource,
F: RangedSource,
W: Write,
V: ComposeVisitor,
C: Cancellation,
{
let mut routing = 0;
let mut counted = CountingSource::new(&mut *source, &mut routing);
let native = match fonts {
Some(fonts) if uses_native_text(&mut counted, limits, cancellation)? => Some(fonts),
_ => None,
};
let mut report = match native {
Some(fonts) => {
convert_c8_native_pdf(source, sink, fonts, table, options, limits, cancellation)?
}
None => {
convert_source_pages_pdf(source, sink, table, visitor, options, limits, cancellation)?
}
};
report.conversion.input_bytes_read = report.conversion.input_bytes_read.saturating_add(routing);
Ok(report)
}