Пример #1
0
        // Rasterizes a single character glyph.
        static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
        {
            string characterString = character.ToString();

            uint glyphIndex = face.GetCharIndex(character);

            face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            // Measure the size of this character.
            var width  = (int)face.Glyph.Advance.X >> 6;
            var height = (int)face.Glyph.Metrics.Height >> 6;

            SizeF size = new SizeF(width, height);

            int characterWidth  = (int)Math.Ceiling(size.Width);
            int characterHeight = (int)Math.Ceiling(size.Height);

            // Pad to make sure we capture any overhangs (negative ABC spacing, etc.)
            int padWidth  = characterWidth;
            int padHeight = characterHeight / 2;

            int bitmapWidth  = characterWidth + padWidth * 2;
            int bitmapHeight = characterHeight + padHeight * 2;

            if (bitmapWidth > MaxGlyphSize || bitmapHeight > MaxGlyphSize)
            {
                throw new Exception("Excessively large glyph won't fit in my lazily implemented fixed size temp surface.");
            }

            // Render the character.
            graphics.Clear(System.Drawing.Color.Black);

            if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows),
                                                  ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

                for (int j = 0; j < gpixelAlphas.Length; j++)
                {
                    int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
                    Marshal.WriteByte(data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
                }

                bitmap.UnlockBits(data);
            }

            // Clone the newly rendered image.
            Bitmap glyphBitmap = null;

            if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
            }
            else
            {
                var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
                var gVA = face.Glyph.Metrics.VerticalAdvance >> 6;

                gHA = gHA > 0 ? gHA : gVA;
                gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new Bitmap(gHA, gVA);
            }

            BitmapUtils.ConvertToGrey(glyphBitmap);

            // not sure about this at all
            var abc = new ABCFloat();

            abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
            abc.B = face.Glyph.Metrics.Width >> 6;
            abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

            // Query its ABC spacing.
            //float? abc = GetCharacterWidth(character, font, graphics);
//			if (glyphBitmap == null)
//				Console.WriteLine("null");


            // Construct the output Glyph object.
            return(new Glyph(character, glyphBitmap)
            {
                XOffset = -padWidth,
                XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
                CharacterWidths = abc
            });
        }
Пример #2
0
        // Rasterizes a single character glyph.
        static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
        {
            uint glyphIndex = face.GetCharIndex(character);

            face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            // Render the character.
            graphics.Clear(System.Drawing.Color.Black);

            if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows),
                                                  ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

                for (int j = 0; j < gpixelAlphas.Length; j++)
                {
                    int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
                    Marshal.WriteByte(data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
                }

                bitmap.UnlockBits(data);
            }

            // Clone the newly rendered image.
            Bitmap glyphBitmap = null;

            if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
            }
            else
            {
                var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
                var gVA = face.Size.Metrics.Height >> 6;

                gHA = gHA > 0 ? gHA : gVA;
                gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new Bitmap(gHA, gVA);
            }

            BitmapUtils.ConvertAlphaToGrey(glyphBitmap);

            // not sure about this at all
            var abc = new ABCFloat();

            abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
            abc.B = face.Glyph.Metrics.Width >> 6;
            abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

            // Construct the output Glyph object.
            return(new Glyph(character, glyphBitmap)
            {
                XOffset = -(face.Glyph.Advance.X >> 6),
                XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
                CharacterWidths = abc
            });
        }