コード例 #1
0
        private void RenderStartAlignedText(DrawingContext dc, PathGeometry svgPath,
                                            ISvgAnimatedLength startOffset, TextAlignment alignment)
        {
            if (svgPath == null || svgPath.Figures == null || svgPath.Figures.Count != 1)
            {
//                Debug.Assert(false, "Monitor invalid path cases in debug mode!");
                return;
            }

            var pathFigure = svgPath.Figures[0];

            _pathLength = WpfConvert.GetPathFigureLength(pathFigure);
            if (_pathLength.Equals(0) || _textLength.Equals(0))
            {
                return;
            }

            //double scalingFactor = pathLength / textLength;
            double scalingFactor = 1.0; // Not scaling the text to fit...
            double progress      = 0;

            if (startOffset != null && startOffset.AnimVal != null)
            {
                ISvgLength offsetLength = startOffset.AnimVal;
                switch (offsetLength.UnitType)
                {
                // If a percentage is given, then the startOffset represents a
                // percentage distance along the entire path.
                case SvgLengthType.Percentage:
                    if (!offsetLength.ValueInSpecifiedUnits.Equals(0))
                    {
                        progress += offsetLength.ValueInSpecifiedUnits / 100d;
                    }
                    break;

                // If a length other than a percentage is given, then the startOffset represents a distance along
                // the path measured in the current user coordinate system.
                case SvgLengthType.Number:
                    progress += offsetLength.ValueInSpecifiedUnits / _pathLength;
                    break;
                }
            }
            PathGeometry pathGeometry = new PathGeometry(new PathFigure[] { pathFigure });

            Point ptPrevPos = new Point(0, 0);

            double letterSpacing = 0;

            if (_textElement.LetterSpacing != null && _textElement.LetterSpacing.AnimVal != null)
            {
                letterSpacing = _textElement.LetterSpacing.AnimVal.ValueInSpecifiedUnits;
            }

            _pathLength += letterSpacing;

            var lengthFactor = 1.0;

            var textLength = this.GetTextLength();

            if (textLength != null && textLength.AnimVal != null)
            {
                var textLengthValue = textLength.AnimVal.ValueInSpecifiedUnits;
                if (textLengthValue > 0)
                {
                    lengthFactor = textLengthValue / _pathLength;
//                    lengthFactor = _textLength / textLengthValue;
//                    lengthFactor = textLengthValue / _textLength;
//                    lengthFactor = _pathLength / textLengthValue;
                    if (lengthFactor < 0.5) // Check for abuse!
                    {
                        lengthFactor = 1;
                    }
                }
            }

            int charCount = _pathChars.Count;

            for (int i = 0; i < charCount; i++)
            {
                var pathChar = _pathChars[i];

                var pathTextRun = _pathTextRuns[pathChar.Index];
                var textBuilder = pathTextRun.Builder;

                double width    = (scalingFactor * pathChar.Width * lengthFactor + letterSpacing);
                double baseline = scalingFactor * textBuilder.Baseline;

                progress += width / 2 / _pathLength;
                if (progress > 1)
                {
                    break;
                }
                Point ptNextPos, ptTangent;

                pathGeometry.GetPointAtFractionLength(progress, out ptNextPos, out ptTangent);

                if (i != 0 && AreEqual(ptNextPos, ptPrevPos))
                {
                    break;
                }

                var textPath = textBuilder.Build(pathTextRun.Element, pathChar.Text, pathChar.X, pathChar.Y);

                var textTransform = new TransformGroup();
                textTransform.Children.Add(new RotateTransform(Math.Atan2(ptTangent.Y, ptTangent.X) * 180 / Math.PI, width / 2, baseline));
                textTransform.Children.Add(new TranslateTransform(ptNextPos.X - width / 2, ptNextPos.Y - baseline));

                var curTransform = textPath.Transform;
                if (curTransform != null && curTransform.Value.IsIdentity == false)
                {
                    textTransform.Children.Add(curTransform);
                }

                textPath.Transform = new MatrixTransform(textTransform.Value);

                pathTextRun.AddRun(textPath);

                progress += width / 2 / _pathLength;

                ptPrevPos = ptNextPos;
            }

            foreach (var pathTextRun in _pathTextRuns)
            {
                pathTextRun.RenderRun(dc);
            }
        }
コード例 #2
0
        private void RenderEndAlignedText(DrawingContext dc, PathGeometry svgPath, ISvgAnimatedLength startOffset)
        {
            if (svgPath == null || svgPath.Figures == null || svgPath.Figures.Count != 1)
            {
                Debug.Assert(false, "Monitor invalid path cases in debug mode!");
                return;
            }

            var pathFigure = svgPath.Figures[0];

            _pathLength = WpfConvert.GetPathFigureLength(pathFigure);
            if (_pathLength.Equals(0) || _textLength.Equals(0))
            {
                return;
            }

            double scalingFactor = 1.0; // Not scaling the text to fit...
            double progress      = 1.0;

            if (startOffset != null && startOffset.AnimVal != null)
            {
                ISvgLength offsetLength = startOffset.AnimVal;
                if (offsetLength.Value < 0)
                {
                    progress = 0;
                }

                switch (offsetLength.UnitType)
                {
                // If a percentage is given, then the startOffset represents a
                // percentage distance along the entire path.
                case SvgLengthType.Percentage:
                    if (!offsetLength.ValueInSpecifiedUnits.Equals(0))
                    {
                        progress += offsetLength.ValueInSpecifiedUnits / 100d;
                    }
                    break;

                // If a length other than a percentage is given, then the startOffset represents a distance along
                // the path measured in the current user coordinate system.
                case SvgLengthType.Number:
                    progress += offsetLength.ValueInSpecifiedUnits / _pathLength;
                    break;
                }
            }
            if (progress < 0)
            {
                progress *= -1;
            }

            if (progress > 1)
            {
                progress = progress - 1;
                while (progress > 1)
                {
                    progress = progress - 1;
                }
            }
            PathGeometry pathGeometry = new PathGeometry(new PathFigure[] { pathFigure });

            Point ptPrevPos = new Point(0, 0);

            int charCount = _pathChars.Count - 1;

            for (int i = charCount; i >= 0; i--)
            {
                var pathChar = _pathChars[i];

                var pathTextRun = _pathTextRuns[pathChar.Index];
                var textBuilder = pathTextRun.Builder;

                double width    = scalingFactor * pathChar.Width;
                double baseline = scalingFactor * textBuilder.Baseline;

                progress -= width / 2 / _pathLength;
                if (progress < 0)
                {
                    break;
                }
                Point ptNext, ptTangent;

                pathGeometry.GetPointAtFractionLength(progress, out ptNext, out ptTangent);

                if (i != charCount && AreEqual(ptNext, ptPrevPos))
                {
                    break;
                }

                var textPath = textBuilder.Build(pathTextRun.Element, pathChar.Text, pathChar.X, pathChar.Y);

                var textTransform = new TransformGroup();
                textTransform.Children.Add(new RotateTransform(Math.Atan2(ptTangent.Y, ptTangent.X) * 180 / Math.PI, width / 2, baseline));
                textTransform.Children.Add(new TranslateTransform(ptNext.X - width / 2, ptNext.Y - baseline));

                var curTransform = textPath.Transform;
                if (curTransform != null && curTransform.Value.IsIdentity == false)
                {
                    //Debug.Assert(false, "TODO: Wish to see the case");
                    textTransform.Children.Add(curTransform);
                }

                textPath.Transform = new MatrixTransform(textTransform.Value);

                pathTextRun.AddRun(textPath);

                progress -= width / 2 / _pathLength;

                ptPrevPos = ptNext;
            }

            foreach (var pathTextRun in _pathTextRuns)
            {
                pathTextRun.RenderRun(dc);
            }
        }
コード例 #3
0
 public SvgAnimatedLength(ISvgLength baseVal, ISvgLength animVal)
 {
     _baseVal = baseVal;
     _animVal = animVal;
 }
コード例 #4
0
        private void DrawStartAlignedTextPath(DrawingContext dc, PathGeometry pathGeometry,
                                              ISvgAnimatedLength startOffset, TextAlignment alignment)
        {
            if (pathGeometry == null || pathGeometry.Figures == null ||
                pathGeometry.Figures.Count != 1)
            {
                return;
            }

            _pathLength = GetPathFigureLength(pathGeometry.Figures[0]);
            if (_pathLength == 0 || _textLength == 0)
            {
                return;
            }

            //double scalingFactor = pathLength / textLength;
            double scalingFactor = 1.0;   // Not scaling the text to fit...
            double progress      = 0;

            if (startOffset != null)
            {
                ISvgLength offsetLength = startOffset.AnimVal;
                if (offsetLength != null)
                {
                    switch (offsetLength.UnitType)
                    {
                    case SvgLengthType.Percentage:
                        if ((float)offsetLength.ValueInSpecifiedUnits != 0)
                        {
                            progress += offsetLength.ValueInSpecifiedUnits / 100d;
                        }
                        break;
                    }
                }
            }
            //PathGeometry pathGeometry =
            //    new PathGeometry(new PathFigure[] { PathFigure });

            Point ptOld = new Point(0, 0);

            for (int i = 0; i < _formattedChars.Count; i++)
            {
                FormattedText formText = _formattedChars[i];

                double width = scalingFactor *
                               formText.WidthIncludingTrailingWhitespace;
                double baseline = scalingFactor * formText.Baseline;
                progress += width / 2 / _pathLength;
                Point point, tangent;

                pathGeometry.GetPointAtFractionLength(progress,
                                                      out point, out tangent);

                if (i != 0)
                {
                    if (point == ptOld)
                    {
                        break;
                    }
                }

                dc.PushTransform(
                    new TranslateTransform(point.X - width / 2,
                                           point.Y - baseline));
                dc.PushTransform(
                    new RotateTransform(Math.Atan2(tangent.Y, tangent.X)
                                        * 180 / Math.PI, width / 2, baseline));
                //dc.PushTransform(
                //    new ScaleTransform(scalingFactor, scalingFactor));

                dc.DrawText(formText, _formattedOrigins[i]);
                dc.Pop();
                dc.Pop();
                //dc.Pop();

                progress += width / 2 / _pathLength;

                ptOld = point;
            }
        }
コード例 #5
0
ファイル: SvgLengthList.cs プロジェクト: codebutler/savagesvg
 public ISvgLength ReplaceItem(ISvgLength newItem, uint index)
 {
     return (ISvgLength) base.ReplaceItem(newItem, index);
 }
コード例 #6
0
 public SvgAnimatedLength(SvgElement ownerElement, string propertyName,
                          SvgLengthDirection direction, string strValue, string defaultValue)
 {
     _baseVal = new SvgLength(ownerElement, propertyName, direction, strValue, defaultValue);
     _animVal = _baseVal;
 }
コード例 #7
0
ファイル: SvgLengthList.cs プロジェクト: codebutler/savagesvg
 public ISvgLength Initialize(ISvgLength newItem)
 {
     return (ISvgLength) base.Initialize(newItem);
 }
コード例 #8
0
ファイル: SvgLengthList.cs プロジェクト: codebutler/savagesvg
 public ISvgLength InsertItemBefore(ISvgLength newItem, uint index)
 {
     return (ISvgLength) base.InsertItemBefore(newItem, index);
 }
コード例 #9
0
ファイル: SvgLengthList.cs プロジェクト: codebutler/savagesvg
 public ISvgLength AppendItem(ISvgLength newItem)
 {
     return (ISvgLength) base.AppendItem(newItem);
 }
コード例 #10
0
ファイル: SvgLengthList.cs プロジェクト: nagyist/savagesvg
 public ISvgLength AppendItem(ISvgLength newItem)
 {
     return((ISvgLength)base.AppendItem(newItem));
 }
コード例 #11
0
ファイル: SvgLengthList.cs プロジェクト: nagyist/savagesvg
 public ISvgLength ReplaceItem(ISvgLength newItem, uint index)
 {
     return((ISvgLength)base.ReplaceItem(newItem, index));
 }
コード例 #12
0
ファイル: SvgLengthList.cs プロジェクト: nagyist/savagesvg
 public ISvgLength InsertItemBefore(ISvgLength newItem, uint index)
 {
     return((ISvgLength)base.InsertItemBefore(newItem, index));
 }
コード例 #13
0
ファイル: SvgLengthList.cs プロジェクト: nagyist/savagesvg
 public ISvgLength Initialize(ISvgLength newItem)
 {
     return((ISvgLength)base.Initialize(newItem));
 }