Skip to content

Commit

Permalink
[fea-rs] Support more granular control via API
Browse files Browse the repository at this point in the history
This is a small set of changes to make it easier to manually run the
validate & compile passes, without using the Compiler struct.
  • Loading branch information
cmyr committed Feb 1, 2024
1 parent 8d53a05 commit c72cee1
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 19 deletions.
25 changes: 24 additions & 1 deletion fea-rs/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod validate;
mod variations;

/// Run the validation pass, returning any diagnostics.
pub(crate) fn validate<V: VariationInfo>(
pub fn validate<V: VariationInfo>(
node: &ParseTree,
glyph_map: &GlyphMap,
fvar: Option<&V>,
Expand All @@ -54,6 +54,29 @@ pub(crate) fn validate<V: VariationInfo>(
DiagnosticSet::new(ctx.errors, node, usize::MAX)
}

/// Run the compilation pass.
///
/// If successful, returns the [`Compilation`] result, and any warnings.
pub fn compile<V: VariationInfo, T: FeatureProvider>(
tree: &ParseTree,
glyph_map: &GlyphMap,
var_info: Option<&V>,
extra_features: Option<&T>,
) -> Result<(Compilation, DiagnosticSet), DiagnosticSet> {
let mut ctx = CompilationCtx::new(glyph_map, tree.source_map(), var_info, extra_features);
ctx.compile(&tree.typed_root());
match ctx.build() {
Ok((compilation, warnings)) => {
let warnings = DiagnosticSet::new(warnings, tree, usize::MAX);
Ok((compilation, warnings))
}
Err(errors) => {
let errors = DiagnosticSet::new(errors, tree, usize::MAX);
Err(errors)
}
}
}

/// A helper function for extracting the glyph order from a UFO
///
/// If the public.glyphOrder key is missing, or the glyphOrder is malformed,
Expand Down
30 changes: 16 additions & 14 deletions fea-rs/src/compile/compile_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl<'a, F: FeatureProvider, V: VariationInfo> CompilationCtx<'a, F, V> {
self.features.sort_and_dedupe_lookups();
}

pub(crate) fn build(&mut self) -> Result<Compilation, Vec<Diagnostic>> {
pub(crate) fn build(&mut self) -> Result<(Compilation, Vec<Diagnostic>), Vec<Diagnostic>> {
if self.errors.iter().any(Diagnostic::is_error) {
return Err(self.errors.clone());
}
Expand Down Expand Up @@ -237,19 +237,21 @@ impl<'a, F: FeatureProvider, V: VariationInfo> CompilationCtx<'a, F, V> {
}
}

Ok(Compilation {
warnings: self.errors.clone(),
head: self.tables.head.as_ref().map(|raw| raw.build(None)),
hhea: self.tables.hhea.clone(),
vhea: self.tables.vhea.clone(),
os2: self.tables.os2.as_ref().map(|raw| raw.build()),
gdef,
base: self.tables.base.as_ref().map(|raw| raw.build()),
name: name_builder.build(),
stat,
gsub,
gpos,
})
Ok((
Compilation {
head: self.tables.head.as_ref().map(|raw| raw.build(None)),
hhea: self.tables.hhea.clone(),
vhea: self.tables.vhea.clone(),
os2: self.tables.os2.as_ref().map(|raw| raw.build()),
gdef,
base: self.tables.base.as_ref().map(|raw| raw.build()),
name: name_builder.build(),
stat,
gsub,
gpos,
},
self.errors.clone(),
))
}

fn run_feature_writer_if_present(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion fea-rs/src/compile/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'a, F: FeatureProvider, V: VariationInfo> Compiler<'a, F, V> {
let diagnostics = DiagnosticSet::new(messages, &tree, self.max_n_errors);
print_warnings_return_errors(diagnostics, self.print_warnings, self.max_n_errors)
.map_err(CompilerError::CompilationFail)?;
Ok(ctx.build().unwrap()) // we've taken the errors, so this can't fail
Ok(ctx.build().unwrap().0) // we've taken the errors, so this can't fail
}

/// Compile to a binary font.
Expand Down
4 changes: 1 addition & 3 deletions fea-rs/src/compile/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use write_fonts::{

use super::Opts;

use crate::{Diagnostic, GlyphMap};
use crate::GlyphMap;

/// The tables generated by this compilation.
///
Expand All @@ -20,8 +20,6 @@ use crate::{Diagnostic, GlyphMap};
///
/// [`to_binary`]: Compilation::to_binary
pub struct Compilation {
/// Any warnings encountered during parsing or compilation
pub warnings: Vec<Diagnostic>,
/// The `head` table, if one was generated
pub head: Option<wtables::head::Head>,
/// The `hhea` table, if one was generated
Expand Down
5 changes: 5 additions & 0 deletions fea-rs/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ impl DiagnosticSet {
self.max_to_print = max_to_print;
}

/// Discard any warnings, keeping only errors
pub fn discard_warnings(&mut self) {
self.messages.retain(|x| x.is_error());
}

/// Remove and return any warnings in this set.
pub fn split_off_warnings(&mut self) -> Option<DiagnosticSet> {
self.messages.sort_unstable_by_key(|d| d.level);
Expand Down

0 comments on commit c72cee1

Please sign in to comment.