public static bool Generate( List <UInt16> chars, int charOffset, int totWidth, int totHeight, int charWidth, int charHeight, Font font, bool drawGrid, out Bitmap bmp, string savepath) { bmp = new Bitmap(totWidth, totHeight); List <CharUnit> charUnits = new List <CharUnit>(); for (int i = 0; i < chars.Count; i++) { CharUnit cu = new CharUnit(); cu.charVal = chars[i]; cu.x = i % (totWidth / charWidth) * charWidth; cu.y = i / (totWidth / charWidth) * charHeight; cu.actrualWidth = 0; charUnits.Add(cu); } using (Graphics g = Graphics.FromImage(bmp)) { StringFormat stringFormat = new StringFormat(); stringFormat.LineAlignment = StringAlignment.Far; stringFormat.Alignment = StringAlignment.Near; g.FillRectangle(Brushes.Black, 0, 0, totWidth, totHeight); if (drawGrid) { for (int i = 0; i < totWidth; i += charWidth) { g.DrawLine(Pens.Red, i, 0, i, totHeight); } for (int i = 0; i < totHeight; i += charHeight) { g.DrawLine(Pens.Red, 0, i, totWidth, i); } } foreach (CharUnit cu in charUnits) { string c = new string((char)cu.charVal, 1); Rectangle cellArea = new Rectangle( cu.x + charOffset, cu.y, charWidth - charOffset, charHeight); //SizeF charSz = g.MeasureString(c, font, cellArea.Size, StringFormat.GenericTypographic); Size charSz = TextRenderer.MeasureText(g, c, font, cellArea.Size, TextFormatFlags.NoPadding); cu.actrualWidth = charSz.Width; Point charLeftTop = new Point( cu.x + charOffset, cu.y + (charHeight - charSz.Height)); if (drawGrid) { g.DrawRectangle(Pens.Blue, charLeftTop.X, charLeftTop.Y, charSz.Width, charSz.Height); } //g.DrawString(c, font, Brushes.White, charLeftTop); TextRenderer.DrawText(g, c, font, charLeftTop, Color.White, TextFormatFlags.NoPadding); Application.DoEvents(); } } if (savepath != null) { bmp.Save(savepath + "\\font.png", ImageFormat.Png); StreamEx sInf = new StreamEx(savepath + "\\font.inf.dat", System.IO.FileMode.Create, System.IO.FileAccess.Write); sInf.WriteUInt16BigEndian((UInt16)chars.Count); sInf.WriteUInt16BigEndian((UInt16)totWidth); sInf.WriteUInt16BigEndian((UInt16)totHeight); sInf.WriteByte((byte)charWidth); sInf.WriteByte((byte)charHeight); sInf.Close(); StreamEx sCod = new StreamEx(savepath + "\\font.cod.dat", System.IO.FileMode.Create, System.IO.FileAccess.Write); for (int i = 0; i < charUnits.Count; i++) { sCod.WriteUInt16BigEndian(charUnits[i].charVal); sCod.WriteUInt16BigEndian((UInt16)charUnits[i].x); sCod.WriteUInt16BigEndian((UInt16)charUnits[i].y); sCod.WriteUInt16BigEndian((UInt16)charUnits[i].actrualWidth); } } return(true); }
public static bool Generate( List <char> chars, bool gdiRender, TextRenderingHint textRenderingHint, int totWidth, int totHeight, int charWidth, int charHeight, Font font, bool drawGrid, out Bitmap bmp, string savepath, string refFileName) { List <CharUnit> charUnits = new List <CharUnit>(); for (int i = 0; i < chars.Count; i++) { CharUnit cu = new CharUnit(); cu.charVal = chars[i].ToString(); // cu.x = i % (totWidth / charWidth) * charWidth; // cu.y = i / (totWidth / charWidth) * charHeight; // cu.actrualWidth = 0; charUnits.Add(cu); } int currentChannel = 0; bmp = new Bitmap(totWidth, totHeight); using (Graphics g = Graphics.FromImage(bmp)) { //g.PageUnit=GraphicsUnit.Pixel; g.TextRenderingHint = textRenderingHint; //g.SmoothingMode=SmoothingMode.HighQuality; StringFormat stringFormat = StringFormat.GenericTypographic; stringFormat.FormatFlags &= ~StringFormatFlags.MeasureTrailingSpaces; //stringFormat.LineAlignment = StringAlignment.Near; //stringFormat.Alignment = StringAlignment.Near; //stringFormat.FormatFlags = StringFormatFlags. g.FillRectangle(Brushes.Black, 0, 0, totWidth, totHeight); if (drawGrid) { // for (int i = 0; i < totWidth; i += charWidth) // { // g.DrawLine(Pens.Red, i, 0, i, totHeight); // } for (int i = 0; i < totHeight; i += charHeight + 1) { g.DrawLine(Pens.Red, 0, i, totWidth, i); } } Point currentPos = new Point(1, 1); foreach (CharUnit cu in charUnits) { //string c = new string((char)cu.charVal, 1); Rectangle cellArea = new Rectangle( currentPos.X, currentPos.Y, charHeight, charHeight); Size charSz; if (gdiRender) { // GDI渲染 charSz = TextRenderer.MeasureText(g, cu.charVal, font, cellArea.Size, TextFormatFlags.NoPadding); } else { // GDI+渲染 charSz = Size.Round(g.MeasureString(cu.charVal, font, charHeight * 2, stringFormat)); } cu.actrualWidth = charSz.Width; cu.visualWidth = cu.actrualWidth; cu.adjustX = 0; if (currentPos.X + cu.actrualWidth + 2 >= totWidth) { currentPos.X = 1; currentPos.Y += charHeight + 1; } if (currentPos.Y + charHeight + 1 >= totHeight) { // save if (savepath != null) { bmp.Save(savepath + "\\" + refFileName + GetChannelText(currentChannel) + ".png", ImageFormat.Png); } g.FillRectangle(Brushes.Black, 0, 0, totWidth, totHeight); currentChannel++; currentPos.X = 1; currentPos.Y = 1; } cu.x = currentPos.X; cu.y = currentPos.Y; cu.channel = currentChannel; if (gdiRender) { // GDI渲染 TextRenderer.DrawText(g, cu.charVal, font, currentPos, Color.White, TextFormatFlags.NoPadding); } else { // GDI+渲染 g.DrawString(cu.charVal, font, Brushes.White, currentPos.X, currentPos.Y, stringFormat); } // 绘制边框 if (drawGrid) { g.DrawRectangle(Pens.White, currentPos.X, currentPos.Y, cu.actrualWidth, charHeight - 1); Application.DoEvents(); } currentPos.X += cu.actrualWidth + 2; } } if (savepath != null) { bmp.Save(savepath + "\\" + refFileName + GetChannelText(currentChannel) + ".png", ImageFormat.Png); StreamEx s = new StreamEx(savepath + "\\" + refFileName + ".new", System.IO.FileMode.Create, System.IO.FileAccess.Write); // s.Position = 8; s.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0xB0, 0x16, 0x8C, 0x05, 0x55, 0x01, 0xFF }); s.WriteInt32BigEndian(charHeight); s.WriteInt32BigEndian(chars.Count); s.WriteInt32BigEndian(totWidth); s.WriteInt32BigEndian(totHeight); s.WriteInt32BigEndian(0); // byte[] indexFixData = new byte[8] { 0xCF, 0xA7, 0xE0, 0xA1, 0x08, 0x55, 0x55, 0xFF }; foreach (CharUnit cu in charUnits) { s.Write(indexFixData); byte[] sjisCod = TextEncoding.ShiftJIS.GetBytes(cu.charVal); s.WriteInt32BigEndian(getCodeInt(sjisCod)); byte[] utf8Cod = TextEncoding.UTF8.GetBytes(cu.charVal); s.WriteInt32BigEndian(getCodeInt(utf8Cod)); s.WriteInt32BigEndian(cu.x); s.WriteInt32BigEndian(cu.y); s.WriteInt32BigEndian(cu.actrualWidth); s.WriteInt32BigEndian(cu.adjustX); s.WriteInt32BigEndian(cu.visualWidth); s.WriteInt32BigEndian(cu.channel); } // s.Write(new byte[] { 0xCC, 0x1C, 0x19, 0x19, 0x01, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0xFD, 0x16, 0xE3, 0xB5, 0x03, 0x15, 0xFF, 0xFF, 0x00, 0x00, 0xC5, 0xB8, 0x00, 0x00, 0xC3, 0xBB, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0x16, 0xE3, 0xB5, 0x03, 0x15, 0xFF, 0xFF, 0x00, 0x00, 0xC5, 0xB8, 0x00, 0x00, 0xC3, 0xBC, 0xFF, 0xFF, 0xFF, 0xFE, 0x69, 0xA4, 0x8E, 0xC4, 0x00 }); while (s.Position % 0x10 != 0) { s.WriteByte(0xff); } // int endBlockOffset = (int)s.Position; s.Write(new byte[] { 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x8E, 0xB0, 0x16, 0x8C, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xA7, 0xE0, 0xA1, 0x00, 0x00, 0x00, 0x04, 0xCC, 0x1C, 0x19, 0x19, 0x00, 0x00, 0x00, 0x08, 0xFD, 0x16, 0xE3, 0xB5, 0x00, 0x00, 0x00, 0x10, 0x69, 0xA4, 0x8E, 0xC4, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x4E, 0x46, 0x00, 0x43, 0x48, 0x52, 0x00, 0x4B, 0x45, 0x52, 0x4E, 0x49, 0x4E, 0x46, 0x00, 0x4B, 0x45, 0x52, 0x4E, 0x00, 0x45, 0x4E, 0x44, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x74, 0x32, 0x62, 0xFE, 0x01, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }); // s.Position = 0; s.WriteInt32BigEndian((int)s.Length / 0x28); s.WriteInt32BigEndian(endBlockOffset); s.Close(); } return(true); }