public WpfGlyphTextBuilder(WpfFontFamilyInfo familyInfo, CultureInfo culture, double fontSize)
            : base(culture, familyInfo.Name, fontSize, null)
        {
            _typeface = new Typeface(familyInfo.Family, familyInfo.Style, familyInfo.Weight, familyInfo.Stretch);

            if (!_typeface.TryGetGlyphTypeface(out _glyphTypeface))
            {
                throw new ArgumentException();
            }
        }
        private void RenderTextPath(SvgTextContentElement element, WpfTextOnPathDrawing pathDrawing,
                                    string text, Point origin, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            double     emSize     = GetComputedFontSize(element);
            FontFamily fontFamily = GetTextFontFamily(element, emSize);

            FontStyle  fontStyle  = GetTextFontStyle(element);
            FontWeight fontWeight = GetTextFontWeight(element);

            FontStretch fontStretch = GetTextFontStretch(element);

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
                                                                        fontStyle, fontStretch);
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       currentFamily, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         pen         = strokePaint.GetPen();

            TextDecorationCollection textDecors = GetTextDecoration(element);
            TextAlignment            alignment  = stringFormat.Alignment;

            pathDrawing.FontSize = emSize;

            pathDrawing.FontFamily  = fontFamily;
            pathDrawing.FontWeight  = fontWeight;
            pathDrawing.FontStretch = fontStretch;

            pathDrawing.Foreground = textBrush;

            pathDrawing.AddTextPath(text, origin);
        }
Beispiel #3
0
        private void RenderTextPath(SvgTextContentElement element, WpfPathTextBuilder pathBuilder,
                                    string text, Point origin, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            WpfSvgPaint fillPaint   = new WpfSvgPaint(_context, element, "fill");
            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Brush       textBrush   = fillPaint.GetBrush();
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }

            double emSize         = GetComputedFontSize(element);
            var    fontFamilyInfo = GetTextFontFamilyInfo(element);

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       fontFamilyInfo, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamilyInfo = familyInfo;
                }
            }

            // Create the text builder object defined by the font family information
            WpfTextBuilder textBuilder = WpfTextBuilder.Create(fontFamilyInfo, this.TextCulture, emSize);

            textBuilder.TextDecorations = GetTextDecoration(element);
            textBuilder.TextAlignment   = stringFormat.Alignment;
            // This is character-by-character placement, text-alignment will distort the view...
            textBuilder.TextAlignment = TextAlignment.Left;

            // Create the path-run information holder for this render request...
            WpfPathTextRun textPathRun = new WpfPathTextRun(element, textBuilder);

            // Finally, register the path-run with path builder...
            pathBuilder.AddTextRun(textPathRun, text, origin, textBrush, textPen);
        }
Beispiel #4
0
        public static WpfTextBuilder Create(WpfFontFamilyInfo familyInfo, CultureInfo culture, double fontSize)
        {
            if (familyInfo == null)
            {
                return(new WpfGlyphTextBuilder(culture, fontSize));
            }
            if (familyInfo.FontFamilyType == WpfFontFamilyType.Svg)
            {
                WpfSvgTextBuilder textBuilder = new WpfSvgTextBuilder(familyInfo.FontElement,
                                                                      culture, familyInfo.Name, fontSize);
                textBuilder.FontVariant = familyInfo.Variant;

                return(textBuilder);
            }

            return(new WpfGlyphTextBuilder(familyInfo, culture, fontSize));
        }
        public override WpfFontFamilyInfo Visit(string fontName, WpfFontFamilyInfo familyInfo,
                                                WpfDrawingContext context)
        {
            if (string.IsNullOrWhiteSpace(fontName))
            {
                return(null);
            }

            if (fontName.StartsWith("Arial", StringComparison.OrdinalIgnoreCase) &&
                fontName.Length > 5)
            {
                if (string.Equals(fontName, "ArialMT",
                                  StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Arial-BoldMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Arial-ItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Arial-BoldItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Arial Unicode MS",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(null);
                }

                return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }
            else if (fontName.StartsWith("Helvetica", StringComparison.OrdinalIgnoreCase))
            {
                if (string.Equals(fontName, "Helvetica", StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Helvetica-Bold",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Helvetica-Oblique",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "Helvetica-BoldOblique",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }

                return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }
            else if (fontName.StartsWith("TimesNewRomanPS", StringComparison.OrdinalIgnoreCase))
            {
                if (string.Equals(fontName, "TimesNewRomanPSMT", StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "TimesNewRomanPS-BoldMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "TimesNewRomanPS-ItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "TimesNewRomanPS-BoldItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }

                return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }
            else if (fontName.StartsWith("CourierNewPS", StringComparison.OrdinalIgnoreCase))
            {
                if (string.Equals(fontName, "CourierNewPSMT", StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "CourierNewPS-BoldMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 familyInfo.Style, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "CourierNewPS-ItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }
                else if (string.Equals(fontName, "CourierNewPS-BoldItalicMT",
                                       StringComparison.OrdinalIgnoreCase))
                {
                    return(new WpfFontFamilyInfo(_arialFamily, FontWeights.Bold,
                                                 FontStyles.Italic, familyInfo.Stretch));
                }

                return(new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }
            else if (fontName.Equals("MS-Gothic", StringComparison.OrdinalIgnoreCase))
            {
                return(new WpfFontFamilyInfo(new FontFamily("MS Gothic"), familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
                //return new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
                //    familyInfo.Style, familyInfo.Stretch);
            }
            else if (fontName.Equals("MS-PGothic", StringComparison.OrdinalIgnoreCase))
            {
                return(new WpfFontFamilyInfo(new FontFamily("MS PGothic"), familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }
            else if (fontName.Equals("MS Pゴシック", StringComparison.OrdinalIgnoreCase))
            {
                return(new WpfFontFamilyInfo(new FontFamily("MS PGothic"), familyInfo.Weight,
                                             familyInfo.Style, familyInfo.Stretch));
            }

            return(null);
            //return new WpfFontFamilyInfo(_arialFamily, familyInfo.Weight,
            //    familyInfo.Style, familyInfo.Stretch);
        }
Beispiel #6
0
        public override void RenderTextRun(SvgTextContentElement element, ref Point ctp,
                                           string text, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            double emSize         = GetComputedFontSize(element);
            var    fontFamilyInfo = GetTextFontFamilyInfo(element);

            FontFamily  fontFamily  = fontFamilyInfo.Family;
            FontStyle   fontStyle   = fontFamilyInfo.Style;
            FontWeight  fontWeight  = fontFamilyInfo.Weight;
            FontStretch fontStretch = fontFamilyInfo.Stretch;

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                //WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
                //    fontStyle, fontStretch);
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       fontFamilyInfo, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            else if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);

            if (textDecors == null)
            {
                SvgTextElement textElement = element.ParentNode as SvgTextElement;

                if (textElement != null)
                {
                    textDecors = GetTextDecoration(textElement);
                }
            }

            TextAlignment alignment = stringFormat.Alignment;

            bool   hasWordSpacing = false;
            string wordSpaceText  = element.GetAttribute("word-spacing");
            double wordSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(wordSpaceText) &&
                double.TryParse(wordSpaceText, out wordSpacing) && !wordSpacing.Equals(0))
            {
                hasWordSpacing = true;
            }

            bool   hasLetterSpacing = false;
            string letterSpaceText  = element.GetAttribute("letter-spacing");
            double letterSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(letterSpaceText) &&
                double.TryParse(letterSpaceText, out letterSpacing) && !letterSpacing.Equals(0))
            {
                hasLetterSpacing = true;
            }

            bool isRotatePosOnly = false;

            IList <WpfTextPosition> textPositions = null;
            int textPosCount = 0;

            if ((placement != null && placement.HasPositions))
            {
                textPositions   = placement.Positions;
                textPosCount    = textPositions.Count;
                isRotatePosOnly = placement.IsRotateOnly;
            }

            var typeFace = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);

            if (textPositions != null && textPositions.Count != 0)
            {
                if (textPositions.Count == text.Trim().Length) //TODO: Best way to handle this...
                {
                    text = text.Trim();
                }
            }

            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
            {
                double spacing = Convert.ToDouble(letterSpacing);

                int startSpaces = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    if (char.IsWhiteSpace(text[i]))
                    {
                        startSpaces++;
                    }
                    else
                    {
                        break;
                    }
                }

                int j = 0;

                string inputText = string.Empty;
                for (int i = 0; i < text.Length; i++)
                {
                    // Avoid rendering only spaces at the start of text run...
                    if (i == 0 && startSpaces != 0)
                    {
                        inputText = text.Substring(0, startSpaces + 1);
                        i        += startSpaces;
                    }
                    else
                    {
                        inputText = new string(text[i], 1);
                    }

                    FormattedText formattedText = new FormattedText(inputText, _context.CultureInfo,
                                                                    stringFormat.Direction, typeFace, emSize, textBrush);

                    if (this.IsMeasuring)
                    {
                        this.AddTextWidth(formattedText.WidthIncludingTrailingWhitespace);
                        continue;
                    }

                    formattedText.Trimming      = stringFormat.Trimming;
                    formattedText.TextAlignment = stringFormat.Alignment;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        formattedText.SetTextDecorations(textDecors);
                    }

                    WpfTextPosition?textPosition = null;
                    if (textPositions != null && j < textPosCount)
                    {
                        textPosition = textPositions[j];
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = formattedText.Baseline;

                    float rotateAngle = (float)rotate;
                    if (textPosition != null)
                    {
                        if (!isRotatePosOnly)
                        {
                            Point pt = textPosition.Value.Location;
                            ctp.X = pt.X;
                            ctp.Y = pt.Y;
                        }
                        rotateAngle = (float)textPosition.Value.Rotation;
                    }
                    Point textStart = ctp;

                    RotateTransform rotateAt = null;
                    if (!rotateAngle.Equals(0))
                    {
                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
                        _textContext.PushTransform(rotateAt);
                    }

                    Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                    if (textPen != null || _context.TextAsGeometry)
                    {
                        Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                        if (textGeometry != null && !textGeometry.IsEmpty())
                        {
                            _textContext.DrawGeometry(textBrush, textPen,
                                                      ExtractTextPathGeometry(textGeometry));

                            this.IsTextPath = true;
                        }
                        else
                        {
                            _textContext.DrawText(formattedText, textPoint);
                        }
                    }
                    else
                    {
                        _textContext.DrawText(formattedText, textPoint);
                    }

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    if (hasLetterSpacing)
                    {
                        ctp.X += bboxWidth + letterSpacing;
                    }
                    if (hasWordSpacing && char.IsWhiteSpace(text[i]))
                    {
                        if (hasLetterSpacing)
                        {
                            ctp.X += wordSpacing;
                        }
                        else
                        {
                            ctp.X += bboxWidth + wordSpacing;
                        }
                    }
                    else
                    {
                        if (!hasLetterSpacing)
                        {
                            ctp.X += bboxWidth;
                        }
                    }

                    if (rotateAt != null)
                    {
                        _textContext.Pop();
                    }
                    j++;
                }
            }
            else
            {
                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
                                                                stringFormat.Direction, typeFace, emSize, textBrush);

                if (this.IsMeasuring)
                {
                    this.AddTextWidth(formattedText.WidthIncludingTrailingWhitespace);
                    return;
                }

                if (alignment == TextAlignment.Center && this.TextWidth > 0)
                {
                    alignment = TextAlignment.Left;
                }

                formattedText.TextAlignment = alignment;
                formattedText.Trimming      = stringFormat.Trimming;

                if (textDecors != null && textDecors.Count != 0)
                {
                    formattedText.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = formattedText.Baseline;

                float rotateAngle = (float)rotate;
                Point textPoint   = new Point(ctp.X, ctp.Y - yCorrection);

                RotateTransform rotateAt = null;
                if (!rotateAngle.Equals(0))
                {
                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
                    _textContext.PushTransform(rotateAt);
                }

                if (textPen != null || _context.TextAsGeometry)
                {
                    Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                    if (textGeometry != null && !textGeometry.IsEmpty())
                    {
                        _textContext.DrawGeometry(textBrush, textPen,
                                                  ExtractTextPathGeometry(textGeometry));

                        this.IsTextPath = true;
                    }
                    else
                    {
                        _textContext.DrawText(formattedText, textPoint);
                    }
                }
                else
                {
                    _textContext.DrawText(formattedText, textPoint);
                }

                //float bboxWidth = (float)formattedText.Width;
                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                if (rotateAt != null)
                {
                    _textContext.Pop();
                }
            }
        }
 public WpfFontTextBuilder(WpfFontFamilyInfo familyInfo, CultureInfo culture, double fontSize)
     : base(culture, familyInfo.Name, fontSize, null)
 {
     _typeface = new Typeface(familyInfo.Family, familyInfo.Style, familyInfo.Weight, familyInfo.Stretch);
 }
        private void DrawTextRun(SvgTextContentElement element, ref Point ctp,
                                 WpfTextRun textRun, double rotate, WpfTextPlacement placement)
        {
            if (textRun == null || textRun.IsEmpty)
            {
                return;
            }

            string text           = textRun.Text;
            double emSize         = GetComputedFontSize(element);
            var    fontFamilyInfo = GetTextFontFamilyInfo(element);

            FontFamily  fontFamily  = fontFamilyInfo.Family;
            FontStyle   fontStyle   = fontFamilyInfo.Style;
            FontWeight  fontWeight  = fontFamilyInfo.Weight;
            FontStretch fontStretch = fontFamilyInfo.Stretch;

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                //WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
                //    fontStyle, fontStretch);
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       fontFamilyInfo, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            else if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);
            TextAlignment            alignment  = stringFormat.Alignment;

            string letterSpacing = element.GetAttribute("letter-spacing");

            if (string.IsNullOrWhiteSpace(letterSpacing))
            {
                FormattedText formattedText = new FormattedText(text,
                                                                textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                stringFormat.Direction, new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                                                emSize, textBrush);

                formattedText.TextAlignment = stringFormat.Alignment;
                formattedText.Trimming      = stringFormat.Trimming;

                if (textDecors != null && textDecors.Count != 0)
                {
                    formattedText.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = formattedText.Baseline;

                Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y);
                _drawContext.PushTransform(rotateAt);

                _drawContext.DrawText(formattedText, textPoint);

                //float bboxWidth = (float)formattedText.Width;
                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
            else
            {
                RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y);
                _drawContext.PushTransform(rotateAt);

                float spacing = Convert.ToSingle(letterSpacing);
                for (int i = 0; i < text.Length; i++)
                {
                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
                                                                    textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                    stringFormat.Direction,
                                                                    new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                                                    emSize, textBrush);

                    formattedText.Trimming      = stringFormat.Trimming;
                    formattedText.TextAlignment = stringFormat.Alignment;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        formattedText.SetTextDecorations(textDecors);
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = formattedText.Baseline;

                    Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                    _drawContext.DrawText(formattedText, textPoint);

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    ctp.X += bboxWidth + spacing;
                }

                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
        }
Beispiel #9
0
        protected WpfFontFamilyInfo GetTextFontFamilyInfo(SvgTextContentElement element)
        {
            _actualFontName = null;

            string fontFamily = element.GetPropertyValue("font-family");

            string[] fontNames = fontFamily.Split(new char[1] {
                ','
            });

            FontStyle   fontStyle   = GetTextFontStyle(element);
            FontWeight  fontWeight  = GetTextFontWeight(element);
            FontStretch fontStretch = GetTextFontStretch(element);

            var comparer   = StringComparison.OrdinalIgnoreCase;
            var docElement = element.OwnerDocument;

            ISet <string> svgFontFamilies = docElement.SvgFontFamilies;
            IDictionary <string, string> styledFontIds = docElement.StyledFontIds;

            IList <string> svgFontNames = null;

            if (svgFontFamilies != null && svgFontFamilies.Count != 0)
            {
                svgFontNames = new List <string>();
            }
            //var systemFontFamilies = Fonts.SystemFontFamilies;

            var wpfSettings         = _context.Settings;
            var fontFamilyNames     = wpfSettings.FontFamilyNames;
            var privateFontFamilies = wpfSettings.HasFontFamilies;

            FontFamily family = null;
            // using separate pointer to give less priority to generic font names
            FontFamily genericFamily = null;

            WpfFontFamilyType familyType = WpfFontFamilyType.None;

            foreach (string fn in fontNames)
            {
                try
                {
                    string fontName = fn.Trim(new char[] { ' ', '\'', '"' });
                    if (svgFontFamilies != null && svgFontFamilies.Count != 0)
                    {
                        if (svgFontFamilies.Contains(fontName))
                        {
                            svgFontNames.Add(fontName);
                            continue;
                        }
                        if (styledFontIds.ContainsKey(fontName))
                        {
                            string mappedFontName = styledFontIds[fontName];
                            if (svgFontFamilies.Contains(mappedFontName))
                            {
                                svgFontNames.Add(mappedFontName);
                                continue;
                            }
                        }
                    }

                    if (string.Equals(fontName, "serif", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericSerif;
                    }
                    else if (string.Equals(fontName, "sans-serif", comparer) ||
                             string.Equals(fontName, "sans serif", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericSansSerif;
                    }
                    else if (string.Equals(fontName, "monospace", comparer))
                    {
                        genericFamily = WpfDrawingSettings.GenericMonospace;
                    }
                    else if (styledFontIds.ContainsKey(fontName))
                    {
                        string mappedFontName = styledFontIds[fontName];
                        family = LookupFontFamily(mappedFontName, fontFamilyNames);
                        if (family != null)
                        {
                            _actualFontName = mappedFontName;
                            familyType      = WpfFontFamilyType.System;
                        }
                    }
                    else
                    {
                        // Try looking up fonts in the system font registry...
                        family = LookupFontFamily(fontName, fontFamilyNames);
                        if (family != null)
                        {
                            _actualFontName = fontName;
                            familyType      = WpfFontFamilyType.System;
                        }

                        // If not found, look through private fonts if available..
                        if (family == null && privateFontFamilies)
                        {
                            family = wpfSettings.LookupFontFamily(fontName);
                            if (family != null)
                            {
                                _actualFontName = fontName;
                                familyType      = WpfFontFamilyType.Private;
                            }
                        }
                    }

                    if (family != null)
                    {
                        return(new WpfFontFamilyInfo(familyType, _actualFontName, family,
                                                     fontWeight, fontStyle, fontStretch));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }

            // If set, use the SVG-Font...
            if (svgFontNames != null && svgFontNames.Count != 0)
            {
                FontFamily altFamily = (genericFamily != null) ? genericFamily : WpfDrawingSettings.DefaultFontFamily;

                IList <SvgFontElement> svgFonts = docElement.GetFonts(svgFontNames);
                if (svgFonts != null && svgFonts.Count != 0)
                {
                    string fontVariant = element.GetPropertyValue("font-variant");

                    // For a single match...
                    if (svgFonts.Count == 1)
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }

                    // For the defined font style...
                    if (fontStyle != FontStyles.Normal)
                    {
                        // Then it is either oblique or italic
                        SvgFontElement closeFont   = null;
                        SvgFontElement closestFont = null;
                        bool           isItalic    = fontStyle.Equals(FontStyles.Italic);
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            var typefaceStyle = GetTextFontStyle(fontFace.FontStyle);
                            if (fontStyle.Equals(typefaceStyle))
                            {
                                closeFont = svgFont;
                                if (closestFont == null)
                                {
                                    closestFont = svgFont;
                                }
                                var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                                if (fontVariant.Equals(fontFace.FontVariant, comparer))
                                {
                                    closestFont = svgFont;
                                    if (fontWeight.Equals(typefaceWeight))
                                    {
                                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                                   fontWeight, fontStyle, fontStretch);

                                        fontFamilyInfo.Variant = fontVariant;
                                        // For rendering that do not support the SVG Fonts...
                                        fontFamilyInfo.Family = altFamily;
                                        return(fontFamilyInfo);
                                    }
                                }
                            }
                            if (closeFont == null)
                            {
                                if (isItalic && typefaceStyle == FontStyles.Oblique)
                                {
                                    closeFont = svgFont;
                                }
                                if (!isItalic && typefaceStyle == FontStyles.Italic)
                                {
                                    closeFont = svgFont;
                                }
                            }
                        }
                        if (closestFont != null)
                        {
                            closeFont = closestFont;
                        }

                        if (closeFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(closeFont.FontFamily, closeFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                    }

                    SvgFontElement variantFont = null;
                    // For multiple matches, we will test the variants...
                    if (!string.IsNullOrWhiteSpace(fontVariant))
                    {
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            if (fontVariant.Equals(fontFace.FontVariant, comparer))
                            {
                                variantFont = svgFont;
                                // Check for more perfect match...
                                var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                                var typefaceStyle  = GetTextFontStyle(fontFace.FontStyle);
                                if (fontStyle.Equals(typefaceStyle) && fontWeight.Equals(typefaceWeight))
                                {
                                    var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                               fontWeight, fontStyle, fontStretch);

                                    fontFamilyInfo.Variant = fontVariant;
                                    // For rendering that do not support the SVG Fonts...
                                    fontFamilyInfo.Family = altFamily;
                                    return(fontFamilyInfo);
                                }
                            }
                        }

                        //if (variantFont != null)
                        //{
                        //    // If there was a matching variant but either style or weight not matched...
                        //    var fontFamilyInfo = new WpfFontFamilyInfo(variantFont.FontFamily, variantFont,
                        //        fontWeight, fontStyle, fontStretch);

                        //    fontFamilyInfo.Variant = fontVariant;
                        //    // For rendering that do not support the SVG Fonts...
                        //    fontFamilyInfo.Family = altFamily;
                        //    return fontFamilyInfo;
                        //}
                    }

                    // For the defined font weights...
                    if (fontWeight != FontWeights.Normal && fontWeight != FontWeights.Regular)
                    {
                        int            weightValue    = fontWeight.ToOpenTypeWeight();
                        int            selectedValue  = int.MaxValue;
                        SvgFontElement sameWeightFont = null;
                        SvgFontElement closestFont    = null;
                        foreach (var svgFont in svgFonts)
                        {
                            var fontFace = svgFont.FontFace;
                            if (fontFace == null)
                            {
                                continue;
                            }
                            var typefaceWeight = GetTextFontWeight(fontFace.FontWeight);
                            if (fontWeight.Equals(typefaceWeight))
                            {
                                sameWeightFont = svgFont;
                                var typefaceStyle = GetTextFontStyle(fontFace.FontStyle);
                                if (fontStyle.Equals(typefaceStyle))
                                {
                                    var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                               fontWeight, fontStyle, fontStretch);

                                    fontFamilyInfo.Variant = fontVariant;
                                    // For rendering that do not support the SVG Fonts...
                                    fontFamilyInfo.Family = altFamily;
                                    return(fontFamilyInfo);
                                }
                            }

                            int weightDiff = Math.Abs(weightValue - typefaceWeight.ToOpenTypeWeight());
                            if (weightDiff < selectedValue)
                            {
                                closestFont   = svgFont;
                                selectedValue = weightDiff;
                            }
                        }

                        // If the weights matched, but not the style
                        if (sameWeightFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(sameWeightFont.FontFamily, sameWeightFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                        if (closestFont != null)
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(closestFont.FontFamily, closestFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            // For rendering that do not support the SVG Fonts...
                            fontFamilyInfo.Family = altFamily;
                            return(fontFamilyInfo);
                        }
                    }

                    if (variantFont != null)
                    {
                        // If there was a matching variant but either style or weight not matched...
                        var fontFamilyInfo = new WpfFontFamilyInfo(variantFont.FontFamily, variantFont,
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }
                    else // If the variant is not found, return the first match...
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        // For rendering that do not support the SVG Fonts...
                        fontFamilyInfo.Family = altFamily;
                        return(fontFamilyInfo);
                    }

                    //// For multiple matches, we will test the variants...
                    //if (string.IsNullOrWhiteSpace(fontVariant))
                    //{
                    //    // Not found, return the first match...
                    //    var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                    //        fontWeight, fontStyle, fontStretch);

                    //    fontFamilyInfo.Variant = fontVariant;
                    //    // For rendering that do not support the SVG Fonts...
                    //    fontFamilyInfo.Family = altFamily;
                    //    return fontFamilyInfo;
                    //}
                }
            }

            if (genericFamily != null)
            {
                return(new WpfFontFamilyInfo(WpfFontFamilyType.Generic, _actualFontName, genericFamily,
                                             fontWeight, fontStyle, fontStretch));
            }

            // No known font-family was found => default to "Arial"
            return(new WpfFontFamilyInfo(familyType, _actualFontName,
                                         WpfDrawingSettings.DefaultFontFamily, fontWeight, fontStyle, fontStretch));
        }
Beispiel #10
0
        public override void RenderSingleLineText(SvgTextContentElement element, ref Point ctp,
                                                  string text, double rotate, WpfTextPlacement placement)
        {
            if (String.IsNullOrEmpty(text))
            {
                return;
            }

            double     emSize     = GetComputedFontSize(element);
            FontFamily fontFamily = GetTextFontFamily(element, emSize);

            FontStyle  fontStyle  = GetTextFontStyle(element);
            FontWeight fontWeight = GetTextFontWeight(element);

            FontStretch fontStretch = GetTextFontStretch(element);

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _drawContext.FontFamilyVisitor;

            if (!String.IsNullOrEmpty(_actualFontName) && fontFamilyVisitor != null)
            {
                WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
                                                                        fontStyle, fontStretch);
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       currentFamily, _drawContext);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_drawContext, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_drawContext, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            else if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);
            TextAlignment            alignment  = stringFormat.Alignment;

            bool   hasWordSpacing = false;
            string wordSpaceText  = element.GetAttribute("word-spacing");
            double wordSpacing    = 0;

            if (!String.IsNullOrEmpty(wordSpaceText) &&
                Double.TryParse(wordSpaceText, out wordSpacing) && (float)wordSpacing != 0)
            {
                hasWordSpacing = true;
            }

            bool   hasLetterSpacing = false;
            string letterSpaceText  = element.GetAttribute("letter-spacing");
            double letterSpacing    = 0;

            if (!String.IsNullOrEmpty(letterSpaceText) &&
                Double.TryParse(letterSpaceText, out letterSpacing) && (float)letterSpacing != 0)
            {
                hasLetterSpacing = true;
            }

            bool isRotatePosOnly = false;

            IList <WpfTextPosition> textPositions = null;
            int textPosCount = 0;

            if ((placement != null && placement.HasPositions))
            {
                textPositions   = placement.Positions;
                textPosCount    = textPositions.Count;
                isRotatePosOnly = placement.IsRotateOnly;
            }

            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
            {
                for (int i = 0; i < text.Length; i++)
                {
                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
                                                                    _drawContext.CultureInfo, stringFormat.Direction,
                                                                    new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                                                    emSize, textBrush);

                    formattedText.TextAlignment = stringFormat.Alignment;
                    formattedText.Trimming      = stringFormat.Trimming;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        formattedText.SetTextDecorations(textDecors);
                    }

                    WpfTextPosition?textPosition = null;
                    if (textPositions != null && i < textPosCount)
                    {
                        textPosition = textPositions[i];
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = formattedText.Baseline;

                    float rotateAngle = (float)rotate;
                    if (textPosition != null)
                    {
                        if (!isRotatePosOnly)
                        {
                            Point pt = textPosition.Value.Location;
                            ctp.X = pt.X;
                            ctp.Y = pt.Y;
                        }
                        rotateAngle = (float)textPosition.Value.Rotation;
                    }
                    Point textStart = ctp;

                    RotateTransform rotateAt = null;
                    if (rotateAngle != 0)
                    {
                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
                        _textContext.PushTransform(rotateAt);
                    }

                    Point textPoint = new Point(textStart.X, textStart.Y - yCorrection);

                    if (textPen != null || _drawContext.TextAsGeometry)
                    {
                        Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                        if (textGeometry != null && !textGeometry.IsEmpty())
                        {
                            _textContext.DrawGeometry(textBrush, textPen,
                                                      ExtractTextPathGeometry(textGeometry));

                            this.IsTextPath = true;
                        }
                        else
                        {
                            _textContext.DrawText(formattedText, textPoint);
                        }
                    }
                    else
                    {
                        _textContext.DrawText(formattedText, textPoint);
                    }

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    if (hasLetterSpacing)
                    {
                        ctp.X += bboxWidth + letterSpacing;
                    }
                    if (hasWordSpacing && Char.IsWhiteSpace(text[i]))
                    {
                        if (hasLetterSpacing)
                        {
                            ctp.X += wordSpacing;
                        }
                        else
                        {
                            ctp.X += bboxWidth + wordSpacing;
                        }
                    }
                    else
                    {
                        if (!hasLetterSpacing)
                        {
                            ctp.X += bboxWidth;
                        }
                    }

                    if (rotateAt != null)
                    {
                        _textContext.Pop();
                    }
                }
            }
            else
            {
                FormattedText formattedText = new FormattedText(text, _drawContext.CultureInfo,
                                                                stringFormat.Direction, new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                                                emSize, textBrush);

                formattedText.TextAlignment = stringFormat.Alignment;
                formattedText.Trimming      = stringFormat.Trimming;

                if (textDecors != null && textDecors.Count != 0)
                {
                    formattedText.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = formattedText.Baseline;

                float rotateAngle = (float)rotate;
                Point textPoint   = new Point(ctp.X, ctp.Y - yCorrection);

                RotateTransform rotateAt = null;
                if (rotateAngle != 0)
                {
                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
                    _textContext.PushTransform(rotateAt);
                }

                if (textPen != null || _drawContext.TextAsGeometry)
                {
                    Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                    if (textGeometry != null && !textGeometry.IsEmpty())
                    {
                        _textContext.DrawGeometry(textBrush, textPen,
                                                  ExtractTextPathGeometry(textGeometry));

                        this.IsTextPath = true;
                    }
                    else
                    {
                        _textContext.DrawText(formattedText, textPoint);
                    }
                }
                else
                {
                    _textContext.DrawText(formattedText, textPoint);
                }

                //float bboxWidth = (float)formattedText.Width;
                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                if (rotateAt != null)
                {
                    _textContext.Pop();
                }
            }
        }
Beispiel #11
0
        private void DrawSingleLineText(SvgTextContentElement element, ref Point ctp,
                                        WpfTextRun textRun, double rotate, WpfTextPlacement placement)
        {
            if (textRun == null || textRun.IsEmpty)
            {
                return;
            }

            string text           = textRun.Text;
            double emSize         = GetComputedFontSize(element);
            var    fontFamilyInfo = GetTextFontFamilyInfo(element);

            FontFamily  fontFamily  = fontFamilyInfo.Family;
            FontStyle   fontStyle   = fontFamilyInfo.Style;
            FontWeight  fontWeight  = fontFamilyInfo.Weight;
            FontStretch fontStretch = fontFamilyInfo.Stretch;

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       fontFamilyInfo, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);
            TextAlignment            alignment  = stringFormat.Alignment;

            var typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);

            string letterSpacing = element.GetAttribute("letter-spacing");

            if (string.IsNullOrWhiteSpace(letterSpacing))
            {
#if DOTNET40 || DOTNET45 || DOTNET46
                FormattedText formattedText = new FormattedText(text,
                                                                textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                stringFormat.Direction, typeface, emSize, textBrush);
#else
                FormattedText formattedText = new FormattedText(text,
                                                                textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                stringFormat.Direction, typeface, emSize, textBrush, _context.PixelsPerDip);
#endif

                if (this.IsMeasuring)
                {
                    this.AddTextWidth(ctp, formattedText.WidthIncludingTrailingWhitespace);
                    return;
                }

//                formattedText.TextAlignment = stringFormat.Alignment;
                formattedText.TextAlignment = TextAlignment.Left;
                formattedText.Trimming      = stringFormat.Trimming;

                if (textDecors != null && textDecors.Count != 0)
                {
                    formattedText.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = formattedText.Baseline;
                //float yCorrection = 0;

                if (textRun.IsLatin && textRun.VerticalOrientation == -1)
                {
                    yCorrection = yCorrection + formattedText.OverhangAfter * 1.5;
                }

                Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                var textSize = this.MeasureString(text, emSize, typeface);

                //float bboxWidth1 = (float)formattedText.Width;
                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;

                TranslateTransform translateAt = null;

                RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y);

                if (alignment == TextAlignment.Center)
                {
//                    translateAt = new TranslateTransform(0, -(textSize.Height - textSize.Width/2) / 2);
                    translateAt = new TranslateTransform(0, -(textSize.Height - yCorrection / 2) / 2);
                }
                else if (alignment == TextAlignment.Right)
                {
//                    translateAt = new TranslateTransform(0, -(textSize.Height + textSize.Width / 2));
                    translateAt = new TranslateTransform(0, -(textSize.Height + yCorrection / 2));
                }
                if (translateAt != null)
                {
                    TransformGroup group = new TransformGroup();
                    group.Children.Add(rotateAt);
                    group.Children.Add(translateAt);
                    _drawContext.PushTransform(group);
                }
                else
                {
                    _drawContext.PushTransform(rotateAt);
                }

                _drawContext.DrawText(formattedText, textPoint);

                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                //if (translateAt != null)
                //{
                //    _textContext.Pop();
                //}
                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
            else
            {
                RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y);
                _drawContext.PushTransform(rotateAt);

                double spacing = Convert.ToDouble(letterSpacing);
                for (int i = 0; i < text.Length; i++)
                {
#if DOTNET40 || DOTNET45 || DOTNET46
                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
                                                                    textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                    stringFormat.Direction, typeface, emSize, textBrush);
#else
                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
                                                                    textRun.IsLatin ? _context.EnglishCultureInfo : _context.CultureInfo,
                                                                    stringFormat.Direction, typeface, emSize, textBrush, _context.PixelsPerDip);
#endif

                    if (this.IsMeasuring)
                    {
                        this.AddTextWidth(ctp, formattedText.WidthIncludingTrailingWhitespace);
                        continue;
                    }

                    formattedText.TextAlignment = stringFormat.Alignment;
                    formattedText.Trimming      = stringFormat.Trimming;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        formattedText.SetTextDecorations(textDecors);
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = formattedText.Baseline;

                    Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                    _drawContext.DrawText(formattedText, textPoint);

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    ctp.X += bboxWidth + spacing;
                }

                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
        }
        private void RenderTextRun(WpfTextTuple textInfo, ref Point ctp,
                                   string text, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            WpfFontFamilyInfo     familyInfo   = textInfo.Item1;
            double                emSize       = textInfo.Item2;
            WpfTextStringFormat   stringFormat = textInfo.Item3;
            SvgTextContentElement element      = textInfo.Item4;

            FontFamily  fontFamily  = familyInfo.Family;
            FontWeight  fontWeight  = familyInfo.Weight;
            FontStyle   fontStyle   = familyInfo.Style;
            FontStretch fontStretch = familyInfo.Stretch;

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }
            if (textPen != null)
            {
                textPen.LineJoin   = PenLineJoin.Miter; // Better for text rendering
                textPen.MiterLimit = 1;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);

            if (textDecors == null)
            {
                SvgTextElement textElement = element.ParentNode as SvgTextElement;

                if (textElement != null)
                {
                    textDecors = GetTextDecoration(textElement);
                }
            }

            TextAlignment alignment = stringFormat.Alignment;

            bool   hasWordSpacing = false;
            string wordSpaceText  = element.GetAttribute("word-spacing");
            double wordSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(wordSpaceText) &&
                double.TryParse(wordSpaceText, out wordSpacing) && !wordSpacing.Equals(0))
            {
                hasWordSpacing = true;
            }

            bool   hasLetterSpacing = false;
            string letterSpaceText  = element.GetAttribute("letter-spacing");
            double letterSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(letterSpaceText) &&
                double.TryParse(letterSpaceText, out letterSpacing) && !letterSpacing.Equals(0))
            {
                hasLetterSpacing = true;
            }

            bool isRotatePosOnly = false;

            IList <WpfTextPosition> textPositions = null;
            int textPosCount = 0;

            if ((placement != null && placement.HasPositions))
            {
                textPositions   = placement.Positions;
                textPosCount    = textPositions.Count;
                isRotatePosOnly = placement.IsRotateOnly;
            }

            WpfTextBuilder textBuilder = WpfTextBuilder.Create(familyInfo, this.TextCulture, emSize);

            this.IsTextPath = true;

            if (textPositions != null && textPositions.Count != 0)
            {
                if (textPositions.Count == text.Trim().Length) //TODO: Best way to handle this...
                {
                    text = text.Trim();
                }
            }

            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
            {
                double spacing = Convert.ToDouble(letterSpacing);

                int startSpaces = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    if (char.IsWhiteSpace(text[i]))
                    {
                        startSpaces++;
                    }
                    else
                    {
                        break;
                    }
                }

                int j = 0;

                string inputText = string.Empty;
                for (int i = 0; i < text.Length; i++)
                {
                    // Avoid rendering only spaces at the start of text run...
                    if (i == 0 && startSpaces != 0)
                    {
                        inputText = text.Substring(0, startSpaces + 1);
                        i        += startSpaces;
                    }
                    else
                    {
                        inputText = new string(text[i], 1);
                    }

                    if (this.IsMeasuring)
                    {
                        var textSize = textBuilder.MeasureText(element, inputText);
                        this.AddTextWidth(ctp, textSize.Width);
                        continue;
                    }

                    textBuilder.Trimming      = stringFormat.Trimming;
                    textBuilder.TextAlignment = stringFormat.Alignment;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        textBuilder.SetTextDecorations(textDecors);
                    }

                    WpfTextPosition?textPosition = null;
                    if (textPositions != null && j < textPosCount)
                    {
                        textPosition = textPositions[j];
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = textBuilder.Baseline;

                    float rotateAngle = (float)rotate;
                    if (textPosition != null)
                    {
                        if (!isRotatePosOnly)
                        {
                            Point pt = textPosition.Value.Location;
                            ctp.X = pt.X;
                            ctp.Y = pt.Y;
                        }
                        rotateAngle = (float)textPosition.Value.Rotation;
                    }
                    Point textStart = ctp;

                    RotateTransform rotateAt = null;
                    if (!rotateAngle.Equals(0))
                    {
                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
                        _drawContext.PushTransform(rotateAt);
                    }

                    Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);

                    Geometry textGeometry = textBuilder.Build(element, inputText, textPoint.X, textPoint.Y);
                    if (textGeometry != null && !textGeometry.IsEmpty())
                    {
                        _drawContext.DrawGeometry(textBrush, textPen,
                                                  ExtractTextPathGeometry(textGeometry));

                        this.IsTextPath = true;
                    }

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = textGeometry.Bounds.Width;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    if (hasLetterSpacing)
                    {
                        ctp.X += bboxWidth + letterSpacing;
                    }
                    if (hasWordSpacing && char.IsWhiteSpace(text[i]))
                    {
                        if (hasLetterSpacing)
                        {
                            ctp.X += wordSpacing;
                        }
                        else
                        {
                            ctp.X += bboxWidth + wordSpacing;
                        }
                    }
                    else
                    {
                        if (!hasLetterSpacing)
                        {
                            ctp.X += bboxWidth;
                        }
                    }

                    if (rotateAt != null)
                    {
                        _drawContext.Pop();
                    }
                    j++;
                }
            }
            else
            {
                if (this.IsMeasuring)
                {
                    var textSize = textBuilder.MeasureText(element, text);
                    this.AddTextWidth(ctp, textSize.Width);
                    return;
                }

                var textContext = this.TextContext;
                if (textContext != null && textContext.IsPositionChanged(element) == false)
                {
                    if (alignment == TextAlignment.Center && this.TextWidth > 0)
                    {
                        alignment = TextAlignment.Left;
                    }
                }

                textBuilder.TextAlignment = alignment;
                textBuilder.Trimming      = stringFormat.Trimming;

                if (textDecors != null && textDecors.Count != 0)
                {
                    textBuilder.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = textBuilder.Baseline;

                float rotateAngle = (float)rotate;
                Point textPoint   = new Point(ctp.X, ctp.Y - yCorrection);

                RotateTransform rotateAt = null;
                if (!rotateAngle.Equals(0))
                {
                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
                    _drawContext.PushTransform(rotateAt);
                }

                Geometry textGeometry = textBuilder.Build(element, text, textPoint.X, textPoint.Y);
                if (textGeometry != null && !textGeometry.IsEmpty())
                {
                    _drawContext.DrawGeometry(textBrush, textPen,
                                              ExtractTextPathGeometry(textGeometry));
                }

                //float bboxWidth = (float)formattedText.Width;
//                double bboxWidth = textGeometry.Bounds.Width;
                double bboxWidth = textBuilder.Width;

                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
        }
        public override void RenderText(SvgTextContentElement element, ref Point ctp,
                                        string text, double rotate, WpfTextPlacement placement)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            double emSize         = GetComputedFontSize(element);
            var    fontFamilyInfo = GetTextFontFamilyInfo(element);

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            if (fontFamilyInfo.FontFamilyType == WpfFontFamilyType.Svg ||
                fontFamilyInfo.FontFamilyType == WpfFontFamilyType.Private)
            {
                WpfTextTuple textInfo = new WpfTextTuple(fontFamilyInfo, emSize, stringFormat, element);
                this.RenderText(textInfo, ref ctp, text, rotate, placement);
                return;
            }

            FontFamily  fontFamily  = fontFamilyInfo.Family;
            FontStyle   fontStyle   = fontFamilyInfo.Style;
            FontWeight  fontWeight  = fontFamilyInfo.Weight;
            FontStretch fontStretch = fontFamilyInfo.Stretch;

            // Fix the use of Postscript fonts...
            WpfFontFamilyVisitor fontFamilyVisitor = _context.FontFamilyVisitor;

            if (!string.IsNullOrWhiteSpace(_actualFontName) && fontFamilyVisitor != null)
            {
                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
                                                                       fontFamilyInfo, _context);
                if (familyInfo != null && !familyInfo.IsEmpty)
                {
                    fontFamily  = familyInfo.Family;
                    fontWeight  = familyInfo.Weight;
                    fontStyle   = familyInfo.Style;
                    fontStretch = familyInfo.Stretch;
                }
            }

            WpfSvgPaint fillPaint = new WpfSvgPaint(_context, element, "fill");
            Brush       textBrush = fillPaint.GetBrush();

            WpfSvgPaint strokePaint = new WpfSvgPaint(_context, element, "stroke");
            Pen         textPen     = strokePaint.GetPen();

            if (textBrush == null && textPen == null)
            {
                return;
            }
            bool isForcedPathMode = false;

            if (textBrush == null)
            {
                // If here, then the pen is not null, and so the fill cannot be null.
                // We set this to transparent for stroke only text path...
                textBrush = Brushes.Transparent;
            }
            else
            {
                // WPF gradient fill does not work well on text, use geometry to render it
                isForcedPathMode = (fillPaint.FillType == WpfFillType.Gradient);
            }
            if (textPen != null)
            {
                textPen.LineJoin = PenLineJoin.Round; // Better for text rendering
                isForcedPathMode = true;
            }

            TextDecorationCollection textDecors = GetTextDecoration(element);
            TextAlignment            alignment  = stringFormat.Alignment;

            bool   hasWordSpacing = false;
            string wordSpaceText  = element.GetAttribute("word-spacing");
            double wordSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(wordSpaceText) &&
                double.TryParse(wordSpaceText, out wordSpacing) && !wordSpacing.Equals(0))
            {
                hasWordSpacing = true;
            }

            bool   hasLetterSpacing = false;
            string letterSpaceText  = element.GetAttribute("letter-spacing");
            double letterSpacing    = 0;

            if (!string.IsNullOrWhiteSpace(letterSpaceText) &&
                double.TryParse(letterSpaceText, out letterSpacing) && !letterSpacing.Equals(0))
            {
                hasLetterSpacing = true;
            }

            bool isRotatePosOnly = false;

            IList <WpfTextPosition> textPositions = null;
            int textPosCount = 0;

            if ((placement != null && placement.HasPositions))
            {
                textPositions   = placement.Positions;
                textPosCount    = textPositions.Count;
                isRotatePosOnly = placement.IsRotateOnly;
            }

            var typeFace = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);

            bool isRightToLeft = false;
            var  xmlLang       = _textElement.XmlLang;

            if (!string.IsNullOrWhiteSpace(xmlLang))
            {
                if (string.Equals(xmlLang, "ar", StringComparison.OrdinalIgnoreCase) ||   // Arabic language
                    string.Equals(xmlLang, "he", StringComparison.OrdinalIgnoreCase))     // Hebrew language
                {
                    isRightToLeft = true;
                }
            }

            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
            {
                for (int i = 0; i < text.Length; i++)
                {
                    var           nextText      = new string(text[i], 1);
                    FormattedText formattedText = new FormattedText(nextText,
                                                                    _context.CultureInfo, stringFormat.Direction, typeFace, emSize, textBrush);

//                    formattedText.FlowDirection = isRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
                    formattedText.TextAlignment = stringFormat.Alignment;
                    formattedText.Trimming      = stringFormat.Trimming;

                    if (textDecors != null && textDecors.Count != 0)
                    {
                        formattedText.SetTextDecorations(textDecors);
                    }

                    WpfTextPosition?textPosition = null;
                    if (textPositions != null && i < textPosCount)
                    {
                        textPosition = textPositions[i];
                    }

                    //float xCorrection = 0;
                    //if (alignment == TextAlignment.Left)
                    //    xCorrection = emSize * 1f / 6f;
                    //else if (alignment == TextAlignment.Right)
                    //    xCorrection = -emSize * 1f / 6f;

                    double yCorrection = formattedText.Baseline;

                    float rotateAngle = (float)rotate;
                    if (textPosition != null)
                    {
                        if (!isRotatePosOnly)
                        {
                            Point pt = textPosition.Value.Location;
                            ctp.X = pt.X;
                            ctp.Y = pt.Y;
                        }
                        rotateAngle = (float)textPosition.Value.Rotation;
                    }
                    Point textStart = ctp;

                    RotateTransform rotateAt = null;
                    if (!rotateAngle.Equals(0))
                    {
                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
                        _drawContext.PushTransform(rotateAt);
                    }

                    Point textPoint = new Point(textStart.X, textStart.Y - yCorrection);

                    if (_context.TextAsGeometry || isForcedPathMode)
                    {
                        Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                        if (textGeometry != null && !textGeometry.IsEmpty())
                        {
                            _drawContext.DrawGeometry(textBrush, textPen, ExtractTextPathGeometry(textGeometry));

                            this.IsTextPath = true;
                        }
                        else
                        {
                            _drawContext.DrawText(formattedText, textPoint);
                        }
                    }
                    else
                    {
                        _drawContext.DrawText(formattedText, textPoint);
                    }

                    //float bboxWidth = (float)formattedText.Width;
                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                    if (alignment == TextAlignment.Center)
                    {
                        bboxWidth /= 2f;
                    }
                    else if (alignment == TextAlignment.Right)
                    {
                        bboxWidth = 0;
                    }

                    //ctp.X += bboxWidth + emSize / 4 + spacing;
                    if (hasLetterSpacing)
                    {
                        ctp.X += bboxWidth + letterSpacing;
                    }
                    if (hasWordSpacing && char.IsWhiteSpace(text[i]))
                    {
                        if (hasLetterSpacing)
                        {
                            ctp.X += wordSpacing;
                        }
                        else
                        {
                            ctp.X += bboxWidth + wordSpacing;
                        }
                    }
                    else
                    {
                        if (!hasLetterSpacing)
                        {
                            ctp.X += bboxWidth;
                        }
                    }

                    if (rotateAt != null)
                    {
                        _drawContext.Pop();
                    }
                }
            }
            else
            {
                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
                                                                stringFormat.Direction, typeFace, emSize, textBrush);

                formattedText.TextAlignment = stringFormat.Alignment;
                formattedText.Trimming      = stringFormat.Trimming;

//                formattedText.FlowDirection = isRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;

                if (textDecors != null && textDecors.Count != 0)
                {
                    formattedText.SetTextDecorations(textDecors);
                }

                //float xCorrection = 0;
                //if (alignment == TextAlignment.Left)
                //    xCorrection = emSize * 1f / 6f;
                //else if (alignment == TextAlignment.Right)
                //    xCorrection = -emSize * 1f / 6f;

                double yCorrection = formattedText.Baseline;

                float rotateAngle = (float)rotate;
                Point textPoint   = new Point(ctp.X, ctp.Y - yCorrection);

                RotateTransform rotateAt = null;
                if (!rotateAngle.Equals(0))
                {
                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
                    _drawContext.PushTransform(rotateAt);
                }

                if (_context.TextAsGeometry || isForcedPathMode)
                {
                    Geometry textGeometry = formattedText.BuildGeometry(textPoint);
                    if (textGeometry != null && !textGeometry.IsEmpty())
                    {
                        _drawContext.DrawGeometry(textBrush, textPen,
                                                  ExtractTextPathGeometry(textGeometry));

                        this.IsTextPath = true;
                    }
                    else
                    {
                        _drawContext.DrawText(formattedText, textPoint);
                    }
                }
                else
                {
                    _drawContext.DrawText(formattedText, textPoint);
                }

                //float bboxWidth = (float)formattedText.Width;
                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
                if (alignment == TextAlignment.Center)
                {
                    bboxWidth /= 2f;
                }
                else if (alignment == TextAlignment.Right)
                {
                    bboxWidth = 0;
                }

                //ctp.X += bboxWidth + emSize / 4;
                ctp.X += bboxWidth;

                if (rotateAt != null)
                {
                    _drawContext.Pop();
                }
            }
        }
Beispiel #14
0
        protected WpfFontFamilyInfo GetTextFontFamilyInfo(SvgTextContentElement element)
        {
            _actualFontName = null;

            string fontFamily = element.GetPropertyValue("font-family");

            string[] fontNames = fontNames = fontFamily.Split(new char[1] {
                ','
            });

            FontStyle   fontStyle   = GetTextFontStyle(element);
            FontWeight  fontWeight  = GetTextFontWeight(element);
            FontStretch fontStretch = GetTextFontStretch(element);

            var comparer = StringComparison.OrdinalIgnoreCase;

            var docElement = element.OwnerDocument;

            ISet <string> svgFontFamilies = docElement.SvgFontFamilies;
            IDictionary <string, string> styledFontIds = docElement.StyledFontIds;

            IList <string> svgFontNames = null;

            if (svgFontFamilies != null && svgFontFamilies.Count != 0)
            {
                svgFontNames = new List <string>();
            }
            var systemFontFamilies = Fonts.SystemFontFamilies;

            FontFamily family = null;

            WpfFontFamilyType familyType = WpfFontFamilyType.None;

            foreach (string fn in fontNames)
            {
                try
                {
                    string fontName = fn.Trim(new char[] { ' ', '\'', '"' });
                    if (svgFontFamilies != null && svgFontFamilies.Count != 0)
                    {
                        if (svgFontFamilies.Contains(fontName))
                        {
                            svgFontNames.Add(fontName);
                            continue;
                        }
                        else if (styledFontIds.ContainsKey(fontName))
                        {
                            string mappedFontName = styledFontIds[fontName];
                            if (svgFontFamilies.Contains(mappedFontName))
                            {
                                svgFontNames.Add(mappedFontName);
                                continue;
                            }
                        }
                    }

                    if (string.Equals(fontName, "serif", comparer))
                    {
                        family     = WpfDrawingSettings.GenericSerif;
                        familyType = WpfFontFamilyType.Generic;
                    }
                    else if (string.Equals(fontName, "sans-serif", comparer))
                    {
                        family     = WpfDrawingSettings.GenericSansSerif;
                        familyType = WpfFontFamilyType.Generic;
                    }
                    else if (string.Equals(fontName, "monospace", comparer))
                    {
                        family     = WpfDrawingSettings.GenericMonospace;
                        familyType = WpfFontFamilyType.Generic;
                    }
                    else if (styledFontIds.ContainsKey(fontName))
                    {
                        string mappedFontName = styledFontIds[fontName];
                        var    funcFamily     = new Func <FontFamily, bool>(ff => string.Equals(ff.Source, mappedFontName, comparer));
                        family = systemFontFamilies.FirstOrDefault(funcFamily);
                        if (family != null)
                        {
                            _actualFontName = mappedFontName;
                            familyType      = WpfFontFamilyType.System;
                        }
                    }
                    else
                    {
                        string normalizedFontName;
                        var    funcFamily = new Func <FontFamily, bool>(ff => string.Equals(ff.Source, fontName, comparer));
                        family = systemFontFamilies.FirstOrDefault(funcFamily);
                        if (family != null)
                        {
                            _actualFontName = fontName;
                            familyType      = WpfFontFamilyType.System;
                        }
                        else if (fontName.IndexOf('-') > 0)
                        {
                            normalizedFontName = fontName.Replace("-", " ");
                            funcFamily         = new Func <FontFamily, bool>(ff => string.Equals(ff.Source,
                                                                                                 normalizedFontName, comparer));
                            family = systemFontFamilies.FirstOrDefault(funcFamily);
                            if (family != null)
                            {
                                _actualFontName = normalizedFontName;
                                familyType      = WpfFontFamilyType.System;
                            }
                        }
                        else if (SplitByCaps(fontName, out normalizedFontName))
                        {
                            funcFamily = new Func <FontFamily, bool>(ff => string.Equals(ff.Source,
                                                                                         normalizedFontName, comparer));
                            family = systemFontFamilies.FirstOrDefault(funcFamily);
                            if (family != null)
                            {
                                _actualFontName = normalizedFontName;
                                familyType      = WpfFontFamilyType.System;
                            }
                        }
                    }

                    if (family != null)
                    {
                        return(new WpfFontFamilyInfo(familyType, _actualFontName, family,
                                                     fontWeight, fontStyle, fontStretch));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }

            // If set, use the SVG-Font...
            if (svgFontNames != null && svgFontNames.Count != 0)
            {
                IList <SvgFontElement> svgFonts = docElement.GetFonts(svgFontNames);
                if (svgFonts != null && svgFonts.Count != 0)
                {
                    string fontVariant = element.GetPropertyValue("font-variant");

                    // For a single match...
                    if (svgFonts.Count == 1)
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        return(fontFamilyInfo);
                    }

                    // For multiple matches, we will test the variants...
                    if (string.IsNullOrWhiteSpace(fontVariant))
                    {
                        // Not found, return the first match...
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        return(fontFamilyInfo);
                    }

                    foreach (var svgFont in svgFonts)
                    {
                        var fontFace = svgFont.FontFace;
                        if (fontFace == null)
                        {
                            continue;
                        }
                        if (fontVariant.Equals(fontFace.FontVariant, comparer))
                        {
                            var fontFamilyInfo = new WpfFontFamilyInfo(svgFont.FontFamily, svgFont,
                                                                       fontWeight, fontStyle, fontStretch);

                            fontFamilyInfo.Variant = fontVariant;
                            return(fontFamilyInfo);
                        }
                    }

                    // If the variant is not found, return the first match...
                    {
                        var fontFamilyInfo = new WpfFontFamilyInfo(svgFonts[0].FontFamily, svgFonts[0],
                                                                   fontWeight, fontStyle, fontStretch);

                        fontFamilyInfo.Variant = fontVariant;
                        return(fontFamilyInfo);
                    }
                }
            }

            // No known font-family was found => default to "Arial Unicode MS"
            return(new WpfFontFamilyInfo(familyType, _actualFontName,
                                         WpfDrawingSettings.DefaultFontFamily, fontWeight, fontStyle, fontStretch));
        }