// ------------------------------------------------------------------ // Dump text paragraph result. // ------------------------------------------------------------------ private static void DumpTextParagraphResult(XmlTextWriter writer, TextParagraphResult paragraph, Visual visualParent) { writer.WriteStartElement("TextParagraph"); // Dump paragraph info writer.WriteStartElement("Element"); writer.WriteAttributeString("Type", paragraph.Element.GetType().FullName); writer.WriteEndElement(); DumpRect(writer, "LayoutBox", paragraph.LayoutBox); Visual visual = DumpParagraphOffset(writer, paragraph, visualParent); DumpTextRange(writer, paragraph.StartPosition, paragraph.EndPosition); DumpLineResults(writer, paragraph.Lines, visual); DumpParagraphResults(writer, "Floaters", paragraph.Floaters, visual); DumpParagraphResults(writer, "Figures", paragraph.Figures, visual); writer.WriteEndElement(); }
/// <summary> /// Retrieves an oriented text position advancing by number of lines from its initial position. /// </summary> /// <param name="paragraph">Text paragraph.</param> /// <param name="suggestedX"> /// The suggested X offset, in pixels, of text position on the destination /// line. If suggestedX is set to Double.NaN it will be ignored, otherwise /// the method will try to find a position on the destination line closest /// to suggestedX. /// </param> /// <param name="count">Number of lines to advance. Negative means move backwards.</param> /// <returns> /// A TextPointer and its orientation matching suggestedX on the /// destination line. /// </returns> private ITextPointer GetPositionAtNextLineFromSiblingTextPara(TextParagraphResult paragraph, double suggestedX, ref int count) { ITextPointer positionOut = null; // TextParagraph - start from the first or last line (depending on the count // value sign) and find the previous/next line in the line array. // If new line (specified by count) is not in the range of this TextParagraph, // update count value by the line count. ReadOnlyCollection<LineResult> lines = paragraph.Lines; Invariant.Assert(lines != null, "Lines collection is null"); if (!paragraph.HasTextContent) { // Paragraph has no text content, which means it either has no lines at all or just figures and floaters. // In either case, we cannot step into it from GetPositionAtNextLine. We must set positionOut to null and // try to advance elsewhere. positionOut = null; } else { Rect paragraphBox = paragraph.LayoutBox; // We are entering this paragraph. Get index of the first/last line // (depending on the sing of count value) and try to find out line index. int lineIndex = (count > 0) ? 0 : lines.Count - 1; // We are about to analyze the first/last line in the paragraph, so adjust the // count to take it into account. if (count < 0) { ++count; } else { --count; } // If the new line is not in the range of this paragraph , change the count // value by the number of lines in the paragraph. if (lineIndex + count < 0) { count += lineIndex; } else if (lineIndex + count > lines.Count - 1) { count -= (lines.Count - 1 - lineIndex); } else { lineIndex = lineIndex + count; count = 0; } // If count is 0, the new line is in this paragraph if (count == 0) { // Get position at suggested X. If suggested X is not provided, // use the first position in the line. if (!DoubleUtil.IsNaN(suggestedX)) { positionOut = lines[lineIndex].GetTextPositionFromDistance(suggestedX); } else { positionOut = lines[lineIndex].StartPosition.CreatePointer(LogicalDirection.Forward); } } else { // If count is not 0, the new line is in the next/previous paragraph. if (count < 0) { // Just in case there are no lines above, set position to the first line. if (!DoubleUtil.IsNaN(suggestedX)) { positionOut = lines[0].GetTextPositionFromDistance(suggestedX); } else { positionOut = lines[0].StartPosition.CreatePointer(LogicalDirection.Forward); } } else { // Just in case there are no lines below, set position to the last line. if (!DoubleUtil.IsNaN(suggestedX)) { positionOut = lines[lines.Count - 1].GetTextPositionFromDistance(suggestedX); } else { positionOut = lines[lines.Count - 1].StartPosition.CreatePointer(LogicalDirection.Forward); } } } } return positionOut; }