Edited at
Quad incDay 18

JSでカーニングエンジンを作ってみる 1回目

More than 3 years have passed since last update.


目的

「HTMLのカーニングはどうしようもない」というのが一般的だとおもいますが、日頃からグラフィックデザイナー陣からの不満の声もあり、社内で利用するものを用意することになりました。


ゴール

この記事だけでは完結しないので、まずはどれぐらいのものが実現できるか探っていきます。


実装方法

単純に思いつくやり方は、テキストを全てspanタグでコーディングしletter-spacingとmarginで調整していくやり方かと思います。今回もこれでやります。

カーニングテーブルにカーニング値を持たせ、前後の文字を判定する。このテーブルはフォントごとに必要となります。今回のフォントはヒラギノで実験します。


注意

パフォーマンスチューニングはしばらくやりません。実現度を探る方向で進めます。

コードも殴り書きです...すみません。


テキストをspanで囲む

実際に使う場合は、HTMLからテキストを抜き取り、span入りのもので置き換える作業が発生しますが、とりあえずはすでにテキストを抜き取ったという前提から恥じます。

文字詰めするサンプルテキスト (qiitaトップから適当にとりました)

var str = "「プログラミングち知識」を共有しよう。SPA開発(OnsenUI)でちょっとだけ可読性を意識する!";

<span>タグで囲む処理

function wrapSpan(str){

var array = str.split('');
var output = "";
for(var i = 0; i < array.length; ++i){
var c = array[i];
output += '<span>' + c + "</span>";
}
return output;
}


文字のカーニングテーブルを作る

適当にカーニングする対象に値を設定します。サンプルなので適当にピックアップしました。

var kerningTable = {

'' : '0.5em',
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : '-0.5em',
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'S' : 0,
'P' : 0,
'A' : 0,
'' : 0,
'' : '-0.1em',
'' : 0,
'O' : 0,
's' : 0,
'e' : 0,
'n' : 0,
'U' : 0,
'I' : 0,
'' : '-0.5em',
'': 0,
'' : '-0.1em',
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'' : 0,
'!' : 0
};


行頭のカーニング

とりあえず、行頭の"「"用の処理を追加します。

for(var i = 0; i < array.length; ++i){

var c = array[i];
var value = kerningTable[c];

var style = "letter-spacing: " + value + '; ';
if( i == 0 && c == '' ){
style += 'margin: -0.5em'
}
output += '<span style="'+ style +'">' + c + "</span>";
}

ここまでで一旦HTMLを出力してみます。

var html = wrapSpan(str);

document.write('<h1>'+html+'</h1>');

ブラウザで確認すると

カーニング前

スクリーンショット 2015-12-18 19.18.27.png

カーニング後

スクリーンショット 2015-12-18 19.17.19.png

十分利用できそうですね。今回の実装では特定の文字の後ろを詰めるだけでした。

どの文字の場合も同じ詰まり方をします。その辺りの実装を次に考えたいと思います。