public void Set(TextBlock textBlock)
 {
     this.fontFamily = textBlock.FontFamily;
     this.fontWeight = textBlock.FontWeight;
     this.fontStyle = textBlock.FontStyle;
     this.fontStretch = textBlock.FontStretch;
 }
Example #2
0
 public Typeface(FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     this.FontFamily = fontFamily;
     this.Style = style;
     this.Weight = weight;
     this.Stretch = stretch;
 }
Example #3
0
 public Typeface(FontFamily fontFamily, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal, FontStretch stretch = FontStretch.Normal)
 {
     this.FontFamily = fontFamily;
     this.Style = style;
     this.Weight = weight;
     this.Stretch = stretch;
 }
Example #4
0
 ///<summary>
 /// Creates a new DrawableFont instance.
 ///</summary>
 ///<param name="family">The font family or the full path to the font file.</param>
 ///<param name="style">The style of the font.</param>
 ///<param name="weight">The weight of the font.</param>
 ///<param name="stretch">The font stretching type.</param>
 public DrawableFont(string family, FontStyleType style, FontWeight weight, FontStretch stretch)
 {
   Family = family;
   Style = style;
   Weight = weight;
   Stretch = stretch;
 }
Example #5
0
 public override object Create(string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     object o = NSFont.FromFontName (fontName, (float)size);
     o = SetStyle (o, style);
     o = SetWeight (o, weight);
     o = SetStretch (o, stretch);
     return o;
 }
Example #6
0
    /// <summary>
    /// Initializes a new instance of the <see cref="DrawableFont"/> class.
    /// </summary>
    /// <param name="family">The font family or the full path to the font file.</param>
    /// <param name="style">The style of the font.</param>
    /// <param name="weight">The weight of the font.</param>
    /// <param name="stretch">The font stretching type.</param>
    public DrawableFont(string family, FontStyleType style, FontWeight weight, FontStretch stretch)
    {
      Throw.IfNullOrEmpty(nameof(family), family);

      Family = family;
      Style = style;
      Weight = weight;
      Stretch = stretch;
    }
Example #7
0
		public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
		{
			var t = GetStretchTrait (stretch) | GetStyleTrait (style);
			var f = NSFontManager.SharedFontManager.FontWithFamily (fontName, t, GetWeightValue (weight), (float)size);
			var fd = FontData.FromFont (NSFontManager.SharedFontManager.ConvertFont (f, t));
			fd.Style = style;
			fd.Weight = weight;
			fd.Stretch = stretch;
			return fd;
		}
        /// <summary>
        /// Determines if the given value represents a valid state of this property.
        /// </summary>
        /// <param name="value">The state that should be used.</param>
        /// <returns>True if the state is valid, otherwise false.</returns>
        protected override Boolean IsValid(CSSValue value)
        {
            FontStretch style;

            if (value is CSSIdentifierValue && _styles.TryGetValue(((CSSIdentifierValue)value).Value, out style))
                _stretch = style;
            else if (value != CSSValue.Inherit)
                return false;

            return true;
        }
 /// <summary>
 /// Create a text format object used for text layout.
 /// </summary>
 /// <param name="fontFamilyName">Name of the font family</param>
 /// <param name="fontWeight">Font weight</param>
 /// <param name="fontStyle">Font style</param>
 /// <param name="fontStretch">Font stretch</param>
 /// <param name="fontSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
 /// <param name="localeName">Locale name(optional)</param>
 /// TODO understand the meaning of Locale name
 /// <returns> newly created text format object </returns>
 public static TextFormat CreateTextFormat(
     string fontFamilyName,
     FontWeight fontWeight, FontStyle fontStyle, FontStretch fontStretch,
     float fontSize,
     string localeName = "en-us")
 {
     var ptr = Factory.CreateTextFormat(fontFamilyName, IntPtr.Zero,
         fontWeight,
         fontStyle, fontStretch, fontSize,
         localeName);
     var dWriteTextFormat = new TextFormat(ptr);
     return dWriteTextFormat;
 }
Example #10
0
        public bool RegisterFont(string name, float fontSize, string fontFace = "Arial", FontWeight fontWeight = FontWeight.Normal, FontStyle fontStyle = FontStyle.Normal, FontStretch fontStretch = FontStretch.Normal) {
            if (_fonts.ContainsKey(name)) {
                Console.WriteLine("Duplicate font name: " + name);
                return false;
            }
            try {
                _fonts[name] = new TextBlockRenderer(_sprite, fontFace, fontWeight, fontStyle, fontStretch, fontSize);
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                return false;
            }

            return true;
        }
Example #11
0
        /// <summary>
        /// Finds a font in the collection that matches the given parameters.
        /// </summary>
        /// <param name="family">The font family name.</param>
        /// <param name="weight">The font weight.</param>
        /// <param name="stretch">The font stretch setting.</param>
        /// <param name="style">The font style.</param>
        /// <returns>The loaded font if it exists in the collection; otherwise, <c>null</c>.</returns>
        public FontFace Load (string family, FontWeight weight = FontWeight.Normal, FontStretch stretch = FontStretch.Normal, FontStyle style = FontStyle.Regular) {
            List<Metadata> sublist;
            if (!fontTable.TryGetValue(family.ToLowerInvariant(), out sublist))
                return null;

            foreach (var file in sublist) {
                if (file.Weight == weight && file.Stretch == stretch && file.Style == style) {
                    if (file.Stream != null)
                        return new FontFace(file.Stream);
                    else {
                        using (var stream = File.OpenRead(file.FileName))
                            return new FontFace(stream);
                    }
                }
            }

            return null;
        }
        public override object SetStretch(object handle, FontStretch stretch)
        {
            FontData f = (FontData) handle;
            f = f.Copy ();

            NSFont font = f.Font;
            if (stretch < FontStretch.SemiCondensed) {
                font = NSFontManager.SharedFontManager.ConvertFont (font, NSFontTraitMask.Condensed);
                font = NSFontManager.SharedFontManager.ConvertFontToNotHaveTrait (font, NSFontTraitMask.Compressed | NSFontTraitMask.Expanded | NSFontTraitMask.Narrow);
            }
            if (stretch == FontStretch.SemiCondensed) {
                font = NSFontManager.SharedFontManager.ConvertFont (font, NSFontTraitMask.Narrow);
                font = NSFontManager.SharedFontManager.ConvertFontToNotHaveTrait (font, NSFontTraitMask.Compressed | NSFontTraitMask.Expanded | NSFontTraitMask.Condensed);
            }
            else if (stretch > FontStretch.Normal) {
                font = NSFontManager.SharedFontManager.ConvertFont (font, NSFontTraitMask.Expanded);
                font = NSFontManager.SharedFontManager.ConvertFontToNotHaveTrait (font, NSFontTraitMask.Compressed | NSFontTraitMask.Narrow | NSFontTraitMask.Condensed);
            }
            else {
                font = NSFontManager.SharedFontManager.ConvertFontToNotHaveTrait (font, NSFontTraitMask.Condensed | NSFontTraitMask.Expanded | NSFontTraitMask.Narrow | NSFontTraitMask.Compressed);
            }
            f.Font = font;
            f.Stretch = stretch;
            return f;
        }
Example #13
0
		public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
		{
			return FontDescription.FromString (fontName + ", " + style + " " + weight + " " + stretch + " " + size.ToString (CultureInfo.InvariantCulture));
		}
        public static FontStretch GetFontStretch(DependencyObject element)
        {
            FontStretch ret = (FontStretch)NoesisGUI_PINVOKE.TextElement_GetFontStretch(DependencyObject.getCPtr(element));

            return(ret);
        }
Example #15
0
 public Font WithStretch(FontStretch stretch)
 {
     return(new Font(handler.SetStretch(Backend, stretch)));
 }
 public static void SetFontStretch(DependencyObject element, FontStretch stretch)
 {
     NoesisGUI_PINVOKE.TextElement_SetFontStretch(DependencyObject.getCPtr(element), (int)stretch);
 }
Example #17
0
        /// <summary>
        /// Get the required height and width of the specified text. Uses Glyph's
        /// </summary>
        public static Size MeasureText(string text, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double fontSize)
        {
            Typeface      typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
            GlyphTypeface glyphTypeface;

            if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
            {
                return(MeasureTextSize(text, fontFamily, fontStyle, fontWeight, fontStretch, fontSize));
            }

            double totalWidth = 0;
            double height     = 0;

            for (int n = 0; n < text.Length; n++)
            {
                ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];

                double width = glyphTypeface.AdvanceWidths[glyphIndex] * fontSize;

                double glyphHeight = glyphTypeface.AdvanceHeights[glyphIndex] * fontSize;

                if (glyphHeight > height)
                {
                    height = glyphHeight;
                }

                totalWidth += width;
            }

            return(new Size(totalWidth, height));
        }
Example #18
0
 public D2DSpriteTextformat CreateTextformat(string fontFamiry, int size = 15, FontWeight weight                 = FontWeight.Normal,
                                             FontStyle style             = FontStyle.Normal, FontStretch stretch = FontStretch.Normal, string locale = "ja-jp")
 {
     return(new D2DSpriteTextformat(this, fontFamiry, size, weight, style, stretch, locale));
 }
Example #19
0
File: Font.cs Project: garuma/xwt
 public Font WithStretch(FontStretch stretch)
 {
     return new Font (handler.SetStretch (Backend, stretch), ToolkitEngine);
 }
Example #20
0
 public override object Create(string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     return(FontDescription.FromString(fontName + ", " + style + " " + weight + " " + stretch + " " + size.ToString(CultureInfo.InvariantCulture)));
 }
Example #21
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal methods

        /// <summary>
        /// This method looks up a certain family in this collection given its name.
        /// If the name was for a specific font face then this method will return its
        /// style, weight and stretch information.
        /// </summary>
        /// <param name="familyName">The name of the family to look for.</param>
        /// <param name="fontStyle">The style if the font face in case family name contained style info.</param>
        /// <param name="fontWeight">The weight if the font face in case family name contained style info.</param>
        /// <param name="fontStretch">The stretch if the font face in case family name contained style info.</param>
        /// <returns>The font family if found.</returns>
        internal IFontFamily LookupFamily(
            string familyName,
            ref FontStyle fontStyle,
            ref FontWeight fontWeight,
            ref FontStretch fontStretch
            )
        {
            if (familyName == null || familyName.Length == 0)
            {
                return(null);
            }

            familyName = familyName.Trim();

            // If we are referencing fonts from the system fonts, then it is cheap to lookup the 4 composite fonts
            // that ship with WPF. Also, it happens often that familyName is "Global User Interface".
            // So in this case we preceed looking into SystemComposite Fonts.
            if (UseSystemFonts)
            {
                CompositeFontFamily compositeFamily = SystemCompositeFonts.FindFamily(familyName);
                if (compositeFamily != null)
                {
                    return(compositeFamily);
                }
            }

            Text.TextInterface.FontFamily fontFamilyDWrite = _fontCollection[familyName];

            // A font family was not found in DWrite's font collection.
            if (fontFamilyDWrite == null)
            {
                // Having user defined composite fonts is not very common. So we defer looking into them to looking DWrite
                // (which is opposite to what we do for system fonts).
                if (!UseSystemFonts)
                {
                    // The family name was not found in DWrite's font collection. It may possibly be the name of a composite font
                    // since DWrite does not recognize composite fonts.
                    CompositeFontFamily compositeFamily = LookUpUserCompositeFamily(familyName);
                    if (compositeFamily != null)
                    {
                        return(compositeFamily);
                    }
                }

                // The family name cannot be found. This may possibly be because the family name contains styling info.
                // For example, "Arial Bold"
                // We will strip off the styling info (one word at a time from the end) and try to find the family name.
                int indexOfSpace = -1;
                System.Text.StringBuilder potentialFaceName = new System.Text.StringBuilder();

                // Start removing off strings from the end hoping they are
                // style info so as to get down to the family name.
                do
                {
                    indexOfSpace = familyName.LastIndexOf(' ');
                    if (indexOfSpace < 0)
                    {
                        break;
                    }
                    else
                    {
                        // store the stripped off style names to look for the specific face later.
                        potentialFaceName.Insert(0, familyName.Substring(indexOfSpace));
                        familyName = familyName.Substring(0, indexOfSpace);
                    }

                    fontFamilyDWrite = _fontCollection[familyName];
                } while (fontFamilyDWrite == null);


                if (fontFamilyDWrite == null)
                {
                    return(null);
                }

                // If there was styling information.
                if (potentialFaceName.Length > 0)
                {
                    // The first character in the potentialFaceName will be a space so we need to strip it off.
                    Text.TextInterface.Font font = GetFontFromFamily(fontFamilyDWrite, potentialFaceName.ToString(1, potentialFaceName.Length - 1));

                    if (font != null)
                    {
                        fontStyle   = new FontStyle((int)font.Style);
                        fontWeight  = new FontWeight((int)font.Weight);
                        fontStretch = new FontStretch((int)font.Stretch);
                    }
                }
            }

            if (UseSystemFonts &&
                LegacyArabicFonts.UsePrivateFontCollectionForLegacyArabicFonts
                // familyName will hold the family name without any face info.
                && LegacyArabicFonts.IsLegacyArabicFont(familyName))
            {
                fontFamilyDWrite = LegacyArabicFonts.LegacyArabicFontCollection[familyName];
                if (fontFamilyDWrite == null)
                {
                    return(SystemCompositeFonts.GetFallbackFontForArabicLegacyFonts());
                }
            }

            return(new PhysicalFontFamily(fontFamilyDWrite));
        }
        int IComparable.CompareTo(object obj)
        {
            TypefaceListItem item = obj as TypefaceListItem;

            if (item == null)
            {
                return(-1);
            }

            // Sort all simulated faces after all non-simulated faces.
            if (_simulated != item._simulated)
            {
                return(_simulated ? 1 : -1);
            }

            // If weight differs then sort based on weight (lightest first).
            int difference = FontWeight.ToOpenTypeWeight() - item.FontWeight.ToOpenTypeWeight();

            if (difference != 0)
            {
                return(difference > 0 ? 1 : -1);
            }

            // If style differs then sort based on style (Normal, Italic, then Oblique).
            FontStyle thisStyle  = FontStyle;
            FontStyle otherStyle = item.FontStyle;

            if (thisStyle != otherStyle)
            {
                if (thisStyle == FontStyles.Normal)
                {
                    // This item is normal style and should come first.
                    return(-1);
                }
                else if (otherStyle == FontStyles.Normal)
                {
                    // The other item is normal style and should come first.
                    return(1);
                }
                else
                {
                    // Neither is normal so sort italic before oblique.
                    return((thisStyle == FontStyles.Italic) ? -1 : 1);
                }
            }

            // If stretch differs then sort based on stretch (Normal first, then numerically).
            FontStretch thisStretch  = FontStretch;
            FontStretch otherStretch = item.FontStretch;

            if (thisStretch != otherStretch)
            {
                if (thisStretch == FontStretches.Normal)
                {
                    // This item is normal stretch and should come first.
                    return(-1);
                }
                else if (otherStretch == FontStretches.Normal)
                {
                    // The other item is normal stretch and should come first.
                    return(1);
                }
                else
                {
                    // Neither is normal so sort numerically.
                    return(thisStretch.ToOpenTypeStretch() < otherStretch.ToOpenTypeStretch() ? -1 : 0);
                }
            }

            // They're the same.
            return(0);
        }
Example #23
0
        /// <summary>
        /// Parses the attributes of the FamilyTypeface element and sets the corresponding
        /// properties on the specified FamilyTypeface object. On return, the reader remains
        /// positioned on the element.
        /// </summary>
        private void ParseFamilyTypefaceAttributes(FamilyTypeface face)
        {
            // Iterate over the attributes.
            if (_reader.MoveToFirstAttribute())
            {
                do
                {
                    // Process attributes in the composite font namespace; ignore any others.
                    if (IsCompositeFontAttribute())
                    {
                        string name = _reader.LocalName;

                        if (name == StyleAttribute)
                        {
                            FontStyle fontStyle = new FontStyle();
                            if (!FontStyles.FontStyleStringToKnownStyle(GetAttributeValue(), CultureInfo.InvariantCulture, ref fontStyle))
                            {
                                FailAttributeValue();
                            }

                            face.Style = fontStyle;
                        }
                        else if (name == WeightAttribute)
                        {
                            FontWeight fontWeight = new FontWeight();
                            if (!FontWeights.FontWeightStringToKnownWeight(GetAttributeValue(), CultureInfo.InvariantCulture, ref fontWeight))
                            {
                                FailAttributeValue();
                            }

                            face.Weight = fontWeight;
                        }
                        else if (name == StretchAttribute)
                        {
                            FontStretch fontStretch = new FontStretch();
                            if (!FontStretches.FontStretchStringToKnownStretch(GetAttributeValue(), CultureInfo.InvariantCulture, ref fontStretch))
                            {
                                FailAttributeValue();
                            }

                            face.Stretch = fontStretch;
                        }
                        else if (name == UnderlinePositionAttribute)
                        {
                            face.UnderlinePosition = GetAttributeAsDouble();
                        }
                        else if (name == UnderlineThicknessAttribute)
                        {
                            face.UnderlineThickness = GetAttributeAsDouble();
                        }
                        else if (name == StrikethroughPositionAttribute)
                        {
                            face.StrikethroughPosition = GetAttributeAsDouble();
                        }
                        else if (name == StrikethroughThicknessAttribute)
                        {
                            face.StrikethroughThickness = GetAttributeAsDouble();
                        }
                        else if (name == CapsHeightAttribute)
                        {
                            face.CapsHeight = GetAttributeAsDouble();
                        }
                        else if (name == XHeightAttribute)
                        {
                            face.XHeight = GetAttributeAsDouble();
                        }
                        else if (name == DeviceFontNameAttribute)
                        {
                            face.DeviceFontName = GetAttributeValue();
                        }
                        else
                        {
                            FailUnknownAttribute();
                        }
                    }
                    else if (!IsIgnorableAttribute())
                    {
                        FailUnknownAttribute();
                    }
                } while (_reader.MoveToNextAttribute());

                _reader.MoveToElement();
            }
        }
Example #24
0
 internal static IntPtr NewStretchAttribute(FontStretch stretch) => Libui.LoadFunction <Signatures.uiNewStretchAttribute>()(stretch);
Example #25
0
 private static Typeface SelectBestMatchingTypeface(FontFamily family, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     ICollection<Typeface> typefaces = family.GetTypefaces();
     if (typefaces.Count == 0)
         return null;
     IEnumerable<Typeface> matchingTypefaces
         = from tf in typefaces
           where tf.Style == style && tf.Weight == weight && tf.Stretch == stretch
           select tf;
     if (matchingTypefaces.Count() == 0)
         matchingTypefaces = from tf in typefaces
                             where tf.Style == style && tf.Weight == weight
                             select tf;
     if (matchingTypefaces.Count() == 0)
         matchingTypefaces = from tf in typefaces
                             where tf.Style == style
                             select tf;
     if (matchingTypefaces.Count() == 0)
         return typefaces.First();
     return matchingTypefaces.First();
 }
Example #26
0
        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);
//#if NETCOREAPP30
//                    FormattedText formattedText = new FormattedText(nextText,
//                        _context.CultureInfo, stringFormat.Direction, typeFace, emSize, textBrush);
//#else
//                    FormattedText formattedText = new FormattedText(nextText, _context.CultureInfo,
//                        stringFormat.Direction, typeFace, emSize, textBrush, _context.PixelsPerDip);
//#endif

//                    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);
//#if NET40
//                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
//                    stringFormat.Direction, typeFace, emSize, textBrush);
//#else
//                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
//                    stringFormat.Direction, typeFace, emSize, textBrush, _context.PixelsPerDip);
//#endif

                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();
                }
            }
        }
Example #27
0
 public Font WithStretch(FontStretch stretch)
 {
     return new Font (handler.SetStretch (Backend, stretch));
 }
Example #28
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);

            WpfTextStringFormat stringFormat = GetTextStringFormat(element);

            if (fontFamilyInfo.FontFamilyType == WpfFontFamilyType.Svg)
            {
                WpfTextTuple textInfo = new WpfTextTuple(fontFamilyInfo, emSize, stringFormat, element);
                this.RenderTextRun(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);

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

                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 NET40
//                    FormattedText formattedText = new FormattedText(inputText,  _context.CultureInfo,
//                        stringFormat.Direction, typeFace, emSize, textBrush);
//#else
//                    FormattedText formattedText = new FormattedText(inputText, _context.CultureInfo,
//                        stringFormat.Direction, typeFace, emSize, textBrush, _context.PixelsPerDip);
//#endif

                    if (this.IsMeasuring)
                    {
                        this.AddTextWidth(ctp, 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);
                        _drawContext.PushTransform(rotateAt);
                    }

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

                    if (isForcedPathMode || _context.TextAsGeometry)
                    {
                        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();
                    }
                    j++;
                }
            }
            else
            {
                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
                                                                stringFormat.Direction, typeFace, emSize, textBrush);
//#if !NET40
//                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
//                    stringFormat.Direction, typeFace, emSize, textBrush, _context.PixelsPerDip);
//#else
//                FormattedText formattedText = new FormattedText(text, _context.CultureInfo,
//                    stringFormat.Direction, typeFace,  emSize, textBrush);
//#endif

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

                var textContext = this.TextContext;
                if (textContext != null && textContext.IsPositionChanged(element) == false)
                {
                    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);
                    _drawContext.PushTransform(rotateAt);
                }

                if (isForcedPathMode || _context.TextAsGeometry)
                {
                    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();
                }
            }
        }
Example #29
0
 internal D2DSpriteTextformat(D2DSpriteBatch batch, string fontFamiry, int size, FontWeight weight,
                              FontStyle style, FontStretch stretch, string locale)
 {
     batch.BatchDisposing += batch_BatchDisposing;
     this.Format           = new TextFormat(batch.context.DWFactory, fontFamiry, weight, style, stretch, size, locale);
 }
Example #30
0
        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)
            {
                SvgTextBaseElement textElement = element.ParentNode as SvgTextBaseElement;

                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.TextDecorations = 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));
                        _drawContext.DrawGeometry(textBrush, textPen, textGeometry);
                    }

                    //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.TextDecorations = 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));
                    _drawContext.DrawGeometry(textBrush, textPen, 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();
                }
            }
        }
Example #31
0
 public static void SetHeaderFontStretch(UIElement element, FontStretch value)
 {
     element.SetValue(HeaderFontStretchProperty, value);
 }
Example #32
0
 /// <summary>
 /// Sets default font properties to be used when not specified in an element
 /// </summary>
 public static void SetFontDefaultProperties(float size, FontWeight weight, FontStretch stretch,
                                             FontStyle style)
 {
     Noesis_SetFontDefaultProperties(size, (int)weight, (int)stretch, (int)style);
 }
Example #33
0
        /// <summary>
        /// Get the required height and width of the specified text. Uses FortammedText
        /// </summary>
        public static Size MeasureTextSize(string text, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double fontSize)
        {
            FormattedText ft = new FormattedText(text,
                                                 CultureInfo.CurrentCulture,
                                                 FlowDirection.LeftToRight,
                                                 new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                                 fontSize,
                                                 Brushes.Black);

            return(new Size(ft.Width, ft.Height));
        }
Example #34
0
        internal static Font FromName(string name, Toolkit toolkit)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name), "Font name cannot be null");
            }
            if (name.Length == 0)
            {
                return(toolkit.FontBackendHandler.SystemFont);
            }

            var handler = toolkit.FontBackendHandler;

            double      size    = -1;
            FontStyle   style   = FontStyle.Normal;
            FontWeight  weight  = FontWeight.Normal;
            FontStretch stretch = FontStretch.Normal;

            int i     = name.LastIndexOf(' ');
            int lasti = name.Length;

            do
            {
                if (lasti > 0 && IsFontSupported(name.Substring(0, lasti)))
                {
                    break;
                }

                string      token = name.Substring(i + 1, lasti - i - 1);
                FontStyle   st;
                FontWeight  fw;
                FontStretch fs;
                double      siz;
                if (double.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out siz)) // Try parsing the number first, since Enum.TryParse can also parse numbers
                {
                    if (size == -1)                                                                  // take only first number
                    {
                        size = siz;
                    }
                }
                else if (Enum.TryParse <FontStyle> (token, true, out st) && st != FontStyle.Normal)
                {
                    style = st;
                }
                else if (Enum.TryParse <FontWeight> (token, true, out fw) && fw != FontWeight.Normal)
                {
                    weight = fw;
                }
                else if (Enum.TryParse <FontStretch> (token, true, out fs) && fs != FontStretch.Normal)
                {
                    stretch = fs;
                }
                else if (token.Length > 0)
                {
                    break;
                }

                lasti = i;
                if (i <= 0)
                {
                    break;
                }

                i = name.LastIndexOf(' ', i - 1);
            } while (true);

            string fname = lasti > 0 ? name.Substring(0, lasti) : string.Empty;

            fname = fname.Length > 0 ? GetSupportedFont(fname) : Font.SystemFont.Family;

            if (size == -1)
            {
                size = SystemFont.Size;
            }

            var fb = handler.Create(fname, size, style, weight, stretch);

            if (fb != null)
            {
                return(new Font(fb, toolkit));
            }
            else
            {
                return(Font.SystemFont);
            }
        }
Example #35
0
        public static Size MeasureString(string candidate, FontFamily FontFamily, FontStyle FontStyle, FontWeight FontWeight, FontStretch FontStretch, double FontSize, TextFormattingMode TextFormattingMode)
        {
            var formattedText = new FormattedText(
                candidate,
                CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight,
                new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
                FontSize,
                Brushes.Black,
                new NumberSubstitution(),
                TextFormattingMode);

            return(new Size(formattedText.Width, formattedText.Height));
        }
Example #36
0
        /// <summary>
        /// DependencyProperty setter for <see cref="FontStretch" /> property.
        /// </summary>
        /// <param name="element">The element to which to write the attached property.</param>
        /// <param name="value">The property value to set</param>
        public static void SetFontStretch(DependencyObject element, FontStretch value)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(FontStretchProperty, value);
        }
Example #37
0
        /// <summary>
        /// Map characters by font face family
        /// </summary>
        private int MapByFontFaceFamily(
            CharacterBufferRange unicodeString,
            CultureInfo culture,
            CultureInfo digitCulture,
            IFontFamily fontFamily,
            FontStyle canonicalStyle,
            FontWeight canonicalWeight,
            FontStretch canonicalStretch,
            ref PhysicalFontFamily firstValidFamily,
            ref int firstValidLength,
            IDeviceFont deviceFont,
            bool nullFont,
            double scaleInEm,
            SpanVector scaledTypefaceSpans,
            int firstCharIndex,
            bool ignoreMissing,
            out int nextValid
            )
        {
            Invariant.Assert(fontFamily != null);

            PhysicalFontFamily fontFaceFamily = fontFamily as PhysicalFontFamily;

            Invariant.Assert(fontFaceFamily != null);

            int advance = unicodeString.Length;

            nextValid = 0;

            GlyphTypeface glyphTypeface = null;

            if (ignoreMissing)
            {
                glyphTypeface = fontFaceFamily.GetGlyphTypeface(canonicalStyle, canonicalWeight, canonicalStretch);
            }
            else if (nullFont)
            {
                glyphTypeface = fontFaceFamily.GetGlyphTypeface(canonicalStyle, canonicalWeight, canonicalStretch);

                advance   = 0; // by definition, null font always yields missing glyphs for whatever codepoint
                nextValid = unicodeString.Length;
            }
            else
            {
                glyphTypeface = fontFaceFamily.MapGlyphTypeface(
                    canonicalStyle,
                    canonicalWeight,
                    canonicalStretch,
                    unicodeString,
                    digitCulture,
                    ref advance,
                    ref nextValid
                    );
            }

            Invariant.Assert(glyphTypeface != null);

            int cch = unicodeString.Length;

            if (!ignoreMissing && advance > 0)
            {
                cch = advance;
            }

            // Do we need to set firstValidFamily?
            if (firstValidLength <= 0)
            {
                // Either firstValidFamily hasn't been set, or has "expired" (see below). The first valid
                // family is the first existing physical font in the font linking chain. We want to remember
                // it so we can use it to map any unresolved characters.
                firstValidFamily = fontFaceFamily;

                // Set the "expiration date" for firstValidFamily. We know that this is the first physical
                // font for the specified character range, but after that family map lookup may result in
                // a different first physical family.
                firstValidLength = unicodeString.Length;
            }

            // Each time we advance we near the expiration date for firstValidFamily.
            firstValidLength -= advance;


            Debug.Assert(cch > 0);
            scaledTypefaceSpans.SetValue(
                firstCharIndex,
                cch,
                new ScaledShapeTypeface(
                    glyphTypeface,
                    deviceFont,
                    scaleInEm,
                    nullFont
                    )
                );

            return(advance);
        }
 internal override void Reset()
 {
     _stretch = FontStretch.Normal;
 }
 NSFontTraitMask GetStretchTrait(FontStretch stretch)
 {
     switch (stretch) {
     case FontStretch.Condensed:
     case FontStretch.ExtraCondensed:
     case FontStretch.SemiCondensed:
         return NSFontTraitMask.Condensed;
     case FontStretch.Normal:
         return default (NSFontTraitMask);
     default:
         return NSFontTraitMask.Expanded;
     }
 }
Example #40
0
			public Builder RestoreState()
			{
				Contract.Ensures(Contract.Result<Builder>() != null);

				TextRun activeState = _States.Pop();

				_ActiveTextRange = activeState.TextRange;
				_ActiveCulture = activeState.Culture;
				_ActiveFamily = activeState.Family;
				_ActiveFeatures = activeState.Features;
				_ActivePointSize = activeState.PointSize;
				_ActiveStretch = activeState.Stretch;
				_ActiveStyle = activeState.Style;
				_ActiveWeight = activeState.Weight;
				_ActiveInline = activeState.Inline;
				_ActiveHAlignment = activeState.HAlignment;
				_ActiveVAlignment = activeState.VAlignment;

				return this;
			}
Example #41
0
        /// <summary>
        /// Maps characters to one of the font families in the specified FontFamilyList. This
        /// function differs from MapByFontFamilyList in that it returns as soon as at least
        /// one character is mapped; it does not keep going until it cannot map any more text.
        /// </summary>
        private int MapOnceByFontFamilyList(
            CharacterBufferRange unicodeString,
            CultureInfo culture,
            CultureInfo digitCulture,
            FontFamily[]                        familyList,
            ref PhysicalFontFamily firstValidFamily,
            ref int firstValidLength,
            IDeviceFont deviceFont,
            double scaleInEm,
            int recursionDepth,
            SpanVector scaledTypefaceSpans,
            int firstCharIndex,
            out int nextValid
            )
        {
            Invariant.Assert(familyList != null);

            int advance = 0;

            nextValid = 0;
            CharacterBufferRange mapString        = unicodeString;
            FontStyle            canonicalStyle   = _canonicalStyle;
            FontWeight           canonicalWeight  = _canonicalWeight;
            FontStretch          canonicalStretch = _canonicalStretch;

            // Note: FontFamilyIdentifier limits the number of family names in a single string. We
            // don't want to also limit the number of iterations here because if Typeface.FontFamily
            // has the maximum number of tokens, this should not prevent us from falling back to the
            // FallbackFontFamily (PS # 1148305).

            // Outer loop to loop over the list of FontFamily.
            for (int i = 0; i < familyList.Length; i++)
            {
                // grab the font family identifier and initialize the
                // target family based on whether it is a named font.
                FontFamilyIdentifier fontFamilyIdentifier = familyList[i].FamilyIdentifier;

                CanonicalFontFamilyReference canonicalFamilyReference = null;
                IFontFamily targetFamily;

                if (fontFamilyIdentifier.Count != 0)
                {
                    // Look up font family and face, in the case of multiple canonical families the weight/style/stretch
                    // may not match the typeface map's, since it is created w/ the first canonical family.
                    canonicalFamilyReference = fontFamilyIdentifier[0];
                    targetFamily             = FontFamily.LookupFontFamilyAndFace(canonicalFamilyReference, ref canonicalStyle, ref canonicalWeight, ref canonicalStretch);
                }
                else
                {
                    targetFamily = familyList[i].FirstFontFamily;
                }

                int familyNameIndex = 0;

                // Inner loop to loop over all name tokens of a FontFamily.
                for (;;)
                {
                    if (targetFamily != null)
                    {
                        advance = MapByFontFamily(
                            mapString,
                            culture,
                            digitCulture,
                            targetFamily,
                            canonicalFamilyReference,
                            canonicalStyle,
                            canonicalWeight,
                            canonicalStretch,
                            ref firstValidFamily,
                            ref firstValidLength,
                            deviceFont,
                            scaleInEm,
                            recursionDepth,
                            scaledTypefaceSpans,
                            firstCharIndex,
                            out nextValid
                            );

                        if (nextValid < mapString.Length)
                        {
                            // only strings before the smallest invalid needs to be mapped since
                            // string beyond smallest invalid can already be mapped to a higher priority font.
                            mapString = new CharacterBufferRange(
                                unicodeString.CharacterBuffer,
                                unicodeString.OffsetToFirstChar,
                                nextValid
                                );
                        }

                        if (advance > 0)
                        {
                            // found the family that shapes this string. We terminate both the
                            // inner and outer loops.
                            i = familyList.Length;
                            break;
                        }
                    }
                    else
                    {
                        // By definition null target does not map any of the input.
                        nextValid = mapString.Length;
                    }

                    if (++familyNameIndex < fontFamilyIdentifier.Count)
                    {
                        // Get the next canonical family name and target family.
                        canonicalFamilyReference = fontFamilyIdentifier[familyNameIndex];
                        targetFamily             = FontFamily.LookupFontFamilyAndFace(canonicalFamilyReference, ref canonicalStyle, ref canonicalWeight, ref canonicalStretch);
                    }
                    else
                    {
                        // Unnamed FontFamily or no more family names in this FontFamily.
                        break;
                    }
                }
            }

            nextValid = mapString.Length;
            return(advance);
        }
Example #42
0
			internal void Reset()
			{
				_Runs.Clear();
				_States.Clear();

				_Alignment = Alignment.Stretch;
				_Indentation = DefaultIndentation;
				_Leading = DefaultLeading;
				_Spacing = DefaultSpacing;
				_Tracking = DefaultTracking;

				_Text.Clear();

				_ActiveCulture = DefaultCulture;
				_ActiveFamily = DefaultFamily;
				_ActivePointSize = DefaultPointSize;
				_ActiveHAlignment = Alignment.Stretch;
				_ActiveVAlignment = Alignment.Stretch;
				_ActiveInline = Size.Empty;
				_ActiveTextRange = IndexedRange.Empty;
				_ActiveStretch = FontStretch.Regular;
				_ActiveStyle = FontStyle.Regular;
				_ActiveWeight = FontWeight.Regular;
				_ActiveFeatures = null;
			}
		public DrawableFont(String family, FontStyleType style, FontWeight weight, FontStretch stretch)
			: base(AssemblyHelper.CreateInstance(Types.DrawableFont, new Type[] {typeof(String), Types.FontStyleType, Types.FontWeight, Types.FontStretch}, family, style, weight, stretch))
		{
		}
Example #44
0
 /// <summary>
 /// Creates a new font. Returns null if the font family is not available in the system
 /// </summary>
 /// <param name="fontName">Font family name</param>
 /// <param name="size">Size in points</param>
 /// <param name="style">Style</param>
 /// <param name="weight">Weight</param>
 /// <param name="stretch">Stretch</param>
 public abstract object Create(string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch);
Example #45
0
 public override object Create(string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     if (Platform.IsMac && fontName == ".AppleSystemUIFont")
         fontName = "-apple-system-font";
     return FontDescription.FromString (fontName + ", " + style + " " + weight + " " + stretch + " " + size.ToString (CultureInfo.InvariantCulture));
 }
Example #46
0
        public object SetStretch(object handle, FontStretch stretch)
        {
            NSFont f = (NSFont) handle;
            NSFontSymbolicTraits traits = f.FontDescriptor.SymbolicTraits;
            if (stretch < FontStretch.Normal) {
                traits |= NSFontSymbolicTraits.CondensedTrait;
                traits &= ~NSFontSymbolicTraits.ExpandedTrait;
            }
            else if (stretch > FontStretch.Normal) {
                traits |= NSFontSymbolicTraits.ExpandedTrait;
                traits &= ~NSFontSymbolicTraits.CondensedTrait;
            }
            else {
                traits &= ~NSFontSymbolicTraits.ExpandedTrait;
                traits &= ~NSFontSymbolicTraits.CondensedTrait;
            }

            return NSFont.FromDescription (f.FontDescriptor.FontDescriptorWithSymbolicTraits (traits), f.FontDescriptor.Matrix);
        }
Example #47
0
 public Font WithStretch(FontStretch stretch)
 {
     return(new Font(handler.SetStretch(Backend, stretch), ToolkitEngine));
 }
Example #48
0
 public virtual FontStretch GetFontStretch()
 => FontStretch.FromOpenTypeStretch(5);
Example #49
0
 public Typeface(string typefaceName, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal, FontStretch stretch = FontStretch.Normal)
     : this(new FontFamily(typefaceName), style, weight, stretch)
 {
     //
 }
Example #50
0
 public Font(string family, double size, FontWeight weight = FontWeight.Normal, FontStyle style = FontStyle.Normal, FontStretch stretch = FontStretch.Normal)
 {
     Family  = family;
     Size    = size;
     Weight  = weight;
     Style   = style;
     Stretch = stretch;
 }
Example #51
0
			public Builder ResetState()
			{
				Contract.Ensures(Contract.Result<Builder>() != null);

				_ActiveTextRange = IndexedRange.Empty;
				_ActiveCulture = DefaultCulture;
				_ActiveFamily = DefaultFamily;
				_ActiveFeatures = null;
				_ActivePointSize = DefaultPointSize;
				_ActiveStretch = FontStretch.Regular;
				_ActiveStyle = FontStyle.Regular;
				_ActiveWeight = FontWeight.Regular;
				_ActiveInline = Size.Empty;
				_ActiveHAlignment = Alignment.Stretch;
				_ActiveVAlignment = Alignment.Stretch;

				return this;
			}
Example #52
0
        public bool TryMatchCharacter(int codepoint, FontStyle fontStyle,
                                      FontWeight fontWeight, FontStretch fontStretch,
                                      FontFamily fontFamily, CultureInfo culture, out Typeface fontKey)
        {
            SKFontStyle skFontStyle;

            switch (fontWeight)
            {
            case FontWeight.Normal when fontStyle == FontStyle.Normal && fontStretch == FontStretch.Normal:
                skFontStyle = SKFontStyle.Normal;
                break;

            case FontWeight.Normal when fontStyle == FontStyle.Italic && fontStretch == FontStretch.Normal:
                skFontStyle = SKFontStyle.Italic;
                break;

            case FontWeight.Bold when fontStyle == FontStyle.Normal && fontStretch == FontStretch.Normal:
                skFontStyle = SKFontStyle.Bold;
                break;

            case FontWeight.Bold when fontStyle == FontStyle.Italic && fontStretch == FontStretch.Normal:
                skFontStyle = SKFontStyle.BoldItalic;
                break;

            default:
                skFontStyle = new SKFontStyle((SKFontStyleWeight)fontWeight, (SKFontStyleWidth)fontStretch, (SKFontStyleSlant)fontStyle);
                break;
            }

            if (culture == null)
            {
                culture = CultureInfo.CurrentUICulture;
            }

            if (t_languageTagBuffer == null)
            {
                t_languageTagBuffer = new string[2];
            }

            t_languageTagBuffer[0] = culture.TwoLetterISOLanguageName;
            t_languageTagBuffer[1] = culture.ThreeLetterISOLanguageName;

            if (fontFamily != null && fontFamily.FamilyNames.HasFallbacks)
            {
                var familyNames = fontFamily.FamilyNames;

                for (var i = 1; i < familyNames.Count; i++)
                {
                    var skTypeface =
                        _skFontManager.MatchCharacter(familyNames[i], skFontStyle, t_languageTagBuffer, codepoint);

                    if (skTypeface == null)
                    {
                        continue;
                    }

                    fontKey = new Typeface(skTypeface.FamilyName, fontStyle, fontWeight, fontStretch);

                    return(true);
                }
            }
            else
            {
                var skTypeface = _skFontManager.MatchCharacter(null, skFontStyle, t_languageTagBuffer, codepoint);

                if (skTypeface != null)
                {
                    fontKey = new Typeface(skTypeface.FamilyName, fontStyle, fontWeight, fontStretch);

                    return(true);
                }
            }

            fontKey = default;

            return(false);
        }
Example #53
0
			public Builder WithStretch(FontStretch stretch)
			{
				Contract.Ensures(Contract.Result<Builder>() != null);

				_ActiveStretch = stretch;

				return this;
			}
Example #54
0
 public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch,
                               FontFamily fontFamily, CultureInfo culture, out Typeface typeface)
 {
     typeface = new Typeface("Arial", fontStyle, fontWeight, fontStretch);
     return(true);
 }
Example #55
0
 public object SetStretch(object handle, FontStretch stretch)
 {
     FontDescription fd = (FontDescription) handle;
     fd = fd.Copy ();
     fd.Stretch = (Pango.Stretch)(int)stretch;
     return fd;
 }
Example #56
0
 public FontStretchAttribute(FontStretch stretch) => Handle = Libui.uiNewStretchAttribute(stretch);
Example #57
0
 public abstract object SetStretch(object handle, FontStretch stretch);
Example #58
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Font"/> structure
 /// </summary>
 /// <param name="family">The specified font family name.</param>
 /// <param name="size">The size of the font.</param>
 /// <param name="weight">The font weight.</param>
 /// <param name="style">The style of the font.</param>
 /// <param name="stretch">The width of the font.</param>
 public Font(string family, double size, FontWeight weight = FontWeight.Normal, FontStyle style = FontStyle.Normal, FontStretch stretch = FontStretch.Normal) => Native = new Libui.uiFontDescriptor()
Example #59
0
 public object Create(string fontName, double size, FontSizeUnit sizeUnit, FontStyle style, FontWeight weight, FontStretch stretch)
 {
     object o  = NSFont.FromFontName (fontName, (float)size);
     return o;
 }
Example #60
0
        static Geometry BuildGlyphRun(TextStyle textStyle, string text, double x, double y, ref double totalwidth)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(new GeometryGroup());
            }

            if (dpiX == 0 || dpiY == 0)
            {
                var sysPara      = typeof(SystemParameters);
                var dpiXProperty = sysPara.GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static);
                var dpiYProperty = sysPara.GetProperty("Dpi", BindingFlags.NonPublic | BindingFlags.Static);

                dpiX = (int)dpiXProperty.GetValue(null, null);
                dpiY = (int)dpiYProperty.GetValue(null, null);
            }
            double   fontSize = textStyle.FontSize;
            GlyphRun glyphs   = null;
            Typeface font     = new Typeface(new FontFamily(textStyle.FontFamily),
                                             textStyle.Fontstyle,
                                             textStyle.Fontweight,
                                             FontStretch.FromOpenTypeStretch(9),
                                             new FontFamily("Arial Unicode MS"));
            GlyphTypeface glyphFace;
            double        baseline = y;

            if (font.TryGetGlyphTypeface(out glyphFace))
            {
#if DOTNET40 || DOTNET45 || DOTNET46
                glyphs = new GlyphRun();
#else
                var dpiScale = new DpiScale(dpiX, dpiY);

                glyphs = new GlyphRun((float)dpiScale.PixelsPerDip);
#endif
                ((System.ComponentModel.ISupportInitialize)glyphs).BeginInit();
                glyphs.GlyphTypeface       = glyphFace;
                glyphs.FontRenderingEmSize = fontSize;
                List <char>   textChars     = new List <char>();
                List <ushort> glyphIndices  = new List <ushort>();
                List <double> advanceWidths = new List <double>();
                totalwidth = 0;
                char[] charsToSkip = new char[] { '\t', '\r', '\n' };
                for (int i = 0; i < text.Length; ++i)
                {
                    char textchar  = text[i];
                    int  codepoint = textchar;
                    //if (charsToSkip.Any<char>(item => item == codepoint))
                    //	continue;
                    ushort glyphIndex;
                    if (glyphFace.CharacterToGlyphMap.TryGetValue(codepoint, out glyphIndex) == false)
                    {
                        continue;
                    }
                    textChars.Add(textchar);
                    double glyphWidth = glyphFace.AdvanceWidths[glyphIndex];
                    glyphIndices.Add(glyphIndex);
                    advanceWidths.Add(glyphWidth * fontSize + textStyle.LetterSpacing);
                    if (char.IsWhiteSpace(textchar))
                    {
                        advanceWidths[advanceWidths.Count - 1] += textStyle.WordSpacing;
                    }
                    totalwidth += advanceWidths[advanceWidths.Count - 1];
                }
                glyphs.Characters    = textChars.ToArray();
                glyphs.GlyphIndices  = glyphIndices.ToArray();
                glyphs.AdvanceWidths = advanceWidths.ToArray();

                // calculate text alignment
                double alignmentoffset = 0;
                if (textStyle.TextAlignment == TextAlignment.Center)
                {
                    alignmentoffset = totalwidth / 2;
                }
                if (textStyle.TextAlignment == TextAlignment.Right)
                {
                    alignmentoffset = totalwidth;
                }

                baseline = y;
                glyphs.BaselineOrigin = new Point(x - alignmentoffset, baseline);
                ((System.ComponentModel.ISupportInitialize)glyphs).EndInit();
            }
            else
            {
                return(new GeometryGroup());
            }

            // add text decoration to geometry
            GeometryGroup gp = new GeometryGroup();
            gp.Children.Add(glyphs.BuildGeometry());
            if (textStyle.TextDecoration != null)
            {
                double decorationPos       = 0;
                double decorationThickness = 0;
                if (textStyle.TextDecoration[0].Location == TextDecorationLocation.Strikethrough)
                {
                    decorationPos       = baseline - (font.StrikethroughPosition * fontSize);
                    decorationThickness = font.StrikethroughThickness * fontSize;
                }
                if (textStyle.TextDecoration[0].Location == TextDecorationLocation.Underline)
                {
                    decorationPos       = baseline - (font.UnderlinePosition * fontSize);
                    decorationThickness = font.UnderlineThickness * fontSize;
                }
                if (textStyle.TextDecoration[0].Location == TextDecorationLocation.OverLine)
                {
                    decorationPos       = baseline - fontSize;
                    decorationThickness = font.StrikethroughThickness * fontSize;
                }
                Rect bounds = new Rect(gp.Bounds.Left, decorationPos, gp.Bounds.Width, decorationThickness);
                gp.Children.Add(new RectangleGeometry(bounds));
            }
            return(gp);
        }