public void Read(FileReader reader, FFNT header) { reader.ReadSignature(4, "CMAP "); uint SectionSize = reader.ReadUInt32(); if (header.Version > 0x3000000) { CharacterCodeBegin = reader.ReadUInt32(); CharacterCodeEnd = reader.ReadUInt32(); MappingMethod = reader.ReadEnum <Mapping>(true); Padding = reader.ReadUInt16(); } else { CharacterCodeBegin = reader.ReadUInt16(); CharacterCodeEnd = reader.ReadUInt16(); MappingMethod = reader.ReadEnum <Mapping>(true); Padding = reader.ReadUInt16(); } uint NextMapOffset = reader.ReadUInt32(); if (NextMapOffset != 0) { reader.Seek(NextMapOffset - 8, SeekOrigin.Current); } }
public void Read(FileReader reader, FFNT header, List <CWDH> CharacterWidths) { long pos = reader.Position; reader.ReadSignature(4, "CWDH"); SectionSize = reader.ReadUInt32(); StartIndex = reader.ReadUInt16(); EndIndex = reader.ReadUInt16(); uint NextWidthSectionOffset = reader.ReadUInt32(); for (ushort i = StartIndex; i <= EndIndex; i++) { var entry = new CharacterWidthEntry(); entry.LeftWidth = reader.ReadSByte(); entry.GlyphWidth = reader.ReadByte(); entry.Width = reader.ReadByte(); WidthEntries.Add(entry); } if (NextWidthSectionOffset != 0) { reader.SeekBegin((int)NextWidthSectionOffset - 8); NextWidthSection = new CWDH(); NextWidthSection.Read(reader, header, CharacterWidths); CharacterWidths.Add(NextWidthSection); } else { reader.SeekBegin(pos + SectionSize); } }
public void Read(FileReader reader, FFNT Header) { if (Header.Platform == FFNT.PlatformType.NX) { uint FirstWordCount = reader.ReadUInt16(); uint Offset = reader.ReadUInt16(); } }
public void Write(FileWriter writer, FFNT Header) { long pos = writer.Position; if (BinaryTextureFile != null) { var mem = new System.IO.MemoryStream(); BinaryTextureFile.Save(mem); SheetDataList[0] = mem.ToArray(); } writer.WriteSignature("TGLP"); writer.Write(uint.MaxValue); writer.Write(CellWidth); writer.Write(CellHeight); writer.Write((byte)SheetDataList.Count); writer.Write(MaxCharWidth); writer.Write(SheetDataList[0].Length); writer.Write(BaseLinePos); writer.Write(Format); writer.Write(ColumnCount); writer.Write(RowCount); writer.Write(SheetWidth); writer.Write(SheetHeight); long _ofsSheetBlocks = writer.Position; writer.Write(uint.MaxValue); if (Header.Platform == FFNT.PlatformType.NX) { writer.Align(4096); } else { writer.Align(8192); } long DataPosition = writer.Position; using (writer.TemporarySeek(_ofsSheetBlocks, SeekOrigin.Begin)) { writer.Write((uint)DataPosition); } for (int i = 0; i < SheetDataList.Count; i++) { writer.Write(SheetDataList[i]); } long SectionEndPosition = writer.Position; //End of section. Set the size using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) { writer.Write((uint)(SectionEndPosition - pos)); } }
public void Write(FileWriter writer, FFNT Header) { long pos = writer.Position; writer.WriteSignature("KRNG"); writer.Write(uint.MaxValue); writer.Write(Data); writer.WriteSectionSizeU32(pos + 4, pos, writer.Position); }
public static void GenerateCMAP(FileReader reader, FFNT header) { var fontSection = header.FontSection; var cmap = new CMAP(); fontSection.CodeMap = cmap; }
public void Read(FileReader reader, FFNT Header) { if (Header.Platform == FFNT.PlatformType.NX) { ushort FirstWordCount = reader.ReadUInt16(); ushort padding = reader.ReadUInt16(); FirstTable = new KerningFirstTable(); FirstTable.Read(reader, Header); } }
public void Write(FileWriter writer, FFNT header) { long pos = writer.Position; writer.WriteSignature("FINF"); writer.Write(uint.MaxValue); writer.Write(Type, true); writer.Write(Height); writer.Write(Width); writer.Write(Ascent); writer.Write(LineFeed); writer.Write(AlterCharIndex); writer.Write(DefaultLeftWidth); writer.Write(DefaultGlyphWidth); writer.Write(DefaultCharWidth); writer.Write(CharEncoding, true); long _ofsTGLP = writer.Position; writer.Write(uint.MaxValue); long _ofsCWDH = writer.Position; writer.Write(uint.MaxValue); long _ofsCMAP = writer.Position; writer.Write(uint.MaxValue); //Save section size long endPos = writer.Position; using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) { writer.Write((uint)(endPos - pos)); } //Save Texture Glyph writer.WriteUint32Offset(_ofsTGLP, -8); TextureGlyph.Write(writer, header); //Save Character Widths writer.WriteUint32Offset(_ofsCWDH, -8); CharacterWidth.Write(writer, header); //Save Code Maps writer.WriteUint32Offset(_ofsCMAP, -8); CodeMap.Write(writer, header); }
public void Read(FileReader reader, FFNT header) { string Signature = reader.ReadString(4, Encoding.ASCII); if (Signature != "TGLP") { throw new Exception($"Invalid signature {Signature}! Expected TGLP."); } SectionSize = reader.ReadUInt32(); CellWidth = reader.ReadByte(); CellHeight = reader.ReadByte(); if (header.Platform <= FFNT.PlatformType.Ctr && header.Version < 0x04000000) { BaseLinePos = reader.ReadByte(); MaxCharWidth = reader.ReadByte(); SheetSize = reader.ReadUInt32(); SheetCount = (byte)reader.ReadUInt16(); } else { SheetCount = reader.ReadByte(); MaxCharWidth = reader.ReadByte(); SheetSize = reader.ReadUInt32(); BaseLinePos = reader.ReadUInt16(); } Format = reader.ReadUInt16(); RowCount = reader.ReadUInt16(); ColumnCount = reader.ReadUInt16(); SheetWidth = reader.ReadUInt16(); SheetHeight = reader.ReadUInt16(); uint sheetOffset = reader.ReadUInt32(); using (reader.TemporarySeek(sheetOffset, SeekOrigin.Begin)) { for (int i = 0; i < SheetCount; i++) { SheetDataList.Add(reader.ReadBytes((int)SheetSize)); if (SheetDataList[i].Length != SheetSize) { throw new Exception("SheetSize mis match!"); } } } }
public void Load(System.IO.Stream stream) { FFNT bffnt = new FFNT(); bffnt.Read(new FileReader(stream)); TGLP tglp = bffnt.finf.tglp; int i = 0; foreach (byte[] texture in tglp.SheetDataList) { SheetEntry sheet = new SheetEntry(); sheet.data = texture; sheet.Text = "Sheet" + i++; } }
public void Load() { IsActive = true; FFNT bffnt = new FFNT(); bffnt.Read(new FileReader(new MemoryStream(Data))); TGLP tglp = bffnt.finf.tglp; int i = 0; foreach (byte[] texture in tglp.SheetDataList) { SheetEntry sheet = new SheetEntry(); sheet.data = texture; sheet.Text = "Sheet" + i++; } }
public static string ToYaml(FFNT header) { YamlMappingNode mapping = new YamlMappingNode(); mapping.Add("Platform", header.Platform.ToString()); mapping.Add("Version", header.Version.ToString("X")); mapping.Add("FontInfo", SaveFontInfo(header.FontSection)); mapping.Add("KerningTable", SaveKerningTable(header.KerningTable)); var doc = new YamlDocument(mapping); YamlStream stream = new YamlStream(doc); var buffer = new StringBuilder(); using (var writer = new StringWriter(buffer)) { stream.Save(writer, true); return(writer.ToString()); } }
public void Read(FileReader reader, FFNT Header, uint size) { Data = reader.ReadBytes((int)(size - 8)); /* if (Header.Platform == FFNT.PlatformType.NX) * { * ushort FirstWordCount = reader.ReadUInt16(); * ushort padding = reader.ReadUInt16(); * * FirstTable = new KerningFirstTable(); * FirstTable.Read(reader, Header); * } * else * { * ushort FirstWordCount = reader.ReadUInt16(); * * FirstTable = new KerningFirstTable(); * FirstTable.Read(reader, Header); * }*/ }
public void Load(System.IO.Stream stream) { Text = FileName; bffnt = new FFNT(); bffnt.Read(new FileReader(stream)); TGLP tglp = bffnt.GetFontSection().tglp; var textureFolder = new TreeNode("Textures"); Nodes.Add(textureFolder); if (tglp.SheetDataList.Count > 0) { var bntx = STFileLoader.OpenFileFormat("Sheet_0", Utils.CombineByteArray(tglp.SheetDataList.ToArray())); if (bntx != null) { textureFolder.Nodes.Add((BNTX)bntx); } else { for (int s = 0; s < tglp.SheetDataList.Count; s++) { var surface = new Gx2ImageBlock(); surface.Text = $"Sheet_{s}"; surface.Load(tglp, s); textureFolder.Nodes.Add(surface); } } } int i = 0; foreach (byte[] texture in tglp.SheetDataList) { // BNTX file = (BNTX)STFileLoader.OpenFileFormat("Sheet" + i++, texture); // Nodes.Add(file); } }
public void Load() { IsActive = true; FFNT bffnt = new FFNT(); bffnt.Read(new FileReader(new MemoryStream(Data))); TGLP tglp = bffnt.finf.tglp; EditorRoot = new TreeNodeFile(FileName, this); int i = 0; foreach (byte[] texture in tglp.SheetDataList) { SheetEntry sheet = new SheetEntry(); sheet.data = texture; sheet.Text = "Sheet" + i++; EditorRoot.Nodes.Add(sheet); } }
public void Write(FileWriter writer, FFNT Header) { Header.BlockCounter += 1; long pos = writer.Position; writer.WriteSignature("CWDH"); writer.Write(uint.MaxValue); //Section Size writer.Write(StartIndex); writer.Write(EndIndex); long DataPos = writer.Position; writer.Write(0); //NextOffset for (int i = 0; i < WidthEntries.Count; i++) { writer.Write(WidthEntries[i].LeftWidth); writer.Write(WidthEntries[i].GlyphWidth); writer.Write(WidthEntries[i].Width); } writer.Align(4); if (NextWidthSection != null) { writer.WriteUint32Offset(DataPos, -8); NextWidthSection.Write(writer, Header); } //Save section size long endPos = writer.Position; using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) { writer.Write((uint)(endPos - pos)); } }
public void Load(System.IO.Stream stream) { CanSave = true; bffnt = new FFNT(); bffnt.Read(new FileReader(stream)); TGLP tglp = bffnt.FontSection.TextureGlyph; if (tglp.SheetDataList.Count > 0) { var bntx = STFileLoader.OpenFileFormat("Sheet_0", Utils.CombineByteArray(tglp.SheetDataList.ToArray())); if (bntx != null) { tglp.BinaryTextureFile = (BNTX)bntx; } else { for (int s = 0; s < tglp.SheetDataList.Count; s++) { var surface = new Gx2ImageBlock(); surface.Text = $"Sheet_{s}"; surface.Load(tglp, s); tglp.Gx2Textures.Add(surface); } } } int i = 0; foreach (byte[] texture in tglp.SheetDataList) { // BNTX file = (BNTX)STFileLoader.OpenFileFormat("Sheet" + i++, texture); // Nodes.Add(file); } }
public void Load(System.IO.Stream stream) { PluginRuntime.BxfntFiles.Add(this); CanSave = true; bffnt = new FFNT(); bffnt.Read(new FileReader(stream)); TGLP tglp = bffnt.FontSection.TextureGlyph; if (tglp.SheetDataList.Count > 0) { if (bffnt.Platform == FFNT.PlatformType.NX) { var bntx = STFileLoader.OpenFileFormat( new MemoryStream(Utils.CombineByteArray(tglp.SheetDataList.ToArray())), "Sheet_0"); if (bntx != null) { tglp.BinaryTextureFile = (BNTX)bntx; } } else if (bffnt.Platform == FFNT.PlatformType.Cafe) { for (int s = 0; s < tglp.SheetDataList.Count; s++) { var surface = new Gx2ImageBlock(); surface.Text = $"Sheet_{s}"; surface.Load(tglp, s); tglp.Textures.Add(surface); } } else if (bffnt.Platform == FFNT.PlatformType.Ctr) { for (int s = 0; s < tglp.SheetDataList.Count; s++) { var surface = new CtrImageBlock(); surface.Text = $"Sheet_{s}"; surface.Load(tglp, s); surface.GetBitmap().Save($"Image{s}.png"); tglp.Textures.Add(surface); } } else { for (int s = 0; s < tglp.SheetDataList.Count; s++) { var surface = new RevImageBlock(); surface.Text = $"Sheet_{s}"; surface.Load(tglp, s); surface.GetBitmap().Save($"Image{s}.png"); tglp.Textures.Add(surface); } } } int i = 0; foreach (byte[] texture in tglp.SheetDataList) { // BNTX file = (BNTX)STFileLoader.OpenFileFormat("Sheet" + i++, texture); // Nodes.Add(file); } }
public void Write(FileWriter writer, FFNT header) { long pos = writer.Position; SheetSize = (uint)SheetDataList[0].Length; SheetCount = (byte)SheetDataList.Count; if (BinaryTextureFile != null) { var mem = new System.IO.MemoryStream(); BinaryTextureFile.Save(mem); var binaryFile = mem.ToArray(); SheetDataList.Clear(); SheetSize = (uint)(binaryFile.Length / SheetCount); uint offset = 0; for (int i = 0; i < SheetCount; i++) { SheetDataList.Add(Utils.SubArray(binaryFile, offset, SheetSize)); offset += SheetSize; } } writer.WriteSignature("TGLP"); writer.Write(uint.MaxValue); writer.Write(CellWidth); writer.Write(CellHeight); if (header.Platform <= FFNT.PlatformType.Ctr && header.Version < 0x04000000) { writer.Write((byte)BaseLinePos); writer.Write(MaxCharWidth); writer.Write(SheetSize); writer.Write((ushort)SheetCount); } else { writer.Write((byte)SheetCount); writer.Write(MaxCharWidth); writer.Write(SheetSize); writer.Write(BaseLinePos); } writer.Write(Format); writer.Write(RowCount); writer.Write(ColumnCount); writer.Write(SheetWidth); writer.Write(SheetHeight); long _ofsSheetBlocks = writer.Position; writer.Write(uint.MaxValue); if (header.Platform == FFNT.PlatformType.NX) { writer.Align(4096); } else if (header.Platform == FFNT.PlatformType.Cafe) { writer.Align(8192); } else if (header.Platform == FFNT.PlatformType.Ctr) { writer.Align(64); } else { writer.Align(32); } long DataPosition = writer.Position; using (writer.TemporarySeek(_ofsSheetBlocks, SeekOrigin.Begin)) { writer.Write((uint)DataPosition); } for (int i = 0; i < SheetDataList.Count; i++) { writer.Write(SheetDataList[i]); } long SectionEndPosition = writer.Position; //End of section. Set the size using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) { writer.Write((uint)(SectionEndPosition - pos)); } }
public void Read(FileReader reader, FFNT header) { CharacterWidths = new List <CWDH>(); CodeMaps = new List <CMAP>(); string Signature = reader.ReadString(4, Encoding.ASCII); if (Signature != "FINF") { throw new Exception($"Invalid signature {Signature}! Expected FINF."); } Size = reader.ReadUInt32(); if (header.Platform <= FFNT.PlatformType.Ctr && header.Version < 0x04000000) { Type = reader.ReadEnum <FontType>(true); LineFeed = reader.ReadByte(); AlterCharIndex = reader.ReadUInt16(); DefaultLeftWidth = reader.ReadByte(); DefaultGlyphWidth = reader.ReadByte(); DefaultCharWidth = reader.ReadByte(); CharEncoding = reader.ReadEnum <CharacterCode>(true); uint tglpOffset = reader.ReadUInt32(); uint cwdhOffset = reader.ReadUInt32(); uint cmapOffset = reader.ReadUInt32(); Height = reader.ReadByte(); Width = reader.ReadByte(); Ascent = reader.ReadByte(); reader.ReadByte(); //Padding //Add counter for TGLP //Note the other counters are inside sections due to recusive setup header.BlockCounter += 1; TextureGlyph = new TGLP(); using (reader.TemporarySeek(tglpOffset - 8, SeekOrigin.Begin)) TextureGlyph.Read(reader, header); CharacterWidth = new CWDH(); CharacterWidths.Add(CharacterWidth); using (reader.TemporarySeek(cwdhOffset - 8, SeekOrigin.Begin)) CharacterWidth.Read(reader, header, CharacterWidths); CodeMap = new CMAP(); CodeMaps.Add(CodeMap); using (reader.TemporarySeek(cmapOffset - 8, SeekOrigin.Begin)) CodeMap.Read(reader, header, CodeMaps); } else { Type = reader.ReadEnum <FontType>(true); Height = reader.ReadByte(); Width = reader.ReadByte(); Ascent = reader.ReadByte(); LineFeed = reader.ReadUInt16(); AlterCharIndex = reader.ReadUInt16(); DefaultLeftWidth = reader.ReadByte(); DefaultGlyphWidth = reader.ReadByte(); DefaultCharWidth = reader.ReadByte(); CharEncoding = reader.ReadEnum <CharacterCode>(true); uint tglpOffset = reader.ReadUInt32(); uint cwdhOffset = reader.ReadUInt32(); uint cmapOffset = reader.ReadUInt32(); //Add counter for TGLP //Note the other counters are inside sections due to recusive setup header.BlockCounter += 1; TextureGlyph = new TGLP(); using (reader.TemporarySeek(tglpOffset - 8, SeekOrigin.Begin)) TextureGlyph.Read(reader, header); CharacterWidth = new CWDH(); CharacterWidths.Add(CharacterWidth); using (reader.TemporarySeek(cwdhOffset - 8, SeekOrigin.Begin)) CharacterWidth.Read(reader, header, CharacterWidths); CodeMap = new CMAP(); CodeMaps.Add(CodeMap); using (reader.TemporarySeek(cmapOffset - 8, SeekOrigin.Begin)) CodeMap.Read(reader, header, CodeMaps); } }
public void Read(FileReader reader, FFNT header, List <CMAP> CodeMaps) { uint CodeBegin = 0; uint CodeEnd = 0; long pos = reader.Position; reader.ReadSignature(4, "CMAP"); SectionSize = reader.ReadUInt32(); if (header.Platform == FFNT.PlatformType.NX) { CodeBegin = reader.ReadUInt32(); CodeEnd = reader.ReadUInt32(); MappingMethod = reader.ReadEnum <Mapping>(true); Padding = reader.ReadUInt16(); } else { CodeBegin = reader.ReadUInt16(); CodeEnd = reader.ReadUInt16(); MappingMethod = reader.ReadEnum <Mapping>(true); Padding = reader.ReadUInt16(); } CharacterCodeBegin = (char)CodeBegin; CharacterCodeEnd = (char)CodeEnd; uint NextMapOffset = reader.ReadUInt32(); //Mapping methods from https: //github.com/IcySon55/Kuriimu/blob/f670c2719affc1eaef8b4c40e40985881247acc7/src/Cetera/Font/BFFNT.cs#L211 switch (MappingMethod) { case Mapping.Direct: var charOffset = reader.ReadUInt16(); for (char i = CharacterCodeBegin; i <= CharacterCodeEnd; i++) { int idx = i - CharacterCodeBegin + charOffset; header.FontSection.CodeMapDictionary[i] = idx < ushort.MaxValue ? idx : 0; } MappingData = new CMAPDirect(); ((CMAPDirect)MappingData).Offset = charOffset; break; case Mapping.Table: List <short> table = new List <short>(); for (char i = CharacterCodeBegin; i <= CharacterCodeEnd; i++) { short idx = reader.ReadInt16(); if (idx != -1) { header.FontSection.CodeMapDictionary[i] = idx; } table.Add(idx); } MappingData = new CMAPIndexTable(); ((CMAPIndexTable)MappingData).Table = table.ToArray(); break; case Mapping.Scan: var CharEntryCount = reader.ReadUInt16(); if (header.Platform == FFNT.PlatformType.NX) { reader.ReadUInt16(); //Padding } uint[] codes = new uint[CharEntryCount]; short[] indexes = new short[CharEntryCount]; for (int i = 0; i < CharEntryCount; i++) { if (header.Platform == FFNT.PlatformType.NX) { uint charCode = reader.ReadUInt32(); short index = reader.ReadInt16(); short padding = reader.ReadInt16(); if (index != -1) { header.FontSection.CodeMapDictionary[(char)charCode] = index; } codes[i] = charCode; indexes[i] = index; } else { ushort charCode = reader.ReadUInt16(); short index = reader.ReadInt16(); if (index != -1) { header.FontSection.CodeMapDictionary[(char)charCode] = index; } codes[i] = charCode; indexes[i] = index; } } MappingData = new CMAPScanMapping(); ((CMAPScanMapping)MappingData).Codes = codes; ((CMAPScanMapping)MappingData).Indexes = indexes; break; } if (NextMapOffset != 0) { reader.SeekBegin(NextMapOffset - 8); NextCodeMapSection = new CMAP(); NextCodeMapSection.Read(reader, header, CodeMaps); CodeMaps.Add(NextCodeMapSection); } else { reader.SeekBegin(pos + SectionSize); } }
public void Write(FileWriter writer, FFNT Header) { Header.BlockCounter += 1; long pos = writer.Position; writer.WriteSignature("CMAP"); writer.Write(uint.MaxValue); //Section Size if (Header.Platform == FFNT.PlatformType.NX) { writer.Write((uint)CharacterCodeBegin); writer.Write((uint)CharacterCodeEnd); } else { writer.Write((ushort)CharacterCodeBegin); writer.Write((ushort)CharacterCodeEnd); } writer.Write(MappingMethod, true); writer.Seek(2); long DataPos = writer.Position; writer.Write(0); //Next Section Offset //Write the data switch (MappingMethod) { case Mapping.Direct: writer.Write(((CMAPDirect)MappingData).Offset); break; case Mapping.Table: for (int i = 0; i < ((CMAPIndexTable)MappingData).Table.Length; i++) { writer.Write(((CMAPIndexTable)MappingData).Table[i]); } break; case Mapping.Scan: writer.Write((ushort)((CMAPScanMapping)MappingData).Codes.Length); if (Header.Platform == FFNT.PlatformType.NX) { writer.Seek(2); //Padding } for (int i = 0; i < ((CMAPScanMapping)MappingData).Codes.Length; i++) { if (Header.Platform == FFNT.PlatformType.NX) { writer.Write((uint)((CMAPScanMapping)MappingData).Codes[i]); writer.Write(((CMAPScanMapping)MappingData).Indexes[i]); writer.Write((ushort)0); //Padding } else { writer.Write((ushort)((CMAPScanMapping)MappingData).Codes[i]); writer.Write(((CMAPScanMapping)MappingData).Indexes[i]); } } break; } writer.Align(4); //Padding //Save section size long endPos = writer.Position; using (writer.TemporarySeek(pos + 4, SeekOrigin.Begin)) { writer.Write((uint)(endPos - pos)); } if (NextCodeMapSection != null) { writer.WriteUint32Offset(DataPos, -8); NextCodeMapSection.Write(writer, Header); } }