示例#1
0
        public static void GenerateCMAP(FileReader reader, FFNT header)
        {
            var fontSection = header.FontSection;
            var cmap = new CMAP();



            fontSection.CodeMap = cmap;
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
            }
        }