diff --git a/examples/harfbuzz-cli/HarfbuzzCli.re b/examples/harfbuzz-cli/HarfbuzzCli.re index 3b834bb14..acd1ca17b 100644 --- a/examples/harfbuzz-cli/HarfbuzzCli.re +++ b/examples/harfbuzz-cli/HarfbuzzCli.re @@ -28,7 +28,9 @@ let run = () => { let renderString = str => { let shapes = Harfbuzz.hb_shape(font, str); + print_endline("-- " ++ str ++ " --"); Array.iter(s => {print_endline("- SHAPE: " ++ show(s))}, shapes); + print_endline("----"); }; renderString("abc"); diff --git a/examples/skia-font-manager-cli/SkiaFontManagerCli.re b/examples/skia-font-manager-cli/SkiaFontManagerCli.re index 428d3c7c9..0105b0bae 100644 --- a/examples/skia-font-manager-cli/SkiaFontManagerCli.re +++ b/examples/skia-font-manager-cli/SkiaFontManagerCli.re @@ -95,6 +95,22 @@ let draw = canvas => { ++ string_of_float(FontMetrics.getMaxCharacterWidth(metrics)), ); }; + + let emoji = "😃"; + let char = Zed_utf8.unsafe_extract(emoji, 0); + let maybeTypeface = + FontManager.matchFamilyStyleCharacter( + fontManager, + "Arial", + style, + ["en_US"], + char, + ); + switch (maybeTypeface) { + | Some(tf) => + print_endline("Found font for emoji: " ++ Typeface.getFamilyName(tf)) + | None => print_endline("No emoji font found") + }; }; let surface = makeSurface(640l, 480l); diff --git a/examples/skia-font-manager-cli/dune b/examples/skia-font-manager-cli/dune index de6346277..111b30674 100644 --- a/examples/skia-font-manager-cli/dune +++ b/examples/skia-font-manager-cli/dune @@ -3,7 +3,7 @@ (package ReveryExamples) (public_names SkiaFontManagerCli) (modes native byte) - (libraries skia skia.wrapped.bindings skia.wrapped)) + (libraries skia skia.wrapped.bindings skia.wrapped Revery.Zed)) (install (section bin) diff --git a/src/reason-skia/Skia.re b/src/reason-skia/Skia.re index 5c9a838e7..d70e88a53 100644 --- a/src/reason-skia/Skia.re +++ b/src/reason-skia/Skia.re @@ -503,6 +503,30 @@ module FontManager = { | None => None }; }; + + let matchFamilyStyleCharacter = (mgr, family, style, locales, character) => { + open Ctypes; + let cLocales = CArray.of_list(string, locales); + + let character32 = character |> Uchar.to_int |> Int32.of_int; + + let maybeTypeface = + SkiaWrapped.FontManager.matchFamilyStyleCharacter( + mgr, + family, + style, + cLocales |> CArray.start, + CArray.length(cLocales), + character32, + ); + + switch (maybeTypeface) { + | Some(tf) as ret => + Gc.finalise(SkiaWrapped.Typeface.delete, tf); + ret; + | None => None + }; + }; }; module RRect = { diff --git a/src/reason-skia/Skia.rei b/src/reason-skia/Skia.rei index 760ddd765..611022fac 100644 --- a/src/reason-skia/Skia.rei +++ b/src/reason-skia/Skia.rei @@ -67,6 +67,8 @@ module FontManager: { let makeDefault: unit => t; let matchFamilyStyle: (t, string, FontStyle.t) => option(Typeface.t); + let matchFamilyStyleCharacter: + (t, string, FontStyle.t, list(string), Uchar.t) => option(Typeface.t); }; module FontMetrics: { diff --git a/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re b/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re index af3cbeff8..cabb9f2dd 100644 --- a/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re +++ b/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re @@ -134,6 +134,18 @@ module M = (F: FOREIGN) => { @-> returning(ptr_opt(SkiaTypes.Typeface.t)), ); + let matchFamilyStyleCharacter = + foreign( + "sk_fontmgr_match_family_style_character", + t + @-> string + @-> FontStyle.t + @-> ptr(string) + @-> int + @-> int32_t + @-> returning(ptr_opt(SkiaTypes.Typeface.t)), + ); + let delete = foreign("sk_fontmgr_unref", t @-> returning(void)); };