最終更新: 2017-10-13T21:42+0900
眠たくないですか? ラスタオペレーションをセットして領域を塗りつぶすだけの操作に比べてビットマップビットを操作する手間をかける価値があるだろうか。Windowsでの標準的な描画方法は、背景を選択領域(背景色)で、文字を選択領域(文字色)で塗るだけみたいだけど。どうして半透明? それともさらに手間をかけて半透明の選択領域を単色からグラデーションパターンにするぐらいやるんだろうか。AeroGlassがそんな風に微妙なパターンを入れてる。どうやったらグラデーションが表現できるのか知らんけど、ピクセル当たり 1バイトで表現できるなら GDIブラシでパターンを塗り込めておけるかも。
テキストの背景色と XORをとったときにユーザーの指定した色になるような色を使って排他的論理和をとってみたりするとどうなるだろう。コントラストを保ちつつ選択領域の全体的な色をコントロールできるのだろか。
やってみた。
//HBRUSH hBrush = ::CreateSolidBrush( SELECTEDAREA_RGB ); HBRUSH hBrush = ::CreateSolidBrush( selColorSetting.GetBackColor() ^ CTypeSupport(this, COLORIDX_TEXT).GetBackColor() ); // assuming SELECTEDAREA_ROP2 == XOR
わりと文字がつぶれる。つぶれないような色を選ぶと上左の画像のような淡い色になってしまい、だったら半透明でいいじゃない? 変更が一行で済むのだけが利点。半透明の方はざっと抜き出してもこんなに。
CreateCompatibleDC( hdc ); CreateCompatibleBitmap( hdc, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top ); SelectObject( hdcMem, hbmpSelected ); BitBlt( hdcMem, 0, 0, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top, hdc, rcClip.left, rcClip.top, SRCCOPY ); GetObject( hbmpSelected, sizeof bmpSelected, &bmpSelected ); GetDIBits( hdcMem, hbmpSelected, 0, bmpSelected.bmHeight, pBits, &bmpinfo, DIB_RGB_COLORS ); for (RGBQUAD* pQuad = pBits; pQuad < pBits + bmpSelected.bmWidth * copiedLines; ++pQuad) SetDIBits( hdcMem, hbmpSelected, 0, copiedLines, pBits, &bmpinfo, DIB_RGB_COLORS ); BitBlt( hdc, rcClip.left, rcClip.top, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top, hdcMem, 0, 0, SRCCOPY ); DeleteObject( hbmpSelected ); DeleteDC( hdcMem );
GetDIBits, for, SetDIBitsあたりがやばいかんじ(速度的に)。
半透明処理にすると、反転の反転で元通りみたいなことができなくなるのだよね。反転処理前のビットマップを保存しておかなければ戻せない。あと矩形選択で行っていた、リージョンを結合して差分をとって PaintRgn一発で選択解除と選択描画のできあがり、ということができない。矩形選択なんて四角を一個塗るだけで済むはずのものなのに……。クライアント領域をいくつかのレイヤーに分けたいなあ。背景<文字の後ろ(罫線など)<文字<文字の前(アンダーライン、対括弧強調など)<選択領域<キャレット みたいに。Z座標でなく更新頻度でわけるのもあり。半透明にすると他にも、左に選択範囲をのばしていくとキャレットの残像が次々増えていく問題が。くじけそう。きままにやるけど。
非効率的なのを承知で CViewSelect::DrawSelectAreaLine() で行っていた処理を CEditView::OnPaint() に委譲した。それが選択描画を取り消すのに一番簡単だったから。Vistaだと確認できないけど古い Windowsだとフリッカーがひどいかもしれない。気付いたのは検索を行ったときにカーソル行アンダーラインがちらつくことが増えたこと。範囲の拡大・縮小も遅い。<追記@2010-10-15>再描画する領域を最小限にする努力が必要。でも重なった二つの矩形が作る領域をどう扱ったものか(9つに分割して、左上↘右下、左下↗右上、左上↖右下、左下↙右上で網羅できるものなのか、もっと簡単にできるのか)、悩み中。</追記>
選択色指定(固定色or半透明)のお試し版がすでにあるとか。なんだよもう。ソース読も。
725 :名無しさん@お腹いっぱい。:2010/10/03(日) 03:45:30 ID:FVNsnn5V0 ちなみに、「下の全部」というタイトルで以下のような物も公開されている。 > 状態:アルファ > bin/pp-disable: skrw_ext13_bgimg_100929.zip Unicode版1.6.5.0 base r1827 > bin/pp-enable: skrw_ext13_bgimgpp_100929_pp.zip Unicode版1.6.5.0 base r1827 > 背景テストデータとini: bgimage 111KB > diff:skrw_ext12_to_ext13bgimgpp100929.zip 78KB ext12からの差分,テスト未整理コードあり > ext+背景表示+プロポーショナル > ClaerType対策に選択文字列の作画表示の実装を追加。OFF→従来のように反転,色指定→固定色,文字色=背景色→元の色と20%で色混合)で設定 > 改行文字の色指定を変更。ベース色<改行の指定色<検索色<選択色。 > pp-enableのほうだけプロポーショナルが使えます。その分動作はあやしいです。 > > r1827/100929/ext13+bgimg v0.4+ppfont v0.2(バージョン情報ではext12になってます) > 選択色指定:デフォルトで色指定になっています。色分けをOFFにすると戻ります。0幅表示未対応 > ・[ext/skrw_search_fast_v0_0]rev1827の大文字小文字変換対応。skr_toupperに切替 > ・[ext]DIFFのデフォルト設定色のRとBが反対だった(iniはBGR順でした)
プロポーショナルフォントが指定できるとメイリオが選べて嬉しい。次は Operaのようにブロック単位でフォントを指定したい。英字は Consolas、日本語はメイリオ、ひらがなは……、カタカナは……というように。
プロポーショナルフォント関連のあやしい動作を一つ発見 >skrw_ext13_bgimgpp_100929 矩形選択で文字のないところを右側に範囲を拡大していくとキャレットが 1pixelずつくらい移動するんだけど、このとき画面が横にスクロールするとルーラーが逆行する。7戻って15進むという具合につじつまは合うみたいだけど。改行の後ろの選択範囲の描画もずれる。
ソース読んだ。選択範囲の半透明処理って、「テキスト」「コメント」「URL」などなどの文字の色と背景色をずらすだけでできたらしい。なんだよもう(二度目)。
CRLFマークがはみだすことの対策もあった。3ピクセル出てるらしい。上の画像ではみだしを確認できるけど、みっともないもんね。改行マークが非表示だと選択範囲が右にちょっとはみ出して見えるのもみっともないと思ってるんだけどどうだろう。
WEB+DB PRESS Vol.54 - WebKit Quest 第5回を読んでる。フェイズはレイヤーより細かい区分。
paint()メソッドを呼び出す側は、何度もpaint()を呼び出します。その際、指定されるPaintPhaseは背景から前景へ推移します。
WebKitはフェーズの数だけ何度も Renderツリーをトラバースし、各フェーズを重ね描きすることでページの描画を行うのです(図5)
enum PaintPhaseのメンバーはこれで全部ではないけどこんなかんじ
レイヤーが必要な場面はこれより大局的な
エディタ領域の描画はフェイズで十分そうね。
いつもお世話になってます。<br>色の合成は、指定色で選択作画を書く→ここをみる→混ぜればできるのを思い出して追加の順だったので、ここを見なければ追加してないところでした。<br>改行記号のON/OFFに関係なく、背景色は指定色で表示されるため...<br>と思ったらdraw_2, trunk2では無視される。な、なんだって!<br>(しかも背景だけだろうと2桁)
後半の意味がわからないと思ったら、ANSI版では改行マークの表示・非表示に関係なく改行マークの背景色が塗られていた。ありえない……。