protected void Initialize()
    {
        if (charsDict != null)
            return;

        charsDict = new Dictionary<int, Character>();
        kernHash = new Dictionary<int, Kerning[]>();
        charsSize = new List<float>(16);

        foreach (Character c in characters)
            charsDict.Add(c.code, c);

        foreach (Kerning k in kernings)
        {
            int hash = k.code0 + k.code1;
            Kerning[] kernArray;

            if (kernHash.TryGetValue(hash, out kernArray))
            {
                int len = kernArray.Length;
                Array.Resize<Kerning>(ref kernArray, len + 1);
                kernArray[len] = k;
            }
            else
            {
                kernArray = new Kerning[1];
                kernArray[0] = k;

                kernHash.Add(hash, kernArray);
            }
        }
    }
示例#2
0
	/// <summary>
	/// Add a new kerning entry to the character (or adjust an existing one).
	/// </summary>

	public void SetKerning (int previousChar, int amount)
	{
		if (kerning == null) kerning = new List<Kerning>();

		for (int i = 0; i < kerning.Count; ++i)
		{
			if (kerning[i].previousChar == previousChar)
			{
				Kerning k = kerning[i];
				k.amount = amount;
				kerning[i] = k;
				return;
			}
		}

		Kerning ker = new Kerning();
		ker.previousChar = previousChar;
		ker.amount = amount;
		kerning.Add(ker);
	}
        private void textBoxInput_TextChanged(object sender, EventArgs e)
        {
            textBoxBreakdown.Clear();
            panelOutput.Controls.Clear();

            string regCol = String.Join("|", headersCol);
            string regRow = String.Join("|", headersRow);

            List <string> output = new List <string>();

            foreach (string block in Regex.Matches(textBoxInput.Text, "[^|\\b].*?\\b|.").OfType <Match>().Where(x => x.Value != " ").Select(x => x.Value))
            {
                if (Regex.Matches(block, "\\W").Count > 0)
                {
                    if (block != " ")
                    {
                        output.Add(block);
                    }
                }
                else
                {
                    MatchCollection match = Regex.Matches(block, String.Format("([{0}]\\d?[{1}]\\d?)|([{1}]\\d?[{0}]\\d?)", regCol, regRow));
                    List <string>   l     = match.OfType <Match>().Select(x => x.Value).ToList();
                    output.Add("(" + String.Join("-", l) + ")");

                    ///This whole flowPanel thing might be better done with calculations and drawing straight to the canvas
                    ///It would allow for glyph overlaps but more calcs will be needed for wrapping

                    FlowLayoutPanel flowPanel = new FlowLayoutPanel();
                    //for not foreach because of importance of glyph position

                    for (int i = 0; i < l.Count; i++)
                    {
                        object tag = FormType.Isolated;
                        string fil = String.Format("{0}\\{1}.png", repository, l[i]);

                        if (languageSettings[Property.CharacterForms].Equals(CharacterForms.Multiple))
                        {
                            if (l.Count != 1)
                            {
                                if (i == 0)
                                {
                                    if (File.Exists(String.Format("{0}\\{1}_initial.png", repository, l[i])))
                                    {
                                        fil = String.Format("{0}\\{1}_initial.png", repository, l[i]);
                                        tag = FormType.Initial;
                                    }
                                }
                                else if (i == l.Count - 1)
                                {
                                    if (File.Exists(String.Format("{0}\\{1}_final.png", repository, l[i])))
                                    {
                                        fil = String.Format("{0}\\{1}_final.png", repository, l[i]);
                                        tag = FormType.Final;
                                    }
                                }
                                else
                                {
                                    if (File.Exists(String.Format("{0}\\{1}_medial.png", repository, l[i])))
                                    {
                                        fil = String.Format("{0}\\{1}_medial.png", repository, l[i]);
                                        tag = FormType.Medial;
                                    }
                                }
                            }
                        }

                        if (File.Exists(fil) || (bool)languageSettings[Property.FillBlanks])
                        {
                            Size s = (Size)languageSettings[Property.Sizing];

                            Bitmap im;
                            if (File.Exists(fil))
                            {
                                using (Image image = Image.FromFile(fil))
                                {
                                    im = (Bitmap)image.GetThumbnailImage(500, 500, null, IntPtr.Zero);
                                }
                            }
                            else
                            {
                                im = nullimage;
                            }
                            Size characterSize = (Size)languageSettings[Property.Sizing];

                            //get crop data
                            Kerning k = (Kerning)languageSettings[Property.Kerning];

                            string extender = tag.Equals(FormType.Isolated) ? "" : "_" + tag.ToString().ToLower();
                            string glyph    = l[i] + extender;
                            string line     = languageInfo.Where(x => x.StartsWith("‡" + glyph + ";")).FirstOrDefault();
                            if (line != null && k != Kerning.Monospace)
                            {
                                Rectangle r = GetLetterCropping(line, languageSettings);

                                Bitmap cropped = new Bitmap(r.Width, r.Height);

                                using (Graphics g = Graphics.FromImage(cropped))
                                {
                                    g.DrawImage(im, new Rectangle(0, 0, r.Width, r.Height), r, GraphicsUnit.Pixel);
                                }
                                im = cropped;
                            }
                            im.MakeTransparent(Color.White);
                            Panel p = new Panel()
                            {
                                BackgroundImage = im, BackgroundImageLayout = ImageLayout.Zoom, Size = characterSize, Tag = tag
                            };
                            /// future feature - on hover, highlight original in text box ///

                            if (k != Kerning.Monospace)
                            {
                                FlowDirection f = (FlowDirection)languageSettings[Property.WordDirection];
                                if (f == FlowDirection.LeftToRight || f == FlowDirection.RightToLeft)
                                {
                                    p.Margin = new Padding((int)k / 2, 3, (int)k / 2, 3);
                                }
                                else
                                {
                                    p.Margin = new Padding(3, (int)k / 2, 3, (int)k / 2);
                                }

                                CropAspect aspect = (CropAspect)languageSettings[Property.CropAspect];
                                if (aspect != CropAspect.None)
                                {
                                    //v,b, or ttb
                                    if (aspect == CropAspect.Vertical || aspect == CropAspect.Both || (aspect == CropAspect.MatchedToWord && p.Margin.Left == 3))
                                    {
                                        p.Height = (int)(p.Height * p.BackgroundImage.Height / 500f);
                                    }
                                    if (aspect == CropAspect.Horizontal || aspect == CropAspect.Both || (aspect == CropAspect.MatchedToWord && p.Margin.Left != 3))
                                    {
                                        p.Width = (int)(p.Width * p.BackgroundImage.Width / 500f);
                                    }
                                }
                            }
                            flowPanel.Controls.Add(p);
                        }
                    }
                    FlowPanelDirection((FlowDirection)languageSettings[Property.WordDirection], flowPanel);
                    panelOutput.Controls.Add(flowPanel);
                }
            }
            textBoxBreakdown.Text = String.Join(" ", output);
        }
        /// <summary>
        ///  This method for loading/saving a font file generated from AngelCode BMFont.
        /// </summary>
        /// <param name="serializer">The binaryserializer to use.</param>
        private void SerializeBMFFont(BinarySerializer serializer)
        {
            // ----------------------------------------------------------
            // Read block Info (1)
            // ----------------------------------------------------------
            byte blockType = 1;
            serializer.Serialize(ref blockType);
            if (blockType != 1)
                return;

            // Skip Info block
            int expectedBlockSize = 0;
            serializer.Serialize(ref expectedBlockSize);
            serializer.Stream.Seek(expectedBlockSize, SeekOrigin.Current);

            // ----------------------------------------------------------
            // Read block Common (2)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 2)
                return;
            var common = new BMFCommon();
            common.Serialize(serializer);

            // Copy the base offset.
            BaseOffset = common.Base;
            LineSpacing = common.LineHeight;

            // ----------------------------------------------------------
            // Read block page names (3)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 3)
                return;
            serializer.Serialize(ref expectedBlockSize);

            // Create bitmap array.
            Bitmaps = new Bitmap[common.PageCount];
            for (int i = 0; i < Bitmaps.Length; i++)
            {
                string name = null;
                serializer.Serialize(ref name, true);
                // Store the name in data
                Bitmaps[i] = new Bitmap { Data = name };
            }

            // ----------------------------------------------------------
            // Read block glyphs (4)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 4)
                return;
            serializer.Serialize(ref expectedBlockSize);

            int countChars = expectedBlockSize/20;

            var bmfGlyph = new BMFGlyph();

            Glyphs = new Glyph[countChars];
            for (int i = 0; i < Glyphs.Length; i++)
            {
                bmfGlyph.Serialize(serializer);

                Glyphs[i] = new Glyph
                                {
                                    Character = bmfGlyph.Id, 
                                    Subrect = new Rectangle(bmfGlyph.X, bmfGlyph.Y, bmfGlyph.Width, bmfGlyph.Height), 
                                    Offset = {X = bmfGlyph.OffsetX, Y = bmfGlyph.OffsetY}, 
                                    XAdvance = bmfGlyph.AdvanceX,
                                    BitmapIndex = bmfGlyph.PageIndex
                                };
            }

            // ----------------------------------------------------------
            // Read block kernings (5) optional
            // ----------------------------------------------------------
            if (serializer.Stream.Position < serializer.Stream.Length)
            {
                // If there is still some data to read, there is probably some kernings
                serializer.Serialize(ref blockType);
                if (blockType != 5)
                    return;
                serializer.Serialize(ref expectedBlockSize);
                int kernelCount = expectedBlockSize/10;

                Kernings = new Kerning[kernelCount];
                for (int i = 0; i < Kernings.Length; i++)
                {
                    serializer.Serialize(ref Kernings[i].First);
                    serializer.Serialize(ref Kernings[i].Second);
                    short offset = 0;
                    serializer.Serialize(ref offset);
                    Kernings[i].Offset = offset;
                }
            }
        }
示例#5
0
        private void Load(IFileStore store)
        {
            using (var stream = store.OpenFile(m_path))
            {
                var    reader = new StreamReader(stream, Encoding.UTF8);
                string line;
                string type    = null;
                var    options = new KeyValuePairs();
                while ((line = reader.ReadLine()) != null)
                {
                    // Parse each line
                    string[] parts = line.Split(' ');
                    if (parts.Length < 1)
                    {
                        continue;
                    }

                    // Extract type and options
                    type = parts[0];
                    options.Clear();
                    for (int i = 1; i < parts.Length; ++i)
                    {
                        string part        = parts[i];
                        int    equalsIndex = part.IndexOf('=');
                        if (equalsIndex >= 0)
                        {
                            string key   = part.Substring(0, equalsIndex);
                            string value = part.Substring(equalsIndex + 1);
                            int    intValue;
                            if (value.StartsWith("\""))
                            {
                                if (value.EndsWith("\"") && value.Length >= 2)
                                {
                                    value = value.Substring(1, value.Length - 2);
                                }
                                else
                                {
                                    value = value.Substring(1) + " ";
                                    i++;
                                    while (!parts[i].EndsWith("\""))
                                    {
                                        value += parts[i] + " ";
                                        i++;
                                    }
                                    value += parts[i].Substring(0, parts[i].Length - 1);
                                }
                                options.Set(key, value);
                            }
                            else if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out intValue))
                            {
                                options.Set(key, intValue);
                            }
                        }
                    }

                    // Interpret
                    switch (type)
                    {
                    case "common":
                    {
                        m_lineHeight = options.GetInteger("lineHeight");
                        m_base       = options.GetInteger("base");
                        m_scaleW     = options.GetInteger("scaleW");
                        m_scaleH     = options.GetInteger("scaleH");
                        m_pages      = new Page[options.GetInteger("pages")];
                        break;
                    }

                    case "page":
                    {
                        int id = options.GetInteger("id");
                        if (id >= PageCount)
                        {
                            Array.Resize(ref m_pages, id + 1);
                        }
                        m_pages[id]      = new Page();
                        m_pages[id].Path = AssetPath.Combine(AssetPath.GetDirectoryName(m_path), options.GetString("file"));
                        break;
                    }

                    case "chars":
                    {
                        m_chars = new Dictionary <int, Char>(options.GetInteger("count"));
                        break;
                    }

                    case "char":
                    {
                        var id = options.GetInteger("id");
                        m_chars[id]          = new Char();
                        m_chars[id].X        = options.GetInteger("x");
                        m_chars[id].Y        = options.GetInteger("y");
                        m_chars[id].Width    = options.GetInteger("width");
                        m_chars[id].Height   = options.GetInteger("height");
                        m_chars[id].XOffset  = options.GetInteger("xoffset");
                        m_chars[id].YOffset  = options.GetInteger("yoffset");
                        m_chars[id].XAdvance = options.GetInteger("xadvance");
                        m_chars[id].Page     = options.GetInteger("page");
                        if (m_chars[id].Page < 0 || m_chars[id].Page >= PageCount)
                        {
                            m_chars[id].Page = 0;
                            //throw new IOException( "Page count out of range" );
                        }
                        break;
                    }

                    case "kernings":
                    {
                        m_kernings = new Dictionary <KerningPair, Kerning>(options.GetInteger("count"));
                        break;
                    }

                    case "kerning":
                    {
                        var first  = options.GetInteger("first");
                        var second = options.GetInteger("second");
                        var pair   = new KerningPair(first, second);
                        m_kernings[pair]        = new Kerning();
                        m_kernings[pair].Amount = options.GetInteger("amount");
                        break;
                    }
                    }
                }
            }
        }
    public void DoXMLPase(ref string content)
    {
        XmlDocument xml = new XmlDocument();

        xml.LoadXml(content);

        XmlNode     info   = xml.GetElementsByTagName("info")[0];
        XmlNode     common = xml.GetElementsByTagName("common")[0];
        XmlNodeList pages  = xml.GetElementsByTagName("pages")[0].ChildNodes;
        XmlNodeList chars  = xml.GetElementsByTagName("chars")[0].ChildNodes;


        fontName = info.Attributes.GetNamedItem("face").InnerText;
        fontSize = ToInt(info, "size");

        lineHeight     = ToInt(common, "lineHeight");
        lineBaseHeight = ToInt(common, "base");
        textureWidth   = ToInt(common, "scaleW");
        textureHeight  = ToInt(common, "scaleH");
        int pageNum = ToInt(common, "pages");

        textureNames = new string[pageNum];

        for (int i = 0; i < pageNum; i++)
        {
            XmlNode page   = pages[i];
            int     pageId = ToInt(page, "id");
            textureNames[pageId] = page.Attributes.GetNamedItem("file").InnerText;
        }

        charInfos = new CharacterInfo[chars.Count];
        for (int i = 0; i < chars.Count; i++)
        {
            XmlNode charNode = chars[i];
            charInfos[i] = CreateCharInfo(
                ToInt(charNode, "id"),
                ToInt(charNode, "x"),
                ToInt(charNode, "y"),
                ToInt(charNode, "width"),
                ToInt(charNode, "height"),
                ToInt(charNode, "xoffset"),
                ToInt(charNode, "yoffset"),
                ToInt(charNode, "xadvance"),
                ToInt(charNode, "page"));
        }

        // kernings
        XmlNode kerningsNode = xml.GetElementsByTagName("kernings")[0];

        if (kerningsNode != null && kerningsNode.HasChildNodes)
        {
            XmlNodeList kerns = kerningsNode.ChildNodes;
            kernings = new Kerning[kerns.Count];
            for (int i = 0; i < kerns.Count; i++)
            {
                XmlNode kerningNode = kerns[i];
                kernings[i]        = new Kerning();
                kernings[i].first  = ToInt(kerningNode, "first");
                kernings[i].second = ToInt(kerningNode, "second");
                kernings[i].amount = ToInt(kerningNode, "amount");
            }
        }
    }
        public override void Read(BinaryReader file, uint size)
        {
            base.Read(file, size);

            var cnt = file.ReadVLQInt32();

            for (int i = 0; i < cnt; i++)
            {
                //This is actually a byte-byte pair but no idea why or how anyone would edit this
                var mapping = new CUInt16(cr2w, Unicodemapping, "");
                mapping.Read(file, size);
                Unicodemapping.AddVariable(mapping);
            }
            Linedist.Read(file, size);
            Maxglyphheight.Read(file, size);
            Kerning.Read(file, size);

            var num = file.ReadVLQInt32();

            for (int i = 0; i < num; i++)
            {
                var glyph = new CArray <CFloat>(cr2w, Glyphs, "Glyph - " + i)
                {
                    Elementtype = "Float"
                };
                // UVs
                CFloat uv00 = new CFloat(cr2w, glyph, "UV[0][0]");
                uv00.Read(file, size);
                glyph.AddVariable(uv00);
                CFloat uv01 = new CFloat(cr2w, glyph, "UV[0][1]");
                uv01.Read(file, size);
                glyph.AddVariable(uv01);
                CFloat uv10 = new CFloat(cr2w, glyph, "UV[1][0]");
                uv10.Read(file, size);
                glyph.AddVariable(uv10);
                CFloat uv11 = new CFloat(cr2w, glyph, "UV[1][1]");
                uv11.Read(file, size);
                glyph.AddVariable(uv11);

                CInt32 textureindex = new CInt32(cr2w, glyph, "Texture index");
                textureindex.Read(file, size);
                glyph.AddVariable(textureindex);
                CInt32 width = new CInt32(cr2w, glyph, "Width");
                width.Read(file, size);
                glyph.AddVariable(width);
                CInt32 height = new CInt32(cr2w, glyph, "Height");
                height.Read(file, size);
                glyph.AddVariable(height);
                CInt32 advance_x = new CInt32(cr2w, glyph, "Advance X");
                advance_x.Read(file, size);
                glyph.AddVariable(advance_x);
                CInt32 bearing_x = new CInt32(cr2w, glyph, "Bearing X");
                bearing_x.Read(file, size);
                glyph.AddVariable(bearing_x);
                CInt32 bearing_y = new CInt32(cr2w, glyph, "Bearing Y");
                bearing_y.Read(file, size);
                glyph.AddVariable(bearing_y);

                Glyphs.AddVariable(glyph);
            }
        }
示例#8
0
        public Bitmap test_draw(ObservableCollection <System.Windows.UIElement> list,
                                ObservableCollection <FontModel> fontList,
                                MaxRectsBinPack binPack,
                                string alphabet,
                                FontSettings fontSettings)
        {
            alphabet = alphabet.Replace("\n", "");
            alphabet = alphabet.Replace("\r", "");
            Library library = new Library();
            Face    face    = library.NewFace(fontSettings.FontName, 0);

            // Find the largest glyph bounding rectangle
            //  Rect glyphRect = getGlyphRect(face, alphabet);
            //int glyphWidth = (int)Math.Ceiling(glyphRect.Width) + 4 * fontSettings.OutlineWidth;
            //int glyphHeight = (int)Math.Ceiling(glyphRect.Height) + 4 * fontSettings.OutlineWidth;
            int glyphWidth  = 18 + 4 * fontSettings.OutlineWidth;
            int glyphHeight = 18 + 4 * fontSettings.OutlineWidth;

            //add new font

            FontModel newFont = new FontModel()
            {
                Id            = (ushort)fontSettings.FontSize,
                size          = fontSettings.FontSize,
                lineheight    = glyphHeight,              // 22,
                spacelength   = (int)(glyphWidth * 0.6f), //todo ?
                baseline      = 0,
                kerning       = -0.5f,
                monowidth     = fontSettings.FontSize + 1,
                letterspacing = 0,
                rangeFrom     = alphabet[0],
                rangeTo       = alphabet[alphabet.Length - 1]
            };

            fontList.Add(newFont);


            Bitmap   bmp = new Bitmap((int)Math.Ceiling((double)fontSettings.ImageWidth), (int)Math.Ceiling((double)fontSettings.ImageHeight));
            Graphics g   = Graphics.FromImage(bmp);

            g.Clear(fontSettings.BgColor);
            //g.Clear(Color.Black);q
            int x = 0, y = 0;

            for (int i = 0; i < alphabet.ToCharArray().Length; i++)
            {
                string currentChar0 = alphabet.ToCharArray()[i].ToString();
                uint   glyphIndex   = face.GetCharIndex(uchar2code(currentChar0));


                if (fontSettings.FontSize <= 14)
                {
                    face.SetPixelSizes((uint)0, (uint)fontSettings.FontSize);
                    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                    face.Glyph.RenderGlyph(RenderMode.Normal);
                }
                else
                {
                    face.SetCharSize(0, fontSettings.FontSize, 0, 72);
                    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                    face.Glyph.RenderGlyph(RenderMode.Lcd);
                }

                //Get character alignment
                float left   = (float)face.Glyph.Metrics.HorizontalBearingX;
                float right  = (float)face.Glyph.Metrics.HorizontalBearingX + (float)face.Glyph.Metrics.Width;
                float top    = (float)face.Glyph.Metrics.HorizontalBearingY;
                float bottom = (float)face.Glyph.Metrics.HorizontalBearingY + (float)face.Glyph.Metrics.Height;
                float FHT    = fontSettings.FontSize;
                int   FHD    = (int)Math.Ceiling(FHT);
                int   kx     = x + face.Glyph.BitmapLeft;
                int   ky     = (int)Math.Round((float)y + (FHD - face.Glyph.BitmapTop));


                ////Select render mode (1 times or 2 times)
                //if (this.grender_mode == "freetype_nearestneighbor")
                //{
                //    face.SetCharSize(0, this.fontHeight * 2, 0, 72);
                //    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                //    face.Glyph.RenderGlyph(RenderMode.Lcd);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }

                //    Bitmap tmpBmp = ftbmp.ToGdipBitmap(this.penColor);

                //    tmpBmp = kPasteImage(tmpBmp, tile_width * 2, tile_height * 2, (int)face.Glyph.BitmapLeft,
                //                        (int)Math.Round(((float)this.fontHeight * 2 - face.Glyph.BitmapTop)));

                //    Bitmap cBmp = kResizeImage(tmpBmp, tmpBmp.Width / 2, tmpBmp.Height / 2, System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(nBmp, x + FontSettings.relativePositionX, y + FontSettings.relativePositionY);
                //    nBmp.Dispose();
                //}
                //else if (this.grender_mode == "freetype_HighQualityBicubic")
                //{
                //    face.SetCharSize(0, this.fontHeight * 2, 0, 72);
                //    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                //    face.Glyph.RenderGlyph(RenderMode.Lcd);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }

                //    Bitmap tmpBmp = ftbmp.ToGdipBitmap(this.penColor);

                //    tmpBmp = kPasteImage(tmpBmp, tile_width * 2, tile_height * 2, (int)face.Glyph.BitmapLeft,
                //        (int)Math.Round(((float)this.fontHeight * 2 - face.Glyph.BitmapTop)));

                //    Bitmap cBmp = kResizeImage(tmpBmp, tmpBmp.Width / 2, tmpBmp.Height / 2, System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic);
                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(nBmp, x + FontSettings.relativePositionX, y + FontSettings.relativePositionY);
                //    nBmp.Dispose();

                //}
                //else if (this.grender_mode == "freetype_drawtwice")
                //{
                //    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                //    face.Glyph.RenderGlyph(RenderMode.Normal);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }
                //    Bitmap cBmp = ftbmp.ToGdipBitmap(this.penColor);
                //    Bitmap sBmp = ftbmp.ToGdipBitmap(this.shadowColor);

                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(sBmp, kx + FontSettings.relativePositionX + 1, ky + FontSettings.relativePositionY + 1);//draw twice
                //    g.DrawImageUnscaled(nBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //    cBmp.Dispose();
                //    nBmp.Dispose();

                //}
                //else if (this.grender_mode == "freeyype_nosmoothing")
                //{
                //    face.SetPixelSizes((uint)0, (uint)this.fontHeight);
                //    face.LoadGlyph(glyphIndex, LoadFlags.Monochrome, LoadTarget.Mono);
                //    face.Glyph.RenderGlyph(RenderMode.Mono);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }
                //    Bitmap cBmp = ftbmp.ToGdipBitmap(this.penColor);
                //    g.DrawImageUnscaled(cBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //    cBmp.Dispose();
                //}

                //    int tile_width = 24;
                //int tile_height = FontSettings.iFontHeight;//24;
                ////else
                ////{
                FTBitmap ftbmp = face.Glyph.Bitmap;

                //    if (ftbmp.Width == 0)
                //    {
                //        x += tile_width;
                //        if (x + tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += tile_height;
                //        }
                //        continue;
                //    }


                Bitmap cBmp = ftbmp.ToGdipBitmap(fontSettings.PenColor);
                Bitmap nBmp = gray2alpha(cBmp);

                Rect newPos = binPack.Insert(cBmp.Width, cBmp.Height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBottomLeftRule);

                //DebugRectangle
                System.Windows.Shapes.Rectangle testRect = new System.Windows.Shapes.Rectangle
                {
                    Stroke          = System.Windows.Media.Brushes.LightGreen,
                    StrokeThickness = 0
                };

                ImageBrush ib = new ImageBrush();
                //    cBmp.MakeTransparent();
                cBmp.Dispose();
                var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(nBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
                                                                                          System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                nBmp.Dispose();
                ib.ImageSource  = source;
                testRect.Fill   = ib;
                testRect.Width  = newPos.Width;
                testRect.Height = newPos.Height;
                Canvas.SetLeft(testRect, newPos.Left);
                Canvas.SetTop(testRect, newPos.Top);
                list.Add(testRect);

                Glyph newGlyph = new Glyph()
                {
                    X      = (int)Math.Ceiling(newPos.Left),
                    Y      = (int)Math.Ceiling(newPos.Top),
                    width  = (int)Math.Ceiling(newPos.Width),
                    height = (int)Math.Ceiling(newPos.Height)
                };
                newFont.SetGlyph(currentChar0, newGlyph);

                //if(glyphIndex == 33)
                //{

                //}
                // Construct KerningData
                for (int j = 0; j < alphabet.ToCharArray().Length; j++)
                {
                    string left_Char0      = alphabet.ToCharArray()[j].ToString();
                    uint   left_glyphIndex = face.GetCharIndex(uchar2code(left_Char0));

                    //if (left_glyphIndex == 45)
                    //{

                    //}
                    //char c1 = mAlphabet[i];
                    //FT_UInt c1Index = FT_Get_Char_Index(face, c1);
                    var delta = face.GetKerning(left_glyphIndex, glyphIndex, KerningMode.Default);

                    // KerningData kd = new KerningData(kern_currentChar0, currentChar0, delta.X.ToInt32() >> 6, 0, delta.Y.ToInt32() >> 6, 0);
                    if (left_glyphIndex == 0 || delta.X == 0) //no kerning
                    {
                        continue;
                    }

                    Kerning newKerning = new Kerning();
                    newKerning.RightGlyphID = left_glyphIndex;
                    newKerning.KerningValue = delta.X.ToInt32() >> 6;
                    newFont.SetKerning(left_Char0, newKerning);
                }

                newFont.SetVerticalOffset(currentChar0, ky);

                //cBmp.Dispose();
                //g.DrawImageUnscaled(nBmp, (int)Math.Ceiling(newPos.X) + fontSettings.relativePositionX, (int)Math.Ceiling(newPos.Y) + fontSettings.relativePositionY);
                //// g.DrawImageUnscaled(nBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //nBmp.Dispose();
            }
            g.Dispose();
            library.Dispose();
            return(bmp);
        }
示例#9
0
        /// <summary>
        /// Create a font from a file.
        /// Return null if an error.
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static BitmapFont ReadFile(string filename)
        {
            var font  = new BitmapFont();
            var bytes = File.ReadAllBytes(filename);

            // start with ASCII "BMF"
            if (bytes.Length < 3 || bytes[0] != 66 || bytes[1] != 77 || bytes[2] != 70)
            {
                return(null); // wrong header
            }
            var version = bytes[3];

            if (version > 3)
            {
                return(null); // unsupported version
            }
            var index = 4;    // start here

            Func <int, int> Read = n =>
            {
                var val = 0;
                for (var i = 0; i < n; ++i)
                {
                    val = bytes[index++];
                }
                return(val);
            };
            Func <int, uint> ReadU = n => (uint)Read(n);
            int pages = 0;

            while (index < bytes.Length)
            {
                var type = bytes[index++];
                var size = Read(4);      // block size, not including type and 4 byte size field
                var next = size + index; // should end here
                switch (type)
                {
                case 1:                     // general info - how font was generated
                {
                    var fontSize = Read(2); // size of TT font
                    var bits     = Read(1);
                    // bit 0: smooth, bit 1: unicode, bit 2: italic, bit 3: bold, bit 4: fixedHeight, bits 5-7: reserved
                    var smooth      = (bits & 1) != 0;     // smoothing was on
                    var unicode     = (bits & 2) != 0;     // a unicode charset
                    var italic      = (bits & 4) != 0;     // font is italic
                    var bold        = (bits & 8) != 0;     // font is bold
                    var fixedHeight = (bits & 16) != 0;

                    var charSet      = Read(1); // name of OEM charset, when not Unicode
                    var stretchH     = Read(2); // 100% means no stretch
                    var aa           = Read(1); // supersampling level used
                    var paddingUp    = Read(1);
                    var paddingRight = Read(1);
                    var paddingDown  = Read(1);
                    var paddingLeft  = Read(1);
                    var spacingH     = Read(1);
                    var spacingV     = Read(1);    // character spacing
                    var outline      = Read(1);    // outline thickness
                    var sb           = new StringBuilder();
                    while (bytes[index] != 0)
                    {
                        sb.Append((char)bytes[index++]);
                    }
                    var name = sb.ToString(); // name of true type font used
                    index++;                  // skip 0
                }

                break;

                case 2:                                   // common
                {
                    font.LineHeight = Read(2);            // uint 0
                    font.Base       = Read(2);            // uint 2
                    var scaleW = Read(2);                 // uint 4
                    var scaleH = Read(2);                 // uint 6
                    pages = Read(2);                      // uint 8 number of texture pages
                    var bitField = Read(1);               // bits 10 bits 0-6: reserved, bit 7: packed
                    var packed   = (bitField & 128) != 0; // if packed, each color channel has monochrome characters and alpha channel describes what's in channels

                    // each channel: Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
                    var alphaChnl = Read(1);       // uint 11
                    var redChnl   = Read(1);       //uint 12
                    var greenChnl = Read(1);       //uint 13
                    var blueChnl  = Read(1);       //uint 14
                }

                break;

                case 3:     // page names for textures
                {
                    for (var i = 0; i < pages; ++i)
                    {
                        var sb = new StringBuilder();
                        while (bytes[index] != 0)
                        {
                            sb.Append((char)bytes[index++]);
                        }
                        var name = sb.ToString();
                        index++;         // skip 0
                    }
                }
                break;

                case 4:     // chars
                {
                    // The number of characters in the file can be computed by taking the size of
                    // the block and dividing with the size of the charInfo structure, i.e.: numChars = charsBlock.blockSize/20.
                    if ((size % 20) != 0)
                    {
                        return(null);        // wrong size
                    }
                    var num = size / 20;
                    for (var i = 0; i < num; ++i)
                    {
                        var c  = new BitmapCharacter();
                        var id = Read(4);      // character ID (unicode?)
                        //uint 0+c*20 These fields are repeated until all characters have been described
                        c.X        = Read(2);  // uint 4+c*20   texture X position
                        c.Y        = Read(2);  //uint 6+c*20    texture Y position
                        c.Width    = Read(2);  //uint 8+c*20  texture width
                        c.Height   = Read(2);  //uint 10+c*20  texture height
                        c.XOffset  = Read(2);  // int 12+c*20  offset when copying to screen
                        c.YOffset  = Read(2);  // int 14+c*20
                        c.XAdvance = Read(2);  //int 16+c*20  advance after drawing character
                        var page = Read(1);    // uint 18+c*20   // texture page where character is found
                        var chnl = Read(1);    // uint 19+c*20 // texture where found (1=blue,2-green,4-red,8=alpha,15=all channels)
                        font.Characters[id] = c;
                    }
                }
                break;

                case 5:     // kerning pairs
                {
                    if ((size % 10) != 0)
                    {
                        return(null);        // wrong size
                    }
                    var num = size / 10;
                    for (var i = 0; i < num; ++i)
                    {
                        // This block is only in the file if there are any kerning pairs with amount differing from 0.
                        var k = new Kerning();
                        // uint 0+c*10 These fields are repeated until all kerning pairs have been described
                        k.First  = Read(4);        // first character id
                        k.Second = Read(4);        // uint 4+c*10  second character id
                        k.Amount = Read(2);        // int 8+c*6 amount to adjust x position
                        font.KerningList.Add(k);
                    }
                }
                break;

                default:
                    return(null);    // unknown block type
                }
                if (next != index)
                {
                    return(null); // wrong block size
                }
            }

            return(font);
        }
示例#10
0
 void ParseKerning() {
     var k = new Kerning();
     k.first = (char) GetInt("first");
     k.second = (char) GetInt("second");
     k.amount = GetInt("amount");
     
     Dictionary<char, Kerning> valueDict;
     if (kerningTable.ContainsKey(k.first)) {
         valueDict = kerningTable[k.first];
     } else {
         valueDict = new Dictionary<char, Kerning>();
         kerningTable[k.first] = valueDict;
     }
     
     valueDict.Add(k.second, k);
 }
示例#11
0
        /// <summary>
        ///  This method for loading/saving a font file generated from AngelCode BMFont.
        /// </summary>
        /// <param name="serializer">The binaryserializer to use.</param>
        private void SerializeBMFFont(BinarySerializer serializer)
        {
            // ----------------------------------------------------------
            // Read block Info (1)
            // ----------------------------------------------------------
            byte blockType = 1;

            serializer.Serialize(ref blockType);
            if (blockType != 1)
            {
                return;
            }

            // Skip Info block
            int expectedBlockSize = 0;

            serializer.Serialize(ref expectedBlockSize);
            serializer.Stream.Seek(expectedBlockSize, SeekOrigin.Current);

            // ----------------------------------------------------------
            // Read block Common (2)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 2)
            {
                return;
            }
            var common = new BMFCommon();

            common.Serialize(serializer);

            // Copy the base offset.
            BaseOffset  = common.Base;
            LineSpacing = common.LineHeight;

            // ----------------------------------------------------------
            // Read block page names (3)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 3)
            {
                return;
            }
            serializer.Serialize(ref expectedBlockSize);

            // Create bitmap array.
            Bitmaps = new Bitmap[common.PageCount];
            for (int i = 0; i < Bitmaps.Length; i++)
            {
                string name = null;
                serializer.Serialize(ref name, true);
                // Store the name in data
                Bitmaps[i] = new Bitmap {
                    Data = name
                };
            }

            // ----------------------------------------------------------
            // Read block glyphs (4)
            // ----------------------------------------------------------
            serializer.Serialize(ref blockType);
            if (blockType != 4)
            {
                return;
            }
            serializer.Serialize(ref expectedBlockSize);

            int countChars = expectedBlockSize / 20;

            var bmfGlyph = new BMFGlyph();

            Glyphs = new Glyph[countChars];
            for (int i = 0; i < Glyphs.Length; i++)
            {
                bmfGlyph.Serialize(serializer);

                Glyphs[i] = new Glyph
                {
                    Character   = bmfGlyph.Id,
                    Subrect     = new Rectangle(bmfGlyph.X, bmfGlyph.Y, bmfGlyph.Width, bmfGlyph.Height),
                    Offset      = { X = bmfGlyph.OffsetX, Y = bmfGlyph.OffsetY },
                    XAdvance    = bmfGlyph.AdvanceX,
                    BitmapIndex = bmfGlyph.PageIndex
                };
            }

            // ----------------------------------------------------------
            // Read block kernings (5) optional
            // ----------------------------------------------------------
            if (serializer.Stream.Position < serializer.Stream.Length)
            {
                // If there is still some data to read, there is probably some kernings
                serializer.Serialize(ref blockType);
                if (blockType != 5)
                {
                    return;
                }
                serializer.Serialize(ref expectedBlockSize);
                int kernelCount = expectedBlockSize / 10;

                Kernings = new Kerning[kernelCount];
                for (int i = 0; i < Kernings.Length; i++)
                {
                    serializer.Serialize(ref Kernings[i].First);
                    serializer.Serialize(ref Kernings[i].Second);
                    short offset = 0;
                    serializer.Serialize(ref offset);
                    Kernings[i].Offset = offset;
                }
            }
        }
示例#12
0
 /// <summary>Parses the FNT file.</summary>
 private void ParseFNTFile()
 {
     string fntFile = m_fntFile;
     StreamReader stream = new StreamReader( fntFile );
     string line;
     char[] separators = new char[] { ' ', '=' };
     while ( ( line = stream.ReadLine() ) != null )
     {
     string[] tokens = line.Split( separators );
     if ( tokens[0] == "info" )
     {
     // Get rendered size
     for ( int i = 1; i < tokens.Length; i++ )
     {
         if ( tokens[i] == "size" )
         {
             m_charSet.RenderedSize = int.Parse( tokens[i + 1] );
         }
     }
     }
     else if ( tokens[0] == "common" )
     {
     // Fill out BitmapCharacterSet fields
     for ( int i = 1; i < tokens.Length; i++ )
     {
         if ( tokens[i] == "lineHeight" )
         {
             m_charSet.LineHeight = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "base" )
         {
             m_charSet.Base = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "scaleW" )
         {
             m_charSet.Width = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "scaleH" )
         {
             m_charSet.Height = int.Parse( tokens[i + 1] );
         }
     }
     }
     else if ( tokens[0] == "char" )
     {
     // New BitmapCharacter
     int index = 0;
     for ( int i = 1; i < tokens.Length; i++ )
     {
         if ( tokens[i] == "id" )
         {
             index = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "x" )
         {
             m_charSet.Characters[index].X = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "y" )
         {
             m_charSet.Characters[index].Y = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "width" )
         {
             m_charSet.Characters[index].Width = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "height" )
         {
             m_charSet.Characters[index].Height = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "xoffset" )
         {
             m_charSet.Characters[index].XOffset = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "yoffset" )
         {
             m_charSet.Characters[index].YOffset = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "xadvance" )
         {
             m_charSet.Characters[index].XAdvance = int.Parse( tokens[i + 1] );
         }
     }
     }
     else if ( tokens[0] == "kerning" )
     {
     // Build kerning list
     int index = 0;
     Kerning k = new Kerning();
     for ( int i = 1; i < tokens.Length; i++ )
     {
         if ( tokens[i] == "first" )
         {
             index = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "second" )
         {
             k.Second = int.Parse( tokens[i + 1] );
         }
         else if ( tokens[i] == "amount" )
         {
             k.Amount = int.Parse( tokens[i + 1] );
         }
     }
     m_charSet.Characters[index].KerningList.Add( k );
     }
     }
     stream.Close();
 }