Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.AvalonEdit/5.0.1/AvalonEdit-5.0.1/Rendering/FormattedTextElement.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 7.4 KB
Line 
1// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19using System;
20using System.Windows;
21using System.Windows.Media;
22using System.Windows.Media.TextFormatting;
23using ICSharpCode.AvalonEdit.Utils;
24
25namespace ICSharpCode.AvalonEdit.Rendering
26{
27  /// <summary>
28  /// Formatted text (not normal document text).
29  /// This is used as base class for various VisualLineElements that are displayed using a
30  /// FormattedText, for example newline markers or collapsed folding sections.
31  /// </summary>
32  public class FormattedTextElement : VisualLineElement
33  {
34    internal readonly FormattedText formattedText;
35    internal string text;
36    internal TextLine textLine;
37   
38    /// <summary>
39    /// Creates a new FormattedTextElement that displays the specified text
40    /// and occupies the specified length in the document.
41    /// </summary>
42    public FormattedTextElement(string text, int documentLength) : base(1, documentLength)
43    {
44      if (text == null)
45        throw new ArgumentNullException("text");
46      this.text = text;
47      this.BreakBefore = LineBreakCondition.BreakPossible;
48      this.BreakAfter = LineBreakCondition.BreakPossible;
49    }
50   
51    /// <summary>
52    /// Creates a new FormattedTextElement that displays the specified text
53    /// and occupies the specified length in the document.
54    /// </summary>
55    public FormattedTextElement(TextLine text, int documentLength) : base(1, documentLength)
56    {
57      if (text == null)
58        throw new ArgumentNullException("text");
59      this.textLine = text;
60      this.BreakBefore = LineBreakCondition.BreakPossible;
61      this.BreakAfter = LineBreakCondition.BreakPossible;
62    }
63   
64    /// <summary>
65    /// Creates a new FormattedTextElement that displays the specified text
66    /// and occupies the specified length in the document.
67    /// </summary>
68    public FormattedTextElement(FormattedText text, int documentLength) : base(1, documentLength)
69    {
70      if (text == null)
71        throw new ArgumentNullException("text");
72      this.formattedText = text;
73      this.BreakBefore = LineBreakCondition.BreakPossible;
74      this.BreakAfter = LineBreakCondition.BreakPossible;
75    }
76   
77    /// <summary>
78    /// Gets/sets the line break condition before the element.
79    /// The default is 'BreakPossible'.
80    /// </summary>
81    public LineBreakCondition BreakBefore { get; set; }
82   
83    /// <summary>
84    /// Gets/sets the line break condition after the element.
85    /// The default is 'BreakPossible'.
86    /// </summary>
87    public LineBreakCondition BreakAfter { get; set; }
88   
89    /// <inheritdoc/>
90    public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
91    {
92      if (textLine == null) {
93        var formatter = TextFormatterFactory.Create(context.TextView);
94        textLine = PrepareText(formatter, this.text, this.TextRunProperties);
95        this.text = null;
96      }
97      return new FormattedTextRun(this, this.TextRunProperties);
98    }
99   
100    /// <summary>
101    /// Constructs a TextLine from a simple text.
102    /// </summary>
103    public static TextLine PrepareText(TextFormatter formatter, string text, TextRunProperties properties)
104    {
105      if (formatter == null)
106        throw new ArgumentNullException("formatter");
107      if (text == null)
108        throw new ArgumentNullException("text");
109      if (properties == null)
110        throw new ArgumentNullException("properties");
111      return formatter.FormatLine(
112        new SimpleTextSource(text, properties),
113        0,
114        32000,
115        new VisualLineTextParagraphProperties {
116          defaultTextRunProperties = properties,
117          textWrapping = TextWrapping.NoWrap,
118          tabSize = 40
119        },
120        null);
121    }
122  }
123 
124  /// <summary>
125  /// This is the TextRun implementation used by the <see cref="FormattedTextElement"/> class.
126  /// </summary>
127  public class FormattedTextRun : TextEmbeddedObject
128  {
129    readonly FormattedTextElement element;
130    TextRunProperties properties;
131   
132    /// <summary>
133    /// Creates a new FormattedTextRun.
134    /// </summary>
135    public FormattedTextRun(FormattedTextElement element, TextRunProperties properties)
136    {
137      if (element == null)
138        throw new ArgumentNullException("element");
139      if (properties == null)
140        throw new ArgumentNullException("properties");
141      this.properties = properties;
142      this.element = element;
143    }
144   
145    /// <summary>
146    /// Gets the element for which the FormattedTextRun was created.
147    /// </summary>
148    public FormattedTextElement Element {
149      get { return element; }
150    }
151   
152    /// <inheritdoc/>
153    public override LineBreakCondition BreakBefore {
154      get { return element.BreakBefore; }
155    }
156   
157    /// <inheritdoc/>
158    public override LineBreakCondition BreakAfter {
159      get { return element.BreakAfter; }
160    }
161   
162    /// <inheritdoc/>
163    public override bool HasFixedSize {
164      get { return true; }
165    }
166   
167    /// <inheritdoc/>
168    public override CharacterBufferReference CharacterBufferReference {
169      get { return new CharacterBufferReference(); }
170    }
171   
172    /// <inheritdoc/>
173    public override int Length {
174      get { return element.VisualLength; }
175    }
176   
177    /// <inheritdoc/>
178    public override TextRunProperties Properties {
179      get { return properties; }
180    }
181   
182    /// <inheritdoc/>
183    public override TextEmbeddedObjectMetrics Format(double remainingParagraphWidth)
184    {
185      var formattedText = element.formattedText;
186      if (formattedText != null) {
187        return new TextEmbeddedObjectMetrics(formattedText.WidthIncludingTrailingWhitespace,
188                                             formattedText.Height,
189                                             formattedText.Baseline);
190      } else {
191        var text = element.textLine;
192        return new TextEmbeddedObjectMetrics(text.WidthIncludingTrailingWhitespace,
193                                             text.Height,
194                                             text.Baseline);
195      }
196    }
197   
198    /// <inheritdoc/>
199    public override Rect ComputeBoundingBox(bool rightToLeft, bool sideways)
200    {
201      var formattedText = element.formattedText;
202      if (formattedText != null) {
203        return new Rect(0, 0, formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
204      } else {
205        var text = element.textLine;
206        return new Rect(0, 0, text.WidthIncludingTrailingWhitespace, text.Height);
207      }
208    }
209   
210    /// <inheritdoc/>
211    public override void Draw(DrawingContext drawingContext, Point origin, bool rightToLeft, bool sideways)
212    {
213      if (element.formattedText != null) {
214        origin.Y -= element.formattedText.Baseline;
215        drawingContext.DrawText(element.formattedText, origin);
216      } else {
217        origin.Y -= element.textLine.Baseline;
218        element.textLine.Draw(drawingContext, origin, InvertAxes.None);
219      }
220    }
221  }
222}
Note: See TracBrowser for help on using the repository browser.