Beispiel #1
0
        /// <summary>
        /// Function to retrieve the built in kerning pairs and advancement information for the font.
        /// </summary>
        /// <param name="graphics">The GDI graphics interface.</param>
        /// <param name="font">The GDI font.</param>
        /// <param name="allowedCharacters">The list of characters available to the font.</param>
        private Dictionary <char, ABC> GetKerningInformation(System.Drawing.Graphics graphics, Font font, IList <char> allowedCharacters)
        {
            Dictionary <char, ABC> advancementInfo;

            KerningPairs.Clear();

            IntPtr prevGdiHandle = Win32API.SetActiveFont(graphics, font);

            try
            {
                advancementInfo = Win32API.GetCharABCWidths(allowedCharacters[0], allowedCharacters[allowedCharacters.Count - 1]);

                if (!Info.UseKerningPairs)
                {
                    return(advancementInfo);
                }

                IList <KERNINGPAIR> kerningPairs = Win32API.GetKerningPairs();

                foreach (KERNINGPAIR pair in kerningPairs.Where(item => item.KernAmount != 0))
                {
                    var newPair = new GorgonKerningPair(Convert.ToChar(pair.First), Convert.ToChar(pair.Second));

                    if ((!allowedCharacters.Contains(newPair.LeftCharacter)) ||
                        (!allowedCharacters.Contains(newPair.RightCharacter)))
                    {
                        continue;
                    }

                    KerningPairs[newPair] = pair.KernAmount;
                }
            }
            finally
            {
                Win32API.RestoreActiveObject(prevGdiHandle);
            }

            return(advancementInfo);
        }
Beispiel #2
0
        /// <summary>
        /// Function to measure the width of an individual line of text.
        /// </summary>
        /// <param name="line">The line to measure.</param>
        /// <param name="useOutline"><b>true</b> to use the font outline, <b>false</b> to disregard it.</param>
        /// <returns>The width of the line.</returns>
        private float GetLineWidth(string line, bool useOutline)
        {
            float size      = 0;
            bool  firstChar = true;

            if (!Glyphs.TryGetValue(Info.DefaultCharacter, out GorgonGlyph defaultGlyph))
            {
                throw new GorgonException(GorgonResult.CannotEnumerate, string.Format(Resources.GORGFX_ERR_FONT_DEFAULT_CHAR_NOT_VALID, Info.DefaultCharacter));
            }

            for (int i = 0; i < line.Length; i++)
            {
                char character = line[i];

                if (!Glyphs.TryGetValue(character, out GorgonGlyph glyph))
                {
                    glyph = defaultGlyph;
                }

                // Skip out on carriage returns and newlines.
                if ((character == '\r') ||
                    (character == '\n'))
                {
                    continue;
                }

                // Whitespace will use the glyph width.
                if (char.IsWhiteSpace(character))
                {
                    size += glyph.Advance;
                    continue;
                }

                // Include the initial offset.
                if (firstChar)
                {
                    size     += (useOutline && glyph.OutlineCoordinates.Width > 0) ? glyph.OutlineOffset.X : glyph.Offset.X;
                    firstChar = false;
                }

                size += glyph.Advance;

                if (!Info.UseKerningPairs)
                {
                    continue;
                }

                if ((i == line.Length - 1) ||
                    (KerningPairs.Count == 0))
                {
                    continue;
                }

                var kerning = new GorgonKerningPair(character, line[i + 1]);

                if (KerningPairs.TryGetValue(kerning, out int kernAmount))
                {
                    size += kernAmount;
                }
            }

            return(size);
        }