Skip to content

Commit

Permalink
Fix images not appearing in PDF
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Dec 7, 2024
1 parent 58c878a commit e802807
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 230 deletions.
13 changes: 6 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ pdf-writer = { version = "0.12.0" }
image = { version = "0.25", default-features = false }
svg2pdf = { version = "0.12.0" }
# dependencies for wasm demo
azul-css = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false }
azul-css-parser = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false }
azul-core = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false, features = ["std"] }
azul-layout = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false, features = ["std", "text_layout"] }
azul-text-layout = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false }
azulc = { git = "https://github.com/fschutt/azul", rev = "8b71bef5439b8f8d4542a2849e66499173562235", default-features = false, features = ["std", "xml", "text_layout", "font_loading"] }
azul-css = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false }
azul-css-parser = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false }
azul-core = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false, features = ["std"] }
azul-layout = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false, features = ["std", "text_layout"] }
azul-text-layout = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false }
azulc = { git = "https://github.com/fschutt/azul", rev = "7e31b697b8e61779b88790aa9a74a95d8295a51a", default-features = false, features = ["std", "xml", "text_layout", "font_loading"] }
rust-fontconfig = { version = "0.1.13", default-features = false }
xmlparser = { version = "0.13.6", default-features = false }
serde = { version = "1" }
Expand Down
62 changes: 38 additions & 24 deletions examples/html.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
use printpdf::*;

const HTML_STRINGS: &[&str; 2] = &[
"<div style='background:red;padding:10px;flex-grow:1;'><div style='background:yellow;padding:20px;'><p>hello</p></div></div>",
"<div style='padding:10px;background:lightblue;'>
<p style='font-size:12px;border:1px solid black;color:red;font-family:Times-Bold;'>Very long text that breaks into multiple lines. asdfasd asdfasdf adsfasdf ladsjfplasdjf asdlfkjasdfl lasdkjfasdölkjf</p>
</div>",
];
const HTML_STRINGS: &[&str; 1] = &["<img src='test.bmp' />"];

pub struct ImgComponent { }
pub struct ImgComponent {}

impl XmlComponentTrait for ImgComponent {

fn get_available_arguments(&self) -> ComponentArguments {
ComponentArguments {
accepts_text: false,
args: vec![("src".to_string(), "String".to_string())]
args: vec![("src".to_string(), "String".to_string())],
}
}

Expand All @@ -24,35 +18,55 @@ impl XmlComponentTrait for ImgComponent {
arguments: &FilteredComponentArguments,
content: &XmlTextContent,
) -> Result<StyledDom, RenderDomError> {
// TODO: parse image from arguments["src"]
Ok(Dom::image(
InternalImageRef::new_rawimage(
translate_to_internal_rawimage(
&RawImage::decode_from_bytes(include_bytes!("./assets/img/dog_alpha.png")).unwrap()
)
).unwrap()
).style(CssApiWrapper::empty()))
use printpdf::html::ImageInfo;

let im_info = arguments
.values
.get("src")
.map(|s| s.as_bytes().to_vec())
.unwrap_or_default();

let image_info = serde_json::from_slice::<ImageInfo>(&im_info)
.ok()
.unwrap_or_default();
let data_format = RawImageFormat::RGB8;

let image = RawImage {
width: image_info.width,
height: image_info.height,
data_format,
pixels: RawImageData::empty(data_format),
tag: im_info,
};

let im = Dom::image(image.to_internal()).style(CssApiWrapper::empty());

Ok(im)
}
}

fn main() -> Result<(), String> {

for (i, h) in HTML_STRINGS.iter().enumerate() {

let components = vec![XmlComponent {
id: "img".to_string(),
renderer: Box::new(ImgComponent { }),
renderer: Box::new(ImgComponent {}),
inherit_vars: false,
}];

let config = XmlRenderOptions {
components,
.. Default::default()
images: vec![(
"test.bmp".to_string(),
include_bytes!("./assets/img/BMP_test.bmp").to_vec(),
)]
.into_iter()
.collect(),
..Default::default()
};

let doc = PdfDocument::new("HTML rendering demo")
.with_html(h, config)?
.save(&PdfSaveOptions::default());
let mut doc = PdfDocument::new("HTML rendering demo");
let pages = doc.html2pages(h, config)?;
let doc = doc.with_pages(pages).save(&PdfSaveOptions::default());
std::fs::write(format!("html{i}.pdf"), doc).unwrap();
}

Expand Down
31 changes: 12 additions & 19 deletions examples/subset.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
use allsorts::subset;
use printpdf::*;

const WIN_1252: &[char; 214] = &[
'!', '"','#', '$', '%','&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<',
'=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c',
'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}',
'~', '€', '‚', 'ƒ', '„', '…', '†', '‡', 'ˆ', '‰', 'Š', '‹', 'Œ',
'Ž', '‘', '’', '“', '•', '–', '—', '˜', '™', 'š', '›', 'œ', 'ž',
'Ÿ', '¡', '¢', '£', '¤', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬',
'®', '¯', '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º',
'»', '¼', '½', '¾', '¿', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç',
'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô',
'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß', 'à', 'á',
'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î',
'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û',
'ü', 'ý', 'þ', 'ÿ'
'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '€',
'‚', 'ƒ', '„', '…', '†', '‡', 'ˆ', '‰', 'Š', '‹', 'Œ', 'Ž', '‘', '’', '“', '•', '–', '—', '˜',
'™', 'š', '›', 'œ', 'ž', 'Ÿ', '¡', '¢', '£', '¤', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬', '®',
'¯', '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿', 'À', 'Á',
'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô',
'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç',
'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú',
'û', 'ü', 'ý', 'þ', 'ÿ',
];

const FONTS: &[(BuiltinFont, &[u8])] = &[
Expand Down
34 changes: 22 additions & 12 deletions src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,8 @@ impl ParsedFont {
}

pub fn subset_simple(&self, chars: &BTreeSet<char>) -> Result<SubsetFont, String> {

let scope = ReadScope::new(&self.original_bytes);
let font_file = scope.read::<FontData<'_>>()
.map_err(|e| e.to_string())?;
let font_file = scope.read::<FontData<'_>>().map_err(|e| e.to_string())?;
let provider = font_file
.table_provider(self.original_index)
.map_err(|e| e.to_string())?;
Expand All @@ -344,9 +342,8 @@ impl ParsedFont {
let mut gids = p.iter().map(|s| s.0).collect::<Vec<_>>();
gids.sort();
gids.dedup();

let bytes = allsorts::subset::subset(&provider, &gids)
.map_err(|e| e.to_string())?;

let bytes = allsorts::subset::subset(&provider, &gids).map_err(|e| e.to_string())?;

Ok(SubsetFont {
bytes,
Expand All @@ -372,9 +369,11 @@ impl ParsedFont {
.table_provider(self.original_index)
.map_err(|e| e.to_string())?;

let font =
allsorts::subset::subset(&provider, &glyph_ids.iter().map(|s| s.0).collect::<Vec<_>>())
.map_err(|e| e.to_string())?;
let font = allsorts::subset::subset(
&provider,
&glyph_ids.iter().map(|s| s.0).collect::<Vec<_>>(),
)
.map_err(|e| e.to_string())?;

Ok(SubsetFont {
bytes: font,
Expand Down Expand Up @@ -633,7 +632,7 @@ impl ParsedFont {
let second_font_file = second_scope.read::<FontData<'_>>().ok()?;
let second_provider = second_font_file.table_provider(font_index).ok()?;

let mut font_data_impl = allsorts::font::Font::new(second_provider).ok()?;
let font_data_impl = allsorts::font::Font::new(second_provider).ok()?;

// required for font layout: gsub_cache, gpos_cache and gdef_table
let gsub_cache = None; // font_data_impl.gsub_cache().ok().and_then(|s| s);
Expand All @@ -651,7 +650,6 @@ impl ParsedFont {
println!("warning: no cmap subtable");
}


let hmtx_data = provider
.table_data(tag::HMTX)
.ok()
Expand All @@ -668,7 +666,19 @@ impl ParsedFont {
.table_data(tag::HHEA)
.ok()
.and_then(|hhea_data| ReadScope::new(&hhea_data?).read::<HheaTable>().ok())
.unwrap_or(unsafe { std::mem::zeroed() });
.unwrap_or(HheaTable {
ascender: 0,
descender: 0,
line_gap: 0,
advance_width_max: 0,
min_left_side_bearing: 0,
min_right_side_bearing: 0,
x_max_extent: 0,
caret_slope_rise: 0,
caret_slope_run: 0,
caret_offset: 0,
num_h_metrics: 0,
});

let font_metrics = FontMetrics::from_bytes(font_bytes, font_index);

Expand Down
Loading

0 comments on commit e802807

Please sign in to comment.