【问题标题】:Length of a string in a specific font特定字体的字符串长度
【发布时间】:2021-03-03 16:05:03
【问题描述】:

我正在尝试计算字体中字符串的长度。目标是创建如下文本:

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 窗口),尽管所有脚本都只是 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/... 中找到字符串的长度而不需要这样的环境?

【问题讨论】:

    标签: string perl fonts


    【解决方案1】:

    看起来Font::AFM 可能是您所追求的,但它依赖于您的系统上可能未安装的 Adob​​e Font Metrics (AFM) 文件。

    或者,您可以尝试将其近似为this answer

    【讨论】:

    • 确实,AFM 不可用,因此不是一个选项。你让我想到了 groff 的字体。
    【解决方案2】:

    基于@Joshua 提到的Roughly approximate the width of a string of text in Python?,我创建了自己的字体大小估计。

    Adobe Font Metrics 确实不是普遍可用的。 作为参考,我使用了大多数 Linux 系统上应该可用的 groff 字体。字形名称和表示存在一些问题。我的输入文本包含 é、ü 等,字体文件包含 'e:u 等。所以,我使用groff 来生成一个我可以解析的表:

    #!/bin/bash
    tmpfont=tmpfont
    
    font=$(basename $1)
    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/\\(\1  /'  $tmpfont
    sed -i 's/^\(...\)\t/\\[\1]  /'  $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/^\(.\)/\1 /'>$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";
    }
    

    对于那些感兴趣的人:问题中给出的文本将产生:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多