Module: Fontisan::Ucd::Aggregator

Defined in:
lib/fontisan/ucd/aggregator.rb

Overview

Produces audit-ready aggregations from a codepoint list + UCD indices.

Pure: no I/O, no side effects. Caller passes the codepoints and the blocks/scripts indices; Aggregator returns the aggregated summaries.

Class Method Summary collapse

Class Method Details

.aggregate_blocks(codepoints, blocks_index) ⇒ Array<Hash>

Aggregate codepoints per Unicode block.

Returns one hash per overlapping block, sorted by first_cp:

{ name:, first_cp:, last_cp:, total:, covered:, fill_ratio:, complete: }

Parameters:

  • codepoints (Array<Integer>)

    sorted not required

  • blocks_index (Index)

Returns:

  • (Array<Hash>)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fontisan/ucd/aggregator.rb', line 21

def aggregate_blocks(codepoints, blocks_index)
  sorted = codepoints.sort
  return [] if sorted.empty?

  coverage = Hash.new { |h, k| h[k] = 0 }
  coverage.compare_by_identity
  first_cp = sorted.first
  last_cp = sorted.last

  overlapping = blocks_index.each_overlapping(first_cp, last_cp).to_a
  overlapping.each do |entry|
    coverage[entry] = count_in_range(sorted, [entry.first_cp, entry.last_cp])
  end

  overlapping.map do |entry|
    covered = coverage[entry]
    total = entry.size
    {
      name: entry.name,
      first_cp: entry.first_cp,
      last_cp: entry.last_cp,
      total: total,
      covered: covered,
      fill_ratio: covered.fdiv(total).round(4),
      complete: covered == total,
    }
  end
end

.aggregate_scripts(codepoints, scripts_index) ⇒ Array<String>

Aggregate unique script names from codepoints.

Parameters:

  • codepoints (Array<Integer>)
  • scripts_index (Index)

Returns:

  • (Array<String>)

    sorted unique script names



55
56
57
58
# File 'lib/fontisan/ucd/aggregator.rb', line 55

def aggregate_scripts(codepoints, scripts_index)
  scripts = codepoints.filter_map { |cp| scripts_index.lookup(cp) }
  scripts.uniq.sort
end