RyanJM
RyanJM

Reputation: 7068

Why won't hb-shape read files when passed a variable?

I have a script that where I'm trying to check to see if a given font has a given character in it. hb-shape (from harfbuzz) is able to do this in the shell:

$ hb-shape "/System/Library/Fonts/Supplemental/Courier New.ttf" t
[t=0+1229]

But when I to do it in the script I get:

hb-shape: /System/Library/Fonts/Supplemental/Courier New.ttf : Failed reading file
Try `hb-shape --help' for more information.

Here is my script:

#!/opt/homebrew/Cellar/bash/5.2.26/bin/bash
mapfile -t fonts < <(fc-list : file | head -4 | tr -d ':' | awk '{$1=$1};1')

for font in "${fonts[@]}"; do
    hb-shape "$font" t
done

Why won't hb-shape handle the variable as an input?

I have tried:

Thank you!

Details

System: Mac OS 14.1.2
ZSH (my terminal): zsh 5.9 (x86_64-apple-darwin23.0)
Bash (my script): 5.2.26
fc-list (part of fontconfig package): fontconfig version 2.15.0
hb-shape (HarfBuzz) 8.4.0

Details re: fc-list

$ fc-list | head -4
fc-list | head -4
/System/Library/Fonts/SFCompact.ttf: .SF Compact:style=Thin
/System/Library/Fonts/Apple Color Emoji.ttc: .Apple Color Emoji UI:style=Regular
/System/Library/Fonts/Supplemental/Verdana Bold.ttf: Verdana:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/System/Library/Fonts/SFNSMonoItalic.ttf: .SF NS Mono:style=Medium Italic

$ fc-list : file | head -4
fc-list : file | head -4
/System/Library/Fonts/Supplemental/Courier New.ttf:
/System/Library/Fonts/Apple Braille Pinpoint 6 Dot.ttf:
/System/Library/Fonts/KohinoorTelugu.ttc:
/System/Library/Fonts/ヒラギノ角ゴシック W2.ttc:

$ fc-list : file | head -4 | tr -d ':' | awk '{$1=$1};1'
fc-list : file | head -4 | tr -d ':' | awk '{$1=$1};1'
/System/Library/Fonts/Supplemental/Courier New.ttf
/System/Library/Fonts/Apple Braille Pinpoint 6 Dot.ttf
/System/Library/Fonts/KohinoorTelugu.ttc
/System/Library/Fonts/ヒラギノ角ゴシック W2.ttc

My attempt with the last two commands (tr, awk) is to clean up the : that is left on the file names.

hexdump

I added hexdump to the main loop:

for font in "${fonts[@]}"; do
    echo "'$font'";
    hexdump -C <<<"$font"
done
$ ./finding-char.sh
./finding-char.sh
'/System/Library/Fonts/Supplemental/Courier New.ttf'
00000000  2f 53 79 73 74 65 6d 2f  4c 69 62 72 61 72 79 2f  |/System/Library/|
00000010  46 6f 6e 74 73 2f 53 75  70 70 6c 65 6d 65 6e 74  |Fonts/Supplement|
00000020  61 6c 2f 43 6f 75 72 69  65 72 20 4e 65 77 2e 74  |al/Courier New.t|
00000030  74 66 0a                                          |tf.|
00000033
'/System/Library/Fonts/Apple Braille Pinpoint 6 Dot.ttf'
00000000  2f 53 79 73 74 65 6d 2f  4c 69 62 72 61 72 79 2f  |/System/Library/|
00000010  46 6f 6e 74 73 2f 41 70  70 6c 65 20 42 72 61 69  |Fonts/Apple Brai|
00000020  6c 6c 65 20 50 69 6e 70  6f 69 6e 74 20 36 20 44  |lle Pinpoint 6 D|
00000030  6f 74 2e 74 74 66 0a                              |ot.ttf.|
00000037
'/System/Library/Fonts/KohinoorTelugu.ttc'
00000000  2f 53 79 73 74 65 6d 2f  4c 69 62 72 61 72 79 2f  |/System/Library/|
00000010  46 6f 6e 74 73 2f 4b 6f  68 69 6e 6f 6f 72 54 65  |Fonts/KohinoorTe|
00000020  6c 75 67 75 2e 74 74 63  0a                       |lugu.ttc.|
00000029
'/System/Library/Fonts/ヒラギノ角ゴシック W2.ttc'
00000000  2f 53 79 73 74 65 6d 2f  4c 69 62 72 61 72 79 2f  |/System/Library/|
00000010  46 6f 6e 74 73 2f e3 83  92 e3 83 a9 e3 82 ad e3  |Fonts/..........|
00000020  82 99 e3 83 8e e8 a7 92  e3 82 b3 e3 82 99 e3 82  |................|
00000030  b7 e3 83 83 e3 82 af 20  57 32 2e 74 74 63 0a     |....... W2.ttc.|
0000003f

So it appears there is a new line: 0a. I'm struggling to figure out how to remove that.

Based on this answer I tried the following, but it returned the same output.

hexdump -C <<<"${font//[$'\t\r\n']}"

I also get the same output when I try with:

for font in "${fonts[@]%:*}"; do
    echo "'$font'";
    hexdump -C <<<"$font"
done

Solution

With the help from @F.Hauri-GiveUpGitHub the following works:

mapfile -t fonts < <(fc-list : file | tr -d ':' | awk '{$1=$1};1')

for font in "${fonts[@]}"; do
    printf "'$font'";
    hb-shape "$(printf '%s' "$font")" ⌘
done | grep -v '\.notdef\|gid0\|\.null'

Upvotes: 0

Views: 50

Answers (0)

Related Questions