Пример #1
0
        // ------------------------------------------------------------------ 
        // Returns ArrayList of rectangles (at msot one) for the given ContentElement 
        // e if it spans all or part of the specified line
        // ----------------------------------------------------------------- 
        private List<Rect> GetRectanglesInSingleLine(
            PTS.FSLINEDESCRIPTIONSINGLE lineDesc,
            ContentElement e,
            int start, 
            int length)
        { 
            // Calculate end of element relative to TextParagraph by adding length to start position 
            int end = start + length;
            List<Rect> rectangles = new List<Rect>(); 

            // If the element does not lie in the line at all, return empty list
            if (start >= lineDesc.dcpLim)
            { 
                // Element starts after line ends
                return rectangles; 
            } 
            if (end <= lineDesc.dcpFirst)
            { 
                // Element ends before line starts
                return rectangles;
            }
 
            // Establish start and end points of element span within the line so that
            // we can get rectangle between them 
            int localStart = (start < lineDesc.dcpFirst) ? lineDesc.dcpFirst : start; 
            int localEnd = (end < lineDesc.dcpLim) ? end : lineDesc.dcpLim;
            Debug.Assert(localEnd > localStart); 

            // Create and format line
            Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition);
            Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(lineDesc.fClearOnLeft), PTS.ToBoolean(lineDesc.fClearOnRight), TextParagraph.TextRunCache); 

            if(IsOptimalParagraph) 
            { 
                ctx.LineFormatLengthTarget = lineDesc.dcpLim - lineDesc.dcpFirst;
            } 

            TextParagraph.FormatLineCore(line, lineDesc.pfsbreakreclineclient, ctx, lineDesc.dcpFirst, lineDesc.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), lineDesc.dcpFirst);

            // Assert that number of characters in Text line is the same as our expected length 
            Invariant.Assert(line.SafeLength == lineDesc.dcpLim - lineDesc.dcpFirst, "Line length is out of [....]");
 
            // Get rectangles from start and end positions of range 
            rectangles = line.GetRangeBounds(localStart, localEnd - localStart, TextDpi.FromTextDpi(lineDesc.urStart), TextDpi.FromTextDpi(lineDesc.vrStart));
 
            // Rectangles must have at least one element
            Invariant.Assert(rectangles.Count > 0);

            // Dispose the line 
            line.Dispose();
 
            return rectangles; 
        }
Пример #2
0
        private List<Rect> GetRectanglesInCompositeLine(
            PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc, 
            ContentElement e, 
            int start,
            int length) 
        {
            List<Rect> rectangles = new List<Rect>();
            int end = start + length;
 
            // If the element does not lie in the line at all, return empty list
            //if (start > lineDesc.dcpLim) 
            //{ 
            //    // Element starts after line ends
            //    return rectangles; 
            //}
            //if (end < lineDesc.dcpFirst)
            //{
                // Element ends before line starts 
            //    return rectangles;
            //} 
 
            // Get list of line elements.
            PTS.FSLINEELEMENT[] arrayLineElement; 
            PtsHelper.LineElementListFromCompositeLine(PtsContext, ref lineDesc, out arrayLineElement);

            for (int elIndex = 0; elIndex < arrayLineElement.Length; elIndex++)
            { 
                PTS.FSLINEELEMENT element = arrayLineElement[elIndex];
 
                // Check if element we are looking for does not span the current element at all 
                if (start >= element.dcpLim)
                { 
                    // Element starts after other element ends
                    continue;
                }
                if (end <= element.dcpFirst) 
                {
                    // Element ends before line starts 
                    continue; 
                }
                // Establish start and end points of element span within the line so that 
                // we can get rectangle between them
                int localStart = (start < element.dcpFirst) ? element.dcpFirst : start;
                int localEnd = (end < element.dcpLim) ? end : element.dcpLim;
                Debug.Assert(localEnd > localStart); 

                Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition); 
                Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(element.fClearOnLeft), PTS.ToBoolean(element.fClearOnRight), TextParagraph.TextRunCache); 

                if(IsOptimalParagraph) 
                {
                    ctx.LineFormatLengthTarget = element.dcpLim - element.dcpFirst;
                }
 
                TextParagraph.FormatLineCore(line, element.pfsbreakreclineclient, ctx, element.dcpFirst, element.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), element.dcpFirst);
 
                // Assert that number of characters in Text line is the same as our expected length 
                Invariant.Assert(line.SafeLength == element.dcpLim - element.dcpFirst, "Line length is out of [....]");
 
                // Get rectangles from start and end positions of range for this element
                List<Rect> elementRectangles = line.GetRangeBounds(localStart, localEnd - localStart, TextDpi.FromTextDpi(element.urStart), TextDpi.FromTextDpi(lineDesc.vrStart));

                // Rectangles must have at least one element 
                Invariant.Assert(elementRectangles.Count > 0);
 
                // Add rectangles from this element to rectangles from whole line 
                rectangles.AddRange(elementRectangles);
 
                // Dispose the line
                line.Dispose();
            }
            return rectangles; 
        }
Пример #3
0
        // ------------------------------------------------------------------ 
        //  Returns rectangles for a single composite line correcsponding to the
        //  given dcp range. Includes trailing whitespaces.
        //  Params:
        //      dcpRangeStart     - range's cp start position. Adjusted for 
        //                          line's cp range.
        //      cchRange          - nuber of cps in the range. 
        //      lineTopSpace      - the value that line's height should 
        //                          be extended to at the top.
        //      lineRightSpace    - the value that line's width should 
        //                          be extended to at the right.
        //      lineDesc          - line description.
        //      lineIndex         - line index.
        //      elemDesc          - element description. 
        //      visibleRect       - visibility rectangle. It is Ok to return
        //                          null if the line is not visible. 
        //      hasAttachedObjects- Attached objects are present 
        //  Returns:
        //      null              - if line is not visible 
        //      rectangles        - otherwise.
        // -----------------------------------------------------------------
        private List<Rect> RectanglesFromDcpRangeOfCompositeLineElement(
            int dcpRangeStart, 
            int cchRange,
            double lineTopSpace, 
            double lineRightSpace, 
            ref PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc,
            int lineIndex, 
            ref PTS.FSLINEELEMENT elemDesc,
            int elemIndex,
            Rect visibleRect)
        { 
            List<Rect> rectangles = null;
 
            Rect elementRect = new PTS.FSRECT(elemDesc.urBBox, lineDesc.vrStart, elemDesc.durBBox, lineDesc.dvrAscent + lineDesc.dvrDescent).FromTextDpi(); 

            //  width has to be adjusted to include trailing whitespaces... 
            LineVisual lineVisual = FetchLineVisualComposite(lineIndex, elemIndex);
            if (lineVisual != null)
            {
                elementRect.Width = Math.Max(lineVisual.WidthIncludingTrailingWhitespace, 0); 
            }
 
            elementRect.Y = elementRect.Y - lineTopSpace; 
            elementRect.Height = elementRect.Height + lineTopSpace;
            elementRect.Width = elementRect.Width + lineRightSpace; 

            // Ignore horizontal offset because TextBox page width != extent width.
            // It's ok to include content that doesn't strictly intersect -- this
            // is a perf optimization and the edge cases won't significantly hurt us. 
            Rect testRect = elementRect;
            testRect.X = visibleRect.X; 
 
            if (testRect.IntersectsWith(visibleRect))
            { 
                // Check whether the line is fully selected - we don't need to reformat it in this case
                if (dcpRangeStart == elemDesc.dcpFirst && elemDesc.dcpLim <= (dcpRangeStart + cchRange))
                {
                    rectangles = new List<Rect>(1); 
                    rectangles.Add(elementRect);
                } 
                else 
                {
                    // Create and format line 
                    Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition);
                    Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(elemDesc.fClearOnLeft), PTS.ToBoolean(elemDesc.fClearOnRight), TextParagraph.TextRunCache);
                    if (IsOptimalParagraph)
                    { 
                        ctx.LineFormatLengthTarget = elemDesc.dcpLim - elemDesc.dcpFirst;
                    } 
                    TextParagraph.FormatLineCore(line, elemDesc.pfsbreakreclineclient, ctx, elemDesc.dcpFirst, elemDesc.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), elemDesc.dcpFirst); 
                    Invariant.Assert(line.SafeLength == elemDesc.dcpLim - elemDesc.dcpFirst, "Line length is out of [....]");
 
                    double duOffset = TextDpi.FromTextDpi(elemDesc.urStart);
                    double dvOffset = TextDpi.FromTextDpi(lineDesc.vrStart);

                    rectangles = line.GetRangeBounds(dcpRangeStart, cchRange, duOffset, dvOffset); 

                    if (!DoubleUtil.IsZero(lineTopSpace)) 
                    { 
                        for (int i = 0, count = rectangles.Count; i < count; ++i)
                        { 
                            Rect r = rectangles[i];
                            r.Y = r.Y - lineTopSpace;
                            r.Height = r.Height + lineTopSpace;
                            rectangles[i] = r; 
                        }
                    } 
 
                    if (!DoubleUtil.IsZero(lineRightSpace))
                    { 
                        // add the rect representing end-of-line / end-of-para
                        rectangles.Add(
                            new Rect(
                                duOffset + TextDpi.FromTextDpi(line.Start + line.Width), 
                                dvOffset - lineTopSpace,
                                lineRightSpace, 
                                TextDpi.FromTextDpi(line.Height) + lineTopSpace 
                                )
                            ); 
                    }

                    //  dispose of the line
                    line.Dispose(); 
                }
            } 
 
            return (rectangles);
        }