ViViは設定された1行の文字数で折り返しを行うレイアウトモードを実装しているので、
極端に長い論理行も折り返し表示することができます。
レイアウト行の各行は一つのクラス構造体 ClayoutLine で表されます。具体的には以下のように定義されています。
class CLayoutLine { public: int m_lgcLine; // 対応する論理行番号 int m_offset; // 対応する論理行の先頭からのオフセット ushort m_length; // 対応する論理行の文字のバイト数 ..... public: CLayoutLine(void); ~CLayoutLine(void); };レイアウト行の先頭文字の論理座標系による文字位置と、その行に含まれる文字列のバイト数を情報として持ちます。 ポインタではなく位置情報にしたのは、ドキュメントデータのデータ構造に依存しないようにするためです。 反面、レイアウト行から論理行への変換に若干のコスト、論理行からレイアウト行への変換にはかなりのコストを要するが、 いい方法を思い付かなかったので、このような構造にしました。ViViのパフォーマンスはそんなに悪くないので、 そんなに悪くない構造であろう(きっと)。
レイアウト情報全体は、上記のクラス構造体を双方向リンクで保持するクラス CViewLineMgr が管理します。 宣言は以下のような感じです。
typedef CList<CLayoutLine, CLayoutLine &> CViewLineList; class CViewLineMgr : public CViewLineList { ..... CDocLineMgr *m_docLineMgr; // 対応する行管理マネージャ public: // レイアウト座標系から論理座標系への変換関数 int layoutToLogical(int line); int layoutToLogical(int, int &); void layoutToLogical(STextPos *, const STextPosVw *); void layoutToLogical(STextPos *, int, int); void layoutToLogical(int &, int &, int, int); // 論理座標系からレイアウト座標系への変換関数 int logicalToLayout(int); void logicalToLayout(const STextPosVw *, int &, int &); void logicalToLayout(const STextPosVw *, STextPos *); ..... void doLayout(void); // レイアウト処理を行う };
ビューが画面にドキュメントテキストを表示する場合、レイアウトモードであれば、CViewLineMgr
の座標変換メソッドを用いて必要な座標変換を行います。また、CViewLineMgr はレイアウト処理を行うメソッド、
doLayout も持っています。すなわち、レイアウト処理に関するもろもろの下請け処理を行うクラスです。
CViewLineMgr, CDocLineMgr は CDocument の派生クラスである CViviDoc が保持し、CView の派生クラスである
CViviView からも利用されます。これらの関係を図示すると以下のようになります。
┏━━━━━━━┓ ┃ ┃ ┃ CViviView ┃ ┃ ┃ ┗━━━━━━━┛ ↑↑ ││ テキスト情報││レイアウト情報 ┌─────┘└─────┐ ┏━━━━━┿━━━━━━━━━━━━┿━━━━━┓ ┃ CViviDoc │ │ ┃ ┃ │ │ ┃ ┃┌────────┐ 参照 ┌────────┐┃ ┃│ │←───┤ │┃ ┃│ CDocLineMgr │ │ CViewLineMgr │┃ ┃│ │ │ │┃ ┃└────────┘ └────────┘┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━┛ |
Copyright (c) 1997 by Nobuhide Tsuda, All Right Reserved.
このホームページに関するご質問、ご要望、バグレポート等は
ntsuda@beam.or.jp
までメールをいただければ幸いです。