Repository: AvaloniaUI/Avalonia
File: src/Avalonia.Controls/SelectableTextBlock.cs (C#)

Code before:
        }

        protected override TextLayout CreateTextLayout(string? text)
        {
            var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);

            var defaultProperties = new GenericTextRunProperties(
                typeface,
                FontFeatures,
                FontSize,
                TextDecorations,
                Foreground);

            var paragraphProperties = new GenericTextParagraphProperties(FlowDirection, TextAlignment, true, false,
                defaultProperties, TextWrapping, LineHeight, 0, LetterSpacing)
            {
                LineSpacing = LineSpacing
            };

            List<ValueSpan<TextRunProperties>>? textStyleOverrides = null;
            var selectionStart = SelectionStart;
            var selectionEnd = SelectionEnd;
            var start = Math.Min(selectionStart, selectionEnd);
            var length = Math.Max(selectionStart, selectionEnd) - start;

            if (length > 0 && SelectionForegroundBrush != null && _textRuns != null)
            {
                // Apply selection foreground color without changing the original text formatting.
                // The built-in SelectableTextBlock selection logic recreates TextRunProperties,
                // which overwrites run-specific Typeface/FontFeatures/FontSize and breaks bold/italic.
                // Here we reuse each run's existing properties and only override the foreground brush.

                var accumulatedLength = 0;
                foreach (var textRun in _textRuns)
                {
                    var runLength = textRun.Text.Length;
                    if (accumulatedLength + runLength <= start ||
                        accumulatedLength >= start + length)
                    {
                        accumulatedLength += runLength;
                        continue;
                    }

                    var overlapStart = Math.Max(start, accumulatedLength);
                    var overlapEnd = Math.Min(start + length, accumulatedLength + runLength);
                    var overlapLength = overlapEnd - overlapStart;

                    textStyleOverrides ??= [];

                    textStyleOverrides.Add(
                        new ValueSpan<TextRunProperties>(

Review comment (suggestion):
By default, we should apply the old logic; only if `_textRuns` is not null should we apply the new logic.

Code after:
        }

        protected override TextLayout CreateTextLayout(string? text)
        {
            var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);

            var defaultProperties = new GenericTextRunProperties(
                typeface,
                FontFeatures,
                FontSize,
                TextDecorations,
                Foreground);

            var paragraphProperties = new GenericTextParagraphProperties(FlowDirection, TextAlignment, true, false,
                defaultProperties, TextWrapping, LineHeight, 0, LetterSpacing)
            {
                LineSpacing = LineSpacing
            };

            List<ValueSpan<TextRunProperties>>? textStyleOverrides = null;
            var selectionStart = SelectionStart;
            var selectionEnd = SelectionEnd;
            var start = Math.Min(selectionStart, selectionEnd);
            var length = Math.Max(selectionStart, selectionEnd) - start;

            if (length > 0 && SelectionForegroundBrush != null)
            {
                if (_textRuns != null)
                {
                    // Apply selection foreground color without changing the original text formatting.
                    // The built-in SelectableTextBlock selection logic recreates TextRunProperties,
                    // which overwrites run-specific Typeface/FontFeatures/FontSize and breaks bold/italic.
                    // Here we reuse each run's existing properties and only override the foreground brush.

                    var accumulatedLength = 0;
                    foreach (var textRun in _textRuns)
                    {
                        var runLength = textRun.Text.Length;
                        if (accumulatedLength + runLength <= start ||
                            accumulatedLength >= start + length)
                        {
                            accumulatedLength += runLength;
                            continue;
                        }

                        var overlapStart = Math.Max(start, accumulatedLength);
                        var overlapEnd = Math.Min(start + length, accumulatedLength + runLength);
                        var overlapLength = overlapEnd - overlapStart;

                        textStyleOverrides ??= [];