Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / PtsHost / linebase.cs / 1305600 / linebase.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: LineBase.cs // // Description: Text line formatter. // // History: // 02/07/2005 : ghermann - Split from Line.cs // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.Text; using MS.Internal.Documents; using MS.Internal.PtsHost.UnsafeNativeMethods; #pragma warning disable 1634, 1691 // avoid generating warnings about unknown // message numbers and unknown pragmas for PRESharp contol namespace MS.Internal.PtsHost { internal abstract class LineBase : UnmanagedHandle { internal LineBase(BaseParaClient paraClient) : base(paraClient.PtsContext) { _paraClient = paraClient; } // ----------------------------------------------------------------- // // TextSource Implementation // // ----------------------------------------------------------------- #region TextSource Implementation ////// Get a text run at specified text source position. /// /// /// dcp of specified position relative to start of line /// internal abstract TextRun GetTextRun(int dcp); ////// Get text immediately before specified text source position. /// /// /// dcp of specified position relative to start of line /// internal abstract TextSpanGetPrecedingText(int dcp); /// /// Get Text effect index from text source character index /// /// /// dcp of specified position relative to start of line /// internal abstract int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int dcp); #endregion TextSource Implementation //-------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Fetch the next run at text position. /// /// /// Current position in text array /// ///protected TextRun HandleText(StaticTextPointer position) { DependencyObject element; StaticTextPointer endOfRunPosition; Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text, "TextPointer does not point to characters."); if (position.Parent != null) { element = position.Parent; } else { element = _paraClient.Paragraph.Element; } // Extract the aggregated properties into something that the textrun can use. // TextProperties textProps = new TextProperties(element, position, false /* inline objects */, true /* get background */); // Calculate the end of the run by finding either: // a) the next intersection of highlight ranges, or // b) the natural end of this textrun endOfRunPosition = position.TextContainer.Highlights.GetNextPropertyChangePosition(position, LogicalDirection.Forward); // Clamp the text run at an arbitrary limit, so we don't make // an unbounded allocation. if (position.GetOffsetToPosition(endOfRunPosition) > 4096) { endOfRunPosition = position.CreatePointer(4096); } // Get character buffer for the text run. char[] textBuffer = new char[position.GetOffsetToPosition(endOfRunPosition)]; // Copy characters from text run into buffer. Note the actual number of characters copied, // which may be different than the buffer's length. Buffer length only specifies the maximum // number of characters int charactersCopied = position.GetTextInRun(LogicalDirection.Forward, textBuffer, 0, textBuffer.Length); // Create text run using the actual number of characters copied return new TextCharacters(textBuffer, 0, charactersCopied, textProps); } /// /// Return next TextRun at element edge start position /// /// /// Current position in text array /// protected TextRun HandleElementStartEdge(StaticTextPointer position) { Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge."); // TextRun run = null; TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward); Debug.Assert(element != null, "Cannot use ITextContainer that does not provide TextElement instances."); Invariant.Assert(!(element is Block), "We do not expect any Blocks inside Paragraphs"); // Treat figure and floaters as special hidden runs. if (element is Figure || element is Floater) { // Get the length of the element int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element); // Create special hidden run. run = new FloatingRun(cch, element is Figure); if (element is Figure) { _hasFigures = true; } else { _hasFloaters = true; } } else if (element is LineBreak) { int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element); run = new LineBreakRun(cch, PTS.FSFLRES.fsflrSoftBreak); } else if (element.IsEmpty) { // Empty TextElement should affect line metrics. // TextFormatter does not support this feature right now, so as workaround // TextRun with ZERO WIDTH SPACE is used. TextProperties textProps = new TextProperties(element, position, false /* inline objects */, true /* get background */); char[] textBuffer = new char[_elementEdgeCharacterLength * 2]; // Assert that _elementEdgeCharacterLength is 1 before we use hard-coded indices Invariant.Assert(_elementEdgeCharacterLength == 1, "Expected value of _elementEdgeCharacterLength is 1"); textBuffer[0] = (char)0x200B; textBuffer[1] = (char)0x200B; run = new TextCharacters(textBuffer, 0, textBuffer.Length, textProps); } else { Inline inline = (Inline) element; DependencyObject parent = inline.Parent; FlowDirection inlineFlowDirection = inline.FlowDirection; FlowDirection parentFlowDirection = inlineFlowDirection; TextDecorationCollection inlineTextDecorations = DynamicPropertyReader.GetTextDecorations(inline); if(parent != null) { parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty); } if (inlineFlowDirection != parentFlowDirection) { // Inline's flow direction is different from its parent. Need to create new TextSpanModifier with flow direction if (inlineTextDecorations == null || inlineTextDecorations.Count == 0) { run = new TextSpanModifier( _elementEdgeCharacterLength, null, null, inlineFlowDirection ); } else { run = new TextSpanModifier( _elementEdgeCharacterLength, inlineTextDecorations, inline.Foreground, inlineFlowDirection ); } } else { if (inlineTextDecorations == null || inlineTextDecorations.Count == 0) { run = new TextHidden(_elementEdgeCharacterLength); } else { run = new TextSpanModifier( _elementEdgeCharacterLength, inlineTextDecorations, inline.Foreground ); } } } return run; } ////// Fetch the next run at element end edge position. /// ElementEndEdge; we can have 2 possibilities: /// (1) Close edge of element associated with the text paragraph, /// create synthetic LineBreak run to end the current line. /// (2) End of inline element, hide CloseEdge character and continue /// /// /// Position in current text array protected TextRun HandleElementEndEdge(StaticTextPointer position) { Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge."); TextRun run; if (position.Parent == _paraClient.Paragraph.Element) { // (1) Close edge of element associated with the text paragraph, // create synthetic LineBreak run to end the current line. run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph); } else { TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward); Debug.Assert(element != null, "Element should be here."); Inline inline = (Inline) element; DependencyObject parent = inline.Parent; FlowDirection parentFlowDirection = inline.FlowDirection; if(parent != null) { parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty); } if (inline.FlowDirection != parentFlowDirection) { run = new TextEndOfSegment(_elementEdgeCharacterLength); } else { TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline); if (textDecorations == null || textDecorations.Count == 0) { // (2) End of inline element, hide CloseEdge character and continue run = new TextHidden(_elementEdgeCharacterLength); } else { run = new TextEndOfSegment(_elementEdgeCharacterLength); } } } return run; } ////// Fetch the next run at embedded object position. /// /// /// Character offset of this run. /// /// /// Current position in the text array. /// protected TextRun HandleEmbeddedObject(int dcp, StaticTextPointer position) { Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement, "TextPointer does not point to embedded object."); TextRun run = null; DependencyObject embeddedObject = position.GetAdjacentElement(LogicalDirection.Forward) as DependencyObject; if (embeddedObject is UIElement) { // Extract the aggregated properties into something that the textrun can use. TextRunProperties textProps = new TextProperties(embeddedObject, position, true /* inline objects */, true /* get background */); // Create inline object run. run = new InlineObjectRun(TextContainerHelper.EmbeddedObjectLength, (UIElement)embeddedObject, textProps, _paraClient.Paragraph as TextParagraph); } else { // If the embedded object is of an unknown type, treat it as hidden content. run = new TextHidden(TextContainerHelper.EmbeddedObjectLength); } return run; } #endregion Protected Methods #region Internal Methods ////// Synthetic character length. /// internal static int SyntheticCharacterLength { get { return _syntheticCharacterLength; } } ////// Returns true if any figure runs have been handled by this text source - Only valid after line is formatted. /// internal bool HasFigures { get { return _hasFigures; } } ////// Returns true if any floater runs have been handled by this text source - Only valid after line is formatted. /// internal bool HasFloaters { get { return _hasFloaters; } } #endregion Internal Methods #region Protected Fields ////// Owner of the line /// protected readonly BaseParaClient _paraClient; ////// Has any figures? /// protected bool _hasFigures; ////// Has any floaters? /// protected bool _hasFloaters; protected static int _syntheticCharacterLength = 1; ////// Element edge character length. /// protected static int _elementEdgeCharacterLength = 1; #endregion Protected Fields } } #pragma warning enable 1634, 1691 // 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
- HighContrastHelper.cs
- ListMarkerSourceInfo.cs
- CompilerInfo.cs
- SQLDecimalStorage.cs
- WebPartsPersonalizationAuthorization.cs
- GuidTagList.cs
- Pool.cs
- ISO2022Encoding.cs
- Permission.cs
- PublisherMembershipCondition.cs
- BitmapEffectGroup.cs
- DataGridItemCollection.cs
- ValueExpressions.cs
- PageParserFilter.cs
- DictionaryEntry.cs
- DataGridViewCheckBoxColumn.cs
- CoTaskMemHandle.cs
- ListenerAdapter.cs
- PeerTransportListenAddressConverter.cs
- SafeWaitHandle.cs
- ConnectionProviderAttribute.cs
- Vector.cs
- DirectionalLight.cs
- CodeVariableDeclarationStatement.cs
- SqlColumnizer.cs
- KeyMatchBuilder.cs
- CompilerParameters.cs
- _ProxyRegBlob.cs
- ManagementException.cs
- CodePageUtils.cs
- TreeNodeSelectionProcessor.cs
- TreeNodeBindingCollection.cs
- _HeaderInfo.cs
- LayoutDump.cs
- ResourceType.cs
- SimpleBitVector32.cs
- ConfigXmlReader.cs
- WsdlBuildProvider.cs
- CodeGenerator.cs
- Crypto.cs
- SessionStateModule.cs
- OleDbStruct.cs
- DataControlField.cs
- ISAPIWorkerRequest.cs
- EmbossBitmapEffect.cs
- BaseTransportHeaders.cs
- SystemIPGlobalStatistics.cs
- ActivityStatusChangeEventArgs.cs
- LookupBindingPropertiesAttribute.cs
- Bind.cs
- __ConsoleStream.cs
- WebSysDefaultValueAttribute.cs
- XamlClipboardData.cs
- TextContainerChangeEventArgs.cs
- EasingKeyFrames.cs
- WsdlImporterElement.cs
- DesignerVerb.cs
- JsonEncodingStreamWrapper.cs
- RegisteredScript.cs
- _ProxyChain.cs
- ImmutableObjectAttribute.cs
- RSAPKCS1SignatureFormatter.cs
- ConfigViewGenerator.cs
- COM2IPerPropertyBrowsingHandler.cs
- SslSecurityTokenParameters.cs
- XmlWrappingWriter.cs
- URLMembershipCondition.cs
- ContainerVisual.cs
- CommentEmitter.cs
- XslVisitor.cs
- DBSqlParserColumn.cs
- EventMetadata.cs
- LogWriteRestartAreaState.cs
- SimpleHandlerBuildProvider.cs
- RectAnimationUsingKeyFrames.cs
- _CommandStream.cs
- _StreamFramer.cs
- TraceContext.cs
- SetterBaseCollection.cs
- ObjectDataSourceMethodEventArgs.cs
- DocumentSchemaValidator.cs
- TextShapeableCharacters.cs
- RegisteredHiddenField.cs
- QueryOperator.cs
- BackStopAuthenticationModule.cs
- PropertyKey.cs
- CqlWriter.cs
- SamlAuthorizationDecisionStatement.cs
- Point4DValueSerializer.cs
- ReaderContextStackData.cs
- TextEditorLists.cs
- ConfigurationSectionGroup.cs
- ReadWriteSpinLock.cs
- ToolStripScrollButton.cs
- BaseParser.cs
- StateChangeEvent.cs
- DelegateHelpers.Generated.cs
- Column.cs
- TypeUtil.cs
- ComboBox.cs