[vlc-commits] Freetype: support Android's new fonts.xml
Salah-Eddin Shaban
git at videolan.org
Tue Sep 19 18:06:15 CEST 2017
vlc | branch: master | Salah-Eddin Shaban <salah at videolan.org> | Sat Mar 11 10:45:01 2017 +0200| [af5378d0d84b68a1b0b39a8ad9f1105a450c12b2] | committer: Jean-Baptiste Kempf
Freetype: support Android's new fonts.xml
NOUGAT is for Android NOUGAT and newer devices
LEGACY is now for older devices.
Modified-by: Geoffrey Métais <geoffrey.metais at gmail.com>
Signed-off-by: Geoffrey Métais <geoffrey.metais at gmail.com>
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=af5378d0d84b68a1b0b39a8ad9f1105a450c12b2
---
modules/text_renderer/freetype/fonts/android.c | 219 ++++++++++++++++++++++--
modules/text_renderer/freetype/freetype.c | 5 +-
modules/text_renderer/freetype/platform_fonts.c | 2 +-
modules/text_renderer/freetype/platform_fonts.h | 10 +-
4 files changed, 212 insertions(+), 24 deletions(-)
diff --git a/modules/text_renderer/freetype/fonts/android.c b/modules/text_renderer/freetype/fonts/android.c
index b07f70b1d2..08e7007c48 100644
--- a/modules/text_renderer/freetype/fonts/android.c
+++ b/modules/text_renderer/freetype/fonts/android.c
@@ -42,12 +42,185 @@
#include "../platform_fonts.h"
-#define ANDROID_SYSTEM_FONTS "file:///system/etc/system_fonts.xml"
-#define ANDROID_FALLBACK_FONTS "file:///system/etc/fallback_fonts.xml"
-#define ANDROID_VENDOR_FONTS "file:///vendor/etc/fallback_fonts.xml"
-#define ANDROID_FONT_PATH "/system/fonts"
+#define ANDROID_SYSTEM_FONTS_NOUGAT "file:///system/etc/fonts.xml"
+#define ANDROID_SYSTEM_FONTS_LEGACY "file:///system/etc/system_fonts.xml"
+#define ANDROID_FALLBACK_FONTS "file:///system/etc/fallback_fonts.xml"
+#define ANDROID_VENDOR_FONTS "file:///vendor/etc/fallback_fonts.xml"
+#define ANDROID_FONT_PATH "/system/fonts"
+
+static int Android_ParseFont( filter_t *p_filter, xml_reader_t *p_xml,
+ vlc_family_t *p_family )
+{
+ bool b_bold = false;
+ bool b_italic = false;
+ const char *psz_val = NULL;
+ const char *psz_attr = NULL;
+ int i_type = 0;
+ int i_weight = 0;
+
+ while( ( psz_attr = xml_ReaderNextAttr( p_xml, &psz_val ) ) )
+ {
+ if( !strcasecmp( "weight", psz_attr ) && psz_val && *psz_val )
+ i_weight = atoi( psz_val );
+ else if( !strcasecmp( "style", psz_attr ) && psz_val && *psz_val )
+ if( !strcasecmp( "italic", psz_val ) )
+ b_italic = true;
+ }
+
+ if( i_weight == 700 )
+ b_bold = true;
+
+ i_type = xml_ReaderNextNode( p_xml, &psz_val );
+
+ if( i_type != XML_READER_TEXT || !psz_val || !*psz_val )
+ {
+ msg_Warn( p_filter, "Android_ParseFont: no file name" );
+ return VLC_EGENERIC;
+ }
+
+ char *psz_fontfile;
+
+ /*
+ * We don't need all font weights. Only 400 (regular) and 700 (bold)
+ */
+ if( i_weight == 400 || i_weight == 700 )
+ if( asprintf( &psz_fontfile, "%s/%s", ANDROID_FONT_PATH, psz_val ) < 0
+ || !NewFont( psz_fontfile, 0, b_bold, b_italic, p_family ) )
+ return VLC_ENOMEM;
+
+ return VLC_SUCCESS;
+}
-static int Android_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
+static int Android_Nougat_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ vlc_dictionary_t *p_dict = &p_sys->family_map;
+ vlc_family_t *p_family = NULL;
+ const char *psz_val = NULL;
+ const char *psz_attr = NULL;
+ const char *psz_name = NULL;
+ int i_type = 0;
+
+ while( ( psz_attr = xml_ReaderNextAttr( p_xml, &psz_val ) ) )
+ {
+ if( !strcasecmp( "name", psz_attr ) && psz_val && *psz_val )
+ {
+ psz_name = psz_val;
+ break;
+ }
+ }
+
+ if( psz_name && *psz_name )
+ {
+ /*
+ * Family has a name. See if we have that name already.
+ * If the name already exists, it's one of the font attachments.
+ */
+ char *psz_lc = ToLower( psz_name );
+ if( unlikely( !psz_lc ) )
+ return VLC_ENOMEM;
+
+ p_family = vlc_dictionary_value_for_key( p_dict, psz_lc );
+
+ free( psz_lc );
+ }
+
+ if( p_family == NULL )
+ {
+ /*
+ * We are either parsing a nameless family, or a named family that
+ * was not previously added to p_sys->family_map.
+ *
+ * Create a new family with the given name or, if psz_name is NULL,
+ * with the name fallback-xxxx
+ */
+ p_family = NewFamily( p_filter, psz_name, &p_sys->p_families,
+ &p_sys->family_map, NULL );
+
+ if( unlikely( !p_family ) )
+ return VLC_ENOMEM;
+ }
+
+ while( ( i_type = xml_ReaderNextNode( p_xml, &psz_val ) ) > 0 )
+ {
+ switch( i_type )
+ {
+ case XML_READER_STARTELEM:
+ if( !strcasecmp( "font", psz_val ) )
+ if( Android_ParseFont( p_filter, p_xml, p_family ) == VLC_ENOMEM )
+ return VLC_ENOMEM;
+ break;
+
+ case XML_READER_ENDELEM:
+ if( !strcasecmp( "family", psz_val ) )
+ {
+ if( strcasestr( p_family->psz_name, FB_NAME ) )
+ {
+ /*
+ * If the family name has "fallback" in it add it to the
+ * default fallback list.
+ */
+ vlc_family_t *p_fallback =
+ NewFamily( p_filter, p_family->psz_name,
+ NULL, &p_sys->fallback_map, FB_LIST_DEFAULT );
+
+ if( unlikely( !p_fallback ) )
+ return VLC_ENOMEM;
+
+ p_fallback->p_fonts = p_family->p_fonts;
+ }
+
+ return VLC_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ msg_Warn( p_filter, "Android_ParseFamily: Corrupt font configuration file" );
+ return VLC_EGENERIC;
+}
+
+static int Android_ParseAlias( filter_t *p_filter, xml_reader_t *p_xml )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ vlc_dictionary_t *p_dict = &p_sys->family_map;
+ vlc_family_t *p_dest = NULL;
+ char *psz_name = NULL;
+ char *psz_dest = NULL;
+ const char *psz_val = NULL;
+ const char *psz_attr = NULL;
+ int i_weight = 0;
+ int i_ret = VLC_SUCCESS;
+
+ while( ( psz_attr = xml_ReaderNextAttr( p_xml, &psz_val ) ) )
+ {
+ if( !strcasecmp( "weight", psz_attr ) && psz_val && *psz_val )
+ i_weight = atoi( psz_val );
+ else if( !strcasecmp( "to", psz_attr ) && psz_val && *psz_val )
+ psz_dest = ToLower( psz_val );
+ else if( !strcasecmp( "name", psz_attr ) && psz_val && *psz_val )
+ psz_name = ToLower( psz_val );
+ }
+
+ if( !psz_dest || !psz_name )
+ {
+ i_ret = VLC_EGENERIC;
+ goto done;
+ }
+
+ p_dest = vlc_dictionary_value_for_key( p_dict, psz_dest );
+
+ if( p_dest && i_weight == 0 )
+ if( vlc_dictionary_value_for_key( p_dict, psz_name ) == NULL )
+ vlc_dictionary_insert( p_dict, psz_name, p_dest );
+
+done:
+ free( psz_dest );
+ free( psz_name );
+ return i_ret;
+}
+
+static int Android_Legacy_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
{
filter_sys_t *p_sys = p_filter->p_sys;
vlc_dictionary_t *p_dict = &p_sys->family_map;
@@ -111,7 +284,7 @@ static int Android_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
/*
* If p_family has not been set by the time we encounter the first file,
* it means this family has no name, and should be used only as a fallback.
- * We create a new family for it in the master list with the name "fallback-xx"
+ * We create a new family for it in the master list with the name "fallback-xxxx"
* and later add it to the "default" fallback list.
*/
else if( !strcasecmp( "file", p_node ) )
@@ -194,11 +367,12 @@ static int Android_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
}
}
- msg_Warn( p_filter, "Android_ParseFamily: Corrupt font configuration file" );
+ msg_Warn( p_filter, "Android_ParseOldFamily: Corrupt font configuration file" );
return VLC_EGENERIC;
}
-static int Android_ParseSystemFonts( filter_t *p_filter, const char *psz_path )
+static int Android_ParseSystemFonts( filter_t *p_filter, const char *psz_path,
+ bool b_new_format )
{
int i_ret = VLC_SUCCESS;
stream_t *p_stream = vlc_stream_NewURL( p_filter, psz_path );
@@ -218,9 +392,19 @@ static int Android_ParseSystemFonts( filter_t *p_filter, const char *psz_path )
int i_type;
while( ( i_type = xml_ReaderNextNode( p_xml, &p_node ) ) > 0 )
{
- if( i_type == XML_READER_STARTELEM && !strcasecmp( "family", p_node ) )
+ if( i_type == XML_READER_STARTELEM && !strcasecmp( "family", p_node ) && b_new_format )
{
- if( ( i_ret = Android_ParseFamily( p_filter, p_xml ) ) )
+ if( ( i_ret = Android_Nougat_ParseFamily( p_filter, p_xml ) ) )
+ break;
+ }
+ else if( i_type == XML_READER_STARTELEM && !strcasecmp( "family", p_node ) && !b_new_format )
+ {
+ if( ( i_ret = Android_Legacy_ParseFamily( p_filter, p_xml ) ) )
+ break;
+ }
+ else if( i_type == XML_READER_STARTELEM && !strcasecmp( "alias", p_node ) && b_new_format )
+ {
+ if( ( i_ret = Android_ParseAlias( p_filter, p_xml ) ) )
break;
}
}
@@ -232,12 +416,15 @@ static int Android_ParseSystemFonts( filter_t *p_filter, const char *psz_path )
int Android_Prepare( filter_t *p_filter )
{
- if( Android_ParseSystemFonts( p_filter, ANDROID_SYSTEM_FONTS ) == VLC_ENOMEM )
- return VLC_EGENERIC;
- if( Android_ParseSystemFonts( p_filter, ANDROID_FALLBACK_FONTS ) == VLC_ENOMEM )
- return VLC_EGENERIC;
- if( Android_ParseSystemFonts( p_filter, ANDROID_VENDOR_FONTS ) == VLC_ENOMEM )
- return VLC_EGENERIC;
+ if( Android_ParseSystemFonts( p_filter, ANDROID_SYSTEM_FONTS_NOUGAT, true ) != VLC_SUCCESS )
+ {
+ if( Android_ParseSystemFonts( p_filter, ANDROID_SYSTEM_FONTS_LEGACY, false ) == VLC_ENOMEM )
+ return VLC_ENOMEM;
+ if( Android_ParseSystemFonts( p_filter, ANDROID_FALLBACK_FONTS, false ) == VLC_ENOMEM )
+ return VLC_ENOMEM;
+ if( Android_ParseSystemFonts( p_filter, ANDROID_VENDOR_FONTS, false ) == VLC_ENOMEM )
+ return VLC_ENOMEM;
+ }
return VLC_SUCCESS;
}
diff --git a/modules/text_renderer/freetype/freetype.c b/modules/text_renderer/freetype/freetype.c
index 39994a01b0..32a1da3e26 100644
--- a/modules/text_renderer/freetype/freetype.c
+++ b/modules/text_renderer/freetype/freetype.c
@@ -319,7 +319,7 @@ static int LoadFontsFromAttachments( filter_t *p_filter )
if( p_face->family_name )
psz_lc = ToLower( p_face->family_name );
else
- if( asprintf( &psz_lc, FB_NAME"-%02d",
+ if( asprintf( &psz_lc, FB_NAME"-%04d",
p_sys->i_fallback_counter++ ) < 0 )
psz_lc = NULL;
@@ -1321,7 +1321,8 @@ static int Create( vlc_object_t *p_this )
p_sys->pf_get_fallbacks = Android_GetFallbacks;
p_sys->pf_select = Generic_Select;
- Android_Prepare( p_filter );
+ if( Android_Prepare( p_filter ) == VLC_ENOMEM )
+ goto error;
#else
p_sys->pf_select = Dummy_Select;
#endif
diff --git a/modules/text_renderer/freetype/platform_fonts.c b/modules/text_renderer/freetype/platform_fonts.c
index 4491f6dce5..943d4c6112 100644
--- a/modules/text_renderer/freetype/platform_fonts.c
+++ b/modules/text_renderer/freetype/platform_fonts.c
@@ -249,7 +249,7 @@ vlc_family_t *NewFamily( filter_t *p_filter, const char *psz_family,
if( psz_family && *psz_family )
psz_name = ToLower( psz_family );
else
- if( asprintf( &psz_name, FB_NAME"-%02d",
+ if( asprintf( &psz_name, FB_NAME"-%04d",
p_sys->i_fallback_counter++ ) < 0 )
psz_name = NULL;
diff --git a/modules/text_renderer/freetype/platform_fonts.h b/modules/text_renderer/freetype/platform_fonts.h
index 932f45b785..848c31a4eb 100644
--- a/modules/text_renderer/freetype/platform_fonts.h
+++ b/modules/text_renderer/freetype/platform_fonts.h
@@ -68,8 +68,8 @@ extern "C" {
# define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/psfonts/mtsansdk.ttf"
# define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monotype Sans Duospace WT K"
#elif defined( __ANDROID__ )
-# define SYSTEM_DEFAULT_FONT_FILE "/system/fonts/DroidSans-Bold.ttf"
-# define SYSTEM_DEFAULT_FAMILY "Droid Sans"
+# define SYSTEM_DEFAULT_FONT_FILE "/system/fonts/Roboto-Regular.ttf"
+# define SYSTEM_DEFAULT_FAMILY "sans-serif"
# define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/system/fonts/DroidSansMono.ttf"
# define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monospace"
#else
@@ -121,7 +121,7 @@ struct vlc_family_t
vlc_family_t *p_next; /**< next family in the chain */
/**
* Human-readable name, usually requested.
- * Can be fallback-xx for font attachments with no family name, and for fallback
+ * Can be fallback-xxxx for font attachments with no family name, and for fallback
* fonts in Android.
* This field is used only for loading the family fonts, and for debugging.
* Apart from that, families are accessed either through the
@@ -194,7 +194,7 @@ char* Generic_Select( filter_t *p_filter, const char* family,
* Creates a new family.
*
* \param psz_family the usual font family name, human-readable;
- * if NULL, will use "fallback-xx"[IN]
+ * if NULL, will use "fallback-xxxx"[IN]
* \param pp_list the family list where to append the new family;
* can be NULL if not in a list, or if the family is to be appended to a fallback list
* within \ref filter_sys_t::fallback_map [IN]
@@ -204,7 +204,7 @@ char* Generic_Select( filter_t *p_filter, const char* family,
* appended there [IN]
* \param psz_key specific key for the dictionary.
* If NULL will use whatever is used for the family name, whether it is the specified \p psz_family
- * or "fallback-xx" [IN]
+ * or "fallback-xxxx" [IN]
*
* \return the new family representation
*/
More information about the vlc-commits
mailing list