void CreateLine() { TextFormatter formatter = TextFormatter.Create(); if (textSource.Text.Length == 0) { TextLine myTextLine = formatter.FormatLine( textSource, 0, this._width, new GenericTextParagraphProperties(fontRender, this.FlowDirection, this.TextWarpping), null); lines.Add(myTextLine); } else { int textStorePosition = 0; this.lines.Clear(); while (textStorePosition < textSource.Text.Length) { TextLine myTextLine = formatter.FormatLine( textSource, textStorePosition, this._width, new GenericTextParagraphProperties(fontRender, this.FlowDirection, this.TextWarpping), null); lines.Add(myTextLine); textStorePosition += myTextLine.Length; } } }
/// <summary> /// Constructs a TextLine from a simple text. /// </summary> internal static TextLine PrepareText(TextFormatter formatter, string text, TextRunProperties properties) { if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } if (text == null) { throw new ArgumentNullException(nameof(text)); } if (properties == null) { throw new ArgumentNullException(nameof(properties)); } return(formatter.FormatLine( new SimpleTextSource(text, properties), 0, 32000, new TextParagraphProperties { DefaultTextRunProperties = properties, TextWrapping = TextWrapping.NoWrap, DefaultIncrementalTab = 40 })); }
private void UpdateFormattedText02() { // Create a DrawingGroup object for storing formatted text. myTextDisplay = new DrawingGroup(); DrawingContext drawingContext = myTextDisplay.Open(); // Update the text store. customTextSource.Text = "The quick red fox jumped over the lazy brown dog."; // Create a TextFormatter object. TextFormatter formatter = TextFormatter.Create(); // Create common paragraph property settings. CustomTextParagraphProperties customTextParagraphProperties = new CustomTextParagraphProperties(); // <SnippetTextFormattingSnippet2> // Create a textline from the text store using the TextFormatter object. TextLine myTextLine = formatter.FormatLine( customTextSource, 0, 400, customTextParagraphProperties, null); // Draw the formatted text into the drawing context. myTextLine.Draw(drawingContext, new Point(0, 0), InvertAxes.None); // </SnippetTextFormattingSnippet2> // Persist the drawn text content. drawingContext.Close(); // Display the formatted text in the DrawingGroup object. myDrawingBrush.Drawing = myTextDisplay; }
/// <summary> /// Constructs a TextLine from a simple text. /// </summary> public static TextLine PrepareText(TextFormatter formatter, string text, TextRunProperties properties) { if (formatter == null) { throw new ArgumentNullException("formatter"); } if (text == null) { throw new ArgumentNullException("text"); } if (properties == null) { throw new ArgumentNullException("properties"); } return(formatter.FormatLine( new SimpleTextSource(text, properties), 0, 32000, new VisualLineTextParagraphProperties { defaultTextRunProperties = properties, textWrapping = TextWrapping.NoWrap, tabSize = 40 }, null)); }
public Size Measure(double width) { var height = 0.0; int textSourcePosition = 0; while (textSourcePosition < textSource.Length) { using (var line = formatter.FormatLine(textSource, textSourcePosition, width, defaultParagraphProps, previousLineBreak: null, textRunCache: textSource.Cache)) { height += line.Height; textSourcePosition += line.Length; } } return(new Size(width, height)); }
Line CreateLine(ITextViewLine viewLine, LineNumberState lineNumberState, int lineNumber) { var lineNumberString = GetLineNumberString(lineNumber); var lineNumberSource = new LineNumberSource(lineNumberString, GetLineNumberTextFormattingRunProperties(viewLine, lineNumberState, lineNumber)); var textLine = textFormatter.FormatLine(lineNumberSource, 0, 0, defaultTextParagraphProperties, null); return(new Line(lineNumber, textLine, lineNumberTextRight, viewLine.TextTop + viewLine.Baseline - textLine.TextBaseline)); }
public override HexFormattedLine FormatLineInVisualBuffer(HexBufferLine line) { if (line == null) { throw new ArgumentNullException(nameof(line)); } var seqColl = HexAndAdornmentSequencer.CreateHexAndAdornmentCollection(line); var linePartsCollection = CreateLinePartsCollection(seqColl, line); var textSource = new HexLinePartsTextSource(linePartsCollection); TextLineBreak previousLineBreak = null; double autoIndent = BaseIndentation; int column = 0; int linePartsIndex = 0; var lineParts = linePartsCollection.LineParts; textSource.SetMaxLineLength(MAX_LINE_LENGTH); var textLine = textFormatter.FormatLine(textSource, column, 0, defaultTextParagraphProperties, previousLineBreak); int startColumn = column; int length = TF.TextLineExtensions.GetLength(textLine, textSource.EndOfLine); column += length; int linePartsEnd = linePartsIndex; Debug.Assert(lineParts.Count == 0 || linePartsEnd < lineParts.Count); while (linePartsEnd < lineParts.Count) { var part = lineParts[linePartsEnd]; linePartsEnd++; if (column <= part.Column + part.ColumnLength) { break; } } linePartsEnd--; var startPos = textSource.ConvertColumnToLinePosition(startColumn); var endPos = textSource.ConvertColumnToLinePosition(column); if (column >= textSource.Length) { endPos = line.TextSpan.End; linePartsEnd = lineParts.Count - 1; } var lineSpan = VST.Span.FromBounds(startPos, endPos); var formattedLine = new HexFormattedLineImpl(linePartsCollection, linePartsIndex, linePartsEnd - linePartsIndex + 1, startColumn, column, line, lineSpan, textLine, autoIndent, ColumnWidth); Debug.Assert(column == textSource.Length); return(formattedLine); }
/// <summary> /// Method for starting the text formatting process. Each event handler /// will call this after the current fontrendering is updated. /// </summary> private void UpdateFormattedText(double pixelsPerDip) { // Make sure all UI is loaded if (!_UILoaded) { return; } // Initialize the text store. _textStore = new CustomTextSource(_pixelsPerDip); int textStorePosition = 0; //Index into the text of the textsource System.Windows.Point linePosition = new System.Windows.Point(0, 0); //current line // Create a DrawingGroup object for storing formatted text. textDest = new DrawingGroup(); DrawingContext dc = textDest.Open(); // Update the text store. _textStore.Text = textToFormat.Text; _textStore.FontRendering = _currentRendering; // Create a TextFormatter object. TextFormatter formatter = TextFormatter.Create(); // Format each line of text from the text store and draw it. while (textStorePosition < _textStore.Text.Length) { // Create a textline from the text store using the TextFormatter object. using (TextLine myTextLine = formatter.FormatLine( _textStore, textStorePosition, 96 * 6, new GenericTextParagraphProperties(_currentRendering, _pixelsPerDip), null)) { // Draw the formatted text into the drawing context. myTextLine.Draw(dc, linePosition, InvertAxes.None); // Update the index position in the text store. textStorePosition += myTextLine.Length; // Update the line position coordinate for the displayed line. linePosition.Y += myTextLine.Height; } } // Persist the drawn text content. dc.Close(); // Display the formatted text in the DrawingGroup object. myDrawingBrush.Drawing = textDest; }
public WpfTextLine MakeTextLine(int lineNumber) { // Use '~' for the phantom line, otherwise the line number. string text = lineNumber == -1 ? "~" : lineNumber.ToString(CultureInfo.CurrentUICulture.NumberFormat); var textSource = new LineNumberTextSource(text, _formatting); var format = new TextFormattingParagraphProperties(_formatting); return(_textFormatter.FormatLine(textSource, 0, 0, format, null)); }
private void UpdateFormattedText() { // Index into the text of the TextSource object. int textStorePosition = 0; // The position of the current line. Point linePosition = new Point(0, 0); // Create a DrawingGroup object for storing formatted text. myTextDisplay = new DrawingGroup(); DrawingContext drawingContext = myTextDisplay.Open(); // Update the text store. customTextSource.Text = textToFormat.Text; // <SnippetTextFormattingSnippet1> // Create a TextFormatter object. TextFormatter formatter = TextFormatter.Create(); // Create common paragraph property settings. CustomTextParagraphProperties customTextParagraphProperties = new CustomTextParagraphProperties(); // Format each line of text from the text store and draw it. while (textStorePosition < customTextSource.Text.Length) { // Create a textline from the text store using the TextFormatter object. using (TextLine myTextLine = formatter.FormatLine( customTextSource, textStorePosition, 96 * 6, customTextParagraphProperties, null)) { // Draw the formatted text into the drawing context. myTextLine.Draw(drawingContext, linePosition, InvertAxes.None); // Update the index position in the text store. textStorePosition += myTextLine.Length; // Update the line position coordinate for the displayed line. linePosition.Y += myTextLine.Height; } } // </SnippetTextFormattingSnippet1> // Persist the drawn text content. drawingContext.Close(); // Display the formatted text in the DrawingGroup object. myDrawingBrush.Drawing = myTextDisplay; }
// Token: 0x06004134 RID: 16692 RVA: 0x0012A210 File Offset: 0x00128410 internal void Format(int dcp, double formatWidth, double paragraphWidth, LineProperties lineProperties, TextRunCache textRunCache, TextFormatter formatter) { this._lineProperties = lineProperties; this._dcp = dcp; this._paragraphWidth = paragraphWidth; lineProperties.IgnoreTextAlignment = (lineProperties.TextAlignment != TextAlignment.Justify); try { this._line = formatter.FormatLine(this, dcp, formatWidth, lineProperties, null, textRunCache); } finally { lineProperties.IgnoreTextAlignment = false; } }
public IList <TextLineVisual> CreateLineVisual(Int32 lineNumber, IList <SpaceNegotiation> spaceNegotiations) { IList <ClassificationSpan> classificationSpans; Int32 startOfLineFromLineNumber = _textView.TextBuffer.GetStartOfLineFromLineNumber(lineNumber); Int32 startOfNextLineFromPosition = _textView.TextBuffer.GetStartOfNextLineFromPosition(startOfLineFromLineNumber); Int32 lengthOfLineFromLineNumber = _textView.TextBuffer.GetLengthOfLineFromLineNumber(lineNumber); Int32 length = 0; if (startOfNextLineFromPosition == startOfLineFromLineNumber) { length = _textView.TextBuffer.GetEndOfLineFromPosition(startOfLineFromLineNumber) - startOfLineFromLineNumber; } else { length = startOfNextLineFromPosition - startOfLineFromLineNumber; } if (length > 0) { classificationSpans = _classifier.GetClassificationSpans(new VersionedTextSpan(_textView.TextBuffer, startOfLineFromLineNumber, length)); } else { classificationSpans = new List <ClassificationSpan>(0); } TextFormattingSource textSource = new TextFormattingSource(_textView.TextBuffer, _classificationFormatMap, startOfLineFromLineNumber, length, classificationSpans, spaceNegotiations); if (_textFormatter == null) { _textFormatter = TextFormatter.Create(); } List <TextLine> textLines = new List <TextLine>(); Int32 firstCharIndex = 0; TextLineBreak previousLineBreak = null; while (firstCharIndex <= length) { TextLine item = _textFormatter.FormatLine(textSource, firstCharIndex, this.MaxLineWidth, _paragraphProperties, previousLineBreak); firstCharIndex += item.Length; previousLineBreak = item.GetTextLineBreak(); textLines.Add(item); } List <TextLineVisual> list3 = new List <TextLineVisual>(); list3.Add(new TextLineVisual(_textView, textLines, new TextSpan(_textView.TextBuffer, startOfLineFromLineNumber, length), length - lengthOfLineFromLineNumber, textSource.VirtualCharacterPositions)); return(list3); }
//------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// <summary> /// Create and format text line. /// </summary> /// <param name="dcp">First character position for the line.</param> /// <param name="formatWidth">Width to pass to LS formatter.</param> /// <param name="paragraphWidth">Line wrapping width.</param> /// <param name="lineProperties">Line's properties.</param> /// <param name="textRunCache">Run cache.</param> /// <param name="formatter">Text formatter.</param> /// <remarks> /// formatWidth/paragraphWidth is an attempt to work around bug 114719. /// Unfortunately, Line Services cannot guarantee that once a line /// has been measured, measuring the same content with the actual line /// width will produce the same line. /// /// For example, suppose we format dcp 0 with paragraphWidth = 100. /// Suppose this results in a line from dcp 0 - 10, with width = 95. /// /// We would expect that a call to FormatLine with dcp = 0, /// paragraphWidth = 95 would result in the same 10 char line. /// But in practice it might return a 9 char line. /// /// The workaround is to pass in an explicit formatting width across /// multiple calls, even if the paragraphWidth changes. /// </remarks> internal void Format(int dcp, double formatWidth, double paragraphWidth, LineProperties lineProperties, TextRunCache textRunCache, TextFormatter formatter) { _lineProperties = lineProperties; _dcp = dcp; _paragraphWidth = paragraphWidth; // We must ignore TextAlignment here since formatWidth does not // necessarilly equal paragraphWidth. We'll adjust on later calls. lineProperties.IgnoreTextAlignment = (lineProperties.TextAlignment != TextAlignment.Justify); try { _line = formatter.FormatLine(this, dcp, formatWidth, lineProperties, null, textRunCache); } finally { lineProperties.IgnoreTextAlignment = false; } }
private void GenerateFormattedText(CustomTextSource textStore, DrawingContext dc, TextFormatter formatter) { int textStorePosition = 0; //Index into the text of the textsource Point linePosition = new Point(0, 0); //current line // Format each line of text from the text store and draw it. while (textStorePosition < textStore.Text.Length) { TextLine textLine = formatter.FormatLine(textStore, textStorePosition, textStore.ParagraphWidth, textStore.CTPProperties, null); // Draw the formatted text into the drawing context. textLine.Draw(dc, linePosition, InvertAxes.None); // Update the index position in the text store. textStorePosition += textLine.Length; // Update the line position coordinate for the displayed line. linePosition.Y += textLine.Height; } }
public void Render(int startPos, int count) { DrawingContext dc = RenderOpen(); if (_textStore != null && count > 0) { _textStore.LastRenderColumn = startPos + count; // Create a TextFormatter object. TextFormatter formatter = TextFormatter.Create(); // Format each line of text from the text store and draw it. // Create a textline from the text store using the TextFormatter object. using (var myTextLine = formatter.FormatLine(_textStore, startPos, 0, _paragraphProps, null)) { // Draw the formatted text into the drawing context. myTextLine.Draw(dc, new Point(), InvertAxes.None); } } dc.Close(); }
public IEnumerable <TextLine> Format(string text, IChatSpanProvider spans, double width, Brush foreground, Brush background, TextWrapping textWrapping) { _text = text; _spans = spans; _background = background; _runProperties = new CustomTextRunProperties(_runProperties.Typeface, _runProperties.FontRenderingEmSize, foreground, Brushes.Transparent, false); _paraProperties = new CustomParagraphProperties(_runProperties); if (width < 0) { width = 0; text = ""; } int idx = 0; while (idx < _text.Length) { var line = _formatter.FormatLine(this, idx, width, _paraProperties, null); idx += line.Length; yield return(line); } }
public TextLine FormatLine(TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak) { return(formatter.FormatLine(textSource, firstCharIndex, paragraphWidth, paragraphProperties, previousLineBreak)); }
private void Render(Point location, string colour) { int textStorePosition = 0; bool flipped; Position = location; if (ParentAtom == null) { flipped = false; } else { flipped = Flipped; } var textStore = new FunctionalGroupTextSource(ParentGroup, colour, flipped); //main textformatter - this does the writing of the visual using (TextFormatter textFormatter = TextFormatter.Create()) { //set up the default paragraph properties var paraprops = new FunctionalGroupTextSource.GenericTextParagraphProperties( FlowDirection.LeftToRight, TextAlignment.Left, true, false, new LabelTextRunProperties(colour), TextWrapping.NoWrap, GlyphText.SymbolSize, 0d); var anchorRuns = textStore.Runs.Where(f => f.IsAnchor); string anchorString = string.Empty; foreach (var run in anchorRuns) { anchorString += run.Text; } using (TextLine myTextLine = textFormatter.FormatLine(textStore, textStorePosition, 999, paraprops, null)) { IList <TextBounds> textBounds; Rect firstRect = Rect.Empty; if (!Flipped) //isolate them at the beginning { textBounds = myTextLine.GetTextBounds(0, anchorString.Length); } else { //isolate them at the end var start = myTextLine.Length - 1 - anchorString.Length; textBounds = myTextLine.GetTextBounds(start, anchorString.Length); } //add all the bounds together foreach (TextBounds anchorBound in textBounds) { firstRect.Union(anchorBound.Rectangle); } //center will be position close to the origin 0,0 Point center = new Point((firstRect.Left + firstRect.Right) / 2, (firstRect.Top + firstRect.Bottom) / 2); //the displacement vector will be added to each relative coordinate for the glyph run var displacementVector = location - center; //locus is where the text line is drawn var locus = new Point(0, 0) + displacementVector; textBounds = myTextLine.GetTextBounds(0, 999); var obb = textBounds[0].Rectangle; //draw the line of text using (DrawingContext dc = RenderOpen()) { myTextLine.Draw(dc, locus, InvertAxes.None); #if DEBUG #if SHOWBOUNDS obb.Offset(new Vector(locus.X, locus.Y)); dc.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.BlueViolet), 1.0), obb); #endif #endif var glyphRuns = myTextLine.GetIndexedGlyphRuns(); List <Point> outline = new List <Point>(); double advanceWidths = 0d; //build up the convex hull from each glyph //you need to add in the advance widths for each //glyph run as they are traversed, //to the outline foreach (IndexedGlyphRun igr in glyphRuns) { var originalRun = textStore.GetTextRun(igr.TextSourceCharacterIndex); var currentRun = igr.GlyphRun; //need to work out how much the current run has been offset from the baseline var runBounds = myTextLine.GetTextBounds(igr.TextSourceCharacterIndex, igr.TextSourceLength); //get the bounding rect var rect = runBounds[0].TextRunBounds[0].Rectangle; //it's relative to the baseline //adjust it rect.Offset(new Vector(locus.X, locus.Y)); var rectCopy = rect; #if DEBUG #if SHOWBOUNDS dc.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.DarkOrange), 1.0), rect); #endif #endif var runOutline = GlyphUtils.GetOutline(currentRun); //need to see if the run has been super or sub-scripted var variants = originalRun.Properties.TypographyProperties.Variants; if (variants == FontVariants.Subscript || variants == FontVariants.Superscript) { //simply union in the rect -it's easier! outline.AddRange(new[] { rectCopy.BottomLeft, rectCopy.BottomRight, rectCopy.TopLeft, rectCopy.TopRight }); } else { //add in the points from the convex hull for (int i = 0; i < runOutline.Count; i++) { var point = runOutline[i] + displacementVector + new Vector(0.0, myTextLine.Baseline); point.X += advanceWidths; runOutline[i] = point; } outline.AddRange(runOutline); } advanceWidths += currentRun.AdvanceWidths.Sum(); } _sortedOutline = (from Point p in outline orderby p.X ascending, p.Y descending select p).ToList(); Hull = Geometry <Point> .GetHull(_sortedOutline, p => p); // Diag: Show Hulls or Atom centres #if DEBUG #if SHOWHULLS dc.DrawGeometry(null, new Pen(Brushes.GreenYellow, thickness: 1), HullGeometry); #endif #if SHOWATOMCENTRES dc.DrawEllipse(Brushes.Red, null, ParentAtom.Position, 5, 5); #endif #endif // End Diag dc.Close(); } } } }
/// <summary> /// When overridden in a derived class, participates in rendering operations that are directed by the layout system. /// The rendering instructions for this element are not used directly when this method is invoked, /// and are instead preserved for later asynchronous use by layout and drawing. /// </summary> /// <param name="drawingContext">The drawing instructions for a specific element. This context is provided to the layout system.</param> protected override void OnRender([NotNull] DrawingContext drawingContext) { Assert.ArgumentNotNull(drawingContext, "drawingContext"); try { if (Visibility != Visibility.Visible) { return; } drawingContext.DrawRectangle(Themes.ThemeManager.Instance.ActiveTheme.GetBrushByTextColor(Themes.TextColor.None, true), new Pen(Themes.ThemeManager.Instance.ActiveTheme.GetBrushByTextColor(Themes.TextColor.None, true), 0), new Rect(0, 0, ActualWidth, ActualHeight)); var renderedLines = 0; if (_selectionSettings.NeedUpdate) { _tempSelectionSettings.SelectedMessages.Clear(); } if (_messages.Count > 0) { var currentHeight = ActualHeight; var lineNumber = _currentLineNumber; while (currentHeight > 0 && lineNumber > 0) { _textSource.Message = _messages[lineNumber - 1]; var textStorePosition = 0; _linesToRenderStack.Clear(); do { var line = _formatter.FormatLine(_textSource, textStorePosition, ActualWidth, _customTextParagraphProperties, null, _textRunCache); _linesToRenderStack.Push(line); textStorePosition += line.Length; }while (textStorePosition < _messages[lineNumber - 1].InnerText.Length); var drawnChars = 0; bool messageSelected = false; while (_linesToRenderStack.Count > 0) { var line = _linesToRenderStack.Pop(); line.Draw(drawingContext, new Point(0, currentHeight - line.Height), InvertAxes.None); _lineHeight = line.Height; drawnChars += line.Length; if (_selectionSettings.NeedUpdate) { messageSelected = ProcessLineForSelection(line, _messages[lineNumber - 1], currentHeight, drawnChars, messageSelected); } currentHeight -= line.Height; line.Dispose(); } renderedLines++; lineNumber--; _textRunCache.Invalidate(); } } _currentNumberOfLinesInView = renderedLines; if (_selectionSettings.NeedUpdate) { _selectionSettings.SelectionEndCharacterNumber = _tempSelectionSettings.SelectionEndCharacterNumber; _selectionSettings.SelectionStartCharacterNumber = _tempSelectionSettings.SelectionStartCharacterNumber; _selectionSettings.SelectedMessages.Clear(); _selectionSettings.SelectedMessages.AddRange(_tempSelectionSettings.SelectedMessages); _selectionSettings.NeedUpdate = false; InvalidateVisual(); } } catch (Exception ex) { _selectionSettings.NeedUpdate = false; _textRunCache.Invalidate(); ClearTextSelection(); ErrorLogger.Instance.Write(string.Format("Error rendering text {0}", ex)); } }
public Collection <IFormattedLine> FormatLineInVisualBuffer(ITextSnapshotLine visualLine) { if (visualLine == null) { throw new ArgumentNullException(nameof(visualLine)); } if (visualLine.Snapshot != TopTextSnapshot) { throw new ArgumentException(); } var seqColl = TextAndAdornmentSequencer.CreateTextAndAdornmentCollection(visualLine, visualLine.Snapshot); var bufferLine = GetBufferLine(seqColl); var linePartsCollection = CreateLinePartsCollection(seqColl, bufferLine.ExtentIncludingLineBreak); var textSource = new LinePartsTextSource(linePartsCollection); var lines = new Collection <IFormattedLine>(); TextLineBreak previousLineBreak = null; double autoIndent = BaseIndentation; int column = 0; for (int lineSegment = 0; ; lineSegment++) { var paragraphProperties = textParagraphPropertiesFactoryService?.Create(this, classificationFormatMap.DefaultTextProperties, TextAndAdornmentSequencer.BufferGraph.CreateMappingSpan(bufferLine.Extent, SpanTrackingMode.EdgeNegative), TextAndAdornmentSequencer.BufferGraph.CreateMappingPoint(textSource.ConvertColumnToBufferPosition(column), PointTrackingMode.Negative), lineSegment) ?? defaultTextParagraphProperties; double paragraphWidth = WordWrapWidth == 0 ? 0 : Math.Max(1, WordWrapWidth - autoIndent - wrapGlyphWidth); textSource.SetMaxLineLength(MAX_LINE_LENGTH); var textLine = textFormatter.FormatLine(textSource, column, paragraphWidth, paragraphProperties, previousLineBreak); int startColumn = column; int length = textLine.GetLength(textSource.EndOfLine); column += length; var startPos = textSource.ConvertColumnToBufferPosition(startColumn); var endPos = textSource.ConvertColumnToBufferPosition(column); if (column >= textSource.Length) { endPos = bufferLine.ExtentIncludingLineBreak.End; } var lineSpan = new SnapshotSpan(startPos, endPos); var wpfLine = new WpfTextViewLine(TextAndAdornmentSequencer.BufferGraph, linePartsCollection, startColumn, column, bufferLine, lineSpan, visualLine.Snapshot, textLine, autoIndent, ColumnWidth); lines.Add(wpfLine); if (column >= textSource.Length) { Debug.Assert(column == textSource.Length); break; } if (startColumn == column) { throw new InvalidOperationException(); } if (lineSegment == 0) { autoIndent = 0; var firstCharColumn = textSource.GetColumnOfFirstNonWhitespace(); if (firstCharColumn < column) { autoIndent += textLine.GetDistanceFromCharacterHit(new CharacterHit(firstCharColumn, 0)); } autoIndent += TabSize / 2 * ColumnWidth; if (autoIndent > MaxAutoIndent) { autoIndent = MaxAutoIndent; } // Base indentation should always be included autoIndent += BaseIndentation; } previousLineBreak = textLine.GetTextLineBreak(); } return(lines); }
protected void InvalidateText() { if (Core == null || Core.IsDisposed) { return; } ITextZone zonebackground = null; ITextZone zoneforeground = null; ITextZone zonefontweight = null; ITextZone zonefontfamily = null; ITextZone zonefontstyle = null; ITextZone zonefontstretch = null; ITextZone zonefontsize = null; ITextItem item = Core.Start.Item; textbuilder.Clear(); fontindics.Clear(); this.skipzone = null; this.skipzonestart = -1; this.openzone = null; this.closezone = null; this.intozone = null; void _FindAllZone(ITextItem startitem) { for (ITextZone zone = startitem.Parent; zone != null; zone = zone.Parent) { if (!(zone.Doc is IDocsFill)) { continue; } IDocsFill doc = (IDocsFill)(zone.Doc); if (doc.Fill == null) { continue; } if (zonebackground == null && doc.Fill.Background != null) { zonebackground = zone; } if (zoneforeground == null && doc.Fill.Foreground != null) { zoneforeground = zone; } if (zonefontweight == null && doc.Fill.FontWeight != null) { zonefontweight = zone; } if (zonefontfamily == null && doc.Fill.FontFamily != null) { zonefontfamily = zone; } if (zonefontstyle == null && doc.Fill.FontStyle != null) { zonefontstyle = zone; } if (zonefontstretch == null && doc.Fill.FontStretch != null) { zonefontstretch = zone; } if (zonefontsize == null && doc.Fill.FontSize != null) { zonefontsize = zone; } if (zonebackground == null) { continue; } if (zoneforeground == null) { continue; } if (zonefontweight == null) { continue; } if (zonefontfamily == null) { continue; } if (zonefontstyle == null) { continue; } if (zonefontsize == null) { continue; } if (zonefontstretch == null) { continue; } break; } } void _RefindAllZone(ITextItem startitem) { zonebackground = null; zoneforeground = null; zonefontweight = null; zonefontfamily = null; zonefontstyle = null; zonefontsize = null; zonefontstretch = null; _FindAllZone(startitem); } void _AppendText(ITextItem additem, string addtext) { FontFamily fontfamily = TextCore.FontFamily; FontStyle fontstyle = TextCore.FontStyle; FontStretch fontstretch = TextCore.FontStretch; FontWeight fontweight = TextCore.FontWeight; double fontsize = TextCore.FontSize; Brush background = null; Brush foreground = TextCore.Foreground; if (additem.Doc is IDocsFill) { IDocsFill doc = (IDocsFill)(additem.Doc); if (doc.Fill != null) { if (doc.Fill.FontFamily != null) { fontfamily = doc.Fill.FontFamily; } if (doc.Fill.FontStyle != null) { fontstyle = doc.Fill.FontStyle.Value; } if (doc.Fill.FontWeight != null) { fontweight = doc.Fill.FontWeight.Value; } if (doc.Fill.FontStretch != null) { fontstretch = doc.Fill.FontStretch.Value; } if (doc.Fill.FontSize != null) { fontsize = doc.Fill.FontSize.Value; } if (doc.Fill.Background != null) { background = new SolidColorBrush(doc.Fill.Background.Value); } if (doc.Fill.Foreground != null) { foreground = new SolidColorBrush(doc.Fill.Foreground.Value); } } } if (zonefontfamily?.Doc is IDocsFill) { fontfamily = ((IDocsFill)(zonefontfamily.Doc)).Fill.FontFamily; } if (zonefontstyle?.Doc is IDocsFill) { fontstyle = ((IDocsFill)(zonefontstyle.Doc)).Fill.FontStyle.Value; } if (zonefontweight?.Doc is IDocsFill) { fontweight = ((IDocsFill)(zonefontweight.Doc)).Fill.FontWeight.Value; } if (zonefontstretch?.Doc is IDocsFill) { fontstretch = ((IDocsFill)(zonefontstretch.Doc)).Fill.FontStretch.Value; } if (zonefontsize?.Doc is IDocsFill) { fontsize = ((IDocsFill)(zonefontsize.Doc)).Fill.FontSize.Value; } if (zonebackground?.Doc is IDocsFill) { background = new SolidColorBrush(((IDocsFill)(zonebackground.Doc)).Fill.Background.Value); } if (zoneforeground?.Doc is IDocsFill) { foreground = new SolidColorBrush(((IDocsFill)(zoneforeground.Doc)).Fill.Foreground.Value); } fontindics.Add(new TextFontIndex(new TextFontCore(fontstyle, fontstretch, fontfamily, fontweight, fontsize, background, foreground), textbuilder.Length)); textbuilder.Append(addtext); } void _AppendSkipZone(ITextZone skipzone) { FontFamily fontfamily = TextCore.FontFamily; FontStyle fontstyle = TextCore.FontStyle; FontStretch fontstretch = TextCore.FontStretch; FontWeight fontweight = TextCore.FontWeight; double fontsize = TextCore.FontSize; Brush background = null; Brush foreground = Brushes.Gray; TextCore.DictBrush.TryGetValue("foreground_skipzone", out foreground); skipzonestart = textbuilder.Length; skipzonecount = 3; fontindics.Add(new TextFontIndex(new TextFontCore(fontstyle, fontstretch, fontfamily, fontweight, fontsize, background, foreground), textbuilder.Length)); int showstart = 0; int showend = 0; if (TextCore.View.Counselor != null) { string zonename = skipzone?.Doc?.Name ?? "{zone_deault}"; MRATextInputContext ictx = new MRATextInputContext(skipzone, 0, 0); MRAZoneContext zctx = new MRAZoneContext(zonename, ictx, MRAZoneAction.Skip); IMRAZoneResult zret = TextCore.View.Counselor.ZoneAction(zctx); if (zret is IMRAZoneSkipResult) { IMRAZoneSkipResult zsret = (IMRAZoneSkipResult)zret; showstart = zsret.ShowStart; showend = zsret.ShowEnd; } } for (int i = 0; i < Math.Min(showstart, skipzone.Items.Count); i++) { textbuilder.Append(skipzone.Items[i].ToString()); } textbuilder.Append("..."); for (int i = Math.Max(0, skipzone.Items.Count - showend); i < skipzone.Items.Count; i++) { textbuilder.Append(skipzone.Items[i].ToString()); } } void _RemoveZone(ITextItem zone) { if (item == zonebackground) { zonebackground = null; } if (item == zoneforeground) { zoneforeground = null; } if (item == zonefontweight) { zonefontweight = null; } if (item == zonefontfamily) { zonefontfamily = null; } if (item == zonefontstyle) { zonefontstyle = null; } if (item == zonefontstretch) { zonefontstretch = null; } if (item == zonefontsize) { zonefontstretch = null; } } void _AddZone(ITextZone zone) { if (zone.Doc is IDocsFill) { IDocsFill doc = (IDocsFill)(zone.Doc); if (doc.Fill != null) { if (doc.Fill.Background != null) { zonebackground = zone; } if (doc.Fill.Foreground != null) { zoneforeground = zone; } if (doc.Fill.FontWeight != null) { zonefontweight = zone; } if (doc.Fill.FontFamily != null) { zonefontfamily = zone; } if (doc.Fill.FontStyle != null) { zonefontstyle = zone; } if (doc.Fill.FontStretch != null) { zonefontstretch = zone; } if (doc.Fill.FontSize != null) { zonefontsize = zone; } } } } _FindAllZone(item); if (Core.Start != null && Core.End != null) { ITextItem startitem = Core.Start.Item; ITextItem enditem = Core.End.Item; startitem = startitem.Parent; enditem = enditem.Parent; while (startitem.Level > enditem.Level) { startitem = startitem.Parent; } while (startitem.Level < enditem.Level) { enditem = enditem.Parent; } while (startitem != enditem) { startitem = startitem.Parent; enditem = enditem.Parent; } while (startitem?.Parent != null) { if (!(startitem is ITextLine) && ((ITextZone)startitem).LineCount > 1) { this.intozone = (ITextZone)startitem; break; } startitem = startitem.Parent; } } { ITextItem startitem = Core.Start.Item; ITextItem enditem = Core.End.Item; if (startitem.ID == 0 && !(startitem.Parent is ITextLine) && !(startitem.Parent is ITextBoxCore) && startitem.Parent.LineCount > 1) { this.openzone = startitem.Parent; } if (enditem.ID == enditem.Parent.Items.Count - 1 && !(enditem.Parent is ITextLine) && !(enditem.Parent is ITextBoxCore) && enditem.Parent.LineCount > 1) { this.closezone = enditem.Parent; } } if (Core.Start.Item == Core.End.Item) { string text = Core.Start.RightPart.Substring(0, Core.End.ItemIndex - Core.Start.ItemIndex); _AppendText(Core.Start.Item, text); } else if (Core is IMRAZoneSkipInfo) { IMRAZoneSkipInfo zscore = (IMRAZoneSkipInfo)Core; this.skipzone = zscore.SkipZone; if (Core.Start.Item.Parent != zscore.SkipZone) { _AppendText(Core.Start.Item, Core.Start.RightPart); while (item != null && item != Core.End.Item) { while (item?.Parent != null && item.ID + 1 >= item.Parent.Items.Count) { item = item.Parent; ITextZone zone = (ITextZone)item; if (!(zone is ITextLine) && zone.LineCount > 1) { this.closezone = zone; } _RemoveZone(item); } if (item?.Parent == null) { break; } item = item.Parent.Items[item.ID + 1]; _FindAllZone(item); while (item is ITextZone) { ITextZone zone = (ITextZone)item; if (zone == zscore.SkipZone) { break; } _AddZone(zone); item = zone.Items.FirstOrDefault(); } if (item == zscore.SkipZone) { break; } _AppendText(item, item.ToString()); } } _AppendSkipZone(zscore.SkipZone); if (Core.End.Item.Parent != zscore.SkipZone) { item = zscore.SkipZone; _RefindAllZone(item); while (item != null && item != Core.End.Item) { while (item?.Parent != null && item.ID + 1 >= item.Parent.Items.Count) { item = item.Parent; _RemoveZone(item); } if (item?.Parent == null) { break; } item = item.Parent.Items[item.ID + 1]; _FindAllZone(item); while (item is ITextZone) { ITextZone zone = (ITextZone)item; if (!(zone is ITextLine) && zone.LineCount > 1) { this.openzone = zone; } _AddZone(zone); item = zone.Items.FirstOrDefault(); } _AppendText(item, item.ToString()); } _AppendText(Core.End.Item, Core.End.LeftPart); } } else { _AppendText(Core.Start.Item, Core.Start.RightPart); while (item != null && item != Core.End.Item) { while (item?.Parent != null && item.ID + 1 >= item.Parent.Items.Count) { item = item.Parent; ITextZone zone = (ITextZone)item; if (!(zone is ITextLine) && zone.LineCount > 1) { this.closezone = zone; if (intozone == null || zone.Level < intozone.Level) { this.intozone = zone; } } _RemoveZone(item); } if (item?.Parent == null) { break; } item = item.Parent.Items[item.ID + 1]; _FindAllZone(item); while (item is ITextZone) { ITextZone zone = (ITextZone)item; if (!(zone is ITextLine) && zone.LineCount > 1) { this.openzone = zone; if (intozone == null || zone.Level < intozone.Level) { this.intozone = zone; } } _AddZone(zone); item = zone.Items.FirstOrDefault(); } if (item == Core.End.Item) { break; } _AppendText(item, item.ToString()); } _AppendText(Core.End.Item, Core.End.LeftPart); } this.textsource = new MRATextSource(textbuilder.ToString(), fontindics); this.textline = textfmtr.FormatLine(textsource, 0, 10000.0, new MRATextParagraphProperties(TextCore, textsource), null); }
protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); Rect rect = new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight); JapaneseTextSource source = new JapaneseTextSource(); source.Text = this.Text; JapaneseTextParagraphProperties textParagraphProperties = this.MakeTextProperties(); source.JapaneseTextRunProperties = (JapaneseTextRunProperties)textParagraphProperties.DefaultTextRunProperties; source.IsVarticalWriting = textParagraphProperties.IsVerticalWriting; if (textParagraphProperties.DefaultTextRunProperties.BackgroundBrush != null) { drawingContext.DrawRectangle(textParagraphProperties.DefaultTextRunProperties.BackgroundBrush, null, rect); } Rect paddingRect = new Rect(this.Padding.Left, this.Padding.Top, Math.Max(0.0, base.ActualWidth - this.Padding.Left - this.Padding.Right), Math.Max(0.0, base.ActualHeight - this.Padding.Top - this.Padding.Bottom)); Point center = new Point((paddingRect.Left + paddingRect.Right) / 2.0, (paddingRect.Top + paddingRect.Bottom) / 2.0); Point startPosition; double paragraphWidth; if (textParagraphProperties.IsVerticalWriting) { Point origin = paddingRect.TopRight; Transform transOrigin = new RotateTransform(-90.0, center.X, center.Y); startPosition = transOrigin.Transform(origin); paragraphWidth = Math.Abs(paddingRect.Height); Transform trans = new RotateTransform(90.0, center.X, center.Y); drawingContext.PushTransform(trans); } else { startPosition = paddingRect.TopLeft; paragraphWidth = Math.Abs(paddingRect.Width); } startPosition.Y += textParagraphProperties.JapaneseTextRunProperties.FontRenderingEmSize; int textStorePosition = 0; Point linePosition = startPosition; TextFormatter formatter = TextFormatter.Create(); while (textStorePosition < source.Text.Length) { using (TextLine textLine = formatter.FormatLine(source, textStorePosition, paragraphWidth, textParagraphProperties, null)) { foreach (IndexedGlyphRun indexedrun in textLine.GetIndexedGlyphRuns()) { if (textParagraphProperties.IsVerticalWriting) { source.UniscribeIndexedGlyphRun(indexedrun); Rect runRect; if (source.GlyphCount != 0 && source.Glyphs[0] != 0) { Point ansiLinePosition = linePosition; ansiLinePosition.Y -= textParagraphProperties.JapaneseTextRunProperties.FontRenderingEmSize / 2.0; runRect = this.DrawIndexedGlyphRun(drawingContext, indexedrun, ansiLinePosition, source, true); } else { Point ansiLinePosition = linePosition; ansiLinePosition.Y -= textParagraphProperties.JapaneseTextRunProperties.FontRenderingEmSize / 10.0; runRect = this.DrawIndexedGlyphRun(drawingContext, indexedrun, ansiLinePosition, source, false); } linePosition.X += runRect.Width; } else { Rect runRect = this.DrawIndexedGlyphRun(drawingContext, indexedrun, linePosition, source, false); linePosition.X += runRect.Width; } } textStorePosition += textLine.Length; linePosition.X = startPosition.X; linePosition.Y += textLine.Height; } } if (textParagraphProperties.IsVerticalWriting) { drawingContext.Pop(); } }