/// <summary> /// Create and return visual node for the line. /// </summary> internal ContainerVisual CreateVisual() { LineVisual visual = new LineVisual(); // Set up the text source for rendering callback _host.Context = this; try { // Handle text trimming. IList<TextSpan<TextRun>> runs = _runs; System.Windows.Media.TextFormatting.TextLine line = _line; if (_line.HasOverflowed && TextParagraph.Properties.TextTrimming != TextTrimming.None) { line = _line.Collapse(GetCollapsingProps(_wrappingWidth, TextParagraph.Properties)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); runs = line.GetTextRunSpans(); } // Add visuals for all embedded elements. if (HasInlineObjects()) { VisualCollection visualChildren = visual.Children; // Get flow direction of the paragraph element. DependencyObject paragraphElement = _paraClient.Paragraph.Element; FlowDirection paragraphFlowDirection = (FlowDirection)paragraphElement.GetValue(FrameworkElement.FlowDirectionProperty); // Before text rendering, add all visuals for inline objects. int dcpRun = _dcp; // Enumerate through all runs in the current line and connect visuals for all inline objects. foreach (TextSpan<TextRun> textSpan in runs) { TextRun run = (TextRun)textSpan.Value; if (run is InlineObjectRun) { InlineObjectRun inlineObject = (InlineObjectRun)run; FlowDirection flowDirection; Rect rect = GetBoundsFromPosition(dcpRun, run.Length, out flowDirection); Debug.Assert(DoubleUtil.GreaterThanOrClose(rect.Width, 0), "Negative inline object's width."); // Disconnect visual from its old parent, if necessary. Visual currentParent = VisualTreeHelper.GetParent(inlineObject.UIElementIsland) as Visual; if (currentParent != null) { ContainerVisual parent = currentParent as ContainerVisual; Invariant.Assert(parent != null, "Parent should always derives from ContainerVisual."); parent.Children.Remove(inlineObject.UIElementIsland); } if (!line.HasCollapsed || ((rect.Left + inlineObject.UIElementIsland.Root.DesiredSize.Width) < line.Width)) { // Check parent's FlowDirection to determine if mirroring is needed if (inlineObject.UIElementIsland.Root is FrameworkElement) { DependencyObject parent = ((FrameworkElement)inlineObject.UIElementIsland.Root).Parent; FlowDirection parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty); PtsHelper.UpdateMirroringTransform(paragraphFlowDirection, parentFlowDirection, inlineObject.UIElementIsland, rect.Width); } visualChildren.Add(inlineObject.UIElementIsland); inlineObject.UIElementIsland.Offset = new Vector(rect.Left, rect.Top); } } // 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; } } // Calculate shift in line offset to render trailing spaces or avoid clipping text double delta = TextDpi.FromTextDpi(CalculateUOffsetShift()); DrawingContext ctx = visual.Open(); line.Draw(ctx, new Point(delta, 0), (_mirror ? InvertAxes.Horizontal : InvertAxes.None)); ctx.Close(); visual.WidthIncludingTrailingWhitespace = line.WidthIncludingTrailingWhitespace - _indent; } finally { _host.Context = null; // clear the context } return visual; }
// Token: 0x06006868 RID: 26728 RVA: 0x001D6FA4 File Offset: 0x001D51A4 internal ContainerVisual CreateVisual() { LineVisual lineVisual = new LineVisual(); this._host.Context = this; try { IList <TextSpan <TextRun> > list = this._runs; TextLine textLine = this._line; if (this._line.HasOverflowed && this.TextParagraph.Properties.TextTrimming != TextTrimming.None) { textLine = this._line.Collapse(new TextCollapsingProperties[] { this.GetCollapsingProps(this._wrappingWidth, this.TextParagraph.Properties) }); Invariant.Assert(textLine.HasCollapsed, "Line has not been collapsed"); list = textLine.GetTextRunSpans(); } if (this.HasInlineObjects()) { VisualCollection children = lineVisual.Children; DependencyObject element = this._paraClient.Paragraph.Element; FlowDirection parentFD = (FlowDirection)element.GetValue(FrameworkElement.FlowDirectionProperty); int num = this._dcp; foreach (TextSpan <TextRun> textSpan in list) { TextRun value = textSpan.Value; if (value is InlineObjectRun) { InlineObjectRun inlineObjectRun = (InlineObjectRun)value; FlowDirection flowDirection; Rect boundsFromPosition = this.GetBoundsFromPosition(num, value.Length, out flowDirection); Visual visual = VisualTreeHelper.GetParent(inlineObjectRun.UIElementIsland) as Visual; if (visual != null) { ContainerVisual containerVisual = visual as ContainerVisual; Invariant.Assert(containerVisual != null, "Parent should always derives from ContainerVisual."); containerVisual.Children.Remove(inlineObjectRun.UIElementIsland); } if (!textLine.HasCollapsed || boundsFromPosition.Left + inlineObjectRun.UIElementIsland.Root.DesiredSize.Width < textLine.Width) { if (inlineObjectRun.UIElementIsland.Root is FrameworkElement) { DependencyObject parent = ((FrameworkElement)inlineObjectRun.UIElementIsland.Root).Parent; FlowDirection childFD = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty); PtsHelper.UpdateMirroringTransform(parentFD, childFD, inlineObjectRun.UIElementIsland, boundsFromPosition.Width); } children.Add(inlineObjectRun.UIElementIsland); inlineObjectRun.UIElementIsland.Offset = new Vector(boundsFromPosition.Left, boundsFromPosition.Top); } } num += textSpan.Length; } } double x = TextDpi.FromTextDpi(this.CalculateUOffsetShift()); DrawingContext drawingContext = lineVisual.Open(); textLine.Draw(drawingContext, new Point(x, 0.0), this._mirror ? InvertAxes.Horizontal : InvertAxes.None); drawingContext.Close(); lineVisual.WidthIncludingTrailingWhitespace = textLine.WidthIncludingTrailingWhitespace - this._indent; } finally { this._host.Context = null; } return(lineVisual); }