Skip to content

Commit 0632a67

Browse files
authored
Merge pull request #2 from harfbuzz/readme
Update readme and name
2 parents bd0ddd9 + 31d9639 commit 0632a67

File tree

6 files changed

+86
-90
lines changed

6 files changed

+86
-90
lines changed

Cargo.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
[package]
2-
name = "rustybuzz"
3-
version = "0.17.0"
4-
authors = ["Yevhenii Reizner <[email protected]>"]
2+
name = "harfruzz"
3+
version = "0.0.1"
54
edition = "2021"
65
description = "A complete harfbuzz shaping algorithm port to Rust."
7-
documentation = "https://docs.rs/rustybuzz/"
6+
documentation = "https://docs.rs/harfruzz/"
87
readme = "README.md"
9-
repository = "https://github.com/RazrFalcon/rustybuzz"
8+
repository = "https://github.com/harfbuzz/harfruzz"
109
license = "MIT"
1110
keywords = ["text", "shaping", "opentype", "truetype"]
1211
categories = ["text-processing"]
@@ -27,6 +26,7 @@ skrifa = { git = "https://github.com/googlefonts/fontations", rev = "2eb4b1c" }
2726
wasmi = { version = "0.34.0", optional = true }
2827
log = "0.4.22"
2928

29+
# TODO: remove entirely
3030
[dependencies.ttf-parser]
3131
git = "https://github.com/RazrFalcon/ttf-parser"
3232
rev = "85c1ff2"

README.md

+30-34
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
1-
# rustybuzz
2-
![Build Status](https://github.com/RazrFalcon/rustybuzz/workflows/Rust/badge.svg)
3-
[![Crates.io](https://img.shields.io/crates/v/rustybuzz.svg)](https://crates.io/crates/rustybuzz)
4-
[![Documentation](https://docs.rs/rustybuzz/badge.svg)](https://docs.rs/rustybuzz)
1+
# harfruzz
2+
![Build Status](https://github.com/harfbuzz/harfruzz/workflows/Rust/badge.svg)
3+
[![Crates.io](https://img.shields.io/crates/v/harfruzz.svg)](https://crates.io/crates/harfruzz)
4+
[![Documentation](https://docs.rs/harfruzz/badge.svg)](https://docs.rs/harfruzz)
5+
6+
`harfruzz` is a fork of [`rustybuzz`](https://docs.rs/rustybuzz) to explore porting from `ttf-parser` to
7+
[`read-fonts`](https://docs.rs/read-fonts) to avoid shipping (and maintaining)
8+
multiple implementations of core font parsing for [`skrifa`](https://docs.rs/skrifa) consumers.
9+
Further context in https://github.com/googlefonts/fontations/issues/956.
510

611
`rustybuzz` is a complete [harfbuzz](https://github.com/harfbuzz/harfbuzz)'s
712
shaping algorithm port to Rust.
813

9-
Matches `harfbuzz` v9.0.0
14+
Matches `harfbuzz` [v9.0.0](https://github.com/harfbuzz/harfbuzz/releases/tag/9.0.0).
1015

1116
## Why?
1217

13-
Because you can add `rustybuzz = "*"` to your project and it just works.
14-
No need for a C++ compiler. No need to configure anything. No need to link to system libraries.
18+
https://github.com/googlefonts/oxidize outlines Google Fonts motivations to try to migrate font
19+
production and consumption to Rust.
1520

1621
## Conformance
1722

18-
rustybuzz passes nearly all of harfbuzz shaping tests (2221 out of 2252 to be more precise).
19-
So it's mostly identical, but there are still some tiny edge-cases which
20-
are not implemented yet or cannot be implemented at all.
23+
The following conformance issues need to be fixed:
24+
25+
* harfruzz does not yet fully pass the harfbuzz shaping or fuzzing tests
26+
* Malformed fonts will cause an error
27+
* HarfBuzz uses fallback/dummy shaper in this case
28+
* No Arabic fallback shaper (requires subsetting)
29+
* `avar2` as well as other parts of the boring-expansion-spec are not supported yet.
2130

2231
## Major changes
2332

24-
- Subsetting removed.
25-
- TrueType parsing is completely handled by the
26-
[ttf-parser](https://github.com/RazrFalcon/ttf-parser).
27-
And while the parsing algorithm is very different, it's not better or worse, just different.
28-
- Malformed fonts will cause an error. HarfBuzz uses fallback/dummy shaper in this case.
2933
- No font size property. Shaping is always using UnitsPerEm. You should scale the result manually.
3034
- Most of the TrueType and Unicode handling code was moved into separate crates.
31-
- rustybuzz doesn't interact with any system libraries and must produce exactly the same
35+
- harfruzz doesn't interact with any system libraries and must produce exactly the same
3236
results on all OS'es and targets.
3337
- `mort` table is not supported, since it's deprecated by Apple.
34-
- No Arabic fallback shaper, since it requires subsetting.
3538
- No `graphite` library support.
36-
- `avar2` as well as other parts of the boring-expansion-spec are not supported yet.
3739

3840
## Performance
3941

@@ -43,32 +45,26 @@ See [benches/README.md](./benches/README.md) for details.
4345

4446
## Notes about the port
4547

46-
rustybuzz is not a faithful port.
48+
harfruzz is not a faithful port.
4749

48-
harfbuzz can roughly be split into 6 parts: shaping, subsetting, TrueType parsing,
49-
Unicode routines, custom containers and utilities (harfbuzz doesn't use C++ std)
50-
and glue for system/3rd party libraries. In the mean time, rustybuzz contains only shaping.
51-
All of the TrueType parsing was moved to the [ttf-parser](https://github.com/RazrFalcon/ttf-parser).
52-
Subsetting was removed. Unicode code was mostly moved to external crates.
53-
We don't need custom containers because Rust's std is good enough.
54-
And we do not use any non Rust libraries, so no glue code either.
50+
harfbuzz (C++ edition) can roughly be split into 6 parts:
5551

56-
In the end, we still have around 23 KLOC. While harfbuzz is around 80 KLOC.
52+
1. shaping, handled by harfruzz
53+
1. subsetting, (`hb-subset`) moves to a standalone crate, [klippa](https://github.com/googlefonts/fontations/tree/main/klippa)
54+
1. TrueType parsing, handled by [`read-fonts`](https://docs.rs/read-fonts)
55+
1. Unicode routines, migrated to external crates
56+
1. custom containers and utilities (harfbuzz doesn't use C++ std), reimplemented in [`fontations`](https://github.com/googlefonts/fontations) where appropriate (e.g. int set)
57+
1. glue for system/3rd party libraries, just gone
5758

5859
## Lines of code
5960

60-
As mentioned above, rustybuzz has around 23 KLOC. But this is not strictly true,
61-
because there are a lot of auto-generated data tables.
62-
63-
You can find the "real" code size using:
61+
You can find the "real" code size (eliminating generated code) using:
6462

6563
```sh
6664
tokei --exclude hb/unicode_norm.rs --exclude hb/ot_shaper_vowel_constraints.rs \
6765
--exclude '*_machine.rs' --exclude '*_table.rs' src
6866
```
6967

70-
Which gives us around 17 KLOC, which is still a lot.
71-
7268
## Future work
7369

7470
Since the port is finished, there is not much to do other than syncing it with
@@ -121,6 +117,6 @@ But except that, there are no `unsafe` in this library and in most of its depend
121117

122118
## License
123119

124-
`rustybuzz` is licensed under the **MIT**.
120+
`harfruzz` is licensed under the **MIT** license.
125121

126122
`harfbuzz` is [licensed](https://github.com/harfbuzz/harfbuzz/blob/master/COPYING) under the **Old MIT**

examples/shape.rs

+26-26
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@ struct Args {
4444
font_file: Option<PathBuf>,
4545
face_index: u32,
4646
font_ptem: Option<f32>,
47-
variations: Vec<rustybuzz::Variation>,
47+
variations: Vec<harfruzz::Variation>,
4848
text: Option<String>,
4949
text_file: Option<PathBuf>,
5050
unicodes: Option<String>,
51-
direction: Option<rustybuzz::Direction>,
52-
language: rustybuzz::Language,
53-
script: Option<rustybuzz::Script>,
51+
direction: Option<harfruzz::Direction>,
52+
language: harfruzz::Language,
53+
script: Option<harfruzz::Script>,
5454
utf8_clusters: bool,
55-
cluster_level: rustybuzz::BufferClusterLevel,
56-
features: Vec<rustybuzz::Feature>,
55+
cluster_level: harfruzz::BufferClusterLevel,
56+
features: Vec<harfruzz::Feature>,
5757
no_glyph_names: bool,
5858
no_positions: bool,
5959
no_advances: bool,
@@ -145,7 +145,7 @@ fn main() {
145145
}
146146

147147
let font_data = std::fs::read(font_path).unwrap();
148-
let mut face = rustybuzz::Face::from_slice(&font_data, args.face_index).unwrap();
148+
let mut face = harfruzz::Face::from_slice(&font_data, args.face_index).unwrap();
149149

150150
face.set_points_per_em(args.font_ptem);
151151

@@ -175,7 +175,7 @@ fn main() {
175175
};
176176

177177
for text in lines {
178-
let mut buffer = rustybuzz::UnicodeBuffer::new();
178+
let mut buffer = harfruzz::UnicodeBuffer::new();
179179
buffer.push_str(&text);
180180

181181
if let Some(d) = args.direction {
@@ -194,31 +194,31 @@ fn main() {
194194
buffer.reset_clusters();
195195
}
196196

197-
let glyph_buffer = rustybuzz::shape(&face, &args.features, buffer);
197+
let glyph_buffer = harfruzz::shape(&face, &args.features, buffer);
198198

199-
let mut format_flags = rustybuzz::SerializeFlags::default();
199+
let mut format_flags = harfruzz::SerializeFlags::default();
200200
if args.no_glyph_names {
201-
format_flags |= rustybuzz::SerializeFlags::NO_GLYPH_NAMES;
201+
format_flags |= harfruzz::SerializeFlags::NO_GLYPH_NAMES;
202202
}
203203

204204
if args.no_clusters || args.ned {
205-
format_flags |= rustybuzz::SerializeFlags::NO_CLUSTERS;
205+
format_flags |= harfruzz::SerializeFlags::NO_CLUSTERS;
206206
}
207207

208208
if args.no_positions {
209-
format_flags |= rustybuzz::SerializeFlags::NO_POSITIONS;
209+
format_flags |= harfruzz::SerializeFlags::NO_POSITIONS;
210210
}
211211

212212
if args.no_advances || args.ned {
213-
format_flags |= rustybuzz::SerializeFlags::NO_ADVANCES;
213+
format_flags |= harfruzz::SerializeFlags::NO_ADVANCES;
214214
}
215215

216216
if args.show_extents {
217-
format_flags |= rustybuzz::SerializeFlags::GLYPH_EXTENTS;
217+
format_flags |= harfruzz::SerializeFlags::GLYPH_EXTENTS;
218218
}
219219

220220
if args.show_flags {
221-
format_flags |= rustybuzz::SerializeFlags::GLYPH_FLAGS;
221+
format_flags |= harfruzz::SerializeFlags::GLYPH_FLAGS;
222222
}
223223

224224
println!("{}", glyph_buffer.serialize(&face, format_flags));
@@ -239,39 +239,39 @@ fn parse_unicodes(s: &str) -> Result<String, String> {
239239
Ok(text)
240240
}
241241

242-
fn parse_features(s: &str) -> Result<Vec<rustybuzz::Feature>, String> {
242+
fn parse_features(s: &str) -> Result<Vec<harfruzz::Feature>, String> {
243243
let mut features = Vec::new();
244244
for f in s.split(',') {
245-
features.push(rustybuzz::Feature::from_str(&f)?);
245+
features.push(harfruzz::Feature::from_str(&f)?);
246246
}
247247

248248
Ok(features)
249249
}
250250

251-
fn parse_variations(s: &str) -> Result<Vec<rustybuzz::Variation>, String> {
251+
fn parse_variations(s: &str) -> Result<Vec<harfruzz::Variation>, String> {
252252
let mut variations = Vec::new();
253253
for v in s.split(',') {
254-
variations.push(rustybuzz::Variation::from_str(&v)?);
254+
variations.push(harfruzz::Variation::from_str(&v)?);
255255
}
256256

257257
Ok(variations)
258258
}
259259

260-
fn parse_cluster(s: &str) -> Result<rustybuzz::BufferClusterLevel, String> {
260+
fn parse_cluster(s: &str) -> Result<harfruzz::BufferClusterLevel, String> {
261261
match s {
262-
"0" => Ok(rustybuzz::BufferClusterLevel::MonotoneGraphemes),
263-
"1" => Ok(rustybuzz::BufferClusterLevel::MonotoneCharacters),
264-
"2" => Ok(rustybuzz::BufferClusterLevel::Characters),
262+
"0" => Ok(harfruzz::BufferClusterLevel::MonotoneGraphemes),
263+
"1" => Ok(harfruzz::BufferClusterLevel::MonotoneCharacters),
264+
"2" => Ok(harfruzz::BufferClusterLevel::Characters),
265265
_ => Err(format!("invalid cluster level")),
266266
}
267267
}
268268

269-
fn system_language() -> rustybuzz::Language {
269+
fn system_language() -> harfruzz::Language {
270270
unsafe {
271271
libc::setlocale(libc::LC_ALL, b"\0" as *const _ as *const i8);
272272
let s = libc::setlocale(libc::LC_CTYPE, std::ptr::null());
273273
let s = std::ffi::CStr::from_ptr(s);
274274
let s = s.to_str().expect("locale must be ASCII");
275-
rustybuzz::Language::from_str(s).unwrap()
275+
harfruzz::Language::from_str(s).unwrap()
276276
}
277277
}

src/hb/face.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<'a> hb_font_t<'a> {
296296
bbox = glyf.bbox(glyph);
297297
}
298298

299-
// See https://github.com/RazrFalcon/rustybuzz/pull/98#issuecomment-1948430785
299+
// See https://github.com/RazrFalcon/harfruzz/pull/98#issuecomment-1948430785
300300
if self.ttfp_face.tables().glyf.is_some() && bbox.is_none() {
301301
// Empty glyph; zero extents.
302302
return true;

src/hb/shape_wasm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn font_get_glyph(caller: Caller<'_, ShapingData>, _font: u32, codepoint: u32, u
134134
// fn font_get_scale(font: u32, x_scale: *mut i32, y_scale: *mut i32);
135135
// Returns the scale of the current font.
136136
fn font_get_scale(mut caller: Caller<'_, ShapingData>, _font: u32, x_scale: u32, y_scale: u32) {
137-
// Return upem as rustybuzz has no scale.
137+
// Return upem as harfruzz has no scale.
138138
let memory = caller.get_export("memory").unwrap().into_memory().unwrap();
139139
let upem = caller.data().font.units_per_em();
140140

@@ -550,8 +550,8 @@ fn shape_with(
550550
.unwrap_or_default()
551551
.to_string_lossy();
552552

553-
if !(shaper.eq_ignore_ascii_case("ot") || shaper.eq_ignore_ascii_case("rustybuzz")) {
554-
log::warn!("Only ot shaper is available in rustybuzz.");
553+
if !(shaper.eq_ignore_ascii_case("ot") || shaper.eq_ignore_ascii_case("harfruzz")) {
554+
log::warn!("Only ot shaper is available in harfruzz.");
555555
return 0;
556556
}
557557

0 commit comments

Comments
 (0)