2012-07-14 1 views
2

AvalonEdit를 사용하여 동영상 스크립트 편집기를 작성하고 있습니다. AvalonEdit의 상단 케이스

나는 등을 나타내는 값 중 하나 "문자", "대화 라인"으로, "유형"속성을 가지도록 DocumentLine 클래스를 확장

내가 스크립트 내에서 특정 유형의 문서 라인을 원하는

대문자 (예 : 문자 이름)로 쓰여집니다.

렌더링 파이프 라인에 문서 줄을 가져 와서 대소 문자를 바꿀 수있는 확장 지점이 있습니까?

DocumentColorizingTransformer를 확장하는 클래스를 만들려고했지만 "protected override void ColorizeLine (DocumentLine line)"메서드 내에서 케이스를 변경하지 않았습니다.

답변

4

대문자가 표시된 문자와 문서 (시각적 열과 문서 오프셋) 간의 매핑을 변경할 수 있기 때문에 어렵습니다.

예를 들어 단일 문자 'ß'(독일어 샤프)는 소문자로만 존재하며 string.ToUpper()을 호출 할 때 두 문자 스트링 "SS"로 변환됩니다. 이 텍스트를 편집하는 것은 까다로운 작업입니다. 기본 문서에 'ß'만 포함되어 있으므로 사용자가 'S'중 하나만 바꿀 수 있습니다.

간단한 해결책은 char.ToUpper() 메서드를 대신 사용하여 원본과 대문자 사이에 일대일 매핑을 적용하는 것입니다. 이렇게하면 'ß'와 같은 글자는 변경되지 않습니다.

는 AvalonEdit 4.2에서 두 변환은 이미 생성 된 VisualLineElements에 사용할 수 있습니다 :

  • 변경 텍스트 실행 특성, 예를 들어, 글꼴 크기, 텍스트 색 등
  • VisualLineElement를 두 개로 분할합니다. 이것은 내부적으로 ChangeLinePart()으로 사용되어 텍스트 부분에 대한 속성을 변경할 수 있습니다.

즉, colorizer에서 텍스트 대체를 수행 할 수 없다는 의미이므로 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에서, I는 VisualLine.ReplaceElement() 방법을 추가했다. 이 옵션을 사용하면 기본 변환기 VisualText을 회선 변/기 (colorizer) 내의 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이 필요합니다.

+0

그런 상세한 답변을 주셔서 감사합니다. 정말 고맙습니다. 당신은 항상 정말로 도움이됩니다. :) –