void BtnPreviewUpdateClick(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(previewChar.Text) ||
                String.IsNullOrEmpty(txtInput.Text))
                return;

                this.Cursor = Cursors.WaitCursor;

                Glyph[] glyphs = new Glyph[previewChar.Text.Length];
                Image[] images = new Image[previewChar.Text.Length];
                uint[] indexes = new uint[previewChar.Text.Length];

                uint charHeight = Convert.ToUInt32(numSize.Value);

                GlyphRenderer.NewFace(txtInput.Text, charHeight);

                for (int i = 0; i < previewChar.Text.Length; i++)
                {
                    GlyphRenderer.CreateGlyph(Convert.ToUInt32(previewChar.Text[i]), out indexes[i], out glyphs[i], out images[i]);
                }

                Dictionary<KerningInfoKey, KerningInfo> kerningMap = new Dictionary<KerningInfoKey, KerningInfo>();
                for (int i1 = 0; i1 < indexes.Length; i1++)
                {
                    for (int i2 = 0; i2 < indexes.Length; i2++)
                    {
                        KerningInfo info = GlyphRenderer.CreateKerningInfo(indexes[i1], indexes[i2]);

                        if (info.HorizontalAdjust == 0 && info.VerticalAdjust == 0)
                            continue;

                        info.LeftChar = Convert.ToUInt32(previewChar.Text[i1]);
                        info.RightChar = Convert.ToUInt32(previewChar.Text[i2]);

                        KerningInfoKey key = new KerningInfoKey(info);

                        kerningMap[key] = info;
                    }
                }

                Image image = CreatePreviewImage(glyphs, images, kerningMap);//,

                Image oldImage = null;
                if (previewBox.Image != null)
                    oldImage = previewBox.Image;

                if(image != null)
                    previewBox.Image = image;

                if (oldImage != null)
                    oldImage.Dispose();

                GlyphRenderer.DoneFace();
                Cursor = Cursors.Default;
        }
        Image CreatePreviewImage(Glyph[] glyphs, Image[] images, 
            Dictionary<KerningInfoKey, KerningInfo> kerningMap)
        {
            int width = 0;
            for (int i = 0; i < glyphs.Length; i++)
            {
                width += (int)glyphs[i].HorizontalAdvance;
            }
            int height = previewBox.Height*3;

            if (height == 0)
                return null;
            Image image = new Bitmap( width>previewBox.Width ? width: previewBox.Width,
                                      height);
            Graphics g = Graphics.FromImage(image);
            Point origin = new Point(0, height/2);
            Pen pen = new Pen(Color.BlueViolet);
            pen.DashStyle = DashStyle.Dash;

            g.DrawLine(pen, origin, new Point(width, origin.Y));
            for (int i = 0; i < glyphs.Length; i++)
            {
                int x = origin.X, y = origin.Y;

                if (i != 0)
                {
                    KerningInfoKey key = new KerningInfoKey((uint)previewChar.Text[i - 1],
                        (uint)previewChar.Text[i]);
                    if (kerningMap.ContainsKey(key))
                    {
                        x += (int)kerningMap[key].HorizontalAdjust;
                        y -= (int)kerningMap[key].VerticalAdjust;
                        origin.X += (int)kerningMap[key].HorizontalAdjust;
                    }
                }
                x += (int)glyphs[i].HorizontalBearingX;
                y -= (int)glyphs[i].HorizontalBearingY;
                origin.X += (int)glyphs[i].HorizontalAdvance;

                if (images[i] == null)
                    continue;
                g.DrawImage(images[i], x, y);
                images[i].Dispose();
            }
            return image;
        }