+++ /dev/null
-#!/usr/bin/perl -CA
- # use the -CA flag so @ARGV is interpreted as UTF-8
-
-use strict;
-use warnings;
-
-binmode STDOUT, ':utf8';
-
-use lib 'ext/Font-TTF/lib';
-use Font::TTF::Font;
-
-my @name_strings = qw(
- copyright
- family
- subfamily
- unique-identifier
- full-name
- version
- postscript
- trademark
- manufacturer
- designer
- description
- vendor-url
- designer-url
- license
- license-url
- RESERVED
- preferred-family
- preferred-subfamily
- compatible-full
- sample-text
- postscript-cid
- wws-family
- wws-subfamily
-);
-my %name_strings;
-$name_strings{$name_strings[$_]} = $_ for 0..$#name_strings;
-
-main();
-
-sub help {
- print <<EOF;
-This tool provides a (relatively) simple way to manipulate the 'name' table of
-TrueType/OpenType fonts.
-
-Usage:
- $0 [options] [commands] [inputfile.ttf] [outputfile.ttf]
-
-Options:
- --verbose, -v print various details about the modifications made
-
-Any sequence of the following commands:
- --print print the font's current name strings
- --set [name] [string] replace the name string's value
- --append [name] [string] append to the name string's value
- --subst [name] [string1] [string2] replace all occurrences of [string1]
- with [string2] in the name string's value
-
-"[name]" can be any of the following: (see the Name ID table on
-http://www.microsoft.com/typography/otspec/name.htm for full explanations)
-
- copyright, family, subfamily, unique-identifier, full-name, version,
- postscript, trademark, manufacturer, designer, description, vendor-url,
- designer-url, license, license-url, preferred-family, preferred-subfamily,
- compatible-full, sample-text, postscript-cid, wws-family, wws-subfamily
-
-EOF
-
- exit 1;
-}
-
-sub modify_name {
- my ($font, $id, $sub) = @_;
- my $str = $font->{name}{strings}[$id];
- my $exists = 0;
- for my $plat (0..$#$str) {
- next unless $str->[$plat];
- for my $enc (0..$#{$str->[$plat]}) {
- next unless $str->[$plat][$enc];
- for my $lang (keys %{$str->[$plat][$enc]}) {
- next unless exists $str->[$plat][$enc]{$lang};
- my $val = $sub->($str->[$plat][$enc]{$lang}, $plat, $enc, $lang);
- $str->[$plat][$enc]{$lang} = $val;
- $exists = 1
- }
- }
- }
- if (not $exists) {
- warn "Can't find existing name string '$name_strings[$id]' ($id)\n";
- }
-}
-
-
-sub json_string {
- my ($str) = @_;
- $str =~ s/([\\"])/\\$1/g;
- $str =~ s/\r/\\r/g;
- $str =~ s/\n/\\n/g;
- $str =~ s/\t/\\t/g;
- $str =~ s/([\x00-\x1f])/sprintf '\u%04X', ord $1/eg;
- return qq{"$str"};
-}
-
-sub print_names {
- my ($font) = @_;
- my @lines;
- for my $nid (0..$#name_strings) {
- my $name = $font->{name}->find_name($nid);
- if (length $name) {
- push @lines, json_string($name_strings[$nid]).': '.json_string($name);
- }
- }
-
- print "{\n";
- print join ",\n\n", @lines;
- print "\n}\n";
-}
-
-sub parse_id {
- my ($name) = @_;
- if ($name =~ /^\d+$/ and $name < @name_strings) {
- return int $name;
- }
- my $id = $name_strings{lc $name};
- return $id if defined $id;
- warn "Invalid name string identifier '$name'\n\n";
- help();
-}
-
-sub main {
- my $verbose = 0;
- my $print = 0;
- my @commands;
-
- my @args = @ARGV;
- my @rest;
- while (@args) {
- $_ = shift @args;
- if ($_ eq '-v' or $_ eq '--verbose') {
- $verbose = 1;
- } elsif ($_ eq '-p' or $_ eq '--print') {
- $print = 1;
- push @commands, [ 'print' ];
- } elsif ($_ eq '--set') {
- @args >= 2 or help();
- my $id = parse_id(shift @args);
- my $val = shift @args;
- push @commands, [ 'set', $id, $val ];
- } elsif ($_ eq '--append') {
- @args >= 2 or help();
- my $id = parse_id(shift @args);
- my $val = shift @args;
- push @commands, [ 'append', $id, $val ];
- } elsif ($_ eq '--subst') {
- @args >= 3 or help();
- my $id = parse_id(shift @args);
- my $val1 = shift @args;
- my $val2 = shift @args;
- push @commands, [ 'subst', $id, $val1, $val2 ];
- } else {
- push @rest, $_;
- }
- }
-
- ($print and (@rest == 1 or @rest == 2)) or @rest == 2 or help();
-
- my ($input_file, $output_file) = @rest;
-
- my $font = Font::TTF::Font->open($input_file) or die "Error opening $input_file: $!";
-
- $font->{name}->read;
-
- for my $cmd (@commands) {
- if ($cmd->[0] eq 'print') {
- print_names($font);
- } elsif ($cmd->[0] eq 'set') {
- my $id = $cmd->[1];
- modify_name($font, $id, sub {
- my ($val, $plat, $enc, $lang) = @_;
- print "Setting string $id (platform=$plat encoding=$enc lang=$lang)\n" if $verbose;
- return $cmd->[2];
- });
- } elsif ($cmd->[0] eq 'append') {
- my $id = $cmd->[1];
- modify_name($font, $id, sub {
- my ($val, $plat, $enc, $lang) = @_;
- print "Appending to string $id (platform=$plat encoding=$enc lang=$lang)\n" if $verbose;
- return $val . $cmd->[2];
- });
- } elsif ($cmd->[0] eq 'subst') {
- my $id = $cmd->[1];
- modify_name($font, $id, sub {
- my ($val, $plat, $enc, $lang) = @_;
- my $pat = quotemeta($cmd->[2]);
- my $n = ($val =~ s/$pat/$cmd->[3]/g) || 0;
- print "Substituting string $id (platform=$plat encoding=$enc lang=$lang) - $n match(es)\n" if $verbose;
- warn "No match found for substitution on string '$name_strings[$id]'\n" if not $n;
- return $val;
- });
- } else {
- die;
- }
- }
-
- $font->out($output_file) if $output_file;
-
- $font->release;
-}