17:55-18:48 @fonc@ bottle でテニスゲーム 20:09-20:37 @fonc@ bottle でテニスゲーム 20:40-21:33 @rest@ 21:34-21:43 @read@ 21:44- @fonc@ bunnu に || の実装 - インクリメンタルサーチ - jolt2 対応 % ./idc -k -I../objects -I../jolt2 jolt2.st ../jolt2/jolt.a todo: || と && の実装 todo: editor を Editor プロトタイプにする。 todo: インスペクト todo: sefFontSize を必ず textExtents: の前に行うよう保証。 todo: table method todo done: 最近の jolt2 に合わせる。 todo done: 文字が無いときにキーを受け付けない件 todo pending: 表示文字幅と計算文字幅が違う。 todo done: フォンと指定 API todo done: undo todo done: binary search を使って compose を速くする。 todo done: TextLineBuffer 最適化 todo done: compose 最適化 && damage rectangle todo done: compose しなおすとちゃんと動く todo done: マウスクリック縦座標おかしい。 todo done: compose の際最後が改行の時空のデータを一つ入れる。 todo done: test 通す todo done: getPosition: をすべて TextView で行う。 todo done: カーソル移動 todo done: 一か八か cairo_text_extents () でやってみる。 = windows でコンパイル libiconv を mingw のページからダウンロードして / に解凍 = slotnames について String の構造 = benchmark 目標 $ time ./bottle Editor.st ./bottle Editor.st 1.71s user 0.05s system 83% cpu 2.096 total ./bottle Editor.st 54.51s user 0.19s system 98% cpu 55.604 total ./bottle Editor.st 52.49s user 0.14s system 99% cpu 53.125 total ./bottle Editor.st 7.64s user 0.07s system 95% cpu 8.108 total ./bottle Editor.st 3.39s user 0.04s system 85% cpu 3.995 total 目標 % time ./bottle _cairo.st takashi@gokiburi:~/src/.../function/bottle% ./bottle _cairo.st 1.78s user 0.03s system 84% cpu 2.140 total ./bottle _cairo.st 6.55s user 0.05s system 94% cpu 6.982 total ./bottle _cairo.st 3.14s user 0.03s system 91% cpu 3.481 total = *[bottle] テキスト回りこみのタイミング - 更新 - レイアウトすぐ行う更新に対して一回だけ。addDirtyText: - 表示ちょっと後で何度行ってもよい。 = *[bottle] Gtk, Cairo, Pango のテキスト回りこみ todo done: イベントに translation を仕込む。 todo done: dirty rectangle を signal で todo done: container の削除 todo done: 外部からテキストを変更した場合はどうなる? せっかく Squeak でテキスト回りこみがどうなってるか調べたんだけど、 bottle では Cairo のフォントをそのまま使っているので同じ技が使えない。 問題は、Cairo オブジェクトをどこで保持するか。現在メインループだけが Cairo を持っており大変美しい。しかし入力後レイアウトの変更時にフォント サイズが必要なので、そこで Cairo が要る。 現在のしくみ - 入力イベント -- damage rectangle 記録 - 出力処理 -- damage rectangle 出力 必要な仕組み - 入力イベント -- damage rectangle 記録 -- テキストレイアウト - 出力処理 関数的処理 - イベント入力 - 画面情報出力 挿入位置の変更 file:///home/takashi/src/cairo-1.4.14/doc/public/html/index.html (shell-command "find ~/src/cairo-1.4.14/src -name '*.[chCH]' -print | etags -o ~/src/cairo-1.4.14/TAGS -") http://www.mail-archive.com/gtk-i18n-list@gnome.org/msg00948.html http://wiki.services.openoffice.org/wiki/Mac_OS_X_Porting_-_Comparison_to_Toolkit_Ports http://lists.cairographics.org/archives/cairo/2007-February/009452.html *[bottle] Squeak の ParagraphEditor 再び テキストをに画面表示するために、長く伸びた行を画面に収まるよう途中で回り込ませる処理が必要だ。そこん所を調べてみた。表示関連をデバッガで追いかけるには下手にブレークポイントを仕込めないので、注意深く実験。 - 描画のデバッグ -- Workspace を開ける -- 同じ所で何度かハロを出し TextMorphForEditView をインスペクト -- インスペクタで self drawOn: Display getCanvas をデバッグ - 編集のデバッグ -- ParagraphEditor>>printIt (Crtl+Shift+I) などの致命的でない機能に halt を仕込む。 行の横幅を決めるには、一文字一文字の横幅を順に足して行って、幅が一杯になるまで埋めなくてはいけない。解析の単位はスペースやタブ、改行などの空白文字 scanCharactersFrom:to:in:rightX:stopConditions:kern: CompositionScanner が解析結果に応じて適切な処理をする。例えば物理改行の前にスペースがあった場合、 CompositionScanner はそこですぐ改行せずに、以前のスペース位置で改行を行う。 print it から横幅を決めるまでのスタックフレーム - CompositionScanner(CharacterScanner)>>basicScanCharactersFrom:to:in:rightX:stopConditions:kern: - CompositionScanner(CharacterScanner)>>scanCharactersFrom:to:in:rightX:stopConditions:kern: - CompositionScanner>>composeFrom:inRectangle:firstLine:leftSide:rightSide: - TextComposer>>composeEachRectangleIn: - TextComposer>>composeAllRectangles: - TextComposer>>composeLinesFrom:to:delta:into:priorLines:atY:textStyle:text:container:wantsColumnBreaks: - TextComposer>>composeAllLines - TextComposer>>composeLinesFrom:to:delta:into:priorLines:atY:textStyle:text:container:wantsColumnBreaks: - MultiNewParagraph(NewParagraph)>>composeLinesFrom:to:delta:into:priorLines:atY: - MultiNewParagraph(NewParagraph)>>recomposeFrom:to:delta: - MultiNewParagraph(NewParagraph)>>replaceFrom:to:with:displaying: - TextMorphEditor>>zapSelectionWith: - TextMorphEditor(ParagraphEditor)>>replace:with:and: - TextMorphEditor(ParagraphEditor)>>insertAndSelect:at: - TextMorphEditor(ParagraphEditor)>>afterSelectionInsertAndSelect: - TextMorphEditor(ParagraphEditor)>>printIt 実際の描画は displayLine:offset:leftInRun: で行われるが、レイアウトと同様 basicScanCharactersFrom:to:in:rightX:stopConditions:kern: で空白文字の処理が行われる。 drawOn: から表示までのスタックフレーム。 - MultiDisplayScanner(MultiCharacterScanner)>>basicScanCharactersFrom:to:in:rightX:stopConditions:kern: - MultiDisplayScanner(MultiCharacterScanner)>>scanCharactersFrom:to:in:rightX:stopConditions:kern: - MultiDisplayScanner>>displayLine:offset:leftInRun: - MultiNewParagraph>>displayOn:using:at: - FormCanvas>>paragraph:bounds:color: - TextMorphForEditView(TextMorph)>>drawOn: まとめ。表示処理を、Squeak では次の二つに分けて行っている。 - 更新時整形 MultiNewParagraph(NewParagraph)>>recomposeFrom:to:delta: など -- 文字列の編集の度に呼ばれる。 -- TextLine (一行の文字数と座標情報)オブジェクトが生成される。 - 表示 MultiDisplayScanner>>displayLine:offset:leftInRun: -- 整形した文字列を表示する。 段落、単語、文字というような階層構造のあるテキストの表示を状態マシンを使って文字単位で行っているために多少ややこしい。