Extracted shared DP core algorithm into dp_process_position() function:
1. Added dp_input_t struct - unified input interface for DP algorithm
- Contains prefix arrays, glue arrays, hyphen info
- Contains K-P parameters (penalties, ratios)
2. Added dp_is_hyphen() function - unified hyphen position detection
- Uses O(log n) binary search
- Replaces is_hyphen_pos() function
3. Added dp_process_position() function - core DP algorithm
- Processes single start position i, tries all end positions k
- Contains complete demerits calculation, fitness classification
- Both entry functions now call this shared core
4. Refactored process_dp_range()
- Builds temporary glue arrays from ekp_paragraph_t
- Creates dp_input_t and calls dp_process_position()
5. Refactored ekp_break_with_prefixes()
- Directly uses input arrays to create dp_input_t
- Calls dp_process_position() for each position
Benefits:
- Single point of maintenance: DP bugs only need fixing once
- Consistency guaranteed: both paths use identical algorithm
- ~100 lines of duplicate code removed
- Better testability: core algorithm can be tested independently
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
Code review found additional functions using global glue params instead
of para's stored params:
- ekp--compute-stretch-capacity: now takes para param
- ekp--compute-shrink-capacity: now takes para param
- ekp--line-badness-and-fitness: now takes para param
- ekp--dp-compute-line-demerits: now takes para param
- ekp--distribute-gap-adjustment: now takes para param
All capacity/distribution calculations now use para's stored glue params
for full consistency across multi-font paragraphs.
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
When multiple paragraphs with different fonts were processed, subsequent
executions would use wrong glue parameters from the cache. This caused
misalignment because different fonts have different spacing values.
Changes:
- Add glue-params field to ekp-para struct to store params at creation
- Add helper functions: ekp--para-glue-ideal/shrink/stretch/min/max
- Update all C module interface functions to use para's stored params
- Update all glue computation functions for consistency
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
When is_last && ideal > line_width, the C module now correctly
triggers force break logic, matching ekp--dp-cache-elisp behavior.
This ensures consistent results between C module and pure Elisp paths.
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>