我正在使用 AvalonEdit 编写电影脚本编辑器。
我扩展了 DocumentLine 类以具有“Type”属性,其值表示“字符”、“对话行”等。
我希望脚本中某种类型的文档行以大写形式编写(例如字符名称)。
渲染管道中是否有一个扩展点可以让我获取文档行并更改其大小写?
我尝试创建一个扩展 DocumentColorizingTransformer 的类,但是更改“protected override void ColorizeLine(DocumentLine line)”方法中的大小写不起作用。
这很困难,因为大写可以改变显示字符和文档之间的映射(视觉列与文档偏移量)。
\n\n例如,单个字符 \'\xc3\x9f\'(德语升号 s)仅以小写字母形式存在,并在调用时转换为两个字符的字符串“SS” string.ToUpper()。\n编辑此文本很棘手:我们不能允许用户仅替换其中一个“S”,因为底层文档仅包含“\xc3\x9f”。
一个简单的解决方案是改用该char.ToUpper()方法,在原始字符和大写字符之间强制执行一对一映射。这将使像“\'\xc3\x9f\”这样的字母保持不变。
在 AvalonEdit 4.2 中,仅允许对已生成的 VisualLineElements 进行两种转换:
\n\nChangeLinePart()以便可以更改文本部分的属性。这意味着无法在着色器中进行文本替换,您需要使用VisualLineElementGenerator.
/// <summary>\n/// Makes all text after a colon (until the end of line) upper-case.\n/// </summary>\npublic class UppercaseGenerator : VisualLineElementGenerator\n{\n public override int GetFirstInterestedOffset(int startOffset)\n {\n TextDocument document = CurrentContext.Document;\n int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset;\n for (int i = startOffset; i < endOffset; i++) {\n char c = document.GetCharAt(i);\n if (c == \':\')\n return i + 1;\n }\n return -1;\n }\n\n public override VisualLineElement ConstructElement(int offset)\n {\n DocumentLine line = CurrentContext.Document.GetLineByOffset(offset);\n return new UppercaseText(CurrentContext.VisualLine, line.EndOffset - offset);\n }\n\n /// <summary>\n /// Displays a portion of the document text, but upper-cased.\n /// </summary>\n class UppercaseText : VisualLineText\n {\n public UppercaseText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)\n {\n }\n\n protected override VisualLineText CreateInstance(int length)\n {\n return new UppercaseText(ParentVisualLine, length);\n }\n\n public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)\n {\n if (context == null)\n throw new ArgumentNullException("context");\n\n int relativeOffset = startVisualColumn - VisualColumn;\n StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset);\n char[] uppercase = new char[text.Count];\n for (int i = 0; i < text.Count; i++) {\n uppercase[i] = char.ToUpper(text.Text[text.Offset + i]);\n }\n return new TextCharacters(uppercase, 0, uppercase.Length, this.TextRunProperties);\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n在 AvalonEdit 4.3.0.8868 中,我添加了方法VisualLine.ReplaceElement()。这可用于将默认VisualText元素替换为UppercaseText行变换器(着色器)中的元素。
请注意,还可以实现对显示为“SS”的“\xc3\x9f\”的支持。为此,您必须实现自己的副本,VisualLineText而不仅仅是覆盖现有副本。然后您可以使用与文档长度不同的视觉长度。和方法将用于提供文档和视觉坐标之间的映射GetRelativeOffset。GetVisualColumns
您还可以使用另一种选择:小型大写字母。
\n\n// in the colorizer:\nChangeLinePart(start, end, e => e.TextRunProperties.SetTypographyProperties(new CapsTypography()));\n\n// helper class\nclass CapsTypography : DefaultTextRunTypographyProperties\n{\n public override FontCapitals Capitals {\n get { return FontCapitals.SmallCaps; }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但是,仅当使用支持小型大写字母的 OpenType 字体时,WPF 才会呈现小型大写字母。在我的测试中,Cambria使用小型大写字母,大多数其他字体不使用。\n此外,该SetTypographyProperties方法和DefaultTextRunTypographyProperties类需要 AvalonEdit 4.3。
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |