1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     font_TagProcessorBase.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 13145 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nn/assert.h>
19 #include <nw/font/font_TagProcessorBase.h>
20 #include <nw/font/font_TextWriterBase.h>
21 
22 
23 namespace nw {
24 namespace font {
25 
26 
27 
28 
29 
30 
31 /* ------------------------------------------------------------------------
32         コンストラクタ/デストラクタ
33    ------------------------------------------------------------------------ */
34 
35 template <typename CharType>
TagProcessorBase()36 TagProcessorBase<CharType>::TagProcessorBase()
37 {
38 }
39 
40 template <typename CharType>
~TagProcessorBase()41 TagProcessorBase<CharType>::~TagProcessorBase()
42 {
43 }
44 
45 
46 
47 
48 /* ------------------------------------------------------------------------
49         タグ処理
50    ------------------------------------------------------------------------ */
51 
52 template <typename CharType>
53 typename TagProcessorBase<CharType>::Operation
Process(u16 code,ContextType * pContext)54 TagProcessorBase<CharType>::Process(
55     u16             code,
56     ContextType*    pContext
57 )
58 {
59     NN_ASSERT(code < ' ');
60     NN_POINTER_ASSERT(pContext);
61 
62     switch (code)
63     {
64     case '\n':
65         ProcessLinefeed(pContext);
66         return OPERATION_NEXT_LINE;
67 
68     case '\t':
69         ProcessTab(pContext);
70         return OPERATION_NO_CHAR_SPACE;
71 
72     default:
73         // nothing to do;
74         break;
75     }
76 
77     return OPERATION_DEFAULT;
78 }
79 
80 template <typename CharType>
81 typename TagProcessorBase<CharType>::Operation
CalcRect(ut::Rect * pRect,u16 code,ContextType * pContext)82 TagProcessorBase<CharType>::CalcRect(
83     ut::Rect*       pRect,
84     u16             code,
85     ContextType*    pContext
86 )
87 {
88     NN_POINTER_ASSERT(pRect);
89     NN_ASSERT(code < ' ');
90     NN_POINTER_ASSERT(pContext);
91 
92     switch (code)
93     {
94     case '\n':
95         {
96             TextWriterBase<CharType>& writer = *pContext->writer;
97 
98             pRect->right    = writer.GetCursorX();
99             pRect->top      = writer.GetCursorY();
100 
101             ProcessLinefeed(pContext);
102 
103             pRect->left     = writer.GetCursorX();
104 
105             // ProcessLinefeed はカーソルを移動するだけで次の行の高さは含まれていないので
106             // 次の行の高さとして FontHeight を足す。
107             pRect->bottom   = writer.GetCursorY() + pContext->writer->GetFontHeight();
108 
109             pRect->Normalize();
110         }
111         return OPERATION_NEXT_LINE;
112 
113     case '\t':
114         {
115             TextWriterBase<CharType>& writer = *pContext->writer;
116 
117             pRect->left     = writer.GetCursorX();
118 
119             ProcessTab(pContext);
120 
121             pRect->right    = writer.GetCursorX();
122             pRect->top      = writer.GetCursorY();
123             pRect->bottom   = pRect->top + writer.GetFontHeight();
124 
125             pRect->Normalize();
126         }
127         return OPERATION_NO_CHAR_SPACE;
128 
129     default:
130         // nothing to do;
131         break;
132     }
133 
134     return OPERATION_DEFAULT;
135 }
136 
137 
138 
139 
140 /* ------------------------------------------------------------------------
141         private タグ処理
142    ------------------------------------------------------------------------ */
143 template <typename CharType>
144 void
ProcessLinefeed(ContextType * pContext)145 TagProcessorBase<CharType>::ProcessLinefeed(ContextType* pContext)
146 {
147     NN_POINTER_ASSERT(pContext);
148 
149     TextWriterBase<CharType>& writer = *pContext->writer;
150 
151     const f32 x   = pContext->xOrigin;
152     const f32 y   = writer.GetCursorY() + writer.GetLineHeight();
153 
154     writer.SetCursor(x, y);
155 }
156 
157 template <typename CharType>
158 void
ProcessTab(ContextType * pContext)159 TagProcessorBase<CharType>::ProcessTab(ContextType* pContext)
160 {
161     NN_POINTER_ASSERT(pContext);
162 
163     TextWriterBase<CharType>& writer = *pContext->writer;
164     const int tabWidth = writer.GetTabWidth();
165 
166     if (tabWidth > 0)
167     {
168         const f32 aCharWidth  = writer.IsWidthFixed() ? writer.GetFixedWidth(): writer.GetFontWidth();
169         const f32 dx          = writer.GetCursorX() - pContext->xOrigin;
170         const f32 tabPixel    = tabWidth * aCharWidth;
171         const int numTab      = static_cast<int>(dx / tabPixel) + 1;
172         const f32 x           = pContext->xOrigin + tabPixel * numTab;
173 
174         writer.SetCursorX(x);
175     }
176 }
177 
178 
179 
180 
181 /* ------------------------------------------------------------------------
182         明示的実体化
183    ------------------------------------------------------------------------ */
184 
185 template class TagProcessorBase<char>;
186 template class TagProcessorBase<wchar_t>;
187 
188 
189 }   // namespace font
190 }   // namespace nw
191