Skip to content

Commit

Permalink
Update img component
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Nov 15, 2024
1 parent 1f08268 commit 6371bf1
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 37 deletions.
Binary file modified .DS_Store
Binary file not shown.
12 changes: 6 additions & 6 deletions Cargo.lock

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

22 changes: 6 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,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 = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false }
azul-css-parser = { git = "https://github.com/fschutt/azul", rev = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false }
azul-core = { git = "https://github.com/fschutt/azul", rev = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false, features = [
"std",
] }
azul-layout = { git = "https://github.com/fschutt/azul", rev = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false, features = [
"std",
"text_layout",
] }
azul-text-layout = { git = "https://github.com/fschutt/azul", rev = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false }
azulc = { git = "https://github.com/fschutt/azul", rev = "6a69b69994d1b4cda89b61922233de88498878ef", default-features = false, features = [
"std",
"xml",
"text_layout",
"font_loading",
] }
azul-css = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", default-features = false }
azul-css-parser = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", default-features = false }
azul-core = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", default-features = false, features = ["std"] }
azul-layout = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", default-features = false, features = ["std", "text_layout"] }
azul-text-layout = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", default-features = false }
azulc = { git = "https://github.com/fschutt/azul", rev = "32e272f4e8ec23dfebb2ec87b32c4d98e4090547", 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
46 changes: 44 additions & 2 deletions examples/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,57 @@ use printpdf::*;

const HTML_STRINGS: &[&str; 1] = &[
// "<div style='background:red;padding:10px;'><div style='background:yellow;padding:20px;'></div></div>",
"<p style='color:red;font-family:sans-serif'>Hello!</p>",
"<p style='color:red;font-family:sans-serif'>Hello!</p><img src='dog-alpha.png' />",
];

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())]
}
}

fn render_dom(
&self,
components: &XmlComponentMap,
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()))
}
}

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

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

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

let config = XmlRenderOptions {
components,
.. Default::default()
};

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

Ok(())
}
42 changes: 32 additions & 10 deletions src/html.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
use crate::{BuiltinFont, Mm, Op, PdfDocument, PdfPage, PdfResources, Pt};
use crate::{BuiltinFont, Mm, Op, PdfDocument, PdfPage, PdfResources, Pt};
use azul_core::{
app_resources::{
DpiScaleFactor, Epoch, IdNamespace, ImageCache, ImageDescriptor, ImageRef, ImageRefHash,
RendererResources,
DpiScaleFactor, Epoch, IdNamespace, ImageCache,
ImageDescriptor, ImageRef, ImageRefHash, RendererResources
},
callbacks::DocumentId,
display_list::{
RectBackground, RenderCallbacks, SolvedLayout, StyleBorderColors, StyleBorderRadius,
StyleBorderStyles, StyleBorderWidths,
},
dom::{NodeData, NodeId},
styled_dom::{ContentGroup, DomId, StyledDom, StyledNode},
styled_dom::{ContentGroup, DomId, StyledNode},
ui_solver::LayoutResult,
window::{FullWindowState, LogicalSize},
xml::{XmlComponentMap, XmlNode},
window::{FullWindowState, LogicalSize}, xml::Xml,
};
use azul_css::{CssPropertyValue, FloatValue, LayoutDisplay, StyleTextColor, U8Vec};
use base64::Engine;
use rust_fontconfig::{FcFont, FcFontCache, FcPattern};
use std::collections::BTreeMap;
pub use azul_core::xml::{
XmlComponent,
XmlComponentTrait,
ComponentArguments,
XmlComponentMap,
FilteredComponentArguments,
XmlTextContent,
RenderDomError,
CompileError,
XmlNode
};
pub use azul_core::styled_dom::StyledDom;
pub use azul_core::dom::Dom;
pub use azul_core::app_resources::ImageRef as InternalImageRef;
pub use azul_css_parser::CssApiWrapper;

const DPI_SCALE: DpiScaleFactor = DpiScaleFactor {
inner: FloatValue::const_new(1),
Expand All @@ -32,12 +47,13 @@ const DOCUMENT_ID: DocumentId = DocumentId {

pub type Base64String = String;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug)]
pub struct XmlRenderOptions {
pub images: BTreeMap<String, Base64String>,
pub fonts: BTreeMap<String, Base64String>,
pub page_width: Mm,
pub page_height: Mm,
pub components: Vec<XmlComponent>,
}

impl Default for XmlRenderOptions {
Expand All @@ -47,15 +63,17 @@ impl Default for XmlRenderOptions {
fonts: Default::default(),
page_width: Mm(210.0),
page_height: Mm(297.0),
components: Default::default(),
}
}
}

pub(crate) fn xml_to_pages(
file_contents: &str,
config: &XmlRenderOptions,
config: XmlRenderOptions,
document: &mut PdfDocument,
) -> Result<Vec<PdfPage>, String> {

let size = LogicalSize {
width: config.page_width.into_pt().0,
height: config.page_height.into_pt().0,
Expand All @@ -66,8 +84,13 @@ pub(crate) fn xml_to_pages(

let fixup = fixup_xml_nodes(&root_nodes);

let styled_dom = azul_core::xml::str_to_dom(&fixup, &mut XmlComponentMap::default())
.map_err(|e| format!("Error constructing DOM: {e}"))?;
let mut components = XmlComponentMap::default();
for c in config.components {
components.register_component(c);
}

let styled_dom = azul_core::xml::str_to_dom(fixup.as_ref(), &mut components)
.map_err(|e| format!("Error constructing DOM: {}", e.to_string()))?;

let dom_id = DomId { inner: 0 };
let mut fake_window_state = FullWindowState::default();
Expand Down Expand Up @@ -447,7 +470,6 @@ fn displaylist_handle_rect(
}

if let Some((text, id, color)) = opt_text {
println!("writing text {text:#?} {id:?}");
ops.push(Op::StartTextSection);
ops.push(Op::SetFillColor {
col: crate::Color::Rgb(crate::Rgb {
Expand Down
65 changes: 64 additions & 1 deletion src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,69 @@ impl RawImage {
pub fn decode_from_bytes(bytes: &[u8]) -> Result<Self, String> {
use image::DynamicImage::*;

let im = image::guess_format(bytes).map_err(|e| e.to_string())?;
let b_len = bytes.len();

#[cfg(not(feature = "gif"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'gif' to decode GIF files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Gif { return Err(err); }
}

#[cfg(not(feature = "jpeg"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'jpeg' to decode JPEG files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Gif { return Err(err); }
}

#[cfg(not(feature = "png"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'png' to decode PNG files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Png { return Err(err); }
}

#[cfg(not(feature = "pnm"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'pnm' to decode PNM files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Pnm { return Err(err); }
}

#[cfg(not(feature = "tiff"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'tiff' to decode TIFF files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Tiff { return Err(err); }
}

#[cfg(not(feature = "tiff"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'tiff' to decode TIFF files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Tiff { return Err(err); }
}

#[cfg(not(feature = "bmp"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'bmp' to decode BMP files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Bmp { return Err(err); }
}

#[cfg(not(feature = "ico"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'ico' to decode ICO files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Ico { return Err(err); }
}

#[cfg(not(feature = "tga"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'tga' to decode TGA files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Tga { return Err(err); }
}

#[cfg(not(feature = "hdr"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'hdr' to decode HDR files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Hdr { return Err(err); }
}

#[cfg(not(feature = "dds"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'dds' to decode DDS files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::Dds { return Err(err); }
}

#[cfg(not(feature = "webp"))] {
let err = format!("cannot decode image (len = {b_len} bytes): printpdf is missing feature 'webp' to decode WEBP files. Please enable it or construct the RawImage manually.");
if im == image::ImageFormat::WebP { return Err(err); }
}

let im = image::ImageReader::new(Cursor::new(bytes))
.with_guessed_format()
.map_err(|e| e.to_string())?
Expand Down Expand Up @@ -269,7 +332,7 @@ pub(crate) fn translate_from_internal_rawimage(
}
}

pub(crate) fn translate_to_internal_rawimage(im: &RawImage) -> azul_core::app_resources::RawImage {
pub fn translate_to_internal_rawimage(im: &RawImage) -> azul_core::app_resources::RawImage {
azul_core::app_resources::RawImage {
pixels: match &im.pixels {
RawImageData::U8(vec) => azul_core::app_resources::RawImageData::U8(vec.clone().into()),
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl PdfDocument {
pub fn with_html(
&mut self,
html: &str,
config: &XmlRenderOptions,
config: XmlRenderOptions,
) -> Result<&mut Self, String> {
let mut pages = crate::html::xml_to_pages(html, config, self)?;
self.pages.append(&mut pages);
Expand Down
3 changes: 2 additions & 1 deletion src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ fn printpdf_from_xml_internal(
page_height: Mm(input.options.page_height_mm.unwrap_or(297.0)),
images: BTreeMap::new(),
fonts: BTreeMap::new(),
components: Vec::new(),
};

let pdf = crate::PdfDocument::new("HTML rendering demo")
.with_html(&input.html, &opts)
.with_html(&input.html, opts)
.map_err(|e| PrintPdfApiReturn {
pdf: String::new(),
status: 2,
Expand Down

0 comments on commit 6371bf1

Please sign in to comment.