[vlc-devel] [PATCH] freetype: comments and documentation
Salah-Eddin Shaban
salshaaban at gmail.com
Wed Nov 4 22:41:38 CET 2015
---
modules/text_renderer/fonts/android.c | 8 +++-
modules/text_renderer/fonts/win32.c | 11 +++++
modules/text_renderer/freetype.h | 21 ++++++---
modules/text_renderer/platform_fonts.c | 16 +++++++
modules/text_renderer/platform_fonts.h | 53 ++++++++++++++++-----
modules/text_renderer/text_layout.c | 86 ++++++++++++++++++----------------
modules/text_renderer/text_layout.h | 21 ++++++++-
7 files changed, 155 insertions(+), 61 deletions(-)
diff --git a/modules/text_renderer/fonts/android.c b/modules/text_renderer/fonts/android.c
index 8061b57..f4942d9 100644
--- a/modules/text_renderer/fonts/android.c
+++ b/modules/text_renderer/fonts/android.c
@@ -111,8 +111,8 @@ 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 and later add it to
- * the "default" fallback list.
+ * We create a new family for it in the master list with the name "fallback-xx"
+ * and later add it to the "default" fallback list.
*/
else if( !strcasecmp( "file", p_node ) )
{
@@ -172,6 +172,10 @@ static int Android_ParseFamily( filter_t *p_filter, xml_reader_t *p_xml )
return VLC_EGENERIC;
}
+ /*
+ * If the family name has "fallback" in it, add it to the
+ * "default" fallback list.
+ */
if( strcasestr( p_family->psz_name, FB_NAME ) )
{
vlc_family_t *p_fallback =
diff --git a/modules/text_renderer/fonts/win32.c b/modules/text_renderer/fonts/win32.c
index 3a3c959..228eb3f 100644
--- a/modules/text_renderer/fonts/win32.c
+++ b/modules/text_renderer/fonts/win32.c
@@ -177,6 +177,11 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *lpelfe, const NEWTEXTM
bool b_bold = ( lpelfe->elfLogFont.lfWeight == FW_BOLD );
bool b_italic = ( lpelfe->elfLogFont.lfItalic != 0 );
+ /*
+ * This function will be called by Windows as many times for each font
+ * of the family as the number of scripts the font supports.
+ * Check to avoid duplicates.
+ */
for( vlc_font_t *p_font = p_family->p_fonts; p_font; p_font = p_font->p_next )
if( !!p_font->b_bold == !!b_bold && !!p_font->b_italic == !!b_italic )
return 1;
@@ -355,6 +360,12 @@ vlc_family_t *Win32_GetFallbacks( filter_t *p_filter, const char *psz_family,
if( p_fallbacks )
p_family = SearchFallbacks( p_filter, p_fallbacks, codepoint );
+ /*
+ * If the fallback list of psz_family has no family which contains the requested
+ * codepoint, try UniscribeFallback(). If it returns a valid family which does
+ * contain that codepoint, add the new family to the fallback list to speed up
+ * later searches.
+ */
if( !p_family )
{
psz_uniscribe = UniscribeFallback( psz_lc, codepoint );
diff --git a/modules/text_renderer/freetype.h b/modules/text_renderer/freetype.h
index ae4f5e4..f6d80e1 100644
--- a/modules/text_renderer/freetype.h
+++ b/modules/text_renderer/freetype.h
@@ -28,6 +28,13 @@
#ifndef VLC_FREETYPE_H
#define VLC_FREETYPE_H
+/** \defgroup freetype Freetype text renderer
+ * Freetype text rendering cross platform
+ * @{
+ * \file
+ * Freetype module
+ */
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@@ -83,25 +90,25 @@ struct filter_sys_t
input_attachment_t **pp_font_attachments;
int i_font_attachments;
- /*
+ /**
* This is the master family list. It owns the lists of vlc_font_t's
* and should be freed using FreeFamiliesAndFonts()
*/
vlc_family_t *p_families;
- /*
+ /**
* This maps a family name to a vlc_family_t within the master list
*/
vlc_dictionary_t family_map;
- /*
+ /**
* This maps a family name to a fallback list of vlc_family_t's.
* Fallback lists only reference the lists of vlc_font_t's within the
* master list, so they should be freed using FreeFamilies()
*/
vlc_dictionary_t fallback_map;
- /* Font face cache */
+ /** Font face cache */
vlc_dictionary_t face_map;
int i_fallback_counter;
@@ -115,14 +122,14 @@ struct filter_sys_t
int *index, uni_char_t codepoint);
/**
- * Get a pointer to the vlc_family_t in the master list that matches psz_family.
+ * Get a pointer to the vlc_family_t in the master list that matches \p psz_family.
* Add this family to the list if it hasn't been added yet.
*/
const vlc_family_t * (*pf_get_family) ( filter_t *p_filter, const char *psz_family );
/**
- * Get the fallback list for psz_family from the system and cache
- * it in fallback_map.
+ * Get the fallback list for \p psz_family from the system and cache
+ * it in \ref fallback_map.
* On Windows fallback lists are populated progressively as required
* using Uniscribe, so we need the codepoint here.
*/
diff --git a/modules/text_renderer/platform_fonts.c b/modules/text_renderer/platform_fonts.c
index 49f694c..4dcd5a2 100644
--- a/modules/text_renderer/platform_fonts.c
+++ b/modules/text_renderer/platform_fonts.c
@@ -30,6 +30,12 @@
* Preamble
*****************************************************************************/
+/** \ingroup freetype_fonts
+ * @{
+ * \file
+ * Platform-independent font management
+ */
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@@ -128,6 +134,16 @@ FT_Face GetFace( filter_t *p_filter, vlc_font_t *p_font )
return p_font->p_face;
}
+/**
+ * Select the best font from the list of vlc_font_t's of the given family.
+ * If a family does not have the exact requested style, the nearest one will be returned.
+ * Like when an italic font is requested from a family which has only a regular font. In this
+ * case the regular font will be returned and FreeType will do synthetic styling on it.
+ *
+ * Not all fonts of a family support the same scripts. As an example, when an italic font
+ * containing an Arabic codepoint is requested from the Arial family, the regular font will
+ * be returned, because the italic font of Arial has no Arabic support.
+ */
static vlc_font_t *GetBestFont( filter_t *p_filter, const vlc_family_t *p_family,
bool b_bold, bool b_italic, uni_char_t codepoint )
{
diff --git a/modules/text_renderer/platform_fonts.h b/modules/text_renderer/platform_fonts.h
index 2fa9951..abf76c7 100644
--- a/modules/text_renderer/platform_fonts.h
+++ b/modules/text_renderer/platform_fonts.h
@@ -98,7 +98,11 @@ typedef struct vlc_font_t vlc_font_t;
struct vlc_font_t
{
vlc_font_t *p_next; /**< next font in the chain */
- char *psz_fontfile; /**< path to the file on the disk */
+ /**
+ * path to the font file on disk, or ":/x" for font attachments, where x
+ * is the attachment index within \ref filter_sys_t::pp_font_attachments
+ */
+ char *psz_fontfile;
int i_index; /**< index of the font in the font file, starts at 0 */
bool b_bold; /**< if the font is a bold version */
bool b_italic; /**< if the font is an italic version */
@@ -111,7 +115,17 @@ struct vlc_font_t
struct vlc_family_t
{
vlc_family_t *p_next; /**< next family in the chain */
- char *psz_name; /**< Human-reable name, usually requested */
+ /**
+ * Human-readable name, usually requested.
+ * Can be fallback-xx 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
+ * \ref filter_sys_t::family_map dictionary, or as a member of some fallback list
+ * in \ref filter_sys_t::fallback_map. And this field plays no role in either of
+ * the two cases.
+ */
+ char *psz_name;
vlc_font_t *p_fonts; /**< fonts matching this family */
};
@@ -171,10 +185,16 @@ char* Generic_Select( filter_t *p_filter, const char* family,
*
* \param psz_family the usual font family name, human-readable;
* if NULL, will use "fallback-xx"[IN]
- * \param pp_list the family list where to append the font;
- * can be NULL if not in a list [IN]
- * \param p_dict dictionnary where to insert this family; can be NULL [IN]
- * \param psz_key specific key for the dictionnary [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]
+ * \param p_dict dictionary where to insert this family; can be NULL.
+ * If the dictionary already has an entry for \p psz_key, which is often the case when adding
+ * a new fallback to a fallback list within \ref filter_sys_t::fallback_map, the new family will be
+ * 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]
*
* \return the new family representation
*/
@@ -185,7 +205,8 @@ vlc_family_t *NewFamily( filter_t *p_filter, const char *psz_family,
/**
* Creates a new font.
*
- * \param psz_fontfile font file [IN]
+ * \param psz_fontfile font file, or ":/x" for font attachments, where x is the attachment index
+ * within \ref filter_sys_t::pp_font_attachments [IN]
* \param i_index index of the font in the font file [IN]
* \param b_bold is a bold font or not [IN]
* \param b_bold is an italic or not [IN]
@@ -193,7 +214,7 @@ vlc_family_t *NewFamily( filter_t *p_filter, const char *psz_family,
* If not NULL, the font will be associated to this family, and
* appended to the font list in that family [IN]
*
- * \remark This function takes ownership of psz_fontfile
+ * \remark This function takes ownership of \p psz_fontfile
* \return the new font
*/
vlc_font_t *NewFont( char *psz_fontfile, int i_index,
@@ -215,15 +236,25 @@ void FreeFamiliesAndFonts( vlc_family_t *p_family );
void FreeFamilies( void *p_families, void *p_obj );
/**
- * Construct the default family list
+ * Construct the default fallback list
*
- * In some platforms, you might want multiple fonts as default
+ * The default fallback list will be searched when all else fails.
+ * It should contain at least one font for each Unicode script.
+ *
+ * No default list is required with FontConfig because FontConfig returns
+ * comprehensive fallback lists. On Windows a default list is used because
+ * Uniscribe seems less reliable than FontConfig in this regard.
+ *
+ * On Android, all fallback families reside within the default fallback list,
+ * which is populated in Android_ParseFamily(), in the XML_READER_ENDELEM section
+ * of that function, where each family is added to the default list if
+ * its name has "fallback" in it. So InitDefaultList() is not called on Android.
*
* \param p_filter the freetype module object [IN]
* \param ppsz_default the table default fonts [IN]
* \param i_size the size of the supplied table [IN]
*
- * return the default family font
+ * \return the default fallback list
*/
vlc_family_t *InitDefaultList( filter_t *p_filter, const char *const *ppsz_default,
int i_size );
diff --git a/modules/text_renderer/text_layout.c b/modules/text_renderer/text_layout.c
index b464e1d..f0d6fc5 100644
--- a/modules/text_renderer/text_layout.c
+++ b/modules/text_renderer/text_layout.c
@@ -29,6 +29,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+/** \ingroup freetype
+ * @{
+ * \file
+ * Text shaping and layout
+ */
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@@ -77,31 +83,31 @@
# define HAVE_FONT_FALLBACK
#endif
-/*
+/**
* Within a paragraph, run_desc_t represents a run of characters
* having the same font face, size, and style, Unicode script
* and text direction
*/
typedef struct run_desc_t
{
- int i_start_offset;
- int i_end_offset;
- FT_Face p_face;
- const text_style_t *p_style;
+ int i_start_offset;
+ int i_end_offset;
+ FT_Face p_face;
+ const text_style_t *p_style;
#ifdef HAVE_HARFBUZZ
- hb_script_t script;
- hb_direction_t direction;
- hb_font_t *p_hb_font;
- hb_buffer_t *p_buffer;
- hb_glyph_info_t *p_glyph_infos;
- hb_glyph_position_t *p_glyph_positions;
- unsigned int i_glyph_count;
+ hb_script_t script;
+ hb_direction_t direction;
+ hb_font_t *p_hb_font;
+ hb_buffer_t *p_buffer;
+ hb_glyph_info_t *p_glyph_infos;
+ hb_glyph_position_t *p_glyph_positions;
+ unsigned int i_glyph_count;
#endif
} run_desc_t;
-/*
+/**
* Glyph bitmaps. Advance and offset are 26.6 values
*/
typedef struct glyph_bitmaps_t
@@ -120,27 +126,27 @@ typedef struct glyph_bitmaps_t
typedef struct paragraph_t
{
- uni_char_t *p_code_points; //Unicode code points
- int *pi_glyph_indices; //Glyph index values within the run's font face
- text_style_t **pp_styles;
- FT_Face *pp_faces;
- int *pi_run_ids; //The run to which each glyph belongs
- glyph_bitmaps_t *p_glyph_bitmaps;
- uint8_t *pi_karaoke_bar;
- int i_size;
- run_desc_t *p_runs;
- int i_runs_count;
- int i_runs_size;
+ uni_char_t *p_code_points; /**< Unicode code points */
+ int *pi_glyph_indices; /**< Glyph index values within the run's font face */
+ text_style_t **pp_styles;
+ FT_Face *pp_faces; /**< Used to determine run boundaries when performing font fallback */
+ int *pi_run_ids; /**< The run to which each glyph belongs */
+ glyph_bitmaps_t *p_glyph_bitmaps;
+ uint8_t *pi_karaoke_bar;
+ int i_size;
+ run_desc_t *p_runs;
+ int i_runs_count;
+ int i_runs_size;
#ifdef HAVE_HARFBUZZ
- hb_script_t *p_scripts;
+ hb_script_t *p_scripts;
#endif
#ifdef HAVE_FRIBIDI
- FriBidiCharType *p_types;
- FriBidiLevel *p_levels;
- FriBidiStrIndex *pi_reordered_indices;
- FriBidiParType paragraph_type;
+ FriBidiCharType *p_types;
+ FriBidiLevel *p_levels;
+ FriBidiStrIndex *pi_reordered_indices;
+ FriBidiParType paragraph_type;
#endif
} paragraph_t;
@@ -460,11 +466,11 @@ static int AddRun( filter_t *p_filter,
return VLC_SUCCESS;
}
-/*
+#ifdef HAVE_FONT_FALLBACK
+/**
* Add a run with font fallback, possibly breaking the run further
* into runs of glyphs that end up having the same font face.
*/
-#ifdef HAVE_FONT_FALLBACK
static int AddRunWithFallback( filter_t *p_filter, paragraph_t *p_paragraph,
int i_start_offset, int i_end_offset )
{
@@ -563,7 +569,7 @@ static bool FaceStyleEquals( filter_t *p_filter, const text_style_t *p_style1,
&& !strcasecmp( psz_fontname1, psz_fontname2 );
}
-/*
+/**
* Segment a paragraph into runs
*/
static int ItemizeParagraph( filter_t *p_filter, paragraph_t *p_paragraph )
@@ -616,14 +622,14 @@ static int ItemizeParagraph( filter_t *p_filter, paragraph_t *p_paragraph )
return VLC_SUCCESS;
}
-/*
+#ifdef HAVE_HARFBUZZ
+/**
* Shape an itemized paragraph using HarfBuzz.
* This is where the glyphs of complex scripts get their positions
* (offsets and advance values) and final forms.
* Glyph substitutions of base glyphs and diacritics may take place,
* so the paragraph size may change.
*/
-#ifdef HAVE_HARFBUZZ
static int ShapeParagraphHarfBuzz( filter_t *p_filter,
paragraph_t **p_old_paragraph )
{
@@ -799,13 +805,13 @@ error:
}
#endif
-/*
+#ifdef HAVE_FRIBIDI
+#ifndef HAVE_HARFBUZZ
+/**
* Shape a paragraph with FriBidi.
* Shaping with FriBidi is currently limited to mirroring and simple
* Arabic shaping.
*/
-#ifdef HAVE_FRIBIDI
-#ifndef HAVE_HARFBUZZ
static int ShapeParagraphFriBidi( filter_t *p_filter, paragraph_t *p_paragraph )
{
@@ -837,7 +843,7 @@ static int ShapeParagraphFriBidi( filter_t *p_filter, paragraph_t *p_paragraph )
return VLC_SUCCESS;
}
-/*
+/**
* Zero-width invisible characters include Unicode control characters and
* zero-width spaces among other things. If not removed they can show up in the
* text as squares or other glyphs depending on the font. Zero-width spaces are
@@ -871,7 +877,7 @@ static int RemoveZeroWidthCharacters( paragraph_t *p_paragraph )
return VLC_SUCCESS;
}
-/*
+/**
* Set advance values of non-spacing marks to zero. Diacritics are
* not positioned correctly but the text is more readable.
* For full shaping HarfBuzz is required.
@@ -889,7 +895,7 @@ static int ZeroNsmAdvance( paragraph_t *p_paragraph )
#endif
#endif
-/*
+/**
* Load the glyphs of a paragraph. When shaping with HarfBuzz the glyph indices
* have already been determined at this point, as well as the advance values.
*/
diff --git a/modules/text_renderer/text_layout.h b/modules/text_renderer/text_layout.h
index 17c7bff..34e1e83 100644
--- a/modules/text_renderer/text_layout.h
+++ b/modules/text_renderer/text_layout.h
@@ -25,6 +25,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+/** \ingroup freetype
+ * @{
+ * \file
+ * Text shaping and layout
+ */
+
#include "freetype.h"
typedef struct
@@ -56,7 +62,20 @@ struct line_desc_t
void FreeLines( line_desc_t *p_lines );
line_desc_t *NewLine( int i_count );
+/**
+ * Layout the text with shaping, bidirectional support, and font fallback if available.
+ *
+ * \param p_filter the FreeType module object [IN]
+ * \param pp_lines the list of line_desc_t's with rendered glyphs [OUT]
+ * \param p_bbox the bounding box of all the lines [OUT]
+ * \param pi_max_face_height maximum line height [OUT]
+ * \param psz_text array of size \p i_len containing character codepoints [IN]
+ * \param pp_styles array of size \p i_len containing character styles [IN]
+ * \param pi_k_dates array of size \p i_len containing karaoke timestamps for characters [IN]
+ * \param i_len length of the arrays \p psz_text, \p pp_styles, and \p pi_k_dates [IN]
+ * \param b_grid true for grid-mode text [IN]
+ */
int LayoutText(filter_t *p_filter, line_desc_t **pp_lines,
FT_BBox *p_bbox, int *pi_max_face_height,
const uni_char_t *psz_text, text_style_t **pp_styles,
- uint32_t *pi_k_dates, int i_len, bool );
+ uint32_t *pi_k_dates, int i_len, bool b_grid );
--
1.9.1
More information about the vlc-devel
mailing list