internal void Merge(TextContentRange other) { Invariant.Assert(other != null); // Skip merge operation if we're merging an empty text content range. if(other._textContainer == null) { return; } if (_textContainer == null) { _cpFirst = other._cpFirst; _cpLast = other._cpLast; _textContainer = other._textContainer; _size = other._size; if (_size != 0) { Invariant.Assert(other._ranges != null); Invariant.Assert(other._ranges.Length >= (other._size * 2)); _ranges = new int[_size * 2]; for (int i = 0; i < _ranges.Length; i++) { _ranges[i] = other._ranges[i]; } } } else { Invariant.Assert(_textContainer == other._textContainer); if (other.IsSimple) { Merge(other._cpFirst, other._cpLast); } else { for (int i = 0; i < other._size; i++) { Merge(other._ranges[i * 2], other._ranges[i * 2 + 1]); } } } Normalize(); }
internal void Merge(TextContentRange other) { Invariant.Assert(other != null); // Skip merge operation if we're merging an empty text content range. if (other._textContainer == null) { return; } if (_textContainer == null) { _cpFirst = other._cpFirst; _cpLast = other._cpLast; _textContainer = other._textContainer; _size = other._size; if (_size != 0) { Invariant.Assert(other._ranges != null); Invariant.Assert(other._ranges.Length >= (other._size * 2)); _ranges = new int[_size * 2]; for (int i = 0; i < _ranges.Length; i++) { _ranges[i] = other._ranges[i]; } } } else { Invariant.Assert(_textContainer == other._textContainer); if (other.IsSimple) { Merge(other._cpFirst, other._cpLast); } else { for (int i = 0; i < other._size; i++) { Merge(other._ranges[i * 2], other._ranges[i * 2 + 1]); } } } Normalize(); }
// Token: 0x0600723B RID: 29243 RVA: 0x0020A3E0 File Offset: 0x002085E0 internal void Merge(TextContentRange other) { Invariant.Assert(other != null); if (other._textContainer == null) { return; } if (this._textContainer == null) { this._cpFirst = other._cpFirst; this._cpLast = other._cpLast; this._textContainer = other._textContainer; this._size = other._size; if (this._size != 0) { Invariant.Assert(other._ranges != null); Invariant.Assert(other._ranges.Length >= other._size * 2); this._ranges = new int[this._size * 2]; for (int i = 0; i < this._ranges.Length; i++) { this._ranges[i] = other._ranges[i]; } } } else { Invariant.Assert(this._textContainer == other._textContainer); if (other.IsSimple) { this.Merge(other._cpFirst, other._cpLast); } else { for (int j = 0; j < other._size; j++) { this.Merge(other._ranges[j * 2], other._ranges[j * 2 + 1]); } } } this.Normalize(); }
internal override TextContentRange GetTextContentRange() { TextContentRange range = null; // Search subpage for table cells PTS.FSTABLEROWDESCRIPTION[] arrayTableRowDesc; PTS.FSKUPDATE fskupdTable; PTS.FSRECT rectTable; if (QueryTableDetails(out arrayTableRowDesc, out fskupdTable, out rectTable)) { range = new TextContentRange(); UpdateChunkInfo(arrayTableRowDesc); TextElement elementOwner = this.Paragraph.Element as TextElement; // Add range for Table leading edge, if necessary if (_isFirstChunk) range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( elementOwner, ElementEdge.BeforeStart)); for (int iR = 0; iR < arrayTableRowDesc.Length; ++iR) { PTS.FSTABLEROWDETAILS tableRowDetails; TableRow row = ((RowParagraph)(PtsContext.HandleToObject(arrayTableRowDesc[iR].fsnmRow))).Row; PTS.Validate(PTS.FsQueryTableObjRowDetails( PtsContext.Context, arrayTableRowDesc[iR].pfstablerow, out tableRowDetails)); if (tableRowDetails.fskboundaryAbove != PTS.FSKTABLEROWBOUNDARY.fsktablerowboundaryBreak) { // Add range for TableRowGroup leading edge, if necessary if (row.Index == 0) range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( row.RowGroup, ElementEdge.BeforeStart)); range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( row, ElementEdge.BeforeStart)); } PTS.FSKUPDATE[] arrayUpdate; IntPtr[] arrayFsCell; PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge; QueryRowDetails( arrayTableRowDesc[iR].pfstablerow, out arrayFsCell, out arrayUpdate, out arrayTableCellMerge); for (int iC = 0; iC < arrayFsCell.Length; ++iC) { if (arrayFsCell[iC] == IntPtr.Zero) { // paginated case - cell may be null continue; } CellParaClient cellParaClient = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC])); range.Merge(cellParaClient.GetTextContentRange()); } if (tableRowDetails.fskboundaryBelow != PTS.FSKTABLEROWBOUNDARY.fsktablerowboundaryBreak) { range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( row, ElementEdge.AfterEnd)); // Add range for TableRowGroup trailing edge, if necessary if (row.Index == row.RowGroup.Rows.Count - 1) range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( row.RowGroup, ElementEdge.AfterEnd)); } } // Add range for Table trailing edge, if necessary if (_isLastChunk) range.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( elementOwner, ElementEdge.AfterEnd)); } if (range == null) { // if table has no rows or no cells range = TextContainerHelper.GetTextContentRangeForTextElement(TableParagraph.Table); } return range; }
internal override TextContentRange GetTextContentRange() { TextContentRange textContentRange; // Query subpage details PTS.FSSUBPAGEDETAILS subpageDetails; PTS.Validate(PTS.FsQuerySubpageDetails(PtsContext.Context, _paraHandle.Value, out subpageDetails)); // Subpage content may be simple or complex - // depending of set of features used in the content of the page. // (1) simple subpage (contains only one track) // (2) complex subpage (contains columns) if (PTS.ToBoolean(subpageDetails.fSimple)) { // (1) simple subpage (contains only one track) textContentRange = PtsHelper.TextContentRangeFromTrack(PtsContext, subpageDetails.u.simple.trackdescr.pfstrack); } else { textContentRange = new TextContentRange(); // (2) complex page (contains columns) // cBasicColumns == 0, means that subpage content is empty if (subpageDetails.u.complex.cBasicColumns != 0) { // Retrieve description for each column. PTS.FSTRACKDESCRIPTION[] arrayColumnDesc; PtsHelper.TrackListFromSubpage(PtsContext, _paraHandle.Value, ref subpageDetails, out arrayColumnDesc); // Arrange each track for (int index = 0; index < arrayColumnDesc.Length; index++) { // Merge TextContentRanges for all columns textContentRange.Merge(PtsHelper.TextContentRangeFromTrack(PtsContext, arrayColumnDesc[index].pfstrack)); } } } // Beginning and end tags should be consumed by host para. // If the first paragraph is the first paragraph in the paraclient and it is the first chunk, // include start position of this element. if (IsFirstChunk) { textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( Paragraph.Element as TextElement, ElementEdge.BeforeStart)); } // If the last paragraph is the last paragraph in the paraclient and it is the last chunk, // include end position of this element. if (IsLastChunk) { textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( Paragraph.Element as TextElement, ElementEdge.AfterEnd)); } return textContentRange; }
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; }
internal static TextContentRange TextContentRangeFromTrack( PtsContext ptsContext, IntPtr pfstrack) { // Get track details PTS.FSTRACKDETAILS trackDetails; PTS.Validate(PTS.FsQueryTrackDetails(ptsContext.Context, pfstrack, out trackDetails)); // Combine ranges from all nested paragraphs. TextContentRange textContentRange = new TextContentRange(); if (trackDetails.cParas != 0) { PTS.FSPARADESCRIPTION[] arrayParaDesc; PtsHelper.ParaListFromTrack(ptsContext, pfstrack, ref trackDetails, out arrayParaDesc); // Merge TextContentRanges for all paragraphs BaseParaClient paraClient; for (int i = 0; i < arrayParaDesc.Length; i++) { paraClient = ptsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient; PTS.ValidateHandle(paraClient); textContentRange.Merge(paraClient.GetTextContentRange()); } } return textContentRange; }
internal override TextContentRange GetTextContentRange() { PTS.FSTEXTDETAILS textDetails; int dcpFirst = 0, dcpLast = 0; // Query paragraph details PTS.Validate(PTS.FsQueryTextDetails(PtsContext.Context, _paraHandle.Value, out textDetails)); Invariant.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull, "Only 'full' text paragraph type is expected."); dcpFirst = textDetails.u.full.dcpFirst; dcpLast = textDetails.u.full.dcpLim; // The last TextParaClient has EOP character included, which does not // exist in the tree. Need to remove it. // NOTE: cannot remove it when formatting line because PTS does not like empty lines. if (HasEOP && dcpLast > Paragraph.Cch) { ErrorHandler.Assert(dcpLast == Paragraph.Cch + Line.SyntheticCharacterLength, ErrorHandler.ParagraphCharacterCountMismatch); dcpLast -= Line.SyntheticCharacterLength; } // Text paragraph has always just one range int dcp = Paragraph.ParagraphStartCharacterPosition; TextContentRange textContentRange; if(TextParagraph.HasFiguresOrFloaters()) { PTS.FSATTACHEDOBJECTDESCRIPTION [] arrayAttachedObjectDesc = null; int attachedObjectCount = textDetails.u.full.cAttachedObjects; textContentRange = new TextContentRange(); // Recurse into figures and floaters if (attachedObjectCount > 0) { // Get list of attached objects PtsHelper.AttachedObjectListFromParagraph(PtsContext, _paraHandle.Value, attachedObjectCount, out arrayAttachedObjectDesc); } // Figures and floaters cannot break TextParagraph.UpdateTextContentRangeFromAttachedObjects(textContentRange, dcp + dcpFirst, dcp + dcpLast, arrayAttachedObjectDesc); } else { textContentRange = new TextContentRange(dcp + dcpFirst, dcp + dcpLast, Paragraph.StructuralCache.TextContainer); } return textContentRange; }
/// <summary> /// Retrieve TextSegments collection for the content of the page represented /// by the TextView. /// </summary> private ReadOnlyCollection<TextSegment> GetTextSegments() { ReadOnlyCollection<TextSegment> textSegments; // For a bottomless page there is always one TextSegment, starting at // the beginning of TextContainer and ending at the last calculated // position, which is: // a) the end of TextContainer, or // b) the interruption position when background layout is in progress. // For a finite page there is no such optimization, so need to query all // columns and merge their TextSegments. if (!_owner.FinitePage) { ITextPointer segmentEnd = _textContainer.End; BackgroundFormatInfo backgroundFormatInfo = _owner.StructuralCache.BackgroundFormatInfo; if (backgroundFormatInfo != null && backgroundFormatInfo.CPInterrupted != -1) { segmentEnd = _textContainer.Start.CreatePointer(backgroundFormatInfo.CPInterrupted, LogicalDirection.Backward); } List<TextSegment> segments = new List<TextSegment>(1); segments.Add(new TextSegment(_textContainer.Start, segmentEnd, true)); textSegments = new ReadOnlyCollection<TextSegment>(segments); } else { TextContentRange textContentRange = new TextContentRange(); // Merge ranges from all columns. ReadOnlyCollection<ColumnResult> columns = Columns; Invariant.Assert(columns != null, "Column collection is empty."); for (int index = 0; index < columns.Count; index++) { textContentRange.Merge(columns[index].TextContentRange); } textSegments = textContentRange.GetTextSegments(); } Invariant.Assert(textSegments != null); return textSegments; }