2

AvalonEdit を使用してムービー スクリプト エディタを作成しています。

DocumentLine クラスを拡張して「Type」プロパティを持ち、値は「文字」、「ダイアログ ライン」などを表します。

スクリプト内の特定のタイプのドキュメント行を大文字で記述したいと考えています (たとえば、文字名)。

レンダリング パイプライン内に、ドキュメント行を取得して大文字と小文字を変更できる拡張ポイントはありますか?

DocumentColorizingTransformer を拡張するクラスを作成してみましたが、「保護されたオーバーライド void ColorizeLine(DocumentLine 行)」メソッド内で大文字と小文字を変更しても機能しませんでした。

4

1 に答える 1

4

大文字を使用すると、表示される文字とドキュメントの間のマッピング (ビジュアル列とドキュメント オフセット) が変わる可能性があるため、これは困難です。

たとえば、1 文字の 'ß' (ドイツ語のシャープ s) は小文字としてのみ存在し、 を呼び出すと 2 文字の文字列 "SS" に変換されstring.ToUpper()ます。このテキストの編集には注意が必要です。基になるドキュメントには 'ß' しか含まれていないため、ユーザーが 'S' の 1 つだけを置き換えることを許可することはできません。

簡単な解決策は、char.ToUpper()代わりにメソッドを使用して、元の文字と大文字の間で 1 対 1 のマッピングを強制することです。これにより、'ß' などの文字は変更されません。

AvalonEdit 4.2 では、生成済みの VisualLineElements で許可される変換は 2 つだけです。

  • テキスト ランのプロパティ (フォント サイズ、テキストの色など) を変更します。
  • VisualLineElement を 2 つに分割します。これはChangeLinePart()、テキスト部分のプロパティを変更できるように内部で使用されます。

これは、カラーライザーでテキスト置換を行うことができないことを意味しますVisualLineElementGenerator。.

/// <summary>
/// Makes all text after a colon (until the end of line) upper-case.
/// </summary>
public class UppercaseGenerator : VisualLineElementGenerator
{
    public override int GetFirstInterestedOffset(int startOffset)
    {
        TextDocument document = CurrentContext.Document;
        int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset;
        for (int i = startOffset; i < endOffset; i++) {
            char c = document.GetCharAt(i);
            if (c == ':')
                return i + 1;
        }
        return -1;
    }

    public override VisualLineElement ConstructElement(int offset)
    {
        DocumentLine line = CurrentContext.Document.GetLineByOffset(offset);
        return new UppercaseText(CurrentContext.VisualLine, line.EndOffset - offset);
    }

    /// <summary>
    /// Displays a portion of the document text, but upper-cased.
    /// </summary>
    class UppercaseText : VisualLineText
    {
        public UppercaseText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)
        {
        }

        protected override VisualLineText CreateInstance(int length)
        {
            return new UppercaseText(ParentVisualLine, length);
        }

        public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            int relativeOffset = startVisualColumn - VisualColumn;
            StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset);
            char[] uppercase = new char[text.Count];
            for (int i = 0; i < text.Count; i++) {
                uppercase[i] = char.ToUpper(text.Text[text.Offset + i]);
            }
            return new TextCharacters(uppercase, 0, uppercase.Length, this.TextRunProperties);
        }
    }
}

AvalonEdit 4.3.0.8868 では、メソッドを追加しましたVisualLine.ReplaceElement()VisualTextこれを使用して、デフォルトの要素をUppercaseTextライン トランスフォーマー (カラーライザー) 内の要素に置き換えることができます。

「ß」を「SS」として表示するためのサポートを実装することも可能であることに注意してください。そのためにはVisualLineText、既存のものをオーバーライドするだけでなく、独自のコピーを実装する必要があります。次に、ドキュメントの長さとは異なる視覚的な長さを使用できます。GetRelativeOffsetメソッドとGetVisualColumnsメソッドを使用して、ドキュメントとビジュアル座標の間のマッピングを提供します。


使用できる別のオプションがあります。スモール キャップです。

// in the colorizer:
ChangeLinePart(start, end, e => e.TextRunProperties.SetTypographyProperties(new CapsTypography()));

// helper class
class CapsTypography : DefaultTextRunTypographyProperties
{
    public override FontCapitals Capitals {
        get { return FontCapitals.SmallCaps; }
    }
}

ただし、WPF は、小さい大文字をサポートする OpenType フォントを使用している場合にのみ小さい大文字をレンダリングします。私のテストでCambriaは、小さな大文字で動作しましたが、他のほとんどのフォントでは動作しません。また、SetTypographyPropertiesメソッドとDefaultTextRunTypographyPropertiesクラスには AvalonEdit 4.3 が必要です。

于 2012-07-19T17:39:22.357 に答える