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
- IOException.cs
- MetadataPropertyCollection.cs
- MailMessageEventArgs.cs
- DragDropHelper.cs
- CanonicalXml.cs
- NativeMethods.cs
- SQLRoleProvider.cs
- querybuilder.cs
- sqlinternaltransaction.cs
- ReflectEventDescriptor.cs
- ExtendedPropertiesHandler.cs
- MatrixTransform.cs
- SemanticTag.cs
- Separator.cs
- TraceSection.cs
- SafeEventLogReadHandle.cs
- SystemColors.cs
- CDSsyncETWBCLProvider.cs
- TableLayoutStyle.cs
- HandledMouseEvent.cs
- FixedDSBuilder.cs
- UserPersonalizationStateInfo.cs
- Sentence.cs
- DashStyles.cs
- Tablet.cs
- EventEntry.cs
- ConnectionPool.cs
- MsmqEncryptionAlgorithm.cs
- DataProtection.cs
- XpsFontSerializationService.cs
- ListViewAutomationPeer.cs
- PointValueSerializer.cs
- ToolStripArrowRenderEventArgs.cs
- IPPacketInformation.cs
- HtmlInputText.cs
- XmlFormatReaderGenerator.cs
- CodeMethodReturnStatement.cs
- GlobalItem.cs
- Privilege.cs
- UserControlBuildProvider.cs
- ProgressBarRenderer.cs
- ObjectCacheSettings.cs
- HtmlHead.cs
- ParallelLoopState.cs
- AbandonedMutexException.cs
- CodePageUtils.cs
- SerializerWriterEventHandlers.cs
- PrintPreviewGraphics.cs
- ObjectParameterCollection.cs
- SocketPermission.cs
- GlyphingCache.cs
- DataServiceClientException.cs
- MimePart.cs
- LineSegment.cs
- VisualStates.cs
- DbConnectionFactory.cs
- GridItemProviderWrapper.cs
- CollectionViewProxy.cs
- ConstructorNeedsTagAttribute.cs
- DocumentPageHost.cs
- DuplicateWaitObjectException.cs
- HttpListenerContext.cs
- RequestStatusBarUpdateEventArgs.cs
- EntityStoreSchemaFilterEntry.cs
- _RequestCacheProtocol.cs
- ProfileServiceManager.cs
- PrimitiveDataContract.cs
- ExpressionBinding.cs
- ConsoleCancelEventArgs.cs
- XmlSchemaComplexContent.cs
- ValidatingPropertiesEventArgs.cs
- Adorner.cs
- XamlTreeBuilder.cs
- WeakEventManager.cs
- TemporaryBitmapFile.cs
- EntityContainerEmitter.cs
- FileEnumerator.cs
- SuppressMergeCheckAttribute.cs
- RelatedView.cs
- Item.cs
- DataMemberConverter.cs
- PublisherMembershipCondition.cs
- HttpApplicationStateBase.cs
- CellPartitioner.cs
- RelatedCurrencyManager.cs
- ScrollableControl.cs
- MetadataItemCollectionFactory.cs
- ControlAdapter.cs
- SemanticBasicElement.cs
- DbExpressionRules.cs
- Annotation.cs
- SqlMethods.cs
- DesignerDataTable.cs
- InternalEnumValidator.cs
- WorkflowIdleElement.cs
- AddressAlreadyInUseException.cs
- PrintDialog.cs
- WorkflowRuntime.cs
- MediaPlayerState.cs
- DrawingContextWalker.cs