WindowsのVimが色付きの絵文字に対応したと聞いてやったがなかなか色がつかなかった件
この記事は@kjunichiの2017年パーソナルアドベントカレンダーの3日目の記事です 。
tl;dr
nmake -f Make_mvc.mak GUI=yes IME=yes MBYTE=yes TERMINAL=yes DIRECTX=yes
背景
TLやVim関連の記事でWindowsのVimが色付きの絵文字に対応したと見かけて、 :terminalが対応されたころからvimのビルドを始めたにわかなので、なかなか絵文字に色がつかずにハマった。
絵文字はでるが、色が出ない
既存の設定が悪い?
ひょっとして、大した設定をしていないけど、設定を無効に起動する方法を調べた
gvim -u NONE
でもダメ。
設定やフォントが必要?
のドキュメントの修正を見て、Rictyフォントが必要なのか?とおもい、
から、クローンの代わりに、zipでDLして展開してフォントをインストール。
前述のドキュメントのように
set encoding=utf-8 set gfn=Ricty_Diminished:h12 set rop=type:directx
と設定するも、NG。
そもそも、手元の環境で絵文字に色がつくのか
今回Vimで実装されてるDIRECTXによるフォント描画で試している環境で絵文字に色が出るのかすら疑った。
を見つけ、コピペしたもの、コンパイルエラーがでて、以下のように修正(張り付けたコードは\ではなく、¥になっていて、 その個所と、リンクえーらとなったuser32ライブラリを#pragmaで追加)して ビルド出来、実行できた。無事に絵文字が色付きで表示されたので、環境的には問題なさそうなことが分かった。
#include <stdio.h> #include <tchar.h> #include <locale.h> #include <iostream> #include <windows.h> #include <wingdi.h> #include <d2d1.h> #include <dwrite.h> // define #ifndef D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT #define D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT ( 0x00000004 ) #endif // lib #pragma comment( lib, "d2d1.lib" ) #pragma comment( lib, "dwrite.lib" ) #pragma comment( lib, "user32.lib") /* メインウインドウイベント処理 */ LRESULT CALLBACK eMainWindowProc( HWND hwnd // handle to window , UINT uMsg // message identifier , WPARAM wParam // first message parameter , LPARAM lParam // second message parameter ); /* UTF32をUTF16に変換する */ std::wstring UTF32toUTF16 ( ULONG qUnicode ) { WCHAR waBuf[ 4 ] = { 0 }; if ( 0x10000 > qUnicode ) { // 0x10000未満 waBuf[ 0 ] = (WCHAR)qUnicode; } else { // 0x10000以上(サロゲートペアにする) waBuf[ 0 ] = (WCHAR)( ( qUnicode - 0x10000 ) / 0x400 + 0xd800 ); waBuf[ 1 ] = (WCHAR)( ( qUnicode - 0x10000 ) % 0x400 + 0xdc00 ); } // 処理結果を返す return( waBuf ); } // グローバル変数 ID2D1Factory* pD2d1Factory = NULL; IDWriteFactory* pDWFactory = NULL; ID2D1HwndRenderTarget* pRenderTarget = NULL; // 絵文字文字列 std::wstring strEmoji; /* Direct2Dでカラー絵文字を描画 */ int _tmain ( int argc , _TCHAR* argv[] ) { // 標準出力にユニコードを表示できるようにする setlocale( LC_ALL, "Japanese" ); WNDCLASSEX tWndClass; HINSTANCE hInstance; TCHAR* cpClassName; TCHAR* cpWindowName; TCHAR* cpMenu; HWND hWnd; MSG tMsg; // アプリケーションインスタンス hInstance = ::GetModuleHandle( NULL ); // クラス名称 cpClassName = _T("MainWindowClass"); // メニュー cpMenu = MAKEINTRESOURCE( NULL ); // ウインドウ名称 cpWindowName = _T("Direct2Dでカラー絵文字を描画"); // ウインドウクラスパラメータセット tWndClass.cbSize = sizeof( WNDCLASSEX ); tWndClass.style = CS_HREDRAW | CS_VREDRAW; tWndClass.lpfnWndProc = eMainWindowProc; tWndClass.cbClsExtra = 0; // ::GetClassLong で取得可能なメモリ tWndClass.cbWndExtra = 0; // ::GetWindowLong で取得可能なメモリ tWndClass.hInstance = hInstance; tWndClass.hIcon = ::LoadIcon( NULL, IDI_APPLICATION ); tWndClass.hCursor = ::LoadCursor( NULL, IDC_ARROW ); tWndClass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 ); tWndClass.lpszMenuName = cpMenu; tWndClass.lpszClassName = cpClassName; tWndClass.hIconSm = NULL; // ウインドウクラス生成 if ( 0 == ::RegisterClassEx( &tWndClass ) ) { /* 失敗 */ return( -1 ); } // ウインドウを生成する hWnd = ::CreateWindowEx ( 0 // extended window style , tWndClass.lpszClassName // pointer to registered class name , cpWindowName // pointer to window name , WS_OVERLAPPEDWINDOW // window style , CW_USEDEFAULT // horizontal position of window , CW_USEDEFAULT // vertical position of window , 640 // window width , 512 // window height , NULL // handle to parent or owner window , NULL // handle to menu, or child-window identifier , hInstance // handle to application instance , (VOID*)0x12345678 // pointer to window-creation data ); /* メッセージループ */ while( 0 != ::GetMessage( &tMsg, NULL, 0, 0 ) ) { ::TranslateMessage ( &tMsg ); ::DispatchMessage ( &tMsg ); } // WM_QUITの終了コードを返却する return( tMsg.wParam ); } /* メインウインドウイベント処理 */ LRESULT CALLBACK eMainWindowProc ( HWND hWnd // handle to window , UINT uMsg // message identifier , WPARAM wParam // first message parameter , LPARAM lParam // second message parameter ) { switch( uMsg ) { case WM_CREATE: //-------------------------------------------- // WM_CREATE //-------------------------------------------- { CREATESTRUCT* tpCreateSt = (CREATESTRUCT*)lParam; /* パラメータ表示 */ wprintf( L"CREATESTRUCT¥n" L"¥tlpCreateParams = 0x%08x\n" L"¥thInstance = 0x%08x\n" L"¥thMenu = 0x%08x\n" L"¥thwndParent = 0x%08x\n" L"¥tcy = %d\n" L"¥tcx = %d\n" L"¥ty = %d\n" L"¥tx = %d\n" L"¥tstyle = 0x%08x\n" L"¥tlpszName = \"%s\"\n" L"¥tlpszClass = \"%s\"\n" L"¥tdwExStyle = 0x%08x\n" , tpCreateSt->lpCreateParams , tpCreateSt->hInstance , tpCreateSt->hMenu , tpCreateSt->hwndParent , tpCreateSt->cy , tpCreateSt->cx , tpCreateSt->y , tpCreateSt->x , tpCreateSt->style , tpCreateSt->lpszName , tpCreateSt->lpszClass , tpCreateSt->dwExStyle ); HRESULT hResult = S_OK; // 絵文字文字列の生成 for ( ULONG qUnicode = 0x1f300; qUnicode <= 0x1f5ff; qUnicode++ ) { strEmoji += UTF32toUTF16( qUnicode ); } /* ID2D1Factoryの生成 */ hResult = ::D2D1CreateFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2d1Factory ); if ( FAILED( hResult ) ) { // エラー std::wcout << L"D2D1CreateFactory失敗" << std::endl; break; } /* IDWriteFactoryの生成 */ hResult = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>( &pDWFactory ) ); if ( FAILED( hResult ) ) { // エラー std::wcout << L"D2D1CreateFactory失敗" << std::endl; break; } /* ID2D1HwndRenderTargetの生成 */ { D2D1_SIZE_U oPixelSize = { tpCreateSt->cx , tpCreateSt->cy }; D2D1_RENDER_TARGET_PROPERTIES oRenderTargetProperties = D2D1::RenderTargetProperties(); D2D1_HWND_RENDER_TARGET_PROPERTIES oHwndRenderTargetProperties = D2D1::HwndRenderTargetProperties( hWnd, oPixelSize ); /* ID2D1HwndRenderTargetの生成 */ hResult = pD2d1Factory->CreateHwndRenderTarget( oRenderTargetProperties , oHwndRenderTargetProperties , &pRenderTarget ); if ( FAILED( hResult ) ) { // エラー std::wcout << L"CreateHwndRenderTarget失敗" << std::endl; break; } } // ウインドウを表示する ::ShowWindow( hWnd, SW_SHOW ); } break; case WM_DESTROY: //-------------------------------------------- // WM_DESTROY //-------------------------------------------- { // ID2D1HwndRenderTargetの破棄 if ( NULL != pRenderTarget ) { pRenderTarget->Release(); } // IDWriteFactoryの破棄 if ( NULL != pDWFactory ) { pDWFactory->Release(); } // ID2D1Factoryの破棄 if ( NULL != pD2d1Factory ) { pD2d1Factory->Release(); } // 終了する( 引数はそのまま終了コードとなります ) ::PostQuitMessage( 0 ); } break; case WM_SIZE: //-------------------------------------------- // WM_SIZE //-------------------------------------------- { D2D1_SIZE_U oPixelSize = { LOWORD( lParam ), HIWORD( lParam ) }; // ターゲットリサイズ pRenderTarget->Resize( &oPixelSize ); } break; case WM_ERASEBKGND: //-------------------------------------------- // WM_ERASEBKGND //-------------------------------------------- { ; } return( TRUE ); case WM_PAINT: //-------------------------------------------- // WM_PAINT //-------------------------------------------- { // ターゲットサイズの取得 D2D1_SIZE_F oTargetSize = pRenderTarget->GetSize(); // 描画開始 pRenderTarget->BeginDraw(); // 背景のクリア D2D1_COLOR_F oBKColor = { 1.0f, 1.0f, 1.0f, 1.0f }; pRenderTarget->Clear( oBKColor ); /* テキストの描画 */ { /* ブラシの生成 */ ID2D1SolidColorBrush* pBrush = NULL; { pRenderTarget->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::Black ) , &pBrush ); } /* テキストフォーマットの生成 */ IDWriteTextFormat* pTextFormat = NULL; { pDWFactory->CreateTextFormat( L"Meiryo" , NULL , DWRITE_FONT_WEIGHT_NORMAL , DWRITE_FONT_STYLE_NORMAL , DWRITE_FONT_STRETCH_NORMAL , 32 , L"" ,&pTextFormat ); } /* テキストの描画 */ if ( NULL != pBrush && NULL != pTextFormat ) { // テキストの描画 pRenderTarget->DrawText( strEmoji.c_str() // 文字列 , strEmoji.size() // 文字数 , pTextFormat , &D2D1::RectF( 0, 0, oTargetSize.width, oTargetSize.height ) , pBrush , (D2D1_DRAW_TEXT_OPTIONS)D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT ); } // テキストフォーマットの破棄 pTextFormat->Release(); // ブラシの破棄 pBrush->Release(); } // 描画終了 pRenderTarget->EndDraw(); } return( FALSE ); } // デフォルト処理呼び出し return ::DefWindowProc( hWnd, uMsg, wParam, lParam ); }
結局必要だったのは
DIRECTXによる描画にはvimビルド時にDIRECTX=yesの指定が必要だった。
この指定がなかったので、:set rop=type:directx
と指定しても無視されて、絵文字に色が出なかった。
nmake -f Make_mvc.mak GUI=yes IME=yes MBYTE=yes TERMINAL=yes DIRECTX=yes
でビルドして、
set encoding=utf-8 set gfn=Ricty_Diminished:h12 set rop=type:directx
として、色付きの絵文字があるテキストを開いたら、無事表示された。
これ、vimのnmakeでビルドする際のDIRECTX=yesが必要だった。で、directxで超早くなると期待したが、webカメラの表示は流石にフルスクリーンだと遅延がひどかった
— kjunichi (@kjunichi) 2017年12月3日
関連記事
8年前の記事
4年前の記事
3年前の記事
2年前の記事
1年前の記事
1年後の記事
2017東京node学園祭の2日目に行ってきた
この記事は@kjunichiの2017年パーソナルアドベントカレンダーの2日目の記事です 。
背景
東京Node学園祭、今年も奥さんの許可が下りて、2日目に参加できました。昨年、一昨年は午後からの参加でしたが、 今年は2日目のみとはいえ、開始から参加できました。
参加したセッションなど
Angular2+ Authentication Tutorial with Auth0
前段の説明で、Passportを作ったメンバーが中心になって作った会社とのことで、自分もPassportをつかって、 Webベースのツイッタークライアントを自作して使ってるので、なんかすこしAuth0さんに親しみを覚えました。
タイトルはAngularとなっていましたが、当日はAngularではなく、Reactを使うとのことでしたが、 ほとんどReactの話はなかったような。。
ちょっと対象のリポジトリのURLが分からず、手元で、動かしながらお話を聞くことができなかったのと、 そもそも自分の英語力ではすべてを理解できなかった(通訳してくれる方がいたので、日本語では ある程度わかりましたが。。)。
それでも、認証、認可といった機能を外だしして、便利に使える、素晴らしいサービスだということが 分かりました。
自分で何かWebサービスを当てたら、早い段階でこのサービス使いたいと思いましたw。
Sharing is Caring… At Scale!
事前の公式のページには生粋のニューヨーカーと記述あり、これは、超早口の英語のリスニングが ためされる発表と思いきや、滅茶苦茶日本語が流暢でビックリ。
大規模なフロントエンドでのコンポーネント開発をコードの重複なく進めるには、 サンプルを集めたカタログ的なページをデザイナー向けに用意して、この中から使ってもらうように する工夫などが印象に残った。
data sketches: A Visualization a Month
大規模データの可視化のお話。 とんでもない領域を描画していて、パフォーマンスが低下してしまったのを 描画領域を狭めて改善させるといったことが聞けた。
JSON Schema Centralized Design
このお話が、全面的に自分の趣味で参加しているものの、もしかしたらSIer仕事でもWeb寄りの現在の仕事の 延長で、将来使えそうなお話という気がしました。
Real-world applications of hash functions
デンマークの鉄道と、日本の鉄道の比較のスライドが印象に残った。
ハッシュのお話で、WASMまで最後は出てきた。
Code And Learn
Node.js関連ではnode-ffiに以前プルリク出してマージされた経験はありますが、 Node.js本体へプルリクをさすことがこのセッション内で出来ました。 ちょっと不要なファイルをプルリクに含めてしまったり、スタッフの@about_hiroppyさんに gitコマンドでリカばって頂いたりお手数おかけしてしたりと、すんなりは行きませんでしたが、 最終的には無事マージされました!
After party
今年は、まったく知ってる方おらず、困ったなぁと、寿司を頬張りながら、徘徊して、 折角なので、今年も海外のスピーカの方とお話をしようと決め、 流暢な日本語と英語を交互に使ったプレゼンをされた@meyeriniさんに、日本語で声をかけて、 結局終始日本語お話しさせてらいました。
そこで、彼女は昨年日本でNode学園祭をやっていることを知り、昨年、来たかったのだそうですが、 時すでに遅く、1年待って、今年、どうしても日本に来たかったので、3本CFPを出して、その甲斐あって 声がかかり日本に来て発表出来て大変うれしかったとの話を聞くことができました。
また、日本が流暢な理由を尋ねたところ、日本の漫画とくに少女漫画に興味を持ち、そこから日本語を覚え、 上智大学に留学された経験もあるとのことでした。
あと、Node.jsではないですが、Rubyも彼女の口から出てきました。昨年お話した@mafintoshさんとお話したときにもRubyの話題が出てきて、ほんとにRubyは海外でも浸透しているのだなぁと感心しました。
会場の隅に置いてあったホワイトボードにさんのワークショップで話題になったであろうベジェ曲線の 解説らしきものが書いてあるのを眺めていたら、背後から、「○○さんですか?」と声を掛けられ、 振り返ると、見知らぬ方、しかし!一日目のVJをされていた@amagitakayosiさんでした!
実は以前
で記事に書いたように、プルリクを送ったことで、自分のことを覚えていてくれたようで、 会場で私のことを見つけて声をかけて頂けましたのでした。
実は自分も2日目も会場にいらっしているようなツイートを見つけていたので、 @amagitakayosiさんの ことを見つけようとは思ったものの、お会いしたことがないので、なかなかわからずにいたので、 まさか、向こうから声をかけてもらえるとはびっくりでしたが、お会いして、いろいろお話できて本当に良かったです。
おわりに
東京Node学園祭の関係者の皆様、今年も素晴らしいイベントをありがとうございました!
関連記事
Nが現れる素数をJuliaでやってみた
この記事は@kjunichiの2017年パーソナルアドベントカレンダーの1日目の記事です 。
これはすごい、どうやってるんだと、パッと見は思った。
を読んで、なんとなくJulia言語で試してたくなり、やってみた。
5が現れる素数を昼休みに恥ずかしいバグに悩まされながらも 計算で来た #julialng / “this five is prime number · GitHub” https://t.co/gJKRpEViM2
— kjunichi (@kjunichi) 2017年11月30日
Pkg.add("Primes") using Primes cnt=0 isPrime=false for a in 1:9 #println("a =", a) for b in 0:9 for c in 0:9 for d in 0:9 for ee in 0:9 for f in 0:9 for g in 0:9 for h in 0:9 for i in [1,3,5,7,9] str5 = "ABC000000000000000"* "005555555555555500"* "005555555555555500"* "005555000000000000"* "005555000000000000"* "000555555555500000"* "000555555555555000"* "000000000000555500"* "000000000000555500"* "005555555555555000"* "005555555555000000"* "DEF000000000000GHI" str5=replace(str5,"A",a) str5 = replace(str5, "B",b) str5 = replace(str5, "C",c) str5 = replace(str5, "D",d) str5 = replace(str5, "E",ee) str5 = replace(str5, "F",f) str5 = replace(str5, "G",g) str5 = replace(str5, "H",h) str5 = replace(str5, "A",a) str5 = replace(str5, "I",i) if isprime(parse(BigInt,str5)) #println(a,b,c,d,ee,f,g,h,i) println(str5) isPrime=true break end cnt=cnt+1 end if isPrime break end end if isPrime break end end if isPrime break end end if isPrime break end end if isPrime break end end if isPrime break end end if isPrime break end end if isPrime break end end #println(cnt)
005555555555555500
005555555555555500
005555000000000000
005555000000000000
000555555555500000
000555555555555000
000000000000555500
000000000000555500
005555555555555000
005555555555000000
000000000000000437
関連記事
- JulialangにHTTP2サーバーをさせたら
- IJuliaをHerokuの無料枠で動かした
- mruby-juliaでPythonもmrubyから呼び出せるようになった
- aobenchをjuliaでやってみた
- 1/7がつくる楕円をJulia言語でプロットする
- Julia言語で任意の点を散布図を描画するには
- Windows(MSVC)でmrubyからGPU対応のTensorflowを動かせた
- Juliaでaobenchを使って並列処理を試した その1
- JuliaでYoutuberを目指す