use crate::builder::tags::{Tag, Tags};
use crate::builder::FontBuilder;
use crate::font::Font;
use crate::tagged_attributes::TaggedAttributes;
use crate::LoadSettings;
use std::io;
pub fn from_str(src: &str) -> crate::Result<Font> {
from_str_ext(src, &Default::default())
}
pub fn from_str_ext(src: &str, settings: &LoadSettings) -> crate::Result<Font> {
from_bytes_ext(src.as_bytes(), settings)
}
pub fn from_bytes(bytes: &[u8]) -> crate::Result<Font> {
from_bytes_ext(bytes, &Default::default())
}
pub fn from_bytes_ext(bytes: &[u8], settings: &LoadSettings) -> crate::Result<Font> {
FontBuilderText::default().load_bytes(bytes, settings)?.build(settings)
}
pub fn from_reader<R: io::Read>(reader: R) -> crate::Result<Font> {
from_reader_ext(reader, &Default::default())
}
pub fn from_reader_ext<R: io::Read>(mut reader: R, settings: &LoadSettings) -> crate::Result<Font> {
let mut vec = Vec::default();
reader.read_to_end(&mut vec)?;
from_bytes_ext(&vec, settings)
}
#[derive(Debug, Default)]
pub struct FontBuilderText {
builder: FontBuilder,
}
impl FontBuilderText {
pub fn load_bytes(
mut self,
bytes: &[u8],
settings: &LoadSettings,
) -> crate::Result<FontBuilder> {
let mut attributes = TaggedAttributes::from_bytes(bytes);
while let Some(Tag { tag, line }) = attributes.next_tag()? {
match tag {
b"info" => self.builder.set_info_attributes(line, &mut attributes),
b"common" => self.builder.set_common_attributes(line, &mut attributes),
b"page" => self.builder.add_page_attributes(&mut attributes),
b"chars" => self.builder.set_char_count_attributes(line, &mut attributes),
b"char" => self.builder.add_char_attributes(&mut attributes),
b"kernings" => self.builder.set_kerning_count_attributes(line, &mut attributes),
b"kerning" => self.builder.add_kerning_attributes(&mut attributes),
tag => {
if settings.ignore_invalid_tags {
Ok(())
} else {
let line = Some(attributes.line());
let tag =
String::from_utf8(tag.into()).map_err(|e| crate::Error::Parse {
line,
entity: "tag".to_owned(),
err: e.to_string(),
})?;
Err(crate::Error::InvalidTag { line, tag })
}
}
}?;
}
Ok(self.builder)
}
}