Module: Fontisan::Converters::OutlineOptimizer
- Included in:
- OutlineConverter
- Defined in:
- lib/fontisan/converters/outline_optimizer.rb
Overview
Optimizes CFF CharStrings using subroutine extraction
This module analyzes CharStrings for repeated patterns, extracts them as subroutines, and rewrites the CharStrings to call the subroutines instead of repeating the code.
The optimization process:
- Analyze patterns across all CharStrings
- Select optimal set of patterns for subroutines
- Optimize subroutine ordering
- Build subroutines from selected patterns
- Rewrite CharStrings to call subroutines
Instance Method Summary collapse
-
#optimize_charstrings(charstrings) ⇒ Array<Array<String>, Array<String>>
Optimize CharStrings using subroutine extraction.
Instance Method Details
#optimize_charstrings(charstrings) ⇒ Array<Array<String>, Array<String>>
Optimize CharStrings using subroutine extraction
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/fontisan/converters/outline_optimizer.rb', line 22 def optimize_charstrings(charstrings) # Convert to hash format expected by PatternAnalyzer charstrings_hash = {} charstrings.each_with_index do |cs, index| charstrings_hash[index] = cs end # Analyze patterns analyzer = Optimizers::PatternAnalyzer.new( min_length: 10, stack_aware: true, ) patterns = analyzer.analyze(charstrings_hash) # Return original if no patterns found return [charstrings, []] if patterns.empty? # Optimize selection optimizer = Optimizers::SubroutineOptimizer.new(patterns, max_subrs: 65_535) selected_patterns = optimizer.optimize_selection # Optimize ordering selected_patterns = optimizer.optimize_ordering(selected_patterns) # Return original if no patterns selected return [charstrings, []] if selected_patterns.empty? # Build subroutines builder = Optimizers::SubroutineBuilder.new(selected_patterns, type: :local) local_subrs = builder.build # Build subroutine map subroutine_map = {} selected_patterns.each_with_index do |pattern, index| subroutine_map[pattern.bytes] = index end # Rewrite CharStrings rewriter = Optimizers::CharstringRewriter.new(subroutine_map, builder) optimized_charstrings = charstrings.map.with_index do |charstring, glyph_id| # Find patterns for this glyph glyph_patterns = selected_patterns.select do |p| p.glyphs.include?(glyph_id) end if glyph_patterns.empty? charstring else rewriter.rewrite(charstring, glyph_patterns, glyph_id) end end [optimized_charstrings, local_subrs] rescue StandardError => e # If optimization fails for any reason, return original CharStrings warn "Optimization warning: #{e.}" [charstrings, []] end |