// 子集化扩展点。
//
// 默认行为等价于 `SubsetOptions::default()`:保留名称/度量/提示相关表,
// 丢弃布局表。调用方可以通过三种方式扩展,而不需要改库代码:
//   1. `keep_table` / `drop_table`:调整表保留策略;
//   2. `with_collector`:为某个字形补充额外依赖(例如 GSUB 连字闭包);
//   3. `with_validator`:追加自定义验收规则。

///|
pub(all) struct SubsetOptions {
  /// 在默认白名单之外强制保留的表。
  keep_optional : Array[String]
  /// 从结果中额外丢弃的表。
  drop_extra : Array[String]
  /// 自定义字形收集器:给定字体与字形,返回额外需要收录的字形编号。
  collector : ((Font, Int) -> Array[Int])?
  /// 自定义验证器:输入原字体、子集字体与字符集,返回失败描述。
  validators : Array[(Font, Font, Array[Int]) -> Array[String]]
}

///|
pub fn SubsetOptions::default() -> SubsetOptions {
  { keep_optional: [], drop_extra: [], collector: None, validators: [], }
}

///|
/// 强制保留某张表。适用于 `GSUB` 这类需要调用方自行处理字形编号的表。
pub fn SubsetOptions::keep_table(
  self : SubsetOptions,
  tag : String,
) -> SubsetOptions {
  let next = self.keep_optional.copy()
  next.push(tag)
  {
    keep_optional: next,
    drop_extra: self.drop_extra,
    collector: self.collector,
    validators: self.validators,
  }
}

///|
/// 额外丢弃某张表。
pub fn SubsetOptions::drop_table(
  self : SubsetOptions,
  tag : String,
) -> SubsetOptions {
  let next = self.drop_extra.copy()
  next.push(tag)
  {
    keep_optional: self.keep_optional,
    drop_extra: next,
    collector: self.collector,
    validators: self.validators,
  }
}

///|
/// 注册自定义字形收集器。
///
/// 收集器会对每个已选字形调用一次,返回的字形会继续参与闭包与编号重排。
/// 这为 GSUB 连字、数学字形变体等「字符之外的字形依赖」提供了扩展入口。
pub fn SubsetOptions::with_collector(
  self : SubsetOptions,
  collector : (Font, Int) -> Array[Int],
) -> SubsetOptions {
  {
    keep_optional: self.keep_optional,
    drop_extra: self.drop_extra,
    collector: Some(collector),
    validators: self.validators,
  }
}

///|
/// 注册自定义验证器。
pub fn SubsetOptions::with_validator(
  self : SubsetOptions,
  validator : (Font, Font, Array[Int]) -> Array[String],
) -> SubsetOptions {
  let next = self.validators.copy()
  next.push(validator)
  {
    keep_optional: self.keep_optional,
    drop_extra: self.drop_extra,
    collector: self.collector,
    validators: next,
  }
}

///|
/// 默认保留的可选表(必需表始终重建)。
pub fn default_optional_tables() -> Array[String] {
  ["name", "OS/2", "cvt ", "fpgm", "prep", "gasp", "post"]
}

///|
/// `tag` 是否应出现在子集结果中。
pub fn SubsetOptions::keeps_table(self : SubsetOptions, tag : String) -> Bool {
  if self.drop_extra.contains(tag) {
    false
  } else if self.keep_optional.contains(tag) {
    true
  } else {
    default_optional_tables().contains(tag)
  }
}