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 }