It's not "Unicode" issue. Arabic has different glyphs for same letter depending on context. A quick and dirty solution:
use strict; use warnings; use Font::TTFMetrics; my $pointsize = 16; my $resolution = 72; my $metrics = Font::TTFMetrics-> new( "Arial.ttf" ); my $c = $pointsize * $resolution / 72 / $metrics-> get_units_per_em; my $str = "\x{0628}\x{0644}\x{062D}\x{0629}"; printf "Wrong answer: %.0f\n", $metrics-> string_width( $str ) * $c; printf "Right answer: %.0f\n", $metrics-> string_width( render_arabic( + $str )) * $c; sub render_arabic { my $word = shift; return $word if length $word == 1; # isolated my %LUT = ( "\x{0628}" => [ "\x{FE90}", "\x{FE92}", "\x{FE91}" ], "\x{0644}" => [ "\x{FEDE}", "\x{FEE0}", "\x{FEDF}" ], "\x{062D}" => [ "\x{FEA2}", "\x{FEA4}", "\x{FEA3}" ], "\x{0629}" => [ "\x{FE94}" ], ); $word =~ s/^. /$LUT{ $& }[ 2 ]/x; $word =~ s/(?<=.).(?=.)/$LUT{ $& }[ 1 ]/xg; $word =~ s/ .$/$LUT{ $& }[ 0 ]/x; return $word }
Wrong answer: 33 Right answer: 22
In reply to Re: How to get an accurate TTFMetrics values for unicode strings?
by vr
in thread How to get an accurate TTFMetrics values for unicode strings?
by Lejocode
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |