AppKit: Align decimal tab stops on the decimal separator

The typesetter laid a decimal tab stop out like a left tab, so a column of numbers started at the stop instead of aligning on its decimal separators. It now follows Cocoa: the first decimal separator of the user's locale starts at the stop, and a segment without one ends at the stop.

* CPTextView/CPTypesetter.j: Position text after a decimal tab stop by the width before its first decimal separator, taken from the browser's locale.

* Tests/Manual/TextEditor/WORKLIST.md: Record the Tab key and the four tab stop types as tested, and the tab stop menu as working.
This commit is contained in:
David Richardson committed 2026-10-23 20:21:32 -06:00
1 parent b222ee0320
commit d605ee9d50
2 files changed
+29 -3

No files matched your search

+27 -2
View File
@@ -49,7 +49,23 @@ CPTypesetterParagraphBreakAction = 1 << 4;
CPTypesetterContainerBreakAction = 1 << 5;
var CPSystemTypesetterFactory,
_sharedSimpleTypesetter;
_sharedSimpleTypesetter,
_CPTypesetterCachedDecimalSeparator = nil;
/*
Returns the decimal separator of the user's locale, which a decimal tab stop aligns on.
*/
var _CPTypesetterDecimalSeparator = function()
{
if (!_CPTypesetterCachedDecimalSeparator)
{
var formatted = (1.5).toLocaleString();
_CPTypesetterCachedDecimalSeparator = formatted.length === 3 ? formatted.charAt(1) : @".";
}
return _CPTypesetterCachedDecimalSeparator;
};
@implementation CPTypesetter : CPObject
@@ -478,7 +494,16 @@ var CPSystemTypesetterFactory,
tabAlignment = [nextTab alignment];
// Mathematically offset the tab character's right boundary
if (tabAlignment === CPCenterTextAlignment)
if ([nextTab tabStopType] === CPDecimalTabStopType)
{
// As in Cocoa, the first decimal separator of the user's locale starts at the stop.
// A segment without one ends at the stop, like a right tab.
var separatorIndex = segmentString.indexOf(_CPTypesetterDecimalSeparator()),
widthBeforeSeparator = separatorIndex === -1 ? nextSegmentWidth : [segmentString.substring(0, separatorIndex) sizeWithFont:currentFont inWidth:NULL].width;
rangeWidth = (tabLocation - widthBeforeSeparator) - lineOrigin.x;
}
else if (tabAlignment === CPCenterTextAlignment)
{
rangeWidth = (tabLocation - nextSegmentWidth / 2.0) - lineOrigin.x;
}