[tech] JavaScript の必要ないソーシャルボタン | Fri, Apr 15. 2016 - 氾濫原 これを作るとき、最初のうちは全てSVGにするぞと意気込んでいて、Ligature Symbols に含まれるものをSVGに変換したらいいのではないかと、いろいろ試していました。
結局その方法はやめたのですが、SVG フォントから、個別の SVG ファイルに変換するスクリプトを雑に書いたので残しておきます。SVG フォント全体だとファイルサイズが大きすぎるので、必要なファイルだけ普通の SVG 画像として抽出するということです。
以下のように perl + XML::LibXML で書きました。グリフ名を引数に与えると、該当するグリフを個別の .svg に書き出します。LigatureSymbols でしか試していませんが、SVG フォントなら他のでもいけるかもしれません。
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use v5.10.0;
use lib lib => glob 'modules/*/lib';
use XML::LibXML;
open(my $fh, "<", "LigatureSymbols-2.11.svg") or die "cannot open < input.txt: $!";
my $font = do { local $/; scalar <$fh> };
close $fh;
my $doc = XML::LibXML->load_xml( string => $font, load_ext_dtd => 0 );
my $xpc = XML::LibXML::XPathContext->new($doc);
# get copyright metadata
my $original_metadata = $xpc->findvalue('/svg/metadata');
my $units_per_em = $xpc->findvalue('/svg/defs/font/font-face/@units-per-em');
my $ascent = $xpc->findvalue('/svg/defs/font/font-face/@ascent');
my $bbox = $xpc->findvalue('/svg/defs/font/font-face/@bbox');
for my $glyph_name (@ARGV) {
my $glyph = $xpc->findnodes(sprintf('/svg/defs/font/glyph[@glyph-name="%s"]', $glyph_name))->[0];
my $horiz_adv_x = $xpc->findvalue('./@horiz-adv-x', $glyph);
my $document = XML::LibXML::Document->new('1.0', 'UTF-8');
my $svg = $document->createElement('svg');
$svg->setAttribute('width', $horiz_adv_x);
$svg->setAttribute('height', $units_per_em);
# $svg->setAttribute('viewBox', $bbox);
$svg->setAttribute('xmlns', 'http://www.w3.org/2000/svg');
$document->setDocumentElement($svg);
my $metadata = $document->createElement('metadata');
$metadata->appendChild($document->createTextNode($original_metadata));
$svg->appendChild($metadata);
my $path = $document->createElement('path');
$path->setAttribute('transform', sprintf("scale(1, -1) translate(0,%s)", -$ascent));
$path->setAttribute('fill', '#fff');
$path->setAttribute('d', $xpc->findvalue('./@d', $glyph));
$svg->appendChild($path);
warn "write to $glyph_name.svg";
say $document->toString(1) ;
open(my $fh, ">", "$glyph_name.svg");
print $fh $document->toString;
close $fh;
}