none
TextOutで文字が欠ける RRS feed

  • 質問

  • お世話になります。

    MFCのプログラムで以下の現象が発生して困っています。
    あるサイズの文字を描画すると「国」や「園」などの文字の上側の線が表示されません。
    フォントは今のところ「MS Pゴシック」や「MS ゴシック」では発生しますが、
    「MS P明朝」や「MS 明朝」など他のフォントでは現象は確認していません。

    WinXP + VisualStudio6.0
    Win7 + VisualStudio2010
    Win7 + VisualStudio2013
    の環境で試しましたがすべて同じ現象です。

    この現象についていろいろと探してみましたが、なかなか見つからず、
    何かご存知の方がいらっしゃったらよろしくお願いします。

    #以下のサンプルで、数値の部分は実際は可変です。
    #ビューポートサイズを変えたりフォントのサイズを変更すると発生しません。

    ---- サンプル ----
    void CTestView::OnDraw(CDC* pDC)
    {
        CTestDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        if (!pDoc)
            return;

        pDC->SetMapMode(MM_ISOTROPIC);
        pDC->SetWindowExt(5000, 5000);
        pDC->SetViewportExt(729, -561);
        pDC->SetViewportOrg(100, 500);

        CFont font;
        font.CreateFont(140, 0, 0, 0, FW_NORMAL, 0, 0, 0, SHIFTJIS_CHARSET,
            OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS | CLIP_LH_ANGLES, DEFAULT_QUALITY,
            VARIABLE_PITCH | FF_DONTCARE, _T("MS Pゴシック"));
        CFont* pOldFont = (CFont *)pDC->SelectObject(&font);

        CString str = _T("国園図圀");
        pDC->TextOut(1500, 3500, str, str.GetLength());

        pDC->SelectObject(pOldFont);
        font.DeleteObject();
    }

    2015年4月16日 8:27

回答

  • SDKで試し、現象を確認しました。

    細かく観察すると、TextOutのクリップ領域のデバイス座標がLPtoDPの値と等しいのに、TextOutの文字出力開始点がクリップ領域より1pixel上にずれているように見えました。

    言い換えると、クリップ領域と文字出力開始点を論理座標からデバイス座標への変換するやり方が異なっているために、不具合が起っているようです。

    私は、FillRgnで同様の経験をしています。Windowsの不具合でしょうけど、対処されるかどうかわかりませんので、対策を提案します。

    DrawText : DT_NOCLIP rc.left = 3500, rc.top = 1500, rc.right=rc.bottom=0(n/a)でうまくいきました。

    (その他)

    > 「MS P明朝」や「MS 明朝」など他のフォントでは現象は確認していません。

    "MS P明朝"で試しましたが、くにがまえの縦線が上線から突き出ている部分が描画されませんでした。

    • 回答としてマーク 星 睦美 2015年4月21日 5:12
    2015年4月19日 7:13

すべての返信

  • レスつきませんね。

    SetWindowExt()、SetViewportExt()を利用して拡大縮小を行う場合、
    一対一(拡大率1)の場合に比べて拡大している場合は特に問題はありませんが、
    縮小している場合は、描画されない部分がありえます。
    当然ですが、それがたまたま文字の上端の横線の場合もありえます。
    掲載されたコードの場合、高さが140[論理単位]のフォントを
    561/5000(=0.1122)倍して表示しますので、縮小になります。

    2015年4月17日 7:28
  • 当てずっぽうですが、

    2015年2月のWindows Updateで提供されたMS15-010KB3013455)の影響の可能性はありますでしょうか? 当該パッチのアンインストールで改善するかどうかです。

    【悲報】Firefox最新版に日本がエッチになってしまう脆弱性発見される

    2015年4月17日 7:59
  • SDKで試し、現象を確認しました。

    細かく観察すると、TextOutのクリップ領域のデバイス座標がLPtoDPの値と等しいのに、TextOutの文字出力開始点がクリップ領域より1pixel上にずれているように見えました。

    言い換えると、クリップ領域と文字出力開始点を論理座標からデバイス座標への変換するやり方が異なっているために、不具合が起っているようです。

    私は、FillRgnで同様の経験をしています。Windowsの不具合でしょうけど、対処されるかどうかわかりませんので、対策を提案します。

    DrawText : DT_NOCLIP rc.left = 3500, rc.top = 1500, rc.right=rc.bottom=0(n/a)でうまくいきました。

    (その他)

    > 「MS P明朝」や「MS 明朝」など他のフォントでは現象は確認していません。

    "MS P明朝"で試しましたが、くにがまえの縦線が上線から突き出ている部分が描画されませんでした。

    • 回答としてマーク 星 睦美 2015年4月21日 5:12
    2015年4月19日 7:13
  • 仲澤@失業者 様
    返信ありがとうございます。

    > SetWindowExt()、SetViewportExt()を利用して拡大縮小を行う場合、
    > 一対一(拡大率1)の場合に比べて拡大している場合は特に問題はありませんが、
    > 縮小している場合は、描画されない部分がありえます。

    そういうこともあるんですね。参考になります。
    ありがとうございました。

    2015年4月20日 1:34
  • 佐祐理 様
    返信ありがとうございます。

    > 2015年2月のWindows Updateで提供されたMS15-010 (KB3013455) の影響の可能性はありますでしょうか?

    当該パッチの入っていない環境で試してみましたが同じでした。
    ありがとうございました。

    2015年4月20日 1:50
  • snao 様
    返信ありがとうございます。

    > 細かく観察すると、TextOutのクリップ領域のデバイス座標がLPtoDPの値と等しいのに、TextOutの文字出力開始点がクリップ領域より1pixel上にずれているように見えました。

    確かにそのような感じに見えますね。

    > 私は、FillRgnで同様の経験をしています。Windowsの不具合でしょうけど、対処されるかどうかわかりませんので、対策を提案します。

    > DrawText : DT_NOCLIP rc.left = 3500, rc.top = 1500, rc.right=rc.bottom=0(n/a)でうまくいきました。

    いろいろと試していただいてありがとうございます。
    最初の投稿には書きませんでしたが、DrawTextでは同じ文字サイズでも現象が発生しないことは確認していました。
    TextOutのままで何か改善策があればと思いましたが、やはりDrawTextに変更するしかなさそうですね。

    > "MS P明朝"で試しましたが、くにがまえの縦線が上線から突き出ている部分が描画されませんでした。

    失礼しました。
    よく見ると確かにそうですね。
    ありがとうございました。

    2015年4月20日 2:02
  • SetBkColorで文字描画領域を見やすくして試してみました。
    文字高さ 400論理単位 --> 16デバイス単位、なので、文字描画領域の高さが 16pixelならば問題ないはず、小さければ文字が欠けると思い、テストしました。
    "MS Pゴシック"、"MS P明朝"は 15pixel
    "Courier New"、"メイリオ"は 16pixel
    でした。
    フォントに原因があるのかもしれません。
    2015年4月22日 12:26
  • snao 様
    返信ありがとうございます。

    > "MS Pゴシック"、"MS P明朝"は 15pixel
    > "Courier New"、"メイリオ"は 16pixel
    > でした。
    > フォントに原因があるのかもしれません。

    こちらでも確認しました。
    フォントが原因ならDrawTextでも同じ現象になってもおかしくないですが、DrawTextだと16pixelになりますね。
    #ちなみに論理サイズを141にするとTextOutでも16pixelで表示されます。

    不思議な現象ですね。
    ありがとうございました。

    2015年4月23日 2:18