/// <summary> /// Creates a <see cref = "T:System.Windows.Media.TextFormatting.TextParagraphProperties" /> for the provided configuration. /// </summary> /// <param name = "formattedLineSource">The <see cref = "T:Microsoft.VisualStudio.Text.Formatting.IFormattedLineSource" /> that's performing the formatting of the line. You can access useful properties about the ongoing formatting operation from this object.</param> /// <param name = "textProperties">The <see cref = "T:Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties" /> of the line for which <see cref = "T:System.Windows.Media.TextFormatting.TextParagraphProperties" /> are to be provided. This paramter can be used to obtain formatting information about the textual contents of the line.</param> /// <param name = "line">The <see cref = "T:Microsoft.VisualStudio.Text.IMappingSpan" /> corresponding to the line that's being formatted/rendered.</param> /// <param name = "lineStart">The <see cref = "T:Microsoft.VisualStudio.Text.IMappingPoint" /> corresponding to the beginning of the line segment that's being formatted. This paramter is relevant for word-wrap scenarios where a single <see cref = "T:Microsoft.VisualStudio.Text.ITextSnapshotLine" /> results in multiple formatted/rendered lines on the view.</param> /// <param name = "lineSegment">The segment number of the line segment that's been currently formatted. This is a zero-based index and is applicable to word-wrapped lines. If a line is word-wrapped into 4 segments, you will receive 4 calls for the line with lineSegments of 0, 1, 2, and 3.</param> /// <returns> /// A <see cref = "T:System.Windows.Media.TextFormatting.TextParagraphProperties" /> to be used when the line is being formatted. /// </returns> /// <remarks> /// Please note that you can return a <see cref = "T:Microsoft.VisualStudio.Text.Formatting.TextFormattingParagraphProperties" /> which has a convenient set of basic properties defined. /// </remarks> public TextParagraphProperties Create( IFormattedLineSource formattedLineSource, TextFormattingRunProperties textProperties, IMappingSpan line, IMappingPoint lineStart, int lineSegment) { if (_TextParagraphProperties == null) { _TextParagraphProperties = new PowerShellTextFormattingParagraphProperties( textProperties, formattedLineSource, ServiceProvider ); } return TextParagraphProperties; }
public static IEnumerable<TextLine> MeasureLines(string text, int width, TextParagraphProperties format, DrawingGroup drawTarget) { using (var dc = drawTarget.Open()) using (var formatter = TextFormatter.Create()) { int index = 0; double y = 0; var source = new BasicSource(text, format.DefaultTextRunProperties); while (index < text.Length) { var line = formatter.FormatLine(source, index, width, format, null); line.Draw(dc, new Point(0, y), InvertAxes.None); y += line.Height; index += line.Length; yield return line; } } }
/// <summary> /// Construct a text marker object /// </summary> /// <param name="style">marker style</param> /// <param name="offset">distance from line start to the end of the marker symbol</param> /// <param name="autoNumberingIndex">autonumbering counter of counter-style marker</param> /// <param name="textParagraphProperties">text paragraph properties</param> public TextSimpleMarkerProperties( TextMarkerStyle style, double offset, int autoNumberingIndex, TextParagraphProperties textParagraphProperties ) { if (textParagraphProperties == null) throw new ArgumentNullException("textParagraphProperties"); _offset = offset; if (style != TextMarkerStyle.None) { if (TextMarkerSource.IsKnownSymbolMarkerStyle(style)) { // autoNumberingIndex is ignored } else if (TextMarkerSource.IsKnownIndexMarkerStyle(style)) { // validate autoNumberingIndex if (autoNumberingIndex < 1) { throw new ArgumentOutOfRangeException("autoNumberingIndex", SR.Get(SRID.ParameterCannotBeLessThan, 1)); } } else { // invalid style throw new ArgumentException(SR.Get(SRID.Enum_Invalid, typeof(TextMarkerStyle)), "style"); } _textSource = new TextMarkerSource( textParagraphProperties, style, autoNumberingIndex ); } }
/// <summary> /// Constructing paragraph properties /// </summary> /// <param name="formatter">Text formatter</param> /// <param name="paragraphProperties">paragraph properties</param> /// <param name="optimalBreak">produce optimal break</param> internal ParaProp( TextFormatterImp formatter, TextParagraphProperties paragraphProperties, bool optimalBreak ) { _paragraphProperties = paragraphProperties; _emSize = TextFormatterImp.RealToIdeal(paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize); _indent = TextFormatterImp.RealToIdeal(paragraphProperties.Indent); _paragraphIndent = TextFormatterImp.RealToIdeal(paragraphProperties.ParagraphIndent); _height = TextFormatterImp.RealToIdeal(paragraphProperties.LineHeight); if (_paragraphProperties.FlowDirection == FlowDirection.RightToLeft) { _statusFlags |= StatusFlags.Rtl; } if (optimalBreak) { _statusFlags |= StatusFlags.OptimalBreak; } }
/// <summary> /// Format and produce a text line either with or without previously known /// line break point. /// </summary> private TextLine FormatLineInternal( TextSource textSource, int firstCharIndex, int lineLength, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache ) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordText, EventTrace.Level.Verbose, EventTrace.Event.WClientStringBegin, "TextFormatterImp.FormatLineInternal Start"); // prepare formatting settings FormatSettings settings = PrepareFormatSettings( textSource, firstCharIndex, paragraphWidth, paragraphProperties, previousLineBreak, textRunCache, (lineLength != 0), // Do optimal break if break is given true, // isSingleLineFormatting _textFormattingMode ); TextLine textLine = null; if ( !settings.Pap.AlwaysCollapsible && previousLineBreak == null && lineLength <= 0 ) { // simple text line. textLine = SimpleTextLine.Create( settings, firstCharIndex, RealToIdealFloor(paragraphWidth) ) as TextLine; } if (textLine == null) { // content is complex, creating complex line textLine = new TextMetrics.FullTextLine( settings, firstCharIndex, lineLength, RealToIdealFloor(paragraphWidth), LineFlags.None ) as TextLine; } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordText, EventTrace.Level.Verbose, EventTrace.Event.WClientStringEnd, "TextFormatterImp.FormatLineInternal End"); return textLine; }
/// <summary> /// Client to ask for the possible smallest and largest paragraph width that can fully contain the passing text content /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <param name="textRunCache">an object representing content cache of the client.</param> /// <returns>min max paragraph width</returns> public abstract MinMaxParagraphWidth FormatMinMaxParagraphWidth( TextSource textSource, int firstCharIndex, TextParagraphProperties paragraphProperties, TextRunCache textRunCache );
HexLine GetHexLine(ulong offset, List<HexLinePart> parts, TextRunProperties textRunProps, TextParagraphProperties paraProps, StringBuilder sb, StringBuilder sb2, double width, short[] bytesAry) { HexLine hexLine; if (offsetToLine.TryGetValue(offset, out hexLine)) return hexLine; hexLine = CreateHexLine(offset, EndOffset, parts, textRunProps, sb, sb2, bytesAry); offsetToLine.Add(offset, hexLine); var hexLineTextSource = new HexLineTextSource(hexLine); var textLines = new List<TextLine>(); int textOffset = 0; const int newLineLength = 1; TextLineBreak previousLineBreak = null; for (;;) { var textLine = textFormatter.FormatLine(hexLineTextSource, 0, width, paraProps, previousLineBreak); textLines.Add(textLine); textOffset += textLine.Length; if (textOffset >= hexLine.Length + newLineLength) break; previousLineBreak = textLine.GetTextLineBreak(); } hexLine.TextLines = textLines.ToArray(); return hexLine; }
VisualLine BuildVisualLine(DocumentLine documentLine, TextRunProperties textRunProperties, TextParagraphProperties paragraphProperties, VisualLineElementGenerator[] generators, IVisualLineTransformer[] transformers, Size availableSize) { if (heightTree.GetIsCollapsed(documentLine)) { throw new InvalidOperationException(); } var visualLine = new VisualLine(documentLine); var textSource = new VisualLineTextSource(visualLine) { Document = this.Document, GlobalTextRunProperties = textRunProperties, TextView = this }; visualLine.ConstructVisualElements(textSource, generators); visualLine.RunTransformers(textSource, transformers); int offset = 0; TextLineBreak lineBreak = null; var textLines = new List<TextLine>(); while (offset <= visualLine.VisualLength) { TextLine tl = textFormatter.FormatLine(textSource, offset, availableSize.Width, paragraphProperties, lineBreak); textLines.Add(tl); offset += tl.Length; lineBreak = tl.GetTextLineBreak(); } visualLine.SetTextLines(textLines); heightTree.SetHeight(visualLine.FirstDocumentLine, visualLine.Height); return visualLine; }
public FormattedLineSource(ITextFormatterProvider textFormatterProvider, ITextParagraphPropertiesFactoryService textParagraphPropertiesFactoryService, ITextSnapshot sourceTextSnapshot, ITextSnapshot visualBufferSnapshot, int tabSize, double baseIndent, double wordWrapWidth, double maxAutoIndent, bool useDisplayMode, IClassifier aggregateClassifier, ITextAndAdornmentSequencer sequencer, IClassificationFormatMap classificationFormatMap, bool isViewWrapEnabled) { if (textFormatterProvider == null) throw new ArgumentNullException(nameof(textFormatterProvider)); if (sourceTextSnapshot == null) throw new ArgumentNullException(nameof(sourceTextSnapshot)); if (visualBufferSnapshot == null) throw new ArgumentNullException(nameof(visualBufferSnapshot)); if (aggregateClassifier == null) throw new ArgumentNullException(nameof(aggregateClassifier)); if (sequencer == null) throw new ArgumentNullException(nameof(sequencer)); if (classificationFormatMap == null) throw new ArgumentNullException(nameof(classificationFormatMap)); if (tabSize <= 0) throw new ArgumentOutOfRangeException(nameof(tabSize)); if (sourceTextSnapshot != visualBufferSnapshot) throw new NotSupportedException("Text snapshot must be identical to visual snapshot"); textFormatter = textFormatterProvider.Create(useDisplayMode); formattedTextCache = new FormattedTextCache(useDisplayMode); this.textParagraphPropertiesFactoryService = textParagraphPropertiesFactoryService; SourceTextSnapshot = sourceTextSnapshot; TopTextSnapshot = visualBufferSnapshot; UseDisplayMode = useDisplayMode; TabSize = tabSize; BaseIndentation = baseIndent; WordWrapWidth = wordWrapWidth; MaxAutoIndent = Math.Round(maxAutoIndent); ColumnWidth = formattedTextCache.GetColumnWidth(classificationFormatMap.DefaultTextProperties); wrapGlyphWidth = isViewWrapEnabled ? 1.5 * ColumnWidth : 0; LineHeight = WpfTextViewLine.DEFAULT_TOP_SPACE + WpfTextViewLine.DEFAULT_BOTTOM_SPACE + formattedTextCache.GetLineHeight(classificationFormatMap.DefaultTextProperties); TextHeightAboveBaseline = formattedTextCache.GetTextHeightAboveBaseline(classificationFormatMap.DefaultTextProperties); TextHeightBelowBaseline = formattedTextCache.GetTextHeightBelowBaseline(classificationFormatMap.DefaultTextProperties); TextAndAdornmentSequencer = sequencer; this.aggregateClassifier = aggregateClassifier; this.classificationFormatMap = classificationFormatMap; defaultTextParagraphProperties = new TextFormattingParagraphProperties(classificationFormatMap.DefaultTextProperties, ColumnWidth * TabSize); }
void OnTextPropertiesChanged() { OnTextPropertiesChangedCore(); useDisplayMode = wpfTextViewHost.TextView.FormattedLineSource.UseDisplayMode; var textFormattingMode = useDisplayMode ? TextFormattingMode.Display : TextFormattingMode.Ideal; var defaultProps = GetDefaultTextFormattingRunProperties(); if (defaultProps == null) return; var brush = defaultProps.BackgroundBrush ?? Brushes.Transparent; if (brush.CanFreeze) brush.Freeze(); Background = brush; var ft = new FormattedText("8", defaultProps.CultureInfo, FlowDirection.LeftToRight, defaultProps.Typeface, defaultProps.FontRenderingEmSize, defaultProps.ForegroundBrush, null, textFormattingMode); currentMaxLineDigits = GetMaxLineDigits(); int maxLineNumberValue = Math.Min(int.MaxValue, (int)(Math.Pow(10, currentMaxLineDigits) - 1)); // Just in case non-digits are part of the string, calculate max string length var lineNumberString = GetLineNumberString(maxLineNumberValue); double leftMarginWidth = ft.Width; double rightMarginWidth = ft.Width; double width = leftMarginWidth + rightMarginWidth + ft.Width * lineNumberString.Length; lineNumberTextRight = width - rightMarginWidth; Width = width; ClearLines(); defaultTextParagraphProperties = new TextFormattingParagraphProperties(defaultProps); textFormatter = textFormatterProvider.Create(useDisplayMode); }
[FriendAccessAllowed] // used by Framework internal abstract TextParagraphCache CreateParagraphCache( #endif TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache );
/// <summary> /// Wrapper of TextFormatter.FormatLine that auto-collapses the line if needed. /// </summary> private TextLine FormatLine(TextSource textSource, int textSourcePosition, double maxLineLength, TextParagraphProperties paraProps, TextLineBreak lineBreak) { TextLine line = _formatter.FormatLine( textSource, textSourcePosition, maxLineLength, paraProps, lineBreak ); if (_that._trimming != TextTrimming.None && line.HasOverflowed && line.Length > 0) { // what I really need here is the last displayed text run of the line // textSourcePosition + line.Length - 1 works except the end of paragraph case, // where line length includes the fake paragraph break run Debug.Assert(_that._text.Length > 0 && textSourcePosition + line.Length <= _that._text.Length + 1); SpanRider thatFormatRider = new SpanRider( _that._formatRuns, _that._latestPosition, Math.Min(textSourcePosition + line.Length - 1, _that._text.Length - 1) ); GenericTextRunProperties lastRunProps = thatFormatRider.CurrentElement as GenericTextRunProperties; TextCollapsingProperties trailingEllipsis; if (_that._trimming == TextTrimming.CharacterEllipsis) trailingEllipsis = new TextTrailingCharacterEllipsis(maxLineLength, lastRunProps); else { Debug.Assert(_that._trimming == TextTrimming.WordEllipsis); trailingEllipsis = new TextTrailingWordEllipsis(maxLineLength, lastRunProps); } TextLine collapsedLine = line.Collapse(trailingEllipsis); if (collapsedLine != line) { line.Dispose(); line = collapsedLine; } } return line; }
internal override TextLine RecreateLine( #endif TextSource textSource, int firstCharIndex, int lineLength, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache ) { return FormatLineInternal( textSource, firstCharIndex, lineLength, paragraphWidth, paragraphProperties, previousLineBreak, textRunCache ); }
public TextSimpleMarkerProperties(System.Windows.TextMarkerStyle style, double offset, int autoNumberingIndex, TextParagraphProperties textParagraphProperties) { }
/// <summary> /// Client to format a text line that fills a paragraph in the document. /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphWidth">width of paragraph in which the line fills</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <param name="previousLineBreak">LineBreak property of the previous text line, or null if this is the first line in the paragraph</param> /// <param name="textRunCache">an object representing content cache of the client.</param> /// <returns>object representing a line of text that client interacts with. </returns> public override TextLine FormatLine( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache ) { return FormatLineInternal( textSource, firstCharIndex, 0, // lineLength paragraphWidth, paragraphProperties, previousLineBreak, textRunCache ); }
/// <summary> /// Client to format a text line that fills a paragraph in the document. /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphWidth">width of paragraph in which the line fills</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <param name="previousLineBreak">LineBreak property of the previous text line, or null if this is the first line in the paragraph</param> /// <returns>object representing a line of text that client interacts with. </returns> public override TextLine FormatLine( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak ) { return FormatLineInternal( textSource, firstCharIndex, 0, // lineLength paragraphWidth, paragraphProperties, previousLineBreak, new TextRunCache() // local cache, only live within this call ); }
/// <summary> /// Constructing TextParagraphProperties from another one /// </summary> /// <param name="textParagraphProperties">source line props</param> public GenericTextParagraphProperties(TextParagraphProperties textParagraphProperties) { _flowDirection = textParagraphProperties.FlowDirection; _defaultTextRunProperties = textParagraphProperties.DefaultTextRunProperties; _textAlignment = textParagraphProperties.TextAlignment; _lineHeight = textParagraphProperties.LineHeight; _firstLineInParagraph = textParagraphProperties.FirstLineInParagraph; _alwaysCollapsible = textParagraphProperties.AlwaysCollapsible; _textWrap = textParagraphProperties.TextWrapping; _indent = textParagraphProperties.Indent; }
internal TextMarkerSource( TextParagraphProperties textParagraphProperties, TextMarkerStyle markerStyle, int autoNumberingIndex ) { Debug.Assert(markerStyle != TextMarkerStyle.None); _textParagraphProperties = textParagraphProperties; TextRunProperties defaultRunProperties = _textParagraphProperties.DefaultTextRunProperties; string symbolString = null; if(IsKnownSymbolMarkerStyle(markerStyle)) { switch(markerStyle) { case TextMarkerStyle.Disc: symbolString = "\x9f"; break; case TextMarkerStyle.Circle: symbolString = "\xa1"; break; case TextMarkerStyle.Square: symbolString = "\x71"; break; case TextMarkerStyle.Box: symbolString = "\xa7"; break; } Typeface defaultTypeface = defaultRunProperties.Typeface; // recreate a new marker run properties based on symbol typeface e.g. Wingding _textRunProperties = new GenericTextRunProperties( new Typeface( new FontFamily("Wingdings"), defaultTypeface.Style, defaultTypeface.Weight, defaultTypeface.Stretch ), defaultRunProperties.FontRenderingEmSize, defaultRunProperties.FontHintingEmSize, defaultRunProperties.TextDecorations, defaultRunProperties.ForegroundBrush, defaultRunProperties.BackgroundBrush, defaultRunProperties.BaselineAlignment, CultureMapper.GetSpecificCulture(defaultRunProperties.CultureInfo), null // default number substitution for culture ); } else if(IsKnownIndexMarkerStyle(markerStyle)) { // Internal client code should have already validated this. Debug.Assert(autoNumberingIndex > 0); _textRunProperties = defaultRunProperties; int counter = autoNumberingIndex; switch(markerStyle) { case TextMarkerStyle.Decimal: _characterArray = ConvertNumberToString(counter, false, DecimalNumerics); break; case TextMarkerStyle.LowerLatin: _characterArray = ConvertNumberToString(counter, true, LowerLatinNumerics); break; case TextMarkerStyle.UpperLatin: _characterArray = ConvertNumberToString(counter, true, UpperLatinNumerics); break; case TextMarkerStyle.LowerRoman: symbolString = ConvertNumberToRomanString(counter, false); break; case TextMarkerStyle.UpperRoman: symbolString = ConvertNumberToRomanString(counter, true); break; } } else { Debug.Assert(false, "Invalid marker style"); } if(symbolString != null) { _characterArray = symbolString.ToCharArray(); } Debug.Assert(_characterArray != null); }
// ------------------------------------------------------------------ // Constructor. // ------------------------------------------------------------------ internal ParaEllipsisLineProperties(TextParagraphProperties lp) { _lp = lp; }
/// <summary> /// Client to format a text line that fills a paragraph in the document. /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphWidth">width of paragraph in which the line fills</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <param name="previousLineBreak">text formatting state at the point where the previous line in the paragraph /// was broken by the text formatting process, as specified by the TextLine.LineBreak property for the previous /// line; this parameter can be null, and will always be null for the first line in a paragraph.</param> /// <param name="textRunCache">an object representing content cache of the client.</param> /// <returns>object representing a line of text that client interacts with. </returns> public abstract TextLine FormatLine( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache );
/// <summary> /// Client to ask for the possible smallest and largest paragraph width that can fully contain the passing text content /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <returns>min max paragraph width</returns> public override MinMaxParagraphWidth FormatMinMaxParagraphWidth( TextSource textSource, int firstCharIndex, TextParagraphProperties paragraphProperties ) { return FormatMinMaxParagraphWidth( textSource, firstCharIndex, paragraphProperties, new TextRunCache() // local cache, only live within this call ); }
/// <summary> /// Client to ask for the possible smallest and largest paragraph width that can fully contain the passing text content /// </summary> /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param> /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param> /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param> /// <param name="textRunCache">an object representing content cache of the client.</param> /// <returns>min max paragraph width</returns> public override MinMaxParagraphWidth FormatMinMaxParagraphWidth( TextSource textSource, int firstCharIndex, TextParagraphProperties paragraphProperties, TextRunCache textRunCache ) { // prepare formatting settings FormatSettings settings = PrepareFormatSettings( textSource, firstCharIndex, 0, // infinite paragraphWidth paragraphProperties, null, // always format the whole paragraph - no previousLineBreak textRunCache, false, // optimalBreak true, // isSingleLineFormatting _textFormattingMode ); // create specialized line specifically for min/max calculation TextMetrics.FullTextLine line = new TextMetrics.FullTextLine( settings, firstCharIndex, 0, // lineLength 0, // paragraph width has no significant meaning in min/max calculation (LineFlags.KeepState | LineFlags.MinMax) ); // line width in this case is the width of a line when the entire paragraph is laid out // as a single long line. MinMaxParagraphWidth minMax = new MinMaxParagraphWidth(line.MinWidth, line.Width); line.Dispose(); return minMax; }
// ------------------------------------------------------------------ // Create and format text line. // // lineStartIndex - index of the first character in the line // width - wrapping width of the line // lineProperties - properties of the line // textRunCache - run cache used by text formatter // showParagraphEllipsis - true if paragraph ellipsis is shown // at the end of the line // ------------------------------------------------------------------ internal void Format(int dcp, double width, TextParagraphProperties lineProperties, TextLineBreak textLineBreak, TextRunCache textRunCache, bool showParagraphEllipsis) { #if TEXTPANELLAYOUTDEBUG TextPanelDebug.IncrementCounter("Line.Format", TextPanelDebug.Category.TextView); #endif _mirror = (lineProperties.FlowDirection == FlowDirection.RightToLeft); _dcp = dcp; _showParagraphEllipsis = showParagraphEllipsis; _wrappingWidth = width; _line = _owner.TextFormatter.FormatLine(this, dcp, width, lineProperties, textLineBreak, textRunCache); }
internal override TextParagraphCache CreateParagraphCache( #endif TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache ) { // prepare formatting settings FormatSettings settings = PrepareFormatSettings( textSource, firstCharIndex, paragraphWidth, paragraphProperties, previousLineBreak, textRunCache, true, // optimalBreak false, // !isSingleLineFormatting _textFormattingMode ); // // Optimal paragraph formatting session specific check // if (!settings.Pap.Wrap && settings.Pap.OptimalBreak) { // Optimal paragraph must wrap. throw new ArgumentException(SR.Get(SRID.OptimalParagraphMustWrap)); } // create paragraph content cache object return new TextParagraphCache( settings, firstCharIndex, RealToIdeal(paragraphWidth) ); }
// ------------------------------------------------------------------ // GetTextMarkerProperties // ------------------------------------------------------------------ internal TextMarkerProperties GetTextMarkerProperties(TextParagraphProperties textParaProps) { return new TextSimpleMarkerProperties(_style, _offset, _index, textParaProps); }
/// <summary> /// Validate all the relevant text formatting initial settings and package them /// </summary> private FormatSettings PrepareFormatSettings( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak, TextRunCache textRunCache, bool useOptimalBreak, bool isSingleLineFormatting, TextFormattingMode textFormattingMode ) { VerifyTextFormattingArguments( textSource, firstCharIndex, paragraphWidth, paragraphProperties, textRunCache ); if (textRunCache.Imp == null) { // No run cache object available, create one textRunCache.Imp = new TextRunCacheImp(); } // initialize formatting settings return new FormatSettings( this, textSource, textRunCache.Imp, new ParaProp(this, paragraphProperties, useOptimalBreak), previousLineBreak, isSingleLineFormatting, textFormattingMode, false ); }
void LineNumberMargin_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { if (Visibility == Visibility.Visible) { if (!hasRegisteredEvents) { RegisterEvents(); SetTop(textLayer, -wpfTextViewHost.TextView.ViewportTop); UpdateMaxLineDigits(); UpdateLineNumberLayerSize(); UpdateForceClearTypeIfNeeded(); OnTextPropertiesChanged(); UpdateLines(Array.Empty<ITextViewLine>(), Array.Empty<ITextViewLine>()); } } else { if (hasRegisteredEvents) UnregisterEvents(); ClearLines(); defaultTextParagraphProperties = null; textFormatter = null; } }
/// <summary> /// Verify all text formatting arguments /// </summary> private void VerifyTextFormattingArguments( TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextRunCache textRunCache ) { if (textSource == null) throw new ArgumentNullException("textSource"); if (textRunCache == null) throw new ArgumentNullException("textRunCache"); if (paragraphProperties == null) throw new ArgumentNullException("paragraphProperties"); if (paragraphProperties.DefaultTextRunProperties == null) throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties"); if (paragraphProperties.DefaultTextRunProperties.Typeface == null) throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties.Typeface"); if (DoubleUtil.IsNaN(paragraphWidth)) throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeNaN)); if (double.IsInfinity(paragraphWidth)) throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeInfinity)); if ( paragraphWidth < 0 || paragraphWidth > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth)); } double realMaxFontRenderingEmSize = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm; if ( paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize < 0 || paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize > realMaxFontRenderingEmSize) { throw new ArgumentOutOfRangeException("paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize", SR.Get(SRID.ParameterMustBeBetween, 0, realMaxFontRenderingEmSize)); } if (paragraphProperties.Indent > Constants.RealInfiniteWidth) throw new ArgumentOutOfRangeException("paragraphProperties.Indent", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth)); if (paragraphProperties.LineHeight > Constants.RealInfiniteWidth) throw new ArgumentOutOfRangeException("paragraphProperties.LineHeight", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth)); if ( paragraphProperties.DefaultIncrementalTab < 0 || paragraphProperties.DefaultIncrementalTab > Constants.RealInfiniteWidth) { throw new ArgumentOutOfRangeException("paragraphProperties.DefaultIncrementalTab", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth)); } }
// ----------------------------------------------------------------- // // Internal Methods // // ------------------------------------------------------------------ #region Internal Methods /// <summary> /// Create and format text line. /// </summary> /// <param name="ctx"> /// Line formatting context. /// </param> /// <param name="dcp"> /// Character position where the line starts. /// </param> /// <param name="width"> /// Requested width of the line. /// </param> /// <param name="trackWidth"> /// Requested width of track. /// </param> /// <param name="lineProps"> /// Line properties. /// </param> /// <param name="textLineBreak"> /// Line break object. /// </param> internal void Format(FormattingContext ctx, int dcp, int width, int trackWidth, TextParagraphProperties lineProps, TextLineBreak textLineBreak) { // Set formatting context _formattingContext = ctx; _dcp = dcp; _host.Context = this; _wrappingWidth = TextDpi.FromTextDpi(width); _trackWidth = TextDpi.FromTextDpi(trackWidth); _mirror = (lineProps.FlowDirection == FlowDirection.RightToLeft); _indent = lineProps.Indent; try { // Create line object if(ctx.LineFormatLengthTarget == -1) { _line = _host.TextFormatter.FormatLine(_host, dcp, _wrappingWidth, lineProps, textLineBreak, ctx.TextRunCache); } else { _line = _host.TextFormatter.RecreateLine(_host, dcp, ctx.LineFormatLengthTarget, _wrappingWidth, lineProps, textLineBreak, ctx.TextRunCache); } _runs = _line.GetTextRunSpans(); Invariant.Assert(_runs != null, "Cannot retrieve runs collection."); // Submit inline objects (only in measure mode) if (_formattingContext.MeasureMode) { List<InlineObject> inlineObjects = new List<InlineObject>(1); int dcpRun = _dcp; // Enumerate through all runs in the current line and retrieve // all inline objects. // If there are any figures / floaters, store this information for later use. foreach (TextSpan<TextRun> textSpan in _runs) { TextRun run = (TextRun)textSpan.Value; if (run is InlineObjectRun) { inlineObjects.Add(new InlineObject(dcpRun, ((InlineObjectRun)run).UIElementIsland, (TextParagraph)_paraClient.Paragraph)); } else if (run is FloatingRun) { if (((FloatingRun)run).Figure) { _hasFigures = true; } else { _hasFloaters = true; } } // Do not use TextRun.Length, because it gives total length of the run. // So, if the run is broken between lines, it gives incorrect value. // Use length of the TextSpan instead, which gives the correct length here. dcpRun += textSpan.Length; } // Submit inline objects to the paragraph cache if (inlineObjects.Count == 0) { inlineObjects = null; } TextParagraph.SubmitInlineObjects(dcp, dcp + ActualLength, inlineObjects); } } finally { // Clear formatting context _host.Context = null; } }
public TextLine FormatLine(TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak) { return formatter.FormatLine(textSource, firstCharIndex, paragraphWidth, paragraphProperties, previousLineBreak); }