Giter VIP home page Giter VIP logo

hb-subset-rs's Introduction

crates.io docs.rs

hb-subset

A Rust wrapper for HarfBuzz subsetting API

This crate exposes HarfBuzz API for subsetting fonts.

What is subsetting?

From HarfBuzz documentation:

Subsetting reduces the codepoint coverage of font files and removes all data that is no longer needed. A subset input describes the desired subset. The input is provided along with a font to the subsetting operation. Output is a new font file containing only the data specified in the input.

Currently most outline and bitmap tables are supported: glyf, CFF, CFF2, sbix, COLR, and CBDT/CBLC. This also includes fonts with variable outlines via OpenType variations. Notably EBDT/EBLC and SVG are not supported. Layout subsetting is supported only for OpenType Layout tables (GSUB, GPOS, GDEF). Notably subsetting of graphite or AAT tables is not yet supported.

Fonts with graphite or AAT tables may still be subsetted but will likely need to use the retain glyph ids option and configure the subset to pass through the layout tables untouched.

In other words, subsetting allows you to take a large font and construct a new, smaller font which has only those characters that you need. Be sure to check the license of the font though, as not all fonts can be legally subsetted.

Why?

Many modern fonts can contain hundreds or even thousands of glyphs, of which only a couple dozen or maybe hundred is needed in any single document. This also means that modern fonts can be very bulky compared to what is actually needed. The solution to this is font subsetting: We can construct a font that includes only those glyphs and features that are needed for the document.

Usage

The simplest way to construct a subset of a font is to use [subset()] function. In the following example, we keep only glyphs that are needed show any combination of characters 'a', 'b' and 'c', e.g. "abc" and "cabba" can be rendered, but "foobar" cannot:

let font = fs::read("tests/fonts/NotoSans.ttf")?;
let subset_font = hb_subset::subset(&font, "abc".chars())?;
fs::write("tests/fonts/subset.ttf", subset_font)?;

To get more control over how the font is subset and what gets included, you can use the lower level API directly:

// Load font directly from a file
let font = Blob::from_file("tests/fonts/NotoSans.ttf")?;
let font = FontFace::new(font)?;

// Construct a subset manually and include only some of the letters
let mut subset = SubsetInput::new()?;
subset.unicode_set().insert('f');
subset.unicode_set().insert('i');

// Subset the font using just-constructed subset input
let new_font = subset.subset_font(&font)?;

// Extract the raw font and write to an output file
std::fs::write("tests/fonts/subset.ttf", &*new_font.underlying_blob())?;

Using bundled version of HarfBuzz

By default, this crate uses the system HarfBuzz installation. If it is not available, or it is too old, this crate can also used a bundled copy of HarfBuzz by using feature bundled:

cargo add hb-subset --features bundled

License

This crate is licenced under MIT license (LICENSE.md or https://opensource.org/licenses/MIT).

This repository includes HarfBuzz as a submodule and links against it. It is licensed with "Old MIT" license.

This repository also contains a copy of NotoSans font for testing purposes, contained in tests/fonts. It is licensed withSIL Open Font License, Version 1.1.

hb-subset-rs's People

Contributors

henkkuli avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

qwerzl

hb-subset-rs's Issues

`SetMutRef` is unsound

The contents of SetMutRef can be stolen and kept longer than the original allocation stays alive:

let mut subset = SubsetInput::new().unwrap();
let mut unicode_set = subset.unicode_set();
let mut stolen = std::mem::replace(&mut *unicode_set, Set::new().unwrap());
drop(subset);
stolen.insert(0);

This crashes the process with a malloc error in the underlying C code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.