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); 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; string letterSpacing = element.GetAttribute("letter-spacing"); if (String.IsNullOrEmpty(letterSpacing)) { FormattedText formattedText = new FormattedText(text, textRun.IsLatin ? _drawContext.EnglishCultureInfo : _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; Point textPoint = new Point(ctp.X, ctp.Y - yCorrection); RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y); _textContext.PushTransform(rotateAt); _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(); } } else { RotateTransform rotateAt = new RotateTransform(90, ctp.X, ctp.Y); _textContext.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 ? _drawContext.EnglishCultureInfo : _drawContext.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); _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; ctp.X += bboxWidth + spacing; } if (rotateAt != null) { _textContext.Pop(); } } }
public abstract WpfFontFamilyInfo Visit(string fontName, WpfFontFamilyInfo familyInfo, WpfDrawingContext context);
public override void RenderTextRun(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); 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.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) { double spacing = Convert.ToDouble(letterSpacing); 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); 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 && 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(ctp.X, ctp.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); 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 != 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(); } } }
public override WpfFontFamilyInfo Visit(string fontName, WpfFontFamilyInfo familyInfo, WpfDrawingContext context) { if (String.IsNullOrEmpty(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); }
private void RenderTextPath(SvgTextContentElement element, WpfTextOnPathDrawing pathDrawing, string text, Point origin, 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 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); }