public static Geometry ConstructTextGeometry(SvgTextContentElement textContentElement, string text, Point position, out Size textDimensions)
        {
            Typeface typeface = new Typeface(
                GetTextFontFamily(textContentElement),
                GetTextFontStyle(textContentElement),
                GetTextFontWeight(textContentElement),
                GetTextFontStretch(textContentElement));

            FormattedText formattedText = new FormattedText(text,
                                                            System.Globalization.CultureInfo.CurrentUICulture,
                                                            GetTextDirection(textContentElement),
                                                            typeface,
                                                            GetComputedFontSize(textContentElement),
                                                            Brushes.Black)
            {
                LineHeight = GetComputedLineHeight(textContentElement)
            };

            SvgTextPositioningElement tpe = textContentElement as SvgTextPositioningElement;

            if (tpe != null)
            {
                position = GetCurrentTextPosition(tpe, position);
            }
            position.Y -= formattedText.Height;

            textDimensions = new Size(formattedText.Width, formattedText.Height);
            return(formattedText.BuildGeometry(position));
        }
        private StringFormat GetStringFormat(SvgTextContentElement element)
        {
            var comparer = StringComparison.OrdinalIgnoreCase;

            StringFormat sf = new StringFormat();

            bool doAlign = true;

            if (element is SvgTSpanElement || element is SvgTRefElement)
            {
                SvgTextPositioningElement posElement = (SvgTextPositioningElement)element;
                if (posElement.X.AnimVal.NumberOfItems == 0)
                {
                    doAlign = false;
                }
            }

            if (doAlign)
            {
                string anchor = element.GetPropertyValue("text-anchor");
                if (string.Equals(anchor, "middle", comparer))
                {
                    sf.Alignment = StringAlignment.Center;
                }
                if (string.Equals(anchor, "end", comparer))
                {
                    sf.Alignment = StringAlignment.Far;
                }
            }

            string dir = element.GetPropertyValue("direction");

            if (string.Equals(dir, "rtl", comparer))
            {
                if (sf.Alignment == StringAlignment.Far)
                {
                    sf.Alignment = StringAlignment.Near;
                }
                else if (sf.Alignment == StringAlignment.Near)
                {
                    sf.Alignment = StringAlignment.Far;
                }
                sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
            }

            dir = element.GetPropertyValue("writing-mode");
            if (string.Equals(dir, "tb", comparer))
            {
                sf.FormatFlags = sf.FormatFlags | StringFormatFlags.DirectionVertical;
            }

            sf.FormatFlags = sf.FormatFlags | StringFormatFlags.MeasureTrailingSpaces;

            return(sf);
        }
Beispiel #3
0
        private ISvgAnimatedLength GetStartOffset(SvgTextBaseElement textElement)
        {
            ISvgAnimatedLengthList    pathOffsets = null;
            SvgTextPositioningElement posElement  = _contentElement as SvgTextPositioningElement;

            if (posElement == null)
            {
                pathOffsets = textElement.Dx;
                if (pathOffsets != null && pathOffsets.Count != 0)
                {
                    return(pathOffsets[0]);
                }
                pathOffsets = textElement.X;
                if (pathOffsets != null && pathOffsets.Count != 0)
                {
                    return(pathOffsets[0]);
                }
                return(null);
            }
            pathOffsets = posElement.Dx;
            if (pathOffsets != null && pathOffsets.Count != 0)
            {
                return(pathOffsets[0]);
            }
            pathOffsets = posElement.X;
            if (pathOffsets != null && pathOffsets.Count != 0)
            {
                return(pathOffsets[0]);
            }

            pathOffsets = textElement.Dx;
            if (pathOffsets != null && pathOffsets.Count != 0)
            {
                return(pathOffsets[0]);
            }
            pathOffsets = textElement.X;
            if (pathOffsets != null && pathOffsets.Count != 0)
            {
                return(pathOffsets[0]);
            }
            return(null);
        }
Beispiel #4
0
 public static Point GetCurrentTextPosition(SvgTextPositioningElement posElement, Point p)
 {
     if (posElement.X.AnimVal.NumberOfItems > 0)
     {
         p.X = (float)posElement.X.AnimVal.GetItem(0).Value;
     }
     if (posElement.Y.AnimVal.NumberOfItems > 0)
     {
         p.Y = (float)posElement.Y.AnimVal.GetItem(0).Value;
     }
     if (posElement.Dx.AnimVal.NumberOfItems > 0)
     {
         p.X += (float)posElement.Dx.AnimVal.GetItem(0).Value;
     }
     if (posElement.Dy.AnimVal.NumberOfItems > 0)
     {
         p.Y += (float)posElement.Dy.AnimVal.GetItem(0).Value;
     }
     return(p);
 }
        protected WpfTextStringFormat GetTextStringFormat(SvgTextContentElement element)
        {
            WpfTextStringFormat sf = WpfTextStringFormat.Default;

            bool doAlign = true;

            if (element is SvgTSpanElement || element is SvgTRefElement)
            {
                SvgTextPositioningElement posElement = (SvgTextPositioningElement)element;
                if (posElement.X.AnimVal.NumberOfItems == 0)
                {
                    doAlign = false;
                }
            }

            var comparer = StringComparison.OrdinalIgnoreCase;

            string dir           = element.GetPropertyValue("direction");
            bool   isRightToLeft = string.Equals(dir, "rtl", comparer);

            sf.Direction = isRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;

            if (doAlign)
            {
                string anchor = element.GetPropertyValue("text-anchor");

                if (isRightToLeft)
                {
                    if (string.Equals(anchor, "middle", comparer))
                    {
                        sf.Anchor = WpfTextAnchor.Middle;
                    }
                    else if (string.Equals(anchor, "end", comparer))
                    {
                        sf.Anchor = WpfTextAnchor.Start;
                    }
                    else
                    {
                        sf.Anchor = WpfTextAnchor.End;
                    }
                }
                else
                {
                    if (string.Equals(anchor, "middle", comparer))
                    {
                        sf.Anchor = WpfTextAnchor.Middle;
                    }
                    else if (string.Equals(anchor, "end", comparer))
                    {
                        sf.Anchor = WpfTextAnchor.End;
                    }
                }
            }
            else
            {
                SvgTextElement textElement = element.ParentNode as SvgTextElement;
                if (textElement != null)
                {
                    string anchor = textElement.GetPropertyValue("text-anchor");
                    if (isRightToLeft)
                    {
                        if (string.Equals(anchor, "middle", comparer))
                        {
                            sf.Anchor = WpfTextAnchor.Middle;
                        }
                        else if (string.Equals(anchor, "end", comparer))
                        {
                            sf.Anchor = WpfTextAnchor.Start;
                        }
                        else
                        {
                            sf.Anchor = WpfTextAnchor.End;
                        }
                    }
                    else
                    {
                        if (string.Equals(anchor, "middle", comparer))
                        {
                            sf.Anchor = WpfTextAnchor.Middle;
                        }
                        else if (string.Equals(anchor, "end", comparer))
                        {
                            sf.Anchor = WpfTextAnchor.End;
                        }
                    }
                }
            }

            //if (isRightToLeft)
            //{
            //    if (sf.Alignment == TextAlignment.Right)
            //        sf.Alignment = TextAlignment.Left;
            //    else if (sf.Alignment == TextAlignment.Left)
            //        sf.Alignment = TextAlignment.Right;

            //    //sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
            //}

            //dir = element.GetPropertyValue("writing-mode");
            //if (dir == "tb")
            //{
            //    sf.FormatFlags = sf.FormatFlags | StringFormatFlags.DirectionVertical;
            //}

            //sf.FormatFlags = sf.FormatFlags | StringFormatFlags.MeasureTrailingSpaces;

            return(sf);
        }
        public static WpfTextPlacement GetCurrentTextPosition(SvgTextPositioningElement posElement, Point p)
        {
            ISvgLengthList xValues  = posElement.X.AnimVal;
            ISvgLengthList yValues  = posElement.Y.AnimVal;
            ISvgLengthList dxValues = posElement.Dx.AnimVal;
            ISvgLengthList dyValues = posElement.Dy.AnimVal;
            ISvgNumberList rValues  = posElement.Rotate.AnimVal;

            bool requiresGlyphPositioning = false;
            bool isXYGlyphPositioning     = false;
            bool isDxyGlyphPositioning    = false;
            bool isRotateGlyphPositioning = false;

            double xValue  = p.X;
            double yValue  = p.Y;
            double rValue  = 0;
            double dxValue = 0;
            double dyValue = 0;

            WpfTextPlacement textPlacement = null;

            if (xValues.NumberOfItems > 0)
            {
                if (xValues.NumberOfItems > 1)
                {
                    isXYGlyphPositioning     = true;
                    requiresGlyphPositioning = true;
                }

                xValue = xValues.GetItem(0).Value;
                p.X    = xValue;
            }
            if (yValues.NumberOfItems > 0)
            {
                if (yValues.NumberOfItems > 1)
                {
                    isXYGlyphPositioning     = true;
                    requiresGlyphPositioning = true;
                }

                yValue = yValues.GetItem(0).Value;
                p.Y    = yValue;
            }
            if (dxValues.NumberOfItems > 0)
            {
                if (dxValues.NumberOfItems > 1)
                {
                    isDxyGlyphPositioning    = true;
                    requiresGlyphPositioning = true;
                }

                dxValue = dxValues.GetItem(0).Value;
                p.X    += dxValue;
            }
            if (dyValues.NumberOfItems > 0)
            {
                if (dyValues.NumberOfItems > 1)
                {
                    isDxyGlyphPositioning    = true;
                    requiresGlyphPositioning = true;
                }

                dyValue = dyValues.GetItem(0).Value;
                p.Y    += dyValue;
            }
            if (rValues.NumberOfItems > 0)
            {
                if (rValues.NumberOfItems > 1)
                {
                    isRotateGlyphPositioning = true;
                    requiresGlyphPositioning = true;
                }

                rValue = rValues.GetItem(0).Value;
            }

            if (requiresGlyphPositioning)
            {
                uint xCount  = xValues.NumberOfItems;
                uint yCount  = yValues.NumberOfItems;
                uint dxCount = dxValues.NumberOfItems;
                uint dyCount = dyValues.NumberOfItems;
                uint rCount  = rValues.NumberOfItems;

                List <WpfTextPosition> textPositions = null;

                bool isRotateOnly = false;

                if (isXYGlyphPositioning)
                {
                    uint itemCount = Math.Max(Math.Max(xCount, yCount), Math.Max(dxCount, dyCount));
                    itemCount     = Math.Max(itemCount, rCount);
                    textPositions = new List <WpfTextPosition>((int)itemCount);

                    double xLast = 0;
                    double yLast = 0;

                    for (uint i = 0; i < itemCount; i++)
                    {
                        double xNext = i < xCount?xValues.GetItem(i).Value  : xValue;

                        double yNext = i < yCount?yValues.GetItem(i).Value  : yValue;

                        double rNext = i < rCount?rValues.GetItem(i).Value  : rValue;

                        double dxNext = i < dxCount?dxValues.GetItem(i).Value : dxValue;

                        double dyNext = i < dyCount?dyValues.GetItem(i).Value : dyValue;

                        if (i < xCount)
                        {
                            xLast = xNext;
                        }
                        else
                        {
                            xNext = xLast;
                        }
                        if (i < yCount)
                        {
                            yLast = yNext;
                        }
                        else
                        {
                            yNext = yLast;
                        }

                        WpfTextPosition textPosition = new WpfTextPosition(
                            new Point(xNext + dxNext, yNext + dyNext), rNext);

                        textPositions.Add(textPosition);
                    }
                }
                else if (isDxyGlyphPositioning)
                {
                }
                else if (isRotateGlyphPositioning)
                {
                    isRotateOnly = true;
                    uint itemCount = Math.Max(Math.Max(xCount, yCount), Math.Max(dxCount, dyCount));
                    itemCount     = Math.Max(itemCount, rCount);
                    textPositions = new List <WpfTextPosition>((int)itemCount);

                    for (uint i = 0; i < itemCount; i++)
                    {
                        double rNext = i < rCount?rValues.GetItem(i).Value  : rValue;

                        WpfTextPosition textPosition = new WpfTextPosition(p, rNext);

                        textPositions.Add(textPosition);
                    }
                }

                if (textPositions != null && textPositions.Count != 0)
                {
                    textPlacement = new WpfTextPlacement(p, rValue, textPositions, isRotateOnly);
                }
                else
                {
                    textPlacement = new WpfTextPlacement(p, rValue);
                }
            }
            else
            {
                textPlacement = new WpfTextPlacement(p, rValue);
            }

            return(textPlacement);
        }
        public static WpfTextPlacement Create(SvgTextPositioningElement posElement, Point p, bool isTextPath = false)
        {
            ISvgLengthList xValues  = posElement.X.AnimVal;
            ISvgLengthList yValues  = posElement.Y.AnimVal;
            ISvgLengthList dxValues = posElement.Dx.AnimVal;
            ISvgLengthList dyValues = posElement.Dy.AnimVal;
            ISvgNumberList rValues  = posElement.Rotate.AnimVal;

            bool requiresGlyphPositioning = false;
            bool isXYGlyphPositioning     = false;
            bool isDxyGlyphPositioning    = false;
            bool isRotateGlyphPositioning = false;

            double xValue  = p.X;
            double yValue  = p.Y;
            double rValue  = 0;
            double dxValue = 0;
            double dyValue = 0;

            WpfTextPlacement textPlacement = null;

            if (xValues.NumberOfItems > 0 && isTextPath == false)
            {
                if (xValues.NumberOfItems > 1)
                {
                    isXYGlyphPositioning     = true;
                    requiresGlyphPositioning = true;
                }

                xValue = xValues.GetItem(xValues.NumberOfItems - 1).Value;
                p.X    = xValue;
            }
            if (yValues.NumberOfItems > 0)
            {
                if (yValues.NumberOfItems > 1)
                {
                    isXYGlyphPositioning     = true;
                    requiresGlyphPositioning = true;
                }

                yValue = yValues.GetItem(yValues.NumberOfItems - 1).Value;
                p.Y    = yValue;
            }
            if (dxValues.NumberOfItems > 0 && isTextPath == false)
            {
                if (dxValues.NumberOfItems > 1)
                {
                    isDxyGlyphPositioning    = true;
                    requiresGlyphPositioning = true;
                }

                dxValue = dxValues.GetItem(dxValues.NumberOfItems - 1).Value;
                p.X    += dxValue;
            }
            if (dyValues.NumberOfItems > 0)
            {
                if (dyValues.NumberOfItems > 1)
                {
                    isDxyGlyphPositioning    = true;
                    requiresGlyphPositioning = true;
                }

                dyValue = dyValues.GetItem(dyValues.NumberOfItems - 1).Value;
                p.Y    += dyValue;
            }
            if (rValues.NumberOfItems > 0)
            {
                if (rValues.NumberOfItems > 1)
                {
                    isRotateGlyphPositioning = true;
                    requiresGlyphPositioning = true;
                }

                // If the element contains more characters than the number of values specified
                // in the "rotate" attribute. In this case the last value specified in the "rotate"
                // attribute of the "tspan" must be applied to the remaining characters in the string.
                rValue = rValues.GetItem(rValues.NumberOfItems - 1).Value;
            }

            if (requiresGlyphPositioning)
            {
                uint xCount  = xValues.NumberOfItems;
                uint yCount  = yValues.NumberOfItems;
                uint dxCount = dxValues.NumberOfItems;
                uint dyCount = dyValues.NumberOfItems;
                uint rCount  = rValues.NumberOfItems;

                List <WpfTextPosition> textPositions = null;

                bool isRotateOnly = false;

                if (isXYGlyphPositioning)
                {
                    uint itemCount = Math.Max(Math.Max(xCount, yCount), Math.Max(dxCount, dyCount));
                    itemCount     = Math.Max(itemCount, rCount);
                    textPositions = new List <WpfTextPosition>((int)itemCount);

                    double xLast = 0;
                    double yLast = 0;

                    for (uint i = 0; i < itemCount; i++)
                    {
                        double xNext = i < xCount?xValues.GetItem(i).Value : xValue;

                        double yNext = i < yCount?yValues.GetItem(i).Value : yValue;

                        double rNext = i < rCount?rValues.GetItem(i).Value : rValue;

                        double dxNext = i < dxCount?dxValues.GetItem(i).Value : dxValue;

                        double dyNext = i < dyCount?dyValues.GetItem(i).Value : dyValue;

                        if (i < xCount)
                        {
                            xLast = xNext;
                        }
                        else
                        {
                            xNext = xLast;
                        }
                        if (i < yCount)
                        {
                            yLast = yNext;
                        }
                        else
                        {
                            yNext = yLast;
                        }

                        WpfTextPosition textPosition = new WpfTextPosition(
                            new Point(xNext + dxNext, yNext + dyNext), rNext);

                        textPositions.Add(textPosition);
                    }
                }
                else if (isDxyGlyphPositioning)
                {
                }
                else if (isRotateGlyphPositioning)
                {
                    isRotateOnly = true;
                    uint itemCount = Math.Max(Math.Max(xCount, yCount), Math.Max(dxCount, dyCount));
                    itemCount     = Math.Max(itemCount, rCount);
                    textPositions = new List <WpfTextPosition>((int)itemCount);

                    for (uint i = 0; i < itemCount; i++)
                    {
                        double rNext = i < rCount?rValues.GetItem(i).Value : rValue;

                        WpfTextPosition textPosition = new WpfTextPosition(p, rNext);

                        textPositions.Add(textPosition);
                    }
                }

                if (textPositions != null && textPositions.Count != 0)
                {
                    textPlacement = new WpfTextPlacement(p, rValue, textPositions, isRotateOnly);
                }
                else
                {
                    textPlacement = new WpfTextPlacement(p, rValue);
                }
            }
            else
            {
                textPlacement = new WpfTextPlacement(p, rValue);
            }

            return(textPlacement);
        }