Skip to content

Commit

Permalink
Add woff2 support (#138)
Browse files Browse the repository at this point in the history
* Adding woff2 loading support

* Specs for magic numbers
  • Loading branch information
kokoISnoTarget authored Sep 17, 2024
1 parent d2f45c7 commit bbeb0dd
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/dom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ data-url = "0.3.1"
image = "0.25.2"
winit = { version = "0.30.4", default-features = false }
usvg = "0.42.0"
woff = "0.3.3"
68 changes: 64 additions & 4 deletions packages/dom/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,40 @@ impl RequestHandler for CssHandler {
_ => None,
})
.for_each(|url_source| {
let mut format = match &url_source.format_hint {
Some(FontFaceSourceFormat::Keyword(fmt)) => *fmt,
Some(FontFaceSourceFormat::String(str)) => match str.as_str() {
"woff2" => FontFaceSourceFormatKeyword::Woff2,
"ttf" => FontFaceSourceFormatKeyword::Truetype,
"otf" => FontFaceSourceFormatKeyword::Opentype,
_ => FontFaceSourceFormatKeyword::None,
},
_ => FontFaceSourceFormatKeyword::None,
};
if format == FontFaceSourceFormatKeyword::None {
let Some((_, end)) = url_source.url.as_str().rsplit_once('.') else {
return;
};
format = match end {
"woff2" => FontFaceSourceFormatKeyword::Woff2,
"woff" => FontFaceSourceFormatKeyword::Woff,
"ttf" => FontFaceSourceFormatKeyword::Truetype,
"otf" => FontFaceSourceFormatKeyword::Opentype,
"svg" => FontFaceSourceFormatKeyword::Svg,
"eot" => FontFaceSourceFormatKeyword::EmbeddedOpentype,
_ => FontFaceSourceFormatKeyword::None,
}
}
if let font_format @ (FontFaceSourceFormatKeyword::Svg
| FontFaceSourceFormatKeyword::EmbeddedOpentype
| FontFaceSourceFormatKeyword::Woff) = format
{
tracing::warn!("Skipping unsupported font of type {:?}", font_format);
return;
}
self.provider.fetch(
Url::from_str(url_source.url.as_str()).unwrap(),
Box::new(FontFaceHandler),
Box::new(FontFaceHandler(format)),
)
});

Expand All @@ -74,10 +105,39 @@ impl RequestHandler for CssHandler {
))
}
}
struct FontFaceHandler;
struct FontFaceHandler(FontFaceSourceFormatKeyword);
impl RequestHandler for FontFaceHandler {
type Data = Resource;
fn bytes(self: Box<Self>, bytes: Bytes, callback: SharedCallback<Self::Data>) {
fn bytes(mut self: Box<Self>, mut bytes: Bytes, callback: SharedCallback<Self::Data>) {
if self.0 == FontFaceSourceFormatKeyword::None {
self.0 = match bytes.as_ref() {
// https://w3c.github.io/woff/woff2/#woff20Header
[0x77, 0x4F, 0x46, 0x32, ..] => FontFaceSourceFormatKeyword::Woff2,
// https://learn.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
[0x4F, 0x54, 0x54, 0x4F, ..] => FontFaceSourceFormatKeyword::Opentype,
// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html#ScalerTypeNote
[0x00, 0x01, 0x00, 0x00, ..] | [0x74, 0x72, 0x75, 0x65, ..] => {
FontFaceSourceFormatKeyword::Truetype
}
_ => FontFaceSourceFormatKeyword::None,
}
}
match self.0 {
FontFaceSourceFormatKeyword::Woff2 => {
tracing::info!("Decompressing woff2 font");
let decompressed = woff::version2::decompress(&bytes);
if let Some(decompressed) = decompressed {
bytes = Bytes::from(decompressed);
} else {
tracing::warn!("Failed to decompress woff2 font");
}
}
FontFaceSourceFormatKeyword::None => {
return;
}
_ => {}
}

callback.call(Resource::Font(bytes))
}
}
Expand Down Expand Up @@ -188,7 +248,7 @@ pub fn walk_tree(indent: usize, node: &Node) {

use blitz_traits::net::{Bytes, RequestHandler, SharedCallback, SharedProvider};
use peniko::Color as PenikoColor;
use style::font_face::Source;
use style::font_face::{FontFaceSourceFormat, FontFaceSourceFormatKeyword, Source};
use style::stylesheets::{CssRule, StylesheetInDocument};

pub trait ToPenikoColor {
Expand Down

0 comments on commit bbeb0dd

Please sign in to comment.