예제 #1
0
        static void CreateSampleMsdfTextureFont(
            string fontfile, float sizeInPoint,
            char[] chars, string outputFile)
        {
            //sample
            var reader = new OpenFontReader();

            using (var fs = new FileStream(fontfile, FileMode.Open))
            {
                //1. read typeface from font file
                Typeface typeface = reader.Read(fs);
                //sample: create sample msdf texture
                //-------------------------------------------------------------
                var builder = new GlyphPathBuilder(typeface);
                //builder.UseTrueTypeInterpreter = this.chkTrueTypeHint.Checked;
                //builder.UseVerticalHinting = this.chkVerticalHinting.Checked;
                //-------------------------------------------------------------
                var atlasBuilder = new SimpleFontAtlasBuilder();

                MsdfGenParams msdfGenParams = new MsdfGenParams();

                int j = chars.Length;
                for (int i = 0; i < j; ++i)
                {
                    //build glyph
                    ushort gindex = typeface.LookupIndex(chars[i]);
                    builder.BuildFromGlyphIndex(gindex, -1);

                    var glyphToContour = new GlyphContourBuilder();
                    //glyphToContour.Read(builder.GetOutputPoints(), builder.GetOutputContours());
                    builder.ReadShapes(glyphToContour);
                    msdfGenParams.shapeScale = 1f / 64;
                    GlyphImage glyphImg = MsdfGlyphGen.CreateMsdfImage(glyphToContour, msdfGenParams);
                    atlasBuilder.AddGlyph(gindex, glyphImg);
                    int w = glyphImg.Width;
                    int h = glyphImg.Height;
                    using (Bitmap bmp = new Bitmap(glyphImg.Width, glyphImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                    {
                        var   bmpdata   = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
                        int[] imgBuffer = glyphImg.GetImageBuffer();
                        System.Runtime.InteropServices.Marshal.Copy(imgBuffer, 0, bmpdata.Scan0, imgBuffer.Length);
                        bmp.UnlockBits(bmpdata);
                        bmp.Save("d:\\WImageTest\\a001_xn2_" + (chars[i]) + ".png");
                    }
                }

                var glyphImg2 = atlasBuilder.BuildSingleImage();
                using (Bitmap bmp = new Bitmap(glyphImg2.Width, glyphImg2.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                {
                    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg2.Width, glyphImg2.Height),
                                               System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
                    int[] intBuffer = glyphImg2.GetImageBuffer();

                    System.Runtime.InteropServices.Marshal.Copy(intBuffer, 0, bmpdata.Scan0, intBuffer.Length);
                    bmp.UnlockBits(bmpdata);
                    bmp.Save("d:\\WImageTest\\a_total.png");
                }
                atlasBuilder.SaveFontInfo("d:\\WImageTest\\a_info.xml");
            }
        }
예제 #2
0
        public static FontFace LoadFont(string fontfile,
                                        ScriptLang scriptLang,
                                        WriteDirection writeDirection,
                                        out SimpleFontAtlas fontAtlas)
        {
            //1. read font info
            ManagedFontFace openFont = (ManagedFontFace)OpenFontLoader.LoadFont(fontfile, scriptLang, writeDirection);

            //2. build texture font on the fly! OR load from prebuilt file
            //
            //2.1 test build texture on the fly
            SimpleFontAtlasBuilder atlas1    = CreateSampleMsdfTextureFont(fontfile, 14, 0, 255);
            GlyphImage             glyphImg2 = atlas1.BuildSingleImage();

            fontAtlas            = atlas1.CreateSimpleFontAtlas();
            fontAtlas.TotalGlyph = glyphImg2;

            //string xmlFontFileInfo = "";
            //GlyphImage glyphImg = null;
            //MySimpleFontAtlasBuilder atlasBuilder = new MySimpleFontAtlasBuilder();
            //SimpleFontAtlas fontAtlas = atlasBuilder.LoadFontInfo(xmlFontFileInfo);
            //glyphImg = atlasBuilder.BuildSingleImage(); //we can create a new glyph or load from prebuilt file
            //fontAtlas.TotalGlyph = glyphImg;


            var textureFontFace = new TextureFontFace(openFont, fontAtlas);

            return(textureFontFace);
        }
예제 #3
0
        public static FontFace LoadFont(
            Typeface typeface,
            TextureFontCreationParams creationParams,
            out SimpleFontAtlas fontAtlas)
        {
            //1. read font info
            NOpenFontFace openFont = (NOpenFontFace)OpenFontLoader.LoadFont(typeface, creationParams.scriptLang, creationParams.writeDirection);

            //------------------------
            SimpleFontAtlasBuilder atlas1 = null;

            switch (creationParams.textureKind)
            {
            default: throw new System.NotSupportedException();

            case TextureKind.AggSubPixel:
                atlas1 = CreateAggSubPixelRenderingTextureFont(
                    typeface,
                    creationParams.originalFontSizeInPoint,
                    creationParams.hintTechnique,
                    GetGlyphIndexIter(typeface, creationParams.langBits)
                    );
                break;

            case TextureKind.AggGrayScale:
                atlas1 = CreateAggTextureFont(
                    typeface,
                    creationParams.originalFontSizeInPoint,
                    creationParams.hintTechnique,
                    GetGlyphIndexIter(typeface, creationParams.langBits)
                    );
                break;

            case TextureKind.Msdf:
                atlas1 = CreateSampleMsdfTextureFont(
                    typeface,
                    creationParams.originalFontSizeInPoint,
                    creationParams.hintTechnique,
                    GetGlyphIndexIter(typeface, creationParams.langBits)
                    );
                break;
            }

            GlyphImage glyphImg2 = atlas1.BuildSingleImage();

            fontAtlas            = atlas1.CreateSimpleFontAtlas();
            fontAtlas.TotalGlyph = glyphImg2;

            //string xmlFontFileInfo = "";
            //GlyphImage glyphImg = null;
            //MySimpleFontAtlasBuilder atlasBuilder = new MySimpleFontAtlasBuilder();
            //SimpleFontAtlas fontAtlas = atlasBuilder.LoadFontInfo(xmlFontFileInfo);
            //glyphImg = atlasBuilder.BuildSingleImage(); //we can create a new glyph or load from prebuilt file
            //fontAtlas.TotalGlyph = glyphImg;

            return(openFont);
            //var textureFontFace = new TextureFontFace(openFont, fontAtlas);
            //return textureFontFace;
        }
예제 #4
0
        /// <summary>
        /// get from cache or create a new one
        /// </summary>
        /// <param name="reqFont"></param>
        /// <returns></returns>
        public SimpleFontAtlas GetFontAtlas(RequestFont reqFont,
                                            out GLBitmap glBmp)
        {
            int             fontKey = reqFont.FontKey;
            SimpleFontAtlas fontAtlas;

            if (!_createdAtlases.TryGetValue(fontKey, out fontAtlas))
            {
                Typeface resolvedTypeface = textServices.ResolveTypeface(reqFont);
                //if we don't have
                //the create it
                SimpleFontAtlasBuilder atlasBuilder = null;
                var textureGen = new GlyphTextureBitmapGenerator();
                textureGen.CreateTextureFontFromScriptLangs(
                    resolvedTypeface,
                    reqFont.SizeInPoints,
                    _textureKind,
                    _currentScriptLangs,
                    (glyphIndex, glyphImage, outputAtlasBuilder) =>
                {
                    if (outputAtlasBuilder != null)
                    {
                        //finish
                        atlasBuilder = outputAtlasBuilder;
                    }
                }
                    );

                GlyphImage totalGlyphsImg = atlasBuilder.BuildSingleImage();
                //create atlas
                fontAtlas            = atlasBuilder.CreateSimpleFontAtlas();
                fontAtlas.TotalGlyph = totalGlyphsImg;
#if DEBUG
                //save glyph image for debug
                //PixelFarm.Agg.ActualImage.SaveImgBufferToPngFile(
                //    totalGlyphsImg.GetImageBuffer(),
                //    totalGlyphsImg.Width * 4,
                //    totalGlyphsImg.Width, totalGlyphsImg.Height,
                //    "d:\\WImageTest\\total_" + reqFont.Name + "_" + reqFont.SizeInPoints + ".png");
#endif

                //cache the atlas
                _createdAtlases.Add(fontKey, fontAtlas);
                //
                //calculate some commonly used values
                fontAtlas.SetTextureScaleInfo(
                    resolvedTypeface.CalculateScaleToPixelFromPointSize(fontAtlas.OriginalFontSizePts),
                    resolvedTypeface.CalculateScaleToPixelFromPointSize(reqFont.SizeInPoints));
                //TODO: review here, use scaled or unscaled values
                fontAtlas.SetCommonFontMetricValues(
                    resolvedTypeface.Ascender,
                    resolvedTypeface.Descender,
                    resolvedTypeface.LineGap,
                    resolvedTypeface.CalculateRecommendLineSpacing());
            }

            glBmp = _loadedGlyphs.GetOrCreateNewOne(fontAtlas);
            return(fontAtlas);
        }
예제 #5
0
        static void CreateSampleMsdfTextureFont(string fontfile, float sizeInPoint, ushort startGlyphIndex, ushort endGlyphIndex, string outputFile)
        {
            //sample
            var reader = new OpenFontReader();

            using (var fs = new FileStream(fontfile, FileMode.Open))
            {
                //1. read typeface from font file
                Typeface typeface = reader.Read(fs);
                //sample: create sample msdf texture
                //-------------------------------------------------------------
                var builder = new GlyphPathBuilder(typeface);
                //builder.UseTrueTypeInterpreter = this.chkTrueTypeHint.Checked;
                //builder.UseVerticalHinting = this.chkVerticalHinting.Checked;
                //-------------------------------------------------------------
                var atlasBuilder = new SimpleFontAtlasBuilder();


                for (ushort gindex = startGlyphIndex; gindex <= endGlyphIndex; ++gindex)
                {
                    //build glyph
                    builder.BuildFromGlyphIndex(gindex, sizeInPoint);

                    var glyphToContour = new GlyphContourBuilder();
                    //glyphToContour.Read(builder.GetOutputPoints(), builder.GetOutputContours());
                    var genParams = new MsdfGenParams();
                    builder.ReadShapes(glyphToContour);
                    genParams.shapeScale = 1f / 64; //we scale later (as original C++ code use 1/64)
                    GlyphImage glyphImg = MsdfGlyphGen.CreateMsdfImage(glyphToContour, genParams);
                    atlasBuilder.AddGlyph(gindex, glyphImg);

                    //using (Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                    //{
                    //    var bmpdata = bmp.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
                    //    System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpdata.Scan0, buffer.Length);
                    //    bmp.UnlockBits(bmpdata);
                    //    bmp.Save("d:\\WImageTest\\a001_xn2_" + n + ".png");
                    //}
                }

                var glyphImg2 = atlasBuilder.BuildSingleImage();
                using (Bitmap bmp = new Bitmap(glyphImg2.Width, glyphImg2.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                {
                    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg2.Width, glyphImg2.Height),
                                               System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
                    int[] intBuffer = glyphImg2.GetImageBuffer();

                    System.Runtime.InteropServices.Marshal.Copy(intBuffer, 0, bmpdata.Scan0, intBuffer.Length);
                    bmp.UnlockBits(bmpdata);
                    bmp.Save("d:\\WImageTest\\a_total.png");
                }
                atlasBuilder.SaveFontInfo("d:\\WImageTest\\a_info.xml");
            }
        }
예제 #6
0
        private void cmdTestFontAtlas_Click(object sender, EventArgs e)
        {
            //read string from txtSampleChars
            //please make sure all are unique. (TODO: check it)
            //then create a font atlas from the sample chars

            char[] sampleChars = txtSampleChars.Text.ToCharArray();
            if (sampleChars.Length == 0)
            {
                return;
            }
            //

            GlyphImage             totalGlyphsImg = null;
            SimpleFontAtlasBuilder atlasBuilder   = null;
            var glyphTextureGen = new GlyphTextureBitmapGenerator();
            //
            Typeface typeface         = _basicOptions.Typeface;
            float    fontSizeInPoints = _basicOptions.FontSizeInPoints;

            //
            glyphTextureGen.CreateTextureFontFromInputChars(
                typeface,
                fontSizeInPoints,
                TextureKind.StencilLcdEffect,
                sampleChars,
                (glyphIndex, glyphImage, outputAtlasBuilder) =>
            {
                if (outputAtlasBuilder != null)
                {
                    //finish
                    atlasBuilder = outputAtlasBuilder;
                }
            }
                );

            atlasBuilder.SpaceCompactOption = SimpleFontAtlasBuilder.CompactOption.ArrangeByHeight;
            totalGlyphsImg = atlasBuilder.BuildSingleImage();
            string fontTextureImg = "d:\\WImageTest\\test_glyph_atlas.png";


            //create atlas
            SimpleFontAtlas fontAtlas = atlasBuilder.CreateSimpleFontAtlas();

            fontAtlas.TotalGlyph = totalGlyphsImg;
            //
            using (MemBitmap memBmp = MemBitmap.CreateFromCopy(totalGlyphsImg.Width, totalGlyphsImg.Height, totalGlyphsImg.GetImageBuffer()))
                using (System.Drawing.Bitmap bmp = new Bitmap(memBmp.Width, memBmp.Height))
                {
                    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, memBmp.Width, memBmp.Height),
                                               System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    var tmpMem = MemBitmap.GetBufferPtr(memBmp);
                    unsafe
                    {
                        PixelFarm.CpuBlit.NativeMemMx.MemCopy((byte *)bmpdata.Scan0,
                                                              (byte *)tmpMem.Ptr,
                                                              tmpMem.LengthInBytes);
                    }
                    bmp.UnlockBits(bmpdata);
                    bmp.Save(fontTextureImg);
                }


#if DEBUG
            //save glyph image for debug
            //PixelFarm.Agg.ActualImage.SaveImgBufferToPngFile(
            //    totalGlyphsImg.GetImageBuffer(),
            //    totalGlyphsImg.Width * 4,
            //    totalGlyphsImg.Width, totalGlyphsImg.Height,
            //    "d:\\WImageTest\\total_" + reqFont.Name + "_" + reqFont.SizeInPoints + ".png");
            ////save image to cache
            //SaveImgBufferToFile(totalGlyphsImg, fontTextureImg);
#endif

            //cache the atlas
            //_createdAtlases.Add(fontKey, fontAtlas);
            ////
            ////calculate some commonly used values
            //fontAtlas.SetTextureScaleInfo(
            //    resolvedTypeface.CalculateScaleToPixelFromPointSize(fontAtlas.OriginalFontSizePts),
            //    resolvedTypeface.CalculateScaleToPixelFromPointSize(reqFont.SizeInPoints));
            ////TODO: review here, use scaled or unscaled values
            //fontAtlas.SetCommonFontMetricValues(
            //    resolvedTypeface.Ascender,
            //    resolvedTypeface.Descender,
            //    resolvedTypeface.LineGap,
            //    resolvedTypeface.CalculateRecommendLineSpacing());

            ///
        }
        /// <summary>
        /// get from cache or create a new one
        /// </summary>
        /// <param name="reqFont"></param>
        /// <returns></returns>
        public SimpleFontAtlas GetFontAtlas(RequestFont reqFont, out GLBitmap glBmp)
        {
#if DEBUG
            _dbugStopWatch.Reset();
            _dbugStopWatch.Start();
#endif

            int             fontKey = reqFont.FontKey;
            SimpleFontAtlas fontAtlas;
            if (!_createdAtlases.TryGetValue(fontKey, out fontAtlas))
            {
                //check from pre-built cache (if availiable)
                Typeface resolvedTypeface = textServices.ResolveTypeface(reqFont);

                string fontTextureFile     = reqFont.Name + " " + fontKey;
                string resolveFontFile     = fontTextureFile + ".info";
                string fontTextureInfoFile = resolveFontFile;
                string fontTextureImg      = fontTextureInfoFile + ".png";

                if (StorageService.Provider.DataExists(fontTextureInfoFile))
                {
                    SimpleFontAtlasBuilder atlasBuilder2 = new SimpleFontAtlasBuilder();

                    using (System.IO.Stream dataStream = StorageService.Provider.ReadDataStream(fontTextureInfoFile))
                    {
                        try
                        {
                            fontAtlas                     = atlasBuilder2.LoadAtlasInfo(dataStream);
                            fontAtlas.TotalGlyph          = ReadGlyphImages(fontTextureImg);
                            fontAtlas.OriginalFontSizePts = reqFont.SizeInPoints;
                            _createdAtlases.Add(fontKey, fontAtlas);
                            //
                            //calculate some commonly used values
                            fontAtlas.SetTextureScaleInfo(
                                resolvedTypeface.CalculateScaleToPixelFromPointSize(fontAtlas.OriginalFontSizePts),
                                resolvedTypeface.CalculateScaleToPixelFromPointSize(reqFont.SizeInPoints));
                            //TODO: review here, use scaled or unscaled values
                            fontAtlas.SetCommonFontMetricValues(
                                resolvedTypeface.Ascender,
                                resolvedTypeface.Descender,
                                resolvedTypeface.LineGap,
                                resolvedTypeface.CalculateRecommendLineSpacing());
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                }
                else
                {
                    GlyphImage             totalGlyphsImg = null;
                    SimpleFontAtlasBuilder atlasBuilder   = null;
                    var textureGen = new GlyphTextureBitmapGenerator();
                    textureGen.CreateTextureFontFromScriptLangs(
                        resolvedTypeface,
                        reqFont.SizeInPoints,
                        _textureKind,
                        _textureBuildDetails,
                        (glyphIndex, glyphImage, outputAtlasBuilder) =>
                    {
                        if (outputAtlasBuilder != null)
                        {
                            //finish
                            atlasBuilder = outputAtlasBuilder;
                        }
                    }
                        );

                    //
                    totalGlyphsImg = atlasBuilder.BuildSingleImage();
                    //if (reqFont.SizeInPoints == 14 && cacheImg != null)
                    //{
                    //    totalGlyphsImg = cacheImg;
                    //}
                    //totalGlyphsImg = Sharpen(totalGlyphsImg, 1); //test shapen primary image
                    //-
                    //
                    //create atlas
                    fontAtlas            = atlasBuilder.CreateSimpleFontAtlas();
                    fontAtlas.TotalGlyph = totalGlyphsImg;
#if DEBUG
                    //save glyph image for debug
                    //PixelFarm.Agg.ActualImage.SaveImgBufferToPngFile(
                    //    totalGlyphsImg.GetImageBuffer(),
                    //    totalGlyphsImg.Width * 4,
                    //    totalGlyphsImg.Width, totalGlyphsImg.Height,
                    //    "d:\\WImageTest\\total_" + reqFont.Name + "_" + reqFont.SizeInPoints + ".png");
                    ////save image to cache
                    SaveImgBufferToFile(totalGlyphsImg, fontTextureImg);
#endif

                    //cache the atlas
                    _createdAtlases.Add(fontKey, fontAtlas);
                    //
                    //calculate some commonly used values
                    fontAtlas.SetTextureScaleInfo(
                        resolvedTypeface.CalculateScaleToPixelFromPointSize(fontAtlas.OriginalFontSizePts),
                        resolvedTypeface.CalculateScaleToPixelFromPointSize(reqFont.SizeInPoints));
                    //TODO: review here, use scaled or unscaled values
                    fontAtlas.SetCommonFontMetricValues(
                        resolvedTypeface.Ascender,
                        resolvedTypeface.Descender,
                        resolvedTypeface.LineGap,
                        resolvedTypeface.CalculateRecommendLineSpacing());

                    ///
#if DEBUG
                    _dbugStopWatch.Stop();
                    System.Diagnostics.Debug.WriteLine("build font atlas: " + _dbugStopWatch.ElapsedMilliseconds + " ms");
#endif

                    //save font info to cache
                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                    {
                        atlasBuilder.SaveAtlasInfo(ms);
                        StorageService.Provider.SaveData(fontTextureInfoFile, ms.ToArray());
                    }
                }
            }

            glBmp = _loadedGlyphs.GetOrCreateNewOne(fontAtlas);
            return(fontAtlas);
        }