Beispiel #1
0
        //--------------------------------------------------------------------
        //
        // Public Properties
        //
        //---------------------------------------------------------------------

        #region Static methods

        public static FixedSOMElement CreateFixedSOMElement(FixedPage page, UIElement uiElement, FixedNode fixedNode, int startIndex, int endIndex)
        {
            FixedSOMElement element = null;

            if (uiElement is Glyphs)
            {
                Glyphs glyphs = uiElement as Glyphs;
                if (glyphs.UnicodeString.Length > 0)
                {
                    GlyphRun glyphRun     = glyphs.ToGlyphRun();
                    Rect     alignmentBox = glyphRun.ComputeAlignmentBox();
                    alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY);
                    GeneralTransform transform = glyphs.TransformToAncestor(page);

                    if (startIndex < 0)
                    {
                        startIndex = 0;
                    }
                    if (endIndex < 0)
                    {
                        endIndex = glyphRun.Characters == null ? 0 : glyphRun.Characters.Count;
                    }
                    element = FixedSOMTextRun.Create(alignmentBox, transform, glyphs, fixedNode, startIndex, endIndex, false);
                }
            }
            else if (uiElement is Image)
            {
                element = FixedSOMImage.Create(page, uiElement as Image, fixedNode);
            }
            else if (uiElement is Path)
            {
                element = FixedSOMImage.Create(page, uiElement as Path, fixedNode);
            }
            return(element);
        }
Beispiel #2
0
        /// <summary>
        /// Retrieves the height and offset, in pixels, of the edge of
        /// the object/character represented by position.
        /// </summary>
        /// <param name="position">
        /// Position of an object/character.
        /// </param>
        /// <param name="transform">
        /// Transform to be applied to returned rect
        /// </param>
        /// <returns>
        /// The height, in pixels, of the edge of the object/character
        /// represented by position.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// </exception>
        /// <remarks>
        /// Rect.Width is always 0.
        /// Output parameter Transform is always Identity. It is not expected that editing scenarios
        /// will require speparate transform with raw rectangle for this case.
        /// If the document is empty, then this method returns the expected
        /// height of a character, if placed at the specified position.
        /// </remarks>
        internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
        {
#if DEBUG
            DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetRectFromTextPosition {0}, {1}", (FixedTextPointer)position, position.LogicalDirection));
#endif

            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedPosition    fixedp;

            // need a default caret size, otherwise infinite corners cause text editor and MultiPageTextView problems.
            // Initialize transform to Identity. This function always returns Identity transform.
            Rect designRect = new Rect(0, 0, 0, 10);
            transform = Transform.Identity;

            Debug.Assert(ftp != null);
            if (ftp.FlowPosition.IsBoundary)
            {
                if (!_GetFirstFixedPosition(ftp, out fixedp))
                {
                    return(designRect);
                }
            }

            else if (!_GetFixedPosition(ftp, out fixedp))
            {
                //
                // This is the start/end element, we need to find out the next element and return the next element
                // start offset/height.
                //
                if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None)
                {
                    ITextPointer     psNext  = position.CreatePointer(1);
                    FixedTextPointer ftpNext = Container.VerifyPosition(psNext);
                    if (!_GetFixedPosition(ftpNext, out fixedp))
                    {
                        return(designRect);
                    }
                }
                else
                {
                    return(designRect);
                }
            }

            if (fixedp.Page != this.PageIndex)
            {
                return(designRect);
            }

            DependencyObject element = this.FixedPage.GetElement(fixedp.Node);
            if (element is Glyphs)
            {
                Glyphs g = (Glyphs)element;
                designRect = _GetGlyphRunDesignRect(g, fixedp.Offset, fixedp.Offset);
                // need to do transform
                GeneralTransform tran = g.TransformToAncestor(this.FixedPage);
                designRect = _GetTransformedCaretRect(tran, designRect.TopLeft, designRect.Height);
            }
            else if (element is Image)
            {
                Image            image  = (Image)element;
                GeneralTransform tran   = image.TransformToAncestor(this.FixedPage);
                Point            offset = new Point(0, 0);
                if (fixedp.Offset > 0)
                {
                    offset.X += image.ActualWidth;
                }
                designRect = _GetTransformedCaretRect(tran, offset, image.ActualHeight);
            }
            else if (element is Path)
            {
                Path             path   = (Path)element;
                GeneralTransform tran   = path.TransformToAncestor(this.FixedPage);
                Rect             bounds = path.Data.Bounds;
                Point            offset = bounds.TopLeft;
                if (fixedp.Offset > 0)
                {
                    offset.X += bounds.Width;
                }
                designRect = _GetTransformedCaretRect(tran, offset, bounds.Height);
            }

            return(designRect);
        }
Beispiel #3
0
        //Processes the Glyphs element, create one or more text runs out of it, add to containing text line and text box
        private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node)
        {
            Debug.Assert(glyphs != null);
            string s = glyphs.UnicodeString;

            if (s.Length == 0 ||
                glyphs.FontRenderingEmSize <= 0)
            {
                return;
            }

            //Multiple table cells separated by wide spaces should be identified
            GlyphRun glyphRun = glyphs.ToGlyphRun();

            if (glyphRun == null)
            {
                //Could not create a GlyphRun out of this Glyphs element
                //Some key properties might be missing/invalid
                return;
            }

            Rect alignmentBox = glyphRun.ComputeAlignmentBox();

            alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY);
            GlyphTypeface    typeFace = glyphRun.GlyphTypeface;
            GeneralTransform trans    = glyphs.TransformToAncestor(_fixedPage);

            int    charIndex          = -1;
            double advWidth           = 0;
            double cumulativeAdvWidth = 0;
            int    lastAdvWidthIndex  = 0;
            int    textRunStartIndex  = 0;
            double lastX      = alignmentBox.Left;
            int    glyphIndex = charIndex;

            do
            {
                charIndex = s.IndexOf(" ", charIndex + 1, s.Length - charIndex - 1, StringComparison.Ordinal);
                if (charIndex >= 0)
                {
                    if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0)
                    {
                        glyphIndex = glyphRun.ClusterMap[charIndex];
                    }
                    else
                    {
                        glyphIndex = charIndex;
                    }
                    //Advance width of the space character in the font
                    double advFont      = typeFace.AdvanceWidths[glyphRun.GlyphIndices[glyphIndex]] * glyphRun.FontRenderingEmSize;
                    double advSpecified = glyphRun.AdvanceWidths[glyphIndex];

                    if ((advSpecified / advFont) > 2)
                    {
                        //Are these seperated by a vertical line?
                        advWidth = 0;
                        for (int i = lastAdvWidthIndex; i < glyphIndex; i++)
                        {
                            advWidth += glyphRun.AdvanceWidths[i];
                        }
                        cumulativeAdvWidth += advWidth;
                        lastAdvWidthIndex   = glyphIndex + 1;


                        if (_lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + cumulativeAdvWidth,
                                                         alignmentBox.Top,
                                                         glyphRun.BaselineOrigin.X + cumulativeAdvWidth + advSpecified,
                                                         alignmentBox.Bottom))
                        {
                            //Create a new FixedTextRun
                            Rect boundingRect = new Rect(lastX, alignmentBox.Top, advWidth + advFont, alignmentBox.Height);

                            int endIndex = charIndex;

                            if ((charIndex == 0 || s[charIndex - 1] == ' ') && (charIndex != s.Length - 1))
                            {
                                endIndex = charIndex + 1;
                            }

                            _CreateTextRun(boundingRect,
                                           trans,
                                           glyphs,
                                           node,
                                           textRunStartIndex,
                                           endIndex);

                            lastX             = lastX + advWidth + advSpecified;
                            textRunStartIndex = charIndex + 1;
                        }
                        cumulativeAdvWidth += advSpecified;
                    }
                }
            } while (charIndex >= 0 && charIndex < s.Length - 1);

            if (textRunStartIndex < s.Length)
            {
                //Last text run
                //For non-partitioned elements this will be the whole Glyphs element
                Rect boundingRect = new Rect(lastX, alignmentBox.Top, alignmentBox.Right - lastX, alignmentBox.Height);

                _CreateTextRun(boundingRect,
                               trans,
                               glyphs,
                               node,
                               textRunStartIndex,
                               s.Length);
            }
        }
        //Processes the Glyphs element, create one or more text runs out of it, add to containing text line and text box
        private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node) 
        {
            Debug.Assert(glyphs != null); 
            string s = glyphs.UnicodeString; 
            if (s.Length == 0 ||
                glyphs.FontRenderingEmSize <= 0) 
            {
                return;
            }
 
           //Multiple table cells separated by wide spaces should be identified
            GlyphRun glyphRun = glyphs.ToGlyphRun(); 
 
            if (glyphRun == null)
            { 
                //Could not create a GlyphRun out of this Glyphs element
                //Some key properties might be missing/invalid
                return;
            } 

            Rect alignmentBox = glyphRun.ComputeAlignmentBox(); 
            alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY); 
            GlyphTypeface typeFace = glyphRun.GlyphTypeface;
            GeneralTransform trans = glyphs.TransformToAncestor(_fixedPage); 

            int charIndex= -1;
            double advWidth = 0;
            double cumulativeAdvWidth = 0; 
            int lastAdvWidthIndex = 0;
            int textRunStartIndex = 0; 
            double lastX = alignmentBox.Left; 
            int glyphIndex = charIndex;
            do 
            {
                charIndex = s.IndexOf(" ", charIndex+1, s.Length - charIndex -1, StringComparison.Ordinal);
                if (charIndex >=0 )
                { 
                    if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0)
                    { 
                        glyphIndex = glyphRun.ClusterMap[charIndex]; 
                    }
                    else 
                    {
                        glyphIndex = charIndex;
                    }
                    //Advance width of the space character in the font 
                    double advFont = typeFace.AdvanceWidths[glyphRun.GlyphIndices[glyphIndex]] * glyphRun.FontRenderingEmSize;
                    double advSpecified = glyphRun.AdvanceWidths[glyphIndex]; 
 
                    if ((advSpecified / advFont) > 2)
                    { 
                        //Are these seperated by a vertical line?
                        advWidth = 0;
                        for (int i=lastAdvWidthIndex; i<glyphIndex; i++)
                        { 
                            advWidth += glyphRun.AdvanceWidths[i];
                        } 
                        cumulativeAdvWidth += advWidth; 
                        lastAdvWidthIndex = glyphIndex + 1;
 

                        if (_lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + cumulativeAdvWidth,
                                                     alignmentBox.Top,
                                                     glyphRun.BaselineOrigin.X + cumulativeAdvWidth + advSpecified, 
                                                     alignmentBox.Bottom))
                        { 
                            //Create a new FixedTextRun 
                            Rect boundingRect = new Rect(lastX, alignmentBox.Top, advWidth + advFont, alignmentBox.Height);
 
                            int endIndex = charIndex;

                            if ((charIndex == 0 || s[charIndex-1] == ' ') && (charIndex != s.Length - 1))
                            { 
                                endIndex = charIndex + 1;
                            } 
 
                            _CreateTextRun(boundingRect,
                                           trans, 
                                           glyphs,
                                           node,
                                           textRunStartIndex,
                                           endIndex); 

                            lastX = lastX + advWidth + advSpecified; 
                            textRunStartIndex = charIndex+1; 
                        }
                        cumulativeAdvWidth += advSpecified; 
                    }

                }
            } while (charIndex >= 0 && charIndex < s.Length-1); 

            if (textRunStartIndex < s.Length) 
            { 
                //Last text run
                //For non-partitioned elements this will be the whole Glyphs element 
                Rect boundingRect = new Rect(lastX, alignmentBox.Top, alignmentBox.Right-lastX, alignmentBox.Height);

                _CreateTextRun( boundingRect,
                                trans, 
                                glyphs,
                                node, 
                                textRunStartIndex, 
                                s.Length);
            } 
        }
        internal void RenderFixedNode(DrawingContext dc)
        {
            //
            //Iterate through fix node to draw red dotted line
            //
            CultureInfo EnglishCulture = System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS;

            int lineCount = _lineResults.Length;

            if (lineCount == 0)
            {
                return;
            }

            FixedNode fixedStartPage = _lineResults[0].Start;
            FixedNode fixedEndPage   = _lineResults[lineCount - 1].End;

            FixedNode[]   fixedNodes = _fixedTextBuilder.FixedFlowMap.FixedOrderGetRangeNodes(fixedStartPage, fixedEndPage);
            FixedPage     fp         = _fixedTextBuilder.FixedTextContainer.FixedDocument.GetFixedPage(PageIndex);
            FormattedText ft;
            Point         prevTextPoint = new Point(0, 0);
            DpiScale      dpi           = fp.GetDpi();

            foreach (FixedNode currentFixedNode in fixedNodes)
            {
                if (currentFixedNode.Page == FixedFlowMap.FixedOrderStartPage)
                {
                    prevTextPoint.X = prevTextPoint.Y = 0;
                    ft = new FormattedText("FixedOrderStartPage",
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }
                if (currentFixedNode.Page == FixedFlowMap.FixedOrderEndPage)
                {
                    prevTextPoint.X = fp.Width - 100;
                    prevTextPoint.Y = fp.Height - 10;
                    ft = new FormattedText("FixedOrderEndPage",
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }
                if (currentFixedNode[1] == FixedFlowMap.FixedOrderStartVisual ||
                    currentFixedNode[1] == FixedFlowMap.FixedOrderEndVisual)
                {
                    prevTextPoint.X = 2;
                    prevTextPoint.Y = prevTextPoint.Y + 10;
                    String outputString = currentFixedNode[1] == FixedFlowMap.FixedOrderStartVisual ?
                                          "FixedOrderStartVisual" : "FixedOrderEndVisual";
                    ft = new FormattedText(outputString,
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }

                DependencyObject dependencyObject = fp.GetElement(currentFixedNode);

                Image image = dependencyObject as Image;
                if (image != null)
                {
                    GeneralTransform transform = image.TransformToAncestor(fp);
                    // You can't use GetContentBounds inside OnRender
                    Rect boundingRect = new Rect(0, 0, image.Width, image.Height);
                    Rect imageRect    = transform.TransformBounds(boundingRect);

                    if (!imageRect.IsEmpty)
                    {
                        // Image might overlap, inflate the box.
                        imageRect.Inflate(1, 1);

                        Pen pen = new Pen(Brushes.DarkMagenta, 1.5);
                        DrawRectOutline(dc, pen, imageRect);

                        prevTextPoint.X = imageRect.Right;
                        prevTextPoint.Y = imageRect.Bottom - 10;
                    }
                    else
                    {
                        prevTextPoint.X = 2;
                        prevTextPoint.Y = prevTextPoint.Y + 10;
                    }
                    ft = new FormattedText(currentFixedNode.ToString(),
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }
                Path path = dependencyObject as Path;
                if (path != null)
                {
                    GeneralTransform transform = path.TransformToAncestor(fp);
                    // You can't use GetContentBounds inside OnRender
                    Rect boundingRect = path.Data.Bounds;
                    Rect imageRect    = transform.TransformBounds(boundingRect);

                    if (!imageRect.IsEmpty)
                    {
                        // Image might overlap, inflate the box.
                        imageRect.Inflate(1, 1);

                        Pen pen = new Pen(Brushes.DarkMagenta, 1.5);
                        DrawRectOutline(dc, pen, imageRect);

                        prevTextPoint.X = imageRect.Right;
                        prevTextPoint.Y = imageRect.Bottom - 10;
                    }
                    else
                    {
                        prevTextPoint.X = 2;
                        prevTextPoint.Y = prevTextPoint.Y + 10;
                    }
                    ft = new FormattedText(currentFixedNode.ToString(),
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }
                Glyphs glyphs = dependencyObject as Glyphs;
                if (glyphs != null)
                {
                    GlyphRun run = glyphs.ToGlyphRun();
                    if (run != null)
                    {
                        Rect glyphBox = run.ComputeAlignmentBox();
                        glyphBox.Offset(glyphs.OriginX, glyphs.OriginY);
                        GeneralTransform transform = glyphs.TransformToAncestor(fp);
                        //
                        // Draw it using the dotted red line
                        //
                        Pen       pen = new Pen(Brushes.Red, 0.5);
                        Transform t   = transform.AffineTransform;
                        if (t != null)
                        {
                            dc.PushTransform(t);
                        }
                        else
                        {
                            dc.PushTransform(Transform.Identity);
                        }
                        DrawRectOutline(dc, pen, glyphBox);

                        prevTextPoint.X = glyphBox.Right;
                        prevTextPoint.Y = glyphBox.Bottom;
                        transform.TryTransform(prevTextPoint, out prevTextPoint);
                        dc.Pop(); // transform
                    }
                    else
                    {
                        prevTextPoint.X = 2;
                        prevTextPoint.Y = prevTextPoint.Y + 10;
                    }

                    ft = new FormattedText(currentFixedNode.ToString(),
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkViolet,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);
                    continue;
                }

                //
                // For anything else, there is this code to draw ...
                //
                prevTextPoint.X = 2;
                prevTextPoint.Y = prevTextPoint.Y + 10;
                ft = new FormattedText(currentFixedNode.ToString(),
                                       EnglishCulture,
                                       FlowDirection.LeftToRight,
                                       new Typeface("Courier New"),
                                       8,
                                       Brushes.DarkViolet,
                                       dpi.PixelsPerDip);
                dc.DrawText(ft, prevTextPoint);
            }
        }
Beispiel #6
0
        //determines whether and where a rectangle intersects a Glyphs
        private bool IntersectGlyphs(Glyphs g, double top, double left, double bottom, double right, out int begin, out int end, out bool includeEnd, out double baseline, out double height)
        {
            begin      = 0;
            end        = 0;
            includeEnd = false;

            GlyphRun run          = g.ToGlyphRun();
            Rect     boundingRect = run.ComputeAlignmentBox();

            boundingRect.Offset(run.BaselineOrigin.X, run.BaselineOrigin.Y);

            //useful for same line detection
            baseline = run.BaselineOrigin.Y;
            height   = boundingRect.Height;

            double           centerLine = boundingRect.Y + .5 * boundingRect.Height;
            GeneralTransform t          = g.TransformToAncestor(_page);

            Point pt1;

            t.TryTransform(new Point(boundingRect.Left, centerLine), out pt1);
            Point pt2;

            t.TryTransform(new Point(boundingRect.Right, centerLine), out pt2);

            double dStart, dEnd;

            bool cross = false;

            if (pt1.X < left)
            {
                if (pt2.X < left)
                {
                    return(false);
                }
                cross = true;
            }
            else if (pt1.X > right)
            {
                if (pt2.X > right)
                {
                    return(false);
                }
                cross = true;
            }
            else if (pt2.X < left || pt2.X > right)
            {
                cross = true;
            }

            if (cross)
            {
                double d1 = (left - pt1.X) / (pt2.X - pt1.X);
                double d2 = (right - pt1.X) / (pt2.X - pt1.X);
                if (d2 > d1)
                {
                    dStart = d1;
                    dEnd   = d2;
                }
                else
                {
                    dStart = d2;
                    dEnd   = d1;
                }
            }
            else
            {
                dStart = 0;
                dEnd   = 1;
            }

            cross = false;
            if (pt1.Y < top)
            {
                if (pt2.Y < top)
                {
                    return(false);
                }
                cross = true;
            }
            else if (pt1.Y > bottom)
            {
                if (pt2.Y > bottom)
                {
                    return(false);
                }
                cross = true;
            }
            else if (pt2.Y < top || pt2.Y > bottom)
            {
                cross = true;
            }

            if (cross)
            {
                double d1 = (top - pt1.Y) / (pt2.Y - pt1.Y);
                double d2 = (bottom - pt1.Y) / (pt2.Y - pt1.Y);
                if (d2 > d1)
                {
                    if (d1 > dStart)
                    {
                        dStart = d1;
                    }
                    if (d2 < dEnd)
                    {
                        dEnd = d2;
                    }
                }
                else
                {
                    if (d2 > dStart)
                    {
                        dStart = d2;
                    }
                    if (d1 < dEnd)
                    {
                        dEnd = d1;
                    }
                }
            }

            dStart = boundingRect.Left + boundingRect.Width * dStart;
            dEnd   = boundingRect.Left + boundingRect.Width * dEnd;

            bool leftToRight = ((run.BidiLevel & 1) == 0);

            begin = GlyphRunHitTest(run, dStart, leftToRight);
            end   = GlyphRunHitTest(run, dEnd, leftToRight);

            if (begin > end)
            {
                int temp = begin;
                begin = end;
                end   = temp;
            }

            Debug.Assert(end >= begin);

            int characterCount = (run.Characters == null) ? 0 : run.Characters.Count;

            includeEnd = (end == characterCount);

            return(true);
        }
        //determines whether and where a rectangle intersects a Glyphs
        private bool IntersectGlyphs(Glyphs g, double top, double left, double bottom, double right, out int begin, out int end, out bool includeEnd, out double baseline, out double height)
        {
            begin = 0; 
            end = 0;
            includeEnd = false; 
 
            GlyphRun run = g.ToGlyphRun();
            Rect boundingRect = run.ComputeAlignmentBox(); 
            boundingRect.Offset(run.BaselineOrigin.X, run.BaselineOrigin.Y);

            //useful for same line detection
            baseline = run.BaselineOrigin.Y; 
            height = boundingRect.Height;
 
            double centerLine = boundingRect.Y + .5 * boundingRect.Height; 
            GeneralTransform t = g.TransformToAncestor(_page);
 
            Point pt1;
            t.TryTransform(new Point(boundingRect.Left, centerLine), out pt1);
            Point pt2;
            t.TryTransform(new Point(boundingRect.Right, centerLine), out pt2); 

            double dStart, dEnd; 
 
            bool cross = false;
            if (pt1.X < left) 
            {
                if (pt2.X < left)
                {
                    return false; 
                }
                cross = true; 
            } 
            else if (pt1.X > right)
            { 
                if (pt2.X > right)
                {
                    return false;
                } 
                cross = true;
            } 
            else if (pt2.X < left || pt2.X > right) 
            {
                cross = true; 
            }

            if (cross)
            { 
                double d1 = (left - pt1.X) / (pt2.X - pt1.X);
                double d2 = (right - pt1.X) / (pt2.X - pt1.X); 
                if (d2 > d1) 
                {
                    dStart = d1; 
                    dEnd = d2;
                }
                else
                { 
                    dStart = d2;
                    dEnd = d1; 
                } 
            }
            else 
            {
                dStart = 0;
                dEnd = 1;
            } 

            cross = false; 
            if (pt1.Y < top) 
            {
                if (pt2.Y < top) 
                {
                    return false;
                }
                cross = true; 
            }
            else if (pt1.Y > bottom) 
            { 
                if (pt2.Y > bottom)
                { 
                    return false;
                }
                cross = true;
            } 
            else if (pt2.Y < top || pt2.Y > bottom)
            { 
                cross = true; 
            }
 
            if (cross)
            {
                double d1 = (top - pt1.Y) / (pt2.Y - pt1.Y);
                double d2 = (bottom - pt1.Y) / (pt2.Y - pt1.Y); 
                if (d2 > d1)
                { 
                    if (d1 > dStart) 
                    {
                        dStart = d1; 
                    }
                    if (d2 < dEnd)
                    {
                        dEnd = d2; 
                    }
                } 
                else 
                {
                    if (d2 > dStart) 
                    {
                    dStart = d2;
                    }
                    if (d1 < dEnd) 
                    {
                        dEnd = d1; 
                    } 
                }
            } 

            dStart = boundingRect.Left + boundingRect.Width * dStart;
            dEnd = boundingRect.Left + boundingRect.Width * dEnd;
 
            bool leftToRight = ((run.BidiLevel & 1) == 0);
 
            begin = GlyphRunHitTest(run, dStart, leftToRight); 
            end = GlyphRunHitTest(run, dEnd, leftToRight);
 
            if (begin > end)
            {
                int temp = begin;
                begin = end; 
                end = temp;
            } 
 
            Debug.Assert(end >= begin);
 
            int characterCount = (run.Characters == null) ? 0 : run.Characters.Count;
            includeEnd = (end == characterCount);

            return true; 
        }
        // Token: 0x06002EDF RID: 11999 RVA: 0x000D3640 File Offset: 0x000D1840
        internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
        {
            FixedTextPointer fixedTextPointer = this.Container.VerifyPosition(position);
            Rect             result           = new Rect(0.0, 0.0, 0.0, 10.0);

            transform = Transform.Identity;
            FixedPosition fixedPosition;

            if (fixedTextPointer.FlowPosition.IsBoundary)
            {
                if (!this._GetFirstFixedPosition(fixedTextPointer, out fixedPosition))
                {
                    return(result);
                }
            }
            else if (!this._GetFixedPosition(fixedTextPointer, out fixedPosition))
            {
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.None)
                {
                    return(result);
                }
                ITextPointer     position2 = position.CreatePointer(1);
                FixedTextPointer ftp       = this.Container.VerifyPosition(position2);
                if (!this._GetFixedPosition(ftp, out fixedPosition))
                {
                    return(result);
                }
            }
            if (fixedPosition.Page != this.PageIndex)
            {
                return(result);
            }
            DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node);

            if (element is Glyphs)
            {
                Glyphs glyphs = (Glyphs)element;
                result = FixedTextView._GetGlyphRunDesignRect(glyphs, fixedPosition.Offset, fixedPosition.Offset);
                GeneralTransform transform2 = glyphs.TransformToAncestor(this.FixedPage);
                result = this._GetTransformedCaretRect(transform2, result.TopLeft, result.Height);
            }
            else if (element is Image)
            {
                Image            image      = (Image)element;
                GeneralTransform transform3 = image.TransformToAncestor(this.FixedPage);
                Point            origin     = new Point(0.0, 0.0);
                if (fixedPosition.Offset > 0)
                {
                    origin.X += image.ActualWidth;
                }
                result = this._GetTransformedCaretRect(transform3, origin, image.ActualHeight);
            }
            else if (element is Path)
            {
                Path             path       = (Path)element;
                GeneralTransform transform4 = path.TransformToAncestor(this.FixedPage);
                Rect             bounds     = path.Data.Bounds;
                Point            topLeft    = bounds.TopLeft;
                if (fixedPosition.Offset > 0)
                {
                    topLeft.X += bounds.Width;
                }
                result = this._GetTransformedCaretRect(transform4, topLeft, bounds.Height);
            }
            return(result);
        }
Beispiel #9
0
        // Token: 0x0600350F RID: 13583 RVA: 0x000F0670 File Offset: 0x000EE870
        private bool IntersectGlyphs(Glyphs g, double top, double left, double bottom, double right, out int begin, out int end, out bool includeEnd, out double baseline, out double height)
        {
            begin      = 0;
            end        = 0;
            includeEnd = false;
            GlyphRun glyphRun = g.ToGlyphRun();
            Rect     rect     = glyphRun.ComputeAlignmentBox();

            rect.Offset(glyphRun.BaselineOrigin.X, glyphRun.BaselineOrigin.Y);
            baseline = glyphRun.BaselineOrigin.Y;
            height   = rect.Height;
            double           y = rect.Y + 0.5 * rect.Height;
            GeneralTransform generalTransform = g.TransformToAncestor(this._page);
            Point            point;

            generalTransform.TryTransform(new Point(rect.Left, y), out point);
            Point point2;

            generalTransform.TryTransform(new Point(rect.Right, y), out point2);
            bool flag = false;

            if (point.X < left)
            {
                if (point2.X < left)
                {
                    return(false);
                }
                flag = true;
            }
            else if (point.X > right)
            {
                if (point2.X > right)
                {
                    return(false);
                }
                flag = true;
            }
            else if (point2.X < left || point2.X > right)
            {
                flag = true;
            }
            double num3;
            double num4;

            if (flag)
            {
                double num  = (left - point.X) / (point2.X - point.X);
                double num2 = (right - point.X) / (point2.X - point.X);
                if (num2 > num)
                {
                    num3 = num;
                    num4 = num2;
                }
                else
                {
                    num3 = num2;
                    num4 = num;
                }
            }
            else
            {
                num3 = 0.0;
                num4 = 1.0;
            }
            flag = false;
            if (point.Y < top)
            {
                if (point2.Y < top)
                {
                    return(false);
                }
                flag = true;
            }
            else if (point.Y > bottom)
            {
                if (point2.Y > bottom)
                {
                    return(false);
                }
                flag = true;
            }
            else if (point2.Y < top || point2.Y > bottom)
            {
                flag = true;
            }
            if (flag)
            {
                double num5 = (top - point.Y) / (point2.Y - point.Y);
                double num6 = (bottom - point.Y) / (point2.Y - point.Y);
                if (num6 > num5)
                {
                    if (num5 > num3)
                    {
                        num3 = num5;
                    }
                    if (num6 < num4)
                    {
                        num4 = num6;
                    }
                }
                else
                {
                    if (num6 > num3)
                    {
                        num3 = num6;
                    }
                    if (num5 < num4)
                    {
                        num4 = num5;
                    }
                }
            }
            num3 = rect.Left + rect.Width * num3;
            num4 = rect.Left + rect.Width * num4;
            bool ltr = (glyphRun.BidiLevel & 1) == 0;

            begin = this.GlyphRunHitTest(glyphRun, num3, ltr);
            end   = this.GlyphRunHitTest(glyphRun, num4, ltr);
            if (begin > end)
            {
                int num7 = begin;
                begin = end;
                end   = num7;
            }
            int num8 = (glyphRun.Characters == null) ? 0 : glyphRun.Characters.Count;

            includeEnd = (end == num8);
            return(true);
        }
Beispiel #10
0
        // Token: 0x06002DF9 RID: 11769 RVA: 0x000CEA3C File Offset: 0x000CCC3C
        private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node)
        {
            string unicodeString = glyphs.UnicodeString;

            if (unicodeString.Length == 0 || glyphs.FontRenderingEmSize <= 0.0)
            {
                return;
            }
            GlyphRun glyphRun = glyphs.ToGlyphRun();

            if (glyphRun == null)
            {
                return;
            }
            Rect rect = glyphRun.ComputeAlignmentBox();

            rect.Offset(glyphs.OriginX, glyphs.OriginY);
            GlyphTypeface    glyphTypeface = glyphRun.GlyphTypeface;
            GeneralTransform trans         = glyphs.TransformToAncestor(this._fixedPage);
            int    num  = -1;
            double num2 = 0.0;
            int    num3 = 0;
            int    num4 = 0;
            double num5 = rect.Left;

            do
            {
                num = unicodeString.IndexOf(" ", num + 1, unicodeString.Length - num - 1, StringComparison.Ordinal);
                if (num >= 0)
                {
                    int num6;
                    if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0)
                    {
                        num6 = (int)glyphRun.ClusterMap[num];
                    }
                    else
                    {
                        num6 = num;
                    }
                    double num7 = glyphTypeface.AdvanceWidths[glyphRun.GlyphIndices[num6]] * glyphRun.FontRenderingEmSize;
                    double num8 = glyphRun.AdvanceWidths[num6];
                    if (num8 / num7 > 2.0)
                    {
                        double num9 = 0.0;
                        for (int i = num3; i < num6; i++)
                        {
                            num9 += glyphRun.AdvanceWidths[i];
                        }
                        num2 += num9;
                        num3  = num6 + 1;
                        if (this._lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + num2, rect.Top, glyphRun.BaselineOrigin.X + num2 + num8, rect.Bottom))
                        {
                            Rect boundingRect = new Rect(num5, rect.Top, num9 + num7, rect.Height);
                            int  endIndex     = num;
                            if ((num == 0 || unicodeString[num - 1] == ' ') && num != unicodeString.Length - 1)
                            {
                                endIndex = num + 1;
                            }
                            this._CreateTextRun(boundingRect, trans, glyphs, node, num4, endIndex);
                            num5 = num5 + num9 + num8;
                            num4 = num + 1;
                        }
                        num2 += num8;
                    }
                }
            }while (num >= 0 && num < unicodeString.Length - 1);
            if (num4 < unicodeString.Length)
            {
                Rect boundingRect2 = new Rect(num5, rect.Top, rect.Right - num5, rect.Height);
                this._CreateTextRun(boundingRect2, trans, glyphs, node, num4, unicodeString.Length);
            }
        }