1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
extern crate gleam;
extern crate xmlparser;
#[macro_use(impl_from, impl_display)]
extern crate azul_core;
extern crate azul_css;
extern crate azul_layout;
#[cfg(feature = "font_loading")]
extern crate font_loader;
#[cfg(feature = "image_loading")]
extern crate image as image_crate;
pub mod xml;
pub mod css;
#[cfg(feature = "font_loading")]
pub mod font;
#[cfg(feature = "image_loading")]
pub mod image;
pub mod layout {
pub use azul_layout::*;
}
pub mod font_loading {
use std::{
path::PathBuf,
io::Error as IoError,
};
use azul_core::app_resources::FontSource;
#[cfg(feature = "text_layout")]
use azul_core::app_resources::LoadedFontSource;
const DEFAULT_FONT_INDEX: i32 = 0;
#[derive(Debug)]
pub enum FontReloadError {
Io(IoError, PathBuf),
FontNotFound(String),
FontLoadingNotActive(String),
}
impl Clone for FontReloadError {
fn clone(&self) -> Self {
use self::FontReloadError::*;
match self {
Io(err, path) => Io(IoError::new(err.kind(), "Io Error"), path.clone()),
FontNotFound(id) => FontNotFound(id.clone()),
FontLoadingNotActive(id) => FontLoadingNotActive(id.clone()),
}
}
}
impl_display!(FontReloadError, {
Io(err, path_buf) => format!("Could not load \"{}\" - IO error: {}", path_buf.as_path().to_string_lossy(), err),
FontNotFound(id) => format!("Could not locate system font: \"{}\" found", id),
FontLoadingNotActive(id) => format!("Could not load system font: \"{}\": crate was not compiled with --features=\"font_loading\"", id)
});
#[cfg(feature = "text_layout")]
pub fn font_source_get_bytes(font_source: &FontSource) -> Option<LoadedFontSource> {
use crate::layout::text_layout::text_shaping::get_font_metrics_freetype;
let (font_bytes, font_index) = font_source_get_bytes_inner(font_source).ok()?;
let font_metrics = get_font_metrics_freetype(&font_bytes, DEFAULT_FONT_INDEX);
Some(LoadedFontSource{ font_bytes, font_index, font_metrics })
}
pub fn font_source_get_bytes_inner(font_source: &FontSource) -> Result<(Vec<u8>, i32), FontReloadError> {
match font_source {
FontSource::Embedded(font_bytes) => Ok((font_bytes.to_vec(), DEFAULT_FONT_INDEX)),
FontSource::File(file_path) => {
std::fs::read(file_path)
.map_err(|e| FontReloadError::Io(e, file_path.clone()))
.map(|font_bytes| (font_bytes, DEFAULT_FONT_INDEX))
},
FontSource::System(id) => {
#[cfg(feature = "font_loading")] {
crate::font::load_system_font(id)
.ok_or(FontReloadError::FontNotFound(id.clone()))
}
#[cfg(not(feature = "font_loading"))] {
Err(FontReloadError::FontLoadingNotActive(id.clone()))
}
},
}
}
}
pub mod image_loading {
use std::{
fmt,
path::PathBuf,
io::Error as IoError,
};
use azul_core::app_resources::{ImageSource, LoadedImageSource};
#[cfg(feature = "image_loading")]
use image::ImageError;
#[derive(Debug)]
pub enum ImageReloadError {
Io(IoError, PathBuf),
#[cfg(feature = "image_loading")]
DecodingError(ImageError),
#[cfg(not(feature = "image_loading"))]
DecodingModuleNotActive,
}
impl fmt::Display for ImageReloadError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::ImageReloadError::*;
match &self {
Io(err, path_buf) => write!(f, "Could not load \"{}\" - IO error: {}", path_buf.as_path().to_string_lossy(), err),
#[cfg(feature = "image_loading")]
DecodingError(err) => write!(f, "Image decoding error: \"{}\"", err),
#[cfg(not(feature = "image_loading"))]
DecodingModuleNotActive => write!(f, "Found decoded image, but crate was not compiled with --features=\"image_loading\""),
}
}
}
pub fn image_source_get_bytes(image_source: &ImageSource) -> Option<LoadedImageSource> {
image_source_get_bytes_inner(image_source).ok()
}
pub fn image_source_get_bytes_inner(image_source: &ImageSource) -> Result<LoadedImageSource, ImageReloadError> {
use azul_core::app_resources::{ImageDescriptor, ImageDescriptorFlags, ImageData};
match image_source {
ImageSource::Embedded(bytes) => {
#[cfg(feature = "image_loading")] {
use crate::image::decode_image_data;
decode_image_data(bytes.to_vec()).map_err(|e| ImageReloadError::DecodingError(e))
}
#[cfg(not(feature = "image_loading"))] {
Err(ImageReloadError::DecodingModuleNotActive)
}
},
ImageSource::Raw(raw_image) => {
use std::sync::Arc;
use azul_core::app_resources::is_image_opaque;
let is_opaque = is_image_opaque(raw_image.data_format, &raw_image.pixels[..]);
let descriptor = ImageDescriptor {
format: raw_image.data_format,
dimensions: raw_image.image_dimensions,
stride: None,
offset: 0,
flags: ImageDescriptorFlags {
is_opaque,
allow_mipmaps: true,
},
};
let data = ImageData::Raw(Arc::new(raw_image.pixels.clone()));
Ok(LoadedImageSource { image_bytes_decoded: data, image_descriptor: descriptor })
},
ImageSource::File(file_path) => {
#[cfg(feature = "image_loading")] {
use std::fs;
use crate::image::decode_image_data;
let bytes = fs::read(file_path).map_err(|e| ImageReloadError::Io(e, file_path.clone()))?;
decode_image_data(bytes).map_err(|e| ImageReloadError::DecodingError(e))
}
#[cfg(not(feature = "image_loading"))] {
Err(ImageReloadError::DecodingModuleNotActive)
}
},
}
}
}