gpt4 book ai didi

c# - Avalon 中的大写编辑

转载 作者:行者123 更新时间:2023-11-30 21:05:46 26 4
gpt4 key购买 nike

我正在使用 AvalonEdit 编写电影脚本编辑器。

我扩展了 DocumentLine 类,使其具有“Type”属性,其值代表“Character”、“Dialog Line”等。

我希望脚本中某种类型的文档行以大写形式书写(例如字符名称)。

渲染管道中是否有一个扩展点允许我获取文档行并更改它的大小写?

我尝试创建一个扩展 DocumentColorizingTransformer 的类,但在“protected override void ColorizeLine(DocumentLine line)”方法中更改大小写不起作用。

最佳答案

这很难,因为大写会改变显示字符和文档之间的映射(视觉列与文档偏移量)。

例如,单个字符“ß”(德语升号 s)仅作为小写字母存在,并在调用 string.ToUpper() 时转换为双字符字符串“SS” .编辑此文本很棘手:我们不能允许用户仅替换其中一个“S”,因为基础文档仅包含“ß”。

一个简单的解决方案是使用 char.ToUpper()方法,在原始字符和大写字符之间强制执行一对一映射。这将使 'ß' 等字母保持不变。

在 AvalonEdit 4.2 中,在已经生成的 VisualLineElements 上只允许进行两种转换:

  • 更改文本运行属性,例如字体大小、文字颜色等
  • 将 VisualLineElement 一分为二 - 这由 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 副本。而不是仅仅覆盖现有的。然后您可以使用不同于文档长度的视觉长度。 GetRelativeOffsetGetVisualColumns方法将用于提供文档和视觉坐标之间的映射。


您可以使用另一种选择:小型大写字母。

// 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。

关于c# - Avalon 中的大写编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11487234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com