Example #1
0
        /// <summary>
        /// 构建文本形状
        /// </summary>
        /// <param name="group">文本形状组</param>
        /// <param name="x">横坐标</param>
        /// <param name="y">纵坐标</param>
        /// <param name="totalwidth">总宽度</param>
        public void BuildTextSpan(GeometryGroup group, ref double x, ref double y, ref double totalwidth)
        {
            if (this.Node.NodeType == XmlNodeType.Element)
            {
                foreach (Tspan item in this.Children)
                {
                    if (item == null)
                    {
                        continue;
                    }

                    item.BuildTextSpan(group, ref x, ref y, ref totalwidth);
                }

                return;
            }

            XText xtext = this.Node as XText;

            if (xtext == null)
            {
                return;
            }

            string text = xtext.Value;

            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            double baseline = y;

            SVGBaseLineShift baseline_shift = this.GetAttributeValue <SVGBaseLineShift>("baseline-shift", true, null);
            double           font_size      = this.GetAttributeValue <SVGDouble>("font-size", true, new SVGDouble(12)).GetValue(12);

            if (baseline_shift != null)
            {
                if (baseline_shift == SVGBaseLineShift.Sub)
                {
                    baseline += font_size * 0.5;
                }
                else if (baseline_shift == SVGBaseLineShift.Super)
                {
                    baseline -= font_size * 1.25;
                }
                else if (baseline_shift != null)
                {
                    baseline += font_size * baseline_shift.Value.GetValue(font_size);
                }
            }

            Geometry geometry = this.BuildGlyphRun(text, x, baseline, ref totalwidth);

            group.Children.Add(geometry);

            x += totalwidth;
        }
Example #2
0
        /// <summary>
        /// 构建文本形状
        /// </summary>
        /// <param name="text">文本内容</param>
        /// <param name="x">横坐标</param>
        /// <param name="y">纵坐标</param>
        /// <param name="totalwidth">总宽度</param>
        /// <returns>形状</returns>
        private Geometry BuildGlyphRun(string text, double x, double y, ref double totalwidth)
        {
            double baseline = y;

            SVGBaseLineShift  baseline_shift  = this.GetAttributeValue <SVGBaseLineShift>("baseline-shift", true, null);
            double            font_size       = this.GetAttributeValue <SVGDouble>("font-size", true, new SVGDouble(12)).GetValue(12);
            SVGFontFamily     font_family     = this.GetAttributeValue <SVGFontFamily>("font-family", true, SVGFontFamily.Default);
            SVGFontWeight     font_weight     = this.GetAttributeValue <SVGFontWeight>("font-weight", true, SVGFontWeight.Default);
            SVGFontStyle      font_style      = this.GetAttributeValue <SVGFontStyle>("font-style", true, SVGFontStyle.Default);
            SVGTextAnchor     text_anchor     = this.GetAttributeValue <SVGTextAnchor>("text-anchor", true, SVGTextAnchor.Default);
            SVGTextDecoration text_decoration = this.GetAttributeValue <SVGTextDecoration>("text-decoration", true, null);
            double            letter_spacing  = this.GetAttributeValue <SVGDouble>("letter-spacing", true, SVGDouble.Zero).GetValue(12);
            double            word_spacing    = this.GetAttributeValue <SVGDouble>("word-spacing", true, SVGDouble.Zero).GetValue(12);

            GlyphRun glyphs = null;

            Typeface      type_face = new Typeface(font_family.Value, font_style.Value, font_weight.Value, FontStretch.FromOpenTypeStretch(9), SVGFontFamily.Default.Value);
            GlyphTypeface glyph_type_face;

            if (!type_face.TryGetGlyphTypeface(out glyph_type_face))
            {
                return(null);
            }

            glyphs = new GlyphRun();

            ((System.ComponentModel.ISupportInitialize)glyphs).BeginInit();

            glyphs.GlyphTypeface       = glyph_type_face;
            glyphs.FontRenderingEmSize = font_size;
            List <char>   text_chars     = new List <char>();
            List <ushort> glyph_indices  = new List <ushort>();
            List <double> advance_widths = new List <double>();

            totalwidth = 0;
            for (int i = 0; i < text.Length; ++i)
            {
                char   c          = text[i];
                int    code_point = c;
                ushort glyph_index;
                if (!glyph_type_face.CharacterToGlyphMap.TryGetValue(code_point, out glyph_index))
                {
                    continue;
                }

                text_chars.Add(c);
                double glyph_width = glyph_type_face.AdvanceWidths[glyph_index];
                glyph_indices.Add(glyph_index);
                advance_widths.Add(glyph_width * font_size + letter_spacing);
                if (char.IsWhiteSpace(c))
                {
                    advance_widths[advance_widths.Count - 1] += word_spacing;
                }
                totalwidth += advance_widths[advance_widths.Count - 1];
            }
            glyphs.Characters    = text_chars.ToArray();
            glyphs.GlyphIndices  = glyph_indices.ToArray();
            glyphs.AdvanceWidths = advance_widths.ToArray();

            double alignmentoffset = 0;

            if (text_anchor.Value == TextAlignment.Center)
            {
                alignmentoffset = totalwidth / 2;
            }
            else if (text_anchor.Value == TextAlignment.Right)
            {
                alignmentoffset = totalwidth;
            }

            glyphs.BaselineOrigin = new Point(x - alignmentoffset, baseline);

            ((System.ComponentModel.ISupportInitialize)glyphs).EndInit();

            GeometryGroup result = new GeometryGroup();

            result.Children.Add(glyphs.BuildGeometry());

            if (text_decoration != null)
            {
                double decoration_pos      = 0;
                double decoration_thinkess = 0;

                if (text_decoration.Value == TextDecorationLocation.Strikethrough)
                {
                    decoration_pos      = baseline - (type_face.StrikethroughPosition * font_size);
                    decoration_thinkess = type_face.StrikethroughThickness * font_size;
                }
                else if (text_decoration.Value == TextDecorationLocation.Underline)
                {
                    decoration_pos      = baseline - (type_face.UnderlinePosition * font_size);
                    decoration_thinkess = type_face.UnderlineThickness * font_size;
                }
                else if (text_decoration.Value == TextDecorationLocation.OverLine)
                {
                    decoration_pos      = baseline - font_size;
                    decoration_thinkess = type_face.StrikethroughThickness * font_size;
                }

                System.Windows.Rect bounds = new System.Windows.Rect(result.Bounds.Left, decoration_pos, result.Bounds.Width, decoration_thinkess);

                result.Children.Add(new RectangleGeometry(bounds));
            }

            return(result);
        }