harfbuzz_rs is a high-level interface to HarfBuzz, exposing its most important
functionality in a safe manner using Rust.
HarfBuzz is a library for performing complex text layout. It does not perform any drawing. This is quite a low-level operation. If you want to simply draw some text on the screen you should maybe choose another more high-level library. However if you want to build a library for drawing text on some canvas or need a lot of control on advanced text layout then this is the right library to use.
To shape a simple string of text you just create a Font from a font file, fill
a Buffer with some text and call the shape function.
use harfbuzz_rs::*;
let path = "path/to/some/font_file.otf";
let index = 0; //< face index in the font file
let face = Face::from_file(path, index)?;
let mut font = Font::new(face);
let buffer = UnicodeBuffer::new().add_str("Hello World!");
let output = shape(&font, buffer, &[]);
// The results of the shaping operation are stored in the `output` buffer.
let positions = output.get_glyph_positions();
let infos = output.get_glyph_infos();
// iterate over the shaped glyphs
for (position, info) in positions.iter().zip(infos) {
let gid = info.codepoint;
let cluster = info.cluster;
let x_advance = position.x_advance;
let x_offset = position.x_offset;
let y_offset = position.y_offset;
// Here you would usually draw the glyphs.
println!("gid{:?}={:?}@{:?},{:?}+{:?}", gid, cluster, x_advance, x_offset, y_offset);
}This should print out something similar to the following:
gid41=0@741,0+0
gid70=1@421,0+0
gid77=2@258,0+0
gid77=3@253,0+0
gid80=4@510,0+0
gid1=5@227,0+0
gid56=6@874,0+0
gid80=7@498,0+0
gid83=8@367,0+0
gid77=9@253,0+0
gid69=10@528,0+0
gid2=11@276,0+0
The values of x_advance, x_offset, y_advance and y_offset are all given in so-called font units by default.
By calling face.upem() you get the number of font units per EM for
a specific face. This upem value can be used to scale the advances and offsets to a given font-size.
For example, if you want to display a font at 16 point (pt) size, that means that 1 EM = 16 pt.
In this example, to convert a value, say x_advance, from font-units to points, we compute ((x_advance * font_size) as f64) / (upem as f64), where font_size = 16 is a variable specifying the font size in points.
Note that harfbuzz internally supports scaling fonts itself as well (using font.set_scale(...), etc.) but in my opinion it is easier to scale the results oneself as described in the paragraph above.
By default this crate compiles the harfbuzz version bundled with it (currently 14.6.0) and links it statically. This needs a C++ compiler.
To link against a system harfbuzz instead, set the environment variable HARFBUZZ_RS_USE_PKG_CONFIG=1 when building. Alternatively, disable the default features:
[dependencies]
harfbuzz_rs = { version = "3", default-features = false }In both cases the build script locates harfbuzz using pkg-config and fails if it cannot be found. The harfbuzz development files must be installed, e.g. libharfbuzz-dev on Debian/Ubuntu, harfbuzz-devel on Fedora, or brew install harfbuzz on macOS.
If you want to use rusttype as font functions enable the rusttype feature.