Class: Ucode::Audit::DiscrepancyDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/ucode/audit/discrepancy_detector.rb

Overview

Detects cheap audit signals — currently OS/2 ulUnicodeRange bit claims that disagree with the font’s cmap coverage.

Pure transformation: takes the four OS/2 ulUnicodeRange 32-bit words + the font’s codepoint set, returns Discrepancy[]. No I/O, no font handle.

OCP: a new discrepancy kind = one constant on Models::Audit::Discrepancy + one method here. The detector never enumerates kinds directly.

Instance Method Summary collapse

Constructor Details

#initialize(ul_unicode_range1:, ul_unicode_range2:, ul_unicode_range3:, ul_unicode_range4:, codepoints:) ⇒ DiscrepancyDetector

Returns a new instance of DiscrepancyDetector.

Parameters:

  • ul_unicode_range1 (Integer)
  • ul_unicode_range2 (Integer)
  • ul_unicode_range3 (Integer)
  • ul_unicode_range4 (Integer)
  • codepoints (Enumerable<Integer>)

    font cmap codepoint set



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/ucode/audit/discrepancy_detector.rb', line 158

def initialize(ul_unicode_range1:, ul_unicode_range2:,
               ul_unicode_range3:, ul_unicode_range4:,
               codepoints:)
  @bits = bits_from_words([
    ul_unicode_range1 || 0,
    ul_unicode_range2 || 0,
    ul_unicode_range3 || 0,
    ul_unicode_range4 || 0,
  ])
  @codepoint_set = codepoints.to_set
end

Instance Method Details

#callArray<Models::Audit::Discrepancy>

Returns:



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/ucode/audit/discrepancy_detector.rb', line 171

def call
  @bits.sort.map do |bit|
    first, last = BIT_RANGES.fetch(bit, [nil, nil])
    next nil if first.nil? # bit set but range unknown — skip

    next nil if range_has_codepoints?(first, last)

    Models::Audit::Discrepancy.new(
      kind: Models::Audit::Discrepancy::KIND_OS2_UNICODE_RANGE_BIT_WITHOUT_CMAP_CODEPOINTS,
      detail: format(
        "OS/2 ulUnicodeRange bit %<bit>d claims %<first>s–%<last>s " \
        "but cmap has 0 codepoints in that range",
        bit: bit,
        first: format("U+%04X", first),
        last: format("U+%04X", last),
      ),
      bit_position: bit,
    )
  end.compact
end