TuttleOFX
1
|
00001 #ifndef _TERRY_FREETYPE_UTIL_HPP_ 00002 #define _TERRY_FREETYPE_UTIL_HPP_ 00003 00004 // (C) Copyright Tom Brinkman 2007. 00005 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) 00007 00008 #include <boost/gil/image.hpp> 00009 #include <terry/numeric/operations.hpp> 00010 #include <terry/numeric/assign.hpp> 00011 #include <terry/numeric/operations_assign.hpp> 00012 00013 namespace terry { 00014 00015 enum 00016 { 00017 Left = ( 0x1 << 0 ), 00018 Center = ( 0x1 << 1 ), 00019 Right = ( 0x1 << 2 ), 00020 Top = ( 0x1 << 3 ), 00021 Middle = ( 0x1 << 4 ), 00022 Bottom = ( 0x1 << 5 ), 00023 FMiddle = ( 0x1 << 6 ), 00024 FBottom = ( 0x1 << 7 ), 00025 }; 00026 00027 struct make_special_interval 00028 { 00029 int size, r, adj, pos; 00030 00031 make_special_interval( int width, int size ) 00032 : size( size ) 00033 , r( ( width - 1 ) % size ) 00034 , adj( ( width - 1 ) / size ) 00035 , pos( 0 ) {} 00036 00037 int operator()( int in ) 00038 { 00039 int out = pos; 00040 00041 pos += adj; 00042 00043 if( r ) 00044 { 00045 ++pos; 00046 --r; 00047 } 00048 00049 return out; 00050 } 00051 00052 }; 00053 00054 struct make_alpha_blend 00055 { 00056 double alpha; 00057 00058 make_alpha_blend( double alpha ) : alpha( alpha ) {} 00059 00060 template <typename T> 00061 void operator()( T& dst, const T src ) 00062 { 00063 double dbl = ( dst * alpha - src * alpha + src * 255.0 ) / 255.0; 00064 00065 dst = (int) dbl; 00066 } 00067 00068 }; 00069 00070 template<typename GlyphView, typename View> 00071 inline 00072 void copy_and_convert_alpha_blended_pixels( const GlyphView& glyphView, const typename View::value_type& glyphColor, const View& dstView ) 00073 { 00074 using namespace boost::gil; 00075 // typedef typename GlyphView::value_type GlyphPixel; 00076 typedef typename View::value_type Pixel; 00077 00078 // typedef pixel<bits32f, layout<typename color_space_type<GlyphView>::type> > GlyphPixel32f; 00079 // typedef pixel<typename channel_type<view_t>::type, layout<gray_t> > PixelGray; 00080 00081 // BOOST_STATIC_ASSERT(( boost::is_same<typename color_space_type<glyphView>::type, gray_t>::value )); 00082 // BOOST_STATIC_ASSERT(( boost::is_same<typename channel_type<glyphView>::type, bits32f>::value )); 00083 00084 for( int y = 0; 00085 y < dstView.height(); 00086 ++y ) 00087 { 00088 typename GlyphView::x_iterator it_glyph = glyphView.x_at( 0, y ); 00089 typename View::x_iterator it_img = dstView.x_at( 0, y ); 00090 for( int x = 0; 00091 x < dstView.width(); 00092 ++x, ++it_glyph, ++it_img ) 00093 { 00094 Pixel pColor = glyphColor; 00095 numeric::pixel_multiplies_scalar_assign_t<float, Pixel>() 00096 ( 00097 get_color( *it_glyph, gray_color_t() ), 00098 pColor 00099 ); 00100 numeric::pixel_multiplies_scalar_assign_t<float, Pixel>() 00101 ( 00102 channel_invert( get_color( *it_glyph, gray_color_t() ) ), 00103 *it_img 00104 ); 00105 numeric::pixel_plus_assign_t<Pixel, Pixel>() 00106 ( 00107 pColor, 00108 *it_img 00109 ); 00110 // TUTTLE_CLOG_VAR( TUTTLE_TRACE, get_color( *it_glyph, gray_color_t() ) ); 00111 // TUTTLE_CLOG_VAR( TUTTLE_TRACE, (*it_img)[0] ); 00112 // TUTTLE_CLOG_VAR( TUTTLE_TRACE, (int)(color[0]) ); 00113 // TUTTLE_CLOG_VAR( TUTTLE_TRACE, (int)(pColor[0]) ); 00114 } 00115 } 00116 } 00117 00118 template <typename view_t, typename value_type> 00119 inline void wuline( const view_t& view, const value_type& pixel, 00120 int X0, int Y0, int X1, int Y1, 00121 int NumLevels, int IntensityBits ) 00122 { 00123 unsigned short IntensityShift, ErrorAdj, ErrorAcc; 00124 unsigned short ErrorAccTemp, Weighting, WeightingComplementMask; 00125 short DeltaX, DeltaY, Temp, XDir; 00126 00127 if( Y0 > Y1 ) 00128 { 00129 Temp = Y0; 00130 Y0 = Y1; 00131 Y1 = Temp; 00132 Temp = X0; 00133 X0 = X1; 00134 X1 = Temp; 00135 } 00136 00137 view( X0, Y0 ) = pixel; 00138 00139 if( ( DeltaX = X1 - X0 ) >= 0 ) 00140 { 00141 XDir = 1; 00142 } 00143 else 00144 { 00145 XDir = -1; 00146 DeltaX = -DeltaX; 00147 } 00148 00149 if( ( DeltaY = Y1 - Y0 ) == 0 ) 00150 { 00151 while( DeltaX-- != 0 ) 00152 { 00153 X0 += XDir; 00154 view( X0, Y0 ) = pixel; 00155 } 00156 00157 return; 00158 } 00159 00160 if( DeltaX == 0 ) 00161 { 00162 do 00163 { 00164 Y0++; 00165 view( X0, Y0 ) = pixel; 00166 } 00167 while( --DeltaY != 0 ); 00168 00169 return; 00170 } 00171 00172 if( DeltaX == DeltaY ) 00173 { 00174 do 00175 { 00176 X0 += XDir; 00177 Y0++; 00178 view( X0, Y0 ) = pixel; 00179 } 00180 while( --DeltaY != 0 ); 00181 00182 return; 00183 } 00184 00185 ErrorAcc = 0; 00186 IntensityShift = 16 - IntensityBits; 00187 WeightingComplementMask = NumLevels - 1; 00188 00189 if( DeltaY > DeltaX ) 00190 { 00191 ErrorAdj = ( (unsigned long) DeltaX << 16 ) / (unsigned long) DeltaY; 00192 00193 while( --DeltaY ) 00194 { 00195 ErrorAccTemp = ErrorAcc; 00196 ErrorAcc += ErrorAdj; 00197 00198 if( ErrorAcc <= ErrorAccTemp ) 00199 X0 += XDir; 00200 00201 Y0++; 00202 00203 Weighting = ErrorAcc >> IntensityShift; 00204 00205 value_type dst = pixel; 00206 boost::gil::static_for_each( dst, view( X0, Y0 ), 00207 make_alpha_blend( ( Weighting ^ WeightingComplementMask ) ) ); 00208 view( X0, Y0 ) = dst; 00209 00210 dst = pixel; 00211 boost::gil::static_for_each( dst, view( X0 + XDir, Y0 ), 00212 make_alpha_blend( Weighting ) ); 00213 view( X0 + XDir, Y0 ) = dst; 00214 } 00215 00216 view( X1, Y1 ) = pixel; 00217 return; 00218 } 00219 00220 ErrorAdj = ( (unsigned long) DeltaY << 16 ) / (unsigned long) DeltaX; 00221 while( --DeltaX ) 00222 { 00223 ErrorAccTemp = ErrorAcc; 00224 ErrorAcc += ErrorAdj; 00225 00226 if( ErrorAcc <= ErrorAccTemp ) 00227 Y0++; 00228 00229 X0 += XDir; 00230 00231 Weighting = ErrorAcc >> IntensityShift; 00232 00233 value_type dst = pixel; 00234 boost::gil::static_for_each( dst, view( X0, Y0 ), 00235 make_alpha_blend( Weighting ^ WeightingComplementMask ) ); 00236 view( X0, Y0 ) = dst; 00237 00238 dst = pixel; 00239 boost::gil::static_for_each( dst, view( X0, Y0 + 1 ), 00240 make_alpha_blend( Weighting ) ); 00241 view( X0, Y0 + 1 ) = dst; 00242 } 00243 00244 view( X1, Y1 ) = pixel; 00245 } 00246 00247 template <typename view_t> 00248 struct draw_line 00249 { 00250 typedef typename view_t::value_type value_type; 00251 const view_t& view; 00252 const value_type& pixel; 00253 short NumLevels; 00254 unsigned short IntensityBits; 00255 00256 draw_line( const view_t& view, const value_type& pixel, 00257 int NumLevels = 256, int IntensityBits = 8 ) 00258 : view( view ) 00259 , pixel( pixel ) 00260 , NumLevels( NumLevels ) 00261 , IntensityBits( IntensityBits ) {} 00262 00263 template <typename point_t> 00264 void operator()( point_t pt0, point_t pt1 ) 00265 { 00266 wuline( view, pixel, 00267 pt0.x, pt0.y, pt1.x, pt1.y, 00268 NumLevels, IntensityBits ); 00269 } 00270 00271 }; 00272 00273 } 00274 00275 #endif 00276