public FFNT(byte[] Data) { EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(Data), Endianness.BigEndian); Header = new FFNTHeader(er); FontInfo = new FINF(er); er.BaseStream.Position = FontInfo.TGLPOffset - 8; TextureGlyph = new TGLP(er); List<CWDH> tmp = new List<CWDH>(); er.BaseStream.Position = FontInfo.CWDHOffset - 8; CWDH Last; do { Last = new CWDH(er); tmp.Add(Last); if (Last.NextCWDHOffset != 0) er.BaseStream.Position = Last.NextCWDHOffset - 8; } while (Last.NextCWDHOffset != 0); CharWidths = tmp.ToArray(); List<CMAP> tmp2 = new List<CMAP>(); er.BaseStream.Position = FontInfo.CMAPOffset - 8; CMAP Last2; do { Last2 = new CMAP(er); tmp2.Add(Last2); if (Last2.NextCMAPOffset != 0) er.BaseStream.Position = Last2.NextCMAPOffset - 8; } while (Last2.NextCMAPOffset != 0); CharMaps = tmp2.ToArray(); er.Close(); }
public FFNT(byte[] Data) { EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(Data), Endianness.LittleEndian); try { Header = new FFNTHeader(er); FontInfo = new FINF(er); TextureGlyph = new TGLP(er); } finally { er.Close(); } }
public CFNT(byte[] Data) { EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(Data), Endianness.LittleEndian); try { Header = new CFNTHeader(er); FontInfo = new FINF(er); er.BaseStream.Position = FontInfo.TGLPOffset - 8; TextureGlyph = new TGLP(er); List <CWDH> tmp = new List <CWDH>(); er.BaseStream.Position = FontInfo.CWDHOffset - 8; CWDH Last; do { Last = new CWDH(er); tmp.Add(Last); if (Last.NextCWDHOffset != 0) { er.BaseStream.Position = Last.NextCWDHOffset - 8; } }while (Last.NextCWDHOffset != 0); CharWidths = tmp.ToArray(); List <CMAP> tmp2 = new List <CMAP>(); er.BaseStream.Position = FontInfo.CMAPOffset - 8; CMAP Last2; do { Last2 = new CMAP(er); tmp2.Add(Last2); if (Last2.NextCMAPOffset != 0) { er.BaseStream.Position = Last2.NextCMAPOffset - 8; } }while (Last2.NextCMAPOffset != 0); CharMaps = tmp2.ToArray(); } finally { er.Close(); } }
public BCFNT(Stream input) { using (var br = new BinaryReaderX(input)) { // @todo: read as sections br.ReadStruct <CFNT>(); if (br.ReadString(4) == "GLGR") { _usesGlgr = true; var glgrSize = br.ReadInt32(); br.BaseStream.Position -= 8; _glgr = br.ReadBytes(glgrSize); } else { br.BaseStream.Position -= 4; } finf = br.ReadStruct <FINF>(); // read TGLP br.BaseStream.Position = finf.tglp_offset - 8; tglp = br.ReadStruct <TGLP>(); // read image data br.BaseStream.Position = tglp.sheet_data_offset; int width = tglp.sheet_width; int height = tglp.sheet_height; if (_usesGlgr) { bmps = new Bitmap[tglp.num_sheets]; for (int i = 0; i < tglp.num_sheets; i++) { var compSize = br.ReadInt32(); var decomp = Huffman.Decompress(new MemoryStream(br.ReadBytes(compSize)), 8, 0); bmps[i] = Image.Common.Load(decomp, new ImageSettings { Width = width, Height = height, Format = ImageSettings.ConvertFormat(tglp.sheet_image_format & 0x7fff) }); } } else { bmps = Enumerable.Range(0, tglp.num_sheets).Select(_ => Image.Common.Load(br.ReadBytes(tglp.sheet_size), new ImageSettings { Width = width, Height = height, Format = ImageSettings.ConvertFormat(tglp.sheet_image_format) })).ToArray(); } // read CWDH for (int offset = finf.cwdh_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cwdh = br.ReadStruct <CWDH>(); for (int i = cwdh.start_index; i <= cwdh.end_index; i++) { lstCWDH.Add(br.ReadStruct <CharWidthInfo>()); } offset = cwdh.next_offset; } // read CMAP for (int offset = finf.cmap_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cmap = br.ReadStruct <CMAP>(); switch (cmap.mapping_method) { case 0: var charOffset = br.ReadUInt16(); for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = i - cmap.code_begin + charOffset; dicCMAP[i] = idx < ushort.MaxValue ? idx : 0; } break; case 1: for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = br.ReadInt16(); if (idx != -1) { dicCMAP[i] = idx; } } break; case 2: var n = br.ReadUInt16(); for (int i = 0; i < n; i++) { char c = br.ReadChar(); int idx = br.ReadInt16(); if (idx != -1) { dicCMAP[c] = idx; } } break; default: throw new Exception("Unsupported mapping method"); } offset = cmap.next_offset; } } }
public BCFNT(Stream input) { using (var br = new BinaryReaderX(input, Encoding.Unicode)) { var cfnt = br.ReadStruct <CFNT>(); finf = br.ReadStruct <FINF>(); // read TGLP br.BaseStream.Position = finf.tglp_offset - 8; tglp = br.ReadStruct <TGLP>(); // read image data br.BaseStream.Position = tglp.sheet_data_offset; int width = tglp.sheet_width; int height = tglp.sheet_height * tglp.num_sheets; var bytes = br.ReadBytes(tglp.sheet_size * tglp.num_sheets); bmp = new Bitmap(width, height); var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { var ptr = (int *)data.Scan0; for (int i = 0; i < width * height; i++) { int x = (i / 64 % (width / 8)) * 8 + (i / 4 & 4) | (i / 2 & 2) | (i & 1); int y = (i / 64 / (width / 8)) * 8 + (i / 8 & 4) | (i / 4 & 2) | (i / 2 & 1); int a; if (tglp.sheet_image_format == 8) // A8 { a = bytes[i]; } else if (tglp.sheet_image_format == 11) // A4 { a = (bytes[i / 2] >> (i % 2 * 4)) % 16 * 17; } else { throw new NotSupportedException("Only supports A4 and A8 for now"); } ptr[width * y + x] = a << 24; } } bmp.UnlockBits(data); // read CWDH for (int offset = finf.cwdh_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cwdh = br.ReadStruct <CWDH>(); for (int i = cwdh.start_index; i <= cwdh.end_index; i++) { lstCWDH.Add(br.ReadStruct <CharWidthInfo>()); } offset = cwdh.next_offset; } // read CMAP for (int offset = finf.cmap_offset; offset != 0;) { br.BaseStream.Position = offset - 8; var cmap = br.ReadStruct <CMAP>(); switch (cmap.mapping_method) { case 0: var charOffset = br.ReadUInt16(); for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = i - cmap.code_begin + charOffset; dicCMAP[i] = idx < UInt16.MaxValue ? idx : 0; } break; case 1: for (char i = cmap.code_begin; i <= cmap.code_end; i++) { int idx = br.ReadUInt16(); dicCMAP[i] = idx < UInt16.MaxValue ? idx : 0; } break; case 2: var n = br.ReadUInt16(); for (int i = 0; i < n; i++) { char c = br.ReadChar(); int idx = br.ReadUInt16(); dicCMAP[c] = idx < UInt16.MaxValue ? idx : 0; } break; default: throw new Exception("Unsupported mapping method"); } offset = cmap.next_offset; } } }