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