Class: Fontisan::Optimizers::SubroutineGenerator
- Inherits:
-
Object
- Object
- Fontisan::Optimizers::SubroutineGenerator
- Defined in:
- lib/fontisan/optimizers/subroutine_generator.rb
Overview
Main orchestrator for CFF subroutine generation pipeline. Coordinates PatternAnalyzer, SubroutineOptimizer, SubroutineBuilder, and CharstringRewriter to generate optimized subroutines for fonts.
The generator processes CharStrings from a CFF font table by:
-
Analyzing patterns across all glyphs
-
Selecting optimal patterns (avoiding conflicts, within limits)
-
Ordering patterns by frequency for efficient encoding
-
Building actual subroutine CharStrings
-
Rewriting original CharStrings with subroutine calls
Constant Summary collapse
- DEFAULT_MIN_PATTERN_LENGTH =
Default minimum pattern length in bytes
10- DEFAULT_MAX_SUBROUTINES =
Default maximum number of subroutines (CFF limit)
65_535
Instance Method Summary collapse
-
#generate(font) ⇒ Hash
Generate subroutines for a font.
-
#initialize(options = {}) ⇒ SubroutineGenerator
constructor
Initialize generator with options.
Constructor Details
#initialize(options = {}) ⇒ SubroutineGenerator
Initialize generator with options
36 37 38 39 40 41 |
# File 'lib/fontisan/optimizers/subroutine_generator.rb', line 36 def initialize( = {}) @min_pattern_length = [:min_pattern_length] || DEFAULT_MIN_PATTERN_LENGTH @max_subroutines = [:max_subroutines] || DEFAULT_MAX_SUBROUTINES @optimize_ordering = [:optimize_ordering] != false end |
Instance Method Details
#generate(font) ⇒ Hash
Generate subroutines for a font
Main entry point for the subroutine generation pipeline. Processes a font’s CFF table to create optimized subroutines and rewrite CharStrings.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/fontisan/optimizers/subroutine_generator.rb', line 58 def generate(font) # 1. Extract CharStrings from CFF table charstrings = extract_charstrings(font) # Handle empty font gracefully if charstrings.empty? return { local_subrs: [], charstrings: {}, bias: 0, savings: 0, pattern_count: 0, selected_count: 0, } end # 2. Analyze patterns analyzer = PatternAnalyzer.new( min_length: @min_pattern_length, stack_aware: true ) patterns = analyzer.analyze(charstrings) # 3. Optimize selection optimizer = SubroutineOptimizer.new(patterns, max_subrs: @max_subroutines) selected_patterns = optimizer.optimize_selection # 4. Optimize ordering (if enabled) if @optimize_ordering selected_patterns = optimizer.optimize_ordering(selected_patterns) end # 5. Build subroutines builder = SubroutineBuilder.new(selected_patterns, type: :local) subroutines = builder.build # 6. Build subroutine map subroutine_map = build_subroutine_map(selected_patterns) # 7. Rewrite CharStrings rewriter = CharstringRewriter.new(subroutine_map, builder) rewritten_charstrings = rewrite_charstrings( charstrings, selected_patterns, rewriter, ) # 8. Return complete result { local_subrs: subroutines, charstrings: rewritten_charstrings, bias: builder.bias, savings: calculate_total_savings(selected_patterns), pattern_count: patterns.length, selected_count: selected_patterns.length, } end |