font_osx: handle fonts where space glyphs return a null bounding box (e.g. Hiragino family)

restore ability to localise info box headings
This commit is contained in:
Vas Crabb 2017-08-06 12:04:54 +10:00
parent 952af08ca6
commit 0a6f98cd7d
6 changed files with 83 additions and 394 deletions

View File

@ -2360,352 +2360,3 @@ msgstr "Vista DAT externa"
#: src/frontend/mame/ui/mainmenu.cpp:154
msgid "Select New Machine"
msgstr "Elegir máquina nueva"
#~ msgid " - ARGB Settings"
#~ msgstr " - Ajustes ARGB"
#~ msgid "Software History"
#~ msgstr "Historial de cambios"
#~ msgid "History"
#~ msgstr "Historial"
#~ msgid "Mameinfo"
#~ msgstr "Información de MAME"
#~ msgid "Messinfo"
#~ msgstr "Información de MESS"
#~ msgid "Sysinfo"
#~ msgstr "Información del sistema"
#~ msgid "Mamescore"
#~ msgstr "Puntuación MAME"
#~ msgid "Gameinit"
#~ msgstr "Inicio de partida"
#~ msgid "Command"
#~ msgstr "Orden"
#~ msgid "The keyboard emulation may not be 100% accurate.\n"
#~ msgstr "La emulación del teclado puede no ser del todo precisa.\n"
#~ msgid "The colors aren't 100% accurate.\n"
#~ msgstr "Los colores no son del todo precisos.\n"
#~ msgid "The colors are completely wrong.\n"
#~ msgstr "Los colores son completamente erróneos.\n"
#~ msgid "The video emulation isn't 100% accurate.\n"
#~ msgstr "La emulación de vídeo no es del todo precisa.\n"
#~ msgid "The sound emulation isn't 100% accurate.\n"
#~ msgstr "La emulación de sonido no es del todo precisa.\n"
#~ msgid "The machine lacks sound.\n"
#~ msgstr "A esta máquina le falta el sonido.\n"
#~ msgid "The machine requires external artwork files\n"
#~ msgstr "La máquina requiere ficheros de arte externos\n"
#~ msgid "The machine has protection which isn't fully emulated.\n"
#~ msgstr ""
#~ "La máquina todavía no emula completamente el sistema de protección.\n"
#~ msgid ""
#~ "\n"
#~ "Certain elements of this machine cannot be emulated as it requires actual "
#~ "physical interaction or consists of mechanical devices. It is not "
#~ "possible to fully play this machine.\n"
#~ msgstr ""
#~ "Algunos elementos de esta máquina no se pueden emular ya que necesitan de "
#~ "una interacción física o se basan en dispositivos mecánicos. Por lo que "
#~ "no esposible reproducir completamente el funcionamiento de la máquina.\n"
#~ msgid ""
#~ "\n"
#~ "\n"
#~ "There are working clones of this machine: "
#~ msgstr ""
#~ "\n"
#~ "\n"
#~ "Existen clones funcionales de esta máquina: "
#~ msgid "General Info"
#~ msgstr "Información general"
#~ msgid ""
#~ "The selected machine is missing one or more required ROM or CHD images. "
#~ "Please select a different machine.\n"
#~ "\n"
#~ "Press any key to continue."
#~ msgstr ""
#~ "Falta la máquina seleccionada o una o más de sus ROMs o imágenes CHD. Por "
#~ "favor, elige otra máquina.\n"
#~ "\n"
#~ "Pulsa cualquier tecla para continuar."
#~ msgid "Romset: %1$-.100s\n"
#~ msgstr "Conjunto de ROMs: %1$-.100s\n"
#~ msgid "Year: %1$s\n"
#~ msgstr "Año: %1$s\n"
#~ msgid "Manufacturer: %1$-.100s\n"
#~ msgstr "Fabricante: %1$-.100s\n"
#~ msgid "Driver is Clone of: %1$-.100s\n"
#~ msgstr "El controlador es un clon de: %1$-.100s\n"
#~ msgid "Driver is Parent\n"
#~ msgstr "Es un controlador padre\n"
#~ msgid "Overall: NOT WORKING\n"
#~ msgstr "En general: NO FUNCIONA\n"
#~ msgid "Overall: Unemulated Protection\n"
#~ msgstr "En general: Protección sin emular\n"
#~ msgid "Overall: Working\n"
#~ msgstr "En general: Funcionando\n"
#~ msgid "Graphics: Imperfect Colors\n"
#~ msgstr "Gráficos: Colores imperfectos\n"
#~ msgid "Graphics: Imperfect\n"
#~ msgstr "Gráficos: Imperfectos\n"
#~ msgid "Graphics: OK\n"
#~ msgstr "Gráficos: Aceptables\n"
#~ msgid "Sound: Unimplemented\n"
#~ msgstr "Sonido: No implementado\n"
#~ msgid "Sound: Imperfect\n"
#~ msgstr "Sonido: Imperfecto\n"
#~ msgid "Sound: OK\n"
#~ msgstr "Sonido: Aceptable\n"
#~ msgid "Driver is Skeleton: %1$s\n"
#~ msgstr "El controlador es esqueleto: %1$s\n"
#~ msgid "Game is Mechanical: %1$s\n"
#~ msgstr "El juego es mecánico: %1$s\n"
#~ msgid "Requires Artwork: %1$s\n"
#~ msgstr "Requiere arte: %1$s\n"
#~ msgid "Requires Clickable Artwork: %1$s\n"
#~ msgstr "Requiere arte clicable: %1$s\n"
#~ msgid "Support Cocktail: %1$s\n"
#~ msgstr "Soporta cóctel: %1$s\n"
#~ msgid "Driver is Bios: %1$s\n"
#~ msgstr "El controlador es una BIOS: %1$s\n"
#~ msgid "Support Save: %1$s\n"
#~ msgstr "Permite guardar: %1$s\n"
#~ msgid "Screen Orientation: %1$s\n"
#~ msgstr "Orientación de pantalla: %1$s\n"
#~ msgid "Requires CHD: %1$s\n"
#~ msgstr "Necesita CHD: %1$s\n"
#~ msgid "Roms Audit Pass: OK\n"
#~ msgstr "Auditoría de ROMs: CORRECTA\n"
#~ msgid "Roms Audit Pass: BAD\n"
#~ msgstr "Auditoría de ROMs: INCORRECTA\n"
#~ msgid "Samples Audit Pass: None Needed\n"
#~ msgstr "Auditoría de las muestras: No Necesaria\n"
#~ msgid "Samples Audit Pass: OK\n"
#~ msgstr "Auditoría de las muestras: CORRECTA\n"
#~ msgid "Samples Audit Pass: BAD\n"
#~ msgstr "Auditoría de las muestras: INCORRECTA\n"
#~ msgid ""
#~ "Roms Audit Pass: Disabled\n"
#~ "Samples Audit Pass: Disabled\n"
#~ msgstr ""
#~ "Auditoría de las ROMs: Desactivado\n"
#~ "Auditoría de las muestras: Desactivado\n"
#~ msgid "Usage"
#~ msgstr "Utilización"
#~ msgid "No Infos Available"
#~ msgstr "No hay información disponible"
#~ msgid ""
#~ "The selected software is missing one or more required files. Please "
#~ "select a different software.\n"
#~ "\n"
#~ "Press any key to continue."
#~ msgstr ""
#~ "Al software elegido le falta uno o varios archivos necesarios. Por favor, "
#~ "elige otro software.\n"
#~ "\n"
#~ "Pulsa cualquier tecla para continuar."
#~ msgid " [internal]"
#~ msgstr " [interno]"
#~ msgid "DATs info"
#~ msgstr "Info de los DATs"
#~ msgid "Save cancelled"
#~ msgstr "Guardado cancelado"
#~ msgid "Load cancelled"
#~ msgstr "Lectura cancelada"
#~ msgid "Save to position %s"
#~ msgstr "Guardar en posición %s"
#~ msgid "Load from position %s"
#~ msgstr "Lectura desde posición %s"
#~ msgid "Export XML format (like -listxml)"
#~ msgstr "Exportar en formato XML (como -listxml)"
#~ msgid "Export TXT format (like -listfull)"
#~ msgstr "Exportar en formato TXT (como -listfull)"
#~ msgid "Dummy"
#~ msgstr "De ejemplo"
#~ msgid "%1$s %2$s ( %3$d / %4$d softwares )"
#~ msgstr "%1$s %2$s ( %3$d / %4$d softwares )"
#~ msgid "Display Options"
#~ msgstr "Ajustes visuales"
#~ msgid ""
#~ "The selected machine is missing one or more required ROM or CHD images. "
#~ "Please select a different machine.\n"
#~ "\n"
#~ "Press any key (except ESC) to continue."
#~ msgstr ""
#~ "Falta la máquina seleccionada o una o más de sus ROMs o imágenes CHD. Por "
#~ "favor, elige otra máquina.\n"
#~ "\n"
#~ "Pulsa cualquier tecla para continuar."
#~ msgid ""
#~ "The selected software is missing one or more required files. Please "
#~ "select a different software.\n"
#~ "\n"
#~ "Press any key (except ESC) to continue."
#~ msgstr ""
#~ "Al software elegido le falta uno o varios archivos necesarios. Por favor, "
#~ "elige otro software.\n"
#~ "\n"
#~ "Pulsa cualquier tecla para continuar."
#~ msgid "Skip displaying information's screen at startup"
#~ msgstr "No mostrar la pantalla de información al inicio"
#~ msgid "Force 4:3 appearance for software snapshot"
#~ msgstr "Forzar apariencia 4:3 para las capturas en software"
#~ msgid ""
#~ "Usage of emulators in conjunction with ROMs you don't own is forbidden by "
#~ "copyright law.\n"
#~ "\n"
#~ "IF YOU ARE NOT LEGALLY ENTITLED TO PLAY \"%1$s\" ON THIS EMULATOR, PRESS "
#~ "ESC.\n"
#~ "\n"
#~ "Otherwise, type OK or move the joystick left then right to continue"
#~ msgstr ""
#~ "El uso de emuladores junto con ROMs que no poseas legalmente está "
#~ "prohibido por las leyes de propiedad intelectual.\n"
#~ "\n"
#~ "SI NO TIENES PERMISO PARA JUGAR A «%1$s» PULSA ESC.\n"
#~ "\n"
#~ "De lo contrario escribe OK o mueve el joystick de izquierda a derecha."
#~ msgid ""
#~ "\n"
#~ "\n"
#~ "Type OK or move the joystick left then right to continue"
#~ msgstr ""
#~ "\n"
#~ "\n"
#~ "Teclea OK o mueve el joystick de izquierda a derecha para continuar"
#~ msgid "Multi-Threaded Rendering"
#~ msgstr "Dibujado multinúcleo"
#~ msgid "Hardware Stretch"
#~ msgstr "Estirar por hardware"
#~ msgid "**Error loading %s.ini**"
#~ msgstr "**Error al leer «%s.ini»**"
#~ msgid "**Error loading ui.ini**"
#~ msgstr "**Error al leer «ui.ini»**"
#~ msgid "Double click or press "
#~ msgstr "Haz doble clic o pulsa "
#~ msgid " to change the color value"
#~ msgstr " para cambiar el color"
#~ msgid " to select"
#~ msgstr " para seleccionar"
#~ msgid "Current "
#~ msgstr "Actual "
#~ msgid " Folders"
#~ msgstr " Carpetas"
#~ msgid "Change)"
#~ msgstr "Cambio)"
#~ msgid "Add"
#~ msgstr "Añadir"
#~ msgid " Folder - Search: "
#~ msgstr " Carpeta - Buscar: "
#~ msgid "Remove "
#~ msgstr "Borrar "
#~ msgid " Folder"
#~ msgstr " Carpeta"
#~ msgid " Search: "
#~ msgstr " Buscar: "
#~ msgid "Graphics: Wrong Colors\n"
#~ msgstr "Gráficos: Colores erróneos\n"
#~ msgid ""
#~ "Usage of emulators in conjunction with ROMs you don't own is forbidden by "
#~ "copyright law.\n"
#~ "\n"
#~ msgstr ""
#~ "El uso de emuladores junto con ROMs que no sean de su propiedad está "
#~ "prohibido por las leyes del copyright.\n"
#~ "\n"
#~ msgid ""
#~ "IF YOU ARE NOT LEGALLY ENTITLED TO PLAY \"%s\" ON THIS EMULATOR, PRESS "
#~ "ESC.\n"
#~ "\n"
#~ msgstr ""
#~ "SI NO TIENES PERMISO PARA JUGAR A \"%s\" EN ESTE EMULADOR, PULSE ESC.\n"
#~ "\n"
#~ msgid "Otherwise, type OK or move the joystick left then right to continue"
#~ msgstr ""
#~ "En otro caso, teclee OK o mueva el joystick de izquierda a derecha para "
#~ "continuar"

View File

@ -17,7 +17,7 @@ function dat.check(set, softlist)
if drvinfo then
info = info .. "\n\n--- DRIVER INFO ---\nDriver: " .. sourcefile .. "\n\n" .. drvinfo
end
return "Mameinfo"
return "MAMEinfo"
end
function dat.get()

View File

@ -18,7 +18,7 @@ function dat.check(set, softlist)
if drvinfo then
info = info .. "\n\n--- DRIVER INFO ---\nDriver: " .. sourcefile .. "\n\n" .. drvinfo
end
return "Messinfo"
return "MESSinfo"
end
function dat.get()

View File

@ -119,7 +119,22 @@ bool menu_select_launch::reselect_last::s_reselect = false;
std::mutex menu_select_launch::s_cache_guard;
menu_select_launch::cache_ptr_map menu_select_launch::s_caches;
// this needs to be here to allow the names from the data plugin to be localised
// it can't have static linkage, and it can't be private or clang will complain
// it also has to be kept in sync with the data plugin
char const *const menu_select_launch::s_info_titles[] = {
__("Command"),
__("Gameinit"),
__("High Scores"),
__("History"),
__("MAMEinfo"),
__("MARPScore"),
__("MESSinfo"),
__("Mamescore"),
__("Sysinfo") };
// instantiate possible variants of select_bios so derived classes don't get link errors
template bool menu_select_launch::select_bios(game_driver const &, bool);
template bool menu_select_launch::select_bios(ui_software_info const &, bool);
@ -2386,7 +2401,7 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
else if (driver)
{
m_info_software = nullptr;
first = "General Info";
first = __("General Info");
if (driver != m_info_driver || ui_globals::curdats_view != m_info_view)
{

View File

@ -122,6 +122,8 @@ protected:
int m_total_lines;
int m_topline_datsview; // right box top line
static char const *const s_info_titles[];
private:
using bitmap_vector = std::vector<bitmap_argb32>;
using texture_ptr_vector = std::vector<texture_ptr>;

View File

@ -54,38 +54,53 @@ private:
bool osd_font_osx::open(std::string const &font_path, std::string const &name, int &height)
{
osd_printf_verbose("FONT NAME %s\n", name.c_str());
CFStringRef const font_name = CFStringCreateWithCString(nullptr, name.c_str(), kCFStringEncodingUTF8);
if (font_name && (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location))
osd_printf_verbose("osd_font_osx::open: name=\"%s\"\n", name.c_str());
CFStringRef const font_name(CFStringCreateWithCString(nullptr, name.c_str(), kCFStringEncodingUTF8));
if (!font_name)
{
// handle bdf fonts in the core
osd_printf_verbose("osd_font_osx::open: failed to create CFString from font name (invalid UTF-8?)\n");
return false;
}
if (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location)
{
// handle BDF fonts in the core
CFRelease(font_name);
return false;
}
CTFontRef ct_font = nullptr;
if (font_name)
CTFontDescriptorRef const font_descriptor(CTFontDescriptorCreateWithNameAndSize(font_name, 0.0));
CFRelease(font_name);
if (!font_descriptor)
{
CTFontDescriptorRef const font_descriptor = CTFontDescriptorCreateWithNameAndSize(font_name, 0.0);
if (font_descriptor)
{
ct_font = CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity);
CFRelease(font_descriptor);
}
CFRelease(font_name);
osd_printf_verbose("osd_font_osx::open: failed to create CoreText font descriptor for \"%s\"\n", name.c_str());
return false;
}
CTFontRef const ct_font(CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity));
CFRelease(font_descriptor);
if (!ct_font)
{
osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name.c_str());
osd_printf_verbose("osd_font_osx::open: failed to create CoreText font for \"%s\"\n", name.c_str());
return false;
}
CFStringRef const real_name = CTFontCopyPostScriptName(ct_font);
char real_name_c_string[255];
CFStringGetCString(real_name, real_name_c_string, 255, kCFStringEncodingUTF8);
osd_printf_verbose("Matching font: %s\n", real_name_c_string);
CFRelease(real_name);
CFStringRef const real_name(CTFontCopyPostScriptName(ct_font));
if (real_name)
{
char const *real_name_c_string(CFStringGetCStringPtr(real_name, kCFStringEncodingUTF8));
std::unique_ptr<char []> buf;
if (!real_name_c_string)
{
CFIndex const len(CFStringGetLength(real_name));
CFIndex const space(CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8) + 1);
buf.reset(new char[space]);
CFStringGetCString(real_name, buf.get(), space, kCFStringEncodingUTF8);
real_name_c_string = buf.get();
}
osd_printf_verbose("osd_font_osx::open: matching font: %s\n", real_name_c_string);
CFRelease(real_name);
}
m_baseline = CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font);
m_height = CTFontGetAscent(ct_font) + m_baseline;
@ -103,7 +118,7 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &name, i
void osd_font_osx::close()
{
if (m_font != nullptr)
if (m_font)
CFRelease(m_font);
m_font = nullptr;
}
@ -128,18 +143,18 @@ bool osd_font_osx::get_bitmap(char32_t chnum, bitmap_argb32 &bitmap, std::int32_
return false;
}
// try to get glyph bounds
CGRect bounds;
if (CGRectEqualToRect(CTFontGetBoundingRectsForGlyphs(m_font, kCTFontHorizontalOrientation, &glyph, &bounds, count), CGRectNull))
// try to get glyph metrics
CGRect const bounds(CTFontGetBoundingRectsForGlyphs(m_font, kCTFontHorizontalOrientation, &glyph, nullptr, count));
CGSize advance(CGSizeZero);
CTFontGetAdvancesForGlyphs(m_font, kCTFontHorizontalOrientation, &glyph, &advance, count);
// CGNullRect can indicate failure, but it's also a valid rectangle for spaces in some fonts (e.g. Hiragino family)
if (CGRectEqualToRect(bounds, CGRectNull) && CGSizeEqualToSize(advance, CGSizeZero))
{
osd_printf_verbose("osd_font_osd::get_bitmap: failed to get glyph bounds for U+%04X\n", unsigned(chnum));
osd_printf_verbose("osd_font_osd::get_bitmap: failed to get glyph metrics for U+%04X\n", unsigned(chnum));
return false;
}
// try to get metrics
CGSize advance;
CTFontGetAdvancesForGlyphs(m_font, kCTFontHorizontalOrientation, &glyph, &advance, count);
// turn everything into integers for MAME and allocate output bitmap
std::size_t const bitmap_width(std::max(std::ceil(bounds.size.width), CGFloat(1.0)));
std::size_t const bitmap_height(m_height);
@ -182,19 +197,23 @@ public:
private:
static CFComparisonResult sort_callback(CTFontDescriptorRef first, CTFontDescriptorRef second, void *refCon)
{
CFStringRef left = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(first, kCTFontDisplayNameAttribute, nullptr);
if (!left) left = (CFStringRef)CTFontDescriptorCopyAttribute(first, kCTFontNameAttribute);
CFStringRef right = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(second, kCTFontDisplayNameAttribute, nullptr);
if (!right) right = (CFStringRef)CTFontDescriptorCopyAttribute(second, kCTFontNameAttribute);
CFStringRef left(CFStringRef(CTFontDescriptorCopyLocalizedAttribute(first, kCTFontDisplayNameAttribute, nullptr)));
if (!left)
left = CFStringRef(CTFontDescriptorCopyAttribute(first, kCTFontNameAttribute));
CFStringRef right(CFStringRef(CTFontDescriptorCopyLocalizedAttribute(second, kCTFontDisplayNameAttribute, nullptr)));
if (!right)
right = CFStringRef(CTFontDescriptorCopyAttribute(second, kCTFontNameAttribute));
CFComparisonResult result;
if (left && right) result = CFStringCompareWithOptions(left, right, CFRangeMake(0, CFStringGetLength(left)), kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNonliteral);
else if (!left) result = kCFCompareLessThan;
else if (!right) result = kCFCompareGreaterThan;
else result = kCFCompareEqualTo;
CFComparisonResult const result(
(left && right) ? CFStringCompareWithOptions(left, right, CFRangeMake(0, CFStringGetLength(left)), kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNonliteral) :
!left ? kCFCompareLessThan :
!right ? kCFCompareGreaterThan :
kCFCompareEqualTo);
if (left) CFRelease(left);
if (right) CFRelease(right);
if (left)
CFRelease(left);
if (right)
CFRelease(right);
return result;
}
};
@ -245,8 +264,10 @@ bool font_osx::get_font_families(std::string const &font_path, std::vector<std::
result.emplace_back(std::move(utf8name), std::move(utf8display));
}
if (name) CFRelease(name);
if (display) CFRelease(display);
if (name)
CFRelease(name);
if (display)
CFRelease(display);
}
return true;