特定字体的字符串长度
Length of a string in a specific font
我正在尝试计算字体中字符串的长度。目标是创建如下文本:
DD Qui n'a pu l'obtenir ne le méritait pas.
LC Ne le méritait pas! Moi?
DD Vous!
LC Ton impudence
Téméraire vieillard, aura sa récompense
在固定字体(如上)中,这很容易。对于比例字体,我可以使用以下方法对前一行的长度进行可接受的近似:
use Tk;
use Tk::Font;
my $mw = MainWindow->new();
my $font = $mw->fontCreate( 'TimesNew Roman' );
sub timesspace {
(my $text)=@_;
my $retval= $font->measure( $text );
return int($retval);
}
(一个合理的估计,因为 Tk 字体与输出处理器的字体不完全相同)。
但是,这需要一个图形环境(因为我创建了一个 Tk window),即使所有脚本都只是 CLI。这导致:
couldn't connect to display "localhost:11.0" at /usr/local/lib64/perl5/Tk/MainWindow.pm line 53.
MainWindow->new() at /usr/local/bin/xml3roff line 10.
是否有一种可靠且简单的方法来查找 Times/Helvetica/... 中字符串的长度而不需要这样的环境?
看起来 Font::AFM
可能是您想要的,但它依赖于您的系统上可能未安装的 Adobe Font Metrics (AFM) 文件。
或者,您可以尝试将其近似为 this answer。
根据@Joshua 提到的Roughly approximate the width of a string of text in Python?,我创建了自己的字体大小估计值。
Adobe Font Metrics 确实不普遍可用。
作为参考,我使用了在大多数 Linux 系统上应该可用的 groff 字体。字形名称和表示存在一些问题。我的输入文本包含 é、ü 等,字体文件包含 'e
、:u
等。因此,我使用 groff
生成一个对我来说可解析的 table:
#!/bin/bash
tmpfont=tmpfont
font=$(basename )
if [ ! -f "/usr/share/groff/current/font/devps/$font" ] ; then
echo "No suchfont $font"
exit
fi
cp "/usr/share/groff/current/font/devps/$font" $tmpfont
sed -i '1,/charset/d' $tmpfont
sed -i 's/,.*//' $tmpfont
sed -i 's/^\(..\)\t/\( /' $tmpfont
sed -i 's/^\(...\)\t/\[] /' $tmpfont
sed -i '/^\(.....*\)\t/d' $tmpfont
sed -i '/"/d' $tmpfont
sed -i 'a .br' $tmpfont
groff $tmpfont > $tmpfont.ps
ps2ascii $tmpfont.ps | sed 's/ //g;s/^\(.\)/ /'>$font.measure
并确定我使用的字符串的宽度:
#!/usr/bin/perl
use strict;
my %fontmeasure;
if (open ( my $FONT,'<',"TI.measure")){
while (<$FONT>){
chomp;
(my $char,my $width)=split ' ';
$fontmeasure{$char}=$width;
}
close $FONT;
}
else {
die "Can't open font measure";
}
$fontmeasure{' '}=250;
my @str;
while (<>){
undef @str;
@str=split (//);
my $total=0;
for (@str){
if (defined($fontmeasure{$_})){
$total=$total+$fontmeasure{$_};
}
else {
$total=$total+250;
}
}
print "$total\n";
}
对于那些感兴趣的人:问题中给出的文本将产生:
我正在尝试计算字体中字符串的长度。目标是创建如下文本:
DD Qui n'a pu l'obtenir ne le méritait pas.
LC Ne le méritait pas! Moi?
DD Vous!
LC Ton impudence
Téméraire vieillard, aura sa récompense
在固定字体(如上)中,这很容易。对于比例字体,我可以使用以下方法对前一行的长度进行可接受的近似:
use Tk;
use Tk::Font;
my $mw = MainWindow->new();
my $font = $mw->fontCreate( 'TimesNew Roman' );
sub timesspace {
(my $text)=@_;
my $retval= $font->measure( $text );
return int($retval);
}
(一个合理的估计,因为 Tk 字体与输出处理器的字体不完全相同)。
但是,这需要一个图形环境(因为我创建了一个 Tk window),即使所有脚本都只是 CLI。这导致:
couldn't connect to display "localhost:11.0" at /usr/local/lib64/perl5/Tk/MainWindow.pm line 53.
MainWindow->new() at /usr/local/bin/xml3roff line 10.
是否有一种可靠且简单的方法来查找 Times/Helvetica/... 中字符串的长度而不需要这样的环境?
看起来 Font::AFM
可能是您想要的,但它依赖于您的系统上可能未安装的 Adobe Font Metrics (AFM) 文件。
或者,您可以尝试将其近似为 this answer。
根据@Joshua 提到的Roughly approximate the width of a string of text in Python?,我创建了自己的字体大小估计值。
Adobe Font Metrics 确实不普遍可用。
作为参考,我使用了在大多数 Linux 系统上应该可用的 groff 字体。字形名称和表示存在一些问题。我的输入文本包含 é、ü 等,字体文件包含 'e
、:u
等。因此,我使用 groff
生成一个对我来说可解析的 table:
#!/bin/bash
tmpfont=tmpfont
font=$(basename )
if [ ! -f "/usr/share/groff/current/font/devps/$font" ] ; then
echo "No suchfont $font"
exit
fi
cp "/usr/share/groff/current/font/devps/$font" $tmpfont
sed -i '1,/charset/d' $tmpfont
sed -i 's/,.*//' $tmpfont
sed -i 's/^\(..\)\t/\( /' $tmpfont
sed -i 's/^\(...\)\t/\[] /' $tmpfont
sed -i '/^\(.....*\)\t/d' $tmpfont
sed -i '/"/d' $tmpfont
sed -i 'a .br' $tmpfont
groff $tmpfont > $tmpfont.ps
ps2ascii $tmpfont.ps | sed 's/ //g;s/^\(.\)/ /'>$font.measure
并确定我使用的字符串的宽度:
#!/usr/bin/perl
use strict;
my %fontmeasure;
if (open ( my $FONT,'<',"TI.measure")){
while (<$FONT>){
chomp;
(my $char,my $width)=split ' ';
$fontmeasure{$char}=$width;
}
close $FONT;
}
else {
die "Can't open font measure";
}
$fontmeasure{' '}=250;
my @str;
while (<>){
undef @str;
@str=split (//);
my $total=0;
for (@str){
if (defined($fontmeasure{$_})){
$total=$total+$fontmeasure{$_};
}
else {
$total=$total+250;
}
}
print "$total\n";
}
对于那些感兴趣的人:问题中给出的文本将产生: