トップページ > 記事閲覧
フォントのカーニングについて
名前:Citrine 日時: 2019/03/16 22:04

いつもお世話になってます。今回Windows版DXライブラリの文字描画について気になる点があったため、スレッドを立てました。 バージョン3.20c時点では、それぞれの文字の幅を基に間隔を調整して、文字列を描画しているように見えます。 日本語の文章や等幅フォントの場合は特に問題ないですが、プロポーショナルフォントを用いて英文(ラテン文字主体の文章)を描画すると、 一部文字の組み合わせにおいて不自然に間隔が空き、フォントによっては強い違和感を覚えます。 以下サンプルコードです。 ----- コード開始 ----- #include "DxLib.h" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) { SetOutApplicationLogValidFlag(FALSE); ChangeWindowMode(TRUE); DxLib_Init(); int FontHandle = CreateFontToHandle(_T("Times New Roman"), 64, 0, DX_FONTTYPE_ANTIALIASING_4X4); DrawBox(0, 0, 640, 480, GetColor(0xFF, 0xFF, 0xFF), TRUE); DrawStringToHandle(20, 10, _T("Average"), GetColor(0x00, 0x00, 0x00), FontHandle); WaitKey(); DxLib_End(); return 0; } ----- コード終了 ----- 上記のコードをビルド・実行した際の内容をスクリーンショットし、GIMP等適当な画像編集ソフトを用いて同じフォントで同じ文章を配置すると、 DXライブラリの描画は“A”と“v”の間隔が若干広いことが分かります。恐らくフォントのカーニング情報を参照していないために、このような描画結果になるのだと思います。 UI等に使用する短い単語であれば他ソフトで画像化して使用するという方法ができますが、長文の場合だとこの方法はとりにくいです。 上記の点を踏まえて、以下の要望があります。 ・ライブラリの文字列描画でフォントのカーニング情報を参照し、文字詰めするようにしてほしい。 ・↑が不可能な場合、各文字のカーニング情報を取得する関数の追加等、代替手段を用意してほしい。 勝手なお願いになってしまいましたが、検討していただければ幸いです。 よろしくお願いします。
メンテ

Page: 1 |

Re: フォントのカーニングについて ( No.1 )
名前:was-blue.0793 日時:2019/03/17 09:22

横から失礼します。 私は逆に"数字が等幅でないフォントで数字だけ等幅で描画できないか"と考えたのですが、難しいようです。 (別名義でその方法について考えた記事がありますが、かなり大変です→qiita.com/Seiten_Minagawa/items/e559b4db01cd2e00180d) フォントを使った文字列描画絡みはDXフォントデータとの兼ね合いもあって難しいと思います。(容量が増加する、過去のDXフォントデータと互換性がなくなるなど……) カーニング設定を取得してそれをDXフォントデータに含めることの難易度によりそうな感じがしますね……
メンテ
Re: フォントのカーニングについて ( No.2 )
名前:管理人 日時:2019/03/17 19:59

ご指摘ありがとうございます すみません、カーニング情報というものを知りませんでした (・・;; 早速カーニング情報を反映した描画を行うようにしてみましたので、よろしければお試しください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM.zip // Android版 ARM用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM64.zip // Android版 ARM64用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x86.zip // Android版 x86用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x64.zip // Android版 x64用 https://dxlib.xsrv.jp/temp/DxLibiOSTest.zip // iOS版 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) あと、DXフォントデータファイルにもカーニング情報を追加しましたので、もしDXフォントデータファイルを お使いでしたらこちらもダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/CreateDXFontDataTest.zip > was-blue.0793さん DXフォントデータに含まれる情報は増えましたがカーニング情報が追加される前のDXフォントデータも使えるようにしました ( カーニング情報が追加された新しいDXフォントデータをカーニング情報対応前のDXライブラリで使うことはできませんが… )
メンテ
Re: フォントのカーニングについて ( No.3 )
名前:Citrine 日時:2019/03/17 23:29

管理人様、お忙しい中の対応ありがとうございます。 文字列描画の際にカーニングが適用されていることを確認しました。 ただ、確認中にバグと思われる挙動を見つけました。(3.20cの時点で既にあったようです) 以下の条件を満たした状態でDrawStringFToHandleを実行すると一部の文字が1ピクセル上にずれて描画されます。 ・描画モードがニアレストネイバー法である ・フォントサイズが16以下である ・フォントのタイプが8×8サンプリングでない(8×8でも起きる組み合わせが少数ある) 自身の環境では、Arial、Palatino Linotype、Noto Sans、Noto Serifにおいてアルファベットの“M”や“v”等が 1ピクセルずれて描画されることを確認しました。 微々たる点ではありますが、一度検証していただけると幸いです。
メンテ
Re: フォントのカーニングについて ( No.4 )
名前:管理人 日時:2019/03/19 01:02

お試しいただきありがとうございます m(_ _)m > 以下の条件を満たした状態でDrawStringFToHandleを実行すると一部の文字が1ピクセル上にずれて描画されます。 ご指摘ありがとうございます すみません、以下のようなプログラムを組んでパラメータを弄って試してみたのですが 現象を再現することができませんでした #include "DxLib.h" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) { int FontHandle ; int Screen ; ChangeWindowMode( TRUE ) ; if( DxLib_Init() < 0 ) { return -1 ; } // フォントハンドルを作成 FontHandle = CreateFontToHandle( _T( "Arial" ), 12, 0, DX_FONTTYPE_NORMAL ) ; // 拡大表示用の仮画面を作成 Screen = MakeScreen( 160, 120, FALSE ) ; // 描画先を仮画面に変更 SetDrawScreen( Screen ) ; // DrawStringToHandle と DrawStringFToHandle で描画 DrawStringToHandle( 20, 10, _T( "AMBvC" ), GetColor( 255,255,255 ), FontHandle ) ; DrawStringFToHandle( 20, 10 + 20, _T( "AMBvC" ), GetColor( 255,255,255 ), FontHandle ) ; // 裏画面に仮画面を4倍拡大して描画 SetDrawScreen( DX_SCREEN_BACK ) ; DrawExtendGraph( 0, 0, 160 * 4, 120 * 4, Screen, FALSE ) ; ScreenFlip() ; WaitKey() ; DxLib_End(); return 0; } お手数で申し訳ありませんが、よろしければ上記のプログラムを変更して1ピクセルずれてしまう 状態を再現していただけないでしょうか? m(_ _;m
メンテ
Re: フォントのカーニングについて ( No.5 )
名前:Citrine 日時:2019/03/19 21:32

度々失礼いたします。 管理人様のコードのフォントハンドル作成箇所と文字描画箇所を以下のようにすることでこちらの環境でずれが起きることを確認しました。 ----- コード開始 ----- // フォントハンドルを作成 FontHandle = CreateFontToHandle(_T("Arial"), 14, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Arial"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Arial"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Arial"), 16, 0, DX_FONTTYPE_ANTIALIASING_4X4); //FontHandle = CreateFontToHandle(_T("Calibri"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Calibri"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Candara"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Candara"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Comic Sans MS"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Comic Sans MS"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Consolas"), 20, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Meiryo"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Meiryo"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Palatino Linotype"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Palatino Linotype"), 16, 0, DX_FONTTYPE_ANTIALIASING_4X4); //FontHandle = CreateFontToHandle(_T("Palatino Linotype"), 16, 0, DX_FONTTYPE_ANTIALIASING_8X8); //FontHandle = CreateFontToHandle(_T("Segoe UI"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Segoe UI"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Segoe UI"), 16, 0, DX_FONTTYPE_ANTIALIASING_4X4); //FontHandle = CreateFontToHandle(_T("Tahoma"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Times New Roman"), 14, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Times New Roman"), 15, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Times New Roman"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Times New Roman"), 14, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Yu Gothic UI"), 12, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Yu Gothic UI"), 16, 0, DX_FONTTYPE_NORMAL); //FontHandle = CreateFontToHandle(_T("Yu Gothic UI"), 16, 0, DX_FONTTYPE_ANTIALIASING); //FontHandle = CreateFontToHandle(_T("Yu Gothic UI"), 16, 0, DX_FONTTYPE_ANTIALIASING_4X4); //FontHandle = CreateFontToHandle(_T("Yu Gothic UI"), 16, 0, DX_FONTTYPE_ANTIALIASING_8X8); // DrawStringToHandle と DrawStringFToHandle で描画 DrawStringToHandle(20, 10, _T("AMBsCwDzEoFn"), GetColor(255, 255, 255), FontHandle); DrawStringFToHandle(20, 10 + 20, _T("AMBsCwDzEoFn"), GetColor(255, 255, 255), FontHandle); ----- コード終了 ----- しかし、当初確認したマシンと別のマシンで確認したところ、描画結果が変わることが分かりました。 ・マシン1 (当初確認したもの) OS: Windows 10 Ver.1903 (Build 18358.1) CPU: AMD Ryzen 7 2700 グラフィックス: Nvidia GeForce GTX 760 結果: 一部文字が1ピクセル上にずれることがある ・マシン2 OS: Windows 8.1 with Update CPU: Intel Core i3 4020Y グラフィックス: Intel HD Graphics 4200 結果: 差異なし ・マシン3 OS: Windows 7 SP1 CPU: Intel Core 2 Duo P8700 グラフィックス: Mobile Intel 4 Series GM45 Express Chipset 結果: 一部文字の1ピクセルずれに加え、文字の形にも差異が現れる どうもこの結果を見る限り、グラフィックカードもしくはOSに依存して発生する現象のようです... 上記のコードを用いた場合の、管理人様の環境での結果が気になるところです。 (↓こちらの環境での描画結果をスクリーンショットにしました。) ttps://drive.google.com/open?id=1M_H3MzbnASj_6134YSYDqJo4z6D4ISLO
メンテ
Re: フォントのカーニングについて ( No.6 )
名前:管理人 日時:2019/03/20 00:37

再現コードとスクリーンショットの掲載ありがとうございます 手元の環境でも1ピクセル上にずれました( GeForce GTX 660 Ti ) DXライブラリでは一部の『指定したサイズよりかなり小さい表示になる』フォントについて 大きさと描画位置を補正する処理を入れていて、描画位置のY座標の補正に補正サイズ / 2.0f という計算があるのですが、これが原因となっていました 補正サイズが奇数だった場合計算結果に 0.5f が入る中途半端な値になりニアレストネイバー法では ひとつ上の座標に描画するかどうかが極めて微妙な値( ピクセルの境界である 0.5f という座標であるため )で 判断されることになるため、文字やOSやグラフィックカードのドライバによって描画結果が異なる状態になっていました ( 尚、int型で座標を指定する DrawString系の関数では同計算が 補正サイズ / 2 と、整数演算 されるため座標が 0.5f などの小数点以下の値が含まれることはないので正常に描画されます ) DrawStringF系の関数でも 補正サイズ / 2 と、整数演算するようにすることで 1ピクセルずれる ことのないように修正してみましたので、よろしければお試しください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい)
メンテ
Re: フォントのカーニングについて ( No.7 )
名前:Citrine(解決) 日時:2019/03/20 23:11

対応ありがとうございます。手持ちの3台とも描画結果に差異がないことを確認しました。 お忙しい中本当にありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存