diff options
| author | YAMAMOTO Mitsuharu | 2019-07-06 14:35:00 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-07-06 14:35:58 +0900 |
| commit | 814b509b1ddf7863d18f7f443e8d733173904e81 (patch) | |
| tree | 612451e17e597ab2de999c5f40f91b351db26fb2 /src | |
| parent | 0e15bd11dc058d5efcdcb16436c3d8cf240859f6 (diff) | |
| download | emacs-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.c | 103 |
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. */ | ||
| 559 | typedef hb_face_t OTF; | ||
| 560 | typedef unsigned int OTF_tag; | ||
| 561 | static OTF *hbotf_open (const char *); | ||
| 562 | static 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 | ||
| 558 | static struct OpenTypeSpec * | 570 | static 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 | |||
| 2888 | static OTF * | ||
| 2889 | hbotf_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 | |||
| 2906 | static int | ||
| 2907 | hbotf_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 | ||
| 2875 | static const char *const ftfont_booleans [] = { | 2972 | static const char *const ftfont_booleans [] = { |