1 #ifndef color_hsl_convert_cmy
2 #define color_hsl_convert_cmy
3 
4 #include "../../_internal/convert.hpp"
5 #include "../../cmy/cmy.hpp"
6 
7 #include "../../_internal/normalize.hpp"
8 #include "../../_internal/diverse.hpp"
9 
10 namespace color
11  {
12   namespace _internal
13    {
14 
15     template< typename hsl_tag_name, typename cmy_tag_name >
16      struct convert
17       <
18         ::color::category::hsl< hsl_tag_name >
19        ,::color::category::cmy< cmy_tag_name >
20       >
21       {
22        public:
23          typedef ::color::category::hsl< hsl_tag_name > category_left_type;
24          typedef ::color::category::cmy< cmy_tag_name > category_right_type;
25          typedef typename ::color::trait::scalar<category_left_type>::instance_type scalar_type;
26 
27          typedef ::color::trait::scalar<category_left_type> scalar_trait_type;
28 
29          typedef ::color::trait::container<category_left_type>     container_left_trait_type;
30          typedef ::color::trait::container<category_right_type>    container_right_trait_type;
31 
32          typedef typename container_left_trait_type::input_type         container_left_input_type;
33          typedef typename container_right_trait_type::model_type  container_right_const_input_type;
34 
35          typedef ::color::_internal::diverse< category_left_type >    diverse_type;
36          typedef ::color::_internal::normalize< category_right_type > normalize_type;
37 
38          enum
39           {
40                    hue_p = ::color::place::_internal::hue<category_left_type>::position_enum
41            ,saturation_p = ::color::place::_internal::saturation<category_left_type>::position_enum
42            , lightness_p = ::color::place::_internal::lightness<category_left_type>::position_enum
43           };
44 
45          enum
46           {
47             cyan_p       = ::color::place::_internal::cyan<category_right_type>::position_enum
48            ,yellow_p     = ::color::place::_internal::yellow<category_right_type>::position_enum
49            ,magenta_p    = ::color::place::_internal::magenta<category_right_type>::position_enum
50           };
51 
processcolor::_internal::convert52          static void process
53           (
54             container_left_input_type         left
55            ,container_right_const_input_type  right
56           )
57           {
58            scalar_type r = scalar_type(1) - normalize_type::template process<    cyan_p>( container_right_trait_type::template get<    cyan_p>( right ) );
59            scalar_type g = scalar_type(1) - normalize_type::template process< magenta_p>( container_right_trait_type::template get< magenta_p>( right ) );
60            scalar_type b = scalar_type(1) - normalize_type::template process<  yellow_p>( container_right_trait_type::template get<  yellow_p>( right ) );
61 
62            const scalar_type hi = std::max<scalar_type>( { r, g, b } );
63            const scalar_type lo = std::min<scalar_type>( { r, g, b } );
64            scalar_type delta = hi - lo;
65 
66            scalar_type h = 0;
67            scalar_type s = 0;
68            scalar_type l = (hi + lo) / scalar_type(2);
69 
70            if( false == scalar_trait_type::is_small( delta ) )
71             {
72              s = delta / ( 1 - fabs( 2*l - 1 ) );
73              if( hi == r )
74               {
75                h = (scalar_type(60)/scalar_type(360)) * (g - b) / delta + (g < b ? scalar_type(1) : scalar_type(0));
76               }
77              if( hi == g )
78               {
79                h = (scalar_type(60)/scalar_type(360)) * (b - r) / delta + (scalar_type(120)/scalar_type(360));
80               }
81              if( hi == b )
82               {
83                h = (scalar_type(60)/scalar_type(360)) * (r - g) / delta + (scalar_type(240)/scalar_type(360));
84               }
85             }
86 
87            container_left_trait_type::template set<       hue_p>( left, diverse_type::template process<       hue_p>( h ) );
88            container_left_trait_type::template set<saturation_p>( left, diverse_type::template process<saturation_p>( s ) );
89            container_left_trait_type::template set< lightness_p>( left, diverse_type::template process< lightness_p>( l ) );
90           }
91       };
92 
93    }
94  }
95 
96 #endif
97