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;
        }
 public void AdjustGlyphInfo(ref Glyph glyphInfo)
 {
     return;
 }
Beispiel #3
0
        public static bool CreateGlyph(uint charCode, out uint charIndex, out Glyph glyph, out Image image)
        {
            glyph = new Glyph();
            charIndex = FT.FT_Get_Char_Index(ftFace, charCode);
            image = null;
            if (charIndex == 0) return false;

            int error = FT.FT_Load_Glyph(ftFace, charIndex, FT.FT_LOAD_DEFAULT| FT.FT_LOAD_NO_HINTING);
            if (error != 0) return false;

            FT_FaceRec* faceRect = (FT_FaceRec*)ftFace.ToPointer();
            FT_GlyphSlotRec* ft_glyph = (FT_GlyphSlotRec*)faceRect->glyph.ToPointer();

            glyph.Code = charCode;

            glyph.HorizontalAdvance = (double)ft_glyph->metrics.horiAdvance / 64.0d;
            glyph.HorizontalBearingX = (double)ft_glyph->metrics.horiBearingX / 64.0d;
            glyph.HorizontalBearingY = (double)ft_glyph->metrics.horiBearingY / 64.0d;
            glyph.VerticalAdvance = (double)ft_glyph->metrics.vertAdvance / 64.0d;
            glyph.VerticalBearingX =(double)ft_glyph->metrics.vertBearingX / 64.0d;
            glyph.VerticalBearingY = (double)ft_glyph->metrics.vertBearingY / 64.0d;

            Painter.AdjustGlyphInfo(ref glyph);
            FT_Outline outline;
            GraphicsPath path = new GraphicsPath(FillMode.Alternate);

            if(ft_glyph->format == FT_Glyph_Format.FT_GLYPH_FORMAT_OUTLINE) {
                outline = ft_glyph->outline;
            } else
                return false;

            PointF[] points = new PointF[outline.n_points];
            TagFlag[] tags = new TagFlag[outline.n_points];
            int* ptr = (int*)outline.points.ToPointer();
            byte* bptr = (byte*)outline.tags.ToPointer();

            for(int i =0; i<outline.n_points; i++) {
                points[i] = new PointF();
                points[i].X = (int)*ptr;
                points[i].X /=64;
                ptr++;

                points[i].Y = (int)(*ptr);
                points[i].Y /= - 64;
                ptr++;

                tags[i] = (TagFlag)(*bptr);
                bptr++;
            }
            short[] contours = new short[outline.n_contours];
            short* sptr = (short*)outline.contours.ToPointer();
            for(int i = 0; i<outline.n_contours; i++, sptr++) {
                contours[i] = *sptr;
            }

            for( int i = 0; i<contours.Length; i++) {
                int begin;
                if(i == 0)
                    begin = 0;
                else
                    begin = contours[i - 1]+1;

                for(int j = begin; j<=contours[i]; j++) {
                    int p1 = j;
                    int p2 = (j + 1 > contours[i]) ? j + 1 + begin - contours[i] -1: j + 1;

                    if ((tags[j] & TagFlag.OnCurve) == 0)
                        continue;

                    if ((tags[p2] & TagFlag.OnCurve) != 0) {
                        path.AddLine(points[p1], points[p2]);
                    }

                    else {
                        List<PointF> pointList = new List<PointF>();
                        pointList.Add(points[p1]);
                        int p = p2;
                        while ((tags[p] & TagFlag.OnCurve) == 0) {
                            pointList.Add(points[p]);
                            p++;
                            if (p > contours[i])
                                p = begin;
                        }

                        pointList.Add(points[p]);

                        AddBezierSpline(pointList.ToArray(), path);
                    }
                }
                path.CloseFigure();
            }
            RectangleF bounds = path.GetBounds();

            bounds.Width = (float) Math.Ceiling(bounds.Width);
            bounds.Height = (float) Math.Ceiling(bounds.Height);

            if(bounds.Width != 0 || bounds.Height != 0) {
                Bitmap output = new Bitmap((int)bounds.Width, (int)bounds.Height);
                Graphics g = Graphics.FromImage(output);

                g.SmoothingMode = antialias? SmoothingMode.AntiAlias:SmoothingMode.None;

                g.TranslateTransform(-bounds.X, -bounds.Y);

                if(painter != null) {
                    painter.PaintPath(g, path);
                }

                path.Dispose();
                g.Dispose();
                image = TrimImage(output);
            }

            if(image != null) {
                glyph.Width = (uint) image.Width;
                glyph.Height = (uint) image.Height;
            } else {
                glyph.Width = 0;
                glyph.Height = 0;
            }

            return true;
        }
        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;
        }