Hatena::ブログ(Diary)

gnupackの開発メモ

2010-12-30

[] emacs 23.2.91のIMEパッチ

来たる emacs23.3のリリースに備えて pretestをビルドしました.IMEパッチは emacs23.2で適用している既存の IMEパッチを流用しています.

パッチは2ファイルに分けています.

emacs-23.2.91-ImeFont-2010-12-30.patchでは,ソースファイル w32fns.c関数 w32_wnd_procへのパッチを行います.ソースファイル中の関係する箇所と変更点(斜体太字)を以下に記載します.

LRESULT CALLBACK
w32_wnd_proc (hwnd, msg, wParam, lParam)
     HWND hwnd;
     UINT msg;
     WPARAM wParam;
     LPARAM lParam;
{
  struct frame *f;
  struct w32_display_info *dpyinfo = &one_w32_display_info;
  W32Msg wmsg;
  int windows_translate;
  int key;

<省略>

  case WM_IME_STARTCOMPOSITION:
    if (!ignore_ime_char)
      {
        HDC hdc;
        LOGFONT lf;
        struct frame *f;
        HFONT ime_font, old_font;
      
        f = x_window_to_frame (dpyinfo, hwnd);
        hdc = GetDC (hwnd);

        ime_font = GetCurrentObject (hdc, OBJ_FONT);
        GetObject (ime_font, sizeof (lf), &lf);
        ime_font = CreateFontIndirect (&lf);

        lf.lfHeight
          = -MulDiv( FRAME_FONT (f)->pixel_size,
                     GetDeviceCaps( hdc, LOGPIXELSY ),
                     MulDiv( GetDeviceCaps(hdc, LOGPIXELSY),
                             GetDeviceCaps(hdc, LOGPIXELSY), 96 )
                   );
        Lisp_Object font_name_org
          = FRAME_FONT(f)->props[FONT_FULLNAME_INDEX];
        char font_name_new[32];
        int i;
        memset(font_name_new, '\0', sizeof(font_name_new));
        strncpy (font_name_new, SDATA(ENCODE_SYSTEM(font_name_org)), LF_FACESIZE);
        for(i=sizeof(font_name_new)-1; i>=0; i--) {
          if(font_name_new[i] == '-') {
            font_name_new[i] = '\0';
            break;
          } else if(font_name_new[i] != '\0') {
            font_name_new[i] = '\0';
          }
        }
#ifdef _UNICODE
        MultiByteToWideChar (CP_ACP, 0, font_name_new, -1, 
                             (LPWSTR) lf.lfFaceName, LF_FACESIZE);
#else
        strncpy (lf.lfFaceName, font_name_new, LF_FACESIZE);
#endif

<省略>

2chで公開されたパッチ(emacs-23.1-ime-font-yattsuke.patch)を見ると,IME変換中の処理は WM_IME_STARTCOMPOSITIONに実装すればよいらしい.さらに同パッチを参考にすると,関数 GetObjectで取得した LOGFONTのメンバ lfHeightにフォントのサイズを設定,lfFaceNameにフォント名を設定するとIME変換中のフォントを設定できるようです.

フォントサイズについては,frameの設定からピクセルサイズ pixel_sizeを取得して,DPIの比率をかけることで算出しています.フォント名については,struct fontprops[FONT_FULLNAME_INDEX]がフォント名のようですが,フォントサイズが付与されているので強引に削除しています(10ptの MSゴシックを使っている場合「MS ゴシック-10.0」となってしまう).

一応,上記のようなロジックでそれっぽく動作していますが,emacs起動後にフォントを変えても IME変換中のフォントは変更されない問題があるので,今後の課題かなぁ…(むしろ,どなたかご存知の方から教えてもらえることに期待してたり…)

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/ksugita0510/20101230/p1