summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2010-10-23 06:39:13 +0000
committer Aaron Giles <aaron@aarongiles.com>2010-10-23 06:39:13 +0000
commit43eca9d9c87831cf3efc7119a1c1cc46f9fd7ac0 (patch)
tree085ba17f5971125abbf106ca00c66e2fb67eaeb4
parentb6647f7ae1d6d4d957c50fc9d4cef581e8425fd4 (diff)
Convert rendfont to C++.
-rw-r--r--src/emu/debugint/debugint.c6
-rw-r--r--src/emu/render.c22
-rw-r--r--src/emu/render.h6
-rw-r--r--src/emu/rendfont.c1040
-rw-r--r--src/emu/rendfont.h117
-rw-r--r--src/emu/rendlay.c10
-rw-r--r--src/emu/ui.c11
-rw-r--r--src/emu/uigfx.c22
8 files changed, 629 insertions, 605 deletions
diff --git a/src/emu/debugint/debugint.c b/src/emu/debugint/debugint.c
index 54973eb082f..5fa4987140e 100644
--- a/src/emu/debugint/debugint.c
+++ b/src/emu/debugint/debugint.c
@@ -889,7 +889,7 @@ static void debugint_exit(running_machine &machine)
}
if (debug_font != NULL)
{
- render_font_free(debug_font);
+ machine.render().font_free(debug_font);
debug_font = NULL;
}
@@ -899,7 +899,7 @@ void debugint_init(running_machine *machine)
{
unicode_char ch;
int chw;
- debug_font = render_font_alloc(*machine, "ui.bdf"); //ui_get_font();
+ debug_font = machine->render().font_alloc("ui.bdf"); //ui_get_font();
debug_font_width = 0;
debug_font_height = 15;
@@ -912,7 +912,7 @@ void debugint_init(running_machine *machine)
for (ch=0;ch<=127;ch++)
{
- chw = render_font_get_char_width(debug_font, debug_font_height, debug_font_aspect, ch);
+ chw = debug_font->char_width(debug_font_height, debug_font_aspect, ch);
if (chw>debug_font_width)
debug_font_width = chw;
}
diff --git a/src/emu/render.c b/src/emu/render.c
index 106fa80cd6a..91da225c469 100644
--- a/src/emu/render.c
+++ b/src/emu/render.c
@@ -789,7 +789,7 @@ void render_container::add_char(float x0, float y0, float height, float aspect,
render_bounds bounds;
bounds.x0 = x0;
bounds.y0 = y0;
- render_texture *texture = render_font_get_char_texture_and_bounds(&font, height, aspect, ch, &bounds);
+ render_texture *texture = font.get_char_texture_and_bounds(height, aspect, ch, bounds);
// add it like a quad
item &newitem = add_generic(CONTAINER_ITEM_QUAD, bounds.x0, bounds.y0, bounds.x1, bounds.y1, argb);
@@ -2514,6 +2514,26 @@ void render_manager::texture_free(render_texture *texture)
//-------------------------------------------------
+// font_alloc - allocate a new font instance
+//-------------------------------------------------
+
+render_font *render_manager::font_alloc(const char *filename)
+{
+ return auto_alloc(&m_machine, render_font(*this, filename));
+}
+
+
+//-------------------------------------------------
+// font_free - release a font instance
+//-------------------------------------------------
+
+void render_manager::font_free(render_font *font)
+{
+ auto_free(&m_machine, font);
+}
+
+
+//-------------------------------------------------
// invalidate_all - remove all refs to a
// particular reference pointer
//-------------------------------------------------
diff --git a/src/emu/render.h b/src/emu/render.h
index 0fd44be7214..a4d92250fa4 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -168,7 +168,7 @@ class screen_device;
class render_container;
class render_manager;
typedef struct _xml_data_node xml_data_node;
-typedef struct _render_font render_font;
+class render_font;
struct object_transform;
class layout_element;
class layout_view;
@@ -741,6 +741,10 @@ public:
// textures
render_texture *texture_alloc(texture_scaler_func scaler = NULL, void *param = NULL);
void texture_free(render_texture *texture);
+
+ // fonts
+ render_font *font_alloc(const char *filename = NULL);
+ void font_free(render_font *font);
// reference tracking
void invalidate_all(void *refptr);
diff --git a/src/emu/rendfont.c b/src/emu/rendfont.c
index 2fa5ba6f4ba..836526ef36e 100644
--- a/src/emu/rendfont.c
+++ b/src/emu/rendfont.c
@@ -4,8 +4,36 @@
Rendering system font management.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -18,223 +46,148 @@
#include "uismall.fh"
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define FONT_FORMAT_TEXT 1
-#define FONT_FORMAT_CACHED 2
-
-#define CACHED_CHAR_SIZE 12
-#define CACHED_HEADER_SIZE 16
-#define CACHED_BDF_HASH_SIZE 1024
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* a render_font contains information about a single character in a font */
-typedef struct _render_font_char render_font_char;
-struct _render_font_char
-{
- INT32 width; /* width from this character to the next */
- INT32 xoffs, yoffs; /* X and Y offset from baseline to top,left of bitmap */
- INT32 bmwidth, bmheight; /* width and height of bitmap */
- const char * rawdata; /* pointer to the raw data for this one */
- bitmap_t * bitmap; /* pointer to the bitmap containing the raw data */
- render_texture * texture; /* pointer to a texture for rendering and sizing */
-};
-
-
-/* a render_font contains information about a font */
-/*typedef struct _render_font render_font; -- defined in rendfont.h */
-struct _render_font
-{
- running_machine * machine;
- int format; /* format of font data */
- int height; /* height of the font, from ascent to descent */
- int yoffs; /* y offset from baseline to descent */
- float scale; /* 1 / height precomputed */
- render_font_char * chars[256]; /* array of character subtables */
- const char * rawdata; /* pointer to the raw data for the font */
- UINT64 rawsize; /* size of the raw font data */
-};
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
+//-------------------------------------------------
+// next_line - return a pointer to the start of
+// the next line
+//-------------------------------------------------
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-static void render_font_char_expand(render_font *font, render_font_char *ch);
-static int render_font_load_cached_bdf(render_font *font, const char *filename);
-static int render_font_load_bdf(render_font *font);
-static int render_font_load_cached(render_font *font, mame_file *file, UINT32 hash);
-static int render_font_save_cached(render_font *font, const char *filename, UINT32 hash);
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-/*-------------------------------------------------
- next_line - return a pointer to the start of
- the next line
--------------------------------------------------*/
-
-INLINE const char *next_line(const char *ptr)
+inline const char *next_line(const char *ptr)
{
- /* scan forward until we hit the end or a carriage return */
+ // scan forward until we hit the end or a carriage return
while (*ptr != 13 && *ptr != 10 && *ptr != 0) ptr++;
- /* if we hit the end, return NULL */
+ // if we hit the end, return NULL
if (*ptr == 0)
return NULL;
- /* eat the trailing linefeed if present */
+ // eat the trailing linefeed if present
if (*++ptr == 10)
ptr++;
return ptr;
}
-/*-------------------------------------------------
- get_char - return a pointer to a character
- in a font, expanding if necessary
--------------------------------------------------*/
+//-------------------------------------------------
+// get_char - return a pointer to a character
+// in a font, expanding if necessary
+//-------------------------------------------------
-INLINE render_font_char *get_char(render_font *font, unicode_char chnum)
+inline render_font::glyph &render_font::get_char(unicode_char chnum)
{
- static render_font_char dummy_char;
- render_font_char *chtable;
- render_font_char *ch;
-
- /* grab the table; if none, return the dummy character */
- chtable = font->chars[chnum / 256];
- if (chtable == NULL)
- return &dummy_char;
-
- /* if the character isn't generated yet, do it now */
- ch = &chtable[chnum % 256];
- if (ch->bitmap == NULL)
- render_font_char_expand(font, ch);
-
- /* return the resulting character */
- return ch;
-}
+ static glyph dummy_glyph;
+ // grab the table; if none, return the dummy character
+ glyph *glyphtable = m_glyphs[chnum / 256];
+ if (glyphtable == NULL)
+ return dummy_glyph;
+ // if the character isn't generated yet, do it now
+ glyph &gl = glyphtable[chnum % 256];
+ if (gl.bitmap == NULL)
+ char_expand(gl);
-/***************************************************************************
- RENDER FONTS
-***************************************************************************/
+ // return the resulting character
+ return gl;
+}
-/*-------------------------------------------------
- render_font_alloc - allocate a new font
- and load the BDF file
--------------------------------------------------*/
-render_font *render_font_alloc(running_machine &machine, const char *filename)
-{
- file_error filerr;
- mame_file *ramfile;
- render_font *font;
- /* allocate and clear memory */
- font = global_alloc_clear(render_font);
- font->machine = &machine;
+//**************************************************************************
+// RENDER FONT
+//**************************************************************************
+
+//-------------------------------------------------
+// render_font - constructor
+//-------------------------------------------------
- /* attempt to load the cached version of the font first */
- if (filename != NULL && render_font_load_cached_bdf(font, filename) == 0)
- return font;
+render_font::render_font(render_manager &manager, const char *filename)
+ : m_manager(manager),
+ m_format(FF_UNKNOWN),
+ m_height(0),
+ m_yoffs(0),
+ m_scale(1.0f),
+ m_rawdata(NULL),
+ m_rawsize(0)
+{
+ memset(m_glyphs, 0, sizeof(m_glyphs));
- /* if we failed, clean up and realloc */
- render_font_free(font);
- font = global_alloc_clear(render_font);
- font->machine = &machine;
+ // attempt to load the cached version of the font first
+ if (filename != NULL && load_cached_bdf(filename))
+ return;
- /* load the raw data instead */
- filerr = mame_fopen_ram(font_uismall, sizeof(font_uismall), OPEN_FLAG_READ, &ramfile);
+ // load the raw data instead
+ mame_file *ramfile;
+ file_error filerr = mame_fopen_ram(font_uismall, sizeof(font_uismall), OPEN_FLAG_READ, &ramfile);
if (filerr == FILERR_NONE)
{
- render_font_load_cached(font, ramfile, 0);
+ load_cached(ramfile, 0);
mame_fclose(ramfile);
}
- return font;
}
-/*-------------------------------------------------
- render_font_free - free an allocated font and
- all of its owned subobjects
--------------------------------------------------*/
+//-------------------------------------------------
+// ~render_font - destructor
+//-------------------------------------------------
-void render_font_free(render_font *font)
+render_font::~render_font()
{
- int tablenum;
-
- /* free all the subtables */
- for (tablenum = 0; tablenum < 256; tablenum++)
- if (font->chars[tablenum] != NULL)
+ // free all the subtables
+ for (int tablenum = 0; tablenum < 256; tablenum++)
+ if (m_glyphs[tablenum] != NULL)
{
- int charnum;
-
- /* loop over characters */
- for (charnum = 0; charnum < 256; charnum++)
+ // loop over characters
+ for (int charnum = 0; charnum < 256; charnum++)
{
- render_font_char *ch = &font->chars[tablenum][charnum];
- font->machine->render().texture_free(ch->texture);
- global_free(ch->bitmap);
+ glyph &gl = m_glyphs[tablenum][charnum];
+ m_manager.texture_free(gl.texture);
+ auto_free(&m_manager.machine(), gl.bitmap);
}
- /* free the subtable itself */
- global_free(font->chars[tablenum]);
+ // free the subtable itself
+ auto_free(&m_manager.machine(), m_glyphs[tablenum]);
}
- /* free the raw data and the size itself */
- if (font->rawdata != NULL)
- global_free((void *)font->rawdata);
- global_free(font);
+ // free the raw data and the size itself
+ auto_free(&m_manager.machine(), m_rawdata);
}
-/*-------------------------------------------------
- render_font_char_expand - expand the raw data
- for a character into a bitmap
--------------------------------------------------*/
+//-------------------------------------------------
+// char_expand - expand the raw data for a
+// character into a bitmap
+//-------------------------------------------------
-static void render_font_char_expand(render_font *font, render_font_char *ch)
+void render_font::char_expand(glyph &gl)
{
- const char *ptr = ch->rawdata;
- UINT8 accum = 0, accumbit = 7;
- int x, y;
-
- /* punt if nothing there */
- if (ch->bmwidth == 0 || ch->bmheight == 0 || ch->rawdata == NULL)
+ // punt if nothing there
+ if (gl.bmwidth == 0 || gl.bmheight == 0 || gl.rawdata == NULL)
return;
- /* allocate a new bitmap of the size we need */
- ch->bitmap = global_alloc(bitmap_t(ch->bmwidth, font->height, BITMAP_FORMAT_ARGB32));
- bitmap_fill(ch->bitmap, NULL, 0);
+ // allocate a new bitmap of the size we need
+ gl.bitmap = auto_alloc(&m_manager.machine(), bitmap_t(gl.bmwidth, m_height, BITMAP_FORMAT_ARGB32));
+ bitmap_fill(gl.bitmap, NULL, 0);
- /* extract the data */
- for (y = 0; y < ch->bmheight; y++)
+ // extract the data
+ const char *ptr = gl.rawdata;
+ UINT8 accum = 0, accumbit = 7;
+ for (int y = 0; y < gl.bmheight; y++)
{
- int desty = y + font->height + font->yoffs - ch->yoffs - ch->bmheight;
- UINT32 *dest = (desty >= 0 && desty < font->height) ? BITMAP_ADDR32(ch->bitmap, desty, 0) : NULL;
+ int desty = y + m_height + m_yoffs - gl.yoffs - gl.bmheight;
+ UINT32 *dest = (desty >= 0 && desty < m_height) ? BITMAP_ADDR32(gl.bitmap, desty, 0) : NULL;
- /* text format */
- if (font->format == FONT_FORMAT_TEXT)
+ // text format
+ if (m_format == FF_TEXT)
{
- /* loop over bytes */
- for (x = 0; x < ch->bmwidth; x += 4)
+ // loop over bytes
+ for (int x = 0; x < gl.bmwidth; x += 4)
{
+ // scan for the next hex digit
int bits = -1;
-
- /* scan for the next hex digit */
while (*ptr != 13 && bits == -1)
{
if (*ptr >= '0' && *ptr <= '9')
@@ -247,7 +200,7 @@ static void render_font_char_expand(render_font *font, render_font_char *ch)
ptr++;
}
- /* expand the four bits */
+ // expand the four bits
if (dest != NULL)
{
*dest++ = (bits & 8) ? MAKE_ARGB(0xff,0xff,0xff,0xff) : MAKE_ARGB(0x00,0xff,0xff,0xff);
@@ -257,14 +210,14 @@ static void render_font_char_expand(render_font *font, render_font_char *ch)
}
}
- /* advance to the next line */
+ // advance to the next line
ptr = next_line(ptr);
}
- /* cached format */
- else if (font->format == FONT_FORMAT_CACHED)
+ // cached format
+ else if (m_format == FF_CACHED)
{
- for (x = 0; x < ch->bmwidth; x++)
+ for (int x = 0; x < gl.bmwidth; x++)
{
if (accumbit == 7)
accum = *ptr++;
@@ -275,588 +228,545 @@ static void render_font_char_expand(render_font *font, render_font_char *ch)
}
}
- /* wrap a texture around the bitmap */
- ch->texture = font->machine->render().texture_alloc(render_texture::hq_scale);
- ch->texture->set_bitmap(ch->bitmap, NULL, TEXFORMAT_ARGB32);
+ // wrap a texture around the bitmap
+ gl.texture = m_manager.texture_alloc(render_texture::hq_scale);
+ gl.texture->set_bitmap(gl.bitmap, NULL, TEXFORMAT_ARGB32);
}
-/*-------------------------------------------------
- render_font_get_pixel_height - return the
- height of the font in pixels
--------------------------------------------------*/
+//-------------------------------------------------
+// get_char_texture_and_bounds - return the
+// texture for a character and compute the
+// bounds of the final bitmap
+//-------------------------------------------------
-INT32 render_font_get_pixel_height(render_font *font)
+render_texture *render_font::get_char_texture_and_bounds(float height, float aspect, unicode_char chnum, render_bounds &bounds)
{
- return font->height;
-}
-
+ glyph &gl = get_char(chnum);
-/*-------------------------------------------------
- render_font_get_char_texture_and_bounds -
- return the texture for a character and compute
- the bounds of the final bitmap
--------------------------------------------------*/
+ // on entry, assume x0,y0 are the top,left coordinate of the cell and add
+ // the character bounding box to that position
+ float scale = m_scale * height;
+ bounds.x0 += (float)gl.xoffs * scale * aspect;
-render_texture *render_font_get_char_texture_and_bounds(render_font *font, float height, float aspect, unicode_char chnum, render_bounds *bounds)
-{
- render_font_char *ch = get_char(font, chnum);
- float scale = font->scale * height;
+ // compute x1,y1 from there based on the bitmap size
+ bounds.x1 = bounds.x0 + (float)gl.bmwidth * scale * aspect;
+ bounds.y1 = bounds.y0 + (float)m_height * scale;
- /* on entry, assume x0,y0 are the top,left coordinate of the cell and add */
- /* the character bounding box to that position */
- bounds->x0 += (float)ch->xoffs * scale * aspect;
-
- /* compute x1,y1 from there based on the bitmap size */
- bounds->x1 = bounds->x0 + (float)ch->bmwidth * scale * aspect;
- bounds->y1 = bounds->y0 + (float)font->height * scale;
-
- /* return the texture */
- return ch->texture;
+ // return the texture
+ return gl.texture;
}
-/*-------------------------------------------------
- render_font_draw_string_to_bitmap - draw a
- string to a bitmap
--------------------------------------------------*/
+//-------------------------------------------------
+// get_scaled_bitmap_and_bounds - return a
+// scaled bitmap and bounding rect for a char
+//-------------------------------------------------
-void render_font_get_scaled_bitmap_and_bounds(render_font *font, bitmap_t *dest, float height, float aspect, unicode_char chnum, rectangle *bounds)
+void render_font::get_scaled_bitmap_and_bounds(bitmap_t &dest, float height, float aspect, unicode_char chnum, rectangle &bounds)
{
- render_font_char *ch = get_char(font, chnum);
- float scale = font->scale * height;
- INT32 origwidth, origheight;
+ glyph &gl = get_char(chnum);
- /* on entry, assume x0,y0 are the top,left coordinate of the cell and add */
- /* the character bounding box to that position */
- bounds->min_x = (float)ch->xoffs * scale * aspect;
- bounds->min_y = 0;
+ // on entry, assume x0,y0 are the top,left coordinate of the cell and add
+ // the character bounding box to that position
+ float scale = m_scale * height;
+ bounds.min_x = (float)gl.xoffs * scale * aspect;
+ bounds.min_y = 0;
- /* compute x1,y1 from there based on the bitmap size */
- bounds->max_x = bounds->min_x + (float)ch->bmwidth * scale * aspect;
- bounds->max_y = bounds->min_y + (float)font->height * scale;
+ // compute x1,y1 from there based on the bitmap size
+ bounds.max_x = bounds.min_x + (float)gl.bmwidth * scale * aspect;
+ bounds.max_y = bounds.min_y + (float)m_height * scale;
- /* if the bitmap isn't big enough, bail */
- if (dest->width < bounds->max_x - bounds->min_x || dest->height < bounds->max_y - bounds->min_y)
+ // if the bitmap isn't big enough, bail
+ if (dest.width < bounds.max_x - bounds.min_x || dest.height < bounds.max_y - bounds.min_y)
return;
- /* scale the font */
- origwidth = dest->width;
- origheight = dest->height;
- dest->width = bounds->max_x - bounds->min_x;
- dest->height = bounds->max_y - bounds->min_y;
+ // scale the font
+ INT32 origwidth = dest.width;
+ INT32 origheight = dest.height;
+ dest.width = bounds.max_x - bounds.min_x;
+ dest.height = bounds.max_y - bounds.min_y;
rectangle clip;
clip.min_x = clip.min_y = 0;
- clip.max_x = ch->bitmap->width - 1;
- clip.max_y = ch->bitmap->height - 1;
- render_texture::hq_scale(*dest, *ch->bitmap, clip, NULL);
- dest->width = origwidth;
- dest->height = origheight;
+ clip.max_x = gl.bitmap->width - 1;
+ clip.max_y = gl.bitmap->height - 1;
+ render_texture::hq_scale(dest, *gl.bitmap, clip, NULL);
+ dest.width = origwidth;
+ dest.height = origheight;
}
-/*-------------------------------------------------
- render_font_char_width - return the width of
- a character at the given height
--------------------------------------------------*/
+//-------------------------------------------------
+// char_width - return the width of a character
+// at the given height
+//-------------------------------------------------
-float render_font_get_char_width(render_font *font, float height, float aspect, unicode_char ch)
+float render_font::char_width(float height, float aspect, unicode_char ch)
{
- return (float)get_char(font, ch)->width * font->scale * height * aspect;
+ return (float)get_char(ch).width * m_scale * height * aspect;
}
-/*-------------------------------------------------
- render_font_string_width - return the width of
- a string at the given height
--------------------------------------------------*/
+//-------------------------------------------------
+// string_width - return the width of a string
+// at the given height
+//-------------------------------------------------
-float render_font_get_string_width(render_font *font, float height, float aspect, const char *string)
+float render_font::string_width(float height, float aspect, const char *string)
{
- const unsigned char *ptr;
+ // loop over the string and accumulate widths
int totwidth = 0;
+ for (const unsigned char *ptr = (const unsigned char *)string; *ptr != 0; ptr++)
+ totwidth += get_char(*ptr).width;
- /* loop over the string and accumulate widths */
- for (ptr = (const unsigned char *)string; *ptr != 0; ptr++)
- totwidth += get_char(font, *ptr)->width;
-
- /* scale the final result based on height */
- return (float)totwidth * font->scale * height * aspect;
+ // scale the final result based on height
+ return (float)totwidth * m_scale * height * aspect;
}
-/*-------------------------------------------------
- render_font_get_utf8string_width - return the
- width of a UTF8-encoded string at the given
- height
--------------------------------------------------*/
+//-------------------------------------------------
+// utf8string_width - return the width of a
+// UTF8-encoded string at the given height
+//-------------------------------------------------
-float render_font_get_utf8string_width(render_font *font, float height, float aspect, const char *utf8string)
+float render_font::utf8string_width(float height, float aspect, const char *utf8string)
{
int length = strlen(utf8string);
- unicode_char uchar;
- int totwidth = 0;
- int count = 0;
- int offset;
- /* loop over the string and accumulate widths */
- for (offset = 0; offset < length; offset += count)
+ // loop over the string and accumulate widths
+ int count;
+ int totwidth = 0;
+ for (int offset = 0; offset < length; offset += count)
{
+ unicode_char uchar;
count = uchar_from_utf8(&uchar, utf8string + offset, length - offset);
if (count == -1)
break;
if (uchar < 0x10000)
- totwidth += get_char(font, uchar)->width;
+ totwidth += get_char(uchar).width;
}
- /* scale the final result based on height */
- return (float)totwidth * font->scale * height * aspect;
+ // scale the final result based on height
+ return (float)totwidth * m_scale * height * aspect;
}
-/*-------------------------------------------------
- render_font_load_cached_bdf - attempt to load
- a cached version of the BDF font 'filename';
- if that fails, fall back on the regular BDF
- loader and create a new cached version
--------------------------------------------------*/
+//-------------------------------------------------
+// load_cached_bdf - attempt to load a cached
+// version of the BDF font 'filename'; if that
+// fails, fall back on the regular BDF loader
+// and create a new cached version
+//-------------------------------------------------
-static int render_font_load_cached_bdf(render_font *font, const char *filename)
+bool render_font::load_cached_bdf(const char *filename)
{
- file_error filerr;
- char *cachedname = NULL;
- char *data = NULL;
- mame_file *cachefile;
+ // first try to open the BDF itself
mame_file *file;
- int result = 1;
- UINT32 bytes;
- UINT32 hash;
-
- /* first try to open the BDF itself */
- filerr = mame_fopen(SEARCHPATH_FONT, filename, OPEN_FLAG_READ, &file);
+ file_error filerr = mame_fopen(SEARCHPATH_FONT, filename, OPEN_FLAG_READ, &file);
if (filerr != FILERR_NONE)
- return 1;
-
- /* determine the file size and allocate memory */
- font->rawsize = mame_fsize(file);
- data = global_alloc_array_clear(char, font->rawsize + 1);
+ return false;
- /* read and hash the first chunk */
- bytes = mame_fread(file, data, MIN(CACHED_BDF_HASH_SIZE, font->rawsize));
- if (bytes != MIN(CACHED_BDF_HASH_SIZE, font->rawsize))
- goto error;
- hash = crc32(0, (const UINT8*)data, bytes) ^ (UINT32)font->rawsize;
+ // determine the file size and allocate memory
+ m_rawsize = mame_fsize(file);
+ char *data = auto_alloc_array_clear(&m_manager.machine(), char, m_rawsize + 1);
- /* create the cached filename */
- cachedname = mame_strdup(filename);
- if (cachedname == NULL)
- goto error;
+ // read the first chunk
+ UINT32 bytes = mame_fread(file, data, MIN(CACHED_BDF_HASH_SIZE, m_rawsize));
+ if (bytes != MIN(CACHED_BDF_HASH_SIZE, m_rawsize))
+ {
+ mame_fclose(file);
+ return false;
+ }
+
+ // has the chunk
+ UINT32 hash = crc32(0, (const UINT8 *)data, bytes) ^ (UINT32)m_rawsize;
- /* change the 'F' to a 'C' on the extension */
- cachedname[strlen(cachedname) - 1] -= 3;
+ // create the cached filename, changing the 'F' to a 'C' on the extension
+ astring cachedname(filename);
+ cachedname.del(cachedname.len() - 3, 3).cat("bdc");
- /* attempt to load a cached version of the font */
+ // attempt to open the cached version of the font
+ mame_file *cachefile;
filerr = mame_fopen(SEARCHPATH_FONT, cachedname, OPEN_FLAG_READ, &cachefile);
if (filerr == FILERR_NONE)
{
- result = render_font_load_cached(font, cachefile, hash);
+ // if we have a cached version, load it
+ bool result = load_cached(cachefile, hash);
mame_fclose(cachefile);
+
+ // if that worked, we're done
+ if (result)
+ {
+ mame_fclose(file);
+ auto_free(&m_manager.machine(), data);
+ return true;
+ }
}
- if (result != 0)
+
+ // read in the rest of the font
+ if (bytes < m_rawsize)
{
- /* if that failed, read the rest of the font and parse it */
- if (bytes < font->rawsize)
+ UINT32 read = mame_fread(file, data + bytes, m_rawsize - bytes);
+ if (read != m_rawsize - bytes)
{
- UINT32 read = mame_fread(file, data + bytes, font->rawsize - bytes);
- if (read != font->rawsize - bytes)
- goto error;
+ mame_fclose(file);
+ auto_free(&m_manager.machine(), data);
+ return false;
}
+ }
- /* NULL-terminate the data and attach it to the font */
- data[font->rawsize] = 0;
- font->rawdata = data;
+ // NULL-terminate the data and attach it to the font
+ data[m_rawsize] = 0;
+ m_rawdata = data;
- /* load the BDF */
- result = render_font_load_bdf(font);
+ // load the BDF
+ bool result = load_bdf();
- /* if we loaded okay, create a cached one */
- if (result == 0)
- render_font_save_cached(font, cachedname, hash);
- }
- else
- global_free(data);
+ // if we loaded okay, create a cached one
+ if (result)
+ save_cached(cachedname, hash);
- /* close the file */
- osd_free(cachedname);
+ // close the file
mame_fclose(file);
return result;
-
-error:
- /* close the file */
- if (cachedname != NULL)
- osd_free(cachedname);
- if (data != NULL)
- global_free(data);
- mame_fclose(file);
- return 1;
}
-/*-------------------------------------------------
- render_font_load_bdf - parse and load a BDF
- font
--------------------------------------------------*/
+//-------------------------------------------------
+// load_bdf - parse and load a BDF font
+//-------------------------------------------------
-static int render_font_load_bdf(render_font *font)
+bool render_font::load_bdf()
{
- const char *ptr;
- int charcount = 0;
+ // set the format to text
+ m_format = FF_TEXT;
- /* set the format to text */
- font->format = FONT_FORMAT_TEXT;
-
- /* first find the FONTBOUNDINGBOX tag */
- for (ptr = font->rawdata; ptr != NULL; ptr = next_line(ptr))
+ // first find the FONTBOUNDINGBOX tag
+ const char *ptr;
+ for (ptr = m_rawdata; ptr != NULL; ptr = next_line(ptr))
{
- int dummy1, dummy2;
-
- /* we only care about a tiny few fields */
+ // we only care about a tiny few fields
if (strncmp(ptr, "FONTBOUNDINGBOX ", 16) == 0)
{
- if (sscanf(ptr + 16, "%d %d %d %d", &dummy1, &font->height, &dummy2, &font->yoffs) != 4)
- return 1;
+ int dummy1, dummy2;
+ if (sscanf(ptr + 16, "%d %d %d %d", &dummy1, &m_height, &dummy2, &m_yoffs) != 4)
+ return false;
break;
}
}
- /* compute the scale factor */
- font->scale = 1.0f / (float)font->height;
+ // compute the scale factor
+ m_scale = 1.0f / (float)m_height;
- /* now scan for characters */
+ // now scan for characters
+ int charcount = 0;
for ( ; ptr != NULL; ptr = next_line(ptr))
{
- /* stop at ENDFONT */
+ // stop at ENDFONT
if (strncmp(ptr, "ENDFONT", 7) == 0)
break;
- /* once we hit a STARTCHAR, parse until the end */
+ // once we hit a STARTCHAR, parse until the end
if (strncmp(ptr, "STARTCHAR ", 10) == 0)
{
int bmwidth = -1, bmheight = -1, xoffs = -1, yoffs = -1;
const char *rawdata = NULL;
int charnum = -1;
int width = -1;
- int dummy1;
- /* scan for interesting per-character tags */
+ // scan for interesting per-character tags
for ( ; ptr != NULL; ptr = next_line(ptr))
{
- /* ENCODING tells us which character */
+ // ENCODING tells us which character
if (strncmp(ptr, "ENCODING ", 9) == 0)
{
if (sscanf(ptr + 9, "%d", &charnum) != 1)
return 1;
}
- /* DWIDTH tells us the width to the next character */
+ // DWIDTH tells us the width to the next character
else if (strncmp(ptr, "DWIDTH ", 7) == 0)
{
+ int dummy1;
if (sscanf(ptr + 7, "%d %d", &width, &dummy1) != 2)
return 1;
}
- /* BBX tells us the height/width of the bitmap and the offsets */
+ // BBX tells us the height/width of the bitmap and the offsets
else if (strncmp(ptr, "BBX ", 4) == 0)
{
if (sscanf(ptr + 4, "%d %d %d %d", &bmwidth, &bmheight, &xoffs, &yoffs) != 4)
return 1;
}
- /* BITMAP is the start of the data */
+ // BITMAP is the start of the data
else if (strncmp(ptr, "BITMAP", 6) == 0)
{
- /* stash the raw pointer and scan for the end of the character */
+ // stash the raw pointer and scan for the end of the character
for (rawdata = ptr = next_line(ptr); ptr != NULL && strncmp(ptr, "ENDCHAR", 7) != 0; ptr = next_line(ptr)) ;
break;
}
}
- /* if we have everything, allocate a new character */
+ // if we have everything, allocate a new character
if (charnum >= 0 && charnum < 65536 && rawdata != NULL && bmwidth >= 0 && bmheight >= 0)
{
- render_font_char *ch;
-
- /* if we don't have a subtable yet, make one */
- if (font->chars[charnum / 256] == NULL)
- font->chars[charnum / 256] = global_alloc_array_clear(render_font_char, 256);
-
- /* fill in the entry */
- ch = &font->chars[charnum / 256][charnum % 256];
- ch->width = width;
- ch->bmwidth = bmwidth;
- ch->bmheight = bmheight;
- ch->xoffs = xoffs;
- ch->yoffs = yoffs;
- ch->rawdata = rawdata;
+ // if we don't have a subtable yet, make one
+ if (m_glyphs[charnum / 256] == NULL)
+ m_glyphs[charnum / 256] = auto_alloc_array_clear(&m_manager.machine(), glyph, 256);
+
+ // fill in the entry
+ glyph &gl = m_glyphs[charnum / 256][charnum % 256];
+ gl.width = width;
+ gl.bmwidth = bmwidth;
+ gl.bmheight = bmheight;
+ gl.xoffs = xoffs;
+ gl.yoffs = yoffs;
+ gl.rawdata = rawdata;
}
- /* some progress for big fonts */
+ // some progress for big fonts
if (++charcount % 256 == 0)
mame_printf_warning("Loading BDF font... (%d characters loaded)\n", charcount);
}
}
- /* make sure all the numbers are the same width */
- if (font->chars[0] != NULL)
+ // make sure all the numbers are the same width
+ if (m_glyphs[0] != NULL)
{
int maxwidth = 0;
for (int ch = '0'; ch <= '9'; ch++)
- if (font->chars[0][ch].bmwidth > maxwidth)
- maxwidth = font->chars[0][ch].width;
+ if (m_glyphs[0][ch].bmwidth > maxwidth)
+ maxwidth = m_glyphs[0][ch].width;
for (int ch = '0'; ch <= '9'; ch++)
- font->chars[0][ch].width = maxwidth;
+ m_glyphs[0][ch].width = maxwidth;
}
- return 0;
+ return true;
}
-/*-------------------------------------------------
- render_font_load_cached - load a font in
- cached format
--------------------------------------------------*/
+//-------------------------------------------------
+// load_cached - load a font in cached format
+//-------------------------------------------------
-static int render_font_load_cached(render_font *font, mame_file *file, UINT32 hash)
+bool render_font::load_cached(mame_file *file, UINT32 hash)
{
- UINT8 header[CACHED_HEADER_SIZE];
- UINT64 offset, filesize;
- UINT8 *data = NULL;
- UINT32 bytes_read;
- int numchars;
- int chindex;
-
- /* get the file size */
- filesize = mame_fsize(file);
+ // get the file size
+ UINT64 filesize = mame_fsize(file);
- /* first read the header */
- bytes_read = mame_fread(file, header, CACHED_HEADER_SIZE);
+ // first read the header
+ UINT8 header[CACHED_HEADER_SIZE];
+ UINT32 bytes_read = mame_fread(file, header, CACHED_HEADER_SIZE);
if (bytes_read != CACHED_HEADER_SIZE)
- goto error;
+ return false;
- /* validate the header */
+ // validate the header
if (header[0] != 'f' || header[1] != 'o' || header[2] != 'n' || header[3] != 't')
- goto error;
+ return false;
if (header[4] != (UINT8)(hash >> 24) || header[5] != (UINT8)(hash >> 16) || header[6] != (UINT8)(hash >> 8) || header[7] != (UINT8)hash)
- goto error;
- font->height = (header[8] << 8) | header[9];
- font->scale = 1.0f / (float)font->height;
- font->yoffs = (INT16)((header[10] << 8) | header[11]);
- numchars = (header[12] << 24) | (header[13] << 16) | (header[14] << 8) | header[15];
+ return false;
+ m_height = (header[8] << 8) | header[9];
+ m_scale = 1.0f / (float)m_height;
+ m_yoffs = (INT16)((header[10] << 8) | header[11]);
+ int numchars = (header[12] << 24) | (header[13] << 16) | (header[14] << 8) | header[15];
if (filesize - CACHED_HEADER_SIZE < numchars * CACHED_CHAR_SIZE)
- goto error;
+ return false;
- /* now read the rest of the data */
- data = global_alloc_array(UINT8, filesize - CACHED_HEADER_SIZE);
+ // now read the rest of the data
+ UINT8 *data = auto_alloc_array(&m_manager.machine(), UINT8, filesize - CACHED_HEADER_SIZE);
bytes_read = mame_fread(file, data, filesize - CACHED_HEADER_SIZE);
if (bytes_read != filesize - CACHED_HEADER_SIZE)
- goto error;
+ {
+ auto_free(&m_manager.machine(), data);
+ return false;
+ }
- /* extract the data from the data */
- offset = numchars * CACHED_CHAR_SIZE;
- for (chindex = 0; chindex < numchars; chindex++)
+ // extract the data from the data
+ UINT64 offset = numchars * CACHED_CHAR_SIZE;
+ for (int chindex = 0; chindex < numchars; chindex++)
{
const UINT8 *info = &data[chindex * CACHED_CHAR_SIZE];
int chnum = (info[0] << 8) | info[1];
- render_font_char *ch;
-
- /* if we don't have a subtable yet, make one */
- if (font->chars[chnum / 256] == NULL)
- font->chars[chnum / 256] = global_alloc_array_clear(render_font_char, 256);
-
- /* fill in the entry */
- ch = &font->chars[chnum / 256][chnum % 256];
- ch->width = (info[2] << 8) | info[3];
- ch->xoffs = (INT16)((info[4] << 8) | info[5]);
- ch->yoffs = (INT16)((info[6] << 8) | info[7]);
- ch->bmwidth = (info[8] << 8) | info[9];
- ch->bmheight = (info[10] << 8) | info[11];
- ch->rawdata = (char *)data + offset;
-
- /* advance the offset past the character */
- offset += (ch->bmwidth * ch->bmheight + 7) / 8;
+
+ // if we don't have a subtable yet, make one
+ if (m_glyphs[chnum / 256] == NULL)
+ m_glyphs[chnum / 256] = auto_alloc_array_clear(&m_manager.machine(), glyph, 256);
+
+ // fill in the entry
+ glyph &gl = m_glyphs[chnum / 256][chnum % 256];
+ gl.width = (info[2] << 8) | info[3];
+ gl.xoffs = (INT16)((info[4] << 8) | info[5]);
+ gl.yoffs = (INT16)((info[6] << 8) | info[7]);
+ gl.bmwidth = (info[8] << 8) | info[9];
+ gl.bmheight = (info[10] << 8) | info[11];
+ gl.rawdata = (char *)data + offset;
+
+ // advance the offset past the character
+ offset += (gl.bmwidth * gl.bmheight + 7) / 8;
if (offset > filesize - CACHED_HEADER_SIZE)
- goto error;
+ {
+ auto_free(&m_manager.machine(), data);
+ return false;
+ }
}
- /* reuse the chartable as a temporary buffer */
- font->format = FONT_FORMAT_CACHED;
- font->rawdata = (char *)data;
- return 0;
-
-error:
- if (data != NULL)
- global_free(data);
- return 1;
+ // reuse the chartable as a temporary buffer
+ m_format = FF_CACHED;
+ m_rawdata = (char *)data;
+ return true;
}
-/*-------------------------------------------------
- render_font_save_cached - save a font in
- cached format
--------------------------------------------------*/
+//-------------------------------------------------
+// save_cached - save a font in cached format
+//-------------------------------------------------
-static int render_font_save_cached(render_font *font, const char *filename, UINT32 hash)
+bool render_font::save_cached(const char *filename, UINT32 hash)
{
- file_error filerr;
- render_font_char *ch;
- UINT32 bytes_written;
- UINT8 *tempbuffer;
- UINT8 *chartable;
- mame_file *file;
- int numchars;
- UINT8 *dest;
- int tableindex;
- int chnum;
-
mame_printf_warning("Generating cached BDF font...\n");
- /* attempt to open the file */
- filerr = mame_fopen(SEARCHPATH_FONT, filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file);
+ // attempt to open the file
+ mame_file *file;
+ file_error filerr = mame_fopen(SEARCHPATH_FONT, filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file);
if (filerr != FILERR_NONE)
- return 1;
+ return false;
- /* determine the number of characters */
- numchars = 0;
- for (chnum = 0; chnum < 65536; chnum++)
+ // determine the number of characters
+ int numchars = 0;
+ for (int chnum = 0; chnum < 65536; chnum++)
{
- render_font_char *chtable = font->chars[chnum / 256];
+ glyph *chtable = m_glyphs[chnum / 256];
if (chtable != NULL)
{
- ch = &chtable[chnum % 256];
- if (ch->width > 0)
+ glyph &gl = chtable[chnum % 256];
+ if (gl.width > 0)
numchars++;
}
}
- /* allocate an array to hold the character data */
- chartable = global_alloc_array_clear(UINT8, numchars * CACHED_CHAR_SIZE);
-
- /* allocate a temp buffer to compress into */
- tempbuffer = global_alloc_array(UINT8, 65536);
-
- /* write the header */
- dest = tempbuffer;
- *dest++ = 'f';
- *dest++ = 'o';
- *dest++ = 'n';
- *dest++ = 't';
- *dest++ = hash >> 24;
- *dest++ = hash >> 16;
- *dest++ = hash >> 8;
- *dest++ = hash & 0xff;
- *dest++ = font->height >> 8;
- *dest++ = font->height & 0xff;
- *dest++ = font->yoffs >> 8;
- *dest++ = font->yoffs & 0xff;
- *dest++ = numchars >> 24;
- *dest++ = numchars >> 16;
- *dest++ = numchars >> 8;
- *dest++ = numchars & 0xff;
- assert(dest - tempbuffer == CACHED_HEADER_SIZE);
- bytes_written = mame_fwrite(file, tempbuffer, dest - tempbuffer);
- if (bytes_written != dest - tempbuffer)
- goto error;
-
- /* write the empty table to the beginning of the file */
- bytes_written = mame_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE);
- if (bytes_written != numchars * CACHED_CHAR_SIZE)
- goto error;
-
- /* loop over all characters */
- tableindex = 0;
- for (chnum = 0; chnum < 65536; chnum++)
+ UINT8 *chartable = NULL;
+ UINT8 *tempbuffer = NULL;
+ try
{
- ch = get_char(font, chnum);
- if (ch != NULL && ch->width > 0)
+ // allocate an array to hold the character data
+ UINT8 *chartable = auto_alloc_array_clear(&m_manager.machine(), UINT8, numchars * CACHED_CHAR_SIZE);
+
+ // allocate a temp buffer to compress into
+ UINT8 *tempbuffer = auto_alloc_array(&m_manager.machine(), UINT8, 65536);
+
+ // write the header
+ UINT8 *dest = tempbuffer;
+ *dest++ = 'f';
+ *dest++ = 'o';
+ *dest++ = 'n';
+ *dest++ = 't';
+ *dest++ = hash >> 24;
+ *dest++ = hash >> 16;
+ *dest++ = hash >> 8;
+ *dest++ = hash & 0xff;
+ *dest++ = m_height >> 8;
+ *dest++ = m_height & 0xff;
+ *dest++ = m_yoffs >> 8;
+ *dest++ = m_yoffs & 0xff;
+ *dest++ = numchars >> 24;
+ *dest++ = numchars >> 16;
+ *dest++ = numchars >> 8;
+ *dest++ = numchars & 0xff;
+ assert(dest - tempbuffer == CACHED_HEADER_SIZE);
+ UINT32 bytes_written = mame_fwrite(file, tempbuffer, dest - tempbuffer);
+ if (bytes_written != dest - tempbuffer)
+ throw emu_fatalerror("Error writing cached file");
+
+ // write the empty table to the beginning of the file
+ bytes_written = mame_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE);
+ if (bytes_written != numchars * CACHED_CHAR_SIZE)
+ throw emu_fatalerror("Error writing cached file");
+
+ // loop over all characters
+ int tableindex = 0;
+ for (int chnum = 0; chnum < 65536; chnum++)
{
- UINT8 accum, accbit;
- int x, y;
-
- /* write out a bit-compressed bitmap if we have one */
- if (ch->bitmap != NULL)
+ glyph &gl = get_char(chnum);
+ if (gl.width > 0)
{
- /* write the data to the tempbuffer */
- dest = tempbuffer;
- accum = 0;
- accbit = 7;
-
- /* bit-encode the character data */
- for (y = 0; y < ch->bmheight; y++)
+ // write out a bit-compressed bitmap if we have one
+ if (gl.bitmap != NULL)
{
- int desty = y + font->height + font->yoffs - ch->yoffs - ch->bmheight;
- const UINT32 *src = (desty >= 0 && desty < font->height) ? BITMAP_ADDR32(ch->bitmap, desty, 0) : NULL;
- for (x = 0; x < ch->bmwidth; x++)
+ // write the data to the tempbuffer
+ dest = tempbuffer;
+ UINT8 accum = 0;
+ UINT8 accbit = 7;
+
+ // bit-encode the character data
+ for (int y = 0; y < gl.bmheight; y++)
{
- if (src != NULL && RGB_ALPHA(src[x]) != 0)
- accum |= 1 << accbit;
- if (accbit-- == 0)
+ int desty = y + m_height + m_yoffs - gl.yoffs - gl.bmheight;
+ const UINT32 *src = (desty >= 0 && desty < m_height) ? BITMAP_ADDR32(gl.bitmap, desty, 0) : NULL;
+ for (int x = 0; x < gl.bmwidth; x++)
{
- *dest++ = accum;
- accum = 0;
- accbit = 7;
+ if (src != NULL && RGB_ALPHA(src[x]) != 0)
+ accum |= 1 << accbit;
+ if (accbit-- == 0)
+ {
+ *dest++ = accum;
+ accum = 0;
+ accbit = 7;
+ }
}
}
- }
- /* flush any extra */
- if (accbit != 7)
- *dest++ = accum;
+ // flush any extra
+ if (accbit != 7)
+ *dest++ = accum;
- /* write the data */
- bytes_written = mame_fwrite(file, tempbuffer, dest - tempbuffer);
- if (bytes_written != dest - tempbuffer)
- goto error;
+ // write the data
+ bytes_written = mame_fwrite(file, tempbuffer, dest - tempbuffer);
+ if (bytes_written != dest - tempbuffer)
+ throw emu_fatalerror("Error writing cached file");
- /* free the bitmap and texture */
- font->machine->render().texture_free(ch->texture);
- ch->texture = NULL;
- global_free(ch->bitmap);
- ch->bitmap = NULL;
- }
+ // free the bitmap and texture
+ m_manager.texture_free(gl.texture);
+ auto_free(&m_manager.machine(), gl.bitmap);
+ gl.texture = NULL;
+ gl.bitmap = NULL;
+ }
- /* compute the table entry */
- dest = &chartable[tableindex++ * CACHED_CHAR_SIZE];
- *dest++ = chnum >> 8;
- *dest++ = chnum & 0xff;
- *dest++ = ch->width >> 8;
- *dest++ = ch->width & 0xff;
- *dest++ = ch->xoffs >> 8;
- *dest++ = ch->xoffs & 0xff;
- *dest++ = ch->yoffs >> 8;
- *dest++ = ch->yoffs & 0xff;
- *dest++ = ch->bmwidth >> 8;
- *dest++ = ch->bmwidth & 0xff;
- *dest++ = ch->bmheight >> 8;
- *dest++ = ch->bmheight & 0xff;
+ // compute the table entry
+ dest = &chartable[tableindex++ * CACHED_CHAR_SIZE];
+ *dest++ = chnum >> 8;
+ *dest++ = chnum & 0xff;
+ *dest++ = gl.width >> 8;
+ *dest++ = gl.width & 0xff;
+ *dest++ = gl.xoffs >> 8;
+ *dest++ = gl.xoffs & 0xff;
+ *dest++ = gl.yoffs >> 8;
+ *dest++ = gl.yoffs & 0xff;
+ *dest++ = gl.bmwidth >> 8;
+ *dest++ = gl.bmwidth & 0xff;
+ *dest++ = gl.bmheight >> 8;
+ *dest++ = gl.bmheight & 0xff;
+ }
}
- }
-
- /* seek back to the beginning and rewrite the table */
- mame_fseek(file, CACHED_HEADER_SIZE, SEEK_SET);
- bytes_written = mame_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE);
- if (bytes_written != numchars * CACHED_CHAR_SIZE)
- goto error;
- /* all done */
- mame_fclose(file);
- global_free(tempbuffer);
- global_free(chartable);
- return 0;
-
-error:
- mame_fclose(file);
- osd_rmfile(filename);
- global_free(tempbuffer);
- global_free(chartable);
- return 1;
+ // seek back to the beginning and rewrite the table
+ mame_fseek(file, CACHED_HEADER_SIZE, SEEK_SET);
+ bytes_written = mame_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE);
+ if (bytes_written != numchars * CACHED_CHAR_SIZE)
+ throw emu_fatalerror("Error writing cached file");
+
+ // all done
+ mame_fclose(file);
+ auto_free(&m_manager.machine(), tempbuffer);
+ auto_free(&m_manager.machine(), chartable);
+ return true;
+ }
+ catch (...)
+ {
+ mame_fclose(file);
+ osd_rmfile(filename);
+ auto_free(&m_manager.machine(), tempbuffer);
+ auto_free(&m_manager.machine(), chartable);
+ return false;
+ }
}
diff --git a/src/emu/rendfont.h b/src/emu/rendfont.h
index d8656b1ac0e..1eba3bc1a71 100644
--- a/src/emu/rendfont.h
+++ b/src/emu/rendfont.h
@@ -4,8 +4,36 @@
Rendering system font management.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -15,18 +43,81 @@
#include "render.h"
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-render_font *render_font_alloc(running_machine &machine, const char *filename);
-void render_font_free(render_font *font);
-INT32 render_font_get_pixel_height(render_font *font);
-render_texture *render_font_get_char_texture_and_bounds(render_font *font, float height, float aspect, unicode_char ch, render_bounds *bounds);
-void render_font_get_scaled_bitmap_and_bounds(render_font *font, bitmap_t *dest, float height, float aspect, unicode_char chnum, rectangle *bounds);
-float render_font_get_char_width(render_font *font, float height, float aspect, unicode_char ch);
-float render_font_get_string_width(render_font *font, float height, float aspect, const char *string);
-float render_font_get_utf8string_width(render_font *font, float height, float aspect, const char *utf8string);
+// ======================> render_font
+
+// a render_font describes and provides an interface to a font
+class render_font
+{
+ friend class render_manager;
+ friend resource_pool_object<render_font>::~resource_pool_object();
+
+ // construction/destruction
+ render_font(render_manager &manager, const char *filename);
+ virtual ~render_font();
+
+public:
+ // getters
+ render_manager &manager() const { return m_manager; }
+
+ // size queries
+ INT32 pixel_height() const { return m_height; }
+ float char_width(float height, float aspect, unicode_char ch);
+ float string_width(float height, float aspect, const char *string);
+ float utf8string_width(float height, float aspect, const char *utf8string);
+
+ // texture/bitmap queries
+ render_texture *get_char_texture_and_bounds(float height, float aspect, unicode_char ch, render_bounds &bounds);
+ void get_scaled_bitmap_and_bounds(bitmap_t &dest, float height, float aspect, unicode_char chnum, rectangle &bounds);
+
+private:
+ // a glyph describes a single glyph
+ class glyph
+ {
+ public:
+ INT32 width; /* width from this character to the next */
+ INT32 xoffs, yoffs; /* X and Y offset from baseline to top,left of bitmap */
+ INT32 bmwidth, bmheight; /* width and height of bitmap */
+ const char * rawdata; /* pointer to the raw data for this one */
+ bitmap_t * bitmap; /* pointer to the bitmap containing the raw data */
+ render_texture * texture; /* pointer to a texture for rendering and sizing */
+ };
+
+ // internal format
+ enum format
+ {
+ FF_UNKNOWN,
+ FF_TEXT,
+ FF_CACHED
+ };
+
+ // helpers
+ glyph &get_char(unicode_char chnum);
+ void char_expand(glyph &ch);
+ bool load_cached_bdf(const char *filename);
+ bool load_bdf();
+ bool load_cached(mame_file *file, UINT32 hash);
+ bool save_cached(const char *filename, UINT32 hash);
+
+ // internal state
+ render_manager & m_manager;
+ format m_format; /* format of font data */
+ int m_height; /* height of the font, from ascent to descent */
+ int m_yoffs; /* y offset from baseline to descent */
+ float m_scale; /* 1 / height precomputed */
+ glyph * m_glyphs[256]; /* array of glyph subtables */
+ const char * m_rawdata; /* pointer to the raw data for the font */
+ UINT64 m_rawsize; /* size of the raw font data */
+
+ // constants
+ static const int CACHED_CHAR_SIZE = 12;
+ static const int CACHED_HEADER_SIZE = 16;
+ static const int CACHED_BDF_HASH_SIZE = 1024;
+};
+
#endif /* __RENDFONT_H__ */
diff --git a/src/emu/rendlay.c b/src/emu/rendlay.c
index 963426f2286..633d2abce0d 100644
--- a/src/emu/rendlay.c
+++ b/src/emu/rendlay.c
@@ -827,12 +827,12 @@ void layout_element::component::draw_text(running_machine &machine, bitmap_t &de
UINT32 a = m_color.a * 255.0;
// get the width of the string
- render_font *font = render_font_alloc(machine, NULL);
+ render_font *font = machine.render().font_alloc();
float aspect = 1.0f;
INT32 width;
while (1)
{
- width = render_font_get_string_width(font, bounds.max_y - bounds.min_y, aspect, m_string);
+ width = font->string_width(bounds.max_y - bounds.min_y, aspect, m_string);
if (width < bounds.max_x - bounds.min_x)
break;
aspect *= 0.9f;
@@ -847,7 +847,7 @@ void layout_element::component::draw_text(running_machine &machine, bitmap_t &de
{
// get the font bitmap
rectangle chbounds;
- render_font_get_scaled_bitmap_and_bounds(font, tempbitmap, bounds.max_y - bounds.min_y, aspect, *s, &chbounds);
+ font->get_scaled_bitmap_and_bounds(*tempbitmap, bounds.max_y - bounds.min_y, aspect, *s, chbounds);
// copy the data into the target
for (int y = 0; y < chbounds.max_y - chbounds.min_y; y++)
@@ -878,12 +878,12 @@ void layout_element::component::draw_text(running_machine &machine, bitmap_t &de
}
// advance in the X direction
- curx += render_font_get_char_width(font, bounds.max_y - bounds.min_y, aspect, *s);
+ curx += font->char_width(bounds.max_y - bounds.min_y, aspect, *s);
}
// free the temporary bitmap and font
global_free(tempbitmap);
- render_font_free(font);
+ machine.render().font_free(font);
}
diff --git a/src/emu/ui.c b/src/emu/ui.c
index 872b34b43fe..61031514f1a 100644
--- a/src/emu/ui.c
+++ b/src/emu/ui.c
@@ -240,7 +240,7 @@ int ui_init(running_machine *machine)
machine->add_notifier(MACHINE_NOTIFY_EXIT, ui_exit);
/* allocate the font and messagebox string */
- ui_font = render_font_alloc(*machine, "ui.bdf");
+ ui_font = machine->render().font_alloc("ui.bdf");
/* initialize the other UI bits */
ui_menu_init(machine);
@@ -263,8 +263,7 @@ int ui_init(running_machine *machine)
static void ui_exit(running_machine &machine)
{
/* free the font */
- if (ui_font != NULL)
- render_font_free(ui_font);
+ machine.render().font_free(ui_font);
ui_font = NULL;
}
@@ -424,7 +423,7 @@ render_font *ui_get_font(void)
float ui_get_line_height(running_machine &machine)
{
- INT32 raw_font_pixel_height = render_font_get_pixel_height(ui_font);
+ INT32 raw_font_pixel_height = ui_font->pixel_height();
render_target &ui_target = machine.render().ui_target();
INT32 target_pixel_height = ui_target.height();
float one_to_one_line_height;
@@ -469,7 +468,7 @@ float ui_get_line_height(running_machine &machine)
float ui_get_char_width(running_machine &machine, unicode_char ch)
{
- return render_font_get_char_width(ui_font, ui_get_line_height(machine), machine.render().ui_aspect(), ch);
+ return ui_font->char_width(ui_get_line_height(machine), machine.render().ui_aspect(), ch);
}
@@ -480,7 +479,7 @@ float ui_get_char_width(running_machine &machine, unicode_char ch)
float ui_get_string_width(running_machine &machine, const char *s)
{
- return render_font_get_utf8string_width(ui_font, ui_get_line_height(machine), machine.render().ui_aspect(), s);
+ return ui_font->utf8string_width(ui_get_line_height(machine), machine.render().ui_aspect(), s);
}
diff --git a/src/emu/uigfx.c b/src/emu/uigfx.c
index 0e2f786ff4c..cb366c194c8 100644
--- a/src/emu/uigfx.c
+++ b/src/emu/uigfx.c
@@ -253,7 +253,7 @@ static void palette_handler(running_machine *machine, render_container *containe
/* add a half character padding for the box */
chheight = ui_get_line_height(*machine);
- chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0');
+ chwidth = ui_font->char_width(chheight, machine->render().ui_aspect(), '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@@ -273,7 +273,7 @@ static void palette_handler(running_machine *machine, render_container *containe
cellboxbounds.y0 += 3.0f * chheight;
/* figure out the title and expand the outer box to fit */
- titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title);
+ titlewidth = ui_font->string_width(chheight, machine->render().ui_aspect(), title);
x0 = 0.0f;
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth));
@@ -287,7 +287,7 @@ static void palette_handler(running_machine *machine, render_container *containe
for (x = 0; title[x] != 0; x++)
{
container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]);
- x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]);
+ x0 += ui_font->char_width(chheight, machine->render().ui_aspect(), title[x]);
}
/* compute the cell size */
@@ -328,7 +328,7 @@ static void palette_handler(running_machine *machine, render_container *containe
sprintf(buffer, "%5X", state->palette.offset + y * state->palette.count);
for (x = 4; x >= 0; x--)
{
- x0 -= render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), buffer[x]);
+ x0 -= ui_font->char_width(chheight, machine->render().ui_aspect(), buffer[x]);
container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]);
}
}
@@ -449,7 +449,7 @@ static void gfxset_handler(running_machine *machine, render_container *container
/* add a half character padding for the box */
chheight = ui_get_line_height(*machine);
- chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0');
+ chwidth = ui_font->char_width(chheight, machine->render().ui_aspect(), '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@@ -514,7 +514,7 @@ static void gfxset_handler(running_machine *machine, render_container *container
/* figure out the title and expand the outer box to fit */
for (x = 0; x < MAX_GFX_ELEMENTS && machine->gfx[x] != NULL; x++) ;
sprintf(title, "GFX %d/%d %dx%d COLOR %X", state->gfxset.set, x - 1, gfx->width, gfx->height, state->gfxset.color[set]);
- titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title);
+ titlewidth = ui_font->string_width(chheight, machine->render().ui_aspect(), title);
x0 = 0.0f;
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth));
@@ -528,7 +528,7 @@ static void gfxset_handler(running_machine *machine, render_container *container
for (x = 0; title[x] != 0; x++)
{
container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]);
- x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]);
+ x0 += ui_font->char_width(chheight, machine->render().ui_aspect(), title[x]);
}
/* draw the top column headers */
@@ -565,7 +565,7 @@ static void gfxset_handler(running_machine *machine, render_container *container
sprintf(buffer, "%5X", state->gfxset.offset[set] + y * xcells);
for (x = 4; x >= 0; x--)
{
- x0 -= render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), buffer[x]);
+ x0 -= ui_font->char_width(chheight, machine->render().ui_aspect(), buffer[x]);
container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]);
}
}
@@ -861,7 +861,7 @@ static void tilemap_handler(running_machine *machine, render_container *containe
/* add a half character padding for the box */
chheight = ui_get_line_height(*machine);
- chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0');
+ chwidth = ui_font->char_width(chheight, machine->render().ui_aspect(), '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@@ -908,7 +908,7 @@ static void tilemap_handler(running_machine *machine, render_container *containe
/* figure out the title and expand the outer box to fit */
sprintf(title, "TMAP %d/%d %dx%d OFFS %d,%d", state->tilemap.which, tilemap_count(machine) - 1, mapwidth, mapheight, state->tilemap.xoffs, state->tilemap.yoffs);
- titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title);
+ titlewidth = ui_font->string_width(chheight, machine->render().ui_aspect(), title);
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
{
boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth);
@@ -924,7 +924,7 @@ static void tilemap_handler(running_machine *machine, render_container *containe
for (x = 0; title[x] != 0; x++)
{
container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]);
- x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]);
+ x0 += ui_font->char_width(chheight, machine->render().ui_aspect(), title[x]);
}
/* update the bitmap */