public void Build( GlyphTextureBitmapGenerator glyphTextureGen, Typeface typeface, float fontSizeInPoints, TextureKind textureKind, GlyphTextureBuildDetail[] buildDetails) { #if DEBUG //overall, glyph atlas generation time System.Diagnostics.Stopwatch dbugStopWatch = new System.Diagnostics.Stopwatch(); dbugStopWatch.Start(); #endif var atlasBuilder = new SimpleBitmapAtlasBuilder(); glyphTextureGen.CreateTextureFontFromBuildDetail( atlasBuilder, typeface, fontSizeInPoints, textureKind, buildDetails); //3. set information before write to font-info atlasBuilder.SpaceCompactOption = SimpleBitmapAtlasBuilder.CompactOption.ArrangeByHeight; atlasBuilder.SetAtlasFontInfo(typeface.Name, fontSizeInPoints); //4. merge all glyph in the builder into a single image using (MemBitmap totalGlyphsImg = atlasBuilder.BuildSingleImage(true)) { if (TextureInfoFilename == null) { //use random suffix string random_suffix = Guid.NewGuid().ToString().Substring(0, 7); string textureName = typeface.Name.ToLower() + "_" + random_suffix + ".info"; string output_imgFilename = textureName + ".png"; TextureInfoFilename = textureName; OutputImgFilename = output_imgFilename; } //5. save atlas info to disk using (FileStream fs = new FileStream(TextureInfoFilename, FileMode.Create)) { atlasBuilder.SaveAtlasInfo(fs); } //6. save total-glyph-image to disk totalGlyphsImg.SaveImage(OutputImgFilename); } #if DEBUG dbugStopWatch.Stop(); dbugBuildTimeMillisec = dbugStopWatch.ElapsedMilliseconds; #endif }
static void CreateSampleMsdfTextureFont(string fontfile, float sizeInPoint, ushort startGlyphIndex, ushort endGlyphIndex, string outputFile) { //sample var reader = new OpenFontReader(); Typeface typeface = null; using (var fs = new FileStream(fontfile, FileMode.Open)) { //1. read typeface from font file typeface = reader.Read(fs); } //sample: create sample msdf texture //------------------------------------------------------------- var builder = new GlyphOutlineBuilder(typeface); //builder.UseTrueTypeInterpreter = this.chkTrueTypeHint.Checked; //builder.UseVerticalHinting = this.chkVerticalHinting.Checked; //------------------------------------------------------------- var atlasBuilder = new SimpleBitmapAtlasBuilder(); atlasBuilder.SetAtlasFontInfo(typeface.Name, sizeInPoint); //create temp folder for each glyph string tempFolderName = "tmp_msdf"; if (Directory.Exists(tempFolderName)) { //DANGER! Directory.Delete(tempFolderName, true); } Directory.CreateDirectory(tempFolderName); if (endGlyphIndex < 1) { endGlyphIndex = (ushort)(typeface.GlyphCount - 1); } for (ushort gindex = startGlyphIndex; gindex <= endGlyphIndex; ++gindex) { //build glyph builder.BuildFromGlyphIndex(gindex, sizeInPoint); var glyphContourBuilder = new ContourBuilder(); var genParams = new MsdfGenParams(); builder.ReadShapes(new GlyphContourBuilder2(glyphContourBuilder)); //genParams.shapeScale = 1f / 64; //we scale later (as original C++ code use 1/64) BitmapAtlasItemSource glyphImg = MsdfImageGen.CreateMsdfImageV1(glyphContourBuilder, genParams); glyphImg.UniqueInt16Name = gindex; atlasBuilder.AddItemSource(glyphImg); using (Bitmap bmp = new Bitmap(glyphImg.Width, glyphImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { int[] buffer = glyphImg.GetImageBuffer(); var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg.Width, glyphImg.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpdata.Scan0, buffer.Length); bmp.UnlockBits(bmpdata); bmp.Save(tempFolderName + "//glyph_" + gindex + ".png"); } } MemBitmap glyphImg2 = atlasBuilder.BuildSingleImage(true); glyphImg2.SaveImage(outputFile); string saveToFile = "a_info.bin"; using (System.IO.FileStream saveFs = new FileStream(saveToFile, FileMode.Create)) { atlasBuilder.SaveAtlasInfo(saveFs); saveFs.Flush(); saveFs.Close(); } // //----------- //test read texture info back var atlasBuilder2 = new SimpleBitmapAtlasBuilder(); using (System.IO.FileStream readFromFs = new FileStream(saveToFile, FileMode.Open)) { var readbackFontAtlas = atlasBuilder2.LoadAtlasInfo(readFromFs); } }