Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Text / Line.cs / 1 / Line.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: Line.cs // // Description: Text line formatter. // // History: // 04/25/2003 : [....] - moving from Avalon branch. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.PtsHost; namespace MS.Internal.Text { // --------------------------------------------------------------------- // Text line formatter. // --------------------------------------------------------------------- internal abstract class Line : TextSource, IDisposable { // ------------------------------------------------------------------ // // IDisposable Implementation // // ----------------------------------------------------------------- #region IDisposable Implementation // ------------------------------------------------------------------ // Free all resources associated with the line. Prepare it for reuse. // ------------------------------------------------------------------ public void Dispose() { // Dispose text line if (_line != null) { _line.Dispose(); _line = null; } } #endregion IDisposable Implementation //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods // ----------------------------------------------------------------- // Constructor. // // owner - owner of the line. // ----------------------------------------------------------------- internal Line(System.Windows.Controls.TextBlock owner) { _owner = owner; _textAlignment = owner.TextAlignment; _showParagraphEllipsis = false; _wrappingWidth = _owner.RenderSize.Width; } // ----------------------------------------------------------------- // 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); } // ----------------------------------------------------------------- // Arrange content of formatted line. // // vc - Visual collection of the parent. // lineOffset - Offset of the line. // ------------------------------------------------------------------ internal virtual void Arrange(VisualCollection vc, Vector lineOffset) { } // ------------------------------------------------------------------ // Render formatted line. // // ctx - Drawing context to be used for rendering. // lineOffset - Offset of the line. // wrappingWidth - Wrapping width for the line. // ----------------------------------------------------------------- internal void Render(DrawingContext ctx, Point lineOffset) { Debug.Assert(_line != null, "Rendering line that has not been measured yet."); // Handle text trimming. System.Windows.Media.TextFormatting.TextLine line = _line; if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Debug.Assert(line.HasCollapsed, "Line has not been collapsed"); } double delta = CalculateXOffsetShift(); line.Draw(ctx, new Point(lineOffset.X + delta, lineOffset.Y), (_mirror ? InvertAxes.Horizontal : InvertAxes.None)); } // ------------------------------------------------------------------ // Retrieve bounds of an object/character at specified text position. // // characterIndex - position of an object/character // flowDirection - flow direction of object/character // // Returns: Bounds of an object/character. // ----------------------------------------------------------------- internal Rect GetBoundsFromTextPosition(int characterIndex, out FlowDirection flowDirection) { return GetBoundsFromPosition(characterIndex, 1, out flowDirection); } ////// Returns an ArrayList of rectangles (Rect) that form the bounds of the region specified between /// the start and end points /// /// /// int offset indicating the starting point of the region for which bounds are required /// /// Length in characters of the region for which bounds are required /// /// /// Offset of line in x direction, to be added to line bounds to get actual rectangle for line /// /// /// Offset of line in y direction, to be added to line bounds to get actual rectangle for line /// ////// This function calls GetTextBounds for the line, and then checks if there are text run bounds. If they exist, /// it uses those as the bounding rectangles. If not, it returns the rectangle for the first (and only) element /// of the text bounds. /// internal ListGetRangeBounds(int cp, int cch, double xOffset, double yOffset) { List rectangles = new List (); // Adjust x offset for trailing spaces double delta = CalculateXOffsetShift(); double adjustedXOffset = xOffset + delta; IList textBounds; if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { // We should not shift offset in this case Invariant.Assert(DoubleUtil.AreClose(delta, 0)); System.Windows.Media.TextFormatting.TextLine line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); textBounds = line.GetTextBounds(cp, cch); } else { textBounds = _line.GetTextBounds(cp, cch); } Invariant.Assert(textBounds.Count > 0); for (int boundIndex = 0; boundIndex < textBounds.Count; boundIndex++) { Rect rect = textBounds[boundIndex].Rectangle; rect.X += adjustedXOffset; rect.Y += yOffset; rectangles.Add(rect); } return rectangles; } //------------------------------------------------------------------- // Retrieve text position index from the distance. // // distance - distance relative to the beginning of the line // // Returns: Text position index. //------------------------------------------------------------------- internal CharacterHit GetTextPositionFromDistance(double distance) { // Adjust distance to account for a line shift due to rendering of trailing spaces double delta = CalculateXOffsetShift(); if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { System.Windows.Media.TextFormatting.TextLine line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Invariant.Assert(DoubleUtil.AreClose(delta, 0)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); return line.GetCharacterHitFromDistance(distance); } return _line.GetCharacterHitFromDistance(distance - delta); } //-------------------------------------------------------------------- // Retrieve text position for next caret position // // index: CharacterHit for current position // // Returns: Text position index. //------------------------------------------------------------------- internal CharacterHit GetNextCaretCharacterHit(CharacterHit index) { return _line.GetNextCaretCharacterHit(index); } //-------------------------------------------------------------------- // Retrieve text position for previous caret position // // index: CharacterHit for current position // // Returns: Text position index. //-------------------------------------------------------------------- internal CharacterHit GetPreviousCaretCharacterHit(CharacterHit index) { return _line.GetPreviousCaretCharacterHit(index); } //------------------------------------------------------------------- // Retrieve text position for backspace caret position // // index: CharacterHit for current position // // Returns: Text position index. //-------------------------------------------------------------------- internal CharacterHit GetBackspaceCaretCharacterHit(CharacterHit index) { return _line.GetBackspaceCaretCharacterHit(index); } /// /// Returns true of char hit is at caret unit boundary. /// /// /// CharacterHit to be tested. /// internal bool IsAtCaretCharacterHit(CharacterHit charHit) { return _line.IsAtCaretCharacterHit(charHit, _dcp); } // ----------------------------------------------------------------- // Find out if there are any inline objects. // ----------------------------------------------------------------- internal virtual bool HasInlineObjects() { return false; } // ----------------------------------------------------------------- // Hit tests to the correct ContentElement within the line. // // offset - offset within the line. // // Returns: ContentElement which has been hit. // ------------------------------------------------------------------ internal virtual IInputElement InputHitTest(double offset) { return null; } ////// Passes linebreak object back up from contained line /// internal TextLineBreak GetTextLineBreak() { if(_line == null) { return null; } return _line.GetTextLineBreak(); } // ----------------------------------------------------------------- // Get length of content hidden by ellipses. // // wrappingWidth - Wrapping width for the line. // // Returns: Length of collapsed content (number of characters hidden // by ellipses). // ------------------------------------------------------------------ internal int GetEllipsesLength() { // There are no ellipses, if: // * there is no overflow in the line // * text trimming is turned off if (!_line.HasOverflowed) { return 0; } if (_owner.ParagraphProperties.TextTrimming == TextTrimming.None) { return 0; } // Create collapsed text line to get length of collapsed content. System.Windows.Media.TextFormatting.TextLine collapsedLine = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Debug.Assert(collapsedLine.HasCollapsed, "Line has not been collapsed"); IListcollapsedRanges = collapsedLine.GetTextCollapsedRanges(); if (collapsedRanges != null) { Debug.Assert(collapsedRanges.Count == 1, "Multiple collapsed ranges are not supported."); TextCollapsedRange collapsedRange = collapsedRanges[0]; return collapsedRange.Length; } return 0; } // ------------------------------------------------------------------ // Gets width of content, collapsed at wrappingWidth (if necessary) // // wrappingWidth - Wrapping width for the line. // // Returns: Width of content, after collapse (may be greater than wrappingWidth) // // ----------------------------------------------------------------- internal double GetCollapsedWidth() { // There are no ellipses, if: // * there is no overflow in the line // * text trimming is turned off if (!_line.HasOverflowed) { return Width; } if (_owner.ParagraphProperties.TextTrimming == TextTrimming.None) { return Width; } // Create collapsed text line to get length of collapsed content. System.Windows.Media.TextFormatting.TextLine collapsedLine = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Debug.Assert(collapsedLine.HasCollapsed, "Line has not been collapsed"); return collapsedLine.Width; } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //------------------------------------------------------------------- #region Internal Properties // ----------------------------------------------------------------- // Calculated width of the line. // ----------------------------------------------------------------- internal double Width { get { if (IsWidthAdjusted) { // Trailing spaces add to width return _line.WidthIncludingTrailingWhitespace; } else { return _line.Width; } } } // ------------------------------------------------------------------ // Distance from the beginning of paragraph edge to the line edge. // ----------------------------------------------------------------- internal double Start { get { if (IsXOffsetAdjusted) { return _line.Start + CalculateXOffsetShift(); } else { return _line.Start; } } } // ------------------------------------------------------------------ // Height of the line; line advance distance. // ------------------------------------------------------------------ internal double Height { get { return _line.Height; } } // ----------------------------------------------------------------- // Distance from top to baseline of this text line. // ------------------------------------------------------------------ internal double BaselineOffset { get { return _line.Baseline; } } // ----------------------------------------------------------------- // Is this the last line of the paragraph? // ----------------------------------------------------------------- internal bool EndOfParagraph { get { // If there are no Newline characters, it is not the end of paragraph. if (_line.NewlineLength == 0) { return false; } // Since there are Newline characters in the line, do more expensive and // accurate check. IList > runs = _line.GetTextRunSpans(); return (((TextSpan )runs[runs.Count-1]).Value is TextEndOfParagraph); } } // ----------------------------------------------------------------- // Length of the line excluding any synthetic characters. // ------------------------------------------------------------------ internal int Length { get { return _line.Length - (EndOfParagraph ? _syntheticCharacterLength : 0); } } // ----------------------------------------------------------------- // Length of the line excluding any synthetic characters and line breaks. // ------------------------------------------------------------------ internal int ContentLength { get { return _line.Length - _line.NewlineLength; } } #endregion Internal Properties //-------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods // ------------------------------------------------------------------ // Retrieve bounds of an object/character at specified text index. // // cp - character index of an object/character // cch - number of positions occupied by object/character // flowDirection - flow direction of object/character // // Returns: Bounds of an object/character. // ----------------------------------------------------------------- protected Rect GetBoundsFromPosition(int cp, int cch, out FlowDirection flowDirection) { Rect rect; // Adjust x offset for trailing spaces double delta = CalculateXOffsetShift(); IList textBounds; if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { // We should not shift offset in this case Invariant.Assert(DoubleUtil.AreClose(delta, 0)); System.Windows.Media.TextFormatting.TextLine line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); textBounds = line.GetTextBounds(cp, cch); } else { textBounds = _line.GetTextBounds(cp, cch); } Invariant.Assert(textBounds != null && textBounds.Count == 1, "Expecting exactly one TextBounds for a single text position."); IList runBounds = textBounds[0].TextRunBounds; if (runBounds != null) { Debug.Assert(runBounds.Count == 1, "Expecting exactly one TextRunBounds for a single text position."); rect = runBounds[0].Rectangle; } else { rect = textBounds[0].Rectangle; } rect.X += delta; flowDirection = textBounds[0].FlowDirection; return rect; } // ----------------------------------------------------------------- // Get collapsing properties. // // wrappingWidth - wrapping width for collapsed line. // paraProperties - paragraph properties. // // Returns: Line collapsing properties. // ----------------------------------------------------------------- protected TextCollapsingProperties GetCollapsingProps(double wrappingWidth, LineProperties paraProperties) { Debug.Assert(paraProperties.TextTrimming != TextTrimming.None, "Text trimming must be enabled."); TextCollapsingProperties collapsingProps; if (paraProperties.TextTrimming == TextTrimming.CharacterEllipsis) { collapsingProps = new TextTrailingCharacterEllipsis(wrappingWidth, paraProperties.DefaultTextRunProperties); } else { collapsingProps = new TextTrailingWordEllipsis(wrappingWidth, paraProperties.DefaultTextRunProperties); } return collapsingProps; } /// /// Returns amount of shift for X-offset to render trailing spaces /// protected double CalculateXOffsetShift() { // Assert that textblock autosize is working correctly and that moving the offset back // will not result in the front of the line being taken off rendered area if (IsXOffsetAdjusted) { if (_textAlignment == TextAlignment.Center) { // Return trailing spaces length divided by two so line remains centered return (_line.Width - _line.WidthIncludingTrailingWhitespace) / 2; } else { return (_line.Width - _line.WidthIncludingTrailingWhitespace); } } else { return 0.0; } } #endregion Protected Methods //-------------------------------------------------------------------- // // Protected Properites // //------------------------------------------------------------------- #region Protected Properties ////// True if eliipsis is displayed in the line /// protected bool ShowEllipsis { get { if (_owner.ParagraphProperties.TextTrimming == TextTrimming.None) { return false; } if (_line.HasOverflowed || _showParagraphEllipsis) { return true; } return false; } } ////// True if line ends in hard line break /// protected bool HasLineBreak { get { return (_line.NewlineLength > 0); } } ////// True if line's X-offset needs adjustment to render trailing spaces /// protected bool IsXOffsetAdjusted { get { return ((_textAlignment == TextAlignment.Right || _textAlignment == TextAlignment.Center) && IsWidthAdjusted); } } ////// True if line's width is adjusted to include trailing spaces. For right and center alignment we need to /// adjust line offset as well, but for left alignment we need to only make a width asjustment /// protected bool IsWidthAdjusted { get { bool adjusted = false; // Trailing spaces rendered only around hard breaks if (HasLineBreak || EndOfParagraph) { // Lines with ellipsis are not shifted because ellipsis would not appear after trailing spaces if (!ShowEllipsis) { adjusted = true; } } return adjusted; } } #endregion Protected Properties //-------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields // ----------------------------------------------------------------- // Owner of the line. // ------------------------------------------------------------------ protected System.Windows.Controls.TextBlock _owner; // ----------------------------------------------------------------- // Cached text line. // ----------------------------------------------------------------- protected System.Windows.Media.TextFormatting.TextLine _line; // ----------------------------------------------------------------- // Index of the first character in the line. // ------------------------------------------------------------------ protected int _dcp; // ----------------------------------------------------------------- // Synthetic character length. // ------------------------------------------------------------------ protected static int _syntheticCharacterLength = 1; // ------------------------------------------------------------------ // Is text mirrored? // ----------------------------------------------------------------- protected bool _mirror; ////// Alignment direction of line. Set during formatting. /// protected TextAlignment _textAlignment; ////// Does the line habe paragraph ellipsis. This is determined during formatting depending upon /// the type of line properties passed. /// protected bool _showParagraphEllipsis; ////// Wrapping width of line /// protected double _wrappingWidth; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TypeInitializationException.cs
- WaitHandleCannotBeOpenedException.cs
- ServiceModelConfiguration.cs
- ParentQuery.cs
- DesignBindingPicker.cs
- TextProperties.cs
- RegularExpressionValidator.cs
- GridLength.cs
- Pts.cs
- HitTestDrawingContextWalker.cs
- SimpleType.cs
- SchemaMerger.cs
- KeyInterop.cs
- ActivityDefaults.cs
- StorageMappingFragment.cs
- EpmHelper.cs
- Group.cs
- TypeInfo.cs
- XsdDuration.cs
- ChannelBinding.cs
- Pen.cs
- ChangeBlockUndoRecord.cs
- Point4D.cs
- ReachSerializer.cs
- WinInet.cs
- Color.cs
- Image.cs
- LoginUtil.cs
- ToolStripDropDownItem.cs
- StatusBarAutomationPeer.cs
- XmlSerializerFactory.cs
- BeginSelectCardRequest.cs
- HScrollProperties.cs
- RootBrowserWindow.cs
- ResourceSet.cs
- FileDialog_Vista.cs
- ResourceSetExpression.cs
- ArrayTypeMismatchException.cs
- TextCharacters.cs
- InstancePersistence.cs
- TextRangeEditTables.cs
- RTLAwareMessageBox.cs
- RuntimeWrappedException.cs
- SequentialOutput.cs
- SeverityFilter.cs
- URI.cs
- X509SecurityTokenAuthenticator.cs
- CapabilitiesPattern.cs
- RenderDataDrawingContext.cs
- OutKeywords.cs
- MsmqIntegrationSecurity.cs
- ToolStripDropDownButton.cs
- Converter.cs
- QEncodedStream.cs
- WorkflowLayouts.cs
- SignatureToken.cs
- MsmqHostedTransportManager.cs
- DrawingServices.cs
- MILUtilities.cs
- ProgressChangedEventArgs.cs
- CompilerGlobalScopeAttribute.cs
- MergePropertyDescriptor.cs
- ResXFileRef.cs
- DocumentPageHost.cs
- XamlSerializer.cs
- TypeDescriptionProviderAttribute.cs
- odbcmetadatacolumnnames.cs
- PerfService.cs
- SqlVisitor.cs
- ToolboxCategoryItems.cs
- DropDownList.cs
- BitmapEffectvisualstate.cs
- DetailsViewCommandEventArgs.cs
- InstanceStoreQueryResult.cs
- MethodBuilderInstantiation.cs
- TableChangeProcessor.cs
- WithParamAction.cs
- InstanceHandle.cs
- BinaryConverter.cs
- OdbcConnectionFactory.cs
- TextTreeTextNode.cs
- MediaTimeline.cs
- BrowserDefinitionCollection.cs
- NotifyCollectionChangedEventArgs.cs
- VersionedStreamOwner.cs
- securestring.cs
- Rotation3D.cs
- OleAutBinder.cs
- PathGradientBrush.cs
- HttpPostClientProtocol.cs
- CalendarDayButton.cs
- RangeValidator.cs
- SelectionEditingBehavior.cs
- NativeMethods.cs
- StylusPointProperties.cs
- SystemGatewayIPAddressInformation.cs
- GetFileNameResult.cs
- StorageEntityTypeMapping.cs
- DataGridViewCellStateChangedEventArgs.cs
- EncryptedPackageFilter.cs