public static TextRunProperties GetGlobalTextRunProperties() { if (textRunProperties == null) { textRunProperties = CreateGlobalTextRunProperties(); } return textRunProperties; }
public TextRunProperties GetTextRunProperties(TextRunProperties defaultTextRunProperties) { var item = (CompletionItem as DescriptionModifyingCompletionItem)?.CompletionItem ?? CompletionItem; return (item.CompletionProvider as ICustomCompletionItemFormatter)?.GetTextRunProperties(item, defaultTextRunProperties) ?? defaultTextRunProperties; }
public static bool Equals(TextRunProperties a, TextRunProperties b) { if (a == b) return true; if (a == null || b == null) return false; if (a.FontHintingEmSize != b.FontHintingEmSize) return false; if (a.FontRenderingEmSize != b.FontRenderingEmSize) return false; if (a.TextDecorations != b.TextDecorations) // We don't use it so this is enough return false; if (a.TextEffects != b.TextEffects) // We don't use it so this is enough return false; if (!a.CultureInfo.Equals(b.CultureInfo)) return false; if (!a.Typeface.Equals(b.Typeface)) return false; if (!Equals(a.BackgroundBrush, b.BackgroundBrush)) return false; if (!Equals(a.ForegroundBrush, b.ForegroundBrush)) return false; if (a.BaselineAlignment != b.BaselineAlignment) return false; if (!Equals(a.NumberSubstitution, b.NumberSubstitution)) return false; if (!Equals(a.TypographyProperties, b.TypographyProperties)) return false; return true; }
/// <summary> /// Store <paramref name="timeStamp"/> and updates the text for the visual. /// </summary> /// <param name="timeStamp">Time of the event.</param> /// <param name="line">The line that this time stamp corresponds to.</param> /// <param name="view">The <see cref="IWpfTextView"/> to whom the <paramref name="line"/> belongs.</param> /// <param name="formatting">Properties for the time stamp text.</param> /// <param name="marginWidth">Used to calculate the horizontal offset for <see cref="OnRender(DrawingContext)"/>.</param> /// <param name="verticalOffset">Used to calculate the vertical offset for <see cref="OnRender(DrawingContext)"/>.</param> /// <param name="showHours">Option to show hours on the time stamp.</param> /// <param name="showMilliseconds">Option to show milliseconds on the time stamp.</param> internal void UpdateVisual(DateTime timeStamp, ITextViewLine line, IWpfTextView view, TextRunProperties formatting, double marginWidth, double verticalOffset, bool showHours, bool showMilliseconds) { this.LineTag = line.IdentityTag; if (timeStamp != this.TimeStamp) { this.TimeStamp = timeStamp; string text = GetFormattedTime(timeStamp, showHours, showMilliseconds); TextFormattingMode textFormattingMode = view.FormattedLineSource.UseDisplayMode ? TextFormattingMode.Display : TextFormattingMode.Ideal; _text = new FormattedText(text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, formatting.Typeface, formatting.FontRenderingEmSize, formatting.ForegroundBrush, InvariantNumberSubstitution, textFormattingMode); _horizontalOffset = Math.Round(marginWidth - _text.Width); this.InvalidateVisual(); // force redraw } double newVerticalOffset = line.TextTop - view.ViewportTop + verticalOffset; if (newVerticalOffset != _verticalOffset) { _verticalOffset = newVerticalOffset; this.InvalidateVisual(); // force redraw } }
/// <summary> /// Modifies the properties of a text run. /// </summary> /// <param name="properties">Properties of a text run or the return value of /// ModifyProperties for a nested text modifier.</param> /// <returns>Returns the actual text run properties to be used for formatting, /// subject to further modification by text modifiers at outer scopes.</returns> public sealed override TextRunProperties ModifyProperties(TextRunProperties properties) { // Get the text decorations applied to the text modifier run. If there are // none, we don't change anything. if (properties == null || _modifierDecorations == null || _modifierDecorations.Count == 0) return properties; // Let brush be the foreground brush for the text modifier run. Any text // decorations defined at the text modifier scope that have a null Pen // should be drawn using this brush, which means we may need to copy some // TextDecoration objects and set the Pen property on the copies. We can // elide this if the same brush is used at both scopes. We shouldn't miss // too many optimization opportunities by using the (lower cost) reference // comparison here because in most cases where the brushes are equal it's // because it's an inherited property. Brush brush = _modifierBrush; if (object.ReferenceEquals(brush, properties.ForegroundBrush)) { // No need to set the pen property. brush = null; } // We're going to create a merged set of text decorations. TextDecorationCollection mergedDecorations; // Get the text decorations of the affected run, if any. TextDecorationCollection runDecorations = properties.TextDecorations; if (runDecorations == null || runDecorations.Count == 0) { // Only the text modifier run defines text decorations so // we don't need to merge anything. if (brush == null) { // Use the text decorations of the modifier run. mergedDecorations = _modifierDecorations; } else { // The foreground brushes differ so copy the text decorations to a // new collection and make sure each has a non-null pen. mergedDecorations = CopyTextDecorations(_modifierDecorations, brush); } } else { // Add the modifier decorations first because we want text decorations // defined at the inner scope (e.g., by the run) to be drawn on top. mergedDecorations = CopyTextDecorations(_modifierDecorations, brush); // Add the text decorations defined at the inner scope; we never need // to set the pen for these because they should be drawn using the // foreground brush. foreach (TextDecoration td in runDecorations) { mergedDecorations.Add(td); } } return new MergedTextRunProperties(properties, mergedDecorations); }
internal void Update( string text, ITextViewLine line, IWpfTextView view, TextRunProperties formatting, double marginWidth, double verticalOffset) { LineTag = line.IdentityTag; if (_text == null || !string.Equals(_text, text, StringComparison.Ordinal)) { _text = text; _formattedText = new FormattedText( _text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, formatting.Typeface, formatting.FontRenderingEmSize, formatting.ForegroundBrush); _horizontalOffset = Math.Round(marginWidth - _formattedText.Width); InvalidateVisual(); } var num = line.TextTop - view.ViewportTop + verticalOffset; // ReSharper disable once CompareOfFloatsByEqualityOperator if (num == _verticalOffset) return; _verticalOffset = num; InvalidateVisual(); }
/// <summary> /// Internal constructor of TextContent /// </summary> private TextCharacters( CharacterBufferReference characterBufferReference, int length, TextRunProperties textRunProperties ) { if (length <= 0) { throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterMustBeGreaterThanZero)); } if (textRunProperties == null) { throw new ArgumentNullException("textRunProperties"); } if (textRunProperties.Typeface == null) { throw new ArgumentNullException("textRunProperties.Typeface"); } if (textRunProperties.CultureInfo == null) { throw new ArgumentNullException("textRunProperties.CultureInfo"); } if (textRunProperties.FontRenderingEmSize <= 0) { throw new ArgumentOutOfRangeException("textRunProperties.FontRenderingEmSize", SR.Get(SRID.ParameterMustBeGreaterThanZero)); } _characterBufferReference = characterBufferReference; _length = length; _textRunProperties = textRunProperties; }
/// <summary> /// Add shapeable text object to the list /// </summary> void IShapeableTextCollector.Add( IList <TextShapeableSymbols> shapeables, CharacterBufferRange characterBufferRange, TextRunProperties textRunProperties, MS.Internal.Text.TextInterface.ItemProps textItem, ShapeTypeface shapeTypeface, double emScale, bool nullShape, TextFormattingMode textFormattingMode ) { Debug.Assert(shapeables != null); shapeables.Add( new TextShapeableCharacters( characterBufferRange, textRunProperties, textRunProperties.FontRenderingEmSize * emScale, textItem, shapeTypeface, nullShape, textFormattingMode, false ) ); }
/// <summary> /// Constructor. /// </summary> /// <param name="cch">Number of text position in the text array occupied by the inline object.</param> /// <param name="element">UIElement representing the inline object.</param> /// <param name="textProps">Text run properties for the inline object.</param> /// <param name="host">Paragraph - the host of the inline object.</param> internal InlineObjectRun(int cch, UIElement element, TextRunProperties textProps, TextParagraph host) { _cch = cch; _textProps = textProps; _host = host; _inlineUIContainer = (InlineUIContainer)LogicalTreeHelper.GetParent(element); }
/// <summary> /// Construct a text trailing word ellipsis collapsing properties /// </summary> /// <param name="width">width in which collapsing is constrained to</param> /// <param name="textRunProperties">text run properties of ellispis symbol</param> public TextTrailingWordEllipsis( double width, TextRunProperties textRunProperties ) { _width = width; _ellipsis = new TextCharacters(StringHorizontalEllipsis, textRunProperties); }
/// <summary> /// Construct a text trailing character ellipsis collapsing properties /// </summary> /// <param name="width">width in which collapsing is constrained to</param> /// <param name="textRunProperties">text run properties of ellispis symbol</param> public TextTrailingCharacterEllipsis( double width, TextRunProperties textRunProperties ) { _width = width; _ellipsis = new TextCharacters(StringHorizontalEllipsis, textRunProperties); }
/// <summary> /// Modifies the specified text run properties by invoking the modifier at /// the current scope and all containing scopes. /// </summary> /// <param name="properties">Properties to modify.</param> /// <returns>Returns the text run properties after modification.</returns> internal TextRunProperties ModifyProperties(TextRunProperties properties) { for (TextModifierScope scope = this; scope != null; scope = scope._parentScope) { properties = scope._modifier.ModifyProperties(properties); } return(properties); }
protected TextLine GetLine(TextRunProperties runProperties, TextSource textSource, int column = 0) { return TextFormatter.Create().FormatLine( textSource, column, 96 * 6, new SimpleParagraphProperties { defaultTextRunProperties = runProperties }, null); }
/// <summary> /// Modifies the specified text run properties by invoking the modifier at /// the current scope and all containing scopes. /// </summary> /// <param name="properties">Properties to modify.</param> /// <returns>Returns the text run properties after modification.</returns> internal TextRunProperties ModifyProperties(TextRunProperties properties) { for (TextModifierScope scope = this; scope != null; scope = scope._parentScope) { properties = scope._modifier.ModifyProperties(properties); } return properties; }
/// <summary> /// Constructor. /// </summary> /// <param name="dcp">Text position of the inline object in the text array.</param> /// <param name="cch">Number of text position in the text array occupied by the inline object.</param> /// <param name="element">UIElement representing the inline object.</param> /// <param name="textProps">Text run properties for the inline object.</param> /// <param name="host">TextBlock element - the host of the inline object.</param> internal InlineObject(int dcp, int cch, UIElement element, TextRunProperties textProps, System.Windows.Controls.TextBlock host) { _dcp = dcp; _cch = cch; _element = element; _textProps = textProps; _host = host; }
/// <summary> /// Creates a new FormattedTextRun. /// </summary> public FormattedTextRun(FormattedTextElement element, TextRunProperties properties) { if (element == null) throw new ArgumentNullException("element"); if (properties == null) throw new ArgumentNullException("properties"); this.properties = properties; this.element = element; }
public HexLinePart(int index, int column, VST.Span span, TextRunProperties textRunProperties) { Debug.Assert(!span.IsEmpty); Debug.Assert(textRunProperties != null); Index = index; Column = column; Span = span; AdornmentElement = null; TextRunProperties = textRunProperties; }
public HexLinePart(int index, int column, VST.Span span, HexAdornmentElement adornmentElement, TextRunProperties textRunProperties) { Debug.Assert(adornmentElement != null); Debug.Assert(textRunProperties != null); Index = index; Column = column; Span = span; AdornmentElement = adornmentElement; TextRunProperties = textRunProperties; }
protected FormattedText GetFormattedText(string text, TextRunProperties runProperties) { return new FormattedText( text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, runProperties.Typeface, runProperties.FontRenderingEmSize, Brushes.Black); }
/// <summary> /// Construct a paragraph break run /// </summary> /// <param name="length">number of characters</param> /// <param name="textRunProperties">linebreak text run properties</param> public TextEndOfParagraph( int length, TextRunProperties textRunProperties ) : base( length, textRunProperties ) {}
public HexTextRunProperties(TextRunProperties other) { this._BackgroundBrush = other.BackgroundBrush; this._CultureInfo = other.CultureInfo; this._FontHintingEmSize = other.FontHintingEmSize; this._FontRenderingEmSize = other.FontRenderingEmSize; this._ForegroundBrush = other.ForegroundBrush; this._TextDecorations = other.TextDecorations; this._TextEffects = other.TextEffects; this._Typeface = other.Typeface; }
/// <summary> /// Construct a paragraph break run /// </summary> /// <param name="length">number of characters</param> /// <param name="textRunProperties">linebreak text run properties</param> public TextEndOfParagraph( int length, TextRunProperties textRunProperties ) : base( length, textRunProperties ) { }
/// <summary> /// Construct a run for text content from string /// </summary> public TextCharacters( string characterString, TextRunProperties textRunProperties ) : this( characterString, 0, // offserToFirstChar (characterString == null) ? 0 : characterString.Length, textRunProperties ) {}
public unsafe TextCharacters( char *unsafeCharacterString, int length, TextRunProperties textRunProperties ) : this( new CharacterBufferReference(unsafeCharacterString, length), length, textRunProperties ) { }
/// <summary> /// Construct a run for text content from string /// </summary> public TextCharacters( string characterString, TextRunProperties textRunProperties ) : this( characterString, 0, // offserToFirstChar (characterString == null) ? 0 : characterString.Length, textRunProperties ) { }
/// <summary> /// Construct a run of text content from character array /// </summary> public TextCharacters( char[] characterArray, int offsetToFirstChar, int length, TextRunProperties textRunProperties ) : this( new CharacterBufferReference(characterArray, offsetToFirstChar), length, textRunProperties ) {}
/// <summary> /// Construct a run for text content from string /// </summary> public TextCharacters( string characterString, int offsetToFirstChar, int length, TextRunProperties textRunProperties ) : this( new CharacterBufferReference(characterString, offsetToFirstChar), length, textRunProperties ) {}
/// <summary> /// Creates a new InlineObjectRun instance. /// </summary> /// <param name="length">The length of the TextRun.</param> /// <param name="properties">The <see cref="TextRunProperties"/> to use.</param> /// <param name="element">The <see cref="UIElement"/> to display.</param> public InlineObjectRun(int length, TextRunProperties properties, UIElement element) { if (length <= 0) throw new ArgumentOutOfRangeException("length", length, "Value must be positive"); if (properties == null) throw new ArgumentNullException("properties"); if (element == null) throw new ArgumentNullException("element"); this.length = length; this.properties = properties; this.element = element; }
/// <summary> /// Construct a run for text content from string /// </summary> public TextCharacters( string characterString, int offsetToFirstChar, int length, TextRunProperties textRunProperties ) : this( new CharacterBufferReference(characterString, offsetToFirstChar), length, textRunProperties ) { }
/// <summary> /// Construct a run of text content from character array /// </summary> public TextCharacters( char[] characterArray, int offsetToFirstChar, int length, TextRunProperties textRunProperties ) : this( new CharacterBufferReference(characterArray, offsetToFirstChar), length, textRunProperties ) { }
/// <summary> /// Construct a linebreak run /// </summary> /// <param name="length">number of characters</param> /// <param name="textRunProperties">linebreak text run properties</param> public TextEndOfLine( int length, TextRunProperties textRunProperties ) { if (length <= 0) throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterMustBeGreaterThanZero)); if (textRunProperties != null && textRunProperties.Typeface == null) throw new ArgumentNullException("textRunProperties.Typeface"); _length = length; _textRunProperties = textRunProperties; }
public GenericTextParagraphProperties(FontRendering newRendering) { _flowDirection = FlowDirection.LeftToRight; _textAlignment = newRendering.TextAlignment; _firstLineInParagraph = false; _alwaysCollapsible = false; _defaultTextRunProperties = new GenericTextRunProperties( newRendering.Typeface, newRendering.FontSize, newRendering.FontSize, newRendering.TextDecorations, newRendering.TextColor, null, BaselineAlignment.Baseline, CultureInfo.CurrentUICulture); _textWrap = TextWrapping.Wrap; _lineHeight = 0; _indent = 0; _paragraphIndent = 0; }
internal void GetShapeableText( Typeface typeface, CharacterBufferReference characterBufferReference, int stringLength, TextRunProperties textRunProperties, CultureInfo digitCulture, bool isRightToLeftParagraph, IList<TextShapeableSymbols> shapeableList, IShapeableTextCollector collector, TextFormattingMode textFormattingMode ) { if (!typeface.Symbol) { Lookup(typeface).GetShapeableText( characterBufferReference, stringLength, textRunProperties, digitCulture, isRightToLeftParagraph, shapeableList, collector, textFormattingMode ); } else { // It's a non-Unicode ("symbol") font, where code points have non-standard meanings. We // therefore want to bypass the usual itemization and font linking. Instead, just map // everything to the default script and first GlyphTypeface. ShapeTypeface shapeTypeface = new ShapeTypeface( typeface.TryGetGlyphTypeface(), null // device font ); collector.Add( shapeableList, new CharacterBufferRange(characterBufferReference, stringLength), textRunProperties, new MS.Internal.Text.TextInterface.ItemProps(), shapeTypeface, 1.0, // scale in Em false, // null shape textFormattingMode ); } }
/// <summary> /// Construct a linebreak run /// </summary> /// <param name="length">number of characters</param> /// <param name="textRunProperties">linebreak text run properties</param> public TextEndOfLine( int length, TextRunProperties textRunProperties ) { if (length <= 0) { throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterMustBeGreaterThanZero)); } if (textRunProperties != null && textRunProperties.Typeface == null) { throw new ArgumentNullException("textRunProperties.Typeface"); } _length = length; _textRunProperties = textRunProperties; }
public GenericTextParagraphProperties( FlowDirection flowDirection, TextAlignment textAlignment, bool firstLineInParagraph, bool alwaysCollapsible, TextRunProperties defaultTextRunProperties, TextWrapping textWrap, double lineHeight, double indent) { _flowDirection = flowDirection; _textAlignment = textAlignment; _firstLineInParagraph = firstLineInParagraph; _alwaysCollapsible = alwaysCollapsible; _defaultTextRunProperties = defaultTextRunProperties; _textWrap = textWrap; _lineHeight = lineHeight; _indent = indent; }
/// <summary> /// Construct a shapeable characters object /// </summary> /// <remarks> /// The shapeTypeface parameter can be null if and only if CheckFastPathNominalGlyphs /// has previously returned true. /// </remarks> internal TextShapeableCharacters( CharacterBufferRange characterRange, TextRunProperties properties, double emSize, ItemProps textItem, ShapeTypeface shapeTypeface, bool nullShape, TextFormattingMode textFormattingMode, bool isSideways ) { _isSideways = isSideways; _textFormattingMode = textFormattingMode; _characterBufferRange = characterRange; _properties = properties; _emSize = emSize; _textItem = textItem; _shapeTypeface = shapeTypeface; _nullShape = nullShape; }
/// <summary> /// Creates a new VisualLineElementTextRunProperties instance that copies its values /// from the specified <paramref name="textRunProperties"/>. /// For the <see cref="TextDecorations"/> and <see cref="TextEffects"/> collections, deep copies /// are created if those collections are not frozen. /// </summary> public VisualLineElementTextRunProperties(TextRunProperties textRunProperties) { if (textRunProperties == null) throw new ArgumentNullException("textRunProperties"); backgroundBrush = textRunProperties.BackgroundBrush; baselineAlignment = textRunProperties.BaselineAlignment; cultureInfo = textRunProperties.CultureInfo; fontHintingEmSize = textRunProperties.FontHintingEmSize; fontRenderingEmSize = textRunProperties.FontRenderingEmSize; foregroundBrush = textRunProperties.ForegroundBrush; typeface = textRunProperties.Typeface; textDecorations = textRunProperties.TextDecorations; if (textDecorations != null && !textDecorations.IsFrozen) { textDecorations = textDecorations.Clone(); } textEffects = textRunProperties.TextEffects; if (textEffects != null && !textEffects.IsFrozen) { textEffects = textEffects.Clone(); } }
/// <summary> /// Resolves number substitution method to one of following values: /// European /// Traditional /// NativeNational /// </summary> internal static NumberSubstitutionMethod GetResolvedSubstitutionMethod(TextRunProperties properties, CultureInfo digitCulture, out bool ignoreUserOverride) { ignoreUserOverride = true; NumberSubstitutionMethod resolvedMethod = NumberSubstitutionMethod.European; if (digitCulture != null) { NumberSubstitutionMethod method; CultureInfo numberCulture = GetNumberCulture(properties, out method, out ignoreUserOverride); if (numberCulture != null) { // First, disambiguate AsCulture method, which depends on digit substitution contained in CultureInfo.NumberFormat if (method == NumberSubstitutionMethod.AsCulture) { switch (numberCulture.NumberFormat.DigitSubstitution) { case DigitShapes.Context: method = NumberSubstitutionMethod.Context; break; case DigitShapes.NativeNational: method = NumberSubstitutionMethod.NativeNational; break; default: method = NumberSubstitutionMethod.European; break; } } // Next, disambiguate Context method, which maps to Traditional if digitCulture != null resolvedMethod = method; if (resolvedMethod == NumberSubstitutionMethod.Context) { resolvedMethod = NumberSubstitutionMethod.Traditional; } } } return resolvedMethod; }
public TextTrailingWordEllipsis(double width, TextRunProperties textRunProperties) { }
public FoldingLineTextRun(FormattedTextElement element, TextRunProperties properties) : base(element, properties) { }
public abstract TextRunProperties ModifyProperties(TextRunProperties properties);
public TextEndOfLine(int length, TextRunProperties textRunProperties) { }
public TextEndOfParagraph(int length, TextRunProperties textRunProperties) : base(default(int)) { }
public TextTrailingCharacterEllipsis(double width, TextRunProperties textRunProperties) { }
/// <summary> /// Break a run of text into individually shape items. /// Shape items are delimited by /// Change of writing system /// Change of glyph typeface /// </summary> IList <TextShapeableSymbols> ITextSymbols.GetTextShapeableSymbols( GlyphingCache glyphingCache, CharacterBufferReference characterBufferReference, int length, bool rightToLeft, bool isRightToLeftParagraph, CultureInfo digitCulture, TextModifierScope textModifierScope, TextFormattingMode textFormattingMode, bool isSideways ) { if (characterBufferReference.CharacterBuffer == null) { throw new ArgumentNullException("characterBufferReference.CharacterBuffer"); } int offsetToFirstChar = characterBufferReference.OffsetToFirstChar - _characterBufferReference.OffsetToFirstChar; Debug.Assert(characterBufferReference.CharacterBuffer == _characterBufferReference.CharacterBuffer); Debug.Assert(offsetToFirstChar >= 0 && offsetToFirstChar < _length); if (length < 0 || offsetToFirstChar + length > _length) { length = _length - offsetToFirstChar; } // Get the actual text run properties in effect, after invoking any // text modifiers that may be in scope. TextRunProperties textRunProperties = _textRunProperties; if (textModifierScope != null) { textRunProperties = textModifierScope.ModifyProperties(textRunProperties); } if (!rightToLeft) { // Fast loop early out for run with all non-complex characters // which can be optimized by not going thru shaping engine. int nominalLength; if (textRunProperties.Typeface.CheckFastPathNominalGlyphs( new CharacterBufferRange(characterBufferReference, length), textRunProperties.FontRenderingEmSize, (float)textRunProperties.PixelsPerDip, 1.0, double.MaxValue, // widthMax true, // keepAWord digitCulture != null, CultureMapper.GetSpecificCulture(textRunProperties.CultureInfo), textFormattingMode, isSideways, false, //breakOnTabs out nominalLength ) && length == nominalLength) { return(new TextShapeableCharacters[] { new TextShapeableCharacters( new CharacterBufferRange(characterBufferReference, nominalLength), textRunProperties, textRunProperties.FontRenderingEmSize, new MS.Internal.Text.TextInterface.ItemProps(), null, // shapeTypeface (no shaping required) false, // nullShape, textFormattingMode, isSideways ) }); } } IList <TextShapeableSymbols> shapeables = new List <TextShapeableSymbols>(2); glyphingCache.GetShapeableText( textRunProperties.Typeface, characterBufferReference, length, textRunProperties, digitCulture, isRightToLeftParagraph, shapeables, this as IShapeableTextCollector, textFormattingMode ); return(shapeables); }
public TextCharacters(char[] characterArray, int offsetToFirstChar, int length, TextRunProperties textRunProperties) { }
public TextCharacters(string characterString, TextRunProperties textRunProperties) { }
public TextCharacters(string characterString, int offsetToFirstChar, int length, TextRunProperties textRunProperties) { }
unsafe public TextCharacters(char *unsafeCharacterString, int length, TextRunProperties textRunProperties) { }