1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     util_Color.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   $Rev: 25398 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_UTIL_UTIL_COLOR_H_
17 #define NN_UTIL_UTIL_COLOR_H_
18 
19 #include <nn/math.h>
20 
21 #ifdef __cplusplus
22 
23 namespace nn {
24 namespace util {
25 
26 struct FloatColor;
27 
28 //--------------------------------------------------------------------------
29 //!  @brief       整数カラーを表す構造体です。
30 //---------------------------------------------------------------------------
31 struct Color8
32 {
33 public:
34     typedef Color8  SelfType;   //!< @details :private
35 
36     /* ------------------------------------------------------------------------
37             定数
38        ------------------------------------------------------------------------ */
39     static const int ELEMENT_MIN         = 0;           //!< カラー要素の最小値です。
40     static const int ELEMENT_MAX         = 255;         //!< カラー要素の最大値です。
41     static const int ALPHA_MIN           = ELEMENT_MIN; //!< alpha の最小値です。
42     static const int ALPHA_MAX           = ELEMENT_MAX; //!< alpha の最大値です。
43     static const int ALPHA_OPACITY       = ALPHA_MAX;   //!< 不透明の alpha 値です。
44     static const int ALPHA_TRANSPARENT   = ALPHA_MIN;   //!< 透明の alpha 値です。
45 
46     static const u32 BLACK      = 0x000000FF;   //!< 黒色の定数です。
47     static const u32 GRAY       = 0x808080FF;   //!< 灰色の定数です。
48     static const u32 WHITE      = 0xFFFFFFFF;   //!< 白色の定数です。
49     static const u32 RED        = 0xFF0000FF;   //!< 赤色の定数です。
50     static const u32 GREEN      = 0x00FF00FF;   //!< 緑色の定数です。
51     static const u32 BLUE       = 0x0000FFFF;   //!< 青色の定数です。
52     static const u32 YELLOW     = 0xFFFF00FF;   //!< 黄色の定数です。
53     static const u32 MAGENTA    = 0xFF00FFFF;   //!< マゼンダの定数です。
54     static const u32 CYAN       = 0x00FFFFFF;   //!< シアンの定数です。
55 
56 
57     /* ------------------------------------------------------------------------
58             関数
59        ------------------------------------------------------------------------ */
60     //----------------------------------------
61     //! @name コンストラクタ/デストラクタ
62     //@{
63 
64     //--------------------------------------------------------------------------
65     //! @brief  デフォルトコンストラクタです。
66     //--------------------------------------------------------------------------
Color8Color867     /* ctor */ Color8() { this->SetU32(WHITE); }
68 
69     //--------------------------------------------------------------------------
70     //! @brief  u32 の値を設定するコンストラクタです。
71     //--------------------------------------------------------------------------
Color8Color872     /* ctor */ /*implicit*/ Color8(u32 color) { this->SetU32(color); }
73 
74     //--------------------------------------------------------------------------
75     //! @brief  RGBA 各要素を設定するコンストラクタです。
76     //--------------------------------------------------------------------------
Color8Color877     /* ctor */ /*implicit*/ Color8(s32 red, s32 green, s32 blue, s32 alpha)
78      : r(static_cast<u8>(red)),
79        g(static_cast<u8>(green)),
80        b(static_cast<u8>(blue)),
81        a(static_cast<u8>(alpha))
82     {
83     }
84 
85     //--------------------------------------------------------------------------
86     //! @brief  デストラクタです。
87     //--------------------------------------------------------------------------
~Color8Color888     /* dtor */ ~Color8() {}
89 
90     //@}
91 
92     //----------------------------------------
93     //! @name 演算子オーバーロード
94     //@{
95 
96     //--------------------------------------------------------------------------
97     //!  @brief        u32 型を代入する代入演算子です。
98     //!
99     //!  @param[out]   color     RGBA8 の u32 型インスタンスです。
100     //!
101     //!  @return       Color8 のインスタンスを返します。
102     //---------------------------------------------------------------------------
103     SelfType&      operator =(u32 color)
104     {
105         this->SetU32(color);
106         return *this;
107     }
108 
109     //--------------------------------------------------------------------------
110     //!  @brief        FloatColor 型を代入する代入演算子です。
111     //!
112     //!  @param[out]   color     FloatColor 型のカラーインスタンスです。
113     //!
114     //!  @return       Color8 のインスタンスを返します。
115     //---------------------------------------------------------------------------
116     SelfType&      operator =(FloatColor& color);
117 
118     //--------------------------------------------------------------------------
119     //! @brief        u32 型へのキャスト演算子です。
120     //!
121     //! @return       u32 で表現した値を返します。
122     //---------------------------------------------------------------------------
u32Color8123     operator u32() const { return ToU32(); }
124 
125     //---- 四則演算
126     //--------------------------------------------------------------------------
127     //! @brief        カラー同士の加算演算子です。
128     //!
129     //! @param[in]    right   加算をおこなうカラー値です。
130     //!
131     //! @return       加算後の値を返します。
132     //---------------------------------------------------------------------------
133     const SelfType operator +(const SelfType& right) const
134     {
135         SelfType color(
136             nn::math::Min(this->r + right.r, ELEMENT_MAX),
137             nn::math::Min(this->g + right.g, ELEMENT_MAX),
138             nn::math::Min(this->b + right.b, ELEMENT_MAX),
139             nn::math::Min(this->a + right.a, ELEMENT_MAX)
140         );
141         return color;
142     }
143 
144     //--------------------------------------------------------------------------
145     //! @brief        カラー同士の減算演算子です。
146     //!
147     //! @param[in]    right   減算をおこなうカラー値です。
148     //!
149     //! @return       減算後の値を返します。
150     //---------------------------------------------------------------------------
151     const SelfType operator -(const SelfType& right) const
152     {
153         SelfType color(
154             nn::math::Max(this->r - right.r, ELEMENT_MIN),
155             nn::math::Max(this->g - right.g, ELEMENT_MIN),
156             nn::math::Max(this->b - right.b, ELEMENT_MIN),
157             nn::math::Max(this->a - right.a, ELEMENT_MIN)
158         );
159         return color;
160     }
161 
162     //--------------------------------------------------------------------------
163     //! @brief        カラー同士の乗算演算子です。
164     //!
165     //! @param[in]    right   乗算をおこなうカラー値です。
166     //!
167     //! @return       乗算後の値を返します。
168     //---------------------------------------------------------------------------
169     const SelfType operator *(const SelfType& right) const
170     {
171         SelfType color(
172             this->r * right.r / ELEMENT_MAX,
173             this->g * right.g / ELEMENT_MAX,
174             this->b * right.b / ELEMENT_MAX,
175             this->a * right.a / ELEMENT_MAX
176         );
177         return color;
178     }
179 
180     //--------------------------------------------------------------------------
181     //! @brief        カラー同士の除算演算子です。
182     //!
183     //! @param[in]    right   除算をおこなうカラー値です。
184     //!
185     //! @return       除算後の値を返します。
186     //---------------------------------------------------------------------------
187     const SelfType operator /(const SelfType& right) const
188     {
189         SelfType color(
190             (right.r != 0) ? nn::math::Min(this->r * ELEMENT_MAX / right.r, ELEMENT_MAX): ELEMENT_MAX,
191             (right.g != 0) ? nn::math::Min(this->g * ELEMENT_MAX / right.g, ELEMENT_MAX): ELEMENT_MAX,
192             (right.b != 0) ? nn::math::Min(this->b * ELEMENT_MAX / right.b, ELEMENT_MAX): ELEMENT_MAX,
193             (right.a != 0) ? nn::math::Min(this->a * ELEMENT_MAX / right.a, ELEMENT_MAX): ELEMENT_MAX
194         );
195         return color;
196     }
197 
198     //---- インクリメント、デクリメント
199     //--------------------------------------------------------------------------
200     //! @brief        前置のインクリメント演算子です。
201     //!
202     //! @return       各要素をインクリメントした値を返します。
203     //---------------------------------------------------------------------------
204     const SelfType operator ++()
205     {
206         if (r < ELEMENT_MAX) { r++; }
207         if (g < ELEMENT_MAX) { g++; }
208         if (b < ELEMENT_MAX) { b++; }
209         if (a < ELEMENT_MAX) { a++; }
210 
211         return *this;
212     }
213 
214     //--------------------------------------------------------------------------
215     //! @brief        後置のインクリメント演算子です。
216     //!
217     //! @return       インクリメント前の値を返します。
218     //---------------------------------------------------------------------------
219     const SelfType operator ++(int)
220     {
221         SelfType old = *this;
222         if (r < ELEMENT_MAX) { r++; }
223         if (g < ELEMENT_MAX) { g++; }
224         if (b < ELEMENT_MAX) { b++; }
225         if (a < ELEMENT_MAX) { a++; }
226 
227         return old;
228     }
229 
230     //--------------------------------------------------------------------------
231     //! @brief        前置のデクリメント演算子です。
232     //!
233     //! @return       各要素をデクリメントした値を返します。
234     //---------------------------------------------------------------------------
235     const SelfType operator --()
236     {
237         if (r > ELEMENT_MIN) { r--; }
238         if (g > ELEMENT_MIN) { g--; }
239         if (b > ELEMENT_MIN) { b--; }
240         if (a > ELEMENT_MIN) { a--; }
241 
242         return *this;
243     }
244 
245     //--------------------------------------------------------------------------
246     //! @brief        後置のデクリメント演算子です。
247     //!
248     //! @return       デクリメント前の値を返します。
249     //---------------------------------------------------------------------------
250     const SelfType operator --(int)
251     {
252         SelfType old = *this;
253         if (r > ELEMENT_MIN) { r--; }
254         if (g > ELEMENT_MIN) { g--; }
255         if (b > ELEMENT_MIN) { b--; }
256         if (a > ELEMENT_MIN) { a--; }
257 
258         return old;
259     }
260 
261     //---- bitごとの和と積
262     //--------------------------------------------------------------------------
263     //! @brief        u32 としての ビット和を求めます。
264     //!
265     //! @param[in]    right ビット和をとるカラーです。
266     //!
267     //! @return       ビット和をとったカラーを返します。
268     //---------------------------------------------------------------------------
269     const SelfType operator |(const SelfType& right) const
270     {
271         return U32RawToColor(this->ToU32Raw() | right.ToU32Raw());
272     }
273 
274     //--------------------------------------------------------------------------
275     //! @brief        u32 としての ビット積を求めます。
276     //!
277     //! @param[in]    right ビット積をとるカラーです。
278     //!
279     //! @return       ビット積をとったカラーを返します。
280     //---------------------------------------------------------------------------
281     const SelfType operator &(const SelfType& right) const
282     {
283         return U32RawToColor(this->ToU32Raw() & right.ToU32Raw());
284     }
285 
286     //--------------------------------------------------------------------------
287     //! @brief        カラー同士の加算代入演算子です。
288     //!
289     //! @param[in]    rhs   加算をおこなうカラー値です。
290     //!
291     //! @return       加算後のオブジェクトへの参照を返します。
292     //---------------------------------------------------------------------------
293     SelfType& operator +=(const SelfType& rhs)
294     {
295         *this = *this + rhs;
296         return *this;
297     }
298 
299     //--------------------------------------------------------------------------
300     //! @brief        カラー同士の減算代入演算子です。
301     //!
302     //! @param[in]    rhs   減算をおこなうカラー値です。
303     //!
304     //! @return       減算後のオブジェクトへの参照を返します。
305     //---------------------------------------------------------------------------
306     SelfType& operator -=(const SelfType& rhs)
307     {
308         *this = *this - rhs;
309         return *this;
310     }
311 
312     //--------------------------------------------------------------------------
313     //! @brief        カラー同士の乗算代入演算子です。
314     //!
315     //! @param[in]    rhs   乗算をおこなうカラー値です。
316     //!
317     //! @return       乗算後のオブジェクトへの参照を返します。
318     //---------------------------------------------------------------------------
319     SelfType& operator *=(const SelfType& rhs)
320     {
321         *this = *this * rhs;
322         return *this;
323     }
324 
325     //--------------------------------------------------------------------------
326     //! @brief        カラー同士の除算代入演算子です。
327     //!
328     //! @param[in]    rhs   除算をおこなうカラー値です。
329     //!
330     //! @return       除算後のオブジェクトへの参照を返します。
331     //---------------------------------------------------------------------------
332     SelfType& operator /=(const SelfType& rhs)
333     {
334         *this = *this / rhs;
335         return *this;
336     }
337 
338     //--------------------------------------------------------------------------
339     //! @brief        u32 をカラーとして加算をおこなう演算子です。
340     //!
341     //! @param[in]    rhs   加算をおこなう u32 値です。
342     //!
343     //! @return       加算後の値を返します。
344     //---------------------------------------------------------------------------
345     const SelfType operator +(u32 rhs) const
346     {
347         const SelfType right = SelfType(rhs);
348         SelfType color(
349             nn::math::Min(this->r + right.r, ELEMENT_MAX),
350             nn::math::Min(this->g + right.g, ELEMENT_MAX),
351             nn::math::Min(this->b + right.b, ELEMENT_MAX),
352             nn::math::Min(this->a + right.a, ELEMENT_MAX)
353         );
354         return color;
355     }
356 
357     //--------------------------------------------------------------------------
358     //! @brief        u32 をカラーとして減算をおこなう演算子です。
359     //!
360     //! @param[in]    rhs   減算をおこなう u32 値です。
361     //!
362     //! @return       減算後の値を返します。
363     //---------------------------------------------------------------------------
364     const SelfType operator -(u32 rhs) const
365     {
366         const SelfType right = SelfType(rhs);
367         SelfType color(
368             nn::math::Max(this->r - right.r, ELEMENT_MIN),
369             nn::math::Max(this->g - right.g, ELEMENT_MIN),
370             nn::math::Max(this->b - right.b, ELEMENT_MIN),
371             nn::math::Max(this->a - right.a, ELEMENT_MIN)
372         );
373         return color;
374     }
375 
376     //--------------------------------------------------------------------------
377     //! @brief        u32 をカラーとして乗算をおこなう演算子です。
378     //!
379     //! @param[in]    rhs   乗算をおこなう u32 値です。
380     //!
381     //! @return       乗算後の値を返します。
382     //---------------------------------------------------------------------------
383     const SelfType operator *(u32 rhs) const
384     {
385         const SelfType right = SelfType(rhs);
386         SelfType color(
387             this->r * right.r / ELEMENT_MAX,
388             this->g * right.g / ELEMENT_MAX,
389             this->b * right.b / ELEMENT_MAX,
390             this->a * right.a / ELEMENT_MAX
391         );
392         return color;
393     }
394 
395     //--------------------------------------------------------------------------
396     //! @brief        u32 をカラーとして除算をおこなう演算子です。
397     //!
398     //! @param[in]    rhs   除算をおこなう u32 値です。
399     //!
400     //! @return       除算後の値を返します。
401     //---------------------------------------------------------------------------
402     const SelfType operator /(u32 rhs) const
403     {
404         const SelfType right = SelfType(rhs);
405         SelfType color(
406             (right.r != 0) ? nn::math::Min(this->r * ELEMENT_MAX / right.r, ELEMENT_MAX): ELEMENT_MAX,
407             (right.g != 0) ? nn::math::Min(this->g * ELEMENT_MAX / right.g, ELEMENT_MAX): ELEMENT_MAX,
408             (right.b != 0) ? nn::math::Min(this->b * ELEMENT_MAX / right.b, ELEMENT_MAX): ELEMENT_MAX,
409             (right.a != 0) ? nn::math::Min(this->a * ELEMENT_MAX / right.a, ELEMENT_MAX): ELEMENT_MAX
410         );
411         return color;
412     }
413 
414     //--------------------------------------------------------------------------
415     //! @brief        u32 をカラーとして論理和演算をおこなう演算子です。
416     //!
417     //! @param[in]    right   論理和演算をおこなう u32 値です。
418     //!
419     //! @return       論理和演算後の値を返します。
420     //---------------------------------------------------------------------------
421     const SelfType operator |(u32 right) const
422     {
423         return *this | SelfType( right );
424     }
425 
426     //--------------------------------------------------------------------------
427     //! @brief        u32 をカラーとして論理積演算をおこなう演算子です。
428     //!
429     //! @param[in]    right   論理積演算をおこなう u32 値です。
430     //!
431     //! @return       論理積演算後の値を返します。
432     //---------------------------------------------------------------------------
433     const SelfType operator &(u32 right) const
434     {
435         return *this & SelfType( right );
436     }
437 
438     //@}
439 
440     //----------------------------------------
441     //! @name 設定/取得
442     //@{
443 
444     //---- アクセサ
445     //--------------------------------------------------------------------------
446     //! @brief        RGBA の値を設定します。
447     //!
448     //! @param[in]    red     カラーの R 要素です。
449     //! @param[in]    green   カラーの G 要素です。
450     //! @param[in]    blue    カラーの B 要素です。
451     //! @param[in]    alpha   カラーの A 要素です。(デフォルト値: 255)
452     //---------------------------------------------------------------------------
453     void        Set(
454                     s32 red,
455                     s32 green,
456                     s32 blue,
457                     s32 alpha = ALPHA_OPACITY )
458     {
459         r = static_cast<u8>(red);
460         g = static_cast<u8>(green);
461         b = static_cast<u8>(blue);
462         a = static_cast<u8>(alpha);
463     }
464 
465     //--------------------------------------------------------------------------
466     //! @brief        RGBA8 のカラー値を設定します。
467     //!
468     //! @param[in]    color   設定するカラー値です。
469     //---------------------------------------------------------------------------
SetColor8470     void        Set(SelfType color)
471     {
472         operator =(color);
473     }
474 
475     //---- 明示的な型変換
476   #if ( NN_ENDIAN == NN_ENDIAN_VALUE_LITTLE )
477     //--------------------------------------------------------------------------
478     //! @brief        u32 としてカラー値を取得します。
479     //!
480     //! @return       カラーを u32 へ変換した値です。
481     //---------------------------------------------------------------------------
ToU32Color8482     u32         ToU32() const
483     {
484         u32 val = *reinterpret_cast<const u32*>(this);
485         return (u32)( (((val) >> 24UL) & 0x000000FFUL) |
486                       (((val) >>  8UL) & 0x0000FF00UL) |
487                       (((val) <<  8UL) & 0x00FF0000UL) |
488                       (((val) << 24UL) & 0xFF000000UL) );
489     }
490 
491     //--------------------------------------------------------------------------
492     //! @brief        u32 として値を設定します。
493     //!
494     //! @param[in]    value   u32 としてのかr−ア値です。
495     //---------------------------------------------------------------------------
SetU32Color8496     void        SetU32(u32 value)
497     {
498         this->ToU32RawRef() = (u32)( (((value) >> 24UL) & 0x000000FFUL) |
499                                      (((value) >>  8UL) & 0x0000FF00UL) |
500                                      (((value) <<  8UL) & 0x00FF0000UL) |
501                                      (((value) << 24UL) & 0xFF000000UL) );
502     }
503 
504   #else
505     //--------------------------------------------------------------------------
506     //! @brief        u32 としてカラー値を取得します。
507     //!
508     //! @return       カラーを u32 へ変換した値です。
509     //---------------------------------------------------------------------------
ToU32Color8510     u32         ToU32() const
511     {
512         return this->ToU32RawRef();
513     }
514 
515     //--------------------------------------------------------------------------
516     //! @brief        u32 として値を設定します。
517     //!
518     //! @param[in]    value   u32 としてのかr−ア値です。
519     //---------------------------------------------------------------------------
SetU32Color8520     void        SetU32(u32 value) { this->ToU32RawRef() = value; }
521 
522   #endif
523 
524     //@}
525 
526 protected:
527 
528     /* ------------------------------------------------------------------------
529             関数
530        ------------------------------------------------------------------------ */
531     //! @details :private
U32RawToColorColor8532     static SelfType U32RawToColor(u32 value)
533     {
534         return *reinterpret_cast<SelfType*>(&value);
535     }
536 
537     //! @details :private
ToU32RawRefColor8538     u32&        ToU32RawRef()
539     {
540         return *reinterpret_cast<u32*>(this);
541     }
542 
543     //! @details :private
ToU32RawRefColor8544     const u32&  ToU32RawRef() const
545     {
546         return *reinterpret_cast<const u32*>(this);
547     }
548 
549     //! @details :private
ToU32RawColor8550     u32         ToU32Raw() const
551     {
552         return *reinterpret_cast<const u32*>(this);
553     }
554 
555 public:
556     u8 r; //!< カラーの R 要素です。 0 ~ 255 の範囲で値を保持します。
557     u8 g; //!< カラーの G 要素です。 0 ~ 255 の範囲で値を保持します。
558     u8 b; //!< カラーの B 要素です。 0 ~ 255 の範囲で値を保持します。
559     u8 a; //!< カラーの A 要素です。 0 ~ 255 の範囲で値を保持します。
560 };
561 
562 //! @details :private
563 typedef Color8   Color;
564 
565 //--------------------------------------------------------------------------
566 //!  @brief       浮動小数カラーを表す構造体です。
567 //---------------------------------------------------------------------------
568 struct FloatColor
569 {
570 public:
571     typedef FloatColor SelfType;    //!< @details :private
572 
573     /* ------------------------------------------------------------------------
574             定数
575        ------------------------------------------------------------------------ */
576     static const int ELEMENT_MIN         = 0;   //!< カラー要素の最小値です。
577     static const int ELEMENT_MAX         = 1;   //!< カラー要素の最大値です。
578     static const int ALPHA_MIN           = ELEMENT_MIN; //!< αの最小値です。
579     static const int ALPHA_MAX           = ELEMENT_MAX; //!< αの最小値です。
580     static const int ALPHA_OPACITY       = ALPHA_MAX;   //!< 不透明のα値です。
581     static const int ALPHA_TRANSPARENT   = ALPHA_MIN;   //!< 透明のα値です。
582 
583     /* ------------------------------------------------------------------------
584             関数
585        ------------------------------------------------------------------------ */
586     //----------------------------------------
587     //! @name コンストラクタ/デストラクタ
588     //@{
589 
590     //--------------------------------------------------------------------------
591     //! @brief  デフォルトコンストラクタです。
592     //--------------------------------------------------------------------------
FloatColorFloatColor593     /* ctor */ FloatColor()
594     : r(0.0f), g(0.0f), b(0.0f), a(1.0f)
595     {
596     }
597 
598     //--------------------------------------------------------------------------
599     //! @brief     VEC4を引数にとるコンストラクタです。
600     //!
601     //! @param[in] vec FloatColor に変換するベクトルです。
602     //--------------------------------------------------------------------------
FloatColorFloatColor603     /* ctor */ /* implicit */  FloatColor(const nn::math::VEC4& vec)
604      : r(vec.x), g(vec.y), b(vec.z), a(vec.w)
605     {
606     }
607 
608     //--------------------------------------------------------------------------
609     //! @brief        Color8 から FloatColor に変換するコンストラクタです。
610     //!
611     //! @param[in]    color   RGBA8 のカラーです。
612     //--------------------------------------------------------------------------
FloatColorFloatColor613     /* ctor */ /* implicit */  FloatColor(Color8 color) { operator =(color); }
614 
615     //--------------------------------------------------------------------------
616     //! @brief        RGBA をそれぞれ指定したコンストクタです。
617     //!
618     //! @param[in]    red     カラーの R 要素です。
619     //! @param[in]    green   カラーの G 要素です。
620     //! @param[in]    blue    カラーの B 要素です。
621     //! @param[in]    alpha   カラーの A 要素です。
622     //--------------------------------------------------------------------------
FloatColorFloatColor623     /* ctor */ FloatColor(f32 red, f32 green, f32 blue, f32 alpha)
624     : r(red), g(green), b(blue), a(alpha)
625     {
626     }
627 
628     //--------------------------------------------------------------------------
629     //! @brief        デストラクタです。
630     //--------------------------------------------------------------------------
~FloatColorFloatColor631     /* dtor */ ~FloatColor() {}
632 
633     //@}
634 
635     //----------------------------------------
636     //! @name 演算子オーバーロード
637     //@{
638 
639     //--------------------------------------------------------------------------
640     //! @brief        RGBA8 のカラーを FloatColor に設定する代入演算子です。
641     //!
642     //! @param[in]    color   RGBA8 のカラーです。
643     //!
644     //! @return       FloatColor のインスタンスを返します。
645     //--------------------------------------------------------------------------
646     SelfType&      operator =(Color8 color)
647     {
648         this->Set(
649             static_cast<s32>(color.r),
650             static_cast<s32>(color.g),
651             static_cast<s32>(color.b),
652             static_cast<s32>(color.a) );
653         return *this;
654     }
655 
656     //--------------------------------------------------------------------------
657     //!  @brief        VEC4 型を代入する代入演算子です。
658     //!
659     //!  @param[out]   vec     VEC4 型のインスタンスです。
660     //!
661     //!  @return       FloatColor のインスタンスを返します。
662     //---------------------------------------------------------------------------
663     SelfType&      operator =(const nn::math::VEC4& vec)
664     {
665         this->Set( vec.x, vec.y, vec.z, vec.w );
666         return *this;
667     }
668 
669     //--------------------------------------------------------------------------
670     //! @brief        f32 配列へのキャスト演算子です。
671     //---------------------------------------------------------------------------
672     operator f32*() { return &r; }
673 
674     //--------------------------------------------------------------------------
675     //! @brief        f32 配列へのキャスト演算子 const 版です。
676     //---------------------------------------------------------------------------
677     operator const f32*() const { return &r; }
678 
679     //--------------------------------------------------------------------------
680     //! @brief        RGBA8 カラーへのキャスト演算子です。
681     //---------------------------------------------------------------------------
Color8FloatColor682     operator Color8() const
683     {
684         return Color8( static_cast<u8>( 0.5f + nn::math::Clamp(r, 0.0f, 1.0f) * 255.f ),
685                        static_cast<u8>( 0.5f + nn::math::Clamp(g, 0.0f, 1.0f) * 255.f ),
686                        static_cast<u8>( 0.5f + nn::math::Clamp(b, 0.0f, 1.0f) * 255.f ),
687                        static_cast<u8>( 0.5f + nn::math::Clamp(a, 0.0f, 1.0f) * 255.f ));
688     }
689 
690     //--------------------------------------------------------------------------
691     //! @brief        VEC4へのキャスト演算子です。
692     //---------------------------------------------------------------------------
693     operator nn::math::VEC4&()
694     {
695         return this->ToVEC4();
696     }
697 
698     //--------------------------------------------------------------------------
699     //! @brief        VEC4へのキャスト演算子 const 版です。
700     //---------------------------------------------------------------------------
701     operator const nn::math::VEC4&() const
702     {
703         return this->ToVEC4();
704     }
705 
706     //---- 四則演算
707     //--------------------------------------------------------------------------
708     //! @brief        カラー同士の加算演算子です。
709     //!
710     //! @param[in]    right   加算をおこなうカラー値です。
711     //!
712     //! @return       加算後の値を返します。
713     //---------------------------------------------------------------------------
714     const SelfType operator +(const SelfType& right) const
715     {
716         SelfType color(
717             this->r + right.r,
718             this->g + right.g,
719             this->b + right.b,
720             this->a + right.a
721         );
722         return color;
723     }
724 
725     //--------------------------------------------------------------------------
726     //! @brief        カラー同士の減算演算子です。
727     //!
728     //! @param[in]    right   減算をおこなうカラー値です。
729     //!
730     //! @return       減算後の値を返します。
731     //---------------------------------------------------------------------------
732     const SelfType operator -(const SelfType& right) const
733     {
734         SelfType color(
735             this->r - right.r,
736             this->g - right.g,
737             this->b - right.b,
738             this->a - right.a
739         );
740         return color;
741     }
742 
743     //--------------------------------------------------------------------------
744     //! @brief        カラー同士の乗算演算子です。
745     //!
746     //! @param[in]    right   乗算をおこなうカラー値です。
747     //!
748     //! @return       乗算後の値を返します。
749     //---------------------------------------------------------------------------
750     const SelfType operator *(const SelfType& right) const
751     {
752         SelfType color(
753             this->r * right.r,
754             this->g * right.g,
755             this->b * right.b,
756             this->a * right.a
757         );
758         return color;
759     }
760 
761     //--------------------------------------------------------------------------
762     //! @brief        カラー同士の除算演算子です。
763     //!
764     //! @param[in]    right   除算をおこなうカラー値です。
765     //!
766     //! @return       除算後の値を返します。
767     //---------------------------------------------------------------------------
768     const SelfType operator /(const SelfType& right) const
769     {
770         SelfType color(
771             (right.r != 0) ? (this->r / right.r) : ELEMENT_MAX,
772             (right.g != 0) ? (this->g / right.g) : ELEMENT_MAX,
773             (right.b != 0) ? (this->b / right.b) : ELEMENT_MAX,
774             (right.a != 0) ? (this->a / right.a) : ELEMENT_MAX
775         );
776         return color;
777     }
778 
779     //--------------------------------------------------------------------------
780     //! @brief        カラー同士の加算代入演算子です。
781     //!
782     //! @param[in]    rhs   加算をおこなうカラー値です。
783     //!
784     //! @return       加算後のオブジェクトへの参照を返します。
785     //---------------------------------------------------------------------------
786     SelfType& operator +=(const SelfType& rhs)
787     {
788         *this = *this + rhs;
789         return *this;
790     }
791 
792     //--------------------------------------------------------------------------
793     //! @brief        カラー同士の減算代入演算子です。
794     //!
795     //! @param[in]    rhs   減算をおこなうカラー値です。
796     //!
797     //! @return       減算後のオブジェクトへの参照を返します。
798     //---------------------------------------------------------------------------
799     SelfType& operator -=(const SelfType& rhs)
800     {
801         *this = *this - rhs;
802         return *this;
803     }
804 
805     //--------------------------------------------------------------------------
806     //! @brief        カラー同士の乗算代入演算子です。
807     //!
808     //! @param[in]    rhs   乗算をおこなうカラー値です。
809     //!
810     //! @return       乗算後のオブジェクトへの参照を返します。
811     //---------------------------------------------------------------------------
812     SelfType& operator *=(const SelfType& rhs)
813     {
814         *this = *this * rhs;
815         return *this;
816     }
817 
818     //--------------------------------------------------------------------------
819     //! @brief        カラー同士の除算代入演算子です。
820     //!
821     //! @param[in]    rhs   除算をおこなうカラー値です。
822     //!
823     //! @return       除算後のオブジェクトへの参照を返します。
824     //---------------------------------------------------------------------------
825     SelfType& operator /=(const SelfType& rhs)
826     {
827         *this = *this / rhs;
828         return *this;
829     }
830 
831     //---- 四則演算
832     //--------------------------------------------------------------------------
833     //! @brief        カラーへ実数を加算する代入演算子です。
834     //!
835     //! @param[in]    right   RGBAそれぞれに加算する値です。
836     //!
837     //! @return       加算後のオブジェクトへの参照を返します。
838     //---------------------------------------------------------------------------
839     SelfType& operator +=(f32 right)
840     {
841         this->r += right;
842         this->g += right;
843         this->b += right;
844         this->a += right;
845         return *this;
846     }
847 
848     //--------------------------------------------------------------------------
849     //! @brief        カラーから実数を減算する代入演算子です。
850     //!
851     //! @param[in]    right   RGBAそれぞれに減算する値です。
852     //!
853     //! @return       減算後のオブジェクトへの参照を返します。
854     //---------------------------------------------------------------------------
855     SelfType& operator -=(f32 right)
856     {
857         this->r -= right;
858         this->g -= right;
859         this->b -= right;
860         this->a -= right;
861         return *this;
862     }
863 
864     //--------------------------------------------------------------------------
865     //! @brief        カラーへ実数を乗算する代入演算子です。
866     //!
867     //! @param[in]    right   RGBAそれぞれに乗算する値です。
868     //!
869     //! @return       乗算後のオブジェクトへの参照を返します。
870     //---------------------------------------------------------------------------
871     SelfType& operator *=(f32 right)
872     {
873         this->r *= right;
874         this->g *= right;
875         this->b *= right;
876         this->a *= right;
877         return *this;
878     }
879 
880     //--------------------------------------------------------------------------
881     //! @brief        カラーへ実数を減算する代入演算子です。
882     //!
883     //! @param[in]    right   RGBAそれぞれに減算する値です。
884     //!
885     //! @return       減算後のオブジェクトへの参照を返します。
886     //---------------------------------------------------------------------------
887     SelfType& operator /=(f32 right)
888     {
889         if (right != 0.0f)
890         {
891             this->r /= right;
892             this->g /= right;
893             this->b /= right;
894             this->a /= right;
895         }
896         else
897         {
898             this->r = ELEMENT_MAX;
899             this->g = ELEMENT_MAX;
900             this->b = ELEMENT_MAX;
901             this->a = ELEMENT_MAX;
902         }
903         return *this;
904     }
905 
906     //--------------------------------------------------------------------------
907     //! @brief        比較演算子です。
908     //!
909     //! @param[in]    rhs     比較する値です。
910     //!
911     //! @return       等しい場合は true、そうでない場合は false を返します。
912     //---------------------------------------------------------------------------
913     bool        operator ==(const SelfType& rhs) const
914     {
915         return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a);
916     }
917 
918     //--------------------------------------------------------------------------
919     //! @brief        否定の比較演算子です。
920     //!
921     //! @param[in]    rhs     比較する値です。
922     //!
923     //! @return       等しい場合は false、そうでない場合は true を返します。
924     //---------------------------------------------------------------------------
925     bool        operator !=(const SelfType& rhs) const
926     {
927         return !(*this == rhs);
928     }
929 
930     //@}
931 
932     //----------------------------------------
933     //! @name 設定/取得
934     //@{
935 
936     //---- アクセサ
937     //--------------------------------------------------------------------------
938     //! @brief        カラーに値を設定します。
939     //!
940     //! @param[in]    red     カラーの R 要素です。
941     //! @param[in]    green   カラーの G 要素です。
942     //! @param[in]    blue    カラーの B 要素です。
943     //! @param[in]    alpha   カラーの A 要素です。(デフォルト値: 1.0)
944     //---------------------------------------------------------------------------
945     void        Set(
946                     f32 red,
947                     f32 green,
948                     f32 blue,
949                     f32 alpha = ALPHA_OPACITY )
950     {
951         r = red;
952         g = green;
953         b = blue;
954         a = alpha;
955     }
956 
957     //---- アクセサ
958     //--------------------------------------------------------------------------
959     //! @brief        0~255 の整数値でカラーを設定します。
960     //!
961     //! @param[in]    red     カラーの R 要素です。
962     //! @param[in]    green   カラーの G 要素です。
963     //! @param[in]    blue    カラーの B 要素です。
964     //! @param[in]    alpha   カラーの A 要素です。(デフォルト値: 255)
965     //---------------------------------------------------------------------------
966     void        Set(
967                     s32 red,
968                     s32 green,
969                     s32 blue,
970                     s32 alpha = Color8::ALPHA_OPACITY )
971     {
972         r = static_cast<f32>( red ) / 255.f;
973         g = static_cast<f32>( green ) / 255.f;;
974         b = static_cast<f32>( blue ) / 255.f;;
975         a = static_cast<f32>( alpha ) / 255.f;;
976     }
977 
978     //--------------------------------------------------------------------------
979     //! @brief        カラー型の値を設定します。
980     //!
981     //! @param[in]    color
982     //---------------------------------------------------------------------------
SetFloatColor983     void        Set(const SelfType& color) { operator =(color); }
984 
985     //--------------------------------------------------------------------------
986     //! @brief        各要素を 0.0 ~ 1.0 の範囲にクランプします。
987     //---------------------------------------------------------------------------
ClampFloatColor988     void        Clamp() { this->Clamp( 0.0f, 1.0f ); }
989 
990     //--------------------------------------------------------------------------
991     //! @brief        各要素を指定の範囲にクランプします。
992     //! @param[in]    low     下限値です。
993     //! @param[in]    high    上限値です。
994     //---------------------------------------------------------------------------
ClampFloatColor995     void        Clamp( f32 low, f32 high )
996     {
997         r = nn::math::Clamp( r, low, high );
998         g = nn::math::Clamp( g, low, high );
999         b = nn::math::Clamp( b, low, high );
1000         a = nn::math::Clamp( a, low, high );
1001     }
1002 
1003     //--------------------------------------------------------------------------
1004     //! @brief        浮動小数型の配列へ変換します。
1005     //---------------------------------------------------------------------------
ToArrayFloatColor1006     f32*        ToArray()       { return reinterpret_cast<f32*>( this ); }
1007 
1008     //--------------------------------------------------------------------------
1009     //! @brief        浮動小数型の const 配列へ変換します。
1010     //---------------------------------------------------------------------------
ToArrayFloatColor1011     const f32*  ToArray() const { return reinterpret_cast<const f32*>( this ); }
1012 
1013     //--------------------------------------------------------------------------
1014     //! @brief        Picaの u32 へ変換します。
1015     //---------------------------------------------------------------------------
ToPicaU32FloatColor1016     u32 ToPicaU32() const
1017     {
1018         u8 red   = static_cast<u8>( 0.5f + nn::math::Clamp(r, 0.0f, 1.0f) * 255.f );
1019         u8 green = static_cast<u8>( 0.5f + nn::math::Clamp(g, 0.0f, 1.0f) * 255.f );
1020         u8 blue  = static_cast<u8>( 0.5f + nn::math::Clamp(b, 0.0f, 1.0f) * 255.f );
1021         u8 alpha = static_cast<u8>( 0.5f + nn::math::Clamp(a, 0.0f, 1.0f) * 255.f );
1022 
1023         return (alpha << 24) | (blue << 16) | (green << 8) | (red);
1024     }
1025 
1026     //@}
1027 
1028 protected:
1029     //! @details :private
ToVEC4FloatColor1030     nn::math::VEC4&        ToVEC4()
1031     {
1032         return *reinterpret_cast<nn::math::VEC4*>(this);
1033     }
1034 
1035     //! @details :private
ToVEC4FloatColor1036     const nn::math::VEC4&  ToVEC4() const
1037     {
1038         return *reinterpret_cast<const nn::math::VEC4*>(this);
1039     }
1040 
1041 public:
1042     f32 r; //!< カラーの R 要素です。
1043     f32 g; //!< カラーの G 要素です。
1044     f32 b; //!< カラーの B 要素です。
1045     f32 a; //!< カラーの A 要素です。
1046 
1047 };
1048 
1049 #if !defined( NN_SWAP_ENDIAN )
1050     //! @details :private
1051     typedef FloatColor ResFloatColor;
1052 #else
1053     //! @details :private
1054     typedef struct
1055     {
1056         nw::ut::ResF32 r;
1057         nw::ut::ResF32 g;
1058         nw::ut::ResF32 b;
1059         nw::ut::ResF32 a;
1060 
FloatColor__anon1067813201081061         operator FloatColor() const
1062             { FloatColor color; color.r = r; color.g = g; color.b = b; color.a = a; return color; }
1063         void operator = (const FloatColor& val) { r = val.r; g = val.g; b = val.b; a = val.a; }
1064     } ResFloatColor;
1065 #endif
1066 
1067 } /* namespace util */
1068 } /* namespace nn */
1069 
1070 #endif // __cplusplus
1071 
1072 #endif //  NN_UTIL_UTIL_COLOR_H_
1073