フォントに含まれる「等幅半角字形」を使えないか

  1. Mery を愛用しています。ありがとうございます。
    バージョン 3.3.0 でフォント周りを改良されていますが、同様にフォント周りで気づいたことがあるのでお尋ねします。
    (日本語)フォントには,通常の(プロポーショナル)半角英数字のほかに、「等幅半角字形」の英数字が用意されているものがあります。ソフトウェアが対応していれば(特に DTP 系が対応している)、この字形を使うことができます。たとえば、メイリオ・游ゴシック・游明朝はこの等幅半角字形の英数字を備えています。
    それで、Mery において日本語フォントを指定し、そのフォントが等幅半角字形を備えていた場合、それを(設定などを通じて)使用できれば、かなり多くのフォントを(テキストエディタらしい)全角:半角の文字幅が 2:1 のものとして使用できます。
    これは技術的に可能なのでしょうか。可能であれば、実装を検討していただけると幸いです。

     |  Hisho  |  返信
  2. Mery をご愛用いただきありがとうございます。

    等幅半角字形ですが、いくつかの制限事項はありますが技術的には実装可能だと思います。

    ① DirectWrite が必要

    Mery のオプションから [DirectWrite を有効にする] をオンにしていただく必要があります。

    ② 「等幅半角字形」の機能的な問題

    「等幅半角字形」は 全角:半角 を 2:1 で描画してくれる機能というわけではなく、半角文字も全角文字も関係なくすべて半角サイズにしてしまう機能のようです。

    恐らく DTP ソフトなどでは半角サイズにしたい部分のみを選択するなどして、手動で適用する仕組みになっているのではないでしょうか?

    これを Mery で実現するとしたら、適用範囲を手動で選択するわけにはいきませんから、例えば、英数字 (a~z、A~Z、0~9) をチェックしてその部分のみに「等幅半角字形」を適用するような仕組みになってしまいます。

    ③ 必ずしも 全角:半角 が 2:1 になるとは限らない

    英数字に「等幅半角字形」を適用したとしても、全角文字の部分は等幅になるとは限りません。

    メイリオの場合、和文はたまたま等幅になっているようですが、全角記号はそうでもなさそうです。また、フォントによっては和文が等幅ではないものもあるかもしれません。

    ちなみに、「等幅 "全角" 字形」というものもあるようで、これを適用すれば全角文字が等幅になるのではないかと思ったのですが、メイリオだと全角記号は幅が狭いままでした。

    -

    というわけで、上記のような制限事項付きの実装で良ければ可能だと思いますが、まだ調査中の段階なので等幅半角字形の仕様や実装のヒントなど、何か情報をお持ちでしたらご協力いただけると助かります。

     |  Kuro  |  返信
  3. お返事ありがとうございます。半角等幅字形について調べました。
    「等幅半角字形」は,フォントが備える文字セットの一部に対して,その代替とできる文字幅が全角の半分の字形がある,ということでよさそうです。
    Adobe-Japan1 の文字セットの一覧
    https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5078.Adobe-Japan1-6.pdf
    を見ると,Adobe-Japan1-3(新しめのフォントが最低限持っている文字のセット)までの範囲で,ASCII 文字,両がな,一部の記号に半角等幅字形が存在しているのがわかります。
    テキストエディタの利用で,「半角文字」といえば ASCII 文字(0x20-0x7E)と半角カタカナでしょうから,ASCII 文字のみを等幅半角字形に置き換えれば,半角等幅字形を備えるほとんどのフォントが半角:全角の幅が 1:2 の幅のものとして使えるのではないかと考えます。
    もちろん,ASCII 以外の欧州言語の文字を中心に,プロポーショナルのものしかないものが含まれますが,これは致し方ないものと思います。
    まとめると,エディタのフォントとして,「等幅半角字形」が存在するものについては,「ASCII 文字に半角等幅字形を使用する」といったオプションを用意することで,かなりの数の和文フォントがテキストエディタで使いやすくなると考えます。好みのフォントでコーディングしたいといった(潜在的な)需要にも応えられるかと思います。
    以上,半角等幅字形について調べて,テキストエディタで使うことを考えたときを想定してまとめました。さらに調査が必要であれば時間を見つけて調べたいと思います。

     |  Hisho  |  返信
  4. 横から失礼します。
    好奇心で私も調べてみました。

    フォント内のGSUBテーブル(リガチャ等の情報が格納されているようなメタ情報テーブル)に "hwid" というサブテーブルが含まれていて、そこで「"A"という標準グリフに対応する半角幅グリフはコレだよ」という紐付けを定義するようです。

    参考: https://docs.microsoft.com/en-us/typography/opentype/spec/features_fj#hwid

    「等幅半角字形」機能というのは、この hwid テーブルの情報を見て、フォントに含まれる半角幅グリフへと置換表示するような機能なのではないでしょうか?(フォント描画のアプリケーション実装については疎いので、完全に推測です)

    なお、この hwid テーブルは、Fontforgeでも様子を見れます。

    IBM Plex Sans JPをFontforgeで開いて確認するのを例に取りますと…
    1. "A" (U+0041) のグリフを 右クリック > グリフ情報 と選択し、[置換]タブを開き、hwid テーブルの情報を確認する。
    2. どうやら「A.half」という名前のグリフが置換先のようだ、というのが見て取れるので、メニューバーから 表示 > 移動 と選択して、「A.half」と入力して対象グリフに移動する。
    3. 「A.half」グリフを開いてみると幅500の、いわゆる半角幅グリフとして描かれているのが分かる。

    興味深いのは、全角 "A" (U+FF21) においても、この hwid テーブルの定義によって「A.half」が置換先になっている点です。これによって、

    > 半角文字も全角文字も関係なくすべて半角サイズにしてしまう機能のようです

    の状況が起こっているのかもしれません。

    P.S.
    CSSでも hwid などのGSUBテーブル情報を読み出して半角表示にしたりする機能が備わっていたことを初めて知りました。
    https://www.tohoho-web.com/css/prop/font-feature-settings.htm
    見た目を切り替えているだけなのでサンプルの「 // hwid 」のあたりの「ゼンカクカナを半角で~」の文章をコピペすると、全て元の全角カナのままで張り付くのが面白かったです。

     |  yuko  |  返信
  5. >> Hisho さん

    情報ありがとうございます。

    なるほど、ひらがなの「あ」とかも半角サイズになってしまったもので、すべての文字を無理やり半角サイズっぽく描画しているだけなのかと思っていましたが、そうではなくて、きちんと代替の字形が用意されているんですね。

    > ASCII 文字のみを等幅半角字形に置き換えれば,半角等幅字形を備えるほとんどのフォントが半角:全角の幅が 1:2 の幅のものとして使えるのではないかと考えます。

    0x20-0x7E の範囲のみに適用ということなら実装可能だと思います。適用範囲をカスタマイズできる機能を…、などというご要望が来ると困ってしまいますけどね。

    > ASCII 以外の欧州言語の文字を中心に,プロポーショナルのものしかないものが含まれますが,これは致し方ないものと思います。

    そうですね。これは懸念事項ではありますが、ご理解いただいた上での実装ということで了解しました。

    > さらに調査が必要であれば時間を見つけて調べたいと思います。

    ご協力ありがとうございます。

    ある程度は開発できまして描画においては上手くいったのですが、文字幅の計算が従来の方法では上手くいかず、別の方法での実装と検証が必要になりそうです。

    次のバージョンでは [等幅半角字形を有効にする] のオプションを用意しておきます (たぶん) ので、実際に使ってみて検証にご協力いただけると幸いです。

    >> yuko さん

    ご協力ありがとうございます。

    教えていただいた手順で FontForge で hwid の定義を見ることができました!なるほど、等幅半角字形を有効にすると、グリフからさらに hwid のデータを参照して別のグリフを探してくるんですね。

    どおりで文字幅の計算が従来の方法ではうまくいかなかったわけです。

    Mery では、コードポイントをグリフ ID に変換して、そのグリフ ID をもとにフォントメトリックを取得して文字幅を計算しているのですが、コードポイントを基準にすると普通のグリフが取得されてしまいますものね。

    半角幅のグリフを取得するためには普通のグリフからさらに hwid を見て、その先にあるグリフを取ってこないといけないわけですね。

    …と、思って調べていたのですが、上記の方法は技術的な情報が見つからず挫折。動作速度が遅くなりますが別の方法での実装になりそうです。

    大雑把に言いますと、描画だけはできているので、裏画面に一度描画してみてその幅を取得するみたいな感じです。

    実験してみたところ動作速度は従来の 300 倍かそれ以上は遅いようで、実用に耐えないレベルであれば、機能自体、廃止させていただくことになるかもしれません。

    > 興味深いのは、全角 "A" (U+FF21) においても、この hwid テーブルの定義によって「A.half」が置換先になっている点です。

    誰得な機能ですねー。英数字 (ASCII) のみに hwid テーブルを定義してくれれば扱いやすいのに…。日本語の「あ」とかも半角幅になりますし。半角カタカナならぬ、半角ひらがなですもん。

    > 見た目を切り替えているだけなのでサンプルの「 // hwid 」のあたりの「ゼンカクカナを半角で~」の文章をコピペすると、全て元の全角カナのままで張り付くのが面白かったです。

    見た目は半角、中身は全角、その名は半角等幅字形!ですね。

    これは OpenType 機能というものなのでしょうか。フォントには詳しくないもので、普通に TrueType フォントでもこれらの機能は使えているように見えるのですが…。

    そもそも OpenType と TrueType の違いも分かっていないもので、トンチンカンなことを言ってたらスミマセン😫

     |  Kuro  |  返信
  6. > 見た目は半角、中身は全角、その名は半角等幅字形!ですね。

    このフォント仕様の難解さ…これはもう黒の組織の仕業に違いありませんね…!

    > これは OpenType 機能というものなのでしょうか。フォントには詳しくないもので、普通に TrueType フォントでもこれらの機能は使えているように見えるのですが…。

    実のところ、私も「TrueTypeなのにOpenType仕様として情報のあるGSUBテーブルとかが含まれるんだなぁ…不思議だなぁ…」くらいにやっていましたw
    で、この機会に改めて調べてみると、以下のような情報がありました。

    > OpenTypeはTrueTypeとPostScriptフォントの両方の総称のため、
    > 拡張子は、
    > PostScriptベース… .OTF
    > TrueTypeベース….TTF もしくは .TTC
    > となりやや分かりづらいです。
    引用元: https://adlive.co/article.php?code=69

    その他、OpenTypeに関する説明スライド
    https://www.iwatafont.co.jp/news/img/about_font.pdf

    どうやら歴史的な背景としては、1990年前後にAdobeにより策定されたPostScript仕様、同時期にMS & Appleにより策定されたTrueType仕様というものがあり、それらを3社でまとめ上げたものが1997年頃に策定されたOpenType仕様、ということらしいですね。

    OpenTypeについてのWikipedia記事 (https://ja.wikipedia.org/wiki/OpenType) を見てみると、「拡張子: .otf, .otc, .ttf, .ttc」とありますので、PostScriptベースかTrueTypeベースかという源流は違えど、いずれの拡張子でもOpenType仕様に則ったファイル構造にはなっているようです。

    いや本当にややこしい…黒の組織め…

     |  yuko  |  返信
  7. ちなみに、いにしえのフォントであるMSゴシックも見てみましたがGSUBテーブルがちゃんと存在していたため、not OpenTypeな旧来のTrueType仕様のフォントは見つける方が難しいかもしれません。

     |  yuko  |  返信
  8. > このフォント仕様の難解さ…これはもう黒の組織の仕業に違いありませんね…!

    うは、ありがとうございますw グリフはいつもひとぉぉぉっつ!とは限らないわけですね、勉強になりました。

    情報ありがとうございます。なんと、ttf の中身は OpenType 仕様のフォントだったのですね。

    開発のほうは完了しまして、「半角等幅字形」の使い方ということで追記のための原稿を書いていたのですが、OpenType 機能について触れなければならず、間違ったことを書いていたらどうしようかと不安だったもので助かりました。

    > not OpenTypeな旧来のTrueType仕様のフォントは見つける方が難しいかもしれません。

    そうなってくると、旧来の TrueType フォントでは検証できていませんが、別に検証しなくてもいいかなーといった感じはありますね。

    私事で恐縮ですが、週明けからワクチン接種で寝込む予定なので今夜か明日にはリリースしておきたいと思っています。

     |  Kuro  |  返信
  9. > グリフはいつもひとぉぉぉっつ!とは限らない

    これはw 「見た目は半角…」のところから、これを言うための伏線だった気すらしてきましたw

    そして、Ver 3.3.1 のリリースお疲れさまでした。
    ワクチン接種目前とのことで、どうぞ養生なさってください。

    メイリオを半角幅表示にすると、まるでMeiryoKeフォントのような趣がありますね。行間をマイナス値に設定して減らすことで、まさしく簡易MeiryoKeな風合いです。

    ところでこれはメイリオのヒンティング上の問題と思われますが、小さめのサイズで等幅半角字形で表示させると、一部の文字がズレて見えるようです。
    ※下記の画像は、1枚目がMeryでの文字サイズ 11 での表示。2枚目がChromeでの文字サイズ 15px での hwid 指定の表示(Meryでのsize 11は、Chromeでの15pxと同程度の表示サイズになります)
    https://imgur.com/a/aWze4o9
    "b" "e" "f" がベースラインより少し上にずれていたり、"s" の上辺の高さが少し高くなってしまっているのが分かりやすいと思います。

    HackGenなどのヒンティング調整時にも出くわしたのでおそらく同じ話だと思うのですが、ヒンティングは文字サイズが小さいときにこういったズレが起こりがちです。文字サイズを大きくすると、こういったズレは大抵解消されます。これはヒンティング自体が、文字サイズが小さいときにボケ感を減らすために使われる処置(表示ピクセル位置をずらして調整する)であるためと想定されます。

    メイリオは特に、趣味フォントでは真似できないほどの明瞭な(それこそフォント名どおりな)ヒンティング処置がなされており、低解像度なモニタであってもパリッとした表示になるのが特徴です。
    通常のグリフではこういったズレは文字サイズをいくら小さくしても見られませんが、半角用文字では詰めが甘いのか、ズレが目立ちます。

    ただしMeryであれば対処法があります。DirectWriteのレンダリングモードを「Outline」に設定することです。(上記URL内、3枚目の画像)
    多少、全体の明瞭感は落ちますが、文字ずれが気になる場合にはこのあたりの設定を調整すればかなり改善が見込めるかと思います。

    メイリオほどメジャーなフォントにもなれば利用者も多いことでしょうし…。こういった文字ずれの問い合わせがあるかもしれないと思い、ひとまず情報共有させていただきました。

     |  yuko  |  返信
  10. お気遣いいただきありがとうございます。

    > 行間をマイナス値に設定して減らすことで、まさしく簡易MeiryoKeな風合いです。

    メイリオだと行間をマイナス値にしたぐらいがちょうど良い感じもしますね。マイナス値にできるようにしておいてよかったー。

    情報ありがとうございます。確かに、文字サイズが小さいとガタガタになっていました。

    Chrome 先生でも発生しているとのことでひとまず安心ですが、なるほどヒンティングが原因でしたか。(ググってきました)

    DirectWrite のレンダリングモードを Outline にすることで改善されることも確認できました。

    > メイリオほどメジャーなフォントにもなれば利用者も多いことでしょうし…。

    今回のバージョンはメイリオフォントが等幅になるというインパクトのためか、いつもの倍以上、リツイートされてるようなのでちょっと心配です。

    これは教えていただかないと原因も対策も分からなかっただろう問題だと思うので、情報共有に感謝します!

     |  Kuro  |  返信
  11. > メイリオだと行間をマイナス値にしたぐらいがちょうど良い感じもしますね。マイナス値にできるようにしておいてよかったー。

    これは大変GJでした🙌
    行間が逆に減ったらより丁度良いけど、そんなことにはならないよね…(スピンエディットぽちぽち……ッ!!?)となりましたw

    > 今回のバージョンはメイリオフォントが等幅になるというインパクトのためか、いつもの倍以上、リツイートされてるようなのでちょっと心配です。

    メイリオを等幅で使いたいという隠れたニーズを掘り当ててしまったかもしれませんね!

     |  yuko  |  返信
  12. もう実装されたとのことで,対応の早さに驚きです。yuko さんも有益な情報をありがとうございます。さっそく使用させていただきます。気づいた点があったらご報告します。
    反響が大きいようで,「半角:全角の文字幅が 1:2 のさまざまなフォントを使いたい」潜在的需要があったことを改めて思い知りました。
    速度の件を懸念していらっしゃいますが,Windows の API 周りは(特に最近のものは)明るくないのでお力になれそうにありません。申し訳なく思います。改善できる方法が見つかればよいのですが。

     |  Hisho  |  返信
  13. 早速お試しいただきありがとうございます。

    > 反響が大きいようで,「半角:全角の文字幅が 1:2 のさまざまなフォントを使いたい」潜在的需要があったことを改めて思い知りました。

    そのようですね。「いいね!」の数がマルチカーソルや Zen モードのときのをあっさり超えていきました。ありがとうございます。

    > 速度の件を懸念していらっしゃいますが,Windows の API 周りは(特に最近のものは)明るくないのでお力になれそうにありません。申し訳なく思います。改善できる方法が見つかればよいのですが。

    いえいえ、お気持ちだけでありがたいです。

    文字幅の計算速度につきましては、若干、気にはなるものの、一度表示した文字の幅をキャッシュすることである程度の高速化を図っていますので、今のところは様子見といったところです。

    また何かお気づきの点などございましたらよろしくお願いします。

     |  Kuro  |  返信
スポンサーリンク