public override PathGeometry Build(SvgTextContentElement element, string text, double x, double y)
        {
            ComputeMeasurement(text, x, y);

            _textWidth = 0;

            if (_glyphRun == null)
            {
                return(new PathGeometry());
            }

            // Approximate the width of the text...
            Rect designRect = _glyphRun.ComputeAlignmentBox();

            designRect.Offset(_glyphRunOrigin.X, _glyphRunOrigin.Y);

            _textWidth = Math.Max(0, designRect.Right);

            PathGeometry pathGeometry = null;

            var geometry = _glyphRun.BuildGeometry();

            if (geometry is PathGeometry)
            {
                pathGeometry = (PathGeometry)geometry;
            }
            else
            {
                pathGeometry = new PathGeometry();
                pathGeometry.AddGeometry(geometry);
            }

            return(pathGeometry);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
 private void ComputeBounds()
 {
     _LayoutBounds = _native.ComputeAlignmentBox().ToUGRect();
     if (HorizontalAlignment != UGHorizontalAlignment.Left)
     {
         if (HorizontalAlignment == UGHorizontalAlignment.Right)
         {
             _LayoutBounds.X = Math.Max(0F, _requestedSize.Width - _LayoutBounds.Width);
         }
         else if (HorizontalAlignment == UGHorizontalAlignment.Center)
         {
             _LayoutBounds.X = Math.Max(0F, (_requestedSize.Width - _LayoutBounds.Width) / 2F);
         }
     }
     if (VerticalAlignment != UGVerticalAlignment.Top)
     {
         if (VerticalAlignment == UGVerticalAlignment.Bottom)
         {
             _LayoutBounds.Y = Math.Max(0F, _requestedSize.Height - _LayoutBounds.Height);
         }
         else if (VerticalAlignment == UGVerticalAlignment.Center)
         {
             _LayoutBounds.Y = Math.Max(0F, (_requestedSize.Height - _LayoutBounds.Height) / 2F);
         }
     }
     else
     {
         _LayoutBounds.Y = 0F;
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the vector that must be added to the atom position to center the glyph
        /// </summary>
        /// <param name="glyphRun">Run of text for atom symbol</param>
        /// <param name="symbolSize">Size of symbol in DIPs</param>
        /// <returns>Vector to be added to atom pos</returns>
        public static Vector GetOffsetVector(GlyphRun glyphRun, double symbolSize)
        {
            Rect   rect   = glyphRun.ComputeAlignmentBox();
            Vector offset = new Vector(-rect.Width / 2, glyphRun.GlyphTypeface.CapsHeight * symbolSize / 2);

            return(offset);
        }
Ejemplo n.º 5
0
        public override Size MeasureText(SvgTextContentElement element, string text, bool canBeWhitespace = true)
        {
            ComputeMeasurement(text, 0, 0);

            if (_glyphRun == null)
            {
                return(new Size(0, 0));
            }

            Rect designRect = _glyphRun.ComputeAlignmentBox();

            //designRect.Offset(_glyphRunOrigin.X, _glyphRunOrigin.Y);

            _textWidth = Math.Max(0, designRect.Right);

            return(new Size(Math.Max(0, designRect.Right), Math.Max(0, designRect.Bottom)));
        }
Ejemplo n.º 6
0
		// Token: 0x06002D3B RID: 11579 RVA: 0x000CC368 File Offset: 0x000CA568
		internal Rect ComputeDesignRect()
		{
			Glyphs glyphs = this._element as Glyphs;
			if (glyphs == null)
			{
				Image image = this._element as Image;
				if (image != null && image.Source != null)
				{
					return new Rect(0.0, 0.0, image.Width, image.Height);
				}
				Path path = this._element as Path;
				if (path != null)
				{
					return path.Data.Bounds;
				}
				return Rect.Empty;
			}
			else
			{
				GlyphRun measurementGlyphRun = glyphs.MeasurementGlyphRun;
				if (measurementGlyphRun == null || this._gBeginOffset >= this._gEndOffset)
				{
					return Rect.Empty;
				}
				Rect result = measurementGlyphRun.ComputeAlignmentBox();
				result.Offset(glyphs.OriginX, glyphs.OriginY);
				int num = (measurementGlyphRun.Characters == null) ? 0 : measurementGlyphRun.Characters.Count;
				double num2 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(this._gBeginOffset, 0));
				double num3;
				if (this._gEndOffset == num)
				{
					num3 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(num - 1, 1));
				}
				else
				{
					num3 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(this._gEndOffset, 0));
				}
				if (num3 < num2)
				{
					double num4 = num2;
					num2 = num3;
					num3 = num4;
				}
				double width = num3 - num2;
				if ((measurementGlyphRun.BidiLevel & 1) != 0)
				{
					result.X = glyphs.OriginX - num3;
				}
				else
				{
					result.X = glyphs.OriginX + num2;
				}
				result.Width = width;
				return result;
			}
		}
Ejemplo n.º 7
0
        private void ComputeMeasurement(string text, double OriginX, double OriginY)
        {
            _unicodeString = text;

            _glyphRun = null;
            ParseGlyphRunProperties();
            if (_glyphRun != null)
            {
                return;
            }

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

            bool haveOriginX = !double.IsNaN(OriginX);
            bool haveOriginY = !double.IsNaN(OriginY);

            bool measurementGlyphRunOriginValid = false;

            Rect alignmentRect = new Rect();

            if (haveOriginX && haveOriginY && leftToRight)
            {
                _glyphRun = CreateGlyphRun(new Point(OriginX, OriginY), this.Language);
                measurementGlyphRunOriginValid = true;
            }
            else
            {
                _glyphRun = CreateGlyphRun(new Point(), this.Language);
                // compute alignment box for origins
                alignmentRect = _glyphRun.ComputeAlignmentBox();
            }

            if (haveOriginX)
            {
                _glyphRunOrigin.X = OriginX;
            }
            else
            {
                _glyphRunOrigin.X = leftToRight ? 0 : alignmentRect.Width;
            }

            if (haveOriginY)
            {
                _glyphRunOrigin.Y = OriginY;
            }
            else
            {
                _glyphRunOrigin.Y = -alignmentRect.Y;
            }

            if (!measurementGlyphRunOriginValid)
            {
                _glyphRun = CreateGlyphRun(_glyphRunOrigin, this.Language);
            }
        }
Ejemplo n.º 8
0
        public override void DrawString(string str, RFont font, RColor color, RPoint point, RSize size, bool rtl)
        {
            var colorConv = ((BrushAdapter)_adapter.GetSolidBrush(color)).Brush;

            bool          glyphRendered = false;
            GlyphTypeface glyphTypeface = ((FontAdapter)font).GlyphTypeface;

            if (glyphTypeface != null)
            {
                double   width  = 0;
                ushort[] glyphs = new ushort[str.Length];
                double[] widths = new double[str.Length];

                int i = 0;
                for (; i < str.Length; i++)
                {
                    ushort glyph;
                    if (!glyphTypeface.CharacterToGlyphMap.TryGetValue(str[i], out glyph))
                    {
                        break;
                    }

                    glyphs[i] = glyph;
                    width    += glyphTypeface.AdvanceWidths[glyph];
                    widths[i] = 96d / 72d * font.Size * glyphTypeface.AdvanceWidths[glyph];
                }

                if (i >= str.Length)
                {
                    point.Y += glyphTypeface.Baseline * font.Size * 96d / 72d;
                    point.X += rtl ? 96d / 72d * font.Size * width : 0;

                    glyphRendered = true;
                    var glyphRun   = new GlyphRun(glyphTypeface, rtl ? 1 : 0, false, 96d / 72d * font.Size, glyphs, Utils.ConvertRound(point), widths, null, null, null, null, null, null);
                    var rect       = glyphRun.ComputeAlignmentBox();
                    var guidelines = new GuidelineSet();
                    guidelines.GuidelinesX.Add(rect.Left);
                    guidelines.GuidelinesX.Add(rect.Right);
                    guidelines.GuidelinesY.Add(rect.Top);
                    guidelines.GuidelinesY.Add(rect.Bottom);
                    _g.PushGuidelineSet(guidelines);
                    _g.DrawGlyphRun(colorConv, glyphRun);
                    _g.Pop();
                }
            }

            if (!glyphRendered)
            {
                var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, rtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, colorConv);
                point.X += rtl ? formattedText.Width : 0;
                _g.DrawText(formattedText, Utils.ConvertRound(point));
            }
        }
        // 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);
        }
        // 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);
        }
Ejemplo n.º 11
0
    public static string ToText(this FrameworkElement root)
    {
        var builder = new StringBuilder();

        foreach (var visual in root.GetSelfAndDescendants().OfType <DrawingVisual>())
        {
            GlyphRun previousRun = null;

            // Order runs first vertically (Y), then horizontally (X).
            foreach (var currentRun in visual.Drawing
                     .GetSelfAndDescendants()
                     .OfType <GlyphRunDrawing>()
                     .Select(glyph => glyph.GlyphRun)
                     .OrderBy(run => run.BaselineOrigin.Y)
                     .ThenBy(run => run.BaselineOrigin.X))
            {
                if (previousRun != null)
                {
                    // If base-line of current text segment is left from base-line of previous text segment, then assume that it is new line.
                    if (currentRun.BaselineOrigin.X <= previousRun.BaselineOrigin.X)
                    {
                        builder.AppendLine();
                    }
                    else
                    {
                        Rect currentRect  = currentRun.ComputeAlignmentBox();
                        Rect previousRect = previousRun.ComputeAlignmentBox();

                        double spaceWidth  = currentRun.BaselineOrigin.X + currentRect.Left - previousRun.BaselineOrigin.X - previousRect.Right;
                        double spaceHeight = (currentRect.Height + previousRect.Height) / 2;

                        // If space between successive text segments has width greater than a sixth of its height, then assume that it is a word (add a space).
                        if (spaceWidth > spaceHeight / 6)
                        {
                            builder.Append(' ');
                        }
                    }
                }

                builder.Append(currentRun.Characters.ToArray());
                previousRun = currentRun;
            }
        }

        return(builder.ToString());
    }
Ejemplo n.º 12
0
        private GlyphRun GetGlyphRun()
        {
            if (_native == null)
            {
                var glyphTypeface = _textFormat.Native;
                var fontSize      = _textFormat.FontSize;
                var length        = _textString.Length;
                var glyphIndices  = new ushort[length];
                var advanceWidths = new double[length];

                var totalWidth = 0.0;
                var height     = 0.0;
                for (var i = 0; i < length; ++i)
                {
                    glyphTypeface.CharacterToGlyphMap.TryGetValue(_textString[i], out var glyphIndex);
                    glyphIndices[i] = glyphIndex;

                    var width = fontSize * glyphTypeface.AdvanceWidths[glyphIndex];
                    advanceWidths[i] = width;
                    totalWidth      += width;

                    height = Math.Max(height, glyphTypeface.AdvanceHeights[glyphIndex]);
                }

                _native = new GlyphRun(
                    glyphTypeface,
                    0,
                    false,
                    fontSize,
                    glyphIndices,
                    new Point(0, Math.Round(fontSize * glyphTypeface.Baseline)),
                    advanceWidths,
                    null, null, null, null, null, null);

                _LayoutBounds = _native.ComputeAlignmentBox().ToUGRect();
                ComputeBounds();
            }
            return(_native);
        }
Ejemplo n.º 13
0
        // 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);
        }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
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);
            }
        }
Ejemplo n.º 17
0
            private WriteableBitmap GetWriteableBitmapDWrite()
            {
                Rect boundBox = _run.ComputeInkBoundingBox();
                Rect alignBox = _run.ComputeAlignmentBox();

                alignBox.X     = boundBox.X;
                alignBox.Width = boundBox.Width;

                Int32Rect          transformedAlign = Round(_transform.TransformBounds(alignBox));
                TranslateTransform translate        = new TranslateTransform(-Round(transformedAlign.X), -Round(alignBox.Y));
                MatrixTransform    finalTransform   = new MatrixTransform(_transform.Value * translate.Value);


                uint width  = (uint)transformedAlign.Width;
                uint height = (uint)transformedAlign.Height;

                DWrite.IDWriteFactory    factory = DWrite.CreateFactory(DWrite.FactoryType.Shared);
                DWrite.IDWriteGdiInterop interop = factory.GetGdiInterop();

                DWrite.IDWriteFontFile font = factory.CreateFontFileReference(_typeface.FontUri.LocalPath, IntPtr.Zero);

                bool isSupported; DWrite.FontFileType fileType; DWrite.FontFaceType faceType; uint faceCount;

                font.Analyze(out isSupported, out fileType, out faceType, out faceCount);
                DWrite.IDWriteFontFace face = factory.CreateFontFace(faceType, 1, new DWrite.IDWriteFontFile[] { font }, 0, (DWrite.FontSimulations)_typeface.StyleSimulations);

                DWrite.GlyphRun run = new DWrite.GlyphRun(_run.GlyphIndices[0]);
                run.EmSize   = (float)_run.FontRenderingEmSize;
                run.FontFace = face;

                DWrite.IDWriteRenderingParams pars = factory.CreateCustomRenderingParams(1, 0, 0, DWrite.PixelGeometry.Flat, _antialiasLevel == AntialiasingLevel.None ? DWrite.RenderingMode.Aliased : DWrite.RenderingMode.GdiClassic);
                DWrite.Matrix matrix = (DWrite.Matrix)finalTransform.Value;

                IntPtr screenDC = User32.GetScreenDC();

pass:
                DWrite.IDWriteBitmapRenderTarget target = interop.CreateBitmapRenderTarget(screenDC, width, height);
                target.SetPixelsPerDip(1);
                target.SetCurrentTransform(ref matrix);
                if (!Target1Failed)
                {
                    try
                    {
                        DWrite.IDWriteBitmapRenderTarget1 target1 = (DWrite.IDWriteBitmapRenderTarget1)target;
                        target1.SetTextAntialiasMode(DWrite.TextAntialiasMode.GrayScale);
                    }
                    catch (COMException) { Target1Failed = true; }
                }

                Win32.Rect rect = target.DrawGlyphRun(0, 0, DWrite.MeasuringMode.GdiClassic, ref run, pars, 0xFFFFFF);

                if (rect.Right > width || rect.Bottom > height)
                {
                    if (finalTransform.Matrix.Determinant == 1.0 && finalTransform.Matrix.M11 == 1 && finalTransform.Matrix.M12 == 0) // translation
                    {
                        // if translation was requested, we need to preserve absolute dimensions
                        width  = (uint)rect.Right;
                        height = (uint)rect.Bottom;
                    }
                    else
                    {
                        // baseline coordinates are subject to transformation, but we need translation
                        width  = (uint)(rect.Right - rect.Left);
                        height = (uint)(rect.Bottom - rect.Top);

                        matrix.OffsetX += -rect.Left;
                        matrix.OffsetY += -rect.Top;
                    }

                    // no easy way to measure ahead
                    goto pass;
                }

                User32.ReleaseScreenDC(screenDC);
                IntPtr memoryDC = target.GetMemoryDC();
                IntPtr hBitmap  = Gdi32.GetCurrentObject(memoryDC, Gdi32.ObjectType.Bitmap);

                BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                if (Target1Failed)
                {
                    return(new WriteableBitmap(new FormatConvertedBitmap(bitmap, PixelFormats.Bgr24, null, 0)));
                }
                else
                {
                    return(new WriteableBitmap(bitmap));
                }

                // DWrite will clean-up the bitmap/memory DC
                // GC will clean-up DWrite
            }
Ejemplo n.º 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);
            }
        }
Ejemplo n.º 19
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);
            }
        }
Ejemplo n.º 20
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);
        }
        public override void RenderText(SvgTextContentElement element,
                                        ref Point ctp, string text, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            int    vertOrientation = -1;
            int    horzOrientation = -1;
            string orientationText = element.GetPropertyValue("glyph-orientation-vertical");

            if (!string.IsNullOrWhiteSpace(orientationText))
            {
                double orientationValue = 0;
                if (double.TryParse(orientationText, out orientationValue))
                {
                    vertOrientation = (int)orientationValue;
                }
            }
            orientationText = element.GetPropertyValue("glyph-orientation-horizontal");
            if (!string.IsNullOrWhiteSpace(orientationText))
            {
                double orientationValue = 0;
                if (double.TryParse(orientationText, out orientationValue))
                {
                    horzOrientation = (int)orientationValue;
                }
            }

            Point startPoint = ctp;
            IList <WpfTextRun> textRunList = WpfTextRun.BreakWords(text,
                                                                   vertOrientation, horzOrientation);

            for (int tr = 0; tr < textRunList.Count; tr++)
            {
                // For unknown reasons, FormattedText will split a text like "-70%" into two parts "-"
                // and "70%". We provide a shift to account for the split...
                double baselineShiftX = 0;
                double baselineShiftY = 0;

                WpfTextRun textRun = textRunList[tr];

                DrawingGroup verticalGroup = new DrawingGroup();

                DrawingContext verticalContext = verticalGroup.Open();
                DrawingContext currentContext  = _drawContext;

                _drawContext = verticalContext;

                this.DrawSingleLineText(element, ref ctp, textRun, rotate, placement);

                verticalContext.Close();

                _drawContext = currentContext;

                if (verticalGroup.Children.Count == 1)
                {
                    DrawingGroup textGroup = verticalGroup.Children[0] as DrawingGroup;
                    if (textGroup != null)
                    {
                        verticalGroup = textGroup;
                    }
                }

                string runText   = textRun.Text;
                int    charCount = runText.Length;

                double            totalHeight = 0;
                DrawingCollection drawings    = verticalGroup.Children;
                int itemCount = drawings != null ? drawings.Count : 0;
                for (int i = 0; i < itemCount; i++)
                {
                    Drawing      textDrawing = drawings[i];
                    DrawingGroup textGroup   = textDrawing as DrawingGroup;

                    if (vertOrientation == -1)
                    {
                        if (textGroup != null)
                        {
                            for (int j = 0; j < textGroup.Children.Count; j++)
                            {
                                GlyphRunDrawing glyphDrawing = textGroup.Children[j] as GlyphRunDrawing;
                                if (glyphDrawing != null)
                                {
                                    if (textRun.IsLatin)
                                    {
                                        GlyphRun glyphRun = glyphDrawing.GlyphRun;

                                        IList <ushort> glyphIndices = glyphRun.GlyphIndices;
                                        IDictionary <ushort, double> allGlyphWeights = glyphRun.GlyphTypeface.AdvanceWidths;
                                        double lastAdvanceWeight =
                                            allGlyphWeights[glyphIndices[glyphIndices.Count - 1]] * glyphRun.FontRenderingEmSize;

                                        totalHeight += glyphRun.ComputeAlignmentBox().Width + lastAdvanceWeight / 2d;
                                    }
                                    else
                                    {
                                        totalHeight += ChangeGlyphOrientation(glyphDrawing,
                                                                              baselineShiftX, baselineShiftY, false);
                                    }
                                }
                            }
                        }
                        else
                        {
                            GlyphRunDrawing glyphDrawing = textDrawing as GlyphRunDrawing;
                            if (glyphDrawing != null)
                            {
                                if (textRun.IsLatin)
                                {
                                    GlyphRun glyphRun = glyphDrawing.GlyphRun;

                                    IList <UInt16> glyphIndices = glyphRun.GlyphIndices;
                                    IDictionary <ushort, double> allGlyphWeights = glyphRun.GlyphTypeface.AdvanceWidths;
                                    double lastAdvanceWeight =
                                        allGlyphWeights[glyphIndices[glyphIndices.Count - 1]] * glyphRun.FontRenderingEmSize;

                                    totalHeight += glyphRun.ComputeAlignmentBox().Width + lastAdvanceWeight / 2d;
                                }
                                else
                                {
                                    totalHeight += ChangeGlyphOrientation(glyphDrawing,
                                                                          baselineShiftX, baselineShiftY, false);
                                }
                            }
                        }
                    }
                    else if (vertOrientation == 0)
                    {
                        if (textGroup != null)
                        {
                            for (int j = 0; j < textGroup.Children.Count; j++)
                            {
                                GlyphRunDrawing glyphDrawing = textGroup.Children[j] as GlyphRunDrawing;
                                if (glyphDrawing != null)
                                {
                                    baselineShiftX = ChangeGlyphOrientation(glyphDrawing,
                                                                            baselineShiftX, baselineShiftY, textRun.IsLatin);
                                    totalHeight += baselineShiftX;
                                }
                            }
                        }
                        else
                        {
                            GlyphRunDrawing glyphDrawing = textDrawing as GlyphRunDrawing;
                            if (textDrawing != null)
                            {
                                totalHeight += ChangeGlyphOrientation(glyphDrawing,
                                                                      baselineShiftX, baselineShiftY, textRun.IsLatin);
                            }
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }

                if (!this.IsMeasuring)
                {
                    _drawContext.DrawDrawing(verticalGroup);
                }

                if (tr < textRunList.Count)
                {
                    ctp.X         = startPoint.X;
                    ctp.Y         = startPoint.Y + totalHeight;
                    startPoint.Y += totalHeight;
                }
            }
        }
        // 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);
        }
        //--------------------------------------------------------------------
        //
        // Public Properties
        //
        //---------------------------------------------------------------------


        //--------------------------------------------------------------------
        //
        // Public Events
        //
        //---------------------------------------------------------------------


        //--------------------------------------------------------------------
        //
        // Internal Methods
        //
        //---------------------------------------------------------------------

        #region Internal Methods

        // Compute the rectangle that covers this highlight
        internal Rect ComputeDesignRect()
        {
            Glyphs g = _element as Glyphs;

            if (g == null)
            {
                Image im = _element as Image;
                if (im != null && im.Source != null)
                {
                    return(new Rect(0, 0, im.Width, im.Height));
                }
                else
                {
                    Path p = _element as Path;
                    if (p != null)
                    {
                        return(p.Data.Bounds);
                    }
                }

                return(Rect.Empty);
            }

            GlyphRun run = g.MeasurementGlyphRun; // g.ToGlyphRun();

            if (run == null || _gBeginOffset >= _gEndOffset)
            {
                return(Rect.Empty);
            }

            Rect designRect = run.ComputeAlignmentBox();

            designRect.Offset(g.OriginX, g.OriginY);

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

            Debug.Assert(_gBeginOffset >= 0);
            Debug.Assert(_gEndOffset <= chrct);

            double x1, x2, width;

            x1 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(_gBeginOffset, 0));

            if (_gEndOffset == chrct)
            {
                x2 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(chrct - 1, 1));
            }
            else
            {
                x2 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(_gEndOffset, 0));
            }

            if (x2 < x1)
            {
                double temp = x1;
                x1 = x2;
                x2 = temp;
            }
            width = x2 - x1;

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

            designRect.Width = width;

#if DEBUG
            DocumentsTrace.FixedTextOM.Highlight.Trace(string.Format("DesignBound {0}", designRect));
#endif
            return(designRect);
        }
Ejemplo n.º 24
0
        private void Test2()
        {
            //Glyph系クラス
            GlyphRun        glyphRun;
            GlyphRunDrawing glyphRunDrawing;
            Glyphs          glyphs;
            GlyphTypeface   glyphTypeface;

            FontFamily fontFamily = new FontFamily("Meiryo UI");
            var        typefaces  = fontFamily.GetTypefaces();
            Uri        myFontUri  = null;

            foreach (var face in typefaces)
            {
                face.TryGetGlyphTypeface(out GlyphTypeface gType);
                myFontUri = gType.FontUri;
                break;
            }

            glyphs                     = new();
            glyphs.FontUri             = myFontUri;
            glyphs.FontRenderingEmSize = 100;
            //glyphs.StyleSimulations = StyleSimulations.BoldItalicSimulation;
            glyphs.UnicodeString = "(ゆっくり)";
            glyphs.Fill          = Brushes.MediumOrchid;
            //glyphs.BidiLevel = 1;
            //glyphs.IsSideways = true;
            GlyphRun gRun      = glyphs.ToGlyphRun();
            var      chars     = gRun.Characters;
            var      clustre   = gRun.ClusterMap;
            var      box       = gRun.ComputeAlignmentBox();
            var      inkBox    = gRun.ComputeInkBoundingBox();
            var      dfName    = gRun.DeviceFontName;
            var      inside    = gRun.GetCaretCharacterHitFromDistance(100, out bool isindside);
            var      hit       = gRun.GetNextCaretCharacterHit(new System.Windows.Media.TextFormatting.CharacterHit());
            var      gInd      = gRun.GlyphIndices;
            var      gOffset   = gRun.GlyphOffsets;
            var      gTypeface = gRun.GlyphTypeface;

            MyGrid.Children.Add(glyphs);

            DrawingVisual dv = new();

            //dv.Offset = new Vector(0, -100);

            using (var dc = dv.RenderOpen())
            {
                //dc.DrawRectangle(Brushes.MediumBlue, null, new Rect(0, 0, 500, 500));
                //dc.DrawRectangle(Brushes.MediumBlue, null, new Rect(0, 0, box.Width, box.Height));
                dc.DrawGlyphRun(Brushes.MediumAquamarine, gRun);
            }
            Rect r3                   = dv.Drawing.Bounds;
            Rect r                    = dv.ContentBounds;
            Rect r2                   = dv.DescendantBounds;
            var  geo                  = gRun.BuildGeometry();
            Rect rectGeo1             = geo.Bounds;
            Rect rectGeo2             = geo.GetRenderBounds(null);
            RenderTargetBitmap bitmap = new((int)box.Width, (int)box.Height, 96, 96, PixelFormats.Pbgra32);

            bitmap.Render(dv);

            glyphRunDrawing   = new(Brushes.MediumAquamarine, gRun);
            MyGrid.Background = new DrawingBrush(glyphRunDrawing);
            //Glyphs
            //FontUri               フォント
            //FontRenderingEmSize   フォントサイズみたいなもの
            //StyleSimulations      太字と斜体の指定
            //BidiLevel             文字を並べる向きの指定、0or偶数で左から、奇数で右からになる
            //ToGlyphRun()          GlyphRun作成

            //GlyphRun クラス (System.Windows.Media) | Microsoft Docs
            //https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.media.glyphrun?view=net-6.0
            //  同じ描画スタイルが設定され、サイズ、フォント、およびフォントの書体が同じである一連のグリフを表します。
            //GlyphRunDrawingと組み合わせて使う

            //プロパティ
            //AdvanceWidths
            //グリフ インデックスに対応するアドバンス幅を表す Double 値の一覧を取得または設定します。

            //BaselineOrigin    Point
            //GlyphRun のベースライン原点を取得または設定します。

            //BidiLevel     Int32
            //GlyphRun の双方向の入れ子レベルを取得または設定します。

            //CaretStops    bool
            //GlyphRun を表す Unicode で UTF16 コード ポイント毎にキャレット ストップがあるかどうかを決定する Boolean 値の一覧を取得または設定します。

            //Characters    List<Char>
            //GlyphRun の Unicode を表す UTF16 コード ポイントの一覧を取得または設定します。

            //ClusterMap    List<Uint16>
            //GlyphRun の文字をグリフ インデックスにマップする UInt16 値の一覧を取得または設定します。

            //DeviceFontName    string
            //GlyphRun が最適化される対象の、デバイス固有のフォントを取得または設定します。

            //FontRenderingEmSize   double
            //GlyphRun のレンダリングに使用する全角サイズを取得または設定します。

            //GlyphIndices      list<Uint16>
            //描画物理フォントのグリフ インデックスを表す UInt16 値の配列を取得または設定します。

            //GlyphOffsets      List<point>
            //GlyphRun のグリフのオフセットを表す Point 値の配列を取得または設定します。

            //GlyphTypeface     GlyphTypeface
            //GlyphTypeface の GlyphRun を取得または設定します。

            //IsHitTestable     bool
            //GlyphRun 内に有効なキャレット文字ヒットがあるかどうかを示す値を取得します。

            //IsSideways        bool
            //グリフを回転するかどうかを示す値を取得または設定します。

            //Language          XmlLanguage
            //XmlLanguage の GlyphRun を取得または設定します。

            //PixelsPerDip      Single
            //テキストを表示する PixelsPerDip を取得または設定します。


            //メソッド
            //BuildGeometry
            //  GlyphRunのジオメトリを取得します。
            //ComputeAlignmentBox   Rect
            //  GlyphRunの配置ボックスを取得します。
            //ComputeInkBoundingBox Rect
            //  GlyphRunのインク境界ボックスを取得します。
            //GetCaretCharacterHitFromDistance(Double, Boolean) CharacterHitグリフラン内でヒットした文字に関する情報を表します。
            //  GlyphRunのキャレットの文字ヒットを表すCharacterHit値を取得します。
            //GetDistanceFromCaretCharacterHit(CharacterHit) double
            //  GlyphRunの前縁から、指定された文字ヒットを含むキャレットストップの前縁または後縁までのオフセットを取得します。
            //GetNextCaretCharacterHit(CharacterHit) CharacterHit
            //  GlyphRunで論理方向にヒットした次の有効なキャレット文字を取得します。
            //GetPreviousCaretCharacterHit(CharacterHit) CharacterHit
            //  GlyphRunで論理方向にヒットした前の有効なキャレット文字を取得します。
        }
Ejemplo n.º 25
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);
        }