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