Skip to content

Commit

Permalink
feat(rendering): pick the right font
Browse files Browse the repository at this point in the history
  • Loading branch information
hualet committed Jan 24, 2025
1 parent 4c99f05 commit a742fe8
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
43 changes: 42 additions & 1 deletion src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ pub struct Document {
pub custom_tags: Option<String>,

#[serde(skip)]
pub res: DocumentRes,
pub doc_res: DocumentRes,
#[serde(skip)]
pub public_res: PublicRes,
}

#[derive(Deserialize, Debug, Default)]
Expand Down Expand Up @@ -110,4 +112,43 @@ impl DocumentRes {
pub fn from_xml(xml: &str) -> Result<DocumentRes, serde_xml_rs::Error> {
serde_xml_rs::from_str(xml)
}
}


/* PublicRes.xml
<?xml version="1.0" encoding="UTF-8"?><ofd:Res xmlns:ofd="http://www.ofdspec.org/2016" BaseLoc="Res">
<ofd:Fonts>
<ofd:Font FamilyName="宋体" FontName="宋体" ID="3"/>
<ofd:Font FamilyName="楷体" FontName="楷体" ID="5"/>
<ofd:Font FamilyName="Courier New" FontName="Courier New" ID="7"/>
</ofd:Fonts>
</ofd:Res>
*/

#[derive(Deserialize, Debug, Default)]
#[serde(rename_all = "PascalCase")]
pub struct PublicRes {
pub base_loc: String,
pub fonts: Fonts,
}

#[derive(Deserialize, Debug, Default)]
#[serde(rename_all = "PascalCase")]
pub struct Fonts {
pub font: Vec<Font>,
}

#[derive(Deserialize, Debug, Default)]
#[serde(rename_all = "PascalCase")]
pub struct Font {
#[serde(rename = "ID")]
pub id: u32,
pub family_name: String,
pub font_name: String,
}

impl PublicRes {
pub fn from_xml(xml: &str) -> Result<PublicRes, serde_xml_rs::Error> {
serde_xml_rs::from_str(xml)
}
}
23 changes: 20 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::path::Path;

use zip::ZipArchive;

use document::{Document, DocumentRes};
use document::{Document, DocumentRes, PublicRes};
use ofd::{Ofd, OfdNode};
use page::Page;
use render::Renderable;
Expand Down Expand Up @@ -55,7 +55,7 @@ pub fn export_ofd_to_png(ofd: &mut Ofd, output_path: &str) -> Result<(), Box<dyn
let mut document = Document::from_xml(&content)?;
println!("document: {:#?}", document);

// Find the DocumentRes.xml file and parse the content to a document_res object.
// Find the DocumentRes.xml file and parse the content to a DocumentRes object.
{
let doc_root_path = ofd.node.doc_body.doc_root.as_str();
let root_path = Path::new(doc_root_path);
Expand All @@ -70,7 +70,24 @@ pub fn export_ofd_to_png(ofd: &mut Ofd, output_path: &str) -> Result<(), Box<dyn

let document_res = DocumentRes::from_xml(&content)?;
println!("document_res: {:#?}", document_res);
document.res = document_res;
document.doc_res = document_res;

// Find the PublicRes.xml file and parse the content to a PublicRes object.
{
let doc_root_path = ofd.node.doc_body.doc_root.as_str();
let root_path = Path::new(doc_root_path);
let res_path = root_path
.parent().ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Parent directory not found"))?
.join(document.common_data.public_res.as_str());
let mut public_res_file = ofd.zip_archive.by_name(res_path.to_str().unwrap())?;

content.clear();
public_res_file.read_to_string(&mut content)?;
}

let public_res = PublicRes::from_xml(&content)?;
println!("public_res: {:#?}", public_res);
document.public_res = public_res;

// Create a cairo surface and context.
let pybox = CT_PageArea::from(document.common_data.page_area.physical_box.clone()).toPixel();
Expand Down
15 changes: 11 additions & 4 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,15 @@ impl Renderable for TextObject {
let color = self.fill_color.as_ref().unwrap_or(&Color::default()).value.clone();
let fill_color = CT_Color::from(color);

// TODO(hualet): load the right font
context.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
let font_id = self.font;
for font in document.public_res.fonts.font.iter() {
if font.id == font_id {
// TODO(hualet): custom font file loading.
context.select_font_face(font.family_name.as_str(),
cairo::FontSlant::Normal, cairo::FontWeight::Normal);
break;
}
}
context.set_font_size(mmtopx(self.size) as f64);

context.set_source_rgb(fill_color.value[0] as f64 / 255.0,
Expand All @@ -99,11 +106,11 @@ impl Renderable for ImageObject {
// 1) find the resource file in DocumentRes with the resource id
// 2) construct the path of the image file
// 3) load the image file and draw
for resource in document.res.multi_medias.multi_media.iter() {
for resource in document.doc_res.multi_medias.multi_media.iter() {
if resource.id == self.resource_id {
let path = Path::new(ofd.node.doc_body.doc_root.as_str());
let res_path = &path.parent().unwrap()
.join(document.res.base_loc.as_str())
.join(document.doc_res.base_loc.as_str())
.join(resource.media_file.as_str());

let mut file = ofd.zip_archive.by_name(res_path.to_str().unwrap()).unwrap();
Expand Down

0 comments on commit a742fe8

Please sign in to comment.