void render_font_command_glyph() { // FIXME: this is copy/pasta from the BDC loading, and it shouldn't be injected into every font emu_file file = new emu_file(OPEN_FLAG_READ); if (!file.open_ram(new MemoryU8(font_uicmd14), (u32)font_uicmd14.Length)) { // get the file size, read the header, and check that it looks good u64 filesize = file.size(); bdc_header header = new bdc_header(); if (!header.read(file)) { osd_printf_warning("render_font::render_font_command_glyph: error reading BDC header\n"); file.close(); return; } else if (!header.check_magic() || (bdc_header.MAJVERSION != header.get_major_version()) || (bdc_header.MINVERSION != header.get_minor_version())) { LOG("render_font::render_font_command_glyph: incompatible BDC file\n"); file.close(); return; } // get global properties from the header m_height_cmd = header.get_height(); m_yoffs_cmd = header.get_y_offset(); u32 numchars = header.get_glyph_count(); if ((file.tell() + ((u64)numchars * bdc_table_entry.size())) > filesize) { LOG("render_font::render_font_command_glyph: BDC file is too small to hold glyph table\n"); file.close(); return; } // now read the rest of the data u64 remaining = filesize - file.tell(); //try { m_rawdata_cmd.resize(remaining); } //catch (...) //{ // global.osd_printf_error("render_font::render_font_command_glyph: allocation error\n"); //} for (u64 bytes_read = 0; remaining > bytes_read;) { u32 chunk = (u32)std.min(u32.MaxValue, remaining); if (file.read(new Pointer <u8>(m_rawdata_cmd, (int)bytes_read), chunk) != chunk) { osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n"); m_rawdata_cmd.clear(); file.close(); return; } bytes_read += chunk; } file.close(); // extract the data from the data size_t offset = (size_t)numchars * bdc_table_entry.size(); bdc_table_entry entry = new bdc_table_entry(m_rawdata_cmd.empty() ? null : new Pointer <u8>(m_rawdata_cmd)); for (unsigned chindex = 0; chindex < numchars; chindex++, entry = entry.get_next()) { // if we don't have a subtable yet, make one int chnum = (int)entry.get_encoding(); LOG("render_font::render_font_command_glyph: loading character {0}\n", chnum); if (m_glyphs_cmd[chnum / 256] == null) { //try { m_glyphs_cmd[chnum / 256] = new List <glyph>(256); // new glyph[256]; for (int i = 0; i < 256; i++) { m_glyphs_cmd[chnum / 256].Add(new glyph()); } } //catch (...) //{ // osd_printf_error("render_font::render_font_command_glyph: allocation error\n"); // m_rawdata_cmd.clear(); // return; //} } // fill in the entry glyph gl = m_glyphs_cmd[chnum / 256][chnum % 256]; gl.width = entry.get_x_advance(); gl.xoffs = entry.get_bb_x_offset(); gl.yoffs = entry.get_bb_y_offset(); gl.bmwidth = entry.get_bb_width(); gl.bmheight = entry.get_bb_height(); gl.rawdata = new Pointer <u8>(m_rawdata_cmd, (int)offset); // advance the offset past the character offset += (size_t)((gl.bmwidth * gl.bmheight + 7) / 8); if (m_rawdata_cmd.size() < offset) { osd_printf_verbose("render_font::render_font_command_glyph: BDC file too small to hold all glyphs\n"); m_rawdata_cmd.clear(); return; } } } }
//------------------------------------------------- // load_cached - load a font in cached format //------------------------------------------------- bool load_cached(emu_file file, u64 length, u32 hash) { // get the file size, read the header, and check that it looks good u64 filesize = file.size(); bdc_header header = new bdc_header(); if (!header.read(file)) { osd_printf_warning("render_font::load_cached: error reading BDC header\n"); return(false); } else if (!header.check_magic() || (bdc_header.MAJVERSION != header.get_major_version()) || (bdc_header.MINVERSION != header.get_minor_version())) { LOG("render_font::load_cached: incompatible BDC file\n"); return(false); } else if (length != 0 && ((header.get_original_length() != length) || (header.get_original_hash() != hash))) { LOG("render_font::load_cached: BDC file does not match original BDF file\n"); return(false); } // get global properties from the header m_height = header.get_height(); m_scale = 1.0f / (float)(m_height); m_yoffs = header.get_y_offset(); m_defchar = header.get_default_character(); u32 numchars = header.get_glyph_count(); if (file.tell() + ((u64)numchars * bdc_table_entry.size()) > filesize) { LOG("render_font::load_cached: BDC file is too small to hold glyph table\n"); return(false); } // now read the rest of the data u64 remaining = filesize - file.tell(); try { m_rawdata.resize(remaining); } catch (Exception) { osd_printf_error("render_font::load_cached: allocation error\n"); } for (u64 bytes_read = 0; remaining > bytes_read;) { u32 chunk = (u32)std.min(u32.MaxValue, remaining); if (file.read(new Pointer <u8>(m_rawdata, (int)bytes_read), chunk) != chunk) //if (file.read(&m_rawdata[bytes_read], chunk) != chunk) { osd_printf_error("render_font::load_cached: error reading BDC data\n"); m_rawdata.clear(); return(false); } bytes_read += chunk; } // extract the data from the data size_t offset = (size_t)numchars * bdc_table_entry.size(); bdc_table_entry entry = new bdc_table_entry(m_rawdata.empty() ? null : new Pointer <u8>(m_rawdata)); for (unsigned chindex = 0; chindex < numchars; chindex++, entry = entry.get_next()) { // if we don't have a subtable yet, make one int chnum = (int)entry.get_encoding(); LOG("render_font::load_cached: loading character {0}\n", chnum); if (m_glyphs[chnum / 256] == null || m_glyphs[chnum / 256].Count == 0) { //try { m_glyphs[chnum / 256] = new List <glyph>(256); // new glyph[256]; for (int i = 0; i < 256; i++) { m_glyphs[chnum / 256].Add(new glyph()); } } //catch (Exception ) //{ // global.osd_printf_error("render_font::load_cached: allocation error\n"); // m_rawdata.clear(); // return false; //} } // fill in the entry glyph gl = m_glyphs[chnum / 256][chnum % 256]; gl.width = entry.get_x_advance(); gl.xoffs = entry.get_bb_x_offset(); gl.yoffs = entry.get_bb_y_offset(); gl.bmwidth = entry.get_bb_width(); gl.bmheight = entry.get_bb_height(); gl.rawdata = new Pointer <u8>(m_rawdata, (int)offset); // advance the offset past the character offset += (size_t)((gl.bmwidth * gl.bmheight + 7) / 8); if (m_rawdata.size() < offset) { osd_printf_verbose("render_font::load_cached: BDC file too small to hold all glyphs\n"); m_rawdata.clear(); return(false); } } // got everything m_format = format.CACHED; return(true); }