private static void Create(int maxTextureWidth, int maxTextureHeight, int maxTextureCount, GlyphServer server, List <ChunkBase> chunkList) { var context = new PagesContext(maxTextureWidth, maxTextureHeight, maxTextureCount); foreach (var item in chunkList) { item.Put(context); } Bitmap[] bitmaps = GenerateBitmaps(chunkList, context); PrintChunks(chunkList, context, bitmaps); FillDictionary(chunkList, context, server.dictionary, bitmaps[0].Width, bitmaps[0].Height); Texture texture = GenerateTexture(bitmaps); server.GlyphTexture = texture; server.TextureWidth = bitmaps[0].Width; server.TextureHeight = bitmaps[0].Height; //// test: save bitmaps to disk. //Test(server.dictionary, bitmaps); foreach (var item in bitmaps) { item.Dispose(); } }
private static GlyphServer Create(List <ChunkBase> chunkList, int maxTextureWidth, int maxTextureHeight, int maxTextureCount) { var context = new PagesContext(maxTextureWidth, maxTextureHeight, maxTextureCount); foreach (var item in chunkList) { item.Put(context); } Bitmap[] bitmaps = GenerateBitmaps(chunkList, context.PageList.Count); PrintChunks(chunkList, context, bitmaps); Dictionary <string, GlyphInfo> dictionary = GetDictionary(chunkList, bitmaps[0].Width, bitmaps[0].Height); Texture texture = GenerateTexture(bitmaps); var server = new GlyphServer(); server.dictionary = dictionary; server.GlyphTexture = texture; server.TextureWidth = bitmaps[0].Width; server.TextureHeight = bitmaps[0].Height; //// test: save bitmaps to disk. //Test(server.dictionary, bitmaps); foreach (var item in bitmaps) { item.Dispose(); } return(server); }
private static Bitmap[] GenerateBitmaps(List <ChunkBase> chunkList, PagesContext context) { List <Page> list = context.PageList; var bitmaps = new Bitmap[list.Count]; if (chunkList.Count == 0) { return(bitmaps); } //var sizes = new SizeF[bitmaps.Length]; var widths = new float[bitmaps.Length]; var heights = new float[bitmaps.Length]; for (int i = 0; i < chunkList.Count; i++) { ChunkBase chunk = chunkList[i]; int index = chunk.PageIndex; if (index >= list.Count) // this happens when chunks overflows of max pages. { continue; } float newWidth = chunk.LeftTop.X + chunk.Size.Width; float newHeight = chunk.LeftTop.Y + chunk.Size.Height; if (widths[index] < newWidth) { widths[index] = newWidth; } if (heights[index] < newHeight) { heights[index] = newHeight; } } float maxWidth = 0.0f, maxHeight = 0.0f; for (int i = 0; i < bitmaps.Length; i++) { if (maxWidth < widths[i]) { maxWidth = widths[i]; } if (maxHeight < heights[i]) { maxHeight = heights[i]; } } for (int i = 0; i < bitmaps.Length; i++) { var bmp = new Bitmap((int)Math.Ceiling(maxWidth), (int)Math.Ceiling(maxHeight)); bitmaps[i] = bmp; } return(bitmaps); }
private static void PrintChunks(List <ChunkBase> chunkList, PagesContext context, Bitmap[] bitmaps) { if (chunkList.Count == 0) { return; } var graphicses = new Graphics[bitmaps.Length]; var bmp = new Bitmap(1, 1); var g = Graphics.FromImage(bmp); int currentIndex = 0; float currentWidth = 0; foreach (var chunk in chunkList) { int index = chunk.PageIndex; if (index >= bitmaps.Length) { continue; } if (currentIndex != index) { currentIndex = index; currentWidth = 0; } string bigStr = "丨" + chunk.Text + "丨"; SizeF bigSize = g.MeasureString(bigStr, chunk.TheFont); var bigChunk = new Bitmap((int)bigSize.Width, (int)bigSize.Height); var bigGraphics = Graphics.FromImage(bigChunk); bigGraphics.DrawString(bigStr, chunk.TheFont, Brushes.White, 0, 0); if (graphicses[index] == null) { graphicses[index] = Graphics.FromImage(bitmaps[index]); } graphicses[index].DrawImage(bigChunk, new RectangleF(currentWidth, 0, chunk.Size.Width, chunk.Size.Height), new RectangleF( (bigSize.Width - chunk.Size.Width) / 2, 0, chunk.Size.Width, chunk.Size.Height), GraphicsUnit.Pixel); currentWidth += chunk.Size.Width; } foreach (var grahpics in graphicses) { grahpics.Dispose(); } g.Dispose(); bmp.Dispose(); }
private static void FillDictionary(List <ChunkBase> chunkList, PagesContext context, Dictionary <string, GlyphInfo> dictionary, int pageWidth, int pageHeight) { foreach (var chunk in chunkList) { string characters = chunk.Text; float x0 = chunk.LeftTop.X; float x1 = x0 + chunk.Size.Width; float y0 = chunk.LeftTop.Y; float y1 = y0 + chunk.Size.Height; int textureIndex = chunk.PageIndex; var glyphInfo = new GlyphInfo(characters, new vec2(x0 / pageWidth, y0 / pageHeight), new vec2(x1 / pageWidth, y1 / pageHeight), textureIndex); dictionary.Add(characters, glyphInfo); } }
private static Bitmap[] GenerateBitmaps(List <ChunkBase> chunkList, PagesContext context) { List <Page> list = context.PageList; var bitmaps = new Bitmap[list.Count]; if (chunkList.Count == 0) { return(bitmaps); } var sizes = new SizeF[list.Count]; for (int i = 0; i < chunkList.Count; i++) { ChunkBase chunk = chunkList[i]; if (chunk.PageIndex >= list.Count) // this happens when chunks overflows of max pages. { break; } int index = chunk.PageIndex; sizes[index].Width += chunk.Size.Width; sizes[index].Height = Math.Max(sizes[index].Height, chunk.Size.Height); } float maxWidth = 0.0f, maxHeight = 0.0f; foreach (var size in sizes) { if (maxWidth < size.Width) { maxWidth = size.Width; } if (maxHeight < size.Height) { maxHeight = size.Height; } } for (int i = 0; i < bitmaps.Length; i++) { var bmp = new Bitmap((int)maxWidth, (int)maxHeight); bitmaps[i] = bmp; } return(bitmaps); }
private static void PrintChunks(List <ChunkBase> chunkList, PagesContext context, Bitmap[] bitmaps) { if (chunkList.Count == 0) { return; } //var graphicses = new Graphics[bitmaps.Length]; var bmp = new Bitmap(1, 1); var g = Graphics.FromImage(bmp); foreach (var chunk in chunkList) { int index = chunk.PageIndex; if (index >= bitmaps.Length) { continue; } string bigStr = "丨" + chunk.Text + "丨"; SizeF bigSize = g.MeasureString(bigStr, chunk.TheFont); var bigBmp = new Bitmap((int)Math.Ceiling(bigSize.Width), (int)Math.Ceiling(bigSize.Height)); using (var bigGraphics = Graphics.FromImage(bigBmp)) { bigGraphics.DrawString(bigStr, chunk.TheFont, Brushes.Black, 0, 0); } //if (graphicses[index] == null) { graphicses[index] = Graphics.FromImage(bitmaps[index]); } using (var graphics = Graphics.FromImage(bitmaps[index])) { graphics.DrawImage(bigBmp, new RectangleF(chunk.LeftTop, chunk.Size), new RectangleF( (bigSize.Width - chunk.Size.Width) / 2, 0, chunk.Size.Width, chunk.Size.Height), GraphicsUnit.Pixel); //graphics.DrawRectangle(Pens.Red, chunk.LeftTop.X, chunk.LeftTop.Y, chunk.Size.Width - 1, chunk.Size.Height - 1); //graphics.DrawRectangle(Pens.Red, 0, 0, bitmaps[index].Width - 1, bitmaps[index].Height - 1); } } g.Dispose(); bmp.Dispose(); }
private static void Create(int textureWidth, int textureHeight, int maxTextureCount, GlyphServer server, List <ChunkBase> chunkList) { var context = new PagesContext(textureWidth, textureHeight, maxTextureCount); foreach (var item in chunkList) { item.Put(context); } Bitmap[] bitmaps = GenerateBitmaps(chunkList, context); PrintChunks(chunkList, context, bitmaps); //for (int i = 0; i < bitmaps.Length; i++) //{ // bitmaps[i].Save(string.Format("{0}.png", i)); //} Texture texture = GenerateTexture(bitmaps); server.GlyphTexture = texture; server.TextureWidth = bitmaps[0].Width; server.TextureHeight = bitmaps[0].Height; FillDictionary(chunkList, context, server.dictionary, bitmaps[0].Width, bitmaps[0].Height); }
/// <summary> /// 把这个单元安排到合适的地方去。 /// </summary> /// <param name="context"></param> public abstract void Put(PagesContext context);
/// <summary> /// /// </summary> /// <param name="context"></param> public override void Put(PagesContext context) { if (context == null) { throw new ArgumentNullException("context"); } Graphics graphics = context.UnitGraphics; if (graphics == null) { throw new Exception("Context already disposed!"); } if (context.CurrentIndex >= context.PageList.Count) { return; } // 超过了允许的最多的页数。 Page page = context.PageList[context.CurrentIndex]; PointF leftTop = context.CurrentLeftTop; SizeF bigSize = graphics.MeasureString("丨" + this.Text + "丨", this.TheFont); SizeF emptySize = graphics.MeasureString("丨丨", this.TheFont); var width = (bigSize.Width - emptySize.Width); var height = bigSize.Height; if (page.Width < leftTop.X + width) // 该换行了。 { if (page.Height < leftTop.Y + context.MaxLineHeight + height) // 要换页了。 { context.CurrentIndex++; if (context.PageList.Count <= context.CurrentIndex && // 页用完了。 context.PageList.Count < context.MaxPageCount) // 还可以申请新页。 { var newPage = new Page(context.PageWidth, context.PageHeight); context.PageList.Add(newPage); } // 用下一页。(无论能否申请新页,都按能申请处理。) { this.LeftTop = new PointF(0, 0); this.Size = new SizeF(width, height); this.PageIndex = context.CurrentIndex; context.CurrentLeftTop = new PointF(width, 0); //context.MaxLineHeight = 0; } } else // 仅仅换行,不换页。 { leftTop = new PointF(0, leftTop.Y + context.MaxLineHeight); this.LeftTop = leftTop; this.Size = new SizeF(width, height); this.PageIndex = context.CurrentIndex; context.CurrentLeftTop = new PointF(leftTop.X + width, leftTop.Y); //context.MaxLineHeight = 0; } } else // 当前行还可以放下此chunk。 { this.LeftTop = leftTop; this.Size = new SizeF(width, height); this.PageIndex = context.CurrentIndex; context.CurrentLeftTop = new PointF(leftTop.X + width, leftTop.Y); if (leftTop.X == 0 || // 第一个字符(串) context.MaxLineHeight < height) { context.MaxLineHeight = height; } } }