Fix word breaking: prevent splitting words with accented characters
Fixed line breaking that would split words like "équivaut" into "é" on one
line and "quivaut" on the next line, even though they're part of the same word.
Root cause analysis (from debug logging):
When text contains accented characters in decomposed form (e + combining
accent), the system processes them as separate atoms:
1. "é" is processed as an accent atom, composed, and added to currentLine
2. "quivaut " is processed as the next ordinary atom
3. Before adding "quivaut ", checkAndPerformInteratomLineBreak() is called
4. This function sees that adding "quivaut " would exceed maxWidth
5. It breaks and flushes the line with "é" at the end
6. "quivaut " starts on a new line
Result: "é" appears alone at the end of one line, "quivaut " on the next.
The fix:
Modified checkAndPerformInteratomLineBreak() in MTTypesetter.swift to detect
when we're about to break in the middle of a word.
This commit is contained in:
@@ -192,6 +192,39 @@ class MTMathUILabelLineWrappingTests: XCTestCase {
|
||||
XCTAssertNil(label.error, "Should have no rendering error")
|
||||
}
|
||||
|
||||
func testUnicodeWordBreaking_EquivautCase() {
|
||||
// Specific test for the reported issue: "équivaut" should not break at "é"
|
||||
let label = MTMathUILabel()
|
||||
label.latex = "\\(\\text{Rappelons la conversion : 1 km équivaut à 1000 m.}\\)"
|
||||
label.font = MTFontManager.fontManager.defaultFont
|
||||
label.labelMode = .text
|
||||
|
||||
// Set the exact width constraint from the bug report
|
||||
label.preferredMaxLayoutWidth = 235
|
||||
let constrainedSize = label.intrinsicContentSize
|
||||
|
||||
// Verify the label can render without errors
|
||||
label.frame = CGRect(origin: .zero, size: constrainedSize)
|
||||
#if os(macOS)
|
||||
label.layout()
|
||||
#else
|
||||
label.layoutSubviews()
|
||||
#endif
|
||||
|
||||
XCTAssertNotNil(label.displayList, "Display list should be created")
|
||||
XCTAssertNil(label.error, "Should have no rendering error")
|
||||
|
||||
// Verify that the text wrapped (multiple lines)
|
||||
XCTAssertGreaterThan(constrainedSize.height, 20, "Should have wrapped to multiple lines")
|
||||
|
||||
// The critical check: ensure "équivaut" is not broken in the middle
|
||||
// We can't easily check the exact line breaks, but we can verify:
|
||||
// 1. The rendering succeeded without crashes
|
||||
// 2. The display has reasonable dimensions
|
||||
XCTAssertGreaterThan(constrainedSize.width, 100, "Width should be reasonable")
|
||||
XCTAssertLessThan(constrainedSize.width, 250, "Width should respect constraint")
|
||||
}
|
||||
|
||||
func testNumberProtection_FrenchDecimal() {
|
||||
let label = MTMathUILabel()
|
||||
// French decimal number should NOT be broken
|
||||
|
||||
Reference in New Issue
Block a user