aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-07-06 14:35:00 +0900
committerYAMAMOTO Mitsuharu2019-07-06 14:35:58 +0900
commit814b509b1ddf7863d18f7f443e8d733173904e81 (patch)
tree612451e17e597ab2de999c5f40f91b351db26fb2 /src
parent0e15bd11dc058d5efcdcb16436c3d8cf240859f6 (diff)
downloademacs-814b509b1ddf7863d18f7f443e8d733173904e81.tar.gz
emacs-814b509b1ddf7863d18f7f443e8d733173904e81.zip
Add HarfBuzz fallbacks for libotf functions used in ftfont_list
* src/ftfont.c [!HAVE_LIBOTF && HAVE_HARFBUZZ]: Include hb-ot.h. (OTF, OTF_tag) [!HAVE_LIBOTF && HAVE_HARFBUZZ]: New typedefs. (hbotf_open, hbotf_check_features) [!HAVE_LIBOTF && HAVE_HARFBUZZ]: New functions. (OTF_open, OTF_close, OTF_check_features) [!HAVE_LIBOTF && HAVE_HARFBUZZ]: New macros. (ftfont_list) [!HAVE_LIBOTF && HAVE_HARFBUZZ]: Use them.
Diffstat (limited to 'src')
-rw-r--r--src/ftfont.c103
1 files changed, 100 insertions, 3 deletions
diff --git a/src/ftfont.c b/src/ftfont.c
index 6f03d966606..74afa2cf5a2 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -552,7 +552,19 @@ struct OpenTypeSpec
552 OTF_TAG_STR (TAG, str); \ 552 OTF_TAG_STR (TAG, str); \
553 (SYM) = font_intern_prop (str, 4, 1); \ 553 (SYM) = font_intern_prop (str, 4, 1); \
554 } while (0) 554 } while (0)
555#endif 555#elif defined HAVE_HARFBUZZ
556/* Libotf emulations on HarfBuzz for the functions called from
557 ftfont_list. They are a bit slower than the original ones, so used
558 as fallbacks when libotf is not available. */
559typedef hb_face_t OTF;
560typedef unsigned int OTF_tag;
561static OTF *hbotf_open (const char *);
562static int hbotf_check_features (OTF *, int, OTF_tag, OTF_tag,
563 const OTF_tag *, int);
564#define OTF_open hbotf_open
565#define OTF_close hb_face_destroy
566#define OTF_check_features hbotf_check_features
567#endif /* !HAVE_LIBOTF && HAVE_HARFBUZZ */
556 568
557 569
558static struct OpenTypeSpec * 570static struct OpenTypeSpec *
@@ -915,7 +927,7 @@ ftfont_list (struct frame *f, Lisp_Object spec)
915 continue; 927 continue;
916 } 928 }
917#endif /* FC_CAPABILITY */ 929#endif /* FC_CAPABILITY */
918#ifdef HAVE_LIBOTF 930#if defined HAVE_LIBOTF || defined HAVE_HARFBUZZ
919 if (otspec) 931 if (otspec)
920 { 932 {
921 FcChar8 *file; 933 FcChar8 *file;
@@ -940,7 +952,7 @@ ftfont_list (struct frame *f, Lisp_Object spec)
940 if (!passed) 952 if (!passed)
941 continue; 953 continue;
942 } 954 }
943#endif /* HAVE_LIBOTF */ 955#endif /* HAVE_LIBOTF || HAVE_HARFBUZZ */
944 if (VECTORP (chars)) 956 if (VECTORP (chars))
945 { 957 {
946 ptrdiff_t j; 958 ptrdiff_t j;
@@ -2870,6 +2882,91 @@ fthbfont_begin_hb_font (struct font *font, double *position_unit)
2870 return ftfont_info->hb_font; 2882 return ftfont_info->hb_font;
2871} 2883}
2872 2884
2885#ifndef HAVE_LIBOTF
2886#include <hb-ot.h>
2887
2888static OTF *
2889hbotf_open (const char *name)
2890{
2891 FT_Face ft_face;
2892
2893 if (! ft_library
2894 && FT_Init_FreeType (&ft_library) != 0)
2895 return NULL;
2896 if (FT_New_Face (ft_library, name, 0, &ft_face)
2897 != 0)
2898 return NULL;
2899
2900 hb_face_t *face = hb_ft_face_create_referenced (ft_face);
2901 FT_Done_Face (ft_face);
2902
2903 return face;
2904}
2905
2906static int
2907hbotf_check_features (OTF *otf, int gsubp,
2908 OTF_tag script, OTF_tag language,
2909 const OTF_tag *features, int n_features)
2910{
2911 hb_face_t *face = otf;
2912 hb_tag_t table_tag = gsubp ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
2913 hb_tag_t script_tag = script, language_tag = language;
2914
2915 unsigned int script_count
2916 = hb_ot_layout_table_get_script_tags (face, table_tag, 0, NULL, NULL);
2917 hb_tag_t *script_tags = xnmalloc (script_count, sizeof *script_tags);
2918 hb_ot_layout_table_get_script_tags (face, table_tag, 0, &script_count,
2919 script_tags);
2920 unsigned int script_index;
2921 for (script_index = 0; script_index < script_count; script_index++)
2922 if (script_tags[script_index] == script_tag)
2923 break;
2924 xfree (script_tags);
2925 if (script_index == script_count)
2926 return 0;
2927
2928 unsigned int language_index;
2929 if (language_tag == 0)
2930 language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
2931 else
2932 {
2933 unsigned int language_count
2934 = hb_ot_layout_script_get_language_tags (face, table_tag, script_index,
2935 0, NULL, NULL);
2936 hb_tag_t *language_tags = xnmalloc (language_count,
2937 sizeof *language_tags);
2938 hb_ot_layout_script_get_language_tags (face, table_tag, script_index, 0,
2939 &language_count, language_tags);
2940 for (language_index = 0; language_index < script_count; language_index++)
2941 if (language_tags[language_index] == language_tag)
2942 break;
2943 xfree (language_tags);
2944 if (language_index == language_count)
2945 return 0;
2946 }
2947
2948 for (int j = 0; j < n_features; j++)
2949 {
2950 hb_tag_t feature_tag = features[j];
2951 hb_bool_t negate = 0;
2952
2953 if (feature_tag == 0)
2954 continue;
2955 if (feature_tag & 0x80000000)
2956 {
2957 feature_tag &= 0x7FFFFFFF;
2958 negate = 1;
2959 }
2960
2961 unsigned int feature_index;
2962 if (hb_ot_layout_language_find_feature (face, table_tag, script_index,
2963 language_index, feature_tag,
2964 &feature_index) == negate)
2965 return 0;
2966 }
2967 return 1;
2968}
2969#endif /* !HAVE_LIBOTF */
2873#endif /* HAVE_HARFBUZZ */ 2970#endif /* HAVE_HARFBUZZ */
2874 2971
2875static const char *const ftfont_booleans [] = { 2972static const char *const ftfont_booleans [] = {