Logo address

Text

Font

2012/11/19

Samples

Font のサンプルを載せる。参考のために、どのように font を指定したのかも表示されている。
見え方は OS とブラウザに依存しているかも知れない。

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

#encoding: utf-8
import svg

c = svg.Canvas(0,0,800,500)

def put(y,f,t):
  c.text(20,y,text=t,font=f,anchor="SW")
  c.text(300,y,text=f,font="Courier")

t="along あい 愛"

f="Times;size:32;style:normal;weight:normal"
put(50,f,t)

f="Times;size:32;style:italic;weight:normal"
put(100,f,t)

f="Helvetica;size:32;style:normal;weight:bold"
put(150,f,t)

f="Courier;size:32;style:normal;weight:bold"
put(200,f,t)

f="Impact;size:32;style:normal;weight:normal"
put(250,f,t)

f="Brush Script MT;size:32;style:normal;weight:bold"
put(300,f,t)

f="Comic Sans MS;size:32;style:italic;weight:bold"
put(350,f,t)

f="Osaka;size:32;style:normal;weight:bold"
put(400,f,t)


f="HiraMinPro;size:32;style:normal;weight:bold"
put(450,f,t)

f="HiraKakuPro-W3;size:32;style:normal;weight:bold"
put(500,f,t)

c.close()

参考のために OSX の Safari の結果を示す。

Chrome は、HiraMinPro を理解していない。Times で処理するのが良さそうである。

Baseline

2012/10/25

SVG には様々な Baseline があるが、よく分からないので全て出してみた。

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

ブラウザによって見え方が異なります。
IE9 は全く baseline の指定が働いていません。
以下に Safari の結果を参考のために載せます。

僕は、これを次のように Python で書いています。

#encoding: utf-8
import svg
c = svg.Canvas(0,0,400,400,map=(0,0,10,9))
c.text(3,0.5,text="Various Baselines",
    #style="font-size:22;font-family:Helvetica")
    font="Helvetica;size:22")
bl=("before-edge","text-before-edge","middle","central","after-edge",
    "text-after-edge","ideographic","alphabetic","hanging","mathematical",
    "inherit")
t="あ漢Thing"
m = 3
for n in range(0, len(bl)):
  y = 2*(n/m) + 2
  if n%m == 0:
    c.line(1,y,9,y,stroke="red")
  x = 3*(n%m) + 1
  c.text(x,y,text=t,baseline=bl[n],font="Times;size:17")
  c.text(x,y-0.6,text=bl[n],font="Times;size:15")
c.close()

補足

2012/11/10

デフォルトのフォントはブラウザによって異なるらしい。今回は、Python 側でデフォルトフォントを Times に設定した。しかし、それでも iPad Safari は日本の文字をゴシックで書いている。これは iPad Safari のバグであろう。

Anchor

2012/11/26

Python/Tk 流の anchor をサポートしている。さらに、padding もサポートし、余白をコントロールできるのであるが、ブラウザによって微妙に違う。

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

#encoding: utf-8
import svg
import math
c = svg.Canvas(0,0,400,400,map=(-2.1,2.1,2.1,-2.1))

dot2 = c.symbol("plus",stroke="red",fill="red",scale=2)

c.grid(1,1,stroke="cyan")
c.use(0,0,ref=dot2)
c.use(1,1,ref=dot2)
c.use(-1,1,ref=dot2)
c.use(1,-1,ref=dot2)
c.use(-1,-1,ref=dot2)

c.text(-1,1,text="NE",font="size:20",anchor="NE")
c.text(-1,1,text="NW",font="size:20",anchor="NW")
c.text(-1,1,text="SE",font="size:20",anchor="SE")
c.text(-1,1,text="SW",font="size:20",anchor="SW")

c.text(-1,-1,text="NE",font="size:20",anchor="NE",pad=0.5)
c.text(-1,-1,text="NW",font="size:20",anchor="NW",pad=0.5)
c.text(-1,-1,text="SE",font="size:20",anchor="SE",pad=0.5)
c.text(-1,-1,text="SW",font="size:20",anchor="SW",pad=0.5)

c.text(1,1,text="N",font="size:20",anchor="N")
c.text(1,1,text="S",font="size:20",anchor="S")

c.text(1,-1,text="E",font="size:20",anchor="E")
c.text(1,-1,text="W",font="size:20",anchor="W")

c.text(0,0,text="C",font="size:40",anchor="C")

c.close()

pad の大きさはフォントサイズを単位にしている。

Text Decoration

2012/11/26

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

#encoding: utf-8
import svg
c = svg.Canvas(0,0,400,200)
c.text(50,50,text="Bold Italic", font="weight:bold;style:italic")
c.text(50,80,text="Overline",decoration="overline")
c.text(50,110,text="Underline",decoration="underline")
c.text(50,140,text="Line Through",decoration="line-through")

c.text(50,170,font="weight:bold;style:italic",decoration=True,text="""Bold Italic
 <tspan text-decoration="overline">Overline</tspan>
 <tspan text-decoration="underline">Underline</tspan>
 <tspan text-decoration="line-through">Line Through</tspan>""")

c.close()

SVG と言うのは SVG サーバ(ここではブラウザ)と一方通行の話しか出来ない。つまり、サーバから情報を採れないのだ。そのために、canvas 上の文字列の長さがわからない、現在の書き込みポイントが分からない、などテキストの扱いが極めて窮屈になる。
どうしても情報を採りたいなら、Javascript の支援を受ける必要があるが、そうしたら、今度は限られた環境でしか実行できない。

Stroked Font and Opacity

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

#encoding: utf-8
import svg
c = svg.Canvas(0,0,400,400,map=(-4,4,4,-4))
c.rect(-3,2,3,-2,fill="green")
c.text(0,2,text="abc",font="size:128",stroke="black;width:2",fill="none",anchor="C")
c.text(3,0,text="abc",font="size:128",stroke="black;width:2",fill="white",anchor="C")
c.text(-3,0,text="abc",font="size:128",stroke="black;width:2",fill="white",anchor="C",opacity=0.5)
c.text(0,-2,text="abc",font="size:128",stroke="black;width:2",fill="red;opacity:0.5",anchor="C")
c.close()
# we have both stroke-opacity and fill-opacity

Text along a Path

SVG では経路に添って文字列を描く事ができる。次は、その例である。

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。

経路の向きは、図では矢印で示してある。左から右方向に向かう経路では、文字列はその上に、通常のスタイルで描かれる。右から左に向かう経路では、図を180度回転してみた時に正常になるように描かれる。

このプログラムのコードは次のとおり。

#encoding: utf-8
import svg
c = svg.Canvas(0,0,500,200,map=(-20,25,20,-25))
p = c.marker("arrow",stroke="cyan",fill="none",scale=3)
c.line(-15,-10,-10,0,0,-20,10,10,15,-10,id="wave",smooth=2,stroke="cyan",marker="end:%s"%p)
c.text(text="Once upon a time there was a boy and a girl.",font="size:20",ref="wave")
c.arc(0,0,r=(15,20),start=0,extent=180,id="arc",stroke="cyan",marker="end:%s"%p)
c.text(text="Once upon a time there was a boy and a girl.",font="size:20",ref="arc")
c.close()

Text Area

2012/12/25

SVG にも textArea タグが存在する。これを使って、テキストのワードラップを実現できる。しかし残念な事に、殆どのブラウザは textArea を理解しない。サポートしているのは、僅かに Opera のみである。

特殊な Font

2013/01/08

特殊なフォントをどのように SVG で使えば良いか?

今回は MathML font を試した。このフォントは TeX の数式で使われている字形と同じである。
Mozilla のサイト(文献[1])から

MathML-fonts.zip
をダウンロードする。この中には
STIX,Asana-Math,Mathjax
が含まれている。含まれているグリフを見るに、数式に使われているのは Mathjax の中の
MathJax_Math-Regular.otf
である。どうやら、この中には数字は含まれていないらしい。

システムへのインストールの方法は、文献[1]に書いてある。

なお、TeX の数式フォントは CTAN ([2]) にもあるが、個々のファイルにはサイズ情報が含まれているので使いにくいかも知れない。

[1] Mozilla,"Fonts for Mozilla's MathML engine"
https://developer.mozilla.org/en-US/docs/Mozilla_MathML_Project/Fonts
https://developer.mozilla.org/@api/deki/files/6182/=MathML-fonts.zip

[2] CTAN,"lm-math – OpenType maths fonts for Latin Modern"
http://www.ctan.org/pkg/lm-math

Web Font

一口に、あるブラウザが、あるフォントをサポートしていると言っても、いろいろなレベルがある。

(a) 指定されたフォントをサーバからダウンロードして使える
(b) ドキュメントに埋め込まれたフォントを利用できる
(c) システムにインストールされたフォントを利用できる

Web ページを作る時には (a) が一番利用しやすい。ここでも (a) に焦点をあてる。
CSS3 になって、スタイルシートの中で、フォントをサーバからダウロードして使う仕組みが定義されたらしい。
文献[3]によると、(true type font を使う場合には)

@font-face {
  font-family: 'Hina2ndGrade';
  src: url('../font/Hina2ndGrade.ttf') format('truetype');
}
のように書く。

Web Font と言うのは、フォントの名前ではなく、CSS によってサーバからダウンロードして使うフォントの総称らしい。

[3] 宮本 麻矢,山田 祥寛「第4回 CSS3のWebフォントを使ってみよう」
http://thinkit.co.jp/story/2011/08/18/2233

SVG Font

いろいろなフォント形式を元に SVG 形式のフォント生成してくれるサーバがある([4])。
これを使って

MathJax_Math-Regular.otf
から
MathJax_Math-Regular.svg
を作成した。生成されたファイルは SVG 形式なので、内部を見て、構成が分かる。それよると
font-family="MathJax_Math"
である。また含まれているグリフは

であり、数字は含まれていない。

さて、この SVG フォントが使えるか?

実験によると、システムに MathJax_Math-Regular をインストールしたものは、

font-family="MathJax_Math"
でブラウザが認識している(Chrome,Fafari,Firefox)注1。他方、インストールされていない場合には、CSS で指定しても認識しなかった。(筆者の方法に問題があった可能性は否定できない)

注1: Opera 12.12 は認識していない。IE は未確認。

[4] FreeFontConverter
http://www.freefontconverter.com/

SVG Font Example

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。
図1: SVG フォント

図1は、MathJax_Math を SVG フォント形式で読み取って書いたもの。これが正常に TeX の数式に使われている字形になっていれば、サーバから読み取ったことになる。しかし筆者の実験によれば、クライアントシステムに MathJax_Math-Regular がインストールされていない限り、正しく表示されない。このことは、フォントをサーバから読み取っていない事を意味している。

他方 WOFF を使った図2は最新の主要なブラウザ(IE9,Chrome,Safari,Firefox,Opera)で正しく表示されるはずである。

WOFF (Web Open Font Format)

WOFF は Mozilla.org が提唱した Web のためのフォント形式である。以下の理由で使いやすい。

これだけの特徴を持てば、SVG フォントの存在意義がなくなる!

さて、今回は

MathJax_Math-Regular.otf
を元に
MathJax_Math-Regular.woff
を生成した。変換には「WOFFコンバータ」(文献[9])を使った。

[5]「次期Firefox 3.6が対応する新しいWebフォント形式“WOFF”とは?」
http://blog.petitboys.com/archives/woff.html

[6] MDN,"WOFF (Web Open Font Format)"
https://developer.mozilla.org/ja/docs/WOFF

[7] MDN,"@font-face"
https://developer.mozilla.org/en-US/docs/CSS/@font-face

[8] W3C,"WOFF File Format 1.0"
http://www.w3.org/TR/WOFF/
2009

[9] WOFFコンバータ
http://opentype.jp/woffconv.htm

WOFF Example

あなたのブラウザは SVG をサポートしていません。最新のブラウザをお使いください。
図2: WOFF フォント

図2は最新の主要なブラウザ(IE9,Chrome,Safari,Firefox,Opera)で正しく表示されるはずである。MathJax_Math-Regular には数字は含まれていないので、数字のフォントはブラウザに依存する。

筆者の Python SVG Library を使ったソースコードを次に示す。

#encoding: utf-8
import svg
c = svg.Canvas(0,0,800,150)

t=("0123456789",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyz")

fontstyle = """
@font-face {
  font-family: "myFont";
  src: url("MathJax_Math-Regular.woff") format('woff');;
}
.myFontClass {
  font-family: "myFont";
  font-size: 32;
}"""

d = c.define()
d.svgout("style",'type="text/css"',fontstyle)
d.end()

f="size:32;style:normal;weight:normal"
y = 20
c.text(20,y+20,text=t[0],font=f,anchor="SW")
c.text(20,y+50,text='<tspan class="myFontClass">%s</tspan>'%t[1],font=f,anchor="SW",decoration=True)
c.text(20,y+80,text='<tspan class="myFontClass">%s</tspan>'%t[2],font=f,anchor="SW",decoration=True)
c.text(20,130,text=f,font="Courier")
c.close()

WOFFコンバータには、WOFF の使い方を示す HTML のサンプルの生成オプションを持っている。このプログラムは、そのサンプルに基づいている。しかし、このサンプルは少し冗長である。このケースではもっと簡単になる。

(1) class を使わないで、

@font-face {
  font-family: "myFont";
  src: url("MathJax_Math-Regular.woff") format('woff');;
}
.myFontClass {
  font-family: "myFont";
  font-size: 32;
}

@font-face {
  font-family: "myFont";
  src: url("MathJax_Math-Regular.woff") format('woff');;
}
として、さらに
<tspan class="myFontClass">

<tspan style="font-family:myFont">
としてもよい。

(2) さらに、tspan を使わないで

f="size:32;style:normal;weight:normal"

f="myFont;size:32;style:normal;weight:normal"
と置き換え、
c.text(20,y+50,text='<tspan class="myFontClass">%s</tspan>'%t[1],font=f,anchor="SW",decoration=True)
c.text(20,y+80,text='<tspan class="myFontClass">%s</tspan>'%t[2],font=f,anchor="SW",decoration=True)

c.text(20,y+50,text=t[1],font=f,anchor="SW",decoration=True)
c.text(20,y+80,text=t[2],font=f,anchor="SW",decoration=True)
としてもよい。