コード例 #1
0
ファイル: FixedSOMElement.cs プロジェクト: beda2280/wpf-1
        //--------------------------------------------------------------------
        //
        // 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);
        }
コード例 #2
0
        // Token: 0x06002EE3 RID: 12003 RVA: 0x000D3B5C File Offset: 0x000D1D5C
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        {
            FixedTextPointer ftp = this.Container.VerifyPosition(position);
            FixedPosition    fixedPosition;

            if (this._GetFixedPosition(ftp, out fixedPosition))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node);
                if (element is Glyphs)
                {
                    Glyphs       glyphs       = (Glyphs)element;
                    GlyphRun     glyphRun     = glyphs.ToGlyphRun();
                    int          num          = (glyphRun.Characters == null) ? 0 : glyphRun.Characters.Count;
                    CharacterHit characterHit = (fixedPosition.Offset == num) ? new CharacterHit(fixedPosition.Offset - 1, 1) : new CharacterHit(fixedPosition.Offset, 0);
                    CharacterHit obj          = (direction == LogicalDirection.Forward) ? glyphRun.GetNextCaretCharacterHit(characterHit) : glyphRun.GetPreviousCaretCharacterHit(characterHit);
                    if (!characterHit.Equals(obj))
                    {
                        LogicalDirection edge = LogicalDirection.Forward;
                        if (obj.TrailingLength > 0)
                        {
                            edge = LogicalDirection.Backward;
                        }
                        int offset = obj.FirstCharacterIndex + obj.TrailingLength;
                        return(this._CreateTextPointer(new FixedPosition(fixedPosition.Node, offset), edge));
                    }
                }
            }
            ITextPointer textPointer = position.CreatePointer();

            textPointer.MoveToNextInsertionPosition(direction);
            return(textPointer);
        }
コード例 #3
0
        // Token: 0x06002EF1 RID: 12017 RVA: 0x000D3FAC File Offset: 0x000D21AC
        private ITextPointer _SnapToText(Point point)
        {
            FixedNode[]  line = this.Container.FixedTextBuilder.GetLine(this.PageIndex, point);
            ITextPointer textPointer;

            if (line != null && line.Length != 0)
            {
                double    num       = double.MaxValue;
                double    xoffset   = 0.0;
                Glyphs    glyphs    = null;
                FixedNode fixedNode = line[0];
                foreach (FixedNode fixedNode2 in line)
                {
                    Glyphs           glyphsElement    = this.FixedPage.GetGlyphsElement(fixedNode2);
                    GeneralTransform generalTransform = this.FixedPage.TransformToDescendant(glyphsElement);
                    Point            inPoint          = point;
                    if (generalTransform != null)
                    {
                        generalTransform.TryTransform(inPoint, out inPoint);
                    }
                    GlyphRun glyphRun = glyphsElement.ToGlyphRun();
                    Rect     rect     = glyphRun.ComputeAlignmentBox();
                    rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY);
                    double num2 = Math.Max(0.0, (inPoint.X > rect.X) ? (inPoint.X - rect.Right) : (rect.X - inPoint.X));
                    double num3 = Math.Max(0.0, (inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y));
                    double num4 = num2 + num3;
                    if (glyphs == null || num4 < num)
                    {
                        num       = num4;
                        glyphs    = glyphsElement;
                        fixedNode = fixedNode2;
                        xoffset   = inPoint.X;
                    }
                }
                int offset;
                LogicalDirection edge;
                this._GlyphRunHitTest(glyphs, xoffset, out offset, out edge);
                FixedPosition fixedPosition = new FixedPosition(fixedNode, offset);
                textPointer = this._CreateTextPointer(fixedPosition, edge);
            }
            else if (point.Y < this.FixedPage.Height / 2.0)
            {
                textPointer = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward);
                textPointer.MoveToInsertionPosition(LogicalDirection.Forward);
            }
            else
            {
                textPointer = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward);
                textPointer.MoveToInsertionPosition(LogicalDirection.Backward);
            }
            return(textPointer);
        }
コード例 #4
0
        // Token: 0x06002EF4 RID: 12020 RVA: 0x000D4420 File Offset: 0x000D2620
        internal static Rect _GetGlyphRunDesignRect(Glyphs g, int charStart, int charEnd)
        {
            GlyphRun glyphRun = g.ToGlyphRun();

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

            result.Offset(glyphRun.BaselineOrigin.X, glyphRun.BaselineOrigin.Y);
            int num = 0;

            if (glyphRun.Characters != null)
            {
                num = glyphRun.Characters.Count;
            }
            else if (g.UnicodeString != null)
            {
                num = g.UnicodeString.Length;
            }
            if (charStart > num)
            {
                charStart = num;
            }
            else if (charStart < 0)
            {
                charStart = 0;
            }
            if (charEnd > num)
            {
                charEnd = num;
            }
            else if (charEnd < 0)
            {
                charEnd = 0;
            }
            double num2  = FixedTextView._GetDistanceToCharacter(glyphRun, charStart);
            double num3  = FixedTextView._GetDistanceToCharacter(glyphRun, charEnd);
            double width = num3 - num2;

            if ((glyphRun.BidiLevel & 1) != 0)
            {
                result.X = glyphRun.BaselineOrigin.X - num3;
            }
            else
            {
                result.X = glyphRun.BaselineOrigin.X + num2;
            }
            result.Width = width;
            return(result);
        }
コード例 #5
0
 // Token: 0x0600301A RID: 12314 RVA: 0x000D8690 File Offset: 0x000D6890
 private void _UpdateHighlightForeground(DrawingContext dc, ArrayList highlights)
 {
     foreach (object obj in highlights)
     {
         FixedHighlight fixedHighlight = (FixedHighlight)obj;
         Brush          brush          = null;
         if (fixedHighlight.HighlightType != FixedHighlightType.None)
         {
             Glyphs glyphs = fixedHighlight.Glyphs;
             if (glyphs != null)
             {
                 Rect rect = fixedHighlight.ComputeDesignRect();
                 if (!(rect == Rect.Empty))
                 {
                     GeneralTransform generalTransform = fixedHighlight.Element.TransformToAncestor(this._page);
                     Transform        affineTransform  = generalTransform.AffineTransform;
                     if (affineTransform != null)
                     {
                         dc.PushTransform(affineTransform);
                     }
                     else
                     {
                         dc.PushTransform(Transform.Identity);
                     }
                     dc.PushClip(new RectangleGeometry(rect));
                     if (fixedHighlight.HighlightType == FixedHighlightType.TextSelection)
                     {
                         brush = SelectionHighlightInfo.ForegroundBrush;
                     }
                     else if (fixedHighlight.HighlightType == FixedHighlightType.AnnotationHighlight)
                     {
                         brush = fixedHighlight.ForegroundBrush;
                     }
                     GlyphRun glyphRun = glyphs.ToGlyphRun();
                     if (brush == null)
                     {
                         brush = glyphs.Fill;
                     }
                     dc.PushGuidelineY1(glyphRun.BaselineOrigin.Y);
                     dc.PushClip(glyphs.Clip);
                     dc.DrawGlyphRun(brush, glyphRun);
                     dc.Pop();
                     dc.Pop();
                     dc.Pop();
                     dc.Pop();
                 }
             }
         }
     }
 }
コード例 #6
0
ファイル: FixedTextView.cs プロジェクト: dox0/DotNet471RS3
        /// <summary>
        /// Finds the next position at the edge of a caret unit in
        /// specified direction.
        /// </summary>
        /// <param name="position">
        /// Initial text position of an object/character.
        /// </param>
        /// <param name="direction">
        /// If Forward, this method returns the "caret unit" position following
        /// the initial position.
        /// If Backward, this method returns the caret unit" position preceding
        /// the initial position.
        /// </param>
        /// <returns>
        /// The next caret unit break position in specified direction.
        /// </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>
        /// In the context of this method, "caret unit" refers to a group of one
        /// or more Unicode code points that map to a single rendered glyph.
        ///
        /// If position is located between two caret units, this method returns
        /// a new position located at the opposite edge of the caret unit in
        /// the indicated direction.
        /// If position is located within a group of Unicode code points that map
        /// to a single caret unit, this method returns a new position at
        /// the indicated edge of the containing caret unit.
        /// If position is located at the beginning of end of content -- there is
        /// no content in the indicated direction -- then this method returns
        /// a position located at the same location as initial position.
        /// </remarks>
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        {
            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedPosition    fixedp;

            if (_GetFixedPosition(ftp, out fixedp))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedp.Node);
                if (element is Glyphs)
                {
                    Glyphs   g   = (Glyphs)element;
                    GlyphRun run = g.ToGlyphRun();

                    int          characterCount = (run.Characters == null) ? 0 : run.Characters.Count;
                    CharacterHit start          = (fixedp.Offset == characterCount) ?
                                                  new CharacterHit(fixedp.Offset - 1, 1) :
                                                  new CharacterHit(fixedp.Offset, 0);
                    CharacterHit next = (direction == LogicalDirection.Forward) ?
                                        run.GetNextCaretCharacterHit(start) :
                                        run.GetPreviousCaretCharacterHit(start);

                    if (!start.Equals(next))
                    {
                        LogicalDirection edge = LogicalDirection.Forward;
                        if (next.TrailingLength > 0)
                        {
                            edge = LogicalDirection.Backward;
                        }

                        int index = next.FirstCharacterIndex + next.TrailingLength;

                        return(_CreateTextPointer(new FixedPosition(fixedp.Node, index), edge));
                    }
                }
            }
            //default behavior is to simply move textpointer
            ITextPointer pointer = position.CreatePointer();

            pointer.MoveToNextInsertionPosition(direction);
            return(pointer);
        }
コード例 #7
0
        // Token: 0x06002EF0 RID: 12016 RVA: 0x000D3F34 File Offset: 0x000D2134
        private void _GlyphRunHitTest(Glyphs g, double xoffset, out int charIndex, out LogicalDirection edge)
        {
            charIndex = 0;
            edge      = LogicalDirection.Forward;
            GlyphRun glyphRun = g.ToGlyphRun();
            double   distance;

            if ((glyphRun.BidiLevel & 1) != 0)
            {
                distance = glyphRun.BaselineOrigin.X - xoffset;
            }
            else
            {
                distance = xoffset - glyphRun.BaselineOrigin.X;
            }
            bool         flag;
            CharacterHit caretCharacterHitFromDistance = glyphRun.GetCaretCharacterHitFromDistance(distance, out flag);

            charIndex = caretCharacterHitFromDistance.FirstCharacterIndex + caretCharacterHitFromDistance.TrailingLength;
            edge      = ((caretCharacterHitFromDistance.TrailingLength > 0) ? LogicalDirection.Backward : LogicalDirection.Forward);
        }
コード例 #8
0
ファイル: FixedTextView.cs プロジェクト: dox0/DotNet471RS3
        private void _GlyphRunHitTest(Glyphs g, double xoffset, out int charIndex, out LogicalDirection edge)
        {
            charIndex = 0;
            edge      = LogicalDirection.Forward;

            GlyphRun run = g.ToGlyphRun();
            bool     isInside;

            double distance;

            if ((run.BidiLevel & 1) != 0)
            {
                distance = run.BaselineOrigin.X - xoffset;
            }
            else
            {
                distance = xoffset - run.BaselineOrigin.X;
            }

            CharacterHit hit = run.GetCaretCharacterHitFromDistance(distance, out isInside);

            charIndex = hit.FirstCharacterIndex + hit.TrailingLength;
            edge      = (hit.TrailingLength > 0) ? LogicalDirection.Backward : LogicalDirection.Forward;
        }
コード例 #9
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; 
        }
コード例 #10
0
ファイル: FixedTextView.cs プロジェクト: dox0/DotNet471RS3
        // char index == -1 implies end of run.
        internal static Rect _GetGlyphRunDesignRect(Glyphs g, int charStart, int charEnd)
        {
            GlyphRun run = g.ToGlyphRun();

            if (run == null)
            {
                return(Rect.Empty);
            }

            Rect designRect = run.ComputeAlignmentBox();

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

            int charCount = 0;

            if (run.Characters != null)
            {
                charCount = run.Characters.Count;
            }
            else if (g.UnicodeString != null)
            {
                charCount = g.UnicodeString.Length;
            }

            if (charStart > charCount)
            {
                //Extra space was added at the end of the run for contiguity
                Debug.Assert(charStart - charCount == 1);
                charStart = charCount;
            }
            else if (charStart < 0)
            {
                //This is a reversed run
                charStart = 0;
            }
            if (charEnd > charCount)
            {
                //Extra space was added at the end of the run for contiguity
                Debug.Assert(charEnd - charCount == 1);
                charEnd = charCount;
            }
            else if (charEnd < 0)
            {
                //This is a reversed run
                charEnd = 0;
            }


            double x1    = _GetDistanceToCharacter(run, charStart);
            double x2    = _GetDistanceToCharacter(run, charEnd);
            double width = x2 - x1;

            if ((run.BidiLevel & 1) != 0)
            {
                // right to left
                designRect.X = run.BaselineOrigin.X - x2;
            }
            else
            {
                designRect.X = run.BaselineOrigin.X + x1;
            }

            designRect.Width = width;

            return(designRect);
        }
コード例 #11
0
        // Token: 0x06002E37 RID: 11831 RVA: 0x000D0E28 File Offset: 0x000CF028
        public static FixedSOMTextRun Create(Rect boundingRect, GeneralTransform transform, Glyphs glyphs, FixedNode fixedNode, int startIndex, int endIndex, bool allowReverseGlyphs)
        {
            if (string.IsNullOrEmpty(glyphs.UnicodeString) || glyphs.FontRenderingEmSize <= 0.0)
            {
                return(null);
            }
            FixedSOMTextRun fixedSOMTextRun = new FixedSOMTextRun(boundingRect, transform, fixedNode, startIndex, endIndex);

            fixedSOMTextRun._fontUri     = glyphs.FontUri;
            fixedSOMTextRun._cultureInfo = glyphs.Language.GetCompatibleCulture();
            fixedSOMTextRun._bidiLevel   = glyphs.BidiLevel;
            fixedSOMTextRun._isSideways  = glyphs.IsSideways;
            fixedSOMTextRun._fontSize    = glyphs.FontRenderingEmSize;
            GlyphRun      glyphRun      = glyphs.ToGlyphRun();
            GlyphTypeface glyphTypeface = glyphRun.GlyphTypeface;

            glyphTypeface.FamilyNames.TryGetValue(fixedSOMTextRun._cultureInfo, out fixedSOMTextRun._fontFamily);
            if (fixedSOMTextRun._fontFamily == null)
            {
                glyphTypeface.FamilyNames.TryGetValue(TypeConverterHelper.InvariantEnglishUS, out fixedSOMTextRun._fontFamily);
            }
            fixedSOMTextRun._fontStyle        = glyphTypeface.Style;
            fixedSOMTextRun._fontWeight       = glyphTypeface.Weight;
            fixedSOMTextRun._fontStretch      = glyphTypeface.Stretch;
            fixedSOMTextRun._defaultCharWidth = ((glyphTypeface.XHeight > 0.0) ? (glyphTypeface.XHeight * glyphs.FontRenderingEmSize) : glyphRun.AdvanceWidths[startIndex]);
            Transform affineTransform = transform.AffineTransform;

            if (affineTransform != null && !affineTransform.Value.IsIdentity)
            {
                Matrix value = affineTransform.Value;
                double num   = Math.Sqrt(value.M12 * value.M12 + value.M22 * value.M22);
                double num2  = Math.Sqrt(value.M11 * value.M11 + value.M21 * value.M21);
                fixedSOMTextRun._fontSize         *= num;
                fixedSOMTextRun._defaultCharWidth *= num2;
            }
            fixedSOMTextRun._foreground = glyphs.Fill;
            string unicodeString = glyphs.UnicodeString;

            fixedSOMTextRun.Text = unicodeString.Substring(startIndex, endIndex - startIndex);
            if (allowReverseGlyphs && fixedSOMTextRun._bidiLevel == 0 && !fixedSOMTextRun._isSideways && startIndex == 0 && endIndex == unicodeString.Length && string.IsNullOrEmpty(glyphs.CaretStops) && FixedTextBuilder.MostlyRTL(unicodeString))
            {
                char[] array = new char[fixedSOMTextRun.Text.Length];
                for (int i = 0; i < fixedSOMTextRun.Text.Length; i++)
                {
                    array[i] = fixedSOMTextRun.Text[fixedSOMTextRun.Text.Length - 1 - i];
                }
                fixedSOMTextRun._isReversed = true;
                fixedSOMTextRun.Text        = new string(array);
            }
            if (unicodeString == "" && glyphs.Indices != null && glyphs.Indices.Length > 0)
            {
                fixedSOMTextRun._isWhiteSpace = false;
            }
            else
            {
                fixedSOMTextRun._isWhiteSpace = true;
                for (int j = 0; j < unicodeString.Length; j++)
                {
                    if (!char.IsWhiteSpace(unicodeString[j]))
                    {
                        fixedSOMTextRun._isWhiteSpace = false;
                        break;
                    }
                }
            }
            return(fixedSOMTextRun);
        }
コード例 #12
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);
            } 
        }
コード例 #13
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);
            }
        }
コード例 #14
0
ファイル: FixedSOMTextRun.cs プロジェクト: JianwenSun/cc
        //--------------------------------------------------------------------
        //
        // Public Methods
        //
        //---------------------------------------------------------------------

        #region public Methods

        public static FixedSOMTextRun Create(Rect boundingRect, GeneralTransform transform, Glyphs glyphs, FixedNode fixedNode, int startIndex, int endIndex, bool allowReverseGlyphs)
        {
            if (String.IsNullOrEmpty(glyphs.UnicodeString) ||
                glyphs.FontRenderingEmSize <= 0)
            {
                return null;
            }
            FixedSOMTextRun run = new FixedSOMTextRun(boundingRect, transform, fixedNode, startIndex, endIndex);
            run._fontUri = glyphs.FontUri;
            run._cultureInfo = glyphs.Language.GetCompatibleCulture();
            run._bidiLevel = glyphs.BidiLevel;
            run._isSideways = glyphs.IsSideways;
            run._fontSize = glyphs.FontRenderingEmSize;

            GlyphRun glyphRun = glyphs.ToGlyphRun();

            GlyphTypeface gtf = glyphRun.GlyphTypeface;
            
            // Find font family
            // glyphs.FontUri, glyphRun.glyphTypeface

            gtf.FamilyNames.TryGetValue(run._cultureInfo, out run._fontFamily);
            if (run._fontFamily == null)
            {
                //Try getting the English name
                gtf.FamilyNames.TryGetValue(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS, out run._fontFamily);
            }
            
            // Find font style (normal, italics, Oblique)
            // need to open Font file.
            run._fontStyle = gtf.Style;

            // Find font weight (bold, semibold, ExtraLight)
            run._fontWeight = gtf.Weight;

            // Find font stretch (UltraCondensed, SemiExpanded, etc)
            run._fontStretch = gtf.Stretch;

            //Height and width should be the same for x character
            run._defaultCharWidth = gtf.XHeight > 0 ? gtf.XHeight * glyphs.FontRenderingEmSize : glyphRun.AdvanceWidths[startIndex];

            Transform trans = transform.AffineTransform;
            if (trans != null &&
                !(trans.Value.IsIdentity))
            {
                Matrix mat = trans.Value;
                double yScale = Math.Sqrt(mat.M12*mat.M12 + mat.M22*mat.M22);
                double xScale = Math.Sqrt(mat.M11 * mat.M11 + mat.M21 * mat.M21);
                run._fontSize *= yScale;
                run._defaultCharWidth *= xScale;
            }

            run._foreground = glyphs.Fill;
            String s = glyphs.UnicodeString;
            run.Text = s.Substring(startIndex, endIndex-startIndex);

            if (allowReverseGlyphs && run._bidiLevel == 0 && !run._isSideways && 
                startIndex == 0 && endIndex == s.Length
                && String.IsNullOrEmpty(glyphs.CaretStops)
                && FixedTextBuilder.MostlyRTL(s))
            {
                char[] chars = new char[run.Text.Length];
                for (int i=0; i<run.Text.Length; i++)
                {
                    chars[i] = run.Text[run.Text.Length - 1 - i];
                }
                run._isReversed = true;
                run.Text = new string(chars);
            }

            if (s == "" && glyphs.Indices != null && glyphs.Indices.Length > 0)
            {
                run._isWhiteSpace = false;
            }
            else
            {
                run._isWhiteSpace = true;
                for (int i = 0; i < s.Length; i++)
                {
                    if (!Char.IsWhiteSpace(s[i]))
                    {
                        run._isWhiteSpace = false;
                        break;
                    }
                }
            }
            return run;
        }
コード例 #15
0
        //--------------------------------------------------------------------
        //
        // Public Methods
        //
        //---------------------------------------------------------------------

        #region public Methods

        public static FixedSOMTextRun Create(Rect boundingRect, GeneralTransform transform, Glyphs glyphs, FixedNode fixedNode, int startIndex, int endIndex, bool allowReverseGlyphs)
        {
            if (String.IsNullOrEmpty(glyphs.UnicodeString) ||
                glyphs.FontRenderingEmSize <= 0)
            {
                return(null);
            }
            FixedSOMTextRun run = new FixedSOMTextRun(boundingRect, transform, fixedNode, startIndex, endIndex);

            run._fontUri     = glyphs.FontUri;
            run._cultureInfo = glyphs.Language.GetCompatibleCulture();
            run._bidiLevel   = glyphs.BidiLevel;
            run._isSideways  = glyphs.IsSideways;
            run._fontSize    = glyphs.FontRenderingEmSize;

            GlyphRun glyphRun = glyphs.ToGlyphRun();

            GlyphTypeface gtf = glyphRun.GlyphTypeface;

            // Find font family
            // glyphs.FontUri, glyphRun.glyphTypeface

            gtf.FamilyNames.TryGetValue(run._cultureInfo, out run._fontFamily);
            if (run._fontFamily == null)
            {
                //Try getting the English name
                gtf.FamilyNames.TryGetValue(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS, out run._fontFamily);
            }

            // Find font style (normal, italics, Oblique)
            // need to open Font file.
            run._fontStyle = gtf.Style;

            // Find font weight (bold, semibold, ExtraLight)
            run._fontWeight = gtf.Weight;

            // Find font stretch (UltraCondensed, SemiExpanded, etc)
            run._fontStretch = gtf.Stretch;

            //Height and width should be the same for x character
            run._defaultCharWidth = gtf.XHeight > 0 ? gtf.XHeight * glyphs.FontRenderingEmSize : glyphRun.AdvanceWidths[startIndex];

            Transform trans = transform.AffineTransform;

            if (trans != null &&
                !(trans.Value.IsIdentity))
            {
                Matrix mat    = trans.Value;
                double yScale = Math.Sqrt(mat.M12 * mat.M12 + mat.M22 * mat.M22);
                double xScale = Math.Sqrt(mat.M11 * mat.M11 + mat.M21 * mat.M21);
                run._fontSize         *= yScale;
                run._defaultCharWidth *= xScale;
            }

            run._foreground = glyphs.Fill;
            String s = glyphs.UnicodeString;

            run.Text = s.Substring(startIndex, endIndex - startIndex);

            if (allowReverseGlyphs && run._bidiLevel == 0 && !run._isSideways &&
                startIndex == 0 && endIndex == s.Length &&
                String.IsNullOrEmpty(glyphs.CaretStops) &&
                FixedTextBuilder.MostlyRTL(s))
            {
                run._isReversed = true;
                run.Text        = string.Create(run.Text.Length, run.Text, (destination, runText) =>
                {
                    for (int i = 0; i < destination.Length; i++)
                    {
                        destination[i] = runText[runText.Length - 1 - i];
                    }
                });
            }

            if (s == "" && glyphs.Indices != null && glyphs.Indices.Length > 0)
            {
                run._isWhiteSpace = false;
            }
            else
            {
                run._isWhiteSpace = true;
                for (int i = 0; i < s.Length; i++)
                {
                    if (!Char.IsWhiteSpace(s[i]))
                    {
                        run._isWhiteSpace = false;
                        break;
                    }
                }
            }
            return(run);
        }
コード例 #16
0
        private void _GlyphRunHitTest(Glyphs g, double xoffset, out int charIndex, out LogicalDirection edge)
        {
            charIndex = 0;
            edge = LogicalDirection.Forward;

            GlyphRun run = g.ToGlyphRun();
            bool isInside;

            double distance;
            if ((run.BidiLevel & 1) != 0)
            {
                distance = run.BaselineOrigin.X - xoffset;
            }
            else
            {
                distance = xoffset - run.BaselineOrigin.X;
            }

            CharacterHit hit = run.GetCaretCharacterHitFromDistance(distance, out isInside);

            charIndex = hit.FirstCharacterIndex + hit.TrailingLength;
            edge = (hit.TrailingLength > 0) ? LogicalDirection.Backward : LogicalDirection.Forward;
        }
コード例 #17
0
        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);
            }
        }
コード例 #18
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);
            }
        }
コード例 #19
0
        // char index == -1 implies end of run. 
        internal static Rect _GetGlyphRunDesignRect(Glyphs g, int charStart, int charEnd)
        {
            GlyphRun run = g.ToGlyphRun();
            if (run == null)
            {
                return Rect.Empty;
            }

            Rect designRect = run.ComputeAlignmentBox();
            designRect.Offset(run.BaselineOrigin.X, run.BaselineOrigin.Y);

            int charCount = 0;
            if (run.Characters != null)
            {
                charCount = run.Characters.Count;
            }
            else if (g.UnicodeString != null)
            {
                charCount = g.UnicodeString.Length;
            }

            if (charStart > charCount)
            {
                //Extra space was added at the end of the run for contiguity
                Debug.Assert(charStart - charCount == 1);
                charStart = charCount;
            }
            else if (charStart < 0)
            {
                //This is a reversed run
                charStart = 0;
            }
            if (charEnd > charCount)
            {
                //Extra space was added at the end of the run for contiguity
                Debug.Assert(charEnd - charCount == 1);
                charEnd = charCount;
            }
            else if (charEnd < 0)
            {
                //This is a reversed run
                charEnd = 0;
            }


            double x1 = _GetDistanceToCharacter(run, charStart);
            double x2 = _GetDistanceToCharacter(run, charEnd);
            double width = x2 - x1;

            if ((run.BidiLevel & 1) != 0)
            {
                // right to left
                designRect.X = run.BaselineOrigin.X - x2;
            }
            else
            {
                designRect.X = run.BaselineOrigin.X + x1;
            }

            designRect.Width = width;

            return designRect;
        }
コード例 #20
0
ファイル: FixedTextView.cs プロジェクト: dox0/DotNet471RS3
        private ITextPointer _SnapToText(Point point)
        {
            ITextPointer itp = null;

            FixedNode[] fixedNodes = Container.FixedTextBuilder.GetLine(this.PageIndex, point);
            if (fixedNodes != null && fixedNodes.Length > 0)
            {
                double    closestDistance = Double.MaxValue;
                double    xoffset         = 0;
                Glyphs    closestGlyphs   = null;
                FixedNode closestNode     = fixedNodes[0];

                foreach (FixedNode node in fixedNodes)
                {
                    Glyphs           startGlyphs   = this.FixedPage.GetGlyphsElement(node);
                    GeneralTransform tranToGlyphs  = this.FixedPage.TransformToDescendant(startGlyphs);
                    Point            transformedPt = point;
                    if (tranToGlyphs != null)
                    {
                        tranToGlyphs.TryTransform(transformedPt, out transformedPt);
                    }

                    GlyphRun run           = startGlyphs.ToGlyphRun();
                    Rect     alignmentRect = run.ComputeAlignmentBox();
                    alignmentRect.Offset(startGlyphs.OriginX, startGlyphs.OriginY);

                    double horizontalDistance = Math.Max(0, (transformedPt.X > alignmentRect.X) ? (transformedPt.X - alignmentRect.Right) : (alignmentRect.X - transformedPt.X));
                    double verticalDistance   = Math.Max(0, (transformedPt.Y > alignmentRect.Y) ? (transformedPt.Y - alignmentRect.Bottom) : (alignmentRect.Y - transformedPt.Y));
                    double manhattanDistance  = horizontalDistance + verticalDistance;

                    if (closestGlyphs == null || manhattanDistance < closestDistance)
                    {
                        closestDistance = manhattanDistance;
                        closestGlyphs   = startGlyphs;
                        closestNode     = node;
                        xoffset         = transformedPt.X;
                    }
                }

                int index;
                LogicalDirection dir;
                _GlyphRunHitTest(closestGlyphs, xoffset, out index, out dir);

                FixedPosition fixedp = new FixedPosition(closestNode, index);
                itp = _CreateTextPointer(fixedp, dir);
                Debug.Assert(itp != null);
            }
            else
            {
                //
                // That condition is only possible when there is no line in the page
                //
                if (point.Y < this.FixedPage.Height / 2)
                {
                    itp = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward);
                    itp.MoveToInsertionPosition(LogicalDirection.Forward);
                }
                else
                {
                    itp = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward);
                    itp.MoveToInsertionPosition(LogicalDirection.Backward);
                }
            }
            return(itp);
        }
コード例 #21
0
ファイル: DataGraphGeometry.cs プロジェクト: xmuliushuo/learn
 /// <summary>
 /// 在指定点画出文字
 /// </summary>
 /// <param name="s">所画的文字内容</param>
 /// <param name="p">文字坐标</param>
 /// <param name="fontsize">文字大小</param>
 /// <returns>返回文字形状</returns>
 private GlyphRun DataGraphPrintText(string s, Point p, int fontsize)
 {
     Glyphs text = new Glyphs();
     text.OriginX = p.X;
     text.OriginY = p.Y;
     text.UnicodeString = s;
     text.FontUri = new Uri(FONT_URI);
     text.FontRenderingEmSize = fontsize;
     return text.ToGlyphRun();
 }
コード例 #22
0
        // Token: 0x06002EF2 RID: 12018 RVA: 0x000D4194 File Offset: 0x000D2394
        private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir)
        {
            int  num    = 1;
            int  page   = fixedp.Page;
            bool result = false;

            FixedNode[] nextLine = this.Container.FixedTextBuilder.GetNextLine(fixedp.Node, scanDir == LogicalDirection.Forward, ref num);
            if (nextLine != null && nextLine.Length != 0)
            {
                FixedPage fixedPage = this.Container.FixedDocument.SyncGetPage(page, false);
                if (double.IsInfinity(suggestedX))
                {
                    suggestedX = 0.0;
                }
                Point     point     = new Point(suggestedX, 0.0);
                Point     point2    = new Point(suggestedX, 1000.0);
                FixedNode fixedNode = nextLine[0];
                Glyphs    g         = null;
                double    num2      = double.MaxValue;
                double    xoffset   = 0.0;
                for (int i = nextLine.Length - 1; i >= 0; i--)
                {
                    FixedNode fixedNode2    = nextLine[i];
                    Glyphs    glyphsElement = fixedPage.GetGlyphsElement(fixedNode2);
                    if (glyphsElement != null)
                    {
                        GeneralTransform generalTransform = fixedPage.TransformToDescendant(glyphsElement);
                        Point            inPoint          = point;
                        Point            inPoint2         = point2;
                        if (generalTransform != null)
                        {
                            generalTransform.TryTransform(inPoint, out inPoint);
                            generalTransform.TryTransform(inPoint2, out inPoint2);
                        }
                        double   num3     = (inPoint2.X - inPoint.X) / (inPoint2.Y - inPoint.Y);
                        GlyphRun glyphRun = glyphsElement.ToGlyphRun();
                        Rect     rect     = glyphRun.ComputeAlignmentBox();
                        rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY);
                        double num4;
                        double num5;
                        if (num3 > 1000.0 || num3 < -1000.0)
                        {
                            num4 = 0.0;
                            num5 = ((inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y));
                        }
                        else
                        {
                            double num6 = (rect.Top + rect.Bottom) / 2.0;
                            num4 = inPoint.X + num3 * (num6 - inPoint.Y);
                            num5 = ((num4 > rect.X) ? (num4 - rect.Right) : (rect.X - num4));
                        }
                        if (num5 < num2)
                        {
                            num2      = num5;
                            xoffset   = num4;
                            fixedNode = fixedNode2;
                            g         = glyphsElement;
                            if (num5 <= 0.0)
                            {
                                break;
                            }
                        }
                    }
                }
                int offset;
                this._GlyphRunHitTest(g, xoffset, out offset, out edge);
                fixedp = new FixedPosition(fixedNode, offset);
                result = true;
            }
            return(result);
        }
コード例 #23
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);
        }
コード例 #24
0
        private void _UpdateHighlightForeground(DrawingContext dc, ArrayList highlights)
        {
            foreach (FixedHighlight fh in highlights)
            {
                Brush fg = null;

                if (fh.HighlightType == FixedHighlightType.None)
                {
#if NEVER
                    // use this code if you want to see unrecognized highlights
                    bg = Brushes.Yellow;
#else
                    continue;
#endif
                }

                Glyphs g = fh.Glyphs;
                if (g == null)
                {
                    continue;
                }


                Rect clipRect = fh.ComputeDesignRect();

                if (clipRect == Rect.Empty)
                {
                    continue;
                }

                GeneralTransform transform = fh.Element.TransformToAncestor(_page);

                Transform t = transform.AffineTransform;
                if (t != null)
                {
                    dc.PushTransform(t);
                }
                else
                {
                    dc.PushTransform(Transform.Identity);
                }

                dc.PushClip(new RectangleGeometry(clipRect));

                if (fh.HighlightType == FixedHighlightType.TextSelection)
                {
                    fg = SelectionHighlightInfo.ForegroundBrush;
                }
                else if (fh.HighlightType == FixedHighlightType.AnnotationHighlight)
                {
                    fg = fh.ForegroundBrush;
                }
                // can add cases for new types of highlights

                GlyphRun gr = g.ToGlyphRun();

                if (fg == null)
                {
                    fg = g.Fill;
                }

                dc.PushGuidelineY1(gr.BaselineOrigin.Y);
                dc.PushClip(g.Clip);
                dc.DrawGlyphRun(fg, gr);
                dc.Pop(); // Glyphs clip
                dc.Pop(); // Guideline
                dc.Pop(); // clip
                dc.Pop(); // transform
            }
        }
コード例 #25
0
ファイル: FixedTextView.cs プロジェクト: dox0/DotNet471RS3
        // If return false, nothing has been modified, which implies out of page boundary
        // The input of suggestedX is in the VisualRoot's cooridnate system
        private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir)
        {
            int  count     = 1;
            int  pageIndex = fixedp.Page;
            bool moved     = false;

            FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, (scanDir == LogicalDirection.Forward), ref count);

            if (fixedNodes != null && fixedNodes.Length > 0)
            {
                FixedPage page = Container.FixedDocument.SyncGetPage(pageIndex, false);
                // This line contains multiple Glyhs. Scan backward
                // util we hit the first one whose OriginX is smaller
                // then suggestedX;
                if (Double.IsInfinity(suggestedX))
                {
                    suggestedX = 0;
                }
                Point topOfPage   = new Point(suggestedX, 0);
                Point secondPoint = new Point(suggestedX, 1000);

                FixedNode hitNode         = fixedNodes[0];
                Glyphs    hitGlyphs       = null;
                double    closestDistance = Double.MaxValue;
                double    xoffset         = 0;

                for (int i = fixedNodes.Length - 1; i >= 0; i--)
                {
                    FixedNode node = fixedNodes[i];
                    Glyphs    g    = page.GetGlyphsElement(node);
                    if (g != null)
                    {
                        GeneralTransform transform = page.TransformToDescendant(g);
                        Point            pt1       = topOfPage;
                        Point            pt2       = secondPoint;
                        if (transform != null)
                        {
                            transform.TryTransform(pt1, out pt1);
                            transform.TryTransform(pt2, out pt2);
                        }
                        double invSlope = (pt2.X - pt1.X) / (pt2.Y - pt1.Y);
                        double xoff, distance;

                        GlyphRun run = g.ToGlyphRun();
                        Rect     box = run.ComputeAlignmentBox();
                        box.Offset(g.OriginX, g.OriginY);

                        if (invSlope > 1000 || invSlope < -1000)
                        {
                            // special case for vertical text
                            xoff     = 0;
                            distance = (pt1.Y > box.Y) ? (pt1.Y - box.Bottom) : (box.Y - pt1.Y);
                        }
                        else
                        {
                            double centerY = (box.Top + box.Bottom) / 2;
                            xoff     = pt1.X + invSlope * (centerY - pt1.Y);
                            distance = (xoff > box.X) ? (xoff - box.Right) : (box.X - xoff);
                        }

                        if (distance < closestDistance)
                        {
                            closestDistance = distance;
                            xoffset         = xoff;
                            hitNode         = node;
                            hitGlyphs       = g;

                            if (distance <= 0)
                            {
                                break;
                            }
                        }
                    }
                }

                Debug.Assert(hitGlyphs != null);

                int charIdx;
                _GlyphRunHitTest(hitGlyphs, xoffset, out charIdx, out edge);

                fixedp = new FixedPosition(hitNode, charIdx);
                moved  = true;
            }

            return(moved);
        }
コード例 #26
0
ファイル: RubberbandSelector.cs プロジェクト: beda2280/wpf-1
        //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);
        }