summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/rendfont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/rendfont.cpp')
-rw-r--r--src/emu/rendfont.cpp367
1 files changed, 159 insertions, 208 deletions
diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp
index 13249a083fc..259d7731fe5 100644
--- a/src/emu/rendfont.cpp
+++ b/src/emu/rendfont.cpp
@@ -10,11 +10,18 @@
#include "emu.h"
#include "rendfont.h"
+
#include "emuopts.h"
-#include "coreutil.h"
+#include "fileio.h"
+#include "render.h"
+
+#include "corestr.h"
+#include "multibyte.h"
+#include "path.h"
#include "osdepend.h"
#include "uismall.fh"
+#include "unicode.h"
#include "ui/uicmd14.fh"
#include "ui/cmddata.h"
@@ -119,13 +126,14 @@ public:
static constexpr unsigned MAJVERSION = 1;
static constexpr unsigned MINVERSION = 0;
- bool read(emu_file &f)
+ bool read(util::read_stream &f)
{
- return f.read(m_data, sizeof(m_data)) == sizeof(m_data);
+ auto const [err, actual] = util::read(f, m_data, sizeof(m_data));
+ return !err && (actual == sizeof(m_data));
}
- bool write(emu_file &f)
+ bool write(util::write_stream &f)
{
- return f.write(m_data, sizeof(m_data)) == sizeof(m_data);
+ return !util::write(f, m_data, sizeof(m_data)).first;
}
bool check_magic() const
@@ -142,51 +150,27 @@ public:
}
u64 get_original_length() const
{
- return
- (u64(m_data[OFFS_ORIGLENGTH + 0]) << (7 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 1]) << (6 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 2]) << (5 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 3]) << (4 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 4]) << (3 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 5]) << (2 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 6]) << (1 * 8)) |
- (u64(m_data[OFFS_ORIGLENGTH + 7]) << (0 * 8));
+ return get_u64be(m_data + OFFS_ORIGLENGTH);
}
u32 get_original_hash() const
{
- return
- (u32(m_data[OFFS_ORIGHASH + 0]) << (3 * 8)) |
- (u32(m_data[OFFS_ORIGHASH + 1]) << (2 * 8)) |
- (u32(m_data[OFFS_ORIGHASH + 2]) << (1 * 8)) |
- (u32(m_data[OFFS_ORIGHASH + 3]) << (0 * 8));
+ return get_u32be(m_data + OFFS_ORIGHASH);
}
u32 get_glyph_count() const
{
- return
- (u32(m_data[OFFS_GLYPHCOUNT + 0]) << (3 * 8)) |
- (u32(m_data[OFFS_GLYPHCOUNT + 1]) << (2 * 8)) |
- (u32(m_data[OFFS_GLYPHCOUNT + 2]) << (1 * 8)) |
- (u32(m_data[OFFS_GLYPHCOUNT + 3]) << (0 * 8));
+ return get_u32be(m_data + OFFS_GLYPHCOUNT);
}
u16 get_height() const
{
- return
- (u16(m_data[OFFS_HEIGHT + 0]) << (1 * 8)) |
- (u16(m_data[OFFS_HEIGHT + 1]) << (0 * 8));
+ return get_u16be(m_data + OFFS_HEIGHT);
}
s16 get_y_offset() const
{
- return
- (u16(m_data[OFFS_YOFFSET + 0]) << (1 * 8)) |
- (u16(m_data[OFFS_YOFFSET + 1]) << (0 * 8));
+ return get_u16be(m_data + OFFS_YOFFSET);
}
s32 get_default_character() const
{
- return
- (u32(m_data[OFFS_DEFCHAR + 0]) << (3 * 8)) |
- (u32(m_data[OFFS_DEFCHAR + 1]) << (2 * 8)) |
- (u32(m_data[OFFS_DEFCHAR + 2]) << (1 * 8)) |
- (u32(m_data[OFFS_DEFCHAR + 3]) << (0 * 8));
+ return get_u32be(m_data + OFFS_DEFCHAR);
}
void set_magic()
@@ -200,45 +184,27 @@ public:
}
void set_original_length(u64 value)
{
- m_data[OFFS_ORIGLENGTH + 0] = u8((value >> (7 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 1] = u8((value >> (6 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 2] = u8((value >> (5 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 3] = u8((value >> (4 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 4] = u8((value >> (3 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 5] = u8((value >> (2 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 6] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_ORIGLENGTH + 7] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u64be(m_data + OFFS_ORIGLENGTH, value);
}
void set_original_hash(u32 value)
{
- m_data[OFFS_ORIGHASH + 0] = u8((value >> (3 * 8)) & 0x00ff);
- m_data[OFFS_ORIGHASH + 1] = u8((value >> (2 * 8)) & 0x00ff);
- m_data[OFFS_ORIGHASH + 2] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_ORIGHASH + 3] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u32be(m_data + OFFS_ORIGHASH, value);
}
void set_glyph_count(u32 value)
{
- m_data[OFFS_GLYPHCOUNT + 0] = u8((value >> (3 * 8)) & 0x00ff);
- m_data[OFFS_GLYPHCOUNT + 1] = u8((value >> (2 * 8)) & 0x00ff);
- m_data[OFFS_GLYPHCOUNT + 2] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_GLYPHCOUNT + 3] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u32be(m_data + OFFS_GLYPHCOUNT, value);
}
void set_height(u16 value)
{
- m_data[OFFS_HEIGHT + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_HEIGHT + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_data + OFFS_HEIGHT, value);
}
void set_y_offset(s16 value)
{
- m_data[OFFS_YOFFSET + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_YOFFSET + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_data + OFFS_YOFFSET, value);
}
void set_default_character(s32 value)
{
- m_data[OFFS_DEFCHAR + 0] = u8((value >> (3 * 8)) & 0x00ff);
- m_data[OFFS_DEFCHAR + 1] = u8((value >> (2 * 8)) & 0x00ff);
- m_data[OFFS_DEFCHAR + 2] = u8((value >> (1 * 8)) & 0x00ff);
- m_data[OFFS_DEFCHAR + 3] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u32be(m_data + OFFS_DEFCHAR, value);
}
private:
@@ -278,74 +244,52 @@ public:
u32 get_encoding() const
{
- return
- (u32(m_ptr[OFFS_ENCODING + 0]) << (3 * 8)) |
- (u32(m_ptr[OFFS_ENCODING + 1]) << (2 * 8)) |
- (u32(m_ptr[OFFS_ENCODING + 2]) << (1 * 8)) |
- (u32(m_ptr[OFFS_ENCODING + 3]) << (0 * 8));
+ return get_u32be(m_ptr + OFFS_ENCODING);
}
u16 get_x_advance() const
{
- return
- (u16(m_ptr[OFFS_XADVANCE + 0]) << (1 * 8)) |
- (u16(m_ptr[OFFS_XADVANCE + 1]) << (0 * 8));
+ return get_u16be(m_ptr + OFFS_XADVANCE);
}
s16 get_bb_x_offset() const
{
- return
- (u16(m_ptr[OFFS_BBXOFFSET + 0]) << (1 * 8)) |
- (u16(m_ptr[OFFS_BBXOFFSET + 1]) << (0 * 8));
+ return get_u16be(m_ptr + OFFS_BBXOFFSET);
}
s16 get_bb_y_offset() const
{
- return
- (u16(m_ptr[OFFS_BBYOFFSET + 0]) << (1 * 8)) |
- (u16(m_ptr[OFFS_BBYOFFSET + 1]) << (0 * 8));
+ return get_u16be(m_ptr + OFFS_BBYOFFSET);
}
u16 get_bb_width() const
{
- return
- (u16(m_ptr[OFFS_BBWIDTH + 0]) << (1 * 8)) |
- (u16(m_ptr[OFFS_BBWIDTH + 1]) << (0 * 8));
+ return get_u16be(m_ptr + OFFS_BBWIDTH);
}
u16 get_bb_height() const
{
- return
- (u16(m_ptr[OFFS_BBHEIGHT + 0]) << (1 * 8)) |
- (u16(m_ptr[OFFS_BBHEIGHT + 1]) << (0 * 8));
+ return get_u16be(m_ptr + OFFS_BBHEIGHT);
}
void set_encoding(u32 value)
{
- m_ptr[OFFS_ENCODING + 0] = u8((value >> (3 * 8)) & 0x00ff);
- m_ptr[OFFS_ENCODING + 1] = u8((value >> (2 * 8)) & 0x00ff);
- m_ptr[OFFS_ENCODING + 2] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_ENCODING + 3] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u32be(m_ptr + OFFS_ENCODING, value);
}
void set_x_advance(u16 value)
{
- m_ptr[OFFS_XADVANCE + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_XADVANCE + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_ptr + OFFS_XADVANCE, value);
}
void set_bb_x_offset(s16 value)
{
- m_ptr[OFFS_BBXOFFSET + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_BBXOFFSET + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_ptr + OFFS_BBXOFFSET, value);
}
void set_bb_y_offset(s16 value)
{
- m_ptr[OFFS_BBYOFFSET + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_BBYOFFSET + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_ptr + OFFS_BBYOFFSET, value);
}
void set_bb_width(u16 value)
{
- m_ptr[OFFS_BBWIDTH + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_BBWIDTH + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_ptr + OFFS_BBWIDTH, value);
}
void set_bb_height(u16 value)
{
- m_ptr[OFFS_BBHEIGHT + 0] = u8((value >> (1 * 8)) & 0x00ff);
- m_ptr[OFFS_BBHEIGHT + 1] = u8((value >> (0 * 8)) & 0x00ff);
+ put_u16be(m_ptr + OFFS_BBHEIGHT, value);
}
bdc_table_entry &operator=(bdc_table_entry const &that) = default;
@@ -372,35 +316,30 @@ private:
} // anonymous namespace
-void convert_command_glyph(std::string &str)
+std::string convert_command_glyph(std::string_view str)
{
- (void)str.c_str(); // force NUL-termination - we depend on it later
- std::size_t const len(str.length());
- std::vector<char> buf(2 * (len + 1));
+ std::vector<char> buf(2 * (str.length() + 1));
std::size_t j(0);
- for (std::size_t i = 0; len > i; )
+ while (!str.empty())
{
// decode UTF-8
char32_t uchar;
- int const codelen(uchar_from_utf8(&uchar, &str[i], len - i));
+ int const codelen(uchar_from_utf8(&uchar, str));
if (0 >= codelen)
break;
- i += codelen;
+ str.remove_prefix(codelen);
// check for three metacharacters
fix_command_t const *fixcmd(nullptr);
switch (uchar)
{
case COMMAND_CONVERT_TEXT:
- for (fix_strings_t *fixtext = convert_text; fixtext->glyph_code; ++fixtext)
+ for (fix_strings_t const *fixtext = convert_text; fixtext->glyph_code; ++fixtext)
{
- if (!fixtext->glyph_str_len)
- fixtext->glyph_str_len = std::strlen(fixtext->glyph_str);
-
- if (!std::strncmp(fixtext->glyph_str, &str[i], fixtext->glyph_str_len))
+ if (str.substr(0, fixtext->glyph_str.length()) == fixtext->glyph_str)
{
uchar = fixtext->glyph_code + COMMAND_UNICODE;
- i += strlen(fixtext->glyph_str);
+ str.remove_prefix(fixtext->glyph_str.length());
break;
}
}
@@ -416,20 +355,20 @@ void convert_command_glyph(std::string &str)
}
// this substitutes a single character
- if (fixcmd)
+ if (fixcmd && !str.empty())
{
- if (str[i] == uchar)
+ if (str[0] == uchar)
{
- ++i;
+ str.remove_prefix(1);
}
else
{
- while (fixcmd->glyph_code && (fixcmd->glyph_char != str[i]))
+ while (fixcmd->glyph_code && !str.empty() && fixcmd->glyph_char != str[0])
++fixcmd;
- if (fixcmd->glyph_code)
+ if (fixcmd->glyph_code && !str.empty())
{
uchar = COMMAND_UNICODE + fixcmd->glyph_code;
- ++i;
+ str.remove_prefix(1);
}
}
}
@@ -440,7 +379,7 @@ void convert_command_glyph(std::string &str)
break;
j += outlen;
}
- str.assign(&buf[0], j);
+ return std::string(&buf[0], j);
}
@@ -481,7 +420,7 @@ inline render_font::glyph &render_font::get_char(char32_t chnum)
static glyph dummy_glyph;
unsigned const page(chnum / 256);
- if (page >= ARRAY_LENGTH(m_glyphs))
+ if (page >= std::size(m_glyphs))
{
if ((0 <= m_defchar) && (chnum != m_defchar))
return get_char(m_defchar);
@@ -596,10 +535,9 @@ render_font::render_font(render_manager &manager, const char *filename)
}
// load the compiled in data instead
- emu_file ramfile(OPEN_FLAG_READ);
- osd_file::error const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall)));
- if (osd_file::error::NONE == filerr)
- load_cached(ramfile, 0, 0);
+ util::random_read::ptr ramfile = util::ram_read(font_uismall, sizeof(font_uismall));
+ if (ramfile)
+ load_cached(*ramfile, 0, 0);
render_font_command_glyph();
}
@@ -671,7 +609,7 @@ void render_font::char_expand(char32_t chnum, glyph &gl)
if (accumbit == 7)
accum = *ptr++;
if (dest != nullptr)
- *dest++ = (accum & (1 << accumbit)) ? fgcol : bgcol;
+ *dest++ = BIT(accum, accumbit) ? fgcol : bgcol;
accumbit = (accumbit - 1) & 7;
}
}
@@ -767,7 +705,7 @@ void render_font::char_expand(char32_t chnum, glyph &gl)
if (accumbit == 7)
accum = *ptr++;
if (dest != nullptr)
- *dest++ = (accum & (1 << accumbit)) ? fgcol : bgcol;
+ *dest++ = BIT(accum, accumbit) ? fgcol : bgcol;
accumbit = (accumbit - 1) & 7;
}
}
@@ -820,7 +758,8 @@ void render_font::get_scaled_bitmap_and_bounds(bitmap_argb32 &dest, float height
bounds.min_y = 0;
// compute x1,y1 from there based on the bitmap size
- bounds.set_width(float(gl.bmwidth) * scale * aspect);
+ float width = float(gl.bmwidth) * scale * aspect;
+ bounds.set_width(width < 0.5f ? 0 : std::max(int(width), 1));
bounds.set_height(float(m_height) * scale);
// if the bitmap isn't big enough, bail
@@ -856,24 +795,23 @@ float render_font::char_width(float height, float aspect, char32_t ch)
// at the given height
//-------------------------------------------------
-float render_font::string_width(float height, float aspect, const char *string)
+float render_font::string_width(float height, float aspect, std::string_view string)
{
// loop over the string and accumulate widths
int totwidth = 0;
- const char *ends = string + strlen(string);
- const char *s = string;
char32_t schar;
// loop over characters
- while (*s != 0)
+ int scharcount;
+ while ((scharcount = uchar_from_utf8(&schar, string)) != 0)
{
- int scharcount = uchar_from_utf8(&schar, s, ends - s);
+ if (0 > scharcount)
+ schar = 0xfffd;
+ string.remove_prefix((0 > scharcount) ? 1 : scharcount);
totwidth += get_char(schar).width;
- s += scharcount;
}
-
// scale the final result based on height
return float(totwidth) * m_scale * height * aspect;
}
@@ -884,21 +822,19 @@ float render_font::string_width(float height, float aspect, const char *string)
// UTF8-encoded string at the given height
//-------------------------------------------------
-float render_font::utf8string_width(float height, float aspect, const char *utf8string)
+float render_font::utf8string_width(float height, float aspect, std::string_view utf8string)
{
- std::size_t const length = std::strlen(utf8string);
-
// loop over the string and accumulate widths
- int count;
s32 totwidth = 0;
- for (std::size_t offset = 0U; offset < length; offset += unsigned(count))
+ while (!utf8string.empty())
{
char32_t uchar;
- count = uchar_from_utf8(&uchar, utf8string + offset, length - offset);
+ int count = uchar_from_utf8(&uchar, utf8string);
if (count < 0)
break;
totwidth += get_char(uchar).width;
+ utf8string.remove_prefix(count);
}
// scale the final result based on height
@@ -913,16 +849,16 @@ float render_font::utf8string_width(float height, float aspect, const char *utf8
// and create a new cached version
//-------------------------------------------------
-bool render_font::load_cached_bdf(const char *filename)
+bool render_font::load_cached_bdf(std::string_view filename)
{
- osd_file::error filerr;
+ std::error_condition filerr;
u32 chunk;
- u64 bytes;
+ std::size_t bytes;
// first try to open the BDF itself
emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_READ);
filerr = file.open(filename);
- if (filerr != osd_file::error::NONE)
+ if (filerr)
return false;
// determine the file size and allocate memory
@@ -947,19 +883,17 @@ bool render_font::load_cached_bdf(const char *filename)
m_rawdata.clear();
return false;
}
- u32 const hash(core_crc32(0, reinterpret_cast<u8 const *>(&m_rawdata[0]), bytes));
+ u32 const hash(util::crc32_creator::simple(&m_rawdata[0], bytes));
// create the cached filename, changing the 'F' to a 'C' on the extension
- std::string cachedname(filename);
- if ((4U < cachedname.length()) && !core_stricmp(&cachedname[cachedname.length() - 4], ".bdf"))
- cachedname.erase(cachedname.length() - 4);
+ std::string cachedname(filename, 0, filename.length() - ((4U < filename.length()) && core_filename_ends_with(filename, ".bdf") ? 4 : 0));
cachedname.append(".bdc");
// attempt to open the cached version of the font
{
emu_file cachefile(m_manager.machine().options().font_path(), OPEN_FLAG_READ);
filerr = cachefile.open(cachedname);
- if (filerr == osd_file::error::NONE)
+ if (!filerr)
{
// if we have a cached version, load it
bool const result = load_cached(cachefile, m_rawsize, hash);
@@ -985,11 +919,25 @@ bool render_font::load_cached_bdf(const char *filename)
m_rawdata[m_rawsize] = '\0';
// load the BDF
- bool const result = load_bdf();
+ bool result = load_bdf();
// if we loaded okay, create a cached one
if (result)
- save_cached(cachedname.c_str(), m_rawsize, hash);
+ {
+ osd_printf_info("Generating cached BDF font...\n");
+
+ // attempt to open the file
+ emu_file cachefile(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
+ filerr = cachefile.open(cachedname);
+ if (filerr)
+ result = false;
+ else
+ {
+ result = save_cached(cachefile, m_rawsize, hash);
+ if (!result)
+ cachefile.remove_on_close();
+ }
+ }
else
m_rawdata.clear();
@@ -1299,7 +1247,7 @@ bool render_font::load_bdf()
{
LOG("render_font::load_bdf: ignoring character with negative x advance\n");
}
- else if ((256 * ARRAY_LENGTH(m_glyphs)) <= encoding)
+ else if ((256 * std::size(m_glyphs)) <= encoding)
{
LOG("render_font::load_bdf: ignoring character with encoding outside range\n");
}
@@ -1331,7 +1279,7 @@ bool render_font::load_bdf()
// some progress for big fonts
if (0 == (++charcount % 256))
- osd_printf_warning("Loading BDF font... (%d characters loaded)\n", charcount);
+ osd_printf_info("Loading BDF font... (%d characters loaded)\n", charcount);
}
}
@@ -1351,12 +1299,17 @@ bool render_font::load_bdf()
// load_cached - load a font in cached format
//-------------------------------------------------
-bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
+bool render_font::load_cached(util::random_read &file, u64 length, u32 hash)
{
// get the file size, read the header, and check that it looks good
- u64 const filesize(file.size());
+ u64 filesize;
bdc_header header;
- if (!header.read(file))
+ if (file.length(filesize))
+ {
+ LOG("render_font::load_cached: error determining size of BDC file\n");
+ return false;
+ }
+ else if (!header.read(file))
{
osd_printf_warning("render_font::load_cached: error reading BDC header\n");
return false;
@@ -1378,14 +1331,25 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
m_yoffs = header.get_y_offset();
m_defchar = header.get_default_character();
u32 const numchars(header.get_glyph_count());
- if ((file.tell() + (u64(numchars) * bdc_table_entry::size())) > filesize)
+ u64 filepos;
+ if (file.tell(filepos))
+ {
+ LOG("render_font::load_cached: failed to determine position in BDC file\n");
+ return false;
+ }
+ else if ((filepos + (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 const remaining(filesize - file.tell());
+ u64 const remaining(filesize - filepos);
+ if (remaining > std::numeric_limits<std::size_t>::max())
+ {
+ osd_printf_error("render_font::load_cached: BDC file is too large to read into memory\n");
+ return false;
+ }
try
{
m_rawdata.resize(std::size_t(remaining));
@@ -1393,17 +1357,14 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
catch (...)
{
osd_printf_error("render_font::load_cached: allocation error\n");
+ return false;
}
- for (u64 bytes_read = 0; remaining > bytes_read; )
+ auto const [err, bytes] = read(file, &m_rawdata[0], remaining);
+ if (err || (bytes != remaining))
{
- u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining));
- 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;
+ osd_printf_error("render_font::load_cached: error reading BDC data\n");
+ m_rawdata.clear();
+ return false;
}
// extract the data from the data
@@ -1457,16 +1418,8 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
// save_cached - save a font in cached format
//-------------------------------------------------
-bool render_font::save_cached(const char *filename, u64 length, u32 hash)
+bool render_font::save_cached(util::random_write &file, u64 length, u32 hash)
{
- osd_printf_warning("Generating cached BDF font...\n");
-
- // attempt to open the file
- emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- osd_file::error const filerr = file.open(filename);
- if (osd_file::error::NONE != filerr)
- return false;
-
// count glyphs
unsigned numchars = 0;
for (glyph const *const page : m_glyphs)
@@ -1481,8 +1434,6 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
try
{
- u32 bytes_written;
-
{
LOG("render_font::save_cached: writing header\n");
bdc_header hdr;
@@ -1495,9 +1446,11 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
hdr.set_y_offset(m_yoffs);
hdr.set_default_character(m_defchar);
if (!hdr.write(file))
- throw emu_fatalerror("Error writing cached file");
+ throw emu_fatalerror("Error writing cached font file");
}
- u64 const table_offs(file.tell());
+ u64 table_offs;
+ if (file.tell(table_offs))
+ throw emu_fatalerror("Error writing cached font file");
// allocate an array to hold the character data
std::vector<u8> chartable(std::size_t(numchars) * bdc_table_entry::size(), 0);
@@ -1506,13 +1459,12 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
std::vector<u8> tempbuffer(65536);
// write the empty table to the beginning of the file
- bytes_written = file.write(&chartable[0], chartable.size());
- if (bytes_written != chartable.size())
- throw emu_fatalerror("Error writing cached file");
+ if (write(file, &chartable[0], chartable.size()).first)
+ throw emu_fatalerror("Error writing cached font file");
// loop over all characters
bdc_table_entry table_entry(chartable.empty() ? nullptr : &chartable[0]);
- for (unsigned chnum = 0; chnum < (256 * ARRAY_LENGTH(m_glyphs)); chnum++)
+ for (unsigned chnum = 0; chnum < (256 * std::size(m_glyphs)); chnum++)
{
if (m_glyphs[chnum / 256] && (0 < m_glyphs[chnum / 256][chnum % 256].width))
{
@@ -1550,9 +1502,8 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
*dest++ = accum;
// write the data
- bytes_written = file.write(&tempbuffer[0], dest - &tempbuffer[0]);
- if (bytes_written != dest - &tempbuffer[0])
- throw emu_fatalerror("Error writing cached file");
+ if (write(file, &tempbuffer[0], dest - &tempbuffer[0]).first)
+ throw emu_fatalerror("Error writing cached font file");
// free the bitmap and texture
m_manager.texture_free(gl.texture);
@@ -1575,17 +1526,10 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
if (!chartable.empty())
{
LOG("render_font::save_cached: writing character table\n");
- file.seek(table_offs, SEEK_SET);
- u8 const *bytes(&chartable[0]);
- for (u64 remaining = chartable.size(); remaining; )
- {
- u32 const chunk((std::min<u64>)(std::numeric_limits<u32>::max(), remaining));
- bytes_written = file.write(bytes, chunk);
- if (chunk != bytes_written)
- throw emu_fatalerror("Error writing cached file");
- bytes += chunk;
- remaining -= chunk;
- }
+ if (file.seek(table_offs, SEEK_SET))
+ return false;
+ if (write(file, &chartable[0], chartable.size()).first)
+ throw emu_fatalerror("Error writing cached font file");
}
// no trouble?
@@ -1593,7 +1537,6 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
}
catch (...)
{
- file.remove_on_close();
return false;
}
}
@@ -1602,13 +1545,13 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
void render_font::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(OPEN_FLAG_READ);
- if (file.open_ram(font_uicmd14, sizeof(font_uicmd14)) == osd_file::error::NONE)
+ util::random_read::ptr file = util::ram_read(font_uicmd14, sizeof(font_uicmd14));
+ if (file)
{
// get the file size, read the header, and check that it looks good
- u64 const filesize(file.size());
+ u64 const filesize = sizeof(font_uicmd14);
bdc_header header;
- if (!header.read(file))
+ if (!header.read(*file))
{
osd_printf_warning("render_font::render_font_command_glyph: error reading BDC header\n");
return;
@@ -1623,14 +1566,25 @@ void render_font::render_font_command_glyph()
m_height_cmd = header.get_height();
m_yoffs_cmd = header.get_y_offset();
u32 const numchars(header.get_glyph_count());
- if ((file.tell() + (u64(numchars) * bdc_table_entry::size())) > filesize)
+ u64 filepos;
+ if (file->tell(filepos))
+ {
+ LOG("render_font::render_font_command_glyph: failed to determine position in BDC file\n");
+ return;
+ }
+ else if ((filepos + (u64(numchars) * bdc_table_entry::size())) > filesize)
{
LOG("render_font::render_font_command_glyph: BDC file is too small to hold glyph table\n");
return;
}
// now read the rest of the data
- u64 const remaining(filesize - file.tell());
+ u64 const remaining(filesize - filepos);
+ if (remaining > std::numeric_limits<std::size_t>::max())
+ {
+ osd_printf_error("render_font::render_font_command_glyph: BDC file is too large to read into memory\n");
+ return;
+ }
try
{
m_rawdata_cmd.resize(std::size_t(remaining));
@@ -1638,17 +1592,14 @@ void render_font::render_font_command_glyph()
catch (...)
{
osd_printf_error("render_font::render_font_command_glyph: allocation error\n");
+ return;
}
- for (u64 bytes_read = 0; remaining > bytes_read; )
+ auto const [err, bytes] = read(*file, &m_rawdata_cmd[0], remaining);
+ if (err || (bytes != remaining))
{
- u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining));
- if (file.read(&m_rawdata_cmd[bytes_read], chunk) != chunk)
- {
- osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n");
- m_rawdata_cmd.clear();
- return;
- }
- bytes_read += chunk;
+ osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n");
+ m_rawdata_cmd.clear();
+ return;
}
// extract the data from the data