1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_CharWriter.h
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: 25674 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_CTR_FONT_CHAR_WRITER_H_
17 #define NN_FONT_CTR_FONT_CHAR_WRITER_H_
18 
19 // 左上原点
20 #define COORDINATE_LT 1
21 
22 #include <cstddef>
23 #include <cstdio>
24 #include <GLES2/gl2.h>
25 #include <nn/types.h>
26 #include <nn/math.h>
27 #include <nn/util/util_Color.h>
28 #include <nn/font/font_Font.h>
29 #include <nn/font/CTR/font_TextWriterResource.h>
30 #include <nn/font/font_Stopwatch.h>
31 
32 // 文字描画用シェーダバイナリファイル名
33 #define NW_FONT_SHADERBINARY            L"nwfont_TextWriterShader.shbin"
34 #define NW_FONT_RECTDRAWER_SHADERBINARY L"nwfont_RectDrawerShader.shbin"
35 
36 namespace nn {
37 namespace font {
38 namespace CTR {
39 
40 struct DispStringBuffer;
41 
42 //---------------------------------------------------------------------------
43 //! @brief        Fontクラスを用いて文字の描画を行うためのクラスです。
44 //---------------------------------------------------------------------------
45 class CharWriter
46 {
47 public:
48     /* ------------------------------------------------------------------------
49 50        ------------------------------------------------------------------------ */
51 
52     //! グラデーションの種類を表す enum です。
53     enum GradationMode
54     {
55         GRADMODE_NONE,                          //!< グラデーションなし
56         GRADMODE_H,                             //!< 水平方向グラデーション
57         GRADMODE_V,                             //!< 垂直方向グラデーション
58 
59         NUM_OF_GRADMODE
60     };
61 
62 
63 
64     /* ------------------------------------------------------------------------
65             定数
66        ------------------------------------------------------------------------ */
67     static const u32 DEFAULT_COLOR_MAPPING_MIN = 0x00000000UL;
68     static const u32 DEFAULT_COLOR_MAPPING_MAX = 0xFFFFFFFFUL;
69 
70 
71     /* ------------------------------------------------------------------------
72             関数
73        ------------------------------------------------------------------------ */
74 
75     //! @name コンストラクタ/デストラクタ
76     //@{
77 
78     //! コンストラクタです。
79                         CharWriter();
80 
81     //! デストラクタです。
82                         ~CharWriter();
83 
84     //@}
85 
86     //! @name フォント
87     //@{
88 
89     //! @brief      フォントを設定します。
90     //!
91     //! @param[in]  pFont  新しく設定するフォントへのポインタ。
92     //!
SetFont(const Font * pFont)93     void                SetFont(const Font* pFont)  { m_pFont = pFont; }
94 
95     //! @brief      フォントを取得します。
96     //!
97     //! @return     フォントが設定されている場合にはフォントへのポインタを返します。
98     //!             設定されていない場合には NULL を返します。
99     //!
GetFont()100     const Font*         GetFont() const             { return m_pFont; }
101 
102     //@}
103 
104     //! @name 文字描画準備
105     //@{
106 
107     //! 文字描画のための準備を行います。
108     void                SetupGX();
109 
110     //! 描画設定の後処理を行います。
FinalizeGX()111     static void         FinalizeGX()
112     {
113         TextWriterResource::FinalizeGX();
114     }
115 
116     //@}
117 
118     //! @name グリフ色の線形変換
119     //@{
120 
121     //! @brief      文字描画時のグリフカラーの線形変換を設定します。
122     //!
123     //! @param[in]  min  各成分についての 0 の変換後の値。
124     //! @param[in]  max  各成分についての 255 の変換後の値。
125     //!
SetColorMapping(util::Color8 min,util::Color8 max)126     void                SetColorMapping(
127                             util::Color8  min,
128                             util::Color8  max
129     )
130     {
131         m_ColorMapping.min = min;
132         m_ColorMapping.max = max;
133     }
134 
135     //! @brief      グリフカラーの線形変換における各成分の 0 の変換後の値を取得します。
136     //!
137     //! @return     グリフカラーの線形変換における各成分の 0 の変換後の値を返します。
138     //!
GetColorMappingMin()139     const util::Color8  GetColorMappingMin() const { return m_ColorMapping.min; }
140 
141     //! @brief      グリフカラーの線形変換における各成分の 255 の変換後の値を取得します。
142     //!
143     //! @return     グリフカラーの線形変換における各成分の 255 の変換後の値を返します。
144     //!
GetColorMappingMax()145     const util::Color8  GetColorMappingMax() const { return m_ColorMapping.max; }
146 
147     //! 文字描画時のグリフカラーの線形変換を行わないように設定します。
ResetColorMapping()148     void                ResetColorMapping()
149     {
150         SetColorMapping(DEFAULT_COLOR_MAPPING_MIN, DEFAULT_COLOR_MAPPING_MAX);
151     }
152 
153     //@}
154 
155     //! @name 文字色/グラデーション
156     //@{
157 
158     //! @brief      文字描画時の追加のアルファ値を設定します。
159     //!
160     //! @param[in]  alpha  新しく設定する追加のアルファ値。
161     //!
SetAlpha(u8 alpha)162     void                SetAlpha(u8 alpha)
163     {
164         m_Alpha = alpha;
165     }
166 
167     //文字描画時の追加のアルファ値を取得します。
168 
169     //! @brief      文字描画時の追加のアルファ値を取得します。
170     //!
171     //! @return     追加のアルファ値を返します。
172     //!
GetAlpha()173     u8                  GetAlpha() const    { return m_Alpha; }
174 
175     //! @brief      グラデーションモードを設定します。
176     //!
177     //! @param[in]  mode    新しく設定するグラデーションモード。
178     //!
SetGradationMode(GradationMode mode)179     void                SetGradationMode(GradationMode mode)
180     {
181         NN_FONT_MINMAX_ASSERT(mode, GRADMODE_NONE, NUM_OF_GRADMODE - 1);
182         m_GradationMode = mode;
183         UpdateVertexColor();
184     }
185 
186     //! @brief      グラデーションモードを取得します。
187     //!
188     //! @return     グラデーションモードを返します。
189     //!
GetGradationMode()190     GradationMode       GetGradationMode() const    { return m_GradationMode; }
191 
192     //! @brief      文字色またはグラデーション色を設定します。
193     //!
194     //! @param[in]  color  文字色。
195     //!
SetTextColor(util::Color8 color)196     void                SetTextColor(util::Color8 color)
197     {
198         m_TextColors[internal::TEXTCOLOR_START] = color;
199         UpdateVertexColor();
200     }
201 
202     //! @brief      文字色またはグラデーション色を設定します。
203     //!
204     //! @param[in]  start  グラデーション開始色。
205     //! @param[in]  end    グラデーション終了色。
206     //!
SetTextColor(util::Color8 start,util::Color8 end)207     void                SetTextColor(
208                             util::Color8  start,
209                             util::Color8  end
210     )
211     {
212         m_TextColors[internal::TEXTCOLOR_START] = start;
213         m_TextColors[internal::TEXTCOLOR_END  ] = end;
214         UpdateVertexColor();
215     }
216 
217     //! @brief      文字色を取得します。
218     //!
219     //! @return     文字色を返します。
220     //!
GetTextColor()221     const util::Color8   GetTextColor() const           { return m_TextColors[internal::TEXTCOLOR_START]; }
222 
223     //! @brief      グラデーション開始色を取得します。
224     //!
225     //! @return     グラデーション開始色を返します。
226     //!
GetGradationStartColor()227     const util::Color8   GetGradationStartColor() const { return m_TextColors[internal::TEXTCOLOR_START]; }
228 
229     //! @brief      グラデーション終了色を取得します。
230     //!
231     //! @return     グラデーション終了色を返します。
232     //!
GetGradationEndColor()233     const util::Color8   GetGradationEndColor() const   { return m_TextColors[internal::TEXTCOLOR_END]; }
234 
235     //@}
236 
237     //! @name 文字の拡大縮小
238     //@{
239 
240     //! @brief      文字の拡大率を指定します。
241     //!
242     //! @param[in]  hScale  横方向拡大率。
243     //! @param[in]  vScale  縦方向拡大率。
244     //!
SetScale(f32 hScale,f32 vScale)245     void                SetScale(
246                             f32 hScale,
247                             f32 vScale
248     )
249     {
250         m_Scale.x = hScale;
251         m_Scale.y = vScale;
252     }
253 
254     //! @brief      文字の拡大率を指定します。
255     //!
256     //! @param[in]  hvScale 拡大率。
257     //!
SetScale(f32 hvScale)258     void                SetScale(f32 hvScale)
259     {
260         m_Scale.x = hvScale;
261         m_Scale.y = hvScale;
262     }
263 
264     //! @brief  文字の横方向の拡大率を取得します。
265     //!
266     //! @return 文字の横方向の拡大率を返します。
267     //!
GetScaleH()268     f32                 GetScaleH() const   { return m_Scale.x; }
269 
270     //! @brief  文字の縦方向の拡大率を取得します。
271     //!
272     //! @return 文字の縦方向の拡大率を返します。
273     //!
GetScaleV()274     f32                 GetScaleV() const   { return m_Scale.y; }
275 
276     //! @brief      文字のサイズを指定します。
277     //!
278     //! @param[in]  width   拡大後のセルの幅。
279     //! @param[in]  height  拡大後のセルの高さ。
280     //!
281     void                SetFontSize(
282                             f32 width,
283                             f32 height);
284 
285     //! @brief      文字のサイズを指定します。
286     //!
287     //! @param[in]  height  拡大後のセルの高さ。
288     //!
289     void                SetFontSize(f32 height);
290 
291     //! @brief      拡大適用後のセル幅を取得します。
292     //!
293     //! @return     フォントが設定されている場合は拡大適用後のセル幅をピクセル単位で取得します。
294     //!             フォントが設定されていない場合の返り値は未定義です。
295     //!
296     f32                 GetFontWidth() const;
297 
298     //! @brief      拡大適用後のセル高さを取得します。
299     //!
300     //! @return     フォントが設定されている場合は拡大適用後のセル高さをピクセル単位で取得します。
301     //!             フォントが設定されていない場合の返り値は未定義です。
302     //!
303     f32                 GetFontHeight() const;
304 
305     //! @brief      拡大適用後のアセントを取得します。
306     //!
307     //! @return     拡大適用後のアセントを返します。
308     //!
309     f32                 GetFontAscent() const;
310 
311     //! @brief      拡大適用後のディセントを取得します。
312     //!
313     //! @return     拡大適用後のディセントを返します。
314     //!
315     f32                 GetFontDescent() const;
316 
317     //@}
318 
319     //! @name 等幅描画
320     //@{
321 
322     //! @brief      強制等幅描画を行うように設定します。
323     //!
324     //! @param[in]  isFixed 強制等幅描画を行うのであれば true を指定します。
325     //!
EnableFixedWidth(bool isFixed)326     void                EnableFixedWidth(bool isFixed)  { m_IsWidthFixed = isFixed; }
327 
328     //! @brief  強制等幅描画を行うかどうかを取得します。
329     //!
330     //! @return 強制等幅描画を行う場合は true を、行わない場合は false を返します。
331     //!
IsWidthFixed()332     bool                IsWidthFixed() const            { return m_IsWidthFixed; }
333 
334     //! @brief      強制等幅描画の文字幅を指定します。
335     //!
336     //! @param[in]  width   新しい等幅描画幅。
337     //!
SetFixedWidth(f32 width)338     void                SetFixedWidth(f32 width)        { m_FixedWidth = width; }
339 
340     //! @brief      強制等幅描画の文字幅を取得します。
341     //!
342     //! @return     強制等幅描画の文字幅を返します。
343     //!
GetFixedWidth()344     f32                 GetFixedWidth() const           { return m_FixedWidth; }
345 
346     //@}
347 
348     //! @name 文字描画
349     //@{
350 
351     //! @brief      文字を描画します。
352     //!
353     //! @param[in]  code    描画する文字の文字コード。
354     //!
355     //! @return     描画した文字の文字幅を返します。
356     //!
357     f32                 Print(CharCode code);
358 
359     //! @brief      グリフを描画します。
360     //!
361     //! @param[in]  glyph   描画する文字のグリフデータ。
362     //!
363     void                DrawGlyph(const Glyph& glyph);
364 
365     //@}
366 
367     //! @name カーソル
368     //@{
369 
370     //! @brief      カーソル位置を指定した新しい座標に設定します。
371     //!
372     //! @param[in]  x   カーソルの新しい X 座標。
373     //! @param[in]  y   カーソルの新しい Y 座標。
374     //!
SetCursor(f32 x,f32 y)375     void                SetCursor(
376                             f32 x,
377                             f32 y
378     )
379     {
380         m_CursorPos.x = x;
381         m_CursorPos.y = y;
382     }
383 
384     //! @brief      カーソル位置を指定した新しい座標に設定します。
385     //!
386     //! @param[in]  x   カーソルの新しい X 座標。
387     //! @param[in]  y   カーソルの新しい Y 座標。
388     //! @param[in]  z   カーソルの新しい Z 座標。
389     //!
SetCursor(f32 x,f32 y,f32 z)390     void                SetCursor(
391                             f32 x,
392                             f32 y,
393                             f32 z
394     )
395     {
396         m_CursorPos.x = x;
397         m_CursorPos.y = y;
398         m_CursorPos.z = z;
399     }
400 
401     //! @brief      カーソルを現在位置から指定された差分だけ移動します。
402     //!
403     //! @param[in]  dx  X 軸方向のカーソル移動量。
404     //! @param[in]  dy  Y 軸方向のカーソル移動量。
405     //!
MoveCursor(f32 dx,f32 dy)406     void                MoveCursor(
407                             f32 dx,
408                             f32 dy
409     )
410     {
411         m_CursorPos.x += dx;
412         m_CursorPos.y += dy;
413     }
414 
415     //! @brief      カーソルを現在位置から指定された差分だけ移動します。
416     //!
417     //! @param[in]  dx  X 軸方向のカーソル移動量。
418     //! @param[in]  dy  Y 軸方向のカーソル移動量。
419     //! @param[in]  dz  Z 軸方向のカーソル移動量。
420     //!
MoveCursor(f32 dx,f32 dy,f32 dz)421     void                MoveCursor(
422                             f32 dx,
423                             f32 dy,
424                             f32 dz
425     )
426     {
427         m_CursorPos.x += dx;
428         m_CursorPos.y += dy;
429         m_CursorPos.z += dz;
430     }
431 
432     //! @brief      カーソルの X 座標を設定します。
433     //!
434     //! @param[in]  x   カーソルの新しい X 座標。
435     //!
SetCursorX(f32 x)436     void                SetCursorX(f32 x)           { m_CursorPos.x = x; }
437 
438     //! @brief      カーソルの Y 座標を設定します。
439     //!
440     //! @param[in]  y   カーソルの新しい Y 座標。
441     //!
SetCursorY(f32 y)442     void                SetCursorY(f32 y)           { m_CursorPos.y = y; }
443 
444     //! @brief      カーソルの Z 座標を設定します。
445     //!
446     //! @param[in]  z   カーソルの新しい Z 座標。
447     //!
SetCursorZ(f32 z)448     void                SetCursorZ(f32 z)           { m_CursorPos.z = z; }
449 
450     //! @brief      カーソルを現在位置から指定された差分だけ移動します。
451     //!
452     //! @param[in]  dx  X 軸方向のカーソル移動量。
453     //!
MoveCursorX(f32 dx)454     void                MoveCursorX(f32 dx)         { m_CursorPos.x += dx; }
455 
456     //! @brief      カーソルを現在位置から指定された差分だけ移動します。
457     //!
458     //! @param[in]  dy  Y 軸方向のカーソル移動量。
459     //!
MoveCursorY(f32 dy)460     void                MoveCursorY(f32 dy)         { m_CursorPos.y += dy; }
461 
462     //! @brief      カーソルを現在位置から指定された差分だけ移動します。
463     //!
464     //! @param[in]  dz  Z 軸方向のカーソル移動量。
465     //!
MoveCursorZ(f32 dz)466     void                MoveCursorZ(f32 dz)         { m_CursorPos.z += dz; }
467 
468     //! @brief      カーソルのX座標を取得します。
469     //!
470     //! @return     カーソルのX座標を返します。
471     //!
GetCursorX()472     f32                 GetCursorX() const          { return m_CursorPos.x; }
473 
474     //! @brief      カーソルのY座標を取得します。
475     //!
476     //! @return     カーソルのY座標を返します。
477     //!
GetCursorY()478     f32                 GetCursorY() const          { return m_CursorPos.y; }
479 
480     //! @brief      カーソルのZ座標を取得します。
481     //!
482     //! @return     カーソルのZ座標を返します。
483     //!
GetCursorZ()484     f32                 GetCursorZ() const          { return m_CursorPos.z; }
485 
486     //@}
487 
488     //! @name シェーダー関連の設定/取得
489     //@{
490 
491     //! @brief      TextWriterResourceインスタンスを取得します。
492     //!
493     //! @return     TextWriterResourceインスタンスへのポインタを返します。
494     //!
GetTextWriterResource()495     TextWriterResource* GetTextWriterResource() const
496     {
497         return m_pTextWriterResource;
498     }
499 
500     //! @brief      TextWriterResourceインスタンスをセットします。
501     //!
502     //! @param[in]  pTextWriterResource  TextWriterResourceインスタンスへのポインタ。
503     //!
SetTextWriterResource(TextWriterResource * pTextWriterResource)504     void                SetTextWriterResource(TextWriterResource* pTextWriterResource)
505     {
506         m_pTextWriterResource = pTextWriterResource;
507     }
508 
509     //@}
510 
511     //! @name 文字列表示用バッファ
512     //@{
513 
514     //! @brief      文字列表示用バッファのサイズを計算します。
515     //!
516     //! @param[in]  charNum         最大描画文字数
517     //!
518     //! @return     文字列表示用バッファのサイズを返します。
519     //!
520     static u32          GetDispStringBufferSize(u32 charNum);
521 
522     //! @brief      文字列表示用バッファを初期化します。
523     //!
524     //! @param[in]  drawBuffer      描画用バッファ。
525     //! @param[in]  charNum         最大描画文字数。
526     //!
527     //! @return     初期化した文字列表示用バッファを返します。
528     //!
529     static DispStringBuffer*
530                         InitDispStringBuffer(
531                             void*   drawBuffer,
532                             u32     charNum);
533 
534     //! @brief      文字列表示用バッファを取得します。
535     //!
536     //! @return     文字列表示用バッファを返します。
537     //!
GetDispStringBuffer()538     DispStringBuffer*   GetDispStringBuffer() const
539     {
540         return m_pDispStringBuffer;
541     }
542 
543     //! @brief      文字列表示用バッファをセットします。
544     //!             NULLを設定した場合は文字列表示用バッファを使用しなくなります。
545     //!
546     //! @param[in]  buffer 文字列表示用バッファ。
547     //!
SetDispStringBuffer(DispStringBuffer * buffer)548     void                SetDispStringBuffer(DispStringBuffer* buffer)
549     {
550         m_pDispStringBuffer = buffer;
551     }
552 
553     //! @brief      文字列の描画を開始します。
554     //!             文字列表示用バッファが設定されている場合に使用します。
555     //!
556     void                StartPrint();
557 
558     //! @brief      文字列の描画を終了します。
559     //!             文字列表示用バッファが設定されている場合に使用します。
560     //!
561     void                EndPrint();
562 
563     //! @brief      文字列表示用のコマンドバッファをカレントのコマンドリストに追加します。
564     //!
565     void                UseCommandBuffer();
566 
567     //@}
568 
569     #if defined(NN_FONT_PROFILE)
570         void                PrintProfile();
571     #endif
572 
573 protected:
574     #if defined(NN_FONT_PROFILE)
575         void                CopyProfileData(const CharWriter& other) const;
576     #endif
577 
578 private:
579 
580     /* ------------------------------------------------------------------------
581 582        ------------------------------------------------------------------------ */
583     typedef math::VEC2      CharScale;
584     typedef math::VEC3      CursorPos;
585 
586     struct ColorMapping
587     {
588         util::Color8        min;
589         util::Color8        max;
590     };
591 
592     /* ------------------------------------------------------------------------
593             関数
594        ------------------------------------------------------------------------ */
595     //---- 描画準備
596 
597     //! @brief      グラフィックスエンジンを文字描画用のデフォルト設定にします。
598     //!
599     //! @param[in]  bAlphaTex テクスチャがアルファのみのテクスチャの場合は真。
600     //!
601     void                SetupGXDefault(bool bAlphaTex = false);
602 
603     //! @brief      グラフィックスエンジンをテクスチャカラーの線形変換ありの
604     //!             文字描画用に設定します。
605     //!
606     //! @param[in]  bAlphaTex テクスチャがアルファのみのテクスチャの場合は真。
607     //!
608     void                SetupGXWithColorMapping(bool bAlphaTex = false);
609 
610     //! 頂点フォーマットを文字描画用に設定します。
611     void                SetupVertexFormat();
612 
613     //! グラフィックスエンジンに対して共通の設定を行います。
614     void                SetupGXCommon();
615 
616     //! @brief      グリフを指定位置に描画します。
617     //!             カーソル移動は行いません。
618     //!
619     //! @param[in]  x      描画位置のX座標。
620     //! @param[in]  glyph  描画するグリフデータ。
621     //!
622     void                PrintGlyph(
623                             f32             x,
624                             const Glyph&    glyph);
625 
626     //! テクスチャを張る四角形ポリゴンの頂点カラーを更新します。
627     void                UpdateVertexColor();
628 
629     //! @brief      グリフデータの持つテクスチャをロードします。
630     //!
631     //! @param[in]  glyph  ロードすべきテクスチャ情報を持つグリフデータ。
632     //!
633     void                LoadTexture(const Glyph& glyph);
634 
635     /* ------------------------------------------------------------------------
636             変数
637        ------------------------------------------------------------------------ */
638     static const GLushort       s_VertexIndexs[];
639 
640     ColorMapping                m_ColorMapping;         //!< カラーマッピング
641     NN_PADDING3;
642     util::Color8                m_VertexColors[internal::TRIFAN_VTX_MAX];
643                                                         //!< 頂点カラー
644     util::Color8                m_TextColors[internal::TEXTCOLOR_MAX];  //!< 文字色
645     GradationMode               m_GradationMode;
646     CharScale                   m_Scale;                //!< 文字拡大率
647     CursorPos                   m_CursorPos;            //!< カーソル位置
648     f32                         m_FixedWidth;           //!< 等幅時の幅
649     const Font*                 m_pFont;                //!< フォント
650 
651     //! TextWriterResourceインスタンスへのポインタ
652     TextWriterResource*         m_pTextWriterResource;
653 
654     //! 頂点バッファオブジェクト用構造体へのポインタ
655     DispStringBuffer*           m_pDispStringBuffer;
656 
657     bool                        m_IsWidthFixed;         //!< 等幅描画するかどうか
658     u8                          m_Alpha;                //!< 不透明度
659     NN_PADDING2;
660 
661     #if defined(NN_FONT_PROFILE)
662         mutable Stopwatch           m_LoadTextureSw;
663         mutable Stopwatch           m_PrintCharSw;
664         mutable u32                 m_LoadTextureCount;
665         mutable u32                 m_PrintCharCount;
666         mutable Stopwatch           m_DispCharSw;
667         mutable u32                 m_DispCharCount;
668     #endif
669 };
670 
671 }   // namespace CTR
672 }   // namespace font
673 }   // namespace nn
674 #endif //  NN_FONT_CTR_FONT_CHAR_WRITER_H_
675