<commit_before>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Copyright (c) <NAME> 2000-2005
 *					All rights reserved
 *
 *  This file is part of GPAC / FreeType font engine module
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *   
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */


#include <gpac/modules/font.h>
#include <gpac/list.h>
#include <gpac/utf.h>
#include <gpac/tools.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
/*TrueType tables*/
#include FT_TRUETYPE_TABLES_H 

typedef struct
{
	FT_Library library;
	FT_Face active_face;
	char *font_dir;

	GF_List *loaded_fonts;

	/*default fonts*/
	char font_serif[1024];
	char font_sans[1024];
	char font_fixed[1024];
} FTBuilder;


static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path)
{
	char szFont[GF_MAX_PATH];
	FT_Face face;
	u32 num_faces, i;
	GF_FontReader *dr = cbck;
	FTBuilder *ftpriv = dr->udta;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path));

	if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0;
	if (!face) return 0;

	num_faces = face->num_faces;
	/*locate right font in collection if several*/
	for (i=0; i<num_faces; i++) {

		/*only scan scalable fonts*/
		if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
			Bool bold, italic, smallcaps;
			strcpy(szFont, face->family_name);

			bold = italic = smallcaps = 0;

			if (face->style_name) {
				char *name = strdup(face->style_name);
				strupr(name);
				if (strstr(name, "BOLD")) bold = 1;
				if (strstr(name, "ITALIC")) italic = 1;
				free(name);
			} else {
				if (face->style_flags & FT_STYLE_FLAG_BOLD) bold = 1;
				if (face->style_flags & FT_STYLE_FLAG_ITALIC) italic = 1;
			}
			
			if (bold) strcat(szFont, " Bold");
			if (italic) strcat(szFont, " Italic");
			if (smallcaps) strcat(szFont, " Smallcaps");
			gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szFont, file_path);

			/*try to assign default fixed fonts*/
			if (!bold && !italic) {
				if (!strlen(ftpriv->font_fixed)) {
					Bool store = 0;
					if (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) store = 1;
					else if (!strnicmp(face->family_name, "Courier", 15)) store = 1;

					if (store) strcpy(ftpriv->font_fixed, face->family_name);
				}
				if (!strlen(ftpriv->font_serif)) {
					Bool store = 0;
					if (!strnicmp(face->family_name, "Times New Roman", 15)) 
						store = 1;

					if (store) strcpy(ftpriv->font_serif, face->family_name);
				}
				if (!strlen(ftpriv->font_sans)) {
					Bool store = 0;
					if (!strnicmp(face->family_name, "Arial", 5)) store = 1;
					else if (!strnicmp(face->family_name, "Verdana", 7)) store = 1;

					if (store) strcpy(ftpriv->font_sans, face->family_name);
				}
			}
		}

		FT_Done_Face(face);
		if (i+1==num_faces) return 0;

		/*load next font in collection*/
		if (FT_New_Face(ftpriv->library, file_path, i+1, & face )) return 0;
		if (!face) return 0;
	}
	return 0;
}

static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path)
{
	Bool ret = gf_enum_directory(file_path, 0, ft_enum_fonts, cbck, "ttf;ttc");
	if (ret) return 1;
	return gf_enum_directory(file_path, 1, ft_enum_fonts_dir, cbck, NULL);
}


static void ft_rescan_fonts(GF_FontReader *dr)
{
	u32 i, count;
	GF_Config *cfg = gf_modules_get_config((GF_BaseInterface *)dr);
	FTBuilder *ftpriv = (FTBuilder *)dr->udta;

	GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("[FreeType] Rescaning font directory %s\n", ftpriv->font_dir));

	count = gf_cfg_get_key_count(cfg, "FontEngine");
	for (i=0; i<count; i++) {
		const char *key = gf_cfg_get_key_name(cfg, "FontEngine", i);
		if (!strcmp(key, "FontReader")) continue;
		if (!strcmp(key, "FontDirectory")) continue;
		if (!strcmp(key, "RescanFonts")) continue;
		/*any other persistent options should go here*/

		gf_cfg_set_key(cfg, "FontEngine", key, NULL);
		count--;
		i--;
	}
	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "RescanFonts", "no");

	strcpy(ftpriv->font_serif, "");
	strcpy(ftpriv->font_sans, "");
	strcpy(ftpriv->font_fixed, "");

	gf_enum_directory(ftpriv->font_dir, 0, ft_enum_fonts, dr, "ttf;ttc");
	gf_enum_directory(ftpriv->font_dir, 0, ft_enum_fonts_dir, dr, "ttf;ttc");

	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed", ftpriv->font_fixed);
	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif", ftpriv->font_serif);<commit_msg>*** empty log message ***<commit_after>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Copyright (c) <NAME> 2000-2005
 *					All rights reserved
 *
 *  This file is part of GPAC / FreeType font engine module
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *   
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */


#include <gpac/modules/font.h>
#include <gpac/list.h>
#include <gpac/utf.h>
#include <gpac/tools.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
/*TrueType tables*/
#include FT_TRUETYPE_TABLES_H 

typedef struct
{
	FT_Library library;
	FT_Face active_face;
	char *font_dir;

	GF_List *loaded_fonts;

	/*default fonts*/
	char font_serif[1024];
	char font_sans[1024];
	char font_fixed[1024];
} FTBuilder;


static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path)
{
	char szFont[GF_MAX_PATH];
	FT_Face face;
	u32 num_faces, i;
	GF_FontReader *dr = cbck;
	FTBuilder *ftpriv = dr->udta;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path));

	if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0;
	if (!face) return 0;

	num_faces = face->num_faces;
	/*locate right font in collection if several*/
	for (i=0; i<num_faces; i++) {

		/*only scan scalable fonts*/
		if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
			Bool bold, italic, smallcaps;
			strcpy(szFont, face->family_name);

			bold = italic = smallcaps = 0;

			if (face->style_name) {
				char *name = strdup(face->style_name);
				strupr(name);
				if (strstr(name, "BOLD")) bold = 1;
				if (strstr(name, "ITALIC")) italic = 1;
				free(name);
			} else {
				if (face->style_flags & FT_STYLE_FLAG_BOLD) bold = 1;
				if (face->style_flags & FT_STYLE_FLAG_ITALIC) italic = 1;
			}
			
			if (bold) strcat(szFont, " Bold");
			if (italic) strcat(szFont, " Italic");
			if (smallcaps) strcat(szFont, " Smallcaps");
			gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szFont, file_path);

			/*try to assign default fixed fonts*/
			if (!bold && !italic) {
				if (!strlen(ftpriv->font_fixed)) {
					Bool store = 0;
					if (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) store = 1;
					else if (!strnicmp(face->family_name, "Courier", 15)) store = 1;

					if (store) strcpy(ftpriv->font_fixed, face->family_name);
				}
				if (!strlen(ftpriv->font_serif)) {
					Bool store = 0;
					if (!strnicmp(face->family_name, "Times New Roman", 15)) 
						store = 1;

					if (store) strcpy(ftpriv->font_serif, face->family_name);
				}
				if (!strlen(ftpriv->font_sans)) {
					Bool store = 0;
					if (!strnicmp(face->family_name, "Arial", 5)) store = 1;
					else if (!strnicmp(face->family_name, "Verdana", 7)) store = 1;

					if (store) strcpy(ftpriv->font_sans, face->family_name);
				}
			}
		}

		FT_Done_Face(face);
		if (i+1==num_faces) return 0;

		/*load next font in collection*/
		if (FT_New_Face(ftpriv->library, file_path, i+1, & face )) return 0;
		if (!face) return 0;
	}
	return 0;
}

static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path)
{
	GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Scanning directory %s (%s)\n", file_name, file_path));
	gf_enum_directory(file_path, 0, ft_enum_fonts, cbck, "ttf;ttc");
	return gf_enum_directory(file_path, 1, ft_enum_fonts_dir, cbck, NULL);
}


static void ft_rescan_fonts(GF_FontReader *dr)
{
	u32 i, count;
	GF_Config *cfg = gf_modules_get_config((GF_BaseInterface *)dr);
	FTBuilder *ftpriv = (FTBuilder *)dr->udta;

	GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("[FreeType] Rescaning font directory %s\n", ftpriv->font_dir));

	count = gf_cfg_get_key_count(cfg, "FontEngine");
	for (i=0; i<count; i++) {
		const char *key = gf_cfg_get_key_name(cfg, "FontEngine", i);
		if (!strcmp(key, "FontReader")) continue;
		if (!strcmp(key, "FontDirectory")) continue;
		if (!strcmp(key, "RescanFonts")) continue;
		/*any other persistent options should go here*/

		gf_cfg_set_key(cfg, "FontEngine", key, NULL);
		count--;
		i--;
	}
	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "RescanFonts", "no");

	strcpy(ftpriv->font_serif, "");
	strcpy(ftpriv->font_sans, "");
	strcpy(ftpriv->font_fixed, "");

	gf_enum_directory(ftpriv->font_dir, 0, ft_enum_fonts, dr, "ttf;ttc");
	gf_enum_directory(ftpriv->font_dir, 1, ft_enum_fonts_dir, dr, NULL);

	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed", ftpriv->font_fixed);
	gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif", ftpriv->font_serif);
{'fraction_non_alphanumeric': 0.1370628000391888, 'fraction_numerical': 0.013422161261879102, 'mean_word_length': 4.261855670103093, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6242202', 'n_tokens_mistral': 4243, 'n_tokens_neox': 3750, 'n_words': 998}