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
- ThemeInfoAttribute.cs
- DataSpaceManager.cs
- ThreadAbortException.cs
- StyleSheetDesigner.cs
- DBSqlParserColumn.cs
- HelloOperationCD1AsyncResult.cs
- SQLByte.cs
- arabicshape.cs
- PermissionAttributes.cs
- OleDbError.cs
- WorkflowApplicationUnloadedException.cs
- SHA1.cs
- BindingList.cs
- GifBitmapEncoder.cs
- ProfilePropertySettingsCollection.cs
- SqlBulkCopyColumnMapping.cs
- CollectionBuilder.cs
- MessageParameterAttribute.cs
- MergePropertyDescriptor.cs
- FormatControl.cs
- CustomAttribute.cs
- Input.cs
- RijndaelManaged.cs
- WindowsProgressbar.cs
- PointLightBase.cs
- XmlSchemaElement.cs
- XhtmlBasicCommandAdapter.cs
- ToolStripPanel.cs
- MemberListBinding.cs
- ExplicitDiscriminatorMap.cs
- SecurityTokenReferenceStyle.cs
- DataGridLinkButton.cs
- MemberNameValidator.cs
- DCSafeHandle.cs
- EntityContainerEmitter.cs
- _SslSessionsCache.cs
- DataTableExtensions.cs
- AssemblyBuilder.cs
- Wildcard.cs
- xml.cs
- InlinedAggregationOperatorEnumerator.cs
- InputQueue.cs
- UnmanagedMemoryStreamWrapper.cs
- UserCancellationException.cs
- WebPageTraceListener.cs
- FrameworkTemplate.cs
- WmlFormAdapter.cs
- Internal.cs
- InputLangChangeEvent.cs
- EmptyEnumerator.cs
- TypeForwardedToAttribute.cs
- Page.cs
- WebScriptServiceHostFactory.cs
- InnerItemCollectionView.cs
- EditorBrowsableAttribute.cs
- SubMenuStyleCollection.cs
- CodeSnippetStatement.cs
- CellConstant.cs
- WinInetCache.cs
- XmlSchemaType.cs
- XmlAttributeProperties.cs
- NavigationProperty.cs
- BinaryNode.cs
- NativeMethods.cs
- FillRuleValidation.cs
- NaturalLanguageHyphenator.cs
- SizeF.cs
- DataSourceHelper.cs
- CqlQuery.cs
- ComponentManagerBroker.cs
- BitVector32.cs
- WindowsFont.cs
- TextPattern.cs
- PinnedBufferMemoryStream.cs
- MemoryPressure.cs
- TypeUtil.cs
- RectangleHotSpot.cs
- MissingMethodException.cs
- Buffer.cs
- DocumentProperties.cs
- TextBox.cs
- Helpers.cs
- EncryptedKeyIdentifierClause.cs
- storepermissionattribute.cs
- _CacheStreams.cs
- SafeRightsManagementQueryHandle.cs
- CompleteWizardStep.cs
- HttpPostLocalhostServerProtocol.cs
- CallTemplateAction.cs
- EntitySetDataBindingList.cs
- StringDictionary.cs
- WpfXamlLoader.cs
- MenuEventArgs.cs
- BrowserCapabilitiesCompiler.cs
- SizeF.cs
- ClientTargetSection.cs
- ReflectTypeDescriptionProvider.cs
- TrackingMemoryStream.cs
- UpdatePanelTrigger.cs
- CodeCastExpression.cs