RPGツクールMVでTrueType美咲フォントをPixel Perfectで表示する

# 前置き
## やりたいこと
ツクールMVで[美咲フォント](http://littlelimit.net/misaki.htm)をそのまま使おうとすると↓のように残念な感じになる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132033/267c4634-796c-416f-5013-5ce4603191d2.png)
これを何とかしてバッチバチのGBAゲーのようにアンチエイリアスなしで描画したい。

## 結果
プラグインでごり押しするとFirefoxはできたけど ~~Chromeは色々あがいたけどダメ。~~ Chrome(nwui.js)でもできた。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132033/b5b29dbb-8f74-de1b-df0c-5697ed1944c3.png)
FirefoxちゃんはちゃんとPixel Perfectに描画できてる。だいすき。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132033/368545f6-b2a6-0ba0-1baf-9b3a6611920b.png)
Google Chrome（ツクール公式プレイヤー）はX方向にボケてしまう。やはりGAFAは悪。

## 免責
3. ある程度スクリプト読み書きできる前提で書いています。
1. あんまりテストしてないのでShopやBattleで表示が壊れるかも
2. 将来のツクールMVの更新で動かなくなるかも

# やり方
## 環境
Firefox 65
ツクール同梱プレイヤー (Chrome 65ベース)

## コード

```js
    padding = 8;

    Window_Base.prototype.standardFontSize = function () {
        return 24;
    };

    Window_Base.prototype.lineHeight = function () {
        return 36 + padding * 2;
    };

    var textWidth = Window_Base.prototype.textWidth;
    Window_Base.prototype.textWidth = function (text) {
        return textWidth.call(this, text) + padding;
    }

    var processNewLine = Window_Base.prototype.processNewLine;
    Window_Base.prototype.processNewLine = function (textState) {
        textState.y += padding;
        textState.height += padding;
        processNewLine.call(this, textState);
    }

    var newPage = Window_Message.prototype.newPage;
    Window_Message.prototype.newPage = function (textState) {
        newPage.call(this, textState);
        textState.y = -0.5 + padding;
    };

    Window_Base.prototype.resetTextColor = function () {
        this.changeTextColor(this.normalColor());
        this.contents.outlineColor = 'rgba(0, 0, 0, 0)';
    };

```

## 解説
* キモはWindow_BaseとWindow_Messageでの座標処理の差し込み。
* 美咲フォントのTTFはどうも24ptを基準に作られているらしく、それ以外だとスケーリングされてアンチエイリアスされてしまうのでstandardFontSizeで24pt固定にする。
* 24ptにしたことでウィンドウのレイアウトがいまいちになってしまうので字間行間ウィンドウサイズを手なおしする処理をlineHeight,textWidth,processNewLine,newPageでやっている。 paddingでおおよその間隔を設定している。ちなみに padding = 4だと横がエディタの文章プレビューとおおよそ一致する。
  * standardPaddingとかtextPaddingという関数があるけど、Window_Messageでは微妙に参照していないので書き換えても反映されない。
* resetTextColorでアウトライン全面無効化。2000みたいに別途カゲを落としてもいいかもしれない。いろいろ試してください。
* FirefoxだとY方向にボケるので `textState.y = -0.5 + padding;` で無理やりズラす。

## 課題
* ShopやBattleでの動確
* そもそもGraphics(Canvas)を小さくしてあとからスケールするほうが良いのでは？
* こんなことにこだわるより作品を完成させる

# おまけ
MVは標準ではタイルセットは48pxが単位になっている。その場合フォントの1px相当がタイルセットの3pxと完全に一致する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132033/a4c72ca9-d523-ff43-4178-fb4aaa7e0dba.png)

タイルセットを16px単位にすると、タイルセットの1pxが2倍にスケールされるため、このようにフォントの1px相当がタイルセットの1.5pxになってタイルセットの解像度と一致しなくなってしまう。このあたりのスケールの仕組みはよく分からない。無念。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132033/9d02de19-3d06-aaf3-39b9-8be28ded94fe.png)

# 追記(2020/5/18)
https://forums.rpgmakerweb.com/index.php?threads/removing-font-blur.75294/#post-708149
似たことをしようとした人がいた。
alpha消してputImageData()したものを描けばよいそう。たしかにキレイにでる。

これだけでも問題ないが、Chromeでは8px美咲フォントのフォントの描画に問題があるので（10pxになってしまう？？？）
16pxで描いて0.5にスケールするときれいになる。

```js

    Bitmap.prototype._drawTextBody = function(text, tx, ty, maxWidth) {
        var context = this._context;
        context.imageSmoothingEnabled = false;
        context.fillStyle = this.textColor;

        context.scale(0.5, 0.5);
        context.fillText(text, tx, ty, maxWidth*2);
     
        var imageData = context.getImageData(0, 0, this.width, this.height);
        var data = imageData.data;
        for (var i = 0; i < data.length; i += 4) {
            if(data[i + 3] < 200) // if alpha less than
                data[i + 3] = 0;  // set alpha to 0
            data[i]     = data[i];     // red
            data[i + 1] = data[i + 1]; // green
            data[i + 2] = data[i + 2]; // blue
        }
        context.putImageData(imageData, 0, 0);

    };

    Window_Base.prototype.standardFontSize = function () {
        return 16; // 16px
    };
```