none
GDIを使った縦書き処理がおかしい(Windows 8)

    質問

  • Windows 8 でだけ発生している問題について、相談したく存じます。
    下記の件、皆様のところでも再現いたしますでしょうか。また、投稿場所違いであればご指摘ください、移動します。

    CreateFont に "@" を付けたフォント名を渡して HFONT を取得、それを用いて DrawText で描画という伝統(?)の方法で縦書きを試みると、下記の記号が縦にならず横に向いたままです。

    • 今のところ三点リーダ(…)、二点リーダ(‥)、ダッシュ(―)の三文字が問題。
      • →罫線・矢印などにも問題が出る模様(別記自己返信参照)
    • 鍵括弧や句読点(「」、。)は問題ない模様。他の文字は未調査。
    • これが原因と思われる各種ソフトの誤動作(すべて Windows 8 のみで異常)
      • ComicStudio 4 (セルシス)
      • LibreOffice Writer
        • おそらく OpenOffice.org も、また Writer 以外も
      • 一太郎 2012 (ジャストシステム)で同様の誤動作を報告している方あり(私は未所有)
    • 縦書きの明示対応はないが、@つきフォントを使うと同様に特定文字がおかしくなるソフト
      • Windows 8 に付属のワードパッドとペイント
    • 本件と異なり Windows 8 でも正常に処理できているソフト
      • CLIP STUDIO PAINT(セルシス = ComicStudio と同じ会社)
      • Paintgraphic2 Pro (ソースネクスト)

    サンプルコード:

    • Visual Studio Express 2012 for Windows Desktop で作成。
    • Windows 8 Pro (64ビット版) で本件の異常動作。
    • 『同じ実行ファイルが』下記 OS で正常動作。
      • Windows Vista Home Premium 64ビット版
      • Windows 7 Home Edition 64ビット版
    • 実行ファイルが 32bit でも 64bit でも Windows 8 でだけ誤動作します。

    ※新規プロジェクトで Visual C++ の Win32 プロジェクトを作り、WM_PAINT の処理を下記コードへ差し換えてください

    void OnPaint(HWND hWnd) {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            auto 高さ = -MulDiv(20, GetDeviceCaps(hdc, LOGPIXELSY), 72);
            HFONT 縦書き書体 = CreateFontW(高さ, 0, 2700, 0,
                    FW_NORMAL, FALSE, FALSE, FALSE,
                    SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE,
                    L"@MS Pゴシック");
            HFONT 元書体 = (HFONT) SelectObject(hdc, 縦書き書体);
            LPWSTR 文字列 = L"三点リーダ…二点リーダ‥ダッシュ――";
            RECT 寸法;
            SetRect(&寸法, 0, 0, 0, 0);
            DrawTextExW(hdc, 文字列, -1, &寸法, DT_CALCRECT | DT_SINGLELINE, NULL);
            RECT rect;
            GetClientRect(hWnd, &rect);
            rect.left = (rect.right + 寸法.bottom) / 2;
            rect.top = (rect.bottom - 寸法.right) / 2;
            DrawTextExW(hdc, 文字列, -1, &rect, DT_SINGLELINE | DT_NOCLIP, NULL);
            SelectObject(hdc, 元書体);
            DeleteObject(縦書き書体);
            EndPaint(hWnd, &ps);
    }

    ※ 2012-11-03 08:29 Microsoft コミュニティにも報告投稿をいたしました。ここで上がっていないソフトの同様な報告もそちらで。

    http://answers.microsoft.com/ja-jp/windows/forum/windows_8-performance/windows-8/acd9cc23-dfab-4039-ade1-254dc9f36bc1

    ※ 2012-11-06 09:56 製品名Typo修正・下記に具体的な対象文字の投稿をしたことを追記

    2012年11月1日 23:45

回答

  • 皆さん、こんにちは
    フォーラムオペレータの佐伯 玲 です。

    修正まで時間がかかっておりましたが昨日公開された更新プログラムで修正されました。

    Windows 8 で、一部の文字の縦書きが正しく処理されない
    http://support.microsoft.com/kb/2781747


    私の環境ではワードパッドで最新の更新プログラム適用前と後で比較した所縦書き表示が正常に回転するようになりました。


    ご確認くださいませ。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレータ 佐伯 玲
    2013年8月15日 6:06

すべての返信

  • サンプルコードを実行したときの参考画像です。

    Windows 8 でだけ縦書き記号が正しく表示できていないことを示す

    2012年11月2日 0:26
  • ちょっと AdHoc が過ぎますが別のコードで問題の出る文字を特定してみました。JIS X 0208 の範囲ではごく限られる文字だけのようですが、しかし頻度が大きいと思われるものが多数を占めます。

    罫線32,矢印4,その他7がWindows8の縦書きでだけおかしい

    void OnPaint(HWND hWnd) {
    	PAINTSTRUCT ps;
    	HDC hdc = BeginPaint(hWnd, &ps);
    	int 高さ = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
    	HFONT 縦書き書体 = CreateFontW(高さ, 0, 2700, 0,
    		FW_NORMAL, FALSE, FALSE, FALSE,
    		SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE,
    		L"@MS 明朝");
    	HFONT 元書体 = (HFONT) SelectObject(hdc, 縦書き書体);
    	enum { MYLINELEN = 16 };
    	WCHAR wbuf[MYLINELEN];
    	CHAR buf[MYLINELEN*2];
    	UINT 開始 = 0x8140;
    	RECT rect, 全体;
    	GetClientRect(hWnd, &全体);
    	LONG 右端 = 全体.right;
    	while (右端 > std::abs(高さ) && 開始 < 0xfa60) {
    		for (UINT i=0; i<MYLINELEN; i++) {
    			buf[i*2] = CHAR((開始 + i) >> 8);
    			buf[i*2+1] = CHAR(開始 + i);
    		}
    		MultiByteToWideChar(932, 0, buf, MYLINELEN*2, wbuf, MYLINELEN);
    		CopyRect(&rect, &全体);
    		int 実高さ = DrawTextExW(hdc, wbuf, MYLINELEN, &rect, DT_CALCRECT | DT_NOCLIP, NULL);
    		SetRect(&rect, 右端 - 実高さ, 全体.top, 右端, 全体.bottom); 
    		DrawTextExW(hdc, wbuf, MYLINELEN, &rect, DT_NOCLIP, NULL);
    		右端 -= 実高さ;
    		開始 += MYLINELEN;
    		if ((開始 & 0xff) == 0) {
    			開始 += 0x40;
    		}
    		switch (開始) {
    		case 0x83e0: 開始 = 0x8440; break;
    		case 0x84c0: 開始 = 0x8740; break;
    		case 0x87a0: 開始 = 0xeee0; break;
    		case 0xef40: 開始 = 0xfa40; break;
    		}
    	}
    	SelectObject(hdc, 元書体);
    	DeleteObject(縦書き書体);
    	EndPaint(hWnd, &ps);
    }

    ― U+2015 ダッシュ(全角)
    ‐ U+2010 ハイフン(四分)
    ∥ U+2225 平行記号
    … U+2026 三点リーダ
    ‥ U+2025 二点リーダ
    ‘ U+2018 左単引用符
    ’ U+2019 右単引用符
    → U+2192 右向矢印
    ← U+2190 左向矢印
    ↑ U+2191 上向矢印
    ↓ U+2193 下向矢印
    下記の JIS X 0208 罫線素片すべて
    ─│┌┐┘└├┬┤┴━━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┝┝┰┥┸╂


    2012年11月5日 3:04
  • ここまで追及できているのなら、Microsoft の技術サポートに突っついた方がいいような気がしています。
    フォーラムは情報交換はできても不具合報告とか、Microsoft からのアドバイスがもらえる場所でもないためです。

    2012年11月5日 13:15
    モデレータ
  • 返信ありがとうございます。

    当方知識の限られた素人の域を出ないものでして、どの程度分かった時点でどこへ連絡すべきかで判断に困っておりました。

    案内いただいた技術サポート、利用してみます。

    ※ 事象自体は未解決なので「回答としてマーク」はまだつけないでおきますが、フォーラムとしては付けておくべきである、ということでしたらご指摘ください。

    2012年11月6日 0:51
  • こんにちは、鈴見咲 君高 さん
    フォーラムオペレータの佐伯 玲 です。

    ご連絡が遅れもうしわけございません。
    本現象についてKBが公開されました。

    Windows 8 で、一部の文字の縦書きが正しく処理されない
    http://support.microsoft.com/kb/2781747

    まずは現象を認識しているという一次報告に近いKBであり調査中のステータスではございますが随時詳細な情報が公開される予定でございます。
    本スレッドとしては一旦このご連絡を持って回答とさせていただきます。

    スレッドは回答としてマークがされていても返信は今後も出来ます。
    追加の情報をご確認いただいた際にこちらへご返信いただいても良いですし、もし関連はしているが別の問題や疑問などございましたら新たにスレッドを作成してご質問いただいても結構です。

    今後ともMSDN フォーラムを宜しくお願い致します。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレータ 佐伯 玲

    2012年11月8日 0:36
  • お知らせありがとうございます。

    関心のある皆様としてもリンク先 Knowledge Base を見ていればよいということになるので、回答としてマークをつけさせていただきました。

    セキュリティがどうこうという話ではないですが、影響範囲その他いろいろと笑えない事象であることは認識されていると思います。フォーラム内の注目度も高いことですし解決に向けてがんばれとお伝えください。

    2012-12-08 08:49 追記:
    本日で一ヶ月になりますが、進捗が全く見られないのでいったん回答としてマークをはずさせていただきました。
    2012年11月8日 2:38
  • 追加の情報についてここに返信してもよい、とのことでしたのでこちらにも。下記、Microsoft コミュニティと同投稿です。

    本件問題が発生する Windows 8 に VMWare Player をインストールし、その中で Windows Vista Home Premium 64ビット版 を動作させた場合、仮想環境内にある Vista 側は正常に動作します。これまでの状況証拠を見る限り、VMWare 以外の仮想化ソフト、Vista 以外の旧 Windows でも同様と思われます。

    2012年11月18日 2:29
  • Microsoft コミュニティの方にも先ほどコメントを書きましたが、Windows 8.1 Preview にてこの問題が解決されているらしき動作になっているのを視認致しました。

    すでに半年を大きく超えており、製品版として動作が確認できるまで安心出来ませんので、まだ「回答としてマーク」はつけません。

    2013年6月30日 8:52
  • 皆さん、こんにちは
    フォーラムオペレータの佐伯 玲 です。

    修正まで時間がかかっておりましたが昨日公開された更新プログラムで修正されました。

    Windows 8 で、一部の文字の縦書きが正しく処理されない
    http://support.microsoft.com/kb/2781747


    私の環境ではワードパッドで最新の更新プログラム適用前と後で比較した所縦書き表示が正常に回転するようになりました。


    ご確認くださいませ。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレータ 佐伯 玲
    2013年8月15日 6:06
  • こちらでも適用してみました。

    ComicStudio や Libre Office などでも正しく動作しているようです。

    Windows 8.1 を待たせずに更新プログラムをだしたことは素晴らしいと思います。

    他方、できることならどうして十か月近くも修正に時間がかかったのか公式リリースが欲しいとも思います。

    ともあれ回答ありがとうございました。

    2013年9月2日 14:08