デカ文字A4ジェネレータというのを書いた。

https://github.com/cho45/dekaimoji-a4

原寸印刷について

いくつか方法があるがピンヘッダのレイアウトを実寸で印刷するツールを書くときに検討した通り、PDF をつくるのが現状では確実と思われる。

その上で、プレビューとの兼ね合いを考えるとさらにいくつか方法がある。

canvas で作った画像を PDF に貼る

「画像で作ってPDFに貼りつける」という方法は JS に限らず安定して確実な出力ができる。

JS の場合でもスムーズにプレビューできるし出力も簡単。ただし出力サイズが大きい場合、メモリが足りなくなることがある。

また、テキストの選択はできなくなる。

PDF オンリー PDF プレビュー

PDF オンリーの場合、ブラウザーがPDFのインライン表示に対応していれば、iframe でプレビューができる。昨今、だいたいのブラウザーで実はpdfが組み込み表示可能なので案外いける。ただしスマフォでは未対応。

2D Context の API にあわせる

jsPDF の場合、単純な図形化なら、2D Context と APIをあわせることができるので、canvasプレビュー、pdf出力がスムーズにできそう。ただしこれはテキストレンダリングしたくなった時点で確実に破綻すると思われる。

  1. トップ
  2. tech
  3. デカい文字をA4で分割して印刷するツールをJSで書いた

[tech] デカい文字をA4で分割して印刷するツールをJSで書いた | Sat, Mar 7. 2015 - 氾濫原 では、実寸サイズを扱うので、多くの場所で mm や cm やら pt などの単位で数値を書きたくなる。

いろんな方法

mm を係数にして毎回乗算する方法

var mm = dpi / 25.4;

10*mm

mm を係数にして毎回除算する方法

var mm = 25.4 / dpi;

10/mm

乗算の逆。

変換を関数にする方法

function mm (num) { ... }

mm(10)

Number のプロトタイプ拡張

Number.prototype.mm = function () { ... };

10..mm()


しかし JSLint とかは 10..mm みたいな呼びかたをすると怒る。

Number のアクセサディスクリプタ

単純なプロトタイプ拡張と比べ、括弧がいらない。

10..mm
function setDPI (dpi) {
	var dpmm = dpi / 25.4;
	var pt = dpi / 72;
	var units = {
		'in' : dpi,
		'pt' : pt,
		'mm' : dpmm,
		'cm' : dpmm * 10,
		'm' : dpmm * 1000
	};

	for (var unit in units) if (units.hasOwnProperty(unit)) (function (factor) {
		Object.defineProperty(Number.prototype, unit, {
			get: function () {
				return this.valueOf() * factor;
			}
		});
	})(units[unit]);
}

setDPI(150);

console.log(10..mm);
console.log(10..cm);

しかし JSLint とかは 10..mm みたいな呼びかたをすると怒る。

アクロバティックな方法

'10 mm'

とかを数値に変換する形

var UnitConverter = function () { this.init.apply(this, arguments) };
UnitConverter.prototype = {
	init : function (opts) {
		if (!opts) opts = {};
		this.setDPI(opts.dpi || 96);
	},

	setDPI : function (dpi) {
		this.dpi = dpi;
		var dpmm = dpi / 25.4;
		var pt = dpi / 72;
		this.units = {
			'in' : dpi,
			'pt' : pt,
			'mm' : dpmm,
			'cm' : dpmm * 10,
			'm' : dpmm * 1000
		};

		var unitNames = [];
		for (var key in this.units) if (this.units.hasOwnProperty(key)) {
			unitNames.push(key);
		}

		this.re = new RegExp('([0-9.]+) (' + unitNames.join('|') + ')');
	},

	unit : function (string) {
		if (string.match(new RegExp('^' + this.re.source + '$'))) {
			return +RegExp.$1 * this.units[RegExp.$2];
		} else {
			return null;
		}
	},

	context : function (fun) {
		var self = this;
		var args = Array.prototype.slice.call(arguments, 1);
		fun = eval('(' + fun.toString().replace(new RegExp("'(" + this.re.source + ")'", 'g'), function (_, s) {
			return self.unit(s);
		}) + ')');
		fun.apply(null ,args);
	}
};

文字列化した関数を置換する。みためクロージャなのにクロージャになってないので変数アクセスで混乱する。つくれない。

結論

普通に係数使うのが一番シンプル。除算のほうがかっこいい気がする。ただし演算子の優先順位に気をつかわないとハマる。

  1. トップ
  2. tech
  3. JS 数値リテラルに単位をつけたい