2012年11月30日金曜日

svgフォントの使い方・まとめと検証

webフォントの1規格としては影の薄いsvgフォントですが,その原因として明快な使い方が示されていない事が挙げられます.svgがhtml5に組み入れられた事により,自由度が増したことでかえって使い方が判らないといった事態を招いているのです.従ってここではこの使い方にスポットを当て,svgフォントを利用する上での注意点について考えて見ることとしましょう.

おさらい・svgフォント


svgフォントはグラフィックを描く際のグリフ(文字形)情報を,svgファイル内に埋め込んでしまう為の仕組みです.このことで環境を選ばずに同じ文字の見た目を保つことが出来る事になります.

また,svgで作ったフォントはhtml文書などからも参照することが出来るとされており,フォントの1形式としても認識されています.svgがテキストファイルであることから,極めて編集しやすいのが特徴で,他のフォント形式(woff,ttf,otf)と相互変換することもできます.

何が問題なのか?


それではsvgフォントを使う上で問題となることは無いのでしょうか?実は多くの問題が残っています.
  • まずひとつにサポートしている環境が少ない点が挙げられます.svgフォントをサポートするwebブラウザはchromeやsafariを始めとしたwebkit系ブラウザとoperaでしか動作しません.firefox及びinternet explorerではsvgフォントの仕組み自体は認識するものの,フォントとしては動作しないのです.これはクロスブラウザでの動作を目指す上で極めて問題です.
  • こういった事からsvgフォントを利用したサンプルを見つけるのは非常に困難です.もしあったとしても,それが正しく動作するといった保証がないため試行錯誤すらままならないのです.これが二つ目の問題点です.
  • そして3つめの問題として,svgフォントを利用する際の自由度が高すぎる点が挙げられます.他のフォント形式では通常フォントを利用する為の仕組みが限定されており,調べれば直ぐに判ります.一方svgフォントでは様々な要因により,フォントの呼び出し方には実に多くのパターンがあります.その上でフォントが動作したり動作しなかったりするのです.
上の二つは仕方がないにせよ,三つ目は調べて見る価値がありそうです.

svgフォントの呼び出しパターン


svgフォントの呼び出しを複雑にしている原因は2つあります.
  • html5でインラインsvgが記述可能となったこと.
    このことにより,html内にフォントを埋め込んだり,外部のsvgフォントを定義したりと複数のパターンが生まれます.
  • フォントの呼び出し方法がsvgの機能とcssの利用の2系統存在している.
    svgではcssをサポートしない環境のことを踏まえsvgの仕組みだけで外部フォントを参照する機能を有しています.このことでフォントの呼び出しパターン数が倍になってしまっています.
以下,このパターンについて解説していきます.なお,いずれもhtmlにsvgフォントを表示する事を想定します.

A・htmlファイルにsvgフォントを埋め込むパターン


インラインsvg要素を使ってhtmlファイルにグリフを埋め込んでしまうパターンです.
このパターンでは(1)「フォントを一括して定義する」と(2)「フォント定義とフォント参照を分ける」の二つのパターンに細分化されます.

A-1・フォントを一括して定義する


svg要素の中にfont要素を定義し,その中でfont-face要素を記述することでフォントを登録します.
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--埋め込みフォントの直接参照-->
  <svg>
   <defs>
    <font id="MyFont" horiz-adv-x="1024" horiz-origin-x="0" horiz-origin-y="0" vert-origin-x="45" vert-origin-y="90" vert-adv-y="90">
     <font-face units-per-em="1024" font-family="MyFont" />
     <glyph glyph-name="1" unicode="1" d="M 197.04,682.98 370.72,912.63 690,912.63 708.8,21 328.49,21 408.3,714.49 187.64,633.45" />
     <glyph glyph-name="2" unicode="2" d="M 207.23,911.67 797.33,862.5 840.1,538.74 382.53,210.85 822.98,161.67 882.87,18.2 l -718.41,0 64.15,413.97 423.34,168.02 8.54,188.54 -504.57,-102.47" />
    </font>
   </defs>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

A-2・フォント定義とフォント参照を分ける


先ほどのフォントの定義部をグリフの定義部とフォントの参照部に分けたものです.
フォントの参照にはfont-face要素を使う方法と@font-face規則を使う方法の二つが存在します.

font-face要素
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--埋め込みフォントのid参照-->
  <svg>
   <defs>
    <font id="MyFont" horiz-adv-x="1024" horiz-origin-x="0" horiz-origin-y="0" vert-origin-x="45" vert-origin-y="90" vert-adv-y="90">
     <font-face units-per-em="1024"/>
     <glyph glyph-name="1" unicode="1" d="M 197.04,682.98 370.72,912.63 690,912.63 708.8,21 328.49,21 408.3,714.49 187.64,633.45" />
     <glyph glyph-name="2" unicode="2" d="M 207.23,911.67 797.33,862.5 840.1,538.74 382.53,210.85 822.98,161.67 882.87,18.2 l -718.41,0 64.15,413.97 423.34,168.02 8.54,188.54 -504.57,-102.47" />
    </font>
    <font-face font-family="MyFont">
     <font-face-src>
      <font-face-uri xlink:href="#MyFont"/>
     </font-face-src>
    </font-face>
   </defs>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

@font-face規則
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--埋め込みフォントのid参照・css-->
  <style>
   @font-face {
    font-family:'MyFont';
    src: url(#MyFont) format("svg");
   }
  </style>
  <svg>
   <defs>
    <font id="MyFont" horiz-adv-x="1024" horiz-origin-x="0" horiz-origin-y="0" vert-origin-x="45" vert-origin-y="90" vert-adv-y="90">
     <font-face units-per-em="1024"/>
     <glyph glyph-name="1" unicode="1" d="M 197.04,682.98 370.72,912.63 690,912.63 708.8,21 328.49,21 408.3,714.49 187.64,633.45" />
     <glyph glyph-name="2" unicode="2" d="M 207.23,911.67 797.33,862.5 840.1,538.74 382.53,210.85 822.98,161.67 882.87,18.2 l -718.41,0 64.15,413.97 423.34,168.02 8.54,188.54 -504.57,-102.47" />
    </font>
   </defs>
 
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

B・外部svgフォントを読み込むパターン


外部svgファイルにsvgフォントを定義し,それをhtmlファイルから読み込むものです.このパターンでは(1)「フォントファイルを参照する」と(2)「フォントidを参照する」の二つのパターンに細分化されます.

フォントファイルは次のとおりです.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <font id="MyFont" horiz-adv-x="1024" horiz-origin-x="0" horiz-origin-y="0" vert-origin-x="45" vert-origin-y="90" vert-adv-y="90">
      <font-face units-per-em="1024" font-family="MyFont"/>
        <glyph glyph-name="1" unicode="1" d="M 197.04,682.98 370.72,912.63 690,912.63 708.8,21 328.49,21 408.3,714.49 187.64,633.45" />
        <glyph glyph-name="2" unicode="2" d="M 207.23,911.67 797.33,862.5 840.1,538.74 382.53,210.85 822.98,161.67 882.87,18.2 l -718.41,0 64.15,413.97 423.34,168.02 8.54,188.54 -504.57,-102.47" />
    </font>
  </defs>
</svg>

B-1・フォントファイルを参照する

svgフォントのファイルを参照するものです.font-face-src要素は通常font要素を参照する必要があるのですが,敢えてファイルを参照させてみます.

font-face要素
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--外部フォントのファイル参照-->
  <svg>
   <defs>
    <font-face font-family="MyFont">
     <font-face-src>
      <font-face-uri xlink:href="svgfont.svg"/>
     </font-face-src>
    </font-face>
   </defs>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

@font-face規則
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--外部フォントのファイル参照・css-->
  <style>
   @font-face {
    font-family:'MyFont';
    src: url(svgfont.svg) format("svg");
   }
  </style>
  <svg>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

B-2・フォントidを参照する

svgフォントのファイルを参照し,更にfont要素を参照させます.

font-face要素
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--外部フォントのid参照-->
  <svg>
   <defs>
    <font-face font-family="MyFont">
     <font-face-src>
      <font-face-uri xlink:href="svgfont.svg#MyFont"/>
     </font-face-src>
    </font-face>
   </defs>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

@font-face規則
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <link rel="stylesheet" type="text/css" href="svgfontusing.css"/>
 </head>
 <body>
  <!--外部フォントのid参照・css-->
  <style>
   @font-face {
    font-family:'MyFont';
    src: url(svgfont.svg#MyFont) format("svg");
   }
  </style>
  <svg>
   <text y="16" font-family="MyFont">12345</text>
  </svg>
  <div style="font-family:MyFont">12345</div>
 </body>
</html>

ここまでで実に7つのパターンが見つかりました.それではこれらはどのような動作をとるのでしょうか?

ブラウザごとに動作を確認してみよう


ここまでのコードを確認するページを作って見ました.



これだけだと判りにくいので,ブラウザごとの表示結果を見てみましょう.

・chrome23

・opera12.11

・safari5
このことから判るように,絶対に動作しないパターンが存在しないのが悩ましところで, 単体の環境だけでは問題が見つかりにくくなっています.A-2とB-1のパターンでは動作しない環境があるため避けたほうが良いでしょう.
またhtmlへの適用は概ね問題はないようですが,svgへの適用ではoperaが不安定な結果となっています.(動いたり動かなかったりする?)

結論


ここまでの結果をまとめると,svgフォントを利用する場合は以下の二つの方法が良さそうです.
  • htmlにフォントを埋め込む場合は,font-faceによるフォントの登録までを一括して行う.
  • 外部svgフォントを読み込む場合は,font要素の名称まで指定する.
    (他のフォント形式よりも詳細に指定する必要がある.)
これで確実とは言わないまでも,ある程度信頼のおける使い方は判りました. が,woff形式に比べれば無駄に面倒と言わざるを得ません.動作しない環境がある事を踏まえると,どうにもsvgフォントはこのままフェードアウトしていく運命にある気がしてなりません・・・

おまけ

  • font-face要素でwoff形式のフォントを読み込むといったことは現状難しいようです.@font-face規則だと問題なく動作することから,完全な互換というわけではないようです.
  • javascriptでsvgフォントを定義しているfont要素を操作するのは動作上良くないようです.そのため拙著のsvg要素の基本的な使い方まとめでは,svgフォントの動作が異様に不安定となっています. (この記事を書くきっかけです.)
  • webkit系ブラウザとoperaとではこの他にも合字フォントの動作が異なるとかいろいろあって,正直カーニングとかその他諸々の調査をする気が起きません.(開発者側の苦労を考えると,ここいら辺が整理されるとは到底考思えない.)ぶっちゃけicomoonでttfに変換出来るだけのありがたい規格と割り切るのも手です.
つーか,w3cの仕様って時々誰に向かって書いているのかわからない物がある…

0 件のコメント:

コメントを投稿