SVG画像の分割スクリプトをPythonに移植した話 - SVG Advent Calendar 2014-


この記事は、SVG Advent Calendar 2014の参加記事です。前回(20日)は @hashcc さんの「東京の鉄道路線図SVGを作りました&パブリックドメインで配布します」でした。
@hashccさんの力作の翌日を担当することになってしまいましたが、微力ながら相応の記事になるよう力を尽くす所存です。

今回は、ルーン文字フォント制作に使用している手製のSVG画像の分割スクリプトを使うことになった経緯、その再実装(リファクタ)に至る過程、そしてその結果について書かせていただきます。

RuneAMN_Pro_Blackletterより


オリジナルフォント作りと、SVG画像の分割スクリプト

わたしが現在公開しているRuneAMNシリーズフォントは、イラスト・デザイン向けに作られたルーン文字フォントです。普通のアルファベットを入れてフォントを適用するだけで簡単に、ルーン文字をデザインに使えるようになっています。
シリーズ構成は、独立したFree版とPro版(有償)があり、それぞれ重複しない独自の書体を収録しています。
他に、Project "daisy bell"の製品として、OlChikiAMN(オルチキ文字フリーフォント)も配布しています。

これらのフォントを制作する際、Illustratorで書体デザインを行っています。そして、SVG画像への書き出しを経由して、FontForgeに読み込ませてフォント化しています。
なぜフォントエディタの編集機能で完結させず、複雑なビルド手順を踏む選択をしたかといえば、FontForgeよりIllustratorのほうが、ベクタ画像のエディタとしては使い慣れており高機能だったという点に尽きます。
また、フォントのデザインの中には、フォントエディタでなければ事実上デザインが不可能なもの(Multiple Masterなど)もありますが、今回はそういったフォント機能を使う予定がなかったため、この手法を選択することができました。

SVG分割スクリプト(svg_splitter.pl)の機能拡張

フォントの制作プロセスにおいて、『すべてのグリフ(文字)を一枚のSVG画像に描いて、後から自動分割したい』という要求がありました。
すべてのグリフを1枚の画像に描きたかったのは、そのほうがファイルの管理が簡単で、デザインを統一しやすいためです。
自動分割というのは、スクリプトにより1枚の画像から、1文字につき1ファイルの状態に分割することができる、ということです。SVG画像の分割を、makeを使ったビルドプロセスに含めるために必須でした。

OlChikiAMN_Series_Fontsより


ところで、SVG画像の圧縮は熱心に研究されている一方で、SVG画像の分割は 、あまり試みられていないようです。
私が見た限りでは、

・Illustrator(スクリプト)は、アートボードで範囲を区切って書き出しても、範囲外の表示されないすべての要素もSVGファイルに含めたまま出力する。
・ InkScapeにはスクリプト化の方法が2種類ある。
  コマンドライン引数の方法では、詳細な制御ができない。
  Python拡張版(inkey)ではなぜかLGPL汚染が懸念されており、さらにAPIの網羅されたドキュメントを見つけることができない。
・Perl、PythonにはSVGを処理する多くのライブラリが存在するが、そのほとんどが「SVGを圧縮」するか「SVGをラスタ画像に書き出す」機能しか持っていない。
  (参考として、PythonのSVG関連ライブラリを調べた方が作った一覧がこちら。 )

結果的に、SVG画像を画像として扱う"まともな"分割器を見つけることができませんでした。

見つかったのは、mashabow@しろもじ氏の手書き文字「てきとうに書いてつくったフォント」用SVG分割器と、M+フォントのビルドシステムに含まれているSVG分割器でした。
このどちらも、SVGを画像ではなくXMLテキストとして解析した後で、SVG要素を独自に計算することでSVG画像の分割を実現しています。
M+の分割器は、SVGの多くの要素に対応していた反面、日本語フォント1万2000文字オーバーをすべて分割できる機能を持たせるために、複雑な構造となっています。(2ファイルに分割されており、内部動作もマルチスレッド化などがされている)。
一方、手書き文字フォントの分割器は、対応要素がpolygonだけである代わりに、1ファイルに完結しており動作も容易に追うことができました。
以上のことから、RuneAMNでは、手書き文字フォントの分割器を、拡張しながら使っていくことにしました。

リファクタ・PerlからPythonへの移植

このスクリプトは、RuneAssingMN_Free、OhChikiAMN_Free、RuneAMN_Proの制作に、機能拡張しながら使われました。ほぼすべての拡張が「その場しのぎのやっつけ仕事」で行われました。そのため、コードベースは混乱を極めており、コピーペーストされた同じ処理がいくつもの場所に分散しており、機能拡張とバグ修正は困難を極める状態になっていました。
例:
・SVG要素を切り出す際、配置位置の計算は、分割サイズで割って余りを出すだけ
 (マイナス値など、グリフ形状が文字の枠からはみ出す部分を持つことを考慮していない)
・分割判定部は、SVG要素の数だけコピーペーストした
 (polygon/rect/circle etc...)

控えめに言ってこのスクリプトは公開することで私の(あって無いような)キャリアに傷をつけるのではないかと危惧するほど汚いfixやその場凌ぎのコードで満ちている。しかし、スクリプトがたとえ飛び出したクジラの内蔵の干物のようであったとしても、生成されたフォントの美しさはカケラも損なわれない。グリフのデザインは、1/10ピクセルも、まったく、狂わないからだ。ならばリファクタリングは時間の無駄と言える。
(Pythonによる再実装を行う前の、本記事の原稿より。)

もちろん、コードが汚いからといって、フォント自体は1ピクセルも変化したりはしないことは誰でもわかっています。コードが綺麗であろうがクジラの内蔵が飛び出した状態であろうが作られたフォントの美しさは全く損なわれることがないことは間違いありません。

しかし実のところ、svg_splitter.plの次の機能追加やバグフィックスは困難を極めるだろう。私は有名な「すべてを一から書き直したい病」にかかっており、誰かがこのスクリプトを使いたいと言ったならば、私は間違いなくすべてを書き直す。そしてその時はPythonを使う。フォントプログラミングとPythonは相性がよく、例えばFontForgeはネイティブ言語とは別にPythonスクリプトによる制御を提供している。また、PythonにはPerlと同じように、SVGのベースであるXMLを処理するためのライブラリがあらかじめ用意されている。余録として、将来Windows環境をサポートする際に、FontForgeのWindowsポート版がPythonインタプリタを持っていることが期待できる。
(Pythonによる再実装を行う前の、本記事の原稿より。)

RuneAMN_Free/Proのアップデートを決意した私は、そのためにはSVG分割スクリプトに新機能が必要であると判断しました。
そこで、以前から考えていた、リファクタを兼ねたPythonへの再実装を行うことにしました。




リファクタリングの結果

再実装中のPythonスクリプト版


Pythonへの移植を行ったため、当然ながら、すべてのコードが1から書きなおされました。
リファクタリングでは「新しい機能はひとつも追加しない」のが鉄則ですが、今回はいくつかの新機能・機能改善を含みます。
以下が、リファクタ作業の結果です。

・見通しの良いコード
   ・すべての機能は関数に分割された。
   ・新しいmain部は20行ほど
   ・新フォントのための新機能を容易に追加できる
   ・transform属性を処理する部分が関数に共通化された。
   ・アプリケーション・ハンガリアン記法になった。
リファクタリング以前、SVG分割器の機能は関数化されていませんでした。
度重なる機能追加により同じ機能があちこちに散らばり、処理の流れが簡単にはわからない状態になっていました。
また、変数名や関数名にもルールらしいものはなかったため、可読性が低く処理を追いかけることが困難になっていました。
リファクタリングの後、多くの部分が適切に関数化され、処理を以前より容易に把握することができるようになりました。
アプリケーション・ハンガリアンは(リファクタリングと共に)Joel on Softwareの受け売りですが、命名規約があることにより以前よりコードが読みやすくなったことは確かです。

・引数の処理を改善。プログラム内部でも、設定値が読みやすくなった。
・SVG要素の再配置の計算を正しい方法に直した
 「分割サイズで割って余りを出す」のではなく、「(分割セル上の行列位置×分割サイズ)を現在位置から引く」ことで、分割セルからはみ出したポイントなどを正しく分割後再配置できるようになりました。
・グループ要素(<g>)を再帰的に探索できるようになった。
 perl版では、対象1グループの中に含まれる(つまり1レイヤーの)SVG要素しか対象にすることができませんでした。
 そこで、グループを再帰的に探索するよう機能拡張しました。
 IllustratorやInkScapeで、書き出し前にレイヤ統合やグループ化解除をする必要がなくなった。
・ついでにいくつかの使っていないpolygonパスのコマンドに対応できた
  ほかの未実装部も容易に追加できるはずです。
・RuneAMN_Proを、.pl版と同じように、すべて問題なくビルドできる。
 汎用であることを心がけてはいますが、一方でこのスクリプトはdaisy bellのフォントプロジェクト専用であり、使われない機能は未実装のまま省略することができます。
 Python版がPerl版とまったく等価な出力が可能で、退行(リグレッション)していないことを確認できました。


また、余録として、
・分割スクリプトを通して、SVGの構文について学習することができた
・Python(Python3)処理系について学習することができた
PythonによるSVGの加工を学ぶことで、将来的にもっと高度なフォントデザイン支援を実現するための、足がかりにしようと考えています。
また、SVGはWebデザインなどの分野でこれからより使われるようになると思われ、理解しておいて損はないはずです。(そしてこれはSVG Advent Calender 2014の記事です。忘れてしまいそうになりますが。)

・SVG分割スクリプトのすべてを、自分でコントロールすることができる
機能追加のために行ったことにリファクタリングにより、フォント制作でしか使われないであろうSVGへの処理を、ビルドのコアに含めることが簡単にできるようになりました。これはフォント自体に影響を与えるものではないので、
『それがビジネスの核となる機能なら−−何が何でも自分でやることだ』
(これもJoel on Software ただし書籍)
の系になるのかどうかはわかりませんが。

ソースコードなど

main部分は、たったのこれだけになりました。
実際のコード部分は20行以下になっています。

if __name__ == '__main__':
 
args = docopt(__doc__)

 
# 設定ファイルを解析する
 
settings = getSettingsFromSettingFilePath(args["<listfile>"])
 
settings['output_dir'] = args['--output_dir']
 
pprint(settings)
 

 
# SVGファイルをxmlとして読み込む
 
tree = ET.parse(args["<src_image>"])
 
rootSvg = tree.getroot()
 
# SVGファイルの縦横サイズを取得する
 
widthSvg = getNumericFromStringHead(rootSvg.get("width"))
 
heightSvg = getNumericFromStringHead(rootSvg.get("height"))
 

 
# Todo: プリプロセスとして、非表示のグループとレイヤ名'*_ignoreSSSMN'を持つレイヤを除去
 
# Todo: 透明なsvg要素も除去する。タイミングは未定。


 
# SVGパスをレイヤ(グループ)ごとに分割器にかける(rootにも要素があるのでレイヤ扱いする)
 
dstsTable = [[0 for i in range(settings['col'])] for j in range(settings['row'])]
 
ravelGroup(dstsTable, settings, rootSvg)

 
writeSvgs(dstsTable, settings)


SVG要素の読み出し部分も、以下のように関数化され、整理されました。
さらに、再帰呼出しを使うことで複数レイヤに対応しました。

"""
 @brief xmlツリーからSVG要素を再帰的に検出して分割処理する
 @param 分割済みデータ連想配列
 @param 設定ファイル情報(分割設定)
 @param xmlツリー(グループ要素)
 @return 分割済みデータ連想配列

 
 
 
(Todo:エラー処理)
"
""
def ravelGroup(dstsTable, settings, svgGroup):
 
svgTransform = svgGroup.get('transform')
 
if svgTransform:
 
 
print('warning: not inplement transform attr.')
 

 
elems = list(svgGroup)
 
for elem in elems:
 
 
if'{http://www.w3.org/2000/svg}g' == elem.tag:
 
 
 
dstsTable = ravelGroup(dstsTable, settings, elem)
 
 
elif '{http://www.w3.org/2000/svg}path' == elem.tag:
 
 
 
dstsTable = ravelPath(dstsTable, settings, elem)
 
 
elif '{http://www.w3.org/2000/svg}rect' == elem.tag:
 
 
 
dstsTable = ravelRect(dstsTable, settings, elem)
 
 
elif '{http://www.w3.org/2000/svg}polygon' == elem.tag:
 
 
 
dstsTable = ravelPolygon(dstsTable, settings, elem)
 
 
elif '{http://www.w3.org/2000/svg}polyline' == elem.tag:
 
 
 
dstsTable = ravelPolyline(dstsTable, settings, elem)
 
 
elif '{http://www.w3.org/2000/svg}circle' == elem.tag:
 
 
 
dstsTable = ravelCircle(dstsTable, settings, elem)
 
 
else:
 
 
 
print("other tag:" + elem.tag)
 
return dstsTable


本スクリプトのコードは全体で559行あります。

最後に

GithubのRuneAssignMN_Series_Fonts他にて、フォント元画像、ビルドスクリプトなどのすべてを、自由なライセンスで公開しています。
また、RuneAMN_Pro_Series_Fontsについても、やはりGithubにてビルドスクリプトとテスト用のフォント元画像を公開しています。





今回紹介した、Python版のsvg_splitter.pyは、RuneAMNフォントの一部として、githubにてBSD class-2ライセンスで公開する予定です。
リリースの告知はフォントと同じにTwitterなどで行う予定です。もし今欲しいという方がいれば、連絡をいただければ個別に差し上げたり公開を早めたり、対応します。

Project "daisy bell"のフォント関連リリースについては、daisy bellのBOOTHまたはSourceForgeにて確認できます。
@MNukazawa でも告知しています。現在、 このtwitterアカウントでフォント制作過程を毎日報告しています。質問などありましたら気軽にどうぞ。

以上です。


明日のSVG Advent Calendar 2014syon さんの「SVGでキラキラをつくりたい(願望)」 です。よろしくお願いします。

docoptを使ってみた(Ubuntu14.04 / python3)



現在、フォント制作に使用している、SVGを分割するPerlスクリプトを、Python3に移植中です。

引数の処理をPythonの流儀に合わせようと検索したところ、
馴染みのあるヘルプを文法に従って書けばパーサを生成してくれます』(リンク先サイト様より引用)というdocoptが紹介されているのを発見。
githubのプロジェクトページによると、MITライセンス。
とても良さそうだったので、導入ついでに引数オプションをいろいろ変更することに。

変数名とコードの整理だけの純粋な移植をするつもりが、早速機能を盛ってしまいました。趣味プログラミングでこれを抑制するのは本当に難しい。



Ubuntu14.04へのdocoptモジュール導入を導入する際、普通にpipコマンドを使うと、Python2の方にdocoptが導入されます。私はPython3で使いたいので、
sudo apt-get install python3-docopt
にてPython3側に導入しました。


以下が、動作確認に使ったコードです。

#!/usr/bin/python3

"""Process some integers.

usage: this_script.py [-h] <src_image> <listfile> [--output_dir=<DIR_OUT>] [--width=<NUM_WIDTH>] [--height=<NUM_HEIGHT>]

options:
    -h, --help  show this help message and exit
    --sum        sum the integers (default: find the max)
    --output_dir=<DIR_OUT>    splitted SVG images output dir [default: glyphs_/]
    --width=<NUM_WIDTH>        width for unit of split base squared(cross-section) [default: 1000]
    --height=<NUM_HEIGHT>    height for unit of split base squared(cross-section) [default: 1000]
"""

from docopt import docopt
from pprint import pprint

if __name__ == '__main__':
    args = docopt(__doc__)
    numWidth = args["--width"]
    numHeight = args["--height"]

    widthUnit = numWidth    #
    heightUnit = numHeight    #

    print(widthUnit)
    print(heightUnit)

    pprint(args)


コマンドによる呼び出しと出力結果は以下のとおり。
python3 docopt_t.py RuneAMN.svg RuneAMN.list --output_dir=amn/ --width=800 --height=800800
800
{'--height': '800',
 '--output_dir': 'amn/',
 '--width': '800',
 '-h': False,
 '<listfile>': 'RuneAMN.list',
 '<src_image>': 'RuneAMN.svg'}



オプション引数名は『<angular-brackets> or UPPER-CASE』で指定しなければならないなど、記述フォーマットにいくつかのルールがあるようです。
とりあえず、docoptを記述した『"""形式コメント""" 』は他のコメントより前に置きましょう。他のコメントを前に書くとdocoptが機能しませんでした。ただし、『#』形式コメントが前にあっても問題なく機能します。
なお、直観に反して、[defailt: 値]の指定はデフォルト値を入れてくれるわけではないようです。いろいろ調べるより、自分でNoneをチェックしてデフォルト値を入れる処理を書いたほうが楽です。


docopt取得値の確認にはpprintが便利でした。

RuneAMN_Proの話 - #LOVEFONT Advent Calendar 2014-


はじめまして。Michinari Nukazawaと申します。
今回は、なぜか空いていた #LOVEFONT Advent Calendar 2014 の7日目の代打として、拙作のルーン文字フォントセット「RuneAssignMN_Free」および「RuneAMN_Pro」と、なぜこれらのフォントを作ったのかについて、書かせていただこうと思います。

6日目はMignon Styleさんの「すっきりして可愛い商用可のフリーフォント MigMix」でした。

まさか、初Advent Calendarが代打になるとは思いませんでした。だったら手を挙げるなという話かもしれませんが。
荒削りですが、ご容赦ください。


自作ルーン文字フォントを作るにあたって、紙面でデザインを練った

あなたは誰?

あらためましてはじめまして。MNukazawaと申します。Project "daisy bell" [booth.pm] の主催者です。
現在は、ルーン文字フォントセット「RuneAssignMN_Free」および、
フォントセット「OlChikiAssingMN_Free」をフリーで公開しています。
また、フォントセット「RuneAMN_Pro」を販売しています。

最近ではオープンソースのフォント作成アプリFontForgeの日本語訳ページ不具合修正などをやったりしていました。
わたしは自分の肩書はプログラマだと思っています。...が、いつのまにやら現在の主なプロダクトはフリーフォントになってしまいました。
責任者はどこか。俺か。


RuneAssingMN、フリーフォント版の簡素な紹介画像
RuneAMN_Pro版ではさすがに、見本画像のデザインにも注意した

フリーフォントの配布はSourceForgeでも行っています。
こちらは、サポートのTwitterアカウント。Twitterでは、今のところほぼ毎日、フォント作成の作業経過を報告しています。

daisy bell のBOOTH。この前予告なしにユーザアイコン領域が追加されて驚いた。

これらのフォントは、ただ配布・販売しているだけでなく、その制作に使用したプログラム(ビルドスクリプト)と素材ファイルをgithub上で無償公開しています。
(Pro版も、すべてのビルドスクリプトと、スクリプトの動作検証用に1フォント素材を公開している)


LOVEFONTはフォント利用者の視点がメインのようなので、今回は製作者として。(アドベントカレンダー内でフォント会社の中の人の登場予定とかありそうで怖いですが...。)

RuneAMN_Proフォントセット作成までの過程

最初に重要なことを。

FreeはProの体験版ではありません

サブセットでもない。
完全に独立したフォントセットで、どちらかというとProが従(後)。

RuneAssignMN_Freeフォント

ソフトウェア世界には「オープンソース」という考え方があります。
「自分の作ったものを無償公開し、いろいろな人に使ってもらう」
オープンソースに貢献したい、何かをオープンソースで公開してみたい。
そう考えていました。

で、ある時、Puella Magi Wikiの解読班&フォント作成に影響された。
(私が公開しているフリー版ルーン文字フォントの割り当て表は見ましたか?)
重要な点として、私はフォント界隈の外の人間として、その時はじめて、
フォントはひとの手で作ることができるんだ!』
ということを認識しました。(フォントワークスジャパンとか何の集団だと思っていたんだ私...。)


これらのことが重なって、『そうだ、フォントを作ろう。』と思い立ったわけです。

しかし、1万文字を超える日本語フォントを作るのはとても大変です。
また、普通のフォントは、大手フォントベンダがすでにほぼ作り尽くしています。
(モリサワとフォントワークスがサブスクリプションに移行したのはAdobeと同じ理由で、製品はすでに完成してしまっており、ユーザはもう新製品を買う理由が無くなったからなのだろうと思います。)
そこで、ちょっと狙いを変えたフォントを作ることにしました。
つまり、『ファンタジーなイラストで使えるフォントを作ろう』。
調べたところ、文字にもいろいろあることがわかりました。
そして、『ルーン文字』のフリーフォントは5件しかない。(そしてライセンスを調べると、本当に「フリー」と呼べるものはそのうち3件だけだった。)
イラスト・デザイン向けにルーン文字フォントの需要はあるのではないかと思いました。

そして、3つのフォントをまとめたフォントセットとして、RuneAssignMN_freeフォントセットをリリースしました。
リリースまでは、初めてだらけの行程でした。たとえば、ルーン文字とアルファベットのライセンスフリーかつ完全な対応表が存在しなかったため、自作する必要がありました。
他にもいろいろ勉強し、技術的な問題を解決しつつ、紆余曲折の末のリリースでした。

このフリーフォントのライセンスは、2-clause BSDです。このライセンスはたとえば、
・このまま値段を付けて売っていい!
・このフォントを元に商業フォントを作って売っていい!
・ゲームとかに組み込んでOK!
・もちろんイラストに使い放題!
・上記のことを作者に連絡する必要もない!
といったことが許されます。(なのでぜひ使ってください。)

また、 フォントだけでなく、作り方と使ったプログラムも同じライセンスで公開しました。

で、満足したのでこれで終わるはずだったのですが。

RuneAMN_Proフォント

Q.「オープンソース」と言いながら、なぜフォント”販売”をすることにした?
A.父が定年退職したので。

私は院卒であったため、まだ社会人2年目...。
手っ取り早くお金になるものはないか?

作ったばかりのフォント+ビルドシステム+まだ作り方を覚えている
=そうだ、フォントを作って売ろう!

しかし、既にフリーで公開しているものを売りたくはない。
=そうだ、(フリー版とビルドシステムを元に)まったく新しい書体を作って売ろう!


Pro版制作にあたって、新たに立ちふさがった技術的な課題など、何が起こったかはいずれ、「RuneAMN_Proへの道 part1〜」などと題して記事にするつもりでいます。今ゆっくり書いている。
そのシリーズでは、フォント作成に特有のSVG画像の取り扱いや、グリフデザインの手順、書体見本誌の作成(PDF注意)。そして何より、「フォントファイル」を「フォント製品」にするために私がやったことを、もっと具体的に書くつもりです。


フォント製品には必ず付いてくる書体見本誌(写真は草稿)。
Web上で公開しているので、購入前に見ることができる。

技術的な課題の例:「RuneAssignMN」 ->  「RuneAMN」へシリーズ名を変更。
Windowsのフォント名前数制限に引っかかったので。(32文字だったっけ?)
(この例はしょぼいな...。)

ともかく、そんな感じです。


で、LOVEFONT的に。

Q. 自分の作ったフォントのなかで、どのフォントが好きなの?理由は?
A. FreeならばSerif、Pro版ではBlackletterかな。
    理由? どれも自分の娘のように可愛いに決まっている。

RuneAssignMN_Serifのここがすごい!

RuneAssignMN_Serifの書体素材画像(のjpg出力)

Roman体のような綺麗なセリフ体を目指しました。
ルーン文字の直線からなる角ばった形状に、セリフがよく似合います。
他のルーン文字フリーフォントに、セリフを持っている書体は存在しません。RuneAMNだけです。


RuneAMN_Blackletter のここがすごい!

ブラックレター体の書体見本より。
魔法・魔術と強く印象づけられたルーン文字と、華美な装飾が特徴のブラックレター体。この組み合わせは非常に相性が良く、非日常を演出するのにこれ以上ない効果を発揮してくれるはずです。
もちろん、他のルーン文字フォントにはブラックレター体は存在しません。
(またかよ、と思いますが、実際ないです。(あったら恥ずかしいなこれ。))



RuneAMNシリーズフォント、今後のFuture

といっても、リリースされるのは夏かもしれないし、そうでないかもしれない、というくらいのものです。
また、Pro版は、購入済みユーザには何らかの優待をする予定です。無償アップグレードとか。

ブラックレター体のデザイン方法

RuneAMNとは直接関係ありませんが、私なりにブラックレター体フォントをデザインした際の知見を還元するつもりです。
そのうち図と言葉にまとめて、Pixivなどにアップロードすると思います。

フリーの文字列素材・フリーの魔法陣素材ほか

RuneAMNフォントが使いやすくなるよう、フォントを使って作成済みの素材を、フリーで公開するつもりです。
また、他にもいろいろと工夫をしようと考えています。
今のところは、サポートのTwitterアカウントにて、一日一個のペースで魔法陣素材を作り貯めているところです。



新しい書体!

フォント製品ですから、製品強化するにあたって、新しい書体の追加に勝るものはありません。
今のところ、複数のKnife書体(くさび形文字書体)の追加が決定しています。
各Knife書体は、デザイン済みで校正前。

デザイン作業中の、RuneAMN_KnifeC書体(仮)


他にも構想・デザイン中の新ルーン書体がありますが、それはまたいずれ紹介できればと思います。

総括:みなさんフォント作りませんか!

ビルドスクリプトも画像ファイルのすべて公開しています。
今も改善を続けています。
(たとえば今日、システムの一部をPython移植してリファクタしたので、機能追加しやすくなりました。これも、いずれ公開します。)
MNukazawa / daisy bellは、競合・ライバルを大歓迎しています。


プログラマの方へ:
FontForgeはすばらしいスクリプト環境(ネイティブorPython)を持っており、画像からのフォント生成を自動化できるすばらしいアプリケーションです。
フォント周りで活躍しているプログラマはあまりいないようなので、FontForge周りやSVG周りで暗躍して、もっとデザイナの方がフォントを作りやすい世界を作りませんか。

そして、プログラマでもフォントを作れます。私は作った。
1万文字を超える収録文字数の日本語フォントとか、むしろプログラマにしか(事実上)作れないと思います。私はまだ作ってないけど。
いかがですか。


デザイナの方へ:
今はGlyphs(Web上に日本語利用者の詳しい解説記事が見つからなかったけど)とか、Superpolator(同上)とか、すばらしい(私は使ったこと無いので...)フォントアプリがあるらしいので、フォント作りませんか。
そして、Glyphsとか、利用者の声をネットで訊いてみたいです。

あ、もし、非フォント系デザイナの方で、フォントを作りたい方がいれば、ロハで相談に乗ります。相談だけかもしれませんが。Twitterでお声掛けください。
あと、FontForgeは無料で、しかも親切な日本語マニュアルまでWeb上に無償公開されているのでオススメです。

今どきのFontForge(2014/12)

以上です。


明日の#LOVEFONT Advent Calendar 2014は、sada_hさんの「精興社書体について #LOVEFONT」です。よろしくお願いします。

jekyllをUbuntu14.04にインストール(github事前確認用)

まずはjekyllインストールまでの経緯について。

FontForge公式サイトは、FontForge日本語訳版ページを持っています。一部翻訳が古くなって英語版に追いついていない箇所もありますが、FontForgeの機能がしっかりとドキュメント化されており、基本的なフォント制作の作業中に困ることはまずありません。
また、日本語で読めるフォント基礎知識のまとめとして内容の充実度は飛び抜けています。FontForgeを直接使わないとしても、フォント制作を始めようという方はぜひ読むべき情報が詰まっています。

fontforge site on jekyll local HTTP server.

そのFontForge公式日本語訳ページなのですが、GitHub Pagesに移行してから文字化けするようになってしまったようです。
メーリングリストに文字化けの報告を上げたところ、『リポジトリアクセス権をあげるから、修正してプルリクエストを書いてみなよ!』と言われたため、いろいろ初めて含みな状態ではありますが、FontForge公式日本語訳ページの修正作業を行った次第です。

さて。
Github Pagesで内容の多いページや意匠にこだわったページを作るために、乱立している静的HTMLページ生成ツールを使うのが最近はスタンダードのようです。
FontForgeもその例に漏れず、Github Pagesに移転した現在の公式ページは、jekyllというRubyベースの生成ツールを使っています。
(日本語訳ページの部分は、普通の静的HTMLですが。)

FontoForge日本語訳ページの文字化けの原因は、ブラウザによるHTML文字コード自動判定機能の判定ミスです。遡れば、GitHub PagesのHTTPサーバ設定でデフォルト文字コードがUTF-8になっていることが原因にあるようで、最終的にはGitHub Pages上で再現と修正確認をすることになりました。
そのためあまりjekyllの導入に意味はなかったのですが、防備録としてここに残す次第です。


前置きが長かったようですが、どちらかというと本題は前置きの方です。
以下が、GitHub Pagesとjekyllについて。


実行環境はUbuntu14.04です。
Ruby環境の導入は『Redmine(非パッケージ)をUbuntu14.04にインストールする手順(暫定)』の際にすでに行っています。
Redmineを動かす際に、追加設定を行い、gemもいくつか導入しています。そのため、もしかしたら今回の手順で必要なものが漏れているかもしれません。あしからず。


現在のFontForgeのREADME.mdには、gemはjekyllのみ必要であるかのように書いてありますが、実際にはgithub-pagesというそのままな名前のgemも必要です。

私の環境では、gemのインストールにとても時間がかかりました(他の作業をして戻ってきても、まだ終わっていない)。

また、『gemの"jekyll/version"が足りない』的なエラーメッセージが出るのは、jekyll製のGithub Pagesサイトが現状でjekyll-2.4.0を要求しているからであり、最新のjekyll-2.5以降のgemが入っていると、このメッセージが出てエラーになる次第です。
以下、gemの導入。

sudo gem install jekyll
sudo gem install github-pages
sudo gem uninstall jekyll

Select gem to uninstall:
 1. jekyll-2.4.0
 2. jekyll-2.5.2
 3. All versions
> 2
Successfully uninstalled jekyll-2.5.2

最初からjekyllのバージョンを指定してインストールすれば良いと思います。

続いて、fontforge公式サイトを使って、jekyllの動作を確認。
(いえ、私にとってはfontforgeが主なのですが)。
git clone https://github.com/fontforge/fontforge.github.io.git
cd fontforge.github.io 
jekyll serve --watch

デフォルトのlocalhost:4000にてjekyllによるHTTPサーバの動作が確認できれば成功です。



なお、私的には本題であるfontforge公式サイトの修正は、無事にマージされました。
FontForge日本語訳版ページが問題なく閲覧できるのがその証拠です。
ルーン文字フリーフォントは、FontForgeとその公式サイトがなければ絶対に実現できませんでした。今回の作業で、少しでもFontForgeのオープンソースコミュニティに貢献の恩返しができたなら嬉しいです。

非表示のレイヤと描画されないパスを削除するIllustratorスクリプト

このスクリプトは、現在販売中のRuneAMN_Proフォントセットを制作していた時に作った。


 RuneAMN_Proフォント ブラックレター体
「シンボル」機能を活用してデザインされた


フォントを制作した際、文字のデザインも私が担当した。
ルーン文字の場合、最低でも26文字デザインする必要がある。文字はひとつずつ違う形を持っているが、文字をパーツに分けて見てみれば、複数の文字が同じ部品を共有している場合もある。

Illustratorで同じ形状のパスをいくつも置く場合に使われる「シンボル」機能は、そのまま使うとシンボルにした形状の位置決めが難しくなる。そこで、透明な長方形パスで囲ってシンボル化することで、位置決めしやすくするテクニックがよく使われる。

手製のフォント画像分割スクリプトと、フォント制作アプリケーションFontForgeの都合から、シンボルを解除して、透明なパスを削除する必要があった。
シンボル化の解除は、パスを全選択して、シンボル化機能の解除アイコンをクリックすれば良いので簡単に済む。
しかし、透明なパスの除去は、手作業ですれば面倒な作業になる。(字形を修正するために、何度も同じ作業が必要になるのでさらに大変。)


幸い、私はプログラマだった。すべてのパスをひとつずつチェックして、透明だったら削除するスクリプトを書くのは簡単だった。
そうして、以下の非表示レイヤと描画されないパスを削除するIllustratorスクリプトが誕生した。


/** 
 * 非表示のパス・レイヤを削除する。
 * Adobe Illustrator script(JavaScript).
 * Michinari.Nukazawa@gmail.com
 * License: BSD class2
 *
 * 既知の問題: 2回適用しないとすべての非表示パスが消えない場合がある。
 */


// 非表示のレイヤを削除する
layers = activeDocument.layers;
for (i=0; i<layers.length; i++)
{
 
if( !layers[i].visible ){
 
 
layers[i].locked = false;
 
 
// 非表示レイヤはremove()しようとするとエラー失敗する
 
 
layers[i].visible = true;
 
 
layers[i].remove();
 
}
}

pathObj = activeDocument.pathItems;
// 非表示のパスを削除する
for (i=0; i<pathObj.length; i++)
{
 

 
if( ((!pathObj[i].filled) && (!pathObj[i].stroked)) || pathObj[i].hidden ){
 
 
pathObj[i].locked = false;
 
 
pathObj[i].remove();
 
}
}


(このスクリプトは動作するが、古くなっている可能性がある。最新版は"delInvisiblePath.jsx"の名前で、RuneAMN_Proフォント 制作スクリプト公開ページにて公開されている。)

Illustratorのjsxスクリプトの使い方は、色々なサイトで説明されているので省略。

このスクリプトは、完全自動化を目指すことはせず、あくまで作業補助のために作ったので不出来ではあるけれど、きちんと機能はする。

BirdFontをビルド(Ubuntu14.04)



フォント作成アプリケーションのBirdFontをビルドしてみた。

といっても、特に面倒な手順はなかった。

ビルドしたBirdFontを起動したところ

ビルドして試そうと思ったのは、LibreGraphicsWorldで紹介されていたため。

 git clone https://git.gitorious.org/birdfont/birdfont.git
 cd birdfont/
 ./configure



までは公式サイトに記載された手順の通りに。


そして、指示される通りに必須パッケージを導入していく。

 sudo apt-get install valac
 sudo apt-get install libgtk-3-dev 
 sudo apt-get install libwebkitgtk-3.0-dev 
 sudo apt-get install libnotify-dev 
 sudo apt-get install libgee-dev 

ビルド手順にある「doit」って何のことだろうと思ったら、なんのことはないpython製のビルドツールらしい。
sudo apt-get install python-doit 
doit





そしてdoitでビルドをかけると、libgit2が足りないと言われる。git連携機能があるのだろうか。
 sudo apt-get install libgit2-dev
 doit


BirdFontの様子見がしたかっただけなので、管理者権限を使ってインストールするほどでもないと判断。
インストールせずに直接起動。
必要なライブラリパスなどを、添付されたスクリプトが適切に設定してくれる。
 ./birdfont.sh


本家には「翻訳はパッチが云々」と書いてあったのだけれど、面倒ばかりが予想されるのでパス。
(中途半端に翻訳パッチを当てると表示が崩れたり、ビルドが上手く行かなかったり。出たてのアプリだと、使い方を海外の情報から探すのに機能名で検索できないなど)

部分的に翻訳されているBirdFontのメニュー

しかしデフォルトで翻訳ファイルが入っていたようで、(中途半端に)翻訳された状態になっている。
Googleを駆使してBirdFontを使う方は
LANG=C ./birdfont.sh
して翻訳されていない状態で使うのが良いかと。


使い勝手のレビューは機会があれば。
FontForgeよりエディタ(ドローツール)部分が良ければ、開発中のRuneAssignMNシリーズ他で、SVGエディタとして採用を考えます。
スクリプトらしきものが見当たらないので、とりあえず乗り換え候補にはならないのですが。

オル・チキ文字のフリーフォントを公開しました(イラストandデザイン向け)

イラスト・デザイン用途に自由に使うことができます。

リリースしたオル・チキ文字フォントの書体見本

ダウンロードはGithubのOlChikiAssignMNプロジェクトページから。
あるいは、Boothアカウントのある方は、Pixiv Boothに出展予定ですのでそちらから。

本フォントにオル・チキ文字とラテン・アルファベットの対応関係は、オル・チキ文字のUnicode表に割り当てられた文字の名称を元にした、オリジナルです。

オル・チキ文字とラテン・アルファベットの対応表





 GithubのOlChikiAssignMNプロジェクトページには、本フォントの元画像ファイルと、ビルドスクリプトがすべて公開されています。
自分でOlCikiAssignMNフォントのビルドを試したり、オリジナルフォントを作成するのに使うこともできます。
( SVG画像の分割スクリプトは、今回のOlChiki文字フォントを作成するためだけの改造を施されており、汚い方法でSVG分割を行っているため、画像によっては成功しない場合があるのですが。)




次は、姉妹版のルーン文字フォントに、新しいバリエーションを追加しようと計画しており、現在鋭意作業中です。

Redmine(非パッケージ)をUbuntu14.04にインストールする手順(暫定)





整理すると、導入して稼働させたのは以下。
Redmine: 2.5-stable(SVNリポジトリ)版
OS: Ubuntu 14.04 amd64
LAMP選択: Ruby, Apache2, MySQL の組み合わせを採用
LAMP導入: Ubuntu14.04標準パッケージを使用
その他(Ruby gem他): Ubuntu14.04標準パッケージを使用


Redmine本体以外は、Ubuntuの標準パッケージを使うことにこだわった。
これは導入の面倒を可能な限り省くためである。
結果的に、Ubuntu14.04が出たばかりの時期であることもあり、バージョン齟齬による問題は起こらなかった。

反対に、 Ubuntuで提供されているRedmineの標準パッケージを使わなかったのは、Redmineの特定バージョン(新版など)を使いたくなった場合に、この導入手順が役に立つよう。
単純に、Ubuntuパッケージ版では最新でない2.4.2が提供されており、最新の2.5版が使いたかったことも理由である。

LAMPは、Rubyはともかく、ほかはApache2/MySQLとした。
Redmineは各種DB・サーバアプリケーションに対応しており、Ruby界隈は新技術との親和性が高いため、Apache2/MySQL以外のアプリケーションを使った手順を紹介している場合もある。
(もちろんこの場合、Apache2/MySQLに読み替えるか、そちらのアプリケーションを使うことになる)
これは、私が使い慣れていて、他に何か始めた際に邪魔にならないのがApache2/MySQLであるというだけの理由。
(今回nginxを導入したとして、後でApache2と共存させるのに頭を悩ませるようなことを避けたかった。)

タイトルの"(暫定)"は、『とりあえず動いていますよ』という意味で、導入手順の最後に、Redmineをサブディレクトリに導入しておきながらApacheの設定ファイルには"DocumentRoot /var/www/html/redmine"と指定する行儀の悪い設定ファイルを書いているため。
たぶん、調べればすぐ解決する問題だが、操作に慣れる目的で導入した、自分でしか使わないRedmineなので、次にインストールする時か、実際に問題が表面化するまでは放置することとした。

Redmine公式サイトのインストール手順を参考にした。
サブディレクトリへのRedmine導入は、公式インストール手順では『2.』として説明されている。

なお、本記事はRedmine導入作業中に書いたメモを元にしている。
そのため、十分に整理・説明されていない。
クリーンな環境での確認もしていないので、抜けている箇所があるかもしれない。
誰か、綺麗な手順に書きなおすか、導入スクリプトにまとめてくれると嬉しく思う。

###### 依存アプリケーションのインストール

## 標準パッケージ(apt)
sudo apt-get install ruby2.0 mysql-server apache2 -y

その他、gemなどのパッケージはあとで導入。

###### Redmineのダウンロードと配置

公式サイト(http://redmine.jp/download/)に書いてあるとおりに、SVNリポジトリから2.5版を取得

sudo apt-get install subversion -y
cd /var/www/html
svn checkout http://svn.redmine.org/redmine/branches/2.5-stable redmine


###### mysqlの設定

テーブルは自動生成? 設定する必要はないらしい。

## UTF-8

各セクションに下記文字コード設定を追記
詳しくは公式インストール手順にて。

vim /etc/my.cnf

[mysqld]
character-set-server=utf8
[mysql]
default-character-set=utf8


sudo service mysql restart

公式インストール手順の通りにUTF-8設定になったことを確認
mysql -u root -p
mysql> show variables like 'character_set%';



## redmineのmysqlユーザを作成

パスワードは適切に設定する。

mysql -u root -p
mysql> create database db_redmine default character set utf8;
mysql> grant all on db_redmine.* to user_redmine@localhost identified by 'パスワード';
mysql> flush privileges;
mysql> exit;


###### Redmine設定ファイル

## データベース設定

vim redmine/config/database.yml


production:
  adapter: mysql2
  database: db_redmine
  host: localhost
  username: user_redmine
  password: ********
  encoding: utf8


## Redmine設定

vim redmine/config/configuration.yml

production:
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "localhost"
      port: 25
      domain: "redmine.example.com"
      # localhostのSMTPサーバを使用する場合

  rmagick_font_path: /usr/share/fonts/truetype/fonts-japanese-gothic.ttf

database_cipher_key: ******



###### 追加のアプリケーション

gem -> bundler -> 各種パッケージ
Redmineに添付されているbundlerインストール設定ファイルを使って、必要なパッケージを導入する。

sudo gem install bundler
bundle install --without development test


下記エラーが出るので、必要なパッケージをAptでUbuntuに導入していくことで対応。
##

An error occurred while installing json (1.8.1), and Bundler cannot continue.
Make sure that `gem install json -v '1.8.1'` succeeds before bundling.


とりあえずこちらに従い、
sudo apt-get install ruby-dev -y

##

An error occurred while installing mysql2 (0.3.16), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.3.16'` succeeds before bundling.


sudo apt-get install libmysqlclient-dev -y

##

An error occurred while installing rmagick (2.13.3), and Bundler cannot
continue.
Make sure that `gem install rmagick -v '2.13.3'` succeeds before bundling.


こちらに従い、
sudo apt-get install libmagick++-dev -y

とりあえず、
"Your bundle is complete!"
と出ればOK。(bug reportについてメッセージが出ましたが。)


#### Redmineの初期設定とデータベースのテーブル作成

bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate


#### Passengerのインストールと(apacheへの)設定

Passengerを導入する。
sudo gem install passenger --no-rdoc --no-ri
// 実際には下記のコマンドを使ったのだったか、あるいは両方必要だった気もする。
sudo apt-get install libapache2-mod-passenger -y

導入後、インストールとは別にビルドコマンドを呼ぶ必要があったらしい。
(https://hirooka.pro/?p=6904)
passenger-install-apache2-module
この際、curl-configなどが足りないと言われるので、
sudo apt-get install apache-dev libcurl4-gnutils-dev -y
導入。

passenger-install-apache2-module --snippet
にて、apacheに設定すべき内容を確認。
コマンドで直接、Passenger設定をApache設定ファイルに書き込む。
sudo sh -c " passenger-install-apache2-module --snippet > /etc/apache2/conf-available/passenger.conf"

sudo service apache2 restart


######## 起動

導入方法および導入先ディレクトリは、『パターン2: サブディレクトリでRedmineを実行』を採用。
sudo vim /etc/apache2/conf-enabled/passenger.conf


RackBaseURI /redmine

LoadModule passenger_module /var/lib/gems/1.9.1/gems/passenger-4.0.49/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
  PassengerRoot /var/lib/gems/1.9.1/gems/passenger-4.0.49
  PassengerDefaultRuby /usr/bin/ruby1.9.1
</IfModule>


として、RackBaseURIさえ追記すれば終了のはずだったのだが。

######apache2リスタート時のエラーメッセージ


AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message

こちらにある通り、
sudo gedit /etc/apache2/httpd.conf
ServerName localhost』を追記
で解決。




### 『redmineがディレクトリで見える』問題



 passenger-status
が動いていなかった。

sudo passenger-status

Version : 4.0.49
Date    : 2014-08-23 16:56:42 +0900
Instance: 5702
----------- General information -----------
Max pool size : 6
Processes     : 0
Requests in top-level queue : 0

----------- Application groups -----------



とりあえずconf-enabled/passenger.confに設定を書いて解決。
追記

   PassengerAppRoot /var/www/html/redmine
   DocumentRoot /var/www/html/redmine
   RackBaseURI /redmine
 』
コメントアウト

 #LoadModule passenger_module /var/lib/gems/1.9.1/gems/passenger-4.0.49/build    out/apache2/mod_passenger.so






Passenger動作確認。

sudo passenger-status 

Version : 4.0.49
Date    : 2014-08-23 18:11:16 +0900
Instance: 10272
----------- General information -----------
Max pool size : 6
Processes     : 2
Requests in top-level queue : 0

----------- Application groups -----------
/var/www/html/redmine#default:
  App root: /var/www/html/redmine
  Requests in queue: 0
  * PID: 10393   Sessions: 0       Processed: 7       Uptime: 32s
    CPU: 3%      Memory  : 48M     Last used: 8s ago
  * PID: 10401   Sessions: 0       Processed: 3       Uptime: 31s
    CPU: 2%      Memory  : 41M     Last used: 8s ago





Github上のmasterブランチを削除


Githubでgh-pagesを使う場合、master/gh-pagesブランチの同期をとる問題が発生しますが、最も簡単な対応は、masterブランチを削除してしまうことです。

そういうわけで、すでにGithub上に上げてあったmasterブランチを削除することにしたのですが、ちょっと手間取ってしまったので防備録。

前提として、gh-pagesブランチの作成とGithubへのプッシュは終了しているものとします。
(このあたりの手順は防備録がこちらにまとめてあります。)

まず、ローカルでmasterブランチを削除します。
git checkout gh-pages
git branch -d master

リモートブランチの削除に使うコマンド自体は、復習 Git: GitHub のブランチを削除する.に書かれている、
git push origin :master

でOKです。
ただし、何もせずただこのコマンドを打っても、以下のエラーが発生する場合があります。
 (エラーメッセージは抜粋)
remote: error: refusing to delete the current branch: refs/heads/master
 ! [remote rejected] master (deletion of the current branch prohibited)

これは、Github上のカレントのリポジトリがmasterであるため、これを削除することはできない、というエラーメッセージです。
(ローカルでもmasterを削除する前にgh-pagesをチェックアウトしている。)
Github上でリポジトリ変更作業を行うには、対象プロジェクトのGithubページから"Setting"をクリックし、Settings項目のDefault Branchをgh-pagesに切り替えるだけです。

Githubのプロジェクト上のSettings画面

フリーのルーン文字フォント集を公開しました

フリーフォントをリリースしました。
複数個のルーン文字フォントで、名称は RuneAssignMN シリーズです。

(update:2015/03/05アップデートしました。)  
(update:2015/07/03アップデートしました。) 
 
RuneAssignMNフォント各種サンプル

イラスト制作向けに特化したルーン文字のフォントで、書体が3種類あり、・イラスト/デザインで自己責任を前提に自由に使えるライセンス
・ルーン文字をパソコンで入力するための面倒な作業が不要
となるよう作られています。

また、サンプルページも用意してあります。

ダウンロード

ダウンロードはSourceForgeのdaisy_bell_フリーフォント公式配布ページからどうぞ。

あるいはBOOTHアカウントをお持ちの方はBOOTHのページからダウンロード可能です。
あなたが、フォント制作に興味のあるLinuxユーザであるならば、フォント制作のために作った素材画像からビルドスクリプトまで、プロジェクトすべてをフリーなライセンスで公開しています。GithubのRuneAssignMN Series Fontsプロジェクトページから、ダウンロードすることが可能です。

使い方

ルーン文字を、ラテン・アルファベットのA~zに割り当ててあります。
自分で英文・ローマ字文章を打ち込むことでルーン文字の文章を描くことができます。
また、フリーの英文を用意してこのフォントを適用するだけで、不自然な繰り返しのないルーン文字で書かれた長文を用意することができます。

Lorem ipsumにRuneAssignフォントを適用した例

割り当て表(フォントに添付してある)

今後の予定

あくまで予定ですが
・フォント作成した際の手順や、制作中に得たノウハウを記事にする
・さらに装飾性が高い書体を増やす
・Gimp2.8環境で、記号がデフォルトフォントにより描画されてしまう問題を解消する
・ルーン文字のユニコード領域を埋める(これは要望があれば)

2014/09追記:姉妹版フォント「OlChikiAssignMN_Series_Font」をリリースしました。

Ubuntu14.04で使える画像ビューア一覧


アニメのコマを静止画で見るために、動画データを静止画へ変換しました。
連続しているアニメのコマを見るのですから、「コマ送り」よろしくパラパラ漫画のように画像を次々と開いて見ていきたいのですが、Ubuntu標準の画像ビューアで見ると、次の画像へ送る処理が遅い。
そこで、高速な画像ビューアを探すことにしました。

なお、対象画像ファイルは、「『よくわかる現代魔法』ノンテロップOP サイズ:1920 x 1080」を、 ffmpeg ではなく avconv コマンドで静止画に吐き出したフルHDのjpg画像です。


以下、チェック項目の説明。

・「透過対応」は、画像の透過部分を市松背景で表示することを指しています。
透過付き画像が開けないという意味ではありません。
透過対応のテストはSVGファイル形式で行いました。

・「ドロップ対応」は、画像ファイルをビューアのウィンドウにドロップして開けることを指します。
たまにWindowsの標準画像ビューアを使うのですが、いつも手癖で画像をドロップしてから開かないことを思い出して不便に感じる次第です。
(リサイズ済みの画像ビューアと同じサイズで画像が開けると、ディスプレイ不動産を荒さないので便利。)

・「表示カスタマイズ」は、限られたディスプレイ不動産を画像ビューアが占めるにあたって、どれだけ画像自体の占有率を上げられるかを示します。
画像ビューア自体のパーツが邪魔になりディスプレイの縦サイズを目一杯使えなくなるアプリケーションは、UIに重大な欠陥を持っていると思います。
(画像処理はGIMPでやるのでフィルタ機能のアイコンなどがいらない、という私の都合によるのかもしれませんが)


なお、文中で"重い"という言葉を使ってしまうかもしれませんが、すべて"遅い"に読み替えてください。
あくまで画像送りの高速さを求めており、メモリ効率は無視しています。
(私の使っているデスクトップはメモリを16GB積んでいるので、足りなくなったりしないと思います)
極端な話、今回の用途では、画像ビューアは画像ファイルを読めるだけ全部先読みしてメモリは使えるだけ使ってしまって良いと思っています。


eog(Eye of Gnome)





透過: 対応(市松模様)
ドロップ対応: 可
表示カスタマイズ: 可(タイトルバーと画像のみにできる・下部にギャラリーを表示可能)
eog
 
Ubuntuの標準画像ビューアです。なぜか遅い。
画像の送りが遅かったため、最初はフルHD画像を50%に縮小。(1980x1080 ->960x540)
さらに画像ファイルをRAMディスク(tmpfs)に載せたのですが、効果はありませんでした。
今回の画像ビューア探しを始めることになってしまいました。

とはいえ、元動画の静止画を連続で見るような用途でなければ遅延は気にならないのではないかと思います。

「アドオンが使用可能」 らしいのですが、なぜかファイルリネーム以上の便利機能を見かけることがありません。

 Mirage




透過: 対応(市松模様)
ドロップ対応: 可
表示カスタマイズ: 可(タイトルバーと画像のみにできる)
Mirage
(画像は「『よくわかる現代魔法』©桜坂洋・宮下未紀/集英社・「現代魔法」製作委員会」より)


一番最初に試した画像ビューアです。

フルHD画像を開くのにeogの半分くらいの時間で済みます。(連打するとさすがにカクつく)
だいたい、キーを押して、もう1キー押すくらいの、一瞬の間隔を置いて開く。

後述のShotwellはUIのカスタマイズと使い勝手が少し狭いので、本当に満足できない場合を除けば、高速なeogの替えアプリケーションとして最良かと思います。







CBR Pager




透過: 不明
ドロップ対応: 不明
表示カスタマイズ: 不明

CBR Pager(+file dialog)

コミックビューアも試してみよう、と思い立ち、目に付いたこのCBRをインストールしてみたのですが。
起動すると、操作パネルがウィンドウの上に浮いているUIがお出迎え。
画像を開こうとするのですが、ドロップには非対応。
仕方がないので「開く」ダイアログを起動すると、見慣れないファイル選択ダイアログが開く。
(古いLinuxアプリケーションには、こういうUIを持つものもあった気がします。)
全体的に、「cbrってもしかしてLISP言語のcdrの間違いなのではないだろうか」と思わせる、初心者お断りな風格。
しかも、デジカメで撮影した .JPG 画像が開けない。

 

Preview 




透過: 不明
ドロップ対応: 不明
表示カスタマイズ: 不明

Preview(+file dialog)


名前:「プレビュー」(わざわざカタカナにされている)
説明:「画像ビューアー」
という、いかにも使いやすそうなシンプルな名前と説明に騙されるなかれ。

CBRよりさらに見慣れない濃い灰色のUIがお出迎え。
画像ビューと思われるウィンドウとは別に、ディスプレイ左上に独自メニューバーが登場。
そこからファイルを開こうとすると、「左に親ディレクトリの一覧、右に選択したディレクトリ内のファイル一覧」というファイル選択ダイアログが登場。
(なお、ダイアログを横に伸ばすと、さらに階層をさかのぼって親ディレクトリが次々表示されるらしい。)
そして、このアプリケーションもデジカメで撮影したJPG画像が開けないようです。
閉じようとしても、画面右下に不気味な目玉アイコンが残ることがあり、このアイコンからなんとかして独自メニューバーを引きずり出し、「Quit」を押さないとアプリを終了させて目玉アイコンを消すことができません。
CBRに続いてこのアプリケーションを開いたので、「もしかしたら画像ビューアでないアプリケーションを間違ってインストールしてしまったのではないか?」と疑心暗鬼になり、Ubuntuソフトウェアセンターで詳細を確認することにしました。

英語の説明文には、" GNUstep"や"NeXTSTEP spirit"の文字が踊っており、ホームディレクトリに「GNUStep」ディレクトリを作った犯人がついでに判明。
意外なところで過去の遺産と巡り会えるものです。
Ubuntuソフトウェアセンターは、このアプリに限って言えば、積極的に初心者を騙しにいっている気すらします。
不気味な目玉アイコンの時点で気づけよ、と言われたらそれまでですが。


  GPicView


 

透過: 非対応(白背景)
ドロップ対応: 可
表示カスタマイズ: 不可
GPicView

他の画像アプリケーションとちがい、起動時にホームディレクトリの先頭にある画像を自動で開くようです。
その他には説明するところがないくらいにシンプルです。操作可能なのは、ウィンドウ下部にある操作アイコンのみで、メニューバーすら存在しません。下部の操作アイコンを消す方法はなし。(全画面表示では消える)
アイコンを消せないとなると誤操作が怖いですが、勝手に保存されたりはしませんし、削除の前には確認ダイアログが出るので大丈夫かと思います。
あまり意味のない話ではありますが、インストール後はこのアプリは「イメージビューワ」などとしか表示されません。また「このアプリについて」的なダイアログも存在しないため、これが「GPicView」なのかどうかわからなくなったりします。
ウィンドウタイトル部に画像の元サイズと拡大率が表示されるため、画像のサイズを簡単に知ることができます。




Shotwell




透過: 不明(SVGファイル非対応)
ドロップ対応: 不可
表示カスタマイズ: 不可
Shotwell(+アプリケーションAboutダイアログ)
(画像は「『よくわかる現代魔法』©桜坂洋・宮下未紀/集英社・「現代魔法」製作委員会」より)


実は最初、「Shotwellははじめから選外」にするつもりでした。
というのも、昔のUbuntu環境でデジカメをShotwellで開いたときに、「UIが使いづらくてしかも遅い」というイメージがついていたからです。
ところが、気まぐれにShotwellでフルHD画像を開いたところ、ほぼ遅延なしで開け、画像を送ることができると判明。
(ただし、さすがに送りキーを連打すると、何回かキー押下を無視します。)
これでドロップ対応していたらよかったのですが、残念ながら対応していませんでした。
また、UIのカスタマイズ項目は見当たりませんでした。ウィンドウ下にある操作アイコンを非表示にできません。

とはいえ、Ubuntuに標準搭載されていて、遅延をほぼ感じないほど高速、連続で送っても固まらないので、今回のように「フルHD動画を1コマずつキャプチャしたものを見る」などの「大容量画像を高速に前後に送って見る」ようなときには、最もストレスが少ないと思われます。


雑感ほか

結論:
高速な画像ビューアに切り替えたいならMirageがおすすめ。
使いづらくてもなお速度を求めるならば、デフォルト搭載されているShotwellが速い。
あと、マンガビューアは大人しくComixにしておきましょう(無関係)。

デジカメ写真整理を目的とした写真ビューアに対して、UIの出来が悪くて遅いという印象を持っていたのですが、どうやらアプリケーションのバージョンアップによって現在は良くなっている場合もあるようです。

一覧と言いつつ、アプリケーション数が少ない上にうち2件は「開けなかった」というのはどうかと思いますが...自分の用途に合うアプリは見つかったので、とりあえず探索終了。



なお、スクリーンショットに使った画像の一部は、
「『よくわかる現代魔法』©桜坂洋・宮下未紀/集英社・「現代魔法」製作委員会」
より。
それ以外は本ブログ筆者の撮影した写真を使っています。

『よくわかる現代魔法』が写ったものを除く、このページのアイコンおよびスクリーンショットは、自由に転用していただいて構いません。
(もちろん、転載者が自分の責任で使用してください。私は一切の義務と責任を負わないこととします。私が(取った写真に)許諾できる範囲で使用を自由にするだけです。アイコンおよびアプリケーション自体の権利は各ソフトウェア作者やプロジェクトが持っていることを忘れないでください。それと桜坂先生AYNIKの2巻もいいですが現代魔法の7巻は(略) )

そして、誰かアプリケーション数をもっと増やして、Ubuntu画像ビューア一覧を作ってください。
真面目に速度計測したレビューなどが読みたいです。
(自分で調べる面倒がなくなって助かります。)

このあたりは、以前書いた「Ubuntu13.04で使える動画編集ソフト一覧」と同じです。

フォント自作入門(2) グリフデザインの手順


このシリーズではフォントファイルを作る手順を解説します。
そしてこのページでは、「どのようにフォントをデザインするか」を中心に解説します。

ターゲットは、前記事で解説した「ラテン・アルファベット 基本字」の「アウトラインフォント」です。


前提となる技術

グリフの作成は、デザインおよびイラストレーションの工程です。
よって、絵を描いた経験があれば役に立ちます。

また、今回は「アウトラインフォント」を作成します。
「アウトラインフォント」制作は「ベクタ画像を描く」作業です。
IllustraterかInkScapeなどのドロー系ソフトの使用経験があると比較的スムーズに進みます。
経験がない場合、アウトラインフォントの制作のハードルは上がってしまいます。


グリフをデザインする

 グリフデザインの開始地点は、おおまかに2種類に分類されます。

1. 使用目的・コンセプトだけが決まっているが、具体的な形状がない。
『髭の生えた老齢のマスターが経営する、オリジナルブレンドのコーヒーが自慢の喫茶店に置かれた、古いメニュー表に使われているフォントを作りたい。メニューは厚手の紙製表紙でできている。見開きのメニューをひらくと内張りの紙は茶色に変色しているが、コーヒーの跳ね跡はほとんどなく、馴染みの客達がメニューを大事に扱ってきたことがわかる。
このフォントはイラストに使用される。半開きのメニュー表をキャラクタが持っていても、メニューの「Coffee」という文字が読めるほど可読性が高く、縮小されてもつぶれにくい』
というところまで決まっているのだが、ではそのフォントのAの頂点に左右の出っ張りが出ているかどうかというと、それはまったく決まっていないので、グリフとして絵に描くことができない。

2. カッコイイ"R"のデザインだけが完成している。
あとは同じデザインを"A~z"の52文字で繰り返せばいい。

でも自分のRの特徴が「人に説明できるほどはっきり」していないので、残りの文字すべてに、グリフ"R"の仲間に見えるデザインを最初から考えてやらなければならない。

あるいは
3.コンセプトすらない
という段階かもしれません。


ともかく、52個のグリフに共通のアイデンティティを持たせ、統一感を与えるには、作成するフォントのデザインに共通する特徴をはっきりさせる必要があります。
「このフォントはかっこいい」
ではなく、
「グリフ中の横線はすべて、マイナス30度に傾斜している」
という、具体性のあるデザインのルールを決める必要があるのです。
特徴を決めておけば、グリフデザインをスムーズに進められるようになります。

では、自作グリフに目的通りの印象をまとわせるためには、どんな形状を与えればよいのか。
グリフを個性的にする特徴には、どのようなものがあるのか。
その参考になるのが、既存フォントの分類方法です。


フォントを特徴により分類する

ノンデザイナーズ・デザインブックにある分類は覚えておくとよいです。
自分が何を作ろうとしているのか把握できます。

とりあえず、フォントにおける「セリフ」の意味は覚えておきましょう。

詳しくは検索するか、あるいは実際にノンデザイナーズ・デザインブックを読んでください。
Oldstyle
Modern
Slab selif
Sans selif
Script
  筆記体、手書き風、筆書き風
Decorative
  イラストっぽい。文字らしい外見をしていない。
  そもそも文字でないor読めないことすらある。


作ろうとしているのはたぶん、* SelifかScriptかDecorativeだと思います。
アニメに登場するオリジナル言語のフォントは、極端なDecorativeだと言えるかもしれません。
(参考:Madoca Runeとその派生StarTrekに登場する各文明言語など。)

とはいえ、フォントの分類は厳密なものではなく、いくつかの特徴を兼ね備えたフォントも存在します。
セリフの付いたScript体、のようなフォントも作ることができるわけです。
(装飾過剰にするとDecorative化していきますが。)


フォントの分類は、まだアイデアのない段階で参考にすると、
「落ち着いた喫茶店のメニュー表に使えるフォントが欲しい」
というあいまいなアイデアを、
・「Slab selifのような極太で太さが一定のフォントは、求めているものではないな」
・「Oldstyleのような横線が斜めで細いフォントが、白い髭の生えたマスタのいる喫茶店のイメージにピッタリだ」
・「セリフ付きのフォントにすると、作品に使う画像内で目立ちすぎるかもしれないな。サイズの縮小にも弱そうだ」

などと考えながら、フォント種別の特徴を取捨選択していけば、求めるフォントのデザインを具体化することができます。


Script(筆記体風)は難しい

・筆記体が持つ自然な線太さをドロー系ツールで再現するのは(初心者には)難しい
・前後の文字がつながるScript体を作るには、「プロポーショナル」フォントを制作するための深い知識と配慮が要る

プロポーショナルフォントと縦横比

・アルファベットのタテヨコ比は2:1(半角)
・等幅(モノスペース)フォント
・可変幅(プロポーショナル)は、見た目をよくできるが、幅を作業量が増えるため初心者向きでない



以上、まとめとして、
・既存フォントの特徴リストを知っていると、フォントデザインが楽になる
・前後の文字が繋がる形状のScriptは、フォント作成の深い知識が必要なのでオススメしない
・初心者がグリフをデザインするなら、半角のモノスペース



グリフのひな形・プロトタイプ文字列をデザインする


フォントデザインでは、最初にすべてのグリフのひな形となるプロトタイプを作成します。
プロトタイプは、フォントが描き出すグリフを想像して描く、検討のためのイラスト・デッサンです。
プロトタイプの段階では、ラテン・アルファベット52字をすべて描く必要はありません。


プロトタイプに使う文字列は、そのフォントがよく使われる文字列がわかっている場合、それを使うべきです。
作品タイトル・登場キャラクタ名などがそれに該当します。

また、特徴的な形状を持つ文字を含む文字列も、プロトタイプ文字列の候補になります。
ベースラインの下に突き出るグリフとなる"y" "g"が含まれる文字列などです。

また、最も重要なのは、下で説明する「出現頻度」です。「作品タイトル」はこの出現頻度を利用したプロトタイプ文字列選択の類例であると言えます。

 たとえば、MagiCursiveプロジェクトでは、作品の英語版タイトルである
「Puella Magi Madoka Magica」(特に最初の"Puella")
をひな形のターゲット文字列として採用しました。
実際に、「Puella」を最初にMadokaRuneで書き出してから、プロトタイプ作成を開始しています。


プロトタイプ文字列が思いつかない場合、"A Very" "The Velocity" から始めればよいと思います。


出現頻度

人間の使う言葉において、すべての文字が等しく使用されるわけではありません。
文字には出現頻度があります。
このことは、プロトタイプ文字列の選定をふくむ、グリフデザインのすべての工程において重要です。
英語の場合、単語では"the"、文字では"e"が他に抜きん出て多く使用されることが知られています。つまり、ラテン・アルファベットのフォントで"e"のグリフデザインが少し悪かっただけでも、すべてが台無しになります。
逆に、''q"のデザインで大失敗をしても、多くの場合は表示すらされないため問題になりません。
ターゲット作品のあるフォントでも、プロトタイプ文字列に悩んだら、出現頻度の高い文字を含む文字列を選択するとよいでしょう。


グリフの生産

グリフの本デザイン

すべてのグリフを描くことにはなりますが、出現頻度の高いフォントに労力を傾けましょう。

フォントファイル作成アプリケーションであるFontForgeに取り込める形式で、グリフを描いたファイルを用意する必要があります。FontForgeに取り込むベクタ形式ファイルとしてはsvgが最適です。また、svgに変換可能であるため、AI形式でベクタに起こしても大丈夫です。

最初からFontForge上でデザインする・FontForge上でラスタからベクタに起こすやり方もあるのですが、残念ながらFontForgeはドロー系アプリとしてはけっして使いやすくありません。

よって、慣れるまでは、グリフひとつごとに
1. ラスタでデザイン
2. ドロー系アプリでトレスしてsvgのベクタ形式に起こす
3. FontForgeに取り込む
という作業手順を踏んだほうがよいです。

また、「svgのベクタ形式」 も、作り方によってFontForgeへの取り込み作業の手間が大きく違います。(そのあたりの話はまた次回)

グリフのデザイン中は、他の文字のグリフを隣に並べて作業すると、グリフのサイズがちぐはぐになることを防ぐことができます。


まとめ







グリフデザインは
1. 少ない文字でグリフの形状を決める
2. 全文字のグリフを量産する
3. ドロー系ツールで清書する
の手順で進む

・作りたいフォントの形状の特徴をはっきりさせる
 (ex.「セリフ」はついているか?)
・Script(筆記体風)は「つなぎ」が難しいので、初心者が挑戦するのはおすすめしない
・等幅(モノスペース)
・プロトタイプは手書きでターゲット文字列から作り始める・ラテン・アルファベット のグリフの縦横比は1:2
・グリフは、とりあえずIllustraterかInkScapeでベクタ画像ファイルとして用意する
 

次回はグリフの集合(svgラスタ形式のグリフファイル)をフォントファイルに変換・出力する方法を説明します。

2014/09追記:
フォントの作り方を説明するより先にルーン文字フォントのリリースが先になってしまいました。
というか、フォント作ったことのない人間が解説するよりはリリースがあったほうが良いので、ある意味これでよかったのかもしれませんが。
友人にフォントの作り方を説明する必要もあるので、なんにせよ「自作フォントの作り方」は、いずれ続きを書きます。

TIGORA(ティゴラ)のトレッキング シューズ

 TIGORA(ティゴラ)の トレッキング シューズを買いました。 メインの靴がアシックスウォーキングで街歩き用なのですが、これまではこれで高尾山などの軽い山も登っていました。 今回、靴底があまりに摩耗したこともあってアシックスウォーキングを買い替えたのですが、ついでに消耗が激...