// ------------------------------------------------------------------ /// Rebuild the kerningTable to store key <first char, second char> to value kerning amount // ------------------------------------------------------------------ public void RebuildKerningTable() { // 如果大部分字符的kerning数量都在10个以下,可以直接线性存到CharInfo里。 if (kerningTable == null) { kerningTable = new Dictionary <KerningTableKey, int> (kernings.Count, KerningTableKey.Comparer.instance); } kerningTable.Clear(); for (int i = 0; i < kernings.Count; ++i) { KerningInfo k = kernings [i]; kerningTable[new KerningTableKey((char)k.first, (char)k.second)] = k.amount; } }
private KerningInfo GetKerningInfo(char ch) { float[] widths = new float[1]; _paint.GetTextWidths(new char[] { ch }, 0, 1, widths); //var bounds = new Rect(); //var s = ch.ToString(); //_paint.GetTextBounds(s, 0, 1, bounds); var result = new KerningInfo(); //result.A = -bounds.Left; //result.B = bounds.Width() + bounds.Left; result.B = widths[0]; return(result); }
public FontDefine(Reader reader) { if (Settings.s.platform == Settings.Platform.GC || Settings.s.platform == Settings.Platform.Xbox360 || Settings.s.mode == Settings.Mode.RaymanArenaXbox) { name = reader.ReadString(50); } characters = new CharacterDefine[256]; for (int i = 0; i < characters.Length; i++) { characters[i] = new CharacterDefine(reader); } if (Settings.s.game != Settings.Game.Dinosaur && Settings.s.game != Settings.Game.LargoWinch) { kerningInfo = new KerningInfo[200]; for (int i = 0; i < kerningInfo.Length; i++) { kerningInfo[i] = new KerningInfo(reader); } unk = reader.ReadUInt16(); } }
public void Convert(Glyph[] glyphs, KerningInfo[] kernings) { DirectoryInfo dirInfo = null; try { dirInfo = new DirectoryInfo(outputPath); } catch(Exception err) { MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Array.Sort(glyphs, new GlyphComparer()); Bitmap output = new Bitmap(textureWidth, textureHeight); Graphics g = Graphics.FromImage(output); uint x = 0, y = 0; uint maxHeight = 0; int fileNo = 0; StreamWriter writer = new StreamWriter(dirInfo.FullName + "/font.lua"); foreach (Glyph glyph in glyphs) { if (x + glyph.Width > output.Width) { x = 0; y += maxHeight+1; if (y + maxHeight > output.Height) { y = 0; g.Dispose(); SaveImage(output, string.Format(dirInfo.FullName + Path.DirectorySeparatorChar +"{0}", fileNo), format); writer.WriteLine("Image {"); writer.WriteLine("\tpath = \"{0}.{1}\",", fileNo, format); writer.WriteLine("\tindex = {0}", fileNo); writer.WriteLine("}"); output.Dispose(); fileNo++; output = new Bitmap(textureWidth, textureHeight); g = Graphics.FromImage(output); } } if (x == 0) maxHeight = glyph.Height; if (glyph.ImagePath != string.Empty) { Bitmap bitmap = new Bitmap(glyph.ImagePath); g.DrawImage(bitmap, x, y); bitmap.Dispose(); } uint code = glyph.Code; char ch = Char.ConvertFromUtf32((int) code)[0]; byte[] buffer = new byte[4]; byte[] src = Encoding.UTF8.GetBytes(ch.ToString()); Array.Reverse(src); Array.Copy(src, buffer, src.Length) ; code = BitConverter.ToUInt32(buffer, 0); writer.WriteLine("Glyph{"); writer.WriteLine("\tcode = {0},",code); writer.WriteLine("\timageIndex = {0},", fileNo); writer.WriteLine("\tcx = {0},", x); writer.WriteLine("\tcy = {0},", y); writer.WriteLine("\twidth = {0},", glyph.Width); writer.WriteLine("\theight = {0},", glyph.Height); writer.WriteLine("\tadv = {0},", glyph.HorizontalAdvance); writer.WriteLine("\tbearingX = {0},", glyph.HorizontalBearingX); writer.WriteLine("\tbearingY = {0},", glyph.HorizontalBearingY); writer.WriteLine("}"); x += glyph.Width+1; } SaveImage(output, string.Format(dirInfo.FullName + "\\{0}", fileNo), format); writer.WriteLine("Image {"); writer.WriteLine("\tpath = \"{0}.{1}\",", fileNo, format); writer.WriteLine("\tindex = {0}", fileNo); writer.WriteLine("}"); foreach(KerningInfo info in kernings) { writer.WriteLine("KerningPair {"); writer.WriteLine("\tleft = {0},", info.LeftChar); writer.WriteLine("\tright = {0},", info.RightChar); writer.WriteLine("\thadjust = {0},", info.HorizontalAdjust); writer.WriteLine("\tvadjust = {0}", info.VerticalAdjust); writer.WriteLine("}"); } g.Dispose(); output.Dispose(); writer.Close(); }
private KerningInfo GetKerningInfo(char ch) { float[] widths = new float[1]; _paint.GetTextWidths(new char[] {ch}, 0, 1, widths); //var bounds = new Rect(); //var s = ch.ToString(); //_paint.GetTextBounds(s, 0, 1, bounds); var result = new KerningInfo(); //result.A = -bounds.Left; //result.B = bounds.Width() + bounds.Left; result.B = widths[0]; return result; }
private void ApplyTag(Dictionary <string, string> tag) { switch (tag["tagtype"]) { case "info": { if (tag.ContainsKey("face")) { GenInfo.FontFace = tag["face"]; } if (tag.ContainsKey("size")) { GenInfo.Size = int.Parse(tag["size"]); } if (tag.ContainsKey("bold")) { GenInfo.Bold = int.Parse(tag["bold"]) == 1 ? true : false; } if (tag.ContainsKey("italic")) { GenInfo.Italic = int.Parse(tag["italic"]) == 1 ? true : false; } if (tag.ContainsKey("charset")) { GenInfo.Charset = tag["charset"]; } if (tag.ContainsKey("unicode")) { GenInfo.IsUnicode = int.Parse(tag["unicode"]) == 1 ? true : false; } if (tag.ContainsKey("stretchH")) { GenInfo.StretchHeight = int.Parse(tag["stretchH"]); } if (tag.ContainsKey("smooth")) { GenInfo.Smoothing = int.Parse(tag["smooth"]) == 1 ? true : false; } if (tag.ContainsKey("aa")) { GenInfo.SupersamplingLevel = int.Parse(tag["aa"]); } if (tag.ContainsKey("padding")) { GenInfo.CharPadding = ParsePadding(tag["padding"]); } if (tag.ContainsKey("spacing")) { GenInfo.CharSpacing = ParsePoint(tag["spacing"]); } if (tag.ContainsKey("outline")) { GenInfo.OutlineWidth = int.Parse(tag["outline"]); } break; } case "common": { if (tag.ContainsKey("lineHeight")) { CommonInfo.LineHeight = int.Parse(tag["lineHeight"]); } if (tag.ContainsKey("base")) { CommonInfo.BaseHeight = int.Parse(tag["base"]); } if (tag.ContainsKey("scaleW")) { CommonInfo.TexScaleWidth = int.Parse(tag["scaleW"]); } if (tag.ContainsKey("scaleH")) { CommonInfo.TexScaleHeight = int.Parse(tag["scaleH"]); } if (tag.ContainsKey("pages")) { CommonInfo.PageCount = int.Parse(tag["pages"]); } if (tag.ContainsKey("packed")) { CommonInfo.Packed = int.Parse(tag["packed"]) == 1 ? true : false; } if (tag.ContainsKey("alphaChnl")) { CommonInfo.AlphaChannelMode = (ChannelMode)int.Parse(tag["alphaChnl"]); } if (tag.ContainsKey("redChnl")) { CommonInfo.RedChannelMode = (ChannelMode)int.Parse(tag["redChnl"]); } if (tag.ContainsKey("greenChnl")) { CommonInfo.GreenChannelMode = (ChannelMode)int.Parse(tag["greenChnl"]); } if (tag.ContainsKey("blueChnl")) { CommonInfo.BlueChannelMode = (ChannelMode)int.Parse(tag["blueChnl"]); } break; } case "page": { int texId = int.Parse(tag["id"]); if (PageTexPaths.Length <= texId) { Array.Resize(ref PageTexPaths, texId + 1); } PageTexPaths[texId] = baseDir + "/" + tag["file"]; break; } case "char": { CharacterInfo thisChr = new CharacterInfo(); thisChr.Id = int.Parse(tag["id"]); thisChr.TexCoordX = int.Parse(tag["x"]); thisChr.TexCoordY = int.Parse(tag["y"]); thisChr.Width = int.Parse(tag["width"]); thisChr.Height = int.Parse(tag["height"]); thisChr.TexturePage = int.Parse(tag["page"]); if (tag.ContainsKey("xoffset")) { thisChr.XOffset = int.Parse(tag["xoffset"]); } if (tag.ContainsKey("yoffset")) { thisChr.YOffset = int.Parse(tag["yoffset"]); } if (tag.ContainsKey("xadvance")) { thisChr.XAdvance = int.Parse(tag["xadvance"]); } if (tag.ContainsKey("chnl")) { thisChr.Channels = (CharacterChannels)int.Parse(tag["chnl"]); } if (Characters.ContainsKey(thisChr.Id)) { Characters[thisChr.Id] = thisChr; } else { Characters.Add(thisChr.Id, thisChr); } break; } case "kerning": { KerningInfo thisKrn = new KerningInfo(); thisKrn.CharOne = int.Parse(tag["first"]); thisKrn.CharTwo = int.Parse(tag["second"]); thisKrn.Amount = int.Parse(tag["amount"]); Tuple <int, int> pairkey = new Tuple <int, int>(thisKrn.CharOne, thisKrn.CharTwo); if (KernPairs.ContainsKey(pairkey)) { KernPairs[pairkey] = thisKrn; } else { KernPairs.Add(pairkey, thisKrn); } break; } default: break; } }