Пример #1
0
            private void FlushPath()
            {
                if (_currPath != null)
                {
                    _currPath.CloseFigure();

                    // Abort on empty paths (e.g. rendering a space)
                    if (_currPath.PointCount < 1)
                    {
                        _anchoredPaths.Clear();
                        _xAnchor  = float.MinValue;
                        _currPath = null;
                        return;
                    }

                    if (_xAnchor > float.MinValue)
                    {
                        float      minX = float.MaxValue;
                        float      maxX = float.MinValue;
                        RectangleF bounds;
                        foreach (var path in _anchoredPaths)
                        {
                            bounds = path.GetBounds();
                            if (bounds.Left < minX)
                            {
                                minX = bounds.Left;
                            }
                            if (bounds.Right > maxX)
                            {
                                maxX = bounds.Right;
                            }
                        }

                        var xOffset = 0f; //_xAnchor - minX;
                        switch (Element.TextAnchor)
                        {
                        case SvgTextAnchor.Middle:
                            if (_anchoredPaths.Count() == 1)
                            {
                                xOffset -= this.TextBounds.Width / 2;
                            }
                            else
                            {
                                xOffset -= (maxX - minX) / 2;
                            }
                            break;

                        case SvgTextAnchor.End:
                            if (_anchoredPaths.Count() == 1)
                            {
                                xOffset -= this.TextBounds.Width;
                            }
                            else
                            {
                                xOffset -= (maxX - minX);
                            }
                            break;
                        }

                        if (xOffset != 0)
                        {
                            using (var matrix = new Matrix())
                            {
                                matrix.Translate(xOffset, 0);
                                foreach (var path in _anchoredPaths)
                                {
                                    path.Transform(matrix);
                                }
                            }
                        }

                        _anchoredPaths.Clear();
                        _xAnchor = float.MinValue;
                    }

                    if (_finalPath == null)
                    {
                        _finalPath = _currPath;
                    }
                    else
                    {
                        _finalPath.AddPath(_currPath, false);
                    }

                    _currPath = null;
                }
            }
Пример #2
0
        /// <summary>
        /// Sets the path on this element and all child elements.  Uses the state
        /// object to track the state of the drawing
        /// </summary>
        /// <param name="state">State of the drawing operation</param>
        /// <param name="doMeasurements">If true, calculate and apply text length adjustments.</param>
        private void SetPath(TextDrawingState state, bool doMeasurements)
        {
            TextDrawingState origState       = null;
            bool             alignOnBaseline = state.BaselinePath != null && (this.TextAnchor == SvgTextAnchor.Middle || this.TextAnchor == SvgTextAnchor.End);

            if (doMeasurements)
            {
                if (this.TextLength != SvgUnit.None)
                {
                    origState = state.Clone();
                }
                else if (alignOnBaseline)
                {
                    origState          = state.Clone();
                    state.BaselinePath = null;
                }
            }

            foreach (var node in GetContentNodes())
            {
                SvgTextBase textNode = node as SvgTextBase;

                if (textNode == null)
                {
                    if (!string.IsNullOrEmpty(node.Content))
                    {
                        state.DrawString(PrepareText(node.Content));
                    }
                }
                else
                {
                    TextDrawingState newState = new TextDrawingState(state, textNode);

                    textNode.SetPath(newState);
                    state.NumChars += newState.NumChars;
                    state.Current   = newState.Current;
                }
            }

            var path = state.GetPath() ?? new GraphicsPath();

            // Apply any text length adjustments
            if (doMeasurements)
            {
                if (this.TextLength != SvgUnit.None)
                {
                    var specLength = this.TextLength.ToDeviceValue(state.Renderer, UnitRenderingType.Horizontal, this);
                    var actLength  = state.TextBounds.Width;
                    var diff       = (actLength - specLength);
                    if (Math.Abs(diff) > 1.5)
                    {
                        if (this.LengthAdjust == SvgTextLengthAdjust.Spacing)
                        {
                            if (this.X.Count < 2)
                            {
                                var numCharDiff = state.NumChars - origState.NumChars - 1;
                                if (numCharDiff != 0)
                                {
                                    origState.LetterSpacingAdjust = -1 * diff / numCharDiff;
                                    SetPath(origState, false);
                                    return;
                                }
                            }
                        }
                        else
                        {
                            using (var matrix = new Matrix())
                            {
                                matrix.Translate(-1 * state.TextBounds.X, 0, MatrixOrder.Append);
                                matrix.Scale(specLength / actLength, 1, MatrixOrder.Append);
                                matrix.Translate(state.TextBounds.X, 0, MatrixOrder.Append);
                                path.Transform(matrix);
                            }
                        }
                    }
                }
                else if (alignOnBaseline)
                {
                    var bounds = path.GetBounds();
                    if (this.TextAnchor == SvgTextAnchor.Middle)
                    {
                        origState.StartOffsetAdjust = -1 * bounds.Width / 2;
                    }
                    else
                    {
                        origState.StartOffsetAdjust = -1 * bounds.Width;
                    }
                    SetPath(origState, false);
                    return;
                }
            }


            _path            = path;
            this.IsPathDirty = false;
        }