Exemple #1
0
        public Vec2i GetKerning(char a, char b)
        {
            FTVector26Dot6 temp    = font.GetKerning(a, b, KerningMode.Default);
            Vec2i          kerning = new Vec2i(temp.X.Value, temp.Y.Value);

            return(kerning);
        }
        private void getKernWidthHeight(Face face, FontInfo info, out int width, out int maxHeight, out int firstAdjust)
        {
            width       = 0;
            maxHeight   = 0;
            firstAdjust = 0;

            for (int i = 0; i < characters.Length; i++)
            {
                char character1 = characters[i];
                uint index1     = face.GetCharIndex(character1);

                face.LoadGlyph(index1, LoadFlags.Default, LoadTarget.Normal);
                GlyphMetrics metrics = face.Glyph.Metrics;

                int yoffset = metrics.VerticalAdvance.ToInt32() - metrics.HorizontalBearingY.ToInt32();
                int nheight = yoffset + metrics.Height.ToInt32();
                int height  = metrics.Height.ToInt32();
                if (height > maxHeight)
                {
                    maxHeight   = height;                   //nheight;
                    firstAdjust = yoffset;
                }

                for (int j = 0; j < characters.Length; j++)
                {
                    char character2 = characters[j];
                    uint index2     = face.GetCharIndex(character2);

                    FTVector26Dot6 kern  = face.GetKerning(index1, index2, KerningMode.Default);
                    int            kernX = kern.X.ToInt32();
                    int            kernY = kern.Y.ToInt32();
                    if (kernX != 0 || kernY != 0)
                    {
                        info.addKerning(new KerningInfo(character1, character2, kernX, kernY));
                    }
                }

                if (i + 1 == characters.Length)
                {
                    width += metrics.Width.ToInt32() + metrics.HorizontalBearingX.ToInt32() + padX;
                }
                else
                {
                    width += metrics.HorizontalAdvance.ToInt32() + padX;
                }
            }
        }
Exemple #3
0
		/// <summary>
		/// Convert a given glyph object to a bitmap glyph object.
		/// </summary>
		/// <remarks><para>
		/// This function does nothing if the glyph format isn't scalable.
		/// </para><para>
		/// The glyph image is translated with the ‘origin’ vector before rendering.
		/// </para><para>
		/// The first parameter is a pointer to an <see cref="Glyph"/> handle, that will be replaced by this function
		/// (with newly allocated data). Typically, you would use (omitting error handling):
		/// </para><para>
		/// --sample code ommitted--
		/// </para></remarks>
		/// <param name="renderMode">An enumeration that describes how the data is rendered.</param>
		/// <param name="origin">
		/// A pointer to a vector used to translate the glyph image before rendering. Can be 0 (if no translation). The
		/// origin is expressed in 26.6 pixels.
		/// </param>
		/// <param name="destroy">
		/// A boolean that indicates that the original glyph image should be destroyed by this function. It is never
		/// destroyed in case of error.
		/// </param>
		public void ToBitmap(RenderMode renderMode, FTVector26Dot6 origin, bool destroy)
		{
			if (disposed)
				throw new ObjectDisposedException("Glyph", "Cannot access a disposed object.");

			IntPtr glyphRef = Reference;
			Error err = FT.FT_Glyph_To_Bitmap(ref glyphRef, renderMode, ref origin, destroy);

			Reference = glyphRef;

			if (err != Error.Ok)
				throw new FreeTypeException(err);
		}
Exemple #4
0
 internal static extern Error FT_Glyph_To_Bitmap(ref IntPtr the_glyph, RenderMode render_mode, ref FTVector26Dot6 origin, [MarshalAs(UnmanagedType.U1)] bool destroy);
Exemple #5
0
 internal static extern Error FT_Get_Kerning(IntPtr face, uint left_glyph, uint right_glyph, uint kern_mode, out FTVector26Dot6 akerning);
Exemple #6
0
        public void ExportFont(string outputPath)
        {
            // should this be user input?
            int padX = 5;
            int padY = 5;

            int   atlas = 0;
            float posX  = 0;
            float posY  = 0;

            List <Bitmap> bitmaps = new List <Bitmap>();
            Dictionary <string, List <Info> > infos = new Dictionary <string, List <Info> >();

            Bitmap   bitmap   = new Bitmap(maxWidth, maxHeight, PixelFormat.Format32bppArgb);
            Graphics graphics = Graphics.FromImage(bitmap);

            graphics.Clear(Color.Transparent);

            string output = "module.font = {\n\tinformation = {\n";

            output += "\t\tfamily = \"" + family + "\";\n";
            output += "\t\tstyles = {" + string.Join(", ", getStyles()) + "};\n";
            output += "\t\tsizes = {" + string.Join(", ", sizes) + "};\n";
            output += "\t\tuseEnums = " + useEnums() + ";\n\t};\n";

            output += "\tstyles = {\n";

            foreach (Face face in faces)
            {
                infos[face.StyleName] = new List <Info>();
                output += "\t\t[\"" + face.StyleName + "\"] = {\n";

                foreach (int size in sizes)
                {
                    Info info = new Info(face.StyleName, size);

                    int lineAdvance = 0;
                    int firstAdjust = 0;

                    float width      = 0;
                    float height     = 0;
                    float lineHeight = 0;

                    face.SetCharSize(size * 96 / 72, 0, 96, 96);

                    for (int i = 0; i < characters.Length; i++)
                    {
                        char c     = characters[i];
                        uint index = face.GetCharIndex(c);
                        face.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal);

                        width += (float)face.Glyph.Metrics.HorizontalAdvance;

                        if (face.Glyph.Metrics.Height > lineHeight)
                        {
                            // Get extra space and subtract it from first line draw?
                            firstAdjust = face.Glyph.Metrics.VerticalAdvance.ToInt32() - face.Glyph.Metrics.HorizontalBearingY.ToInt32();
                            lineHeight  = (float)face.Glyph.Metrics.Height;
                        }

                        for (int j = 0; j < characters.Length; j++)
                        {
                            char k      = characters[j];
                            uint index2 = face.GetCharIndex(k);

                            FTVector26Dot6 kern  = face.GetKerning(index, index2, KerningMode.Default);
                            int            kernx = kern.X.ToInt32();
                            int            kerny = kern.Y.ToInt32();

                            if (kernx != 0 | kerny != 0)
                            {
                                info.addKerning(c, new Info.kerningInfo(k, kernx, kerny));
                            }
                        }
                    }

                    if (width > maxWidth)
                    {
                        int overlaps = (int)Math.Truncate(width / maxWidth);
                        width  = maxWidth;
                        height = ((overlaps + 1) * (lineHeight + padY));
                    }
                    else
                    {
                        width  = maxWidth;
                        height = lineHeight + padY;
                    }

                    face.SetUnpatentedHinting(true);

                    for (int i = 0; i < characters.Length; i++)
                    {
                        char c     = characters[i];
                        uint index = face.GetCharIndex(c);
                        face.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal);
                        face.Glyph.RenderGlyph(RenderMode.Normal);

                        if (c == ' ')
                        {
                            posX += (float)face.Glyph.Metrics.HorizontalAdvance + (float)padX;
                            info.addCharacter(c, new Info.characterInfo(c, face.Glyph.Metrics.HorizontalAdvance.ToInt32(), 0, 0, 0, 0, 0, atlas));
                            continue;
                        }

                        if (posX + face.Glyph.Metrics.Width + face.Glyph.BitmapLeft + padX > width)
                        {
                            posX  = 0;
                            posY += lineHeight + padY;
                        }

                        if (posY > (maxHeight - (lineHeight + padY)))
                        {
                            bitmaps.Add(bitmap);
                            bitmap   = new Bitmap(maxWidth, maxHeight, PixelFormat.Format32bppArgb);
                            graphics = Graphics.FromImage(bitmap);
                            graphics.Clear(Color.Transparent);

                            posX   = 0;
                            posY   = 0;
                            atlas += 1;
                        }

                        int xadvance  = face.Glyph.Metrics.HorizontalAdvance.ToInt32();
                        int imgWidth  = face.Glyph.Metrics.Width.ToInt32();
                        int imgHeight = face.Glyph.Metrics.Height.ToInt32();
                        int imgX      = (int)posX;
                        int imgY      = (int)posY;
                        int yoffset   = face.Glyph.Metrics.VerticalAdvance.ToInt32() - face.Glyph.Metrics.HorizontalBearingY.ToInt32();

                        // some fonts that might be missing characters will leave open spaces because their bitmap is empty.
                        if (face.Glyph.Bitmap.Width > 0)
                        {
                            FTBitmap ftbmp = face.Glyph.Bitmap;
                            Bitmap   copy  = ftbmp.ToGdipBitmap(Color.White);
                            graphics.DrawImageUnscaled(copy, imgX, imgY);
                        }

                        info.addCharacter(c, new Info.characterInfo(c, xadvance, imgX, imgY, yoffset, imgWidth, imgHeight, atlas));

                        posX       += (float)imgWidth + (float)padX;
                        lineAdvance = face.Glyph.Metrics.VerticalAdvance.ToInt32();
                    }

                    posX  = 0;
                    posY += lineHeight + padY;

                    info.lineHeight  = lineAdvance;
                    info.firstAdjust = firstAdjust;

                    infos[face.StyleName].Add(info);
                    output += info.buildLuaString("\t\t\t") + "\n";
                }
                output += "\t\t};\n";
            }
            output += "\t};\n};\n";

            bitmaps.Add(bitmap);
            graphics.Dispose();

            // create images
            int count = 0;

            foreach (Bitmap bmp in bitmaps)
            {
                count += 1;
                bmp.Save(outputPath + "\\" + family + "_" + count + ".png");
            }

            string header = "--[[\n\t@Font " + family + "\n";

            header += "\t@Sizes {" + string.Join(", ", sizes) + "}\n";
            header += "\t@Author N/A\n";
            header += "\t@Link N/A\n--]]\n\n";

            header += "local module = {};\n\n";
            header += "module.atlases = {\n";

            for (int i = 1; i <= count; i++)
            {
                header += "\t[" + i + "] = \"rbxassetid://\";\n";
            }

            header += "};\n\n" + output;
            header += "\n\nreturn module;";


            File.WriteAllText(outputPath + "\\" + family + ".lua", header);
        }