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) { 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); } }