1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: font_TagProcessorBase.h
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: 31628 $
16 *---------------------------------------------------------------------------*/
17
18 #ifndef NW_FONT_TAGPROCESSORBASE_H_
19 #define NW_FONT_TAGPROCESSORBASE_H_
20
21 #include <nn/types.h>
22 #include <nw/ut/ut_Rect.h>
23
24 namespace nw {
25 namespace font {
26
27
28
29 template <typename CharType>
30 class TextWriterBase;
31
32
33 template <typename CharType>
34 struct PrintContext
35 {
36 TextWriterBase<CharType>* writer; //!< 文字列描画に使用しているTextWriterへのポインタ。
37 const CharType* str; //!< 描画中の文字列へのポインタ。
38 const f32 xOrigin; //!< 描画開始X座標。
39 const f32 yOrigin; //!< 描画開始Y座標。
40 u32 flags; //!< TextWriter::ContextFlag のOR。
41
PrintContextPrintContext42 PrintContext(
43 TextWriterBase<CharType>* aWriter,
44 const CharType* aStr,
45 const f32 aXOrigin,
46 const f32 aYOrigin,
47 u32 aFlags
48 )
49 : writer(aWriter),
50 str(aStr),
51 xOrigin(aXOrigin),
52 yOrigin(aYOrigin),
53 flags(aFlags)
54 {}
55 };
56
57 //---------------------------------------------------------------------------
58 //! @brief グリフグループが定義されているフォントリソースを扱うクラスです。
59 //!
60 //! @tparam CharType 文字の型。
61 //---------------------------------------------------------------------------
62 template <typename CharType>
63 class TagProcessorBase
64 {
65 public:
66 /* ------------------------------------------------------------------------
67 型
68 ------------------------------------------------------------------------ */
69
70 //! 呼び出し元 (TextWriter) が行うべき処理の列挙子です。
71 enum Operation
72 {
73 //! @brief 行頭では次の文字との間に文字間を開けません。
74 //! 行頭以外の位置では次の文字との間に文字間を開けます。
75 //!
76 OPERATION_DEFAULT,
77
78 //! @brief 行頭以外の位置でタグ処理が行われた場合、
79 //! デフォルトでは次の文字との間に文字間を空けますが、
80 //! これを空けないようにします。
81 //!
82 OPERATION_NO_CHAR_SPACE,
83
84 //! @brief 行頭でタグ処理が行われた場合、
85 //! デフォルトでは次の文字との間に文字間を空けませんが、
86 //! これを空けるようにします。
87 //!
88 OPERATION_CHAR_SPACE,
89
90 //! @brief 改行時に必要な処理のうち X 座標の調整のみを行います。
91 //! Y 座標の調整は行いません。
92 //! また、次の文字との間に文字間を開けません。
93 //!
94 OPERATION_NEXT_LINE,
95
96 //! @brief 文字列の途中で文字列描画を終了する場合に使用します。
97 //!
98 OPERATION_END_DRAW,
99
100 //! @details :private
101 NUM_OF_OPERATION
102 };
103
104 /* ------------------------------------------------------------------------
105 関数
106 ------------------------------------------------------------------------ */
107
108 //! @name コンストラクタ / デストラクタ
109 //@{
110
111 //! コンストラクタです。
TagProcessorBase()112 TagProcessorBase() {}
113
114
115 //! デストラクタです。
~TagProcessorBase()116 virtual ~TagProcessorBase() {}
117
118
119 //@}
120
121
122 //! @name タグ処理
123 //@{
124
125 //! @brief タグに従って処理を行います。
126 //!
127 //! @param[in] code タグ処理の起点となった制御文字コード。(0x0000 ~ 0x001F)
128 //! @param[in,out] pContext 文字列の描画状態情報へのポインタ。
129 //!
130 //! @return 呼び出し元 (TextWriter) が行うべき処理を返します。
131 //!
Process(u16 code,PrintContext<CharType> * pContext)132 virtual Operation Process(
133 u16 code,
134 PrintContext<CharType>* pContext
135 )
136 {
137 NN_ASSERT(code < ' ');
138 NN_POINTER_ASSERT(pContext);
139
140 switch (code)
141 {
142 case '\n':
143 ProcessLinefeed(pContext);
144 return OPERATION_NEXT_LINE;
145
146 case '\t':
147 ProcessTab(pContext);
148 return OPERATION_NO_CHAR_SPACE;
149
150 default:
151 // nothing to do;
152 break;
153 }
154
155 return OPERATION_DEFAULT;
156 }
157
158 //! @brief タグの影響範囲を計算します。
159 //!
160 //! @param[out] pRect タグの影響範囲を格納する矩形構造体へのポインタ。
161 //! @param[in] code タグ処理の起点となった制御文字コード。(0x0000 ~ 0x001F)
162 //! @param[in,out] pContext 文字列の描画状態情報へのポインタ。
163 //!
164 //! @return 呼び出し元 (TextWriter) が行うべき処理を返します。
165 //! 同じタグに対して Process() 関数が返す値と同じ値を返すべきです。
166 //!
CalcRect(ut::Rect * pRect,u16 code,PrintContext<CharType> * pContext)167 virtual Operation CalcRect(
168 ut::Rect* pRect,
169 u16 code,
170 PrintContext<CharType>* pContext
171 )
172 {
173 NN_POINTER_ASSERT(pRect);
174 NN_ASSERT(code < ' ');
175 NN_POINTER_ASSERT(pContext);
176
177 switch (code)
178 {
179 case '\n':
180 {
181 TextWriterBase<CharType>& writer = *pContext->writer;
182
183 pRect->right = writer.GetCursorX();
184 pRect->top = writer.GetCursorY();
185
186 ProcessLinefeed(pContext);
187
188 pRect->left = writer.GetCursorX();
189
190 // ProcessLinefeed はカーソルを移動するだけで次の行の高さは含まれていないので
191 // 次の行の高さとして FontHeight を足す。
192 pRect->bottom = writer.GetCursorY() + pContext->writer->GetFontHeight();
193
194 pRect->Normalize();
195 }
196 return OPERATION_NEXT_LINE;
197
198 case '\t':
199 {
200 TextWriterBase<CharType>& writer = *pContext->writer;
201
202 pRect->left = writer.GetCursorX();
203
204 ProcessTab(pContext);
205
206 pRect->right = writer.GetCursorX();
207 pRect->top = writer.GetCursorY();
208 pRect->bottom = pRect->top + writer.GetFontHeight();
209
210 pRect->Normalize();
211 }
212 return OPERATION_NO_CHAR_SPACE;
213
214 default:
215 // nothing to do;
216 break;
217 }
218
219 return OPERATION_DEFAULT;
220 }
221
222 //@}
223
224 private:
225 /* ------------------------------------------------------------------------
226 型
227 ------------------------------------------------------------------------ */
228 typedef PrintContext<CharType> ContextType;
229
230 void ProcessLinefeed(ContextType* pContext);
231 void ProcessTab(ContextType* pContext);
232 };
233
234 /* ------------------------------------------------------------------------
235 private タグ処理
236 ------------------------------------------------------------------------ */
237 template <typename CharType>
238 void
ProcessLinefeed(ContextType * pContext)239 TagProcessorBase<CharType>::ProcessLinefeed(ContextType* pContext)
240 {
241 NN_POINTER_ASSERT(pContext);
242
243 TextWriterBase<CharType>& writer = *pContext->writer;
244
245 const f32 x = pContext->xOrigin;
246 const f32 y = writer.GetCursorY() + writer.GetLineHeight();
247
248 writer.SetCursor(x, y);
249 }
250
251 template <typename CharType>
252 void
ProcessTab(ContextType * pContext)253 TagProcessorBase<CharType>::ProcessTab(ContextType* pContext)
254 {
255 NN_POINTER_ASSERT(pContext);
256
257 TextWriterBase<CharType>& writer = *pContext->writer;
258 const int tabWidth = writer.GetTabWidth();
259
260 if (tabWidth > 0)
261 {
262 const f32 aCharWidth = writer.IsWidthFixed() ? writer.GetFixedWidth(): writer.GetFontWidth();
263 const f32 dx = writer.GetCursorX() - pContext->xOrigin;
264 const f32 tabPixel = tabWidth * aCharWidth;
265 const int numTab = static_cast<int>(dx / tabPixel) + 1;
266 const f32 x = pContext->xOrigin + tabPixel * numTab;
267
268 writer.SetCursorX(x);
269 }
270 }
271
272 } // namespace font
273 } // namespace nw
274
275 #endif // NW_FONT_TAGPROCESSORBASE_H_
276