Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / MS / Internal / PtsHost / ContainerParaClient.cs / 1 / ContainerParaClient.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: ContainerParaClient.cs
//
// Description: ContainerParaClient is responsible for handling display
// related data of paragraph containers.
//
// History:
// 05/05/2003 : grzegorz - moving from Avalon branch.
//
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections;
using System.Diagnostics;
using System.Security;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents;
using MS.Internal.Documents;
using MS.Internal.Text;
using MS.Internal.PtsHost.UnsafeNativeMethods;
namespace MS.Internal.PtsHost
{
///
/// ContainerParaClient is responsible for handling display related data
/// of paragraph containers.
///
internal class ContainerParaClient : BaseParaClient
{
///
/// Constructor.
///
///
/// Paragraph associated with this object.
///
internal ContainerParaClient(ContainerParagraph paragraph) : base(paragraph)
{
}
///
/// Arrange paragraph.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// and some PtsHelper functions
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
protected override void OnArrange()
{
base.OnArrange();
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Adjust rectangle and offset to take into account MBPs
MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
if(ParentFlowDirection != PageFlowDirection)
{
mbp.MirrorMargin();
}
_rect.u += mbp.MarginLeft;
_rect.du -= mbp.MarginLeft + mbp.MarginRight;
_rect.du = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.du);
_rect.dv = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.dv);
uint fswdirSubtrack = PTS.FlowDirectionToFswdir(_flowDirection);
// There is possibility to get empty track.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
PtsHelper.ArrangeParaList(PtsContext, subtrackDetails.fsrc, arrayParaDesc, fswdirSubtrack);
}
}
///
/// Hit tests to the correct IInputElement within the paragraph
/// that the mouse is over.
///
///
/// Point which gives location of Hit test
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override IInputElement InputHitTest(PTS.FSPOINT pt)
{
IInputElement ie = null;
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Hittest subtrack content.
// There might be possibility to get empty sub-track, skip the sub-track
// in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
ie = PtsHelper.InputHitTestParaList(PtsContext, pt, ref subtrackDetails.fsrc, arrayParaDesc);
}
// If nothing is hit, return the owner of the paragraph.
if (ie == null && _rect.Contains(pt))
{
ie = Paragraph.Element as IInputElement;
}
return ie;
}
///
/// Returns ArrayList of rectangles for the given ContentElement e if
/// e lies in this client. Otherwise returns empty list.
///
///
/// ContentElement for which rectangles are needed
///
///
/// Int representing start offset of e.
///
///
/// int representing number of positions occupied by e.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override List GetRectangles(ContentElement e, int start, int length)
{
List rectangles = new List();
if (this.Paragraph.Element as ContentElement == e)
{
// We have found the element. Return rectangles for this paragraph.
GetRectanglesForParagraphElement(out rectangles);
}
else
{
// Element not found as Paragraph.Element. Look inside
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// There might be possibility to get empty sub-track, skip the sub-track
// in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
// No changes to offset, since there are no subpages generated, only lists of paragraphs
PTS.FSPARADESCRIPTION[] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
rectangles = PtsHelper.GetRectanglesInParaList(PtsContext, e, start, length, arrayParaDesc);
}
else
{
rectangles = new List();
}
}
// Rectangles must be non-null
Invariant.Assert(rectangles != null);
return rectangles;
}
///
/// Validate visual node associated with paragraph.
///
///
/// Inherited update info
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited)
{
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Draw border and background info.
// Adjust rectangle and offset to take into account MBPs
MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
if(ThisFlowDirection != PageFlowDirection)
{
mbp.MirrorBP();
}
Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);
_visual.DrawBackgroundAndBorder(backgroundBrush, mbp.BorderBrush, mbp.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk);
// There might be possibility to get empty sub-track, skip the sub-track in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
PtsHelper.UpdateParaListVisuals(PtsContext, _visual.Children, fskupdInherited, arrayParaDesc);
}
else
{
_visual.Children.Clear();
}
}
///
/// Updates the viewport for this para
///
///
/// Fsrect with viewport info
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// and PtsHelper.ParaListFromSubtrack.
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override void UpdateViewport(ref PTS.FSRECT viewport)
{
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// There might be possibility to get empty sub-track, skip the sub-track in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
PtsHelper.UpdateViewportParaList(PtsContext, arrayParaDesc, ref viewport);
}
}
///
/// Create and return paragraph result representing this paragraph.
///
internal override ParagraphResult CreateParagraphResult()
{
/*
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// If there is just one paragraph, do not create container. Return just this paragraph.
if (subtrackDetails.cParas == 1)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(_paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
return paraClient.CreateParagraphResult();
}
*/
return new ContainerParagraphResult(this);
}
///
/// Return TextContentRange for the content of the paragraph.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override TextContentRange GetTextContentRange()
{
TextElement elementOwner = this.Paragraph.Element as TextElement;
TextContentRange textContentRange;
BaseParaClient paraClient;
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.FSPARADESCRIPTION[] arrayParaDesc;
Invariant.Assert(elementOwner != null, "Expecting TextElement as owner of ContainerParagraph.");
// Query paragraph details
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// If container is empty, return range for the entire element.
// If the beginning and the end of content of the paragraph is
// part of this ParaClient, return range for the entire element.
// Otherwise combine ranges from all nested paragraphs.
if (subtrackDetails.cParas == 0 || (_isFirstChunk && _isLastChunk))
{
textContentRange = TextContainerHelper.GetTextContentRangeForTextElement(elementOwner);
}
else
{
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Merge TextContentRanges for all paragraphs
textContentRange = new TextContentRange();
for (int i = 0; i < arrayParaDesc.Length; i++)
{
paraClient = Paragraph.StructuralCache.PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
textContentRange.Merge(paraClient.GetTextContentRange());
}
// If the first paragraph is the first paragraph in the container and it is the first chunk,
// include start position of this element.
if (_isFirstChunk)
{
textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
elementOwner, ElementEdge.BeforeStart));
}
// If the last paragraph is the last paragraph in the container and it is the last chunk,
// include end position of this element.
if (_isLastChunk)
{
textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
elementOwner, ElementEdge.AfterEnd));
}
}
Invariant.Assert(textContentRange != null);
return textContentRange;
}
///
/// Returns a new colleciton of ParagraphResults for the contained paragraphs.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal ReadOnlyCollection GetChildrenParagraphResults(out bool hasTextContent)
{
#if TEXTPANELLAYOUTDEBUG
TextPanelDebug.IncrementCounter("ContainerPara.GetParagraphs", TextPanelDebug.Category.TextView);
#endif
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// hasTextContent is set to true if any of the children paragraphs has text content, not just attached objects
hasTextContent = false;
if (subtrackDetails.cParas == 0)
{
return new ReadOnlyCollection(new List(0));
}
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
List paragraphResults = new List(arrayParaDesc.Length);
for (int i = 0; i < arrayParaDesc.Length; i++)
{
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
ParagraphResult paragraphResult = paraClient.CreateParagraphResult();
if (paragraphResult.HasTextContent)
{
hasTextContent = true;
}
paragraphResults.Add(paragraphResult);
}
return new ReadOnlyCollection(paragraphResults);
}
///
/// Update information about first/last chunk.
///
///
/// True if para is first chunk of paginated content
///
///
/// True if para is last chunk of paginated content
///
internal void SetChunkInfo(bool isFirstChunk, bool isLastChunk)
{
_isFirstChunk = isFirstChunk;
_isLastChunk = isLastChunk;
}
///
/// Returns baseline for first text line
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override int GetFirstTextLineBaseline()
{
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
if (subtrackDetails.cParas == 0)
{
return _rect.v;
}
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
return paraClient.GetFirstTextLineBaseline();
}
///
/// Returns tight bounding path geometry.
///
internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
{
bool hasTextContent;
ReadOnlyCollection paragraphs = GetChildrenParagraphResults(out hasTextContent);
Invariant.Assert(paragraphs != null, "Paragraph collection is null.");
if (paragraphs.Count > 0)
{
return (TextDocumentView.GetTightBoundingGeometryFromTextPositionsHelper(paragraphs, startPosition, endPosition, TextDpi.FromTextDpi(_dvrTopSpace), visibleRect));
}
return null;
}
///
/// Is this the first chunk of paginated content.
///
internal override bool IsFirstChunk
{
get
{
return _isFirstChunk;
}
}
private bool _isFirstChunk;
///
/// Is this the last chunk of paginated content.
///
internal override bool IsLastChunk
{
get
{
return _isLastChunk;
}
}
private bool _isLastChunk;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: ContainerParaClient.cs
//
// Description: ContainerParaClient is responsible for handling display
// related data of paragraph containers.
//
// History:
// 05/05/2003 : grzegorz - moving from Avalon branch.
//
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections;
using System.Diagnostics;
using System.Security;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents;
using MS.Internal.Documents;
using MS.Internal.Text;
using MS.Internal.PtsHost.UnsafeNativeMethods;
namespace MS.Internal.PtsHost
{
///
/// ContainerParaClient is responsible for handling display related data
/// of paragraph containers.
///
internal class ContainerParaClient : BaseParaClient
{
///
/// Constructor.
///
///
/// Paragraph associated with this object.
///
internal ContainerParaClient(ContainerParagraph paragraph) : base(paragraph)
{
}
///
/// Arrange paragraph.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// and some PtsHelper functions
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
protected override void OnArrange()
{
base.OnArrange();
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Adjust rectangle and offset to take into account MBPs
MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
if(ParentFlowDirection != PageFlowDirection)
{
mbp.MirrorMargin();
}
_rect.u += mbp.MarginLeft;
_rect.du -= mbp.MarginLeft + mbp.MarginRight;
_rect.du = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.du);
_rect.dv = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.dv);
uint fswdirSubtrack = PTS.FlowDirectionToFswdir(_flowDirection);
// There is possibility to get empty track.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
PtsHelper.ArrangeParaList(PtsContext, subtrackDetails.fsrc, arrayParaDesc, fswdirSubtrack);
}
}
///
/// Hit tests to the correct IInputElement within the paragraph
/// that the mouse is over.
///
///
/// Point which gives location of Hit test
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override IInputElement InputHitTest(PTS.FSPOINT pt)
{
IInputElement ie = null;
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Hittest subtrack content.
// There might be possibility to get empty sub-track, skip the sub-track
// in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
ie = PtsHelper.InputHitTestParaList(PtsContext, pt, ref subtrackDetails.fsrc, arrayParaDesc);
}
// If nothing is hit, return the owner of the paragraph.
if (ie == null && _rect.Contains(pt))
{
ie = Paragraph.Element as IInputElement;
}
return ie;
}
///
/// Returns ArrayList of rectangles for the given ContentElement e if
/// e lies in this client. Otherwise returns empty list.
///
///
/// ContentElement for which rectangles are needed
///
///
/// Int representing start offset of e.
///
///
/// int representing number of positions occupied by e.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override List GetRectangles(ContentElement e, int start, int length)
{
List rectangles = new List();
if (this.Paragraph.Element as ContentElement == e)
{
// We have found the element. Return rectangles for this paragraph.
GetRectanglesForParagraphElement(out rectangles);
}
else
{
// Element not found as Paragraph.Element. Look inside
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// There might be possibility to get empty sub-track, skip the sub-track
// in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
// No changes to offset, since there are no subpages generated, only lists of paragraphs
PTS.FSPARADESCRIPTION[] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
rectangles = PtsHelper.GetRectanglesInParaList(PtsContext, e, start, length, arrayParaDesc);
}
else
{
rectangles = new List();
}
}
// Rectangles must be non-null
Invariant.Assert(rectangles != null);
return rectangles;
}
///
/// Validate visual node associated with paragraph.
///
///
/// Inherited update info
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited)
{
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// Draw border and background info.
// Adjust rectangle and offset to take into account MBPs
MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
if(ThisFlowDirection != PageFlowDirection)
{
mbp.MirrorBP();
}
Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);
_visual.DrawBackgroundAndBorder(backgroundBrush, mbp.BorderBrush, mbp.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk);
// There might be possibility to get empty sub-track, skip the sub-track in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
PtsHelper.UpdateParaListVisuals(PtsContext, _visual.Children, fskupdInherited, arrayParaDesc);
}
else
{
_visual.Children.Clear();
}
}
///
/// Updates the viewport for this para
///
///
/// Fsrect with viewport info
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
/// and PtsHelper.ParaListFromSubtrack.
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override void UpdateViewport(ref PTS.FSRECT viewport)
{
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// There might be possibility to get empty sub-track, skip the sub-track in such case.
if (subtrackDetails.cParas != 0)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Render list of paragraphs
PtsHelper.UpdateViewportParaList(PtsContext, arrayParaDesc, ref viewport);
}
}
///
/// Create and return paragraph result representing this paragraph.
///
internal override ParagraphResult CreateParagraphResult()
{
/*
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// If there is just one paragraph, do not create container. Return just this paragraph.
if (subtrackDetails.cParas == 1)
{
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(_paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
return paraClient.CreateParagraphResult();
}
*/
return new ContainerParagraphResult(this);
}
///
/// Return TextContentRange for the content of the paragraph.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override TextContentRange GetTextContentRange()
{
TextElement elementOwner = this.Paragraph.Element as TextElement;
TextContentRange textContentRange;
BaseParaClient paraClient;
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.FSPARADESCRIPTION[] arrayParaDesc;
Invariant.Assert(elementOwner != null, "Expecting TextElement as owner of ContainerParagraph.");
// Query paragraph details
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// If container is empty, return range for the entire element.
// If the beginning and the end of content of the paragraph is
// part of this ParaClient, return range for the entire element.
// Otherwise combine ranges from all nested paragraphs.
if (subtrackDetails.cParas == 0 || (_isFirstChunk && _isLastChunk))
{
textContentRange = TextContainerHelper.GetTextContentRangeForTextElement(elementOwner);
}
else
{
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
// Merge TextContentRanges for all paragraphs
textContentRange = new TextContentRange();
for (int i = 0; i < arrayParaDesc.Length; i++)
{
paraClient = Paragraph.StructuralCache.PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
textContentRange.Merge(paraClient.GetTextContentRange());
}
// If the first paragraph is the first paragraph in the container and it is the first chunk,
// include start position of this element.
if (_isFirstChunk)
{
textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
elementOwner, ElementEdge.BeforeStart));
}
// If the last paragraph is the last paragraph in the container and it is the last chunk,
// include end position of this element.
if (_isLastChunk)
{
textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
elementOwner, ElementEdge.AfterEnd));
}
}
Invariant.Assert(textContentRange != null);
return textContentRange;
}
///
/// Returns a new colleciton of ParagraphResults for the contained paragraphs.
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal ReadOnlyCollection GetChildrenParagraphResults(out bool hasTextContent)
{
#if TEXTPANELLAYOUTDEBUG
TextPanelDebug.IncrementCounter("ContainerPara.GetParagraphs", TextPanelDebug.Category.TextView);
#endif
// Query paragraph details
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
// hasTextContent is set to true if any of the children paragraphs has text content, not just attached objects
hasTextContent = false;
if (subtrackDetails.cParas == 0)
{
return new ReadOnlyCollection(new List(0));
}
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
List paragraphResults = new List(arrayParaDesc.Length);
for (int i = 0; i < arrayParaDesc.Length; i++)
{
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
ParagraphResult paragraphResult = paraClient.CreateParagraphResult();
if (paragraphResult.HasTextContent)
{
hasTextContent = true;
}
paragraphResults.Add(paragraphResult);
}
return new ReadOnlyCollection(paragraphResults);
}
///
/// Update information about first/last chunk.
///
///
/// True if para is first chunk of paginated content
///
///
/// True if para is last chunk of paginated content
///
internal void SetChunkInfo(bool isFirstChunk, bool isLastChunk)
{
_isFirstChunk = isFirstChunk;
_isLastChunk = isLastChunk;
}
///
/// Returns baseline for first text line
///
///
/// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
/// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
/// which ensures that partial trust code won't be able to set it to a random value.
/// The subtrackDetails parameter passed to other methods is generated securely in this function.
///
[SecurityCritical, SecurityTreatAsSafe]
internal override int GetFirstTextLineBaseline()
{
PTS.FSSUBTRACKDETAILS subtrackDetails;
PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
if (subtrackDetails.cParas == 0)
{
return _rect.v;
}
// Get list of paragraphs
PTS.FSPARADESCRIPTION [] arrayParaDesc;
PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
PTS.ValidateHandle(paraClient);
return paraClient.GetFirstTextLineBaseline();
}
///
/// Returns tight bounding path geometry.
///
internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
{
bool hasTextContent;
ReadOnlyCollection paragraphs = GetChildrenParagraphResults(out hasTextContent);
Invariant.Assert(paragraphs != null, "Paragraph collection is null.");
if (paragraphs.Count > 0)
{
return (TextDocumentView.GetTightBoundingGeometryFromTextPositionsHelper(paragraphs, startPosition, endPosition, TextDpi.FromTextDpi(_dvrTopSpace), visibleRect));
}
return null;
}
///
/// Is this the first chunk of paginated content.
///
internal override bool IsFirstChunk
{
get
{
return _isFirstChunk;
}
}
private bool _isFirstChunk;
///
/// Is this the last chunk of paginated content.
///
internal override bool IsLastChunk
{
get
{
return _isLastChunk;
}
}
private bool _isLastChunk;
}
}
// 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
- ImageClickEventArgs.cs
- HttpChannelListener.cs
- BoundPropertyEntry.cs
- HMACMD5.cs
- BinaryFormatter.cs
- IsolatedStorageFilePermission.cs
- SwitchLevelAttribute.cs
- EntityDataSourceWrapper.cs
- X509CertificateStore.cs
- FixedSOMLineRanges.cs
- AsyncDataRequest.cs
- IdnElement.cs
- CheckedListBox.cs
- SoapCodeExporter.cs
- CorrelationExtension.cs
- ContextMenu.cs
- precedingquery.cs
- CodeIdentifiers.cs
- Crypto.cs
- DynamicMethod.cs
- ExceptionWrapper.cs
- TypeReference.cs
- SoapSchemaImporter.cs
- GcSettings.cs
- DictionaryContent.cs
- VectorCollectionConverter.cs
- PackageStore.cs
- TouchPoint.cs
- X509UI.cs
- HostSecurityManager.cs
- CacheSection.cs
- NumberSubstitution.cs
- ResourceType.cs
- TemplateControl.cs
- IdentityManager.cs
- BinaryNode.cs
- MemberProjectedSlot.cs
- SystemIcmpV4Statistics.cs
- PropertyPath.cs
- GeometryGroup.cs
- DbParameterHelper.cs
- MediaPlayer.cs
- NameGenerator.cs
- LinqDataSourceEditData.cs
- CLSCompliantAttribute.cs
- PageFunction.cs
- SchemaHelper.cs
- NameValuePermission.cs
- GenericQueueSurrogate.cs
- SchemaImporterExtension.cs
- _SingleItemRequestCache.cs
- _CookieModule.cs
- OciHandle.cs
- FixedFindEngine.cs
- MatrixAnimationUsingPath.cs
- SqlConnectionString.cs
- ForeignConstraint.cs
- SoapReflector.cs
- RegexCharClass.cs
- Utils.cs
- Trigger.cs
- DataGridViewTopLeftHeaderCell.cs
- WebPartTracker.cs
- RSAPKCS1KeyExchangeFormatter.cs
- DataGridViewBand.cs
- CodeVariableDeclarationStatement.cs
- DataGridViewButtonColumn.cs
- FileRecordSequenceCompletedAsyncResult.cs
- GrammarBuilderPhrase.cs
- LayoutSettings.cs
- Permission.cs
- ProgressBarAutomationPeer.cs
- KnownIds.cs
- DataGridPagerStyle.cs
- DockingAttribute.cs
- StrokeIntersection.cs
- BinaryFormatterWriter.cs
- UIElementCollection.cs
- PersonalizationState.cs
- PolicyImporterElement.cs
- XmlSchemaAttribute.cs
- NavigationProperty.cs
- CompressionTracing.cs
- QilFunction.cs
- DoubleIndependentAnimationStorage.cs
- ExecutionEngineException.cs
- LicenseContext.cs
- QilXmlWriter.cs
- StringToken.cs
- MessageSmuggler.cs
- PersistenceIOParticipant.cs
- _ChunkParse.cs
- ServiceProviders.cs
- InternalTypeHelper.cs
- ProfileSettings.cs
- InkCanvasAutomationPeer.cs
- IssuedTokenClientElement.cs
- ErrorWebPart.cs
- Italic.cs
- Int32CollectionConverter.cs