Class: Fontisan::Optimizers::PatternAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/optimizers/pattern_analyzer.rb

Overview

Analyzes CharString patterns across glyphs to identify repeated sequences suitable for subroutinization. Implements suffix tree-based pattern matching for efficient detection of repeated byte sequences.

Can optionally use stack-aware detection to ensure patterns are stack-neutral, making them safe for subroutinization without causing stack underflow/overflow.

Examples:

Basic usage

analyzer = PatternAnalyzer.new(min_length: 10)
charstrings = { 0 => "\x01\x02...", 1 => "\x01\x02..." }
patterns = analyzer.analyze(charstrings)

Stack-aware analysis

analyzer = PatternAnalyzer.new(min_length: 10, stack_aware: true)
patterns = analyzer.analyze(charstrings)

See Also:

  • docs/SUBROUTINE_ARCHITECTUREdocs/SUBROUTINE_ARCHITECTURE.md

Defined Under Namespace

Classes: Pattern

Instance Method Summary collapse

Constructor Details

#initialize(min_length: 10, stack_aware: false) ⇒ PatternAnalyzer

Initialize pattern analyzer

Parameters:

  • min_length (Integer) (defaults to: 10)

    minimum pattern length in bytes

  • stack_aware (Boolean) (defaults to: false)

    whether to enforce stack-neutral patterns



57
58
59
60
61
62
# File 'lib/fontisan/optimizers/pattern_analyzer.rb', line 57

def initialize(min_length: 10, stack_aware: false)
  @min_length = min_length
  @stack_aware = stack_aware
  @patterns = {}
  @stack_trackers = {} # Cache StackTracker instances per glyph
end

Instance Method Details

#analyze(charstrings) ⇒ Array<Pattern>

Analyze CharStrings to find repeated patterns

Parameters:

  • charstrings (Hash<Integer, String>)

    glyph_id => charstring_bytes

Returns:

  • (Array<Pattern>)

    patterns sorted by savings (descending)

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fontisan/optimizers/pattern_analyzer.rb', line 68

def analyze(charstrings)
  raise ArgumentError, "No CharStrings provided" if charstrings.empty?

  # Build stack trackers if stack-aware mode enabled
  build_stack_trackers(charstrings) if @stack_aware

  # Extract all byte sequences and build pattern candidates
  extract_patterns(charstrings)

  # Calculate savings for each pattern
  calculate_savings

  # Filter patterns by minimum length and positive savings
  filter_patterns

  # Sort by savings (descending) and return
  @patterns.values.sort_by { |p| -p.savings }
end