New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement downloadable fonts on Windows #15096
Conversation
@@ -40,11 +42,211 @@ impl FontTableMethods for FontTable { | |||
} | |||
} | |||
|
|||
fn make_tag(tag_bytes: &[u8]) -> FontTableTag { | |||
assert!(tag_bytes.len() == 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If you use assert_eq!
this will display the length in the eventuality that it fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, though it's only used statically.
style: FontStyle::Normal, | ||
}; | ||
|
||
if let Some(mut name_table_bytes) = face.get_font_table(make_tag(b"name")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe this would be a bit cleaner if you do something like:
let mut name_table_bytes = match face.get_font_table(make_tag(b"name")) {
Some(table) => table,
None => return Err(()),
};
// Use name_table_bytes here.
This applies also to other places below.
|
4d24edc
to
704c945
Compare
704c945
to
a9611c3
Compare
Rebased and addressed review comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me. Haven't audited the truetype crate, but it's (co-?)authored by @vvuk, so I think we can account you as responsible for it :)
License-wise it's fine (just for the record).
I've left mostly stylistic comments since most of the job is done in truetype
.
r=me with it addressed
let mut face_name_index = None; | ||
|
||
for i in 0..records.len() { | ||
// the truetype crate can only decode mac platform format names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we support this? If so, consider filling an issue and referencing it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably? I actually don't think we ever use the family and face name from downloaded fonts, since I believe you specify those in the @font-face
anyway. If someone can confirm that, we can change this around to just give dummy UUIDs or something for family/face, and then the only thing left would be the OS/2
table, which is very simple to parse... in which case we could just do everything ourselves.
continue; | ||
} | ||
|
||
if records[i].language_id != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for this I guess.
let names = try_lossy!(NamingTable::read(&mut name_table_cursor)); | ||
let (family, face) = match names { | ||
NamingTable::Format0(ref table) => { | ||
if let Some((family_index, face_index)) = get_family_face_indices(&table.records) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My previous comment also applied here and in the Format1
arm, though this is not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah; these were more compact so I didn't change them. I don't really like the mass duplicated code here anyway, but short of refactoring a bunch of stuff out I can't think of how I'd change it.
// names. We want name_id 1 and 2, and we need to use platform_id == 1 and | ||
// language_id == 0 to avoid limitations in the truetype crate. We *could* just | ||
// do our own parsing here, and use the offset/length data and pull the values out | ||
// ourselves. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make this a doc comment?
Oh, FYI you appear in the author list on https://crates.io/crates/truetype :) Well, I opened #15105 and bodoni/truetype#5 regarding possible security implications we may need to care about in medium/long term. Meanwhile this is ok to land IMO. @bors-servo r+ |
📌 Commit a9611c3 has been approved by |
Implement downloadable fonts on Windows This PR implements downloadable font support for Servo. It depends on new changes in webrender and dwrote, and adds a dependency on the `truetype` crate for pulling out basic font information. The original DirectWrite API does not provide an easy way to query font information direct from a `FontFace` (which is what you create from a `FontFile`). There are new DirectWrite APIs starting with Windows 10 that allow for this, but they are Win 10+ only, and `winapi-rs` does not yet have bindings for those versions of the interfaces (specificially, `IDirectWriteFontFace3`). The way to do this with DW is to go through a lot of pain in creating a custom collection and enumerator, add your font to your custom collection, then query the collection for its properties. Instead, we just parse the truetype tables directly to pull out the few bits of information that we need. The `truetype` crate is ok, but I discovered some bugs (an update needs to get pushed to crates.io before this will build). It might be more worthwhile to just implement the tiny bit of truetype parsing that we need ourselves in Servo. I'm guessing there are existing tests for downloadable fonts... --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15096) <!-- Reviewable:end -->
☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt1, mac-rel-wpt2, windows-gnu-dev, windows-msvc-dev |
This PR implements downloadable font support for Servo. It depends on new changes in webrender and dwrote, and adds a dependency on the
truetype
crate for pulling out basic font information. The original DirectWrite API does not provide an easy way to query font information direct from aFontFace
(which is what you create from aFontFile
). There are new DirectWrite APIs starting with Windows 10 that allow for this, but they are Win 10+ only, andwinapi-rs
does not yet have bindings for those versions of the interfaces (specificially,IDirectWriteFontFace3
). The way to do this with DW is to go through a lot of pain in creating a custom collection and enumerator, add your font to your custom collection, then query the collection for its properties.Instead, we just parse the truetype tables directly to pull out the few bits of information that we need. The
truetype
crate is ok, but I discovered some bugs (an update needs to get pushed to crates.io before this will build). It might be more worthwhile to just implement the tiny bit of truetype parsing that we need ourselves in Servo.I'm guessing there are existing tests for downloadable fonts...
./mach build -d
does not report any errors./mach test-tidy
does not report any errorsThis change is